1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 109da0cea3a32e274ad8b40174a25e5f8c532fbd9bcaryclark@google.com// FIXME: needs to be in a header 119da0cea3a32e274ad8b40174a25e5f8c532fbd9bcaryclark@google.combool SkSetPoly3To3_A(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]); 129da0cea3a32e274ad8b40174a25e5f8c532fbd9bcaryclark@google.com 138f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.comtypedef double SkDScalar; 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.comstatic SkScalar SkDScalar_toScalar(SkDScalar value) { 168f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com return static_cast<float>(value); 178f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com} 188f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.comstatic SkScalar divide(SkDScalar numer, SkDScalar denom) { 198f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com return static_cast<float>(numer / denom); 208f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com} 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkDScalar SkDScalar_setMul(SkScalar a, SkScalar b) { 238637a365518a82901d313d61eecd83a0c5102fe9robertphillips@google.com return (SkDScalar) ((SkDScalar) a * b); 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void computeOuterProduct(SkScalar op[4], 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint pts0[3], const SkPoint& ave0, 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint pts1[3], const SkPoint& ave1) { 294516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com sk_bzero(op, 4 * sizeof(op[0])); 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 3; i++) { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x0 = pts0[i].fX - ave0.fX; 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar y0 = pts0[i].fY - ave0.fY; 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x1 = pts1[i].fX - ave1.fX; 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar y1 = pts1[i].fY - ave1.fY; 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com op[0] += SkScalarMul(x0, x1); 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com op[1] += SkScalarMul(x0, y1); 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com op[2] += SkScalarMul(y0, x1); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com op[3] += SkScalarMul(y0, y1); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkDScalar ddot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) { 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkDScalar_setMul(ax, bx) + SkDScalar_setMul(ay, by); 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar dot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) { 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkDScalar_toScalar(ddot(ax, ay, bx, by)); 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 508637a365518a82901d313d61eecd83a0c5102fe9robertphillips@google.combool SkSetPoly3To3_A(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]) { 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint& srcAve = src[0]; 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint& dstAve = dst[0]; 53d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar srcOP[4], dstOP[4]; 55d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com computeOuterProduct(srcOP, src, srcAve, src, srcAve); 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com computeOuterProduct(dstOP, src, srcAve, dst, dstAve); 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar det = SkDScalar_setMul(srcOP[0], srcOP[3]) - 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar_setMul(srcOP[1], srcOP[2]); 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar M[4]; 63d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar srcOP0 = srcOP[3]; 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar srcOP1 = -srcOP[1]; 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar srcOP2 = -srcOP[2]; 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalar srcOP3 = srcOP[0]; 68d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com M[0] = ddot(srcOP0, srcOP1, dstOP[0], dstOP[2]); 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com M[1] = ddot(srcOP2, srcOP3, dstOP[0], dstOP[2]); 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com M[2] = ddot(srcOP0, srcOP1, dstOP[1], dstOP[3]); 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com M[3] = ddot(srcOP2, srcOP3, dstOP[1], dstOP[3]); 73d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->reset(); 75525644095b9b30923560fc933550f16127962a5fepoger@google.com matrix->setScaleX(divide(M[0], det)); 76525644095b9b30923560fc933550f16127962a5fepoger@google.com matrix->setSkewX( divide(M[1], det)); 77525644095b9b30923560fc933550f16127962a5fepoger@google.com matrix->setSkewY (divide(M[2], det)); 78525644095b9b30923560fc933550f16127962a5fepoger@google.com matrix->setScaleY(divide(M[3], det)); 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setTranslateX(dstAve.fX - dot(srcAve.fX, srcAve.fY, 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->getScaleX(), matrix->getSkewX())); 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setTranslateY(dstAve.fY - dot(srcAve.fX, srcAve.fY, 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->getSkewY(), matrix->getScaleY())); 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 85