tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

t1driver.c (23752B)


      1 /****************************************************************************
      2 *
      3 * t1driver.c
      4 *
      5 *   Type 1 driver interface (body).
      6 *
      7 * Copyright (C) 1996-2025 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 "t1driver.h"
     20 #include "t1gload.h"
     21 #include "t1load.h"
     22 
     23 #include "t1errors.h"
     24 
     25 #ifndef T1_CONFIG_OPTION_NO_AFM
     26 #include "t1afm.h"
     27 #endif
     28 
     29 #include <freetype/internal/ftdebug.h>
     30 #include <freetype/internal/ftstream.h>
     31 #include <freetype/internal/fthash.h>
     32 #include <freetype/internal/ftpsprop.h>
     33 #include <freetype/ftdriver.h>
     34 
     35 #include <freetype/internal/services/svmm.h>
     36 #include <freetype/internal/services/svgldict.h>
     37 #include <freetype/internal/services/svfntfmt.h>
     38 #include <freetype/internal/services/svpostnm.h>
     39 #include <freetype/internal/services/svpscmap.h>
     40 #include <freetype/internal/services/svpsinfo.h>
     41 #include <freetype/internal/services/svprop.h>
     42 #include <freetype/internal/services/svkern.h>
     43 
     44 
     45  /**************************************************************************
     46   *
     47   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     48   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     49   * messages during execution.
     50   */
     51 #undef  FT_COMPONENT
     52 #define FT_COMPONENT  t1driver
     53 
     54  /*
     55   * GLYPH DICT SERVICE
     56   *
     57   */
     58 
     59  FT_CALLBACK_DEF( FT_Error )
     60  t1_get_glyph_name( FT_Face     face,        /* T1_Face */
     61                     FT_UInt     glyph_index,
     62                     FT_Pointer  buffer,
     63                     FT_UInt     buffer_max )
     64  {
     65    T1_Face  t1face = (T1_Face)face;
     66 
     67 
     68    FT_STRCPYN( buffer, t1face->type1.glyph_names[glyph_index], buffer_max );
     69 
     70    return FT_Err_Ok;
     71  }
     72 
     73 
     74  FT_CALLBACK_DEF( FT_UInt )
     75  t1_get_name_index( FT_Face           face,        /* T1_Face */
     76                     const FT_String*  glyph_name )
     77  {
     78    T1_Face  t1face = (T1_Face)face;
     79    FT_Int   i;
     80 
     81 
     82    for ( i = 0; i < t1face->type1.num_glyphs; i++ )
     83    {
     84      FT_String*  gname = t1face->type1.glyph_names[i];
     85 
     86 
     87      if ( !ft_strcmp( glyph_name, gname ) )
     88        return (FT_UInt)i;
     89    }
     90 
     91    return 0;
     92  }
     93 
     94 
     95  static const FT_Service_GlyphDictRec  t1_service_glyph_dict =
     96  {
     97    t1_get_glyph_name,  /* FT_GlyphDict_GetNameFunc   get_name   */
     98    t1_get_name_index   /* FT_GlyphDict_NameIndexFunc name_index */
     99  };
    100 
    101 
    102  /*
    103   * POSTSCRIPT NAME SERVICE
    104   *
    105   */
    106 
    107  static const char*
    108  t1_get_ps_name( FT_Face  face )    /* T1_Face */
    109  {
    110    T1_Face  t1face = (T1_Face)face;
    111 
    112 
    113    return (const char*) t1face->type1.font_name;
    114  }
    115 
    116 
    117  static const FT_Service_PsFontNameRec  t1_service_ps_name =
    118  {
    119    (FT_PsName_GetFunc)t1_get_ps_name     /* get_ps_font_name */
    120  };
    121 
    122 
    123  /*
    124   * MULTIPLE MASTERS SERVICE
    125   *
    126   */
    127 
    128 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
    129  static const FT_Service_MultiMastersRec  t1_service_multi_masters =
    130  {
    131    T1_Get_Multi_Master,    /* FT_Get_MM_Func             get_mm             */
    132    T1_Set_MM_Design,       /* FT_Set_MM_Design_Func      set_mm_design      */
    133    T1_Set_MM_Blend,        /* FT_Set_MM_Blend_Func       set_mm_blend       */
    134    T1_Get_MM_Blend,        /* FT_Get_MM_Blend_Func       get_mm_blend       */
    135    T1_Get_MM_Var,          /* FT_Get_MM_Var_Func         get_mm_var         */
    136    T1_Set_Var_Design,      /* FT_Set_Var_Design_Func     set_var_design     */
    137    T1_Get_Var_Design,      /* FT_Get_Var_Design_Func     get_var_design     */
    138    T1_Reset_MM_Blend,      /* FT_Set_Named_Instance_Func set_named_instance */
    139    NULL,   /* FT_Get_Default_Named_Instance_Func get_default_named_instance */
    140    T1_Set_MM_WeightVector,
    141            /* FT_Set_MM_WeightVector_Func        set_mm_weightvector        */
    142    T1_Get_MM_WeightVector,
    143            /* FT_Get_MM_WeightVector_Func        get_mm_weightvector        */
    144 
    145    NULL,   /* FT_Construct_PS_Name_Func          construct_ps_name          */
    146    NULL,   /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map     */
    147    NULL,   /* FT_Var_Load_Item_Var_Store_Func    load_item_variation_store  */
    148    NULL,   /* FT_Var_Get_Item_Delta_Func         get_item_delta             */
    149    NULL,   /* FT_Var_Done_Item_Var_Store_Func    done_item_variation_store  */
    150    NULL,   /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map   */
    151    NULL,           /* FT_Get_Var_Blend_Func      get_var_blend              */
    152    T1_Done_Blend   /* FT_Done_Blend_Func         done_blend                 */
    153  };
    154 #endif
    155 
    156 
    157  /*
    158   * POSTSCRIPT INFO SERVICE
    159   *
    160   */
    161 
    162  static FT_Error
    163  t1_ps_get_font_info( FT_Face          face,
    164                       PS_FontInfoRec*  afont_info )
    165  {
    166    *afont_info = ((T1_Face)face)->type1.font_info;
    167 
    168    return FT_Err_Ok;
    169  }
    170 
    171 
    172  static FT_Error
    173  t1_ps_get_font_extra( FT_Face           face,
    174                        PS_FontExtraRec*  afont_extra )
    175  {
    176    *afont_extra = ((T1_Face)face)->type1.font_extra;
    177 
    178    return FT_Err_Ok;
    179  }
    180 
    181 
    182  static FT_Int
    183  t1_ps_has_glyph_names( FT_Face  face )
    184  {
    185    FT_UNUSED( face );
    186 
    187    return 1;
    188  }
    189 
    190 
    191  static FT_Error
    192  t1_ps_get_font_private( FT_Face         face,
    193                          PS_PrivateRec*  afont_private )
    194  {
    195    *afont_private = ((T1_Face)face)->type1.private_dict;
    196 
    197    return FT_Err_Ok;
    198  }
    199 
    200 
    201  static FT_Long
    202  t1_ps_get_font_value( FT_Face       face,
    203                        PS_Dict_Keys  key,
    204                        FT_UInt       idx,
    205                        void         *value,
    206                        FT_Long       value_len_ )
    207  {
    208    FT_ULong  retval    = 0; /* always >= 1 if valid */
    209    FT_ULong  value_len = value_len_ < 0 ? 0 : (FT_ULong)value_len_;
    210 
    211    T1_Face  t1face = (T1_Face)face;
    212    T1_Font  type1  = &t1face->type1;
    213 
    214 
    215    switch ( key )
    216    {
    217    case PS_DICT_FONT_TYPE:
    218      retval = sizeof ( type1->font_type );
    219      if ( value && value_len >= retval )
    220        *((FT_Byte *)value) = type1->font_type;
    221      break;
    222 
    223    case PS_DICT_FONT_MATRIX:
    224      if ( idx < sizeof ( type1->font_matrix ) /
    225                   sizeof ( type1->font_matrix.xx ) )
    226      {
    227        FT_Fixed  val = 0;
    228 
    229 
    230        retval = sizeof ( val );
    231        if ( value && value_len >= retval )
    232        {
    233          switch ( idx )
    234          {
    235          case 0:
    236            val = type1->font_matrix.xx;
    237            break;
    238          case 1:
    239            val = type1->font_matrix.xy;
    240            break;
    241          case 2:
    242            val = type1->font_matrix.yx;
    243            break;
    244          case 3:
    245            val = type1->font_matrix.yy;
    246            break;
    247          }
    248          *((FT_Fixed *)value) = val;
    249        }
    250      }
    251      break;
    252 
    253    case PS_DICT_FONT_BBOX:
    254      if ( idx < sizeof ( type1->font_bbox ) /
    255                   sizeof ( type1->font_bbox.xMin ) )
    256      {
    257        FT_Fixed  val = 0;
    258 
    259 
    260        retval = sizeof ( val );
    261        if ( value && value_len >= retval )
    262        {
    263          switch ( idx )
    264          {
    265          case 0:
    266            val = type1->font_bbox.xMin;
    267            break;
    268          case 1:
    269            val = type1->font_bbox.yMin;
    270            break;
    271          case 2:
    272            val = type1->font_bbox.xMax;
    273            break;
    274          case 3:
    275            val = type1->font_bbox.yMax;
    276            break;
    277          }
    278          *((FT_Fixed *)value) = val;
    279        }
    280      }
    281      break;
    282 
    283    case PS_DICT_PAINT_TYPE:
    284      retval = sizeof ( type1->paint_type );
    285      if ( value && value_len >= retval )
    286        *((FT_Byte *)value) = type1->paint_type;
    287      break;
    288 
    289    case PS_DICT_FONT_NAME:
    290      if ( type1->font_name )
    291      {
    292        retval = ft_strlen( type1->font_name ) + 1;
    293        if ( value && value_len >= retval )
    294          ft_memcpy( value, (void *)( type1->font_name ), retval );
    295      }
    296      break;
    297 
    298    case PS_DICT_UNIQUE_ID:
    299      retval = sizeof ( type1->private_dict.unique_id );
    300      if ( value && value_len >= retval )
    301        *((FT_Int *)value) = type1->private_dict.unique_id;
    302      break;
    303 
    304    case PS_DICT_NUM_CHAR_STRINGS:
    305      retval = sizeof ( type1->num_glyphs );
    306      if ( value && value_len >= retval )
    307        *((FT_Int *)value) = type1->num_glyphs;
    308      break;
    309 
    310    case PS_DICT_CHAR_STRING_KEY:
    311      if ( idx < (FT_UInt)type1->num_glyphs )
    312      {
    313        retval = ft_strlen( type1->glyph_names[idx] ) + 1;
    314        if ( value && value_len >= retval )
    315          ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval );
    316      }
    317      break;
    318 
    319    case PS_DICT_CHAR_STRING:
    320      if ( idx < (FT_UInt)type1->num_glyphs )
    321      {
    322        retval = type1->charstrings_len[idx] + 1;
    323        if ( value && value_len >= retval )
    324        {
    325          ft_memcpy( value, (void *)( type1->charstrings[idx] ),
    326                     retval - 1 );
    327          ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
    328        }
    329      }
    330      break;
    331 
    332    case PS_DICT_ENCODING_TYPE:
    333      retval = sizeof ( type1->encoding_type );
    334      if ( value && value_len >= retval )
    335        *((T1_EncodingType *)value) = type1->encoding_type;
    336      break;
    337 
    338    case PS_DICT_ENCODING_ENTRY:
    339      if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY &&
    340           idx < (FT_UInt)type1->encoding.num_chars       )
    341      {
    342        retval = ft_strlen( type1->encoding.char_name[idx] ) + 1;
    343        if ( value && value_len >= retval )
    344          ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ),
    345                     retval );
    346      }
    347      break;
    348 
    349    case PS_DICT_NUM_SUBRS:
    350      retval = sizeof ( type1->num_subrs );
    351      if ( value && value_len >= retval )
    352        *((FT_Int *)value) = type1->num_subrs;
    353      break;
    354 
    355    case PS_DICT_SUBR:
    356      {
    357        FT_Bool  ok = 0;
    358 
    359 
    360        if ( type1->subrs_hash )
    361        {
    362          /* convert subr index to array index */
    363          size_t*  val = ft_hash_num_lookup( (FT_Int)idx,
    364                                             type1->subrs_hash );
    365 
    366 
    367          if ( val )
    368          {
    369            idx = *val;
    370            ok  = 1;
    371          }
    372        }
    373        else
    374        {
    375          if ( idx < (FT_UInt)type1->num_subrs )
    376            ok = 1;
    377        }
    378 
    379        if ( ok && type1->subrs )
    380        {
    381          retval = type1->subrs_len[idx] + 1;
    382          if ( value && value_len >= retval )
    383          {
    384            ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 );
    385            ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
    386          }
    387        }
    388      }
    389      break;
    390 
    391    case PS_DICT_STD_HW:
    392      retval = sizeof ( type1->private_dict.standard_width[0] );
    393      if ( value && value_len >= retval )
    394        *((FT_UShort *)value) = type1->private_dict.standard_width[0];
    395      break;
    396 
    397    case PS_DICT_STD_VW:
    398      retval = sizeof ( type1->private_dict.standard_height[0] );
    399      if ( value && value_len >= retval )
    400        *((FT_UShort *)value) = type1->private_dict.standard_height[0];
    401      break;
    402 
    403    case PS_DICT_NUM_BLUE_VALUES:
    404      retval = sizeof ( type1->private_dict.num_blue_values );
    405      if ( value && value_len >= retval )
    406        *((FT_Byte *)value) = type1->private_dict.num_blue_values;
    407      break;
    408 
    409    case PS_DICT_BLUE_VALUE:
    410      if ( idx < type1->private_dict.num_blue_values )
    411      {
    412        retval = sizeof ( type1->private_dict.blue_values[idx] );
    413        if ( value && value_len >= retval )
    414          *((FT_Short *)value) = type1->private_dict.blue_values[idx];
    415      }
    416      break;
    417 
    418    case PS_DICT_BLUE_SCALE:
    419      retval = sizeof ( type1->private_dict.blue_scale );
    420      if ( value && value_len >= retval )
    421        *((FT_Fixed *)value) = type1->private_dict.blue_scale;
    422      break;
    423 
    424    case PS_DICT_BLUE_FUZZ:
    425      retval = sizeof ( type1->private_dict.blue_fuzz );
    426      if ( value && value_len >= retval )
    427        *((FT_Int *)value) = type1->private_dict.blue_fuzz;
    428      break;
    429 
    430    case PS_DICT_BLUE_SHIFT:
    431      retval = sizeof ( type1->private_dict.blue_shift );
    432      if ( value && value_len >= retval )
    433        *((FT_Int *)value) = type1->private_dict.blue_shift;
    434      break;
    435 
    436    case PS_DICT_NUM_OTHER_BLUES:
    437      retval = sizeof ( type1->private_dict.num_other_blues );
    438      if ( value && value_len >= retval )
    439        *((FT_Byte *)value) = type1->private_dict.num_other_blues;
    440      break;
    441 
    442    case PS_DICT_OTHER_BLUE:
    443      if ( idx < type1->private_dict.num_other_blues )
    444      {
    445        retval = sizeof ( type1->private_dict.other_blues[idx] );
    446        if ( value && value_len >= retval )
    447          *((FT_Short *)value) = type1->private_dict.other_blues[idx];
    448      }
    449      break;
    450 
    451    case PS_DICT_NUM_FAMILY_BLUES:
    452      retval = sizeof ( type1->private_dict.num_family_blues );
    453      if ( value && value_len >= retval )
    454        *((FT_Byte *)value) = type1->private_dict.num_family_blues;
    455      break;
    456 
    457    case PS_DICT_FAMILY_BLUE:
    458      if ( idx < type1->private_dict.num_family_blues )
    459      {
    460        retval = sizeof ( type1->private_dict.family_blues[idx] );
    461        if ( value && value_len >= retval )
    462          *((FT_Short *)value) = type1->private_dict.family_blues[idx];
    463      }
    464      break;
    465 
    466    case PS_DICT_NUM_FAMILY_OTHER_BLUES:
    467      retval = sizeof ( type1->private_dict.num_family_other_blues );
    468      if ( value && value_len >= retval )
    469        *((FT_Byte *)value) = type1->private_dict.num_family_other_blues;
    470      break;
    471 
    472    case PS_DICT_FAMILY_OTHER_BLUE:
    473      if ( idx < type1->private_dict.num_family_other_blues )
    474      {
    475        retval = sizeof ( type1->private_dict.family_other_blues[idx] );
    476        if ( value && value_len >= retval )
    477          *((FT_Short *)value) = type1->private_dict.family_other_blues[idx];
    478      }
    479      break;
    480 
    481    case PS_DICT_NUM_STEM_SNAP_H:
    482      retval = sizeof ( type1->private_dict.num_snap_widths );
    483      if ( value && value_len >= retval )
    484        *((FT_Byte *)value) = type1->private_dict.num_snap_widths;
    485      break;
    486 
    487    case PS_DICT_STEM_SNAP_H:
    488      if ( idx < type1->private_dict.num_snap_widths )
    489      {
    490        retval = sizeof ( type1->private_dict.snap_widths[idx] );
    491        if ( value && value_len >= retval )
    492          *((FT_Short *)value) = type1->private_dict.snap_widths[idx];
    493      }
    494      break;
    495 
    496    case PS_DICT_NUM_STEM_SNAP_V:
    497      retval = sizeof ( type1->private_dict.num_snap_heights );
    498      if ( value && value_len >= retval )
    499        *((FT_Byte *)value) = type1->private_dict.num_snap_heights;
    500      break;
    501 
    502    case PS_DICT_STEM_SNAP_V:
    503      if ( idx < type1->private_dict.num_snap_heights )
    504      {
    505        retval = sizeof ( type1->private_dict.snap_heights[idx] );
    506        if ( value && value_len >= retval )
    507          *((FT_Short *)value) = type1->private_dict.snap_heights[idx];
    508      }
    509      break;
    510 
    511    case PS_DICT_RND_STEM_UP:
    512      retval = sizeof ( type1->private_dict.round_stem_up );
    513      if ( value && value_len >= retval )
    514        *((FT_Bool *)value) = type1->private_dict.round_stem_up;
    515      break;
    516 
    517    case PS_DICT_FORCE_BOLD:
    518      retval = sizeof ( type1->private_dict.force_bold );
    519      if ( value && value_len >= retval )
    520        *((FT_Bool *)value) = type1->private_dict.force_bold;
    521      break;
    522 
    523    case PS_DICT_MIN_FEATURE:
    524      if ( idx < sizeof ( type1->private_dict.min_feature ) /
    525                   sizeof ( type1->private_dict.min_feature[0] ) )
    526      {
    527        retval = sizeof ( type1->private_dict.min_feature[idx] );
    528        if ( value && value_len >= retval )
    529          *((FT_Short *)value) = type1->private_dict.min_feature[idx];
    530      }
    531      break;
    532 
    533    case PS_DICT_LEN_IV:
    534      retval = sizeof ( type1->private_dict.lenIV );
    535      if ( value && value_len >= retval )
    536        *((FT_Int *)value) = type1->private_dict.lenIV;
    537      break;
    538 
    539    case PS_DICT_PASSWORD:
    540      retval = sizeof ( type1->private_dict.password );
    541      if ( value && value_len >= retval )
    542        *((FT_Long *)value) = type1->private_dict.password;
    543      break;
    544 
    545    case PS_DICT_LANGUAGE_GROUP:
    546      retval = sizeof ( type1->private_dict.language_group );
    547      if ( value && value_len >= retval )
    548        *((FT_Long *)value) = type1->private_dict.language_group;
    549      break;
    550 
    551    case PS_DICT_IS_FIXED_PITCH:
    552      retval = sizeof ( type1->font_info.is_fixed_pitch );
    553      if ( value && value_len >= retval )
    554        *((FT_Bool *)value) = type1->font_info.is_fixed_pitch;
    555      break;
    556 
    557    case PS_DICT_UNDERLINE_POSITION:
    558      retval = sizeof ( type1->font_info.underline_position );
    559      if ( value && value_len >= retval )
    560        *((FT_Short *)value) = type1->font_info.underline_position;
    561      break;
    562 
    563    case PS_DICT_UNDERLINE_THICKNESS:
    564      retval = sizeof ( type1->font_info.underline_thickness );
    565      if ( value && value_len >= retval )
    566        *((FT_UShort *)value) = type1->font_info.underline_thickness;
    567      break;
    568 
    569    case PS_DICT_FS_TYPE:
    570      retval = sizeof ( type1->font_extra.fs_type );
    571      if ( value && value_len >= retval )
    572        *((FT_UShort *)value) = type1->font_extra.fs_type;
    573      break;
    574 
    575    case PS_DICT_VERSION:
    576      if ( type1->font_info.version )
    577      {
    578        retval = ft_strlen( type1->font_info.version ) + 1;
    579        if ( value && value_len >= retval )
    580          ft_memcpy( value, (void *)( type1->font_info.version ), retval );
    581      }
    582      break;
    583 
    584    case PS_DICT_NOTICE:
    585      if ( type1->font_info.notice )
    586      {
    587        retval = ft_strlen( type1->font_info.notice ) + 1;
    588        if ( value && value_len >= retval )
    589          ft_memcpy( value, (void *)( type1->font_info.notice ), retval );
    590      }
    591      break;
    592 
    593    case PS_DICT_FULL_NAME:
    594      if ( type1->font_info.full_name )
    595      {
    596        retval = ft_strlen( type1->font_info.full_name ) + 1;
    597        if ( value && value_len >= retval )
    598          ft_memcpy( value, (void *)( type1->font_info.full_name ), retval );
    599      }
    600      break;
    601 
    602    case PS_DICT_FAMILY_NAME:
    603      if ( type1->font_info.family_name )
    604      {
    605        retval = ft_strlen( type1->font_info.family_name ) + 1;
    606        if ( value && value_len >= retval )
    607          ft_memcpy( value, (void *)( type1->font_info.family_name ),
    608                     retval );
    609      }
    610      break;
    611 
    612    case PS_DICT_WEIGHT:
    613      if ( type1->font_info.weight )
    614      {
    615        retval = ft_strlen( type1->font_info.weight ) + 1;
    616        if ( value && value_len >= retval )
    617          ft_memcpy( value, (void *)( type1->font_info.weight ), retval );
    618      }
    619      break;
    620 
    621    case PS_DICT_ITALIC_ANGLE:
    622      retval = sizeof ( type1->font_info.italic_angle );
    623      if ( value && value_len >= retval )
    624        *((FT_Long *)value) = type1->font_info.italic_angle;
    625      break;
    626    }
    627 
    628    return retval == 0 ? -1 : (FT_Long)retval;
    629  }
    630 
    631 
    632  static const FT_Service_PsInfoRec  t1_service_ps_info =
    633  {
    634    t1_ps_get_font_info,     /* PS_GetFontInfoFunc    ps_get_font_info    */
    635    t1_ps_get_font_extra,    /* PS_GetFontExtraFunc   ps_get_font_extra   */
    636    t1_ps_has_glyph_names,   /* PS_HasGlyphNamesFunc  ps_has_glyph_names  */
    637    t1_ps_get_font_private,  /* PS_GetFontPrivateFunc ps_get_font_private */
    638    t1_ps_get_font_value,    /* PS_GetFontValueFunc   ps_get_font_value   */
    639  };
    640 
    641 
    642 #ifndef T1_CONFIG_OPTION_NO_AFM
    643  static const FT_Service_KerningRec  t1_service_kerning =
    644  {
    645    T1_Get_Track_Kerning,       /* get_track */
    646  };
    647 #endif
    648 
    649 
    650  /*
    651   * PROPERTY SERVICE
    652   *
    653   */
    654 
    655  FT_DEFINE_SERVICE_PROPERTIESREC(
    656    t1_service_properties,
    657 
    658    ps_property_set,  /* FT_Properties_SetFunc set_property */
    659    ps_property_get   /* FT_Properties_GetFunc get_property */
    660  )
    661 
    662  /*
    663   * SERVICE LIST
    664   *
    665   */
    666 
    667  static const FT_ServiceDescRec  t1_services[] =
    668  {
    669    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name },
    670    { FT_SERVICE_ID_GLYPH_DICT,           &t1_service_glyph_dict },
    671    { FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_TYPE_1 },
    672    { FT_SERVICE_ID_POSTSCRIPT_INFO,      &t1_service_ps_info },
    673    { FT_SERVICE_ID_PROPERTIES,           &t1_service_properties },
    674 
    675 #ifndef T1_CONFIG_OPTION_NO_AFM
    676    { FT_SERVICE_ID_KERNING,              &t1_service_kerning },
    677 #endif
    678 
    679 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
    680    { FT_SERVICE_ID_MULTI_MASTERS,        &t1_service_multi_masters },
    681 #endif
    682    { NULL, NULL }
    683  };
    684 
    685 
    686  FT_CALLBACK_DEF( FT_Module_Interface )
    687  Get_Interface( FT_Module         module,
    688                 const FT_String*  t1_interface )
    689  {
    690    FT_UNUSED( module );
    691 
    692    return ft_service_list_lookup( t1_services, t1_interface );
    693  }
    694 
    695 
    696 #ifndef T1_CONFIG_OPTION_NO_AFM
    697 
    698  /**************************************************************************
    699   *
    700   * @Function:
    701   *   Get_Kerning
    702   *
    703   * @Description:
    704   *   A driver method used to return the kerning vector between two
    705   *   glyphs of the same face.
    706   *
    707   * @Input:
    708   *   face ::
    709   *     A handle to the source face object.
    710   *
    711   *   left_glyph ::
    712   *     The index of the left glyph in the kern pair.
    713   *
    714   *   right_glyph ::
    715   *     The index of the right glyph in the kern pair.
    716   *
    717   * @Output:
    718   *   kerning ::
    719   *     The kerning vector.  This is in font units for
    720   *     scalable formats, and in pixels for fixed-sizes
    721   *     formats.
    722   *
    723   * @Return:
    724   *   FreeType error code.  0 means success.
    725   *
    726   * @Note:
    727   *   Only horizontal layouts (left-to-right & right-to-left) are
    728   *   supported by this function.  Other layouts, or more sophisticated
    729   *   kernings are out of scope of this method (the basic driver
    730   *   interface is meant to be simple).
    731   *
    732   *   They can be implemented by format-specific interfaces.
    733   */
    734  static FT_Error
    735  Get_Kerning( FT_Face     t1face,        /* T1_Face */
    736               FT_UInt     left_glyph,
    737               FT_UInt     right_glyph,
    738               FT_Vector*  kerning )
    739  {
    740    T1_Face  face = (T1_Face)t1face;
    741 
    742 
    743    kerning->x = 0;
    744    kerning->y = 0;
    745 
    746    if ( face->afm_data )
    747      T1_Get_Kerning( (AFM_FontInfo)face->afm_data,
    748                      left_glyph,
    749                      right_glyph,
    750                      kerning );
    751 
    752    return FT_Err_Ok;
    753  }
    754 
    755 
    756 #endif /* T1_CONFIG_OPTION_NO_AFM */
    757 
    758 
    759  FT_CALLBACK_TABLE_DEF
    760  const FT_Driver_ClassRec  t1_driver_class =
    761  {
    762    {
    763      FT_MODULE_FONT_DRIVER       |
    764      FT_MODULE_DRIVER_SCALABLE   |
    765      FT_MODULE_DRIVER_HAS_HINTER,
    766 
    767      sizeof ( PS_DriverRec ),
    768 
    769      "type1",
    770      0x10000L,
    771      0x20000L,
    772 
    773      NULL,    /* module-specific interface */
    774 
    775      T1_Driver_Init,           /* FT_Module_Constructor  module_init   */
    776      T1_Driver_Done,           /* FT_Module_Destructor   module_done   */
    777      Get_Interface,            /* FT_Module_Requester    get_interface */
    778    },
    779 
    780    sizeof ( T1_FaceRec ),
    781    sizeof ( T1_SizeRec ),
    782    sizeof ( T1_GlyphSlotRec ),
    783 
    784    T1_Face_Init,               /* FT_Face_InitFunc  init_face */
    785    T1_Face_Done,               /* FT_Face_DoneFunc  done_face */
    786    T1_Size_Init,               /* FT_Size_InitFunc  init_size */
    787    T1_Size_Done,               /* FT_Size_DoneFunc  done_size */
    788    T1_GlyphSlot_Init,          /* FT_Slot_InitFunc  init_slot */
    789    T1_GlyphSlot_Done,          /* FT_Slot_DoneFunc  done_slot */
    790 
    791    T1_Load_Glyph,              /* FT_Slot_LoadFunc  load_glyph */
    792 
    793 #ifdef T1_CONFIG_OPTION_NO_AFM
    794    NULL,                       /* FT_Face_GetKerningFunc   get_kerning  */
    795    NULL,                       /* FT_Face_AttachFunc       attach_file  */
    796 #else
    797    Get_Kerning,                /* FT_Face_GetKerningFunc   get_kerning  */
    798    T1_Read_Metrics,            /* FT_Face_AttachFunc       attach_file  */
    799 #endif
    800    T1_Get_Advances,            /* FT_Face_GetAdvancesFunc  get_advances */
    801 
    802    T1_Size_Request,            /* FT_Size_RequestFunc  request_size */
    803    NULL                        /* FT_Size_SelectFunc   select_size  */
    804  };
    805 
    806 
    807 /* END */