Here is the updated patch for 2.6.4 - there are some minor collisions with the 
new subpixel hinting  mode.

while updating the diff I looked into the global variable issue. Putting the 
diagnostic messaging pointer inside TT_Face is fairly straight forward, and it 
isn't too hard to do it per TT_Face, which is even better than per FT_Library. 
However

- diagnostics on parallel threads seem a bit of over-design - most people are 
unlikely ever to test multiple faces in parallel. Testing on single face is 
demanding enough - did I mention that it took about 5 days of CPU time to run 
the MS 2003 binary through the MS shipped fonts in win 8.1?

- extracting the face handle and passing it back increases the complexity of 
the C<->C# interface. Before implementing the rasterization test, I have relied 
on SharpFont ( https://github.com/Robmaister/SharpFont ) to handle the C<->C# 
interaction. And I have enhanced SharpFont on the way as needed. The current 
change by-passes SharpFont. I do not want to spend time increasing the 
complexity of what's really a temporary by-pass.

Anyway, you or others are welcomed to improve the patch. I'm going to start 
packaging after this e-mail, and hope to release the next Font Val (with a 
patched freetype 2.6.4 backend) in the next few days.

--------------------------------------------
On Mon, 4/7/16, Behdad Esfahbod <[email protected]> wrote:

 global variable is not desirable.  Put it on the FT_Library
 at least.
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 2e3f9ef..534e30f 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -90,12 +90,29 @@
 #define BOUNDSL( x, n )  ( (FT_ULong)(x) >= (FT_ULong)(n) )
 
 
+typedef int (*diagnostics_Function)(const char* message, const char* const opcode, int range_base, int is_composite, int IP, int callTop, int opc, int start);
+
+static diagnostics_Function diagnostics = NULL;
+
 #undef  SUCCESS
 #define SUCCESS  0
 
 #undef  FAILURE
 #define FAILURE  1
 
+  FT_EXPORT_DEF( void )
+  TT_diagnostics_unset( void )
+  {
+    diagnostics = NULL;
+  }
+
+  FT_EXPORT_DEF( void )
+  TT_diagnostics_set( diagnostics_Function funcptr )
+  {
+    diagnostics = funcptr;
+  }
+
+#define DIAGNOSTICS(message, context) if (diagnostics) (*diagnostics)(message, opcode_name[(context)->opcode] + 2, ( (context)->callTop ? (context)->callStack->Caller_Range : (context)->curRange ), (context)->is_composite , (context)->IP, (context)->callTop, ((context)->callTop ? ((context)->callStack + (context)->callTop - 1)->Def->opc : 0), ((context)->callTop ? ((context)->callStack + (context)->callTop - 1)->Def->start : 0))
 
   /*************************************************************************/
   /*                                                                       */
@@ -910,7 +927,7 @@
   };
 
 
-#ifdef FT_DEBUG_LEVEL_TRACE
+#if defined(FT_DEBUG_LEVEL_TRACE) || defined(DIAGNOSTICS)
 
   /* the first hex digit gives the length of the opcode name; the space */
   /* after the digit is here just to increase readability of the source */
@@ -1664,17 +1681,19 @@
                FT_F26Dot6      distance )
   {
     FT_F26Dot6  v;
+    FT_Long F_dot_P = 0, moved_x = 0, moved_y = 0;
 
 
     v = exc->GS.freeVector.x;
 
     if ( v != 0 )
     {
+        moved_x = FT_MulDiv( distance, v, exc->F_dot_P );
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
       if ( SUBPIXEL_HINTING_INFINALITY                            &&
            ( !exc->ignore_x_mode                                ||
              ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
-        zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+        zone->cur[point].x += moved_x;
       else
 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
@@ -1683,12 +1702,12 @@
       /* diagonal moves, but only post-IUP.  DejaVu tries to adjust */
       /* diagonal stems like on `Z' and `z' post-IUP.               */
       if ( SUBPIXEL_HINTING_MINIMAL && !exc->backwards_compatibility )
-        zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+        zone->cur[point].x += moved_x;
       else
 #endif
 
       if ( NO_SUBPIXEL_HINTING )
-        zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P );
+        zone->cur[point].x += moved_x;
 
       zone->tags[point] |= FT_CURVE_TAG_TOUCH_X;
     }
@@ -1697,16 +1716,27 @@
 
     if ( v != 0 )
     {
+      moved_y = FT_MulDiv( distance, v, exc->F_dot_P );
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       if ( !( SUBPIXEL_HINTING_MINIMAL     &&
               exc->backwards_compatibility &&
               exc->iupx_called             &&
               exc->iupy_called             ) )
 #endif
-        zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P );
+        zone->cur[point].y += moved_y;
 
       zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y;
     }
+
+    F_dot_P =
+      ( (FT_Long)exc->GS.projVector.x * exc->GS.freeVector.x +
+        (FT_Long)exc->GS.projVector.y * exc->GS.freeVector.y ) >> 14;
+
+    if ( FT_ABS( F_dot_P ) < 0x400L )
+      {
+        if ( (moved_x == 0 || moved_y == 0) && distance != 0 )
+          DIAGNOSTICS("_rast_W_PF_VECTORS_AT_OR_NEAR_PERP", exc );
+      }
   }
 
 
