Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 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 |
||
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_XFREE86_NAME_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, |
||
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 | /* |
||
625 | /* Get_Kerning */ |
||
626 | /* */ |
||
627 | /* |
||
628 | /* A driver method used to return the kerning vector between two */ |
||
629 | /* glyphs of the same face. */ |
||
630 | /* */ |
||
631 | /* */ |
||
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 | /* |
||
639 | /* kerning :: The kerning vector. This is in font units for */ |
||
640 | /* scalable formats, and in pixels for fixed-sizes */ |
||
641 | /* formats. */ |
||
642 | /* */ |
||
643 | /* |
||
644 | /* FreeType error code. 0 means success. */ |
||
645 | /* */ |
||
646 | /* |
||
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 | |||
723 | }; |
||
724 | |||
725 | |||
726 | /* END */>>>>>>>>>>>>>> |