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