1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* cidload.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* CID-keyed Type1 font loader (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_CONFIG_CONFIG_H 22*37da2899SCharles.Forsyth #include FT_MULTIPLE_MASTERS_H 23*37da2899SCharles.Forsyth #include FT_INTERNAL_TYPE1_TYPES_H 24*37da2899SCharles.Forsyth 25*37da2899SCharles.Forsyth #include "cidload.h" 26*37da2899SCharles.Forsyth 27*37da2899SCharles.Forsyth #include "ciderrs.h" 28*37da2899SCharles.Forsyth 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth /*************************************************************************/ 31*37da2899SCharles.Forsyth /* */ 32*37da2899SCharles.Forsyth /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 33*37da2899SCharles.Forsyth /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 34*37da2899SCharles.Forsyth /* messages during execution. */ 35*37da2899SCharles.Forsyth /* */ 36*37da2899SCharles.Forsyth #undef FT_COMPONENT 37*37da2899SCharles.Forsyth #define FT_COMPONENT trace_cidload 38*37da2899SCharles.Forsyth 39*37da2899SCharles.Forsyth 40*37da2899SCharles.Forsyth /* read a single offset */ 41*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Long ) cid_get_offset(FT_Byte ** start,FT_Byte offsize)42*37da2899SCharles.Forsyth cid_get_offset( FT_Byte** start, 43*37da2899SCharles.Forsyth FT_Byte offsize ) 44*37da2899SCharles.Forsyth { 45*37da2899SCharles.Forsyth FT_Long result; 46*37da2899SCharles.Forsyth FT_Byte* p = *start; 47*37da2899SCharles.Forsyth 48*37da2899SCharles.Forsyth 49*37da2899SCharles.Forsyth for ( result = 0; offsize > 0; offsize-- ) 50*37da2899SCharles.Forsyth { 51*37da2899SCharles.Forsyth result <<= 8; 52*37da2899SCharles.Forsyth result |= *p++; 53*37da2899SCharles.Forsyth } 54*37da2899SCharles.Forsyth 55*37da2899SCharles.Forsyth *start = p; 56*37da2899SCharles.Forsyth return result; 57*37da2899SCharles.Forsyth } 58*37da2899SCharles.Forsyth 59*37da2899SCharles.Forsyth 60*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) cid_decrypt(FT_Byte * buffer,FT_Offset length,FT_UShort seed)61*37da2899SCharles.Forsyth cid_decrypt( FT_Byte* buffer, 62*37da2899SCharles.Forsyth FT_Offset length, 63*37da2899SCharles.Forsyth FT_UShort seed ) 64*37da2899SCharles.Forsyth { 65*37da2899SCharles.Forsyth while ( length > 0 ) 66*37da2899SCharles.Forsyth { 67*37da2899SCharles.Forsyth FT_Byte plain; 68*37da2899SCharles.Forsyth 69*37da2899SCharles.Forsyth 70*37da2899SCharles.Forsyth plain = (FT_Byte)( *buffer ^ ( seed >> 8 ) ); 71*37da2899SCharles.Forsyth seed = (FT_UShort)( ( *buffer + seed ) * 52845U + 22719 ); 72*37da2899SCharles.Forsyth *buffer++ = plain; 73*37da2899SCharles.Forsyth length--; 74*37da2899SCharles.Forsyth } 75*37da2899SCharles.Forsyth } 76*37da2899SCharles.Forsyth 77*37da2899SCharles.Forsyth 78*37da2899SCharles.Forsyth /*************************************************************************/ 79*37da2899SCharles.Forsyth /*************************************************************************/ 80*37da2899SCharles.Forsyth /***** *****/ 81*37da2899SCharles.Forsyth /***** TYPE 1 SYMBOL PARSING *****/ 82*37da2899SCharles.Forsyth /***** *****/ 83*37da2899SCharles.Forsyth /*************************************************************************/ 84*37da2899SCharles.Forsyth /*************************************************************************/ 85*37da2899SCharles.Forsyth 86*37da2899SCharles.Forsyth 87*37da2899SCharles.Forsyth static FT_Error cid_load_keyword(CID_Face face,CID_Loader * loader,const T1_Field keyword)88*37da2899SCharles.Forsyth cid_load_keyword( CID_Face face, 89*37da2899SCharles.Forsyth CID_Loader* loader, 90*37da2899SCharles.Forsyth const T1_Field keyword ) 91*37da2899SCharles.Forsyth { 92*37da2899SCharles.Forsyth FT_Error error; 93*37da2899SCharles.Forsyth CID_Parser* parser = &loader->parser; 94*37da2899SCharles.Forsyth FT_Byte* object; 95*37da2899SCharles.Forsyth void* dummy_object; 96*37da2899SCharles.Forsyth CID_FaceInfo cid = &face->cid; 97*37da2899SCharles.Forsyth 98*37da2899SCharles.Forsyth 99*37da2899SCharles.Forsyth /* if the keyword has a dedicated callback, call it */ 100*37da2899SCharles.Forsyth if ( keyword->type == T1_FIELD_TYPE_CALLBACK ) 101*37da2899SCharles.Forsyth { 102*37da2899SCharles.Forsyth keyword->reader( (FT_Face)face, parser ); 103*37da2899SCharles.Forsyth error = parser->root.error; 104*37da2899SCharles.Forsyth goto Exit; 105*37da2899SCharles.Forsyth } 106*37da2899SCharles.Forsyth 107*37da2899SCharles.Forsyth /* we must now compute the address of our target object */ 108*37da2899SCharles.Forsyth switch ( keyword->location ) 109*37da2899SCharles.Forsyth { 110*37da2899SCharles.Forsyth case T1_FIELD_LOCATION_CID_INFO: 111*37da2899SCharles.Forsyth object = (FT_Byte*)cid; 112*37da2899SCharles.Forsyth break; 113*37da2899SCharles.Forsyth 114*37da2899SCharles.Forsyth case T1_FIELD_LOCATION_FONT_INFO: 115*37da2899SCharles.Forsyth object = (FT_Byte*)&cid->font_info; 116*37da2899SCharles.Forsyth break; 117*37da2899SCharles.Forsyth 118*37da2899SCharles.Forsyth default: 119*37da2899SCharles.Forsyth { 120*37da2899SCharles.Forsyth CID_FaceDict dict; 121*37da2899SCharles.Forsyth 122*37da2899SCharles.Forsyth 123*37da2899SCharles.Forsyth if ( parser->num_dict < 0 ) 124*37da2899SCharles.Forsyth { 125*37da2899SCharles.Forsyth FT_ERROR(( "cid_load_keyword: invalid use of `%s'!\n", 126*37da2899SCharles.Forsyth keyword->ident )); 127*37da2899SCharles.Forsyth error = CID_Err_Syntax_Error; 128*37da2899SCharles.Forsyth goto Exit; 129*37da2899SCharles.Forsyth } 130*37da2899SCharles.Forsyth 131*37da2899SCharles.Forsyth dict = cid->font_dicts + parser->num_dict; 132*37da2899SCharles.Forsyth switch ( keyword->location ) 133*37da2899SCharles.Forsyth { 134*37da2899SCharles.Forsyth case T1_FIELD_LOCATION_PRIVATE: 135*37da2899SCharles.Forsyth object = (FT_Byte*)&dict->private_dict; 136*37da2899SCharles.Forsyth break; 137*37da2899SCharles.Forsyth 138*37da2899SCharles.Forsyth default: 139*37da2899SCharles.Forsyth object = (FT_Byte*)dict; 140*37da2899SCharles.Forsyth } 141*37da2899SCharles.Forsyth } 142*37da2899SCharles.Forsyth } 143*37da2899SCharles.Forsyth 144*37da2899SCharles.Forsyth dummy_object = object; 145*37da2899SCharles.Forsyth 146*37da2899SCharles.Forsyth /* now, load the keyword data in the object's field(s) */ 147*37da2899SCharles.Forsyth if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY || 148*37da2899SCharles.Forsyth keyword->type == T1_FIELD_TYPE_FIXED_ARRAY ) 149*37da2899SCharles.Forsyth error = cid_parser_load_field_table( &loader->parser, keyword, 150*37da2899SCharles.Forsyth &dummy_object ); 151*37da2899SCharles.Forsyth else 152*37da2899SCharles.Forsyth error = cid_parser_load_field( &loader->parser, keyword, &dummy_object ); 153*37da2899SCharles.Forsyth Exit: 154*37da2899SCharles.Forsyth return error; 155*37da2899SCharles.Forsyth } 156*37da2899SCharles.Forsyth 157*37da2899SCharles.Forsyth 158*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) parse_font_bbox(CID_Face face,CID_Parser * parser)159*37da2899SCharles.Forsyth parse_font_bbox( CID_Face face, 160*37da2899SCharles.Forsyth CID_Parser* parser ) 161*37da2899SCharles.Forsyth { 162*37da2899SCharles.Forsyth FT_Fixed temp[4]; 163*37da2899SCharles.Forsyth FT_BBox* bbox = &face->cid.font_bbox; 164*37da2899SCharles.Forsyth 165*37da2899SCharles.Forsyth 166*37da2899SCharles.Forsyth (void)cid_parser_to_fixed_array( parser, 4, temp, 0 ); 167*37da2899SCharles.Forsyth bbox->xMin = FT_RoundFix( temp[0] ); 168*37da2899SCharles.Forsyth bbox->yMin = FT_RoundFix( temp[1] ); 169*37da2899SCharles.Forsyth bbox->xMax = FT_RoundFix( temp[2] ); 170*37da2899SCharles.Forsyth bbox->yMax = FT_RoundFix( temp[3] ); 171*37da2899SCharles.Forsyth 172*37da2899SCharles.Forsyth return CID_Err_Ok; /* this is a callback function; */ 173*37da2899SCharles.Forsyth /* we must return an error code */ 174*37da2899SCharles.Forsyth } 175*37da2899SCharles.Forsyth 176*37da2899SCharles.Forsyth 177*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) parse_font_matrix(CID_Face face,CID_Parser * parser)178*37da2899SCharles.Forsyth parse_font_matrix( CID_Face face, 179*37da2899SCharles.Forsyth CID_Parser* parser ) 180*37da2899SCharles.Forsyth { 181*37da2899SCharles.Forsyth FT_Matrix* matrix; 182*37da2899SCharles.Forsyth FT_Vector* offset; 183*37da2899SCharles.Forsyth CID_FaceDict dict; 184*37da2899SCharles.Forsyth FT_Face root = (FT_Face)&face->root; 185*37da2899SCharles.Forsyth FT_Fixed temp[6]; 186*37da2899SCharles.Forsyth FT_Fixed temp_scale; 187*37da2899SCharles.Forsyth 188*37da2899SCharles.Forsyth 189*37da2899SCharles.Forsyth if ( parser->num_dict >= 0 ) 190*37da2899SCharles.Forsyth { 191*37da2899SCharles.Forsyth dict = face->cid.font_dicts + parser->num_dict; 192*37da2899SCharles.Forsyth matrix = &dict->font_matrix; 193*37da2899SCharles.Forsyth offset = &dict->font_offset; 194*37da2899SCharles.Forsyth 195*37da2899SCharles.Forsyth (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); 196*37da2899SCharles.Forsyth 197*37da2899SCharles.Forsyth temp_scale = ABS( temp[3] ); 198*37da2899SCharles.Forsyth 199*37da2899SCharles.Forsyth /* Set Units per EM based on FontMatrix values. We set the value to */ 200*37da2899SCharles.Forsyth /* `1000/temp_scale', because temp_scale was already multiplied by */ 201*37da2899SCharles.Forsyth /* 1000 (in t1_tofixed(), from psobjs.c). */ 202*37da2899SCharles.Forsyth root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L, 203*37da2899SCharles.Forsyth FT_DivFix( temp_scale, 1000 ) ) ); 204*37da2899SCharles.Forsyth 205*37da2899SCharles.Forsyth /* we need to scale the values by 1.0/temp[3] */ 206*37da2899SCharles.Forsyth if ( temp_scale != 0x10000L ) 207*37da2899SCharles.Forsyth { 208*37da2899SCharles.Forsyth temp[0] = FT_DivFix( temp[0], temp_scale ); 209*37da2899SCharles.Forsyth temp[1] = FT_DivFix( temp[1], temp_scale ); 210*37da2899SCharles.Forsyth temp[2] = FT_DivFix( temp[2], temp_scale ); 211*37da2899SCharles.Forsyth temp[4] = FT_DivFix( temp[4], temp_scale ); 212*37da2899SCharles.Forsyth temp[5] = FT_DivFix( temp[5], temp_scale ); 213*37da2899SCharles.Forsyth temp[3] = 0x10000L; 214*37da2899SCharles.Forsyth } 215*37da2899SCharles.Forsyth 216*37da2899SCharles.Forsyth matrix->xx = temp[0]; 217*37da2899SCharles.Forsyth matrix->yx = temp[1]; 218*37da2899SCharles.Forsyth matrix->xy = temp[2]; 219*37da2899SCharles.Forsyth matrix->yy = temp[3]; 220*37da2899SCharles.Forsyth 221*37da2899SCharles.Forsyth /* note that the font offsets are expressed in integer font units */ 222*37da2899SCharles.Forsyth offset->x = temp[4] >> 16; 223*37da2899SCharles.Forsyth offset->y = temp[5] >> 16; 224*37da2899SCharles.Forsyth } 225*37da2899SCharles.Forsyth 226*37da2899SCharles.Forsyth return CID_Err_Ok; /* this is a callback function; */ 227*37da2899SCharles.Forsyth /* we must return an error code */ 228*37da2899SCharles.Forsyth } 229*37da2899SCharles.Forsyth 230*37da2899SCharles.Forsyth 231*37da2899SCharles.Forsyth FT_CALLBACK_DEF( FT_Error ) parse_fd_array(CID_Face face,CID_Parser * parser)232*37da2899SCharles.Forsyth parse_fd_array( CID_Face face, 233*37da2899SCharles.Forsyth CID_Parser* parser ) 234*37da2899SCharles.Forsyth { 235*37da2899SCharles.Forsyth CID_FaceInfo cid = &face->cid; 236*37da2899SCharles.Forsyth FT_Memory memory = face->root.memory; 237*37da2899SCharles.Forsyth FT_Error error = CID_Err_Ok; 238*37da2899SCharles.Forsyth FT_Long num_dicts; 239*37da2899SCharles.Forsyth 240*37da2899SCharles.Forsyth 241*37da2899SCharles.Forsyth num_dicts = cid_parser_to_int( parser ); 242*37da2899SCharles.Forsyth 243*37da2899SCharles.Forsyth if ( !cid->font_dicts ) 244*37da2899SCharles.Forsyth { 245*37da2899SCharles.Forsyth FT_Int n; 246*37da2899SCharles.Forsyth 247*37da2899SCharles.Forsyth 248*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) 249*37da2899SCharles.Forsyth goto Exit; 250*37da2899SCharles.Forsyth 251*37da2899SCharles.Forsyth cid->num_dicts = (FT_UInt)num_dicts; 252*37da2899SCharles.Forsyth 253*37da2899SCharles.Forsyth /* don't forget to set a few defaults */ 254*37da2899SCharles.Forsyth for ( n = 0; n < cid->num_dicts; n++ ) 255*37da2899SCharles.Forsyth { 256*37da2899SCharles.Forsyth CID_FaceDict dict = cid->font_dicts + n; 257*37da2899SCharles.Forsyth 258*37da2899SCharles.Forsyth 259*37da2899SCharles.Forsyth /* default value for lenIV */ 260*37da2899SCharles.Forsyth dict->private_dict.lenIV = 4; 261*37da2899SCharles.Forsyth } 262*37da2899SCharles.Forsyth } 263*37da2899SCharles.Forsyth 264*37da2899SCharles.Forsyth Exit: 265*37da2899SCharles.Forsyth return error; 266*37da2899SCharles.Forsyth } 267*37da2899SCharles.Forsyth 268*37da2899SCharles.Forsyth 269*37da2899SCharles.Forsyth static 270*37da2899SCharles.Forsyth const T1_FieldRec cid_field_records[] = 271*37da2899SCharles.Forsyth { 272*37da2899SCharles.Forsyth 273*37da2899SCharles.Forsyth #include "cidtoken.h" 274*37da2899SCharles.Forsyth 275*37da2899SCharles.Forsyth T1_FIELD_CALLBACK( "FontBBox", parse_font_bbox ) 276*37da2899SCharles.Forsyth T1_FIELD_CALLBACK( "FDArray", parse_fd_array ) 277*37da2899SCharles.Forsyth T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) 278*37da2899SCharles.Forsyth { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } 279*37da2899SCharles.Forsyth }; 280*37da2899SCharles.Forsyth 281*37da2899SCharles.Forsyth 282*37da2899SCharles.Forsyth static int is_alpha(char c)283*37da2899SCharles.Forsyth is_alpha( char c ) 284*37da2899SCharles.Forsyth { 285*37da2899SCharles.Forsyth return ( ft_isalnum( (int)c ) || 286*37da2899SCharles.Forsyth c == '.' || 287*37da2899SCharles.Forsyth c == '_' ); 288*37da2899SCharles.Forsyth } 289*37da2899SCharles.Forsyth 290*37da2899SCharles.Forsyth 291*37da2899SCharles.Forsyth static FT_Error cid_parse_dict(CID_Face face,CID_Loader * loader,FT_Byte * base,FT_Long size)292*37da2899SCharles.Forsyth cid_parse_dict( CID_Face face, 293*37da2899SCharles.Forsyth CID_Loader* loader, 294*37da2899SCharles.Forsyth FT_Byte* base, 295*37da2899SCharles.Forsyth FT_Long size ) 296*37da2899SCharles.Forsyth { 297*37da2899SCharles.Forsyth CID_Parser* parser = &loader->parser; 298*37da2899SCharles.Forsyth 299*37da2899SCharles.Forsyth 300*37da2899SCharles.Forsyth parser->root.cursor = base; 301*37da2899SCharles.Forsyth parser->root.limit = base + size; 302*37da2899SCharles.Forsyth parser->root.error = 0; 303*37da2899SCharles.Forsyth 304*37da2899SCharles.Forsyth { 305*37da2899SCharles.Forsyth FT_Byte* cur = base; 306*37da2899SCharles.Forsyth FT_Byte* limit = cur + size; 307*37da2899SCharles.Forsyth 308*37da2899SCharles.Forsyth 309*37da2899SCharles.Forsyth for ( ;cur < limit; cur++ ) 310*37da2899SCharles.Forsyth { 311*37da2899SCharles.Forsyth /* look for `%ADOBeginFontDict' */ 312*37da2899SCharles.Forsyth if ( *cur == '%' && cur + 20 < limit && 313*37da2899SCharles.Forsyth ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) 314*37da2899SCharles.Forsyth { 315*37da2899SCharles.Forsyth cur += 17; 316*37da2899SCharles.Forsyth 317*37da2899SCharles.Forsyth /* if /FDArray was found, then cid->num_dicts is > 0, and */ 318*37da2899SCharles.Forsyth /* we can start increasing parser->num_dict */ 319*37da2899SCharles.Forsyth if ( face->cid.num_dicts > 0 ) 320*37da2899SCharles.Forsyth parser->num_dict++; 321*37da2899SCharles.Forsyth } 322*37da2899SCharles.Forsyth /* look for immediates */ 323*37da2899SCharles.Forsyth else if ( *cur == '/' && cur + 2 < limit ) 324*37da2899SCharles.Forsyth { 325*37da2899SCharles.Forsyth FT_Byte* cur2; 326*37da2899SCharles.Forsyth FT_Int len; 327*37da2899SCharles.Forsyth 328*37da2899SCharles.Forsyth 329*37da2899SCharles.Forsyth cur++; 330*37da2899SCharles.Forsyth 331*37da2899SCharles.Forsyth cur2 = cur; 332*37da2899SCharles.Forsyth while ( cur2 < limit && is_alpha( *cur2 ) ) 333*37da2899SCharles.Forsyth cur2++; 334*37da2899SCharles.Forsyth 335*37da2899SCharles.Forsyth len = (FT_Int)( cur2 - cur ); 336*37da2899SCharles.Forsyth if ( len > 0 && len < 22 ) 337*37da2899SCharles.Forsyth { 338*37da2899SCharles.Forsyth /* now compare the immediate name to the keyword table */ 339*37da2899SCharles.Forsyth T1_Field keyword = (T1_Field) cid_field_records; 340*37da2899SCharles.Forsyth 341*37da2899SCharles.Forsyth 342*37da2899SCharles.Forsyth for (;;) 343*37da2899SCharles.Forsyth { 344*37da2899SCharles.Forsyth FT_Byte* name; 345*37da2899SCharles.Forsyth 346*37da2899SCharles.Forsyth 347*37da2899SCharles.Forsyth name = (FT_Byte*)keyword->ident; 348*37da2899SCharles.Forsyth if ( !name ) 349*37da2899SCharles.Forsyth break; 350*37da2899SCharles.Forsyth 351*37da2899SCharles.Forsyth if ( cur[0] == name[0] && 352*37da2899SCharles.Forsyth len == (FT_Int)ft_strlen( (const char*)name ) ) 353*37da2899SCharles.Forsyth { 354*37da2899SCharles.Forsyth FT_Int n; 355*37da2899SCharles.Forsyth 356*37da2899SCharles.Forsyth 357*37da2899SCharles.Forsyth for ( n = 1; n < len; n++ ) 358*37da2899SCharles.Forsyth if ( cur[n] != name[n] ) 359*37da2899SCharles.Forsyth break; 360*37da2899SCharles.Forsyth 361*37da2899SCharles.Forsyth if ( n >= len ) 362*37da2899SCharles.Forsyth { 363*37da2899SCharles.Forsyth /* we found it - run the parsing callback */ 364*37da2899SCharles.Forsyth parser->root.cursor = cur2; 365*37da2899SCharles.Forsyth cid_parser_skip_spaces( parser ); 366*37da2899SCharles.Forsyth parser->root.error = cid_load_keyword( face, 367*37da2899SCharles.Forsyth loader, 368*37da2899SCharles.Forsyth keyword ); 369*37da2899SCharles.Forsyth if ( parser->root.error ) 370*37da2899SCharles.Forsyth return parser->root.error; 371*37da2899SCharles.Forsyth 372*37da2899SCharles.Forsyth cur = parser->root.cursor; 373*37da2899SCharles.Forsyth break; 374*37da2899SCharles.Forsyth } 375*37da2899SCharles.Forsyth } 376*37da2899SCharles.Forsyth keyword++; 377*37da2899SCharles.Forsyth } 378*37da2899SCharles.Forsyth } 379*37da2899SCharles.Forsyth } 380*37da2899SCharles.Forsyth } 381*37da2899SCharles.Forsyth } 382*37da2899SCharles.Forsyth return parser->root.error; 383*37da2899SCharles.Forsyth } 384*37da2899SCharles.Forsyth 385*37da2899SCharles.Forsyth 386*37da2899SCharles.Forsyth /* read the subrmap and the subrs of each font dict */ 387*37da2899SCharles.Forsyth static FT_Error cid_read_subrs(CID_Face face)388*37da2899SCharles.Forsyth cid_read_subrs( CID_Face face ) 389*37da2899SCharles.Forsyth { 390*37da2899SCharles.Forsyth CID_FaceInfo cid = &face->cid; 391*37da2899SCharles.Forsyth FT_Memory memory = face->root.memory; 392*37da2899SCharles.Forsyth FT_Stream stream = face->root.stream; 393*37da2899SCharles.Forsyth FT_Error error; 394*37da2899SCharles.Forsyth FT_Int n; 395*37da2899SCharles.Forsyth CID_Subrs subr; 396*37da2899SCharles.Forsyth FT_UInt max_offsets = 0; 397*37da2899SCharles.Forsyth FT_ULong* offsets = 0; 398*37da2899SCharles.Forsyth 399*37da2899SCharles.Forsyth 400*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) ) 401*37da2899SCharles.Forsyth goto Exit; 402*37da2899SCharles.Forsyth 403*37da2899SCharles.Forsyth subr = face->subrs; 404*37da2899SCharles.Forsyth for ( n = 0; n < cid->num_dicts; n++, subr++ ) 405*37da2899SCharles.Forsyth { 406*37da2899SCharles.Forsyth CID_FaceDict dict = cid->font_dicts + n; 407*37da2899SCharles.Forsyth FT_Int lenIV = dict->private_dict.lenIV; 408*37da2899SCharles.Forsyth FT_UInt count, num_subrs = dict->num_subrs; 409*37da2899SCharles.Forsyth FT_ULong data_len; 410*37da2899SCharles.Forsyth FT_Byte* p; 411*37da2899SCharles.Forsyth 412*37da2899SCharles.Forsyth 413*37da2899SCharles.Forsyth /* reallocate offsets array if needed */ 414*37da2899SCharles.Forsyth if ( num_subrs + 1 > max_offsets ) 415*37da2899SCharles.Forsyth { 416*37da2899SCharles.Forsyth FT_UInt new_max = ( num_subrs + 1 + 3 ) & -4; 417*37da2899SCharles.Forsyth 418*37da2899SCharles.Forsyth 419*37da2899SCharles.Forsyth if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) 420*37da2899SCharles.Forsyth goto Fail; 421*37da2899SCharles.Forsyth 422*37da2899SCharles.Forsyth max_offsets = new_max; 423*37da2899SCharles.Forsyth } 424*37da2899SCharles.Forsyth 425*37da2899SCharles.Forsyth /* read the subrmap's offsets */ 426*37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || 427*37da2899SCharles.Forsyth FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) 428*37da2899SCharles.Forsyth goto Fail; 429*37da2899SCharles.Forsyth 430*37da2899SCharles.Forsyth p = (FT_Byte*)stream->cursor; 431*37da2899SCharles.Forsyth for ( count = 0; count <= num_subrs; count++ ) 432*37da2899SCharles.Forsyth offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes ); 433*37da2899SCharles.Forsyth 434*37da2899SCharles.Forsyth FT_FRAME_EXIT(); 435*37da2899SCharles.Forsyth 436*37da2899SCharles.Forsyth /* now, compute the size of subrs charstrings, */ 437*37da2899SCharles.Forsyth /* allocate, and read them */ 438*37da2899SCharles.Forsyth data_len = offsets[num_subrs] - offsets[0]; 439*37da2899SCharles.Forsyth 440*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || 441*37da2899SCharles.Forsyth FT_ALLOC( subr->code[0], data_len ) ) 442*37da2899SCharles.Forsyth goto Fail; 443*37da2899SCharles.Forsyth 444*37da2899SCharles.Forsyth if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || 445*37da2899SCharles.Forsyth FT_STREAM_READ( subr->code[0], data_len ) ) 446*37da2899SCharles.Forsyth goto Fail; 447*37da2899SCharles.Forsyth 448*37da2899SCharles.Forsyth /* set up pointers */ 449*37da2899SCharles.Forsyth for ( count = 1; count <= num_subrs; count++ ) 450*37da2899SCharles.Forsyth { 451*37da2899SCharles.Forsyth FT_ULong len; 452*37da2899SCharles.Forsyth 453*37da2899SCharles.Forsyth 454*37da2899SCharles.Forsyth len = offsets[count] - offsets[count - 1]; 455*37da2899SCharles.Forsyth subr->code[count] = subr->code[count - 1] + len; 456*37da2899SCharles.Forsyth } 457*37da2899SCharles.Forsyth 458*37da2899SCharles.Forsyth /* decrypt subroutines, but only if lenIV >= 0 */ 459*37da2899SCharles.Forsyth if ( lenIV >= 0 ) 460*37da2899SCharles.Forsyth { 461*37da2899SCharles.Forsyth for ( count = 0; count < num_subrs; count++ ) 462*37da2899SCharles.Forsyth { 463*37da2899SCharles.Forsyth FT_ULong len; 464*37da2899SCharles.Forsyth 465*37da2899SCharles.Forsyth 466*37da2899SCharles.Forsyth len = offsets[count + 1] - offsets[count]; 467*37da2899SCharles.Forsyth cid_decrypt( subr->code[count], len, 4330 ); 468*37da2899SCharles.Forsyth } 469*37da2899SCharles.Forsyth } 470*37da2899SCharles.Forsyth 471*37da2899SCharles.Forsyth subr->num_subrs = num_subrs; 472*37da2899SCharles.Forsyth } 473*37da2899SCharles.Forsyth 474*37da2899SCharles.Forsyth Exit: 475*37da2899SCharles.Forsyth FT_FREE( offsets ); 476*37da2899SCharles.Forsyth return error; 477*37da2899SCharles.Forsyth 478*37da2899SCharles.Forsyth Fail: 479*37da2899SCharles.Forsyth if ( face->subrs ) 480*37da2899SCharles.Forsyth { 481*37da2899SCharles.Forsyth for ( n = 0; n < cid->num_dicts; n++ ) 482*37da2899SCharles.Forsyth { 483*37da2899SCharles.Forsyth if ( face->subrs[n].code ) 484*37da2899SCharles.Forsyth FT_FREE( face->subrs[n].code[0] ); 485*37da2899SCharles.Forsyth 486*37da2899SCharles.Forsyth FT_FREE( face->subrs[n].code ); 487*37da2899SCharles.Forsyth } 488*37da2899SCharles.Forsyth FT_FREE( face->subrs ); 489*37da2899SCharles.Forsyth } 490*37da2899SCharles.Forsyth goto Exit; 491*37da2899SCharles.Forsyth } 492*37da2899SCharles.Forsyth 493*37da2899SCharles.Forsyth 494*37da2899SCharles.Forsyth static void t1_init_loader(CID_Loader * loader,CID_Face face)495*37da2899SCharles.Forsyth t1_init_loader( CID_Loader* loader, 496*37da2899SCharles.Forsyth CID_Face face ) 497*37da2899SCharles.Forsyth { 498*37da2899SCharles.Forsyth FT_UNUSED( face ); 499*37da2899SCharles.Forsyth 500*37da2899SCharles.Forsyth FT_MEM_ZERO( loader, sizeof ( *loader ) ); 501*37da2899SCharles.Forsyth } 502*37da2899SCharles.Forsyth 503*37da2899SCharles.Forsyth 504*37da2899SCharles.Forsyth static void t1_done_loader(CID_Loader * loader)505*37da2899SCharles.Forsyth t1_done_loader( CID_Loader* loader ) 506*37da2899SCharles.Forsyth { 507*37da2899SCharles.Forsyth CID_Parser* parser = &loader->parser; 508*37da2899SCharles.Forsyth 509*37da2899SCharles.Forsyth 510*37da2899SCharles.Forsyth /* finalize parser */ 511*37da2899SCharles.Forsyth cid_parser_done( parser ); 512*37da2899SCharles.Forsyth } 513*37da2899SCharles.Forsyth 514*37da2899SCharles.Forsyth 515*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) cid_face_open(CID_Face face)516*37da2899SCharles.Forsyth cid_face_open( CID_Face face ) 517*37da2899SCharles.Forsyth { 518*37da2899SCharles.Forsyth CID_Loader loader; 519*37da2899SCharles.Forsyth CID_Parser* parser; 520*37da2899SCharles.Forsyth FT_Error error; 521*37da2899SCharles.Forsyth 522*37da2899SCharles.Forsyth 523*37da2899SCharles.Forsyth t1_init_loader( &loader, face ); 524*37da2899SCharles.Forsyth 525*37da2899SCharles.Forsyth parser = &loader.parser; 526*37da2899SCharles.Forsyth error = cid_parser_new( parser, face->root.stream, face->root.memory, 527*37da2899SCharles.Forsyth (PSAux_Service)face->psaux ); 528*37da2899SCharles.Forsyth if ( error ) 529*37da2899SCharles.Forsyth goto Exit; 530*37da2899SCharles.Forsyth 531*37da2899SCharles.Forsyth error = cid_parse_dict( face, &loader, 532*37da2899SCharles.Forsyth parser->postscript, 533*37da2899SCharles.Forsyth parser->postscript_len ); 534*37da2899SCharles.Forsyth if ( error ) 535*37da2899SCharles.Forsyth goto Exit; 536*37da2899SCharles.Forsyth 537*37da2899SCharles.Forsyth face->cid.data_offset = loader.parser.data_offset; 538*37da2899SCharles.Forsyth error = cid_read_subrs( face ); 539*37da2899SCharles.Forsyth 540*37da2899SCharles.Forsyth Exit: 541*37da2899SCharles.Forsyth t1_done_loader( &loader ); 542*37da2899SCharles.Forsyth return error; 543*37da2899SCharles.Forsyth } 544*37da2899SCharles.Forsyth 545*37da2899SCharles.Forsyth 546*37da2899SCharles.Forsyth /* END */ 547