shithub: freetype+ttf2subf

Download patch

ref: fbff3e8fc75e891ced1d8350234bc9d8f21314b9
parent: c64f644264cc3955daefc1dcc99f3a610b48850b
author: David Turner <[email protected]>
date: Mon Feb 21 11:18:25 EST 2000

added a memory checking test program, used to
solve the memory leak reported by Jack Davis

git/fs: mount .git/fs: mount/attach disallowed
--- /dev/null
+++ b/demos/src/memtest.c
@@ -1,0 +1,174 @@
+/* memtest.c */
+
+#include <freetype.h>
+#include <ftobjs.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+  EXPORT_DEF
+  void  FT_Default_Drivers( FT_Library  library );
+
+
+/* Our own memory allocator. To check that a single block isn't freed */
+/* several time, we simply do not call "free"..                       */
+
+
+#define MAX_RECORDED_BLOCKS  4096
+#define CHECK_DUPLICATES
+
+typedef  struct MyBlock
+{
+  void*  base;
+  long   size;
+
+} MyBlock;
+
+static  MyBlock my_blocks[ MAX_RECORDED_BLOCKS ];
+static  int     num_my_blocks = 0;
+
+/* record a new block in the table, check for duplicates too */
+static
+void  record_my_block( void*  base, long  size )
+{
+  if (size <= 0)
+  {
+    fprintf( stderr, "adding a block with non-positive length - should not happen \n" );
+    exit(1);
+  }
+  
+  if ( num_my_blocks < MAX_RECORDED_BLOCKS )
+  {
+    MyBlock*  block;
+    
+#ifdef CHECK_DUPLICATES
+    MyBlock*  limit;
+    block = my_blocks;
+    limit = block + num_my_blocks;
+    for ( ; block < limit; block++ )
+    {
+      if ( block->base == base && block->size != 0 )
+      {
+        fprintf( stderr, "duplicate memory block at %08lx\n", (long)block->base );
+        exit(1);
+      }
+    }
+#endif
+
+    block = my_blocks + num_my_blocks++;
+    block->base = base;
+    block->size = size;
+  }
+  else
+  {
+    fprintf( stderr, "Too many memory blocks -- test exited !!\n" );
+    exit(1);
+  }
+}
+
+/* forget a block, and check that it isn't part of our table already */
+static
+void  forget_my_block( void*  base )
+{
+  MyBlock*  block = my_blocks + num_my_blocks-1;
+  
+  /* we scan in reverse, because transient blocks are always located */
+  /* at the end of the table.. (it supposedly faster then..)         */
+  for ( ; block >= my_blocks; block-- )
+  {
+    if ( block->base == base )
+    {
+      if (block->size > 0)
+      {
+        block->size = 0;
+        return;
+      }
+      else
+      {
+        fprintf( stderr, "Block at %08lx released twice \n", (long)base );
+        exit(1);
+      }
+    }
+  }
+  fprintf( stderr, "Trying to release an unallocated block at %08lx\n",
+                   (long)base );
+  exit(1);
+}
+
+
+static
+void*  my_alloc( FT_Memory  memory,
+                 long       size )
+{
+  void*  p = malloc(size);
+  if (p)
+    record_my_block(p,size);
+    
+  return p;
+}
+
+static
+void   my_free( FT_Memory memory, void*  block )
+{
+  forget_my_block(block);
+  free(block);
+}
+
+static
+void*  my_realloc( FT_Memory memory,
+                   long      cur_size,
+                   long      new_size,
+                   void*     block )
+{
+  void*  p;
+
+  p = my_alloc( memory, new_size );
+  if (p)
+  {
+    my_free( memory, block );
+    record_my_block( p, new_size );
+  }
+  return p;
+}
+
+
+struct FT_MemoryRec_  my_memory =
+{
+  0,
+  my_alloc,
+  my_free,
+  my_realloc
+};
+
+
+int  main( void )
+{
+    FT_Library  library;
+    FT_Face     face;
+    int         glyphIndex;
+    int         result;
+
+    /* Create a new library with our own memory manager */
+    result = FT_New_Library( &my_memory, &library );
+    
+    /* the new library has no drivers in it, add the default ones */
+    /* (implemented in ftinit.c)..                                */
+    FT_Default_Drivers(library);
+
+    result = FT_New_Face( library, "d:/ttf/arial.ttf", 0, &face );
+    result = FT_Set_Char_Size( face, 0, 16*64, 96, 96 );
+
+    glyphIndex = FT_Get_Char_Index( face, (int)'A' );
+
+    /* memory error occurs in FT_DoneFreeType() if FT_Load_Glyph() is called */
+    result = FT_Load_Glyph(face, glyphIndex, FT_LOAD_DEFAULT );
+
+    result = FT_Done_Face( face );
+
+    result = FT_Done_FreeType( library ); 
+
+    return 0;
+}
+
+
+