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_D(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]); 129da0cea3a32e274ad8b40174a25e5f8c532fbd9bcaryclark@google.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef int64_t SkDScalar; 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar SkDScalar_toScalar(SkDScalar value) { 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar result = (value + (1 << 15)) >> 16; 178e06dabfe643b483fd59eb0a511b4b23ba640ba7bsalomon@google.com SkDEBUGCODE(int top = static_cast<int>(result >> 31);) 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(top == 0 || top == -1); 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (SkScalar)result; 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkDScalar SkDScalar_setMul(SkScalar a, SkScalar b) { 239da0cea3a32e274ad8b40174a25e5f8c532fbd9bcaryclark@google.com return (SkDScalar) ((SkDScalar) a * (SkDScalar) b); 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void computeOuterProduct(SkMatrix* matrix, 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint pts0[3], const SkPoint& ave0, 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint pts1[3], const SkPoint& ave1) { 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar tmp[4]; 304516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com sk_bzero(tmp, sizeof(tmp)); 31d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 3; i++) { 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x0 = pts0[i].fX - ave0.fX; 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar y0 = pts0[i].fY - ave0.fY; 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x1 = pts1[i].fX - ave1.fX; 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar y1 = pts1[i].fY - ave1.fY; 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp[0] += SkDScalar_setMul(x0, x1); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp[1] += SkDScalar_setMul(x0, y1); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp[2] += SkDScalar_setMul(y0, x1); 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp[3] += SkDScalar_setMul(y0, y1); 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->reset(); 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setScaleX(SkDScalar_toScalar(tmp[0])); 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setSkewY( SkDScalar_toScalar(tmp[1])); 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setSkewX( SkDScalar_toScalar(tmp[2])); 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setScaleY(SkDScalar_toScalar(tmp[3])); 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkScalar dot(SkScalar ax, SkScalar ay, SkScalar bx, SkScalar by) { 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkDScalar_toScalar(SkDScalar_setMul(ax, bx) + 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDScalar_setMul(ay, by)); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 548637a365518a82901d313d61eecd83a0c5102fe9robertphillips@google.combool SkSetPoly3To3_D(SkMatrix* matrix, const SkPoint src[3], const SkPoint dst[3]) { 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint& srcAve = src[0]; 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint& dstAve = dst[0]; 57d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix srcOP, dstOP; 59d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com computeOuterProduct(&srcOP, src, srcAve, src, srcAve); 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!srcOP.invert(&srcOP)) { 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com computeOuterProduct(&dstOP, src, srcAve, dst, dstAve); 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setConcat(dstOP, srcOP); 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setTranslateX(dstAve.fX - dot(srcAve.fX, srcAve.fY, 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->getScaleX(), matrix->getSkewX())); 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->setTranslateY(dstAve.fY - dot(srcAve.fX, srcAve.fY, 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix->getSkewY(), matrix->getScaleY())); 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 75