shithub: freetype+ttf2subf

Download patch

ref: 36d2eab05468d531cf8f51dce4cbca27e553b672
parent: 2066e0acd6e78520a4837e74a6d34aa41a2ce4d6
author: Werner Lemberg <[email protected]>
date: Tue Sep 5 15:24:34 EDT 2006

* src/truetype/ttpload.c (tt_face_load_hdmx): Handle `record_size'
values which have the upper two bytes set to 0xFF instead of 0xFF
(as it happens in at least two CJKV fonts, `HAN NOM A.ttf' and
`HAN NOM B.ttf').

* src/smooth/ftgrays.c [GRAYS_USE_GAMMA]: Really remove all code.

Formatting.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,28 @@
-2006-09-05  David Turner  <[email protected]>
+2006-09-05  Werner Lemberg  <[email protected]>
 
-        * src/smooth/ftgrays.c: minor source cleanups and optimization
+	* src/truetype/ttpload.c (tt_face_load_hdmx): Handle `record_size'
+	values which have the upper two bytes set to 0xFF instead of 0xFF
+	(as it happens in at least two CJKV fonts, `HAN NOM A.ttf' and
+	`HAN NOM B.ttf').
 
-        * src/smooth/ftgrays.c (gray_sweep): Avoid buffer overwrites
-        when to drawing the end of a bitmap scanline. The fun never ends ;-)
+	* src/smooth/ftgrays.c [GRAYS_USE_GAMMA]: Really remove all code.
 
+2006-09-05  David Turner  <[email protected]>
+
+	Minor source cleanups and optimizations.
+
+	* src/smooth/ftgrays.c (GRAYS_COMPACT): Removed.
+	(TRaster): Remove `count_ex' and `count_ey'.
+	(gray_find_cell): Remove 2nd and 3rd argument.
+	(gray_alloc_cell): Merged with `gray_find_cell'.
+	(gray_record_cell): Simplify.
+	(gray_set_cell): Rewrite.
+	(gray_start_cell): Apply offsets to `ras.ex' and `ras.ey'.
+	(gray_render_span): Don't use FT_MEM_SET for small values.
+	(gray_dump_cells) [DEBUG_GRAYS]: New function.
+	(gray_sweep): Avoid buffer overwrites when to drawing the end of a
+	bitmap scanline.
+	(gray_convert_glyph): Fix speed-up.
 
 2006-09-04  David Turner  <[email protected]>
 
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -91,7 +91,7 @@
 #define FT_COMPONENT  trace_smooth
 
 
-#define ErrRaster_MemoryOverflow   -4
+#define ErrRaster_MemoryOverflow  -4
 
 
 #ifdef _STANDALONE_
@@ -160,6 +160,7 @@
   /* define this to dump debugging information */
 #define xxxDEBUG_GRAYS
 
+
   /* as usual, for the speed hungry :-) */
 
 #ifndef FT_STATIC_RASTER
@@ -207,6 +208,7 @@
 #define DOWNSCALE( x )  ( (x) << ( 6 - PIXEL_BITS ) )
 #endif
 
+
   /*************************************************************************/
   /*                                                                       */
   /*   TYPE DEFINITIONS                                                    */
@@ -225,7 +227,7 @@
 
 #if PIXEL_BITS <= 7
 
-  typedef int   TArea;
+  typedef int  TArea;
 
 #else /* PIXEL_BITS >= 8 */
 
@@ -233,7 +235,7 @@
 #if FT_UINT_MAX == 0xFFFFU
   typedef long  TArea;
 #else
-  typedef int  TArea;
+  typedef int   TArea;
 #endif
 
 #endif /* PIXEL_BITS >= 8 */
@@ -242,17 +244,17 @@
   /* maximal number of gray spans in a call to the span callback */
 #define FT_MAX_GRAY_SPANS  32
 
-typedef struct TCell_*   PCell;
 
-typedef struct TCell_
-{
-  int     x;
-  int     cover;
-  TArea   area;
-  PCell   next;
+  typedef struct TCell_*  PCell;
 
-} TCell;
+  typedef struct  TCell_
+  {
+    int    x;
+    int    cover;
+    TArea  area;
+    PCell  next;
 
+  } TCell;
 
 
   typedef struct  TRaster_
