1 /***************************************************************************/
5 /* OpenType objects manager (body). */
7 /* Copyright 1996-2016 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_CALC_H
23 #include FT_INTERNAL_STREAM_H
25 #include FT_TRUETYPE_IDS_H
26 #include FT_TRUETYPE_TAGS_H
27 #include FT_INTERNAL_SFNT_H
28 #include FT_CFF_DRIVER_H
38 /*************************************************************************/
40 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
41 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
42 /* messages during execution. */
45 #define FT_COMPONENT trace_cffobjs
48 /*************************************************************************/
52 /* Note that we store the global hints in the size's `internal' root */
55 /*************************************************************************/
58 static PSH_Globals_Funcs
59 cff_size_get_globals_funcs( CFF_Size size
)
61 CFF_Face face
= (CFF_Face
)size
->root
.face
;
62 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
63 PSHinter_Service pshinter
= font
->pshinter
;
67 module
= FT_Get_Module( size
->root
.face
->driver
->root
.library
,
69 return ( module
&& pshinter
&& pshinter
->get_globals_funcs
)
70 ? pshinter
->get_globals_funcs( module
)
76 cff_size_done( FT_Size cffsize
) /* CFF_Size */
78 CFF_Size size
= (CFF_Size
)cffsize
;
79 CFF_Face face
= (CFF_Face
)size
->root
.face
;
80 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
81 CFF_Internal internal
= (CFF_Internal
)cffsize
->internal
;
86 PSH_Globals_Funcs funcs
;
89 funcs
= cff_size_get_globals_funcs( size
);
95 funcs
->destroy( internal
->topfont
);
97 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
98 funcs
->destroy( internal
->subfonts
[i
- 1] );
101 /* `internal' is freed by destroy_size (in ftobjs.c) */
106 /* CFF and Type 1 private dictionaries have slightly different */
107 /* structures; we need to synthesize a Type 1 dictionary on the fly */
110 cff_make_private_dict( CFF_SubFont subfont
,
113 CFF_Private cpriv
= &subfont
->private_dict
;
117 FT_MEM_ZERO( priv
, sizeof ( *priv
) );
119 count
= priv
->num_blue_values
= cpriv
->num_blue_values
;
120 for ( n
= 0; n
< count
; n
++ )
121 priv
->blue_values
[n
] = (FT_Short
)cpriv
->blue_values
[n
];
123 count
= priv
->num_other_blues
= cpriv
->num_other_blues
;
124 for ( n
= 0; n
< count
; n
++ )
125 priv
->other_blues
[n
] = (FT_Short
)cpriv
->other_blues
[n
];
127 count
= priv
->num_family_blues
= cpriv
->num_family_blues
;
128 for ( n
= 0; n
< count
; n
++ )
129 priv
->family_blues
[n
] = (FT_Short
)cpriv
->family_blues
[n
];
131 count
= priv
->num_family_other_blues
= cpriv
->num_family_other_blues
;
132 for ( n
= 0; n
< count
; n
++ )
133 priv
->family_other_blues
[n
] = (FT_Short
)cpriv
->family_other_blues
[n
];
135 priv
->blue_scale
= cpriv
->blue_scale
;
136 priv
->blue_shift
= (FT_Int
)cpriv
->blue_shift
;
137 priv
->blue_fuzz
= (FT_Int
)cpriv
->blue_fuzz
;
139 priv
->standard_width
[0] = (FT_UShort
)cpriv
->standard_width
;
140 priv
->standard_height
[0] = (FT_UShort
)cpriv
->standard_height
;
142 count
= priv
->num_snap_widths
= cpriv
->num_snap_widths
;
143 for ( n
= 0; n
< count
; n
++ )
144 priv
->snap_widths
[n
] = (FT_Short
)cpriv
->snap_widths
[n
];
146 count
= priv
->num_snap_heights
= cpriv
->num_snap_heights
;
147 for ( n
= 0; n
< count
; n
++ )
148 priv
->snap_heights
[n
] = (FT_Short
)cpriv
->snap_heights
[n
];
150 priv
->force_bold
= cpriv
->force_bold
;
151 priv
->language_group
= cpriv
->language_group
;
152 priv
->lenIV
= cpriv
->lenIV
;
156 FT_LOCAL_DEF( FT_Error
)
157 cff_size_init( FT_Size cffsize
) /* CFF_Size */
159 CFF_Size size
= (CFF_Size
)cffsize
;
160 FT_Error error
= FT_Err_Ok
;
161 PSH_Globals_Funcs funcs
= cff_size_get_globals_funcs( size
);
166 CFF_Face face
= (CFF_Face
)cffsize
->face
;
167 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
168 CFF_Internal internal
= NULL
;
171 FT_Memory memory
= cffsize
->face
->memory
;
176 if ( FT_NEW( internal
) )
179 cff_make_private_dict( &font
->top_font
, &priv
);
180 error
= funcs
->create( cffsize
->face
->memory
, &priv
,
181 &internal
->topfont
);
185 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
187 CFF_SubFont sub
= font
->subfonts
[i
- 1];
190 cff_make_private_dict( sub
, &priv
);
191 error
= funcs
->create( cffsize
->face
->memory
, &priv
,
192 &internal
->subfonts
[i
- 1] );
197 cffsize
->internal
= (FT_Size_Internal
)(void*)internal
;
200 size
->strike_index
= 0xFFFFFFFFUL
;
207 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
209 FT_LOCAL_DEF( FT_Error
)
210 cff_size_select( FT_Size size
,
211 FT_ULong strike_index
)
213 CFF_Size cffsize
= (CFF_Size
)size
;
214 PSH_Globals_Funcs funcs
;
217 cffsize
->strike_index
= strike_index
;
219 FT_Select_Metrics( size
->face
, strike_index
);
221 funcs
= cff_size_get_globals_funcs( cffsize
);
225 CFF_Face face
= (CFF_Face
)size
->face
;
226 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
227 CFF_Internal internal
= (CFF_Internal
)size
->internal
;
229 FT_Long top_upm
= (FT_Long
)font
->top_font
.font_dict
.units_per_em
;
233 funcs
->set_scale( internal
->topfont
,
234 size
->metrics
.x_scale
, size
->metrics
.y_scale
,
237 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
239 CFF_SubFont sub
= font
->subfonts
[i
- 1];
240 FT_Long sub_upm
= (FT_Long
)sub
->font_dict
.units_per_em
;
241 FT_Pos x_scale
, y_scale
;
244 if ( top_upm
!= sub_upm
)
246 x_scale
= FT_MulDiv( size
->metrics
.x_scale
, top_upm
, sub_upm
);
247 y_scale
= FT_MulDiv( size
->metrics
.y_scale
, top_upm
, sub_upm
);
251 x_scale
= size
->metrics
.x_scale
;
252 y_scale
= size
->metrics
.y_scale
;
255 funcs
->set_scale( internal
->subfonts
[i
- 1],
256 x_scale
, y_scale
, 0, 0 );
263 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
266 FT_LOCAL_DEF( FT_Error
)
267 cff_size_request( FT_Size size
,
268 FT_Size_Request req
)
270 CFF_Size cffsize
= (CFF_Size
)size
;
271 PSH_Globals_Funcs funcs
;
274 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
276 if ( FT_HAS_FIXED_SIZES( size
->face
) )
278 CFF_Face cffface
= (CFF_Face
)size
->face
;
279 SFNT_Service sfnt
= (SFNT_Service
)cffface
->sfnt
;
280 FT_ULong strike_index
;
283 if ( sfnt
->set_sbit_strike( cffface
, req
, &strike_index
) )
284 cffsize
->strike_index
= 0xFFFFFFFFUL
;
286 return cff_size_select( size
, strike_index
);
289 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
291 FT_Request_Metrics( size
->face
, req
);
293 funcs
= cff_size_get_globals_funcs( cffsize
);
297 CFF_Face cffface
= (CFF_Face
)size
->face
;
298 CFF_Font font
= (CFF_Font
)cffface
->extra
.data
;
299 CFF_Internal internal
= (CFF_Internal
)size
->internal
;
301 FT_Long top_upm
= (FT_Long
)font
->top_font
.font_dict
.units_per_em
;
305 funcs
->set_scale( internal
->topfont
,
306 size
->metrics
.x_scale
, size
->metrics
.y_scale
,
309 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
311 CFF_SubFont sub
= font
->subfonts
[i
- 1];
312 FT_Long sub_upm
= (FT_Long
)sub
->font_dict
.units_per_em
;
313 FT_Pos x_scale
, y_scale
;
316 if ( top_upm
!= sub_upm
)
318 x_scale
= FT_MulDiv( size
->metrics
.x_scale
, top_upm
, sub_upm
);
319 y_scale
= FT_MulDiv( size
->metrics
.y_scale
, top_upm
, sub_upm
);
323 x_scale
= size
->metrics
.x_scale
;
324 y_scale
= size
->metrics
.y_scale
;
327 funcs
->set_scale( internal
->subfonts
[i
- 1],
328 x_scale
, y_scale
, 0, 0 );
336 /*************************************************************************/
340 /*************************************************************************/
343 cff_slot_done( FT_GlyphSlot slot
)
345 slot
->internal
->glyph_hints
= NULL
;
349 FT_LOCAL_DEF( FT_Error
)
350 cff_slot_init( FT_GlyphSlot slot
)
352 CFF_Face face
= (CFF_Face
)slot
->face
;
353 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
354 PSHinter_Service pshinter
= font
->pshinter
;
362 module
= FT_Get_Module( slot
->face
->driver
->root
.library
,
366 T2_Hints_Funcs funcs
;
369 funcs
= pshinter
->get_t2_funcs( module
);
370 slot
->internal
->glyph_hints
= (void*)funcs
;
378 /*************************************************************************/
382 /*************************************************************************/
385 cff_strcpy( FT_Memory memory
,
386 const FT_String
* source
)
392 (void)FT_STRDUP( result
, source
);
400 /* Strip all subset prefixes of the form `ABCDEF+'. Usually, there */
401 /* is only one, but font names like `APCOOG+JFABTD+FuturaBQ-Bold' */
402 /* have been seen in the wild. */
405 remove_subset_prefix( FT_String
* name
)
408 FT_Int32 length
= (FT_Int32
)strlen( name
) + 1;
409 FT_Bool continue_search
= 1;
412 while ( continue_search
)
414 if ( length
>= 7 && name
[6] == '+' )
416 for ( idx
= 0; idx
< 6; idx
++ )
418 /* ASCII uppercase letters */
419 if ( !( 'A' <= name
[idx
] && name
[idx
] <= 'Z' ) )
423 if ( continue_search
)
425 for ( idx
= 7; idx
< length
; idx
++ )
426 name
[idx
- 7] = name
[idx
];
436 /* Remove the style part from the family name (if present). */
439 remove_style( FT_String
* family_name
,
440 const FT_String
* style_name
)
442 FT_Int32 family_name_length
, style_name_length
;
445 family_name_length
= (FT_Int32
)strlen( family_name
);
446 style_name_length
= (FT_Int32
)strlen( style_name
);
448 if ( family_name_length
> style_name_length
)
453 for ( idx
= 1; idx
<= style_name_length
; ++idx
)
455 if ( family_name
[family_name_length
- idx
] !=
456 style_name
[style_name_length
- idx
] )
460 if ( idx
> style_name_length
)
462 /* family_name ends with style_name; remove it */
463 idx
= family_name_length
- style_name_length
- 1;
465 /* also remove special characters */
466 /* between real family name and style */
468 ( family_name
[idx
] == '-' ||
469 family_name
[idx
] == ' ' ||
470 family_name
[idx
] == '_' ||
471 family_name
[idx
] == '+' ) )
475 family_name
[idx
+ 1] = '\0';
481 FT_LOCAL_DEF( FT_Error
)
482 cff_face_init( FT_Stream stream
,
483 FT_Face cffface
, /* CFF_Face */
486 FT_Parameter
* params
)
488 CFF_Face face
= (CFF_Face
)cffface
;
491 FT_Service_PsCMaps psnames
;
492 PSHinter_Service pshinter
;
493 FT_Bool pure_cff
= 1;
494 FT_Bool sfnt_format
= 0;
495 FT_Library library
= cffface
->driver
->root
.library
;
498 sfnt
= (SFNT_Service
)FT_Get_Module_Interface(
502 FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" ));
503 error
= FT_THROW( Missing_Module
);
507 FT_FACE_FIND_GLOBAL_SERVICE( face
, psnames
, POSTSCRIPT_CMAPS
);
509 pshinter
= (PSHinter_Service
)FT_Get_Module_Interface(
510 library
, "pshinter" );
512 FT_TRACE2(( "CFF driver\n" ));
514 /* create input stream from resource */
515 if ( FT_STREAM_SEEK( 0 ) )
518 /* check whether we have a valid OpenType file */
519 error
= sfnt
->init_face( stream
, face
, face_index
, num_params
, params
);
522 if ( face
->format_tag
!= TTAG_OTTO
) /* `OTTO'; OpenType/CFF font */
524 FT_TRACE2(( " not an OpenType/CFF font\n" ));
525 error
= FT_THROW( Unknown_File_Format
);
529 /* if we are performing a simple font format check, exit immediately */
530 if ( face_index
< 0 )
535 /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
536 /* font; in the latter case it doesn't have a `head' table */
537 error
= face
->goto_table( face
, TTAG_head
, stream
, 0 );
542 /* load font directory */
543 error
= sfnt
->load_face( stream
, face
, face_index
,
544 num_params
, params
);
550 /* load the `cmap' table explicitly */
551 error
= sfnt
->load_cmap( face
, stream
);
556 /* now load the CFF part of the file */
557 error
= face
->goto_table( face
, TTAG_CFF
, stream
, 0 );
563 /* rewind to start of file; we are going to load a pure-CFF font */
564 if ( FT_STREAM_SEEK( 0 ) )
569 /* now load and parse the CFF table in the file */
572 CFF_FontRecDict dict
;
573 FT_Memory memory
= cffface
->memory
;
581 face
->extra
.data
= cff
;
582 error
= cff_font_load( library
, stream
, face_index
, cff
, pure_cff
);
586 /* if we are performing a simple font format check, exit immediately */
587 /* (this is here for pure CFF) */
588 if ( face_index
< 0 )
590 cffface
->num_faces
= (FT_Long
)cff
->num_faces
;
594 cff
->pshinter
= pshinter
;
595 cff
->psnames
= psnames
;
597 cffface
->face_index
= face_index
& 0xFFFF;
599 /* Complement the root flags with some interesting information. */
600 /* Note that this is only necessary for pure CFF and CEF fonts; */
601 /* SFNT based fonts use the `name' table instead. */
603 cffface
->num_glyphs
= (FT_Long
)cff
->num_glyphs
;
605 dict
= &cff
->top_font
.font_dict
;
607 /* we need the `PSNames' module for CFF and CEF formats */
608 /* which aren't CID-keyed */
609 if ( dict
->cid_registry
== 0xFFFFU
&& !psnames
)
611 FT_ERROR(( "cff_face_init:"
612 " cannot open CFF & CEF fonts\n"
614 " without the `PSNames' module\n" ));
615 error
= FT_THROW( Missing_Module
);
619 #ifdef FT_DEBUG_LEVEL_TRACE
625 FT_TRACE4(( "SIDs\n" ));
627 /* dump string index, including default strings for convenience */
628 for ( idx
= 0; idx
< cff
->num_strings
+ 390; idx
++ )
630 s
= cff_index_get_sid_string( cff
, idx
);
632 FT_TRACE4((" %5d %s\n", idx
, s
));
635 #endif /* FT_DEBUG_LEVEL_TRACE */
637 if ( !dict
->has_font_matrix
)
638 dict
->units_per_em
= pure_cff
? 1000 : face
->root
.units_per_EM
;
640 /* Normalize the font matrix so that `matrix->yy' is 1; the */
641 /* scaling is done with `units_per_em' then (at this point, */
642 /* it already contains the scaling factor, but without */
643 /* normalization of the matrix). */
645 /* Note that the offsets must be expressed in integer font */
649 FT_Matrix
* matrix
= &dict
->font_matrix
;
650 FT_Vector
* offset
= &dict
->font_offset
;
651 FT_ULong
* upm
= &dict
->units_per_em
;
652 FT_Fixed temp
= FT_ABS( matrix
->yy
);
655 if ( temp
!= 0x10000L
)
657 *upm
= (FT_ULong
)FT_DivFix( (FT_Long
)*upm
, temp
);
659 matrix
->xx
= FT_DivFix( matrix
->xx
, temp
);
660 matrix
->yx
= FT_DivFix( matrix
->yx
, temp
);
661 matrix
->xy
= FT_DivFix( matrix
->xy
, temp
);
662 matrix
->yy
= FT_DivFix( matrix
->yy
, temp
);
663 offset
->x
= FT_DivFix( offset
->x
, temp
);
664 offset
->y
= FT_DivFix( offset
->y
, temp
);
671 for ( i
= cff
->num_subfonts
; i
> 0; i
-- )
673 CFF_FontRecDict sub
= &cff
->subfonts
[i
- 1]->font_dict
;
674 CFF_FontRecDict top
= &cff
->top_font
.font_dict
;
682 if ( sub
->has_font_matrix
)
687 /* if we have a top-level matrix, */
688 /* concatenate the subfont matrix */
690 if ( top
->has_font_matrix
)
692 if ( top
->units_per_em
> 1 && sub
->units_per_em
> 1 )
693 scaling
= (FT_Long
)FT_MIN( top
->units_per_em
,
698 FT_Matrix_Multiply_Scaled( &top
->font_matrix
,
701 FT_Vector_Transform_Scaled( &sub
->font_offset
,
705 sub
->units_per_em
= (FT_ULong
)
706 FT_MulDiv( (FT_Long
)sub
->units_per_em
,
707 (FT_Long
)top
->units_per_em
,
713 sub
->font_matrix
= top
->font_matrix
;
714 sub
->font_offset
= top
->font_offset
;
716 sub
->units_per_em
= top
->units_per_em
;
719 matrix
= &sub
->font_matrix
;
720 offset
= &sub
->font_offset
;
721 upm
= &sub
->units_per_em
;
722 temp
= FT_ABS( matrix
->yy
);
724 if ( temp
!= 0x10000L
)
726 *upm
= (FT_ULong
)FT_DivFix( (FT_Long
)*upm
, temp
);
728 matrix
->xx
= FT_DivFix( matrix
->xx
, temp
);
729 matrix
->yx
= FT_DivFix( matrix
->yx
, temp
);
730 matrix
->xy
= FT_DivFix( matrix
->xy
, temp
);
731 matrix
->yy
= FT_DivFix( matrix
->yy
, temp
);
732 offset
->x
= FT_DivFix( offset
->x
, temp
);
733 offset
->y
= FT_DivFix( offset
->y
, temp
);
742 char* style_name
= NULL
;
745 /* set up num_faces */
746 cffface
->num_faces
= (FT_Long
)cff
->num_faces
;
748 /* compute number of glyphs */
749 if ( dict
->cid_registry
!= 0xFFFFU
)
750 cffface
->num_glyphs
= (FT_Long
)( cff
->charset
.max_cid
+ 1 );
752 cffface
->num_glyphs
= (FT_Long
)cff
->charstrings_index
.count
;
754 /* set global bbox, as well as EM size */
755 cffface
->bbox
.xMin
= dict
->font_bbox
.xMin
>> 16;
756 cffface
->bbox
.yMin
= dict
->font_bbox
.yMin
>> 16;
757 /* no `U' suffix here to 0xFFFF! */
758 cffface
->bbox
.xMax
= ( dict
->font_bbox
.xMax
+ 0xFFFF ) >> 16;
759 cffface
->bbox
.yMax
= ( dict
->font_bbox
.yMax
+ 0xFFFF ) >> 16;
761 cffface
->units_per_EM
= (FT_UShort
)( dict
->units_per_em
);
763 cffface
->ascender
= (FT_Short
)( cffface
->bbox
.yMax
);
764 cffface
->descender
= (FT_Short
)( cffface
->bbox
.yMin
);
766 cffface
->height
= (FT_Short
)( ( cffface
->units_per_EM
* 12 ) / 10 );
767 if ( cffface
->height
< cffface
->ascender
- cffface
->descender
)
768 cffface
->height
= (FT_Short
)( cffface
->ascender
- cffface
->descender
);
770 cffface
->underline_position
=
771 (FT_Short
)( dict
->underline_position
>> 16 );
772 cffface
->underline_thickness
=
773 (FT_Short
)( dict
->underline_thickness
>> 16 );
775 /* retrieve font family & style name */
776 cffface
->family_name
= cff_index_get_name(
778 (FT_UInt
)( face_index
& 0xFFFF ) );
779 if ( cffface
->family_name
)
781 char* full
= cff_index_get_sid_string( cff
,
784 char* family
= cffface
->family_name
;
785 char* family_name
= NULL
;
788 remove_subset_prefix( cffface
->family_name
);
790 if ( dict
->family_name
)
792 family_name
= cff_index_get_sid_string( cff
,
795 family
= family_name
;
798 /* We try to extract the style name from the full name. */
799 /* We need to ignore spaces and dashes during the search. */
800 if ( full
&& family
)
804 /* skip common characters at the start of both strings */
805 if ( *fullp
== *family
)
812 /* ignore spaces and dashes in full name during comparison */
813 if ( *fullp
== ' ' || *fullp
== '-' )
819 /* ignore spaces and dashes in family name during comparison */
820 if ( *family
== ' ' || *family
== '-' )
826 if ( !*family
&& *fullp
)
828 /* The full name begins with the same characters as the */
829 /* family name, with spaces and dashes removed. In this */
830 /* case, the remaining string in `fullp' will be used as */
831 /* the style name. */
832 style_name
= cff_strcpy( memory
, fullp
);
834 /* remove the style part from the family name (if present) */
835 remove_style( cffface
->family_name
, style_name
);
843 char *cid_font_name
=
844 cff_index_get_sid_string( cff
,
845 dict
->cid_font_name
);
848 /* do we have a `/FontName' for a CID-keyed font? */
850 cffface
->family_name
= cff_strcpy( memory
, cid_font_name
);
854 cffface
->style_name
= style_name
;
856 /* assume "Regular" style if we don't know better */
857 cffface
->style_name
= cff_strcpy( memory
, (char *)"Regular" );
859 /*******************************************************************/
861 /* Compute face flags. */
863 flags
= FT_FACE_FLAG_SCALABLE
| /* scalable outlines */
864 FT_FACE_FLAG_HORIZONTAL
| /* horizontal data */
865 FT_FACE_FLAG_HINTER
; /* has native hinter */
868 flags
|= FT_FACE_FLAG_SFNT
;
870 /* fixed width font? */
871 if ( dict
->is_fixed_pitch
)
872 flags
|= FT_FACE_FLAG_FIXED_WIDTH
;
874 /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
876 /* kerning available? */
877 if ( face
->kern_pairs
)
878 flags
|= FT_FACE_FLAG_KERNING
;
881 cffface
->face_flags
|= flags
;
883 /*******************************************************************/
885 /* Compute style flags. */
889 if ( dict
->italic_angle
)
890 flags
|= FT_STYLE_FLAG_ITALIC
;
893 char *weight
= cff_index_get_sid_string( cff
,
898 if ( !ft_strcmp( weight
, "Bold" ) ||
899 !ft_strcmp( weight
, "Black" ) )
900 flags
|= FT_STYLE_FLAG_BOLD
;
904 if ( !(flags
& FT_STYLE_FLAG_BOLD
) && cffface
->style_name
)
905 if ( !ft_strncmp( cffface
->style_name
, "Bold", 4 ) ||
906 !ft_strncmp( cffface
->style_name
, "Black", 5 ) )
907 flags
|= FT_STYLE_FLAG_BOLD
;
909 cffface
->style_flags
= flags
;
913 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
914 /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
915 /* has unset this flag because of the 3.0 `post' table. */
916 if ( dict
->cid_registry
== 0xFFFFU
)
917 cffface
->face_flags
|= FT_FACE_FLAG_GLYPH_NAMES
;
920 if ( dict
->cid_registry
!= 0xFFFFU
&& pure_cff
)
921 cffface
->face_flags
|= FT_FACE_FLAG_CID_KEYED
;
924 /*******************************************************************/
926 /* Compute char maps. */
929 /* Try to synthesize a Unicode charmap if there is none available */
930 /* already. If an OpenType font contains a Unicode "cmap", we */
931 /* will use it, whatever be in the CFF part of the file. */
933 FT_CharMapRec cmaprec
;
936 CFF_Encoding encoding
= &cff
->encoding
;
939 for ( nn
= 0; nn
< (FT_UInt
)cffface
->num_charmaps
; nn
++ )
941 cmap
= cffface
->charmaps
[nn
];
943 /* Windows Unicode? */
944 if ( cmap
->platform_id
== TT_PLATFORM_MICROSOFT
&&
945 cmap
->encoding_id
== TT_MS_ID_UNICODE_CS
)
948 /* Apple Unicode platform id? */
949 if ( cmap
->platform_id
== TT_PLATFORM_APPLE_UNICODE
)
950 goto Skip_Unicode
; /* Apple Unicode */
953 /* since CID-keyed fonts don't contain glyph names, we can't */
954 /* construct a cmap */
955 if ( pure_cff
&& cff
->top_font
.font_dict
.cid_registry
!= 0xFFFFU
)
958 /* we didn't find a Unicode charmap -- synthesize one */
959 cmaprec
.face
= cffface
;
960 cmaprec
.platform_id
= TT_PLATFORM_MICROSOFT
;
961 cmaprec
.encoding_id
= TT_MS_ID_UNICODE_CS
;
962 cmaprec
.encoding
= FT_ENCODING_UNICODE
;
964 nn
= (FT_UInt
)cffface
->num_charmaps
;
966 error
= FT_CMap_New( &CFF_CMAP_UNICODE_CLASS_REC_GET
, NULL
,
969 FT_ERR_NEQ( error
, No_Unicode_Glyph_Name
) )
973 /* if no Unicode charmap was previously selected, select this one */
974 if ( cffface
->charmap
== NULL
&& nn
!= (FT_UInt
)cffface
->num_charmaps
)
975 cffface
->charmap
= cffface
->charmaps
[nn
];
978 if ( encoding
->count
> 0 )
983 cmaprec
.face
= cffface
;
984 cmaprec
.platform_id
= TT_PLATFORM_ADOBE
; /* Adobe platform id */
986 if ( encoding
->offset
== 0 )
988 cmaprec
.encoding_id
= TT_ADOBE_ID_STANDARD
;
989 cmaprec
.encoding
= FT_ENCODING_ADOBE_STANDARD
;
990 clazz
= &CFF_CMAP_ENCODING_CLASS_REC_GET
;
992 else if ( encoding
->offset
== 1 )
994 cmaprec
.encoding_id
= TT_ADOBE_ID_EXPERT
;
995 cmaprec
.encoding
= FT_ENCODING_ADOBE_EXPERT
;
996 clazz
= &CFF_CMAP_ENCODING_CLASS_REC_GET
;
1000 cmaprec
.encoding_id
= TT_ADOBE_ID_CUSTOM
;
1001 cmaprec
.encoding
= FT_ENCODING_ADOBE_CUSTOM
;
1002 clazz
= &CFF_CMAP_ENCODING_CLASS_REC_GET
;
1005 error
= FT_CMap_New( clazz
, NULL
, &cmaprec
, NULL
);
1015 FT_LOCAL_DEF( void )
1016 cff_face_done( FT_Face cffface
) /* CFF_Face */
1018 CFF_Face face
= (CFF_Face
)cffface
;
1026 memory
= cffface
->memory
;
1027 sfnt
= (SFNT_Service
)face
->sfnt
;
1030 sfnt
->done_face( face
);
1033 CFF_Font cff
= (CFF_Font
)face
->extra
.data
;
1038 cff_font_done( cff
);
1039 FT_FREE( face
->extra
.data
);
1045 FT_LOCAL_DEF( FT_Error
)
1046 cff_driver_init( FT_Module module
) /* CFF_Driver */
1048 CFF_Driver driver
= (CFF_Driver
)module
;
1051 /* set default property values, cf. `ftcffdrv.h' */
1052 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
1053 driver
->hinting_engine
= FT_CFF_HINTING_FREETYPE
;
1055 driver
->hinting_engine
= FT_CFF_HINTING_ADOBE
;
1058 driver
->no_stem_darkening
= TRUE
;
1060 driver
->darken_params
[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1
;
1061 driver
->darken_params
[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1
;
1062 driver
->darken_params
[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2
;
1063 driver
->darken_params
[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2
;
1064 driver
->darken_params
[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3
;
1065 driver
->darken_params
[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3
;
1066 driver
->darken_params
[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4
;
1067 driver
->darken_params
[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4
;
1073 FT_LOCAL_DEF( void )
1074 cff_driver_done( FT_Module module
) /* CFF_Driver */
1076 FT_UNUSED( module
);