Index: remoting/host/chromeos/point_transformer.cc |
diff --git a/remoting/host/chromeos/point_transformer.cc b/remoting/host/chromeos/point_transformer.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2c8b89317a9f974816dbd3da74305bd7100be144 |
--- /dev/null |
+++ b/remoting/host/chromeos/point_transformer.cc |
@@ -0,0 +1,62 @@ |
+// Copyright 2014 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 "remoting/host/chromeos/point_transformer.h" |
+ |
+#include "ash/shell.h" |
+#include "ui/aura/window_tree_host.h" |
+#include "ui/compositor/dip_util.h" |
+ |
+namespace remoting { |
+ |
+PointTransformer::PointTransformer() { |
+ root_window_ = ash::Shell::GetPrimaryRootWindow(); |
+ root_window_->AddObserver(this); |
+} |
+ |
+PointTransformer::~PointTransformer() { |
+ root_window_->RemoveObserver(this); |
+} |
+ |
+void PointTransformer::OnWindowTransformed(aura::Window* window) { |
+ CHECK_EQ(window, root_window_); |
+ |
+ ui::Layer* layer = root_window_->layer(); |
+ float scale = ui::GetDeviceScaleFactor(layer); |
+ |
+ // |layer->transform()| returns a transform comprising a rotation and a |
+ // translation, but in DIPs, so we need to switch device pixels to |
+ // DIPs, apply it, then switch from DIPs back to device pixels. |
+ gfx::Transform rotation = layer->transform(); |
+ gfx::Transform inverse_rotation; |
+ gfx::Transform to_device_pixels; |
+ gfx::Transform to_dip; |
+ |
+ CHECK(!rotation.GetInverse(&inverse_rotation)) |
+ << "Cannot inverse the root transform." << rotation.ToString(); |
+ |
+ to_device_pixels.Scale(scale, scale); |
+ to_dip.Scale(1 / scale, 1 / scale); |
+ |
+ // Matrix transformations are applied from right to left. See annotations. |
+ // (3) (2) (1) |
+ root_to_screen_ = to_device_pixels * rotation * to_dip; |
+ screen_to_root_ = to_device_pixels * inverse_rotation * to_dip; |
+} |
+ |
+gfx::PointF PointTransformer::ToScreenCoordinates( |
+ const gfx::PointF& root_location) { |
+ gfx::Point3F screen_location(root_location); |
+ root_to_screen_.TransformPoint(&screen_location); |
+ return screen_location.AsPointF(); |
+} |
+ |
+gfx::PointF PointTransformer::FromScreenCoordinates( |
+ const gfx::PointF& screen_location) { |
+ gfx::Point3F root_location(screen_location); |
+ screen_to_root_.TransformPoint(&root_location); |
+ return root_location.AsPointF(); |
+} |
+ |
+} // namespace remoting |