@@ -382,7 +384,7 @@
     int     x = ras.ex;
 
 
-    pcell = &ras.ycells[ ras.ey ];
+    pcell = &ras.ycells[ras.ey];
     for (;;)
     {
       cell = *pcell;
@@ -414,10 +416,11 @@
   static void
   gray_record_cell( RAS_ARG )
   {
-    if ( !ras.invalid && (ras.area | ras.cover) )
+    if ( !ras.invalid && ( ras.area | ras.cover ) )
     {
-      PCell   cell = gray_find_cell( RAS_VAR );
+      PCell  cell = gray_find_cell( RAS_VAR );
 
+
       cell->area  += ras.area;
       cell->cover += ras.cover;
     }
@@ -463,7 +466,7 @@
     ras.ex      = ex;
     ras.ey      = ey;
     ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||
-                              ex >= ras.count_ex );
+                              ex >= ras.count_ex           );
   }
 
 
@@ -472,11 +475,11 @@
   /* Start a new contour at a given cell.                                  */
   /*                                                                       */
   static void
-  gray_start_cell( RAS_ARG_  TCoord  ex,
-                             TCoord  ey )
+  gray_start_cell( RAS_ARG_ TCoord  ex,
+                            TCoord  ey )
   {
     if ( ex < ras.min_ex )
-      ex = (TCoord)(ras.min_ex - 1);
+      ex = (TCoord)( ras.min_ex - 1 );
 
     ras.area    = 0;
     ras.cover   = 0;
@@ -494,11 +497,11 @@
   /* Render a scanline as one or more cells.                               */
   /*                                                                       */
   static void
-  gray_render_scanline( RAS_ARG_  TCoord  ey,
-                                  TPos    x1,
-                                  TCoord  y1,
-                                  TPos    x2,
-                                  TCoord  y2 )
+  gray_render_scanline( RAS_ARG_ TCoord  ey,
+                                 TPos    x1,
+                                 TCoord  y1,
+                                 TPos    x2,
+                                 TCoord  y2 )
   {
     TCoord  ex1, ex2, fx1, fx2, delta;
     long    p, first, dx;
@@ -611,7 +614,7 @@
 
 
     ey1 = TRUNC( ras.last_ey );
-    ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
+    ey2 = TRUNC( to_y );     /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
     fy1 = (TCoord)( ras.y - ras.last_ey );
     fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
 
@@ -675,6 +678,7 @@
         ras.area  += area;
         ras.cover += delta;
         ey1       += incr;
+
         gray_set_cell( raster, ex, ey1 );
       }
 
@@ -681,6 +685,7 @@
       delta      = (int)( fy2 - ONE_PIXEL + first );
       ras.area  += (TArea)two_fx * delta;
       ras.cover += delta;
+
       goto End;
     }
 
@@ -807,7 +812,7 @@
     {
       /* we compute the mid-point directly in order to avoid */
       /* calling gray_split_conic()                          */
-      TPos   to_x, to_y, mid_x, mid_y;
+      TPos  to_x, to_y, mid_x, mid_y;
 
 
       to_x  = UPSCALE( to->x );
@@ -817,6 +822,7 @@
 
       gray_render_line( RAS_VAR_ mid_x, mid_y );
       gray_render_line( RAS_VAR_ to_x, to_y );
+
       return;
     }
 
@@ -878,6 +884,7 @@
         arc -= 2;
       }
     }
+
     return;
   }
 
@@ -1026,6 +1033,7 @@
         arc -= 3;
       }
     }
+
     return;
   }
 
@@ -1106,10 +1114,10 @@
 
       if ( coverage )
       {
-       /* for small-spans, it's faster to do it ourselves than
-        * calling memset. this is mainly due to the cost of the
-        * function call.
-        */
+        /* For small-spans it is faster to do it by ourselves than
+         * calling `memset'.  This is mainly due to the cost of the
+         * function call.
+         */
         if ( spans->len >= 8 )
           FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );
         else
