Home | History | Annotate | Download | only in experimental
      1 #include "SkMatrix.h"
      2 
      3 typedef int64_t SkDScalar;
      4 
      5 static SkScalar SkDScalar_toScalar(SkDScalar value) {
      6     SkDScalar result = (value + (1 << 15)) >> 16;
      7     int top = result >> 31;
      8     SkASSERT(top == 0 || top == -1);
      9     return (SkScalar)result;
     10 }
     11 
     12 static SkDScalar SkDScalar_setMul(SkScalar a, SkScalar b) {
     13     return (SkDScalar)a * b;
     14 }
     15 
     16 static void computeOuterProduct(SkMatrix* matrix,
     17                                 const SkPoint pts0[3], const SkPoint& ave0,
     18                                 const SkPoint pts1[3], const SkPoint& ave1) {
     19     SkDScalar tmp[4];
     20     sk_bzero(tmp, sizeof(tmp));
     21 
     22     for (int i = 0; i < 3; i++) {
     23         SkScalar x0 = pts0[i].fX - ave0.fX;
     24         SkScalar y0 = pts0[i].fY - ave0.fY;
     25         SkScalar x1 = pts1[i].fX - ave1.fX;
     26         SkScalar y1 = pts1[i].fY - ave1.fY;
     27         tmp[0] += SkDScalar_setMul(x0, x1);
     28         tmp[1] += SkDScalar_setMul(x0, y1);
     29         tmp[2] += SkDScalar_setMul(y0, x1);
     30         tmp[3] += SkDScalar_setMul(y0, y1);
     31     }
     32     matrix->reset();
     33     matrix->setScaleX(SkDScalar_toScalar(tmp[0]));
     34     matrix->setSkewY( SkDScalar_toScalar(tmp[1]));
     35     matrix->setSkewX( SkDScalar_toScalar(tmp[2]));
     36     matrix->setScaleY(SkDScalar_toScalar(tmp[3]));
     37 }
     38 
     39 static SkScalar dot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) {
     40     return SkDScalar_toScalar(SkDScalar_setMul(ax, bx) +
     41                               SkDScalar_setMul(ay, by));
     42 }
     43 
     44 bool SkSetPoly3To3(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]) {
     45     const SkPoint& srcAve = src[0];
     46     const SkPoint& dstAve = dst[0];
     47 
     48     SkMatrix srcOP, dstOP;
     49 
     50     computeOuterProduct(&srcOP, src, srcAve, src, srcAve);
     51 
     52     if (!srcOP.invert(&srcOP)) {
     53         return false;
     54     }
     55 
     56     computeOuterProduct(&dstOP, src, srcAve, dst, dstAve);
     57 
     58     matrix->setConcat(dstOP, srcOP);
     59     matrix->setTranslateX(dstAve.fX - dot(srcAve.fX, srcAve.fY,
     60                                     matrix->getScaleX(), matrix->getSkewX()));
     61     matrix->setTranslateY(dstAve.fY - dot(srcAve.fX, srcAve.fY,
     62                                     matrix->getSkewY(), matrix->getScaleY()));
     63     return true;
     64 }
     65 
     66