shithub: freetype+ttf2subf

Download patch

ref: 9b3d1c75ad150b7964b7e8cc5619c0f5b49ec72f
parent: 607358967fdedae281f8e6eac33f8a6d4c9aa403
author: David Turner <[email protected]>
date: Fri Jul 7 15:47:34 EDT 2000

- fixed a leak in the Type 1 driver
- updated the CFF driver to support flex opcodes

git/fs: mount .git/fs: mount/attach disallowed
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,23 @@
 LATEST CHANGES
 
+  - found a memory leak in the "type1" driver
+  
+  - incorporated Tom's patches to support flex operators correctly
+    in OpenType/CFF fonts.. Now all I need is to support pure CFF
+    and CEF fonts to be done with this driver.. :-)
+
+  - added the Windows FNT/FON driver in "src/winfonts". For now,
+    it always "simulates" a Unicode charmap, so it shouldn't be
+    considered completed right now..
+    
+    It's there to be more a proof of concept than anything else
+    anyway. The driver is a single C source file, that compiles
+    to 3 Kb of code..
+    
+    I'm still working on the PCF/BDF drivers.. but I'm too lazy
+    to finish them now..
+
+
   - CHANGES TO THE HIGH-LEVEL API
   
     o FT_Get_Kerning has a new parameter that allows you to select
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -7,3 +7,4 @@
 FT_USE_MODULE(tt_driver_class)
 FT_USE_MODULE(t1_driver_class)
 FT_USE_MODULE(t1z_driver_class)
+FT_USE_MODULE(winfnt_driver_class)
--- a/include/freetype/ftoutln.h
+++ b/include/freetype/ftoutln.h
@@ -96,7 +96,12 @@
                                            FT_Int       numContours,
                                            FT_Outline*  outline );
 
+  FT_EXPORT_DEF(FT_Error)  FT_Outline_New_Internal( FT_Memory    memory,
+                                                    FT_UInt      numPoints,
+                                                    FT_Int       numContours,
+                                                    FT_Outline*  outline );
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -128,6 +133,9 @@
   /*                                                                       */
   FT_EXPORT_DEF(FT_Error)  FT_Outline_Done( FT_Library   library,
                                             FT_Outline*  outline );
+
+  FT_EXPORT_DEF( FT_Error )  FT_Outline_Done_Internal( FT_Memory    memory,
+                                                       FT_Outline*  outline );
 
   /*************************************************************************/
   /*                                                                       */
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -175,6 +175,10 @@
 #define GET_ULong()    FT_GET_MACRO( FT_Get_Long, FT_ULong )
 #define GET_Tag4()     FT_GET_MACRO( FT_Get_Long, FT_ULong )
 
+#define GET_ShortLE()   FT_GET_MACRO( FT_Get_ShortLE, FT_Short )
+#define GET_UShortLE()  FT_GET_MACRO( FT_Get_ShortLE, FT_UShort )
+#define GET_LongLE()    FT_GET_MACRO( FT_Get_LongLE,  FT_Short )
+#define GET_ULongLE()   FT_GET_MACRO( FT_Get_LongLE,  FT_Short )
 
 #define FT_READ_MACRO( func, type, var )        \
           ( var = (type)func( stream, &error ), \
@@ -189,6 +193,10 @@
 #define READ_Long( var )     FT_READ_MACRO( FT_Read_Long, FT_Long, var )
 #define READ_ULong( var )    FT_READ_MACRO( FT_Read_Long, FT_ULong, var )
 
+#define READ_ShortLE( var )    FT_READ_MACRO( FT_Read_ShortLE, FT_Short, var )
+#define READ_UShortLE( var )   FT_READ_MACRO( FT_Read_ShortLE, FT_UShort, var )
+#define READ_LongLE( var )     FT_READ_MACRO( FT_Read_LongLE, FT_Long, var )
+#define READ_ULongLE( var )    FT_READ_MACRO( FT_Read_LongLE, FT_ULong, var )
 
 
   BASE_DEF(void) FT_New_Memory_Stream( FT_Library  library,
@@ -234,8 +242,11 @@
 
   BASE_DEF(FT_Long)   FT_Get_Long( FT_Stream  stream );
 
+  BASE_DEF(FT_Short)  FT_Get_ShortLE( FT_Stream  stream );
 
+  BASE_DEF(FT_Long)   FT_Get_LongLE( FT_Stream  stream );
 
+
   BASE_DEF(FT_Char)   FT_Read_Char( FT_Stream  stream,
                                     FT_Error*  error );
 
@@ -247,6 +258,12 @@
 
   BASE_DEF(FT_Long)   FT_Read_Long( FT_Stream  stream,
                                     FT_Error*  error );
+
+  BASE_DEF(FT_Short)  FT_Read_ShortLE( FT_Stream  stream,
+                                       FT_Error*  error );
+
+  BASE_DEF(FT_Long)   FT_Read_LongLE( FT_Stream  stream,
+                                      FT_Error*  error );
 
   BASE_DEF(FT_Error)  FT_Read_Fields( FT_Stream             stream,
                                       const FT_Frame_Field* fields,
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1937,10 +1937,10 @@
     {
       metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM );
       metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM );
+
+      ft_recompute_scaled_metrics( face, metrics );
     }
 
-    ft_recompute_scaled_metrics( face, metrics );
-
     if ( clazz->set_char_sizes )
       error = clazz->set_char_sizes( face->size,
                                      char_width,
@@ -2014,9 +2014,9 @@
 
       metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
                                     face->units_per_EM );
+                                    
+      ft_recompute_scaled_metrics( face, metrics );
     }
