freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [ft-devel] a flag making FT_Open_Face() to use fallback family name


From: David Bevan
Subject: RE: [ft-devel] a flag making FT_Open_Face() to use fallback family name
Date: Thu, 26 Aug 2010 11:35:36 -0400

Two brief comments:

 

We’ve been treating unnamed fonts from PDFs as “tricky” in our code for some time, with the following addition to tt_check_trickyness():

 

    /*** Emtex change ***/

    /* ER38292 if no family name in the font program */

    /* treat the font with no name as one of the 'tricky' fonts */

    if ( !name )

      return TRUE;

 

Given the expiry of the TT patents, is there still a need for handling tricky fonts specially? We assumed not, and that when we got around to upgrading to the new FreeType (2.4.1), we could handle all fonts the same. Have we misunderstood?

 

Thanks.

 

David %^>

 

 

> -----Original Message-----

> From: address@hidden

> [mailto:address@hidden On Behalf Of

> address@hidden

> Sent: 26 August 2010 16:01

> To: freetype-devel

> Subject: [ft-devel] a flag making FT_Open_Face() to use fallback family

> name

>

> Sorry for posting so many.

>

> In previous post, I proposed a patch to expose the tricky

> font list to FT2 client, to check if the font is tricky by

> its name before the creation of FT_Face object:

>     http://lists.gnu.org/archive/html/freetype-devel/2010-

> 08/msg00018.html

>

> The reason why the name only without font data is that

> Type42/Type11 TrueType font may lack "name" table (and FT2

> cannot know the font name from the font file).

>

> I've tried another idea to reduce the additional code size:

> an introduction of new flag for FT_Open_Face(), to pass

> a fallback family name. By using the flag, FT_Open_Face()

> uses the fallback family name (taken from the optional

> parameters) when sfnt data lacks "name" table.

>

> Or, should I use FT_Face_Attach function for TrueType?

> At present, the feature is only used by PS Type1 font to

> add the metric infos stored in external AFM/PFM file.

> It may be possible (in technical meaning) to write a function

> to add/overwrite the information taken from PDF font

> descriptor stream (e.g. PS font name, StemV, Ascent, Descent,

> ItalicAngle, CapHeight, FontBBox etc). However, the attempt

> to overwrite something in TrueType is not PDF-specific issue,

> so the usage of the attach feature must be considered well.

> If you think FT_Face_Attach is better than passing fallback

> family name flag to FT_Open_Face(), please ignore following

> part of this post, and give me short comment.

>

> Regards,

> mpsuzuki

>

> ==========================================================

>

> The patch to add fallback family name feature is following:

> diff --git a/include/freetype/ftsnames.h b/include/freetype/ftsnames.h

> index 485e4e1..7e95229 100644

> --- a/include/freetype/ftsnames.h

> +++ b/include/freetype/ftsnames.h

> @@ -189,6 +189,22 @@ FT_BEGIN_HEADER

>     */

>  #define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY  FT_MAKE_TAG( 'i', 'g',

> 'p', 's' )

>

> +

> +

> /*************************************************************************

> **

> +   *

> +   * @constant:

> +   *   FT_PARAM_TAG_FALLBACK_NAME_FAMILY

> +   *

> +   * @description:

> +   *   A constant used as the tag of @FT_Parameter structures to specify

> +   *   a fallback family name. The embedded TrueType font in Type42 or

> +   *   Type11 format may lack the name table in its sfnt stream. To make

> +   *   FT_Face object with valid family name for such fonts, this option

> +   *   should be used.

> +   *

> +   */

> +#define FT_PARAM_TAG_FALLBACK_NAME_FAMILY  FT_MAKE_TAG( 'f', 'b', 'n',

> 'f' )

> +

>    /* */

>

>

> diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c

> index 6e35e2d..5e64046 100644

> --- a/src/sfnt/sfobjs.c

