1 #include "SkMatrix.h" 2 3 #ifdef SK_SCALAR_IS_FIXED 4 typedef int64_t SkDScalar; 5 6 static SkScalar SkDScalar_toScalar(SkDScalar value) { 7 SkDScalar result = (value + (1 << 15)) >> 16; 8 int top = result >> 31; 9 SkASSERT(top == 0 || top == -1); 10 return (SkScalar)result; 11 } 12 static SkScalar div(SkDScalar numer, SkDScalar denom) { 13 denom >>= 16; 14 return numer / denom; 15 } 16 #else 17 typedef double SkDScalar; 18 19 static SkScalar SkDScalar_toScalar(SkDScalar value) { 20 return static_cast<float>(value); 21 } 22 static SkScalar div(SkDScalar numer, SkDScalar denom) { 23 return static_cast<float>(numer / denom); 24 } 25 #endif 26 27 static SkDScalar SkDScalar_setMul(SkScalar a, SkScalar b) { 28 return (SkDScalar)a * b; 29 } 30 31 static void computeOuterProduct(SkScalar op[4], 32 const SkPoint pts0[3], const SkPoint& ave0, 33 const SkPoint pts1[3], const SkPoint& ave1) { 34 sk_bzero(op, 4 * sizeof(op[0])); 35 for (int i = 0; i < 3; i++) { 36 SkScalar x0 = pts0[i].fX - ave0.fX; 37 SkScalar y0 = pts0[i].fY - ave0.fY; 38 SkScalar x1 = pts1[i].fX - ave1.fX; 39 SkScalar y1 = pts1[i].fY - ave1.fY; 40 op[0] += SkScalarMul(x0, x1); 41 op[1] += SkScalarMul(x0, y1); 42 op[2] += SkScalarMul(y0, x1); 43 op[3] += SkScalarMul(y0, y1); 44 } 45 } 46 47 static SkDScalar ddot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) { 48 return SkDScalar_setMul(ax, bx) + SkDScalar_setMul(ay, by); 49 } 50 51 static SkScalar dot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) { 52 return SkDScalar_toScalar(ddot(ax, ay, bx, by)); 53 } 54 55 bool SkSetPoly3To3(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]) { 56 const SkPoint& srcAve = src[0]; 57 const SkPoint& dstAve = dst[0]; 58 59 SkScalar srcOP[4], dstOP[4]; 60 61 computeOuterProduct(srcOP, src, srcAve, src, srcAve); 62 computeOuterProduct(dstOP, src, srcAve, dst, dstAve); 63 64 SkDScalar det = SkDScalar_setMul(srcOP[0], srcOP[3]) - 65 SkDScalar_setMul(srcOP[1], srcOP[2]); 66 67 SkDScalar M[4]; 68 69 const SkScalar srcOP0 = srcOP[3]; 70 const SkScalar srcOP1 = -srcOP[1]; 71 const SkScalar srcOP2 = -srcOP[2]; 72 const SkScalar srcOP3 = srcOP[0]; 73 74 M[0] = ddot(srcOP0, srcOP1, dstOP[0], dstOP[2]); 75 M[1] = ddot(srcOP2, srcOP3, dstOP[0], dstOP[2]); 76 M[2] = ddot(srcOP0, srcOP1, dstOP[1], dstOP[3]); 77 M[3] = ddot(srcOP2, srcOP3, dstOP[1], dstOP[3]); 78 79 matrix->reset(); 80 matrix->setScaleX(div(M[0], det)); 81 matrix->setSkewX( div(M[1], det)); 82 matrix->setSkewY (div(M[2], det)); 83 matrix->setScaleY(div(M[3], det)); 84 matrix->setTranslateX(dstAve.fX - dot(srcAve.fX, srcAve.fY, 85 matrix->getScaleX(), matrix->getSkewX())); 86 matrix->setTranslateY(dstAve.fY - dot(srcAve.fX, srcAve.fY, 87 matrix->getSkewY(), matrix->getScaleY())); 88 return true; 89 } 90 91