shithub: freetype+ttf2subf

Download patch

ref: 2b0ac18990e7800aad568cf91dcb510ef9beff62
parent: 2e9519885b8e7e5fdc9d75b35992ef7bbf15e53a
author: Nikolaus Waxweiler <[email protected]>
date: Sat Feb 18 05:42:23 EST 2017

Add face property for stem darkening.

* include/freetype/ftautoh.h (FT_PARAM_TAG_STEM_DARKENING): New
macro.

* include/freetype/internal/ftobjs.h (FT_Face_InternalRec): Add
`no_stem_darkening' field.

* src/autofit/afloader.c (af_loader_load_glyph),
src/autofit/afmodule.c (af_property_set): Updated.

* src/base/ftobjs.c: Include FT_AUTOHINTER_H.
(ft_open_face_internal): Updated.
(FT_Face_Properties): Handle FT_PARAM_TAG_STEM_DARKENING.

* src/cff/cf2ft.c (cf2_decoder_parse_charstrings): Updated.

* src/cff/cffdrivr.c (cff_property_set): Updated.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,28 @@
 2017-02-16  Nikolaus Waxweiler  <[email protected]>
 	    Werner Lemberg  <[email protected]>
 
+	Add face property for stem darkening.
+
+	* include/freetype/ftautoh.h (FT_PARAM_TAG_STEM_DARKENING): New
+	macro.
+
+	* include/freetype/internal/ftobjs.h (FT_Face_InternalRec): Add
+	`no_stem_darkening' field.
+
+	* src/autofit/afloader.c (af_loader_load_glyph),
+	src/autofit/afmodule.c (af_property_set): Updated.
+
+	* src/base/ftobjs.c: Include FT_AUTOHINTER_H.
+	(ft_open_face_internal): Updated.
+	(FT_Face_Properties): Handle FT_PARAM_TAG_STEM_DARKENING.
+
+	* src/cff/cf2ft.c (cf2_decoder_parse_charstrings): Updated.
+
+	* src/cff/cffdrivr.c (cff_property_set): Updated.
+
+2017-02-16  Nikolaus Waxweiler  <[email protected]>
+	    Werner Lemberg  <[email protected]>
+
 	Add face property for LCD filter weights.
 
 	* include/freetype/ftlcdfil.h (FT_PARAM_TAG_LCD_FILTER_WEIGHTS,
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -3629,6 +3629,10 @@
    *   Note that only a subset of the available properties can be
    *   controlled.
    *
+   *   * Stem darkening (@FT_PARAM_TAG_STEM_DARKENING, corresponding to the
+   *     property `no-stem-darkening' provided by the `autofit' and `cff'
+   *     modules; see @auto_hinter and @cff_driver).
+   *
    *   * LCD filter weights (@FT_PARAM_TAG_LCD_FILTER_WEIGHTS, corresponding
    *     to function @FT_Library_SetLcdFilterWeights).
    *
@@ -3647,6 +3651,43 @@
    *
    * @return:
    *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   Here an example that sets two properties.  You must define
+   *   FT_CONFIG_OPTION_SUBPIXEL_RENDERING to make the LCD filter examples
+   *   work.
+   *
+   *   {
+   *     FT_Parameter         property1;
+   *     FT_Bool              darken_stems = 1;
+   *
+   *     FT_Parameter         property2;
+   *     FT_LcdFiveTapFilter  custom_weight =
+   *                            { 0x10, 0x40, 0x70, 0x40, 0x10 };
+   *
+   *     FT_Parameter         properties[2] = { property1, property2 };
+   *
+   *
+   *     property1.tag  = FT_PARAM_TAG_STEM_DARKENING;
+   *     property1.data = &darken_stems;
+   *
+   *     property2.tag  = FT_PARAM_TAG_LCD_FILTER_WEIGHTS;
+   *     property2.data = custom_weight;
+   *
+   *     FT_Face_Properties( face, 2, properties );
+   *   }
+   *
+   *   The next example resets a single property to its default value.
+   *
+   *   {
+   *     FT_Parameter  property;
+   *
+   *
+   *     property.tag  = FT_PARAM_TAG_LCD_FILTER_WEIGHTS;
+   *     property.data = NULL;
+   *
+   *     FT_Face_Option( face, 1, &property );
+   *   }
    *
    */
   FT_EXPORT( FT_Error )
--- a/include/freetype/ftautoh.h
+++ b/include/freetype/ftautoh.h
@@ -477,9 +477,30 @@
    *   of emboldening versus the CFF driver.
    *
    *   This property can be set via the `FREETYPE_PROPERTIES' environment
-   *   variable similar to the CFF driver.
+   *   variable similar to the CFF driver.  It can also be set per face
+   *   using @FT_Face_Properties with @FT_PARAM_TAG_STEM_DARKENING.
    *
    */
+
+
+  /*
+   * @constant:
+   *   FT_PARAM_TAG_STEM_DARKENING
+   *
+   * @description:
+   *   An @FT_Parameter tag to be used with @FT_Face_Properties.  The
+   *   corresponding Boolean argument specifies whether to apply stem
+   *   darkening, overriding the global default values or the values set up
+   *   with @FT_Property_Set (see @no-stem-darkening[autofit] and
+   *   @no-stem-darkening[cff]).
+   *
+   *   This is a passive setting that only takes effect if the font driver
+   *   or autohinter honors it, which the CFF driver always does, but the
+   *   autohinter only in `light' hinting mode (as of version 2.7.0).
+   *
+   */
+#define FT_PARAM_TAG_STEM_DARKENING \
+          FT_MAKE_TAG( 'd', 'a', 'r', 'k' )
 
 
   /**************************************************************************
--- a/include/freetype/ftcffdrv.h
+++ b/include/freetype/ftcffdrv.h
@@ -203,6 +203,8 @@
    *
    *   This property can be set via the `FREETYPE_PROPERTIES' environment
    *   variable (using values 1 and 0 for `on' and `off', respectively).
+   *   It can also be set per face using @FT_Face_Properties with
+   *   @FT_PARAM_TAG_STEM_DARKENING.
    *
    */
 
--- a/include/freetype/ftlcdfil.h
+++ b/include/freetype/ftlcdfil.h
@@ -268,6 +268,9 @@
    *   defined in your build of the library, which should correspond to all
    *   default builds of FreeType.
    *
+   *   LCD filter weights can also be set per face using @FT_Face_Properties
+   *   with @FT_PARAM_TAG_LCD_FILTER_WEIGHTS.
+   *
    * @since:
    *   2.4.0
    */
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -348,6 +348,11 @@
   /*      @FT_Done_Face only destroys a face if the counter is~1,          */
   /*      otherwise it simply decrements it.                               */
   /*                                                                       */
+  /*    no_stem_darkening ::                                               */
+  /*      Overrides the module-level default, see @stem-darkening[cff],    */
+  /*      for example.  FALSE and TRUE toggle stem darkening on and off,   */
+  /*      respectively, value~-1 means to use the module/driver default.   */
+  /*                                                                       */
   /*    lcd_weights ::                                                     */
   /*      Overrides the library default with custom weights for the 5-tap  */
   /*      FIR filter.  `{0, 0, 0, 0, 0}' means to use the library default. */
@@ -365,6 +370,8 @@
 #endif
 
     FT_Int              refcount;
+
+    FT_Char             no_stem_darkening;
 
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
     FT_LcdFiveTapFilter  lcd_weights;  /* preset or custom filter weights */
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -336,8 +336,14 @@
      *  `standard_{vertical,horizontal}_width' change.
      *
      *  Ignore errors and carry on without emboldening.
+     *
      */
-    if ( !module->no_stem_darkening )
+
+    /* stem darkening only works well in `light' mode */
+    if ( scaler.render_mode == FT_RENDER_MODE_LIGHT    &&
+         ( !face->internal->no_stem_darkening        ||
+           ( face->internal->no_stem_darkening < 0 &&
+             !module->no_stem_darkening            ) ) )
       af_loader_embolden_glyph_in_slot( loader, face, style_metrics );
 
     loader->transformed = internal->glyph_transformed;
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -304,12 +304,10 @@
         long         nsd = ft_strtol( s, NULL, 10 );
 
 
-        if ( nsd == 0 )
-          module->no_stem_darkening = 0;
-        else if ( nsd == 1 )
-          module->no_stem_darkening = 1;
+        if ( !nsd )
+          module->no_stem_darkening = FALSE;
         else
-          return FT_THROW( Invalid_Argument );
+          module->no_stem_darkening = TRUE;
       }
       else
 #endif
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -37,6 +37,8 @@
 #include FT_SERVICE_KERNING_H
 #include FT_SERVICE_TRUETYPE_ENGINE_H
 
