| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 // MSVC++ requires this to be set before any other includes to get M_PI. | 5 // MSVC++ requires this to be set before any other includes to get M_PI. |
| 6 #define _USE_MATH_DEFINES | 6 #define _USE_MATH_DEFINES |
| 7 | 7 |
| 8 #include "ui/gfx/transform.h" | 8 #include "ui/gfx/transform.h" |
| 9 | 9 |
| 10 #include <cmath> | 10 #include <cmath> |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 if (matrix_.isIdentity()) | 199 if (matrix_.isIdentity()) |
| 200 matrix_.setDouble(3, 2, -1.0 / depth); | 200 matrix_.setDouble(3, 2, -1.0 / depth); |
| 201 else { | 201 else { |
| 202 SkMatrix44 m; | 202 SkMatrix44 m; |
| 203 m.setDouble(3, 2, -1.0 / depth); | 203 m.setDouble(3, 2, -1.0 / depth); |
| 204 matrix_.preConcat(m); | 204 matrix_.preConcat(m); |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 | 207 |
| 208 void Transform::PreconcatTransform(const Transform& transform) { | 208 void Transform::PreconcatTransform(const Transform& transform) { |
| 209 if (!transform.matrix_.isIdentity()) { | 209 if (matrix_.isIdentity()) { |
| 210 matrix_ = transform.matrix_; |
| 211 } else if (!transform.matrix_.isIdentity()) { |
| 210 matrix_.preConcat(transform.matrix_); | 212 matrix_.preConcat(transform.matrix_); |
| 211 } | 213 } |
| 212 } | 214 } |
| 213 | 215 |
| 214 void Transform::ConcatTransform(const Transform& transform) { | 216 void Transform::ConcatTransform(const Transform& transform) { |
| 215 if (!transform.matrix_.isIdentity()) { | 217 if (matrix_.isIdentity()) { |
| 218 matrix_ = transform.matrix_; |
| 219 } else if (!transform.matrix_.isIdentity()) { |
| 216 matrix_.postConcat(transform.matrix_); | 220 matrix_.postConcat(transform.matrix_); |
| 217 } | 221 } |
| 218 } | 222 } |
| 219 | 223 |
| 220 bool Transform::IsIdentity() const { | 224 bool Transform::IsIdentity() const { |
| 221 return matrix_.isIdentity(); | 225 return matrix_.isIdentity(); |
| 222 } | 226 } |
| 223 | 227 |
| 224 bool Transform::IsIdentityOrTranslation() const { | 228 bool Transform::IsIdentityOrTranslation() const { |
| 229 if (matrix_.isIdentity()) |
| 230 return true; |
| 231 |
| 225 bool has_no_perspective = !matrix_.getDouble(3, 0) && | 232 bool has_no_perspective = !matrix_.getDouble(3, 0) && |
| 226 !matrix_.getDouble(3, 1) && | 233 !matrix_.getDouble(3, 1) && |
| 227 !matrix_.getDouble(3, 2) && | 234 !matrix_.getDouble(3, 2) && |
| 228 (matrix_.getDouble(3, 3) == 1); | 235 (matrix_.getDouble(3, 3) == 1); |
| 229 | 236 |
| 230 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) && | 237 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) && |
| 231 !matrix_.getDouble(0, 2) && | 238 !matrix_.getDouble(0, 2) && |
| 232 !matrix_.getDouble(1, 0) && | 239 !matrix_.getDouble(1, 0) && |
| 233 !matrix_.getDouble(1, 2) && | 240 !matrix_.getDouble(1, 2) && |
| 234 !matrix_.getDouble(2, 0) && | 241 !matrix_.getDouble(2, 0) && |
| 235 !matrix_.getDouble(2, 1); | 242 !matrix_.getDouble(2, 1); |
| 236 | 243 |
| 237 bool has_no_scale = matrix_.getDouble(0, 0) == 1 && | 244 bool has_no_scale = matrix_.getDouble(0, 0) == 1 && |
| 238 matrix_.getDouble(1, 1) == 1 && | 245 matrix_.getDouble(1, 1) == 1 && |
| 239 matrix_.getDouble(2, 2) == 1; | 246 matrix_.getDouble(2, 2) == 1; |
| 240 | 247 |
| 241 return has_no_perspective && has_no_rotation_or_skew && has_no_scale; | 248 return has_no_perspective && has_no_rotation_or_skew && has_no_scale; |
| 242 } | 249 } |
| 243 | 250 |
| 244 bool Transform::IsScaleOrTranslation() const { | 251 bool Transform::IsScaleOrTranslation() const { |
| 252 if (matrix_.isIdentity()) |
| 253 return true; |
| 254 |
| 245 bool has_no_perspective = !matrix_.getDouble(3, 0) && | 255 bool has_no_perspective = !matrix_.getDouble(3, 0) && |
| 246 !matrix_.getDouble(3, 1) && | 256 !matrix_.getDouble(3, 1) && |
| 247 !matrix_.getDouble(3, 2) && | 257 !matrix_.getDouble(3, 2) && |
| 248 (matrix_.getDouble(3, 3) == 1); | 258 (matrix_.getDouble(3, 3) == 1); |
| 249 | 259 |
| 250 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) && | 260 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) && |
| 251 !matrix_.getDouble(0, 2) && | 261 !matrix_.getDouble(0, 2) && |
| 252 !matrix_.getDouble(1, 0) && | 262 !matrix_.getDouble(1, 0) && |
| 253 !matrix_.getDouble(1, 2) && | 263 !matrix_.getDouble(1, 2) && |
| 254 !matrix_.getDouble(2, 0) && | 264 !matrix_.getDouble(2, 0) && |
| 255 !matrix_.getDouble(2, 1); | 265 !matrix_.getDouble(2, 1); |
| 256 | 266 |
| 257 return has_no_perspective && has_no_rotation_or_skew; | 267 return has_no_perspective && has_no_rotation_or_skew; |
| 258 } | 268 } |
| 259 | 269 |
| 260 bool Transform::HasPerspective() const { | 270 bool Transform::HasPerspective() const { |
| 261 return matrix_.getDouble(3, 0) || | 271 return !matrix_.isIdentity() && |
| 262 matrix_.getDouble(3, 1) || | 272 (matrix_.getDouble(3, 0) || |
| 263 matrix_.getDouble(3, 2) || | 273 matrix_.getDouble(3, 1) || |
| 264 (matrix_.getDouble(3, 3) != 1); | 274 matrix_.getDouble(3, 2) || |
| 275 (matrix_.getDouble(3, 3) != 1)); |
| 265 } | 276 } |
| 266 | 277 |
| 267 bool Transform::IsInvertible() const { | 278 bool Transform::IsInvertible() const { |
| 268 return std::abs(matrix_.determinant()) > kTooSmallForDeterminant; | 279 return std::abs(matrix_.determinant()) > kTooSmallForDeterminant; |
| 269 } | 280 } |
| 270 | 281 |
| 271 bool Transform::IsBackFaceVisible() const { | 282 bool Transform::IsBackFaceVisible() const { |
| 272 // Compute whether a layer with a forward-facing normal of (0, 0, 1, 0) | 283 // Compute whether a layer with a forward-facing normal of (0, 0, 1, 0) |
| 273 // would have its back face visible after applying the transform. | 284 // would have its back face visible after applying the transform. |
| 274 // | 285 if (matrix_.isIdentity()) |
| 286 return false; |
| 287 |
| 275 // This is done by transforming the normal and seeing if the resulting z | 288 // This is done by transforming the normal and seeing if the resulting z |
| 276 // value is positive or negative. However, note that transforming a normal | 289 // value is positive or negative. However, note that transforming a normal |
| 277 // actually requires using the inverse-transpose of the original transform. | 290 // actually requires using the inverse-transpose of the original transform. |
| 278 // | 291 // |
| 279 // We can avoid inverting and transposing the matrix since we know we want | 292 // We can avoid inverting and transposing the matrix since we know we want |
| 280 // to transform only the specific normal vector (0, 0, 1, 0). In this case, | 293 // to transform only the specific normal vector (0, 0, 1, 0). In this case, |
| 281 // we only need the 3rd row, 3rd column of the inverse-transpose. We can | 294 // we only need the 3rd row, 3rd column of the inverse-transpose. We can |
| 282 // calculate only the 3rd row 3rd column element of the inverse, skipping | 295 // calculate only the 3rd row 3rd column element of the inverse, skipping |
| 283 // everything else. | 296 // everything else. |
| 284 // | 297 // |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 // TODO(sad): Try to avoid trying to invert the matrix. | 380 // TODO(sad): Try to avoid trying to invert the matrix. |
| 368 SkMatrix44 inverse; | 381 SkMatrix44 inverse; |
| 369 if (!matrix_.invert(&inverse)) | 382 if (!matrix_.invert(&inverse)) |
| 370 return false; | 383 return false; |
| 371 | 384 |
| 372 TransformPointInternal(inverse, point); | 385 TransformPointInternal(inverse, point); |
| 373 return true; | 386 return true; |
| 374 } | 387 } |
| 375 | 388 |
| 376 void Transform::TransformRect(RectF* rect) const { | 389 void Transform::TransformRect(RectF* rect) const { |
| 390 if (matrix_.isIdentity()) |
| 391 return; |
| 392 |
| 377 SkRect src = RectFToSkRect(*rect); | 393 SkRect src = RectFToSkRect(*rect); |
| 378 const SkMatrix& matrix = matrix_; | 394 const SkMatrix& matrix = matrix_; |
| 379 matrix.mapRect(&src); | 395 matrix.mapRect(&src); |
| 380 *rect = SkRectToRectF(src); | 396 *rect = SkRectToRectF(src); |
| 381 } | 397 } |
| 382 | 398 |
| 383 bool Transform::TransformRectReverse(RectF* rect) const { | 399 bool Transform::TransformRectReverse(RectF* rect) const { |
| 400 if (matrix_.isIdentity()) |
| 401 return true; |
| 402 |
| 384 SkMatrix44 inverse; | 403 SkMatrix44 inverse; |
| 385 if (!matrix_.invert(&inverse)) | 404 if (!matrix_.invert(&inverse)) |
| 386 return false; | 405 return false; |
| 406 |
| 387 const SkMatrix& matrix = inverse; | 407 const SkMatrix& matrix = inverse; |
| 388 SkRect src = RectFToSkRect(*rect); | 408 SkRect src = RectFToSkRect(*rect); |
| 389 matrix.mapRect(&src); | 409 matrix.mapRect(&src); |
| 390 *rect = SkRectToRectF(src); | 410 *rect = SkRectToRectF(src); |
| 391 return true; | 411 return true; |
| 392 } | 412 } |
| 393 | 413 |
| 394 bool Transform::Blend(const Transform& from, double progress) { | 414 bool Transform::Blend(const Transform& from, double progress) { |
| 395 if (progress <= 0.0) { | 415 if (progress <= 0.0) { |
| 396 *this = from; | 416 *this = from; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 407 return false; | 427 return false; |
| 408 | 428 |
| 409 if (!BlendDecomposedTransforms(&to_decomp, to_decomp, from_decomp, progress)) | 429 if (!BlendDecomposedTransforms(&to_decomp, to_decomp, from_decomp, progress)) |
| 410 return false; | 430 return false; |
| 411 | 431 |
| 412 matrix_ = ComposeTransform(to_decomp).matrix(); | 432 matrix_ = ComposeTransform(to_decomp).matrix(); |
| 413 return true; | 433 return true; |
| 414 } | 434 } |
| 415 | 435 |
| 416 Transform Transform::operator*(const Transform& other) const { | 436 Transform Transform::operator*(const Transform& other) const { |
| 437 if (matrix_.isIdentity()) |
| 438 return other; |
| 439 if (other.matrix_.isIdentity()) |
| 440 return *this; |
| 417 Transform to_return; | 441 Transform to_return; |
| 418 to_return.matrix_.setConcat(matrix_, other.matrix_); | 442 to_return.matrix_.setConcat(matrix_, other.matrix_); |
| 419 return to_return; | 443 return to_return; |
| 420 } | 444 } |
| 421 | 445 |
| 422 Transform& Transform::operator*=(const Transform& other) { | 446 Transform& Transform::operator*=(const Transform& other) { |
| 423 matrix_.preConcat(other.matrix_); | 447 PreconcatTransform(other); |
| 424 return *this; | 448 return *this; |
| 425 } | 449 } |
| 426 | 450 |
| 427 void Transform::TransformPointInternal(const SkMatrix44& xform, | 451 void Transform::TransformPointInternal(const SkMatrix44& xform, |
| 428 Point3F& point) const { | 452 Point3F& point) const { |
| 453 if (xform.isIdentity()) |
| 454 return; |
| 455 |
| 429 SkMScalar p[4] = { | 456 SkMScalar p[4] = { |
| 430 SkDoubleToMScalar(point.x()), | 457 SkDoubleToMScalar(point.x()), |
| 431 SkDoubleToMScalar(point.y()), | 458 SkDoubleToMScalar(point.y()), |
| 432 SkDoubleToMScalar(point.z()), | 459 SkDoubleToMScalar(point.z()), |
| 433 SkDoubleToMScalar(1) | 460 SkDoubleToMScalar(1) |
| 434 }; | 461 }; |
| 435 | 462 |
| 436 xform.mapMScalars(p); | 463 xform.mapMScalars(p); |
| 437 | 464 |
| 438 if (p[3] != 1 && abs(p[3]) > 0) { | 465 if (p[3] != 1 && abs(p[3]) > 0) { |
| 439 point.SetPoint(p[0] / p[3], p[1] / p[3], p[2]/ p[3]); | 466 point.SetPoint(p[0] / p[3], p[1] / p[3], p[2]/ p[3]); |
| 440 } else { | 467 } else { |
| 441 point.SetPoint(p[0], p[1], p[2]); | 468 point.SetPoint(p[0], p[1], p[2]); |
| 442 } | 469 } |
| 443 } | 470 } |
| 444 | 471 |
| 445 void Transform::TransformPointInternal(const SkMatrix44& xform, | 472 void Transform::TransformPointInternal(const SkMatrix44& xform, |
| 446 Point& point) const { | 473 Point& point) const { |
| 474 if (xform.isIdentity()) |
| 475 return; |
| 476 |
| 447 SkMScalar p[4] = { | 477 SkMScalar p[4] = { |
| 448 SkDoubleToMScalar(point.x()), | 478 SkDoubleToMScalar(point.x()), |
| 449 SkDoubleToMScalar(point.y()), | 479 SkDoubleToMScalar(point.y()), |
| 450 SkDoubleToMScalar(0), | 480 SkDoubleToMScalar(0), |
| 451 SkDoubleToMScalar(1) | 481 SkDoubleToMScalar(1) |
| 452 }; | 482 }; |
| 453 | 483 |
| 454 xform.mapMScalars(p); | 484 xform.mapMScalars(p); |
| 455 | 485 |
| 456 point.SetPoint(ToRoundedInt(p[0]), ToRoundedInt(p[1])); | 486 point.SetPoint(ToRoundedInt(p[0]), ToRoundedInt(p[1])); |
| 457 } | 487 } |
| 458 | 488 |
| 459 } // namespace gfx | 489 } // namespace gfx |
| OLD | NEW |