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