1/***************************************************************************/
2/* */
3/* cffdrivr.c */
4/* */
5/* OpenType font driver implementation (body). */
6/* */
7/* Copyright 1996-2018 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 FT_FREETYPE_H
21#include FT_INTERNAL_DEBUG_H
22#include FT_INTERNAL_STREAM_H
23#include FT_INTERNAL_SFNT_H
24#include FT_INTERNAL_POSTSCRIPT_AUX_H
25#include FT_INTERNAL_POSTSCRIPT_PROPS_H
26#include FT_SERVICE_CID_H
27#include FT_SERVICE_POSTSCRIPT_INFO_H
28#include FT_SERVICE_POSTSCRIPT_NAME_H
29#include FT_SERVICE_TT_CMAP_H
30#include FT_SERVICE_CFF_TABLE_LOAD_H
31
32#include "cffdrivr.h"
33#include "cffgload.h"
34#include "cffload.h"
35#include "cffcmap.h"
36#include "cffparse.h"
37#include "cffobjs.h"
38
39#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
40#include FT_SERVICE_MULTIPLE_MASTERS_H
41#include FT_SERVICE_METRICS_VARIATIONS_H
42#endif
43
44#include "cfferrs.h"
45#include "cffpic.h"
46
47#include FT_SERVICE_FONT_FORMAT_H
48#include FT_SERVICE_GLYPH_DICT_H
49#include FT_SERVICE_PROPERTIES_H
50#include FT_DRIVER_H
51
52
53 /*************************************************************************/
54 /* */
55 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
56 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
57 /* messages during execution. */
58 /* */
59#undef FT_COMPONENT
60#define FT_COMPONENT trace_cffdriver
61
62
63 /*************************************************************************/
64 /*************************************************************************/
65 /*************************************************************************/
66 /**** ****/
67 /**** ****/
68 /**** F A C E S ****/
69 /**** ****/
70 /**** ****/
71 /*************************************************************************/
72 /*************************************************************************/
73 /*************************************************************************/
74
75
76 /*************************************************************************/
77 /* */
78 /* <Function> */
79 /* cff_get_kerning */
80 /* */
81 /* <Description> */
82 /* A driver method used to return the kerning vector between two */
83 /* glyphs of the same face. */
84 /* */
85 /* <Input> */
86 /* face :: A handle to the source face object. */
87 /* */
88 /* left_glyph :: The index of the left glyph in the kern pair. */
89 /* */
90 /* right_glyph :: The index of the right glyph in the kern pair. */
91 /* */
92 /* <Output> */
93 /* kerning :: The kerning vector. This is in font units for */
94 /* scalable formats, and in pixels for fixed-sizes */
95 /* formats. */
96 /* */
97 /* <Return> */
98 /* FreeType error code. 0 means success. */
99 /* */
100 /* <Note> */
101 /* Only horizontal layouts (left-to-right & right-to-left) are */
102 /* supported by this function. Other layouts, or more sophisticated */
103 /* kernings, are out of scope of this method (the basic driver */
104 /* interface is meant to be simple). */
105 /* */
106 /* They can be implemented by format-specific interfaces. */
107 /* */
108 FT_CALLBACK_DEF( FT_Error )
109 cff_get_kerning( FT_Face ttface, /* TT_Face */
110 FT_UInt left_glyph,
111 FT_UInt right_glyph,
112 FT_Vector* kerning )
113 {
114 TT_Face face = (TT_Face)ttface;
115 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
116
117
118 kerning->x = 0;
119 kerning->y = 0;
120
121 if ( sfnt )
122 kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
123
124 return FT_Err_Ok;
125 }
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 FT_TRACE1(( "cff_glyph_load: glyph index %d\n", glyph_index ));
169
170 /* check whether we want a scaled outline or bitmap */
171 if ( !size )
172 load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
173
174 /* reset the size object if necessary */
175 if ( load_flags & FT_LOAD_NO_SCALE )
176 size = NULL;
177
178 if ( size )
179 {
180 /* these two objects must have the same parent */
181 if ( cffsize->face != cffslot->face )
182 return FT_THROW( Invalid_Face_Handle );
183 }
184
185 /* now load the glyph outline if necessary */
186 error = cff_slot_load( slot, size, glyph_index, load_flags );
187
188 /* force drop-out mode to 2 - irrelevant now */
189 /* slot->outline.dropout_mode = 2; */
190
191 return error;
192 }
193
194
195 FT_CALLBACK_DEF( FT_Error )
196 cff_get_advances( FT_Face face,
197 FT_UInt start,
198 FT_UInt count,
199 FT_Int32 flags,
200 FT_Fixed* advances )
201 {
202 FT_UInt nn;
203 FT_Error error = FT_Err_Ok;
204 FT_GlyphSlot slot = face->glyph;
205
206
207 if ( FT_IS_SFNT( face ) )
208 {
209 /* OpenType 1.7 mandates that the data from `hmtx' table be used; */
210 /* it is no longer necessary that those values are identical to */
211 /* the values in the `CFF' table */
212
213 TT_Face ttface = (TT_Face)face;
214 FT_Short dummy;
215
216
217 if ( flags & FT_LOAD_VERTICAL_LAYOUT )
218 {
219#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
220 /* no fast retrieval for blended MM fonts without VVAR table */
221 if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
222 !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
223 return FT_THROW( Unimplemented_Feature );
224#endif
225
226 /* check whether we have data from the `vmtx' table at all; */
227 /* otherwise we extract the info from the CFF glyphstrings */
228 /* (instead of synthesizing a global value using the `OS/2' */
229 /* table) */
230 if ( !ttface->vertical_info )
231 goto Missing_Table;
232
233 for ( nn = 0; nn < count; nn++ )
234 {
235 FT_UShort ah;
236
237
238 ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
239 1,
240 start + nn,
241 &dummy,
242 &ah );
243
244 FT_TRACE5(( " idx %d: advance height %d font unit%s\n",
245 start + nn,
246 ah,
247 ah == 1 ? "" : "s" ));
248 advances[nn] = ah;
249 }
250 }
251 else
252 {
253#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
254 /* no fast retrieval for blended MM fonts without HVAR table */
255 if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
256 !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
257 return FT_THROW( Unimplemented_Feature );
258#endif
259
260 /* check whether we have data from the `hmtx' table at all */
261 if ( !ttface->horizontal.number_Of_HMetrics )
262 goto Missing_Table;
263
264 for ( nn = 0; nn < count; nn++ )
265 {
266 FT_UShort aw;
267
268
269 ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
270 0,
271 start + nn,
272 &dummy,
273 &aw );
274
275 FT_TRACE5(( " idx %d: advance width %d font unit%s\n",
276 start + nn,
277 aw,
278 aw == 1 ? "" : "s" ));
279 advances[nn] = aw;
280 }
281 }
282
283 return error;
284 }
285
286 Missing_Table:
287 flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
288
289 for ( nn = 0; nn < count; nn++ )
290 {
291 error = cff_glyph_load( slot, face->size, start + nn, flags );
292 if ( error )
293 break;
294
295 advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
296 ? slot->linearVertAdvance
297 : slot->linearHoriAdvance;
298 }
299
300 return error;
301 }
302
303
304 /*
305 * GLYPH DICT SERVICE
306 *
307 */
308
309 static FT_Error
310 cff_get_glyph_name( CFF_Face face,
311 FT_UInt glyph_index,
312 FT_Pointer buffer,
313 FT_UInt buffer_max )
314 {
315 CFF_Font font = (CFF_Font)face->extra.data;
316 FT_String* gname;
317 FT_UShort sid;
318 FT_Error error;
319
320
321 /* CFF2 table does not have glyph names; */
322 /* we need to use `post' table method */
323 if ( font->version_major == 2 )
324 {
325 FT_Library library = FT_FACE_LIBRARY( face );
326 FT_Module sfnt_module = FT_Get_Module( library, "sfnt" );
327 FT_Service_GlyphDict service =
328 (FT_Service_GlyphDict)ft_module_get_service(
329 sfnt_module,
330 FT_SERVICE_ID_GLYPH_DICT,
331 0 );
332
333
334 if ( service && service->get_name )
335 return service->get_name( FT_FACE( face ),
336 glyph_index,
337 buffer,
338 buffer_max );
339 else
340 {
341 FT_ERROR(( "cff_get_glyph_name:"
342 " cannot get glyph name from a CFF2 font\n"
343 " "
344 " without the `PSNames' module\n" ));
345 error = FT_THROW( Missing_Module );
346 goto Exit;
347 }
348 }
349
350 if ( !font->psnames )
351 {
352 FT_ERROR(( "cff_get_glyph_name:"
353 " cannot get glyph name from CFF & CEF fonts\n"
354 " "
355 " without the `PSNames' module\n" ));
356 error = FT_THROW( Missing_Module );
357 goto Exit;
358 }
359
360 /* first, locate the sid in the charset table */
361 sid = font->charset.sids[glyph_index];
362
363 /* now, lookup the name itself */
364 gname = cff_index_get_sid_string( font, sid );
365
366 if ( gname )
367 FT_STRCPYN( buffer, gname, buffer_max );
368
369 error = FT_Err_Ok;
370
371 Exit:
372 return error;
373 }
374
375
376 static FT_UInt
377 cff_get_name_index( CFF_Face face,
378 FT_String* glyph_name )
379 {
380 CFF_Font cff;
381 CFF_Charset charset;
382 FT_Service_PsCMaps psnames;
383 FT_String* name;
384 FT_UShort sid;
385 FT_UInt i;
386
387
388 cff = (CFF_FontRec *)face->extra.data;
389 charset = &cff->charset;
390
391 /* CFF2 table does not have glyph names; */
392 /* we need to use `post' table method */
393 if ( cff->version_major == 2 )
394 {
395 FT_Library library = FT_FACE_LIBRARY( face );
396 FT_Module sfnt_module = FT_Get_Module( library, "sfnt" );
397 FT_Service_GlyphDict service =
398 (FT_Service_GlyphDict)ft_module_get_service(
399 sfnt_module,
400 FT_SERVICE_ID_GLYPH_DICT,
401 0 );
402
403
404 if ( service && service->name_index )
405 return service->name_index( FT_FACE( face ), glyph_name );
406 else
407 {
408 FT_ERROR(( "cff_get_name_index:"
409 " cannot get glyph index from a CFF2 font\n"
410 " "
411 " without the `PSNames' module\n" ));
412 return 0;
413 }
414 }
415
416 FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
417 if ( !psnames )
418 return 0;
419
420 for ( i = 0; i < cff->num_glyphs; i++ )
421 {
422 sid = charset->sids[i];
423
424 if ( sid > 390 )
425 name = cff_index_get_string( cff, sid - 391 );
426 else
427 name = (FT_String *)psnames->adobe_std_strings( sid );
428
429 if ( !name )
430 continue;
431
432 if ( !ft_strcmp( glyph_name, name ) )
433 return i;
434 }
435
436 return 0;
437 }
438
439
440 FT_DEFINE_SERVICE_GLYPHDICTREC(
441 cff_service_glyph_dict,
442
443 (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, /* get_name */
444 (FT_GlyphDict_NameIndexFunc)cff_get_name_index /* name_index */
445 )
446
447
448 /*
449 * POSTSCRIPT INFO SERVICE
450 *
451 */
452
453 static FT_Int
454 cff_ps_has_glyph_names( FT_Face face )
455 {
456 return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
457 }
458
459
460 static FT_Error
461 cff_ps_get_font_info( CFF_Face face,
462 PS_FontInfoRec* afont_info )
463 {
464 CFF_Font cff = (CFF_Font)face->extra.data;
465 FT_Error error = FT_Err_Ok;
466
467
468 if ( cff && !cff->font_info )
469 {
470 CFF_FontRecDict dict = &cff->top_font.font_dict;
471 PS_FontInfoRec *font_info = NULL;
472 FT_Memory memory = face->root.memory;
473
474
475 if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
476 goto Fail;
477
478 font_info->version = cff_index_get_sid_string( cff,
479 dict->version );
480 font_info->notice = cff_index_get_sid_string( cff,
481 dict->notice );
482 font_info->full_name = cff_index_get_sid_string( cff,
483 dict->full_name );
484 font_info->family_name = cff_index_get_sid_string( cff,
485 dict->family_name );
486 font_info->weight = cff_index_get_sid_string( cff,
487 dict->weight );
488 font_info->italic_angle = dict->italic_angle;
489 font_info->is_fixed_pitch = dict->is_fixed_pitch;
490 font_info->underline_position = (FT_Short)dict->underline_position;
491 font_info->underline_thickness = (FT_UShort)dict->underline_thickness;
492
493 cff->font_info = font_info;
494 }
495
496 if ( cff )
497 *afont_info = *cff->font_info;
498
499 Fail:
500 return error;
501 }
502
503
504 static FT_Error
505 cff_ps_get_font_extra( CFF_Face face,
506 PS_FontExtraRec* afont_extra )
507 {
508 CFF_Font cff = (CFF_Font)face->extra.data;
509 FT_Error error = FT_Err_Ok;
510
511
512 if ( cff && cff->font_extra == NULL )
513 {
514 CFF_FontRecDict dict = &cff->top_font.font_dict;
515 PS_FontExtraRec* font_extra = NULL;
516 FT_Memory memory = face->root.memory;
517 FT_String* embedded_postscript;
518
519
520 if ( FT_ALLOC( font_extra, sizeof ( *font_extra ) ) )
521 goto Fail;
522
523 font_extra->fs_type = 0U;
524
525 embedded_postscript = cff_index_get_sid_string(
526 cff,
527 dict->embedded_postscript );
528 if ( embedded_postscript )
529 {
530 FT_String* start_fstype;
531 FT_String* start_def;
532
533
534 /* Identify the XYZ integer in `/FSType XYZ def' substring. */
535 if ( ( start_fstype = ft_strstr( embedded_postscript,
536 "/FSType" ) ) != NULL &&
537 ( start_def = ft_strstr( start_fstype +
538 sizeof ( "/FSType" ) - 1,
539 "def" ) ) != NULL )
540 {
541 FT_String* s;
542
543
544 for ( s = start_fstype + sizeof ( "/FSType" ) - 1;
545 s != start_def;
546 s++ )
547 {
548 if ( *s >= '0' && *s <= '9' )
549 {
550 if ( font_extra->fs_type >= ( FT_USHORT_MAX - 9 ) / 10 )
551 {
552 /* Overflow - ignore the FSType value. */
553 font_extra->fs_type = 0U;
554 break;
555 }
556
557 font_extra->fs_type *= 10;
558 font_extra->fs_type += (FT_UShort)( *s - '0' );
559 }
560 else if ( *s != ' ' && *s != '\n' && *s != '\r' )
561 {
562 /* Non-whitespace character between `/FSType' and next `def' */
563 /* - ignore the FSType value. */
564 font_extra->fs_type = 0U;
565 break;
566 }
567 }
568 }
569 }
570
571 cff->font_extra = font_extra;
572 }
573
574 if ( cff )
575 *afont_extra = *cff->font_extra;
576
577 Fail:
578 return error;
579 }
580
581
582 FT_DEFINE_SERVICE_PSINFOREC(
583 cff_service_ps_info,
584
585 (PS_GetFontInfoFunc) cff_ps_get_font_info, /* ps_get_font_info */
586 (PS_GetFontExtraFunc) cff_ps_get_font_extra, /* ps_get_font_extra */
587 (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, /* ps_has_glyph_names */
588 /* unsupported with CFF fonts */
589 (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */
590 /* not implemented */
591 (PS_GetFontValueFunc) NULL /* ps_get_font_value */
592 )
593
594
595 /*
596 * POSTSCRIPT NAME SERVICE
597 *
598 */
599
600 static const char*
601 cff_get_ps_name( CFF_Face face )
602 {
603 CFF_Font cff = (CFF_Font)face->extra.data;
604 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
605
606
607 /* following the OpenType specification 1.7, we return the name stored */
608 /* in the `name' table for a CFF wrapped into an SFNT container */
609
610 if ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt )
611 {
612 FT_Library library = FT_FACE_LIBRARY( face );
613 FT_Module sfnt_module = FT_Get_Module( library, "sfnt" );
614 FT_Service_PsFontName service =
615 (FT_Service_PsFontName)ft_module_get_service(
616 sfnt_module,
617 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME,
618 0 );
619
620
621 if ( service && service->get_ps_font_name )
622 return service->get_ps_font_name( FT_FACE( face ) );
623 }
624
625 return (const char*)cff->font_name;
626 }
627
628
629 FT_DEFINE_SERVICE_PSFONTNAMEREC(
630 cff_service_ps_name,
631
632 (FT_PsName_GetFunc)cff_get_ps_name /* get_ps_font_name */
633 )
634
635
636 /*
637 * TT CMAP INFO
638 *
639 * If the charmap is a synthetic Unicode encoding cmap or
640 * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO
641 * service defined in SFNT module.
642 *
643 * Otherwise call the service function in the sfnt module.
644 *
645 */
646 static FT_Error
647 cff_get_cmap_info( FT_CharMap charmap,
648 TT_CMapInfo *cmap_info )
649 {
650 FT_CMap cmap = FT_CMAP( charmap );
651 FT_Error error = FT_Err_Ok;
652
653 FT_Face face = FT_CMAP_FACE( cmap );
654 FT_Library library = FT_FACE_LIBRARY( face );
655
656
657 if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET &&
658 cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET )
659 {
660 FT_Module sfnt = FT_Get_Module( library, "sfnt" );
661 FT_Service_TTCMaps service =
662 (FT_Service_TTCMaps)ft_module_get_service( sfnt,
663 FT_SERVICE_ID_TT_CMAP,
664 0 );
665
666
667 if ( service && service->get_cmap_info )
668 error = service->get_cmap_info( charmap, cmap_info );
669 }
670 else
671 error = FT_THROW( Invalid_CharMap_Format );
672
673 return error;
674 }
675
676
677 FT_DEFINE_SERVICE_TTCMAPSREC(
678 cff_service_get_cmap_info,
679
680 (TT_CMap_Info_GetFunc)cff_get_cmap_info /* get_cmap_info */
681 )
682
683
684 /*
685 * CID INFO SERVICE
686 *
687 */
688 static FT_Error
689 cff_get_ros( CFF_Face face,
690 const char* *registry,
691 const char* *ordering,
692 FT_Int *supplement )
693 {
694 FT_Error error = FT_Err_Ok;
695 CFF_Font cff = (CFF_Font)face->extra.data;
696
697
698 if ( cff )
699 {
700 CFF_FontRecDict dict = &cff->top_font.font_dict;
701
702
703 if ( dict->cid_registry == 0xFFFFU )
704 {
705 error = FT_THROW( Invalid_Argument );
706 goto Fail;
707 }
708
709 if ( registry )
710 {
711 if ( !cff->registry )
712 cff->registry = cff_index_get_sid_string( cff,
713 dict->cid_registry );
714 *registry = cff->registry;
715 }
716
717 if ( ordering )
718 {
719 if ( !cff->ordering )
720 cff->ordering = cff_index_get_sid_string( cff,
721 dict->cid_ordering );
722 *ordering = cff->ordering;
723 }
724
725 /*
726 * XXX: According to Adobe TechNote #5176, the supplement in CFF
727 * can be a real number. We truncate it to fit public API
728 * since freetype-2.3.6.
729 */
730 if ( supplement )
731 {
732 if ( dict->cid_supplement < FT_INT_MIN ||
733 dict->cid_supplement > FT_INT_MAX )
734 FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
735 dict->cid_supplement ));
736 *supplement = (FT_Int)dict->cid_supplement;
737 }
738 }
739
740 Fail:
741 return error;
742 }
743
744
745 static FT_Error
746 cff_get_is_cid( CFF_Face face,
747 FT_Bool *is_cid )
748 {
749 FT_Error error = FT_Err_Ok;
750 CFF_Font cff = (CFF_Font)face->extra.data;
751
752
753 *is_cid = 0;
754
755 if ( cff )
756 {
757 CFF_FontRecDict dict = &cff->top_font.font_dict;
758
759
760 if ( dict->cid_registry != 0xFFFFU )
761 *is_cid = 1;
762 }
763
764 return error;
765 }
766
767
768 static FT_Error
769 cff_get_cid_from_glyph_index( CFF_Face face,
770 FT_UInt glyph_index,
771 FT_UInt *cid )
772 {
773 FT_Error error = FT_Err_Ok;
774 CFF_Font cff;
775
776
777 cff = (CFF_Font)face->extra.data;
778
779 if ( cff )
780 {
781 FT_UInt c;
782 CFF_FontRecDict dict = &cff->top_font.font_dict;
783
784
785 if ( dict->cid_registry == 0xFFFFU )
786 {
787 error = FT_THROW( Invalid_Argument );
788 goto Fail;
789 }
790
791 if ( glyph_index > cff->num_glyphs )
792 {
793 error = FT_THROW( Invalid_Argument );
794 goto Fail;
795 }
796
797 c = cff->charset.sids[glyph_index];
798
799 if ( cid )
800 *cid = c;
801 }
802
803 Fail:
804 return error;
805 }
806
807
808 FT_DEFINE_SERVICE_CIDREC(
809 cff_service_cid_info,
810
811 (FT_CID_GetRegistryOrderingSupplementFunc)
812 cff_get_ros, /* get_ros */
813 (FT_CID_GetIsInternallyCIDKeyedFunc)
814 cff_get_is_cid, /* get_is_cid */
815 (FT_CID_GetCIDFromGlyphIndexFunc)
816 cff_get_cid_from_glyph_index /* get_cid_from_glyph_index */
817 )
818
819
820 /*
821 * PROPERTY SERVICE
822 *
823 */
824
825 FT_DEFINE_SERVICE_PROPERTIESREC(
826 cff_service_properties,
827
828 (FT_Properties_SetFunc)ps_property_set, /* set_property */
829 (FT_Properties_GetFunc)ps_property_get ) /* get_property */
830
831
832#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
833
834 /*
835 * MULTIPLE MASTER SERVICE
836 *
837 */
838
839 static FT_Error
840 cff_set_mm_blend( CFF_Face face,
841 FT_UInt num_coords,
842 FT_Fixed* coords )
843 {
844 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
845
846
847 return mm->set_mm_blend( FT_FACE( face ), num_coords, coords );
848 }
849
850
851 static FT_Error
852 cff_get_mm_blend( CFF_Face face,
853 FT_UInt num_coords,
854 FT_Fixed* coords )
855 {
856 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
857
858
859 return mm->get_mm_blend( FT_FACE( face ), num_coords, coords );
860 }
861
862
863 static FT_Error
864 cff_get_mm_var( CFF_Face face,
865 FT_MM_Var* *master )
866 {
867 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
868
869
870 return mm->get_mm_var( FT_FACE( face ), master );
871 }
872
873
874 static FT_Error
875 cff_set_var_design( CFF_Face face,
876 FT_UInt num_coords,
877 FT_Fixed* coords )
878 {
879 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
880
881
882 return mm->set_var_design( FT_FACE( face ), num_coords, coords );
883 }
884
885
886 static FT_Error
887 cff_get_var_design( CFF_Face face,
888 FT_UInt num_coords,
889 FT_Fixed* coords )
890 {
891 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
892
893
894 return mm->get_var_design( FT_FACE( face ), num_coords, coords );
895 }
896
897
898 static FT_Error
899 cff_set_instance( CFF_Face face,
900 FT_UInt instance_index )
901 {
902 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
903
904
905 return mm->set_instance( FT_FACE( face ), instance_index );
906 }
907
908
909 FT_DEFINE_SERVICE_MULTIMASTERSREC(
910 cff_service_multi_masters,
911
912 (FT_Get_MM_Func) NULL, /* get_mm */
913 (FT_Set_MM_Design_Func) NULL, /* set_mm_design */
914 (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */
915 (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */
916 (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */
917 (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */
918 (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */
919 (FT_Set_Instance_Func) cff_set_instance, /* set_instance */
920
921 (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */
922 (FT_Done_Blend_Func) cff_done_blend /* done_blend */
923 )
924
925
926 /*
927 * METRICS VARIATIONS SERVICE
928 *
929 */
930
931 static FT_Error
932 cff_hadvance_adjust( CFF_Face face,
933 FT_UInt gindex,
934 FT_Int *avalue )
935 {
936 FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var;
937
938
939 return var->hadvance_adjust( FT_FACE( face ), gindex, avalue );
940 }
941
942
943 static void
944 cff_metrics_adjust( CFF_Face face )
945 {
946 FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var;
947
948
949 var->metrics_adjust( FT_FACE( face ) );
950 }
951
952
953 FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
954 cff_service_metrics_variations,
955
956 (FT_HAdvance_Adjust_Func)cff_hadvance_adjust, /* hadvance_adjust */
957 (FT_LSB_Adjust_Func) NULL, /* lsb_adjust */
958 (FT_RSB_Adjust_Func) NULL, /* rsb_adjust */
959
960 (FT_VAdvance_Adjust_Func)NULL, /* vadvance_adjust */
961 (FT_TSB_Adjust_Func) NULL, /* tsb_adjust */
962 (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */
963 (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */
964
965 (FT_Metrics_Adjust_Func) cff_metrics_adjust /* metrics_adjust */
966 )
967#endif
968
969
970 /*
971 * CFFLOAD SERVICE
972 *
973 */
974
975 FT_DEFINE_SERVICE_CFFLOADREC(
976 cff_service_cff_load,
977
978 (FT_Get_Standard_Encoding_Func)cff_get_standard_encoding,
979 (FT_Load_Private_Dict_Func) cff_load_private_dict,
980 (FT_FD_Select_Get_Func) cff_fd_select_get,
981 (FT_Blend_Check_Vector_Func) cff_blend_check_vector,
982 (FT_Blend_Build_Vector_Func) cff_blend_build_vector
983 )
984
985
986 /*************************************************************************/
987 /*************************************************************************/
988 /*************************************************************************/
989 /**** ****/
990 /**** ****/
991 /**** D R I V E R I N T E R F A C E ****/
992 /**** ****/
993 /**** ****/
994 /*************************************************************************/
995 /*************************************************************************/
996 /*************************************************************************/
997
998#if !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES && \
999 defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
1000 FT_DEFINE_SERVICEDESCREC10(
1001 cff_services,
1002
1003 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF,
1004 FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET,
1005 FT_SERVICE_ID_METRICS_VARIATIONS, &CFF_SERVICE_METRICS_VAR_GET,
1006 FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET,
1007 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
1008 FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET,
1009 FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
1010 FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET,
1011 FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET,
1012 FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET
1013 )
1014#elif !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES
1015 FT_DEFINE_SERVICEDESCREC8(
1016 cff_services,
1017
1018 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF,
1019 FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET,
1020 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
1021 FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET,
1022 FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
1023 FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET,
1024 FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET,
1025 FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET
1026 )
1027#elif defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
1028 FT_DEFINE_SERVICEDESCREC9(
1029 cff_services,
1030
1031 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF,
1032 FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET,
1033 FT_SERVICE_ID_METRICS_VARIATIONS, &CFF_SERVICE_METRICS_VAR_GET,
1034 FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET,
1035 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
1036 FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
1037 FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET,
1038 FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET,
1039 FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET
1040 )
1041#else
1042 FT_DEFINE_SERVICEDESCREC7(
1043 cff_services,
1044
1045 FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF,
1046 FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET,
1047 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
1048 FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET,
1049 FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET,
1050 FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET,
1051 FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET
1052 )
1053#endif
1054
1055
1056 FT_CALLBACK_DEF( FT_Module_Interface )
1057 cff_get_interface( FT_Module driver, /* CFF_Driver */
1058 const char* module_interface )
1059 {
1060 FT_Library library;
1061 FT_Module sfnt;
1062 FT_Module_Interface result;
1063
1064
1065 /* CFF_SERVICES_GET dereferences `library' in PIC mode */
1066#ifdef FT_CONFIG_OPTION_PIC
1067 if ( !driver )
1068 return NULL;
1069 library = driver->library;
1070 if ( !library )
1071 return NULL;
1072#endif
1073
1074 result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface );
1075 if ( result )
1076 return result;
1077
1078 /* `driver' is not yet evaluated in non-PIC mode */
1079#ifndef FT_CONFIG_OPTION_PIC
1080 if ( !driver )
1081 return NULL;
1082 library = driver->library;
1083 if ( !library )
1084 return NULL;
1085#endif
1086
1087 /* we pass our request to the `sfnt' module */
1088 sfnt = FT_Get_Module( library, "sfnt" );
1089
1090 return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
1091 }
1092
1093
1094 /* The FT_DriverInterface structure is defined in ftdriver.h. */
1095
1096#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
1097#define CFF_SIZE_SELECT cff_size_select
1098#else
1099#define CFF_SIZE_SELECT 0
1100#endif
1101
1102 FT_DEFINE_DRIVER(
1103 cff_driver_class,
1104
1105 FT_MODULE_FONT_DRIVER |
1106 FT_MODULE_DRIVER_SCALABLE |
1107 FT_MODULE_DRIVER_HAS_HINTER |
1108 FT_MODULE_DRIVER_HINTS_LIGHTLY,
1109
1110 sizeof ( PS_DriverRec ),
1111 "cff",
1112 0x10000L,
1113 0x20000L,
1114
1115 NULL, /* module-specific interface */
1116
1117 cff_driver_init, /* FT_Module_Constructor module_init */
1118 cff_driver_done, /* FT_Module_Destructor module_done */
1119 cff_get_interface, /* FT_Module_Requester get_interface */
1120
1121 sizeof ( TT_FaceRec ),
1122 sizeof ( CFF_SizeRec ),
1123 sizeof ( CFF_GlyphSlotRec ),
1124
1125 cff_face_init, /* FT_Face_InitFunc init_face */
1126 cff_face_done, /* FT_Face_DoneFunc done_face */
1127 cff_size_init, /* FT_Size_InitFunc init_size */
1128 cff_size_done, /* FT_Size_DoneFunc done_size */
1129 cff_slot_init, /* FT_Slot_InitFunc init_slot */
1130 cff_slot_done, /* FT_Slot_DoneFunc done_slot */
1131
1132 cff_glyph_load, /* FT_Slot_LoadFunc load_glyph */
1133
1134 cff_get_kerning, /* FT_Face_GetKerningFunc get_kerning */
1135 NULL, /* FT_Face_AttachFunc attach_file */
1136 cff_get_advances, /* FT_Face_GetAdvancesFunc get_advances */
1137
1138 cff_size_request, /* FT_Size_RequestFunc request_size */
1139 CFF_SIZE_SELECT /* FT_Size_SelectFunc select_size */
1140 )
1141
1142
1143/* END */
1144