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