1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ash/host/transformer_helper.h" 6 7 #include "ash/host/ash_window_tree_host.h" 8 #include "ash/host/root_window_transformer.h" 9 #include "ui/aura/window.h" 10 #include "ui/aura/window_tree_host.h" 11 #include "ui/compositor/dip_util.h" 12 #include "ui/gfx/geometry/insets.h" 13 #include "ui/gfx/geometry/rect.h" 14 #include "ui/gfx/geometry/rect_f.h" 15 #include "ui/gfx/geometry/size.h" 16 #include "ui/gfx/size_conversions.h" 17 #include "ui/gfx/transform.h" 18 19 namespace ash { 20 namespace { 21 22 // A simple RootWindowTransformer without host insets. 23 class SimpleRootWindowTransformer : public RootWindowTransformer { 24 public: 25 SimpleRootWindowTransformer(const aura::Window* root_window, 26 const gfx::Transform& transform) 27 : root_window_(root_window), transform_(transform) {} 28 29 // RootWindowTransformer overrides: 30 virtual gfx::Transform GetTransform() const OVERRIDE { return transform_; } 31 32 virtual gfx::Transform GetInverseTransform() const OVERRIDE { 33 gfx::Transform invert; 34 if (!transform_.GetInverse(&invert)) 35 return transform_; 36 return invert; 37 } 38 39 virtual gfx::Rect GetRootWindowBounds(const gfx::Size& host_size) const 40 OVERRIDE { 41 gfx::Rect bounds(host_size); 42 gfx::RectF new_bounds(ui::ConvertRectToDIP(root_window_->layer(), bounds)); 43 transform_.TransformRect(&new_bounds); 44 return gfx::Rect(gfx::ToFlooredSize(new_bounds.size())); 45 } 46 47 virtual gfx::Insets GetHostInsets() const OVERRIDE { return gfx::Insets(); } 48 49 private: 50 virtual ~SimpleRootWindowTransformer() {} 51 52 const aura::Window* root_window_; 53 const gfx::Transform transform_; 54 55 DISALLOW_COPY_AND_ASSIGN(SimpleRootWindowTransformer); 56 }; 57 58 } // namespace 59 60 TransformerHelper::TransformerHelper(AshWindowTreeHost* ash_host) 61 : ash_host_(ash_host) { 62 SetTransform(gfx::Transform()); 63 } 64 65 TransformerHelper::~TransformerHelper() {} 66 67 gfx::Insets TransformerHelper::GetHostInsets() const { 68 return transformer_->GetHostInsets(); 69 } 70 71 void TransformerHelper::SetTransform(const gfx::Transform& transform) { 72 scoped_ptr<RootWindowTransformer> transformer(new SimpleRootWindowTransformer( 73 ash_host_->AsWindowTreeHost()->window(), transform)); 74 SetRootWindowTransformer(transformer.Pass()); 75 } 76 77 void TransformerHelper::SetRootWindowTransformer( 78 scoped_ptr<RootWindowTransformer> transformer) { 79 transformer_ = transformer.Pass(); 80 aura::WindowTreeHost* host = ash_host_->AsWindowTreeHost(); 81 aura::Window* window = host->window(); 82 window->SetTransform(transformer_->GetTransform()); 83 // If the layer is not animating, then we need to update the root window 84 // size immediately. 85 if (!window->layer()->GetAnimator()->is_animating()) 86 host->UpdateRootWindowSize(host->GetBounds().size()); 87 } 88 89 gfx::Transform TransformerHelper::GetTransform() const { 90 float scale = ui::GetDeviceScaleFactor( 91 ash_host_->AsWindowTreeHost()->window()->layer()); 92 gfx::Transform transform; 93 transform.Scale(scale, scale); 94 transform *= transformer_->GetTransform(); 95 return transform; 96 } 97 98 gfx::Transform TransformerHelper::GetInverseTransform() const { 99 float scale = ui::GetDeviceScaleFactor( 100 ash_host_->AsWindowTreeHost()->window()->layer()); 101 gfx::Transform transform; 102 transform.Scale(1.0f / scale, 1.0f / scale); 103 return transformer_->GetInverseTransform() * transform; 104 } 105 106 void TransformerHelper::UpdateWindowSize(const gfx::Size& host_size) { 107 ash_host_->AsWindowTreeHost()->window()->SetBounds( 108 transformer_->GetRootWindowBounds(host_size)); 109 } 110 111 } // namespace ash 112