1 /***************************************************************************/
5 /* OpenType objects manager (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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
35 /*************************************************************************/
37 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
38 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
39 /* messages during execution. */
42 #define FT_COMPONENT trace_cffobjs
45 /*************************************************************************/
49 /* Note that we store the global hints in the size's `internal' root */
52 /*************************************************************************/
55 static PSH_Globals_Funcs
56 cff_size_get_globals_funcs( CFF_Size size
)
58 CFF_Face face
= (CFF_Face
)size
->root
.face
;
59 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
60 PSHinter_Service pshinter
= (PSHinter_Service
)font
->pshinter
;
64 module
= FT_Get_Module( size
->root
.face
->driver
->root
.library
,
66 return ( module
&& pshinter
&& pshinter
->get_globals_funcs
)
67 ? pshinter
->get_globals_funcs( module
)
73 cff_size_done( FT_Size cffsize
) /* CFF_Size */
75 CFF_Size size
= (CFF_Size
)cffsize
;
76 CFF_Face face
= (CFF_Face
)size
->root
.face
;
77 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
78 CFF_Internal internal
= (CFF_Internal
)cffsize
->internal
;
83 PSH_Globals_Funcs funcs
;
86 funcs
= cff_size_get_globals_funcs( size
);
92 funcs
->destroy( internal
->topfont
);
94 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
95 funcs
->destroy( internal
->subfonts
[i
- 1] );
98 /* `internal' is freed by destroy_size (in ftobjs.c) */
103 /* CFF and Type 1 private dictionaries have slightly different */
104 /* structures; we need to synthetize a Type 1 dictionary on the fly */
107 cff_make_private_dict( CFF_SubFont subfont
,
110 CFF_Private cpriv
= &subfont
->private_dict
;
114 FT_MEM_ZERO( priv
, sizeof ( *priv
) );
116 count
= priv
->num_blue_values
= cpriv
->num_blue_values
;
117 for ( n
= 0; n
< count
; n
++ )
118 priv
->blue_values
[n
] = (FT_Short
)cpriv
->blue_values
[n
];
120 count
= priv
->num_other_blues
= cpriv
->num_other_blues
;
121 for ( n
= 0; n
< count
; n
++ )
122 priv
->other_blues
[n
] = (FT_Short
)cpriv
->other_blues
[n
];
124 count
= priv
->num_family_blues
= cpriv
->num_family_blues
;
125 for ( n
= 0; n
< count
; n
++ )
126 priv
->family_blues
[n
] = (FT_Short
)cpriv
->family_blues
[n
];
128 count
= priv
->num_family_other_blues
= cpriv
->num_family_other_blues
;
129 for ( n
= 0; n
< count
; n
++ )
130 priv
->family_other_blues
[n
] = (FT_Short
)cpriv
->family_other_blues
[n
];
132 priv
->blue_scale
= cpriv
->blue_scale
;
133 priv
->blue_shift
= (FT_Int
)cpriv
->blue_shift
;
134 priv
->blue_fuzz
= (FT_Int
)cpriv
->blue_fuzz
;
136 priv
->standard_width
[0] = (FT_UShort
)cpriv
->standard_width
;
137 priv
->standard_height
[0] = (FT_UShort
)cpriv
->standard_height
;
139 count
= priv
->num_snap_widths
= cpriv
->num_snap_widths
;
140 for ( n
= 0; n
< count
; n
++ )
141 priv
->snap_widths
[n
] = (FT_Short
)cpriv
->snap_widths
[n
];
143 count
= priv
->num_snap_heights
= cpriv
->num_snap_heights
;
144 for ( n
= 0; n
< count
; n
++ )
145 priv
->snap_heights
[n
] = (FT_Short
)cpriv
->snap_heights
[n
];
147 priv
->force_bold
= cpriv
->force_bold
;
148 priv
->language_group
= cpriv
->language_group
;
149 priv
->lenIV
= cpriv
->lenIV
;
153 FT_LOCAL_DEF( FT_Error
)
154 cff_size_init( FT_Size cffsize
) /* CFF_Size */
156 CFF_Size size
= (CFF_Size
)cffsize
;
157 FT_Error error
= CFF_Err_Ok
;
158 PSH_Globals_Funcs funcs
= cff_size_get_globals_funcs( size
);
163 CFF_Face face
= (CFF_Face
)cffsize
->face
;
164 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
165 CFF_Internal internal
;
168 FT_Memory memory
= cffsize
->face
->memory
;
173 if ( FT_NEW( internal
) )
176 cff_make_private_dict( &font
->top_font
, &priv
);
177 error
= funcs
->create( cffsize
->face
->memory
, &priv
,
178 &internal
->topfont
);
182 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
184 CFF_SubFont sub
= font
->subfonts
[i
- 1];
187 cff_make_private_dict( sub
, &priv
);
188 error
= funcs
->create( cffsize
->face
->memory
, &priv
,
189 &internal
->subfonts
[i
- 1] );
194 cffsize
->internal
= (FT_Size_Internal
)(void*)internal
;
197 size
->strike_index
= 0xFFFFFFFFUL
;
204 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
206 FT_LOCAL_DEF( FT_Error
)
207 cff_size_select( FT_Size size
,
208 FT_ULong strike_index
)
210 CFF_Size cffsize
= (CFF_Size
)size
;
211 PSH_Globals_Funcs funcs
;
214 cffsize
->strike_index
= strike_index
;
216 FT_Select_Metrics( size
->face
, strike_index
);
218 funcs
= cff_size_get_globals_funcs( cffsize
);
222 CFF_Face face
= (CFF_Face
)size
->face
;
223 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
224 CFF_Internal internal
= (CFF_Internal
)size
->internal
;
226 FT_Int top_upm
= font
->top_font
.font_dict
.units_per_em
;
230 funcs
->set_scale( internal
->topfont
,
231 size
->metrics
.x_scale
, size
->metrics
.y_scale
,
234 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
236 CFF_SubFont sub
= font
->subfonts
[i
- 1];
237 FT_Int sub_upm
= sub
->font_dict
.units_per_em
;
238 FT_Pos x_scale
, y_scale
;
241 if ( top_upm
!= sub_upm
)
243 x_scale
= FT_MulDiv( size
->metrics
.x_scale
, top_upm
, sub_upm
);
244 y_scale
= FT_MulDiv( size
->metrics
.y_scale
, top_upm
, sub_upm
);
248 x_scale
= size
->metrics
.x_scale
;
249 y_scale
= size
->metrics
.y_scale
;
252 funcs
->set_scale( internal
->subfonts
[i
- 1],
253 x_scale
, y_scale
, 0, 0 );
260 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
263 FT_LOCAL_DEF( FT_Error
)
264 cff_size_request( FT_Size size
,
265 FT_Size_Request req
)
267 CFF_Size cffsize
= (CFF_Size
)size
;
268 PSH_Globals_Funcs funcs
;
271 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
273 if ( FT_HAS_FIXED_SIZES( size
->face
) )
275 CFF_Face cffface
= (CFF_Face
)size
->face
;
276 SFNT_Service sfnt
= (SFNT_Service
)cffface
->sfnt
;
277 FT_ULong strike_index
;
280 if ( sfnt
->set_sbit_strike( cffface
, req
, &strike_index
) )
281 cffsize
->strike_index
= 0xFFFFFFFFUL
;
283 return cff_size_select( size
, strike_index
);
286 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
288 FT_Request_Metrics( size
->face
, req
);
290 funcs
= cff_size_get_globals_funcs( cffsize
);
294 CFF_Face cffface
= (CFF_Face
)size
->face
;
295 CFF_Font font
= (CFF_Font
)cffface
->extra
.data
;
296 CFF_Internal internal
= (CFF_Internal
)size
->internal
;
298 FT_Int top_upm
= font
->top_font
.font_dict
.units_per_em
;
302 funcs
->set_scale( internal
->topfont
,
303 size
->metrics
.x_scale
, size
->metrics
.y_scale
,
306 for ( i
= font
->num_subfonts
; i
> 0; i
-- )
308 CFF_SubFont sub
= font
->subfonts
[i
- 1];
309 FT_Int sub_upm
= sub
->font_dict
.units_per_em
;
310 FT_Pos x_scale
, y_scale
;
313 if ( top_upm
!= sub_upm
)
315 x_scale
= FT_MulDiv( size
->metrics
.x_scale
, top_upm
, sub_upm
);
316 y_scale
= FT_MulDiv( size
->metrics
.y_scale
, top_upm
, sub_upm
);
320 x_scale
= size
->metrics
.x_scale
;
321 y_scale
= size
->metrics
.y_scale
;
324 funcs
->set_scale( internal
->subfonts
[i
- 1],
325 x_scale
, y_scale
, 0, 0 );
333 /*************************************************************************/
337 /*************************************************************************/
340 cff_slot_done( FT_GlyphSlot slot
)
342 slot
->internal
->glyph_hints
= 0;
346 FT_LOCAL_DEF( FT_Error
)
347 cff_slot_init( FT_GlyphSlot slot
)
349 CFF_Face face
= (CFF_Face
)slot
->face
;
350 CFF_Font font
= (CFF_Font
)face
->extra
.data
;
351 PSHinter_Service pshinter
= (PSHinter_Service
)font
->pshinter
;
359 module
= FT_Get_Module( slot
->face
->driver
->root
.library
,
363 T2_Hints_Funcs funcs
;
366 funcs
= pshinter
->get_t2_funcs( module
);
367 slot
->internal
->glyph_hints
= (void*)funcs
;
375 /*************************************************************************/
379 /*************************************************************************/
382 cff_strcpy( FT_Memory memory
,
383 const FT_String
* source
)
389 (void)FT_STRDUP( result
, source
);
397 FT_LOCAL_DEF( FT_Error
)
398 cff_face_init( FT_Stream stream
,
399 FT_Face cffface
, /* CFF_Face */
402 FT_Parameter
* params
)
404 CFF_Face face
= (CFF_Face
)cffface
;
407 FT_Service_PsCMaps psnames
;
408 PSHinter_Service pshinter
;
409 FT_Bool pure_cff
= 1;
410 FT_Bool sfnt_format
= 0;
414 FT_FACE_FIND_GLOBAL_SERVICE( face
, sfnt
, SFNT
);
415 FT_FACE_FIND_GLOBAL_SERVICE( face
, psnames
, POSTSCRIPT_NAMES
);
416 FT_FACE_FIND_GLOBAL_SERVICE( face
, pshinter
, POSTSCRIPT_HINTER
);
421 sfnt
= (SFNT_Service
)FT_Get_Module_Interface(
422 cffface
->driver
->root
.library
, "sfnt" );
426 FT_FACE_FIND_GLOBAL_SERVICE( face
, psnames
, POSTSCRIPT_CMAPS
);
428 pshinter
= (PSHinter_Service
)FT_Get_Module_Interface(
429 cffface
->driver
->root
.library
, "pshinter" );
432 /* create input stream from resource */
433 if ( FT_STREAM_SEEK( 0 ) )
436 /* check whether we have a valid OpenType file */
437 error
= sfnt
->init_face( stream
, face
, face_index
, num_params
, params
);
440 if ( face
->format_tag
!= 0x4F54544FL
) /* `OTTO'; OpenType/CFF font */
442 FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
446 /* if we are performing a simple font format check, exit immediately */
447 if ( face_index
< 0 )
450 /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */
451 if ( face_index
> 0 )
453 FT_ERROR(( "cff_face_init: invalid face index\n" ));
454 error
= CFF_Err_Invalid_Argument
;
460 /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
461 /* font; in the latter case it doesn't have a `head' table */
462 error
= face
->goto_table( face
, TTAG_head
, stream
, 0 );
467 /* load font directory */
468 error
= sfnt
->load_face( stream
, face
,
469 face_index
, num_params
, params
);
475 /* load the `cmap' table explicitly */
476 error
= sfnt
->load_cmap( face
, stream
);
480 /* XXX: we don't load the GPOS table, as OpenType Layout */
481 /* support will be added later to a layout library on top of */
485 /* now load the CFF part of the file */
486 error
= face
->goto_table( face
, TTAG_CFF
, stream
, 0 );
492 /* rewind to start of file; we are going to load a pure-CFF font */
493 if ( FT_STREAM_SEEK( 0 ) )
498 /* now load and parse the CFF table in the file */
501 CFF_FontRecDict dict
;
502 FT_Memory memory
= cffface
->memory
;
510 face
->extra
.data
= cff
;
511 error
= cff_font_load( stream
, face_index
, cff
);
515 cff
->pshinter
= pshinter
;
516 cff
->psnames
= (void*)psnames
;
518 /* Complement the root flags with some interesting information. */
519 /* Note that this is only necessary for pure CFF and CEF fonts; */
520 /* SFNT based fonts use the `name' table instead. */
522 cffface
->num_glyphs
= cff
->num_glyphs
;
524 dict
= &cff
->top_font
.font_dict
;
526 /* we need the `PSNames' module for CFF and CEF formats */
527 /* which aren't CID-keyed */
528 if ( dict
->cid_registry
== 0xFFFFU
&& !psnames
)
530 FT_ERROR(( "cff_face_init:" ));
531 FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
533 FT_ERROR(( " without the `PSNames' module\n" ));
537 if ( !dict
->units_per_em
)
538 dict
->units_per_em
= pure_cff
? 1000 : face
->root
.units_per_EM
;
540 /* Normalize the font matrix so that `matrix->xx' is 1; the */
541 /* scaling is done with `units_per_em' then (at this point, */
542 /* it already contains the scaling factor, but without */
543 /* normalization of the matrix). */
545 /* Note that the offsets must be expressed in integer font */
549 FT_Matrix
* matrix
= &dict
->font_matrix
;
550 FT_Vector
* offset
= &dict
->font_offset
;
551 FT_ULong
* upm
= &dict
->units_per_em
;
552 FT_Fixed temp
= FT_ABS( matrix
->yy
);
555 if ( temp
!= 0x10000L
)
557 *upm
= FT_DivFix( *upm
, temp
);
559 matrix
->xx
= FT_DivFix( matrix
->xx
, temp
);
560 matrix
->yx
= FT_DivFix( matrix
->yx
, temp
);
561 matrix
->xy
= FT_DivFix( matrix
->xy
, temp
);
562 matrix
->yy
= FT_DivFix( matrix
->yy
, temp
);
563 offset
->x
= FT_DivFix( offset
->x
, temp
);
564 offset
->y
= FT_DivFix( offset
->y
, temp
);
571 for ( i
= cff
->num_subfonts
; i
> 0; i
-- )
573 CFF_FontRecDict sub
= &cff
->subfonts
[i
- 1]->font_dict
;
574 CFF_FontRecDict top
= &cff
->top_font
.font_dict
;
582 if ( sub
->units_per_em
)
587 if ( top
->units_per_em
> 1 && sub
->units_per_em
> 1 )
588 scaling
= FT_MIN( top
->units_per_em
, sub
->units_per_em
);
592 FT_Matrix_Multiply_Scaled( &top
->font_matrix
,
595 FT_Vector_Transform_Scaled( &sub
->font_offset
,
599 sub
->units_per_em
= FT_MulDiv( sub
->units_per_em
,
605 sub
->font_matrix
= top
->font_matrix
;
606 sub
->font_offset
= top
->font_offset
;
608 sub
->units_per_em
= top
->units_per_em
;
611 matrix
= &sub
->font_matrix
;
612 offset
= &sub
->font_offset
;
613 upm
= &sub
->units_per_em
;
614 temp
= FT_ABS( matrix
->yy
);
616 if ( temp
!= 0x10000L
)
618 *upm
= FT_DivFix( *upm
, temp
);
620 /* if *upm is larger than 100*1000 we divide by 1000 -- */
621 /* this can happen if e.g. there is no top-font FontMatrix */
622 /* and the subfont FontMatrix already contains the complete */
623 /* scaling for the subfont (see section 5.11 of the PLRM) */
625 /* 100 is a heuristic value */
627 if ( *upm
> 100L * 1000L )
628 *upm
= ( *upm
+ 500 ) / 1000;
630 matrix
->xx
= FT_DivFix( matrix
->xx
, temp
);
631 matrix
->yx
= FT_DivFix( matrix
->yx
, temp
);
632 matrix
->xy
= FT_DivFix( matrix
->xy
, temp
);
633 matrix
->yy
= FT_DivFix( matrix
->yy
, temp
);
634 offset
->x
= FT_DivFix( offset
->x
, temp
);
635 offset
->y
= FT_DivFix( offset
->y
, temp
);
644 char* style_name
= NULL
;
647 /* set up num_faces */
648 cffface
->num_faces
= cff
->num_faces
;
650 /* compute number of glyphs */
651 if ( dict
->cid_registry
!= 0xFFFFU
)
652 cffface
->num_glyphs
= cff
->charset
.max_cid
;
654 cffface
->num_glyphs
= cff
->charstrings_index
.count
;
656 /* set global bbox, as well as EM size */
657 cffface
->bbox
.xMin
= dict
->font_bbox
.xMin
>> 16;
658 cffface
->bbox
.yMin
= dict
->font_bbox
.yMin
>> 16;
659 cffface
->bbox
.xMax
= ( dict
->font_bbox
.xMax
+ 0xFFFFU
) >> 16;
660 cffface
->bbox
.yMax
= ( dict
->font_bbox
.yMax
+ 0xFFFFU
) >> 16;
663 cffface
->units_per_EM
= dict
->units_per_em
;
665 cffface
->ascender
= (FT_Short
)( cffface
->bbox
.yMax
);
666 cffface
->descender
= (FT_Short
)( cffface
->bbox
.yMin
);
668 cffface
->height
= (FT_Short
)( ( cffface
->units_per_EM
* 12 ) / 10 );
669 if ( cffface
->height
< cffface
->ascender
- cffface
->descender
)
670 cffface
->height
= (FT_Short
)( cffface
->ascender
- cffface
->descender
);
672 cffface
->underline_position
=
673 (FT_Short
)( dict
->underline_position
>> 16 );
674 cffface
->underline_thickness
=
675 (FT_Short
)( dict
->underline_thickness
>> 16 );
677 /* retrieve font family & style name */
678 cffface
->family_name
= cff_index_get_name( &cff
->name_index
,
681 if ( cffface
->family_name
)
683 char* full
= cff_index_get_sid_string( &cff
->string_index
,
687 char* family
= cffface
->family_name
;
688 char* family_name
= 0;
691 if ( dict
->family_name
)
693 family_name
= cff_index_get_sid_string( &cff
->string_index
,
697 family
= family_name
;
700 /* We try to extract the style name from the full name. */
701 /* We need to ignore spaces and dashes during the search. */
702 if ( full
&& family
)
706 /* skip common characters at the start of both strings */
707 if ( *fullp
== *family
)
714 /* ignore spaces and dashes in full name during comparison */
715 if ( *fullp
== ' ' || *fullp
== '-' )
721 /* ignore spaces and dashes in family name during comparison */
722 if ( *family
== ' ' || *family
== '-' )
728 if ( !*family
&& *fullp
)
730 /* The full name begins with the same characters as the */
731 /* family name, with spaces and dashes removed. In this */
732 /* case, the remaining string in `fullp' will be used as */
733 /* the style name. */
734 style_name
= cff_strcpy( memory
, fullp
);
740 FT_FREE( family_name
);
746 char *cid_font_name
=
747 cff_index_get_sid_string( &cff
->string_index
,
752 /* do we have a `/FontName' for a CID-keyed font? */
754 cffface
->family_name
= cid_font_name
;
758 cffface
->style_name
= style_name
;
760 /* assume "Regular" style if we don't know better */
761 cffface
->style_name
= cff_strcpy( memory
, (char *)"Regular" );
763 /*******************************************************************/
765 /* Compute face flags. */
767 flags
= FT_FACE_FLAG_SCALABLE
| /* scalable outlines */
768 FT_FACE_FLAG_HORIZONTAL
| /* horizontal data */
769 FT_FACE_FLAG_HINTER
; /* has native hinter */
772 flags
|= FT_FACE_FLAG_SFNT
;
774 /* fixed width font? */
775 if ( dict
->is_fixed_pitch
)
776 flags
|= FT_FACE_FLAG_FIXED_WIDTH
;
778 /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
780 /* kerning available? */
781 if ( face
->kern_pairs
)
782 flags
|= FT_FACE_FLAG_KERNING
;
785 cffface
->face_flags
= flags
;
787 /*******************************************************************/
789 /* Compute style flags. */
793 if ( dict
->italic_angle
)
794 flags
|= FT_STYLE_FLAG_ITALIC
;
797 char *weight
= cff_index_get_sid_string( &cff
->string_index
,
803 if ( !ft_strcmp( weight
, "Bold" ) ||
804 !ft_strcmp( weight
, "Black" ) )
805 flags
|= FT_STYLE_FLAG_BOLD
;
810 if ( !(flags
& FT_STYLE_FLAG_BOLD
) && cffface
->style_name
)
811 if ( !ft_strncmp( cffface
->style_name
, "Bold", 4 ) ||
812 !ft_strncmp( cffface
->style_name
, "Black", 5 ) )
813 flags
|= FT_STYLE_FLAG_BOLD
;
815 cffface
->style_flags
= flags
;
819 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
820 /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
821 /* has unset this flag because of the 3.0 `post' table. */
822 if ( dict
->cid_registry
== 0xFFFFU
)
823 cffface
->face_flags
|= FT_FACE_FLAG_GLYPH_NAMES
;
826 if ( dict
->cid_registry
!= 0xFFFFU
)
827 cffface
->face_flags
|= FT_FACE_FLAG_CID_KEYED
;
830 /*******************************************************************/
832 /* Compute char maps. */
835 /* Try to synthetize a Unicode charmap if there is none available */
836 /* already. If an OpenType font contains a Unicode "cmap", we */
837 /* will use it, whatever be in the CFF part of the file. */
839 FT_CharMapRec cmaprec
;
842 CFF_Encoding encoding
= &cff
->encoding
;
845 for ( nn
= 0; nn
< (FT_UInt
)cffface
->num_charmaps
; nn
++ )
847 cmap
= cffface
->charmaps
[nn
];
849 /* Windows Unicode (3,1)? */
850 if ( cmap
->platform_id
== 3 && cmap
->encoding_id
== 1 )
853 /* Deprecated Unicode platform id? */
854 if ( cmap
->platform_id
== 0 )
855 goto Skip_Unicode
; /* Standard Unicode (deprecated) */
858 /* since CID-keyed fonts don't contain glyph names, we can't */
859 /* construct a cmap */
860 if ( pure_cff
&& cff
->top_font
.font_dict
.cid_registry
!= 0xFFFFU
)
863 /* we didn't find a Unicode charmap -- synthesize one */
864 cmaprec
.face
= cffface
;
865 cmaprec
.platform_id
= 3;
866 cmaprec
.encoding_id
= 1;
867 cmaprec
.encoding
= FT_ENCODING_UNICODE
;
869 nn
= (FT_UInt
)cffface
->num_charmaps
;
871 FT_CMap_New( &cff_cmap_unicode_class_rec
, NULL
, &cmaprec
, NULL
);
873 /* if no Unicode charmap was previously selected, select this one */
874 if ( cffface
->charmap
== NULL
&& nn
!= (FT_UInt
)cffface
->num_charmaps
)
875 cffface
->charmap
= cffface
->charmaps
[nn
];
878 if ( encoding
->count
> 0 )
883 cmaprec
.face
= cffface
;
884 cmaprec
.platform_id
= 7; /* Adobe platform id */
886 if ( encoding
->offset
== 0 )
888 cmaprec
.encoding_id
= TT_ADOBE_ID_STANDARD
;
889 cmaprec
.encoding
= FT_ENCODING_ADOBE_STANDARD
;
890 clazz
= &cff_cmap_encoding_class_rec
;
892 else if ( encoding
->offset
== 1 )
894 cmaprec
.encoding_id
= TT_ADOBE_ID_EXPERT
;
895 cmaprec
.encoding
= FT_ENCODING_ADOBE_EXPERT
;
896 clazz
= &cff_cmap_encoding_class_rec
;
900 cmaprec
.encoding_id
= TT_ADOBE_ID_CUSTOM
;
901 cmaprec
.encoding
= FT_ENCODING_ADOBE_CUSTOM
;
902 clazz
= &cff_cmap_encoding_class_rec
;
905 FT_CMap_New( clazz
, NULL
, &cmaprec
, NULL
);
914 error
= CFF_Err_Unknown_File_Format
;
920 cff_face_done( FT_Face cffface
) /* CFF_Face */
922 CFF_Face face
= (CFF_Face
)cffface
;
923 FT_Memory memory
= cffface
->memory
;
924 SFNT_Service sfnt
= (SFNT_Service
)face
->sfnt
;
928 sfnt
->done_face( face
);
931 CFF_Font cff
= (CFF_Font
)face
->extra
.data
;
936 cff_font_done( cff
);
937 FT_FREE( face
->extra
.data
);
943 FT_LOCAL_DEF( FT_Error
)
944 cff_driver_init( FT_Module module
)
953 cff_driver_done( FT_Module module
)