blob: 844901c011eb5d22b560724c41ed7c56d65ad874 [file] [log] [blame]
reeda39667c2016-08-22 06:39:49 -07001/*
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
14class SkMatrixPriv {
15public:
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 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
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 }
reed6a882062016-08-24 04:22:08 -070068
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 }
reeda39667c2016-08-22 06:39:49 -0700100};
101
102#endif