• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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