shithub: freetype+ttf2subf

Download patch

ref: 08fd250e1af0aa16d18012d39462e6ca9bbc6e90
parent: f837a50ec3a4f240d73f018f237f9f58631e2ba5
author: Werner Lemberg <[email protected]>
date: Mon Jan 9 06:30:32 EST 2017

[pcf] Make long family names configurable.

The change from 2016-09-29 was too radical (except for people using
the openSuSE GNU/Linux distribution).  To ameliorate the situation,
PCF_CONFIG_OPTION_LONG_FAMILY_NAMES gets introduced which controls
the feature; if set, a new PCF property option
`no-long-family-names' can be used to switch this feature off.

* include/freetype/config/ftoption.h, devel/ftoption.h
(PCF_CONFIG_OPTION_LONG_FAMILY_NAMES): New option.

* include/freetype/ftpcfdrv.h: New header file (only containing
comments currently, used for building the documentation).

* include/freetype/config/ftheader.h (FT_PCF_DRIVER_H): New macro.

* src/pcf/pcf.h (PCF_Driver): Add `no_long_family_names' field.

* src/pcf/pcfdrivr.c: Include FT_SERVICE_PROPERTIES_H and
FT_PCF_DRIVER_H.
(pcf_property_set, pcf_property_get): New functions.
(pcf_service_properties): New service.
(pcf_servives): Updated.
(pcf_driver_init) [PCF_CONFIG_OPTION_LONG_FAMILY_NAMES]: Handle
`no_long_family_names'.

* src/pcf/pcfread.c (pcf_load_font): Handle `no_long_family_names'
and PCF_CONFIG_OPTION_LONG_FAMILY_NAMES.

* docs/CHANGES: Updated.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,38 @@
 2017-01-09  Werner Lemberg  <[email protected]>
 
+	[pcf] Make long family names configurable.
+
+	The change from 2016-09-29 was too radical (except for people using
+	the openSuSE GNU/Linux distribution).  To ameliorate the situation,
+	PCF_CONFIG_OPTION_LONG_FAMILY_NAMES gets introduced which controls
+	the feature; if set, a new PCF property option
+	`no-long-family-names' can be used to switch this feature off.
+
+	* include/freetype/config/ftoption.h, devel/ftoption.h
+	(PCF_CONFIG_OPTION_LONG_FAMILY_NAMES): New option.
+
+	* include/freetype/ftpcfdrv.h: New header file (only containing
+	comments currently, used for building the documentation).
+
+	* include/freetype/config/ftheader.h (FT_PCF_DRIVER_H): New macro.
+
+	* src/pcf/pcf.h (PCF_Driver): Add `no_long_family_names' field.
+
+	* src/pcf/pcfdrivr.c: Include FT_SERVICE_PROPERTIES_H and
+	FT_PCF_DRIVER_H.
+	(pcf_property_set, pcf_property_get): New functions.
+	(pcf_service_properties): New service.
+	(pcf_servives): Updated.
+	(pcf_driver_init) [PCF_CONFIG_OPTION_LONG_FAMILY_NAMES]: Handle
+	`no_long_family_names'.
+
+	* src/pcf/pcfread.c (pcf_load_font): Handle `no_long_family_names'
+	and PCF_CONFIG_OPTION_LONG_FAMILY_NAMES.
+
+	* docs/CHANGES: Updated.
+
+2017-01-09  Werner Lemberg  <[email protected]>
+
 	[pcf] Introduce a driver structure.
 
 	To be filled later on with something useful.
--- a/devel/ftoption.h
+++ b/devel/ftoption.h
@@ -82,8 +82,8 @@
   /* to control the various font drivers and modules.  The controllable    */
   /* properties are listed in the section `Controlling FreeType Modules'   */
   /* in the reference's table of contents; currently there are properties  */