> +++ b/src/sfnt/sfobjs.c

> @@ -530,6 +530,7 @@

>      FT_Bool       is_apple_sbit;

>      FT_Bool       ignore_preferred_family = FALSE;

>      FT_Bool       ignore_preferred_subfamily = FALSE;

> +    FT_String*    fallback_name_family = NULL;

>

>      SFNT_Service  sfnt = (SFNT_Service)face->sfnt;

>

> @@ -543,10 +544,25 @@

>

>        for ( i = 0; i < num_params; i++ )

>        {

> -        if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY )

> -          ignore_preferred_family = TRUE;

> -        else if ( params[i].tag ==

> FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY )

> -          ignore_preferred_subfamily = TRUE;

> +        switch( params[i].tag )

> +        {

> +          case FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY:

> +            ignore_preferred_family = TRUE;

> +            break;

> +          case FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY:

> +            ignore_preferred_subfamily = TRUE;

> +            break;

> +          case FT_PARAM_TAG_FALLBACK_NAME_FAMILY:

> +            fallback_name_family = (FT_String*)params[i].data;

> +            break;

> +          default:

> +            FT_TRACE2(( "sfnt_load_face: ignore unknown FT_Param"

> +                        " tagged [%c%c%c%c]\n",

> +                        ( params[i].tag >> 24 ) & 0xFF,

> +                        ( params[i].tag >> 16 ) & 0xFF,

> +                        ( params[i].tag >>  8 ) & 0xFF,

> +                        ( params[i].tag       ) & 0xFF ));

> +        }

>        }

>      }

>

> @@ -766,6 +782,21 @@

>          GET_NAME( FONT_SUBFAMILY, &face->root.style_name );

>      }

>

> +    /* fallback for empty names */

> +    {

> +      FT_Memory  memory = face->root.stream->memory;

> +      FT_UInt    len;

> +

> +

> +      if ( !face->root.family_name && fallback_name_family )

> +      {

> +        len = ft_strlen( fallback_name_family );

> +        if ( !FT_NEW_ARRAY( face->root.family_name, len + 1 ) )

> +          ft_memcpy( face->root.family_name, fallback_name_family, len +

> 1 );

> +      }

> +      /* subfamily/styles are needed? */

> +    }

> +

>      /* now set up root fields */

>      {

>        FT_Face  root  = &face->root;

>

>

> -------------------------------------------------------------------

>

> Maybe it is not easy to understand how to use this.

> The patch for freetype2-demos attached to the end of this

> message. It modifies ftdump & ftview and add "-F" option

> to specify the fallback family name. It works aslike:

>

>     $ ./ftdump ./dell440_037-000.ttf

>     There is 1 face in this file.

>

>     ----- Face number: 0 -----

>

>     font name entries

>     family:     (null)

>     style:      (null)

>     postscript: UNAVAILABLE

>

>     ...

>

>

>     $ ./ftdump -F MingLiU ./dell440_037-000.ttf

>     There is 1 face in this file.

>

>     ----- Face number: 0 -----

>

>     font name entries

>     family:     MingLiU

>     style:      (null)

>     postscript: UNAVAILABLE

>

>     ...

>

> Some people will wonder "so what? what is the advantage

> of such joking feature?". Please try ftview. If you

> execute ftview for dell440_037-000.ttf without fallback

> family name, the hinting switch will work - if hinted,

> the glyph is correct, if unhinted, the glyph is broken.

>

> Maybe it sounds odd, this is NOT what the residents in

> the world of flooding MingLiU. What they (including me)

> expect is: even if FT_New_Face() is invoked with FT_LOAD_NO_HINTING,

> the hinter should be enabled. So the hinting switch changes

> nothing for MingLiU is expected. If you try genuine MingLiU

> not subsetted, you will find such behaviour. This hook is

> realized by the tricky font list.

>

> Then, if you execute with fallback family name,

>

>     $ ./ftview -F MingLiU 40 ./dell440_037-000.ttf

>

> You will find hinting is always enabled and the switch

> does not change anything. This is the behaviour that

> the residents in the world of flooding MingLiU expect.

>

> The patch for freetype2-demos is following:

>

> diff --git a/src/ftcommon.c b/src/ftcommon.c

> index 8a60c15..938dace 100644

> --- a/src/ftcommon.c

> +++ b/src/ftcommon.c

> @@ -17,6 +17,7 @@

>  #include FT_CACHE_H

>  #include FT_CACHE_MANAGER_H

>

> +#include FT_SFNT_NAMES_H

>  #include FT_BITMAP_H

>

>  #include "common.h"

> @@ -191,6 +192,34 @@

>    };

