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 |