summary refs log tree commit diff
path: root/src/freetype/ftutil.c
diff options
context:
space:
mode:
authorWlodekM <[email protected]>2024-06-16 10:35:45 +0300
committerWlodekM <[email protected]>2024-06-16 10:35:45 +0300
commitabef6da56913f1c55528103e60a50451a39628b1 (patch)
treeb3c8092471ecbb73e568cd0d336efa0e7871ee8d /src/freetype/ftutil.c
initial commit
Diffstat (limited to 'src/freetype/ftutil.c')
-rw-r--r--src/freetype/ftutil.c352
1 files changed, 352 insertions, 0 deletions
diff --git a/src/freetype/ftutil.c b/src/freetype/ftutil.c
new file mode 100644
index 0000000..d774408
--- /dev/null
+++ b/src/freetype/ftutil.c
@@ -0,0 +1,352 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftutil.c                                                               */
+/*                                                                         */
+/*    FreeType utility file for memory and list management (body).         */
+/*                                                                         */
+/*  Copyright 2002-2018 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include "ft2build.h"
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_MEMORY_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_LIST_H
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_memory
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                                                               *****/
+  /*****               M E M O R Y   M A N A G E M E N T               *****/
+  /*****                                                               *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  FT_BASE_DEF( FT_Pointer )
+  ft_mem_alloc( FT_Memory  memory,
+                FT_Long    size,
+                FT_Error  *p_error )
+  {
+    FT_Error    error;
+    FT_Pointer  block = ft_mem_qalloc( memory, size, &error );
+
+    if ( !error && size > 0 )
+      FT_MEM_ZERO( block, size );
+
+    *p_error = error;
+    return block;
+  }
+
+
+  FT_BASE_DEF( FT_Pointer )
+  ft_mem_qalloc( FT_Memory  memory,
+                 FT_Long    size,
+                 FT_Error  *p_error )
+  {
+    FT_Error    error = FT_Err_Ok;
+    FT_Pointer  block = NULL;
+
+
+    if ( size > 0 )
+    {
+      block = memory->alloc( memory, size );
+      if ( !block )
+        error = FT_THROW( Out_Of_Memory );
+    }
+    else if ( size < 0 )
+    {
+      /* may help catch/prevent security issues */
+      error = FT_THROW( Invalid_Argument );
+    }
+
+    *p_error = error;
+    return block;
+  }
+
+
+  FT_BASE_DEF( FT_Pointer )
+  ft_mem_realloc( FT_Memory  memory,
+                  FT_Long    item_size,
+                  FT_Long    cur_count,
+                  FT_Long    new_count,
+                  void*      block,
+                  FT_Error  *p_error )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+
+    block = ft_mem_qrealloc( memory, item_size,
+                             cur_count, new_count, block, &error );
+    if ( !error && new_count > cur_count )
+      FT_MEM_ZERO( (char*)block + cur_count * item_size,
+                   ( new_count - cur_count ) * item_size );
+
+    *p_error = error;
+    return block;
+  }
+
+
+  FT_BASE_DEF( FT_Pointer )
+  ft_mem_qrealloc( FT_Memory  memory,
+                   FT_Long    item_size,
+                   FT_Long    cur_count,
+                   FT_Long    new_count,
+                   void*      block,
+                   FT_Error  *p_error )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+
+    /* Note that we now accept `item_size == 0' as a valid parameter, in
+     * order to cover very weird cases where an ALLOC_MULT macro would be
+     * called.
+     */
+    if ( cur_count < 0 || new_count < 0 || item_size < 0 )
+    {
+      /* may help catch/prevent nasty security issues */
+      error = FT_THROW( Invalid_Argument );
+    }
+    else if ( new_count == 0 || item_size == 0 )
+    {
+      ft_mem_free( memory, block );
+      block = NULL;
+    }
+    else if ( new_count > FT_INT_MAX / item_size )
+    {
+      error = FT_THROW( Array_Too_Large );
+    }
+    else if ( cur_count == 0 )
+    {
+      FT_ASSERT( !block );
+
+      block = memory->alloc( memory, new_count * item_size );
+      if ( block == NULL )
+        error = FT_THROW( Out_Of_Memory );
+    }
+    else
+    {
+      FT_Pointer  block2;
+      FT_Long     cur_size = cur_count * item_size;
+      FT_Long     new_size = new_count * item_size;
+
+
+      block2 = memory->realloc( memory, cur_size, new_size, block );
+      if ( !block2 )
+        error = FT_THROW( Out_Of_Memory );
+      else
+        block = block2;
+    }
+
+    *p_error = error;
+    return block;
+  }
+
+
+  FT_BASE_DEF( void )
+  ft_mem_free( FT_Memory   memory,
+               const void *P )
+  {
+    if ( P )
+      memory->free( memory, (void*)P );
+  }
+
+
+  FT_BASE_DEF( FT_Pointer )
+  ft_mem_dup( FT_Memory    memory,
+              const void*  address,
+              FT_ULong     size,
+              FT_Error    *p_error )
+  {
+    FT_Error    error;
+    FT_Pointer  p = ft_mem_qalloc( memory, (FT_Long)size, &error );
+
+
+    if ( !error && address )
+      ft_memcpy( p, address, size );
+
+    *p_error = error;
+    return p;
+  }
+
+
+  FT_BASE_DEF( FT_Pointer )
+  ft_mem_strdup( FT_Memory    memory,
+                 const char*  str,
+                 FT_Error    *p_error )
+  {
+    FT_ULong  len = str ? (FT_ULong)ft_strlen( str ) + 1
+                        : 0;
+
+
+    return ft_mem_dup( memory, str, len, p_error );
+  }
+
+
+  FT_BASE_DEF( FT_Int )
+  ft_mem_strcpyn( char*        dst,
+                  const char*  src,
+                  FT_ULong     size )
+  {
+    while ( size > 1 && *src != 0 )
+    {
+      *dst++ = *src++;
+      size--;
+    }
+
+    *dst = 0;  /* always zero-terminate */
+
+    return *src != 0;
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                                                               *****/
+  /*****            D O U B L Y   L I N K E D   L I S T S              *****/
+  /*****                                                               *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_list
+
+  /* documentation is in ftlist.h */
+
+  FT_EXPORT_DEF( FT_ListNode )
+  FT_List_Find( FT_List  list,
+                void*    data )
+  {
+    FT_ListNode  cur;
+
+
+    if ( !list )
+      return NULL;
+
+    cur = list->head;
+    while ( cur )
+    {
+      if ( cur->data == data )
+        return cur;
+
+      cur = cur->next;
+    }
+
+    return NULL;
+  }
+
+
+  /* documentation is in ftlist.h */
+
+  FT_EXPORT_DEF( void )
+  FT_List_Add( FT_List      list,
+               FT_ListNode  node )
+  {
+    FT_ListNode  before;
+
+
+    if ( !list || !node )
+      return;
+
+    before = list->tail;
+
+    node->next = NULL;
+    node->prev = before;
+
+    if ( before )
+      before->next = node;
+    else
+      list->head = node;
+
+    list->tail = node;
+  }
+
+
+  /* documentation is in ftlist.h */
+
+  FT_EXPORT_DEF( void )
+  FT_List_Remove( FT_List      list,
+                  FT_ListNode  node )
+  {
+    FT_ListNode  before, after;
+
+
+    if ( !list || !node )
+      return;
+
+    before = node->prev;
+    after  = node->next;
+
+    if ( before )
+      before->next = after;
+    else
+      list->head = after;
+
+    if ( after )
+      after->prev = before;
+    else
+      list->tail = before;
+  }
+
+
+  /* documentation is in ftlist.h */
+
+  FT_EXPORT_DEF( void )
+  FT_List_Finalize( FT_List             list,
+                    FT_List_Destructor  destroy,
+                    FT_Memory           memory,
+                    void*               user )
+  {
+    FT_ListNode  cur;
+
+
+    if ( !list || !memory )
+      return;
+
+    cur = list->head;
+    while ( cur )
+    {
+      FT_ListNode  next = cur->next;
+      void*        data = cur->data;
+
+
+      if ( destroy )
+        destroy( memory, data, user );
+
+      FT_FREE( cur );
+      cur = next;
+    }
+
+    list->head = NULL;
+    list->tail = NULL;
+  }
+
+
+/* END */