OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ftcalc.c */ | 3 /* ftcalc.c */ |
4 /* */ | 4 /* */ |
5 /* Arithmetic computations (body). */ | 5 /* Arithmetic computations (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 1996-2006, 2008, 2012-2014 by */ | 7 /* Copyright 1996-2015 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 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 FT_END_STMNT | 79 FT_END_STMNT |
80 | 80 |
81 /* The following three functions are available regardless of whether */ | 81 /* The following three functions are available regardless of whether */ |
82 /* FT_LONG64 is defined. */ | 82 /* FT_LONG64 is defined. */ |
83 | 83 |
84 /* documentation is in freetype.h */ | 84 /* documentation is in freetype.h */ |
85 | 85 |
86 FT_EXPORT_DEF( FT_Fixed ) | 86 FT_EXPORT_DEF( FT_Fixed ) |
87 FT_RoundFix( FT_Fixed a ) | 87 FT_RoundFix( FT_Fixed a ) |
88 { | 88 { |
89 return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL | 89 return ( a + 0x8000L - ( a < 0 ) ) & ~0xFFFFL; |
90 : -((-a + 0x8000L ) & ~0xFFFFL ); | |
91 } | 90 } |
92 | 91 |
93 | 92 |
94 /* documentation is in freetype.h */ | 93 /* documentation is in freetype.h */ |
95 | 94 |
96 FT_EXPORT_DEF( FT_Fixed ) | 95 FT_EXPORT_DEF( FT_Fixed ) |
97 FT_CeilFix( FT_Fixed a ) | 96 FT_CeilFix( FT_Fixed a ) |
98 { | 97 { |
99 return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL | 98 return ( a + 0xFFFFL ) & ~0xFFFFL; |
100 : -((-a + 0xFFFFL ) & ~0xFFFFL ); | |
101 } | 99 } |
102 | 100 |
103 | 101 |
104 /* documentation is in freetype.h */ | 102 /* documentation is in freetype.h */ |
105 | 103 |
106 FT_EXPORT_DEF( FT_Fixed ) | 104 FT_EXPORT_DEF( FT_Fixed ) |
107 FT_FloorFix( FT_Fixed a ) | 105 FT_FloorFix( FT_Fixed a ) |
108 { | 106 { |
109 return ( a >= 0 ) ? a & ~0xFFFFL | 107 return a & ~0xFFFFL; |
110 : -((-a) & ~0xFFFFL ); | |
111 } | 108 } |
112 | 109 |
113 #ifndef FT_MSB | 110 #ifndef FT_MSB |
114 | 111 |
115 FT_BASE_DEF ( FT_Int ) | 112 FT_BASE_DEF ( FT_Int ) |
116 FT_MSB( FT_UInt32 z ) | 113 FT_MSB( FT_UInt32 z ) |
117 { | 114 { |
118 FT_Int shift = 0; | 115 FT_Int shift = 0; |
| 116 |
119 | 117 |
120 /* determine msb bit index in `shift' */ | 118 /* determine msb bit index in `shift' */ |
121 if ( z & 0xFFFF0000U ) | 119 if ( z & 0xFFFF0000UL ) |
122 { | 120 { |
123 z >>= 16; | 121 z >>= 16; |
124 shift += 16; | 122 shift += 16; |
125 } | 123 } |
126 if ( z & 0x0000FF00U ) | 124 if ( z & 0x0000FF00UL ) |
127 { | 125 { |
128 z >>= 8; | 126 z >>= 8; |
129 shift += 8; | 127 shift += 8; |
130 } | 128 } |
131 if ( z & 0x000000F0U ) | 129 if ( z & 0x000000F0UL ) |
132 { | 130 { |
133 z >>= 4; | 131 z >>= 4; |
134 shift += 4; | 132 shift += 4; |
135 } | 133 } |
136 if ( z & 0x0000000CU ) | 134 if ( z & 0x0000000CUL ) |
137 { | 135 { |
138 z >>= 2; | 136 z >>= 2; |
139 shift += 2; | 137 shift += 2; |
140 } | 138 } |
141 if ( z & 0x00000002U ) | 139 if ( z & 0x00000002UL ) |
142 { | 140 { |
143 /* z >>= 1; */ | 141 /* z >>= 1; */ |
144 shift += 1; | 142 shift += 1; |
145 } | 143 } |
146 | 144 |
147 return shift; | 145 return shift; |
148 } | 146 } |
149 | 147 |
150 #endif /* !FT_MSB */ | 148 #endif /* !FT_MSB */ |
151 | 149 |
(...skipping 13 matching lines...) Expand all Loading... |
165 return FT_Vector_Length( &v ); | 163 return FT_Vector_Length( &v ); |
166 } | 164 } |
167 | 165 |
168 | 166 |
169 #ifdef FT_LONG64 | 167 #ifdef FT_LONG64 |
170 | 168 |
171 | 169 |
172 /* documentation is in freetype.h */ | 170 /* documentation is in freetype.h */ |
173 | 171 |
174 FT_EXPORT_DEF( FT_Long ) | 172 FT_EXPORT_DEF( FT_Long ) |
175 FT_MulDiv( FT_Long a, | 173 FT_MulDiv( FT_Long a_, |
176 FT_Long b, | 174 FT_Long b_, |
177 FT_Long c ) | 175 FT_Long c_ ) |
178 { | 176 { |
179 FT_Int s = 1; | 177 FT_Int s = 1; |
180 FT_Long d; | 178 FT_UInt64 a, b, c, d; |
| 179 FT_Long d_; |
181 | 180 |
182 | 181 |
183 FT_MOVE_SIGN( a, s ); | 182 FT_MOVE_SIGN( a_, s ); |
184 FT_MOVE_SIGN( b, s ); | 183 FT_MOVE_SIGN( b_, s ); |
185 FT_MOVE_SIGN( c, s ); | 184 FT_MOVE_SIGN( c_, s ); |
186 | 185 |
187 d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c | 186 a = (FT_UInt64)a_; |
188 : 0x7FFFFFFFL ); | 187 b = (FT_UInt64)b_; |
| 188 c = (FT_UInt64)c_; |
189 | 189 |
190 return ( s > 0 ) ? d : -d; | 190 d = c > 0 ? ( a * b + ( c >> 1 ) ) / c |
| 191 : 0x7FFFFFFFUL; |
| 192 |
| 193 d_ = (FT_Long)d; |
| 194 |
| 195 return s < 0 ? -d_ : d_; |
191 } | 196 } |
192 | 197 |
193 | 198 |
194 /* documentation is in ftcalc.h */ | 199 /* documentation is in ftcalc.h */ |
195 | 200 |
196 FT_BASE_DEF( FT_Long ) | 201 FT_BASE_DEF( FT_Long ) |
197 FT_MulDiv_No_Round( FT_Long a, | 202 FT_MulDiv_No_Round( FT_Long a_, |
198 FT_Long b, | 203 FT_Long b_, |
199 FT_Long c ) | 204 FT_Long c_ ) |
200 { | 205 { |
201 FT_Int s = 1; | 206 FT_Int s = 1; |
202 FT_Long d; | 207 FT_UInt64 a, b, c, d; |
| 208 FT_Long d_; |
203 | 209 |
204 | 210 |
205 FT_MOVE_SIGN( a, s ); | 211 FT_MOVE_SIGN( a_, s ); |
206 FT_MOVE_SIGN( b, s ); | 212 FT_MOVE_SIGN( b_, s ); |
207 FT_MOVE_SIGN( c, s ); | 213 FT_MOVE_SIGN( c_, s ); |
208 | 214 |
209 d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c | 215 a = (FT_UInt64)a_; |
210 : 0x7FFFFFFFL ); | 216 b = (FT_UInt64)b_; |
| 217 c = (FT_UInt64)c_; |
211 | 218 |
212 return ( s > 0 ) ? d : -d; | 219 d = c > 0 ? a * b / c |
| 220 : 0x7FFFFFFFUL; |
| 221 |
| 222 d_ = (FT_Long)d; |
| 223 |
| 224 return s < 0 ? -d_ : d_; |
213 } | 225 } |
214 | 226 |
215 | 227 |
216 /* documentation is in freetype.h */ | 228 /* documentation is in freetype.h */ |
217 | 229 |
218 FT_EXPORT_DEF( FT_Long ) | 230 FT_EXPORT_DEF( FT_Long ) |
219 FT_MulFix( FT_Long a, | 231 FT_MulFix( FT_Long a_, |
220 FT_Long b ) | 232 FT_Long b_ ) |
221 { | 233 { |
222 #ifdef FT_MULFIX_ASSEMBLER | 234 #ifdef FT_MULFIX_ASSEMBLER |
223 | 235 |
224 return FT_MULFIX_ASSEMBLER( a, b ); | 236 return FT_MULFIX_ASSEMBLER( a_, b_ ); |
225 | 237 |
226 #else | 238 #else |
227 | 239 |
228 FT_Int s = 1; | 240 FT_Int64 ab = (FT_Int64)a_ * (FT_Int64)b_; |
229 FT_Long c; | |
230 | 241 |
231 | 242 /* this requires arithmetic right shift of signed numbers */ |
232 FT_MOVE_SIGN( a, s ); | 243 return (FT_Long)( ( ab + 0x8000L - ( ab < 0 ) ) >> 16 ); |
233 FT_MOVE_SIGN( b, s ); | |
234 | |
235 c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); | |
236 | |
237 return ( s > 0 ) ? c : -c; | |
238 | 244 |
239 #endif /* FT_MULFIX_ASSEMBLER */ | 245 #endif /* FT_MULFIX_ASSEMBLER */ |
240 } | 246 } |
241 | 247 |
242 | 248 |
243 /* documentation is in freetype.h */ | 249 /* documentation is in freetype.h */ |
244 | 250 |
245 FT_EXPORT_DEF( FT_Long ) | 251 FT_EXPORT_DEF( FT_Long ) |
246 FT_DivFix( FT_Long a, | 252 FT_DivFix( FT_Long a_, |
247 FT_Long b ) | 253 FT_Long b_ ) |
248 { | 254 { |
249 FT_Int s = 1; | 255 FT_Int s = 1; |
250 FT_Long q; | 256 FT_UInt64 a, b, q; |
| 257 FT_Long q_; |
251 | 258 |
252 | 259 |
253 FT_MOVE_SIGN( a, s ); | 260 FT_MOVE_SIGN( a_, s ); |
254 FT_MOVE_SIGN( b, s ); | 261 FT_MOVE_SIGN( b_, s ); |
255 | 262 |
256 q = (FT_Long)( b > 0 ? ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b | 263 a = (FT_UInt64)a_; |
257 : 0x7FFFFFFFL ); | 264 b = (FT_UInt64)b_; |
258 | 265 |
259 return ( s < 0 ? -q : q ); | 266 q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b |
| 267 : 0x7FFFFFFFUL; |
| 268 |
| 269 q_ = (FT_Long)q; |
| 270 |
| 271 return s < 0 ? -q_ : q_; |
260 } | 272 } |
261 | 273 |
262 | 274 |
263 #else /* !FT_LONG64 */ | 275 #else /* !FT_LONG64 */ |
264 | 276 |
265 | 277 |
266 static void | 278 static void |
267 ft_multo64( FT_UInt32 x, | 279 ft_multo64( FT_UInt32 x, |
268 FT_UInt32 y, | 280 FT_UInt32 y, |
269 FT_Int64 *z ) | 281 FT_Int64 *z ) |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 /* */ | 405 /* */ |
394 /* a << 16 <= X - c/2 */ | 406 /* a << 16 <= X - c/2 */ |
395 /* */ | 407 /* */ |
396 /* is scaled down by 2^16 and we use */ | 408 /* is scaled down by 2^16 and we use */ |
397 /* */ | 409 /* */ |
398 /* a <= 65535 - (c >> 17) . */ | 410 /* a <= 65535 - (c >> 17) . */ |
399 | 411 |
400 /* documentation is in freetype.h */ | 412 /* documentation is in freetype.h */ |
401 | 413 |
402 FT_EXPORT_DEF( FT_Long ) | 414 FT_EXPORT_DEF( FT_Long ) |
403 FT_MulDiv( FT_Long a, | 415 FT_MulDiv( FT_Long a_, |
404 FT_Long b, | 416 FT_Long b_, |
405 FT_Long c ) | 417 FT_Long c_ ) |
406 { | 418 { |
407 FT_Int s = 1; | 419 FT_Int s = 1; |
| 420 FT_UInt32 a, b, c; |
408 | 421 |
409 | 422 |
410 /* XXX: this function does not allow 64-bit arguments */ | 423 /* XXX: this function does not allow 64-bit arguments */ |
411 if ( a == 0 || b == c ) | |
412 return a; | |
413 | 424 |
414 FT_MOVE_SIGN( a, s ); | 425 FT_MOVE_SIGN( a_, s ); |
415 FT_MOVE_SIGN( b, s ); | 426 FT_MOVE_SIGN( b_, s ); |
416 FT_MOVE_SIGN( c, s ); | 427 FT_MOVE_SIGN( c_, s ); |
| 428 |
| 429 a = (FT_UInt32)a_; |
| 430 b = (FT_UInt32)b_; |
| 431 c = (FT_UInt32)c_; |
417 | 432 |
418 if ( c == 0 ) | 433 if ( c == 0 ) |
419 a = 0x7FFFFFFFL; | 434 a = 0x7FFFFFFFUL; |
420 | 435 |
421 else if ( (FT_ULong)a + b <= 129894UL - ( c >> 17 ) ) | 436 else if ( a + b <= 129894UL - ( c >> 17 ) ) |
422 a = ( (FT_ULong)a * b + ( c >> 1 ) ) / c; | 437 a = ( a * b + ( c >> 1 ) ) / c; |
423 | 438 |
424 else | 439 else |
425 { | 440 { |
426 FT_Int64 temp, temp2; | 441 FT_Int64 temp, temp2; |
427 | 442 |
428 | 443 |
429 ft_multo64( a, b, &temp ); | 444 ft_multo64( a, b, &temp ); |
430 | 445 |
431 temp2.hi = 0; | 446 temp2.hi = 0; |
432 temp2.lo = c >> 1; | 447 temp2.lo = c >> 1; |
433 | 448 |
434 FT_Add64( &temp, &temp2, &temp ); | 449 FT_Add64( &temp, &temp2, &temp ); |
435 | 450 |
436 /* last attempt to ditch long division */ | 451 /* last attempt to ditch long division */ |
437 a = temp.hi == 0 ? temp.lo / c | 452 a = temp.hi == 0 ? temp.lo / c |
438 : ft_div64by32( temp.hi, temp.lo, c ); | 453 : ft_div64by32( temp.hi, temp.lo, c ); |
439 } | 454 } |
440 | 455 |
441 return ( s < 0 ? -a : a ); | 456 a_ = (FT_Long)a; |
| 457 |
| 458 return s < 0 ? -a_ : a_; |
442 } | 459 } |
443 | 460 |
444 | 461 |
445 FT_BASE_DEF( FT_Long ) | 462 FT_BASE_DEF( FT_Long ) |
446 FT_MulDiv_No_Round( FT_Long a, | 463 FT_MulDiv_No_Round( FT_Long a_, |
447 FT_Long b, | 464 FT_Long b_, |
448 FT_Long c ) | 465 FT_Long c_ ) |
449 { | 466 { |
450 FT_Int s = 1; | 467 FT_Int s = 1; |
| 468 FT_UInt32 a, b, c; |
451 | 469 |
452 | 470 |
453 if ( a == 0 || b == c ) | 471 /* XXX: this function does not allow 64-bit arguments */ |
454 return a; | |
455 | 472 |
456 FT_MOVE_SIGN( a, s ); | 473 FT_MOVE_SIGN( a_, s ); |
457 FT_MOVE_SIGN( b, s ); | 474 FT_MOVE_SIGN( b_, s ); |
458 FT_MOVE_SIGN( c, s ); | 475 FT_MOVE_SIGN( c_, s ); |
| 476 |
| 477 a = (FT_UInt32)a_; |
| 478 b = (FT_UInt32)b_; |
| 479 c = (FT_UInt32)c_; |
459 | 480 |
460 if ( c == 0 ) | 481 if ( c == 0 ) |
461 a = 0x7FFFFFFFL; | 482 a = 0x7FFFFFFFUL; |
462 | 483 |
463 else if ( (FT_ULong)a + b <= 131071UL ) | 484 else if ( a + b <= 131071UL ) |
464 a = (FT_ULong)a * b / c; | 485 a = a * b / c; |
465 | 486 |
466 else | 487 else |
467 { | 488 { |
468 FT_Int64 temp; | 489 FT_Int64 temp; |
469 | 490 |
470 | 491 |
471 ft_multo64( a, b, &temp ); | 492 ft_multo64( a, b, &temp ); |
472 | 493 |
473 /* last attempt to ditch long division */ | 494 /* last attempt to ditch long division */ |
474 a = temp.hi == 0 ? temp.lo / c | 495 a = temp.hi == 0 ? temp.lo / c |
475 : ft_div64by32( temp.hi, temp.lo, c ); | 496 : ft_div64by32( temp.hi, temp.lo, c ); |
476 } | 497 } |
477 | 498 |
478 return ( s < 0 ? -a : a ); | 499 a_ = (FT_Long)a; |
| 500 |
| 501 return s < 0 ? -a_ : a_; |
479 } | 502 } |
480 | 503 |
481 | 504 |
482 /* documentation is in freetype.h */ | 505 /* documentation is in freetype.h */ |
483 | 506 |
484 FT_EXPORT_DEF( FT_Long ) | 507 FT_EXPORT_DEF( FT_Long ) |
485 FT_MulFix( FT_Long a, | 508 FT_MulFix( FT_Long a_, |
486 FT_Long b ) | 509 FT_Long b_ ) |
487 { | 510 { |
488 #ifdef FT_MULFIX_ASSEMBLER | 511 #ifdef FT_MULFIX_ASSEMBLER |
489 | 512 |
490 return FT_MULFIX_ASSEMBLER( a, b ); | 513 return FT_MULFIX_ASSEMBLER( a_, b_ ); |
491 | 514 |
492 #elif 0 | 515 #elif 0 |
493 | 516 |
494 /* | 517 /* |
495 * This code is nonportable. See comment below. | 518 * This code is nonportable. See comment below. |
496 * | 519 * |
497 * However, on a platform where right-shift of a signed quantity fills | 520 * However, on a platform where right-shift of a signed quantity fills |
498 * the leftmost bits by copying the sign bit, it might be faster. | 521 * the leftmost bits by copying the sign bit, it might be faster. |
499 */ | 522 */ |
500 | 523 |
501 FT_Long sa, sb; | 524 FT_Long sa, sb; |
502 FT_ULong ua, ub; | 525 FT_UInt32 a, b; |
503 | 526 |
504 | 527 |
505 if ( a == 0 || b == 0x10000L ) | |
506 return a; | |
507 | |
508 /* | 528 /* |
509 * This is a clever way of converting a signed number `a' into its | 529 * This is a clever way of converting a signed number `a' into its |
510 * absolute value (stored back into `a') and its sign. The sign is | 530 * absolute value (stored back into `a') and its sign. The sign is |
511 * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' | 531 * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' |
512 * was negative. (Similarly for `b' and `sb'). | 532 * was negative. (Similarly for `b' and `sb'). |
513 * | 533 * |
514 * Unfortunately, it doesn't work (at least not portably). | 534 * Unfortunately, it doesn't work (at least not portably). |
515 * | 535 * |
516 * It makes the assumption that right-shift on a negative signed value | 536 * It makes the assumption that right-shift on a negative signed value |
517 * fills the leftmost bits by copying the sign bit. This is wrong. | 537 * fills the leftmost bits by copying the sign bit. This is wrong. |
518 * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, | 538 * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, |
519 * the result of right-shift of a negative signed value is | 539 * the result of right-shift of a negative signed value is |
520 * implementation-defined. At least one implementation fills the | 540 * implementation-defined. At least one implementation fills the |
521 * leftmost bits with 0s (i.e., it is exactly the same as an unsigned | 541 * leftmost bits with 0s (i.e., it is exactly the same as an unsigned |
522 * right shift). This means that when `a' is negative, `sa' ends up | 542 * right shift). This means that when `a' is negative, `sa' ends up |
523 * with the value 1 rather than -1. After that, everything else goes | 543 * with the value 1 rather than -1. After that, everything else goes |
524 * wrong. | 544 * wrong. |
525 */ | 545 */ |
526 sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); | 546 sa = ( a_ >> ( sizeof ( a_ ) * 8 - 1 ) ); |
527 a = ( a ^ sa ) - sa; | 547 a = ( a_ ^ sa ) - sa; |
528 sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); | 548 sb = ( b_ >> ( sizeof ( b_ ) * 8 - 1 ) ); |
529 b = ( b ^ sb ) - sb; | 549 b = ( b_ ^ sb ) - sb; |
530 | 550 |
531 ua = (FT_ULong)a; | 551 a = (FT_UInt32)a_; |
532 ub = (FT_ULong)b; | 552 b = (FT_UInt32)b_; |
533 | 553 |
534 if ( ua + ( ub >> 8 ) <= 8190UL ) | 554 if ( a + ( b >> 8 ) <= 8190UL ) |
535 ua = ( ua * ub + 0x8000U ) >> 16; | 555 a = ( a * b + 0x8000U ) >> 16; |
536 else | 556 else |
537 { | 557 { |
538 FT_ULong al = ua & 0xFFFFU; | 558 FT_UInt32 al = a & 0xFFFFUL; |
539 | 559 |
540 | 560 |
541 ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + | 561 a = ( a >> 16 ) * b + al * ( b >> 16 ) + |
542 ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); | 562 ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 ); |
543 } | 563 } |
544 | 564 |
545 sa ^= sb, | 565 sa ^= sb; |
546 ua = (FT_ULong)(( ua ^ sa ) - sa); | 566 a = ( a ^ sa ) - sa; |
547 | 567 |
548 return (FT_Long)ua; | 568 return (FT_Long)a; |
549 | 569 |
550 #else /* 0 */ | 570 #else /* 0 */ |
551 | 571 |
552 FT_Int s = 1; | 572 FT_Int s = 1; |
553 FT_ULong ua, ub; | 573 FT_UInt32 a, b; |
554 | 574 |
555 | 575 |
556 if ( a == 0 || b == 0x10000L ) | 576 /* XXX: this function does not allow 64-bit arguments */ |
557 return a; | |
558 | 577 |
559 FT_MOVE_SIGN( a, s ); | 578 FT_MOVE_SIGN( a_, s ); |
560 FT_MOVE_SIGN( b, s ); | 579 FT_MOVE_SIGN( b_, s ); |
561 | 580 |
562 ua = (FT_ULong)a; | 581 a = (FT_UInt32)a_; |
563 ub = (FT_ULong)b; | 582 b = (FT_UInt32)b_; |
564 | 583 |
565 if ( ua + ( ub >> 8 ) <= 8190UL ) | 584 if ( a + ( b >> 8 ) <= 8190UL ) |
566 ua = ( ua * ub + 0x8000UL ) >> 16; | 585 a = ( a * b + 0x8000UL ) >> 16; |
567 else | 586 else |
568 { | 587 { |
569 FT_ULong al = ua & 0xFFFFUL; | 588 FT_UInt32 al = a & 0xFFFFUL; |
570 | 589 |
571 | 590 |
572 ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + | 591 a = ( a >> 16 ) * b + al * ( b >> 16 ) + |
573 ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); | 592 ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 ); |
574 } | 593 } |
575 | 594 |
576 return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); | 595 a_ = (FT_Long)a; |
| 596 |
| 597 return s < 0 ? -a_ : a_; |
577 | 598 |
578 #endif /* 0 */ | 599 #endif /* 0 */ |
579 | 600 |
580 } | 601 } |
581 | 602 |
582 | 603 |
583 /* documentation is in freetype.h */ | 604 /* documentation is in freetype.h */ |
584 | 605 |
585 FT_EXPORT_DEF( FT_Long ) | 606 FT_EXPORT_DEF( FT_Long ) |
586 FT_DivFix( FT_Long a, | 607 FT_DivFix( FT_Long a_, |
587 FT_Long b ) | 608 FT_Long b_ ) |
588 { | 609 { |
589 FT_Int s = 1; | 610 FT_Int s = 1; |
590 FT_Long q; | 611 FT_UInt32 a, b, q; |
| 612 FT_Long q_; |
591 | 613 |
592 | 614 |
593 /* XXX: this function does not allow 64-bit arguments */ | 615 /* XXX: this function does not allow 64-bit arguments */ |
594 | 616 |
595 FT_MOVE_SIGN( a, s ); | 617 FT_MOVE_SIGN( a_, s ); |
596 FT_MOVE_SIGN( b, s ); | 618 FT_MOVE_SIGN( b_, s ); |
| 619 |
| 620 a = (FT_UInt32)a_; |
| 621 b = (FT_UInt32)b_; |
597 | 622 |
598 if ( b == 0 ) | 623 if ( b == 0 ) |
599 { | 624 { |
600 /* check for division by 0 */ | 625 /* check for division by 0 */ |
601 q = 0x7FFFFFFFL; | 626 q = 0x7FFFFFFFUL; |
602 } | 627 } |
603 else if ( a <= 65535L - ( b >> 17 ) ) | 628 else if ( a <= 65535UL - ( b >> 17 ) ) |
604 { | 629 { |
605 /* compute result directly */ | 630 /* compute result directly */ |
606 q = (FT_Long)( ( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / b ); | 631 q = ( ( a << 16 ) + ( b >> 1 ) ) / b; |
607 } | 632 } |
608 else | 633 else |
609 { | 634 { |
610 /* we need more bits; we have to do it by hand */ | 635 /* we need more bits; we have to do it by hand */ |
611 FT_Int64 temp, temp2; | 636 FT_Int64 temp, temp2; |
612 | 637 |
613 | 638 |
614 temp.hi = a >> 16; | 639 temp.hi = a >> 16; |
615 temp.lo = a << 16; | 640 temp.lo = a << 16; |
616 temp2.hi = 0; | 641 temp2.hi = 0; |
617 temp2.lo = b >> 1; | 642 temp2.lo = b >> 1; |
618 | 643 |
619 FT_Add64( &temp, &temp2, &temp ); | 644 FT_Add64( &temp, &temp2, &temp ); |
620 q = (FT_Long)ft_div64by32( temp.hi, temp.lo, b ); | 645 q = ft_div64by32( temp.hi, temp.lo, b ); |
621 } | 646 } |
622 | 647 |
623 return ( s < 0 ? -q : q ); | 648 q_ = (FT_Long)q; |
| 649 |
| 650 return s < 0 ? -q_ : q_; |
624 } | 651 } |
625 | 652 |
626 | 653 |
627 #endif /* FT_LONG64 */ | 654 #endif /* !FT_LONG64 */ |
628 | 655 |
629 | 656 |
630 /* documentation is in ftglyph.h */ | 657 /* documentation is in ftglyph.h */ |
631 | 658 |
632 FT_EXPORT_DEF( void ) | 659 FT_EXPORT_DEF( void ) |
633 FT_Matrix_Multiply( const FT_Matrix* a, | 660 FT_Matrix_Multiply( const FT_Matrix* a, |
634 FT_Matrix *b ) | 661 FT_Matrix *b ) |
635 { | 662 { |
636 FT_Fixed xx, xy, yx, yy; | 663 FT_Fixed xx, xy, yx, yy; |
637 | 664 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 FT_MulDiv( vector->y, matrix->xy, val ); | 751 FT_MulDiv( vector->y, matrix->xy, val ); |
725 | 752 |
726 yz = FT_MulDiv( vector->x, matrix->yx, val ) + | 753 yz = FT_MulDiv( vector->x, matrix->yx, val ) + |
727 FT_MulDiv( vector->y, matrix->yy, val ); | 754 FT_MulDiv( vector->y, matrix->yy, val ); |
728 | 755 |
729 vector->x = xz; | 756 vector->x = xz; |
730 vector->y = yz; | 757 vector->y = yz; |
731 } | 758 } |
732 | 759 |
733 | 760 |
| 761 /* documentation is in ftcalc.h */ |
| 762 |
| 763 FT_BASE_DEF( FT_UInt32 ) |
| 764 FT_Vector_NormLen( FT_Vector* vector ) |
| 765 { |
| 766 FT_Int32 x_ = vector->x; |
| 767 FT_Int32 y_ = vector->y; |
| 768 FT_Int32 b, z; |
| 769 FT_UInt32 x, y, u, v, l; |
| 770 FT_Int sx = 1, sy = 1, shift; |
| 771 |
| 772 |
| 773 FT_MOVE_SIGN( x_, sx ); |
| 774 FT_MOVE_SIGN( y_, sy ); |
| 775 |
| 776 x = (FT_UInt32)x_; |
| 777 y = (FT_UInt32)y_; |
| 778 |
| 779 /* trivial cases */ |
| 780 if ( x == 0 ) |
| 781 { |
| 782 if ( y > 0 ) |
| 783 vector->y = sy * 0x10000; |
| 784 return y; |
| 785 } |
| 786 else if ( y == 0 ) |
| 787 { |
| 788 if ( x > 0 ) |
| 789 vector->x = sx * 0x10000; |
| 790 return x; |
| 791 } |
| 792 |
| 793 /* Estimate length and prenormalize by shifting so that */ |
| 794 /* the new approximate length is between 2/3 and 4/3. */ |
| 795 /* The magic constant 0xAAAAAAAAUL (2/3 of 2^32) helps */ |
| 796 /* achieve this in 16.16 fixed-point representation. */ |
| 797 l = x > y ? x + ( y >> 1 ) |
| 798 : y + ( x >> 1 ); |
| 799 |
| 800 shift = 31 - FT_MSB( l ); |
| 801 shift -= 15 + ( l >= ( 0xAAAAAAAAUL >> shift ) ); |
| 802 |
| 803 if ( shift > 0 ) |
| 804 { |
| 805 x <<= shift; |
| 806 y <<= shift; |
| 807 |
| 808 /* re-estimate length for tiny vectors */ |
| 809 l = x > y ? x + ( y >> 1 ) |
| 810 : y + ( x >> 1 ); |
| 811 } |
| 812 else |
| 813 { |
| 814 x >>= -shift; |
| 815 y >>= -shift; |
| 816 l >>= -shift; |
| 817 } |
| 818 |
| 819 /* lower linear approximation for reciprocal length minus one */ |
| 820 b = 0x10000 - (FT_Int32)l; |
| 821 |
| 822 x_ = (FT_Int32)x; |
| 823 y_ = (FT_Int32)y; |
| 824 |
| 825 /* Newton's iterations */ |
| 826 do |
| 827 { |
| 828 u = (FT_UInt32)( x_ + ( x_ * b >> 16 ) ); |
| 829 v = (FT_UInt32)( y_ + ( y_ * b >> 16 ) ); |
| 830 |
| 831 /* Normalized squared length in the parentheses approaches 2^32. */ |
| 832 /* On two's complement systems, converting to signed gives the */ |
| 833 /* difference with 2^32 even if the expression wraps around. */ |
| 834 z = -(FT_Int32)( u * u + v * v ) / 0x200; |
| 835 z = z * ( ( 0x10000 + b ) >> 8 ) / 0x10000; |
| 836 |
| 837 b += z; |
| 838 |
| 839 } while ( z > 0 ); |
| 840 |
| 841 vector->x = sx < 0 ? -(FT_Pos)u : (FT_Pos)u; |
| 842 vector->y = sy < 0 ? -(FT_Pos)v : (FT_Pos)v; |
| 843 |
| 844 /* Conversion to signed helps to recover from likely wrap around */ |
| 845 /* in calculating the prenormalized length, because it gives the */ |
| 846 /* correct difference with 2^32 on two's complement systems. */ |
| 847 l = (FT_UInt32)( 0x10000 + (FT_Int32)( u * x + v * y ) / 0x10000 ); |
| 848 if ( shift > 0 ) |
| 849 l = ( l + ( 1 << ( shift - 1 ) ) ) >> shift; |
| 850 else |
| 851 l <<= -shift; |
| 852 |
| 853 return l; |
| 854 } |
| 855 |
| 856 |
734 #if 0 | 857 #if 0 |
735 | 858 |
736 /* documentation is in ftcalc.h */ | 859 /* documentation is in ftcalc.h */ |
737 | 860 |
738 FT_BASE_DEF( FT_Int32 ) | 861 FT_BASE_DEF( FT_Int32 ) |
739 FT_SqrtFixed( FT_Int32 x ) | 862 FT_SqrtFixed( FT_Int32 x ) |
740 { | 863 { |
741 FT_UInt32 root, rem_hi, rem_lo, test_div; | 864 FT_UInt32 root, rem_hi, rem_lo, test_div; |
742 FT_Int count; | 865 FT_Int count; |
743 | 866 |
744 | 867 |
745 root = 0; | 868 root = 0; |
746 | 869 |
747 if ( x > 0 ) | 870 if ( x > 0 ) |
748 { | 871 { |
749 rem_hi = 0; | 872 rem_hi = 0; |
750 rem_lo = x; | 873 rem_lo = (FT_UInt32)x; |
751 count = 24; | 874 count = 24; |
752 do | 875 do |
753 { | 876 { |
754 rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); | 877 rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); |
755 rem_lo <<= 2; | 878 rem_lo <<= 2; |
756 root <<= 1; | 879 root <<= 1; |
757 test_div = ( root << 1 ) + 1; | 880 test_div = ( root << 1 ) + 1; |
758 | 881 |
759 if ( rem_hi >= test_div ) | 882 if ( rem_hi >= test_div ) |
760 { | 883 { |
(...skipping 10 matching lines...) Expand all Loading... |
771 | 894 |
772 | 895 |
773 /* documentation is in ftcalc.h */ | 896 /* documentation is in ftcalc.h */ |
774 | 897 |
775 FT_BASE_DEF( FT_Int ) | 898 FT_BASE_DEF( FT_Int ) |
776 ft_corner_orientation( FT_Pos in_x, | 899 ft_corner_orientation( FT_Pos in_x, |
777 FT_Pos in_y, | 900 FT_Pos in_y, |
778 FT_Pos out_x, | 901 FT_Pos out_x, |
779 FT_Pos out_y ) | 902 FT_Pos out_y ) |
780 { | 903 { |
781 FT_Long result; /* avoid overflow on 16-bit system */ | 904 #ifdef FT_LONG64 |
| 905 |
| 906 FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; |
782 | 907 |
783 | 908 |
784 /* deal with the trivial cases quickly */ | 909 return ( delta > 0 ) - ( delta < 0 ); |
785 if ( in_y == 0 ) | |
786 { | |
787 if ( in_x >= 0 ) | |
788 result = out_y; | |
789 else | |
790 result = -out_y; | |
791 } | |
792 else if ( in_x == 0 ) | |
793 { | |
794 if ( in_y >= 0 ) | |
795 result = -out_x; | |
796 else | |
797 result = out_x; | |
798 } | |
799 else if ( out_y == 0 ) | |
800 { | |
801 if ( out_x >= 0 ) | |
802 result = in_y; | |
803 else | |
804 result = -in_y; | |
805 } | |
806 else if ( out_x == 0 ) | |
807 { | |
808 if ( out_y >= 0 ) | |
809 result = -in_x; | |
810 else | |
811 result = in_x; | |
812 } | |
813 else /* general case */ | |
814 { | |
815 #ifdef FT_LONG64 | |
816 | |
817 FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; | |
818 | |
819 | |
820 if ( delta == 0 ) | |
821 result = 0; | |
822 else | |
823 result = 1 - 2 * ( delta < 0 ); | |
824 | 910 |
825 #else | 911 #else |
826 | 912 |
| 913 FT_Int result; |
| 914 |
| 915 |
| 916 if ( (FT_ULong)FT_ABS( in_x ) + (FT_ULong)FT_ABS( out_y ) <= 131071UL && |
| 917 (FT_ULong)FT_ABS( in_y ) + (FT_ULong)FT_ABS( out_x ) <= 131071UL ) |
| 918 { |
| 919 FT_Long z1 = in_x * out_y; |
| 920 FT_Long z2 = in_y * out_x; |
| 921 |
| 922 |
| 923 if ( z1 > z2 ) |
| 924 result = +1; |
| 925 else if ( z1 < z2 ) |
| 926 result = -1; |
| 927 else |
| 928 result = 0; |
| 929 } |
| 930 else /* products might overflow 32 bits */ |
| 931 { |
827 FT_Int64 z1, z2; | 932 FT_Int64 z1, z2; |
828 | 933 |
829 | 934 |
830 /* XXX: this function does not allow 64-bit arguments */ | 935 /* XXX: this function does not allow 64-bit arguments */ |
831 ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); | 936 ft_multo64( (FT_UInt32)in_x, (FT_UInt32)out_y, &z1 ); |
832 ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); | 937 ft_multo64( (FT_UInt32)in_y, (FT_UInt32)out_x, &z2 ); |
833 | 938 |
834 if ( z1.hi > z2.hi ) | 939 if ( z1.hi > z2.hi ) |
835 result = +1; | 940 result = +1; |
836 else if ( z1.hi < z2.hi ) | 941 else if ( z1.hi < z2.hi ) |
837 result = -1; | 942 result = -1; |
838 else if ( z1.lo > z2.lo ) | 943 else if ( z1.lo > z2.lo ) |
839 result = +1; | 944 result = +1; |
840 else if ( z1.lo < z2.lo ) | 945 else if ( z1.lo < z2.lo ) |
841 result = -1; | 946 result = -1; |
842 else | 947 else |
843 result = 0; | 948 result = 0; |
844 | |
845 #endif | |
846 } | 949 } |
847 | 950 |
848 /* XXX: only the sign of return value, +1/0/-1 must be used */ | 951 /* XXX: only the sign of return value, +1/0/-1 must be used */ |
849 return (FT_Int)result; | 952 return result; |
| 953 |
| 954 #endif |
850 } | 955 } |
851 | 956 |
852 | 957 |
853 /* documentation is in ftcalc.h */ | 958 /* documentation is in ftcalc.h */ |
854 | 959 |
855 FT_BASE_DEF( FT_Int ) | 960 FT_BASE_DEF( FT_Int ) |
856 ft_corner_is_flat( FT_Pos in_x, | 961 ft_corner_is_flat( FT_Pos in_x, |
857 FT_Pos in_y, | 962 FT_Pos in_y, |
858 FT_Pos out_x, | 963 FT_Pos out_x, |
859 FT_Pos out_y ) | 964 FT_Pos out_y ) |
(...skipping 29 matching lines...) Expand all Loading... |
889 | 994 |
890 /* now do a simple length comparison: */ | 995 /* now do a simple length comparison: */ |
891 /* */ | 996 /* */ |
892 /* d_in + d_out < 17/16 d_hypot */ | 997 /* d_in + d_out < 17/16 d_hypot */ |
893 | 998 |
894 return ( d_in + d_out - d_hypot ) < ( d_hypot >> 4 ); | 999 return ( d_in + d_out - d_hypot ) < ( d_hypot >> 4 ); |
895 } | 1000 } |
896 | 1001 |
897 | 1002 |
898 /* END */ | 1003 /* END */ |
OLD | NEW |