shithub: freetype+ttf2subf

Download patch

ref: cdee7d1423f8c498d1c131adc82079ffb462fb07
parent: a678560dc23f7dfa6d6cda8d0d35be37c04713e2
author: Werner Lemberg <[email protected]>
date: Sun May 31 07:54:42 EDT 2015

[truetype] Add tracing information to GX code.

* src/truetype/ttgxvar.c (ft_var_load_avar, ft_var_load_gvar,
ft_var_apply_tuple, TT_Get_MM_Var, TT_Set_MM_Blend,
TT_Set_Var_Design, tt_face_vary_cvt): Do it.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2015-05-31  Werner Lemberg  <[email protected]>
+
+	[truetype] Add tracing information to GX code.
+
+	* src/truetype/ttgxvar.c (ft_var_load_avar, ft_var_load_gvar,
+	ft_var_apply_tuple, TT_Get_MM_Var, TT_Set_MM_Blend,
+	TT_Set_Var_Design, tt_face_vary_cvt): Do it.
+
 2015-05-28  Werner Lemberg  <[email protected]>
 
 	* src/tools/apinames.c (names_dump): Fix invalid reference.
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -301,12 +301,15 @@
     FT_UNUSED( error );
 
 
+    FT_TRACE2(( "AVAR " ));
+
     blend->avar_checked = TRUE;
-    if ( ( error = face->goto_table( face,
-                                     TTAG_avar,
-                                     stream,
-                                     &table_len ) ) != 0 )
+    error = face->goto_table( face, TTAG_avar, stream, &table_len );
+    if ( error )
+    {
+      FT_TRACE2(( "is missing\n" ));
       return;
+    }
 
     if ( FT_FRAME_ENTER( table_len ) )
       return;
@@ -314,10 +317,21 @@
     version   = FT_GET_LONG();
     axisCount = FT_GET_LONG();
 
-    if ( version != 0x00010000L                       ||
-         axisCount != (FT_Long)blend->mmvar->num_axis )
+    if ( version != 0x00010000L )
+    {
+      FT_TRACE2(( "bad table version\n" ));
       goto Exit;
+    }
 