>

>

> +  static FT_Error

> +  ft_new_face_with_params( FT_Library     library,

> +                           const char*    pathname,

> +                           FT_UInt        face_index,

> +                           FT_UInt        num_params,

> +                           FT_Parameter*  params,

> +                           FT_Face*       aface )

> +  {

> +    FT_Error      error = FT_Err_Invalid_Argument;

> +    FT_Open_Args  args;

> +

> +    if ( !pathname )

> +      return error;

> +

> +    args.flags    = FT_OPEN_PATHNAME;

> +    args.pathname = (char*)pathname;

> +    args.stream   = NULL;

> +

> +    if ( num_params > 0 )

> +    {

> +      args.flags     |= FT_OPEN_PARAMS;

> +      args.num_params = num_params;

> +      args.params     = params;

> +    }

> +    return FT_Open_Face( library, &args, face_index, aface );

> +  }

> +

> +

>

> /*************************************************************************

> /

>    /*

> */

>    /* The face requester is a function provided by the client application

> */

> @@ -206,6 +235,8 @@

>                       FT_Face*    aface )

>    {

>      PFont  font = (PFont)face_id;

> +    FT_Parameter  param = { FT_PARAM_TAG_FALLBACK_NAME_FAMILY,

> +                            font->fallback_name_family };

>

>      FT_UNUSED( request_data );

>

> @@ -216,10 +247,12 @@

>                                    font->face_index,

>                                    aface );

>      else

> -      error = FT_New_Face( lib,

> -                           font->filepathname,

> -                           font->face_index,

> -                           aface );

> +      error = ft_new_face_with_params( lib,

> +                                       font->filepathname,

> +                                       font->face_index,

> +                                       1, &param,

> +                                       aface );

> +

>      if ( !error )

