misc/libfreetype/src/cff/cffobjs.c
changeset 9431 0f5961910e27
parent 9357 a501f5ec7b34
parent 9429 7a97a554ac80
child 9433 f0a8ac191839
equal deleted inserted replaced
9357:a501f5ec7b34 9431:0f5961910e27
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  cffobjs.c                                                              */
       
     4 /*                                                                         */
       
     5 /*    OpenType objects manager (body).                                     */
       
     6 /*                                                                         */
       
     7 /*  Copyright 1996-2011 by                                                 */
       
     8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
       
     9 /*                                                                         */
       
    10 /*  This file is part of the FreeType project, and may only be used,       */
       
    11 /*  modified, and distributed under the terms of the FreeType project      */
       
    12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
       
    13 /*  this file you indicate that you have read the license and              */
       
    14 /*  understand and accept it fully.                                        */
       
    15 /*                                                                         */
       
    16 /***************************************************************************/
       
    17 
       
    18 
       
    19 #include <ft2build.h>
       
    20 #include FT_INTERNAL_DEBUG_H
       
    21 #include FT_INTERNAL_CALC_H
       
    22 #include FT_INTERNAL_STREAM_H
       
    23 #include FT_ERRORS_H
       
    24 #include FT_TRUETYPE_IDS_H
       
    25 #include FT_TRUETYPE_TAGS_H
       
    26 #include FT_INTERNAL_SFNT_H
       
    27 #include "cffobjs.h"
       
    28 #include "cffload.h"
       
    29 #include "cffcmap.h"
       
    30 #include "cfferrs.h"
       
    31 #include "cffpic.h"
       
    32 
       
    33 
       
    34   /*************************************************************************/
       
    35   /*                                                                       */
       
    36   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
       
    37   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
       
    38   /* messages during execution.                                            */
       
    39   /*                                                                       */
       
    40 #undef  FT_COMPONENT
       
    41 #define FT_COMPONENT  trace_cffobjs
       
    42 
       
    43 
       
    44   /*************************************************************************/
       
    45   /*                                                                       */
       
    46   /*                            SIZE FUNCTIONS                             */
       
    47   /*                                                                       */
       
    48   /*  Note that we store the global hints in the size's `internal' root    */
       
    49   /*  field.                                                               */
       
    50   /*                                                                       */
       
    51   /*************************************************************************/
       
    52 
       
    53 
       
    54   static PSH_Globals_Funcs
       
    55   cff_size_get_globals_funcs( CFF_Size  size )
       
    56   {
       
    57     CFF_Face          face     = (CFF_Face)size->root.face;
       
    58     CFF_Font          font     = (CFF_Font)face->extra.data;
       
    59     PSHinter_Service  pshinter = font->pshinter;
       
    60     FT_Module         module;
       
    61 
       
    62 
       
    63     module = FT_Get_Module( size->root.face->driver->root.library,
       
    64                             "pshinter" );
       
    65     return ( module && pshinter && pshinter->get_globals_funcs )
       
    66            ? pshinter->get_globals_funcs( module )
       
    67            : 0;
       
    68   }
       
    69 
       
    70 
       
    71   FT_LOCAL_DEF( void )
       
    72   cff_size_done( FT_Size  cffsize )        /* CFF_Size */
       
    73   {
       
    74     CFF_Size      size     = (CFF_Size)cffsize;
       
    75     CFF_Face      face     = (CFF_Face)size->root.face;
       
    76     CFF_Font      font     = (CFF_Font)face->extra.data;
       
    77     CFF_Internal  internal = (CFF_Internal)cffsize->internal;
       
    78 
       
    79 
       
    80     if ( internal )
       
    81     {
       
    82       PSH_Globals_Funcs  funcs;
       
    83 
       
    84 
       
    85       funcs = cff_size_get_globals_funcs( size );
       
    86       if ( funcs )
       
    87       {
       
    88         FT_UInt  i;
       
    89 
       
    90 
       
    91         funcs->destroy( internal->topfont );
       
    92 
       
    93         for ( i = font->num_subfonts; i > 0; i-- )
       
    94           funcs->destroy( internal->subfonts[i - 1] );
       
    95       }
       
    96 
       
    97       /* `internal' is freed by destroy_size (in ftobjs.c) */
       
    98     }
       
    99   }
       
   100 
       
   101 
       
   102   /* CFF and Type 1 private dictionaries have slightly different      */
       
   103   /* structures; we need to synthesize a Type 1 dictionary on the fly */
       
   104 
       
   105   static void
       
   106   cff_make_private_dict( CFF_SubFont  subfont,
       
   107                          PS_Private   priv )
       
   108   {
       
   109     CFF_Private  cpriv = &subfont->private_dict;
       
   110     FT_UInt      n, count;
       
   111 
       
   112 
       
   113     FT_MEM_ZERO( priv, sizeof ( *priv ) );
       
   114 
       
   115     count = priv->num_blue_values = cpriv->num_blue_values;
       
   116     for ( n = 0; n < count; n++ )
       
   117       priv->blue_values[n] = (FT_Short)cpriv->blue_values[n];
       
   118 
       
   119     count = priv->num_other_blues = cpriv->num_other_blues;
       
   120     for ( n = 0; n < count; n++ )
       
   121       priv->other_blues[n] = (FT_Short)cpriv->other_blues[n];
       
   122 
       
   123     count = priv->num_family_blues = cpriv->num_family_blues;
       
   124     for ( n = 0; n < count; n++ )
       
   125       priv->family_blues[n] = (FT_Short)cpriv->family_blues[n];
       
   126 
       
   127     count = priv->num_family_other_blues = cpriv->num_family_other_blues;
       
   128     for ( n = 0; n < count; n++ )
       
   129       priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
       
   130 
       
   131     priv->blue_scale = cpriv->blue_scale;
       
   132     priv->blue_shift = (FT_Int)cpriv->blue_shift;
       
   133     priv->blue_fuzz  = (FT_Int)cpriv->blue_fuzz;
       
   134 
       
   135     priv->standard_width[0]  = (FT_UShort)cpriv->standard_width;
       
   136     priv->standard_height[0] = (FT_UShort)cpriv->standard_height;
       
   137 
       
   138     count = priv->num_snap_widths = cpriv->num_snap_widths;
       
   139     for ( n = 0; n < count; n++ )
       
   140       priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
       
   141 
       
   142     count = priv->num_snap_heights = cpriv->num_snap_heights;
       
   143     for ( n = 0; n < count; n++ )
       
   144       priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
       
   145 
       
   146     priv->force_bold     = cpriv->force_bold;
       
   147     priv->language_group = cpriv->language_group;
       
   148     priv->lenIV          = cpriv->lenIV;
       
   149   }
       
   150 
       
   151 
       
   152   FT_LOCAL_DEF( FT_Error )
       
   153   cff_size_init( FT_Size  cffsize )         /* CFF_Size */
       
   154   {
       
   155     CFF_Size           size  = (CFF_Size)cffsize;
       
   156     FT_Error           error = CFF_Err_Ok;
       
   157     PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );
       
   158 
       
   159 
       
   160     if ( funcs )
       
   161     {
       
   162       CFF_Face      face     = (CFF_Face)cffsize->face;
       
   163       CFF_Font      font     = (CFF_Font)face->extra.data;
       
   164       CFF_Internal  internal;
       
   165 
       
   166       PS_PrivateRec  priv;
       
   167       FT_Memory      memory = cffsize->face->memory;
       
   168 
       
   169       FT_UInt  i;
       
   170 
       
   171 
       
   172       if ( FT_NEW( internal ) )
       
   173         goto Exit;
       
   174 
       
   175       cff_make_private_dict( &font->top_font, &priv );
       
   176       error = funcs->create( cffsize->face->memory, &priv,
       
   177                              &internal->topfont );
       
   178       if ( error )
       
   179         goto Exit;
       
   180 
       
   181       for ( i = font->num_subfonts; i > 0; i-- )
       
   182       {
       
   183         CFF_SubFont  sub = font->subfonts[i - 1];
       
   184 
       
   185 
       
   186         cff_make_private_dict( sub, &priv );
       
   187         error = funcs->create( cffsize->face->memory, &priv,
       
   188                                &internal->subfonts[i - 1] );
       
   189         if ( error )
       
   190           goto Exit;
       
   191       }
       
   192 
       
   193       cffsize->internal = (FT_Size_Internal)(void*)internal;
       
   194     }
       
   195 
       
   196     size->strike_index = 0xFFFFFFFFUL;
       
   197 
       
   198   Exit:
       
   199     return error;
       
   200   }
       
   201 
       
   202 
       
   203 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
       
   204 
       
   205   FT_LOCAL_DEF( FT_Error )
       
   206   cff_size_select( FT_Size   size,
       
   207                    FT_ULong  strike_index )
       
   208   {
       
   209     CFF_Size           cffsize = (CFF_Size)size;
       
   210     PSH_Globals_Funcs  funcs;
       
   211 
       
   212 
       
   213     cffsize->strike_index = strike_index;
       
   214 
       
   215     FT_Select_Metrics( size->face, strike_index );
       
   216 
       
   217     funcs = cff_size_get_globals_funcs( cffsize );
       
   218 
       
   219     if ( funcs )
       
   220     {
       
   221       CFF_Face      face     = (CFF_Face)size->face;
       
   222       CFF_Font      font     = (CFF_Font)face->extra.data;
       
   223       CFF_Internal  internal = (CFF_Internal)size->internal;
       
   224 
       
   225       FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
       
   226       FT_UInt   i;
       
   227 
       
   228 
       
   229       funcs->set_scale( internal->topfont,
       
   230                         size->metrics.x_scale, size->metrics.y_scale,
       
   231                         0, 0 );
       
   232 
       
   233       for ( i = font->num_subfonts; i > 0; i-- )
       
   234       {
       
   235         CFF_SubFont  sub     = font->subfonts[i - 1];
       
   236         FT_ULong     sub_upm = sub->font_dict.units_per_em;
       
   237         FT_Pos       x_scale, y_scale;
       
   238 
       
   239 
       
   240         if ( top_upm != sub_upm )
       
   241         {
       
   242           x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
       
   243           y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
       
   244         }
       
   245         else
       
   246         {
       
   247           x_scale = size->metrics.x_scale;
       
   248           y_scale = size->metrics.y_scale;
       
   249         }
       
   250 
       
   251         funcs->set_scale( internal->subfonts[i - 1],
       
   252                           x_scale, y_scale, 0, 0 );
       
   253       }
       
   254     }
       
   255 
       
   256     return CFF_Err_Ok;
       
   257   }
       
   258 
       
   259 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
       
   260 
       
   261 
       
   262   FT_LOCAL_DEF( FT_Error )
       
   263   cff_size_request( FT_Size          size,
       
   264                     FT_Size_Request  req )
       
   265   {
       
   266     CFF_Size           cffsize = (CFF_Size)size;
       
   267     PSH_Globals_Funcs  funcs;
       
   268 
       
   269 
       
   270 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
       
   271 
       
   272     if ( FT_HAS_FIXED_SIZES( size->face ) )
       
   273     {
       
   274       CFF_Face      cffface = (CFF_Face)size->face;
       
   275       SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
       
   276       FT_ULong      strike_index;
       
   277 
       
   278 
       
   279       if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )
       
   280         cffsize->strike_index = 0xFFFFFFFFUL;
       
   281       else
       
   282         return cff_size_select( size, strike_index );
       
   283     }
       
   284 
       
   285 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
       
   286 
       
   287     FT_Request_Metrics( size->face, req );
       
   288 
       
   289     funcs = cff_size_get_globals_funcs( cffsize );
       
   290 
       
   291     if ( funcs )
       
   292     {
       
   293       CFF_Face      cffface  = (CFF_Face)size->face;
       
   294       CFF_Font      font     = (CFF_Font)cffface->extra.data;
       
   295       CFF_Internal  internal = (CFF_Internal)size->internal;
       
   296 
       
   297       FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
       
   298       FT_UInt   i;
       
   299 
       
   300 
       
   301       funcs->set_scale( internal->topfont,
       
   302                         size->metrics.x_scale, size->metrics.y_scale,
       
   303                         0, 0 );
       
   304 
       
   305       for ( i = font->num_subfonts; i > 0; i-- )
       
   306       {
       
   307         CFF_SubFont  sub     = font->subfonts[i - 1];
       
   308         FT_ULong     sub_upm = sub->font_dict.units_per_em;
       
   309         FT_Pos       x_scale, y_scale;
       
   310 
       
   311 
       
   312         if ( top_upm != sub_upm )
       
   313         {
       
   314           x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
       
   315           y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
       
   316         }
       
   317         else
       
   318         {
       
   319           x_scale = size->metrics.x_scale;
       
   320           y_scale = size->metrics.y_scale;
       
   321         }
       
   322 
       
   323         funcs->set_scale( internal->subfonts[i - 1],
       
   324                           x_scale, y_scale, 0, 0 );
       
   325       }
       
   326     }
       
   327 
       
   328     return CFF_Err_Ok;
       
   329   }
       
   330 
       
   331 
       
   332   /*************************************************************************/
       
   333   /*                                                                       */
       
   334   /*                            SLOT  FUNCTIONS                            */
       
   335   /*                                                                       */
       
   336   /*************************************************************************/
       
   337 
       
   338   FT_LOCAL_DEF( void )
       
   339   cff_slot_done( FT_GlyphSlot  slot )
       
   340   {
       
   341     slot->internal->glyph_hints = 0;
       
   342   }
       
   343 
       
   344 
       
   345   FT_LOCAL_DEF( FT_Error )
       
   346   cff_slot_init( FT_GlyphSlot  slot )
       
   347   {
       
   348     CFF_Face          face     = (CFF_Face)slot->face;
       
   349     CFF_Font          font     = (CFF_Font)face->extra.data;
       
   350     PSHinter_Service  pshinter = font->pshinter;
       
   351 
       
   352 
       
   353     if ( pshinter )
       
   354     {
       
   355       FT_Module  module;
       
   356 
       
   357 
       
   358       module = FT_Get_Module( slot->face->driver->root.library,
       
   359                               "pshinter" );
       
   360       if ( module )
       
   361       {
       
   362         T2_Hints_Funcs  funcs;
       
   363 
       
   364 
       
   365         funcs = pshinter->get_t2_funcs( module );
       
   366         slot->internal->glyph_hints = (void*)funcs;
       
   367       }
       
   368     }
       
   369 
       
   370     return CFF_Err_Ok;
       
   371   }
       
   372 
       
   373 
       
   374   /*************************************************************************/
       
   375   /*                                                                       */
       
   376   /*                           FACE  FUNCTIONS                             */
       
   377   /*                                                                       */
       
   378   /*************************************************************************/
       
   379 
       
   380   static FT_String*
       
   381   cff_strcpy( FT_Memory         memory,
       
   382               const FT_String*  source )
       
   383   {
       
   384     FT_Error    error;
       
   385     FT_String*  result;
       
   386 
       
   387 
       
   388     (void)FT_STRDUP( result, source );
       
   389 
       
   390     FT_UNUSED( error );
       
   391 
       
   392     return result;
       
   393   }
       
   394 
       
   395 
       
   396   /* Strip all subset prefixes of the form `ABCDEF+'.  Usually, there */
       
   397   /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold'   */
       
   398   /* have been seen in the wild.                                      */
       
   399 
       
   400   static void
       
   401   remove_subset_prefix( FT_String*  name )
       
   402   {
       
   403     FT_Int32  idx             = 0;
       
   404     FT_Int32  length          = strlen( name ) + 1;
       
   405     FT_Bool   continue_search = 1;
       
   406  
       
   407 
       
   408     while ( continue_search )
       
   409     {
       
   410       if ( length >= 7 && name[6] == '+' )
       
   411       {
       
   412         for ( idx = 0; idx < 6; idx++ )
       
   413         {
       
   414           /* ASCII uppercase letters */
       
   415           if ( !( 'A' <= name[idx] && name[idx] <= 'Z' ) )
       
   416             continue_search = 0;
       
   417         }
       
   418 
       
   419         if ( continue_search )
       
   420         {
       
   421           for ( idx = 7; idx < length; idx++ )
       
   422             name[idx - 7] = name[idx];
       
   423           length -= 7;
       
   424         }
       
   425       }
       
   426       else
       
   427         continue_search = 0;
       
   428     }
       
   429   }
       
   430 
       
   431 
       
   432   /* Remove the style part from the family name (if present). */
       
   433 
       
   434   static void
       
   435   remove_style( FT_String*        family_name,
       
   436                 const FT_String*  style_name )
       
   437   {
       
   438     FT_Int32  family_name_length, style_name_length;
       
   439 
       
   440 
       
   441     family_name_length = strlen( family_name );
       
   442     style_name_length  = strlen( style_name );
       
   443 
       
   444     if ( family_name_length > style_name_length )
       
   445     {
       
   446       FT_Int  idx;
       
   447 
       
   448 
       
   449       for ( idx = 1; idx <= style_name_length; ++idx )
       
   450       {
       
   451         if ( family_name[family_name_length - idx] !=
       
   452              style_name[style_name_length - idx] )
       
   453           break;
       
   454       }
       
   455 
       
   456       if ( idx > style_name_length )
       
   457       {
       
   458         /* family_name ends with style_name; remove it */
       
   459         idx = family_name_length - style_name_length - 1;
       
   460 
       
   461         /* also remove special characters     */
       
   462         /* between real family name and style */
       
   463         while ( idx > 0                     &&
       
   464                 ( family_name[idx] == '-' ||
       
   465                   family_name[idx] == ' ' ||
       
   466                   family_name[idx] == '_' ||
       
   467                   family_name[idx] == '+' ) )
       
   468           --idx;
       
   469 
       
   470         if ( idx > 0 )
       
   471           family_name[idx + 1] = '\0';
       
   472       }
       
   473     }
       
   474   }
       
   475 
       
   476 
       
   477   FT_LOCAL_DEF( FT_Error )
       
   478   cff_face_init( FT_Stream      stream,
       
   479                  FT_Face        cffface,        /* CFF_Face */
       
   480                  FT_Int         face_index,
       
   481                  FT_Int         num_params,
       
   482                  FT_Parameter*  params )
       
   483   {
       
   484     CFF_Face            face        = (CFF_Face)cffface;
       
   485     FT_Error            error;
       
   486     SFNT_Service        sfnt;
       
   487     FT_Service_PsCMaps  psnames;
       
   488     PSHinter_Service    pshinter;
       
   489     FT_Bool             pure_cff    = 1;
       
   490     FT_Bool             sfnt_format = 0;
       
   491     FT_Library          library     = cffface->driver->root.library;
       
   492 
       
   493 
       
   494     sfnt = (SFNT_Service)FT_Get_Module_Interface(
       
   495              library, "sfnt" );
       
   496     if ( !sfnt )
       
   497       goto Bad_Format;
       
   498 
       
   499     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
       
   500 
       
   501     pshinter = (PSHinter_Service)FT_Get_Module_Interface(
       
   502                  library, "pshinter" );
       
   503 
       
   504     /* create input stream from resource */
       
   505     if ( FT_STREAM_SEEK( 0 ) )
       
   506       goto Exit;
       
   507 
       
   508     /* check whether we have a valid OpenType file */
       
   509     error = sfnt->init_face( stream, face, face_index, num_params, params );
       
   510     if ( !error )
       
   511     {
       
   512       if ( face->format_tag != TTAG_OTTO )  /* `OTTO'; OpenType/CFF font */
       
   513       {
       
   514         FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
       
   515         goto Bad_Format;
       
   516       }
       
   517 
       
   518       /* if we are performing a simple font format check, exit immediately */
       
   519       if ( face_index < 0 )
       
   520         return CFF_Err_Ok;
       
   521 
       
   522       /* UNDOCUMENTED!  A CFF in an SFNT can have only a single font. */
       
   523       if ( face_index > 0 )
       
   524       {
       
   525         FT_ERROR(( "cff_face_init: invalid face index\n" ));
       
   526         error = CFF_Err_Invalid_Argument;
       
   527         goto Exit;
       
   528       }
       
   529 
       
   530       sfnt_format = 1;
       
   531 
       
   532       /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
       
   533       /* font; in the latter case it doesn't have a `head' table         */
       
   534       error = face->goto_table( face, TTAG_head, stream, 0 );
       
   535       if ( !error )
       
   536       {
       
   537         pure_cff = 0;
       
   538 
       
   539         /* load font directory */
       
   540         error = sfnt->load_face( stream, face, 0, num_params, params );
       
   541         if ( error )
       
   542           goto Exit;
       
   543       }
       
   544       else
       
   545       {
       
   546         /* load the `cmap' table explicitly */
       
   547         error = sfnt->load_cmap( face, stream );
       
   548         if ( error )
       
   549           goto Exit;
       
   550 
       
   551         /* XXX: we don't load the GPOS table, as OpenType Layout     */
       
   552         /* support will be added later to a layout library on top of */
       
   553         /* FreeType 2                                                */
       
   554       }
       
   555 
       
   556       /* now load the CFF part of the file */
       
   557       error = face->goto_table( face, TTAG_CFF, stream, 0 );
       
   558       if ( error )
       
   559         goto Exit;
       
   560     }
       
   561     else
       
   562     {
       
   563       /* rewind to start of file; we are going to load a pure-CFF font */
       
   564       if ( FT_STREAM_SEEK( 0 ) )
       
   565         goto Exit;
       
   566       error = CFF_Err_Ok;
       
   567     }
       
   568 
       
   569     /* now load and parse the CFF table in the file */
       
   570     {
       
   571       CFF_Font         cff;
       
   572       CFF_FontRecDict  dict;
       
   573       FT_Memory        memory = cffface->memory;
       
   574       FT_Int32         flags;
       
   575       FT_UInt          i;
       
   576 
       
   577 
       
   578       if ( FT_NEW( cff ) )
       
   579         goto Exit;
       
   580 
       
   581       face->extra.data = cff;
       
   582       error = cff_font_load( library, stream, face_index, cff, pure_cff );
       
   583       if ( error )
       
   584         goto Exit;
       
   585 
       
   586       cff->pshinter = pshinter;
       
   587       cff->psnames  = psnames;
       
   588 
       
   589       cffface->face_index = face_index;
       
   590 
       
   591       /* Complement the root flags with some interesting information. */
       
   592       /* Note that this is only necessary for pure CFF and CEF fonts; */
       
   593       /* SFNT based fonts use the `name' table instead.               */
       
   594 
       
   595       cffface->num_glyphs = cff->num_glyphs;
       
   596 
       
   597       dict = &cff->top_font.font_dict;
       
   598 
       
   599       /* we need the `PSNames' module for CFF and CEF formats */
       
   600       /* which aren't CID-keyed                               */
       
   601       if ( dict->cid_registry == 0xFFFFU && !psnames )
       
   602       {
       
   603         FT_ERROR(( "cff_face_init:"
       
   604                    " cannot open CFF & CEF fonts\n"
       
   605                    "              "
       
   606                    " without the `PSNames' module\n" ));
       
   607         goto Bad_Format;
       
   608       }
       
   609 
       
   610       if ( !dict->units_per_em )
       
   611         dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
       
   612 
       
   613       /* Normalize the font matrix so that `matrix->xx' is 1; the */
       
   614       /* scaling is done with `units_per_em' then (at this point, */
       
   615       /* it already contains the scaling factor, but without      */
       
   616       /* normalization of the matrix).                            */
       
   617       /*                                                          */
       
   618       /* Note that the offsets must be expressed in integer font  */
       
   619       /* units.                                                   */
       
   620 
       
   621       {
       
   622         FT_Matrix*  matrix = &dict->font_matrix;
       
   623         FT_Vector*  offset = &dict->font_offset;
       
   624         FT_ULong*   upm    = &dict->units_per_em;
       
   625         FT_Fixed    temp   = FT_ABS( matrix->yy );
       
   626 
       
   627 
       
   628         if ( temp != 0x10000L )
       
   629         {
       
   630           *upm = FT_DivFix( *upm, temp );
       
   631 
       
   632           matrix->xx = FT_DivFix( matrix->xx, temp );
       
   633           matrix->yx = FT_DivFix( matrix->yx, temp );
       
   634           matrix->xy = FT_DivFix( matrix->xy, temp );
       
   635           matrix->yy = FT_DivFix( matrix->yy, temp );
       
   636           offset->x  = FT_DivFix( offset->x,  temp );
       
   637           offset->y  = FT_DivFix( offset->y,  temp );
       
   638         }
       
   639 
       
   640         offset->x >>= 16;
       
   641         offset->y >>= 16;
       
   642       }
       
   643 
       
   644       for ( i = cff->num_subfonts; i > 0; i-- )
       
   645       {
       
   646         CFF_FontRecDict  sub = &cff->subfonts[i - 1]->font_dict;
       
   647         CFF_FontRecDict  top = &cff->top_font.font_dict;
       
   648 
       
   649         FT_Matrix*  matrix;
       
   650         FT_Vector*  offset;
       
   651         FT_ULong*   upm;
       
   652         FT_Fixed    temp;
       
   653 
       
   654 
       
   655         if ( sub->units_per_em )
       
   656         {
       
   657           FT_Long  scaling;
       
   658 
       
   659 
       
   660           if ( top->units_per_em > 1 && sub->units_per_em > 1 )
       
   661             scaling = FT_MIN( top->units_per_em, sub->units_per_em );
       
   662           else
       
   663             scaling = 1;
       
   664 
       
   665           FT_Matrix_Multiply_Scaled( &top->font_matrix,
       
   666                                      &sub->font_matrix,
       
   667                                      scaling );
       
   668           FT_Vector_Transform_Scaled( &sub->font_offset,
       
   669                                       &top->font_matrix,
       
   670                                       scaling );
       
   671 
       
   672           sub->units_per_em = FT_MulDiv( sub->units_per_em,
       
   673                                          top->units_per_em,
       
   674                                          scaling );
       
   675         }
       
   676         else
       
   677         {
       
   678           sub->font_matrix = top->font_matrix;
       
   679           sub->font_offset = top->font_offset;
       
   680 
       
   681           sub->units_per_em = top->units_per_em;
       
   682         }
       
   683 
       
   684         matrix = &sub->font_matrix;
       
   685         offset = &sub->font_offset;
       
   686         upm    = &sub->units_per_em;
       
   687         temp   = FT_ABS( matrix->yy );
       
   688 
       
   689         if ( temp != 0x10000L )
       
   690         {
       
   691           *upm = FT_DivFix( *upm, temp );
       
   692 
       
   693           /* if *upm is larger than 100*1000 we divide by 1000 --     */
       
   694           /* this can happen if e.g. there is no top-font FontMatrix  */
       
   695           /* and the subfont FontMatrix already contains the complete */
       
   696           /* scaling for the subfont (see section 5.11 of the PLRM)   */
       
   697 
       
   698           /* 100 is a heuristic value */
       
   699 
       
   700           if ( *upm > 100L * 1000L )
       
   701             *upm = ( *upm + 500 ) / 1000;
       
   702 
       
   703           matrix->xx = FT_DivFix( matrix->xx, temp );
       
   704           matrix->yx = FT_DivFix( matrix->yx, temp );
       
   705           matrix->xy = FT_DivFix( matrix->xy, temp );
       
   706           matrix->yy = FT_DivFix( matrix->yy, temp );
       
   707           offset->x  = FT_DivFix( offset->x,  temp );
       
   708           offset->y  = FT_DivFix( offset->y,  temp );
       
   709         }
       
   710 
       
   711         offset->x >>= 16;
       
   712         offset->y >>= 16;
       
   713       }
       
   714 
       
   715       if ( pure_cff )
       
   716       {
       
   717         char*  style_name = NULL;
       
   718 
       
   719 
       
   720         /* set up num_faces */
       
   721         cffface->num_faces = cff->num_faces;
       
   722 
       
   723         /* compute number of glyphs */
       
   724         if ( dict->cid_registry != 0xFFFFU )
       
   725           cffface->num_glyphs = cff->charset.max_cid + 1;
       
   726         else
       
   727           cffface->num_glyphs = cff->charstrings_index.count;
       
   728 
       
   729         /* set global bbox, as well as EM size */
       
   730         cffface->bbox.xMin =   dict->font_bbox.xMin            >> 16;
       
   731         cffface->bbox.yMin =   dict->font_bbox.yMin            >> 16;
       
   732         /* no `U' suffix here to 0xFFFF! */
       
   733         cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16;
       
   734         cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16;
       
   735 
       
   736         cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
       
   737 
       
   738         cffface->ascender  = (FT_Short)( cffface->bbox.yMax );
       
   739         cffface->descender = (FT_Short)( cffface->bbox.yMin );
       
   740 
       
   741         cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
       
   742         if ( cffface->height < cffface->ascender - cffface->descender )
       
   743           cffface->height = (FT_Short)( cffface->ascender - cffface->descender );
       
   744 
       
   745         cffface->underline_position  =
       
   746           (FT_Short)( dict->underline_position >> 16 );
       
   747         cffface->underline_thickness =
       
   748           (FT_Short)( dict->underline_thickness >> 16 );
       
   749 
       
   750         /* retrieve font family & style name */
       
   751         cffface->family_name = cff_index_get_name( cff, face_index );
       
   752         if ( cffface->family_name )
       
   753         {
       
   754           char*  full   = cff_index_get_sid_string( cff,
       
   755                                                     dict->full_name );
       
   756           char*  fullp  = full;
       
   757           char*  family = cffface->family_name;
       
   758           char*  family_name = NULL;
       
   759 
       
   760 
       
   761           remove_subset_prefix( cffface->family_name ); 
       
   762 
       
   763           if ( dict->family_name )
       
   764           {
       
   765             family_name = cff_index_get_sid_string( cff,
       
   766                                                     dict->family_name );
       
   767             if ( family_name )
       
   768               family = family_name;
       
   769           }
       
   770 
       
   771           /* We try to extract the style name from the full name.   */
       
   772           /* We need to ignore spaces and dashes during the search. */
       
   773           if ( full && family )
       
   774           {
       
   775             while ( *fullp )
       
   776             {
       
   777               /* skip common characters at the start of both strings */
       
   778               if ( *fullp == *family )
       
   779               {
       
   780                 family++;
       
   781                 fullp++;
       
   782                 continue;
       
   783               }
       
   784 
       
   785               /* ignore spaces and dashes in full name during comparison */
       
   786               if ( *fullp == ' ' || *fullp == '-' )
       
   787               {
       
   788                 fullp++;
       
   789                 continue;
       
   790               }
       
   791 
       
   792               /* ignore spaces and dashes in family name during comparison */
       
   793               if ( *family == ' ' || *family == '-' )
       
   794               {
       
   795                 family++;
       
   796                 continue;
       
   797               }
       
   798 
       
   799               if ( !*family && *fullp )
       
   800               {
       
   801                 /* The full name begins with the same characters as the  */
       
   802                 /* family name, with spaces and dashes removed.  In this */
       
   803                 /* case, the remaining string in `fullp' will be used as */
       
   804                 /* the style name.                                       */
       
   805                 style_name = cff_strcpy( memory, fullp );
       
   806 
       
   807                 /* remove the style part from the family name (if present) */
       
   808                 remove_style( cffface->family_name, style_name ); 
       
   809               }
       
   810               break;
       
   811             }
       
   812           }
       
   813         }
       
   814         else
       
   815         {
       
   816           char  *cid_font_name =
       
   817                    cff_index_get_sid_string( cff,
       
   818                                              dict->cid_font_name );
       
   819 
       
   820 
       
   821           /* do we have a `/FontName' for a CID-keyed font? */
       
   822           if ( cid_font_name )
       
   823             cffface->family_name = cff_strcpy( memory, cid_font_name );
       
   824         }
       
   825 
       
   826         if ( style_name )
       
   827           cffface->style_name = style_name;
       
   828         else
       
   829           /* assume "Regular" style if we don't know better */
       
   830           cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
       
   831 
       
   832         /*******************************************************************/
       
   833         /*                                                                 */
       
   834         /* Compute face flags.                                             */
       
   835         /*                                                                 */
       
   836         flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE   | /* scalable outlines */
       
   837                              FT_FACE_FLAG_HORIZONTAL | /* horizontal data   */
       
   838                              FT_FACE_FLAG_HINTER );    /* has native hinter */
       
   839 
       
   840         if ( sfnt_format )
       
   841           flags |= (FT_UInt32)FT_FACE_FLAG_SFNT;
       
   842 
       
   843         /* fixed width font? */
       
   844         if ( dict->is_fixed_pitch )
       
   845           flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH;
       
   846 
       
   847   /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
       
   848 #if 0
       
   849         /* kerning available? */
       
   850         if ( face->kern_pairs )
       
   851           flags |= (FT_UInt32)FT_FACE_FLAG_KERNING;
       
   852 #endif
       
   853 
       
   854         cffface->face_flags = flags;
       
   855 
       
   856         /*******************************************************************/
       
   857         /*                                                                 */
       
   858         /* Compute style flags.                                            */
       
   859         /*                                                                 */
       
   860         flags = 0;
       
   861 
       
   862         if ( dict->italic_angle )
       
   863           flags |= FT_STYLE_FLAG_ITALIC;
       
   864 
       
   865         {
       
   866           char  *weight = cff_index_get_sid_string( cff,
       
   867                                                     dict->weight );
       
   868 
       
   869 
       
   870           if ( weight )
       
   871             if ( !ft_strcmp( weight, "Bold"  ) ||
       
   872                  !ft_strcmp( weight, "Black" ) )
       
   873               flags |= FT_STYLE_FLAG_BOLD;
       
   874         }
       
   875 
       
   876         /* double check */
       
   877         if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
       
   878           if ( !ft_strncmp( cffface->style_name, "Bold", 4 )  ||
       
   879                !ft_strncmp( cffface->style_name, "Black", 5 ) )
       
   880             flags |= FT_STYLE_FLAG_BOLD;
       
   881 
       
   882         cffface->style_flags = flags;
       
   883       }
       
   884 
       
   885 
       
   886 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
       
   887       /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
       
   888       /* has unset this flag because of the 3.0 `post' table.          */
       
   889       if ( dict->cid_registry == 0xFFFFU )
       
   890         cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
       
   891 #endif
       
   892 
       
   893       if ( dict->cid_registry != 0xFFFFU && pure_cff )
       
   894         cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
       
   895 
       
   896 
       
   897       /*******************************************************************/
       
   898       /*                                                                 */
       
   899       /* Compute char maps.                                              */
       
   900       /*                                                                 */
       
   901 
       
   902       /* Try to synthesize a Unicode charmap if there is none available */
       
   903       /* already.  If an OpenType font contains a Unicode "cmap", we    */
       
   904       /* will use it, whatever be in the CFF part of the file.          */
       
   905       {
       
   906         FT_CharMapRec  cmaprec;
       
   907         FT_CharMap     cmap;
       
   908         FT_UInt        nn;
       
   909         CFF_Encoding   encoding = &cff->encoding;
       
   910 
       
   911 
       
   912         for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
       
   913         {
       
   914           cmap = cffface->charmaps[nn];
       
   915 
       
   916           /* Windows Unicode? */
       
   917           if ( cmap->platform_id == TT_PLATFORM_MICROSOFT &&
       
   918                cmap->encoding_id == TT_MS_ID_UNICODE_CS   )
       
   919             goto Skip_Unicode;
       
   920 
       
   921           /* Apple Unicode platform id? */
       
   922           if ( cmap->platform_id == TT_PLATFORM_APPLE_UNICODE )
       
   923             goto Skip_Unicode; /* Apple Unicode */
       
   924         }
       
   925 
       
   926         /* since CID-keyed fonts don't contain glyph names, we can't */
       
   927         /* construct a cmap                                          */
       
   928         if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
       
   929           goto Exit;
       
   930 
       
   931 #ifdef FT_MAX_CHARMAP_CACHEABLE
       
   932         if ( nn + 1 > FT_MAX_CHARMAP_CACHEABLE )
       
   933         {
       
   934           FT_ERROR(( "cff_face_init: no Unicode cmap is found, "
       
   935                      "and too many subtables (%d) to add synthesized cmap\n",
       
   936                      nn ));
       
   937           goto Exit;
       
   938         }
       
   939 #endif
       
   940 
       
   941         /* we didn't find a Unicode charmap -- synthesize one */
       
   942         cmaprec.face        = cffface;
       
   943         cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
       
   944         cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
       
   945         cmaprec.encoding    = FT_ENCODING_UNICODE;
       
   946 
       
   947         nn = (FT_UInt)cffface->num_charmaps;
       
   948 
       
   949         error = FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL,
       
   950                              &cmaprec, NULL );
       
   951         if ( error && FT_Err_No_Unicode_Glyph_Name != error )
       
   952           goto Exit;
       
   953         error = FT_Err_Ok;
       
   954 
       
   955         /* if no Unicode charmap was previously selected, select this one */
       
   956         if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
       
   957           cffface->charmap = cffface->charmaps[nn];
       
   958 
       
   959       Skip_Unicode:
       
   960 #ifdef FT_MAX_CHARMAP_CACHEABLE
       
   961         if ( nn > FT_MAX_CHARMAP_CACHEABLE )
       
   962         {
       
   963           FT_ERROR(( "cff_face_init: Unicode cmap is found, "
       
   964                      "but too many preceding subtables (%d) to access\n",
       
   965                      nn - 1 ));
       
   966           goto Exit;
       
   967         }
       
   968 #endif
       
   969         if ( encoding->count > 0 )
       
   970         {
       
   971           FT_CMap_Class  clazz;
       
   972 
       
   973 
       
   974           cmaprec.face        = cffface;
       
   975           cmaprec.platform_id = TT_PLATFORM_ADOBE;  /* Adobe platform id */
       
   976 
       
   977           if ( encoding->offset == 0 )
       
   978           {
       
   979             cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
       
   980             cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;
       
   981             clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
       
   982           }
       
   983           else if ( encoding->offset == 1 )
       
   984           {
       
   985             cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
       
   986             cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;
       
   987             clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
       
   988           }
       
   989           else
       
   990           {
       
   991             cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
       
   992             cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;
       
   993             clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
       
   994           }
       
   995 
       
   996           error = FT_CMap_New( clazz, NULL, &cmaprec, NULL );
       
   997         }
       
   998       }
       
   999     }
       
  1000 
       
  1001   Exit:
       
  1002     return error;
       
  1003 
       
  1004   Bad_Format:
       
  1005     error = CFF_Err_Unknown_File_Format;
       
  1006     goto Exit;
       
  1007   }
       
  1008 
       
  1009 
       
  1010   FT_LOCAL_DEF( void )
       
  1011   cff_face_done( FT_Face  cffface )         /* CFF_Face */
       
  1012   {
       
  1013     CFF_Face      face = (CFF_Face)cffface;
       
  1014     FT_Memory     memory;
       
  1015     SFNT_Service  sfnt;
       
  1016 
       
  1017 
       
  1018     if ( !face )
       
  1019       return;
       
  1020 
       
  1021     memory = cffface->memory;
       
  1022     sfnt   = (SFNT_Service)face->sfnt;
       
  1023 
       
  1024     if ( sfnt )
       
  1025       sfnt->done_face( face );
       
  1026 
       
  1027     {
       
  1028       CFF_Font  cff = (CFF_Font)face->extra.data;
       
  1029 
       
  1030 
       
  1031       if ( cff )
       
  1032       {
       
  1033         cff_font_done( cff );
       
  1034         FT_FREE( face->extra.data );
       
  1035       }
       
  1036     }
       
  1037   }
       
  1038 
       
  1039 
       
  1040   FT_LOCAL_DEF( FT_Error )
       
  1041   cff_driver_init( FT_Module  module )
       
  1042   {
       
  1043     FT_UNUSED( module );
       
  1044 
       
  1045     return CFF_Err_Ok;
       
  1046   }
       
  1047 
       
  1048 
       
  1049   FT_LOCAL_DEF( void )
       
  1050   cff_driver_done( FT_Module  module )
       
  1051   {
       
  1052     FT_UNUSED( module );
       
  1053   }
       
  1054 
       
  1055 
       
  1056 /* END */