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 by */ | 7 /* Copyright 1996-2006, 2008, 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 /* */ | 19 /* */ |
20 /* Support for 1-complement arithmetic has been totally dropped in this */ | 20 /* Support for 1-complement arithmetic has been totally dropped in this */ |
21 /* release. You can still write your own code if you need it. */ | 21 /* release. You can still write your own code if you need it. */ |
22 /* */ | 22 /* */ |
23 /*************************************************************************/ | 23 /*************************************************************************/ |
24 | 24 |
25 /*************************************************************************/ | 25 /*************************************************************************/ |
26 /* */ | 26 /* */ |
27 /* Implementing basic computation routines. */ | 27 /* Implementing basic computation routines. */ |
28 /* */ | 28 /* */ |
29 /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ | 29 /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ |
30 /* and FT_FloorFix() are declared in freetype.h. */ | 30 /* and FT_FloorFix() are declared in freetype.h. */ |
31 /* */ | 31 /* */ |
32 /*************************************************************************/ | 32 /*************************************************************************/ |
33 | 33 |
34 | 34 |
35 #include <ft2build.h> | 35 #include <ft2build.h> |
36 #include FT_GLYPH_H | 36 #include FT_GLYPH_H |
| 37 #include FT_TRIGONOMETRY_H |
37 #include FT_INTERNAL_CALC_H | 38 #include FT_INTERNAL_CALC_H |
38 #include FT_INTERNAL_DEBUG_H | 39 #include FT_INTERNAL_DEBUG_H |
39 #include FT_INTERNAL_OBJECTS_H | 40 #include FT_INTERNAL_OBJECTS_H |
40 | 41 |
41 #ifdef FT_MULFIX_INLINED | 42 #ifdef FT_MULFIX_INLINED |
42 #undef FT_MulFix | 43 #undef FT_MulFix |
43 #endif | 44 #endif |
44 | 45 |
45 /* we need to define a 64-bits data type here */ | 46 /* we need to emulate a 64-bit data type if a real one isn't available */ |
46 | 47 |
47 #ifdef FT_LONG64 | 48 #ifndef FT_LONG64 |
48 | |
49 typedef FT_INT64 FT_Int64; | |
50 | |
51 #else | |
52 | 49 |
53 typedef struct FT_Int64_ | 50 typedef struct FT_Int64_ |
54 { | 51 { |
55 FT_UInt32 lo; | 52 FT_UInt32 lo; |
56 FT_UInt32 hi; | 53 FT_UInt32 hi; |
57 | 54 |
58 } FT_Int64; | 55 } FT_Int64; |
59 | 56 |
60 #endif /* FT_LONG64 */ | 57 #endif /* !FT_LONG64 */ |
61 | 58 |
62 | 59 |
63 /*************************************************************************/ | 60 /*************************************************************************/ |
64 /* */ | 61 /* */ |
65 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | 62 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
66 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | 63 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
67 /* messages during execution. */ | 64 /* messages during execution. */ |
68 /* */ | 65 /* */ |
69 #undef FT_COMPONENT | 66 #undef FT_COMPONENT |
70 #define FT_COMPONENT trace_calc | 67 #define FT_COMPONENT trace_calc |
(...skipping 25 matching lines...) Expand all Loading... |
96 /* documentation is in freetype.h */ | 93 /* documentation is in freetype.h */ |
97 | 94 |
98 FT_EXPORT_DEF( FT_Fixed ) | 95 FT_EXPORT_DEF( FT_Fixed ) |
99 FT_FloorFix( FT_Fixed a ) | 96 FT_FloorFix( FT_Fixed a ) |
100 { | 97 { |
101 return ( a >= 0 ) ? a & ~0xFFFFL | 98 return ( a >= 0 ) ? a & ~0xFFFFL |
102 : -((-a) & ~0xFFFFL ); | 99 : -((-a) & ~0xFFFFL ); |
103 } | 100 } |
104 | 101 |
105 | 102 |
106 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS | 103 FT_BASE_DEF ( FT_Int ) |
| 104 FT_MSB( FT_UInt32 z ) |
| 105 { |
| 106 FT_Int shift = 0; |
| 107 |
| 108 /* determine msb bit index in `shift' */ |
| 109 if ( z >= ( 1L << 16 ) ) |
| 110 { |
| 111 z >>= 16; |
| 112 shift += 16; |
| 113 } |
| 114 if ( z >= ( 1L << 8 ) ) |
| 115 { |
| 116 z >>= 8; |
| 117 shift += 8; |
| 118 } |
| 119 if ( z >= ( 1L << 4 ) ) |
| 120 { |
| 121 z >>= 4; |
| 122 shift += 4; |
| 123 } |
| 124 if ( z >= ( 1L << 2 ) ) |
| 125 { |
| 126 z >>= 2; |
| 127 shift += 2; |
| 128 } |
| 129 if ( z >= ( 1L << 1 ) ) |
| 130 { |
| 131 z >>= 1; |
| 132 shift += 1; |
| 133 } |
| 134 |
| 135 return shift; |
| 136 } |
| 137 |
107 | 138 |
108 /* documentation is in ftcalc.h */ | 139 /* documentation is in ftcalc.h */ |
109 | 140 |
110 FT_EXPORT_DEF( FT_Int32 ) | 141 FT_BASE_DEF( FT_Fixed ) |
111 FT_Sqrt32( FT_Int32 x ) | 142 FT_Hypot( FT_Fixed x, |
| 143 FT_Fixed y ) |
112 { | 144 { |
113 FT_UInt32 val, root, newroot, mask; | 145 FT_Vector v; |
114 | 146 |
115 | 147 |
116 root = 0; | 148 v.x = x; |
117 mask = (FT_UInt32)0x40000000UL; | 149 v.y = y; |
118 val = (FT_UInt32)x; | |
119 | 150 |
120 do | 151 return FT_Vector_Length( &v ); |
121 { | |
122 newroot = root + mask; | |
123 if ( newroot <= val ) | |
124 { | |
125 val -= newroot; | |
126 root = newroot + mask; | |
127 } | |
128 | |
129 root >>= 1; | |
130 mask >>= 2; | |
131 | |
132 } while ( mask != 0 ); | |
133 | |
134 return root; | |
135 } | 152 } |
136 | 153 |
137 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ | |
138 | |
139 | 154 |
140 #ifdef FT_LONG64 | 155 #ifdef FT_LONG64 |
141 | 156 |
142 | 157 |
143 /* documentation is in freetype.h */ | 158 /* documentation is in freetype.h */ |
144 | 159 |
145 FT_EXPORT_DEF( FT_Long ) | 160 FT_EXPORT_DEF( FT_Long ) |
146 FT_MulDiv( FT_Long a, | 161 FT_MulDiv( FT_Long a, |
147 FT_Long b, | 162 FT_Long b, |
148 FT_Long c ) | 163 FT_Long c ) |
149 { | 164 { |
150 FT_Int s; | 165 FT_Int s; |
151 FT_Long d; | 166 FT_Long d; |
152 | 167 |
153 | 168 |
154 s = 1; | 169 s = 1; |
155 if ( a < 0 ) { a = -a; s = -1; } | 170 if ( a < 0 ) { a = -a; s = -1; } |
156 if ( b < 0 ) { b = -b; s = -s; } | 171 if ( b < 0 ) { b = -b; s = -s; } |
157 if ( c < 0 ) { c = -c; s = -s; } | 172 if ( c < 0 ) { c = -c; s = -s; } |
158 | 173 |
159 d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c | 174 d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c |
160 : 0x7FFFFFFFL ); | 175 : 0x7FFFFFFFL ); |
161 | 176 |
162 return ( s > 0 ) ? d : -d; | 177 return ( s > 0 ) ? d : -d; |
163 } | 178 } |
164 | 179 |
165 | 180 |
166 #ifdef TT_USE_BYTECODE_INTERPRETER | |
167 | |
168 /* documentation is in ftcalc.h */ | 181 /* documentation is in ftcalc.h */ |
169 | 182 |
170 FT_BASE_DEF( FT_Long ) | 183 FT_BASE_DEF( FT_Long ) |
171 FT_MulDiv_No_Round( FT_Long a, | 184 FT_MulDiv_No_Round( FT_Long a, |
172 FT_Long b, | 185 FT_Long b, |
173 FT_Long c ) | 186 FT_Long c ) |
174 { | 187 { |
175 FT_Int s; | 188 FT_Int s; |
176 FT_Long d; | 189 FT_Long d; |
177 | 190 |
178 | 191 |
179 s = 1; | 192 s = 1; |
180 if ( a < 0 ) { a = -a; s = -1; } | 193 if ( a < 0 ) { a = -a; s = -1; } |
181 if ( b < 0 ) { b = -b; s = -s; } | 194 if ( b < 0 ) { b = -b; s = -s; } |
182 if ( c < 0 ) { c = -c; s = -s; } | 195 if ( c < 0 ) { c = -c; s = -s; } |
183 | 196 |
184 d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c | 197 d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c |
185 : 0x7FFFFFFFL ); | 198 : 0x7FFFFFFFL ); |
186 | 199 |
187 return ( s > 0 ) ? d : -d; | 200 return ( s > 0 ) ? d : -d; |
188 } | 201 } |
189 | 202 |
190 #endif /* TT_USE_BYTECODE_INTERPRETER */ | |
191 | |
192 | 203 |
193 /* documentation is in freetype.h */ | 204 /* documentation is in freetype.h */ |
194 | 205 |
195 FT_EXPORT_DEF( FT_Long ) | 206 FT_EXPORT_DEF( FT_Long ) |
196 FT_MulFix( FT_Long a, | 207 FT_MulFix( FT_Long a, |
197 FT_Long b ) | 208 FT_Long b ) |
198 { | 209 { |
199 #ifdef FT_MULFIX_ASSEMBLER | 210 #ifdef FT_MULFIX_ASSEMBLER |
200 | 211 |
201 return FT_MULFIX_ASSEMBLER( a, b ); | 212 return FT_MULFIX_ASSEMBLER( a, b ); |
(...skipping 26 matching lines...) Expand all Loading... |
228 | 239 |
229 /* documentation is in freetype.h */ | 240 /* documentation is in freetype.h */ |
230 | 241 |
231 FT_EXPORT_DEF( FT_Long ) | 242 FT_EXPORT_DEF( FT_Long ) |
232 FT_DivFix( FT_Long a, | 243 FT_DivFix( FT_Long a, |
233 FT_Long b ) | 244 FT_Long b ) |
234 { | 245 { |
235 FT_Int32 s; | 246 FT_Int32 s; |
236 FT_UInt32 q; | 247 FT_UInt32 q; |
237 | 248 |
| 249 |
238 s = 1; | 250 s = 1; |
239 if ( a < 0 ) { a = -a; s = -1; } | 251 if ( a < 0 ) |
240 if ( b < 0 ) { b = -b; s = -s; } | 252 { |
| 253 a = -a; |
| 254 s = -1; |
| 255 } |
| 256 if ( b < 0 ) |
| 257 { |
| 258 b = -b; |
| 259 s = -s; |
| 260 } |
241 | 261 |
242 if ( b == 0 ) | 262 if ( b == 0 ) |
243 /* check for division by 0 */ | 263 /* check for division by 0 */ |
244 q = 0x7FFFFFFFL; | 264 q = 0x7FFFFFFFL; |
245 else | 265 else |
246 /* compute result directly */ | 266 /* compute result directly */ |
247 q = (FT_UInt32)( ( ( (FT_Int64)a << 16 ) + ( b >> 1 ) ) / b ); | 267 q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b ); |
248 | 268 |
249 return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); | 269 return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); |
250 } | 270 } |
251 | 271 |
252 | 272 |
253 #else /* !FT_LONG64 */ | 273 #else /* !FT_LONG64 */ |
254 | 274 |
255 | 275 |
256 static void | 276 static void |
257 ft_multo64( FT_UInt32 x, | 277 ft_multo64( FT_UInt32 x, |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 FT_Add64( &temp, &temp2, &temp ); | 405 FT_Add64( &temp, &temp2, &temp ); |
386 a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); | 406 a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); |
387 } | 407 } |
388 else | 408 else |
389 a = 0x7FFFFFFFL; | 409 a = 0x7FFFFFFFL; |
390 | 410 |
391 return ( s < 0 ? -a : a ); | 411 return ( s < 0 ? -a : a ); |
392 } | 412 } |
393 | 413 |
394 | 414 |
395 #ifdef TT_USE_BYTECODE_INTERPRETER | |
396 | |
397 FT_BASE_DEF( FT_Long ) | 415 FT_BASE_DEF( FT_Long ) |
398 FT_MulDiv_No_Round( FT_Long a, | 416 FT_MulDiv_No_Round( FT_Long a, |
399 FT_Long b, | 417 FT_Long b, |
400 FT_Long c ) | 418 FT_Long c ) |
401 { | 419 { |
402 long s; | 420 long s; |
403 | 421 |
404 | 422 |
405 if ( a == 0 || b == c ) | 423 if ( a == 0 || b == c ) |
406 return a; | 424 return a; |
(...skipping 12 matching lines...) Expand all Loading... |
419 | 437 |
420 ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); | 438 ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); |
421 a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); | 439 a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); |
422 } | 440 } |
423 else | 441 else |
424 a = 0x7FFFFFFFL; | 442 a = 0x7FFFFFFFL; |
425 | 443 |
426 return ( s < 0 ? -a : a ); | 444 return ( s < 0 ? -a : a ); |
427 } | 445 } |
428 | 446 |
429 #endif /* TT_USE_BYTECODE_INTERPRETER */ | |
430 | |
431 | 447 |
432 /* documentation is in freetype.h */ | 448 /* documentation is in freetype.h */ |
433 | 449 |
434 FT_EXPORT_DEF( FT_Long ) | 450 FT_EXPORT_DEF( FT_Long ) |
435 FT_MulFix( FT_Long a, | 451 FT_MulFix( FT_Long a, |
436 FT_Long b ) | 452 FT_Long b ) |
437 { | 453 { |
438 #ifdef FT_MULFIX_ASSEMBLER | 454 #ifdef FT_MULFIX_ASSEMBLER |
439 | 455 |
440 return FT_MULFIX_ASSEMBLER( a, b ); | 456 return FT_MULFIX_ASSEMBLER( a, b ); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 s ^= (FT_Int32)b; b = FT_ABS( b ); | 561 s ^= (FT_Int32)b; b = FT_ABS( b ); |
546 | 562 |
547 if ( (FT_UInt32)b == 0 ) | 563 if ( (FT_UInt32)b == 0 ) |
548 { | 564 { |
549 /* check for division by 0 */ | 565 /* check for division by 0 */ |
550 q = (FT_UInt32)0x7FFFFFFFL; | 566 q = (FT_UInt32)0x7FFFFFFFL; |
551 } | 567 } |
552 else if ( ( a >> 16 ) == 0 ) | 568 else if ( ( a >> 16 ) == 0 ) |
553 { | 569 { |
554 /* compute result directly */ | 570 /* compute result directly */ |
555 q = (FT_UInt32)( ( a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; | 571 q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; |
556 } | 572 } |
557 else | 573 else |
558 { | 574 { |
559 /* we need more bits; we have to do it by hand */ | 575 /* we need more bits; we have to do it by hand */ |
560 FT_Int64 temp, temp2; | 576 FT_Int64 temp, temp2; |
561 | 577 |
562 | 578 |
563 temp.hi = (FT_Int32) ( a >> 16 ); | 579 temp.hi = (FT_Int32)( a >> 16 ); |
564 temp.lo = (FT_UInt32)( a << 16 ); | 580 temp.lo = (FT_UInt32)a << 16; |
565 temp2.hi = 0; | 581 temp2.hi = 0; |
566 temp2.lo = (FT_UInt32)( b >> 1 ); | 582 temp2.lo = (FT_UInt32)( b >> 1 ); |
567 FT_Add64( &temp, &temp2, &temp ); | 583 FT_Add64( &temp, &temp2, &temp ); |
568 q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); | 584 q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); |
569 } | 585 } |
570 | 586 |
571 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); | 587 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); |
572 } | 588 } |
573 | 589 |
574 | 590 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 | 736 |
721 /* documentation is in ftglyph.h */ | 737 /* documentation is in ftglyph.h */ |
722 | 738 |
723 FT_EXPORT_DEF( FT_Error ) | 739 FT_EXPORT_DEF( FT_Error ) |
724 FT_Matrix_Invert( FT_Matrix* matrix ) | 740 FT_Matrix_Invert( FT_Matrix* matrix ) |
725 { | 741 { |
726 FT_Pos delta, xx, yy; | 742 FT_Pos delta, xx, yy; |
727 | 743 |
728 | 744 |
729 if ( !matrix ) | 745 if ( !matrix ) |
730 return FT_Err_Invalid_Argument; | 746 return FT_THROW( Invalid_Argument ); |
731 | 747 |
732 /* compute discriminant */ | 748 /* compute discriminant */ |
733 delta = FT_MulFix( matrix->xx, matrix->yy ) - | 749 delta = FT_MulFix( matrix->xx, matrix->yy ) - |
734 FT_MulFix( matrix->xy, matrix->yx ); | 750 FT_MulFix( matrix->xy, matrix->yx ); |
735 | 751 |
736 if ( !delta ) | 752 if ( !delta ) |
737 return FT_Err_Invalid_Argument; /* matrix can't be inverted */ | 753 return FT_THROW( Invalid_Argument ); /* matrix can't be inverted */ |
738 | 754 |
739 matrix->xy = - FT_DivFix( matrix->xy, delta ); | 755 matrix->xy = - FT_DivFix( matrix->xy, delta ); |
740 matrix->yx = - FT_DivFix( matrix->yx, delta ); | 756 matrix->yx = - FT_DivFix( matrix->yx, delta ); |
741 | 757 |
742 xx = matrix->xx; | 758 xx = matrix->xx; |
743 yy = matrix->yy; | 759 yy = matrix->yy; |
744 | 760 |
745 matrix->xx = FT_DivFix( yy, delta ); | 761 matrix->xx = FT_DivFix( yy, delta ); |
746 matrix->yy = FT_DivFix( xx, delta ); | 762 matrix->yy = FT_DivFix( xx, delta ); |
747 | 763 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 ay = out_y + in_y; | 965 ay = out_y + in_y; |
950 if ( ay < 0 ) | 966 if ( ay < 0 ) |
951 ay = -ay; | 967 ay = -ay; |
952 d_corner = ax + ay; | 968 d_corner = ax + ay; |
953 | 969 |
954 return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); | 970 return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); |
955 } | 971 } |
956 | 972 |
957 | 973 |
958 /* END */ | 974 /* END */ |
OLD | NEW |