>      {

>        char*  suffix;

> @@ -344,11 +377,13 @@

>

>

>    FT_Error

> -  FTDemo_Install_Font( FTDemo_Handle*  handle,

> -                       const char*     filepath )

> +  FTDemo_Install_Font_With_Params( FTDemo_Handle*  handle,

> +                                   const char*     filepath,

> +                                   FT_UInt         num_params,

> +                                   FT_Parameter*   params )

>    {

>      static char  filename[1024 + 5];

> -    int          i, len, num_faces;

> +    int          i, j, len, num_faces;

>      FT_Face      face;

>

>

> @@ -359,8 +394,8 @@

>      strncpy( filename, filepath, len );

>      filename[len] = 0;

>

> -    error = FT_New_Face( handle->library, filename, 0, &face );

> -

> +    error = ft_new_face_with_params( handle->library, filename, 0,

> +                                     num_params, params, &face );

>  #ifndef macintosh

>      /* could not open the file directly; we will now try various */

>      /* suffixes like `.ttf' or `.pfb'                            */

> @@ -390,7 +425,8 @@

>          /* try with current suffix */

>          strcpy( p, suffix[0] );

>

> -        error = FT_New_Face( handle->library, filename, 0, &face );

> +        error = ft_new_face_with_params( handle->library, filename, 0,

> +                                         num_params, params, &face );

>          if ( !error )

>          {

>            found = 1;

> @@ -414,7 +450,8 @@

>

>        if ( i > 0 )

>        {

> -        error = FT_New_Face( handle->library, filename, i, &face );

> +        error = ft_new_face_with_params( handle->library, filename, i,

> +                                         num_params, params, &face );

>          if ( error )

>            continue;

>        }

> @@ -434,6 +471,14 @@

>        font->filepathname = (char*)malloc( strlen( filename ) + 1 );

>        strcpy( (char*)font->filepathname, filename );

>

> +      font->fallback_name_family = NULL;

> +      for ( j = 0; j < num_params; j++ )

> +        if ( params[j].tag == FT_PARAM_TAG_FALLBACK_NAME_FAMILY )

> +        {

> +          font->fallback_name_family = (char*)malloc( strlen(

> params[j].data ) );

> +          strcpy( (char*)font->fallback_name_family, params[j].data );

> +        }

> +

>        font->face_index = i;

>        font->cmap_index = face->charmap ? FT_Get_Charmap_Index( face-

> >charmap )

>                                         : 0;

> @@ -520,6 +565,14 @@

>    }

>

>

> +  FT_Error

> +  FTDemo_Install_Font( FTDemo_Handle*  handle,

> +                       const char*     filepath )

> +  {

> +    return FTDemo_Install_Font_With_Params( handle, filepath, 0, NULL );

> +  }

> +

> +

>    void

>    FTDemo_Set_Current_Font( FTDemo_Handle*  handle,

>                             PFont           font )

> diff --git a/src/ftcommon.h b/src/ftcommon.h

> index e6ce02f..10875c2 100644

> --- a/src/ftcommon.h

> +++ b/src/ftcommon.h

> @@ -117,6 +117,8 @@

>      void*        file_address;  /* for preloaded files */

>      size_t       file_size;

>

> +    /* FT_Face object may be recreated, so info for recreation should be

> stored in PFont */

> +    FT_String*   fallback_name_family;

>    } TFont, *PFont;

>

>    enum {

> @@ -206,6 +208,13 @@

>

>    /* install a font */

>    FT_Error

> +  FTDemo_Install_Font_With_Params( FTDemo_Handle*  handle,

> +                                   const char*     filepath,

> +                                   FT_UInt         num_params,

> +                                   FT_Parameter*   params );

> +

> +

> +  FT_Error

>    FTDemo_Install_Font( FTDemo_Handle*  handle,

>                         const char*     filepath );

>

> diff --git a/src/ftdump.c b/src/ftdump.c

> index 3bb7fc0..d35e2d4 100644

> --- a/src/ftdump.c

> +++ b/src/ftdump.c

> @@ -36,6 +36,7 @@

>    int  debug       = 0;

>    int  trace_level = 0;

>    int  name_tables = 0;

> +  char*  fallback_name_family = NULL;

>

>

>    /* PanicZ */

> @@ -73,6 +74,7 @@

>      fprintf( stderr, "  -l level  trace level for debug information\n" );

>  #  endif

>  #endif

> +    fprintf( stderr, "  -F        fallback family name\n" );

>      fprintf( stderr, "  -n        print SFNT name tables\n" );

>      fprintf( stderr, "  -v        be verbose\n" );

>      fprintf( stderr, "\n" );

> @@ -557,7 +559,7 @@

>

>      while ( 1 )

>      {

> -      option = getopt( argc, argv, "dl:nv" );

> +      option = getopt( argc, argv, "dl:F:nv" );

>

>        if ( option == -1 )

>          break;

> @@ -574,6 +576,10 @@

>            usage( execname );

>          break;

>

> +      case 'F':

> +        fallback_name_family = optarg;

> +        break;

> +

>        case 'n':

>          name_tables = 1;

>          break;

> @@ -666,7 +672,30 @@

>

>      for ( i = 0; i < num_faces; i++ )

>      {

> +#if 0

>        error = FT_New_Face( library, filename, i, &face );

> +#else

> +      {

> +        error = FT_Err_Invalid_Argument;

> +        if ( filename[0] )

> +        {

> +          FT_Open_Args  args;

> +          FT_Parameter  param;

> +

> +

> +          args.flags    = FT_OPEN_PATHNAME | FT_OPEN_PARAMS;

> +          args.pathname = (char*)filename;

> +          args.stream   = NULL;

> +

> +          param.tag     = FT_PARAM_TAG_FALLBACK_NAME_FAMILY;

> +          param.data    = fallback_name_family;

> +          args.params   = &param;

> +          args.num_params = 1;

> +

> +          error = FT_Open_Face( library, &args, i, &face );

> +        }

> +      }

> +#endif

>        if ( error )

>          PanicZ( "Could not open face." );

>

> diff --git a/src/ftview.c b/src/ftview.c

> index 42ed67c..d132e36 100644

> --- a/src/ftview.c

> +++ b/src/ftview.c

> @@ -26,6 +26,7 @@

>  #include FT_STROKER_H

>  #include FT_SYNTHESIS_H

>  #include FT_LCD_FILTER_H

> +#include FT_SFNT_NAMES_H

>

>  #define MAXPTSIZE      500                 /* dtp */

>  #define HEADER_HEIGHT  8

> @@ -92,11 +93,12 @@

>      int            use_custom_lcd_filter;

>      unsigned char  filter_weights[5];

>      int            fw_index;

> +    char*          fallback_name_family;

>

>    } status = { RENDER_MODE_ALL, FT_ENCODING_NONE, 72, 48, -1,

>                 1.0, 0.04, 0.22,

>                 0, 0, 0, 0, 0, NULL, { 0 }, 0, 0,

> -               0, "\x10\x40\x70\x40\x10", 2 };

> +               0, "\x10\x40\x70\x40\x10", 2, NULL };

>

>

>    static FTDemo_Display*  display;

> @@ -1247,6 +1249,7 @@

>      fprintf( stderr,  "            `.afm' or `.pfm').\n" );

>      fprintf( stderr,  "\n" );

>      fprintf( stderr,  "  -r R      Use resolution R dpi (default: 72

> dpi).\n" );

> +    fprintf( stderr,  "  -F name   Specify fallback family name.\n" );

>      fprintf( stderr,  "  -f index  Specify first index to display.\n" );

>      fprintf( stderr,  "  -e enc    Specify encoding tag (default: no

> encoding).\n" );

>      fprintf( stderr,  "  -D        Dump cache usage statistics.\n" );

> @@ -1272,7 +1275,7 @@

>

>      while ( 1 )

>      {

> -      option = getopt( *argc, *argv, "Dde:f:L:l:r:m:p" );

> +      option = getopt( *argc, *argv, "Dde:F:f:L:l:r:m:p" );

>

>        if ( option == -1 )

>          break;

> @@ -1291,6 +1294,10 @@

>          status.encoding = FTDemo_Make_Encoding_Tag( optarg );

>          break;

>

> +      case 'F':

> +        status.fallback_name_family  = optarg;

> +        break;

> +

>        case 'f':

>          status.Num  = atoi( optarg );

>          break;

> @@ -1386,7 +1393,14 @@

>        FTDemo_Set_Preload( handle, 1 );

>

>      for ( ; argc > 0; argc--, argv++ )

> -      FTDemo_Install_Font( handle, argv[0] );

> +    {

> +      FT_Parameter  param;

> +

> +

> +      param.tag  = FT_PARAM_TAG_FALLBACK_NAME_FAMILY;

> +      param.data = "">

> +      FTDemo_Install_Font_With_Params( handle, argv[0], 1, &param );

> +    }

>

>      if ( handle->num_fonts == 0 )

>        Fatal( "could not find/open any font file" );

 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]