1 /***************************************************************************/
5 /* OpenType objects manager (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_CALC_H
22 #include FT_INTERNAL_STREAM_H
24 #include FT_TRUETYPE_IDS_H
25 #include FT_TRUETYPE_TAGS_H
26 #include FT_INTERNAL_SFNT_H
27 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
28 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
36 /*************************************************************************/
38 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
39 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
40 /* messages during execution. */
43 #define FT_COMPONENT trace_cffobjs
46 /*************************************************************************/
50 /* Note that we store the global hints in the size's `internal' root */
53 /*************************************************************************/
56 static PSH_Globals_Funcs
57 cff_size_get_globals_funcs( CFF_Size size
)
59 CFF_Face face
= (CFF_Face
)size
->root
.face
;
60 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
61 PSHinter_Service pshinter
= (PSHinter_Service
)font
->pshinter
;
65 module
= FT_Get_Module( size
->root
.face
->driver
->root
.library
,
67 return ( module
&& pshinter
&& pshinter
->get_globals_funcs
)
68 ? pshinter
->get_globals_funcs( module
)
74 cff_size_done( FT_Size cffsize
) /* CFF_Size */
76 CFF_Size size
= (CFF_Size
)cffsize
;
77 CFF_Face face
= (CFF_Face
)size
->root
.face
;
78 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
79 CFF_Internal internal
= (CFF_Internal
)cffsize
->internal
;
84 PSH_Globals_Funcs funcs
;
87 funcs
= cff_size_get_globals_funcs( size
);
93 funcs
->destroy( internal
->topfont
);
95 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
96 funcs
->destroy( internal
->subfonts
[i
- 1] );
99 /* `internal' is freed by destroy_size (in ftobjs.c) */
104 /* CFF and Type 1 private dictionaries have slightly different */
105 /* structures; we need to synthesize a Type 1 dictionary on the fly */
108 cff_make_private_dict( CFF_SubFont subfont
,
111 CFF_Private cpriv
= &subfont
->private_dict
;
115 FT_MEM_ZERO( priv
, sizeof ( *priv
) );
117 count
= priv
->num_blue_values
= cpriv
->num_blue_values
;
118 for ( n
= 0; n
< count
; n
++ )
119 priv
->blue_values
[n
] = (FT_Short
)cpriv
->blue_values
[n
];
121 count
= priv
->num_other_blues
= cpriv
->num_other_blues
;
122 for ( n
= 0; n
< count
; n
++ )
123 priv
->other_blues
[n
] = (FT_Short
)cpriv
->other_blues
[n
];
125 count
= priv
->num_family_blues
= cpriv
->num_family_blues
;
126 for ( n
= 0; n
< count
; n
++ )
127 priv
->family_blues
[n
] = (FT_Short
)cpriv
->family_blues
[n
];
129 count
= priv
->num_family_other_blues
= cpriv
->num_family_other_blues
;
130 for ( n
= 0; n
< count
; n
++ )
131 priv
->family_other_blues
[n
] = (FT_Short
)cpriv
->family_other_blues
[n
];
133 priv
->blue_scale
= cpriv
->blue_scale
;
134 priv
->blue_shift
= (FT_Int
)cpriv
->blue_shift
;
135 priv
->blue_fuzz
= (FT_Int
)cpriv
->blue_fuzz
;
137 priv
->standard_width
[0] = (FT_UShort
)cpriv
->standard_width
;
138 priv
->standard_height
[0] = (FT_UShort
)cpriv
->standard_height
;
140 count
= priv
->num_snap_widths
= cpriv
->num_snap_widths
;
141 for ( n
= 0; n
< count
; n
++ )
142 priv
->snap_widths
[n
] = (FT_Short
)cpriv
->snap_widths
[n
];
144 count
= priv
->num_snap_heights
= cpriv
->num_snap_heights
;
145 for ( n
= 0; n
< count
; n
++ )
146 priv
->snap_heights
[n
] = (FT_Short
)cpriv
->snap_heights
[n
];
148 priv
->force_bold
= cpriv
->force_bold
;
149 priv
->language_group
= cpriv
->language_group
;
150 priv
->lenIV
= cpriv
->lenIV
;
154 FT_LOCAL_DEF( FT_Error
)
155 cff_size_init( FT_Size cffsize
) /* CFF_Size */
157 CFF_Size size
= (CFF_Size
)cffsize
;
158 FT_Error error
= CFF_Err_Ok
;
159 PSH_Globals_Funcs funcs
= cff_size_get_globals_funcs( size
);
164 CFF_Face face
= (CFF_Face
)cffsize
->face
;
165 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
166 CFF_Internal internal
;
169 FT_Memory memory
= cffsize
->face
->memory
;
174 if ( FT_NEW( internal
) )
177 cff_make_private_dict( &font
->top_font
, &priv
);
178 error
= funcs
->create( cffsize
->face
->memory
, &priv
,
179 &internal
->topfont
);
183 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
185 CFF_SubFont sub
= font
->subfonts
[i
- 1];
188 cff_make_private_dict( sub
, &priv
);
189 error
= funcs
->create( cffsize
->face
->memory
, &priv
,
190 &internal
->subfonts
[i
- 1] );
195 cffsize
->internal
= (FT_Size_Internal
)(void*)internal
;
198 size
->strike_index
= 0xFFFFFFFFUL
;
205 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
207 FT_LOCAL_DEF( FT_Error
)
208 cff_size_select( FT_Size size
,
209 FT_ULong strike_index
)
211 CFF_Size cffsize
= (CFF_Size
)size
;
212 PSH_Globals_Funcs funcs
;
215 cffsize
->strike_index
= strike_index
;
217 FT_Select_Metrics( size
->face
, strike_index
);
219 funcs
= cff_size_get_globals_funcs( cffsize
);
223 CFF_Face face
= (CFF_Face
)size
->face
;
224 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
225 CFF_Internal internal
= (CFF_Internal
)size
->internal
;
227 FT_ULong top_upm
= font
->top_font
.font_dict
.units_per_em
;
231 funcs
->set_scale( internal
->topfont
,
232 size
->metrics
.x_scale
, size
->metrics
.y_scale
,
235 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
237 CFF_SubFont sub
= font
->subfonts
[i
- 1];
238 FT_ULong sub_upm
= sub
->font_dict
.units_per_em
;
239 FT_Pos x_scale
, y_scale
;
242 if ( top_upm
!= sub_upm
)
244 x_scale
= FT_MulDiv( size
->metrics
.x_scale
, top_upm
, sub_upm
);
245 y_scale
= FT_MulDiv( size
->metrics
.y_scale
, top_upm
, sub_upm
);
249 x_scale
= size
->metrics
.x_scale
;
250 y_scale
= size
->metrics
.y_scale
;
253 funcs
->set_scale( internal
->subfonts
[i
- 1],
254 x_scale
, y_scale
, 0, 0 );
261 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
264 FT_LOCAL_DEF( FT_Error
)
265 cff_size_request( FT_Size size
,
266 FT_Size_Request req
)
268 CFF_Size cffsize
= (CFF_Size
)size
;
269 PSH_Globals_Funcs funcs
;
272 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
274 if ( FT_HAS_FIXED_SIZES( size
->face
) )
276 CFF_Face cffface
= (CFF_Face
)size
->face
;
277 SFNT_Service sfnt
= (SFNT_Service
)cffface
->sfnt
;
278 FT_ULong strike_index
;
281 if ( sfnt
->set_sbit_strike( cffface
, req
, &strike_index
) )
282 cffsize
->strike_index
= 0xFFFFFFFFUL
;
284 return cff_size_select( size
, strike_index
);
287 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
289 FT_Request_Metrics( size
->face
, req
);
291 funcs
= cff_size_get_globals_funcs( cffsize
);
295 CFF_Face cffface
= (CFF_Face
)size
->face
;
296 CFF_Font font
= (CFF_Font
)cffface
->extra
.data
;
297 CFF_Internal internal
= (CFF_Internal
)size
->internal
;
299 FT_ULong top_upm
= font
->top_font
.font_dict
.units_per_em
;
303 funcs
->set_scale( internal
->topfont
,
304 size
->metrics
.x_scale
, size
->metrics
.y_scale
,
307 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
309 CFF_SubFont sub
= font
->subfonts
[i
- 1];
310 FT_ULong sub_upm
= sub
->font_dict
.units_per_em
;
311 FT_Pos x_scale
, y_scale
;
314 if ( top_upm
!= sub_upm
)
316 x_scale
= FT_MulDiv( size
->metrics
.x_scale
, top_upm
, sub_upm
);
317 y_scale
= FT_MulDiv( size
->metrics
.y_scale
, top_upm
, sub_upm
);
321 x_scale
= size
->metrics
.x_scale
;
322 y_scale
= size
->metrics
.y_scale
;
325 funcs
->set_scale( internal
->subfonts
[i
- 1],
326 x_scale
, y_scale
, 0, 0 );
334 /*************************************************************************/
338 /*************************************************************************/
341 cff_slot_done( FT_GlyphSlot slot
)
343 slot
->internal
->glyph_hints
= 0;
347 FT_LOCAL_DEF( FT_Error
)
348 cff_slot_init( FT_GlyphSlot slot
)
350 CFF_Face face
= (CFF_Face
)slot
->face
;
351 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
352 PSHinter_Service pshinter
= (PSHinter_Service
)font
->pshinter
;
360 module
= FT_Get_Module( slot
->face
->driver
->root
.library
,
364 T2_Hints_Funcs funcs
;
367 funcs
= pshinter
->get_t2_funcs( module
);
368 slot
->internal
->glyph_hints
= (void*)funcs
;
376 /*************************************************************************/
380 /*************************************************************************/
383 cff_strcpy( FT_Memory memory
,
384 const FT_String
* source
)
390 (void)FT_STRDUP( result
, source
);
398 FT_LOCAL_DEF( FT_Error
)
399 cff_face_init( FT_Stream stream
,
400 FT_Face cffface
, /* CFF_Face */
403 FT_Parameter
* params
)
405 CFF_Face face
= (CFF_Face
)cffface
;
408 FT_Service_PsCMaps psnames
;
409 PSHinter_Service pshinter
;
410 FT_Bool pure_cff
= 1;
411 FT_Bool sfnt_format
= 0;
412 FT_Library library
= cffface
->driver
->root
.library
;
416 FT_FACE_FIND_GLOBAL_SERVICE( face
, sfnt
, SFNT
);
417 FT_FACE_FIND_GLOBAL_SERVICE( face
, psnames
, POSTSCRIPT_NAMES
);
418 FT_FACE_FIND_GLOBAL_SERVICE( face
, pshinter
, POSTSCRIPT_HINTER
);
423 sfnt
= (SFNT_Service
)FT_Get_Module_Interface(
428 FT_FACE_FIND_GLOBAL_SERVICE( face
, psnames
, POSTSCRIPT_CMAPS
);
430 pshinter
= (PSHinter_Service
)FT_Get_Module_Interface(
431 library
, "pshinter" );
434 /* create input stream from resource */
435 if ( FT_STREAM_SEEK( 0 ) )
438 /* check whether we have a valid OpenType file */
439 error
= sfnt
->init_face( stream
, face
, face_index
, num_params
, params
);
442 if ( face
->format_tag
!= TTAG_OTTO
) /* `OTTO'; OpenType/CFF font */
444 FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
448 /* if we are performing a simple font format check, exit immediately */
449 if ( face_index
< 0 )
452 /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */
453 if ( face_index
> 0 )
455 FT_ERROR(( "cff_face_init: invalid face index\n" ));
456 error
= CFF_Err_Invalid_Argument
;
462 /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
463 /* font; in the latter case it doesn't have a `head' table */
464 error
= face
->goto_table( face
, TTAG_head
, stream
, 0 );
469 /* load font directory */
470 error
= sfnt
->load_face( stream
, face
, 0, num_params
, params
);
476 /* load the `cmap' table explicitly */
477 error
= sfnt
->load_cmap( face
, stream
);
481 /* XXX: we don't load the GPOS table, as OpenType Layout */
482 /* support will be added later to a layout library on top of */
486 /* now load the CFF part of the file */
487 error
= face
->goto_table( face
, TTAG_CFF
, stream
, 0 );
493 /* rewind to start of file; we are going to load a pure-CFF font */
494 if ( FT_STREAM_SEEK( 0 ) )
499 /* now load and parse the CFF table in the file */
502 CFF_FontRecDict dict
;
503 FT_Memory memory
= cffface
->memory
;
511 face
->extra
.data
= cff
;
512 error
= cff_font_load( library
, stream
, face_index
, cff
, pure_cff
);
516 cff
->pshinter
= pshinter
;
517 cff
->psnames
= (void*)psnames
;
519 cffface
->face_index
= face_index
;
521 /* Complement the root flags with some interesting information. */
522 /* Note that this is only necessary for pure CFF and CEF fonts; */
523 /* SFNT based fonts use the `name' table instead. */
525 cffface
->num_glyphs
= cff
->num_glyphs
;
527 dict
= &cff
->top_font
.font_dict
;
529 /* we need the `PSNames' module for CFF and CEF formats */
530 /* which aren't CID-keyed */
531 if ( dict
->cid_registry
== 0xFFFFU
&& !psnames
)
533 FT_ERROR(( "cff_face_init:"
534 " cannot open CFF & CEF fonts\n"
536 " without the `PSNames' module\n" ));
540 if ( !dict
->units_per_em
)
541 dict
->units_per_em
= pure_cff
? 1000 : face
->root
.units_per_EM
;
543 /* Normalize the font matrix so that `matrix->xx' is 1; the */
544 /* scaling is done with `units_per_em' then (at this point, */
545 /* it already contains the scaling factor, but without */
546 /* normalization of the matrix). */
548 /* Note that the offsets must be expressed in integer font */
552 FT_Matrix
* matrix
= &dict
->font_matrix
;
553 FT_Vector
* offset
= &dict
->font_offset
;
554 FT_ULong
* upm
= &dict
->units_per_em
;
555 FT_Fixed temp
= FT_ABS( matrix
->yy
);
558 if ( temp
!= 0x10000L
)
560 *upm
= FT_DivFix( *upm
, temp
);
562 matrix
->xx
= FT_DivFix( matrix
->xx
, temp
);
563 matrix
->yx
= FT_DivFix( matrix
->yx
, temp
);
564 matrix
->xy
= FT_DivFix( matrix
->xy
, temp
);
565 matrix
->yy
= FT_DivFix( matrix
->yy
, temp
);
566 offset
->x
= FT_DivFix( offset
->x
, temp
);
567 offset
->y
= FT_DivFix( offset
->y
, temp
);
574 for ( i
= cff
->num_subfonts
; i
> 0; i
-- )
576 CFF_FontRecDict sub
= &cff
->subfonts
[i
- 1]->font_dict
;
577 CFF_FontRecDict top
= &cff
->top_font
.font_dict
;
585 if ( sub
->units_per_em
)
590 if ( top
->units_per_em
> 1 && sub
->units_per_em
> 1 )
591 scaling
= FT_MIN( top
->units_per_em
, sub
->units_per_em
);
595 FT_Matrix_Multiply_Scaled( &top
->font_matrix
,
598 FT_Vector_Transform_Scaled( &sub
->font_offset
,
602 sub
->units_per_em
= FT_MulDiv( sub
->units_per_em
,
608 sub
->font_matrix
= top
->font_matrix
;
609 sub
->font_offset
= top
->font_offset
;
611 sub
->units_per_em
= top
->units_per_em
;
614 matrix
= &sub
->font_matrix
;
615 offset
= &sub
->font_offset
;
616 upm
= &sub
->units_per_em
;
617 temp
= FT_ABS( matrix
->yy
);
619 if ( temp
!= 0x10000L
)
621 *upm
= FT_DivFix( *upm
, temp
);
623 /* if *upm is larger than 100*1000 we divide by 1000 -- */
624 /* this can happen if e.g. there is no top-font FontMatrix */
625 /* and the subfont FontMatrix already contains the complete */
626 /* scaling for the subfont (see section 5.11 of the PLRM) */
628 /* 100 is a heuristic value */
630 if ( *upm
> 100L * 1000L )
631 *upm
= ( *upm
+ 500 ) / 1000;
633 matrix
->xx
= FT_DivFix( matrix
->xx
, temp
);
634 matrix
->yx
= FT_DivFix( matrix
->yx
, temp
);
635 matrix
->xy
= FT_DivFix( matrix
->xy
, temp
);
636 matrix
->yy
= FT_DivFix( matrix
->yy
, temp
);
637 offset
->x
= FT_DivFix( offset
->x
, temp
);
638 offset
->y
= FT_DivFix( offset
->y
, temp
);
647 char* style_name
= NULL
;
650 /* set up num_faces */
651 cffface
->num_faces
= cff
->num_faces
;
653 /* compute number of glyphs */
654 if ( dict
->cid_registry
!= 0xFFFFU
)
655 cffface
->num_glyphs
= cff
->charset
.max_cid
;
657 cffface
->num_glyphs
= cff
->charstrings_index
.count
;
659 /* set global bbox, as well as EM size */
660 cffface
->bbox
.xMin
= dict
->font_bbox
.xMin
>> 16;
661 cffface
->bbox
.yMin
= dict
->font_bbox
.yMin
>> 16;
662 /* no `U' suffix here to 0xFFFF! */
663 cffface
->bbox
.xMax
= ( dict
->font_bbox
.xMax
+ 0xFFFF ) >> 16;
664 cffface
->bbox
.yMax
= ( dict
->font_bbox
.yMax
+ 0xFFFF ) >> 16;
666 cffface
->units_per_EM
= (FT_UShort
)( dict
->units_per_em
);
668 cffface
->ascender
= (FT_Short
)( cffface
->bbox
.yMax
);
669 cffface
->descender
= (FT_Short
)( cffface
->bbox
.yMin
);
671 cffface
->height
= (FT_Short
)( ( cffface
->units_per_EM
* 12 ) / 10 );
672 if ( cffface
->height
< cffface
->ascender
- cffface
->descender
)
673 cffface
->height
= (FT_Short
)( cffface
->ascender
- cffface
->descender
);
675 cffface
->underline_position
=
676 (FT_Short
)( dict
->underline_position
>> 16 );
677 cffface
->underline_thickness
=
678 (FT_Short
)( dict
->underline_thickness
>> 16 );
680 /* retrieve font family & style name */
681 cffface
->family_name
= cff_index_get_name( &cff
->name_index
,
684 if ( cffface
->family_name
)
686 char* full
= cff_index_get_sid_string( &cff
->string_index
,
690 char* family
= cffface
->family_name
;
691 char* family_name
= 0;
694 if ( dict
->family_name
)
696 family_name
= cff_index_get_sid_string( &cff
->string_index
,
700 family
= family_name
;
703 /* We try to extract the style name from the full name. */
704 /* We need to ignore spaces and dashes during the search. */
705 if ( full
&& family
)
709 /* skip common characters at the start of both strings */
710 if ( *fullp
== *family
)
717 /* ignore spaces and dashes in full name during comparison */
718 if ( *fullp
== ' ' || *fullp
== '-' )
724 /* ignore spaces and dashes in family name during comparison */
725 if ( *family
== ' ' || *family
== '-' )
731 if ( !*family
&& *fullp
)
733 /* The full name begins with the same characters as the */
734 /* family name, with spaces and dashes removed. In this */
735 /* case, the remaining string in `fullp' will be used as */
736 /* the style name. */
737 style_name
= cff_strcpy( memory
, fullp
);
743 FT_FREE( family_name
);
749 char *cid_font_name
=
750 cff_index_get_sid_string( &cff
->string_index
,
755 /* do we have a `/FontName' for a CID-keyed font? */
757 cffface
->family_name
= cid_font_name
;
761 cffface
->style_name
= style_name
;
763 /* assume "Regular" style if we don't know better */
764 cffface
->style_name
= cff_strcpy( memory
, (char *)"Regular" );
766 /*******************************************************************/
768 /* Compute face flags. */
770 flags
= (FT_UInt32
)( FT_FACE_FLAG_SCALABLE
| /* scalable outlines */
771 FT_FACE_FLAG_HORIZONTAL
| /* horizontal data */
772 FT_FACE_FLAG_HINTER
); /* has native hinter */
775 flags
|= (FT_UInt32
)FT_FACE_FLAG_SFNT
;
777 /* fixed width font? */
778 if ( dict
->is_fixed_pitch
)
779 flags
|= (FT_UInt32
)FT_FACE_FLAG_FIXED_WIDTH
;
781 /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
783 /* kerning available? */
784 if ( face
->kern_pairs
)
785 flags
|= (FT_UInt32
)FT_FACE_FLAG_KERNING
;
788 cffface
->face_flags
= flags
;
790 /*******************************************************************/
792 /* Compute style flags. */
796 if ( dict
->italic_angle
)
797 flags
|= FT_STYLE_FLAG_ITALIC
;
800 char *weight
= cff_index_get_sid_string( &cff
->string_index
,
806 if ( !ft_strcmp( weight
, "Bold" ) ||
807 !ft_strcmp( weight
, "Black" ) )
808 flags
|= FT_STYLE_FLAG_BOLD
;
813 if ( !(flags
& FT_STYLE_FLAG_BOLD
) && cffface
->style_name
)
814 if ( !ft_strncmp( cffface
->style_name
, "Bold", 4 ) ||
815 !ft_strncmp( cffface
->style_name
, "Black", 5 ) )
816 flags
|= FT_STYLE_FLAG_BOLD
;
818 cffface
->style_flags
= flags
;
822 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
823 /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
824 /* has unset this flag because of the 3.0 `post' table. */
825 if ( dict
->cid_registry
== 0xFFFFU
)
826 cffface
->face_flags
|= FT_FACE_FLAG_GLYPH_NAMES
;
829 if ( dict
->cid_registry
!= 0xFFFFU
&& pure_cff
)
830 cffface
->face_flags
|= FT_FACE_FLAG_CID_KEYED
;
833 /*******************************************************************/
835 /* Compute char maps. */
838 /* Try to synthesize a Unicode charmap if there is none available */
839 /* already. If an OpenType font contains a Unicode "cmap", we */
840 /* will use it, whatever be in the CFF part of the file. */
842 FT_CharMapRec cmaprec
;
845 CFF_Encoding encoding
= &cff
->encoding
;
848 for ( nn
= 0; nn
< (FT_UInt
)cffface
->num_charmaps
; nn
++ )
850 cmap
= cffface
->charmaps
[nn
];
852 /* Windows Unicode (3,1)? */
853 if ( cmap
->platform_id
== 3 && cmap
->encoding_id
== 1 )
856 /* Deprecated Unicode platform id? */
857 if ( cmap
->platform_id
== 0 )
858 goto Skip_Unicode
; /* Standard Unicode (deprecated) */
861 /* since CID-keyed fonts don't contain glyph names, we can't */
862 /* construct a cmap */
863 if ( pure_cff
&& cff
->top_font
.font_dict
.cid_registry
!= 0xFFFFU
)
866 /* we didn't find a Unicode charmap -- synthesize one */
867 cmaprec
.face
= cffface
;
868 cmaprec
.platform_id
= 3;
869 cmaprec
.encoding_id
= 1;
870 cmaprec
.encoding
= FT_ENCODING_UNICODE
;
872 nn
= (FT_UInt
)cffface
->num_charmaps
;
874 FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET
, NULL
, &cmaprec
, NULL
);
876 /* if no Unicode charmap was previously selected, select this one */
877 if ( cffface
->charmap
== NULL
&& nn
!= (FT_UInt
)cffface
->num_charmaps
)
878 cffface
->charmap
= cffface
->charmaps
[nn
];
881 if ( encoding
->count
> 0 )
886 cmaprec
.face
= cffface
;
887 cmaprec
.platform_id
= 7; /* Adobe platform id */
889 if ( encoding
->offset
== 0 )
891 cmaprec
.encoding_id
= TT_ADOBE_ID_STANDARD
;
892 cmaprec
.encoding
= FT_ENCODING_ADOBE_STANDARD
;
893 clazz
= &FT_CFF_CMAP_ENCODING_CLASS_REC_GET
;
895 else if ( encoding
->offset
== 1 )
897 cmaprec
.encoding_id
= TT_ADOBE_ID_EXPERT
;
898 cmaprec
.encoding
= FT_ENCODING_ADOBE_EXPERT
;
899 clazz
= &FT_CFF_CMAP_ENCODING_CLASS_REC_GET
;
903 cmaprec
.encoding_id
= TT_ADOBE_ID_CUSTOM
;
904 cmaprec
.encoding
= FT_ENCODING_ADOBE_CUSTOM
;
905 clazz
= &FT_CFF_CMAP_ENCODING_CLASS_REC_GET
;
908 FT_CMap_New( clazz
, NULL
, &cmaprec
, NULL
);
917 error
= CFF_Err_Unknown_File_Format
;
923 cff_face_done( FT_Face cffface
) /* CFF_Face */
925 CFF_Face face
= (CFF_Face
)cffface
;
933 memory
= cffface
->memory
;
934 sfnt
= (SFNT_Service
)face
->sfnt
;
937 sfnt
->done_face( face
);
940 CFF_Font cff
= (CFF_Font
)face
->extra
.data
;
945 cff_font_done( cff
);
946 FT_FREE( face
->extra
.data
);
952 FT_LOCAL_DEF( FT_Error
)
953 cff_driver_init( FT_Module module
)
962 cff_driver_done( FT_Module module
)