Home | History | Annotate | Download | only in cff
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  cffdrivr.c                                                             */
      4 /*                                                                         */
      5 /*    OpenType font driver implementation (body).                          */
      6 /*                                                                         */
      7 /*  Copyright 1996-2012 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_FREETYPE_H
     21 #include FT_INTERNAL_DEBUG_H
     22 #include FT_INTERNAL_STREAM_H
     23 #include FT_INTERNAL_SFNT_H
     24 #include FT_SERVICE_CID_H
     25 #include FT_SERVICE_POSTSCRIPT_INFO_H
     26 #include FT_SERVICE_POSTSCRIPT_NAME_H
     27 #include FT_SERVICE_TT_CMAP_H
     28 
     29 #include "cffdrivr.h"
     30 #include "cffgload.h"
     31 #include "cffload.h"
     32 #include "cffcmap.h"
     33 #include "cffparse.h"
     34 
     35 #include "cfferrs.h"
     36 #include "cffpic.h"
     37 
     38 #include FT_SERVICE_XFREE86_NAME_H
     39 #include FT_SERVICE_GLYPH_DICT_H
     40 
     41 
     42   /*************************************************************************/
     43   /*                                                                       */
     44   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     45   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     46   /* messages during execution.                                            */
     47   /*                                                                       */
     48 #undef  FT_COMPONENT
     49 #define FT_COMPONENT  trace_cffdriver
     50 
     51 
     52   /*************************************************************************/
     53   /*************************************************************************/
     54   /*************************************************************************/
     55   /****                                                                 ****/
     56   /****                                                                 ****/
     57   /****                          F A C E S                              ****/
     58   /****                                                                 ****/
     59   /****                                                                 ****/
     60   /*************************************************************************/
     61   /*************************************************************************/
     62   /*************************************************************************/
     63 
     64 
     65 #undef  PAIR_TAG
     66 #define PAIR_TAG( left, right )  ( ( (FT_ULong)left << 16 ) | \
     67                                      (FT_ULong)right        )
     68 
     69 
     70   /*************************************************************************/
     71   /*                                                                       */
     72   /* <Function>                                                            */
     73   /*    cff_get_kerning                                                    */
     74   /*                                                                       */
     75   /* <Description>                                                         */
     76   /*    A driver method used to return the kerning vector between two      */
     77   /*    glyphs of the same face.                                           */
     78   /*                                                                       */
     79   /* <Input>                                                               */
     80   /*    face        :: A handle to the source face object.                 */
     81   /*                                                                       */
     82   /*    left_glyph  :: The index of the left glyph in the kern pair.       */
     83   /*                                                                       */
     84   /*    right_glyph :: The index of the right glyph in the kern pair.      */
     85   /*                                                                       */
     86   /* <Output>                                                              */
     87   /*    kerning     :: The kerning vector.  This is in font units for      */
     88   /*                   scalable formats, and in pixels for fixed-sizes     */
     89   /*                   formats.                                            */
     90   /*                                                                       */
     91   /* <Return>                                                              */
     92   /*    FreeType error code.  0 means success.                             */
     93   /*                                                                       */
     94   /* <Note>                                                                */
     95   /*    Only horizontal layouts (left-to-right & right-to-left) are        */
     96   /*    supported by this function.  Other layouts, or more sophisticated  */
     97   /*    kernings, are out of scope of this method (the basic driver        */
     98   /*    interface is meant to be simple).                                  */
     99   /*                                                                       */
    100   /*    They can be implemented by format-specific interfaces.             */
    101   /*                                                                       */
    102   FT_CALLBACK_DEF( FT_Error )
    103   cff_get_kerning( FT_Face     ttface,          /* TT_Face */
    104                    FT_UInt     left_glyph,
    105                    FT_UInt     right_glyph,
    106                    FT_Vector*  kerning )
    107   {
    108     TT_Face       face = (TT_Face)ttface;
    109     SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
    110 
    111 
    112     kerning->x = 0;
    113     kerning->y = 0;
    114 
    115     if ( sfnt )
    116       kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
    117 
    118     return CFF_Err_Ok;
    119   }
    120 
    121 
    122 #undef PAIR_TAG
    123 
    124 
    125   /*************************************************************************/
    126   /*                                                                       */
    127   /* <Function>                                                            */
    128   /*    cff_glyph_load                                                     */
    129   /*                                                                       */
    130   /* <Description>                                                         */
    131   /*    A driver method used to load a glyph within a given glyph slot.    */
    132   /*                                                                       */
    133   /* <Input>                                                               */
    134   /*    slot        :: A handle to the target slot object where the glyph  */
    135   /*                   will be loaded.                                     */
    136   /*                                                                       */
    137   /*    size        :: A handle to the source face size at which the glyph */
    138   /*                   must be scaled, loaded, etc.                        */
    139   /*                                                                       */
    140   /*    glyph_index :: The index of the glyph in the font file.            */
    141   /*                                                                       */
    142   /*    load_flags  :: A flag indicating what to load for this glyph.  The */
    143   /*                   FT_LOAD_??? constants can be used to control the    */
    144   /*                   glyph loading process (e.g., whether the outline    */
    145   /*                   should be scaled, whether to load bitmaps or not,   */
    146   /*                   whether to hint the outline, etc).                  */
    147   /*                                                                       */
    148   /* <Return>                                                              */
    149   /*    FreeType error code.  0 means success.                             */
    150   /*                                                                       */
    151   FT_CALLBACK_DEF( FT_Error )
    152   cff_glyph_load( FT_GlyphSlot  cffslot,      /* CFF_GlyphSlot */
    153                   FT_Size       cffsize,      /* CFF_Size      */
    154                   FT_UInt       glyph_index,
    155                   FT_Int32      load_flags )
    156   {
    157     FT_Error       error;
    158     CFF_GlyphSlot  slot = (CFF_GlyphSlot)cffslot;
    159     CFF_Size       size = (CFF_Size)cffsize;
    160 
    161 
    162     if ( !slot )
    163       return CFF_Err_Invalid_Slot_Handle;
    164 
    165     /* check whether we want a scaled outline or bitmap */
    166     if ( !size )
    167       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
    168 
    169     /* reset the size object if necessary */
    170     if ( load_flags & FT_LOAD_NO_SCALE )
    171       size = NULL;
    172 
    173     if ( size )
    174     {
    175       /* these two objects must have the same parent */
    176       if ( cffsize->face != cffslot->face )
    177         return CFF_Err_Invalid_Face_Handle;
    178     }
    179 
    180     /* now load the glyph outline if necessary */
    181     error = cff_slot_load( slot, size, glyph_index, load_flags );
    182 
    183     /* force drop-out mode to 2 - irrelevant now */
    184     /* slot->outline.dropout_mode = 2; */
    185 
    186     return error;
    187   }
    188 
    189 
    190   FT_CALLBACK_DEF( FT_Error )
    191   cff_get_advances( FT_Face    face,
    192                     FT_UInt    start,
    193                     FT_UInt    count,
    194                     FT_Int32   flags,
    195                     FT_Fixed*  advances )
    196   {
    197     FT_UInt       nn;
    198     FT_Error      error = CFF_Err_Ok;
    199     FT_GlyphSlot  slot  = face->glyph;
    200 
    201 
    202     flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
    203 
    204     for ( nn = 0; nn < count; nn++ )
    205     {
    206       error = cff_glyph_load( slot, face->size, start + nn, flags );
    207       if ( error )
    208         break;
    209 
    210       advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
    211                      ? slot->linearVertAdvance
    212                      : slot->linearHoriAdvance;
    213     }
    214 
    215     return error;
    216   }
    217 
    218 
    219   /*
    220    *  GLYPH DICT SERVICE
    221    *
    222    */
    223 
    224   static FT_Error
    225   cff_get_glyph_name( CFF_Face    face,
    226                       FT_UInt     glyph_index,
    227                       FT_Pointer  buffer,
    228                       FT_UInt     buffer_max )
    229   {
    230     CFF_Font    font   = (CFF_Font)face->extra.data;
    231     FT_String*  gname;
    232     FT_UShort   sid;
    233     FT_Error    error;
    234 
    235 
    236     if ( !font->psnames )
    237     {
    238       FT_ERROR(( "cff_get_glyph_name:"
    239                  " cannot get glyph name from CFF & CEF fonts\n"
    240                  "                   "
    241                  " without the `PSNames' module\n" ));
    242       error = CFF_Err_Missing_Module;
    243       goto Exit;
    244     }
    245 
    246     /* first, locate the sid in the charset table */
    247     sid = font->charset.sids[glyph_index];
    248 
    249     /* now, lookup the name itself */
    250     gname = cff_index_get_sid_string( font, sid );
    251 
    252     if ( gname )
    253       FT_STRCPYN( buffer, gname, buffer_max );
    254 
    255     error = CFF_Err_Ok;
    256 
    257   Exit:
    258     return error;
    259   }
    260 
    261 
    262   static FT_UInt
    263   cff_get_name_index( CFF_Face    face,
    264                       FT_String*  glyph_name )
    265   {
    266     CFF_Font            cff;
    267     CFF_Charset         charset;
    268     FT_Service_PsCMaps  psnames;
    269     FT_String*          name;
    270     FT_UShort           sid;
    271     FT_UInt             i;
    272 
    273 
    274     cff     = (CFF_FontRec *)face->extra.data;
    275     charset = &cff->charset;
    276 
    277     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
    278     if ( !psnames )
    279       return 0;
    280 
    281     for ( i = 0; i < cff->num_glyphs; i++ )
    282     {
    283       sid = charset->sids[i];
    284 
    285       if ( sid > 390 )
    286         name = cff_index_get_string( cff, sid - 391 );
    287       else
    288         name = (FT_String *)psnames->adobe_std_strings( sid );
    289 
    290       if ( !name )
    291         continue;
    292 
    293       if ( !ft_strcmp( glyph_name, name ) )
    294         return i;
    295     }
    296 
    297     return 0;
    298   }
    299 
    300 
    301   FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict,
    302     (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,
    303     (FT_GlyphDict_NameIndexFunc)cff_get_name_index
    304   )
    305 
    306 
    307   /*
    308    *  POSTSCRIPT INFO SERVICE
    309    *
    310    */
    311 
    312   static FT_Int
    313   cff_ps_has_glyph_names( FT_Face  face )
    314   {
    315     return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
    316   }
    317 
    318 
    319   static FT_Error
    320   cff_ps_get_font_info( CFF_Face         face,
    321                         PS_FontInfoRec*  afont_info )
    322   {
    323     CFF_Font  cff   = (CFF_Font)face->extra.data;
    324     FT_Error  error = CFF_Err_Ok;
    325 
    326 
    327     if ( cff && cff->font_info == NULL )
    328     {
    329       CFF_FontRecDict  dict   = &cff->top_font.font_dict;
    330       PS_FontInfoRec  *font_info = NULL;
    331       FT_Memory        memory = face->root.memory;
    332 
    333 
    334       if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
    335         goto Fail;
    336 
    337       font_info->version     = cff_index_get_sid_string( cff,
    338                                                          dict->version );
    339       font_info->notice      = cff_index_get_sid_string( cff,
    340                                                          dict->notice );
    341       font_info->full_name   = cff_index_get_sid_string( cff,
    342                                                          dict->full_name );
    343       font_info->family_name = cff_index_get_sid_string( cff,
    344                                                          dict->family_name );
    345       font_info->weight      = cff_index_get_sid_string( cff,
    346                                                          dict->weight );
    347       font_info->italic_angle        = dict->italic_angle;
    348       font_info->is_fixed_pitch      = dict->is_fixed_pitch;
    349       font_info->underline_position  = (FT_Short)dict->underline_position;
    350       font_info->underline_thickness = (FT_Short)dict->underline_thickness;
    351 
    352       cff->font_info = font_info;
    353     }
    354 
    355     if ( cff )
    356       *afont_info = *cff->font_info;
    357 
    358   Fail:
    359     return error;
    360   }
    361 
    362 
    363   FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info,
    364     (PS_GetFontInfoFunc)   cff_ps_get_font_info,
    365     (PS_GetFontExtraFunc)  NULL,
    366     (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
    367     (PS_GetFontPrivateFunc)NULL,        /* unsupported with CFF fonts */
    368     (PS_GetFontValueFunc)  NULL         /* not implemented            */
    369   )
    370 
    371 
    372   /*
    373    *  POSTSCRIPT NAME SERVICE
    374    *
    375    */
    376 
    377   static const char*
    378   cff_get_ps_name( CFF_Face  face )
    379   {
    380     CFF_Font  cff = (CFF_Font)face->extra.data;
    381 
    382 
    383     return (const char*)cff->font_name;
    384   }
    385 
    386 
    387   FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name,
    388     (FT_PsName_GetFunc)cff_get_ps_name
    389   )
    390 
    391 
    392   /*
    393    * TT CMAP INFO
    394    *
    395    * If the charmap is a synthetic Unicode encoding cmap or
    396    * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO
    397    * service defined in SFNT module.
    398    *
    399    * Otherwise call the service function in the sfnt module.
    400    *
    401    */
    402   static FT_Error
    403   cff_get_cmap_info( FT_CharMap    charmap,
    404                      TT_CMapInfo  *cmap_info )
    405   {
    406     FT_CMap   cmap  = FT_CMAP( charmap );
    407     FT_Error  error = CFF_Err_Ok;
    408     FT_Face    face    = FT_CMAP_FACE( cmap );
    409     FT_Library library = FT_FACE_LIBRARY( face );
    410 
    411 
    412     cmap_info->language = 0;
    413     cmap_info->format   = 0;
    414 
    415     if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET &&
    416          cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET  )
    417     {
    418       FT_Module           sfnt    = FT_Get_Module( library, "sfnt" );
    419       FT_Service_TTCMaps  service =
    420         (FT_Service_TTCMaps)ft_module_get_service( sfnt,
    421                                                    FT_SERVICE_ID_TT_CMAP );
    422 
    423 
    424       if ( service && service->get_cmap_info )
    425         error = service->get_cmap_info( charmap, cmap_info );
    426     }
    427 
    428     return error;
    429   }
    430 
    431 
    432   FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info,
    433     (TT_CMap_Info_GetFunc)cff_get_cmap_info
    434   )
    435 
    436 
    437   /*
    438    *  CID INFO SERVICE
    439    *
    440    */
    441   static FT_Error
    442   cff_get_ros( CFF_Face      face,
    443                const char*  *registry,
    444                const char*  *ordering,
    445                FT_Int       *supplement )
    446   {
    447     FT_Error  error = CFF_Err_Ok;
    448     CFF_Font  cff   = (CFF_Font)face->extra.data;
    449 
    450 
    451     if ( cff )
    452     {
    453       CFF_FontRecDict  dict = &cff->top_font.font_dict;
    454 
    455 
    456       if ( dict->cid_registry == 0xFFFFU )
    457       {
    458         error = CFF_Err_Invalid_Argument;
    459         goto Fail;
    460       }
    461 
    462       if ( registry )
    463       {
    464         if ( cff->registry == NULL )
    465           cff->registry = cff_index_get_sid_string( cff,
    466                                                     dict->cid_registry );
    467         *registry = cff->registry;
    468       }
    469 
    470       if ( ordering )
    471       {
    472         if ( cff->ordering == NULL )
    473           cff->ordering = cff_index_get_sid_string( cff,
    474                                                     dict->cid_ordering );
    475         *ordering = cff->ordering;
    476       }
    477 
    478       /*
    479        * XXX: According to Adobe TechNote #5176, the supplement in CFF
    480        *      can be a real number. We truncate it to fit public API
    481        *      since freetype-2.3.6.
    482        */
    483       if ( supplement )
    484       {
    485         if ( dict->cid_supplement < FT_INT_MIN ||
    486              dict->cid_supplement > FT_INT_MAX )
    487           FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
    488                       dict->cid_supplement ));
    489         *supplement = (FT_Int)dict->cid_supplement;
    490       }
    491     }
    492 
    493   Fail:
    494     return error;
    495   }
    496 
    497 
    498   static FT_Error
    499   cff_get_is_cid( CFF_Face  face,
    500                   FT_Bool  *is_cid )
    501   {
    502     FT_Error  error = CFF_Err_Ok;
    503     CFF_Font  cff   = (CFF_Font)face->extra.data;
    504 
    505 
    506     *is_cid = 0;
    507 
    508     if ( cff )
    509     {
    510       CFF_FontRecDict  dict = &cff->top_font.font_dict;
    511 
    512 
    513       if ( dict->cid_registry != 0xFFFFU )
    514         *is_cid = 1;
    515     }
    516 
    517     return error;
    518   }
    519 
    520 
    521   static FT_Error
    522   cff_get_cid_from_glyph_index( CFF_Face  face,
    523                                 FT_UInt   glyph_index,
    524                                 FT_UInt  *cid )
    525   {
    526     FT_Error  error = CFF_Err_Ok;
    527     CFF_Font  cff;
    528 
    529 
    530     cff = (CFF_Font)face->extra.data;
    531 
    532     if ( cff )
    533     {
    534       FT_UInt          c;
    535       CFF_FontRecDict  dict = &cff->top_font.font_dict;
    536 
    537 
    538       if ( dict->cid_registry == 0xFFFFU )
    539       {
    540         error = CFF_Err_Invalid_Argument;
    541         goto Fail;
    542       }
    543 
    544       if ( glyph_index > cff->num_glyphs )
    545       {
    546         error = CFF_Err_Invalid_Argument;
    547         goto Fail;
    548       }
    549 
    550       c = cff->charset.sids[glyph_index];
    551 
    552       if ( cid )
    553         *cid = c;
    554     }
    555 
    556   Fail:
    557     return error;
    558   }
    559 
    560 
    561   FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info,
    562     (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,
    563     (FT_CID_GetIsInternallyCIDKeyedFunc)      cff_get_is_cid,
    564     (FT_CID_GetCIDFromGlyphIndexFunc)         cff_get_cid_from_glyph_index
    565   )
    566 
    567 
    568   /*************************************************************************/
    569   /*************************************************************************/
    570   /*************************************************************************/
    571   /****                                                                 ****/
    572   /****                                                                 ****/
    573   /****                D R I V E R  I N T E R F A C E                   ****/
    574   /****                                                                 ****/
    575   /****                                                                 ****/
    576   /*************************************************************************/
    577   /*************************************************************************/
    578   /*************************************************************************/
    579 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
    580   FT_DEFINE_SERVICEDESCREC6(cff_services,
    581     FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
    582     FT_SERVICE_ID_POSTSCRIPT_INFO,      &FT_CFF_SERVICE_PS_INFO_GET,
    583     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
    584     FT_SERVICE_ID_GLYPH_DICT,           &FT_CFF_SERVICE_GLYPH_DICT_GET,
    585     FT_SERVICE_ID_TT_CMAP,              &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
    586     FT_SERVICE_ID_CID,                  &FT_CFF_SERVICE_CID_INFO_GET
    587   )
    588 #else
    589   FT_DEFINE_SERVICEDESCREC5(cff_services,
    590     FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
    591     FT_SERVICE_ID_POSTSCRIPT_INFO,      &FT_CFF_SERVICE_PS_INFO_GET,
    592     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
    593     FT_SERVICE_ID_TT_CMAP,              &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
    594     FT_SERVICE_ID_CID,                  &FT_CFF_SERVICE_CID_INFO_GET
    595   )
    596 #endif
    597 
    598   FT_CALLBACK_DEF( FT_Module_Interface )
    599   cff_get_interface( FT_Module    driver,       /* CFF_Driver */
    600                      const char*  module_interface )
    601   {
    602     FT_Library           library;
    603     FT_Module            sfnt;
    604     FT_Module_Interface  result;
    605 
    606 
    607     /* FT_CFF_SERVICES_GET derefers `library' in PIC mode */
    608 #ifdef FT_CONFIG_OPTION_PIC
    609     if ( !driver )
    610       return NULL;
    611     library = driver->library;
    612     if ( !library )
    613       return NULL;
    614 #endif
    615 
    616     result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface );
    617     if ( result != NULL )
    618       return result;
    619 
    620     /* `driver' is not yet evaluated in non-PIC mode */
    621 #ifndef FT_CONFIG_OPTION_PIC
    622     if ( !driver )
    623       return NULL;
    624     library = driver->library;
    625     if ( !library )
    626       return NULL;
    627 #endif
    628 
    629     /* we pass our request to the `sfnt' module */
    630     sfnt = FT_Get_Module( library, "sfnt" );
    631 
    632     return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
    633   }
    634 
    635 
    636   /* The FT_DriverInterface structure is defined in ftdriver.h. */
    637 
    638 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
    639 #define CFF_SIZE_SELECT cff_size_select
    640 #else
    641 #define CFF_SIZE_SELECT 0
    642 #endif
    643 
    644   FT_DEFINE_DRIVER( cff_driver_class,
    645 
    646       FT_MODULE_FONT_DRIVER       |
    647       FT_MODULE_DRIVER_SCALABLE   |
    648       FT_MODULE_DRIVER_HAS_HINTER,
    649 
    650       sizeof ( CFF_DriverRec ),
    651       "cff",
    652       0x10000L,
    653       0x20000L,
    654 
    655       0,   /* module-specific interface */
    656 
    657       cff_driver_init,
    658       cff_driver_done,
    659       cff_get_interface,
    660 
    661     /* now the specific driver fields */
    662     sizeof ( TT_FaceRec ),
    663     sizeof ( CFF_SizeRec ),
    664     sizeof ( CFF_GlyphSlotRec ),
    665 
    666     cff_face_init,
    667     cff_face_done,
    668     cff_size_init,
    669     cff_size_done,
    670     cff_slot_init,
    671     cff_slot_done,
    672 
    673     ft_stub_set_char_sizes,  /* FT_CONFIG_OPTION_OLD_INTERNALS */
    674     ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
    675 
    676     cff_glyph_load,
    677 
    678     cff_get_kerning,
    679     0,                       /* FT_Face_AttachFunc */
    680     cff_get_advances,
    681 
    682     cff_size_request,
    683 
    684     CFF_SIZE_SELECT
    685   )
    686 
    687 
    688 /* END */
    689