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