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 19namespace ash { 20namespace { 21 22// A simple RootWindowTransformer without host insets. 23class 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 60TransformerHelper::TransformerHelper(AshWindowTreeHost* ash_host) 61 : ash_host_(ash_host) { 62 SetTransform(gfx::Transform()); 63} 64 65TransformerHelper::~TransformerHelper() {} 66 67gfx::Insets TransformerHelper::GetHostInsets() const { 68 return transformer_->GetHostInsets(); 69} 70 71void 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 77void 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 89gfx::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 98gfx::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 106void TransformerHelper::UpdateWindowSize(const gfx::Size& host_size) { 107 ash_host_->AsWindowTreeHost()->window()->SetBounds( 108 transformer_->GetRootWindowBounds(host_size)); 109} 110 111} // namespace ash 112