1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkMatrixPriv_DEFINE 9 #define SkMatrixPriv_DEFINE 10 11 #include "SkMatrix.h" 12 #include "SkNx.h" 13 14 class SkMatrixPriv { 15 public: 16 /** 17 * Attempt to map the rect through the inverse of the matrix. If it is not invertible, 18 * then this returns false and dst is unchanged. 19 */ InverseMapRect(const SkMatrix & mx,SkRect * dst,const SkRect & src)20 static bool SK_WARN_UNUSED_RESULT InverseMapRect(const SkMatrix& mx, 21 SkRect* dst, const SkRect& src) { 22 if (mx.getType() <= SkMatrix::kTranslate_Mask) { 23 SkScalar tx = mx.getTranslateX(); 24 SkScalar ty = mx.getTranslateY(); 25 Sk4f trans(tx, ty, tx, ty); 26 (Sk4f::Load(&src.fLeft) - trans).store(&dst->fLeft); 27 return true; 28 } 29 // Insert other special-cases here (e.g. scale+translate) 30 31 // general case 32 SkMatrix inverse; 33 if (mx.invert(&inverse)) { 34 inverse.mapRect(dst, src); 35 return true; 36 } 37 return false; 38 } 39 MapPointsWithStride(const SkMatrix & mx,SkPoint pts[],size_t stride,int count)40 static void MapPointsWithStride(const SkMatrix& mx, SkPoint pts[], size_t stride, int count) { 41 SkASSERT(stride >= sizeof(SkPoint)); 42 SkASSERT(0 == stride % sizeof(SkScalar)); 43 44 SkMatrix::TypeMask tm = mx.getType(); 45 46 if (SkMatrix::kIdentity_Mask == tm) { 47 return; 48 } 49 if (SkMatrix::kTranslate_Mask == tm) { 50 const SkScalar tx = mx.getTranslateX(); 51 const SkScalar ty = mx.getTranslateY(); 52 Sk2s trans(tx, ty); 53 for (int i = 0; i < count; ++i) { 54 (Sk2s::Load(&pts->fX) + trans).store(&pts->fX); 55 pts = (SkPoint*)((intptr_t)pts + stride); 56 } 57 return; 58 } 59 // Insert other special-cases here (e.g. scale+translate) 60 61 // general case 62 SkMatrix::MapXYProc proc = mx.getMapXYProc(); 63 for (int i = 0; i < count; ++i) { 64 proc(mx, pts->fX, pts->fY, pts); 65 pts = (SkPoint*)((intptr_t)pts + stride); 66 } 67 } 68 SetMappedRectFan(const SkMatrix & mx,const SkRect & rect,SkPoint quad[4])69 static void SetMappedRectFan(const SkMatrix& mx, const SkRect& rect, SkPoint quad[4]) { 70 SkMatrix::TypeMask tm = mx.getType(); 71 SkScalar l = rect.fLeft; 72 SkScalar t = rect.fTop; 73 SkScalar r = rect.fRight; 74 SkScalar b = rect.fBottom; 75 if (tm <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) { 76 const SkScalar tx = mx.getTranslateX(); 77 const SkScalar ty = mx.getTranslateY(); 78 if (tm <= SkMatrix::kTranslate_Mask) { 79 l += tx; 80 t += ty; 81 r += tx; 82 b += ty; 83 } else { 84 const SkScalar sx = mx.getScaleX(); 85 const SkScalar sy = mx.getScaleY(); 86 l = sx * l + tx; 87 t = sy * t + ty; 88 r = sx * r + tx; 89 b = sy * b + ty; 90 } 91 quad[0].set(l, t); 92 quad[1].set(l, b); 93 quad[2].set(r, b); 94 quad[3].set(r, t); 95 } else { 96 quad[0].setRectFan(l, t, r, b); 97 mx.mapPoints(quad, quad, 4); 98 } 99 } 100 }; 101 102 #endif 103