-  /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'), and  */
-  /* TrueType (file `ftttdrv.h').                                          */
+  /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'),      */
+  /* TrueType (file `ftttdrv.h'), and PCF (file `ftpcfdrv.h').             */
   /*                                                                       */
   /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */
   /* multiple lines for better readability).                               */
@@ -830,6 +830,33 @@
   /* the cff driver module.                                                */
   /*                                                                       */
 #define CFF_CONFIG_OPTION_OLD_ENGINE
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****         P C F   D R I V E R    C O N F I G U R A T I O N        ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* There are many PCF fonts just called `Fixed' which look completely    */
+  /* different, and which have nothing to do with each other.  When        */
+  /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */
+  /* random, the style changes often if one changes the size and one       */
+  /* cannot select some fonts at all.  This option makes the PCF module    */
+  /* prepend the foundry name (plus a space) to the family name.           */
+  /*                                                                       */
+  /* We also check whether we have `wide' characters; all put together, we */
+  /* get family names like `Sony Fixed' or `Misc Fixed Wide'.              */
+  /*                                                                       */
+  /* If this option is activated, it can be controlled with the            */
+  /* `no-long-family-names' property of the pcf driver module.             */
+  /*                                                                       */
+#define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
 
 
   /*************************************************************************/
--- a/docs/CHANGES
+++ b/docs/CHANGES
@@ -1,4 +1,20 @@
 
+CHANGES BETWEEN 2.7.1 and 2.7.2
+
+  I. IMPORTANT CHANGES
+
+    - The PCF change to show more `colourful' family names (introduced
+      in version 2.7.1) was too radical; it can now be configured with
+      PCF_CONFIG_OPTION_LONG_FAMILY_NAMES   at   compile   time.    If
+      activated, it can  be switched off at run time  with the new pcf
+      property  `no-long-family-names'.  If  the `FREETYPE_PROPERTIES'
+      environment variable is available, you can say
+
+        FREETYPE_PROPERTIES=pcf:no-long-family-names=1
+
+
+======================================================================
+
 CHANGES BETWEEN 2.7 and 2.7.1
 
   I. IMPORTANT CHANGES
--- a/include/freetype/config/ftheader.h
+++ b/include/freetype/config/ftheader.h
@@ -357,6 +357,19 @@
   /*************************************************************************
    *
    * @macro:
+   *   FT_PCF_DRIVER_H
+   *
+   * @description:
+   *   A macro used in #include statements to name the file containing
+   *   structures and macros related to the PCF driver module.
+   *
+   */
+#define FT_PCF_DRIVER_H  <freetype/ftpcfdrv.h>
+
+
+  /*************************************************************************
+   *
+   * @macro:
    *   FT_TYPE1_TABLES_H
    *
    * @description:
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -82,8 +82,8 @@
   /* to control the various font drivers and modules.  The controllable    */
   /* properties are listed in the section `Controlling FreeType Modules'   */
   /* in the reference's table of contents; currently there are properties  */
-  /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'), and  */
-  /* TrueType (file `ftttdrv.h').                                          */
+  /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'),      */
+  /* TrueType (file `ftttdrv.h'), and PCF (file `ftpcfdrv.h').             */
   /*                                                                       */
   /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */
   /* multiple lines for better readability).                               */
@@ -830,6 +830,33 @@
   /* the cff driver module.                                                */
   /*                                                                       */
 /* #define CFF_CONFIG_OPTION_OLD_ENGINE */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****         P C F   D R I V E R    C O N F I G U R A T I O N        ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* There are many PCF fonts just called `Fixed' which look completely    */
+  /* different, and which have nothing to do with each other.  When        */
+  /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */
+  /* random, the style changes often if one changes the size and one       */
+  /* cannot select some fonts at all.  This option makes the PCF module    */
+  /* prepend the foundry name (plus a space) to the family name.           */
+  /*                                                                       */
+  /* We also check whether we have `wide' characters; all put together, we */
+  /* get family names like `Sony Fixed' or `Misc Fixed Wide'.              */
+  /*                                                                       */
+  /* If this option is activated, it can be controlled with the            */
+  /* `no-long-family-names' property of the pcf driver module.             */
+  /*                                                                       */
+#define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
 
 
   /*************************************************************************/