+    FT_TRACE2(( "loaded\n" ));
+
+    if ( axisCount != (FT_Long)blend->mmvar->num_axis )
+    {
+      FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `cvar'\n"
+                  "                  table are different\n" ));
+      goto Exit;
+    }
+
     if ( FT_NEW_ARRAY( blend->avar_segment, axisCount ) )
       goto Exit;
 
@@ -324,6 +338,8 @@
     segment = &blend->avar_segment[0];
     for ( i = 0; i < axisCount; i++, segment++ )
     {
+      FT_TRACE5(( "  axis %d:\n", i ));
+
       segment->pairCount = FT_GET_USHORT();
       if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) )
       {
@@ -343,7 +359,13 @@
         /* convert to Fixed */
         segment->correspondence[j].fromCoord = FT_GET_SHORT() << 2;
         segment->correspondence[j].toCoord   = FT_GET_SHORT() << 2;
+
+        FT_TRACE5(( "    mapping %.4f to %.4f\n",
+                    segment->correspondence[j].fromCoord / 65536.0,
+                    segment->correspondence[j].toCoord / 65536.0 ));
       }
+
+      FT_TRACE5(( "\n" ));
     }
 
   Exit:
@@ -410,11 +432,16 @@
     };
 
 
+    FT_TRACE2(( "GVAR " ));
+
     if ( ( error = face->goto_table( face,
                                      TTAG_gvar,
                                      stream,
                                      &table_len ) ) != 0 )
+    {
+      FT_TRACE2(( "is missing\n" ));
       goto Exit;
+    }
 
     gvar_start = FT_STREAM_POS( );
     if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) )
@@ -424,13 +451,26 @@
     blend->gv_glyphcnt = gvar_head.glyphCount;
     offsetToData       = gvar_start + gvar_head.offsetToData;
 
-    if ( gvar_head.version   != (FT_Long)0x00010000L              ||
-         gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
+    if ( gvar_head.version != 0x00010000L )
     {
+      FT_TRACE1(( "bad table version\n" ));
       error = FT_THROW( Invalid_Table );
       goto Exit;
     }
 
+    FT_TRACE2(( "loaded\n" ));
+
+    if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
+    {
+      FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n"
+                  "                  table are different\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    FT_TRACE5(( "gvar: there are %d shared coordinates:\n",
+                blend->tuplecount ));
+
     if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) )
       goto Exit;
 
@@ -469,10 +509,20 @@
         goto Exit;
 
       for ( i = 0; i < blend->tuplecount; i++ )
+      {
+        FT_TRACE5(( "  [ " ));
         for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; j++ )
+        {
           blend->tuplecoords[i * gvar_head.axisCount + j] =
             FT_GET_SHORT() << 2;                /* convert to FT_Fixed */
+          FT_TRACE5(( "%.4f ",
+            blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
+        }
+        FT_TRACE5(( "]\n" ));
+      }
 
+      FT_TRACE5(( "\n" ));
+
       FT_FRAME_EXIT();
     }
 
@@ -521,46 +571,81 @@
 
     for ( i = 0; i < blend->num_axis; i++ )
     {
+      FT_TRACE6(( "    axis coordinate %d (%.4f):\n",
+                  i, blend->normalizedcoords[i] / 65536.0 ));
+
+      /* It's not clear why (for intermediate tuples) we don't need     */
+      /* to check against start/end -- the documentation says we don't. */
+      /* Similarly, it's unclear why we don't need to scale along the   */
+      /* axis.                                                          */
+
       if ( tuple_coords[i] == 0 )
-        /* It's not clear why (for intermediate tuples) we don't need     */
-        /* to check against start/end -- the documentation says we don't. */
-        /* Similarly, it's unclear why we don't need to scale along the   */
-        /* axis.                                                          */
+      {
+        FT_TRACE6(( "      tuple coordinate is zero, ignored\n", i ));
         continue;
+      }
 
-      else if ( blend->normalizedcoords[i] == 0                           ||
-                ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
+      else if ( blend->normalizedcoords[i] == 0 )
+      {
+        FT_TRACE6(( "      axis coordinate is zero, stop\n" ));
+        apply = 0;
+        break;
+      }
+
+      else if ( ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) ||
                 ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) )
       {
+        FT_TRACE6(( "      tuple coordinate value %.4f is exceeded, stop\n",
+                    tuple_coords[i] / 65536.0 ));
         apply = 0;
         break;
       }
 
       else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
+      {
+        FT_TRACE6(( "      tuple coordinate value %.4f fits\n",
+                    tuple_coords[i] / 65536.0 ));
         /* not an intermediate tuple */
         apply = FT_MulFix( apply,
                            blend->normalizedcoords[i] > 0
                              ? blend->normalizedcoords[i]
                              : -blend->normalizedcoords[i] );
+      }
 
       else if ( blend->normalizedcoords[i] <= im_start_coords[i] ||
                 blend->normalizedcoords[i] >= im_end_coords[i]   )
       {
+        FT_TRACE6(( "      intermediate tuple range [%.4f;%.4f] is exceeded,"
+                    " stop\n",
+                    im_start_coords[i] / 65536.0,
+                    im_end_coords[i] / 65536.0 ));
         apply = 0;
         break;
       }
 
       else if ( blend->normalizedcoords[i] < tuple_coords[i] )
+      {
+        FT_TRACE6(( "      intermediate tuple range [%.4f;%.4f] fits\n",
+                    im_start_coords[i] / 65536.0,
+                    im_end_coords[i] / 65536.0 ));
         apply = FT_MulDiv( apply,
                            blend->normalizedcoords[i] - im_start_coords[i],
                            tuple_coords[i] - im_start_coords[i] );
+      }
 
       else
+      {
+        FT_TRACE6(( "      intermediate tuple range [%.4f;%.4f] fits\n",
+                    im_start_coords[i] / 65536.0,
+                    im_end_coords[i] / 65536.0 ));
         apply = FT_MulDiv( apply,
                            im_end_coords[i] - blend->normalizedcoords[i],
                            im_end_coords[i] - tuple_coords[i] );
+      }
     }
 
+    FT_TRACE6(( "    apply factor is %.4f\n", apply / 65536.0 ));
+
     return apply;
   }
 
@@ -674,14 +759,23 @@
 
     if ( face->blend == NULL )
     {
+      FT_TRACE2(( "FVAR " ));
+
       /* both `fvar' and `gvar' must be present */
       if ( ( error = face->goto_table( face, TTAG_gvar,
                                        stream, &table_len ) ) != 0 )
+      {
+        FT_TRACE1(( "\n"
+                    "TT_Get_MM_Var: `gvar' table is missing\n" ));
         goto Exit;
+      }
 
       if ( ( error = face->goto_table( face, TTAG_fvar,
                                        stream, &table_len ) ) != 0 )
+      {
+        FT_TRACE1(( "is missing\n" ));
         goto Exit;
+      }
 
       fvar_start = FT_STREAM_POS( );
 
@@ -704,10 +798,16 @@
            fvar_head.offsetToData + fvar_head.axisCount * 20U +
              fvar_head.instanceCount * fvar_head.instanceSize > table_len )
       {
+        FT_TRACE1(( "\n"
+                    "TT_Get_MM_Var: invalid `fvar' header\n" ));
         error = FT_THROW( Invalid_Table );
         goto Exit;
       }
 
