1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* psobjs.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* Auxiliary functions for PostScript fonts (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_POSTSCRIPT_AUX_H 21*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 22*37da2899SCharles.Forsyth 23*37da2899SCharles.Forsyth #include "psobjs.h" 24*37da2899SCharles.Forsyth 25*37da2899SCharles.Forsyth #include "psauxerr.h" 26*37da2899SCharles.Forsyth 27*37da2899SCharles.Forsyth 28*37da2899SCharles.Forsyth /*************************************************************************/ 29*37da2899SCharles.Forsyth /*************************************************************************/ 30*37da2899SCharles.Forsyth /***** *****/ 31*37da2899SCharles.Forsyth /***** PS_TABLE *****/ 32*37da2899SCharles.Forsyth /***** *****/ 33*37da2899SCharles.Forsyth /*************************************************************************/ 34*37da2899SCharles.Forsyth /*************************************************************************/ 35*37da2899SCharles.Forsyth 36*37da2899SCharles.Forsyth /*************************************************************************/ 37*37da2899SCharles.Forsyth /* */ 38*37da2899SCharles.Forsyth /* <Function> */ 39*37da2899SCharles.Forsyth /* ps_table_new */ 40*37da2899SCharles.Forsyth /* */ 41*37da2899SCharles.Forsyth /* <Description> */ 42*37da2899SCharles.Forsyth /* Initializes a PS_Table. */ 43*37da2899SCharles.Forsyth /* */ 44*37da2899SCharles.Forsyth /* <InOut> */ 45*37da2899SCharles.Forsyth /* table :: The address of the target table. */ 46*37da2899SCharles.Forsyth /* */ 47*37da2899SCharles.Forsyth /* <Input> */ 48*37da2899SCharles.Forsyth /* count :: The table size = the maximum number of elements. */ 49*37da2899SCharles.Forsyth /* */ 50*37da2899SCharles.Forsyth /* memory :: The memory object to use for all subsequent */ 51*37da2899SCharles.Forsyth /* reallocations. */ 52*37da2899SCharles.Forsyth /* */ 53*37da2899SCharles.Forsyth /* <Return> */ 54*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. */ 55*37da2899SCharles.Forsyth /* */ 56*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) ps_table_new(PS_Table table,FT_Int count,FT_Memory memory)57*37da2899SCharles.Forsyth ps_table_new( PS_Table table, 58*37da2899SCharles.Forsyth FT_Int count, 59*37da2899SCharles.Forsyth FT_Memory memory ) 60*37da2899SCharles.Forsyth { 61*37da2899SCharles.Forsyth FT_Error error; 62*37da2899SCharles.Forsyth 63*37da2899SCharles.Forsyth 64*37da2899SCharles.Forsyth table->memory = memory; 65*37da2899SCharles.Forsyth if ( FT_NEW_ARRAY( table->elements, count ) || 66*37da2899SCharles.Forsyth FT_NEW_ARRAY( table->lengths, count ) ) 67*37da2899SCharles.Forsyth goto Exit; 68*37da2899SCharles.Forsyth 69*37da2899SCharles.Forsyth table->max_elems = count; 70*37da2899SCharles.Forsyth table->init = 0xDEADBEEFUL; 71*37da2899SCharles.Forsyth table->num_elems = 0; 72*37da2899SCharles.Forsyth table->block = 0; 73*37da2899SCharles.Forsyth table->capacity = 0; 74*37da2899SCharles.Forsyth table->cursor = 0; 75*37da2899SCharles.Forsyth 76*37da2899SCharles.Forsyth *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs; 77*37da2899SCharles.Forsyth 78*37da2899SCharles.Forsyth Exit: 79*37da2899SCharles.Forsyth if ( error ) 80*37da2899SCharles.Forsyth FT_FREE( table->elements ); 81*37da2899SCharles.Forsyth 82*37da2899SCharles.Forsyth return error; 83*37da2899SCharles.Forsyth } 84*37da2899SCharles.Forsyth 85*37da2899SCharles.Forsyth 86*37da2899SCharles.Forsyth static void shift_elements(PS_Table table,FT_Byte * old_base)87*37da2899SCharles.Forsyth shift_elements( PS_Table table, 88*37da2899SCharles.Forsyth FT_Byte* old_base ) 89*37da2899SCharles.Forsyth { 90*37da2899SCharles.Forsyth FT_Long delta = (FT_Long)( table->block - old_base ); 91*37da2899SCharles.Forsyth FT_Byte** offset = table->elements; 92*37da2899SCharles.Forsyth FT_Byte** limit = offset + table->max_elems; 93*37da2899SCharles.Forsyth 94*37da2899SCharles.Forsyth 95*37da2899SCharles.Forsyth for ( ; offset < limit; offset++ ) 96*37da2899SCharles.Forsyth { 97*37da2899SCharles.Forsyth if ( offset[0] ) 98*37da2899SCharles.Forsyth offset[0] += delta; 99*37da2899SCharles.Forsyth } 100*37da2899SCharles.Forsyth } 101*37da2899SCharles.Forsyth 102*37da2899SCharles.Forsyth 103*37da2899SCharles.Forsyth static FT_Error reallocate_t1_table(PS_Table table,FT_Long new_size)104*37da2899SCharles.Forsyth reallocate_t1_table( PS_Table table, 105*37da2899SCharles.Forsyth FT_Long new_size ) 106*37da2899SCharles.Forsyth { 107*37da2899SCharles.Forsyth FT_Memory memory = table->memory; 108*37da2899SCharles.Forsyth FT_Byte* old_base = table->block; 109*37da2899SCharles.Forsyth FT_Error error; 110*37da2899SCharles.Forsyth 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsyth /* allocate new base block */ 113*37da2899SCharles.Forsyth if ( FT_ALLOC( table->block, new_size ) ) 114*37da2899SCharles.Forsyth return error; 115*37da2899SCharles.Forsyth 116*37da2899SCharles.Forsyth /* copy elements and shift offsets */ 117*37da2899SCharles.Forsyth if (old_base ) 118*37da2899SCharles.Forsyth { 119*37da2899SCharles.Forsyth FT_MEM_COPY( table->block, old_base, table->capacity ); 120*37da2899SCharles.Forsyth shift_elements( table, old_base ); 121*37da2899SCharles.Forsyth FT_FREE( old_base ); 122*37da2899SCharles.Forsyth } 123*37da2899SCharles.Forsyth 124*37da2899SCharles.Forsyth table->capacity = new_size; 125*37da2899SCharles.Forsyth 126*37da2899SCharles.Forsyth return PSaux_Err_Ok; 127*37da2899SCharles.Forsyth } 128*37da2899SCharles.Forsyth 129*37da2899SCharles.Forsyth 130*37da2899SCharles.Forsyth /*************************************************************************/ 131*37da2899SCharles.Forsyth /* */ 132*37da2899SCharles.Forsyth /* <Function> */ 133*37da2899SCharles.Forsyth /* ps_table_add */ 134*37da2899SCharles.Forsyth /* */ 135*37da2899SCharles.Forsyth /* <Description> */ 136*37da2899SCharles.Forsyth /* Adds an object to a PS_Table, possibly growing its memory block. */ 137*37da2899SCharles.Forsyth /* */ 138*37da2899SCharles.Forsyth /* <InOut> */ 139*37da2899SCharles.Forsyth /* table :: The target table. */ 140*37da2899SCharles.Forsyth /* */ 141*37da2899SCharles.Forsyth /* <Input> */ 142*37da2899SCharles.Forsyth /* idx :: The index of the object in the table. */ 143*37da2899SCharles.Forsyth /* */ 144*37da2899SCharles.Forsyth /* object :: The address of the object to copy in memory. */ 145*37da2899SCharles.Forsyth /* */ 146*37da2899SCharles.Forsyth /* length :: The length in bytes of the source object. */ 147*37da2899SCharles.Forsyth /* */ 148*37da2899SCharles.Forsyth /* <Return> */ 149*37da2899SCharles.Forsyth /* FreeType error code. 0 means success. An error is returned if a */ 150*37da2899SCharles.Forsyth /* reallocation fails. */ 151*37da2899SCharles.Forsyth /* */ 152*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) ps_table_add(PS_Table table,FT_Int idx,void * object,FT_Int length)153*37da2899SCharles.Forsyth ps_table_add( PS_Table table, 154*37da2899SCharles.Forsyth FT_Int idx, 155*37da2899SCharles.Forsyth void* object, 156*37da2899SCharles.Forsyth FT_Int length ) 157*37da2899SCharles.Forsyth { 158*37da2899SCharles.Forsyth if ( idx < 0 || idx > table->max_elems ) 159*37da2899SCharles.Forsyth { 160*37da2899SCharles.Forsyth FT_ERROR(( "ps_table_add: invalid index\n" )); 161*37da2899SCharles.Forsyth return PSaux_Err_Invalid_Argument; 162*37da2899SCharles.Forsyth } 163*37da2899SCharles.Forsyth 164*37da2899SCharles.Forsyth /* grow the base block if needed */ 165*37da2899SCharles.Forsyth if ( table->cursor + length > table->capacity ) 166*37da2899SCharles.Forsyth { 167*37da2899SCharles.Forsyth FT_Error error; 168*37da2899SCharles.Forsyth FT_Offset new_size = table->capacity; 169*37da2899SCharles.Forsyth FT_Long in_offset; 170*37da2899SCharles.Forsyth 171*37da2899SCharles.Forsyth 172*37da2899SCharles.Forsyth in_offset = (FT_Long)((FT_Byte*)object - table->block); 173*37da2899SCharles.Forsyth if ( (FT_ULong)in_offset >= table->capacity ) 174*37da2899SCharles.Forsyth in_offset = -1; 175*37da2899SCharles.Forsyth 176*37da2899SCharles.Forsyth while ( new_size < table->cursor + length ) 177*37da2899SCharles.Forsyth { 178*37da2899SCharles.Forsyth /* increase size by 25% and round up to the nearest multiple of 1024 */ 179*37da2899SCharles.Forsyth new_size += (new_size >> 2) + 1; 180*37da2899SCharles.Forsyth new_size = ( new_size + 1023 ) & -1024; 181*37da2899SCharles.Forsyth } 182*37da2899SCharles.Forsyth 183*37da2899SCharles.Forsyth error = reallocate_t1_table( table, new_size ); 184*37da2899SCharles.Forsyth if ( error ) 185*37da2899SCharles.Forsyth return error; 186*37da2899SCharles.Forsyth 187*37da2899SCharles.Forsyth if ( in_offset >= 0 ) 188*37da2899SCharles.Forsyth object = table->block + in_offset; 189*37da2899SCharles.Forsyth } 190*37da2899SCharles.Forsyth 191*37da2899SCharles.Forsyth /* add the object to the base block and adjust offset */ 192*37da2899SCharles.Forsyth table->elements[idx] = table->block + table->cursor; 193*37da2899SCharles.Forsyth table->lengths [idx] = length; 194*37da2899SCharles.Forsyth FT_MEM_COPY( table->block + table->cursor, object, length ); 195*37da2899SCharles.Forsyth 196*37da2899SCharles.Forsyth table->cursor += length; 197*37da2899SCharles.Forsyth return PSaux_Err_Ok; 198*37da2899SCharles.Forsyth } 199*37da2899SCharles.Forsyth 200*37da2899SCharles.Forsyth 201*37da2899SCharles.Forsyth /*************************************************************************/ 202*37da2899SCharles.Forsyth /* */ 203*37da2899SCharles.Forsyth /* <Function> */ 204*37da2899SCharles.Forsyth /* ps_table_done */ 205*37da2899SCharles.Forsyth /* */ 206*37da2899SCharles.Forsyth /* <Description> */ 207*37da2899SCharles.Forsyth /* Finalizes a PS_TableRec (i.e., reallocate it to its current */ 208*37da2899SCharles.Forsyth /* cursor). */ 209*37da2899SCharles.Forsyth /* */ 210*37da2899SCharles.Forsyth /* <InOut> */ 211*37da2899SCharles.Forsyth /* table :: The target table. */ 212*37da2899SCharles.Forsyth /* */ 213*37da2899SCharles.Forsyth /* <Note> */ 214*37da2899SCharles.Forsyth /* This function does NOT release the heap's memory block. It is up */ 215*37da2899SCharles.Forsyth /* to the caller to clean it, or reference it in its own structures. */ 216*37da2899SCharles.Forsyth /* */ 217*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) ps_table_done(PS_Table table)218*37da2899SCharles.Forsyth ps_table_done( PS_Table table ) 219*37da2899SCharles.Forsyth { 220*37da2899SCharles.Forsyth FT_Memory memory = table->memory; 221*37da2899SCharles.Forsyth FT_Error error; 222*37da2899SCharles.Forsyth FT_Byte* old_base = table->block; 223*37da2899SCharles.Forsyth 224*37da2899SCharles.Forsyth 225*37da2899SCharles.Forsyth /* should never fail, because rec.cursor <= rec.size */ 226*37da2899SCharles.Forsyth if ( !old_base ) 227*37da2899SCharles.Forsyth return; 228*37da2899SCharles.Forsyth 229*37da2899SCharles.Forsyth if ( FT_ALLOC( table->block, table->cursor ) ) 230*37da2899SCharles.Forsyth return; 231*37da2899SCharles.Forsyth FT_MEM_COPY( table->block, old_base, table->cursor ); 232*37da2899SCharles.Forsyth shift_elements( table, old_base ); 233*37da2899SCharles.Forsyth 234*37da2899SCharles.Forsyth table->capacity = table->cursor; 235*37da2899SCharles.Forsyth FT_FREE( old_base ); 236*37da2899SCharles.Forsyth 237*37da2899SCharles.Forsyth FT_UNUSED( error ); 238*37da2899SCharles.Forsyth } 239*37da2899SCharles.Forsyth 240*37da2899SCharles.Forsyth 241*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) ps_table_release(PS_Table table)242*37da2899SCharles.Forsyth ps_table_release( PS_Table table ) 243*37da2899SCharles.Forsyth { 244*37da2899SCharles.Forsyth FT_Memory memory = table->memory; 245*37da2899SCharles.Forsyth 246*37da2899SCharles.Forsyth 247*37da2899SCharles.Forsyth if ( (FT_ULong)table->init == 0xDEADBEEFUL ) 248*37da2899SCharles.Forsyth { 249*37da2899SCharles.Forsyth FT_FREE( table->block ); 250*37da2899SCharles.Forsyth FT_FREE( table->elements ); 251*37da2899SCharles.Forsyth FT_FREE( table->lengths ); 252*37da2899SCharles.Forsyth table->init = 0; 253*37da2899SCharles.Forsyth } 254*37da2899SCharles.Forsyth } 255*37da2899SCharles.Forsyth 256*37da2899SCharles.Forsyth 257*37da2899SCharles.Forsyth /*************************************************************************/ 258*37da2899SCharles.Forsyth /*************************************************************************/ 259*37da2899SCharles.Forsyth /***** *****/ 260*37da2899SCharles.Forsyth /***** T1 PARSER *****/ 261*37da2899SCharles.Forsyth /***** *****/ 262*37da2899SCharles.Forsyth /*************************************************************************/ 263*37da2899SCharles.Forsyth /*************************************************************************/ 264*37da2899SCharles.Forsyth 265*37da2899SCharles.Forsyth 266*37da2899SCharles.Forsyth #define IS_T1_WHITESPACE( c ) ( (c) == ' ' || (c) == '\t' ) 267*37da2899SCharles.Forsyth #define IS_T1_LINESPACE( c ) ( (c) == '\r' || (c) == '\n' ) 268*37da2899SCharles.Forsyth 269*37da2899SCharles.Forsyth #define IS_T1_SPACE( c ) ( IS_T1_WHITESPACE( c ) || IS_T1_LINESPACE( c ) ) 270*37da2899SCharles.Forsyth 271*37da2899SCharles.Forsyth 272*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) ps_parser_skip_spaces(PS_Parser parser)273*37da2899SCharles.Forsyth ps_parser_skip_spaces( PS_Parser parser ) 274*37da2899SCharles.Forsyth { 275*37da2899SCharles.Forsyth FT_Byte* cur = parser->cursor; 276*37da2899SCharles.Forsyth FT_Byte* limit = parser->limit; 277*37da2899SCharles.Forsyth 278*37da2899SCharles.Forsyth 279*37da2899SCharles.Forsyth while ( cur < limit ) 280*37da2899SCharles.Forsyth { 281*37da2899SCharles.Forsyth FT_Byte c = *cur; 282*37da2899SCharles.Forsyth 283*37da2899SCharles.Forsyth 284*37da2899SCharles.Forsyth if ( !IS_T1_SPACE( c ) ) 285*37da2899SCharles.Forsyth break; 286*37da2899SCharles.Forsyth cur++; 287*37da2899SCharles.Forsyth } 288*37da2899SCharles.Forsyth parser->cursor = cur; 289*37da2899SCharles.Forsyth } 290*37da2899SCharles.Forsyth 291*37da2899SCharles.Forsyth 292*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) ps_parser_skip_alpha(PS_Parser parser)293*37da2899SCharles.Forsyth ps_parser_skip_alpha( PS_Parser parser ) 294*37da2899SCharles.Forsyth { 295*37da2899SCharles.Forsyth FT_Byte* cur = parser->cursor; 296*37da2899SCharles.Forsyth FT_Byte* limit = parser->limit; 297*37da2899SCharles.Forsyth 298*37da2899SCharles.Forsyth 299*37da2899SCharles.Forsyth while ( cur < limit ) 300*37da2899SCharles.Forsyth { 301*37da2899SCharles.Forsyth FT_Byte c = *cur; 302*37da2899SCharles.Forsyth 303*37da2899SCharles.Forsyth 304*37da2899SCharles.Forsyth if ( IS_T1_SPACE( c ) ) 305*37da2899SCharles.Forsyth break; 306*37da2899SCharles.Forsyth cur++; 307*37da2899SCharles.Forsyth } 308*37da2899SCharles.Forsyth parser->cursor = cur; 309*37da2899SCharles.Forsyth } 310*37da2899SCharles.Forsyth 311*37da2899SCharles.Forsyth 312*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) ps_parser_to_token(PS_Parser parser,T1_Token token)313*37da2899SCharles.Forsyth ps_parser_to_token( PS_Parser parser, 314*37da2899SCharles.Forsyth T1_Token token ) 315*37da2899SCharles.Forsyth { 316*37da2899SCharles.Forsyth FT_Byte* cur; 317*37da2899SCharles.Forsyth FT_Byte* limit; 318*37da2899SCharles.Forsyth FT_Byte starter, ender; 319*37da2899SCharles.Forsyth FT_Int embed; 320*37da2899SCharles.Forsyth 321*37da2899SCharles.Forsyth 322*37da2899SCharles.Forsyth token->type = T1_TOKEN_TYPE_NONE; 323*37da2899SCharles.Forsyth token->start = 0; 324*37da2899SCharles.Forsyth token->limit = 0; 325*37da2899SCharles.Forsyth 326*37da2899SCharles.Forsyth /* first of all, skip space */ 327*37da2899SCharles.Forsyth ps_parser_skip_spaces( parser ); 328*37da2899SCharles.Forsyth 329*37da2899SCharles.Forsyth cur = parser->cursor; 330*37da2899SCharles.Forsyth limit = parser->limit; 331*37da2899SCharles.Forsyth 332*37da2899SCharles.Forsyth if ( cur < limit ) 333*37da2899SCharles.Forsyth { 334*37da2899SCharles.Forsyth switch ( *cur ) 335*37da2899SCharles.Forsyth { 336*37da2899SCharles.Forsyth /************* check for strings ***********************/ 337*37da2899SCharles.Forsyth case '(': 338*37da2899SCharles.Forsyth token->type = T1_TOKEN_TYPE_STRING; 339*37da2899SCharles.Forsyth ender = ')'; 340*37da2899SCharles.Forsyth goto Lookup_Ender; 341*37da2899SCharles.Forsyth 342*37da2899SCharles.Forsyth /************* check for programs/array ****************/ 343*37da2899SCharles.Forsyth case '{': 344*37da2899SCharles.Forsyth token->type = T1_TOKEN_TYPE_ARRAY; 345*37da2899SCharles.Forsyth ender = '}'; 346*37da2899SCharles.Forsyth goto Lookup_Ender; 347*37da2899SCharles.Forsyth 348*37da2899SCharles.Forsyth /************* check for table/array ******************/ 349*37da2899SCharles.Forsyth case '[': 350*37da2899SCharles.Forsyth token->type = T1_TOKEN_TYPE_ARRAY; 351*37da2899SCharles.Forsyth ender = ']'; 352*37da2899SCharles.Forsyth 353*37da2899SCharles.Forsyth Lookup_Ender: 354*37da2899SCharles.Forsyth embed = 1; 355*37da2899SCharles.Forsyth starter = *cur++; 356*37da2899SCharles.Forsyth token->start = cur; 357*37da2899SCharles.Forsyth while ( cur < limit ) 358*37da2899SCharles.Forsyth { 359*37da2899SCharles.Forsyth if ( *cur == starter ) 360*37da2899SCharles.Forsyth embed++; 361*37da2899SCharles.Forsyth else if ( *cur == ender ) 362*37da2899SCharles.Forsyth { 363*37da2899SCharles.Forsyth embed--; 364*37da2899SCharles.Forsyth if ( embed <= 0 ) 365*37da2899SCharles.Forsyth { 366*37da2899SCharles.Forsyth token->limit = cur++; 367*37da2899SCharles.Forsyth break; 368*37da2899SCharles.Forsyth } 369*37da2899SCharles.Forsyth } 370*37da2899SCharles.Forsyth cur++; 371*37da2899SCharles.Forsyth } 372*37da2899SCharles.Forsyth break; 373*37da2899SCharles.Forsyth 374*37da2899SCharles.Forsyth /* **************** otherwise, it's any token **********/ 375*37da2899SCharles.Forsyth default: 376*37da2899SCharles.Forsyth token->start = cur++; 377*37da2899SCharles.Forsyth token->type = T1_TOKEN_TYPE_ANY; 378*37da2899SCharles.Forsyth while ( cur < limit && !IS_T1_SPACE( *cur ) ) 379*37da2899SCharles.Forsyth cur++; 380*37da2899SCharles.Forsyth 381*37da2899SCharles.Forsyth token->limit = cur; 382*37da2899SCharles.Forsyth } 383*37da2899SCharles.Forsyth 384*37da2899SCharles.Forsyth if ( !token->limit ) 385*37da2899SCharles.Forsyth { 386*37da2899SCharles.Forsyth token->start = 0; 387*37da2899SCharles.Forsyth token->type = T1_TOKEN_TYPE_NONE; 388*37da2899SCharles.Forsyth } 389*37da2899SCharles.Forsyth 390*37da2899SCharles.Forsyth parser->cursor = cur; 391*37da2899SCharles.Forsyth } 392*37da2899SCharles.Forsyth } 393*37da2899SCharles.Forsyth 394*37da2899SCharles.Forsyth 395*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) ps_parser_to_token_array(PS_Parser parser,T1_Token tokens,FT_UInt max_tokens,FT_Int * pnum_tokens)396*37da2899SCharles.Forsyth ps_parser_to_token_array( PS_Parser parser, 397*37da2899SCharles.Forsyth T1_Token tokens, 398*37da2899SCharles.Forsyth FT_UInt max_tokens, 399*37da2899SCharles.Forsyth FT_Int* pnum_tokens ) 400*37da2899SCharles.Forsyth { 401*37da2899SCharles.Forsyth T1_TokenRec master; 402*37da2899SCharles.Forsyth 403*37da2899SCharles.Forsyth 404*37da2899SCharles.Forsyth *pnum_tokens = -1; 405*37da2899SCharles.Forsyth 406*37da2899SCharles.Forsyth ps_parser_to_token( parser, &master ); 407*37da2899SCharles.Forsyth if ( master.type == T1_TOKEN_TYPE_ARRAY ) 408*37da2899SCharles.Forsyth { 409*37da2899SCharles.Forsyth FT_Byte* old_cursor = parser->cursor; 410*37da2899SCharles.Forsyth FT_Byte* old_limit = parser->limit; 411*37da2899SCharles.Forsyth T1_Token cur = tokens; 412*37da2899SCharles.Forsyth T1_Token limit = cur + max_tokens; 413*37da2899SCharles.Forsyth 414*37da2899SCharles.Forsyth 415*37da2899SCharles.Forsyth parser->cursor = master.start; 416*37da2899SCharles.Forsyth parser->limit = master.limit; 417*37da2899SCharles.Forsyth 418*37da2899SCharles.Forsyth while ( parser->cursor < parser->limit ) 419*37da2899SCharles.Forsyth { 420*37da2899SCharles.Forsyth T1_TokenRec token; 421*37da2899SCharles.Forsyth 422*37da2899SCharles.Forsyth 423*37da2899SCharles.Forsyth ps_parser_to_token( parser, &token ); 424*37da2899SCharles.Forsyth if ( !token.type ) 425*37da2899SCharles.Forsyth break; 426*37da2899SCharles.Forsyth 427*37da2899SCharles.Forsyth if ( cur < limit ) 428*37da2899SCharles.Forsyth *cur = token; 429*37da2899SCharles.Forsyth 430*37da2899SCharles.Forsyth cur++; 431*37da2899SCharles.Forsyth } 432*37da2899SCharles.Forsyth 433*37da2899SCharles.Forsyth *pnum_tokens = (FT_Int)( cur - tokens ); 434*37da2899SCharles.Forsyth 435*37da2899SCharles.Forsyth parser->cursor = old_cursor; 436*37da2899SCharles.Forsyth parser->limit = old_limit; 437*37da2899SCharles.Forsyth } 438*37da2899SCharles.Forsyth } 439*37da2899SCharles.Forsyth 440*37da2899SCharles.Forsyth 441*37da2899SCharles.Forsyth static FT_Long T1Radix(FT_Long radixBase,FT_Byte ** cur,FT_Byte * limit)442*37da2899SCharles.Forsyth T1Radix( FT_Long radixBase, 443*37da2899SCharles.Forsyth FT_Byte** cur, 444*37da2899SCharles.Forsyth FT_Byte* limit ) 445*37da2899SCharles.Forsyth { 446*37da2899SCharles.Forsyth FT_Long result = 0; 447*37da2899SCharles.Forsyth FT_Byte radixEndChar0 = 448*37da2899SCharles.Forsyth (FT_Byte)( radixBase > 10 ? '9' + 1 : '0' + radixBase ); 449*37da2899SCharles.Forsyth FT_Byte radixEndChar1 = 450*37da2899SCharles.Forsyth (FT_Byte)( 'A' + radixBase - 10 ); 451*37da2899SCharles.Forsyth FT_Byte radixEndChar2 = 452*37da2899SCharles.Forsyth (FT_Byte)( 'a' + radixBase - 10 ); 453*37da2899SCharles.Forsyth 454*37da2899SCharles.Forsyth 455*37da2899SCharles.Forsyth while( *cur < limit ) 456*37da2899SCharles.Forsyth { 457*37da2899SCharles.Forsyth if ( (*cur)[0] >= '0' && (*cur)[0] < radixEndChar0 ) 458*37da2899SCharles.Forsyth result = result * radixBase + (*cur)[0] - '0'; 459*37da2899SCharles.Forsyth 460*37da2899SCharles.Forsyth else if ( radixBase > 10 && 461*37da2899SCharles.Forsyth (*cur)[0] >= 'A' && (*cur)[0] < radixEndChar1 ) 462*37da2899SCharles.Forsyth result = result * radixBase + ( (*cur)[0] - 'A' + 10 ); 463*37da2899SCharles.Forsyth 464*37da2899SCharles.Forsyth else if ( radixBase > 10 && 465*37da2899SCharles.Forsyth (*cur)[0] >= 'a' && (*cur)[0] < radixEndChar2 ) 466*37da2899SCharles.Forsyth result = result * radixBase + ( (*cur)[0] - 'a' + 10 ); 467*37da2899SCharles.Forsyth 468*37da2899SCharles.Forsyth else 469*37da2899SCharles.Forsyth return result; 470*37da2899SCharles.Forsyth 471*37da2899SCharles.Forsyth (*cur)++; 472*37da2899SCharles.Forsyth } 473*37da2899SCharles.Forsyth 474*37da2899SCharles.Forsyth return result; 475*37da2899SCharles.Forsyth } 476*37da2899SCharles.Forsyth 477*37da2899SCharles.Forsyth 478*37da2899SCharles.Forsyth static FT_Long t1_toint(FT_Byte ** cursor,FT_Byte * limit)479*37da2899SCharles.Forsyth t1_toint( FT_Byte** cursor, 480*37da2899SCharles.Forsyth FT_Byte* limit ) 481*37da2899SCharles.Forsyth { 482*37da2899SCharles.Forsyth FT_Long result = 0; 483*37da2899SCharles.Forsyth FT_Byte* cur = *cursor; 484*37da2899SCharles.Forsyth FT_Byte c = '\0', d; 485*37da2899SCharles.Forsyth 486*37da2899SCharles.Forsyth 487*37da2899SCharles.Forsyth for ( ; cur < limit; cur++ ) 488*37da2899SCharles.Forsyth { 489*37da2899SCharles.Forsyth c = *cur; 490*37da2899SCharles.Forsyth d = (FT_Byte)( c - '0' ); 491*37da2899SCharles.Forsyth if ( d < 10 ) 492*37da2899SCharles.Forsyth break; 493*37da2899SCharles.Forsyth 494*37da2899SCharles.Forsyth if ( c == '-' ) 495*37da2899SCharles.Forsyth { 496*37da2899SCharles.Forsyth cur++; 497*37da2899SCharles.Forsyth break; 498*37da2899SCharles.Forsyth } 499*37da2899SCharles.Forsyth } 500*37da2899SCharles.Forsyth 501*37da2899SCharles.Forsyth if ( cur < limit ) 502*37da2899SCharles.Forsyth { 503*37da2899SCharles.Forsyth do 504*37da2899SCharles.Forsyth { 505*37da2899SCharles.Forsyth d = (FT_Byte)( cur[0] - '0' ); 506*37da2899SCharles.Forsyth if ( d >= 10 ) 507*37da2899SCharles.Forsyth { 508*37da2899SCharles.Forsyth if ( cur[0] == '#' ) 509*37da2899SCharles.Forsyth { 510*37da2899SCharles.Forsyth cur++; 511*37da2899SCharles.Forsyth result = T1Radix( result, &cur, limit ); 512*37da2899SCharles.Forsyth } 513*37da2899SCharles.Forsyth break; 514*37da2899SCharles.Forsyth } 515*37da2899SCharles.Forsyth 516*37da2899SCharles.Forsyth result = result * 10 + d; 517*37da2899SCharles.Forsyth cur++; 518*37da2899SCharles.Forsyth 519*37da2899SCharles.Forsyth } while ( cur < limit ); 520*37da2899SCharles.Forsyth 521*37da2899SCharles.Forsyth if ( c == '-' ) 522*37da2899SCharles.Forsyth result = -result; 523*37da2899SCharles.Forsyth } 524*37da2899SCharles.Forsyth 525*37da2899SCharles.Forsyth *cursor = cur; 526*37da2899SCharles.Forsyth return result; 527*37da2899SCharles.Forsyth } 528*37da2899SCharles.Forsyth 529*37da2899SCharles.Forsyth 530*37da2899SCharles.Forsyth static FT_Long t1_tofixed(FT_Byte ** cursor,FT_Byte * limit,FT_Long power_ten)531*37da2899SCharles.Forsyth t1_tofixed( FT_Byte** cursor, 532*37da2899SCharles.Forsyth FT_Byte* limit, 533*37da2899SCharles.Forsyth FT_Long power_ten ) 534*37da2899SCharles.Forsyth { 535*37da2899SCharles.Forsyth FT_Byte* cur = *cursor; 536*37da2899SCharles.Forsyth FT_Long num, divider, result; 537*37da2899SCharles.Forsyth FT_Int sign = 0; 538*37da2899SCharles.Forsyth FT_Byte d; 539*37da2899SCharles.Forsyth 540*37da2899SCharles.Forsyth 541*37da2899SCharles.Forsyth if ( cur >= limit ) 542*37da2899SCharles.Forsyth return 0; 543*37da2899SCharles.Forsyth 544*37da2899SCharles.Forsyth /* first of all, check the sign */ 545*37da2899SCharles.Forsyth if ( *cur == '-' ) 546*37da2899SCharles.Forsyth { 547*37da2899SCharles.Forsyth sign = 1; 548*37da2899SCharles.Forsyth cur++; 549*37da2899SCharles.Forsyth } 550*37da2899SCharles.Forsyth 551*37da2899SCharles.Forsyth /* then, read the integer part, if any */ 552*37da2899SCharles.Forsyth if ( *cur != '.' ) 553*37da2899SCharles.Forsyth result = t1_toint( &cur, limit ) << 16; 554*37da2899SCharles.Forsyth else 555*37da2899SCharles.Forsyth result = 0; 556*37da2899SCharles.Forsyth 557*37da2899SCharles.Forsyth num = 0; 558*37da2899SCharles.Forsyth divider = 1; 559*37da2899SCharles.Forsyth 560*37da2899SCharles.Forsyth if ( cur >= limit ) 561*37da2899SCharles.Forsyth goto Exit; 562*37da2899SCharles.Forsyth 563*37da2899SCharles.Forsyth /* read decimal part, if any */ 564*37da2899SCharles.Forsyth if ( *cur == '.' && cur + 1 < limit ) 565*37da2899SCharles.Forsyth { 566*37da2899SCharles.Forsyth cur++; 567*37da2899SCharles.Forsyth 568*37da2899SCharles.Forsyth for (;;) 569*37da2899SCharles.Forsyth { 570*37da2899SCharles.Forsyth d = (FT_Byte)( *cur - '0' ); 571*37da2899SCharles.Forsyth if ( d >= 10 ) 572*37da2899SCharles.Forsyth break; 573*37da2899SCharles.Forsyth 574*37da2899SCharles.Forsyth if ( divider < 10000000L ) 575*37da2899SCharles.Forsyth { 576*37da2899SCharles.Forsyth num = num * 10 + d; 577*37da2899SCharles.Forsyth divider *= 10; 578*37da2899SCharles.Forsyth } 579*37da2899SCharles.Forsyth 580*37da2899SCharles.Forsyth cur++; 581*37da2899SCharles.Forsyth if ( cur >= limit ) 582*37da2899SCharles.Forsyth break; 583*37da2899SCharles.Forsyth } 584*37da2899SCharles.Forsyth } 585*37da2899SCharles.Forsyth 586*37da2899SCharles.Forsyth /* read exponent, if any */ 587*37da2899SCharles.Forsyth if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) ) 588*37da2899SCharles.Forsyth { 589*37da2899SCharles.Forsyth cur++; 590*37da2899SCharles.Forsyth power_ten += t1_toint( &cur, limit ); 591*37da2899SCharles.Forsyth } 592*37da2899SCharles.Forsyth 593*37da2899SCharles.Forsyth Exit: 594*37da2899SCharles.Forsyth /* raise to power of ten if needed */ 595*37da2899SCharles.Forsyth while ( power_ten > 0 ) 596*37da2899SCharles.Forsyth { 597*37da2899SCharles.Forsyth result = result * 10; 598*37da2899SCharles.Forsyth num = num * 10; 599*37da2899SCharles.Forsyth power_ten--; 600*37da2899SCharles.Forsyth } 601*37da2899SCharles.Forsyth 602*37da2899SCharles.Forsyth while ( power_ten < 0 ) 603*37da2899SCharles.Forsyth { 604*37da2899SCharles.Forsyth result = result / 10; 605*37da2899SCharles.Forsyth divider = divider * 10; 606*37da2899SCharles.Forsyth power_ten++; 607*37da2899SCharles.Forsyth } 608*37da2899SCharles.Forsyth 609*37da2899SCharles.Forsyth if ( num ) 610*37da2899SCharles.Forsyth result += FT_DivFix( num, divider ); 611*37da2899SCharles.Forsyth 612*37da2899SCharles.Forsyth if ( sign ) 613*37da2899SCharles.Forsyth result = -result; 614*37da2899SCharles.Forsyth 615*37da2899SCharles.Forsyth *cursor = cur; 616*37da2899SCharles.Forsyth return result; 617*37da2899SCharles.Forsyth } 618*37da2899SCharles.Forsyth 619*37da2899SCharles.Forsyth 620*37da2899SCharles.Forsyth static FT_Int t1_tocoordarray(FT_Byte ** cursor,FT_Byte * limit,FT_Int max_coords,FT_Short * coords)621*37da2899SCharles.Forsyth t1_tocoordarray( FT_Byte** cursor, 622*37da2899SCharles.Forsyth FT_Byte* limit, 623*37da2899SCharles.Forsyth FT_Int max_coords, 624*37da2899SCharles.Forsyth FT_Short* coords ) 625*37da2899SCharles.Forsyth { 626*37da2899SCharles.Forsyth FT_Byte* cur = *cursor; 627*37da2899SCharles.Forsyth FT_Int count = 0; 628*37da2899SCharles.Forsyth FT_Byte c, ender; 629*37da2899SCharles.Forsyth 630*37da2899SCharles.Forsyth 631*37da2899SCharles.Forsyth if ( cur >= limit ) 632*37da2899SCharles.Forsyth goto Exit; 633*37da2899SCharles.Forsyth 634*37da2899SCharles.Forsyth /* check for the beginning of an array; if not, only one number will */ 635*37da2899SCharles.Forsyth /* be read */ 636*37da2899SCharles.Forsyth c = *cur; 637*37da2899SCharles.Forsyth ender = 0; 638*37da2899SCharles.Forsyth 639*37da2899SCharles.Forsyth if ( c == '[' ) 640*37da2899SCharles.Forsyth ender = ']'; 641*37da2899SCharles.Forsyth 642*37da2899SCharles.Forsyth if ( c == '{' ) 643*37da2899SCharles.Forsyth ender = '}'; 644*37da2899SCharles.Forsyth 645*37da2899SCharles.Forsyth if ( ender ) 646*37da2899SCharles.Forsyth cur++; 647*37da2899SCharles.Forsyth 648*37da2899SCharles.Forsyth /* now, read the coordinates */ 649*37da2899SCharles.Forsyth for ( ; cur < limit; ) 650*37da2899SCharles.Forsyth { 651*37da2899SCharles.Forsyth /* skip whitespace in front of data */ 652*37da2899SCharles.Forsyth for (;;) 653*37da2899SCharles.Forsyth { 654*37da2899SCharles.Forsyth c = *cur; 655*37da2899SCharles.Forsyth if ( c != ' ' && c != '\t' ) 656*37da2899SCharles.Forsyth break; 657*37da2899SCharles.Forsyth 658*37da2899SCharles.Forsyth cur++; 659*37da2899SCharles.Forsyth if ( cur >= limit ) 660*37da2899SCharles.Forsyth goto Exit; 661*37da2899SCharles.Forsyth } 662*37da2899SCharles.Forsyth 663*37da2899SCharles.Forsyth if ( count >= max_coords || c == ender ) 664*37da2899SCharles.Forsyth break; 665*37da2899SCharles.Forsyth 666*37da2899SCharles.Forsyth coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 ); 667*37da2899SCharles.Forsyth count++; 668*37da2899SCharles.Forsyth 669*37da2899SCharles.Forsyth if ( !ender ) 670*37da2899SCharles.Forsyth break; 671*37da2899SCharles.Forsyth } 672*37da2899SCharles.Forsyth 673*37da2899SCharles.Forsyth Exit: 674*37da2899SCharles.Forsyth *cursor = cur; 675*37da2899SCharles.Forsyth return count; 676*37da2899SCharles.Forsyth } 677*37da2899SCharles.Forsyth 678*37da2899SCharles.Forsyth 679*37da2899SCharles.Forsyth static FT_Int t1_tofixedarray(FT_Byte ** cursor,FT_Byte * limit,FT_Int max_values,FT_Fixed * values,FT_Int power_ten)680*37da2899SCharles.Forsyth t1_tofixedarray( FT_Byte** cursor, 681*37da2899SCharles.Forsyth FT_Byte* limit, 682*37da2899SCharles.Forsyth FT_Int max_values, 683*37da2899SCharles.Forsyth FT_Fixed* values, 684*37da2899SCharles.Forsyth FT_Int power_ten ) 685*37da2899SCharles.Forsyth { 686*37da2899SCharles.Forsyth FT_Byte* cur = *cursor; 687*37da2899SCharles.Forsyth FT_Int count = 0; 688*37da2899SCharles.Forsyth FT_Byte c, ender; 689*37da2899SCharles.Forsyth 690*37da2899SCharles.Forsyth 691*37da2899SCharles.Forsyth if ( cur >= limit ) goto Exit; 692*37da2899SCharles.Forsyth 693*37da2899SCharles.Forsyth /* check for the beginning of an array. If not, only one number will */ 694*37da2899SCharles.Forsyth /* be read */ 695*37da2899SCharles.Forsyth c = *cur; 696*37da2899SCharles.Forsyth ender = 0; 697*37da2899SCharles.Forsyth 698*37da2899SCharles.Forsyth if ( c == '[' ) 699*37da2899SCharles.Forsyth ender = ']'; 700*37da2899SCharles.Forsyth 701*37da2899SCharles.Forsyth if ( c == '{' ) 702*37da2899SCharles.Forsyth ender = '}'; 703*37da2899SCharles.Forsyth 704*37da2899SCharles.Forsyth if ( ender ) 705*37da2899SCharles.Forsyth cur++; 706*37da2899SCharles.Forsyth 707*37da2899SCharles.Forsyth /* now, read the values */ 708*37da2899SCharles.Forsyth for ( ; cur < limit; ) 709*37da2899SCharles.Forsyth { 710*37da2899SCharles.Forsyth /* skip whitespace in front of data */ 711*37da2899SCharles.Forsyth for (;;) 712*37da2899SCharles.Forsyth { 713*37da2899SCharles.Forsyth c = *cur; 714*37da2899SCharles.Forsyth if ( c != ' ' && c != '\t' ) 715*37da2899SCharles.Forsyth break; 716*37da2899SCharles.Forsyth 717*37da2899SCharles.Forsyth cur++; 718*37da2899SCharles.Forsyth if ( cur >= limit ) 719*37da2899SCharles.Forsyth goto Exit; 720*37da2899SCharles.Forsyth } 721*37da2899SCharles.Forsyth 722*37da2899SCharles.Forsyth if ( count >= max_values || c == ender ) 723*37da2899SCharles.Forsyth break; 724*37da2899SCharles.Forsyth 725*37da2899SCharles.Forsyth values[count] = t1_tofixed( &cur, limit, power_ten ); 726*37da2899SCharles.Forsyth count++; 727*37da2899SCharles.Forsyth 728*37da2899SCharles.Forsyth if ( !ender ) 729*37da2899SCharles.Forsyth break; 730*37da2899SCharles.Forsyth } 731*37da2899SCharles.Forsyth 732*37da2899SCharles.Forsyth Exit: 733*37da2899SCharles.Forsyth *cursor = cur; 734*37da2899SCharles.Forsyth return count; 735*37da2899SCharles.Forsyth } 736*37da2899SCharles.Forsyth 737*37da2899SCharles.Forsyth 738*37da2899SCharles.Forsyth #if 0 739*37da2899SCharles.Forsyth 740*37da2899SCharles.Forsyth static FT_String* 741*37da2899SCharles.Forsyth t1_tostring( FT_Byte** cursor, 742*37da2899SCharles.Forsyth FT_Byte* limit, 743*37da2899SCharles.Forsyth FT_Memory memory ) 744*37da2899SCharles.Forsyth { 745*37da2899SCharles.Forsyth FT_Byte* cur = *cursor; 746*37da2899SCharles.Forsyth FT_PtrDist len = 0; 747*37da2899SCharles.Forsyth FT_Int count; 748*37da2899SCharles.Forsyth FT_String* result; 749*37da2899SCharles.Forsyth FT_Error error; 750*37da2899SCharles.Forsyth 751*37da2899SCharles.Forsyth 752*37da2899SCharles.Forsyth /* XXX: some stupid fonts have a `Notice' or `Copyright' string */ 753*37da2899SCharles.Forsyth /* that simply doesn't begin with an opening parenthesis, even */ 754*37da2899SCharles.Forsyth /* though they have a closing one! E.g. "amuncial.pfb" */ 755*37da2899SCharles.Forsyth /* */ 756*37da2899SCharles.Forsyth /* We must deal with these ill-fated cases there. Note that */ 757*37da2899SCharles.Forsyth /* these fonts didn't work with the old Type 1 driver as the */ 758*37da2899SCharles.Forsyth /* notice/copyright was not recognized as a valid string token */ 759*37da2899SCharles.Forsyth /* and made the old token parser commit errors. */ 760*37da2899SCharles.Forsyth 761*37da2899SCharles.Forsyth while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) ) 762*37da2899SCharles.Forsyth cur++; 763*37da2899SCharles.Forsyth if ( cur + 1 >= limit ) 764*37da2899SCharles.Forsyth return 0; 765*37da2899SCharles.Forsyth 766*37da2899SCharles.Forsyth if ( *cur == '(' ) 767*37da2899SCharles.Forsyth cur++; /* skip the opening parenthesis, if there is one */ 768*37da2899SCharles.Forsyth 769*37da2899SCharles.Forsyth *cursor = cur; 770*37da2899SCharles.Forsyth count = 0; 771*37da2899SCharles.Forsyth 772*37da2899SCharles.Forsyth /* then, count its length */ 773*37da2899SCharles.Forsyth for ( ; cur < limit; cur++ ) 774*37da2899SCharles.Forsyth { 775*37da2899SCharles.Forsyth if ( *cur == '(' ) 776*37da2899SCharles.Forsyth count++; 777*37da2899SCharles.Forsyth 778*37da2899SCharles.Forsyth else if ( *cur == ')' ) 779*37da2899SCharles.Forsyth { 780*37da2899SCharles.Forsyth count--; 781*37da2899SCharles.Forsyth if ( count < 0 ) 782*37da2899SCharles.Forsyth break; 783*37da2899SCharles.Forsyth } 784*37da2899SCharles.Forsyth } 785*37da2899SCharles.Forsyth 786*37da2899SCharles.Forsyth len = cur - *cursor; 787*37da2899SCharles.Forsyth if ( cur >= limit || FT_ALLOC( result, len + 1 ) ) 788*37da2899SCharles.Forsyth return 0; 789*37da2899SCharles.Forsyth 790*37da2899SCharles.Forsyth /* now copy the string */ 791*37da2899SCharles.Forsyth FT_MEM_COPY( result, *cursor, len ); 792*37da2899SCharles.Forsyth result[len] = '\0'; 793*37da2899SCharles.Forsyth *cursor = cur; 794*37da2899SCharles.Forsyth return result; 795*37da2899SCharles.Forsyth } 796*37da2899SCharles.Forsyth 797*37da2899SCharles.Forsyth #endif /* 0 */ 798*37da2899SCharles.Forsyth 799*37da2899SCharles.Forsyth 800*37da2899SCharles.Forsyth static int t1_tobool(FT_Byte ** cursor,FT_Byte * limit)801*37da2899SCharles.Forsyth t1_tobool( FT_Byte** cursor, 802*37da2899SCharles.Forsyth FT_Byte* limit ) 803*37da2899SCharles.Forsyth { 804*37da2899SCharles.Forsyth FT_Byte* cur = *cursor; 805*37da2899SCharles.Forsyth FT_Bool result = 0; 806*37da2899SCharles.Forsyth 807*37da2899SCharles.Forsyth 808*37da2899SCharles.Forsyth /* return 1 if we find `true', 0 otherwise */ 809*37da2899SCharles.Forsyth if ( cur + 3 < limit && 810*37da2899SCharles.Forsyth cur[0] == 't' && 811*37da2899SCharles.Forsyth cur[1] == 'r' && 812*37da2899SCharles.Forsyth cur[2] == 'u' && 813*37da2899SCharles.Forsyth cur[3] == 'e' ) 814*37da2899SCharles.Forsyth { 815*37da2899SCharles.Forsyth result = 1; 816*37da2899SCharles.Forsyth cur += 5; 817*37da2899SCharles.Forsyth } 818*37da2899SCharles.Forsyth else if ( cur + 4 < limit && 819*37da2899SCharles.Forsyth cur[0] == 'f' && 820*37da2899SCharles.Forsyth cur[1] == 'a' && 821*37da2899SCharles.Forsyth cur[2] == 'l' && 822*37da2899SCharles.Forsyth cur[3] == 's' && 823*37da2899SCharles.Forsyth cur[4] == 'e' ) 824*37da2899SCharles.Forsyth { 825*37da2899SCharles.Forsyth result = 0; 826*37da2899SCharles.Forsyth cur += 6; 827*37da2899SCharles.Forsyth } 828*37da2899SCharles.Forsyth 829*37da2899SCharles.Forsyth *cursor = cur; 830*37da2899SCharles.Forsyth return result; 831*37da2899SCharles.Forsyth } 832*37da2899SCharles.Forsyth 833*37da2899SCharles.Forsyth 834*37da2899SCharles.Forsyth /* Load a simple field (i.e. non-table) into the current list of objects */ 835*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) ps_parser_load_field(PS_Parser parser,const T1_Field field,void ** objects,FT_UInt max_objects,FT_ULong * pflags)836*37da2899SCharles.Forsyth ps_parser_load_field( PS_Parser parser, 837*37da2899SCharles.Forsyth const T1_Field field, 838*37da2899SCharles.Forsyth void** objects, 839*37da2899SCharles.Forsyth FT_UInt max_objects, 840*37da2899SCharles.Forsyth FT_ULong* pflags ) 841*37da2899SCharles.Forsyth { 842*37da2899SCharles.Forsyth T1_TokenRec token; 843*37da2899SCharles.Forsyth FT_Byte* cur; 844*37da2899SCharles.Forsyth FT_Byte* limit; 845*37da2899SCharles.Forsyth FT_UInt count; 846*37da2899SCharles.Forsyth FT_UInt idx; 847*37da2899SCharles.Forsyth FT_Error error; 848*37da2899SCharles.Forsyth 849*37da2899SCharles.Forsyth 850*37da2899SCharles.Forsyth ps_parser_to_token( parser, &token ); 851*37da2899SCharles.Forsyth if ( !token.type ) 852*37da2899SCharles.Forsyth goto Fail; 853*37da2899SCharles.Forsyth 854*37da2899SCharles.Forsyth count = 1; 855*37da2899SCharles.Forsyth idx = 0; 856*37da2899SCharles.Forsyth cur = token.start; 857*37da2899SCharles.Forsyth limit = token.limit; 858*37da2899SCharles.Forsyth 859*37da2899SCharles.Forsyth /* we must detect arrays */ 860*37da2899SCharles.Forsyth if ( field->type == T1_FIELD_TYPE_BBOX ) 861*37da2899SCharles.Forsyth { 862*37da2899SCharles.Forsyth T1_TokenRec token2; 863*37da2899SCharles.Forsyth FT_Byte* old_cur = parser->cursor; 864*37da2899SCharles.Forsyth FT_Byte* old_limit = parser->limit; 865*37da2899SCharles.Forsyth 866*37da2899SCharles.Forsyth 867*37da2899SCharles.Forsyth parser->cursor = token.start; 868*37da2899SCharles.Forsyth parser->limit = token.limit; 869*37da2899SCharles.Forsyth 870*37da2899SCharles.Forsyth ps_parser_to_token( parser, &token2 ); 871*37da2899SCharles.Forsyth parser->cursor = old_cur; 872*37da2899SCharles.Forsyth parser->limit = old_limit; 873*37da2899SCharles.Forsyth 874*37da2899SCharles.Forsyth if ( token2.type == T1_TOKEN_TYPE_ARRAY ) 875*37da2899SCharles.Forsyth goto FieldArray; 876*37da2899SCharles.Forsyth } 877*37da2899SCharles.Forsyth else if ( token.type == T1_TOKEN_TYPE_ARRAY ) 878*37da2899SCharles.Forsyth { 879*37da2899SCharles.Forsyth FieldArray: 880*37da2899SCharles.Forsyth /* if this is an array, and we have no blend, an error occurs */ 881*37da2899SCharles.Forsyth if ( max_objects == 0 ) 882*37da2899SCharles.Forsyth goto Fail; 883*37da2899SCharles.Forsyth 884*37da2899SCharles.Forsyth count = max_objects; 885*37da2899SCharles.Forsyth idx = 1; 886*37da2899SCharles.Forsyth } 887*37da2899SCharles.Forsyth 888*37da2899SCharles.Forsyth for ( ; count > 0; count--, idx++ ) 889*37da2899SCharles.Forsyth { 890*37da2899SCharles.Forsyth FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; 891*37da2899SCharles.Forsyth FT_Long val; 892*37da2899SCharles.Forsyth FT_String* string; 893*37da2899SCharles.Forsyth 894*37da2899SCharles.Forsyth 895*37da2899SCharles.Forsyth switch ( field->type ) 896*37da2899SCharles.Forsyth { 897*37da2899SCharles.Forsyth case T1_FIELD_TYPE_BOOL: 898*37da2899SCharles.Forsyth val = t1_tobool( &cur, limit ); 899*37da2899SCharles.Forsyth goto Store_Integer; 900*37da2899SCharles.Forsyth 901*37da2899SCharles.Forsyth case T1_FIELD_TYPE_FIXED: 902*37da2899SCharles.Forsyth val = t1_tofixed( &cur, limit, 3 ); 903*37da2899SCharles.Forsyth goto Store_Integer; 904*37da2899SCharles.Forsyth 905*37da2899SCharles.Forsyth case T1_FIELD_TYPE_INTEGER: 906*37da2899SCharles.Forsyth val = t1_toint( &cur, limit ); 907*37da2899SCharles.Forsyth 908*37da2899SCharles.Forsyth Store_Integer: 909*37da2899SCharles.Forsyth switch ( field->size ) 910*37da2899SCharles.Forsyth { 911*37da2899SCharles.Forsyth case 1: 912*37da2899SCharles.Forsyth *(FT_Byte*)q = (FT_Byte)val; 913*37da2899SCharles.Forsyth break; 914*37da2899SCharles.Forsyth 915*37da2899SCharles.Forsyth case 2: 916*37da2899SCharles.Forsyth *(FT_UShort*)q = (FT_UShort)val; 917*37da2899SCharles.Forsyth break; 918*37da2899SCharles.Forsyth 919*37da2899SCharles.Forsyth case 4: 920*37da2899SCharles.Forsyth *(FT_UInt32*)q = (FT_UInt32)val; 921*37da2899SCharles.Forsyth break; 922*37da2899SCharles.Forsyth 923*37da2899SCharles.Forsyth default: /* for 64-bit systems */ 924*37da2899SCharles.Forsyth *(FT_Long*)q = val; 925*37da2899SCharles.Forsyth } 926*37da2899SCharles.Forsyth break; 927*37da2899SCharles.Forsyth 928*37da2899SCharles.Forsyth case T1_FIELD_TYPE_STRING: 929*37da2899SCharles.Forsyth { 930*37da2899SCharles.Forsyth FT_Memory memory = parser->memory; 931*37da2899SCharles.Forsyth FT_UInt len = (FT_UInt)( limit - cur ); 932*37da2899SCharles.Forsyth 933*37da2899SCharles.Forsyth 934*37da2899SCharles.Forsyth if ( *(FT_String**)q ) 935*37da2899SCharles.Forsyth /* with synthetic fonts, it's possible to find a field twice */ 936*37da2899SCharles.Forsyth break; 937*37da2899SCharles.Forsyth 938*37da2899SCharles.Forsyth if ( FT_ALLOC( string, len + 1 ) ) 939*37da2899SCharles.Forsyth goto Exit; 940*37da2899SCharles.Forsyth 941*37da2899SCharles.Forsyth FT_MEM_COPY( string, cur, len ); 942*37da2899SCharles.Forsyth string[len] = 0; 943*37da2899SCharles.Forsyth 944*37da2899SCharles.Forsyth *(FT_String**)q = string; 945*37da2899SCharles.Forsyth } 946*37da2899SCharles.Forsyth break; 947*37da2899SCharles.Forsyth 948*37da2899SCharles.Forsyth case T1_FIELD_TYPE_BBOX: 949*37da2899SCharles.Forsyth { 950*37da2899SCharles.Forsyth FT_Fixed temp[4]; 951*37da2899SCharles.Forsyth FT_BBox* bbox = (FT_BBox*)q; 952*37da2899SCharles.Forsyth 953*37da2899SCharles.Forsyth 954*37da2899SCharles.Forsyth /* we need the '[' and ']' delimiters */ 955*37da2899SCharles.Forsyth token.start--; 956*37da2899SCharles.Forsyth token.limit++; 957*37da2899SCharles.Forsyth (void)t1_tofixedarray( &token.start, token.limit, 4, temp, 0 ); 958*37da2899SCharles.Forsyth 959*37da2899SCharles.Forsyth bbox->xMin = FT_RoundFix( temp[0] ); 960*37da2899SCharles.Forsyth bbox->yMin = FT_RoundFix( temp[1] ); 961*37da2899SCharles.Forsyth bbox->xMax = FT_RoundFix( temp[2] ); 962*37da2899SCharles.Forsyth bbox->yMax = FT_RoundFix( temp[3] ); 963*37da2899SCharles.Forsyth } 964*37da2899SCharles.Forsyth break; 965*37da2899SCharles.Forsyth 966*37da2899SCharles.Forsyth default: 967*37da2899SCharles.Forsyth /* an error occured */ 968*37da2899SCharles.Forsyth goto Fail; 969*37da2899SCharles.Forsyth } 970*37da2899SCharles.Forsyth } 971*37da2899SCharles.Forsyth 972*37da2899SCharles.Forsyth #if 0 /* obsolete - keep for reference */ 973*37da2899SCharles.Forsyth if ( pflags ) 974*37da2899SCharles.Forsyth *pflags |= 1L << field->flag_bit; 975*37da2899SCharles.Forsyth #else 976*37da2899SCharles.Forsyth FT_UNUSED( pflags ); 977*37da2899SCharles.Forsyth #endif 978*37da2899SCharles.Forsyth 979*37da2899SCharles.Forsyth error = PSaux_Err_Ok; 980*37da2899SCharles.Forsyth 981*37da2899SCharles.Forsyth Exit: 982*37da2899SCharles.Forsyth return error; 983*37da2899SCharles.Forsyth 984*37da2899SCharles.Forsyth Fail: 985*37da2899SCharles.Forsyth error = PSaux_Err_Invalid_File_Format; 986*37da2899SCharles.Forsyth goto Exit; 987*37da2899SCharles.Forsyth } 988*37da2899SCharles.Forsyth 989*37da2899SCharles.Forsyth 990*37da2899SCharles.Forsyth #define T1_MAX_TABLE_ELEMENTS 32 991*37da2899SCharles.Forsyth 992*37da2899SCharles.Forsyth 993*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) ps_parser_load_field_table(PS_Parser parser,const T1_Field field,void ** objects,FT_UInt max_objects,FT_ULong * pflags)994*37da2899SCharles.Forsyth ps_parser_load_field_table( PS_Parser parser, 995*37da2899SCharles.Forsyth const T1_Field field, 996*37da2899SCharles.Forsyth void** objects, 997*37da2899SCharles.Forsyth FT_UInt max_objects, 998*37da2899SCharles.Forsyth FT_ULong* pflags ) 999*37da2899SCharles.Forsyth { 1000*37da2899SCharles.Forsyth T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS]; 1001*37da2899SCharles.Forsyth T1_Token token; 1002*37da2899SCharles.Forsyth FT_Int num_elements; 1003*37da2899SCharles.Forsyth FT_Error error = 0; 1004*37da2899SCharles.Forsyth FT_Byte* old_cursor; 1005*37da2899SCharles.Forsyth FT_Byte* old_limit; 1006*37da2899SCharles.Forsyth T1_FieldRec fieldrec = *(T1_Field)field; 1007*37da2899SCharles.Forsyth 1008*37da2899SCharles.Forsyth 1009*37da2899SCharles.Forsyth #if 1 1010*37da2899SCharles.Forsyth fieldrec.type = T1_FIELD_TYPE_INTEGER; 1011*37da2899SCharles.Forsyth if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ) 1012*37da2899SCharles.Forsyth fieldrec.type = T1_FIELD_TYPE_FIXED; 1013*37da2899SCharles.Forsyth #endif 1014*37da2899SCharles.Forsyth 1015*37da2899SCharles.Forsyth ps_parser_to_token_array( parser, elements, 32, &num_elements ); 1016*37da2899SCharles.Forsyth if ( num_elements < 0 ) 1017*37da2899SCharles.Forsyth goto Fail; 1018*37da2899SCharles.Forsyth 1019*37da2899SCharles.Forsyth if ( num_elements > T1_MAX_TABLE_ELEMENTS ) 1020*37da2899SCharles.Forsyth num_elements = T1_MAX_TABLE_ELEMENTS; 1021*37da2899SCharles.Forsyth 1022*37da2899SCharles.Forsyth old_cursor = parser->cursor; 1023*37da2899SCharles.Forsyth old_limit = parser->limit; 1024*37da2899SCharles.Forsyth 1025*37da2899SCharles.Forsyth /* we store the elements count */ 1026*37da2899SCharles.Forsyth *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = 1027*37da2899SCharles.Forsyth (FT_Byte)num_elements; 1028*37da2899SCharles.Forsyth 1029*37da2899SCharles.Forsyth /* we now load each element, adjusting the field.offset on each one */ 1030*37da2899SCharles.Forsyth token = elements; 1031*37da2899SCharles.Forsyth for ( ; num_elements > 0; num_elements--, token++ ) 1032*37da2899SCharles.Forsyth { 1033*37da2899SCharles.Forsyth parser->cursor = token->start; 1034*37da2899SCharles.Forsyth parser->limit = token->limit; 1035*37da2899SCharles.Forsyth ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 ); 1036*37da2899SCharles.Forsyth fieldrec.offset += fieldrec.size; 1037*37da2899SCharles.Forsyth } 1038*37da2899SCharles.Forsyth 1039*37da2899SCharles.Forsyth #if 0 /* obsolete -- keep for reference */ 1040*37da2899SCharles.Forsyth if ( pflags ) 1041*37da2899SCharles.Forsyth *pflags |= 1L << field->flag_bit; 1042*37da2899SCharles.Forsyth #else 1043*37da2899SCharles.Forsyth FT_UNUSED( pflags ); 1044*37da2899SCharles.Forsyth #endif 1045*37da2899SCharles.Forsyth 1046*37da2899SCharles.Forsyth parser->cursor = old_cursor; 1047*37da2899SCharles.Forsyth parser->limit = old_limit; 1048*37da2899SCharles.Forsyth 1049*37da2899SCharles.Forsyth Exit: 1050*37da2899SCharles.Forsyth return error; 1051*37da2899SCharles.Forsyth 1052*37da2899SCharles.Forsyth Fail: 1053*37da2899SCharles.Forsyth error = PSaux_Err_Invalid_File_Format; 1054*37da2899SCharles.Forsyth goto Exit; 1055*37da2899SCharles.Forsyth } 1056*37da2899SCharles.Forsyth 1057*37da2899SCharles.Forsyth 1058*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Long ) ps_parser_to_int(PS_Parser parser)1059*37da2899SCharles.Forsyth ps_parser_to_int( PS_Parser parser ) 1060*37da2899SCharles.Forsyth { 1061*37da2899SCharles.Forsyth return t1_toint( &parser->cursor, parser->limit ); 1062*37da2899SCharles.Forsyth } 1063*37da2899SCharles.Forsyth 1064*37da2899SCharles.Forsyth 1065*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Fixed ) ps_parser_to_fixed(PS_Parser parser,FT_Int power_ten)1066*37da2899SCharles.Forsyth ps_parser_to_fixed( PS_Parser parser, 1067*37da2899SCharles.Forsyth FT_Int power_ten ) 1068*37da2899SCharles.Forsyth { 1069*37da2899SCharles.Forsyth return t1_tofixed( &parser->cursor, parser->limit, power_ten ); 1070*37da2899SCharles.Forsyth } 1071*37da2899SCharles.Forsyth 1072*37da2899SCharles.Forsyth 1073*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Int ) ps_parser_to_coord_array(PS_Parser parser,FT_Int max_coords,FT_Short * coords)1074*37da2899SCharles.Forsyth ps_parser_to_coord_array( PS_Parser parser, 1075*37da2899SCharles.Forsyth FT_Int max_coords, 1076*37da2899SCharles.Forsyth FT_Short* coords ) 1077*37da2899SCharles.Forsyth { 1078*37da2899SCharles.Forsyth return t1_tocoordarray( &parser->cursor, parser->limit, 1079*37da2899SCharles.Forsyth max_coords, coords ); 1080*37da2899SCharles.Forsyth } 1081*37da2899SCharles.Forsyth 1082*37da2899SCharles.Forsyth 1083*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Int ) ps_parser_to_fixed_array(PS_Parser parser,FT_Int max_values,FT_Fixed * values,FT_Int power_ten)1084*37da2899SCharles.Forsyth ps_parser_to_fixed_array( PS_Parser parser, 1085*37da2899SCharles.Forsyth FT_Int max_values, 1086*37da2899SCharles.Forsyth FT_Fixed* values, 1087*37da2899SCharles.Forsyth FT_Int power_ten ) 1088*37da2899SCharles.Forsyth { 1089*37da2899SCharles.Forsyth return t1_tofixedarray( &parser->cursor, parser->limit, 1090*37da2899SCharles.Forsyth max_values, values, power_ten ); 1091*37da2899SCharles.Forsyth } 1092*37da2899SCharles.Forsyth 1093*37da2899SCharles.Forsyth 1094*37da2899SCharles.Forsyth #if 0 1095*37da2899SCharles.Forsyth 1096*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_String* ) 1097*37da2899SCharles.Forsyth T1_ToString( PS_Parser parser ) 1098*37da2899SCharles.Forsyth { 1099*37da2899SCharles.Forsyth return t1_tostring( &parser->cursor, parser->limit, parser->memory ); 1100*37da2899SCharles.Forsyth } 1101*37da2899SCharles.Forsyth 1102*37da2899SCharles.Forsyth 1103*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Bool ) 1104*37da2899SCharles.Forsyth T1_ToBool( PS_Parser parser ) 1105*37da2899SCharles.Forsyth { 1106*37da2899SCharles.Forsyth return t1_tobool( &parser->cursor, parser->limit ); 1107*37da2899SCharles.Forsyth } 1108*37da2899SCharles.Forsyth 1109*37da2899SCharles.Forsyth #endif /* 0 */ 1110*37da2899SCharles.Forsyth 1111*37da2899SCharles.Forsyth 1112*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) ps_parser_init(PS_Parser parser,FT_Byte * base,FT_Byte * limit,FT_Memory memory)1113*37da2899SCharles.Forsyth ps_parser_init( PS_Parser parser, 1114*37da2899SCharles.Forsyth FT_Byte* base, 1115*37da2899SCharles.Forsyth FT_Byte* limit, 1116*37da2899SCharles.Forsyth FT_Memory memory ) 1117*37da2899SCharles.Forsyth { 1118*37da2899SCharles.Forsyth parser->error = 0; 1119*37da2899SCharles.Forsyth parser->base = base; 1120*37da2899SCharles.Forsyth parser->limit = limit; 1121*37da2899SCharles.Forsyth parser->cursor = base; 1122*37da2899SCharles.Forsyth parser->memory = memory; 1123*37da2899SCharles.Forsyth parser->funcs = ps_parser_funcs; 1124*37da2899SCharles.Forsyth } 1125*37da2899SCharles.Forsyth 1126*37da2899SCharles.Forsyth 1127*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) ps_parser_done(PS_Parser parser)1128*37da2899SCharles.Forsyth ps_parser_done( PS_Parser parser ) 1129*37da2899SCharles.Forsyth { 1130*37da2899SCharles.Forsyth FT_UNUSED( parser ); 1131*37da2899SCharles.Forsyth } 1132*37da2899SCharles.Forsyth 1133*37da2899SCharles.Forsyth 1134*37da2899SCharles.Forsyth /*************************************************************************/ 1135*37da2899SCharles.Forsyth /*************************************************************************/ 1136*37da2899SCharles.Forsyth /***** *****/ 1137*37da2899SCharles.Forsyth /***** T1 BUILDER *****/ 1138*37da2899SCharles.Forsyth /***** *****/ 1139*37da2899SCharles.Forsyth /*************************************************************************/ 1140*37da2899SCharles.Forsyth /*************************************************************************/ 1141*37da2899SCharles.Forsyth 1142*37da2899SCharles.Forsyth /*************************************************************************/ 1143*37da2899SCharles.Forsyth /* */ 1144*37da2899SCharles.Forsyth /* <Function> */ 1145*37da2899SCharles.Forsyth /* t1_builder_init */ 1146*37da2899SCharles.Forsyth /* */ 1147*37da2899SCharles.Forsyth /* <Description> */ 1148*37da2899SCharles.Forsyth /* Initializes a given glyph builder. */ 1149*37da2899SCharles.Forsyth /* */ 1150*37da2899SCharles.Forsyth /* <InOut> */ 1151*37da2899SCharles.Forsyth /* builder :: A pointer to the glyph builder to initialize. */ 1152*37da2899SCharles.Forsyth /* */ 1153*37da2899SCharles.Forsyth /* <Input> */ 1154*37da2899SCharles.Forsyth /* face :: The current face object. */ 1155*37da2899SCharles.Forsyth /* */ 1156*37da2899SCharles.Forsyth /* size :: The current size object. */ 1157*37da2899SCharles.Forsyth /* */ 1158*37da2899SCharles.Forsyth /* glyph :: The current glyph object. */ 1159*37da2899SCharles.Forsyth /* */ 1160*37da2899SCharles.Forsyth /* hinting :: Whether hinting should be applied. */ 1161*37da2899SCharles.Forsyth /* */ 1162*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) t1_builder_init(T1_Builder builder,FT_Face face,FT_Size size,FT_GlyphSlot glyph,FT_Bool hinting)1163*37da2899SCharles.Forsyth t1_builder_init( T1_Builder builder, 1164*37da2899SCharles.Forsyth FT_Face face, 1165*37da2899SCharles.Forsyth FT_Size size, 1166*37da2899SCharles.Forsyth FT_GlyphSlot glyph, 1167*37da2899SCharles.Forsyth FT_Bool hinting ) 1168*37da2899SCharles.Forsyth { 1169*37da2899SCharles.Forsyth builder->path_begun = 0; 1170*37da2899SCharles.Forsyth builder->load_points = 1; 1171*37da2899SCharles.Forsyth 1172*37da2899SCharles.Forsyth builder->face = face; 1173*37da2899SCharles.Forsyth builder->glyph = glyph; 1174*37da2899SCharles.Forsyth builder->memory = face->memory; 1175*37da2899SCharles.Forsyth 1176*37da2899SCharles.Forsyth if ( glyph ) 1177*37da2899SCharles.Forsyth { 1178*37da2899SCharles.Forsyth FT_GlyphLoader loader = glyph->internal->loader; 1179*37da2899SCharles.Forsyth 1180*37da2899SCharles.Forsyth 1181*37da2899SCharles.Forsyth builder->loader = loader; 1182*37da2899SCharles.Forsyth builder->base = &loader->base.outline; 1183*37da2899SCharles.Forsyth builder->current = &loader->current.outline; 1184*37da2899SCharles.Forsyth FT_GlyphLoader_Rewind( loader ); 1185*37da2899SCharles.Forsyth 1186*37da2899SCharles.Forsyth builder->hints_globals = size->internal; 1187*37da2899SCharles.Forsyth builder->hints_funcs = 0; 1188*37da2899SCharles.Forsyth 1189*37da2899SCharles.Forsyth if ( hinting ) 1190*37da2899SCharles.Forsyth builder->hints_funcs = glyph->internal->glyph_hints; 1191*37da2899SCharles.Forsyth } 1192*37da2899SCharles.Forsyth 1193*37da2899SCharles.Forsyth if ( size ) 1194*37da2899SCharles.Forsyth { 1195*37da2899SCharles.Forsyth builder->scale_x = size->metrics.x_scale; 1196*37da2899SCharles.Forsyth builder->scale_y = size->metrics.y_scale; 1197*37da2899SCharles.Forsyth } 1198*37da2899SCharles.Forsyth 1199*37da2899SCharles.Forsyth builder->pos_x = 0; 1200*37da2899SCharles.Forsyth builder->pos_y = 0; 1201*37da2899SCharles.Forsyth 1202*37da2899SCharles.Forsyth builder->left_bearing.x = 0; 1203*37da2899SCharles.Forsyth builder->left_bearing.y = 0; 1204*37da2899SCharles.Forsyth builder->advance.x = 0; 1205*37da2899SCharles.Forsyth builder->advance.y = 0; 1206*37da2899SCharles.Forsyth 1207*37da2899SCharles.Forsyth builder->funcs = t1_builder_funcs; 1208*37da2899SCharles.Forsyth } 1209*37da2899SCharles.Forsyth 1210*37da2899SCharles.Forsyth 1211*37da2899SCharles.Forsyth /*************************************************************************/ 1212*37da2899SCharles.Forsyth /* */ 1213*37da2899SCharles.Forsyth /* <Function> */ 1214*37da2899SCharles.Forsyth /* t1_builder_done */ 1215*37da2899SCharles.Forsyth /* */ 1216*37da2899SCharles.Forsyth /* <Description> */ 1217*37da2899SCharles.Forsyth /* Finalizes a given glyph builder. Its contents can still be used */ 1218*37da2899SCharles.Forsyth /* after the call, but the function saves important information */ 1219*37da2899SCharles.Forsyth /* within the corresponding glyph slot. */ 1220*37da2899SCharles.Forsyth /* */ 1221*37da2899SCharles.Forsyth /* <Input> */ 1222*37da2899SCharles.Forsyth /* builder :: A pointer to the glyph builder to finalize. */ 1223*37da2899SCharles.Forsyth /* */ 1224*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) t1_builder_done(T1_Builder builder)1225*37da2899SCharles.Forsyth t1_builder_done( T1_Builder builder ) 1226*37da2899SCharles.Forsyth { 1227*37da2899SCharles.Forsyth FT_GlyphSlot glyph = builder->glyph; 1228*37da2899SCharles.Forsyth 1229*37da2899SCharles.Forsyth 1230*37da2899SCharles.Forsyth if ( glyph ) 1231*37da2899SCharles.Forsyth glyph->outline = *builder->base; 1232*37da2899SCharles.Forsyth } 1233*37da2899SCharles.Forsyth 1234*37da2899SCharles.Forsyth 1235*37da2899SCharles.Forsyth /* check that there is enough space for `count' more points */ 1236*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) t1_builder_check_points(T1_Builder builder,FT_Int count)1237*37da2899SCharles.Forsyth t1_builder_check_points( T1_Builder builder, 1238*37da2899SCharles.Forsyth FT_Int count ) 1239*37da2899SCharles.Forsyth { 1240*37da2899SCharles.Forsyth return FT_GlyphLoader_CheckPoints( builder->loader, count, 0 ); 1241*37da2899SCharles.Forsyth } 1242*37da2899SCharles.Forsyth 1243*37da2899SCharles.Forsyth 1244*37da2899SCharles.Forsyth /* add a new point, do not check space */ 1245*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) t1_builder_add_point(T1_Builder builder,FT_Pos x,FT_Pos y,FT_Byte flag)1246*37da2899SCharles.Forsyth t1_builder_add_point( T1_Builder builder, 1247*37da2899SCharles.Forsyth FT_Pos x, 1248*37da2899SCharles.Forsyth FT_Pos y, 1249*37da2899SCharles.Forsyth FT_Byte flag ) 1250*37da2899SCharles.Forsyth { 1251*37da2899SCharles.Forsyth FT_Outline* outline = builder->current; 1252*37da2899SCharles.Forsyth 1253*37da2899SCharles.Forsyth 1254*37da2899SCharles.Forsyth if ( builder->load_points ) 1255*37da2899SCharles.Forsyth { 1256*37da2899SCharles.Forsyth FT_Vector* point = outline->points + outline->n_points; 1257*37da2899SCharles.Forsyth FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; 1258*37da2899SCharles.Forsyth 1259*37da2899SCharles.Forsyth 1260*37da2899SCharles.Forsyth if ( builder->shift ) 1261*37da2899SCharles.Forsyth { 1262*37da2899SCharles.Forsyth x >>= 16; 1263*37da2899SCharles.Forsyth y >>= 16; 1264*37da2899SCharles.Forsyth } 1265*37da2899SCharles.Forsyth point->x = x; 1266*37da2899SCharles.Forsyth point->y = y; 1267*37da2899SCharles.Forsyth *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); 1268*37da2899SCharles.Forsyth 1269*37da2899SCharles.Forsyth builder->last = *point; 1270*37da2899SCharles.Forsyth } 1271*37da2899SCharles.Forsyth outline->n_points++; 1272*37da2899SCharles.Forsyth } 1273*37da2899SCharles.Forsyth 1274*37da2899SCharles.Forsyth 1275*37da2899SCharles.Forsyth /* check space for a new on-curve point, then add it */ 1276*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) t1_builder_add_point1(T1_Builder builder,FT_Pos x,FT_Pos y)1277*37da2899SCharles.Forsyth t1_builder_add_point1( T1_Builder builder, 1278*37da2899SCharles.Forsyth FT_Pos x, 1279*37da2899SCharles.Forsyth FT_Pos y ) 1280*37da2899SCharles.Forsyth { 1281*37da2899SCharles.Forsyth FT_Error error; 1282*37da2899SCharles.Forsyth 1283*37da2899SCharles.Forsyth 1284*37da2899SCharles.Forsyth error = t1_builder_check_points( builder, 1 ); 1285*37da2899SCharles.Forsyth if ( !error ) 1286*37da2899SCharles.Forsyth t1_builder_add_point( builder, x, y, 1 ); 1287*37da2899SCharles.Forsyth 1288*37da2899SCharles.Forsyth return error; 1289*37da2899SCharles.Forsyth } 1290*37da2899SCharles.Forsyth 1291*37da2899SCharles.Forsyth 1292*37da2899SCharles.Forsyth /* check room for a new contour, then add it */ 1293*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) t1_builder_add_contour(T1_Builder builder)1294*37da2899SCharles.Forsyth t1_builder_add_contour( T1_Builder builder ) 1295*37da2899SCharles.Forsyth { 1296*37da2899SCharles.Forsyth FT_Outline* outline = builder->current; 1297*37da2899SCharles.Forsyth FT_Error error; 1298*37da2899SCharles.Forsyth 1299*37da2899SCharles.Forsyth 1300*37da2899SCharles.Forsyth if ( !builder->load_points ) 1301*37da2899SCharles.Forsyth { 1302*37da2899SCharles.Forsyth outline->n_contours++; 1303*37da2899SCharles.Forsyth return PSaux_Err_Ok; 1304*37da2899SCharles.Forsyth } 1305*37da2899SCharles.Forsyth 1306*37da2899SCharles.Forsyth error = FT_GlyphLoader_CheckPoints( builder->loader, 0, 1 ); 1307*37da2899SCharles.Forsyth if ( !error ) 1308*37da2899SCharles.Forsyth { 1309*37da2899SCharles.Forsyth if ( outline->n_contours > 0 ) 1310*37da2899SCharles.Forsyth outline->contours[outline->n_contours - 1] = 1311*37da2899SCharles.Forsyth (short)( outline->n_points - 1 ); 1312*37da2899SCharles.Forsyth 1313*37da2899SCharles.Forsyth outline->n_contours++; 1314*37da2899SCharles.Forsyth } 1315*37da2899SCharles.Forsyth 1316*37da2899SCharles.Forsyth return error; 1317*37da2899SCharles.Forsyth } 1318*37da2899SCharles.Forsyth 1319*37da2899SCharles.Forsyth 1320*37da2899SCharles.Forsyth /* if a path was begun, add its first on-curve point */ 1321*37da2899SCharles.Forsyth FT_LOCAL_DEF( FT_Error ) t1_builder_start_point(T1_Builder builder,FT_Pos x,FT_Pos y)1322*37da2899SCharles.Forsyth t1_builder_start_point( T1_Builder builder, 1323*37da2899SCharles.Forsyth FT_Pos x, 1324*37da2899SCharles.Forsyth FT_Pos y ) 1325*37da2899SCharles.Forsyth { 1326*37da2899SCharles.Forsyth FT_Error error = 0; 1327*37da2899SCharles.Forsyth 1328*37da2899SCharles.Forsyth 1329*37da2899SCharles.Forsyth /* test whether we are building a new contour */ 1330*37da2899SCharles.Forsyth if ( !builder->path_begun ) 1331*37da2899SCharles.Forsyth { 1332*37da2899SCharles.Forsyth builder->path_begun = 1; 1333*37da2899SCharles.Forsyth error = t1_builder_add_contour( builder ); 1334*37da2899SCharles.Forsyth if ( !error ) 1335*37da2899SCharles.Forsyth error = t1_builder_add_point1( builder, x, y ); 1336*37da2899SCharles.Forsyth } 1337*37da2899SCharles.Forsyth return error; 1338*37da2899SCharles.Forsyth } 1339*37da2899SCharles.Forsyth 1340*37da2899SCharles.Forsyth 1341*37da2899SCharles.Forsyth /* close the current contour */ 1342*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) t1_builder_close_contour(T1_Builder builder)1343*37da2899SCharles.Forsyth t1_builder_close_contour( T1_Builder builder ) 1344*37da2899SCharles.Forsyth { 1345*37da2899SCharles.Forsyth FT_Outline* outline = builder->current; 1346*37da2899SCharles.Forsyth 1347*37da2899SCharles.Forsyth 1348*37da2899SCharles.Forsyth /* XXXX: We must not include the last point in the path if it */ 1349*37da2899SCharles.Forsyth /* is located on the first point. */ 1350*37da2899SCharles.Forsyth if ( outline->n_points > 1 ) 1351*37da2899SCharles.Forsyth { 1352*37da2899SCharles.Forsyth FT_Int first = 0; 1353*37da2899SCharles.Forsyth FT_Vector* p1 = outline->points + first; 1354*37da2899SCharles.Forsyth FT_Vector* p2 = outline->points + outline->n_points - 1; 1355*37da2899SCharles.Forsyth FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; 1356*37da2899SCharles.Forsyth 1357*37da2899SCharles.Forsyth 1358*37da2899SCharles.Forsyth if ( outline->n_contours > 1 ) 1359*37da2899SCharles.Forsyth { 1360*37da2899SCharles.Forsyth first = outline->contours[outline->n_contours - 2] + 1; 1361*37da2899SCharles.Forsyth p1 = outline->points + first; 1362*37da2899SCharles.Forsyth } 1363*37da2899SCharles.Forsyth 1364*37da2899SCharles.Forsyth /* `delete' last point only if it coincides with the first */ 1365*37da2899SCharles.Forsyth /* point and it is not a control point (which can happen). */ 1366*37da2899SCharles.Forsyth if ( p1->x == p2->x && p1->y == p2->y ) 1367*37da2899SCharles.Forsyth if ( *control == FT_CURVE_TAG_ON ) 1368*37da2899SCharles.Forsyth outline->n_points--; 1369*37da2899SCharles.Forsyth } 1370*37da2899SCharles.Forsyth 1371*37da2899SCharles.Forsyth if ( outline->n_contours > 0 ) 1372*37da2899SCharles.Forsyth outline->contours[outline->n_contours - 1] = 1373*37da2899SCharles.Forsyth (short)( outline->n_points - 1 ); 1374*37da2899SCharles.Forsyth } 1375*37da2899SCharles.Forsyth 1376*37da2899SCharles.Forsyth 1377*37da2899SCharles.Forsyth /*************************************************************************/ 1378*37da2899SCharles.Forsyth /*************************************************************************/ 1379*37da2899SCharles.Forsyth /***** *****/ 1380*37da2899SCharles.Forsyth /***** OTHER *****/ 1381*37da2899SCharles.Forsyth /***** *****/ 1382*37da2899SCharles.Forsyth /*************************************************************************/ 1383*37da2899SCharles.Forsyth /*************************************************************************/ 1384*37da2899SCharles.Forsyth 1385*37da2899SCharles.Forsyth FT_LOCAL_DEF( void ) t1_decrypt(FT_Byte * buffer,FT_Offset length,FT_UShort seed)1386*37da2899SCharles.Forsyth t1_decrypt( FT_Byte* buffer, 1387*37da2899SCharles.Forsyth FT_Offset length, 1388*37da2899SCharles.Forsyth FT_UShort seed ) 1389*37da2899SCharles.Forsyth { 1390*37da2899SCharles.Forsyth while ( length > 0 ) 1391*37da2899SCharles.Forsyth { 1392*37da2899SCharles.Forsyth FT_Byte plain; 1393*37da2899SCharles.Forsyth 1394*37da2899SCharles.Forsyth 1395*37da2899SCharles.Forsyth plain = (FT_Byte)( *buffer ^ ( seed >> 8 ) ); 1396*37da2899SCharles.Forsyth seed = (FT_UShort)( ( *buffer + seed ) * 52845U + 22719 ); 1397*37da2899SCharles.Forsyth *buffer++ = plain; 1398*37da2899SCharles.Forsyth length--; 1399*37da2899SCharles.Forsyth } 1400*37da2899SCharles.Forsyth } 1401*37da2899SCharles.Forsyth 1402*37da2899SCharles.Forsyth 1403*37da2899SCharles.Forsyth /* END */ 1404