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 |