Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Side by Side Diff: ui/gfx/transform.cc

Issue 7044062: Use SkMatrix44 for the underlying implementation of ui::Transform (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Gardening patch Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/gfx/transform.h ('k') | ui/gfx/transform_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/transform.h" 5 #include "ui/gfx/transform.h"
6 6 #include "ui/gfx/point3.h"
7 #include <cmath>
8
9 #include "ui/gfx/point.h"
10 #include "ui/gfx/rect.h" 7 #include "ui/gfx/rect.h"
11 #include "ui/gfx/skia_util.h" 8 #include "ui/gfx/skia_util.h"
12 9
10 namespace {
11
12 static int SymmetricRound(float x) {
13 return static_cast<int>(
14 x > 0
15 ? std::floor(x + 0.5f)
16 : std::ceil(x - 0.5f));
17 }
18
19 static const float EPSILON = 1e-6f;
20
21 static bool ApproximatelyEqual(float a, float b) {
22 if (a == 0) {
23 return fabs(b) < EPSILON;
24 }
25 if (b == 0) {
26 return fabs(a) < EPSILON;
27 }
28 return fabs(a - b) / std::max(fabs(a), fabs(b)) < EPSILON;
29 }
30
31 } // namespace
32
13 namespace ui { 33 namespace ui {
14 34
15 Transform::Transform() { 35 Transform::Transform() {
16 matrix_.reset(); 36 matrix_.reset();
17 } 37 }
18 38
19 Transform::~Transform() {} 39 Transform::~Transform() {}
20 40
41 bool Transform::operator==(const Transform& rhs) const {
42 for (int i = 0; i < 4; ++i) {
43 for (int j = 0; j < 4; ++j) {
44 if (!ApproximatelyEqual(matrix_.get(i,j), rhs.matrix_.get(i,j))) {
45 return false;
46 }
47 }
48 }
49 return true;
50 }
51
52 bool Transform::operator!=(const Transform& rhs) const {
53 return !(*this == rhs);
54 }
55
21 void Transform::SetRotate(float degree) { 56 void Transform::SetRotate(float degree) {
22 matrix_.setRotate(SkFloatToScalar(degree)); 57 matrix_.setRotateDegreesAbout(0, 0, 1, SkFloatToScalar(degree));
23 } 58 }
24 59
25 void Transform::SetScaleX(float x) { 60 void Transform::SetScaleX(float x) {
26 matrix_.setScaleX(SkFloatToScalar(x)); 61 matrix_.set(0, 0, SkFloatToScalar(x));
27 } 62 }
28 63
29 void Transform::SetScaleY(float y) { 64 void Transform::SetScaleY(float y) {
30 matrix_.setScaleY(SkFloatToScalar(y)); 65 matrix_.set(1, 1, SkFloatToScalar(y));
31 } 66 }
32 67
33 void Transform::SetScale(float x, float y) { 68 void Transform::SetScale(float x, float y) {
34 matrix_.setScale(SkFloatToScalar(x), SkFloatToScalar(y)); 69 matrix_.setScale(
70 SkFloatToScalar(x),
71 SkFloatToScalar(y),
72 matrix_.get(2, 2));
35 } 73 }
36 74
37 void Transform::SetTranslateX(float x) { 75 void Transform::SetTranslateX(float x) {
38 matrix_.setTranslateX(SkFloatToScalar(x)); 76 matrix_.set(0, 3, SkFloatToScalar(x));
39 } 77 }
40 78
41 void Transform::SetTranslateY(float y) { 79 void Transform::SetTranslateY(float y) {
42 matrix_.setTranslateY(SkFloatToScalar(y)); 80 matrix_.set(1, 3, SkFloatToScalar(y));
43 } 81 }
44 82
45 void Transform::SetTranslate(float x, float y) { 83 void Transform::SetTranslate(float x, float y) {
46 matrix_.setTranslate(SkFloatToScalar(x), SkFloatToScalar(y)); 84 matrix_.setTranslate(
85 SkFloatToScalar(x),
86 SkFloatToScalar(y),
87 matrix_.get(2, 3));
47 } 88 }
48 89
49 void Transform::ConcatRotate(float degree) { 90 void Transform::ConcatRotate(float degree) {
50 matrix_.postRotate(SkFloatToScalar(degree)); 91 SkMatrix44 rot;
92 rot.setRotateDegreesAbout(0, 0, 1, SkFloatToScalar(degree));
93 matrix_.postConcat(rot);
51 } 94 }
52 95
53 void Transform::ConcatScale(float x, float y) { 96 void Transform::ConcatScale(float x, float y) {
54 matrix_.postScale(SkFloatToScalar(x), SkFloatToScalar(y)); 97 SkMatrix44 scale;
98 scale.setScale(SkFloatToScalar(x), SkFloatToScalar(y), 1);
99 matrix_.postConcat(scale);
55 } 100 }
56 101
57 void Transform::ConcatTranslate(float x, float y) { 102 void Transform::ConcatTranslate(float x, float y) {
58 matrix_.postTranslate(SkFloatToScalar(x), SkFloatToScalar(y)); 103 SkMatrix44 translate;
104 translate.setTranslate(SkFloatToScalar(x), SkFloatToScalar(y), 0);
105 matrix_.postConcat(translate);
59 } 106 }
60 107
61 bool Transform::PreconcatTransform(const Transform& transform) { 108 void Transform::PreconcatTransform(const Transform& transform) {
62 return matrix_.setConcat(matrix_, transform.matrix_); 109 if (!transform.matrix_.isIdentity()) {
110 matrix_.preConcat(transform.matrix_);
111 }
63 } 112 }
64 113
65 bool Transform::ConcatTransform(const Transform& transform) { 114 void Transform::ConcatTransform(const Transform& transform) {
66 return matrix_.setConcat(transform.matrix_, matrix_); 115 if (!transform.matrix_.isIdentity()) {
116 matrix_.postConcat(transform.matrix_);
117 }
67 } 118 }
68 119
69 bool Transform::HasChange() const { 120 bool Transform::HasChange() const {
70 return !matrix_.isIdentity(); 121 return !matrix_.isIdentity();
71 } 122 }
72 123
73 bool Transform::TransformPoint(gfx::Point* point) const { 124 void Transform::TransformPoint(gfx::Point& point) const {
74 SkPoint skp; 125 TransformPointInternal(matrix_, point);
75 matrix_.mapXY(SkIntToScalar(point->x()), SkIntToScalar(point->y()), &skp); 126 }
76 point->SetPoint(static_cast<int>(std::floor(skp.fX)), 127
77 static_cast<int>(std::floor(skp.fY))); 128 void Transform::TransformPoint(gfx::Point3f& point) const {
129 TransformPointInternal(matrix_, point);
130 }
131
132 bool Transform::TransformPointReverse(gfx::Point& point) const {
133 // TODO(sad): Try to avoid trying to invert the matrix.
134 SkMatrix44 inverse;
135 if (!matrix_.invert(&inverse))
136 return false;
137
138 TransformPointInternal(inverse, point);
78 return true; 139 return true;
79 } 140 }
80 141
81 bool Transform::TransformPointReverse(gfx::Point* point) const { 142 bool Transform::TransformPointReverse(gfx::Point3f& point) const {
82 SkMatrix inverse;
83 // TODO(sad): Try to avoid trying to invert the matrix. 143 // TODO(sad): Try to avoid trying to invert the matrix.
84 if (matrix_.invert(&inverse)) { 144 SkMatrix44 inverse;
85 SkPoint skp; 145 if (!matrix_.invert(&inverse))
86 inverse.mapXY(SkIntToScalar(point->x()), SkIntToScalar(point->y()), &skp); 146 return false;
87 point->SetPoint(static_cast<int>(std::floor(skp.fX)), 147
88 static_cast<int>(std::floor(skp.fY))); 148 TransformPointInternal(inverse, point);
89 return true; 149 return true;
90 }
91 return false;
92 } 150 }
93 151
94 bool Transform::TransformRect(gfx::Rect* rect) const { 152 void Transform::TransformRect(gfx::Rect* rect) const {
95 SkRect src = gfx::RectToSkRect(*rect); 153 SkRect src = gfx::RectToSkRect(*rect);
96 if (!matrix_.mapRect(&src)) 154 const SkMatrix& matrix = matrix_;
155 matrix.mapRect(&src);
156 *rect = gfx::SkRectToRect(src);
157 }
158
159 bool Transform::TransformRectReverse(gfx::Rect* rect) const {
160 SkMatrix44 inverse;
161 if (!matrix_.invert(&inverse))
97 return false; 162 return false;
163 const SkMatrix& matrix = inverse;
164 SkRect src = gfx::RectToSkRect(*rect);
165 matrix.mapRect(&src);
98 *rect = gfx::SkRectToRect(src); 166 *rect = gfx::SkRectToRect(src);
99 return true; 167 return true;
100 } 168 }
101 169
102 bool Transform::TransformRectReverse(gfx::Rect* rect) const { 170 void Transform::TransformPointInternal(const SkMatrix44& xform,
103 SkMatrix inverse; 171 gfx::Point3f& point) const {
104 if (!matrix_.invert(&inverse)) 172 SkScalar p[4] = {
105 return false; 173 SkFloatToScalar(point.x()),
174 SkFloatToScalar(point.y()),
175 SkFloatToScalar(point.z()),
176 1 };
106 177
107 SkRect src = gfx::RectToSkRect(*rect); 178 xform.map(p);
108 if (!inverse.mapRect(&src)) 179
109 return false; 180 if (p[3] != 1 && abs(p[3]) > 0) {
110 *rect = gfx::SkRectToRect(src); 181 point.SetPoint(p[0] / p[3], p[1] / p[3], p[2]/ p[3]);
111 return true; 182 } else {
183 point.SetPoint(p[0], p[1], p[2]);
184 }
185 }
186
187 void Transform::TransformPointInternal(const SkMatrix44& xform,
188 gfx::Point& point) const {
189 SkScalar p[4] = {
190 SkIntToScalar(point.x()),
191 SkIntToScalar(point.y()),
192 0,
193 1 };
194
195 xform.map(p);
196
197 point.SetPoint(SymmetricRound(p[0]),
198 SymmetricRound(p[1]));
112 } 199 }
113 200
114 } // namespace ui 201 } // namespace ui
OLDNEW
« no previous file with comments | « ui/gfx/transform.h ('k') | ui/gfx/transform_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698