xref: /aosp_15_r20/external/freetype/src/type1/t1driver.c (revision 63949dbd25bcc50c4e1178497ff9e9574d44fc5a)
1 /****************************************************************************
2  *
3  * t1driver.c
4  *
5  *   Type 1 driver interface (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 "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 )
t1_get_glyph_name(FT_Face face,FT_UInt glyph_index,FT_Pointer buffer,FT_UInt buffer_max)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 )
t1_get_name_index(FT_Face face,const FT_String * glyph_name)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*
t1_get_ps_name(FT_Face face)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
t1_ps_get_font_info(FT_Face face,PS_FontInfoRec * afont_info)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
t1_ps_get_font_extra(FT_Face face,PS_FontExtraRec * afont_extra)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
t1_ps_has_glyph_names(FT_Face face)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
t1_ps_get_font_private(FT_Face face,PS_PrivateRec * afont_private)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
t1_ps_get_font_value(FT_Face face,PS_Dict_Keys key,FT_UInt idx,void * value,FT_Long value_len_)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         {
316           ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval );
317           ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
318         }
319       }
320       break;
321 
322     case PS_DICT_CHAR_STRING:
323       if ( idx < (FT_UInt)type1->num_glyphs )
324       {
325         retval = type1->charstrings_len[idx] + 1;
326         if ( value && value_len >= retval )
327         {
328           ft_memcpy( value, (void *)( type1->charstrings[idx] ),
329                      retval - 1 );
330           ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
331         }
332       }
333       break;
334 
335     case PS_DICT_ENCODING_TYPE:
336       retval = sizeof ( type1->encoding_type );
337       if ( value && value_len >= retval )
338         *((T1_EncodingType *)value) = type1->encoding_type;
339       break;
340 
341     case PS_DICT_ENCODING_ENTRY:
342       if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY &&
343            idx < (FT_UInt)type1->encoding.num_chars       )
344       {
345         retval = ft_strlen( type1->encoding.char_name[idx] ) + 1;
346         if ( value && value_len >= retval )
347         {
348           ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ),
349                      retval - 1 );
350           ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
351         }
352       }
353       break;
354 
355     case PS_DICT_NUM_SUBRS:
356       retval = sizeof ( type1->num_subrs );
357       if ( value && value_len >= retval )
358         *((FT_Int *)value) = type1->num_subrs;
359       break;
360 
361     case PS_DICT_SUBR:
362       {
363         FT_Bool  ok = 0;
364 
365 
366         if ( type1->subrs_hash )
367         {
368           /* convert subr index to array index */
369           size_t*  val = ft_hash_num_lookup( (FT_Int)idx,
370                                              type1->subrs_hash );
371 
372 
373           if ( val )
374           {
375             idx = *val;
376             ok  = 1;
377           }
378         }
379         else
380         {
381           if ( idx < (FT_UInt)type1->num_subrs )
382             ok = 1;
383         }
384 
385         if ( ok && type1->subrs )
386         {
387           retval = type1->subrs_len[idx] + 1;
388           if ( value && value_len >= retval )
389           {
390             ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 );
391             ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
392           }
393         }
394       }
395       break;
396 
397     case PS_DICT_STD_HW:
398       retval = sizeof ( type1->private_dict.standard_width[0] );
399       if ( value && value_len >= retval )
400         *((FT_UShort *)value) = type1->private_dict.standard_width[0];
401       break;
402 
403     case PS_DICT_STD_VW:
404       retval = sizeof ( type1->private_dict.standard_height[0] );
405       if ( value && value_len >= retval )
406         *((FT_UShort *)value) = type1->private_dict.standard_height[0];
407       break;
408 
409     case PS_DICT_NUM_BLUE_VALUES:
410       retval = sizeof ( type1->private_dict.num_blue_values );
411       if ( value && value_len >= retval )
412         *((FT_Byte *)value) = type1->private_dict.num_blue_values;
413       break;
414 
415     case PS_DICT_BLUE_VALUE:
416       if ( idx < type1->private_dict.num_blue_values )
417       {
418         retval = sizeof ( type1->private_dict.blue_values[idx] );
419         if ( value && value_len >= retval )
420           *((FT_Short *)value) = type1->private_dict.blue_values[idx];
421       }
422       break;
423 
424     case PS_DICT_BLUE_SCALE:
425       retval = sizeof ( type1->private_dict.blue_scale );
426       if ( value && value_len >= retval )
427         *((FT_Fixed *)value) = type1->private_dict.blue_scale;
428       break;
429 
430     case PS_DICT_BLUE_FUZZ:
431       retval = sizeof ( type1->private_dict.blue_fuzz );
432       if ( value && value_len >= retval )
433         *((FT_Int *)value) = type1->private_dict.blue_fuzz;
434       break;
435 
436     case PS_DICT_BLUE_SHIFT:
437       retval = sizeof ( type1->private_dict.blue_shift );
438       if ( value && value_len >= retval )
439         *((FT_Int *)value) = type1->private_dict.blue_shift;
440       break;
441 
442     case PS_DICT_NUM_OTHER_BLUES:
443       retval = sizeof ( type1->private_dict.num_other_blues );
444       if ( value && value_len >= retval )
445         *((FT_Byte *)value) = type1->private_dict.num_other_blues;
446       break;
447 
448     case PS_DICT_OTHER_BLUE:
449       if ( idx < type1->private_dict.num_other_blues )
450       {
451         retval = sizeof ( type1->private_dict.other_blues[idx] );
452         if ( value && value_len >= retval )
453           *((FT_Short *)value) = type1->private_dict.other_blues[idx];
454       }
455       break;
456 
457     case PS_DICT_NUM_FAMILY_BLUES:
458       retval = sizeof ( type1->private_dict.num_family_blues );
459       if ( value && value_len >= retval )
460         *((FT_Byte *)value) = type1->private_dict.num_family_blues;
461       break;
462 
463     case PS_DICT_FAMILY_BLUE:
464       if ( idx < type1->private_dict.num_family_blues )
465       {
466         retval = sizeof ( type1->private_dict.family_blues[idx] );
467         if ( value && value_len >= retval )
468           *((FT_Short *)value) = type1->private_dict.family_blues[idx];
469       }
470       break;
471 
472     case PS_DICT_NUM_FAMILY_OTHER_BLUES:
473       retval = sizeof ( type1->private_dict.num_family_other_blues );
474       if ( value && value_len >= retval )
475         *((FT_Byte *)value) = type1->private_dict.num_family_other_blues;
476       break;
477 
478     case PS_DICT_FAMILY_OTHER_BLUE:
479       if ( idx < type1->private_dict.num_family_other_blues )
480       {
481         retval = sizeof ( type1->private_dict.family_other_blues[idx] );
482         if ( value && value_len >= retval )
483           *((FT_Short *)value) = type1->private_dict.family_other_blues[idx];
484       }
485       break;
486 
487     case PS_DICT_NUM_STEM_SNAP_H:
488       retval = sizeof ( type1->private_dict.num_snap_widths );
489       if ( value && value_len >= retval )
490         *((FT_Byte *)value) = type1->private_dict.num_snap_widths;
491       break;
492 
493     case PS_DICT_STEM_SNAP_H:
494       if ( idx < type1->private_dict.num_snap_widths )
495       {
496         retval = sizeof ( type1->private_dict.snap_widths[idx] );
497         if ( value && value_len >= retval )
498           *((FT_Short *)value) = type1->private_dict.snap_widths[idx];
499       }
500       break;
501 
502     case PS_DICT_NUM_STEM_SNAP_V:
503       retval = sizeof ( type1->private_dict.num_snap_heights );
504       if ( value && value_len >= retval )
505         *((FT_Byte *)value) = type1->private_dict.num_snap_heights;
506       break;
507 
508     case PS_DICT_STEM_SNAP_V:
509       if ( idx < type1->private_dict.num_snap_heights )
510       {
511         retval = sizeof ( type1->private_dict.snap_heights[idx] );
512         if ( value && value_len >= retval )
513           *((FT_Short *)value) = type1->private_dict.snap_heights[idx];
514       }
515       break;
516 
517     case PS_DICT_RND_STEM_UP:
518       retval = sizeof ( type1->private_dict.round_stem_up );
519       if ( value && value_len >= retval )
520         *((FT_Bool *)value) = type1->private_dict.round_stem_up;
521       break;
522 
523     case PS_DICT_FORCE_BOLD:
524       retval = sizeof ( type1->private_dict.force_bold );
525       if ( value && value_len >= retval )
526         *((FT_Bool *)value) = type1->private_dict.force_bold;
527       break;
528 
529     case PS_DICT_MIN_FEATURE:
530       if ( idx < sizeof ( type1->private_dict.min_feature ) /
531                    sizeof ( type1->private_dict.min_feature[0] ) )
532       {
533         retval = sizeof ( type1->private_dict.min_feature[idx] );
534         if ( value && value_len >= retval )
535           *((FT_Short *)value) = type1->private_dict.min_feature[idx];
536       }
537       break;
538 
539     case PS_DICT_LEN_IV:
540       retval = sizeof ( type1->private_dict.lenIV );
541       if ( value && value_len >= retval )
542         *((FT_Int *)value) = type1->private_dict.lenIV;
543       break;
544 
545     case PS_DICT_PASSWORD:
546       retval = sizeof ( type1->private_dict.password );
547       if ( value && value_len >= retval )
548         *((FT_Long *)value) = type1->private_dict.password;
549       break;
550 
551     case PS_DICT_LANGUAGE_GROUP:
552       retval = sizeof ( type1->private_dict.language_group );
553       if ( value && value_len >= retval )
554         *((FT_Long *)value) = type1->private_dict.language_group;
555       break;
556 
557     case PS_DICT_IS_FIXED_PITCH:
558       retval = sizeof ( type1->font_info.is_fixed_pitch );
559       if ( value && value_len >= retval )
560         *((FT_Bool *)value) = type1->font_info.is_fixed_pitch;
561       break;
562 
563     case PS_DICT_UNDERLINE_POSITION:
564       retval = sizeof ( type1->font_info.underline_position );
565       if ( value && value_len >= retval )
566         *((FT_Short *)value) = type1->font_info.underline_position;
567       break;
568 
569     case PS_DICT_UNDERLINE_THICKNESS:
570       retval = sizeof ( type1->font_info.underline_thickness );
571       if ( value && value_len >= retval )
572         *((FT_UShort *)value) = type1->font_info.underline_thickness;
573       break;
574 
575     case PS_DICT_FS_TYPE:
576       retval = sizeof ( type1->font_extra.fs_type );
577       if ( value && value_len >= retval )
578         *((FT_UShort *)value) = type1->font_extra.fs_type;
579       break;
580 
581     case PS_DICT_VERSION:
582       if ( type1->font_info.version )
583       {
584         retval = ft_strlen( type1->font_info.version ) + 1;
585         if ( value && value_len >= retval )
586           ft_memcpy( value, (void *)( type1->font_info.version ), retval );
587       }
588       break;
589 
590     case PS_DICT_NOTICE:
591       if ( type1->font_info.notice )
592       {
593         retval = ft_strlen( type1->font_info.notice ) + 1;
594         if ( value && value_len >= retval )
595           ft_memcpy( value, (void *)( type1->font_info.notice ), retval );
596       }
597       break;
598 
599     case PS_DICT_FULL_NAME:
600       if ( type1->font_info.full_name )
601       {
602         retval = ft_strlen( type1->font_info.full_name ) + 1;
603         if ( value && value_len >= retval )
604           ft_memcpy( value, (void *)( type1->font_info.full_name ), retval );
605       }
606       break;
607 
608     case PS_DICT_FAMILY_NAME:
609       if ( type1->font_info.family_name )
610       {
611         retval = ft_strlen( type1->font_info.family_name ) + 1;
612         if ( value && value_len >= retval )
613           ft_memcpy( value, (void *)( type1->font_info.family_name ),
614                      retval );
615       }
616       break;
617 
618     case PS_DICT_WEIGHT:
619       if ( type1->font_info.weight )
620       {
621         retval = ft_strlen( type1->font_info.weight ) + 1;
622         if ( value && value_len >= retval )
623           ft_memcpy( value, (void *)( type1->font_info.weight ), retval );
624       }
625       break;
626 
627     case PS_DICT_ITALIC_ANGLE:
628       retval = sizeof ( type1->font_info.italic_angle );
629       if ( value && value_len >= retval )
630         *((FT_Long *)value) = type1->font_info.italic_angle;
631       break;
632     }
633 
634     return retval == 0 ? -1 : (FT_Long)retval;
635   }
636 
637 
638   static const FT_Service_PsInfoRec  t1_service_ps_info =
639   {
640     t1_ps_get_font_info,     /* PS_GetFontInfoFunc    ps_get_font_info    */
641     t1_ps_get_font_extra,    /* PS_GetFontExtraFunc   ps_get_font_extra   */
642     t1_ps_has_glyph_names,   /* PS_HasGlyphNamesFunc  ps_has_glyph_names  */
643     t1_ps_get_font_private,  /* PS_GetFontPrivateFunc ps_get_font_private */
644     t1_ps_get_font_value,    /* PS_GetFontValueFunc   ps_get_font_value   */
645   };
646 
647 
648 #ifndef T1_CONFIG_OPTION_NO_AFM
649   static const FT_Service_KerningRec  t1_service_kerning =
650   {
651     T1_Get_Track_Kerning,       /* get_track */
652   };
653 #endif
654 
655 
656   /*
657    * PROPERTY SERVICE
658    *
659    */
660 
661   FT_DEFINE_SERVICE_PROPERTIESREC(
662     t1_service_properties,
663 
664     ps_property_set,  /* FT_Properties_SetFunc set_property */
665     ps_property_get   /* FT_Properties_GetFunc get_property */
666   )
667 
668   /*
669    * SERVICE LIST
670    *
671    */
672 
673   static const FT_ServiceDescRec  t1_services[] =
674   {
675     { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name },
676     { FT_SERVICE_ID_GLYPH_DICT,           &t1_service_glyph_dict },
677     { FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_TYPE_1 },
678     { FT_SERVICE_ID_POSTSCRIPT_INFO,      &t1_service_ps_info },
679     { FT_SERVICE_ID_PROPERTIES,           &t1_service_properties },
680 
681 #ifndef T1_CONFIG_OPTION_NO_AFM
682     { FT_SERVICE_ID_KERNING,              &t1_service_kerning },
683 #endif
684 
685 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
686     { FT_SERVICE_ID_MULTI_MASTERS,        &t1_service_multi_masters },
687 #endif
688     { NULL, NULL }
689   };
690 
691 
692   FT_CALLBACK_DEF( FT_Module_Interface )
Get_Interface(FT_Module module,const FT_String * t1_interface)693   Get_Interface( FT_Module         module,
694                  const FT_String*  t1_interface )
695   {
696     FT_UNUSED( module );
697 
698     return ft_service_list_lookup( t1_services, t1_interface );
699   }
700 
701 
702 #ifndef T1_CONFIG_OPTION_NO_AFM
703 
704   /**************************************************************************
705    *
706    * @Function:
707    *   Get_Kerning
708    *
709    * @Description:
710    *   A driver method used to return the kerning vector between two
711    *   glyphs of the same face.
712    *
713    * @Input:
714    *   face ::
715    *     A handle to the source face object.
716    *
717    *   left_glyph ::
718    *     The index of the left glyph in the kern pair.
719    *
720    *   right_glyph ::
721    *     The index of the right glyph in the kern pair.
722    *
723    * @Output:
724    *   kerning ::
725    *     The kerning vector.  This is in font units for
726    *     scalable formats, and in pixels for fixed-sizes
727    *     formats.
728    *
729    * @Return:
730    *   FreeType error code.  0 means success.
731    *
732    * @Note:
733    *   Only horizontal layouts (left-to-right & right-to-left) are
734    *   supported by this function.  Other layouts, or more sophisticated
735    *   kernings are out of scope of this method (the basic driver
736    *   interface is meant to be simple).
737    *
738    *   They can be implemented by format-specific interfaces.
739    */
740   static FT_Error
Get_Kerning(FT_Face t1face,FT_UInt left_glyph,FT_UInt right_glyph,FT_Vector * kerning)741   Get_Kerning( FT_Face     t1face,        /* T1_Face */
742                FT_UInt     left_glyph,
743                FT_UInt     right_glyph,
744                FT_Vector*  kerning )
745   {
746     T1_Face  face = (T1_Face)t1face;
747 
748 
749     kerning->x = 0;
750     kerning->y = 0;
751 
752     if ( face->afm_data )
753       T1_Get_Kerning( (AFM_FontInfo)face->afm_data,
754                       left_glyph,
755                       right_glyph,
756                       kerning );
757 
758     return FT_Err_Ok;
759   }
760 
761 
762 #endif /* T1_CONFIG_OPTION_NO_AFM */
763 
764 
765   FT_CALLBACK_TABLE_DEF
766   const FT_Driver_ClassRec  t1_driver_class =
767   {
768     {
769       FT_MODULE_FONT_DRIVER       |
770       FT_MODULE_DRIVER_SCALABLE   |
771       FT_MODULE_DRIVER_HAS_HINTER,
772 
773       sizeof ( PS_DriverRec ),
774 
775       "type1",
776       0x10000L,
777       0x20000L,
778 
779       NULL,    /* module-specific interface */
780 
781       T1_Driver_Init,           /* FT_Module_Constructor  module_init   */
782       T1_Driver_Done,           /* FT_Module_Destructor   module_done   */
783       Get_Interface,            /* FT_Module_Requester    get_interface */
784     },
785 
786     sizeof ( T1_FaceRec ),
787     sizeof ( T1_SizeRec ),
788     sizeof ( T1_GlyphSlotRec ),
789 
790     T1_Face_Init,               /* FT_Face_InitFunc  init_face */
791     T1_Face_Done,               /* FT_Face_DoneFunc  done_face */
792     T1_Size_Init,               /* FT_Size_InitFunc  init_size */
793     T1_Size_Done,               /* FT_Size_DoneFunc  done_size */
794     T1_GlyphSlot_Init,          /* FT_Slot_InitFunc  init_slot */
795     T1_GlyphSlot_Done,          /* FT_Slot_DoneFunc  done_slot */
796 
797     T1_Load_Glyph,              /* FT_Slot_LoadFunc  load_glyph */
798 
799 #ifdef T1_CONFIG_OPTION_NO_AFM
800     NULL,                       /* FT_Face_GetKerningFunc   get_kerning  */
801     NULL,                       /* FT_Face_AttachFunc       attach_file  */
802 #else
803     Get_Kerning,                /* FT_Face_GetKerningFunc   get_kerning  */
804     T1_Read_Metrics,            /* FT_Face_AttachFunc       attach_file  */
805 #endif
806     T1_Get_Advances,            /* FT_Face_GetAdvancesFunc  get_advances */
807 
808     T1_Size_Request,            /* FT_Size_RequestFunc  request_size */
809     NULL                        /* FT_Size_SelectFunc   select_size  */
810   };
811 
812 
813 /* END */
814