Commit 8f8ae8c52d7bb3b92909bc2e5ff91678b0f793aa

Werner Lemberg 2016-07-11T15:11:38

Handle properties in `FREETYPE_PROPERTIES' environment variable. This commit covers the most important one. * src/autofit/afmodule.c (af_property_set): Handle `warping', `darkening-parameters', and `no-stem-darkening'. * src/cff/cffdrivr.c (cff_property_set): Handle `darkening-parameters', `hinting-engine', and `no-stem-darkening'. * src/truetype/ttdriver.c (tt_property_set): Handle `interpreter-version'.

diff --git a/ChangeLog b/ChangeLog
index 830840e..1a1b4a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
 2016-07-11  Werner Lemberg  <wl@gnu.org>
 
+	Handle properties in `FREETYPE_PROPERTIES' environment variable.
+
+	This commit covers the most important one.
+
+	* src/autofit/afmodule.c (af_property_set): Handle `warping',
+	`darkening-parameters', and `no-stem-darkening'.
+
+	* src/cff/cffdrivr.c (cff_property_set): Handle
+	`darkening-parameters', `hinting-engine', and `no-stem-darkening'.
+
+	* src/truetype/ttdriver.c (tt_property_set): Handle
+	`interpreter-version'.
+
+2016-07-11  Werner Lemberg  <wl@gnu.org>
+
 	Replace calls to `atol' with `strtol'.
 
 	We later on need strtol's `endptr' feature.
diff --git a/include/freetype/ftautoh.h b/include/freetype/ftautoh.h
index 40c8003..48ff1aa 100644
--- a/include/freetype/ftautoh.h
+++ b/include/freetype/ftautoh.h
@@ -428,6 +428,9 @@ FT_BEGIN_HEADER
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable (using values 1 and 0 for `on' and `off', respectively).
+   *
    *   The warping code can also change advance widths.  Have a look at the
    *   `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure
    *   for details on improving inter-glyph distances while rendering.
@@ -473,6 +476,9 @@ FT_BEGIN_HEADER
    *   The smaller the size (especially 9ppem and down), the higher the loss
    *   of emboldening versus the CFF driver.
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable similar to the CFF driver.
+   *
    */
 
 
@@ -489,6 +495,8 @@ FT_BEGIN_HEADER
    *   CFF_CONFIG_OPTION_DARKENING_PARAMETER_* #defines for consistency.
    *   Note the differences described in @no-stem-darkening[autofit].
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable similar to the CFF driver.
    */
 
 
diff --git a/include/freetype/ftcffdrv.h b/include/freetype/ftcffdrv.h
index ad34541..8f88cc4 100644
--- a/include/freetype/ftcffdrv.h
+++ b/include/freetype/ftcffdrv.h
@@ -148,6 +148,8 @@ FT_BEGIN_HEADER
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable (using values `adobe' or `freetype').
    */
 
 