-
-    ft_recompute_scaled_metrics( face, metrics );
 
     if ( clazz->set_pixel_sizes )
       error = clazz->set_pixel_sizes( face->size,
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -270,6 +270,39 @@
   }
 
 
+  FT_EXPORT_FUNC( FT_Error )  FT_Outline_New_Internal( FT_Memory    memory,
+                                                       FT_UInt      numPoints,
+                                                       FT_Int       numContours,
+                                                       FT_Outline*  outline )
+  {
+    FT_Error   error;
+
+
+    if ( !outline )
+      return FT_Err_Invalid_Argument;
+
+    *outline = null_outline;
+
+    if ( ALLOC_ARRAY( outline->points,   numPoints * 2L, FT_Pos    ) ||
+         ALLOC_ARRAY( outline->tags,     numPoints,      FT_Byte   ) ||
+         ALLOC_ARRAY( outline->contours, numContours,    FT_UShort ) )
+      goto Fail;
+
+    outline->n_points    = (FT_UShort)numPoints;
+    outline->n_contours  = (FT_Short)numContours;
+    outline->flags      |= ft_outline_owner;
+
+    return FT_Err_Ok;
+
+  Fail:
+    outline->flags |= ft_outline_owner;
+    FT_Outline_Done_Internal( memory, outline );
+
+    return error;
+  }
+
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -302,40 +335,17 @@
   /*    The reason why this function takes a `library' parameter is simply */
   /*    to use the library's memory allocator.                             */
   /*                                                                       */
-  BASE_FUNC( FT_Error )  FT_Outline_New( FT_Library   library,
-                                         FT_UInt      numPoints,
-                                         FT_Int       numContours,
-                                         FT_Outline*  outline )
+  FT_EXPORT_FUNC( FT_Error )  FT_Outline_New( FT_Library   library,
+                                              FT_UInt      numPoints,
+                                              FT_Int       numContours,
+                                              FT_Outline*  outline )
   {
-    FT_Error   error;
-    FT_Memory  memory;
-
-
-    if ( !outline )
-      return FT_Err_Invalid_Argument;
-
-    *outline = null_outline;
-    memory   = library->memory;
-
-    if ( ALLOC_ARRAY( outline->points,   numPoints * 2L, FT_Pos    ) ||
-         ALLOC_ARRAY( outline->tags,     numPoints,      FT_Byte   ) ||
-         ALLOC_ARRAY( outline->contours, numContours,    FT_UShort ) )
-      goto Fail;
-
-    outline->n_points    = (FT_UShort)numPoints;
-    outline->n_contours  = (FT_Short)numContours;
-    outline->flags      |= ft_outline_owner;
-
-    return FT_Err_Ok;
-
-  Fail:
-    outline->flags |= ft_outline_owner;
-    FT_Outline_Done( library, outline );
-
-    return error;
+    return FT_Outline_New_Internal( library->memory, numPoints,
+                                    numContours, outline );
+    
   }
+  
 
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -414,12 +424,10 @@
   /*    The reason why this function takes an `outline' parameter is       */
   /*    simply to use FT_Free().                                           */
   /*                                                                       */
-  BASE_FUNC( FT_Error )  FT_Outline_Done( FT_Library   library,
-                                          FT_Outline*  outline )
-  {
-    FT_Memory  memory = library->memory;
 
-
+  FT_EXPORT_FUNC( FT_Error )  FT_Outline_Done_Internal( FT_Memory    memory,
+                                                        FT_Outline*  outline )
+  {
     if ( outline )
     {
       if ( outline->flags & ft_outline_owner )
@@ -435,7 +443,14 @@
     else
       return FT_Err_Invalid_Argument;
   }
+                                          
+                                          
+  FT_EXPORT_FUNC( FT_Error )  FT_Outline_Done( FT_Library   library,
+                                               FT_Outline*  outline )
 
+  {
+    return FT_Outline_Done_Internal( library->memory, outline );
+  }
 
   /*************************************************************************/
   /*                                                                       */
@@ -463,8 +478,8 @@
   /* <MT-Note>                                                             */
   /*    Yes.                                                               */
   /*                                                                       */
-  BASE_FUNC( void )  FT_Outline_Get_CBox( FT_Outline*  outline,
-                                          FT_BBox*     cbox )
+  FT_EXPORT_FUNC( void )  FT_Outline_Get_CBox( FT_Outline*  outline,
+                                               FT_BBox*     cbox )
   {
     FT_Pos  xMin, yMin, xMax, yMax;
 
@@ -529,9 +544,9 @@
   /* <MT-Note>                                                             */
   /*    Yes.                                                               */
   /*                                                                       */
-  BASE_FUNC( void )  FT_Outline_Translate( FT_Outline*  outline,
-                                           FT_Pos       xOffset,
-                                           FT_Pos       yOffset )
+  FT_EXPORT_FUNC( void )  FT_Outline_Translate( FT_Outline*  outline,
+                                                FT_Pos       xOffset,
+                                                FT_Pos       yOffset )
   {
     FT_UShort   n;
     FT_Vector*  vec = outline->points;
@@ -562,7 +577,7 @@
   /*    This functions toggles the bit flag `ft_outline_reverse_fill' in   */
   /*    the outline's `flags' field.                                       */
   /*                                                                       */
-  BASE_FUNC( void )  FT_Outline_Reverse( FT_Outline*  outline )
+  FT_EXPORT_FUNC( void )  FT_Outline_Reverse( FT_Outline*  outline )
   {
     FT_UShort  n;
     FT_Int     first, last;
--- a/src/base/ftstream.c
+++ b/src/base/ftstream.c
@@ -301,6 +301,24 @@
   }
 
 
+  BASE_FUNC( FT_Short )  FT_Get_ShortLE( FT_Stream  stream )
+  {
+    FT_Byte*  p;
+    FT_Short  result;
+
+
+    FT_Assert( stream && stream->cursor );
+
+    result         = 0;
+    p              = stream->cursor;
+    if ( p + 1 < stream->limit )
+      result       = NEXT_ShortLE( p );
+    stream->cursor = p;
+
+    return result;
+  }
+
+
   BASE_FUNC( FT_Long )  FT_Get_Offset( FT_Stream  stream )
   {
     FT_Byte*  p;
@@ -335,6 +353,23 @@
   }
 
 
+  BASE_FUNC( FT_Long )  FT_Get_LongLE( FT_Stream  stream )
+  {
+    FT_Byte*  p;
+    FT_Long   result;
+
+
+    FT_Assert( stream && stream->cursor );
+
+    result         = 0;
+    p              = stream->cursor;
+    if ( p + 3 < stream->limit )
+      result       = NEXT_LongLE( p );
+    stream->cursor = p;
+    return result;
+  }
+
+
   BASE_FUNC( FT_Char )  FT_Read_Char( FT_Stream  stream,
                                       FT_Error*  error )
   {
@@ -417,6 +452,52 @@
   }
 
 
+  BASE_FUNC( FT_Short )  FT_Read_ShortLE( FT_Stream  stream,
+                                          FT_Error*  error )
+  {
+    FT_Byte   reads[2];
+    FT_Byte*  p = 0;
+    FT_Short  result = 0;
+
+
+    FT_Assert( stream );
+
+    *error = FT_Err_Ok;
+
+    if ( stream->pos + 1 < stream->size )
+    {
+      if ( stream->read )
+      {
+        if ( stream->read( stream, stream->pos, reads, 2L ) != 2L )
+          goto Fail;
+
+        p = reads;
+      }
+      else
+      {
+        p = stream->base + stream->pos;
+      }
+
+      if ( p )
+        result = NEXT_ShortLE( p );
+    }
+    else
+      goto Fail;
+
+    stream->pos += 2;
+
+    return result;
+
+  Fail:
+    *error = FT_Err_Invalid_Stream_Operation;
+    FT_ERROR(( "FT_Read_Short:" ));
+    FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+               stream->pos, stream->size ));
+
+    return 0;
+  }
+
+
   BASE_FUNC( FT_Long )  FT_Read_Offset( FT_Stream  stream,
                                         FT_Error*  error )
   {
@@ -507,6 +588,54 @@
 
     return 0;
   }
+
+
+  BASE_FUNC( FT_Long )  FT_Read_LongLE( FT_Stream  stream,
+                                        FT_Error*  error )
+  {
+    FT_Byte   reads[4];
+    FT_Byte*  p = 0;
+    FT_Long   result = 0;
+
+
+    FT_Assert( stream );
+
+    *error = FT_Err_Ok;
+
+    if ( stream->pos + 3 < stream->size )
+    {
+      if ( stream->read )
+      {
+        if ( stream->read( stream, stream->pos, reads, 4L ) != 4L )
+          goto Fail;
+
+        p = reads;
+      }
+      else
+      {
+        p = stream->base + stream->pos;
+      }
+
+      if ( p )
+        result = NEXT_LongLE( p );
+    }
+    else
+      goto Fail;
+
+    stream->pos += 4;
+
+    return result;
+
+  Fail:
+    FT_ERROR(( "FT_Read_Long:" ));
+    FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+               stream->pos, stream->size ));
+    *error = FT_Err_Invalid_Stream_Operation;
+
+    return 0;
+  }
+
+
 
 
   BASE_FUNC( FT_Error ) FT_Read_Fields( FT_Stream              stream,
--- a/src/cff/t2gload.c
+++ b/src/cff/t2gload.c
@@ -464,19 +464,17 @@
                          FT_Pos       x,
                          FT_Pos       y )
   {
+    FT_Error  error;
+    
     /* test whether we are building a new contour */
     if ( !builder->path_begun )
     {
-      FT_Error  error;
-
-
       builder->path_begun = 1;
       error = add_contour( builder );
-      if ( error )
-        return error;
+      if ( !error )
+        error = add_point1( builder, x, y );
     }
-
-    return add_point1( builder, x, y );
+    return error;
   }
 
 