+      FT_TRACE2(( "loaded\n" ));
+
+      FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount ));
+
       if ( FT_NEW( face->blend ) )
         goto Exit;
 
@@ -779,9 +879,17 @@
         a->name[3] = (FT_String)( ( a->tag       ) & 0xFF );
         a->name[4] = '\0';
 
+        FT_TRACE5(( "  \"%s\": minimum=%.4f, default=%.4f, maximum=%.4f\n",
+                    a->name,
+                    a->minimum / 65536.0,
+                    a->def / 65536.0,
+                    a->maximum / 65536.0 ));
+
         a++;
       }
 
+      FT_TRACE5(( "\n" ));
+
       ns = mmvar->namedstyle;
       for ( i = 0; i < fvar_head.instanceCount; i++, ns++ )
       {
@@ -907,15 +1015,29 @@
     mmvar = blend->mmvar;
 
     if ( num_coords > mmvar->num_axis )
+    {
+      FT_TRACE2(( "TT_Set_MM_Blend: only using first %d of %d coordinates\n",
+                  mmvar->num_axis, num_coords ));
       num_coords = mmvar->num_axis;
+    }
 
+    FT_TRACE5(( "normalized design coordinates:\n" ));
+
     for ( i = 0; i < num_coords; i++ )
+    {
+      FT_TRACE5(( "  %.4f\n", coords[i] / 65536.0 ));
       if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
       {
+        FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.4f\n"
+                    "                 is out of range [-1;1]\n",
+                    coords[i] / 65536.0 ));
         error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
+    }
 
+    FT_TRACE5(( "\n" ));
+
     if ( blend->glyphoffsets == NULL )
       if ( ( error = ft_var_load_gvar( face ) ) != 0 )
         goto Exit;
@@ -1046,7 +1168,12 @@
     mmvar = blend->mmvar;
 
     if ( num_coords > mmvar->num_axis )
+    {
+      FT_TRACE2(( "TT_Set_Var_Design:"
+                  " only using first %d of %d coordinates\n",
+                  mmvar->num_axis, num_coords ));
       num_coords = mmvar->num_axis;
+    }
 
     /* Axis normalization is a two stage process.  First we normalize */
     /* based on the [min,def,max] values for the axis to be [-1,0,1]. */
@@ -1055,11 +1182,19 @@
     if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) )
       goto Exit;
 
+    FT_TRACE5(( "design coordinates:\n" ));
+
     a = mmvar->axis;
     for ( i = 0; i < num_coords; i++, a++ )
     {
+      FT_TRACE5(( "  %.4f\n", coords[i] / 65536.0 ));
       if ( coords[i] > a->maximum || coords[i] < a->minimum )
       {
+        FT_TRACE1(( "TT_Set_Var_Design: normalized design coordinate %.4f\n"
+                    "                   is out of range [%.4f;%.4f]\n",
+                    coords[i] / 65536.0,
+                    a->minimum / 65536.0,
+                    a->maximum / 65536.0 ));
         error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
@@ -1074,6 +1209,8 @@
                                    a->maximum - a->def );
     }
 
+    FT_TRACE5(( "\n" ));
+
     for ( ; i < mmvar->num_axis; i++ )
       normalized[i] = 0;
 
