Home | History | Annotate | Download | only in truetype
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  ttdriver.c                                                             */
      4 /*                                                                         */
      5 /*    TrueType font driver implementation (body).                          */
      6 /*                                                                         */
      7 /*  Copyright 1996-2018 by                                                 */
      8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
      9 /*                                                                         */
     10 /*  This file is part of the FreeType project, and may only be used,       */
     11 /*  modified, and distributed under the terms of the FreeType project      */
     12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     13 /*  this file you indicate that you have read the license and              */
     14 /*  understand and accept it fully.                                        */
     15 /*                                                                         */
     16 /***************************************************************************/
     17 
     18 
     19 #include <ft2build.h>
     20 #include FT_INTERNAL_DEBUG_H
     21 #include FT_INTERNAL_STREAM_H
     22 #include FT_INTERNAL_SFNT_H
     23 #include FT_SERVICE_FONT_FORMAT_H
     24 
     25 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     26 #include FT_MULTIPLE_MASTERS_H
     27 #include FT_SERVICE_MULTIPLE_MASTERS_H
     28 #include FT_SERVICE_METRICS_VARIATIONS_H
     29 #endif
     30 
     31 #include FT_SERVICE_TRUETYPE_ENGINE_H
     32 #include FT_SERVICE_TRUETYPE_GLYF_H
     33 #include FT_SERVICE_PROPERTIES_H
     34 #include FT_DRIVER_H
     35 
     36 #include "ttdriver.h"
     37 #include "ttgload.h"
     38 #include "ttpload.h"
     39 
     40 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     41 #include "ttgxvar.h"
     42 #endif
     43 
     44 #include "tterrors.h"
     45 
     46 #include "ttpic.h"
     47 
     48   /*************************************************************************/
     49   /*                                                                       */
     50   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     51   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     52   /* messages during execution.                                            */
     53   /*                                                                       */
     54 #undef  FT_COMPONENT
     55 #define FT_COMPONENT  trace_ttdriver
     56 
     57 
     58   /*
     59    *  PROPERTY SERVICE
     60    *
     61    */
     62   static FT_Error
     63   tt_property_set( FT_Module    module,         /* TT_Driver */
     64                    const char*  property_name,
     65                    const void*  value,
     66                    FT_Bool      value_is_string )
     67   {
     68     FT_Error   error  = FT_Err_Ok;
     69     TT_Driver  driver = (TT_Driver)module;
     70 
     71 #ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
     72     FT_UNUSED( value_is_string );
     73 #endif
     74 
     75 
     76     if ( !ft_strcmp( property_name, "interpreter-version" ) )
     77     {
     78       FT_UInt  interpreter_version;
     79 
     80 
     81 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
     82       if ( value_is_string )
     83       {
     84         const char*  s = (const char*)value;
     85 
     86 
     87         interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 );
     88       }
     89       else
     90 #endif
     91       {
     92         FT_UInt*  iv = (FT_UInt*)value;
     93 
     94 
     95         interpreter_version = *iv;
     96       }
     97 
     98       if ( interpreter_version == TT_INTERPRETER_VERSION_35
     99 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
    100            || interpreter_version == TT_INTERPRETER_VERSION_38
    101 #endif
    102 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
    103            || interpreter_version == TT_INTERPRETER_VERSION_40
    104 #endif
    105          )
    106         driver->interpreter_version = interpreter_version;
    107       else
    108         error = FT_ERR( Unimplemented_Feature );
    109 
    110       return error;
    111     }
    112 
    113     FT_TRACE0(( "tt_property_set: missing property `%s'\n",
    114                 property_name ));
    115     return FT_THROW( Missing_Property );
    116   }
    117 
    118 
    119   static FT_Error
    120   tt_property_get( FT_Module    module,         /* TT_Driver */
    121                    const char*  property_name,
    122                    const void*  value )
    123   {
    124     FT_Error   error  = FT_Err_Ok;
    125     TT_Driver  driver = (TT_Driver)module;
    126 
    127     FT_UInt  interpreter_version = driver->interpreter_version;
    128 
    129 
    130     if ( !ft_strcmp( property_name, "interpreter-version" ) )
    131     {
    132       FT_UInt*  val = (FT_UInt*)value;
    133 
    134 
    135       *val = interpreter_version;
    136 
    137       return error;
    138     }
    139 
    140     FT_TRACE0(( "tt_property_get: missing property `%s'\n",
    141                 property_name ));
    142     return FT_THROW( Missing_Property );
    143   }
    144 
    145 
    146   FT_DEFINE_SERVICE_PROPERTIESREC(
    147     tt_service_properties,
    148 
    149     (FT_Properties_SetFunc)tt_property_set,     /* set_property */
    150     (FT_Properties_GetFunc)tt_property_get      /* get_property */
    151   )
    152 
    153 
    154   /*************************************************************************/
    155   /*************************************************************************/
    156   /*************************************************************************/
    157   /****                                                                 ****/
    158   /****                                                                 ****/
    159   /****                          F A C E S                              ****/
    160   /****                                                                 ****/
    161   /****                                                                 ****/
    162   /*************************************************************************/
    163   /*************************************************************************/
    164   /*************************************************************************/
    165 
    166 
    167   /*************************************************************************/
    168   /*                                                                       */
    169   /* <Function>                                                            */
    170   /*    tt_get_kerning                                                     */
    171   /*                                                                       */
    172   /* <Description>                                                         */
    173   /*    A driver method used to return the kerning vector between two      */
    174   /*    glyphs of the same face.                                           */
    175   /*                                                                       */
    176   /* <Input>                                                               */
    177   /*    face        :: A handle to the source face object.                 */
    178   /*                                                                       */
    179   /*    left_glyph  :: The index of the left glyph in the kern pair.       */
    180   /*                                                                       */
    181   /*    right_glyph :: The index of the right glyph in the kern pair.      */
    182   /*                                                                       */
    183   /* <Output>                                                              */
    184   /*    kerning     :: The kerning vector.  This is in font units for      */
    185   /*                   scalable formats, and in pixels for fixed-sizes     */
    186   /*                   formats.                                            */
    187   /*                                                                       */
    188   /* <Return>                                                              */
    189   /*    FreeType error code.  0 means success.                             */
    190   /*                                                                       */
    191   /* <Note>                                                                */
    192   /*    Only horizontal layouts (left-to-right & right-to-left) are        */
    193   /*    supported by this function.  Other layouts, or more sophisticated  */
    194   /*    kernings, are out of scope of this method (the basic driver        */
    195   /*    interface is meant to be simple).                                  */
    196   /*                                                                       */
    197   /*    They can be implemented by format-specific interfaces.             */
    198   /*                                                                       */
    199   static FT_Error
    200   tt_get_kerning( FT_Face     ttface,          /* TT_Face */
    201                   FT_UInt     left_glyph,
    202                   FT_UInt     right_glyph,
    203                   FT_Vector*  kerning )
    204   {
    205     TT_Face       face = (TT_Face)ttface;
    206     SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
    207 
    208 
    209     kerning->x = 0;
    210     kerning->y = 0;
    211 
    212     if ( sfnt )
    213       kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
    214 
    215     return 0;
    216   }
    217 
    218 
    219   static FT_Error
    220   tt_get_advances( FT_Face    ttface,
    221                    FT_UInt    start,
    222                    FT_UInt    count,
    223                    FT_Int32   flags,
    224                    FT_Fixed  *advances )
    225   {
    226     FT_UInt  nn;
    227     TT_Face  face = (TT_Face)ttface;
    228 
    229 
    230     /* XXX: TODO: check for sbits */
    231 
    232     if ( flags & FT_LOAD_VERTICAL_LAYOUT )
    233     {
    234 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    235       /* no fast retrieval for blended MM fonts without VVAR table */
    236       if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) &&
    237            !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE )        )
    238         return FT_THROW( Unimplemented_Feature );
    239 #endif
    240 
    241       for ( nn = 0; nn < count; nn++ )
    242       {
    243         FT_Short   tsb;
    244         FT_UShort  ah;
    245 
    246 
    247         /* since we don't need `tsb', we use zero for `yMax' parameter */
    248         TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah );
    249         advances[nn] = ah;
    250       }
    251     }
    252     else
    253     {
    254 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    255       /* no fast retrieval for blended MM fonts without HVAR table */
    256       if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) &&
    257            !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE )        )
    258         return FT_THROW( Unimplemented_Feature );
    259 #endif
    260 
    261       for ( nn = 0; nn < count; nn++ )
    262       {
    263         FT_Short   lsb;
    264         FT_UShort  aw;
    265 
    266 
    267         TT_Get_HMetrics( face, start + nn, &lsb, &aw );
    268         advances[nn] = aw;
    269       }
    270     }
    271 
    272     return FT_Err_Ok;
    273   }
    274 
    275 
    276   /*************************************************************************/
    277   /*************************************************************************/
    278   /*************************************************************************/
    279   /****                                                                 ****/
    280   /****                                                                 ****/
    281   /****                           S I Z E S                             ****/
    282   /****                                                                 ****/
    283   /****                                                                 ****/
    284   /*************************************************************************/
    285   /*************************************************************************/
    286   /*************************************************************************/
    287 
    288 
    289 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
    290 
    291   static FT_Error
    292   tt_size_select( FT_Size   size,
    293                   FT_ULong  strike_index )
    294   {
    295     TT_Face   ttface = (TT_Face)size->face;
    296     TT_Size   ttsize = (TT_Size)size;
    297     FT_Error  error  = FT_Err_Ok;
    298 
    299 
    300     ttsize->strike_index = strike_index;
    301 
    302     if ( FT_IS_SCALABLE( size->face ) )
    303     {
    304       /* use the scaled metrics, even when tt_size_reset fails */
    305       FT_Select_Metrics( size->face, strike_index );
    306 
    307       tt_size_reset( ttsize, 0 ); /* ignore return value */
    308     }
    309     else
    310     {
    311       SFNT_Service      sfnt         = (SFNT_Service)ttface->sfnt;
    312       FT_Size_Metrics*  size_metrics = &size->metrics;
    313 
    314 
    315       error = sfnt->load_strike_metrics( ttface,
    316                                          strike_index,
    317                                          size_metrics );
    318       if ( error )
    319         ttsize->strike_index = 0xFFFFFFFFUL;
    320     }
    321 
    322     return error;
    323   }
    324 
    325 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
    326 
    327 
    328   static FT_Error
    329   tt_size_request( FT_Size          size,
    330                    FT_Size_Request  req )
    331   {
    332     TT_Size   ttsize = (TT_Size)size;
    333     FT_Error  error  = FT_Err_Ok;
    334 
    335 
    336 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
    337 
    338     if ( FT_HAS_FIXED_SIZES( size->face ) )
    339     {
    340       TT_Face       ttface = (TT_Face)size->face;
    341       SFNT_Service  sfnt   = (SFNT_Service)ttface->sfnt;
    342       FT_ULong      strike_index;
    343 
    344 
    345       error = sfnt->set_sbit_strike( ttface, req, &strike_index );
    346 
    347       if ( error )
    348         ttsize->strike_index = 0xFFFFFFFFUL;
    349       else
    350         return tt_size_select( size, strike_index );
    351     }
    352 
    353 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
    354 
    355     FT_Request_Metrics( size->face, req );
    356 
    357     if ( FT_IS_SCALABLE( size->face ) )
    358     {
    359       error = tt_size_reset( ttsize, 0 );
    360 
    361 #ifdef TT_USE_BYTECODE_INTERPRETER
    362       /* for the `MPS' bytecode instruction we need the point size */
    363       if ( !error )
    364       {
    365         FT_UInt  resolution =
    366                    ttsize->metrics->x_ppem > ttsize->metrics->y_ppem
    367                      ? req->horiResolution
    368                      : req->vertResolution;
    369 
    370 
    371         /* if we don't have a resolution value, assume 72dpi */
    372         if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES ||
    373              !resolution                              )
    374           resolution = 72;
    375 
    376         ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem,
    377                                         64 * 72,
    378                                         resolution );
    379       }
    380 #endif
    381     }
    382 
    383     return error;
    384   }
    385 
    386 
    387   /*************************************************************************/
    388   /*                                                                       */
    389   /* <Function>                                                            */
    390   /*    tt_glyph_load                                                      */
    391   /*                                                                       */
    392   /* <Description>                                                         */
    393   /*    A driver method used to load a glyph within a given glyph slot.    */
    394   /*                                                                       */
    395   /* <Input>                                                               */
    396   /*    slot        :: A handle to the target slot object where the glyph  */
    397   /*                   will be loaded.                                     */
    398   /*                                                                       */
    399   /*    size        :: A handle to the source face size at which the glyph */
    400   /*                   must be scaled, loaded, etc.                        */
    401   /*                                                                       */
    402   /*    glyph_index :: The index of the glyph in the font file.            */
    403   /*                                                                       */
    404   /*    load_flags  :: A flag indicating what to load for this glyph.  The */
    405   /*                   FT_LOAD_XXX constants can be used to control the    */
    406   /*                   glyph loading process (e.g., whether the outline    */
    407   /*                   should be scaled, whether to load bitmaps or not,   */
    408   /*                   whether to hint the outline, etc).                  */
    409   /*                                                                       */
    410   /* <Return>                                                              */
    411   /*    FreeType error code.  0 means success.                             */
    412   /*                                                                       */
    413   static FT_Error
    414   tt_glyph_load( FT_GlyphSlot  ttslot,      /* TT_GlyphSlot */
    415                  FT_Size       ttsize,      /* TT_Size      */
    416                  FT_UInt       glyph_index,
    417                  FT_Int32      load_flags )
    418   {
    419     TT_GlyphSlot  slot = (TT_GlyphSlot)ttslot;
    420     TT_Size       size = (TT_Size)ttsize;
    421     FT_Face       face = ttslot->face;
    422     FT_Error      error;
    423 
    424 
    425     if ( !slot )
    426       return FT_THROW( Invalid_Slot_Handle );
    427 
    428     if ( !size )
    429       return FT_THROW( Invalid_Size_Handle );
    430 
    431     if ( !face )
    432       return FT_THROW( Invalid_Face_Handle );
    433 
    434 #ifdef FT_CONFIG_OPTION_INCREMENTAL
    435     if ( glyph_index >= (FT_UInt)face->num_glyphs &&
    436          !face->internal->incremental_interface   )
    437 #else
    438     if ( glyph_index >= (FT_UInt)face->num_glyphs )
    439 #endif
    440       return FT_THROW( Invalid_Argument );
    441 
    442     if ( load_flags & FT_LOAD_NO_HINTING )
    443     {
    444       /* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT   */
    445       /* are necessary to disable hinting for tricky fonts */
    446 
    447       if ( FT_IS_TRICKY( face ) )
    448         load_flags &= ~FT_LOAD_NO_HINTING;
    449 
    450       if ( load_flags & FT_LOAD_NO_AUTOHINT )
    451         load_flags |= FT_LOAD_NO_HINTING;
    452     }
    453 
    454     if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) )
    455     {
    456       load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE;
    457 
    458       if ( !FT_IS_TRICKY( face ) )
    459         load_flags |= FT_LOAD_NO_HINTING;
    460     }
    461 
    462     /* use hinted metrics only if we load a glyph with hinting */
    463     size->metrics = ( load_flags & FT_LOAD_NO_HINTING )
    464                       ? &ttsize->metrics
    465                       : &size->hinted_metrics;
    466 
    467     /* now load the glyph outline if necessary */
    468     error = TT_Load_Glyph( size, slot, glyph_index, load_flags );
    469 
    470     /* force drop-out mode to 2 - irrelevant now */
    471     /* slot->outline.dropout_mode = 2; */
    472 
    473     return error;
    474   }
    475 
    476 
    477   /*************************************************************************/
    478   /*************************************************************************/
    479   /*************************************************************************/
    480   /****                                                                 ****/
    481   /****                                                                 ****/
    482   /****                D R I V E R  I N T E R F A C E                   ****/
    483   /****                                                                 ****/
    484   /****                                                                 ****/
    485   /*************************************************************************/
    486   /*************************************************************************/
    487   /*************************************************************************/
    488 
    489 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    490 
    491   FT_DEFINE_SERVICE_MULTIMASTERSREC(
    492     tt_service_gx_multi_masters,
    493 
    494     (FT_Get_MM_Func)        NULL,                   /* get_mm         */
    495     (FT_Set_MM_Design_Func) NULL,                   /* set_mm_design  */
    496     (FT_Set_MM_Blend_Func)  TT_Set_MM_Blend,        /* set_mm_blend   */
    497     (FT_Get_MM_Blend_Func)  TT_Get_MM_Blend,        /* get_mm_blend   */
    498     (FT_Get_MM_Var_Func)    TT_Get_MM_Var,          /* get_mm_var     */
    499     (FT_Set_Var_Design_Func)TT_Set_Var_Design,      /* set_var_design */
    500     (FT_Get_Var_Design_Func)TT_Get_Var_Design,      /* get_var_design */
    501     (FT_Set_Instance_Func)  TT_Set_Named_Instance,  /* set_instance   */
    502 
    503     (FT_Get_Var_Blend_Func) tt_get_var_blend,       /* get_var_blend  */
    504     (FT_Done_Blend_Func)    tt_done_blend           /* done_blend     */
    505   )
    506 
    507   FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
    508     tt_service_metrics_variations,
    509 
    510     (FT_HAdvance_Adjust_Func)tt_hadvance_adjust,     /* hadvance_adjust */
    511     (FT_LSB_Adjust_Func)     NULL,                   /* lsb_adjust      */
    512     (FT_RSB_Adjust_Func)     NULL,                   /* rsb_adjust      */
    513 
    514     (FT_VAdvance_Adjust_Func)tt_vadvance_adjust,     /* vadvance_adjust */
    515     (FT_TSB_Adjust_Func)     NULL,                   /* tsb_adjust      */
    516     (FT_BSB_Adjust_Func)     NULL,                   /* bsb_adjust      */
    517     (FT_VOrg_Adjust_Func)    NULL,                   /* vorg_adjust     */
    518 
    519     (FT_Metrics_Adjust_Func) tt_apply_mvar           /* metrics_adjust  */
    520   )
    521 
    522 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
    523 
    524 
    525   static const FT_Service_TrueTypeEngineRec  tt_service_truetype_engine =
    526   {
    527 #ifdef TT_USE_BYTECODE_INTERPRETER
    528 
    529     FT_TRUETYPE_ENGINE_TYPE_PATENTED
    530 
    531 #else /* !TT_USE_BYTECODE_INTERPRETER */
    532 
    533     FT_TRUETYPE_ENGINE_TYPE_NONE
    534 
    535 #endif /* TT_USE_BYTECODE_INTERPRETER */
    536   };
    537 
    538 
    539   FT_DEFINE_SERVICE_TTGLYFREC(
    540     tt_service_truetype_glyf,
    541 
    542     (TT_Glyf_GetLocationFunc)tt_face_get_location      /* get_location */
    543   )
    544 
    545 
    546 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    547   FT_DEFINE_SERVICEDESCREC6(
    548     tt_services,
    549 
    550     FT_SERVICE_ID_FONT_FORMAT,        FT_FONT_FORMAT_TRUETYPE,
    551     FT_SERVICE_ID_MULTI_MASTERS,      &TT_SERVICE_GX_MULTI_MASTERS_GET,
    552     FT_SERVICE_ID_METRICS_VARIATIONS, &TT_SERVICE_METRICS_VARIATIONS_GET,
    553     FT_SERVICE_ID_TRUETYPE_ENGINE,    &tt_service_truetype_engine,
    554     FT_SERVICE_ID_TT_GLYF,            &TT_SERVICE_TRUETYPE_GLYF_GET,
    555     FT_SERVICE_ID_PROPERTIES,         &TT_SERVICE_PROPERTIES_GET )
    556 #else
    557   FT_DEFINE_SERVICEDESCREC4(
    558     tt_services,
    559 
    560     FT_SERVICE_ID_FONT_FORMAT,     FT_FONT_FORMAT_TRUETYPE,
    561     FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
    562     FT_SERVICE_ID_TT_GLYF,         &TT_SERVICE_TRUETYPE_GLYF_GET,
    563     FT_SERVICE_ID_PROPERTIES,      &TT_SERVICE_PROPERTIES_GET )
    564 #endif
    565 
    566 
    567   FT_CALLBACK_DEF( FT_Module_Interface )
    568   tt_get_interface( FT_Module    driver,    /* TT_Driver */
    569                     const char*  tt_interface )
    570   {
    571     FT_Library           library;
    572     FT_Module_Interface  result;
    573     FT_Module            sfntd;
    574     SFNT_Service         sfnt;
    575 
    576 
    577     /* TT_SERVICES_GET dereferences `library' in PIC mode */
    578 #ifdef FT_CONFIG_OPTION_PIC
    579     if ( !driver )
    580       return NULL;
    581     library = driver->library;
    582     if ( !library )
    583       return NULL;
    584 #endif
    585 
    586     result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface );
    587     if ( result )
    588       return result;
    589 
    590 #ifndef FT_CONFIG_OPTION_PIC
    591     if ( !driver )
    592       return NULL;
    593     library = driver->library;
    594     if ( !library )
    595       return NULL;
    596 #endif
    597 
    598     /* only return the default interface from the SFNT module */
    599     sfntd = FT_Get_Module( library, "sfnt" );
    600     if ( sfntd )
    601     {
    602       sfnt = (SFNT_Service)( sfntd->clazz->module_interface );
    603       if ( sfnt )
    604         return sfnt->get_interface( driver, tt_interface );
    605     }
    606 
    607     return 0;
    608   }
    609 
    610 
    611   /* The FT_DriverInterface structure is defined in ftdriver.h. */
    612 
    613 #ifdef TT_USE_BYTECODE_INTERPRETER
    614 #define TT_HINTER_FLAG  FT_MODULE_DRIVER_HAS_HINTER
    615 #else
    616 #define TT_HINTER_FLAG  0
    617 #endif
    618 
    619 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
    620 #define TT_SIZE_SELECT  tt_size_select
    621 #else
    622 #define TT_SIZE_SELECT  0
    623 #endif
    624 
    625   FT_DEFINE_DRIVER(
    626     tt_driver_class,
    627 
    628       FT_MODULE_FONT_DRIVER     |
    629       FT_MODULE_DRIVER_SCALABLE |
    630       TT_HINTER_FLAG,
    631 
    632       sizeof ( TT_DriverRec ),
    633 
    634       "truetype",      /* driver name                           */
    635       0x10000L,        /* driver version == 1.0                 */
    636       0x20000L,        /* driver requires FreeType 2.0 or above */
    637 
    638       NULL,    /* module-specific interface */
    639 
    640       tt_driver_init,           /* FT_Module_Constructor  module_init   */
    641       tt_driver_done,           /* FT_Module_Destructor   module_done   */
    642       tt_get_interface,         /* FT_Module_Requester    get_interface */
    643 
    644     sizeof ( TT_FaceRec ),
    645     sizeof ( TT_SizeRec ),
    646     sizeof ( FT_GlyphSlotRec ),
    647 
    648     tt_face_init,               /* FT_Face_InitFunc  init_face */
    649     tt_face_done,               /* FT_Face_DoneFunc  done_face */
    650     tt_size_init,               /* FT_Size_InitFunc  init_size */
    651     tt_size_done,               /* FT_Size_DoneFunc  done_size */
    652     tt_slot_init,               /* FT_Slot_InitFunc  init_slot */
    653     NULL,                       /* FT_Slot_DoneFunc  done_slot */
    654 
    655     tt_glyph_load,              /* FT_Slot_LoadFunc  load_glyph */
    656 
    657     tt_get_kerning,             /* FT_Face_GetKerningFunc   get_kerning  */
    658     NULL,                       /* FT_Face_AttachFunc       attach_file  */
    659     tt_get_advances,            /* FT_Face_GetAdvancesFunc  get_advances */
    660 
    661     tt_size_request,            /* FT_Size_RequestFunc  request_size */
    662     TT_SIZE_SELECT              /* FT_Size_SelectFunc   select_size  */
    663   )
    664 
    665 
    666 /* END */
    667