Index: ash/utility/transformer_util.cc |
diff --git a/ash/utility/transformer_util.cc b/ash/utility/transformer_util.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a0ce1eb45e759bd446ed7efd297c247b65f8d8e2 |
--- /dev/null |
+++ b/ash/utility/transformer_util.cc |
@@ -0,0 +1,134 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ash/utility/transformer_util.h" |
+ |
+#include <cmath> |
+ |
+#include "ash/magnifier/magnification_controller.h" |
+#include "ash/shell.h" |
+#include "third_party/skia/include/core/SkMatrix44.h" |
+#include "ui/base/class_property.h" |
+#include "ui/display/manager/display_manager.h" |
+#include "ui/display/manager/managed_display_info.h" |
+#include "ui/gfx/geometry/insets.h" |
+#include "ui/gfx/transform.h" |
+ |
+DECLARE_UI_CLASS_PROPERTY_TYPE(display::Display::Rotation); |
+ |
+namespace ash { |
+ |
+#if defined(OS_WIN) |
+DEFINE_UI_CLASS_PROPERTY_KEY(display::Display::Rotation, |
+ kRotationPropertyKey, |
+ display::Display::ROTATE_0); |
+#endif |
oshima
2017/04/13 23:51:45
you can remove OS_WIN part as ash no longer suppor
wutao
2017/04/14 00:17:54
Done.
|
+ |
+// Round near zero value to zero. |
+void RoundNearZero(gfx::Transform* transform) { |
+ const float kEpsilon = 0.001f; |
+ SkMatrix44& matrix = transform->matrix(); |
+ for (int x = 0; x < 4; ++x) { |
+ for (int y = 0; y < 4; ++y) { |
+ if (std::abs(SkMScalarToFloat(matrix.get(x, y))) < kEpsilon) |
+ matrix.set(x, y, SkFloatToMScalar(0.0f)); |
+ } |
+ } |
+} |
+ |
+gfx::Transform CreateRotationTransform(display::Display::Rotation old_rotation, |
+ display::Display::Rotation new_rotation, |
+ const display::Display& display) { |
+ const int rotation_angle = 90 * (((new_rotation - old_rotation) + 4) % 4); |
+ gfx::Transform rotate; |
+ // The origin is (0, 0), so the translate width/height must be reduced by |
+ // 1 pixel. |
+ float one_pixel = 1.0f / display.device_scale_factor(); |
+ switch (rotation_angle) { |
+ case 0: |
+ break; |
+ case 90: |
+ rotate.Translate(display.bounds().height() - one_pixel, 0); |
+ rotate.Rotate(90); |
+ break; |
+ case 180: |
+ rotate.Translate(display.bounds().width() - one_pixel, |
+ display.bounds().height() - one_pixel); |
+ rotate.Rotate(180); |
+ break; |
+ case 270: |
+ rotate.Translate(0, display.bounds().width() - one_pixel); |
+ rotate.Rotate(270); |
+ break; |
+ } |
+ |
+ RoundNearZero(&rotate); |
+ return rotate; |
+} |
+ |
+// TODO(oshima): Transformers should be able to adjust itself |
+// when the device scale factor is changed, instead of |
+// precalculating the transform using fixed value. |
+ |
+gfx::Transform CreateRootWindowRotationTransform( |
+ aura::Window* root_window, |
+ const display::Display& display) { |
+ display::ManagedDisplayInfo info = |
+ Shell::Get()->display_manager()->GetDisplayInfo(display.id()); |
+ |
+// TODO(oshima): Add animation. (crossfade+rotation, or just cross-fade) |
+#if defined(OS_WIN) |
+ // Windows 8 bots refused to resize the host window, and |
+ // updating the transform results in incorrectly resizing |
+ // the root window. Don't apply the transform unless |
+ // necessary so that unit tests pass on win8 bots. |
+ if (info.GetActiveRotation() == |
+ root_window->GetProperty(kRotationPropertyKey)) { |
+ return gfx::Transform(); |
+ } |
+ root_window->SetProperty(kRotationPropertyKey, info.GetActiveRotation()); |
+#endif |
+ |
+ return CreateRotationTransform(display::Display::ROTATE_0, |
+ info.GetActiveRotation(), display); |
+} |
oshima
2017/04/13 23:51:45
do you have to move these other than CreateRotatio
wutao
2017/04/14 00:17:54
I do not. I only need CreateRotationTransform. I c
|
+ |
+gfx::Transform CreateMagnifierTransform(aura::Window* root_window) { |
+ MagnificationController* magnifier = Shell::Get()->magnification_controller(); |
+ float magnifier_scale = 1.f; |
+ gfx::Point magnifier_offset; |
+ if (magnifier && magnifier->IsEnabled()) { |
+ magnifier_scale = magnifier->GetScale(); |
+ magnifier_offset = magnifier->GetWindowPosition(); |
+ } |
+ gfx::Transform transform; |
+ if (magnifier_scale != 1.f) { |
+ transform.Scale(magnifier_scale, magnifier_scale); |
+ transform.Translate(-magnifier_offset.x(), -magnifier_offset.y()); |
+ } |
+ return transform; |
+} |
+ |
+gfx::Transform CreateInsetsAndScaleTransform(const gfx::Insets& insets, |
+ float device_scale_factor, |
+ float ui_scale) { |
+ gfx::Transform transform; |
+ if (insets.top() != 0 || insets.left() != 0) { |
+ float x_offset = insets.left() / device_scale_factor; |
+ float y_offset = insets.top() / device_scale_factor; |
+ transform.Translate(x_offset, y_offset); |
+ } |
+ float inverted_scale = 1.0f / ui_scale; |
+ transform.Scale(inverted_scale, inverted_scale); |
+ return transform; |
+} |
+ |
+gfx::Transform CreateMirrorTransform(const display::Display& display) { |
+ gfx::Transform transform; |
+ transform.matrix().set3x3(-1, 0, 0, 0, 1, 0, 0, 0, 1); |
+ transform.Translate(-display.size().width(), 0); |
+ return transform; |
+} |
+ |
+} // namespace ash |