1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* cffobjs.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* OpenType objects manager (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 1996-2001, 2002 by */ 8*37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9*37da2899SCharles.Forsyth /* */ 10*37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11*37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12*37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13*37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14*37da2899SCharles.Forsyth /* understand and accept it fully. */ 15*37da2899SCharles.Forsyth /* */ 16*37da2899SCharles.Forsyth /***************************************************************************/ 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth #include <ft2build.h> 20*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 21*37da2899SCharles.Forsyth #include FT_INTERNAL_CALC_H 22*37da2899SCharles.Forsyth #include FT_INTERNAL_STREAM_H 23*37da2899SCharles.Forsyth #include FT_ERRORS_H 24*37da2899SCharles.Forsyth #include FT_TRUETYPE_IDS_H 25*37da2899SCharles.Forsyth #include FT_TRUETYPE_TAGS_H 26*37da2899SCharles.Forsyth #include FT_INTERNAL_SFNT_H 27*37da2899SCharles.Forsyth #include FT_INTERNAL_POSTSCRIPT_NAMES_H 28*37da2899SCharles.Forsyth #include FT_INTERNAL_POSTSCRIPT_HINTS_H 29*37da2899SCharles.Forsyth #include "cffobjs.h" 30*37da2899SCharles.Forsyth #include "cffload.h" 31*37da2899SCharles.Forsyth #include "cffcmap.h" 32*37da2899SCharles.Forsyth #include "cfferrs.h" 33*37da2899SCharles.Forsyth 34*37da2899SCharles.Forsyth 35*37da2899SCharles.Forsyth /*************************************************************************/ 36*37da2899SCharles.Forsyth /* */ 37*37da2899SCharles.Forsyth /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 38*37da2899SCharles.Forsyth /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 39*37da2899SCharles.Forsyth /* messages during execution. */ 40*37da2899SCharles.Forsyth /* */ 41*37da2899SCharles.Forsyth #undef FT_COMPONENT 42*37da2899SCharles.Forsyth #define FT_COMPONENT trace_cffobjs 43*37da2899SCharles.Forsyth 44*37da2899SCharles.Forsyth 45*37da2899SCharles.Forsyth /*************************************************************************/ 46*37da2899SCharles.Forsyth /* */ 47*37da2899SCharles.Forsyth /* SIZE FUNCTIONS */ 48*37da2899SCharles.Forsyth /* */ 49*37da2899SCharles.Forsyth /* Note that we store the global hints in the size's "internal" root */ 50*37da2899SCharles.Forsyth /* field. */ 51*37da2899SCharles.Forsyth /* */ 52*37da2899SCharles.Forsyth /*************************************************************************/ 53*37da2899SCharles.Forsyth 54*37da2899SCharles.Forsyth 55*37da2899SCharles.Forsyth static PSH_Globals_Funcs cff_size_get_globals_funcs(CFF_Size size)56*37da2899SCharles.Forsyth cff_size_get_globals_funcs( CFF_Size size ) 57*37da2899SCharles.Forsyth { 58*37da2899SCharles.Forsyth CFF_Face face = (CFF_Face)size->face; 59*37da2899SCharles.Forsyth CFF_Font font = (CFF_FontRec *)face->extra.data; 60*37da2899SCharles.Forsyth PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; 61*37da2899SCharles.Forsyth FT_Module module; 62*37da2899SCharles.Forsyth 63*37da2899SCharles.Forsyth 64*37da2899SCharles.Forsyth module = FT_Get_Module( size->face->driver->root.library, 65*37da2899SCharles.Forsyth "pshinter" ); 66*37da2899SCharles.Forsyth return ( module && pshinter && pshinter->get_globals_funcs ) 67*37da2899SCharles.Forsyth ? pshinter->get_globals_funcs( module ) 68*37da2899SCharles.Forsyth : 0; 69*37da2899SCharles.Forsyth } 70*37da2899SCharles.Forsyth 71*37da2899SCharles.Forsyth 72*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) cff_size_done(CFF_Size size)73*37da2899SCharles.Forsyth cff_size_done( CFF_Size size ) 74*37da2899SCharles.Forsyth { 75*37da2899SCharles.Forsyth if ( size->internal ) 76*37da2899SCharles.Forsyth { 77*37da2899SCharles.Forsyth PSH_Globals_Funcs funcs; 78*37da2899SCharles.Forsyth 79*37da2899SCharles.Forsyth 80*37da2899SCharles.Forsyth funcs = cff_size_get_globals_funcs( size ); 81*37da2899SCharles.Forsyth if ( funcs ) 82*37da2899SCharles.Forsyth funcs->destroy( (PSH_Globals)size->internal ); 83*37da2899SCharles.Forsyth 84*37da2899SCharles.Forsyth size->internal = 0; 85*37da2899SCharles.Forsyth } 86*37da2899SCharles.Forsyth } 87*37da2899SCharles.Forsyth 88*37da2899SCharles.Forsyth 89*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) cff_size_init(CFF_Size size)90*37da2899SCharles.Forsyth cff_size_init( CFF_Size size ) 91*37da2899SCharles.Forsyth { 92*37da2899SCharles.Forsyth FT_Error error = 0; 93*37da2899SCharles.Forsyth PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); 94*37da2899SCharles.Forsyth 95*37da2899SCharles.Forsyth 96*37da2899SCharles.Forsyth if ( funcs ) 97*37da2899SCharles.Forsyth { 98*37da2899SCharles.Forsyth PSH_Globals globals; 99*37da2899SCharles.Forsyth CFF_Face face = (CFF_Face)size->face; 100*37da2899SCharles.Forsyth CFF_Font font = (CFF_FontRec *)face->extra.data; 101*37da2899SCharles.Forsyth CFF_SubFont subfont = &font->top_font; 102*37da2899SCharles.Forsyth 103*37da2899SCharles.Forsyth CFF_Private cpriv = &subfont->private_dict; 104*37da2899SCharles.Forsyth PS_PrivateRec priv; 105*37da2899SCharles.Forsyth 106*37da2899SCharles.Forsyth 107*37da2899SCharles.Forsyth /* IMPORTANT: The CFF and Type1 private dictionaries have */ 108*37da2899SCharles.Forsyth /* slightly different structures; we need to */ 109*37da2899SCharles.Forsyth /* synthetize a type1 dictionary on the fly here. */ 110*37da2899SCharles.Forsyth 111*37da2899SCharles.Forsyth { 112*37da2899SCharles.Forsyth FT_UInt n, count; 113*37da2899SCharles.Forsyth 114*37da2899SCharles.Forsyth 115*37da2899SCharles.Forsyth FT_MEM_ZERO( &priv, sizeof ( priv ) ); 116*37da2899SCharles.Forsyth 117*37da2899SCharles.Forsyth count = priv.num_blue_values = cpriv->num_blue_values; 118*37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 119*37da2899SCharles.Forsyth priv.blue_values[n] = (FT_Short)cpriv->blue_values[n]; 120*37da2899SCharles.Forsyth 121*37da2899SCharles.Forsyth count = priv.num_other_blues = cpriv->num_other_blues; 122*37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 123*37da2899SCharles.Forsyth priv.other_blues[n] = (FT_Short)cpriv->other_blues[n]; 124*37da2899SCharles.Forsyth 125*37da2899SCharles.Forsyth count = priv.num_family_blues = cpriv->num_family_blues; 126*37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 127*37da2899SCharles.Forsyth priv.family_blues[n] = (FT_Short)cpriv->family_blues[n]; 128*37da2899SCharles.Forsyth 129*37da2899SCharles.Forsyth count = priv.num_family_other_blues = cpriv->num_family_other_blues; 130*37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 131*37da2899SCharles.Forsyth priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; 132*37da2899SCharles.Forsyth 133*37da2899SCharles.Forsyth priv.blue_scale = cpriv->blue_scale; 134*37da2899SCharles.Forsyth priv.blue_shift = (FT_Int)cpriv->blue_shift; 135*37da2899SCharles.Forsyth priv.blue_fuzz = (FT_Int)cpriv->blue_fuzz; 136*37da2899SCharles.Forsyth 137*37da2899SCharles.Forsyth priv.standard_width[0] = (FT_UShort)cpriv->standard_width; 138*37da2899SCharles.Forsyth priv.standard_height[0] = (FT_UShort)cpriv->standard_height; 139*37da2899SCharles.Forsyth 140*37da2899SCharles.Forsyth count = priv.num_snap_widths = cpriv->num_snap_widths; 141*37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 142*37da2899SCharles.Forsyth priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; 143*37da2899SCharles.Forsyth 144*37da2899SCharles.Forsyth count = priv.num_snap_heights = cpriv->num_snap_heights; 145*37da2899SCharles.Forsyth for ( n = 0; n < count; n++ ) 146*37da2899SCharles.Forsyth priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; 147*37da2899SCharles.Forsyth 148*37da2899SCharles.Forsyth priv.force_bold = cpriv->force_bold; 149*37da2899SCharles.Forsyth priv.language_group = cpriv->language_group; 150*37da2899SCharles.Forsyth priv.lenIV = cpriv->lenIV; 151*37da2899SCharles.Forsyth } 152*37da2899SCharles.Forsyth 153*37da2899SCharles.Forsyth error = funcs->create( size->face->memory, &priv, &globals ); 154*37da2899SCharles.Forsyth if ( !error ) 155*37da2899SCharles.Forsyth size->internal = (FT_Size_Internal)(void*)globals; 156*37da2899SCharles.Forsyth } 157*37da2899SCharles.Forsyth 158*37da2899SCharles.Forsyth return error; 159*37da2899SCharles.Forsyth } 160*37da2899SCharles.Forsyth 161*37da2899SCharles.Forsyth 162*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) cff_size_reset(CFF_Size size)163*37da2899SCharles.Forsyth cff_size_reset( CFF_Size size ) 164*37da2899SCharles.Forsyth { 165*37da2899SCharles.Forsyth PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); 166*37da2899SCharles.Forsyth FT_Error error = 0; 167*37da2899SCharles.Forsyth 168*37da2899SCharles.Forsyth 169*37da2899SCharles.Forsyth if ( funcs ) 170*37da2899SCharles.Forsyth error = funcs->set_scale( (PSH_Globals)size->internal, 171*37da2899SCharles.Forsyth size->metrics.x_scale, 172*37da2899SCharles.Forsyth size->metrics.y_scale, 173*37da2899SCharles.Forsyth 0, 0 ); 174*37da2899SCharles.Forsyth return error; 175*37da2899SCharles.Forsyth } 176*37da2899SCharles.Forsyth 177*37da2899SCharles.Forsyth 178*37da2899SCharles.Forsyth /*************************************************************************/ 179*37da2899SCharles.Forsyth /* */ 180*37da2899SCharles.Forsyth /* SLOT FUNCTIONS */ 181*37da2899SCharles.Forsyth /* */ 182*37da2899SCharles.Forsyth /*************************************************************************/ 183*37da2899SCharles.Forsyth 184*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) cff_slot_done(CFF_GlyphSlot slot)185*37da2899SCharles.Forsyth cff_slot_done( CFF_GlyphSlot slot ) 186*37da2899SCharles.Forsyth { 187*37da2899SCharles.Forsyth slot->root.internal->glyph_hints = 0; 188*37da2899SCharles.Forsyth } 189*37da2899SCharles.Forsyth 190*37da2899SCharles.Forsyth 191*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) cff_slot_init(CFF_GlyphSlot slot)192*37da2899SCharles.Forsyth cff_slot_init( CFF_GlyphSlot slot ) 193*37da2899SCharles.Forsyth { 194*37da2899SCharles.Forsyth CFF_Face face = (CFF_Face)slot->root.face; 195*37da2899SCharles.Forsyth CFF_Font font = (CFF_FontRec *)face->extra.data; 196*37da2899SCharles.Forsyth PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; 197*37da2899SCharles.Forsyth 198*37da2899SCharles.Forsyth 199*37da2899SCharles.Forsyth if ( pshinter ) 200*37da2899SCharles.Forsyth { 201*37da2899SCharles.Forsyth FT_Module module; 202*37da2899SCharles.Forsyth 203*37da2899SCharles.Forsyth 204*37da2899SCharles.Forsyth module = FT_Get_Module( slot->root.face->driver->root.library, 205*37da2899SCharles.Forsyth "pshinter" ); 206*37da2899SCharles.Forsyth if ( module ) 207*37da2899SCharles.Forsyth { 208*37da2899SCharles.Forsyth T2_Hints_Funcs funcs; 209*37da2899SCharles.Forsyth 210*37da2899SCharles.Forsyth 211*37da2899SCharles.Forsyth funcs = pshinter->get_t2_funcs( module ); 212*37da2899SCharles.Forsyth slot->root.internal->glyph_hints = (void*)funcs; 213*37da2899SCharles.Forsyth } 214*37da2899SCharles.Forsyth } 215*37da2899SCharles.Forsyth 216*37da2899SCharles.Forsyth return 0; 217*37da2899SCharles.Forsyth } 218*37da2899SCharles.Forsyth 219*37da2899SCharles.Forsyth 220*37da2899SCharles.Forsyth /*************************************************************************/ 221*37da2899SCharles.Forsyth /* */ 222*37da2899SCharles.Forsyth /* FACE FUNCTIONS */ 223*37da2899SCharles.Forsyth /* */ 224*37da2899SCharles.Forsyth /*************************************************************************/ 225*37da2899SCharles.Forsyth 226*37da2899SCharles.Forsyth static FT_String* cff_strcpy(FT_Memory memory,const FT_String * source)227*37da2899SCharles.Forsyth cff_strcpy( FT_Memory memory, 228*37da2899SCharles.Forsyth const FT_String* source ) 229*37da2899SCharles.Forsyth { 230*37da2899SCharles.Forsyth FT_Error error; 231*37da2899SCharles.Forsyth FT_String* result = 0; 232*37da2899SCharles.Forsyth FT_Int len = (FT_Int)ft_strlen( source ); 233*37da2899SCharles.Forsyth 234*37da2899SCharles.Forsyth 235*37da2899SCharles.Forsyth if ( !FT_ALLOC( result, len + 1 ) ) 236*37da2899SCharles.Forsyth { 237*37da2899SCharles.Forsyth FT_MEM_COPY( result, source, len ); 238*37da2899SCharles.Forsyth result[len] = 0; 239*37da2899SCharles.Forsyth } 240*37da2899SCharles.Forsyth 241*37da2899SCharles.Forsyth FT_UNUSED( error ); 242*37da2899SCharles.Forsyth 243*37da2899SCharles.Forsyth return result; 244*37da2899SCharles.Forsyth } 245*37da2899SCharles.Forsyth 246*37da2899SCharles.Forsyth 247*37da2899SCharles.Forsyth 248*37da2899SCharles.Forsyth 249*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) cff_face_init(FT_Stream stream,CFF_Face face,FT_Int face_index,FT_Int num_params,FT_Parameter * params)250*37da2899SCharles.Forsyth cff_face_init( FT_Stream stream, 251*37da2899SCharles.Forsyth CFF_Face face, 252*37da2899SCharles.Forsyth FT_Int face_index, 253*37da2899SCharles.Forsyth FT_Int num_params, 254*37da2899SCharles.Forsyth FT_Parameter* params ) 255*37da2899SCharles.Forsyth { 256*37da2899SCharles.Forsyth FT_Error error; 257*37da2899SCharles.Forsyth SFNT_Service sfnt; 258*37da2899SCharles.Forsyth PSNames_Service psnames; 259*37da2899SCharles.Forsyth PSHinter_Service pshinter; 260*37da2899SCharles.Forsyth FT_Bool pure_cff = 1; 261*37da2899SCharles.Forsyth FT_Bool sfnt_format = 0; 262*37da2899SCharles.Forsyth 263*37da2899SCharles.Forsyth 264*37da2899SCharles.Forsyth sfnt = (SFNT_Service)FT_Get_Module_Interface( 265*37da2899SCharles.Forsyth face->root.driver->root.library, "sfnt" ); 266*37da2899SCharles.Forsyth if ( !sfnt ) 267*37da2899SCharles.Forsyth goto Bad_Format; 268*37da2899SCharles.Forsyth 269*37da2899SCharles.Forsyth psnames = (PSNames_Service)FT_Get_Module_Interface( 270*37da2899SCharles.Forsyth face->root.driver->root.library, "psnames" ); 271*37da2899SCharles.Forsyth 272*37da2899SCharles.Forsyth pshinter = (PSHinter_Service)FT_Get_Module_Interface( 273*37da2899SCharles.Forsyth face->root.driver->root.library, "pshinter" ); 274*37da2899SCharles.Forsyth 275*37da2899SCharles.Forsyth /* create input stream from resource */ 276*37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( 0 ) ) 277*37da2899SCharles.Forsyth goto Exit; 278*37da2899SCharles.Forsyth 279*37da2899SCharles.Forsyth /* check that we have a valid OpenType file */ 280*37da2899SCharles.Forsyth error = sfnt->init_face( stream, face, face_index, num_params, params ); 281*37da2899SCharles.Forsyth if ( !error ) 282*37da2899SCharles.Forsyth { 283*37da2899SCharles.Forsyth if ( face->format_tag != 0x4F54544FL ) /* `OTTO'; OpenType/CFF font */ 284*37da2899SCharles.Forsyth { 285*37da2899SCharles.Forsyth FT_TRACE2(( "[not a valid OpenType/CFF font]\n" )); 286*37da2899SCharles.Forsyth goto Bad_Format; 287*37da2899SCharles.Forsyth } 288*37da2899SCharles.Forsyth 289*37da2899SCharles.Forsyth /* if we are performing a simple font format check, exit immediately */ 290*37da2899SCharles.Forsyth if ( face_index < 0 ) 291*37da2899SCharles.Forsyth return CFF_Err_Ok; 292*37da2899SCharles.Forsyth 293*37da2899SCharles.Forsyth sfnt_format = 1; 294*37da2899SCharles.Forsyth 295*37da2899SCharles.Forsyth /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ 296*37da2899SCharles.Forsyth /* font in the later case; it doesn't have a `head' table */ 297*37da2899SCharles.Forsyth error = face->goto_table( face, TTAG_head, stream, 0 ); 298*37da2899SCharles.Forsyth if ( !error ) 299*37da2899SCharles.Forsyth { 300*37da2899SCharles.Forsyth pure_cff = 0; 301*37da2899SCharles.Forsyth 302*37da2899SCharles.Forsyth /* load font directory */ 303*37da2899SCharles.Forsyth error = sfnt->load_face( stream, face, 304*37da2899SCharles.Forsyth face_index, num_params, params ); 305*37da2899SCharles.Forsyth if ( error ) 306*37da2899SCharles.Forsyth goto Exit; 307*37da2899SCharles.Forsyth } 308*37da2899SCharles.Forsyth else 309*37da2899SCharles.Forsyth { 310*37da2899SCharles.Forsyth /* load the `cmap' table by hand */ 311*37da2899SCharles.Forsyth error = sfnt->load_charmaps( face, stream ); 312*37da2899SCharles.Forsyth if ( error ) 313*37da2899SCharles.Forsyth goto Exit; 314*37da2899SCharles.Forsyth 315*37da2899SCharles.Forsyth /* XXX: we don't load the GPOS table, as OpenType Layout */ 316*37da2899SCharles.Forsyth /* support will be added later to a layout library on top of */ 317*37da2899SCharles.Forsyth /* FreeType 2 */ 318*37da2899SCharles.Forsyth } 319*37da2899SCharles.Forsyth 320*37da2899SCharles.Forsyth /* now, load the CFF part of the file */ 321*37da2899SCharles.Forsyth error = face->goto_table( face, TTAG_CFF, stream, 0 ); 322*37da2899SCharles.Forsyth if ( error ) 323*37da2899SCharles.Forsyth goto Exit; 324*37da2899SCharles.Forsyth } 325*37da2899SCharles.Forsyth else 326*37da2899SCharles.Forsyth { 327*37da2899SCharles.Forsyth /* rewind to start of file; we are going to load a pure-CFF font */ 328*37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( 0 ) ) 329*37da2899SCharles.Forsyth goto Exit; 330*37da2899SCharles.Forsyth error = CFF_Err_Ok; 331*37da2899SCharles.Forsyth } 332*37da2899SCharles.Forsyth 333*37da2899SCharles.Forsyth /* now load and parse the CFF table in the file */ 334*37da2899SCharles.Forsyth { 335*37da2899SCharles.Forsyth CFF_Font cff; 336*37da2899SCharles.Forsyth FT_Memory memory = face->root.memory; 337*37da2899SCharles.Forsyth FT_Face root; 338*37da2899SCharles.Forsyth FT_Int32 flags; 339*37da2899SCharles.Forsyth 340*37da2899SCharles.Forsyth 341*37da2899SCharles.Forsyth if ( FT_NEW( cff ) ) 342*37da2899SCharles.Forsyth goto Exit; 343*37da2899SCharles.Forsyth 344*37da2899SCharles.Forsyth face->extra.data = cff; 345*37da2899SCharles.Forsyth error = cff_font_load( stream, face_index, cff ); 346*37da2899SCharles.Forsyth if ( error ) 347*37da2899SCharles.Forsyth goto Exit; 348*37da2899SCharles.Forsyth 349*37da2899SCharles.Forsyth cff->pshinter = pshinter; 350*37da2899SCharles.Forsyth cff->psnames = psnames; 351*37da2899SCharles.Forsyth 352*37da2899SCharles.Forsyth /* Complement the root flags with some interesting information. */ 353*37da2899SCharles.Forsyth /* Note that this is only necessary for pure CFF and CEF fonts. */ 354*37da2899SCharles.Forsyth 355*37da2899SCharles.Forsyth root = &face->root; 356*37da2899SCharles.Forsyth root->num_glyphs = cff->num_glyphs; 357*37da2899SCharles.Forsyth 358*37da2899SCharles.Forsyth if ( pure_cff ) 359*37da2899SCharles.Forsyth { 360*37da2899SCharles.Forsyth CFF_FontRecDict dict = &cff->top_font.font_dict; 361*37da2899SCharles.Forsyth 362*37da2899SCharles.Forsyth 363*37da2899SCharles.Forsyth /* we need the `PSNames' module for pure-CFF and CEF formats */ 364*37da2899SCharles.Forsyth if ( !psnames ) 365*37da2899SCharles.Forsyth { 366*37da2899SCharles.Forsyth FT_ERROR(( "cff_face_init:" )); 367*37da2899SCharles.Forsyth FT_ERROR(( " cannot open CFF & CEF fonts\n" )); 368*37da2899SCharles.Forsyth FT_ERROR(( " " )); 369*37da2899SCharles.Forsyth FT_ERROR(( " without the `PSNames' module\n" )); 370*37da2899SCharles.Forsyth goto Bad_Format; 371*37da2899SCharles.Forsyth } 372*37da2899SCharles.Forsyth 373*37da2899SCharles.Forsyth /* Set up num_faces. */ 374*37da2899SCharles.Forsyth root->num_faces = cff->num_faces; 375*37da2899SCharles.Forsyth 376*37da2899SCharles.Forsyth /* compute number of glyphs */ 377*37da2899SCharles.Forsyth if ( dict->cid_registry ) 378*37da2899SCharles.Forsyth root->num_glyphs = dict->cid_count; 379*37da2899SCharles.Forsyth else 380*37da2899SCharles.Forsyth root->num_glyphs = cff->charstrings_index.count; 381*37da2899SCharles.Forsyth 382*37da2899SCharles.Forsyth /* set global bbox, as well as EM size */ 383*37da2899SCharles.Forsyth root->bbox.xMin = dict->font_bbox.xMin >> 16; 384*37da2899SCharles.Forsyth root->bbox.yMin = dict->font_bbox.yMin >> 16; 385*37da2899SCharles.Forsyth root->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; 386*37da2899SCharles.Forsyth root->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; 387*37da2899SCharles.Forsyth 388*37da2899SCharles.Forsyth 389*37da2899SCharles.Forsyth root->ascender = (FT_Short)( root->bbox.yMax ); 390*37da2899SCharles.Forsyth root->descender = (FT_Short)( root->bbox.yMin ); 391*37da2899SCharles.Forsyth root->height = (FT_Short)( 392*37da2899SCharles.Forsyth ( ( root->ascender - root->descender ) * 12 ) / 10 ); 393*37da2899SCharles.Forsyth 394*37da2899SCharles.Forsyth if ( dict->units_per_em ) 395*37da2899SCharles.Forsyth root->units_per_EM = dict->units_per_em; 396*37da2899SCharles.Forsyth else 397*37da2899SCharles.Forsyth root->units_per_EM = 1000; 398*37da2899SCharles.Forsyth 399*37da2899SCharles.Forsyth /* retrieve font family & style name */ 400*37da2899SCharles.Forsyth root->family_name = cff_index_get_name( &cff->name_index, face_index ); 401*37da2899SCharles.Forsyth if ( dict->cid_registry ) 402*37da2899SCharles.Forsyth root->style_name = cff_strcpy( memory, "Regular" ); /* XXXX */ 403*37da2899SCharles.Forsyth else 404*37da2899SCharles.Forsyth root->style_name = cff_index_get_sid_string( &cff->string_index, 405*37da2899SCharles.Forsyth dict->weight, 406*37da2899SCharles.Forsyth psnames ); 407*37da2899SCharles.Forsyth 408*37da2899SCharles.Forsyth /*******************************************************************/ 409*37da2899SCharles.Forsyth /* */ 410*37da2899SCharles.Forsyth /* Compute face flags. */ 411*37da2899SCharles.Forsyth /* */ 412*37da2899SCharles.Forsyth flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ 413*37da2899SCharles.Forsyth FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ 414*37da2899SCharles.Forsyth 415*37da2899SCharles.Forsyth if ( sfnt_format ) 416*37da2899SCharles.Forsyth flags |= FT_FACE_FLAG_SFNT; 417*37da2899SCharles.Forsyth 418*37da2899SCharles.Forsyth /* fixed width font? */ 419*37da2899SCharles.Forsyth if ( dict->is_fixed_pitch ) 420*37da2899SCharles.Forsyth flags |= FT_FACE_FLAG_FIXED_WIDTH; 421*37da2899SCharles.Forsyth 422*37da2899SCharles.Forsyth /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ 423*37da2899SCharles.Forsyth #if 0 424*37da2899SCharles.Forsyth /* kerning available? */ 425*37da2899SCharles.Forsyth if ( face->kern_pairs ) 426*37da2899SCharles.Forsyth flags |= FT_FACE_FLAG_KERNING; 427*37da2899SCharles.Forsyth #endif 428*37da2899SCharles.Forsyth 429*37da2899SCharles.Forsyth #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES 430*37da2899SCharles.Forsyth flags |= FT_FACE_FLAG_GLYPH_NAMES; 431*37da2899SCharles.Forsyth #endif 432*37da2899SCharles.Forsyth 433*37da2899SCharles.Forsyth root->face_flags = flags; 434*37da2899SCharles.Forsyth 435*37da2899SCharles.Forsyth /*******************************************************************/ 436*37da2899SCharles.Forsyth /* */ 437*37da2899SCharles.Forsyth /* Compute style flags. */ 438*37da2899SCharles.Forsyth /* */ 439*37da2899SCharles.Forsyth flags = 0; 440*37da2899SCharles.Forsyth 441*37da2899SCharles.Forsyth if ( dict->italic_angle ) 442*37da2899SCharles.Forsyth flags |= FT_STYLE_FLAG_ITALIC; 443*37da2899SCharles.Forsyth 444*37da2899SCharles.Forsyth /* XXX: may not be correct */ 445*37da2899SCharles.Forsyth if ( cff->top_font.private_dict.force_bold ) 446*37da2899SCharles.Forsyth flags |= FT_STYLE_FLAG_BOLD; 447*37da2899SCharles.Forsyth 448*37da2899SCharles.Forsyth root->style_flags = flags; 449*37da2899SCharles.Forsyth } 450*37da2899SCharles.Forsyth 451*37da2899SCharles.Forsyth /*******************************************************************/ 452*37da2899SCharles.Forsyth /* */ 453*37da2899SCharles.Forsyth /* Compute char maps. */ 454*37da2899SCharles.Forsyth /* */ 455*37da2899SCharles.Forsyth 456*37da2899SCharles.Forsyth /* Try to synthetize a Unicode charmap if there is none available */ 457*37da2899SCharles.Forsyth /* already. If an OpenType font contains a Unicode "cmap", we */ 458*37da2899SCharles.Forsyth /* will use it, whatever be in the CFF part of the file. */ 459*37da2899SCharles.Forsyth { 460*37da2899SCharles.Forsyth FT_CharMapRec cmaprec; 461*37da2899SCharles.Forsyth FT_CharMap cmap; 462*37da2899SCharles.Forsyth FT_UInt nn; 463*37da2899SCharles.Forsyth CFF_Encoding encoding = &cff->encoding; 464*37da2899SCharles.Forsyth 465*37da2899SCharles.Forsyth 466*37da2899SCharles.Forsyth for ( nn = 0; nn < (FT_UInt) root->num_charmaps; nn++ ) 467*37da2899SCharles.Forsyth { 468*37da2899SCharles.Forsyth cmap = root->charmaps[nn]; 469*37da2899SCharles.Forsyth 470*37da2899SCharles.Forsyth /* Windows Unicode (3,1)? */ 471*37da2899SCharles.Forsyth if ( cmap->platform_id == 3 && cmap->encoding_id == 1 ) 472*37da2899SCharles.Forsyth goto Skip_Unicode; 473*37da2899SCharles.Forsyth 474*37da2899SCharles.Forsyth /* Deprecated Unicode platform id? */ 475*37da2899SCharles.Forsyth if ( cmap->platform_id == 0 ) 476*37da2899SCharles.Forsyth goto Skip_Unicode; /* Standard Unicode (deprecated) */ 477*37da2899SCharles.Forsyth } 478*37da2899SCharles.Forsyth 479*37da2899SCharles.Forsyth /* we didn't find a Unicode charmap, synthetize one */ 480*37da2899SCharles.Forsyth cmaprec.face = root; 481*37da2899SCharles.Forsyth cmaprec.platform_id = 3; 482*37da2899SCharles.Forsyth cmaprec.encoding_id = 1; 483*37da2899SCharles.Forsyth cmaprec.encoding = FT_ENCODING_UNICODE; 484*37da2899SCharles.Forsyth 485*37da2899SCharles.Forsyth nn = (FT_UInt) root->num_charmaps; 486*37da2899SCharles.Forsyth 487*37da2899SCharles.Forsyth FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); 488*37da2899SCharles.Forsyth 489*37da2899SCharles.Forsyth /* if no Unicode charmap was previously selected, select this one */ 490*37da2899SCharles.Forsyth if ( root->charmap == NULL && nn != (FT_UInt) root->num_charmaps ) 491*37da2899SCharles.Forsyth root->charmap = root->charmaps[nn]; 492*37da2899SCharles.Forsyth 493*37da2899SCharles.Forsyth Skip_Unicode: 494*37da2899SCharles.Forsyth if ( encoding->count > 0 ) 495*37da2899SCharles.Forsyth { 496*37da2899SCharles.Forsyth FT_CMap_Class clazz; 497*37da2899SCharles.Forsyth 498*37da2899SCharles.Forsyth 499*37da2899SCharles.Forsyth cmaprec.face = root; 500*37da2899SCharles.Forsyth cmaprec.platform_id = 7; /* Adobe platform id */ 501*37da2899SCharles.Forsyth 502*37da2899SCharles.Forsyth if ( encoding->offset == 0 ) 503*37da2899SCharles.Forsyth { 504*37da2899SCharles.Forsyth cmaprec.encoding_id = 0; 505*37da2899SCharles.Forsyth cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; 506*37da2899SCharles.Forsyth clazz = &cff_cmap_encoding_class_rec; 507*37da2899SCharles.Forsyth } 508*37da2899SCharles.Forsyth else if ( encoding->offset == 1 ) 509*37da2899SCharles.Forsyth { 510*37da2899SCharles.Forsyth cmaprec.encoding_id = 1; 511*37da2899SCharles.Forsyth cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; 512*37da2899SCharles.Forsyth clazz = &cff_cmap_encoding_class_rec; 513*37da2899SCharles.Forsyth } 514*37da2899SCharles.Forsyth else 515*37da2899SCharles.Forsyth { 516*37da2899SCharles.Forsyth cmaprec.encoding_id = 3; 517*37da2899SCharles.Forsyth cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; 518*37da2899SCharles.Forsyth clazz = &cff_cmap_encoding_class_rec; 519*37da2899SCharles.Forsyth } 520*37da2899SCharles.Forsyth 521*37da2899SCharles.Forsyth FT_CMap_New( clazz, NULL, &cmaprec, NULL ); 522*37da2899SCharles.Forsyth } 523*37da2899SCharles.Forsyth 524*37da2899SCharles.Forsyth } 525*37da2899SCharles.Forsyth } 526*37da2899SCharles.Forsyth 527*37da2899SCharles.Forsyth Exit: 528*37da2899SCharles.Forsyth return error; 529*37da2899SCharles.Forsyth 530*37da2899SCharles.Forsyth Bad_Format: 531*37da2899SCharles.Forsyth error = CFF_Err_Unknown_File_Format; 532*37da2899SCharles.Forsyth goto Exit; 533*37da2899SCharles.Forsyth } 534*37da2899SCharles.Forsyth 535*37da2899SCharles.Forsyth 536*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) cff_face_done(CFF_Face face)537*37da2899SCharles.Forsyth cff_face_done( CFF_Face face ) 538*37da2899SCharles.Forsyth { 539*37da2899SCharles.Forsyth FT_Memory memory = face->root.memory; 540*37da2899SCharles.Forsyth SFNT_Service sfnt = (SFNT_Service)face->sfnt; 541*37da2899SCharles.Forsyth 542*37da2899SCharles.Forsyth 543*37da2899SCharles.Forsyth if ( sfnt ) 544*37da2899SCharles.Forsyth sfnt->done_face( face ); 545*37da2899SCharles.Forsyth 546*37da2899SCharles.Forsyth { 547*37da2899SCharles.Forsyth CFF_Font cff = (CFF_Font)face->extra.data; 548*37da2899SCharles.Forsyth 549*37da2899SCharles.Forsyth 550*37da2899SCharles.Forsyth if ( cff ) 551*37da2899SCharles.Forsyth { 552*37da2899SCharles.Forsyth cff_font_done( cff ); 553*37da2899SCharles.Forsyth FT_FREE( face->extra.data ); 554*37da2899SCharles.Forsyth } 555*37da2899SCharles.Forsyth } 556*37da2899SCharles.Forsyth } 557*37da2899SCharles.Forsyth 558*37da2899SCharles.Forsyth 559*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) cff_driver_init(CFF_Driver driver)560*37da2899SCharles.Forsyth cff_driver_init( CFF_Driver driver ) 561*37da2899SCharles.Forsyth { 562*37da2899SCharles.Forsyth FT_UNUSED( driver ); 563*37da2899SCharles.Forsyth 564*37da2899SCharles.Forsyth return CFF_Err_Ok; 565*37da2899SCharles.Forsyth } 566*37da2899SCharles.Forsyth 567*37da2899SCharles.Forsyth 568*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) cff_driver_done(CFF_Driver driver)569*37da2899SCharles.Forsyth cff_driver_done( CFF_Driver driver ) 570*37da2899SCharles.Forsyth { 571*37da2899SCharles.Forsyth FT_UNUSED( driver ); 572*37da2899SCharles.Forsyth } 573*37da2899SCharles.Forsyth 574*37da2899SCharles.Forsyth 575*37da2899SCharles.Forsyth /* END */ 576