@@ -901,7 +899,7 @@
           break;
 
         case t2_op_hmoveto:
-          FT_TRACE4(( " vmoveto" ));
+          FT_TRACE4(( " hmoveto" ));
 
           close_contour( builder );
           builder->path_begun = 0;
@@ -1152,6 +1150,7 @@
           }
           break;
 
+
         case t2_op_rcurveline:
           {
             FT_Int  num_curves = ( num_args - 2 ) / 6;
@@ -1191,6 +1190,198 @@
             args = stack;
           }
           break;
+
+
+
+        case t2_op_hflex1:
+          {
+            FT_Pos start_y;
+   
+            FT_TRACE4(( " hflex1" ));
+   
+            args = stack;
+   
+            /* Adding five more points; 4 control points, 1 on curve point. */
+            if (start_point ( builder, x, y ) || check_points ( builder, 5 ) )
+              goto Memory_Error;
+   
+            /* Record the starting point's y postion for later use */
+            start_y = y;
+   
+            /* first control point */
+            x += args[0];
+            y += args[1];
+            add_point( builder, x, y, 0 );
+   
+            /* second control point */
+            x += args[2];
+            y += args[3];
+            add_point( builder, x, y, 0 );
+   
+            /* join point; on curve, with y-value the same as the last */
+            /* control point's y-value                                 */
+            x += args[4];
+            add_point( builder, x, y, 1 );
+            
+            /* third control point, with y-value the same as the join */
+            /* point's y-value                                        */
+            x += args[5];
+            add_point( builder, x, y, 0 );
+   
+            /* fourth control point */
+            x += args[6];
+            y += args[7];
+            add_point( builder, x, y, 0 );
+   
+            /* ending point, with y-value the same as the start  */
+            /* point's y-value. we don't add this point, though. */
+            x += args[8];
+            y  = start_y;
+   
+            args = stack;
+            break;
+          }
+
+
+        case t2_op_hflex:
+          {
+            FT_Pos start_y;
+ 
+            FT_TRACE4(( " hflex" ));
+ 
+            args = stack;
+ 
+            /* Adding five more points; 4 control points, 1 on curve point. */
+            if (start_point ( builder, x, y ) || check_points ( builder, 5 ) )
+ 
+              goto Memory_Error;
+ 
+            /* Record the starting point's y postion for later use */
+            start_y = y;
+ 
+            /* first control point */
+            x += args[0];
+            add_point( builder, x, y, 0 );
+ 
+            /* second control point */
+            x += args[1];
+            y += args[2];
+            add_point( builder, x, y, 0 );
+  
+            /* join point; on curve, with y-value the same as the last */
+            /* control point's y-value                                 */
+            x += args[3];
+            add_point( builder, x, y, 1 );
+ 
+            /* third control point, with y-value the same as the join */
+            /* point's y-value                                        */
+            x += args[4];
+            add_point( builder, x, y, 0 );
+ 
+            /* fourth control point */
+            x += args[5];
+            y  = start_y;
+            add_point( builder, x, y, 0 );
+ 
+            /* ending point, with y-value the same as the start point's */
+            /* y-value we don't add this point, though.                 */
+            x += args[6];
+ 
+            args = stack;
+            break;
+          }
+
+
+        case t2_op_flex1:
+          {
+            FT_Pos start_x, start_y; /* record start x,y values for alter use */
+            FT_Int dx = 0, dy = 0;   /* used in hort./vert. algorithm below   */
+            FT_Int hort_flag, count;
+ 
+            FT_TRACE4(( " flex1" ));
+   
+            /* Adding five more points; 4 control points, 1 on curve point. */
+            if (start_point ( builder, x, y ) || check_points ( builder, 5 ) )
+               goto Memory_Error;
+   
+             /* Record the starting point's x,y postion for later use */
+            start_x = x;
+            start_y = y;
+   
+            /* XXXX: figure out if this is supposed to be a horizontal or */
+            /* vertical flex. The Type 2 specification is vague...        */
+   
+            args = stack;
+            
+            /* grab up to the last argument */
+            while ( args < decoder->top - 1)
+            {
+              dx += args[0];
+              dy += args[1];
+              args += 2;
+            }
+   
+            /* rewind */
+            args = stack;
+   
+            if ( dx < 0 ) dx = -dx;
+            if ( dy < 0 ) dy = -dy;
+   
+            /* strange test, but here it is... */
+            hort_flag = (dx > dy);
+   
+            for ( count = 5; count > 0; count-- )
+            {
+              x += args[0];
+              y += args[1];
+              add_point( builder, x, y, (FT_Bool)(count == 3) );
+              args += 2;
+            }
+   
+            if (hort_flag)
+            {
+              x += args[0];
+              y  = start_y;
+            }
+            else
+            {
+              x  = start_x;
+              y += args[0];
+            }
+   
+            args = stack;
+            break;
+           }
+  
+
+        case t2_op_flex:
+          {
+            FT_UInt   count;
+            
+            FT_TRACE4(( " flex" ));
+   
+             if (start_point ( builder, x, y ) || check_points ( builder, 5 ) )
+               goto Memory_Error;
+   
+            args = stack;
+            for ( count = 5; count > 0; count-- )
+            {
+              x += args[0];
+              y += args[1];
+              add_point( builder, x, y, (FT_Bool)(count == 3) );
+              args += 2;
+            }
+            
+            x += args[0];
+            y += args[1];
+  
+            args = stack;
+          }
+          break;
+
+
+
+
 
         case t2_op_endchar:
           FT_TRACE4(( " endchar" ));
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -239,7 +239,7 @@
   const CID_Field_Rec  t1_field_records[] =
   {
 #include <cidtokens.h>
-    { 0 }
+    { 0, 0, 0, 0, 0, 0, 0, 0 }
   };
 
 
--- a/src/type1/t1tokens.c
+++ b/src/type1/t1tokens.c
@@ -373,6 +373,7 @@
     return T1_Err_Ok;
 
   Fail:
+    FREE( tokzer->base );
     FREE( tokzer );
     return error;
   }