@@ -1116,17 +1124,18 @@
         {
           unsigned char*  q = p + spans->x;
 
+
           switch ( spans->len )
           {
-            case 7: *q++ = (unsigned char)coverage;
-            case 6: *q++ = (unsigned char)coverage;
-            case 5: *q++ = (unsigned char)coverage;
-            case 4: *q++ = (unsigned char)coverage;
-            case 3: *q++ = (unsigned char)coverage;
-            case 2: *q++ = (unsigned char)coverage;
-            case 1: *q   = (unsigned char)coverage;
-            default:
-               ;
+          case 7: *q++ = (unsigned char)coverage;
+          case 6: *q++ = (unsigned char)coverage;
+          case 5: *q++ = (unsigned char)coverage;
+          case 4: *q++ = (unsigned char)coverage;
+          case 3: *q++ = (unsigned char)coverage;
+          case 2: *q++ = (unsigned char)coverage;
+          case 1: *q   = (unsigned char)coverage;
+          default:
+            ;
           }
         }
       }
@@ -1140,9 +1149,9 @@
                        TPos    area,
                        int     acount )
   {
-    FT_Span*   span;
-    int        count;
-    int        coverage;
+    FT_Span*  span;
+    int       count;
+    int       coverage;
 
 
     /* compute the coverage line's coverage, depending on the    */
@@ -1176,13 +1185,13 @@
 
     if ( coverage )
     {
-      /* see if we can add this span to the current list */
+      /* see whether we can add this span to the current list */
       count = ras.num_gray_spans;
       span  = ras.gray_spans + count - 1;
       if ( count > 0                          &&
            ras.span_y == y                    &&
            (int)span->x + span->len == (int)x &&
-           span->coverage == coverage )
+           span->coverage == coverage         )
       {
         span->len = (unsigned short)( span->len + acount );
         return;
@@ -1225,6 +1234,7 @@
       span->x        = (short)x;
       span->len      = (unsigned short)acount;
       span->coverage = (unsigned char)coverage;
+
       ras.num_gray_spans++;
     }
   }
@@ -1237,10 +1247,12 @@
   {
     int  yindex;
 
+
     for ( yindex = 0; yindex < ras.ycount; yindex++ )
     {
       PCell  cell;
 
+
       printf( "%3d:", yindex );
 
       for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
@@ -1380,9 +1392,12 @@
       v_start = outline->points[first];
       v_last  = outline->points[last];
 
-      v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y );
-      v_last.x  = SCALED( v_last.x );  v_last.y  = SCALED( v_last.y );
+      v_start.x = SCALED( v_start.x );
+      v_start.y = SCALED( v_start.y );
 
+      v_last.x  = SCALED( v_last.x );
+      v_last.y  = SCALED( v_last.y );
+
       v_control = v_start;
 
       point = outline->points + first;
@@ -1464,7 +1479,8 @@
 
               if ( tag == FT_CURVE_TAG_ON )
               {
-                error = func_interface->conic_to( &v_control, &vec, user );
+                error = func_interface->conic_to( &v_control, &vec,
+                                                  user );
                 if ( error )
                   goto Exit;
                 continue;
@@ -1476,7 +1492,8 @@
               v_middle.x = ( v_control.x + vec.x ) / 2;
               v_middle.y = ( v_control.y + vec.y ) / 2;
 
-              error = func_interface->conic_to( &v_control, &v_middle, user );
+              error = func_interface->conic_to( &v_control, &v_middle,
+                                                user );
               if ( error )
                 goto Exit;
 
@@ -1484,7 +1501,8 @@
               goto Do_Conic;
             }
 
-            error = func_interface->conic_to( &v_control, &v_start, user );
+            error = func_interface->conic_to( &v_control, &v_start,
+                                              user );
             goto Close;
           }
 
@@ -1500,9 +1518,12 @@
             point += 2;
             tags  += 2;
 
-            vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y );
-            vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y );
+            vec1.x = SCALED( point[-2].x );
+            vec1.y = SCALED( point[-2].y );
 
