1// Copyright (c) 2012 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 "ui/gfx/display.h" 6 7#include <algorithm> 8 9#include "base/command_line.h" 10#include "base/logging.h" 11#include "base/strings/string_number_conversions.h" 12#include "base/strings/stringprintf.h" 13#include "ui/gfx/insets.h" 14#include "ui/gfx/point_conversions.h" 15#include "ui/gfx/point_f.h" 16#include "ui/gfx/size_conversions.h" 17#include "ui/gfx/switches.h" 18 19namespace gfx { 20namespace { 21 22bool HasForceDeviceScaleFactorImpl() { 23 return CommandLine::ForCurrentProcess()->HasSwitch( 24 switches::kForceDeviceScaleFactor); 25} 26 27float GetForcedDeviceScaleFactorImpl() { 28 double scale_in_double = 1.0; 29 if (HasForceDeviceScaleFactorImpl()) { 30 std::string value = CommandLine::ForCurrentProcess()-> 31 GetSwitchValueASCII(switches::kForceDeviceScaleFactor); 32 if (!base::StringToDouble(value, &scale_in_double)) 33 LOG(ERROR) << "Failed to parse the default device scale factor:" << value; 34 } 35 return static_cast<float>(scale_in_double); 36} 37 38int64 internal_display_id_ = -1; 39 40} // namespace 41 42const int64 Display::kInvalidDisplayID = -1; 43 44// static 45float Display::GetForcedDeviceScaleFactor() { 46 static const float kForcedDeviceScaleFactor = 47 GetForcedDeviceScaleFactorImpl(); 48 return kForcedDeviceScaleFactor; 49} 50 51//static 52bool Display::HasForceDeviceScaleFactor() { 53 static const bool kHasForceDeviceScaleFactor = 54 HasForceDeviceScaleFactorImpl(); 55 return kHasForceDeviceScaleFactor; 56} 57 58Display::Display() 59 : id_(kInvalidDisplayID), 60 device_scale_factor_(GetForcedDeviceScaleFactor()), 61 rotation_(ROTATE_0), 62 touch_support_(TOUCH_SUPPORT_UNKNOWN) { 63} 64 65Display::Display(int64 id) 66 : id_(id), 67 device_scale_factor_(GetForcedDeviceScaleFactor()), 68 rotation_(ROTATE_0), 69 touch_support_(TOUCH_SUPPORT_UNKNOWN) { 70} 71 72Display::Display(int64 id, const gfx::Rect& bounds) 73 : id_(id), 74 bounds_(bounds), 75 work_area_(bounds), 76 device_scale_factor_(GetForcedDeviceScaleFactor()), 77 rotation_(ROTATE_0), 78 touch_support_(TOUCH_SUPPORT_UNKNOWN) { 79#if defined(USE_AURA) 80 SetScaleAndBounds(device_scale_factor_, bounds); 81#endif 82} 83 84Display::~Display() { 85} 86 87int Display::RotationAsDegree() const { 88 switch (rotation_) { 89 case ROTATE_0: 90 return 0; 91 case ROTATE_90: 92 return 90; 93 case ROTATE_180: 94 return 180; 95 case ROTATE_270: 96 return 270; 97 } 98 99 NOTREACHED(); 100 return 0; 101} 102 103void Display::SetRotationAsDegree(int rotation) { 104 switch (rotation) { 105 case 0: 106 rotation_ = ROTATE_0; 107 break; 108 case 90: 109 rotation_ = ROTATE_90; 110 break; 111 case 180: 112 rotation_ = ROTATE_180; 113 break; 114 case 270: 115 rotation_ = ROTATE_270; 116 break; 117 default: 118 // We should not reach that but we will just ignore the call if we do. 119 NOTREACHED(); 120 } 121} 122 123Insets Display::GetWorkAreaInsets() const { 124 return gfx::Insets(work_area_.y() - bounds_.y(), 125 work_area_.x() - bounds_.x(), 126 bounds_.bottom() - work_area_.bottom(), 127 bounds_.right() - work_area_.right()); 128} 129 130void Display::SetScaleAndBounds( 131 float device_scale_factor, 132 const gfx::Rect& bounds_in_pixel) { 133 Insets insets = bounds_.InsetsFrom(work_area_); 134 if (!HasForceDeviceScaleFactor()) { 135#if defined(OS_MACOSX) 136 // Unless an explicit scale factor was provided for testing, ensure the 137 // scale is integral. 138 device_scale_factor = static_cast<int>(device_scale_factor); 139#endif 140 device_scale_factor_ = device_scale_factor; 141 } 142 device_scale_factor_ = std::max(1.0f, device_scale_factor_); 143 bounds_ = gfx::Rect( 144 gfx::ToFlooredPoint(gfx::ScalePoint(bounds_in_pixel.origin(), 145 1.0f / device_scale_factor_)), 146 gfx::ToFlooredSize(gfx::ScaleSize(bounds_in_pixel.size(), 147 1.0f / device_scale_factor_))); 148 UpdateWorkAreaFromInsets(insets); 149} 150 151void Display::SetSize(const gfx::Size& size_in_pixel) { 152 gfx::Point origin = bounds_.origin(); 153#if defined(USE_AURA) 154 gfx::PointF origin_f = origin; 155 origin_f.Scale(device_scale_factor_); 156 origin.SetPoint(origin_f.x(), origin_f.y()); 157#endif 158 SetScaleAndBounds(device_scale_factor_, gfx::Rect(origin, size_in_pixel)); 159} 160 161void Display::UpdateWorkAreaFromInsets(const gfx::Insets& insets) { 162 work_area_ = bounds_; 163 work_area_.Inset(insets); 164} 165 166gfx::Size Display::GetSizeInPixel() const { 167 return gfx::ToFlooredSize(gfx::ScaleSize(size(), device_scale_factor_)); 168} 169 170std::string Display::ToString() const { 171 return base::StringPrintf( 172 "Display[%lld] bounds=%s, workarea=%s, scale=%f, %s", 173 static_cast<long long int>(id_), 174 bounds_.ToString().c_str(), 175 work_area_.ToString().c_str(), 176 device_scale_factor_, 177 IsInternal() ? "internal" : "external"); 178} 179 180bool Display::IsInternal() const { 181 return is_valid() && (id_ == internal_display_id_); 182} 183 184int64 Display::InternalDisplayId() { 185 return internal_display_id_; 186} 187 188void Display::SetInternalDisplayId(int64 internal_display_id) { 189 internal_display_id_ = internal_display_id; 190} 191 192} // namespace gfx 193