OLD | NEW |
| (Empty) |
1 /***************************************************************************/ | |
2 /* */ | |
3 /* cffdrivr.c */ | |
4 /* */ | |
5 /* OpenType font driver implementation (body). */ | |
6 /* */ | |
7 /* Copyright 1996-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 "../../include/freetype/freetype.h" | |
21 #include "../../include/freetype/internal/ftdebug.h" | |
22 #include "../../include/freetype/internal/ftstream.h" | |
23 #include "../../include/freetype/internal/sfnt.h" | |
24 #include "../../include/freetype/internal/services/svcid.h" | |
25 #include "../../include/freetype/internal/services/svpsinfo.h" | |
26 #include "../../include/freetype/internal/services/svpostnm.h" | |
27 #include "../../include/freetype/internal/services/svttcmap.h" | |
28 | |
29 #include "cffdrivr.h" | |
30 #include "cffgload.h" | |
31 #include "cffload.h" | |
32 #include "cffcmap.h" | |
33 #include "cffparse.h" | |
34 | |
35 #include "cfferrs.h" | |
36 #include "cffpic.h" | |
37 | |
38 #include "../../include/freetype/internal/services/svxf86nm.h" | |
39 #include "../../include/freetype/internal/services/svgldict.h" | |
40 #include "../../include/freetype/internal/services/svprop.h" | |
41 #include "../../include/freetype/ftcffdrv.h" | |
42 | |
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 trace_cffdriver | |
53 | |
54 | |
55 /*************************************************************************/ | |
56 /*************************************************************************/ | |
57 /*************************************************************************/ | |
58 /**** ****/ | |
59 /**** ****/ | |
60 /**** F A C E S ****/ | |
61 /**** ****/ | |
62 /**** ****/ | |
63 /*************************************************************************/ | |
64 /*************************************************************************/ | |
65 /*************************************************************************/ | |
66 | |
67 | |
68 #undef PAIR_TAG | |
69 #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ | |
70 (FT_ULong)right ) | |
71 | |
72 | |
73 /*************************************************************************/ | |
74 /* */ | |
75 /* <Function> */ | |
76 /* cff_get_kerning */ | |
77 /* */ | |
78 /* <Description> */ | |
79 /* A driver method used to return the kerning vector between two */ | |
80 /* glyphs of the same face. */ | |
81 /* */ | |
82 /* <Input> */ | |
83 /* face :: A handle to the source face object. */ | |
84 /* */ | |
85 /* left_glyph :: The index of the left glyph in the kern pair. */ | |
86 /* */ | |
87 /* right_glyph :: The index of the right glyph in the kern pair. */ | |
88 /* */ | |
89 /* <Output> */ | |
90 /* kerning :: The kerning vector. This is in font units for */ | |
91 /* scalable formats, and in pixels for fixed-sizes */ | |
92 /* formats. */ | |
93 /* */ | |
94 /* <Return> */ | |
95 /* FreeType error code. 0 means success. */ | |
96 /* */ | |
97 /* <Note> */ | |
98 /* Only horizontal layouts (left-to-right & right-to-left) are */ | |
99 /* supported by this function. Other layouts, or more sophisticated */ | |
100 /* kernings, are out of scope of this method (the basic driver */ | |
101 /* interface is meant to be simple). */ | |
102 /* */ | |
103 /* They can be implemented by format-specific interfaces. */ | |
104 /* */ | |
105 FT_CALLBACK_DEF( FT_Error ) | |
106 cff_get_kerning( FT_Face ttface, /* TT_Face */ | |
107 FT_UInt left_glyph, | |
108 FT_UInt right_glyph, | |
109 FT_Vector* kerning ) | |
110 { | |
111 TT_Face face = (TT_Face)ttface; | |
112 SFNT_Service sfnt = (SFNT_Service)face->sfnt; | |
113 | |
114 | |
115 kerning->x = 0; | |
116 kerning->y = 0; | |
117 | |
118 if ( sfnt ) | |
119 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); | |
120 | |
121 return FT_Err_Ok; | |
122 } | |
123 | |
124 | |
125 #undef PAIR_TAG | |
126 | |
127 | |
128 /*************************************************************************/ | |
129 /* */ | |
130 /* <Function> */ | |
131 /* cff_glyph_load */ | |
132 /* */ | |
133 /* <Description> */ | |
134 /* A driver method used to load a glyph within a given glyph slot. */ | |
135 /* */ | |
136 /* <Input> */ | |
137 /* slot :: A handle to the target slot object where the glyph */ | |
138 /* will be loaded. */ | |
139 /* */ | |
140 /* size :: A handle to the source face size at which the glyph */ | |
141 /* must be scaled, loaded, etc. */ | |
142 /* */ | |
143 /* glyph_index :: The index of the glyph in the font file. */ | |
144 /* */ | |
145 /* load_flags :: A flag indicating what to load for this glyph. The */ | |
146 /* FT_LOAD_??? constants can be used to control the */ | |
147 /* glyph loading process (e.g., whether the outline */ | |
148 /* should be scaled, whether to load bitmaps or not, */ | |
149 /* whether to hint the outline, etc). */ | |
150 /* */ | |
151 /* <Return> */ | |
152 /* FreeType error code. 0 means success. */ | |
153 /* */ | |
154 FT_CALLBACK_DEF( FT_Error ) | |
155 cff_glyph_load( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */ | |
156 FT_Size cffsize, /* CFF_Size */ | |
157 FT_UInt glyph_index, | |
158 FT_Int32 load_flags ) | |
159 { | |
160 FT_Error error; | |
161 CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; | |
162 CFF_Size size = (CFF_Size)cffsize; | |
163 | |
164 | |
165 if ( !slot ) | |
166 return FT_THROW( Invalid_Slot_Handle ); | |
167 | |
168 /* check whether we want a scaled outline or bitmap */ | |
169 if ( !size ) | |
170 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; | |
171 | |
172 /* reset the size object if necessary */ | |
173 if ( load_flags & FT_LOAD_NO_SCALE ) | |
174 size = NULL; | |
175 | |
176 if ( size ) | |
177 { | |
178 /* these two objects must have the same parent */ | |
179 if ( cffsize->face != cffslot->face ) | |
180 return FT_THROW( Invalid_Face_Handle ); | |
181 } | |
182 | |
183 /* now load the glyph outline if necessary */ | |
184 error = cff_slot_load( slot, size, glyph_index, load_flags ); | |
185 | |
186 /* force drop-out mode to 2 - irrelevant now */ | |
187 /* slot->outline.dropout_mode = 2; */ | |
188 | |
189 return error; | |
190 } | |
191 | |
192 | |
193 FT_CALLBACK_DEF( FT_Error ) | |
194 cff_get_advances( FT_Face face, | |
195 FT_UInt start, | |
196 FT_UInt count, | |
197 FT_Int32 flags, | |
198 FT_Fixed* advances ) | |
199 { | |
200 FT_UInt nn; | |
201 FT_Error error = FT_Err_Ok; | |
202 FT_GlyphSlot slot = face->glyph; | |
203 | |
204 | |
205 flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; | |
206 | |
207 for ( nn = 0; nn < count; nn++ ) | |
208 { | |
209 error = cff_glyph_load( slot, face->size, start + nn, flags ); | |
210 if ( error ) | |
211 break; | |
212 | |
213 advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) | |
214 ? slot->linearVertAdvance | |
215 : slot->linearHoriAdvance; | |
216 } | |
217 | |
218 return error; | |
219 } | |
220 | |
221 | |
222 /* | |
223 * GLYPH DICT SERVICE | |
224 * | |
225 */ | |
226 | |
227 static FT_Error | |
228 cff_get_glyph_name( CFF_Face face, | |
229 FT_UInt glyph_index, | |
230 FT_Pointer buffer, | |
231 FT_UInt buffer_max ) | |
232 { | |
233 CFF_Font font = (CFF_Font)face->extra.data; | |
234 FT_String* gname; | |
235 FT_UShort sid; | |
236 FT_Error error; | |
237 | |
238 | |
239 if ( !font->psnames ) | |
240 { | |
241 FT_ERROR(( "cff_get_glyph_name:" | |
242 " cannot get glyph name from CFF & CEF fonts\n" | |
243 " " | |
244 " without the `PSNames' module\n" )); | |
245 error = FT_THROW( Missing_Module ); | |
246 goto Exit; | |
247 } | |
248 | |
249 /* first, locate the sid in the charset table */ | |
250 sid = font->charset.sids[glyph_index]; | |
251 | |
252 /* now, lookup the name itself */ | |
253 gname = cff_index_get_sid_string( font, sid ); | |
254 | |
255 if ( gname ) | |
256 FT_STRCPYN( buffer, gname, buffer_max ); | |
257 | |
258 error = FT_Err_Ok; | |
259 | |
260 Exit: | |
261 return error; | |
262 } | |
263 | |
264 | |
265 static FT_UInt | |
266 cff_get_name_index( CFF_Face face, | |
267 FT_String* glyph_name ) | |
268 { | |
269 CFF_Font cff; | |
270 CFF_Charset charset; | |
271 FT_Service_PsCMaps psnames; | |
272 FT_String* name; | |
273 FT_UShort sid; | |
274 FT_UInt i; | |
275 | |
276 | |
277 cff = (CFF_FontRec *)face->extra.data; | |
278 charset = &cff->charset; | |
279 | |
280 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); | |
281 if ( !psnames ) | |
282 return 0; | |
283 | |
284 for ( i = 0; i < cff->num_glyphs; i++ ) | |
285 { | |
286 sid = charset->sids[i]; | |
287 | |
288 if ( sid > 390 ) | |
289 name = cff_index_get_string( cff, sid - 391 ); | |
290 else | |
291 name = (FT_String *)psnames->adobe_std_strings( sid ); | |
292 | |
293 if ( !name ) | |
294 continue; | |
295 | |
296 if ( !ft_strcmp( glyph_name, name ) ) | |
297 return i; | |
298 } | |
299 | |
300 return 0; | |
301 } | |
302 | |
303 | |
304 FT_DEFINE_SERVICE_GLYPHDICTREC( | |
305 cff_service_glyph_dict, | |
306 (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, | |
307 (FT_GlyphDict_NameIndexFunc)cff_get_name_index | |
308 ) | |
309 | |
310 | |
311 /* | |
312 * POSTSCRIPT INFO SERVICE | |
313 * | |
314 */ | |
315 | |
316 static FT_Int | |
317 cff_ps_has_glyph_names( FT_Face face ) | |
318 { | |
319 return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; | |
320 } | |
321 | |
322 | |
323 static FT_Error | |
324 cff_ps_get_font_info( CFF_Face face, | |
325 PS_FontInfoRec* afont_info ) | |
326 { | |
327 CFF_Font cff = (CFF_Font)face->extra.data; | |
328 FT_Error error = FT_Err_Ok; | |
329 | |
330 | |
331 if ( cff && cff->font_info == NULL ) | |
332 { | |
333 CFF_FontRecDict dict = &cff->top_font.font_dict; | |
334 PS_FontInfoRec *font_info = NULL; | |
335 FT_Memory memory = face->root.memory; | |
336 | |
337 | |
338 if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) | |
339 goto Fail; | |
340 | |
341 font_info->version = cff_index_get_sid_string( cff, | |
342 dict->version ); | |
343 font_info->notice = cff_index_get_sid_string( cff, | |
344 dict->notice ); | |
345 font_info->full_name = cff_index_get_sid_string( cff, | |
346 dict->full_name ); | |
347 font_info->family_name = cff_index_get_sid_string( cff, | |
348 dict->family_name ); | |
349 font_info->weight = cff_index_get_sid_string( cff, | |
350 dict->weight ); | |
351 font_info->italic_angle = dict->italic_angle; | |
352 font_info->is_fixed_pitch = dict->is_fixed_pitch; | |
353 font_info->underline_position = (FT_Short)dict->underline_position; | |
354 font_info->underline_thickness = (FT_Short)dict->underline_thickness; | |
355 | |
356 cff->font_info = font_info; | |
357 } | |
358 | |
359 if ( cff ) | |
360 *afont_info = *cff->font_info; | |
361 | |
362 Fail: | |
363 return error; | |
364 } | |
365 | |
366 | |
367 FT_DEFINE_SERVICE_PSINFOREC( | |
368 cff_service_ps_info, | |
369 (PS_GetFontInfoFunc) cff_ps_get_font_info, | |
370 (PS_GetFontExtraFunc) NULL, | |
371 (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, | |
372 (PS_GetFontPrivateFunc)NULL, /* unsupported with CFF fonts */ | |
373 (PS_GetFontValueFunc) NULL /* not implemented */ | |
374 ) | |
375 | |
376 | |
377 /* | |
378 * POSTSCRIPT NAME SERVICE | |
379 * | |
380 */ | |
381 | |
382 static const char* | |
383 cff_get_ps_name( CFF_Face face ) | |
384 { | |
385 CFF_Font cff = (CFF_Font)face->extra.data; | |
386 | |
387 | |
388 return (const char*)cff->font_name; | |
389 } | |
390 | |
391 | |
392 FT_DEFINE_SERVICE_PSFONTNAMEREC( | |
393 cff_service_ps_name, | |
394 (FT_PsName_GetFunc)cff_get_ps_name | |
395 ) | |
396 | |
397 | |
398 /* | |
399 * TT CMAP INFO | |
400 * | |
401 * If the charmap is a synthetic Unicode encoding cmap or | |
402 * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO | |
403 * service defined in SFNT module. | |
404 * | |
405 * Otherwise call the service function in the sfnt module. | |
406 * | |
407 */ | |
408 static FT_Error | |
409 cff_get_cmap_info( FT_CharMap charmap, | |
410 TT_CMapInfo *cmap_info ) | |
411 { | |
412 FT_CMap cmap = FT_CMAP( charmap ); | |
413 FT_Error error = FT_Err_Ok; | |
414 | |
415 FT_Face face = FT_CMAP_FACE( cmap ); | |
416 FT_Library library = FT_FACE_LIBRARY( face ); | |
417 | |
418 | |
419 cmap_info->language = 0; | |
420 cmap_info->format = 0; | |
421 | |
422 if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET && | |
423 cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET ) | |
424 { | |
425 FT_Module sfnt = FT_Get_Module( library, "sfnt" ); | |
426 FT_Service_TTCMaps service = | |
427 (FT_Service_TTCMaps)ft_module_get_service( sfnt, | |
428 FT_SERVICE_ID_TT_CMAP ); | |
429 | |
430 | |
431 if ( service && service->get_cmap_info ) | |
432 error = service->get_cmap_info( charmap, cmap_info ); | |
433 } | |
434 | |
435 return error; | |
436 } | |
437 | |
438 | |
439 FT_DEFINE_SERVICE_TTCMAPSREC( | |
440 cff_service_get_cmap_info, | |
441 (TT_CMap_Info_GetFunc)cff_get_cmap_info | |
442 ) | |
443 | |
444 | |
445 /* | |
446 * CID INFO SERVICE | |
447 * | |
448 */ | |
449 static FT_Error | |
450 cff_get_ros( CFF_Face face, | |
451 const char* *registry, | |
452 const char* *ordering, | |
453 FT_Int *supplement ) | |
454 { | |
455 FT_Error error = FT_Err_Ok; | |
456 CFF_Font cff = (CFF_Font)face->extra.data; | |
457 | |
458 | |
459 if ( cff ) | |
460 { | |
461 CFF_FontRecDict dict = &cff->top_font.font_dict; | |
462 | |
463 | |
464 if ( dict->cid_registry == 0xFFFFU ) | |
465 { | |
466 error = FT_THROW( Invalid_Argument ); | |
467 goto Fail; | |
468 } | |
469 | |
470 if ( registry ) | |
471 { | |
472 if ( cff->registry == NULL ) | |
473 cff->registry = cff_index_get_sid_string( cff, | |
474 dict->cid_registry ); | |
475 *registry = cff->registry; | |
476 } | |
477 | |
478 if ( ordering ) | |
479 { | |
480 if ( cff->ordering == NULL ) | |
481 cff->ordering = cff_index_get_sid_string( cff, | |
482 dict->cid_ordering ); | |
483 *ordering = cff->ordering; | |
484 } | |
485 | |
486 /* | |
487 * XXX: According to Adobe TechNote #5176, the supplement in CFF | |
488 * can be a real number. We truncate it to fit public API | |
489 * since freetype-2.3.6. | |
490 */ | |
491 if ( supplement ) | |
492 { | |
493 if ( dict->cid_supplement < FT_INT_MIN || | |
494 dict->cid_supplement > FT_INT_MAX ) | |
495 FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n", | |
496 dict->cid_supplement )); | |
497 *supplement = (FT_Int)dict->cid_supplement; | |
498 } | |
499 } | |
500 | |
501 Fail: | |
502 return error; | |
503 } | |
504 | |
505 | |
506 static FT_Error | |
507 cff_get_is_cid( CFF_Face face, | |
508 FT_Bool *is_cid ) | |
509 { | |
510 FT_Error error = FT_Err_Ok; | |
511 CFF_Font cff = (CFF_Font)face->extra.data; | |
512 | |
513 | |
514 *is_cid = 0; | |
515 | |
516 if ( cff ) | |
517 { | |
518 CFF_FontRecDict dict = &cff->top_font.font_dict; | |
519 | |
520 | |
521 if ( dict->cid_registry != 0xFFFFU ) | |
522 *is_cid = 1; | |
523 } | |
524 | |
525 return error; | |
526 } | |
527 | |
528 | |
529 static FT_Error | |
530 cff_get_cid_from_glyph_index( CFF_Face face, | |
531 FT_UInt glyph_index, | |
532 FT_UInt *cid ) | |
533 { | |
534 FT_Error error = FT_Err_Ok; | |
535 CFF_Font cff; | |
536 | |
537 | |
538 cff = (CFF_Font)face->extra.data; | |
539 | |
540 if ( cff ) | |
541 { | |
542 FT_UInt c; | |
543 CFF_FontRecDict dict = &cff->top_font.font_dict; | |
544 | |
545 | |
546 if ( dict->cid_registry == 0xFFFFU ) | |
547 { | |
548 error = FT_THROW( Invalid_Argument ); | |
549 goto Fail; | |
550 } | |
551 | |
552 if ( glyph_index > cff->num_glyphs ) | |
553 { | |
554 error = FT_THROW( Invalid_Argument ); | |
555 goto Fail; | |
556 } | |
557 | |
558 c = cff->charset.sids[glyph_index]; | |
559 | |
560 if ( cid ) | |
561 *cid = c; | |
562 } | |
563 | |
564 Fail: | |
565 return error; | |
566 } | |
567 | |
568 | |
569 FT_DEFINE_SERVICE_CIDREC( | |
570 cff_service_cid_info, | |
571 (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, | |
572 (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, | |
573 (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index | |
574 ) | |
575 | |
576 | |
577 /* | |
578 * PROPERTY SERVICE | |
579 * | |
580 */ | |
581 static FT_Error | |
582 cff_property_set( FT_Module module, /* CFF_Driver */ | |
583 const char* property_name, | |
584 const void* value ) | |
585 { | |
586 FT_Error error = FT_Err_Ok; | |
587 CFF_Driver driver = (CFF_Driver)module; | |
588 | |
589 | |
590 if ( !ft_strcmp( property_name, "hinting-engine" ) ) | |
591 { | |
592 FT_UInt* hinting_engine = (FT_UInt*)value; | |
593 | |
594 | |
595 #ifndef CFF_CONFIG_OPTION_OLD_ENGINE | |
596 if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) | |
597 error = FT_ERR( Unimplemented_Feature ); | |
598 else | |
599 #endif | |
600 driver->hinting_engine = *hinting_engine; | |
601 | |
602 return error; | |
603 } | |
604 else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) | |
605 { | |
606 FT_Bool* no_stem_darkening = (FT_Bool*)value; | |
607 | |
608 | |
609 driver->no_stem_darkening = *no_stem_darkening; | |
610 | |
611 return error; | |
612 } | |
613 | |
614 FT_TRACE0(( "cff_property_set: missing property `%s'\n", | |
615 property_name )); | |
616 return FT_THROW( Missing_Property ); | |
617 } | |
618 | |
619 | |
620 static FT_Error | |
621 cff_property_get( FT_Module module, /* CFF_Driver */ | |
622 const char* property_name, | |
623 const void* value ) | |
624 { | |
625 FT_Error error = FT_Err_Ok; | |
626 CFF_Driver driver = (CFF_Driver)module; | |
627 | |
628 FT_UInt hinting_engine = driver->hinting_engine; | |
629 FT_Bool no_stem_darkening = driver->no_stem_darkening; | |
630 | |
631 | |
632 if ( !ft_strcmp( property_name, "hinting-engine" ) ) | |
633 { | |
634 FT_UInt* val = (FT_UInt*)value; | |
635 | |
636 | |
637 *val = hinting_engine; | |
638 | |
639 return error; | |
640 } | |
641 else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) | |
642 { | |
643 FT_Bool* val = (FT_Bool*)value; | |
644 | |
645 | |
646 *val = no_stem_darkening; | |
647 | |
648 return error; | |
649 } | |
650 | |
651 FT_TRACE0(( "cff_property_get: missing property `%s'\n", | |
652 property_name )); | |
653 return FT_THROW( Missing_Property ); | |
654 } | |
655 | |
656 | |
657 FT_DEFINE_SERVICE_PROPERTIESREC( | |
658 cff_service_properties, | |
659 (FT_Properties_SetFunc)cff_property_set, | |
660 (FT_Properties_GetFunc)cff_property_get ) | |
661 | |
662 | |
663 /*************************************************************************/ | |
664 /*************************************************************************/ | |
665 /*************************************************************************/ | |
666 /**** ****/ | |
667 /**** ****/ | |
668 /**** D R I V E R I N T E R F A C E ****/ | |
669 /**** ****/ | |
670 /**** ****/ | |
671 /*************************************************************************/ | |
672 /*************************************************************************/ | |
673 /*************************************************************************/ | |
674 | |
675 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES | |
676 FT_DEFINE_SERVICEDESCREC7( | |
677 cff_services, | |
678 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, | |
679 FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, | |
680 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, | |
681 FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, | |
682 FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, | |
683 FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, | |
684 FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET | |
685 ) | |
686 #else | |
687 FT_DEFINE_SERVICEDESCREC6( | |
688 cff_services, | |
689 FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF, | |
690 FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, | |
691 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, | |
692 FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, | |
693 FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, | |
694 FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET | |
695 ) | |
696 #endif | |
697 | |
698 | |
699 FT_CALLBACK_DEF( FT_Module_Interface ) | |
700 cff_get_interface( FT_Module driver, /* CFF_Driver */ | |
701 const char* module_interface ) | |
702 { | |
703 FT_Library library; | |
704 FT_Module sfnt; | |
705 FT_Module_Interface result; | |
706 | |
707 | |
708 /* CFF_SERVICES_GET derefers `library' in PIC mode */ | |
709 #ifdef FT_CONFIG_OPTION_PIC | |
710 if ( !driver ) | |
711 return NULL; | |
712 library = driver->library; | |
713 if ( !library ) | |
714 return NULL; | |
715 #endif | |
716 | |
717 result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface ); | |
718 if ( result != NULL ) | |
719 return result; | |
720 | |
721 /* `driver' is not yet evaluated in non-PIC mode */ | |
722 #ifndef FT_CONFIG_OPTION_PIC | |
723 if ( !driver ) | |
724 return NULL; | |
725 library = driver->library; | |
726 if ( !library ) | |
727 return NULL; | |
728 #endif | |
729 | |
730 /* we pass our request to the `sfnt' module */ | |
731 sfnt = FT_Get_Module( library, "sfnt" ); | |
732 | |
733 return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; | |
734 } | |
735 | |
736 | |
737 /* The FT_DriverInterface structure is defined in ftdriver.h. */ | |
738 | |
739 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS | |
740 #define CFF_SIZE_SELECT cff_size_select | |
741 #else | |
742 #define CFF_SIZE_SELECT 0 | |
743 #endif | |
744 | |
745 FT_DEFINE_DRIVER( | |
746 cff_driver_class, | |
747 | |
748 FT_MODULE_FONT_DRIVER | | |
749 FT_MODULE_DRIVER_SCALABLE | | |
750 FT_MODULE_DRIVER_HAS_HINTER, | |
751 | |
752 sizeof ( CFF_DriverRec ), | |
753 "cff", | |
754 0x10000L, | |
755 0x20000L, | |
756 | |
757 0, /* module-specific interface */ | |
758 | |
759 cff_driver_init, | |
760 cff_driver_done, | |
761 cff_get_interface, | |
762 | |
763 /* now the specific driver fields */ | |
764 sizeof ( TT_FaceRec ), | |
765 sizeof ( CFF_SizeRec ), | |
766 sizeof ( CFF_GlyphSlotRec ), | |
767 | |
768 cff_face_init, | |
769 cff_face_done, | |
770 cff_size_init, | |
771 cff_size_done, | |
772 cff_slot_init, | |
773 cff_slot_done, | |
774 | |
775 cff_glyph_load, | |
776 | |
777 cff_get_kerning, | |
778 0, /* FT_Face_AttachFunc */ | |
779 cff_get_advances, | |
780 | |
781 cff_size_request, | |
782 | |
783 CFF_SIZE_SELECT | |
784 ) | |
785 | |
786 | |
787 /* END */ | |
OLD | NEW |