1a39667c848146d9070e1a45662fb292d8e6bb8fbreed/* 2a39667c848146d9070e1a45662fb292d8e6bb8fbreed * Copyright 2016 Google Inc. 3a39667c848146d9070e1a45662fb292d8e6bb8fbreed * 4a39667c848146d9070e1a45662fb292d8e6bb8fbreed * Use of this source code is governed by a BSD-style license that can be 5a39667c848146d9070e1a45662fb292d8e6bb8fbreed * found in the LICENSE file. 6a39667c848146d9070e1a45662fb292d8e6bb8fbreed */ 7a39667c848146d9070e1a45662fb292d8e6bb8fbreed 8a39667c848146d9070e1a45662fb292d8e6bb8fbreed#ifndef SkMatrixPriv_DEFINE 9a39667c848146d9070e1a45662fb292d8e6bb8fbreed#define SkMatrixPriv_DEFINE 10a39667c848146d9070e1a45662fb292d8e6bb8fbreed 11a39667c848146d9070e1a45662fb292d8e6bb8fbreed#include "SkMatrix.h" 12a39667c848146d9070e1a45662fb292d8e6bb8fbreed#include "SkNx.h" 13a39667c848146d9070e1a45662fb292d8e6bb8fbreed 14a39667c848146d9070e1a45662fb292d8e6bb8fbreedclass SkMatrixPriv { 15a39667c848146d9070e1a45662fb292d8e6bb8fbreedpublic: 16a39667c848146d9070e1a45662fb292d8e6bb8fbreed /** 17a39667c848146d9070e1a45662fb292d8e6bb8fbreed * Attempt to map the rect through the inverse of the matrix. If it is not invertible, 18a39667c848146d9070e1a45662fb292d8e6bb8fbreed * then this returns false and dst is unchanged. 19a39667c848146d9070e1a45662fb292d8e6bb8fbreed */ 20a39667c848146d9070e1a45662fb292d8e6bb8fbreed static bool SK_WARN_UNUSED_RESULT InverseMapRect(const SkMatrix& mx, 21a39667c848146d9070e1a45662fb292d8e6bb8fbreed SkRect* dst, const SkRect& src) { 22a39667c848146d9070e1a45662fb292d8e6bb8fbreed if (mx.getType() <= SkMatrix::kTranslate_Mask) { 23a39667c848146d9070e1a45662fb292d8e6bb8fbreed SkScalar tx = mx.getTranslateX(); 24a39667c848146d9070e1a45662fb292d8e6bb8fbreed SkScalar ty = mx.getTranslateY(); 25a39667c848146d9070e1a45662fb292d8e6bb8fbreed Sk4f trans(tx, ty, tx, ty); 26a39667c848146d9070e1a45662fb292d8e6bb8fbreed (Sk4f::Load(&src.fLeft) - trans).store(&dst->fLeft); 27a39667c848146d9070e1a45662fb292d8e6bb8fbreed return true; 28a39667c848146d9070e1a45662fb292d8e6bb8fbreed } 29a39667c848146d9070e1a45662fb292d8e6bb8fbreed // Insert other special-cases here (e.g. scale+translate) 30a39667c848146d9070e1a45662fb292d8e6bb8fbreed 31a39667c848146d9070e1a45662fb292d8e6bb8fbreed // general case 32a39667c848146d9070e1a45662fb292d8e6bb8fbreed SkMatrix inverse; 33a39667c848146d9070e1a45662fb292d8e6bb8fbreed if (mx.invert(&inverse)) { 34a39667c848146d9070e1a45662fb292d8e6bb8fbreed inverse.mapRect(dst, src); 35a39667c848146d9070e1a45662fb292d8e6bb8fbreed return true; 36a39667c848146d9070e1a45662fb292d8e6bb8fbreed } 37a39667c848146d9070e1a45662fb292d8e6bb8fbreed return false; 38a39667c848146d9070e1a45662fb292d8e6bb8fbreed } 39a39667c848146d9070e1a45662fb292d8e6bb8fbreed 40a39667c848146d9070e1a45662fb292d8e6bb8fbreed static void MapPointsWithStride(const SkMatrix& mx, SkPoint pts[], size_t stride, int count) { 41a39667c848146d9070e1a45662fb292d8e6bb8fbreed SkASSERT(stride >= sizeof(SkPoint)); 42a39667c848146d9070e1a45662fb292d8e6bb8fbreed SkASSERT(0 == stride % sizeof(SkScalar)); 43a39667c848146d9070e1a45662fb292d8e6bb8fbreed 44a39667c848146d9070e1a45662fb292d8e6bb8fbreed SkMatrix::TypeMask tm = mx.getType(); 45a39667c848146d9070e1a45662fb292d8e6bb8fbreed 46a39667c848146d9070e1a45662fb292d8e6bb8fbreed if (SkMatrix::kIdentity_Mask == tm) { 47a39667c848146d9070e1a45662fb292d8e6bb8fbreed return; 48a39667c848146d9070e1a45662fb292d8e6bb8fbreed } 49a39667c848146d9070e1a45662fb292d8e6bb8fbreed if (SkMatrix::kTranslate_Mask == tm) { 50a39667c848146d9070e1a45662fb292d8e6bb8fbreed const SkScalar tx = mx.getTranslateX(); 51a39667c848146d9070e1a45662fb292d8e6bb8fbreed const SkScalar ty = mx.getTranslateY(); 52a39667c848146d9070e1a45662fb292d8e6bb8fbreed Sk2s trans(tx, ty); 53a39667c848146d9070e1a45662fb292d8e6bb8fbreed for (int i = 0; i < count; ++i) { 54a39667c848146d9070e1a45662fb292d8e6bb8fbreed (Sk2s::Load(&pts->fX) + trans).store(&pts->fX); 55a39667c848146d9070e1a45662fb292d8e6bb8fbreed pts = (SkPoint*)((intptr_t)pts + stride); 56a39667c848146d9070e1a45662fb292d8e6bb8fbreed } 57a39667c848146d9070e1a45662fb292d8e6bb8fbreed return; 58a39667c848146d9070e1a45662fb292d8e6bb8fbreed } 59a39667c848146d9070e1a45662fb292d8e6bb8fbreed // Insert other special-cases here (e.g. scale+translate) 60a39667c848146d9070e1a45662fb292d8e6bb8fbreed 61a39667c848146d9070e1a45662fb292d8e6bb8fbreed // general case 62a39667c848146d9070e1a45662fb292d8e6bb8fbreed SkMatrix::MapXYProc proc = mx.getMapXYProc(); 63a39667c848146d9070e1a45662fb292d8e6bb8fbreed for (int i = 0; i < count; ++i) { 64a39667c848146d9070e1a45662fb292d8e6bb8fbreed proc(mx, pts->fX, pts->fY, pts); 65a39667c848146d9070e1a45662fb292d8e6bb8fbreed pts = (SkPoint*)((intptr_t)pts + stride); 66a39667c848146d9070e1a45662fb292d8e6bb8fbreed } 67a39667c848146d9070e1a45662fb292d8e6bb8fbreed } 686a88206b2ece8b64534c87fca156e5fe161f884ereed 696a88206b2ece8b64534c87fca156e5fe161f884ereed static void SetMappedRectFan(const SkMatrix& mx, const SkRect& rect, SkPoint quad[4]) { 706a88206b2ece8b64534c87fca156e5fe161f884ereed SkMatrix::TypeMask tm = mx.getType(); 716a88206b2ece8b64534c87fca156e5fe161f884ereed SkScalar l = rect.fLeft; 726a88206b2ece8b64534c87fca156e5fe161f884ereed SkScalar t = rect.fTop; 736a88206b2ece8b64534c87fca156e5fe161f884ereed SkScalar r = rect.fRight; 746a88206b2ece8b64534c87fca156e5fe161f884ereed SkScalar b = rect.fBottom; 756a88206b2ece8b64534c87fca156e5fe161f884ereed if (tm <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) { 766a88206b2ece8b64534c87fca156e5fe161f884ereed const SkScalar tx = mx.getTranslateX(); 776a88206b2ece8b64534c87fca156e5fe161f884ereed const SkScalar ty = mx.getTranslateY(); 786a88206b2ece8b64534c87fca156e5fe161f884ereed if (tm <= SkMatrix::kTranslate_Mask) { 796a88206b2ece8b64534c87fca156e5fe161f884ereed l += tx; 806a88206b2ece8b64534c87fca156e5fe161f884ereed t += ty; 816a88206b2ece8b64534c87fca156e5fe161f884ereed r += tx; 826a88206b2ece8b64534c87fca156e5fe161f884ereed b += ty; 836a88206b2ece8b64534c87fca156e5fe161f884ereed } else { 846a88206b2ece8b64534c87fca156e5fe161f884ereed const SkScalar sx = mx.getScaleX(); 856a88206b2ece8b64534c87fca156e5fe161f884ereed const SkScalar sy = mx.getScaleY(); 866a88206b2ece8b64534c87fca156e5fe161f884ereed l = sx * l + tx; 876a88206b2ece8b64534c87fca156e5fe161f884ereed t = sy * t + ty; 886a88206b2ece8b64534c87fca156e5fe161f884ereed r = sx * r + tx; 896a88206b2ece8b64534c87fca156e5fe161f884ereed b = sy * b + ty; 906a88206b2ece8b64534c87fca156e5fe161f884ereed } 916a88206b2ece8b64534c87fca156e5fe161f884ereed quad[0].set(l, t); 926a88206b2ece8b64534c87fca156e5fe161f884ereed quad[1].set(l, b); 936a88206b2ece8b64534c87fca156e5fe161f884ereed quad[2].set(r, b); 946a88206b2ece8b64534c87fca156e5fe161f884ereed quad[3].set(r, t); 956a88206b2ece8b64534c87fca156e5fe161f884ereed } else { 966a88206b2ece8b64534c87fca156e5fe161f884ereed quad[0].setRectFan(l, t, r, b); 976a88206b2ece8b64534c87fca156e5fe161f884ereed mx.mapPoints(quad, quad, 4); 986a88206b2ece8b64534c87fca156e5fe161f884ereed } 996a88206b2ece8b64534c87fca156e5fe161f884ereed } 100a39667c848146d9070e1a45662fb292d8e6bb8fbreed}; 101a39667c848146d9070e1a45662fb292d8e6bb8fbreed 102a39667c848146d9070e1a45662fb292d8e6bb8fbreed#endif 103