--- a/include/freetype/ftchapters.h
+++ b/include/freetype/ftchapters.h
@@ -77,6 +77,7 @@
 /*    auto_hinter                                                          */
 /*    cff_driver                                                           */
 /*    tt_driver                                                            */
+/*    pcf_driver                                                           */
 /*                                                                         */
 /***************************************************************************/
 
--- /dev/null
+++ b/include/freetype/ftpcfdrv.h
@@ -1,0 +1,105 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftpcfdrv.h                                                             */
+/*                                                                         */
+/*    FreeType API for controlling the PCF driver (specification only).    */
+/*                                                                         */
+/*  Copyright 2017 by                                                      */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef FTPCFDRV_H_
+#define FTPCFDRV_H_
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifdef FREETYPE_H
+#error "freetype.h of FreeType 1 has been loaded!"
+#error "Please fix the directory search order for header files"
+#error "so that freetype.h of FreeType 2 is found first."
+#endif
+
+
+FT_BEGIN_HEADER
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   pcf_driver
+   *
+   * @title:
+   *   The PCF driver
+   *
+   * @abstract:
+   *   Controlling the PCF driver module.
+   *
+   * @description:
+   *   While FreeType's PCF driver doesn't expose API functions by itself,
+   *   it is possible to control its behaviour with @FT_Property_Set and
+   *   @FT_Property_Get.  Right now, there is a single property
+   *   `no-long-family-names' available if FreeType is compiled with
+   *   PCF_CONFIG_OPTION_LONG_FAMILY_NAMES.
+   *
+   *   The PCF driver's module name is `pcf'.
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @property:
+   *   no-long-family-names
+   *
+   * @description:
+   *   If PCF_CONFIG_OPTION_LONG_FAMILY_NAMES is active while compiling
+   *   FreeType, the PCF driver constructs long family names.
+   *
+   *   There are many PCF fonts just called `Fixed' which look completely
+   *   different, and which have nothing to do with each other.  When
+   *   selecting `Fixed' in KDE or Gnome one gets results that appear rather
+   *   random, the style changes often if one changes the size and one
+   *   cannot select some fonts at all.  The improve this situation, the PCF
+   *   module prepends the foundry name (plus a space) to the family name. 
+   *   It also checks whether there are `wide' characters; all put together,
+   *   family names like `Sony Fixed' or `Misc Fixed Wide' are constructed.
+   *
+   *   If `no-long-family-names' is set, this feature gets switched off.
+   *
+   *   {
+   *     FT_Library  library;
+   *     FT_Bool     no_long_family_names = TRUE;
+   *
+   *
+   *     FT_Init_FreeType( &library );
+   *
+   *     FT_Property_Set( library, "pcf",
+   *                               "no-long-family-names",
+   *                               &no_long_family_names );
+   *   }
+   *
+   * @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).
+   *
+   */
+
+
+FT_END_HEADER
+
+
+#endif /* FTPCFDRV_H_ */
+
+
+/* END */
--- a/src/pcf/pcf.h
+++ b/src/pcf/pcf.h
@@ -167,6 +167,8 @@
   {
     FT_DriverRec  root;
 
+    FT_Bool  no_long_family_names;
+
   } PCF_DriverRec, *PCF_Driver;
 
 
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -49,6 +49,8 @@
 
 #include FT_SERVICE_BDF_H
 #include FT_SERVICE_FONT_FORMAT_H
+#include FT_SERVICE_PROPERTIES_H
+#include FT_PCF_DRIVER_H
 
 
   /*************************************************************************/
@@ -667,6 +669,110 @@
   };
 
 
+  /*
+   *  PROPERTY SERVICE
+   *
+   */
+  static FT_Error
+  pcf_property_set( FT_Module    module,         /* PCF_Driver */
+                    const char*  property_name,
+                    const void*  value,
+                    FT_Bool      value_is_string )
+  {
+#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
+
+    FT_Error    error  = FT_Err_Ok;
+    PCF_Driver  driver = (PCF_Driver)module;
+
+#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+    FT_UNUSED( value_is_string );
+#endif
+
+
+    if ( !ft_strcmp( property_name, "no-long-family-names" ) )
+    {
+#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+      if ( value_is_string )
+      {
+        const char*  s   = (const char*)value;
+        long         lfn = ft_strtol( s, NULL, 10 );
+
+
+        if ( lfn == 0 )
+          driver->no_long_family_names = 0;
+        else if ( lfn == 1 )
+          driver->no_long_family_names = 1;
+        else
+          return FT_THROW( Invalid_Argument );
+      }
+      else
+#endif
+      {
+        FT_Bool*  no_long_family_names = (FT_Bool*)value;
+
+
+        driver->no_long_family_names = *no_long_family_names;
+      }
+
+      return error;
+    }
+
+#else /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
+
+    FT_UNUSED( module );
+    FT_UNUSED( value );
+    FT_UNUSED( value_is_string );
+
+#endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
+
+    FT_TRACE0(( "pcf_property_set: missing property `%s'\n",
+                property_name ));
+    return FT_THROW( Missing_Property );
+  }
+
+
+  static FT_Error
+  pcf_property_get( FT_Module    module,         /* PCF_Driver */
+                    const char*  property_name,
+                    const void*  value )
+  {
+#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
+
+    FT_Error    error  = FT_Err_Ok;
+    PCF_Driver  driver = (PCF_Driver)module;
+
+
+    if ( !ft_strcmp( property_name, "no-long-family-names" ) )
+    {
+      FT_Bool   no_long_family_names = driver->no_long_family_names;
+      FT_Bool*  val                  = (FT_Bool*)value;
+
+
+      *val = no_long_family_names;
+
+      return error;
+    }
+
+#else /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
+
+    FT_UNUSED( module );
+    FT_UNUSED( value );
+
+#endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
+
+    FT_TRACE0(( "pcf_property_get: missing property `%s'\n",
+                property_name ));
+    return FT_THROW( Missing_Property );
+  }
+
+
+  FT_DEFINE_SERVICE_PROPERTIESREC(
+    pcf_service_properties,
+
+    (FT_Properties_SetFunc)pcf_property_set,      /* set_property */
+    (FT_Properties_GetFunc)pcf_property_get )     /* get_property */
+
+
  /*
   *
   *  SERVICE LIST
@@ -677,6 +783,7 @@
   {
     { FT_SERVICE_ID_BDF,         &pcf_service_bdf },
     { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PCF },
+    { FT_SERVICE_ID_PROPERTIES,  &pcf_service_properties },
     { NULL, NULL }
   };
 
@@ -694,7 +801,14 @@
   FT_CALLBACK_DEF( FT_Error )
   pcf_driver_init( FT_Module  module )      /* PCF_Driver */
   {
+#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
+    PCF_Driver  driver = (PCF_Driver)module;
+
+
+    driver->no_long_family_names = 0;
+#else
     FT_UNUSED( module );
+#endif
 
     return FT_Err_Ok;
   }
