| 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 |