1 /***************************************************************************/
5 /* OpenType objects manager (body). */
7 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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_FontRec
*)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
;
78 if ( cffsize
->internal
)
80 PSH_Globals_Funcs funcs
;
83 funcs
= cff_size_get_globals_funcs( size
);
85 funcs
->destroy( (PSH_Globals
)cffsize
->internal
);
87 cffsize
->internal
= 0;
92 FT_LOCAL_DEF( FT_Error
)
93 cff_size_init( FT_Size cffsize
) /* CFF_Size */
95 CFF_Size size
= (CFF_Size
)cffsize
;
96 FT_Error error
= CFF_Err_Ok
;
97 PSH_Globals_Funcs funcs
= cff_size_get_globals_funcs( size
);
103 CFF_Face face
= (CFF_Face
)cffsize
->face
;
104 CFF_Font font
= (CFF_FontRec
*)face
->extra
.data
;
105 CFF_SubFont subfont
= &font
->top_font
;
107 CFF_Private cpriv
= &subfont
->private_dict
;
111 /* IMPORTANT: The CFF and Type1 private dictionaries have */
112 /* slightly different structures; we need to */
113 /* synthetize a type1 dictionary on the fly here. */
119 FT_MEM_ZERO( &priv
, sizeof ( priv
) );
121 count
= priv
.num_blue_values
= cpriv
->num_blue_values
;
122 for ( n
= 0; n
< count
; n
++ )
123 priv
.blue_values
[n
] = (FT_Short
)cpriv
->blue_values
[n
];
125 count
= priv
.num_other_blues
= cpriv
->num_other_blues
;
126 for ( n
= 0; n
< count
; n
++ )
127 priv
.other_blues
[n
] = (FT_Short
)cpriv
->other_blues
[n
];
129 count
= priv
.num_family_blues
= cpriv
->num_family_blues
;
130 for ( n
= 0; n
< count
; n
++ )
131 priv
.family_blues
[n
] = (FT_Short
)cpriv
->family_blues
[n
];
133 count
= priv
.num_family_other_blues
= cpriv
->num_family_other_blues
;
134 for ( n
= 0; n
< count
; n
++ )
135 priv
.family_other_blues
[n
] = (FT_Short
)cpriv
->family_other_blues
[n
];
137 priv
.blue_scale
= cpriv
->blue_scale
;
138 priv
.blue_shift
= (FT_Int
)cpriv
->blue_shift
;
139 priv
.blue_fuzz
= (FT_Int
)cpriv
->blue_fuzz
;
141 priv
.standard_width
[0] = (FT_UShort
)cpriv
->standard_width
;
142 priv
.standard_height
[0] = (FT_UShort
)cpriv
->standard_height
;
144 count
= priv
.num_snap_widths
= cpriv
->num_snap_widths
;
145 for ( n
= 0; n
< count
; n
++ )
146 priv
.snap_widths
[n
] = (FT_Short
)cpriv
->snap_widths
[n
];
148 count
= priv
.num_snap_heights
= cpriv
->num_snap_heights
;
149 for ( n
= 0; n
< count
; n
++ )
150 priv
.snap_heights
[n
] = (FT_Short
)cpriv
->snap_heights
[n
];
152 priv
.force_bold
= cpriv
->force_bold
;
153 priv
.language_group
= cpriv
->language_group
;
154 priv
.lenIV
= cpriv
->lenIV
;
157 error
= funcs
->create( cffsize
->face
->memory
, &priv
, &globals
);
159 cffsize
->internal
= (FT_Size_Internal
)(void*)globals
;
162 size
->strike_index
= 0xFFFFFFFFUL
;
168 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
170 FT_LOCAL_DEF( FT_Error
)
171 cff_size_select( FT_Size size
,
172 FT_ULong strike_index
)
174 CFF_Size cffsize
= (CFF_Size
)size
;
175 PSH_Globals_Funcs funcs
;
178 cffsize
->strike_index
= strike_index
;
180 FT_Select_Metrics( size
->face
, strike_index
);
182 funcs
= cff_size_get_globals_funcs( cffsize
);
185 funcs
->set_scale( (PSH_Globals
)size
->internal
,
186 size
->metrics
.x_scale
,
187 size
->metrics
.y_scale
,
193 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
196 FT_LOCAL_DEF( FT_Error
)
197 cff_size_request( FT_Size size
,
198 FT_Size_Request req
)
200 CFF_Size cffsize
= (CFF_Size
)size
;
201 PSH_Globals_Funcs funcs
;
204 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
206 if ( FT_HAS_FIXED_SIZES( size
->face
) )
208 CFF_Face cffface
= (CFF_Face
)size
->face
;
209 SFNT_Service sfnt
= (SFNT_Service
)cffface
->sfnt
;
210 FT_ULong strike_index
;
213 if ( sfnt
->set_sbit_strike( cffface
, req
, &strike_index
) )
214 cffsize
->strike_index
= 0xFFFFFFFFUL
;
216 return cff_size_select( size
, strike_index
);
219 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
221 FT_Request_Metrics( size
->face
, req
);
223 funcs
= cff_size_get_globals_funcs( cffsize
);
226 funcs
->set_scale( (PSH_Globals
)size
->internal
,
227 size
->metrics
.x_scale
,
228 size
->metrics
.y_scale
,
235 /*************************************************************************/
239 /*************************************************************************/
242 cff_slot_done( FT_GlyphSlot slot
)
244 slot
->internal
->glyph_hints
= 0;
248 FT_LOCAL_DEF( FT_Error
)
249 cff_slot_init( FT_GlyphSlot slot
)
251 CFF_Face face
= (CFF_Face
)slot
->face
;
252 CFF_Font font
= (CFF_FontRec
*)face
->extra
.data
;
253 PSHinter_Service pshinter
= (PSHinter_Service
)font
->pshinter
;
261 module
= FT_Get_Module( slot
->face
->driver
->root
.library
,
265 T2_Hints_Funcs funcs
;
268 funcs
= pshinter
->get_t2_funcs( module
);
269 slot
->internal
->glyph_hints
= (void*)funcs
;
277 /*************************************************************************/
281 /*************************************************************************/
284 cff_strcpy( FT_Memory memory
,
285 const FT_String
* source
)
291 result
= ft_mem_strdup( memory
, source
, &error
);
297 FT_LOCAL_DEF( FT_Error
)
298 cff_face_init( FT_Stream stream
,
299 FT_Face cffface
, /* CFF_Face */
302 FT_Parameter
* params
)
304 CFF_Face face
= (CFF_Face
)cffface
;
307 FT_Service_PsCMaps psnames
;
308 PSHinter_Service pshinter
;
309 FT_Bool pure_cff
= 1;
310 FT_Bool sfnt_format
= 0;
314 FT_FACE_FIND_GLOBAL_SERVICE( face
, sfnt
, SFNT
);
315 FT_FACE_FIND_GLOBAL_SERVICE( face
, psnames
, POSTSCRIPT_NAMES
);
316 FT_FACE_FIND_GLOBAL_SERVICE( face
, pshinter
, POSTSCRIPT_HINTER
);
321 sfnt
= (SFNT_Service
)FT_Get_Module_Interface(
322 cffface
->driver
->root
.library
, "sfnt" );
326 FT_FACE_FIND_GLOBAL_SERVICE( face
, psnames
, POSTSCRIPT_CMAPS
);
328 pshinter
= (PSHinter_Service
)FT_Get_Module_Interface(
329 cffface
->driver
->root
.library
, "pshinter" );
332 /* create input stream from resource */
333 if ( FT_STREAM_SEEK( 0 ) )
336 /* check whether we have a valid OpenType file */
337 error
= sfnt
->init_face( stream
, face
, face_index
, num_params
, params
);
340 if ( face
->format_tag
!= 0x4F54544FL
) /* `OTTO'; OpenType/CFF font */
342 FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
346 /* if we are performing a simple font format check, exit immediately */
347 if ( face_index
< 0 )
350 /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */
351 if ( face_index
> 0 )
353 FT_ERROR(( "cff_face_init: invalid face index\n" ));
354 error
= CFF_Err_Invalid_Argument
;
360 /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
361 /* font; in the latter case it doesn't have a `head' table */
362 error
= face
->goto_table( face
, TTAG_head
, stream
, 0 );
367 /* load font directory */
368 error
= sfnt
->load_face( stream
, face
,
369 face_index
, num_params
, params
);
375 /* load the `cmap' table explicitly */
376 error
= sfnt
->load_cmap( face
, stream
);
380 /* XXX: we don't load the GPOS table, as OpenType Layout */
381 /* support will be added later to a layout library on top of */
385 /* now load the CFF part of the file */
386 error
= face
->goto_table( face
, TTAG_CFF
, stream
, 0 );
392 /* rewind to start of file; we are going to load a pure-CFF font */
393 if ( FT_STREAM_SEEK( 0 ) )
398 /* now load and parse the CFF table in the file */
401 CFF_FontRecDict dict
;
402 FT_Memory memory
= cffface
->memory
;
410 face
->extra
.data
= cff
;
411 error
= cff_font_load( stream
, face_index
, cff
);
415 cff
->pshinter
= pshinter
;
416 cff
->psnames
= (void*)psnames
;
418 /* Complement the root flags with some interesting information. */
419 /* Note that this is only necessary for pure CFF and CEF fonts; */
420 /* SFNT based fonts use the `name' table instead. */
422 cffface
->num_glyphs
= cff
->num_glyphs
;
424 dict
= &cff
->top_font
.font_dict
;
426 /* we need the `PSNames' module for CFF and CEF formats */
427 /* which aren't CID-keyed */
428 if ( dict
->cid_registry
== 0xFFFFU
&& !psnames
)
430 FT_ERROR(( "cff_face_init:" ));
431 FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
433 FT_ERROR(( " without the `PSNames' module\n" ));
439 char* style_name
= NULL
;
442 /* set up num_faces */
443 cffface
->num_faces
= cff
->num_faces
;
445 /* compute number of glyphs */
446 if ( dict
->cid_registry
!= 0xFFFFU
)
447 cffface
->num_glyphs
= dict
->cid_count
;
449 cffface
->num_glyphs
= cff
->charstrings_index
.count
;
451 /* set global bbox, as well as EM size */
452 cffface
->bbox
.xMin
= dict
->font_bbox
.xMin
>> 16;
453 cffface
->bbox
.yMin
= dict
->font_bbox
.yMin
>> 16;
454 cffface
->bbox
.xMax
= ( dict
->font_bbox
.xMax
+ 0xFFFFU
) >> 16;
455 cffface
->bbox
.yMax
= ( dict
->font_bbox
.yMax
+ 0xFFFFU
) >> 16;
457 if ( !dict
->units_per_em
)
458 dict
->units_per_em
= 1000;
460 cffface
->units_per_EM
= dict
->units_per_em
;
462 cffface
->ascender
= (FT_Short
)( cffface
->bbox
.yMax
);
463 cffface
->descender
= (FT_Short
)( cffface
->bbox
.yMin
);
465 cffface
->height
= (FT_Short
)( ( cffface
->units_per_EM
* 12 ) / 10 );
466 if ( cffface
->height
< cffface
->ascender
- cffface
->descender
)
467 cffface
->height
= (FT_Short
)( cffface
->ascender
- cffface
->descender
);
469 cffface
->underline_position
=
470 (FT_Short
)( dict
->underline_position
>> 16 );
471 cffface
->underline_thickness
=
472 (FT_Short
)( dict
->underline_thickness
>> 16 );
474 /* retrieve font family & style name */
475 cffface
->family_name
= cff_index_get_name( &cff
->name_index
,
478 if ( cffface
->family_name
)
480 char* full
= cff_index_get_sid_string( &cff
->string_index
,
484 char* family
= cffface
->family_name
;
485 char* family_name
= 0;
488 if ( dict
->family_name
)
490 family_name
= cff_index_get_sid_string( &cff
->string_index
,
494 family
= family_name
;
497 /* We try to extract the style name from the full name. */
498 /* We need to ignore spaces and dashes during the search. */
499 if ( full
&& family
)
503 /* skip common characters at the start of both strings */
504 if ( *fullp
== *family
)
511 /* ignore spaces and dashes in full name during comparison */
512 if ( *fullp
== ' ' || *fullp
== '-' )
518 /* ignore spaces and dashes in family name during comparison */
519 if ( *family
== ' ' || *family
== '-' )
525 if ( !*family
&& *fullp
)
527 /* The full name begins with the same characters as the */
528 /* family name, with spaces and dashes removed. In this */
529 /* case, the remaining string in `fullp' will be used as */
530 /* the style name. */
531 style_name
= cff_strcpy( memory
, fullp
);
537 FT_FREE( family_name
);
543 char *cid_font_name
=
544 cff_index_get_sid_string( &cff
->string_index
,
549 /* do we have a `/FontName' for a CID-keyed font? */
551 cffface
->family_name
= cid_font_name
;
555 cffface
->style_name
= style_name
;
557 /* assume "Regular" style if we don't know better */
558 cffface
->style_name
= cff_strcpy( memory
, (char *)"Regular" );
560 /*******************************************************************/
562 /* Compute face flags. */
564 flags
= FT_FACE_FLAG_SCALABLE
| /* scalable outlines */
565 FT_FACE_FLAG_HORIZONTAL
| /* horizontal data */
566 FT_FACE_FLAG_HINTER
; /* has native hinter */
569 flags
|= FT_FACE_FLAG_SFNT
;
571 /* fixed width font? */
572 if ( dict
->is_fixed_pitch
)
573 flags
|= FT_FACE_FLAG_FIXED_WIDTH
;
575 /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
577 /* kerning available? */
578 if ( face
->kern_pairs
)
579 flags
|= FT_FACE_FLAG_KERNING
;
582 cffface
->face_flags
= flags
;
584 /*******************************************************************/
586 /* Compute style flags. */
590 if ( dict
->italic_angle
)
591 flags
|= FT_STYLE_FLAG_ITALIC
;
594 char *weight
= cff_index_get_sid_string( &cff
->string_index
,
600 if ( !ft_strcmp( weight
, "Bold" ) ||
601 !ft_strcmp( weight
, "Black" ) )
602 flags
|= FT_STYLE_FLAG_BOLD
;
607 if ( !(flags
& FT_STYLE_FLAG_BOLD
) && cffface
->style_name
)
608 if ( !ft_strncmp( cffface
->style_name
, "Bold", 4 ) ||
609 !ft_strncmp( cffface
->style_name
, "Black", 5 ) )
610 flags
|= FT_STYLE_FLAG_BOLD
;
612 cffface
->style_flags
= flags
;
616 if ( !dict
->units_per_em
)
617 dict
->units_per_em
= face
->root
.units_per_EM
;
620 /* handle font matrix settings in subfonts (if any) */
621 for ( i
= cff
->num_subfonts
; i
> 0; i
-- )
623 CFF_FontRecDict sub
= &cff
->subfonts
[i
- 1]->font_dict
;
624 CFF_FontRecDict top
= &cff
->top_font
.font_dict
;
627 if ( sub
->units_per_em
)
632 scale
.xx
= scale
.yy
= (FT_Fixed
)FT_DivFix( top
->units_per_em
,
634 scale
.xy
= scale
.yx
= 0;
636 FT_Matrix_Multiply( &scale
, &sub
->font_matrix
);
637 FT_Vector_Transform( &sub
->font_offset
, &scale
);
641 sub
->font_matrix
= top
->font_matrix
;
642 sub
->font_offset
= top
->font_offset
;
646 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
647 /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
648 /* has unset this flag because of the 3.0 `post' table */
649 if ( dict
->cid_registry
== 0xFFFFU
)
650 cffface
->face_flags
|= FT_FACE_FLAG_GLYPH_NAMES
;
653 /*******************************************************************/
655 /* Compute char maps. */
658 /* Try to synthetize a Unicode charmap if there is none available */
659 /* already. If an OpenType font contains a Unicode "cmap", we */
660 /* will use it, whatever be in the CFF part of the file. */
662 FT_CharMapRec cmaprec
;
665 CFF_Encoding encoding
= &cff
->encoding
;
668 for ( nn
= 0; nn
< (FT_UInt
)cffface
->num_charmaps
; nn
++ )
670 cmap
= cffface
->charmaps
[nn
];
672 /* Windows Unicode (3,1)? */
673 if ( cmap
->platform_id
== 3 && cmap
->encoding_id
== 1 )
676 /* Deprecated Unicode platform id? */
677 if ( cmap
->platform_id
== 0 )
678 goto Skip_Unicode
; /* Standard Unicode (deprecated) */
681 /* since CID-keyed fonts don't contain glyph names, we can't */
682 /* construct a cmap */
683 if ( pure_cff
&& cff
->top_font
.font_dict
.cid_registry
!= 0xFFFFU
)
686 /* we didn't find a Unicode charmap -- synthetize one */
687 cmaprec
.face
= cffface
;
688 cmaprec
.platform_id
= 3;
689 cmaprec
.encoding_id
= 1;
690 cmaprec
.encoding
= FT_ENCODING_UNICODE
;
692 nn
= (FT_UInt
)cffface
->num_charmaps
;
694 FT_CMap_New( &cff_cmap_unicode_class_rec
, NULL
, &cmaprec
, NULL
);
696 /* if no Unicode charmap was previously selected, select this one */
697 if ( cffface
->charmap
== NULL
&& nn
!= (FT_UInt
)cffface
->num_charmaps
)
698 cffface
->charmap
= cffface
->charmaps
[nn
];
701 if ( encoding
->count
> 0 )
706 cmaprec
.face
= cffface
;
707 cmaprec
.platform_id
= 7; /* Adobe platform id */
709 if ( encoding
->offset
== 0 )
711 cmaprec
.encoding_id
= TT_ADOBE_ID_STANDARD
;
712 cmaprec
.encoding
= FT_ENCODING_ADOBE_STANDARD
;
713 clazz
= &cff_cmap_encoding_class_rec
;
715 else if ( encoding
->offset
== 1 )
717 cmaprec
.encoding_id
= TT_ADOBE_ID_EXPERT
;
718 cmaprec
.encoding
= FT_ENCODING_ADOBE_EXPERT
;
719 clazz
= &cff_cmap_encoding_class_rec
;
723 cmaprec
.encoding_id
= TT_ADOBE_ID_CUSTOM
;
724 cmaprec
.encoding
= FT_ENCODING_ADOBE_CUSTOM
;
725 clazz
= &cff_cmap_encoding_class_rec
;
728 FT_CMap_New( clazz
, NULL
, &cmaprec
, NULL
);
737 error
= CFF_Err_Unknown_File_Format
;
743 cff_face_done( FT_Face cffface
) /* CFF_Face */
745 CFF_Face face
= (CFF_Face
)cffface
;
746 FT_Memory memory
= cffface
->memory
;
747 SFNT_Service sfnt
= (SFNT_Service
)face
->sfnt
;
751 sfnt
->done_face( face
);
754 CFF_Font cff
= (CFF_Font
)face
->extra
.data
;
759 cff_font_done( cff
);
760 FT_FREE( face
->extra
.data
);
766 FT_LOCAL_DEF( FT_Error
)
767 cff_driver_init( FT_Module module
)
776 cff_driver_done( FT_Module module
)