| 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 |