misc/libfreetype/src/cff/cffdrivr.c
changeset 9372 915436ff64ab
parent 9371 f3840de881bd
child 9373 b769a8e38cbd
equal deleted inserted replaced
9371:f3840de881bd 9372:915436ff64ab
     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,   */
       
     8 /*            2010 by                                                      */
       
     9 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
       
    10 /*                                                                         */
       
    11 /*  This file is part of the FreeType project, and may only be used,       */
       
    12 /*  modified, and distributed under the terms of the FreeType project      */
       
    13 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
       
    14 /*  this file you indicate that you have read the license and              */
       
    15 /*  understand and accept it fully.                                        */
       
    16 /*                                                                         */
       
    17 /***************************************************************************/
       
    18 
       
    19 
       
    20 #include <ft2build.h>
       
    21 #include FT_FREETYPE_H
       
    22 #include FT_INTERNAL_DEBUG_H
       
    23 #include FT_INTERNAL_STREAM_H
       
    24 #include FT_INTERNAL_SFNT_H
       
    25 #include FT_SERVICE_CID_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_String*  gname;
       
   233     FT_UShort   sid;
       
   234     FT_Error    error;
       
   235 
       
   236 
       
   237     if ( !font->psnames )
       
   238     {
       
   239       FT_ERROR(( "cff_get_glyph_name:"
       
   240                  " cannot get glyph name from CFF & CEF fonts\n"
       
   241                  "                   "
       
   242                  " without the `PSNames' module\n" ));
       
   243       error = CFF_Err_Unknown_File_Format;
       
   244       goto Exit;
       
   245     }
       
   246 
       
   247     /* first, locate the sid in the charset table */
       
   248     sid = font->charset.sids[glyph_index];
       
   249 
       
   250     /* now, lookup the name itself */
       
   251     gname = cff_index_get_sid_string( font, sid );
       
   252 
       
   253     if ( gname )
       
   254       FT_STRCPYN( buffer, gname, buffer_max );
       
   255 
       
   256     error = CFF_Err_Ok;
       
   257 
       
   258   Exit:
       
   259     return error;
       
   260   }
       
   261 
       
   262 
       
   263   static FT_UInt
       
   264   cff_get_name_index( CFF_Face    face,
       
   265                       FT_String*  glyph_name )
       
   266   {
       
   267     CFF_Font            cff;
       
   268     CFF_Charset         charset;
       
   269     FT_Service_PsCMaps  psnames;
       
   270     FT_String*          name;
       
   271     FT_UShort           sid;
       
   272     FT_UInt             i;
       
   273 
       
   274 
       
   275     cff     = (CFF_FontRec *)face->extra.data;
       
   276     charset = &cff->charset;
       
   277 
       
   278     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
       
   279     if ( !psnames )
       
   280       return 0;
       
   281 
       
   282     for ( i = 0; i < cff->num_glyphs; i++ )
       
   283     {
       
   284       sid = charset->sids[i];
       
   285 
       
   286       if ( sid > 390 )
       
   287         name = cff_index_get_string( cff, sid - 391 );
       
   288       else
       
   289         name = (FT_String *)psnames->adobe_std_strings( sid );
       
   290 
       
   291       if ( !name )
       
   292         continue;
       
   293 
       
   294       if ( !ft_strcmp( glyph_name, name ) )
       
   295         return i;
       
   296     }
       
   297 
       
   298     return 0;
       
   299   }
       
   300 
       
   301 
       
   302   FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict,
       
   303     (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,
       
   304     (FT_GlyphDict_NameIndexFunc)cff_get_name_index
       
   305   )
       
   306 
       
   307 
       
   308   /*
       
   309    *  POSTSCRIPT INFO SERVICE
       
   310    *
       
   311    */
       
   312 
       
   313   static FT_Int
       
   314   cff_ps_has_glyph_names( FT_Face  face )
       
   315   {
       
   316     return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
       
   317   }
       
   318 
       
   319 
       
   320   static FT_Error
       
   321   cff_ps_get_font_info( CFF_Face         face,
       
   322                         PS_FontInfoRec*  afont_info )
       
   323   {
       
   324     CFF_Font  cff   = (CFF_Font)face->extra.data;
       
   325     FT_Error  error = CFF_Err_Ok;
       
   326 
       
   327 
       
   328     if ( cff && cff->font_info == NULL )
       
   329     {
       
   330       CFF_FontRecDict  dict   = &cff->top_font.font_dict;
       
   331       PS_FontInfoRec  *font_info;
       
   332       FT_Memory        memory = face->root.memory;
       
   333 
       
   334 
       
   335       if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
       
   336         goto Fail;
       
   337 
       
   338       font_info->version     = cff_index_get_sid_string( cff,
       
   339                                                          dict->version );
       
   340       font_info->notice      = cff_index_get_sid_string( cff,
       
   341                                                          dict->notice );
       
   342       font_info->full_name   = cff_index_get_sid_string( cff,
       
   343                                                          dict->full_name );
       
   344       font_info->family_name = cff_index_get_sid_string( cff,
       
   345                                                          dict->family_name );
       
   346       font_info->weight      = cff_index_get_sid_string( cff,
       
   347                                                          dict->weight );
       
   348       font_info->italic_angle        = dict->italic_angle;
       
   349       font_info->is_fixed_pitch      = dict->is_fixed_pitch;
       
   350       font_info->underline_position  = (FT_Short)dict->underline_position;
       
   351       font_info->underline_thickness = (FT_Short)dict->underline_thickness;
       
   352 
       
   353       cff->font_info = font_info;
       
   354     }
       
   355 
       
   356     if ( cff )
       
   357       *afont_info = *cff->font_info;
       
   358 
       
   359   Fail:
       
   360     return error;
       
   361   }
       
   362 
       
   363 
       
   364   FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info,
       
   365     (PS_GetFontInfoFunc)   cff_ps_get_font_info,
       
   366     (PS_GetFontExtraFunc)  NULL,
       
   367     (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
       
   368     (PS_GetFontPrivateFunc)NULL         /* unsupported with CFF fonts */
       
   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_Module            sfnt;
       
   603     FT_Module_Interface  result;
       
   604 
       
   605 
       
   606     result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface );
       
   607     if ( result != NULL )
       
   608       return  result;
       
   609 
       
   610     if ( !driver )
       
   611       return NULL;
       
   612 
       
   613     /* we pass our request to the `sfnt' module */
       
   614     sfnt = FT_Get_Module( driver->library, "sfnt" );
       
   615 
       
   616     return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
       
   617   }
       
   618 
       
   619 
       
   620   /* The FT_DriverInterface structure is defined in ftdriver.h. */
       
   621 
       
   622 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
       
   623 #define CFF_SIZE_SELECT cff_size_select
       
   624 #else
       
   625 #define CFF_SIZE_SELECT 0
       
   626 #endif
       
   627 
       
   628   FT_DEFINE_DRIVER(cff_driver_class,
       
   629       FT_MODULE_FONT_DRIVER       |
       
   630       FT_MODULE_DRIVER_SCALABLE   |
       
   631       FT_MODULE_DRIVER_HAS_HINTER,
       
   632 
       
   633       sizeof( CFF_DriverRec ),
       
   634       "cff",
       
   635       0x10000L,
       
   636       0x20000L,
       
   637 
       
   638       0,   /* module-specific interface */
       
   639 
       
   640       cff_driver_init,
       
   641       cff_driver_done,
       
   642       cff_get_interface,
       
   643 
       
   644     /* now the specific driver fields */
       
   645     sizeof( TT_FaceRec ),
       
   646     sizeof( CFF_SizeRec ),
       
   647     sizeof( CFF_GlyphSlotRec ),
       
   648 
       
   649     cff_face_init,
       
   650     cff_face_done,
       
   651     cff_size_init,
       
   652     cff_size_done,
       
   653     cff_slot_init,
       
   654     cff_slot_done,
       
   655 
       
   656     ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
       
   657     ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
       
   658 
       
   659     Load_Glyph,
       
   660 
       
   661     cff_get_kerning,
       
   662     0,                      /* FT_Face_AttachFunc      */
       
   663     cff_get_advances,       /* FT_Face_GetAdvancesFunc */
       
   664 
       
   665     cff_size_request,
       
   666 
       
   667     CFF_SIZE_SELECT
       
   668   )
       
   669 
       
   670 
       
   671 /* END */