Line data Source code
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 : */
20 0 : static bool SK_WARN_UNUSED_RESULT InverseMapRect(const SkMatrix& mx,
21 : SkRect* dst, const SkRect& src) {
22 0 : if (mx.getType() <= SkMatrix::kTranslate_Mask) {
23 0 : SkScalar tx = mx.getTranslateX();
24 0 : SkScalar ty = mx.getTranslateY();
25 : Sk4f trans(tx, ty, tx, ty);
26 0 : (Sk4f::Load(&src.fLeft) - trans).store(&dst->fLeft);
27 0 : return true;
28 : }
29 : // Insert other special-cases here (e.g. scale+translate)
30 :
31 : // general case
32 : SkMatrix inverse;
33 0 : if (mx.invert(&inverse)) {
34 0 : inverse.mapRect(dst, src);
35 0 : return true;
36 : }
37 0 : return false;
38 : }
39 :
40 0 : static void MapPointsWithStride(const SkMatrix& mx, SkPoint pts[], size_t stride, int count) {
41 0 : SkASSERT(stride >= sizeof(SkPoint));
42 0 : SkASSERT(0 == stride % sizeof(SkScalar));
43 :
44 0 : SkMatrix::TypeMask tm = mx.getType();
45 :
46 0 : if (SkMatrix::kIdentity_Mask == tm) {
47 0 : return;
48 : }
49 0 : if (SkMatrix::kTranslate_Mask == tm) {
50 0 : const SkScalar tx = mx.getTranslateX();
51 0 : const SkScalar ty = mx.getTranslateY();
52 : Sk2s trans(tx, ty);
53 0 : for (int i = 0; i < count; ++i) {
54 0 : (Sk2s::Load(&pts->fX) + trans).store(&pts->fX);
55 0 : pts = (SkPoint*)((intptr_t)pts + stride);
56 : }
57 0 : return;
58 : }
59 : // Insert other special-cases here (e.g. scale+translate)
60 :
61 : // general case
62 0 : SkMatrix::MapXYProc proc = mx.getMapXYProc();
63 0 : for (int i = 0; i < count; ++i) {
64 0 : proc(mx, pts->fX, pts->fY, pts);
65 0 : pts = (SkPoint*)((intptr_t)pts + stride);
66 : }
67 : }
68 :
69 0 : static void SetMappedRectFan(const SkMatrix& mx, const SkRect& rect, SkPoint quad[4]) {
70 0 : SkMatrix::TypeMask tm = mx.getType();
71 0 : SkScalar l = rect.fLeft;
72 0 : SkScalar t = rect.fTop;
73 0 : SkScalar r = rect.fRight;
74 0 : SkScalar b = rect.fBottom;
75 0 : if (tm <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) {
76 0 : const SkScalar tx = mx.getTranslateX();
77 0 : const SkScalar ty = mx.getTranslateY();
78 0 : if (tm <= SkMatrix::kTranslate_Mask) {
79 0 : l += tx;
80 0 : t += ty;
81 0 : r += tx;
82 0 : b += ty;
83 : } else {
84 0 : const SkScalar sx = mx.getScaleX();
85 0 : const SkScalar sy = mx.getScaleY();
86 0 : l = sx * l + tx;
87 0 : t = sy * t + ty;
88 0 : r = sx * r + tx;
89 0 : b = sy * b + ty;
90 : }
91 0 : quad[0].set(l, t);
92 0 : quad[1].set(l, b);
93 0 : quad[2].set(r, b);
94 0 : quad[3].set(r, t);
95 : } else {
96 0 : quad[0].setRectFan(l, t, r, b);
97 0 : mx.mapPoints(quad, quad, 4);
98 : }
99 0 : }
100 : };
101 :
102 : #endif
|