+            vec2.x = SCALED( point[-1].x );
+            vec2.y = SCALED( point[-1].y );
+
             if ( point <= limit )
             {
               FT_Vector  vec;
@@ -1689,13 +1710,13 @@
         ras.invalid   = 1;
         ras.min_ey    = band->min;
         ras.max_ey    = band->max;
-	ras.count_ey  = band->max - band->min;
+        ras.count_ey  = band->max - band->min;
 
         error = gray_convert_glyph_inner( RAS_VAR );
 
         if ( !error )
         {
-          gray_sweep( RAS_VAR_  &ras.target );
+          gray_sweep( RAS_VAR_ &ras.target );
           band--;
           continue;
         }
@@ -1703,13 +1724,13 @@
           return 1;
 
       ReduceBands:
-        /* render pool overflow, we will reduce the render band by half */
+        /* render pool overflow; we will reduce the render band by half */
         bottom = band->min;
         top    = band->max;
         middle = bottom + ( ( top - bottom ) >> 1 );
 
-        /* waoow! This is too complex for a single scanline, something */
-        /* must be really rotten here!                                 */
+        /* This is too complex for a single scanline; there must */
+        /* be some problems.                                     */
         if ( middle == bottom )
         {
 #ifdef DEBUG_GRAYS
@@ -1825,10 +1846,6 @@
     *araster = (FT_Raster)&the_raster;
     FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
 
-#ifdef GRAYS_USE_GAMMA
-    grays_init_gamma( (PRaster)*araster );
-#endif
-
     return 0;
   }
 
@@ -1855,10 +1872,6 @@
     {
       raster->memory = memory;
       *araster = (FT_Raster)raster;
-
-#ifdef GRAYS_USE_GAMMA
-      grays_init_gamma( raster );
-#endif
     }
 
     return error;
@@ -1878,9 +1891,9 @@
 
 
   static void
-  gray_raster_reset( FT_Raster    raster,
-                     char*        pool_base,
-                     long         pool_size )
+  gray_raster_reset( FT_Raster  raster,
+                     char*      pool_base,
+                     long       pool_size )
   {
     PRaster  rast = (PRaster)raster;
 
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -562,7 +562,23 @@
     num_records = FT_NEXT_USHORT( p );
     record_size = FT_NEXT_ULONG( p );
 
-    if ( version != 0 || num_records > 255 || record_size > 0x40000 )
+    /* The maximum number of bytes in an hdmx device record is the */
+    /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is   */
+    /* the reason why `record_size' is a long (which we read as    */
+    /* unsigned long for convenience).  In practice, two bytes     */
+    /* sufficient to hold the size value.                          */
+    /*                                                             */
+    /* There are at least two fonts, HANNOM-A and HANNOM-B version */
+    /* 2.0 (2005), which get this wrong: The upper two bytes of    */
+    /* the size value are set to 0xFF instead of 0x00.  We catch   */
+    /* and fix this.                                               */
+
+    if ( record_size >= 0xFFFF0000UL )
+      record_size &= 0xFFFFU;
+
+    /* The limit for `num_records' is a heuristic value. */
+
+    if ( version != 0 || num_records > 255 || record_size > 0x10001L )
     {
       error = TT_Err_Invalid_File_Format;
       goto Fail;
@@ -638,12 +654,25 @@
 
     FT_FRAME_EXIT();
 
+    /* The maximum number of bytes in an hdmx device record is the */
+    /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is   */
+    /* the reason why `record_size' is a long.  In practice, two   */
+    /* bytes sufficient to hold the size value.                    */
+    /*                                                             */
+    /* There are at least two fonts, HANNOM-A and HANNOM-B version */
+    /* 2.0 (2005), which get this wrong: The upper two bytes of    */
+    /* the size value are set to 0xFF instead of 0x00.  We catch   */
+    /* and fix this.                                               */
+
+    if ( (FT_ULong)record_size >= 0xFFFF0000UL )
+      record_size = (FT_Long)( (FT_ULong)record_size & 0xFFFFU );
+
     if ( record_size < 0 || num_records < 0 )
       return TT_Err_Invalid_File_Format;
 
     /* Only recognize format 0 */
     if ( hdmx->version != 0 )
-      goto Exit;
+      return TT_Err_Invalid_File_Format;
 
     /* we can't use FT_QNEW_ARRAY here; otherwise tt_face_free_hdmx */
     /* could fail during deallocation                               */