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