OLD | NEW |
| (Empty) |
1 /***************************************************************************/ | |
2 /* */ | |
3 /* t1driver.c */ | |
4 /* */ | |
5 /* Type 1 driver interface (body). */ | |
6 /* */ | |
7 /* Copyright 1996-2004, 2006, 2007, 2009, 2011, 2013 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 "../../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 "../../include/freetype/internal/ftdebug.h" | |
31 #include "../../include/freetype/internal/ftstream.h" | |
32 | |
33 #include "../../include/freetype/internal/services/svmm.h" | |
34 #include "../../include/freetype/internal/services/svgldict.h" | |
35 #include "../../include/freetype/internal/services/svxf86nm.h" | |
36 #include "../../include/freetype/internal/services/svpostnm.h" | |
37 #include "../../include/freetype/internal/services/svpscmap.h" | |
38 #include "../../include/freetype/internal/services/svpsinfo.h" | |
39 #include "../../include/freetype/internal/services/svkern.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, | |
91 (FT_GlyphDict_NameIndexFunc)t1_get_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 | |
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, | |
122 (FT_Set_MM_Design_Func) T1_Set_MM_Design, | |
123 (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, | |
124 (FT_Get_MM_Var_Func) T1_Get_MM_Var, | |
125 (FT_Set_Var_Design_Func)T1_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_Long retval = -1; | |
182 T1_Face t1face = (T1_Face)face; | |
183 T1_Font type1 = &t1face->type1; | |
184 | |
185 | |
186 switch ( key ) | |
187 { | |
188 case PS_DICT_FONT_TYPE: | |
189 retval = sizeof ( type1->font_type ); | |
190 if ( value && value_len >= retval ) | |
191 *((FT_Byte *)value) = type1->font_type; | |
192 break; | |
193 | |
194 case PS_DICT_FONT_MATRIX: | |
195 if ( idx < sizeof ( type1->font_matrix ) / | |
196 sizeof ( type1->font_matrix.xx ) ) | |
197 { | |
198 FT_Fixed val = 0; | |
199 | |
200 | |
201 retval = sizeof ( val ); | |
202 if ( value && value_len >= retval ) | |
203 { | |
204 switch ( idx ) | |
205 { | |
206 case 0: | |
207 val = type1->font_matrix.xx; | |
208 break; | |
209 case 1: | |
210 val = type1->font_matrix.xy; | |
211 break; | |
212 case 2: | |
213 val = type1->font_matrix.yx; | |
214 break; | |
215 case 3: | |
216 val = type1->font_matrix.yy; | |
217 break; | |
218 } | |
219 *((FT_Fixed *)value) = val; | |
220 } | |
221 } | |
222 break; | |
223 | |
224 case PS_DICT_FONT_BBOX: | |
225 if ( idx < sizeof ( type1->font_bbox ) / | |
226 sizeof ( type1->font_bbox.xMin ) ) | |
227 { | |
228 FT_Fixed val = 0; | |
229 | |
230 | |
231 retval = sizeof ( val ); | |
232 if ( value && value_len >= retval ) | |
233 { | |
234 switch ( idx ) | |
235 { | |
236 case 0: | |
237 val = type1->font_bbox.xMin; | |
238 break; | |
239 case 1: | |
240 val = type1->font_bbox.yMin; | |
241 break; | |
242 case 2: | |
243 val = type1->font_bbox.xMax; | |
244 break; | |
245 case 3: | |
246 val = type1->font_bbox.yMax; | |
247 break; | |
248 } | |
249 *((FT_Fixed *)value) = val; | |
250 } | |
251 } | |
252 break; | |
253 | |
254 case PS_DICT_PAINT_TYPE: | |
255 retval = sizeof ( type1->paint_type ); | |
256 if ( value && value_len >= retval ) | |
257 *((FT_Byte *)value) = type1->paint_type; | |
258 break; | |
259 | |
260 case PS_DICT_FONT_NAME: | |
261 retval = (FT_Long)( ft_strlen( type1->font_name ) + 1 ); | |
262 if ( value && value_len >= retval ) | |
263 ft_memcpy( value, (void *)( type1->font_name ), retval ); | |
264 break; | |
265 | |
266 case PS_DICT_UNIQUE_ID: | |
267 retval = sizeof ( type1->private_dict.unique_id ); | |
268 if ( value && value_len >= retval ) | |
269 *((FT_Int *)value) = type1->private_dict.unique_id; | |
270 break; | |
271 | |
272 case PS_DICT_NUM_CHAR_STRINGS: | |
273 retval = sizeof ( type1->num_glyphs ); | |
274 if ( value && value_len >= retval ) | |
275 *((FT_Int *)value) = type1->num_glyphs; | |
276 break; | |
277 | |
278 case PS_DICT_CHAR_STRING_KEY: | |
279 if ( idx < (FT_UInt)type1->num_glyphs ) | |
280 { | |
281 retval = (FT_Long)( ft_strlen( type1->glyph_names[idx] ) + 1 ); | |
282 if ( value && value_len >= retval ) | |
283 { | |
284 ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval ); | |
285 ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; | |
286 } | |
287 } | |
288 break; | |
289 | |
290 case PS_DICT_CHAR_STRING: | |
291 if ( idx < (FT_UInt)type1->num_glyphs ) | |
292 { | |
293 retval = (FT_Long)( type1->charstrings_len[idx] + 1 ); | |
294 if ( value && value_len >= retval ) | |
295 { | |
296 ft_memcpy( value, (void *)( type1->charstrings[idx] ), | |
297 retval - 1 ); | |
298 ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; | |
299 } | |
300 } | |
301 break; | |
302 | |
303 case PS_DICT_ENCODING_TYPE: | |
304 retval = sizeof ( type1->encoding_type ); | |
305 if ( value && value_len >= retval ) | |
306 *((T1_EncodingType *)value) = type1->encoding_type; | |
307 break; | |
308 | |
309 case PS_DICT_ENCODING_ENTRY: | |
310 if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY && | |
311 idx < (FT_UInt)type1->encoding.num_chars ) | |
312 { | |
313 retval = (FT_Long)( ft_strlen( type1->encoding.char_name[idx] ) + 1 ); | |
314 if ( value && value_len >= retval ) | |
315 { | |
316 ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ), | |
317 retval - 1 ); | |
318 ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; | |
319 } | |
320 } | |
321 break; | |
322 | |
323 case PS_DICT_NUM_SUBRS: | |
324 retval = sizeof ( type1->num_subrs ); | |
325 if ( value && value_len >= retval ) | |
326 *((FT_Int *)value) = type1->num_subrs; | |
327 break; | |
328 | |
329 case PS_DICT_SUBR: | |
330 if ( idx < (FT_UInt)type1->num_subrs ) | |
331 { | |
332 retval = (FT_Long)( type1->subrs_len[idx] + 1 ); | |
333 if ( value && value_len >= retval ) | |
334 { | |
335 ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); | |
336 ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; | |
337 } | |
338 } | |
339 break; | |
340 | |
341 case PS_DICT_STD_HW: | |
342 retval = sizeof ( type1->private_dict.standard_width[0] ); | |
343 if ( value && value_len >= retval ) | |
344 *((FT_UShort *)value) = type1->private_dict.standard_width[0]; | |
345 break; | |
346 | |
347 case PS_DICT_STD_VW: | |
348 retval = sizeof ( type1->private_dict.standard_height[0] ); | |
349 if ( value && value_len >= retval ) | |
350 *((FT_UShort *)value) = type1->private_dict.standard_height[0]; | |
351 break; | |
352 | |
353 case PS_DICT_NUM_BLUE_VALUES: | |
354 retval = sizeof ( type1->private_dict.num_blue_values ); | |
355 if ( value && value_len >= retval ) | |
356 *((FT_Byte *)value) = type1->private_dict.num_blue_values; | |
357 break; | |
358 | |
359 case PS_DICT_BLUE_VALUE: | |
360 if ( idx < type1->private_dict.num_blue_values ) | |
361 { | |
362 retval = sizeof ( type1->private_dict.blue_values[idx] ); | |
363 if ( value && value_len >= retval ) | |
364 *((FT_Short *)value) = type1->private_dict.blue_values[idx]; | |
365 } | |
366 break; | |
367 | |
368 case PS_DICT_BLUE_SCALE: | |
369 retval = sizeof ( type1->private_dict.blue_scale ); | |
370 if ( value && value_len >= retval ) | |
371 *((FT_Fixed *)value) = type1->private_dict.blue_scale; | |
372 break; | |
373 | |
374 case PS_DICT_BLUE_FUZZ: | |
375 retval = sizeof ( type1->private_dict.blue_fuzz ); | |
376 if ( value && value_len >= retval ) | |
377 *((FT_Int *)value) = type1->private_dict.blue_fuzz; | |
378 break; | |
379 | |
380 case PS_DICT_BLUE_SHIFT: | |
381 retval = sizeof ( type1->private_dict.blue_shift ); | |
382 if ( value && value_len >= retval ) | |
383 *((FT_Int *)value) = type1->private_dict.blue_shift; | |
384 break; | |
385 | |
386 case PS_DICT_NUM_OTHER_BLUES: | |
387 retval = sizeof ( type1->private_dict.num_other_blues ); | |
388 if ( value && value_len >= retval ) | |
389 *((FT_Byte *)value) = type1->private_dict.num_other_blues; | |
390 break; | |
391 | |
392 case PS_DICT_OTHER_BLUE: | |
393 if ( idx < type1->private_dict.num_other_blues ) | |
394 { | |
395 retval = sizeof ( type1->private_dict.other_blues[idx] ); | |
396 if ( value && value_len >= retval ) | |
397 *((FT_Short *)value) = type1->private_dict.other_blues[idx]; | |
398 } | |
399 break; | |
400 | |
401 case PS_DICT_NUM_FAMILY_BLUES: | |
402 retval = sizeof ( type1->private_dict.num_family_blues ); | |
403 if ( value && value_len >= retval ) | |
404 *((FT_Byte *)value) = type1->private_dict.num_family_blues; | |
405 break; | |
406 | |
407 case PS_DICT_FAMILY_BLUE: | |
408 if ( idx < type1->private_dict.num_family_blues ) | |
409 { | |
410 retval = sizeof ( type1->private_dict.family_blues[idx] ); | |
411 if ( value && value_len >= retval ) | |
412 *((FT_Short *)value) = type1->private_dict.family_blues[idx]; | |
413 } | |
414 break; | |
415 | |
416 case PS_DICT_NUM_FAMILY_OTHER_BLUES: | |
417 retval = sizeof ( type1->private_dict.num_family_other_blues ); | |
418 if ( value && value_len >= retval ) | |
419 *((FT_Byte *)value) = type1->private_dict.num_family_other_blues; | |
420 break; | |
421 | |
422 case PS_DICT_FAMILY_OTHER_BLUE: | |
423 if ( idx < type1->private_dict.num_family_other_blues ) | |
424 { | |
425 retval = sizeof ( type1->private_dict.family_other_blues[idx] ); | |
426 if ( value && value_len >= retval ) | |
427 *((FT_Short *)value) = type1->private_dict.family_other_blues[idx]; | |
428 } | |
429 break; | |
430 | |
431 case PS_DICT_NUM_STEM_SNAP_H: | |
432 retval = sizeof ( type1->private_dict.num_snap_widths ); | |
433 if ( value && value_len >= retval ) | |
434 *((FT_Byte *)value) = type1->private_dict.num_snap_widths; | |
435 break; | |
436 | |
437 case PS_DICT_STEM_SNAP_H: | |
438 if ( idx < type1->private_dict.num_snap_widths ) | |
439 { | |
440 retval = sizeof ( type1->private_dict.snap_widths[idx] ); | |
441 if ( value && value_len >= retval ) | |
442 *((FT_Short *)value) = type1->private_dict.snap_widths[idx]; | |
443 } | |
444 break; | |
445 | |
446 case PS_DICT_NUM_STEM_SNAP_V: | |
447 retval = sizeof ( type1->private_dict.num_snap_heights ); | |
448 if ( value && value_len >= retval ) | |
449 *((FT_Byte *)value) = type1->private_dict.num_snap_heights; | |
450 break; | |
451 | |
452 case PS_DICT_STEM_SNAP_V: | |
453 if ( idx < type1->private_dict.num_snap_heights ) | |
454 { | |
455 retval = sizeof ( type1->private_dict.snap_heights[idx] ); | |
456 if ( value && value_len >= retval ) | |
457 *((FT_Short *)value) = type1->private_dict.snap_heights[idx]; | |
458 } | |
459 break; | |
460 | |
461 case PS_DICT_RND_STEM_UP: | |
462 retval = sizeof ( type1->private_dict.round_stem_up ); | |
463 if ( value && value_len >= retval ) | |
464 *((FT_Bool *)value) = type1->private_dict.round_stem_up; | |
465 break; | |
466 | |
467 case PS_DICT_FORCE_BOLD: | |
468 retval = sizeof ( type1->private_dict.force_bold ); | |
469 if ( value && value_len >= retval ) | |
470 *((FT_Bool *)value) = type1->private_dict.force_bold; | |
471 break; | |
472 | |
473 case PS_DICT_MIN_FEATURE: | |
474 if ( idx < sizeof ( type1->private_dict.min_feature ) / | |
475 sizeof ( type1->private_dict.min_feature[0] ) ) | |
476 { | |
477 retval = sizeof ( type1->private_dict.min_feature[idx] ); | |
478 if ( value && value_len >= retval ) | |
479 *((FT_Short *)value) = type1->private_dict.min_feature[idx]; | |
480 } | |
481 break; | |
482 | |
483 case PS_DICT_LEN_IV: | |
484 retval = sizeof ( type1->private_dict.lenIV ); | |
485 if ( value && value_len >= retval ) | |
486 *((FT_Int *)value) = type1->private_dict.lenIV; | |
487 break; | |
488 | |
489 case PS_DICT_PASSWORD: | |
490 retval = sizeof ( type1->private_dict.password ); | |
491 if ( value && value_len >= retval ) | |
492 *((FT_Long *)value) = type1->private_dict.password; | |
493 break; | |
494 | |
495 case PS_DICT_LANGUAGE_GROUP: | |
496 retval = sizeof ( type1->private_dict.language_group ); | |
497 if ( value && value_len >= retval ) | |
498 *((FT_Long *)value) = type1->private_dict.language_group; | |
499 break; | |
500 | |
501 case PS_DICT_IS_FIXED_PITCH: | |
502 retval = sizeof ( type1->font_info.is_fixed_pitch ); | |
503 if ( value && value_len >= retval ) | |
504 *((FT_Bool *)value) = type1->font_info.is_fixed_pitch; | |
505 break; | |
506 | |
507 case PS_DICT_UNDERLINE_POSITION: | |
508 retval = sizeof ( type1->font_info.underline_position ); | |
509 if ( value && value_len >= retval ) | |
510 *((FT_Short *)value) = type1->font_info.underline_position; | |
511 break; | |
512 | |
513 case PS_DICT_UNDERLINE_THICKNESS: | |
514 retval = sizeof ( type1->font_info.underline_thickness ); | |
515 if ( value && value_len >= retval ) | |
516 *((FT_UShort *)value) = type1->font_info.underline_thickness; | |
517 break; | |
518 | |
519 case PS_DICT_FS_TYPE: | |
520 retval = sizeof ( type1->font_extra.fs_type ); | |
521 if ( value && value_len >= retval ) | |
522 *((FT_UShort *)value) = type1->font_extra.fs_type; | |
523 break; | |
524 | |
525 case PS_DICT_VERSION: | |
526 retval = (FT_Long)( ft_strlen( type1->font_info.version ) + 1 ); | |
527 if ( value && value_len >= retval ) | |
528 ft_memcpy( value, (void *)( type1->font_info.version ), retval ); | |
529 break; | |
530 | |
531 case PS_DICT_NOTICE: | |
532 retval = (FT_Long)( ft_strlen( type1->font_info.notice ) + 1 ); | |
533 if ( value && value_len >= retval ) | |
534 ft_memcpy( value, (void *)( type1->font_info.notice ), retval ); | |
535 break; | |
536 | |
537 case PS_DICT_FULL_NAME: | |
538 retval = (FT_Long)( ft_strlen( type1->font_info.full_name ) + 1 ); | |
539 if ( value && value_len >= retval ) | |
540 ft_memcpy( value, (void *)( type1->font_info.full_name ), retval ); | |
541 break; | |
542 | |
543 case PS_DICT_FAMILY_NAME: | |
544 retval = (FT_Long)( ft_strlen( type1->font_info.family_name ) + 1 ); | |
545 if ( value && value_len >= retval ) | |
546 ft_memcpy( value, (void *)( type1->font_info.family_name ), retval ); | |
547 break; | |
548 | |
549 case PS_DICT_WEIGHT: | |
550 retval = (FT_Long)( ft_strlen( type1->font_info.weight ) + 1 ); | |
551 if ( value && value_len >= retval ) | |
552 ft_memcpy( value, (void *)( type1->font_info.weight ), retval ); | |
553 break; | |
554 | |
555 case PS_DICT_ITALIC_ANGLE: | |
556 retval = sizeof ( type1->font_info.italic_angle ); | |
557 if ( value && value_len >= retval ) | |
558 *((FT_Long *)value) = type1->font_info.italic_angle; | |
559 break; | |
560 | |
561 default: | |
562 break; | |
563 } | |
564 | |
565 return retval; | |
566 } | |
567 | |
568 | |
569 static const FT_Service_PsInfoRec t1_service_ps_info = | |
570 { | |
571 (PS_GetFontInfoFunc) t1_ps_get_font_info, | |
572 (PS_GetFontExtraFunc) t1_ps_get_font_extra, | |
573 (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, | |
574 (PS_GetFontPrivateFunc)t1_ps_get_font_private, | |
575 (PS_GetFontValueFunc) t1_ps_get_font_value, | |
576 }; | |
577 | |
578 | |
579 #ifndef T1_CONFIG_OPTION_NO_AFM | |
580 static const FT_Service_KerningRec t1_service_kerning = | |
581 { | |
582 T1_Get_Track_Kerning, | |
583 }; | |
584 #endif | |
585 | |
586 | |
587 /* | |
588 * SERVICE LIST | |
589 * | |
590 */ | |
591 | |
592 static const FT_ServiceDescRec t1_services[] = | |
593 { | |
594 { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &t1_service_ps_name }, | |
595 { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict }, | |
596 { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TYPE_1 }, | |
597 { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info }, | |
598 | |
599 #ifndef T1_CONFIG_OPTION_NO_AFM | |
600 { FT_SERVICE_ID_KERNING, &t1_service_kerning }, | |
601 #endif | |
602 | |
603 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT | |
604 { FT_SERVICE_ID_MULTI_MASTERS, &t1_service_multi_masters }, | |
605 #endif | |
606 { NULL, NULL } | |
607 }; | |
608 | |
609 | |
610 FT_CALLBACK_DEF( FT_Module_Interface ) | |
611 Get_Interface( FT_Module module, | |
612 const FT_String* t1_interface ) | |
613 { | |
614 FT_UNUSED( module ); | |
615 | |
616 return ft_service_list_lookup( t1_services, t1_interface ); | |
617 } | |
618 | |
619 | |
620 #ifndef T1_CONFIG_OPTION_NO_AFM | |
621 | |
622 /*************************************************************************/ | |
623 /* */ | |
624 /* <Function> */ | |
625 /* Get_Kerning */ | |
626 /* */ | |
627 /* <Description> */ | |
628 /* A driver method used to return the kerning vector between two */ | |
629 /* glyphs of the same face. */ | |
630 /* */ | |
631 /* <Input> */ | |
632 /* face :: A handle to the source face object. */ | |
633 /* */ | |
634 /* left_glyph :: The index of the left glyph in the kern pair. */ | |
635 /* */ | |
636 /* right_glyph :: The index of the right glyph in the kern pair. */ | |
637 /* */ | |
638 /* <Output> */ | |
639 /* kerning :: The kerning vector. This is in font units for */ | |
640 /* scalable formats, and in pixels for fixed-sizes */ | |
641 /* formats. */ | |
642 /* */ | |
643 /* <Return> */ | |
644 /* FreeType error code. 0 means success. */ | |
645 /* */ | |
646 /* <Note> */ | |
647 /* Only horizontal layouts (left-to-right & right-to-left) are */ | |
648 /* supported by this function. Other layouts, or more sophisticated */ | |
649 /* kernings are out of scope of this method (the basic driver */ | |
650 /* interface is meant to be simple). */ | |
651 /* */ | |
652 /* They can be implemented by format-specific interfaces. */ | |
653 /* */ | |
654 static FT_Error | |
655 Get_Kerning( FT_Face t1face, /* T1_Face */ | |
656 FT_UInt left_glyph, | |
657 FT_UInt right_glyph, | |
658 FT_Vector* kerning ) | |
659 { | |
660 T1_Face face = (T1_Face)t1face; | |
661 | |
662 | |
663 kerning->x = 0; | |
664 kerning->y = 0; | |
665 | |
666 if ( face->afm_data ) | |
667 T1_Get_Kerning( (AFM_FontInfo)face->afm_data, | |
668 left_glyph, | |
669 right_glyph, | |
670 kerning ); | |
671 | |
672 return FT_Err_Ok; | |
673 } | |
674 | |
675 | |
676 #endif /* T1_CONFIG_OPTION_NO_AFM */ | |
677 | |
678 | |
679 FT_CALLBACK_TABLE_DEF | |
680 const FT_Driver_ClassRec t1_driver_class = | |
681 { | |
682 { | |
683 FT_MODULE_FONT_DRIVER | | |
684 FT_MODULE_DRIVER_SCALABLE | | |
685 FT_MODULE_DRIVER_HAS_HINTER, | |
686 | |
687 sizeof ( FT_DriverRec ), | |
688 | |
689 "type1", | |
690 0x10000L, | |
691 0x20000L, | |
692 | |
693 0, /* format interface */ | |
694 | |
695 T1_Driver_Init, | |
696 T1_Driver_Done, | |
697 Get_Interface, | |
698 }, | |
699 | |
700 sizeof ( T1_FaceRec ), | |
701 sizeof ( T1_SizeRec ), | |
702 sizeof ( T1_GlyphSlotRec ), | |
703 | |
704 T1_Face_Init, | |
705 T1_Face_Done, | |
706 T1_Size_Init, | |
707 T1_Size_Done, | |
708 T1_GlyphSlot_Init, | |
709 T1_GlyphSlot_Done, | |
710 | |
711 T1_Load_Glyph, | |
712 | |
713 #ifdef T1_CONFIG_OPTION_NO_AFM | |
714 0, /* FT_Face_GetKerningFunc */ | |
715 0, /* FT_Face_AttachFunc */ | |
716 #else | |
717 Get_Kerning, | |
718 T1_Read_Metrics, | |
719 #endif | |
720 T1_Get_Advances, | |
721 T1_Size_Request, | |
722 0 /* FT_Size_SelectFunc */ | |
723 }; | |
724 | |
725 | |
726 /* END */ | |
OLD | NEW |