OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 "cc/base/math_util.h" | 5 #include "cc/base/math_util.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <limits> | 9 #include <limits> |
10 | 10 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 static inline void AddVertexToClippedQuad3d(const gfx::Point3F& new_vertex, | 114 static inline void AddVertexToClippedQuad3d(const gfx::Point3F& new_vertex, |
115 gfx::Point3F clipped_quad[8], | 115 gfx::Point3F clipped_quad[8], |
116 int* num_vertices_in_clipped_quad) { | 116 int* num_vertices_in_clipped_quad) { |
117 clipped_quad[*num_vertices_in_clipped_quad] = new_vertex; | 117 clipped_quad[*num_vertices_in_clipped_quad] = new_vertex; |
118 (*num_vertices_in_clipped_quad)++; | 118 (*num_vertices_in_clipped_quad)++; |
119 } | 119 } |
120 | 120 |
121 gfx::Rect MathUtil::MapEnclosingClippedRect(const gfx::Transform& transform, | 121 gfx::Rect MathUtil::MapEnclosingClippedRect(const gfx::Transform& transform, |
122 const gfx::Rect& src_rect) { | 122 const gfx::Rect& src_rect) { |
123 if (transform.IsIdentityOrIntegerTranslation()) { | 123 if (transform.IsIdentityOrIntegerTranslation()) { |
124 return src_rect + | 124 gfx::Vector2d offset(static_cast<int>(transform.matrix().getFloat(0, 3)), |
125 gfx::Vector2d( | 125 static_cast<int>(transform.matrix().getFloat(1, 3))); |
126 static_cast<int>(SkMScalarToFloat(transform.matrix().get(0, 3))), | 126 return src_rect + offset; |
127 static_cast<int>( | |
128 SkMScalarToFloat(transform.matrix().get(1, 3)))); | |
129 } | 127 } |
130 return gfx::ToEnclosingRect(MapClippedRect(transform, gfx::RectF(src_rect))); | 128 return gfx::ToEnclosingRect(MapClippedRect(transform, gfx::RectF(src_rect))); |
131 } | 129 } |
132 | 130 |
133 gfx::RectF MathUtil::MapClippedRect(const gfx::Transform& transform, | 131 gfx::RectF MathUtil::MapClippedRect(const gfx::Transform& transform, |
134 const gfx::RectF& src_rect) { | 132 const gfx::RectF& src_rect) { |
135 if (transform.IsIdentityOrTranslation()) { | 133 if (transform.IsIdentityOrTranslation()) { |
136 return src_rect + | 134 gfx::Vector2dF offset(transform.matrix().getFloat(0, 3), |
137 gfx::Vector2dF(SkMScalarToFloat(transform.matrix().get(0, 3)), | 135 transform.matrix().getFloat(1, 3)); |
138 SkMScalarToFloat(transform.matrix().get(1, 3))); | 136 return src_rect + offset; |
139 } | 137 } |
140 | 138 |
141 // Apply the transform, but retain the result in homogeneous coordinates. | 139 // Apply the transform, but retain the result in homogeneous coordinates. |
142 | 140 |
143 SkMScalar quad[4 * 2]; // input: 4 x 2D points | 141 SkMScalar quad[4 * 2]; // input: 4 x 2D points |
144 quad[0] = src_rect.x(); | 142 quad[0] = src_rect.x(); |
145 quad[1] = src_rect.y(); | 143 quad[1] = src_rect.y(); |
146 quad[2] = src_rect.right(); | 144 quad[2] = src_rect.right(); |
147 quad[3] = src_rect.y(); | 145 quad[3] = src_rect.y(); |
148 quad[4] = src_rect.right(); | 146 quad[4] = src_rect.right(); |
149 quad[5] = src_rect.bottom(); | 147 quad[5] = src_rect.bottom(); |
150 quad[6] = src_rect.x(); | 148 quad[6] = src_rect.x(); |
151 quad[7] = src_rect.bottom(); | 149 quad[7] = src_rect.bottom(); |
152 | 150 |
153 SkMScalar result[4 * 4]; // output: 4 x 4D homogeneous points | 151 SkMScalar result[4 * 4]; // output: 4 x 4D homogeneous points |
154 transform.matrix().map2(quad, 4, result); | 152 transform.matrix().map2(quad, 4, result); |
155 | 153 |
156 HomogeneousCoordinate hc0(result[0], result[1], result[2], result[3]); | 154 HomogeneousCoordinate hc0(result[0], result[1], result[2], result[3]); |
157 HomogeneousCoordinate hc1(result[4], result[5], result[6], result[7]); | 155 HomogeneousCoordinate hc1(result[4], result[5], result[6], result[7]); |
158 HomogeneousCoordinate hc2(result[8], result[9], result[10], result[11]); | 156 HomogeneousCoordinate hc2(result[8], result[9], result[10], result[11]); |
159 HomogeneousCoordinate hc3(result[12], result[13], result[14], result[15]); | 157 HomogeneousCoordinate hc3(result[12], result[13], result[14], result[15]); |
160 return ComputeEnclosingClippedRect(hc0, hc1, hc2, hc3); | 158 return ComputeEnclosingClippedRect(hc0, hc1, hc2, hc3); |
161 } | 159 } |
162 | 160 |
163 gfx::Rect MathUtil::ProjectEnclosingClippedRect(const gfx::Transform& transform, | 161 gfx::Rect MathUtil::ProjectEnclosingClippedRect(const gfx::Transform& transform, |
164 const gfx::Rect& src_rect) { | 162 const gfx::Rect& src_rect) { |
165 if (transform.IsIdentityOrIntegerTranslation()) { | 163 if (transform.IsIdentityOrIntegerTranslation()) { |
166 return src_rect + | 164 gfx::Vector2d offset(static_cast<int>(transform.matrix().getFloat(0, 3)), |
167 gfx::Vector2d( | 165 static_cast<int>(transform.matrix().getFloat(1, 3))); |
168 static_cast<int>(SkMScalarToFloat(transform.matrix().get(0, 3))), | 166 return src_rect + offset; |
169 static_cast<int>( | |
170 SkMScalarToFloat(transform.matrix().get(1, 3)))); | |
171 } | 167 } |
172 return gfx::ToEnclosingRect( | 168 return gfx::ToEnclosingRect( |
173 ProjectClippedRect(transform, gfx::RectF(src_rect))); | 169 ProjectClippedRect(transform, gfx::RectF(src_rect))); |
174 } | 170 } |
175 | 171 |
176 gfx::RectF MathUtil::ProjectClippedRect(const gfx::Transform& transform, | 172 gfx::RectF MathUtil::ProjectClippedRect(const gfx::Transform& transform, |
177 const gfx::RectF& src_rect) { | 173 const gfx::RectF& src_rect) { |
178 if (transform.IsIdentityOrTranslation()) { | 174 if (transform.IsIdentityOrTranslation()) { |
179 return src_rect + | 175 gfx::Vector2dF offset(transform.matrix().getFloat(0, 3), |
180 gfx::Vector2dF(SkMScalarToFloat(transform.matrix().get(0, 3)), | 176 transform.matrix().getFloat(1, 3)); |
181 SkMScalarToFloat(transform.matrix().get(1, 3))); | 177 return src_rect + offset; |
182 } | 178 } |
183 | 179 |
184 // Perform the projection, but retain the result in homogeneous coordinates. | 180 // Perform the projection, but retain the result in homogeneous coordinates. |
185 gfx::QuadF q = gfx::QuadF(src_rect); | 181 gfx::QuadF q = gfx::QuadF(src_rect); |
186 HomogeneousCoordinate h1 = ProjectHomogeneousPoint(transform, q.p1()); | 182 HomogeneousCoordinate h1 = ProjectHomogeneousPoint(transform, q.p1()); |
187 HomogeneousCoordinate h2 = ProjectHomogeneousPoint(transform, q.p2()); | 183 HomogeneousCoordinate h2 = ProjectHomogeneousPoint(transform, q.p2()); |
188 HomogeneousCoordinate h3 = ProjectHomogeneousPoint(transform, q.p3()); | 184 HomogeneousCoordinate h3 = ProjectHomogeneousPoint(transform, q.p3()); |
189 HomogeneousCoordinate h4 = ProjectHomogeneousPoint(transform, q.p4()); | 185 HomogeneousCoordinate h4 = ProjectHomogeneousPoint(transform, q.p4()); |
190 | 186 |
191 return ComputeEnclosingClippedRect(h1, h2, h3, h4); | 187 return ComputeEnclosingClippedRect(h1, h2, h3, h4); |
192 } | 188 } |
193 | 189 |
| 190 gfx::Rect MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( |
| 191 const gfx::Transform& transform, |
| 192 const gfx::Rect& rect) { |
| 193 DCHECK(transform.Preserves2dAxisAlignment()); |
| 194 |
| 195 if (transform.IsIdentityOrIntegerTranslation()) { |
| 196 gfx::Vector2d offset(static_cast<int>(transform.matrix().getFloat(0, 3)), |
| 197 static_cast<int>(transform.matrix().getFloat(1, 3))); |
| 198 return rect + offset; |
| 199 } |
| 200 if (transform.IsIdentityOrTranslation()) { |
| 201 gfx::Vector2dF offset(transform.matrix().getFloat(0, 3), |
| 202 transform.matrix().getFloat(1, 3)); |
| 203 return gfx::ToEnclosedRect(rect + offset); |
| 204 } |
| 205 |
| 206 SkMScalar quad[2 * 2]; // input: 2 x 2D points |
| 207 quad[0] = rect.x(); |
| 208 quad[1] = rect.y(); |
| 209 quad[2] = rect.right(); |
| 210 quad[3] = rect.bottom(); |
| 211 |
| 212 SkMScalar result[4 * 2]; // output: 2 x 4D homogeneous points |
| 213 transform.matrix().map2(quad, 2, result); |
| 214 |
| 215 HomogeneousCoordinate hc0(result[0], result[1], result[2], result[3]); |
| 216 HomogeneousCoordinate hc1(result[4], result[5], result[6], result[7]); |
| 217 DCHECK(!hc0.ShouldBeClipped()); |
| 218 DCHECK(!hc1.ShouldBeClipped()); |
| 219 |
| 220 gfx::PointF top_left(hc0.CartesianPoint2d()); |
| 221 gfx::PointF bottom_right(hc1.CartesianPoint2d()); |
| 222 return gfx::ToEnclosedRect(gfx::BoundingRect(top_left, bottom_right)); |
| 223 } |
| 224 |
194 void MathUtil::MapClippedQuad(const gfx::Transform& transform, | 225 void MathUtil::MapClippedQuad(const gfx::Transform& transform, |
195 const gfx::QuadF& src_quad, | 226 const gfx::QuadF& src_quad, |
196 gfx::PointF clipped_quad[8], | 227 gfx::PointF clipped_quad[8], |
197 int* num_vertices_in_clipped_quad) { | 228 int* num_vertices_in_clipped_quad) { |
198 HomogeneousCoordinate h1 = | 229 HomogeneousCoordinate h1 = |
199 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p1())); | 230 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p1())); |
200 HomogeneousCoordinate h2 = | 231 HomogeneousCoordinate h2 = |
201 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p2())); | 232 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p2())); |
202 HomogeneousCoordinate h3 = | 233 HomogeneousCoordinate h3 = |
203 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p3())); | 234 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p3())); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 | 460 |
430 return gfx::RectF(gfx::PointF(xmin, ymin), | 461 return gfx::RectF(gfx::PointF(xmin, ymin), |
431 gfx::SizeF(xmax - xmin, ymax - ymin)); | 462 gfx::SizeF(xmax - xmin, ymax - ymin)); |
432 } | 463 } |
433 | 464 |
434 gfx::QuadF MathUtil::MapQuad(const gfx::Transform& transform, | 465 gfx::QuadF MathUtil::MapQuad(const gfx::Transform& transform, |
435 const gfx::QuadF& q, | 466 const gfx::QuadF& q, |
436 bool* clipped) { | 467 bool* clipped) { |
437 if (transform.IsIdentityOrTranslation()) { | 468 if (transform.IsIdentityOrTranslation()) { |
438 gfx::QuadF mapped_quad(q); | 469 gfx::QuadF mapped_quad(q); |
439 mapped_quad += | 470 mapped_quad += gfx::Vector2dF(transform.matrix().getFloat(0, 3), |
440 gfx::Vector2dF(SkMScalarToFloat(transform.matrix().get(0, 3)), | 471 transform.matrix().getFloat(1, 3)); |
441 SkMScalarToFloat(transform.matrix().get(1, 3))); | |
442 *clipped = false; | 472 *clipped = false; |
443 return mapped_quad; | 473 return mapped_quad; |
444 } | 474 } |
445 | 475 |
446 HomogeneousCoordinate h1 = | 476 HomogeneousCoordinate h1 = |
447 MapHomogeneousPoint(transform, gfx::Point3F(q.p1())); | 477 MapHomogeneousPoint(transform, gfx::Point3F(q.p1())); |
448 HomogeneousCoordinate h2 = | 478 HomogeneousCoordinate h2 = |
449 MapHomogeneousPoint(transform, gfx::Point3F(q.p2())); | 479 MapHomogeneousPoint(transform, gfx::Point3F(q.p2())); |
450 HomogeneousCoordinate h3 = | 480 HomogeneousCoordinate h3 = |
451 MapHomogeneousPoint(transform, gfx::Point3F(q.p3())); | 481 MapHomogeneousPoint(transform, gfx::Point3F(q.p3())); |
(...skipping 10 matching lines...) Expand all Loading... |
462 h3.CartesianPoint2d(), | 492 h3.CartesianPoint2d(), |
463 h4.CartesianPoint2d()); | 493 h4.CartesianPoint2d()); |
464 } | 494 } |
465 | 495 |
466 gfx::QuadF MathUtil::MapQuad3d(const gfx::Transform& transform, | 496 gfx::QuadF MathUtil::MapQuad3d(const gfx::Transform& transform, |
467 const gfx::QuadF& q, | 497 const gfx::QuadF& q, |
468 gfx::Point3F* p, | 498 gfx::Point3F* p, |
469 bool* clipped) { | 499 bool* clipped) { |
470 if (transform.IsIdentityOrTranslation()) { | 500 if (transform.IsIdentityOrTranslation()) { |
471 gfx::QuadF mapped_quad(q); | 501 gfx::QuadF mapped_quad(q); |
472 mapped_quad += | 502 mapped_quad += gfx::Vector2dF(transform.matrix().getFloat(0, 3), |
473 gfx::Vector2dF(SkMScalarToFloat(transform.matrix().get(0, 3)), | 503 transform.matrix().getFloat(1, 3)); |
474 SkMScalarToFloat(transform.matrix().get(1, 3))); | |
475 *clipped = false; | 504 *clipped = false; |
476 p[0] = gfx::Point3F(mapped_quad.p1().x(), mapped_quad.p1().y(), 0.0f); | 505 p[0] = gfx::Point3F(mapped_quad.p1().x(), mapped_quad.p1().y(), 0.0f); |
477 p[1] = gfx::Point3F(mapped_quad.p2().x(), mapped_quad.p2().y(), 0.0f); | 506 p[1] = gfx::Point3F(mapped_quad.p2().x(), mapped_quad.p2().y(), 0.0f); |
478 p[2] = gfx::Point3F(mapped_quad.p3().x(), mapped_quad.p3().y(), 0.0f); | 507 p[2] = gfx::Point3F(mapped_quad.p3().x(), mapped_quad.p3().y(), 0.0f); |
479 p[3] = gfx::Point3F(mapped_quad.p4().x(), mapped_quad.p4().y(), 0.0f); | 508 p[3] = gfx::Point3F(mapped_quad.p4().x(), mapped_quad.p4().y(), 0.0f); |
480 return mapped_quad; | 509 return mapped_quad; |
481 } | 510 } |
482 | 511 |
483 HomogeneousCoordinate h1 = | 512 HomogeneousCoordinate h1 = |
484 MapHomogeneousPoint(transform, gfx::Point3F(q.p1())); | 513 MapHomogeneousPoint(transform, gfx::Point3F(q.p1())); |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 | 819 |
791 double MathUtil::AsDoubleSafely(double value) { | 820 double MathUtil::AsDoubleSafely(double value) { |
792 return std::min(value, std::numeric_limits<double>::max()); | 821 return std::min(value, std::numeric_limits<double>::max()); |
793 } | 822 } |
794 | 823 |
795 float MathUtil::AsFloatSafely(float value) { | 824 float MathUtil::AsFloatSafely(float value) { |
796 return std::min(value, std::numeric_limits<float>::max()); | 825 return std::min(value, std::numeric_limits<float>::max()); |
797 } | 826 } |
798 | 827 |
799 } // namespace cc | 828 } // namespace cc |
OLD | NEW |