@@ -1082,10 +1219,15 @@
 
     if ( blend->avar_segment != NULL )
     {
+      FT_TRACE5(( "normalized design coordinates"
+                  " before applying `avar' data:\n" ));
+
       av = blend->avar_segment;
       for ( i = 0; i < mmvar->num_axis; i++, av++ )
       {
         for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
+        {
+          FT_TRACE5(( "  %.4f\n", normalized[i] / 65536.0 ));
           if ( normalized[i] < av->correspondence[j].fromCoord )
           {
             normalized[i] =
@@ -1097,6 +1239,7 @@
               av->correspondence[j - 1].toCoord;
             break;
           }
+        }
       }
     }
 
@@ -1163,8 +1306,8 @@
 
     if ( blend == NULL )
     {
-      FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" ));
-
+      FT_TRACE2(( "\n"
+                  "tt_face_vary_cvt: no blend specified\n" ));
       error = FT_Err_Ok;
       goto Exit;
     }
@@ -1171,8 +1314,8 @@
 
     if ( face->cvt == NULL )
     {
-      FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" ));
-
+      FT_TRACE2(( "\n"
+                  "tt_face_vary_cvt: no `cvt ' table\n" ));
       error = FT_Err_Ok;
       goto Exit;
     }
@@ -1201,6 +1344,8 @@
       goto FExit;
     }
 
+    FT_TRACE2(( "loaded\n" ));
+
     if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis )    ||
          FT_NEW_ARRAY( im_start_coords, blend->num_axis ) ||
          FT_NEW_ARRAY( im_end_coords, blend->num_axis )   )
@@ -1213,6 +1358,8 @@
     /* tuplecount, but John Jenkins says that shared points don't apply */
     /* to `cvar', and no other flags are defined.                       */
 
+    FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount ));
+
     for ( i = 0; i < ( tupleCount & 0xFFF ); i++ )
     {
       FT_UInt   tupleDataSize;
@@ -1220,6 +1367,8 @@
       FT_Fixed  apply;
 
 
+      FT_TRACE6(( "  tuple %d:\n", i ));
+
       tupleDataSize = FT_GET_USHORT();
       tupleIndex    = FT_GET_USHORT();
 
@@ -1280,22 +1429,70 @@
 
       else if ( localpoints == ALL_POINTS )
       {
+#ifdef FT_DEBUG_LEVEL_TRACE
+        int  count = 0;
+#endif
+
+
+        FT_TRACE7(( "    CVT deltas:\n" ));
+
         /* this means that there are deltas for every entry in cvt */
         for ( j = 0; j < face->cvt_size; j++ )
-          face->cvt[j] = (FT_Short)( face->cvt[j] +
+        {
+          FT_Long  orig_cvt = face->cvt[j];
+
+
+          face->cvt[j] = (FT_Short)( orig_cvt +
                                      FT_MulFix( deltas[j], apply ) );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+          if ( orig_cvt != face->cvt[j] )
+          {
+            FT_TRACE7(( "      %d: %d -> %d\n",
+                        j, orig_cvt, face->cvt[j] ));
+            count++;
+          }
+#endif
+        }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+        if ( !count )
+          FT_TRACE7(( "      none\n" ));
+#endif
       }
 
       else
       {
+#ifdef FT_DEBUG_LEVEL_TRACE
+        int  count = 0;
+#endif
+
+
+        FT_TRACE7(( "    CVT deltas:\n" ));
+
         for ( j = 0; j < point_count; j++ )
         {
-          int  pindex = localpoints[j];
+          int      pindex   = localpoints[j];
+          FT_Long  orig_cvt = face->cvt[pindex];
 
 
-          face->cvt[pindex] = (FT_Short)( face->cvt[pindex] +
+          face->cvt[pindex] = (FT_Short)( orig_cvt +
                                           FT_MulFix( deltas[j], apply ) );
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+          if ( orig_cvt != face->cvt[pindex] )
+          {
+            FT_TRACE7(( "      %d: %d -> %d\n",
+                        pindex, orig_cvt, face->cvt[pindex] ));
+            count++;
+          }
+#endif
         }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+        if ( !count )
+          FT_TRACE7(( "      none\n" ));
+#endif
       }
 
       if ( localpoints != ALL_POINTS )
@@ -1306,6 +1503,8 @@
 
       FT_Stream_SeekSet( stream, here );
     }
+
+    FT_TRACE5(( "\n" ));
 
   FExit:
     FT_FRAME_EXIT();