@@ -199,6 +201,9 @@ FT_BEGIN_HEADER
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable (using values 1 and 0 for `on' and `off', respectively).
+   *
    */
 
 
@@ -248,6 +253,14 @@ FT_BEGIN_HEADER
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable, using eight comma-separated integers without spaces.  Here
+   *   the above example, using `\' to break the line for readability.
+   *
+   *   {
+   *     FREETYPE_PROPERTIES=\
+   *     cff:darkening-parameters=500,300,1000,200,1500,100,2000,0
+   *   }
    */
 
   /* */
diff --git a/include/freetype/ftttdrv.h b/include/freetype/ftttdrv.h
index 0d868bc..22186ee 100644
--- a/include/freetype/ftttdrv.h
+++ b/include/freetype/ftttdrv.h
@@ -181,6 +181,8 @@ FT_BEGIN_HEADER
    * @note:
    *   This property can be used with @FT_Property_Get also.
    *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable (using values `35', `38', or `40').
    */
 
 
diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c
index 03680be..4a6b049 100644
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -184,15 +184,26 @@
 #ifdef AF_CONFIG_OPTION_USE_WARPER
     else if ( !ft_strcmp( property_name, "warping" ) )
     {
-      FT_Bool*  warping;
+      if ( value_is_string )
+      {
+        const char*  s = (const char*)value;
+        long         w = ft_strtol( s, NULL, 10 );
 
 
-      if ( value_is_string )
-        return FT_THROW( Invalid_Argument );
+        if ( w == 0 )
+          module->warping = 0;
+        else if ( w == 1 )
+          module->warping = 1;
+        else
+          return FT_THROW( Invalid_Argument );
+      }
+      else
+      {
+        FT_Bool*  warping = (FT_Bool*)value;
 
-      warping = (FT_Bool*)value;
 
-      module->warping = *warping;
+        module->warping = *warping;
+      }
 
       return error;
     }
@@ -201,12 +212,34 @@
     {
       FT_Int*  darken_params;
       FT_Int   x1, y1, x2, y2, x3, y3, x4, y4;
+      FT_Int   dp[8];
 
 
       if ( value_is_string )
-        return FT_THROW( Invalid_Argument );
+      {
+        const char*  s = (const char*)value;
+        char*        ep;
+        int          i;
 
-      darken_params = (FT_Int*)value;
+
+        /* eight comma-separated numbers */
+        for ( i = 0; i < 7; i++ )
+        {
+          dp[i] = (FT_Int)ft_strtol( s, &ep, 10 );
+          if ( *ep != ',' || s == ep )
+            return FT_THROW( Invalid_Argument );
+
+          s = ep + 1;
+        }
+
+        dp[7] = (FT_Int)ft_strtol( s, &ep, 10 );
+        if ( !( *ep == '\0' || *ep == ' ' ) || s == ep )
+          return FT_THROW( Invalid_Argument );
+
+        darken_params = dp;
+      }
+      else
+        darken_params = (FT_Int*)value;
 
       x1 = darken_params[0];
       y1 = darken_params[1];
@@ -236,15 +269,26 @@
     }
     else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
     {
-      FT_Bool*  no_stem_darkening;
+      if ( value_is_string )
+      {
+        const char*  s   = (const char*)value;
+        long         nsd = ft_strtol( s, NULL, 10 );
 
 
-      if ( value_is_string )
-        return FT_THROW( Invalid_Argument );
+        if ( nsd == 0 )
+          module->no_stem_darkening = 0;
+        else if ( nsd == 1 )
+          module->no_stem_darkening = 1;
+        else
+          return FT_THROW( Invalid_Argument );
+      }
+      else
+      {
+        FT_Bool*  no_stem_darkening = (FT_Bool*)value;
 
-      no_stem_darkening = (FT_Bool*)value;
 
-      module->no_stem_darkening = *no_stem_darkening;
+        module->no_stem_darkening = *no_stem_darkening;
+      }
 
       return error;
     }
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 88bb7e6..2e2a437 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -670,12 +670,34 @@
     {
       FT_Int*  darken_params;
       FT_Int   x1, y1, x2, y2, x3, y3, x4, y4;
+      FT_Int   dp[8];
 
 
       if ( value_is_string )
-        return FT_THROW( Invalid_Argument );
+      {
+        const char*  s = (const char*)value;
+        char*        ep;
+        int          i;
+
+
+        /* eight comma-separated numbers */
+        for ( i = 0; i < 7; i++ )
+        {
+          dp[i] = (FT_Int)ft_strtol( s, &ep, 10 );
+          if ( *ep != ',' || s == ep )
+            return FT_THROW( Invalid_Argument );
+
+          s = ep + 1;
+        }
 
-      darken_params = (FT_Int*)value;
+        dp[7] = (FT_Int)ft_strtol( s, &ep, 10 );
+        if ( !( *ep == '\0' || *ep == ' ' ) || s == ep )
+          return FT_THROW( Invalid_Argument );
+
+        darken_params = dp;
+      }
+      else
+        darken_params = (FT_Int*)value;
 
       x1 = darken_params[0];
       y1 = darken_params[1];
@@ -705,36 +727,58 @@
     }
     else if ( !ft_strcmp( property_name, "hinting-engine" ) )
     {
-      FT_UInt*  hinting_engine;
-
-
       if ( value_is_string )
-        return FT_THROW( Invalid_Argument );
+      {
+        const char*  s = (const char*)value;
 
-      hinting_engine = (FT_UInt*)value;
 
-      if ( *hinting_engine == FT_CFF_HINTING_ADOBE
+        if ( !ft_strcmp( s, "adobe" ) )
+          driver->hinting_engine = FT_CFF_HINTING_ADOBE;
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-           || *hinting_engine == FT_CFF_HINTING_FREETYPE
+        else if ( !ft_strcmp( s, "freetype" ) )
+          driver->hinting_engine = FT_CFF_HINTING_FREETYPE;
 #endif
-         )
-        driver->hinting_engine = *hinting_engine;
+        else
+          return FT_THROW( Invalid_Argument );
+      }
       else
-        error = FT_ERR( Unimplemented_Feature );
+      {
+        FT_UInt*  hinting_engine = (FT_UInt*)value;
 
-      return error;
+        if ( *hinting_engine == FT_CFF_HINTING_ADOBE
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+             || *hinting_engine == FT_CFF_HINTING_FREETYPE
+#endif
+           )
+          driver->hinting_engine = *hinting_engine;
+        else
+          error = FT_ERR( Unimplemented_Feature );
+
+        return error;
+      }
     }
     else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
     {
-      FT_Bool*  no_stem_darkening;
+      if ( value_is_string )
+      {
+        const char*  s   = (const char*)value;
+        long         nsd = ft_strtol( s, NULL, 10 );
 
 
-      if ( value_is_string )
-        return FT_THROW( Invalid_Argument );
+        if ( nsd == 0 )
+          driver->no_stem_darkening = 0;
+        else if ( nsd == 1 )
+          driver->no_stem_darkening = 1;
+        else
+          return FT_THROW( Invalid_Argument );
+      }
+      else
+      {
+        FT_Bool*  no_stem_darkening = (FT_Bool*)value;
 
-      no_stem_darkening = (FT_Bool*)value;
 
-      driver->no_stem_darkening = *no_stem_darkening;
+        driver->no_stem_darkening = *no_stem_darkening;
+      }
 
       return error;
     }
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
index 83a8042..3debf78 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -70,23 +70,33 @@
 
     if ( !ft_strcmp( property_name, "interpreter-version" ) )
     {
-      FT_UInt*  interpreter_version;
+      FT_UInt  interpreter_version;
 
 
       if ( value_is_string )
-        return FT_THROW( Invalid_Argument );
+      {
+        const char*  s = (const char*)value;
+
+
+        interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 );
+      }
+      else
+      {
+        FT_UInt*  iv = (FT_UInt*)value;
 
-      interpreter_version = (FT_UInt*)value;
 
-      if ( *interpreter_version == TT_INTERPRETER_VERSION_35
+        interpreter_version = *iv;
+      }
+
+      if ( interpreter_version == TT_INTERPRETER_VERSION_35
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-           || *interpreter_version == TT_INTERPRETER_VERSION_38
+           || interpreter_version == TT_INTERPRETER_VERSION_38
 #endif
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-           || *interpreter_version == TT_INTERPRETER_VERSION_40
+           || interpreter_version == TT_INTERPRETER_VERSION_40
 #endif
          )
-        driver->interpreter_version = *interpreter_version;
+        driver->interpreter_version = interpreter_version;
       else
         error = FT_ERR( Unimplemented_Feature );