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

Unified Diff: ui/gfx/interpolated_transform.cc

Issue 10210002: Interpolated rotations should end cleanly where possible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | ui/gfx/interpolated_transform_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/interpolated_transform.cc
diff --git a/ui/gfx/interpolated_transform.cc b/ui/gfx/interpolated_transform.cc
index 6989fdaff2528e330489beb6fc18f4d1cdb46e47..54ecba93f489f9e7be551795b884b4d71b5a7089 100644
--- a/ui/gfx/interpolated_transform.cc
+++ b/ui/gfx/interpolated_transform.cc
@@ -17,6 +17,54 @@ namespace {
static const float EPSILON = 1e-6f;
+bool IsMultipleOfNinetyDegrees(float degrees)
+{
+ float remainder = fabs(fmod(degrees, 90.0f));
+ return remainder < EPSILON || 90.0f - remainder < EPSILON;
+}
+
+// Returns false if |degrees| is not a multiple of ninety degrees or if
+// |rotation| is NULL. It does not affect |rotation| in this case. Otherwise
+// *rotation is set to be the appropriate sanitized rotation matrix. That is,
+// the rotation matrix corresponding to |degrees| which has entries that are all
+// either 0, 1 or -1.
+bool MassageRotationIfMultipleOfNinetyDegrees(ui::Transform* rotation,
+ float degrees)
+{
+ if (!IsMultipleOfNinetyDegrees(degrees) || !rotation)
+ return false;
+
+ ui::Transform transform;
+ SkMatrix44& m = transform.matrix();
+ float degrees_by_ninety = degrees / 90.0f;
+
+ int n = static_cast<int>(degrees_by_ninety > 0
+ ? floor(degrees_by_ninety + 0.5f)
+ : ceil(degrees_by_ninety - 0.5f));
+
+ n %= 4;
+ if (n < 0)
+ n += 4;
+
+ // n should now be in the range [0, 3]
+ if (n == 1) {
+ m.set3x3( 0, 1, 0,
+ -1, 0, 0,
+ 0, 0, 1);
+ } else if (n == 2) {
+ m.set3x3(-1, 0, 0,
+ 0, -1, 0,
+ 0, 0, 1);
+ } else if (n == 3) {
+ m.set3x3( 0, -1, 0,
+ 1, 0, 0,
+ 0, 0, 1);
+ }
+
+ *rotation = transform;
+ return true;
+}
+
} // namespace
namespace ui {
@@ -157,7 +205,10 @@ InterpolatedRotation::~InterpolatedRotation() {}
ui::Transform InterpolatedRotation::InterpolateButDoNotCompose(float t) const {
ui::Transform result;
- result.SetRotate(ValueBetween(t, start_degrees_, end_degrees_));
+ float interpolated_degrees = ValueBetween(t, start_degrees_, end_degrees_);
+ result.SetRotate(interpolated_degrees);
+ if (t == 0.0f || t == 1.0f)
+ MassageRotationIfMultipleOfNinetyDegrees(&result, interpolated_degrees);
return result;
}
@@ -268,7 +319,6 @@ InterpolatedTranslation::InterpolateButDoNotCompose(float t) const {
// TODO(vollick) 3d xforms.
result.SetTranslate(ValueBetween(t, start_pos_.x(), end_pos_.x()),
ValueBetween(t, start_pos_.y(), end_pos_.y()));
-
return result;
}
« no previous file with comments | « no previous file | ui/gfx/interpolated_transform_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698