15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/touch/touch_device.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_base_switches.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/display.h"
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/metro.h"
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/gfx/win/dpi.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <Windows.h>
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ScaleFactorComparator(const ScaleFactor& lhs, const ScaleFactor& rhs){
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return GetScaleForScaleFactor(lhs) < GetScaleForScaleFactor(rhs);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<ScaleFactor>* g_supported_scale_factors = NULL;
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const float kScaleFactorScales[] = {1.0f, 1.0f, 1.25f, 1.33f, 1.4f, 1.5f, 1.8f,
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    2.0f, 2.5f, 3.0f};
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(NUM_SCALE_FACTORS == arraysize(kScaleFactorScales),
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               kScaleFactorScales_incorrect_size);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SetSupportedScaleFactors(
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::vector<ui::ScaleFactor>& scale_factors) {
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (g_supported_scale_factors != NULL)
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    delete g_supported_scale_factors;
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  g_supported_scale_factors = new std::vector<ScaleFactor>(scale_factors);
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::sort(g_supported_scale_factors->begin(),
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            g_supported_scale_factors->end(),
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            ScaleFactorComparator);
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Set ImageSkia's supported scales.
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::vector<float> scales;
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (std::vector<ScaleFactor>::const_iterator it =
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          g_supported_scale_factors->begin();
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)       it != g_supported_scale_factors->end(); ++it) {
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scales.push_back(kScaleFactorScales[*it]);
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::ImageSkia::SetSupportedScales(scales);
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const std::vector<ScaleFactor>& GetSupportedScaleFactors() {
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(g_supported_scale_factors != NULL);
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return *g_supported_scale_factors;
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ScaleFactor GetSupportedScaleFactor(float scale) {
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(g_supported_scale_factors != NULL);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScaleFactor closest_match = SCALE_FACTOR_100P;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float smallest_diff =  std::numeric_limits<float>::max();
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < g_supported_scale_factors->size(); ++i) {
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ScaleFactor scale_factor = (*g_supported_scale_factors)[i];
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float diff = std::abs(kScaleFactorScales[scale_factor] - scale);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (diff < smallest_diff) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      closest_match = scale_factor;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      smallest_diff = diff;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_NE(closest_match, SCALE_FACTOR_NONE);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return closest_match;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)float GetImageScale(ScaleFactor scale_factor) {
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_WIN)
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (gfx::IsHighDPIEnabled())
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return gfx::win::GetDeviceScaleFactor();
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return GetScaleForScaleFactor(scale_factor);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochfloat GetScaleForScaleFactor(ScaleFactor scale_factor) {
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return kScaleFactorScales[scale_factor];
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ScopedSetSupportedScaleFactors::ScopedSetSupportedScaleFactors(
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::vector<ui::ScaleFactor>& new_scale_factors) {
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (g_supported_scale_factors) {
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    original_scale_factors_ =
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        new std::vector<ScaleFactor>(*g_supported_scale_factors);
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else {
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    original_scale_factors_ = NULL;
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetSupportedScaleFactors(new_scale_factors);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ScopedSetSupportedScaleFactors::~ScopedSetSupportedScaleFactors() {
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (original_scale_factors_) {
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SetSupportedScaleFactors(*original_scale_factors_);
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    delete original_scale_factors_;
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else {
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    delete g_supported_scale_factors;
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    g_supported_scale_factors = NULL;
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace test
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX)
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)float GetScaleFactorForNativeView(gfx::NativeView view) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Screen* screen = gfx::Screen::GetScreenFor(view);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (screen->IsDIPEnabled()) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Display display = screen->GetDisplayNearestWindow(view);
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return display.device_scale_factor();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return 1.0f;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(OS_MACOSX)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
134