SkSetPoly3To3_A.cpp revision 525644095b9b30923560fc933550f16127962a5f
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h" 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_SCALAR_IS_FIXED 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef int64_t SkDScalar; 58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static SkScalar SkDScalar_toScalar(SkDScalar value) { 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar result = (value + (1 << 15)) >> 16; 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int top = result >> 31; 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(top == 0 || top == -1); 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (SkScalar)result; 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12525644095b9b30923560fc933550f16127962a5fepoger@google.com static SkScalar divide(SkDScalar numer, SkDScalar denom) { 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com denom >>= 16; 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return numer / denom; 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef double SkDScalar; 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static SkScalar SkDScalar_toScalar(SkDScalar value) { 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return static_cast<float>(value); 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22525644095b9b30923560fc933550f16127962a5fepoger@google.com static SkScalar divide(SkDScalar numer, SkDScalar denom) { 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return static_cast<float>(numer / denom); 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkDScalar SkDScalar_setMul(SkScalar a, SkScalar b) { 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (SkDScalar)a * b; 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void computeOuterProduct(SkScalar op[4], 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint pts0[3], const SkPoint& ave0, 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint pts1[3], const SkPoint& ave1) { 344516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com sk_bzero(op, 4 * sizeof(op[0])); 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 3; i++) { 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x0 = pts0[i].fX - ave0.fX; 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar y0 = pts0[i].fY - ave0.fY; 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x1 = pts1[i].fX - ave1.fX; 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar y1 = pts1[i].fY - ave1.fY; 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com op[0] += SkScalarMul(x0, x1); 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com op[1] += SkScalarMul(x0, y1); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com op[2] += SkScalarMul(y0, x1); 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com op[3] += SkScalarMul(y0, y1); 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkDScalar ddot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) { 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkDScalar_setMul(ax, bx) + SkDScalar_setMul(ay, by); 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar dot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) { 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkDScalar_toScalar(ddot(ax, ay, bx, by)); 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkSetPoly3To3(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]) { 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint& srcAve = src[0]; 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint& dstAve = dst[0]; 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar srcOP[4], dstOP[4]; 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com computeOuterProduct(srcOP, src, srcAve, src, srcAve); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com computeOuterProduct(dstOP, src, srcAve, dst, dstAve); 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar det = SkDScalar_setMul(srcOP[0], srcOP[3]) - 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar_setMul(srcOP[1], srcOP[2]); 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar M[4]; 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar srcOP0 = srcOP[3]; 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar srcOP1 = -srcOP[1]; 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar srcOP2 = -srcOP[2]; 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar srcOP3 = srcOP[0]; 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com M[0] = ddot(srcOP0, srcOP1, dstOP[0], dstOP[2]); 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com M[1] = ddot(srcOP2, srcOP3, dstOP[0], dstOP[2]); 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com M[2] = ddot(srcOP0, srcOP1, dstOP[1], dstOP[3]); 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com M[3] = ddot(srcOP2, srcOP3, dstOP[1], dstOP[3]); 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->reset(); 80525644095b9b30923560fc933550f16127962a5fepoger@google.com matrix->setScaleX(divide(M[0], det)); 81525644095b9b30923560fc933550f16127962a5fepoger@google.com matrix->setSkewX( divide(M[1], det)); 82525644095b9b30923560fc933550f16127962a5fepoger@google.com matrix->setSkewY (divide(M[2], det)); 83525644095b9b30923560fc933550f16127962a5fepoger@google.com matrix->setScaleY(divide(M[3], det)); 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setTranslateX(dstAve.fX - dot(srcAve.fX, srcAve.fY, 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->getScaleX(), matrix->getSkewX())); 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setTranslateY(dstAve.fY - dot(srcAve.fX, srcAve.fY, 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->getSkewY(), matrix->getScaleY())); 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 91