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