1 // Copyright 2018 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/magnifier/magnifier_utils.h"
6
7 #include <algorithm>
8 #include <cmath>
9
10 #include "ash/shell.h"
11 #include "base/check_op.h"
12 #include "base/numerics/ranges.h"
13 #include "ui/aura/window.h"
14 #include "ui/aura/window_tree_host.h"
15 #include "ui/base/ime/chromeos/ime_bridge.h"
16
17 namespace ash {
18 namespace magnifier_utils {
19
20 namespace {
21
22 // Converts the given |scale| to an index such that
23 // `kMagnificationScaleFactor ^ index = scale`.
IndexFromScale(float scale)24 int IndexFromScale(float scale) {
25 // Remember from the Logarithm rules:
26 // logBar(Foo) = log2(Foo) / log2(Bar).
27 return std::round(std::log(scale) / std::log(kMagnificationScaleFactor));
28 }
29
30 } // namespace
31
GetScaleFromScroll(float linear_offset,float current_scale,float min_scale,float max_scale)32 float GetScaleFromScroll(float linear_offset,
33 float current_scale,
34 float min_scale,
35 float max_scale) {
36 DCHECK_GE(current_scale, min_scale);
37 DCHECK_LE(current_scale, max_scale);
38
39 // Convert the current scale back to its corresponding linear scale according
40 // to the formula `scale = (max - min) * offset ^ 2 + min`.
41 const float scale_range = max_scale - min_scale;
42 float linear_adjustment =
43 std::sqrt((current_scale - min_scale) / scale_range);
44 // Add the new linear offset.
45 linear_adjustment += linear_offset;
46
47 // Convert back to the exponential scale.
48 return scale_range * linear_adjustment * linear_adjustment + min_scale;
49 }
50
GetNextMagnifierScaleValue(int delta_index,float current_scale,float min_scale,float max_scale)51 float GetNextMagnifierScaleValue(int delta_index,
52 float current_scale,
53 float min_scale,
54 float max_scale) {
55 const int current_index = IndexFromScale(current_scale);
56 const int new_scale_index = current_index + delta_index;
57 const float new_scale = std::pow(kMagnificationScaleFactor, new_scale_index);
58 return base::ClampToRange(new_scale, min_scale, max_scale);
59 }
60
GetInputMethod(aura::Window * root_window)61 ui::InputMethod* GetInputMethod(aura::Window* root_window) {
62 ui::IMEBridge* bridge = ui::IMEBridge::Get();
63 if (bridge && bridge->GetInputContextHandler())
64 return bridge->GetInputContextHandler()->GetInputMethod();
65
66 if (root_window && root_window->GetHost())
67 return root_window->GetHost()->GetInputMethod();
68
69 // Needed by a handful of browser tests that use MockInputMethod.
70 return Shell::GetRootWindowForNewWindows()->GetHost()->GetInputMethod();
71 }
72
73 } // namespace magnifier_utils
74 } // namespace ash
75