• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SkMatrix.h"
2 
computeOuterProduct(SkScalar op[4],const SkPoint pts0[3],const SkPoint & ave0,const SkPoint pts1[3],const SkPoint & ave1)3 static void computeOuterProduct(SkScalar op[4],
4                                 const SkPoint pts0[3], const SkPoint& ave0,
5                                 const SkPoint pts1[3], const SkPoint& ave1) {
6     bzero(op, 4 * sizeof(op[0]));
7     for (int i = 0; i < 3; i++) {
8         SkScalar x0 = pts0[i].fX - ave0.fX;
9         SkScalar y0 = pts0[i].fY - ave0.fY;
10         SkScalar x1 = pts1[i].fX - ave1.fX;
11         SkScalar y1 = pts1[i].fY - ave1.fY;
12         op[0] += SkScalarMul(x0, x1);
13         op[1] += SkScalarMul(x0, y1);
14         op[2] += SkScalarMul(y0, x1);
15         op[3] += SkScalarMul(y0, y1);
16     }
17 }
18 
dot(SkScalar ax,SkScalar ay,SkScalar bx,SkScalar by)19 static SkScalar dot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) {
20     return SkScalarMul(ax, bx) + SkScalarMul(ay, by);
21 }
22 
SkSetPoly3To3(SkMatrix * matrix,const SkPoint src[3],const SkPoint dst[3])23 bool SkSetPoly3To3(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]) {
24     const SkPoint& srcAve = src[0];
25     const SkPoint& dstAve = dst[0];
26 
27     SkScalar srcOP[4], dstOP[4];
28 
29     computeOuterProduct(srcOP, src, srcAve, src, srcAve);
30     computeOuterProduct(dstOP, src, srcAve, dst, dstAve);
31 
32     SkScalar det = SkScalarMul(srcOP[0], srcOP[3]) - SkScalarMul(srcOP[1], srcOP[2]);
33 
34     // need SkScalarNearlyZeroSquared for this (to match Chrome's fix)
35     if (SkScalarNearlyZero(det)) {
36         return false;
37     }
38 
39     SkScalar invDet = SkScalarInvert(det);
40 
41     // now compute invDet * [srcOP]T * [dstOP]
42 
43     // scale and transpose
44     const SkScalar srcOP0 = SkScalarMul( srcOP[3], invDet);
45     const SkScalar srcOP1 = SkScalarMul(-srcOP[1], invDet);
46     const SkScalar srcOP2 = SkScalarMul(-srcOP[2], invDet);
47     const SkScalar srcOP3 = SkScalarMul( srcOP[0], invDet);
48 
49     matrix->reset();
50     matrix->setScaleX(dot(srcOP0, srcOP1, dstOP[0], dstOP[2]));
51     matrix->setSkewX( dot(srcOP2, srcOP3, dstOP[0], dstOP[2]));
52     matrix->setSkewY (dot(srcOP0, srcOP1, dstOP[1], dstOP[3]));
53     matrix->setScaleY(dot(srcOP2, srcOP3, dstOP[1], dstOP[3]));
54     matrix->setTranslateX(dstAve.fX - dot(srcAve.fX, srcAve.fY,
55                                     matrix->getScaleX(), matrix->getSkewX()));
56     matrix->setTranslateY(dstAve.fY - dot(srcAve.fX, srcAve.fY,
57                                     matrix->getSkewY(), matrix->getScaleY()));
58     return true;
59 }
60 
61