+#include FT_AUTOHINTER_H
+
 #ifdef FT_CONFIG_OPTION_MAC_FONTS
 #include "ftbase.h"
 #endif
@@ -2425,6 +2427,8 @@
 
       internal->refcount = 1;
 
+      internal->no_stem_darkening = -1;
+
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
       ft_memset( internal->lcd_weights, 0, FT_LCD_FILTER_FIVE_TAPS );
 #endif
@@ -3611,7 +3615,22 @@
 
     for ( ; num_properties > 0; num_properties-- )
     {
-      if ( properties->tag == FT_PARAM_TAG_LCD_FILTER_WEIGHTS )
+      if ( properties->tag == FT_PARAM_TAG_STEM_DARKENING )
+      {
+        if ( properties->data )
+        {
+          if ( *( (FT_Bool*)properties->data ) == TRUE )
+            face->internal->no_stem_darkening = FALSE;
+          else
+            face->internal->no_stem_darkening = TRUE;
+        }
+        else
+        {
+          /* use module default */
+          face->internal->no_stem_darkening = -1;
+        }
+      }
+      else if ( properties->tag == FT_PARAM_TAG_LCD_FILTER_WEIGHTS )
       {
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
         if ( properties->data )
--- a/src/cff/cf2ft.c
+++ b/src/cff/cf2ft.c
@@ -340,6 +340,11 @@
       CFF_Builder*  builder = &decoder->builder;
       CFF_Driver    driver  = (CFF_Driver)FT_FACE_DRIVER( builder->face );
 
+      FT_Bool  no_stem_darkening_driver =
+                 driver->no_stem_darkening;
+      FT_Char  no_stem_darkening_font =
+                 builder->face->root.internal->no_stem_darkening;
+
       /* local error */
       FT_Error       error2 = FT_Err_Ok;
       CF2_BufferRec  buf;
@@ -373,7 +378,9 @@
       font->renderingFlags = 0;
       if ( hinted )
         font->renderingFlags |= CF2_FlagsHinted;
-      if ( scaled && !driver->no_stem_darkening )
+      if ( scaled && ( !no_stem_darkening_font        ||
+                       ( no_stem_darkening_font < 0 &&
+                         !no_stem_darkening_driver  ) ) )
         font->renderingFlags |= CF2_FlagsDarkened;
 
       font->darkenParams[0] = driver->darken_params[0];
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -854,12 +854,10 @@
         long         nsd = ft_strtol( s, NULL, 10 );
 
 
-        if ( nsd == 0 )
-          driver->no_stem_darkening = 0;
-        else if ( nsd == 1 )
-          driver->no_stem_darkening = 1;
+        if ( !nsd )
+          driver->no_stem_darkening = FALSE;
         else
-          return FT_THROW( Invalid_Argument );
+          driver->no_stem_darkening = TRUE;
       }
       else
 #endif