1 /***************************************************************************/ 2 /* */ 3 /* psconv.c */ 4 /* */ 5 /* Some convenience conversions (body). */ 6 /* */ 7 /* Copyright 2006, 2008 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 10 /* This file is part of the FreeType project, and may only be used, */ 11 /* modified, and distributed under the terms of the FreeType project */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 /* this file you indicate that you have read the license and */ 14 /* understand and accept it fully. */ 15 /* */ 16 /***************************************************************************/ 17 18 19 #include <ft2build.h> 20 #include FT_INTERNAL_POSTSCRIPT_AUX_H 21 #include FT_INTERNAL_DEBUG_H 22 23 #include "psconv.h" 24 #include "psobjs.h" 25 #include "psauxerr.h" 26 27 28 /* The following array is used by various functions to quickly convert */ 29 /* digits (both decimal and non-decimal) into numbers. */ 30 31 #if 'A' == 65 32 /* ASCII */ 33 34 static const FT_Char ft_char_table[128] = 35 { 36 /* 0x00 */ 37 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 38 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, 41 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 42 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, 43 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 44 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, 45 }; 46 47 /* no character >= 0x80 can represent a valid number */ 48 #define OP >= 49 50 #endif /* 'A' == 65 */ 51 52 #if 'A' == 193 53 /* EBCDIC */ 54 55 static const FT_Char ft_char_table[128] = 56 { 57 /* 0x80 */ 58 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, 59 -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 60 -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, 61 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1, 63 -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 64 -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, 65 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, 66 }; 67 68 /* no character < 0x80 can represent a valid number */ 69 #define OP < 70 71 #endif /* 'A' == 193 */ 72 73 74 FT_LOCAL_DEF( FT_Int ) PS_Conv_Strtol(FT_Byte ** cursor,FT_Byte * limit,FT_Int base)75 PS_Conv_Strtol( FT_Byte** cursor, 76 FT_Byte* limit, 77 FT_Int base ) 78 { 79 FT_Byte* p = *cursor; 80 FT_Int num = 0; 81 FT_Bool sign = 0; 82 83 84 if ( p == limit || base < 2 || base > 36 ) 85 return 0; 86 87 if ( *p == '-' || *p == '+' ) 88 { 89 sign = FT_BOOL( *p == '-' ); 90 91 p++; 92 if ( p == limit ) 93 return 0; 94 } 95 96 for ( ; p < limit; p++ ) 97 { 98 FT_Char c; 99 100 101 if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) 102 break; 103 104 c = ft_char_table[*p & 0x7f]; 105 106 if ( c < 0 || c >= base ) 107 break; 108 109 num = num * base + c; 110 } 111 112 if ( sign ) 113 num = -num; 114 115 *cursor = p; 116 117 return num; 118 } 119 120 121 FT_LOCAL_DEF( FT_Int ) PS_Conv_ToInt(FT_Byte ** cursor,FT_Byte * limit)122 PS_Conv_ToInt( FT_Byte** cursor, 123 FT_Byte* limit ) 124 125 { 126 FT_Byte* p; 127 FT_Int num; 128 129 130 num = PS_Conv_Strtol( cursor, limit, 10 ); 131 p = *cursor; 132 133 if ( p < limit && *p == '#' ) 134 { 135 *cursor = p + 1; 136 137 return PS_Conv_Strtol( cursor, limit, num ); 138 } 139 else 140 return num; 141 } 142 143 144 FT_LOCAL_DEF( FT_Fixed ) PS_Conv_ToFixed(FT_Byte ** cursor,FT_Byte * limit,FT_Int power_ten)145 PS_Conv_ToFixed( FT_Byte** cursor, 146 FT_Byte* limit, 147 FT_Int power_ten ) 148 { 149 FT_Byte* p = *cursor; 150 FT_Fixed integral; 151 FT_Long decimal = 0, divider = 1; 152 FT_Bool sign = 0; 153 154 155 if ( p == limit ) 156 return 0; 157 158 if ( *p == '-' || *p == '+' ) 159 { 160 sign = FT_BOOL( *p == '-' ); 161 162 p++; 163 if ( p == limit ) 164 return 0; 165 } 166 167 if ( *p != '.' ) 168 integral = PS_Conv_ToInt( &p, limit ) << 16; 169 else 170 integral = 0; 171 172 /* read the decimal part */ 173 if ( p < limit && *p == '.' ) 174 { 175 p++; 176 177 for ( ; p < limit; p++ ) 178 { 179 FT_Char c; 180 181 182 if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) 183 break; 184 185 c = ft_char_table[*p & 0x7f]; 186 187 if ( c < 0 || c >= 10 ) 188 break; 189 190 if ( !integral && power_ten > 0 ) 191 { 192 power_ten--; 193 decimal = decimal * 10 + c; 194 } 195 else 196 { 197 if ( divider < 10000000L ) 198 { 199 decimal = decimal * 10 + c; 200 divider *= 10; 201 } 202 } 203 } 204 } 205 206 /* read exponent, if any */ 207 if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) ) 208 { 209 p++; 210 power_ten += PS_Conv_ToInt( &p, limit ); 211 } 212 213 while ( power_ten > 0 ) 214 { 215 integral *= 10; 216 decimal *= 10; 217 power_ten--; 218 } 219 220 while ( power_ten < 0 ) 221 { 222 integral /= 10; 223 divider *= 10; 224 power_ten++; 225 } 226 227 if ( decimal ) 228 integral += FT_DivFix( decimal, divider ); 229 230 if ( sign ) 231 integral = -integral; 232 233 *cursor = p; 234 235 return integral; 236 } 237 238 239 #if 0 240 FT_LOCAL_DEF( FT_UInt ) 241 PS_Conv_StringDecode( FT_Byte** cursor, 242 FT_Byte* limit, 243 FT_Byte* buffer, 244 FT_UInt n ) 245 { 246 FT_Byte* p; 247 FT_UInt r = 0; 248 249 250 for ( p = *cursor; r < n && p < limit; p++ ) 251 { 252 FT_Byte b; 253 254 255 if ( *p != '\\' ) 256 { 257 buffer[r++] = *p; 258 259 continue; 260 } 261 262 p++; 263 264 switch ( *p ) 265 { 266 case 'n': 267 b = '\n'; 268 break; 269 case 'r': 270 b = '\r'; 271 break; 272 case 't': 273 b = '\t'; 274 break; 275 case 'b': 276 b = '\b'; 277 break; 278 case 'f': 279 b = '\f'; 280 break; 281 case '\r': 282 p++; 283 if ( *p != '\n' ) 284 { 285 b = *p; 286 287 break; 288 } 289 /* no break */ 290 case '\n': 291 continue; 292 break; 293 default: 294 if ( IS_PS_DIGIT( *p ) ) 295 { 296 b = *p - '0'; 297 298 p++; 299 300 if ( IS_PS_DIGIT( *p ) ) 301 { 302 b = b * 8 + *p - '0'; 303 304 p++; 305 306 if ( IS_PS_DIGIT( *p ) ) 307 b = b * 8 + *p - '0'; 308 else 309 { 310 buffer[r++] = b; 311 b = *p; 312 } 313 } 314 else 315 { 316 buffer[r++] = b; 317 b = *p; 318 } 319 } 320 else 321 b = *p; 322 break; 323 } 324 325 buffer[r++] = b; 326 } 327 328 *cursor = p; 329 330 return r; 331 } 332 #endif /* 0 */ 333 334 335 FT_LOCAL_DEF( FT_UInt ) PS_Conv_ASCIIHexDecode(FT_Byte ** cursor,FT_Byte * limit,FT_Byte * buffer,FT_UInt n)336 PS_Conv_ASCIIHexDecode( FT_Byte** cursor, 337 FT_Byte* limit, 338 FT_Byte* buffer, 339 FT_UInt n ) 340 { 341 FT_Byte* p; 342 FT_UInt r = 0; 343 FT_UInt w = 0; 344 FT_UInt pad = 0x01; 345 346 347 n *= 2; 348 349 #if 1 350 351 p = *cursor; 352 if ( n > (FT_UInt)( limit - p ) ) 353 n = (FT_UInt)( limit - p ); 354 355 /* we try to process two nibbles at a time to be as fast as possible */ 356 for ( ; r < n; r++ ) 357 { 358 FT_UInt c = p[r]; 359 360 361 if ( IS_PS_SPACE( c ) ) 362 continue; 363 364 if ( c OP 0x80 ) 365 break; 366 367 c = ft_char_table[c & 0x7F]; 368 if ( (unsigned)c >= 16 ) 369 break; 370 371 pad = ( pad << 4 ) | c; 372 if ( pad & 0x100 ) 373 { 374 buffer[w++] = (FT_Byte)pad; 375 pad = 0x01; 376 } 377 } 378 379 if ( pad != 0x01 ) 380 buffer[w++] = (FT_Byte)( pad << 4 ); 381 382 *cursor = p + r; 383 384 return w; 385 386 #else /* 0 */ 387 388 for ( r = 0; r < n; r++ ) 389 { 390 FT_Char c; 391 392 393 if ( IS_PS_SPACE( *p ) ) 394 continue; 395 396 if ( *p OP 0x80 ) 397 break; 398 399 c = ft_char_table[*p & 0x7f]; 400 401 if ( (unsigned)c >= 16 ) 402 break; 403 404 if ( r & 1 ) 405 { 406 *buffer = (FT_Byte)(*buffer + c); 407 buffer++; 408 } 409 else 410 *buffer = (FT_Byte)(c << 4); 411 412 r++; 413 } 414 415 *cursor = p; 416 417 return ( r + 1 ) / 2; 418 419 #endif /* 0 */ 420 421 } 422 423 424 FT_LOCAL_DEF( FT_UInt ) PS_Conv_EexecDecode(FT_Byte ** cursor,FT_Byte * limit,FT_Byte * buffer,FT_UInt n,FT_UShort * seed)425 PS_Conv_EexecDecode( FT_Byte** cursor, 426 FT_Byte* limit, 427 FT_Byte* buffer, 428 FT_UInt n, 429 FT_UShort* seed ) 430 { 431 FT_Byte* p; 432 FT_UInt r; 433 FT_UInt s = *seed; 434 435 436 #if 1 437 438 p = *cursor; 439 if ( n > (FT_UInt)(limit - p) ) 440 n = (FT_UInt)(limit - p); 441 442 for ( r = 0; r < n; r++ ) 443 { 444 FT_UInt val = p[r]; 445 FT_UInt b = ( val ^ ( s >> 8 ) ); 446 447 448 s = ( (val + s)*52845U + 22719 ) & 0xFFFFU; 449 buffer[r] = (FT_Byte) b; 450 } 451 452 *cursor = p + n; 453 *seed = (FT_UShort)s; 454 455 #else /* 0 */ 456 457 for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ ) 458 { 459 FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) ); 460 461 462 s = (FT_UShort)( ( *p + s ) * 52845U + 22719 ); 463 *buffer++ = b; 464 } 465 *cursor = p; 466 *seed = s; 467 468 #endif /* 0 */ 469 470 return r; 471 } 472 473 474 /* END */ 475