@@ -3982,6 +4012,10 @@
       }
       exc->numIDefs++;
     }
+    else
+    {
+      DIAGNOSTICS("_rast_E_INSTR_DEFD_BY_FS", exc );
+    }
 
     /* opcode must be unsigned 8-bit integer */
     if ( 0 > args[0] || args[0] > 0x00FF )
@@ -4161,6 +4195,7 @@
     if ( BOUNDS( aIdx1, exc->zp2.n_points ) ||
          BOUNDS( aIdx2, exc->zp1.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return FAILURE;
@@ -4307,6 +4342,7 @@
   {
     FT_Short  S;
     FT_Long   X, Y;
+    FT_Long P_dot_P;
 
 
     /* Only use low 16bits, then sign extend */
@@ -4315,6 +4351,11 @@
     S = (FT_Short)args[0];
     X = (FT_Long)S;
 
+    P_dot_P = ( X * X +  Y * Y ) >> 14;
+
+    if ( P_dot_P < 0x3C00 ) /* arbitrary - expect 0x4000 */
+      DIAGNOSTICS("_rast_E_VECTOR_XY_INVALID", exc );
+
     Normalize( X, Y, &exc->GS.projVector );
 
     exc->GS.dualVector = exc->GS.projVector;
@@ -4334,6 +4375,7 @@
   {
     FT_Short  S;
     FT_Long   X, Y;
+    FT_Long F_dot_F;
 
 
     /* Only use low 16bits, then sign extend */
@@ -4342,6 +4384,11 @@
     S = (FT_Short)args[0];
     X = S;
 
+    F_dot_F = ( X * X +  Y * Y ) >> 14;
+
+    if ( F_dot_F < 0x3C00 ) /* arbitrary - expect 0x4000 */
+      DIAGNOSTICS("_rast_E_VECTOR_XY_INVALID", exc );
+
     Normalize( X, Y, &exc->GS.freeVector );
     Compute_Funcs( exc );
   }
@@ -4683,6 +4730,7 @@
 
     if ( BOUNDSL( L, exc->zp2.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       R = 0;
@@ -4721,6 +4769,7 @@
 
     if ( BOUNDS( L, exc->zp2.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return;
@@ -4766,6 +4815,7 @@
     if ( BOUNDS( L, exc->zp0.n_points ) ||
          BOUNDS( K, exc->zp1.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       D = 0;
@@ -4846,6 +4896,7 @@
     if ( BOUNDS( p2, exc->zp1.n_points ) ||
          BOUNDS( p1, exc->zp2.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return;
@@ -5074,6 +5125,9 @@
     exc->GS.instruct_control &= ~(FT_Byte)Kf;
     exc->GS.instruct_control |= (FT_Byte)L;
 
+    if ( exc->callTop && ( exc->callStack->Caller_Range == tt_coderange_glyph ) )
+      DIAGNOSTICS("_rast_E_NOT_CALLED_FROM_PREPROGRAM", exc );
+
     if ( K == 3 )
     {
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
@@ -5199,6 +5253,7 @@
 
       if ( BOUNDS( point, exc->pts.n_points ) )
       {
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
         if ( exc->pedantic_hinting )
         {
           exc->error = FT_THROW( Invalid_Reference );
@@ -5245,6 +5300,7 @@
     if ( BOUNDS( K, exc->pts.n_points ) ||
          BOUNDS( L, exc->pts.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return;
@@ -5283,6 +5339,7 @@
     if ( BOUNDS( K, exc->pts.n_points ) ||
          BOUNDS( L, exc->pts.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return;
@@ -5318,6 +5375,7 @@
 
     if ( BOUNDS( p, zp.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       *refp = 0;
@@ -5405,6 +5463,7 @@
 
       if ( BOUNDS( point, exc->zp2.n_points ) )
       {
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
         if ( exc->pedantic_hinting )
         {
           exc->error = FT_THROW( Invalid_Reference );
@@ -5574,6 +5633,7 @@
 
       if ( BOUNDS( point, exc->zp2.n_points ) )
       {
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
         if ( exc->pedantic_hinting )
         {
           exc->error = FT_THROW( Invalid_Reference );
@@ -5721,6 +5781,7 @@
     if ( BOUNDS( point,       exc->zp1.n_points ) ||
          BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return;
@@ -5775,6 +5836,7 @@
 
     if ( BOUNDS( point, exc->zp0.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return;
@@ -5841,6 +5903,8 @@
     if ( BOUNDS( point,     exc->zp0.n_points ) ||
          BOUNDSL( cvtEntry, exc->cvtSize )      )
     {
+      if ( BOUNDS( point,     exc->zp0.n_points ) )
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
@@ -5950,6 +6014,7 @@
     if ( BOUNDS( point,       exc->zp1.n_points ) ||
          BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
@@ -6105,6 +6170,9 @@
          BOUNDSL( cvtEntry,   exc->cvtSize + 1 )  ||
          BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
+      if ( BOUNDS( point,       exc->zp1.n_points ) ||
+           BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
@@ -6315,6 +6383,8 @@
     if ( exc->top < exc->GS.loop                  ||
          BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
+      if ( BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
@@ -6328,6 +6398,7 @@
 
       if ( BOUNDS( point, exc->zp1.n_points ) )
       {
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
         if ( exc->pedantic_hinting )
         {
           exc->error = FT_THROW( Invalid_Reference );
@@ -6389,6 +6460,7 @@
          BOUNDS( a1,    exc->zp1.n_points ) ||
          BOUNDS( point, exc->zp2.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return;
@@ -6468,6 +6540,7 @@
     if ( BOUNDS( p1, exc->zp1.n_points ) ||
          BOUNDS( p2, exc->zp0.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return;
@@ -6514,6 +6587,7 @@
 
     if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       goto Fail;
@@ -6533,6 +6607,7 @@
     if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ||
          BOUNDS( exc->GS.rp2, exc->zp1.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       old_range = 0;
       cur_range = 0;
     }
@@ -6567,6 +6642,7 @@
       /* check point bounds */
       if ( BOUNDS( point, exc->zp2.n_points ) )
       {
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
         if ( exc->pedantic_hinting )
         {
           exc->error = FT_THROW( Invalid_Reference );
@@ -6615,13 +6691,18 @@
           /*   new_dist - cur_dist = delta                   ,       */
           /*   new_dist - cur_dist = org_dist - cur_dist     ,       */
           /*              new_dist = org_dist                .       */
-
           new_dist = org_dist;
+          DIAGNOSTICS("_rast_E_RP1_RP2_SAME_POS_ON_PROJ", exc );
         }
       }
       else
         new_dist = 0;
 
+      /*
+      if ( (new_dist - cur_dist) != 0 && (new_dist - org_dist) == 0)
+        DIAGNOSTICS("_rast_E_RP1_RP2_SAME_POS_ON_PROJ", exc );
+      */
+
       exc->func_move( exc,
                       &exc->zp2,
                       (FT_UShort)point,
@@ -6652,6 +6733,7 @@
 
     if ( BOUNDS( point, exc->zp0.n_points ) )
     {
+      DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
       if ( exc->pedantic_hinting )
         exc->error = FT_THROW( Invalid_Reference );
       return;
@@ -6877,8 +6959,10 @@
       end_point   = exc->pts.contours[contour] - exc->pts.first_point;
       first_point = point;
 
-      if ( BOUNDS( end_point, exc->pts.n_points ) )
+      if ( BOUNDS( end_point, exc->pts.n_points ) ) {
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
         end_point = exc->pts.n_points - 1;
+      }
 
       while ( point <= end_point && ( exc->pts.tags[point] & mask ) == 0 )
         point++;
@@ -7086,8 +7170,11 @@
         }
       }
       else
+      {
+        DIAGNOSTICS("_rast_E_POINT_OUT_OF_RANGE", exc );
         if ( exc->pedantic_hinting )
           exc->error = FT_THROW( Invalid_Reference );
+      }
     }
 
   Fail:
_______________________________________________
Freetype-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/freetype-devel

Reply via email to