--- a/src/pcf/pcfread.c
+++ b/src/pcf/pcfread.c
@@ -1393,57 +1393,75 @@
       prop = pcf_find_property( face, "FAMILY_NAME" );
       if ( prop && prop->isString )
       {
-        /* Prepend the foundry name plus a space to the family name.      */
-        /* There are many fonts just called `Fixed' which look completely */
-        /* different, and which have nothing to do with each other.  When */
-        /* selecting `Fixed' in KDE or Gnome one gets results that appear */
-        /* rather random, the style changes often if one changes the size */
-        /* and one cannot select some fonts at all.                       */
-        /*                                                                */
-        /* We also check whether we have `wide' characters; all put       */
-        /* together, we get family names like `Sony Fixed' or `Misc Fixed */
-        /* Wide'.                                                         */
-        PCF_Property  foundry_prop, point_size_prop, average_width_prop;
 
-        int  l    = ft_strlen( prop->value.atom ) + 1;
-        int  wide = 0;
+#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
 
+        PCF_Driver  driver = (PCF_Driver)FT_FACE_DRIVER( face );
 
-        foundry_prop       = pcf_find_property( face, "FOUNDRY" );
-        point_size_prop    = pcf_find_property( face, "POINT_SIZE" );
-        average_width_prop = pcf_find_property( face, "AVERAGE_WIDTH" );
 
-        if ( point_size_prop && average_width_prop )
+        if ( !driver->no_long_family_names )
         {
-          if ( average_width_prop->value.l >= point_size_prop->value.l )
+          /* Prepend the foundry name plus a space to the family name.     */
+          /* There are many fonts just called `Fixed' which look           */
+          /* completely different, and which have nothing to do with each  */
+          /* other.  When selecting `Fixed' in KDE or Gnome one gets       */
+          /* results that appear rather random, the style changes often if */
+          /* one changes the size and one cannot select some fonts at all. */
+          /*                                                               */
+          /* We also check whether we have `wide' characters; all put      */
+          /* together, we get family names like `Sony Fixed' or `Misc      */
+          /* Fixed Wide'.                                                  */
+
+          PCF_Property  foundry_prop, point_size_prop, average_width_prop;
+
+          int  l    = ft_strlen( prop->value.atom ) + 1;
+          int  wide = 0;
+
+
+          foundry_prop       = pcf_find_property( face, "FOUNDRY" );
+          point_size_prop    = pcf_find_property( face, "POINT_SIZE" );
+          average_width_prop = pcf_find_property( face, "AVERAGE_WIDTH" );
+
+          if ( point_size_prop && average_width_prop )
           {
-            /* This font is at least square shaped or even wider */
-            wide = 1;
-            l   += ft_strlen( " Wide" );
+            if ( average_width_prop->value.l >= point_size_prop->value.l )
+            {
+              /* This font is at least square shaped or even wider */
+              wide = 1;
+              l   += ft_strlen( " Wide" );
+            }
           }
-        }
 
-        if ( foundry_prop && foundry_prop->isString )
-        {
-          l += ft_strlen( foundry_prop->value.atom ) + 1;
+          if ( foundry_prop && foundry_prop->isString )
+          {
+            l += ft_strlen( foundry_prop->value.atom ) + 1;
 
-          if ( FT_NEW_ARRAY( root->family_name, l ) )
-            goto Exit;
+            if ( FT_NEW_ARRAY( root->family_name, l ) )
+              goto Exit;
 
-          ft_strcpy( root->family_name, foundry_prop->value.atom );
-          ft_strcat( root->family_name, " " );
-          ft_strcat( root->family_name, prop->value.atom );
+            ft_strcpy( root->family_name, foundry_prop->value.atom );
+            ft_strcat( root->family_name, " " );
+            ft_strcat( root->family_name, prop->value.atom );
+          }
+          else
+          {
+            if ( FT_NEW_ARRAY( root->family_name, l ) )
+              goto Exit;
+
+            ft_strcpy( root->family_name, prop->value.atom );
+          }
+
+          if ( wide )
+            ft_strcat( root->family_name, " Wide" );
         }
         else
+
+#endif /* PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
+
         {
-          if ( FT_NEW_ARRAY( root->family_name, l ) )
+          if ( FT_STRDUP( root->family_name, prop->value.atom ) )
             goto Exit;
-
-          ft_strcpy( root->family_name, prop->value.atom );
         }
-
-        if ( wide )
-          ft_strcat( root->family_name, " Wide" );
       }
       else
         root->family_name = NULL;