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 |