Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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