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