Commit 7e185dcd7928c0f8730dc18af152db7f83ebca4c

Ewald Hew 2017-09-25T06:40:32

Allow `type1' module to use the Adobe engine. Add the callback and some conditionals to switch between the two engines. * include/freetype/internal/psaux.h (T1_Decoder_FuncsRec): Change function declarations. * src/psaux/psauxmod.c (T1_Decoder_FuncsRec): Register the callbacks. * src/psaux/psobjs.c (ps_builder_add_point): Add conditionals for number conversion. * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Add code to choose which renderer to use. * src/cid/cidgload.c (cid_load_glyph): Update call. * src/base/ftobjs.c, src/psaux/psobjs.c, src/type1/t1gload.c: Update includes.

diff --git a/ChangeLog b/ChangeLog
index bfe2237..ef1290e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
 2017-09-25  Ewald Hew  <ewaldhew@gmail.com>
 
+	Allow `type1' module to use the Adobe engine.
+
+	Add the callback and some conditionals to switch between the two
+	engines.
+
+	* include/freetype/internal/psaux.h (T1_Decoder_FuncsRec): Change
+	function declarations.
+	* src/psaux/psauxmod.c (T1_Decoder_FuncsRec): Register the
+	callbacks.
+
+	* src/psaux/psobjs.c (ps_builder_add_point): Add conditionals for
+	number conversion.
+
+	* src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String): Add code
+	to choose which renderer to use.
+
+	* src/cid/cidgload.c (cid_load_glyph): Update call.
+	* src/base/ftobjs.c, src/psaux/psobjs.c, src/type1/t1gload.c: Update
+	includes.
+
+2017-09-25  Ewald Hew  <ewaldhew@gmail.com>
+
 	[type1] Add Adobe engine configuration.
 
 	Use the previously changed PS_Driver in type1 module to store
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index 24c02e7..a8469f7 100644
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -872,9 +872,15 @@ FT_BEGIN_HEADER
     (*done)( T1_Decoder  decoder );
 
     FT_Error
-    (*parse_charstrings)( T1_Decoder  decoder,
-                          FT_Byte*    base,
-                          FT_UInt     len );
+    (*parse_charstrings_old)( T1_Decoder  decoder,
+                              FT_Byte*    base,
+                              FT_UInt     len );
+
+    FT_Error
+    (*parse_charstrings)( PS_Decoder*  decoder,
+                          FT_Byte*     charstring_base,
+                          FT_ULong     charstring_len );
+
 
   } T1_Decoder_FuncsRec;
 
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index b96c333..4672a76 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -169,7 +169,7 @@
       if ( decoder->lenIV >= 0 )
         psaux->t1_decrypt( charstring, glyph_length, 4330 );
 
-      error = decoder->funcs.parse_charstrings(
+      error = decoder->funcs.parse_charstrings_old(
                 decoder, charstring + cs_offset,
                 glyph_length - cs_offset );
     }
diff --git a/src/psaux/psauxmod.c b/src/psaux/psauxmod.c
index bc7002a..9c07309 100644
--- a/src/psaux/psauxmod.c
+++ b/src/psaux/psauxmod.c
@@ -90,7 +90,8 @@
   {
     t1_decoder_init,              /* init              */
     t1_decoder_done,              /* done              */
-    t1_decoder_parse_charstrings  /* parse_charstrings */
+    t1_decoder_parse_charstrings, /* parse_charstrings_old */
+    cf2_decoder_parse_charstrings /* parse_charstrings */
   };
 
 
diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
index eecbda6..8d0f0fe 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -20,6 +20,8 @@
 #include FT_INTERNAL_POSTSCRIPT_AUX_H
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_CALC_H
+#include FT_CFF_DRIVER_H
+#include FT_TYPE1_DRIVER_H
 
 #include "psobjs.h"
 #include "psconv.h"
@@ -2160,25 +2162,24 @@
       FT_Vector*  point   = outline->points + outline->n_points;
       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;
 
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
       PS_Driver  driver   = (PS_Driver)FT_FACE_DRIVER( builder->face );
 
-
-      if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+      if ( !builder->is_t1 &&
+           driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
       {
         point->x = x >> 16;
         point->y = y >> 16;
       }
       else
 #endif
-#ifdef T1_CONFIG_OPTION_OLD_ENGINE
-      if ( builder->is_t1 )
+      if ( builder->is_t1 &&
+           driver->hinting_engine == FT_T1_HINTING_FREETYPE )
       {
         point->x = FIXED_TO_INT( x );
         point->y = FIXED_TO_INT( y );
       }
       else
-#endif
       {
         /* cf2_decoder_parse_charstrings uses 16.16 coordinates */
         point->x = x >> 10;
diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c
index aaf19b6..22b14e4 100644
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -23,6 +23,7 @@
 #include FT_INTERNAL_STREAM_H
 #include FT_OUTLINE_H
 #include FT_INTERNAL_POSTSCRIPT_AUX_H
+#include FT_TYPE1_DRIVER_H
 
 #include "t1errors.h"
 
@@ -63,11 +64,16 @@
     T1_Font   type1 = &face->type1;
     FT_Error  error = FT_Err_Ok;
 
+    PSAux_Service            psaux         = (PSAux_Service)face->psaux;
+    const T1_Decoder_Funcs   decoder_funcs = psaux->t1_decoder_funcs;
+    PS_Decoder               psdecoder;
+
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     FT_Incremental_InterfaceRec *inc =
                       face->root.internal->incremental_interface;
 #endif
 
+    PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face );
 
     decoder->font_matrix = type1->font_matrix;
     decoder->font_offset = type1->font_offset;
@@ -90,9 +96,40 @@
     }
 
     if ( !error )
-      error = decoder->funcs.parse_charstrings(
-                decoder, (FT_Byte*)char_string->pointer,
-                (FT_UInt)char_string->length );
+    {
+      /* choose which renderer to use */
+      if ( driver->hinting_engine == FT_T1_HINTING_FREETYPE )
+        error = decoder_funcs->parse_charstrings_old( decoder,
+                                                      (FT_Byte*)char_string->pointer,
+                                                      (FT_UInt)char_string->length );
+      else
+      {
+        psaux->ps_decoder_init( decoder, TRUE, &psdecoder );
+
+        error = decoder_funcs->parse_charstrings( &psdecoder,
+                                                  (FT_Byte*)char_string->pointer,
+                                                  (FT_ULong)char_string->length );
+
+#if 0 /* TODO(ewaldhew) */
+        /* Adobe's engine uses 16.16 numbers everywhere;              */
+        /* as a consequence, glyphs larger than 2000ppem get rejected */
+        if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
+        {
+          /* this time, we retry unhinted and scale up the glyph later on */
+          /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */
+          /* 0x400 for both `x_scale' and `y_scale' in this case)         */
+          hinting       = FALSE;
+          force_scaling = TRUE;
+          glyph->hint   = hinting;
+
+          error = decoder_funcs->parse_charstrings( &psdecoder,
+                                                    (FT_Byte*)char_string->pointer,
+                                                    (FT_ULong)char_string->length );
+        }
+#endif
+      }
+
+    }
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL