| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkMatrix.h" | 8 #include "SkMatrix.h" |
| 9 #include "Sk64.h" | 9 #include "Sk64.h" |
| 10 #include "SkFloatBits.h" | 10 #include "SkFloatBits.h" |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 SkMatrix m; | 306 SkMatrix m; |
| 307 m.setScale(sx, sy, px, py); | 307 m.setScale(sx, sy, px, py); |
| 308 return this->preConcat(m); | 308 return this->preConcat(m); |
| 309 } | 309 } |
| 310 | 310 |
| 311 bool SkMatrix::preScale(SkScalar sx, SkScalar sy) { | 311 bool SkMatrix::preScale(SkScalar sx, SkScalar sy) { |
| 312 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { | 312 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { |
| 313 return true; | 313 return true; |
| 314 } | 314 } |
| 315 | 315 |
| 316 #ifdef SK_SCALAR_IS_FIXED | |
| 317 SkMatrix m; | |
| 318 m.setScale(sx, sy); | |
| 319 return this->preConcat(m); | |
| 320 #else | |
| 321 // the assumption is that these multiplies are very cheap, and that | 316 // the assumption is that these multiplies are very cheap, and that |
| 322 // a full concat and/or just computing the matrix type is more expensive. | 317 // a full concat and/or just computing the matrix type is more expensive. |
| 323 // Also, the fixed-point case checks for overflow, but the float doesn't, | 318 // Also, the fixed-point case checks for overflow, but the float doesn't, |
| 324 // so we can get away with these blind multiplies. | 319 // so we can get away with these blind multiplies. |
| 325 | 320 |
| 326 fMat[kMScaleX] = SkScalarMul(fMat[kMScaleX], sx); | 321 fMat[kMScaleX] = SkScalarMul(fMat[kMScaleX], sx); |
| 327 fMat[kMSkewY] = SkScalarMul(fMat[kMSkewY], sx); | 322 fMat[kMSkewY] = SkScalarMul(fMat[kMSkewY], sx); |
| 328 fMat[kMPersp0] = SkScalarMul(fMat[kMPersp0], sx); | 323 fMat[kMPersp0] = SkScalarMul(fMat[kMPersp0], sx); |
| 329 | 324 |
| 330 fMat[kMSkewX] = SkScalarMul(fMat[kMSkewX], sy); | 325 fMat[kMSkewX] = SkScalarMul(fMat[kMSkewX], sy); |
| 331 fMat[kMScaleY] = SkScalarMul(fMat[kMScaleY], sy); | 326 fMat[kMScaleY] = SkScalarMul(fMat[kMScaleY], sy); |
| 332 fMat[kMPersp1] = SkScalarMul(fMat[kMPersp1], sy); | 327 fMat[kMPersp1] = SkScalarMul(fMat[kMPersp1], sy); |
| 333 | 328 |
| 334 this->orTypeMask(kScale_Mask); | 329 this->orTypeMask(kScale_Mask); |
| 335 return true; | 330 return true; |
| 336 #endif | |
| 337 } | 331 } |
| 338 | 332 |
| 339 bool SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 333 bool SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 340 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { | 334 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { |
| 341 return true; | 335 return true; |
| 342 } | 336 } |
| 343 SkMatrix m; | 337 SkMatrix m; |
| 344 m.setScale(sx, sy, px, py); | 338 m.setScale(sx, sy, px, py); |
| 345 return this->postConcat(m); | 339 return this->postConcat(m); |
| 346 } | 340 } |
| 347 | 341 |
| 348 bool SkMatrix::postScale(SkScalar sx, SkScalar sy) { | 342 bool SkMatrix::postScale(SkScalar sx, SkScalar sy) { |
| 349 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { | 343 if (SK_Scalar1 == sx && SK_Scalar1 == sy) { |
| 350 return true; | 344 return true; |
| 351 } | 345 } |
| 352 SkMatrix m; | 346 SkMatrix m; |
| 353 m.setScale(sx, sy); | 347 m.setScale(sx, sy); |
| 354 return this->postConcat(m); | 348 return this->postConcat(m); |
| 355 } | 349 } |
| 356 | 350 |
| 357 #ifdef SK_SCALAR_IS_FIXED | |
| 358 static inline SkFixed roundidiv(SkFixed numer, int denom) { | |
| 359 int ns = numer >> 31; | |
| 360 int ds = denom >> 31; | |
| 361 numer = (numer ^ ns) - ns; | |
| 362 denom = (denom ^ ds) - ds; | |
| 363 | |
| 364 SkFixed answer = (numer + (denom >> 1)) / denom; | |
| 365 int as = ns ^ ds; | |
| 366 return (answer ^ as) - as; | |
| 367 } | |
| 368 #endif | |
| 369 | |
| 370 // this guy perhaps can go away, if we have a fract/high-precision way to | 351 // this guy perhaps can go away, if we have a fract/high-precision way to |
| 371 // scale matrices | 352 // scale matrices |
| 372 bool SkMatrix::postIDiv(int divx, int divy) { | 353 bool SkMatrix::postIDiv(int divx, int divy) { |
| 373 if (divx == 0 || divy == 0) { | 354 if (divx == 0 || divy == 0) { |
| 374 return false; | 355 return false; |
| 375 } | 356 } |
| 376 | 357 |
| 377 #ifdef SK_SCALAR_IS_FIXED | |
| 378 fMat[kMScaleX] = roundidiv(fMat[kMScaleX], divx); | |
| 379 fMat[kMSkewX] = roundidiv(fMat[kMSkewX], divx); | |
| 380 fMat[kMTransX] = roundidiv(fMat[kMTransX], divx); | |
| 381 | |
| 382 fMat[kMScaleY] = roundidiv(fMat[kMScaleY], divy); | |
| 383 fMat[kMSkewY] = roundidiv(fMat[kMSkewY], divy); | |
| 384 fMat[kMTransY] = roundidiv(fMat[kMTransY], divy); | |
| 385 #else | |
| 386 const float invX = 1.f / divx; | 358 const float invX = 1.f / divx; |
| 387 const float invY = 1.f / divy; | 359 const float invY = 1.f / divy; |
| 388 | 360 |
| 389 fMat[kMScaleX] *= invX; | 361 fMat[kMScaleX] *= invX; |
| 390 fMat[kMSkewX] *= invX; | 362 fMat[kMSkewX] *= invX; |
| 391 fMat[kMTransX] *= invX; | 363 fMat[kMTransX] *= invX; |
| 392 | 364 |
| 393 fMat[kMScaleY] *= invY; | 365 fMat[kMScaleY] *= invY; |
| 394 fMat[kMSkewY] *= invY; | 366 fMat[kMSkewY] *= invY; |
| 395 fMat[kMTransY] *= invY; | 367 fMat[kMTransY] *= invY; |
| 396 #endif | |
| 397 | 368 |
| 398 this->setTypeMask(kUnknown_Mask); | 369 this->setTypeMask(kUnknown_Mask); |
| 399 return true; | 370 return true; |
| 400 } | 371 } |
| 401 | 372 |
| 402 ////////////////////////////////////////////////////////////////////////////////
//// | 373 ////////////////////////////////////////////////////////////////////////////////
//// |
| 403 | 374 |
| 404 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, | 375 void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, |
| 405 SkScalar px, SkScalar py) { | 376 SkScalar px, SkScalar py) { |
| 406 const SkScalar oneMinusCosV = SK_Scalar1 - cosV; | 377 const SkScalar oneMinusCosV = SK_Scalar1 - cosV; |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 inv->fMat[kMSkewX] = SkScalarMulShift(SkPerspMul(fMat[kMTransX], fM
at[kMPersp1]) - SkPerspMul(fMat[kMSkewX], fMat[kMPersp2]), scale, shift); | 820 inv->fMat[kMSkewX] = SkScalarMulShift(SkPerspMul(fMat[kMTransX], fM
at[kMPersp1]) - SkPerspMul(fMat[kMSkewX], fMat[kMPersp2]), scale, shift); |
| 850 inv->fMat[kMTransX] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM
at[kMTransY]) - SkScalarMul(fMat[kMTransX], fMat[kMScaleY]), scale, shift); | 821 inv->fMat[kMTransX] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM
at[kMTransY]) - SkScalarMul(fMat[kMTransX], fMat[kMScaleY]), scale, shift); |
| 851 | 822 |
| 852 inv->fMat[kMSkewY] = SkScalarMulShift(SkPerspMul(fMat[kMTransY], fM
at[kMPersp0]) - SkPerspMul(fMat[kMSkewY], fMat[kMPersp2]), scale, shift); | 823 inv->fMat[kMSkewY] = SkScalarMulShift(SkPerspMul(fMat[kMTransY], fM
at[kMPersp0]) - SkPerspMul(fMat[kMSkewY], fMat[kMPersp2]), scale, shift); |
| 853 inv->fMat[kMScaleY] = SkScalarMulShift(SkPerspMul(fMat[kMScaleX], fM
at[kMPersp2]) - SkPerspMul(fMat[kMTransX], fMat[kMPersp0]), scale, shift); | 824 inv->fMat[kMScaleY] = SkScalarMulShift(SkPerspMul(fMat[kMScaleX], fM
at[kMPersp2]) - SkPerspMul(fMat[kMTransX], fMat[kMPersp0]), scale, shift); |
| 854 inv->fMat[kMTransY] = SkScalarMulShift(SkScalarMul(fMat[kMTransX], f
Mat[kMSkewY]) - SkScalarMul(fMat[kMScaleX], fMat[kMTransY]), scale, shift); | 825 inv->fMat[kMTransY] = SkScalarMulShift(SkScalarMul(fMat[kMTransX], f
Mat[kMSkewY]) - SkScalarMul(fMat[kMScaleX], fMat[kMTransY]), scale, shift); |
| 855 | 826 |
| 856 inv->fMat[kMPersp0] = SkScalarMulShift(SkScalarMul(fMat[kMSkewY], fM
at[kMPersp1]) - SkScalarMul(fMat[kMScaleY], fMat[kMPersp0]), scale, shift); | 827 inv->fMat[kMPersp0] = SkScalarMulShift(SkScalarMul(fMat[kMSkewY], fM
at[kMPersp1]) - SkScalarMul(fMat[kMScaleY], fMat[kMPersp0]), scale, shift); |
| 857 inv->fMat[kMPersp1] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM
at[kMPersp0]) - SkScalarMul(fMat[kMScaleX], fMat[kMPersp1]), scale, shift); | 828 inv->fMat[kMPersp1] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fM
at[kMPersp0]) - SkScalarMul(fMat[kMScaleX], fMat[kMPersp1]), scale, shift); |
| 858 inv->fMat[kMPersp2] = SkScalarMulShift(SkScalarMul(fMat[kMScaleX], f
Mat[kMScaleY]) - SkScalarMul(fMat[kMSkewX], fMat[kMSkewY]), scale, shift); | 829 inv->fMat[kMPersp2] = SkScalarMulShift(SkScalarMul(fMat[kMScaleX], f
Mat[kMScaleY]) - SkScalarMul(fMat[kMSkewX], fMat[kMSkewY]), scale, shift); |
| 859 #ifdef SK_SCALAR_IS_FIXED | |
| 860 if (SkAbs32(inv->fMat[kMPersp2]) > SK_Fixed1) { | |
| 861 Sk64 tmp; | |
| 862 | |
| 863 tmp.set(SK_Fract1); | |
| 864 tmp.shiftLeft(16); | |
| 865 tmp.div(inv->fMat[kMPersp2], Sk64::kRound_DivOption); | |
| 866 | |
| 867 SkFract scale = tmp.get32(); | |
| 868 | |
| 869 for (int i = 0; i < 9; i++) { | |
| 870 inv->fMat[i] = SkFractMul(inv->fMat[i], scale); | |
| 871 } | |
| 872 } | |
| 873 inv->fMat[kMPersp2] = SkFixedToFract(inv->fMat[kMPersp2]); | |
| 874 #endif | |
| 875 } else { // not perspective | 830 } else { // not perspective |
| 876 #ifdef SK_SCALAR_IS_FIXED | |
| 877 Sk64 tx, ty; | |
| 878 int clzNumer; | |
| 879 | |
| 880 // check the 2x2 for overflow | |
| 881 { | |
| 882 int32_t value = SkAbs32(fMat[kMScaleY]); | |
| 883 value |= SkAbs32(fMat[kMSkewX]); | |
| 884 value |= SkAbs32(fMat[kMScaleX]); | |
| 885 value |= SkAbs32(fMat[kMSkewY]); | |
| 886 clzNumer = SkCLZ(value); | |
| 887 if (shift - clzNumer > 31) | |
| 888 return false; // overflow | |
| 889 } | |
| 890 | |
| 891 set_muladdmul(&tx, fMat[kMSkewX], fMat[kMTransY], -fMat[kMScaleY], f
Mat[kMTransX]); | |
| 892 set_muladdmul(&ty, fMat[kMSkewY], fMat[kMTransX], -fMat[kMScaleX], f
Mat[kMTransY]); | |
| 893 // check tx,ty for overflow | |
| 894 clzNumer = SkCLZ(SkAbs32(tx.fHi) | SkAbs32(ty.fHi)); | |
| 895 if (shift - clzNumer > 14) { | |
| 896 return false; // overflow | |
| 897 } | |
| 898 | |
| 899 int fixedShift = 61 - shift; | |
| 900 int sk64shift = 44 - shift + clzNumer; | |
| 901 | |
| 902 inv->fMat[kMScaleX] = SkMulShift(fMat[kMScaleY], scale, fixedShift); | |
| 903 inv->fMat[kMSkewX] = SkMulShift(-fMat[kMSkewX], scale, fixedShift); | |
| 904 inv->fMat[kMTransX] = SkMulShift(tx.getShiftRight(33 - clzNumer), sc
ale, sk64shift); | |
| 905 | |
| 906 inv->fMat[kMSkewY] = SkMulShift(-fMat[kMSkewY], scale, fixedShift); | |
| 907 inv->fMat[kMScaleY] = SkMulShift(fMat[kMScaleX], scale, fixedShift); | |
| 908 inv->fMat[kMTransY] = SkMulShift(ty.getShiftRight(33 - clzNumer), sc
ale, sk64shift); | |
| 909 #else | |
| 910 inv->fMat[kMScaleX] = SkDoubleToFloat(fMat[kMScaleY] * scale); | 831 inv->fMat[kMScaleX] = SkDoubleToFloat(fMat[kMScaleY] * scale); |
| 911 inv->fMat[kMSkewX] = SkDoubleToFloat(-fMat[kMSkewX] * scale); | 832 inv->fMat[kMSkewX] = SkDoubleToFloat(-fMat[kMSkewX] * scale); |
| 912 inv->fMat[kMTransX] = mul_diff_scale(fMat[kMSkewX], fMat[kMTransY], | 833 inv->fMat[kMTransX] = mul_diff_scale(fMat[kMSkewX], fMat[kMTransY], |
| 913 fMat[kMScaleY], fMat[kMTransX], scale); | 834 fMat[kMScaleY], fMat[kMTransX], scale); |
| 914 | 835 |
| 915 inv->fMat[kMSkewY] = SkDoubleToFloat(-fMat[kMSkewY] * scale); | 836 inv->fMat[kMSkewY] = SkDoubleToFloat(-fMat[kMSkewY] * scale); |
| 916 inv->fMat[kMScaleY] = SkDoubleToFloat(fMat[kMScaleX] * scale); | 837 inv->fMat[kMScaleY] = SkDoubleToFloat(fMat[kMScaleX] * scale); |
| 917 inv->fMat[kMTransY] = mul_diff_scale(fMat[kMSkewY], fMat[kMTransX], | 838 inv->fMat[kMTransY] = mul_diff_scale(fMat[kMSkewY], fMat[kMTransX], |
| 918 fMat[kMScaleX], fMat[kMTransY], scale); | 839 fMat[kMScaleX], fMat[kMTransY], scale); |
| 919 #endif | 840 |
| 920 inv->fMat[kMPersp0] = 0; | 841 inv->fMat[kMPersp0] = 0; |
| 921 inv->fMat[kMPersp1] = 0; | 842 inv->fMat[kMPersp1] = 0; |
| 922 inv->fMat[kMPersp2] = kMatrix22Elem; | 843 inv->fMat[kMPersp2] = kMatrix22Elem; |
| 923 | 844 |
| 924 } | 845 } |
| 925 | 846 |
| 926 inv->setTypeMask(fTypeMask); | 847 inv->setTypeMask(fTypeMask); |
| 927 | 848 |
| 928 if (inv == &tmp) { | 849 if (inv == &tmp) { |
| 929 *(SkMatrix*)this = tmp; | 850 *(SkMatrix*)this = tmp; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 dst->fX = SkScalarMul(sx, mx) + SkScalarMulAdd(sy, kx, tx); | 952 dst->fX = SkScalarMul(sx, mx) + SkScalarMulAdd(sy, kx, tx); |
| 1032 dst += 1; | 953 dst += 1; |
| 1033 } while (--count); | 954 } while (--count); |
| 1034 } | 955 } |
| 1035 } | 956 } |
| 1036 | 957 |
| 1037 void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[], | 958 void SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[], |
| 1038 const SkPoint src[], int count) { | 959 const SkPoint src[], int count) { |
| 1039 SkASSERT(m.hasPerspective()); | 960 SkASSERT(m.hasPerspective()); |
| 1040 | 961 |
| 1041 #ifdef SK_SCALAR_IS_FIXED | |
| 1042 SkFixed persp2 = SkFractToFixed(m.fMat[kMPersp2]); | |
| 1043 #endif | |
| 1044 | |
| 1045 if (count > 0) { | 962 if (count > 0) { |
| 1046 do { | 963 do { |
| 1047 SkScalar sy = src->fY; | 964 SkScalar sy = src->fY; |
| 1048 SkScalar sx = src->fX; | 965 SkScalar sx = src->fX; |
| 1049 src += 1; | 966 src += 1; |
| 1050 | 967 |
| 1051 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + | 968 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + |
| 1052 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; | 969 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; |
| 1053 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + | 970 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + |
| 1054 SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; | 971 SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; |
| 1055 #ifdef SK_SCALAR_IS_FIXED | 972 SkScalar z = SkScalarMul(sx, m.fMat[kMPersp0]) + |
| 1056 SkFixed z = SkFractMul(sx, m.fMat[kMPersp0]) + | 973 SkScalarMulAdd(sy, m.fMat[kMPersp1], m.fMat[kMPersp2]); |
| 1057 SkFractMul(sy, m.fMat[kMPersp1]) + persp2; | |
| 1058 #else | |
| 1059 float z = SkScalarMul(sx, m.fMat[kMPersp0]) + | |
| 1060 SkScalarMulAdd(sy, m.fMat[kMPersp1], m.fMat[kMPersp2]); | |
| 1061 #endif | |
| 1062 if (z) { | 974 if (z) { |
| 1063 z = SkScalarFastInvert(z); | 975 z = SkScalarFastInvert(z); |
| 1064 } | 976 } |
| 1065 | 977 |
| 1066 dst->fY = SkScalarMul(y, z); | 978 dst->fY = SkScalarMul(y, z); |
| 1067 dst->fX = SkScalarMul(x, z); | 979 dst->fX = SkScalarMul(x, z); |
| 1068 dst += 1; | 980 dst += 1; |
| 1069 } while (--count); | 981 } while (--count); |
| 1070 } | 982 } |
| 1071 } | 983 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 /////////////////////////////////////////////////////////////////////////////// | 1096 /////////////////////////////////////////////////////////////////////////////// |
| 1185 | 1097 |
| 1186 void SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1098 void SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
| 1187 SkPoint* pt) { | 1099 SkPoint* pt) { |
| 1188 SkASSERT(m.hasPerspective()); | 1100 SkASSERT(m.hasPerspective()); |
| 1189 | 1101 |
| 1190 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + | 1102 SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + |
| 1191 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; | 1103 SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; |
| 1192 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1104 SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + |
| 1193 SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; | 1105 SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; |
| 1194 #ifdef SK_SCALAR_IS_FIXED | 1106 SkScalar z = SkScalarMul(sx, m.fMat[kMPersp0]) + |
| 1195 SkFixed z = SkFractMul(sx, m.fMat[kMPersp0]) + | 1107 SkScalarMul(sy, m.fMat[kMPersp1]) + m.fMat[kMPersp2]; |
| 1196 SkFractMul(sy, m.fMat[kMPersp1]) + | |
| 1197 SkFractToFixed(m.fMat[kMPersp2]); | |
| 1198 #else | |
| 1199 float z = SkScalarMul(sx, m.fMat[kMPersp0]) + | |
| 1200 SkScalarMul(sy, m.fMat[kMPersp1]) + m.fMat[kMPersp2]; | |
| 1201 #endif | |
| 1202 if (z) { | 1108 if (z) { |
| 1203 z = SkScalarFastInvert(z); | 1109 z = SkScalarFastInvert(z); |
| 1204 } | 1110 } |
| 1205 pt->fX = SkScalarMul(x, z); | 1111 pt->fX = SkScalarMul(x, z); |
| 1206 pt->fY = SkScalarMul(y, z); | 1112 pt->fY = SkScalarMul(y, z); |
| 1207 } | 1113 } |
| 1208 | 1114 |
| 1209 #ifdef SK_SCALAR_IS_FIXED | |
| 1210 static SkFixed fixmuladdmul(SkFixed a, SkFixed b, SkFixed c, SkFixed d) { | |
| 1211 Sk64 tmp, tmp1; | |
| 1212 | |
| 1213 tmp.setMul(a, b); | |
| 1214 tmp1.setMul(c, d); | |
| 1215 return tmp.addGetFixed(tmp1); | |
| 1216 // tmp.add(tmp1); | |
| 1217 // return tmp.getFixed(); | |
| 1218 } | |
| 1219 #endif | |
| 1220 | |
| 1221 void SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1115 void SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
| 1222 SkPoint* pt) { | 1116 SkPoint* pt) { |
| 1223 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask)
; | 1117 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask)
; |
| 1224 | 1118 |
| 1225 #ifdef SK_SCALAR_IS_FIXED | |
| 1226 pt->fX = fixmuladdmul(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + | |
| 1227 m.fMat[kMTransX]; | |
| 1228 pt->fY = fixmuladdmul(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + | |
| 1229 m.fMat[kMTransY]; | |
| 1230 #else | |
| 1231 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + | 1119 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + |
| 1232 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); | 1120 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); |
| 1233 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1121 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + |
| 1234 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); | 1122 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); |
| 1235 #endif | |
| 1236 } | 1123 } |
| 1237 | 1124 |
| 1238 void SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1125 void SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
| 1239 SkPoint* pt) { | 1126 SkPoint* pt) { |
| 1240 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask); | 1127 SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask); |
| 1241 SkASSERT(0 == m.fMat[kMTransX]); | 1128 SkASSERT(0 == m.fMat[kMTransX]); |
| 1242 SkASSERT(0 == m.fMat[kMTransY]); | 1129 SkASSERT(0 == m.fMat[kMTransY]); |
| 1243 | 1130 |
| 1244 #ifdef SK_SCALAR_IS_FIXED | |
| 1245 pt->fX = fixmuladdmul(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]); | |
| 1246 pt->fY = fixmuladdmul(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]); | |
| 1247 #else | |
| 1248 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + | 1131 pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + |
| 1249 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); | 1132 SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); |
| 1250 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + | 1133 pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + |
| 1251 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); | 1134 SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); |
| 1252 #endif | |
| 1253 } | 1135 } |
| 1254 | 1136 |
| 1255 void SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, | 1137 void SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, |
| 1256 SkPoint* pt) { | 1138 SkPoint* pt) { |
| 1257 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) | 1139 SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) |
| 1258 == kScale_Mask); | 1140 == kScale_Mask); |
| 1259 | 1141 |
| 1260 pt->fX = SkScalarMulAdd(sx, m.fMat[kMScaleX], m.fMat[kMTransX]); | 1142 pt->fX = SkScalarMulAdd(sx, m.fMat[kMScaleX], m.fMat[kMTransX]); |
| 1261 pt->fY = SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); | 1143 pt->fY = SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); |
| 1262 } | 1144 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1296 // repeat the persp proc 8 times | 1178 // repeat the persp proc 8 times |
| 1297 SkMatrix::Persp_xy, SkMatrix::Persp_xy, | 1179 SkMatrix::Persp_xy, SkMatrix::Persp_xy, |
| 1298 SkMatrix::Persp_xy, SkMatrix::Persp_xy, | 1180 SkMatrix::Persp_xy, SkMatrix::Persp_xy, |
| 1299 SkMatrix::Persp_xy, SkMatrix::Persp_xy, | 1181 SkMatrix::Persp_xy, SkMatrix::Persp_xy, |
| 1300 SkMatrix::Persp_xy, SkMatrix::Persp_xy | 1182 SkMatrix::Persp_xy, SkMatrix::Persp_xy |
| 1301 }; | 1183 }; |
| 1302 | 1184 |
| 1303 /////////////////////////////////////////////////////////////////////////////// | 1185 /////////////////////////////////////////////////////////////////////////////// |
| 1304 | 1186 |
| 1305 // if its nearly zero (just made up 26, perhaps it should be bigger or smaller) | 1187 // if its nearly zero (just made up 26, perhaps it should be bigger or smaller) |
| 1306 #ifdef SK_SCALAR_IS_FIXED | 1188 #define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26))) |
| 1307 typedef SkFract SkPerspElemType; | |
| 1308 #define PerspNearlyZero(x) (SkAbs32(x) < (SK_Fract1 >> 26)) | |
| 1309 #else | |
| 1310 typedef float SkPerspElemType; | |
| 1311 #define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26))) | |
| 1312 #endif | |
| 1313 | 1189 |
| 1314 bool SkMatrix::fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const { | 1190 bool SkMatrix::fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const { |
| 1315 if (PerspNearlyZero(fMat[kMPersp0])) { | 1191 if (PerspNearlyZero(fMat[kMPersp0])) { |
| 1316 if (stepX || stepY) { | 1192 if (stepX || stepY) { |
| 1317 if (PerspNearlyZero(fMat[kMPersp1]) && | 1193 if (PerspNearlyZero(fMat[kMPersp1]) && |
| 1318 PerspNearlyZero(fMat[kMPersp2] - kMatrix22Elem)) { | 1194 PerspNearlyZero(fMat[kMPersp2] - kMatrix22Elem)) { |
| 1319 if (stepX) { | 1195 if (stepX) { |
| 1320 *stepX = SkScalarToFixed(fMat[kMScaleX]); | 1196 *stepX = SkScalarToFixed(fMat[kMScaleX]); |
| 1321 } | 1197 } |
| 1322 if (stepY) { | 1198 if (stepY) { |
| 1323 *stepY = SkScalarToFixed(fMat[kMSkewY]); | 1199 *stepY = SkScalarToFixed(fMat[kMSkewY]); |
| 1324 } | 1200 } |
| 1325 } else { | 1201 } else { |
| 1326 #ifdef SK_SCALAR_IS_FIXED | 1202 SkScalar z = y * fMat[kMPersp1] + fMat[kMPersp2]; |
| 1327 SkFixed z = SkFractMul(y, fMat[kMPersp1]) + | |
| 1328 SkFractToFixed(fMat[kMPersp2]); | |
| 1329 #else | |
| 1330 float z = y * fMat[kMPersp1] + fMat[kMPersp2]; | |
| 1331 #endif | |
| 1332 if (stepX) { | 1203 if (stepX) { |
| 1333 *stepX = SkScalarToFixed(SkScalarDiv(fMat[kMScaleX], z)); | 1204 *stepX = SkScalarToFixed(SkScalarDiv(fMat[kMScaleX], z)); |
| 1334 } | 1205 } |
| 1335 if (stepY) { | 1206 if (stepY) { |
| 1336 *stepY = SkScalarToFixed(SkScalarDiv(fMat[kMSkewY], z)); | 1207 *stepY = SkScalarToFixed(SkScalarDiv(fMat[kMSkewY], z)); |
| 1337 } | 1208 } |
| 1338 } | 1209 } |
| 1339 } | 1210 } |
| 1340 return true; | 1211 return true; |
| 1341 } | 1212 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1388 *p++ = x; x += dx; | 1259 *p++ = x; x += dx; |
| 1389 *p++ = y; y += dy; | 1260 *p++ = y; y += dy; |
| 1390 } | 1261 } |
| 1391 | 1262 |
| 1392 fCount -= n; | 1263 fCount -= n; |
| 1393 return n; | 1264 return n; |
| 1394 } | 1265 } |
| 1395 | 1266 |
| 1396 /////////////////////////////////////////////////////////////////////////////// | 1267 /////////////////////////////////////////////////////////////////////////////// |
| 1397 | 1268 |
| 1398 #ifdef SK_SCALAR_IS_FIXED | |
| 1399 | |
| 1400 static inline bool poly_to_point(SkPoint* pt, const SkPoint poly[], int count) { | |
| 1401 SkFixed x = SK_Fixed1, y = SK_Fixed1; | |
| 1402 SkPoint pt1, pt2; | |
| 1403 Sk64 w1, w2; | |
| 1404 | |
| 1405 if (count > 1) { | |
| 1406 pt1.fX = poly[1].fX - poly[0].fX; | |
| 1407 pt1.fY = poly[1].fY - poly[0].fY; | |
| 1408 y = SkPoint::Length(pt1.fX, pt1.fY); | |
| 1409 if (y == 0) { | |
| 1410 return false; | |
| 1411 } | |
| 1412 switch (count) { | |
| 1413 case 2: | |
| 1414 break; | |
| 1415 case 3: | |
| 1416 pt2.fX = poly[0].fY - poly[2].fY; | |
| 1417 pt2.fY = poly[2].fX - poly[0].fX; | |
| 1418 goto CALC_X; | |
| 1419 default: | |
| 1420 pt2.fX = poly[0].fY - poly[3].fY; | |
| 1421 pt2.fY = poly[3].fX - poly[0].fX; | |
| 1422 CALC_X: | |
| 1423 w1.setMul(pt1.fX, pt2.fX); | |
| 1424 w2.setMul(pt1.fY, pt2.fY); | |
| 1425 w1.add(w2); | |
| 1426 w1.div(y, Sk64::kRound_DivOption); | |
| 1427 if (!w1.is32()) { | |
| 1428 return false; | |
| 1429 } | |
| 1430 x = w1.get32(); | |
| 1431 break; | |
| 1432 } | |
| 1433 } | |
| 1434 pt->set(x, y); | |
| 1435 return true; | |
| 1436 } | |
| 1437 | |
| 1438 bool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst, | |
| 1439 const SkPoint& scalePt) { | |
| 1440 // need to check if SkFixedDiv overflows... | |
| 1441 | |
| 1442 const SkFixed scale = scalePt.fY; | |
| 1443 dst->fMat[kMScaleX] = SkFixedDiv(srcPt[1].fY - srcPt[0].fY, scale); | |
| 1444 dst->fMat[kMSkewY] = SkFixedDiv(srcPt[0].fX - srcPt[1].fX, scale); | |
| 1445 dst->fMat[kMPersp0] = 0; | |
| 1446 dst->fMat[kMSkewX] = SkFixedDiv(srcPt[1].fX - srcPt[0].fX, scale); | |
| 1447 dst->fMat[kMScaleY] = SkFixedDiv(srcPt[1].fY - srcPt[0].fY, scale); | |
| 1448 dst->fMat[kMPersp1] = 0; | |
| 1449 dst->fMat[kMTransX] = srcPt[0].fX; | |
| 1450 dst->fMat[kMTransY] = srcPt[0].fY; | |
| 1451 dst->fMat[kMPersp2] = SK_Fract1; | |
| 1452 dst->setTypeMask(kUnknown_Mask); | |
| 1453 return true; | |
| 1454 } | |
| 1455 | |
| 1456 bool SkMatrix::Poly3Proc(const SkPoint srcPt[], SkMatrix* dst, | |
| 1457 const SkPoint& scale) { | |
| 1458 // really, need to check if SkFixedDiv overflow'd | |
| 1459 | |
| 1460 dst->fMat[kMScaleX] = SkFixedDiv(srcPt[2].fX - srcPt[0].fX, scale.fX); | |
| 1461 dst->fMat[kMSkewY] = SkFixedDiv(srcPt[2].fY - srcPt[0].fY, scale.fX); | |
| 1462 dst->fMat[kMPersp0] = 0; | |
| 1463 dst->fMat[kMSkewX] = SkFixedDiv(srcPt[1].fX - srcPt[0].fX, scale.fY); | |
| 1464 dst->fMat[kMScaleY] = SkFixedDiv(srcPt[1].fY - srcPt[0].fY, scale.fY); | |
| 1465 dst->fMat[kMPersp1] = 0; | |
| 1466 dst->fMat[kMTransX] = srcPt[0].fX; | |
| 1467 dst->fMat[kMTransY] = srcPt[0].fY; | |
| 1468 dst->fMat[kMPersp2] = SK_Fract1; | |
| 1469 dst->setTypeMask(kUnknown_Mask); | |
| 1470 return true; | |
| 1471 } | |
| 1472 | |
| 1473 bool SkMatrix::Poly4Proc(const SkPoint srcPt[], SkMatrix* dst, | |
| 1474 const SkPoint& scale) { | |
| 1475 SkFract a1, a2; | |
| 1476 SkFixed x0, y0, x1, y1, x2, y2; | |
| 1477 | |
| 1478 x0 = srcPt[2].fX - srcPt[0].fX; | |
| 1479 y0 = srcPt[2].fY - srcPt[0].fY; | |
| 1480 x1 = srcPt[2].fX - srcPt[1].fX; | |
| 1481 y1 = srcPt[2].fY - srcPt[1].fY; | |
| 1482 x2 = srcPt[2].fX - srcPt[3].fX; | |
| 1483 y2 = srcPt[2].fY - srcPt[3].fY; | |
| 1484 | |
| 1485 /* check if abs(x2) > abs(y2) */ | |
| 1486 if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) { | |
| 1487 SkFixed denom = SkMulDiv(x1, y2, x2) - y1; | |
| 1488 if (0 == denom) { | |
| 1489 return false; | |
| 1490 } | |
| 1491 a1 = SkFractDiv(SkMulDiv(x0 - x1, y2, x2) - y0 + y1, denom); | |
| 1492 } else { | |
| 1493 SkFixed denom = x1 - SkMulDiv(y1, x2, y2); | |
| 1494 if (0 == denom) { | |
| 1495 return false; | |
| 1496 } | |
| 1497 a1 = SkFractDiv(x0 - x1 - SkMulDiv(y0 - y1, x2, y2), denom); | |
| 1498 } | |
| 1499 | |
| 1500 /* check if abs(x1) > abs(y1) */ | |
| 1501 if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) { | |
| 1502 SkFixed denom = y2 - SkMulDiv(x2, y1, x1); | |
| 1503 if (0 == denom) { | |
| 1504 return false; | |
| 1505 } | |
| 1506 a2 = SkFractDiv(y0 - y2 - SkMulDiv(x0 - x2, y1, x1), denom); | |
| 1507 } else { | |
| 1508 SkFixed denom = SkMulDiv(y2, x1, y1) - x2; | |
| 1509 if (0 == denom) { | |
| 1510 return false; | |
| 1511 } | |
| 1512 a2 = SkFractDiv(SkMulDiv(y0 - y2, x1, y1) - x0 + x2, denom); | |
| 1513 } | |
| 1514 | |
| 1515 // need to check if SkFixedDiv overflows... | |
| 1516 dst->fMat[kMScaleX] = SkFixedDiv(SkFractMul(a2, srcPt[3].fX) + | |
| 1517 srcPt[3].fX - srcPt[0].fX, scale.fX); | |
| 1518 dst->fMat[kMSkewY] = SkFixedDiv(SkFractMul(a2, srcPt[3].fY) + | |
| 1519 srcPt[3].fY - srcPt[0].fY, scale.fX); | |
| 1520 dst->fMat[kMPersp0] = SkFixedDiv(a2, scale.fX); | |
| 1521 dst->fMat[kMSkewX] = SkFixedDiv(SkFractMul(a1, srcPt[1].fX) + | |
| 1522 srcPt[1].fX - srcPt[0].fX, scale.fY); | |
| 1523 dst->fMat[kMScaleY] = SkFixedDiv(SkFractMul(a1, srcPt[1].fY) + | |
| 1524 srcPt[1].fY - srcPt[0].fY, scale.fY); | |
| 1525 dst->fMat[kMPersp1] = SkFixedDiv(a1, scale.fY); | |
| 1526 dst->fMat[kMTransX] = srcPt[0].fX; | |
| 1527 dst->fMat[kMTransY] = srcPt[0].fY; | |
| 1528 dst->fMat[kMPersp2] = SK_Fract1; | |
| 1529 dst->setTypeMask(kUnknown_Mask); | |
| 1530 return true; | |
| 1531 } | |
| 1532 | |
| 1533 #else /* Scalar is float */ | |
| 1534 | |
| 1535 static inline bool checkForZero(float x) { | 1269 static inline bool checkForZero(float x) { |
| 1536 return x*x == 0; | 1270 return x*x == 0; |
| 1537 } | 1271 } |
| 1538 | 1272 |
| 1539 static inline bool poly_to_point(SkPoint* pt, const SkPoint poly[], int count) { | 1273 static inline bool poly_to_point(SkPoint* pt, const SkPoint poly[], int count) { |
| 1540 float x = 1, y = 1; | 1274 float x = 1, y = 1; |
| 1541 SkPoint pt1, pt2; | 1275 SkPoint pt1, pt2; |
| 1542 | 1276 |
| 1543 if (count > 1) { | 1277 if (count > 1) { |
| 1544 pt1.fX = poly[1].fX - poly[0].fX; | 1278 pt1.fX = poly[1].fX - poly[0].fX; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1657 dst->fMat[kMScaleY] = SkScalarMul(SkScalarMul(a1, srcPt[1].fY) + | 1391 dst->fMat[kMScaleY] = SkScalarMul(SkScalarMul(a1, srcPt[1].fY) + |
| 1658 srcPt[1].fY - srcPt[0].fY, invScale); | 1392 srcPt[1].fY - srcPt[0].fY, invScale); |
| 1659 dst->fMat[kMPersp1] = SkScalarMul(a1, invScale); | 1393 dst->fMat[kMPersp1] = SkScalarMul(a1, invScale); |
| 1660 dst->fMat[kMTransX] = srcPt[0].fX; | 1394 dst->fMat[kMTransX] = srcPt[0].fX; |
| 1661 dst->fMat[kMTransY] = srcPt[0].fY; | 1395 dst->fMat[kMTransY] = srcPt[0].fY; |
| 1662 dst->fMat[kMPersp2] = 1; | 1396 dst->fMat[kMPersp2] = 1; |
| 1663 dst->setTypeMask(kUnknown_Mask); | 1397 dst->setTypeMask(kUnknown_Mask); |
| 1664 return true; | 1398 return true; |
| 1665 } | 1399 } |
| 1666 | 1400 |
| 1667 #endif | |
| 1668 | |
| 1669 typedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*, const SkPoint&); | 1401 typedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*, const SkPoint&); |
| 1670 | 1402 |
| 1671 /* Taken from Rob Johnson's original sample code in QuickDraw GX | 1403 /* Taken from Rob Johnson's original sample code in QuickDraw GX |
| 1672 */ | 1404 */ |
| 1673 bool SkMatrix::setPolyToPoly(const SkPoint src[], const SkPoint dst[], | 1405 bool SkMatrix::setPolyToPoly(const SkPoint src[], const SkPoint dst[], |
| 1674 int count) { | 1406 int count) { |
| 1675 if ((unsigned)count > 4) { | 1407 if ((unsigned)count > 4) { |
| 1676 SkDebugf("--- SkMatrix::setPolyToPoly count out of range %d\n", count); | 1408 SkDebugf("--- SkMatrix::setPolyToPoly count out of range %d\n", count); |
| 1677 return false; | 1409 return false; |
| 1678 } | 1410 } |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1994 rotation1->fX = cos1; | 1726 rotation1->fX = cos1; |
| 1995 rotation1->fY = sin1; | 1727 rotation1->fY = sin1; |
| 1996 } | 1728 } |
| 1997 if (NULL != rotation2) { | 1729 if (NULL != rotation2) { |
| 1998 rotation2->fX = cos2; | 1730 rotation2->fX = cos2; |
| 1999 rotation2->fY = sin2; | 1731 rotation2->fY = sin2; |
| 2000 } | 1732 } |
| 2001 | 1733 |
| 2002 return true; | 1734 return true; |
| 2003 } | 1735 } |
| OLD | NEW |