| OLD | NEW |
| 1 /***************************************************************************/ | 1 /***************************************************************************/ |
| 2 /* */ | 2 /* */ |
| 3 /* psconv.c */ | 3 /* psconv.c */ |
| 4 /* */ | 4 /* */ |
| 5 /* Some convenience conversions (body). */ | 5 /* Some convenience conversions (body). */ |
| 6 /* */ | 6 /* */ |
| 7 /* Copyright 2006, 2008, 2009, 2012 by */ | 7 /* Copyright 2006, 2008, 2009, 2012-2013 by */ |
| 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
| 9 /* */ | 9 /* */ |
| 10 /* This file is part of the FreeType project, and may only be used, */ | 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 */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
| 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
| 13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
| 14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
| 15 /* */ | 15 /* */ |
| 16 /***************************************************************************/ | 16 /***************************************************************************/ |
| 17 | 17 |
| 18 | 18 |
| 19 #include <ft2build.h> | 19 #include <ft2build.h> |
| 20 #include FT_INTERNAL_POSTSCRIPT_AUX_H | 20 #include FT_INTERNAL_POSTSCRIPT_AUX_H |
| 21 #include FT_INTERNAL_DEBUG_H |
| 21 | 22 |
| 22 #include "psconv.h" | 23 #include "psconv.h" |
| 23 #include "psauxerr.h" | 24 #include "psauxerr.h" |
| 24 | 25 |
| 25 | 26 |
| 27 /*************************************************************************/ |
| 28 /* */ |
| 29 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
| 30 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
| 31 /* messages during execution. */ |
| 32 /* */ |
| 33 #undef FT_COMPONENT |
| 34 #define FT_COMPONENT trace_psconv |
| 35 |
| 36 |
| 26 /* The following array is used by various functions to quickly convert */ | 37 /* The following array is used by various functions to quickly convert */ |
| 27 /* digits (both decimal and non-decimal) into numbers. */ | 38 /* digits (both decimal and non-decimal) into numbers. */ |
| 28 | 39 |
| 29 #if 'A' == 65 | 40 #if 'A' == 65 |
| 30 /* ASCII */ | 41 /* ASCII */ |
| 31 | 42 |
| 32 static const FT_Char ft_char_table[128] = | 43 static const FT_Char ft_char_table[128] = |
| 33 { | 44 { |
| 34 /* 0x00 */ | 45 /* 0x00 */ |
| 35 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | 46 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 62 -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, | 73 -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, | 74 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, |
| 64 }; | 75 }; |
| 65 | 76 |
| 66 /* no character < 0x80 can represent a valid number */ | 77 /* no character < 0x80 can represent a valid number */ |
| 67 #define OP < | 78 #define OP < |
| 68 | 79 |
| 69 #endif /* 'A' == 193 */ | 80 #endif /* 'A' == 193 */ |
| 70 | 81 |
| 71 | 82 |
| 72 FT_LOCAL_DEF( FT_Int ) | 83 FT_LOCAL_DEF( FT_Long ) |
| 73 PS_Conv_Strtol( FT_Byte** cursor, | 84 PS_Conv_Strtol( FT_Byte** cursor, |
| 74 FT_Byte* limit, | 85 FT_Byte* limit, |
| 75 FT_Int base ) | 86 FT_Long base ) |
| 76 { | 87 { |
| 77 FT_Byte* p = *cursor; | 88 FT_Byte* p = *cursor; |
| 78 FT_Int num = 0; | 89 |
| 79 FT_Bool sign = 0; | 90 FT_Long num = 0; |
| 91 FT_Bool sign = 0; |
| 92 FT_Bool have_overflow = 0; |
| 93 |
| 94 FT_Long num_limit; |
| 95 FT_Char c_limit; |
| 80 | 96 |
| 81 | 97 |
| 82 if ( p >= limit || base < 2 || base > 36 ) | 98 if ( p >= limit ) |
| 99 goto Bad; |
| 100 |
| 101 if ( base < 2 || base > 36 ) |
| 102 { |
| 103 FT_TRACE4(( "!!!INVALID BASE:!!!" )); |
| 83 return 0; | 104 return 0; |
| 105 } |
| 84 | 106 |
| 85 if ( *p == '-' || *p == '+' ) | 107 if ( *p == '-' || *p == '+' ) |
| 86 { | 108 { |
| 87 sign = FT_BOOL( *p == '-' ); | 109 sign = FT_BOOL( *p == '-' ); |
| 88 | 110 |
| 89 p++; | 111 p++; |
| 90 if ( p == limit ) | 112 if ( p == limit ) |
| 91 return 0; | 113 goto Bad; |
| 92 } | 114 } |
| 93 | 115 |
| 116 num_limit = 0x7FFFFFFFL / base; |
| 117 c_limit = (FT_Char)( 0x7FFFFFFFL % base ); |
| 118 |
| 94 for ( ; p < limit; p++ ) | 119 for ( ; p < limit; p++ ) |
| 95 { | 120 { |
| 96 FT_Char c; | 121 FT_Char c; |
| 97 | 122 |
| 98 | 123 |
| 99 if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) | 124 if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) |
| 100 break; | 125 break; |
| 101 | 126 |
| 102 c = ft_char_table[*p & 0x7f]; | 127 c = ft_char_table[*p & 0x7f]; |
| 103 | 128 |
| 104 if ( c < 0 || c >= base ) | 129 if ( c < 0 || c >= base ) |
| 105 break; | 130 break; |
| 106 | 131 |
| 107 num = num * base + c; | 132 if ( num > num_limit || ( num == num_limit && c > c_limit ) ) |
| 133 have_overflow = 1; |
| 134 else |
| 135 num = num * base + c; |
| 136 } |
| 137 |
| 138 *cursor = p; |
| 139 |
| 140 if ( have_overflow ) |
| 141 { |
| 142 num = 0x7FFFFFFFL; |
| 143 FT_TRACE4(( "!!!OVERFLOW:!!!" )); |
| 108 } | 144 } |
| 109 | 145 |
| 110 if ( sign ) | 146 if ( sign ) |
| 111 num = -num; | 147 num = -num; |
| 112 | 148 |
| 149 return num; |
| 150 |
| 151 Bad: |
| 152 FT_TRACE4(( "!!!END OF DATA:!!!" )); |
| 153 return 0; |
| 154 } |
| 155 |
| 156 |
| 157 FT_LOCAL_DEF( FT_Long ) |
| 158 PS_Conv_ToInt( FT_Byte** cursor, |
| 159 FT_Byte* limit ) |
| 160 |
| 161 { |
| 162 FT_Byte* p = *cursor; |
| 163 FT_Byte* curp; |
| 164 |
| 165 FT_Long num; |
| 166 |
| 167 |
| 168 curp = p; |
| 169 num = PS_Conv_Strtol( &p, limit, 10 ); |
| 170 |
| 171 if ( p == curp ) |
| 172 return 0; |
| 173 |
| 174 if ( p < limit && *p == '#' ) |
| 175 { |
| 176 p++; |
| 177 |
| 178 curp = p; |
| 179 num = PS_Conv_Strtol( &p, limit, num ); |
| 180 |
| 181 if ( p == curp ) |
| 182 return 0; |
| 183 } |
| 184 |
| 113 *cursor = p; | 185 *cursor = p; |
| 114 | 186 |
| 115 return num; | 187 return num; |
| 116 } | 188 } |
| 117 | 189 |
| 118 | 190 |
| 119 FT_LOCAL_DEF( FT_Int ) | |
| 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 ) | 191 FT_LOCAL_DEF( FT_Fixed ) |
| 143 PS_Conv_ToFixed( FT_Byte** cursor, | 192 PS_Conv_ToFixed( FT_Byte** cursor, |
| 144 FT_Byte* limit, | 193 FT_Byte* limit, |
| 145 FT_Int power_ten ) | 194 FT_Long power_ten ) |
| 146 { | 195 { |
| 147 FT_Byte* p = *cursor; | 196 FT_Byte* p = *cursor; |
| 148 FT_Fixed integral; | 197 FT_Byte* curp; |
| 149 FT_Long decimal = 0, divider = 1; | 198 |
| 150 FT_Bool sign = 0; | 199 FT_Fixed integral = 0; |
| 200 FT_Long decimal = 0; |
| 201 FT_Long divider = 1; |
| 202 |
| 203 FT_Bool sign = 0; |
| 204 FT_Bool have_overflow = 0; |
| 205 FT_Bool have_underflow = 0; |
| 151 | 206 |
| 152 | 207 |
| 153 if ( p >= limit ) | 208 if ( p >= limit ) |
| 154 return 0; | 209 goto Bad; |
| 155 | 210 |
| 156 if ( *p == '-' || *p == '+' ) | 211 if ( *p == '-' || *p == '+' ) |
| 157 { | 212 { |
| 158 sign = FT_BOOL( *p == '-' ); | 213 sign = FT_BOOL( *p == '-' ); |
| 159 | 214 |
| 160 p++; | 215 p++; |
| 161 if ( p == limit ) | 216 if ( p == limit ) |
| 162 return 0; | 217 goto Bad; |
| 163 } | 218 } |
| 164 | 219 |
| 220 /* read the integer part */ |
| 165 if ( *p != '.' ) | 221 if ( *p != '.' ) |
| 166 integral = PS_Conv_ToInt( &p, limit ) << 16; | 222 { |
| 167 else | 223 curp = p; |
| 168 integral = 0; | 224 integral = PS_Conv_ToInt( &p, limit ); |
| 225 |
| 226 if ( p == curp ) |
| 227 return 0; |
| 228 |
| 229 if ( integral > 0x7FFF ) |
| 230 have_overflow = 1; |
| 231 else |
| 232 integral = (FT_Fixed)( (FT_UInt32)integral << 16 ); |
| 233 } |
| 169 | 234 |
| 170 /* read the decimal part */ | 235 /* read the decimal part */ |
| 171 if ( p < limit && *p == '.' ) | 236 if ( p < limit && *p == '.' ) |
| 172 { | 237 { |
| 173 p++; | 238 p++; |
| 174 | 239 |
| 175 for ( ; p < limit; p++ ) | 240 for ( ; p < limit; p++ ) |
| 176 { | 241 { |
| 177 FT_Char c; | 242 FT_Char c; |
| 178 | 243 |
| 179 | 244 |
| 180 if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) | 245 if ( IS_PS_SPACE( *p ) || *p OP 0x80 ) |
| 181 break; | 246 break; |
| 182 | 247 |
| 183 c = ft_char_table[*p & 0x7f]; | 248 c = ft_char_table[*p & 0x7f]; |
| 184 | 249 |
| 185 if ( c < 0 || c >= 10 ) | 250 if ( c < 0 || c >= 10 ) |
| 186 break; | 251 break; |
| 187 | 252 |
| 188 if ( !integral && power_ten > 0 ) | 253 if ( decimal < 0xCCCCCCCL ) |
| 189 { | 254 { |
| 190 power_ten--; | |
| 191 decimal = decimal * 10 + c; | 255 decimal = decimal * 10 + c; |
| 192 } | 256 |
| 193 else | 257 if ( !integral && power_ten > 0 ) |
| 194 { | 258 power_ten--; |
| 195 if ( divider < 10000000L ) | 259 else |
| 196 { | |
| 197 decimal = decimal * 10 + c; | |
| 198 divider *= 10; | 260 divider *= 10; |
| 199 } | |
| 200 } | 261 } |
| 201 } | 262 } |
| 202 } | 263 } |
| 203 | 264 |
| 204 /* read exponent, if any */ | 265 /* read exponent, if any */ |
| 205 if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) ) | 266 if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) ) |
| 206 { | 267 { |
| 268 FT_Long exponent; |
| 269 |
| 270 |
| 207 p++; | 271 p++; |
| 208 power_ten += PS_Conv_ToInt( &p, limit ); | 272 |
| 273 curp = p; |
| 274 exponent = PS_Conv_ToInt( &p, limit ); |
| 275 |
| 276 if ( curp == p ) |
| 277 return 0; |
| 278 |
| 279 /* arbitrarily limit exponent */ |
| 280 if ( exponent > 1000 ) |
| 281 have_overflow = 1; |
| 282 else if ( exponent < -1000 ) |
| 283 have_underflow = 1; |
| 284 else |
| 285 power_ten += exponent; |
| 209 } | 286 } |
| 210 | 287 |
| 288 *cursor = p; |
| 289 |
| 290 if ( !integral && !decimal ) |
| 291 return 0; |
| 292 |
| 293 if ( have_overflow ) |
| 294 goto Overflow; |
| 295 if ( have_underflow ) |
| 296 goto Underflow; |
| 297 |
| 211 while ( power_ten > 0 ) | 298 while ( power_ten > 0 ) |
| 212 { | 299 { |
| 300 if ( integral >= 0xCCCCCCCL ) |
| 301 goto Overflow; |
| 213 integral *= 10; | 302 integral *= 10; |
| 214 decimal *= 10; | 303 |
| 304 if ( decimal >= 0xCCCCCCCL ) |
| 305 { |
| 306 if ( divider == 1 ) |
| 307 goto Overflow; |
| 308 divider /= 10; |
| 309 } |
| 310 else |
| 311 decimal *= 10; |
| 312 |
| 215 power_ten--; | 313 power_ten--; |
| 216 } | 314 } |
| 217 | 315 |
| 218 while ( power_ten < 0 ) | 316 while ( power_ten < 0 ) |
| 219 { | 317 { |
| 220 integral /= 10; | 318 integral /= 10; |
| 221 divider *= 10; | 319 if ( divider < 0xCCCCCCCL ) |
| 320 divider *= 10; |
| 321 else |
| 322 decimal /= 10; |
| 323 |
| 324 if ( !integral && !decimal ) |
| 325 goto Underflow; |
| 326 |
| 222 power_ten++; | 327 power_ten++; |
| 223 } | 328 } |
| 224 | 329 |
| 225 if ( decimal ) | 330 if ( decimal ) |
| 226 integral += FT_DivFix( decimal, divider ); | 331 { |
| 332 decimal = FT_DivFix( decimal, divider ); |
| 333 /* it's not necessary to check this addition for overflow */ |
| 334 /* due to the structure of the real number representation */ |
| 335 integral += decimal; |
| 336 } |
| 227 | 337 |
| 338 Exit: |
| 228 if ( sign ) | 339 if ( sign ) |
| 229 integral = -integral; | 340 integral = -integral; |
| 230 | 341 |
| 231 *cursor = p; | 342 return integral; |
| 232 | 343 |
| 233 return integral; | 344 Bad: |
| 345 FT_TRACE4(( "!!!END OF DATA:!!!" )); |
| 346 return 0; |
| 347 |
| 348 Overflow: |
| 349 integral = 0x7FFFFFFFL; |
| 350 FT_TRACE4(( "!!!OVERFLOW:!!!" )); |
| 351 goto Exit; |
| 352 |
| 353 Underflow: |
| 354 FT_TRACE4(( "!!!UNDERFLOW:!!!" )); |
| 355 return 0; |
| 234 } | 356 } |
| 235 | 357 |
| 236 | 358 |
| 237 #if 0 | 359 #if 0 |
| 238 FT_LOCAL_DEF( FT_UInt ) | 360 FT_LOCAL_DEF( FT_UInt ) |
| 239 PS_Conv_StringDecode( FT_Byte** cursor, | 361 PS_Conv_StringDecode( FT_Byte** cursor, |
| 240 FT_Byte* limit, | 362 FT_Byte* limit, |
| 241 FT_Byte* buffer, | 363 FT_Byte* buffer, |
| 242 FT_Offset n ) | 364 FT_Offset n ) |
| 243 { | 365 { |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 *cursor = p; | 593 *cursor = p; |
| 472 *seed = s; | 594 *seed = s; |
| 473 | 595 |
| 474 #endif /* 0 */ | 596 #endif /* 0 */ |
| 475 | 597 |
| 476 return r; | 598 return r; |
| 477 } | 599 } |
| 478 | 600 |
| 479 | 601 |
| 480 /* END */ | 602 /* END */ |
| OLD | NEW |