Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: remoting/webapp/base/js/viewport.js

Issue 1109453005: [Chromoting] Extract shared viewport code into viewport.js. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 /**
6 * @fileoverview
7 * Provides shared view port management utilities.
8 */
9
10 /** @suppress {duplicate} */
11 var remoting = remoting || {};
12
13 (function() {
14
15 'use strict';
16
17 /** @type {Object} */
18 remoting.Viewport = {};
19
20 /**
21 * Helper function accepting client and host dimensions, and returning a chosen
22 * size for the plugin element, in DIPs.
23 *
24 * @param {{width: number, height: number}} clientSizeDips Available client
25 * dimensions, in DIPs.
26 * @param {number} clientPixelRatio Number of physical pixels per client DIP.
27 * @param {{width: number, height: number}} desktopSize Size of the host desktop
28 * in physical pixels.
29 * @param {{x: number, y: number}} desktopDpi DPI of the host desktop in both
30 * dimensions.
31 * @param {number} desktopScale The scale factor configured for the host.
32 * @param {boolean} isFullscreen True if full-screen mode is active.
33 * @param {boolean} shrinkToFit True if shrink-to-fit should be applied.
34 * @return {{width: number, height: number}} Chosen plugin dimensions, in DIPs.
35 */
36 remoting.Viewport.choosePluginSize = function(
37 clientSizeDips, clientPixelRatio, desktopSize, desktopDpi, desktopScale,
38 isFullscreen, shrinkToFit) {
39 base.debug.assert(clientSizeDips.width > 0);
40 base.debug.assert(clientSizeDips.height > 0);
41 base.debug.assert(clientPixelRatio >= 1.0);
42 base.debug.assert(desktopSize.width > 0);
43 base.debug.assert(desktopSize.height > 0);
44 base.debug.assert(desktopDpi.x > 0);
45 base.debug.assert(desktopDpi.y > 0);
46 base.debug.assert(desktopScale > 0);
47
48 // We have the following goals in sizing the desktop display at the client:
49 // 1. Avoid losing detail by down-scaling beyond 1:1 host:device pixels.
50 // 2. Avoid up-scaling if that will cause the client to need scrollbars.
51 // 3. Avoid introducing blurriness with non-integer up-scaling factors.
52 // 4. Avoid having huge "letterboxes" around the desktop, if it's really
53 // small.
54 // 5. Compensate for mismatched DPIs, so that the behaviour of features like
55 // shrink-to-fit matches their "natural" rather than their pixel size.
56 // e.g. with shrink-to-fit active a 1024x768 low-DPI host on a 640x480
57 // high-DPI client will be up-scaled to 1280x960, rather than displayed
58 // at 1:1 host:physical client pixels.
59 //
60 // To determine the ideal size we follow a four-stage process:
61 // 1. Determine the "natural" size at which to display the desktop.
62 // a. Initially assume 1:1 mapping of desktop to client device pixels.
63 // b. If host DPI is less than the client's then up-scale accordingly.
64 // c. If desktopScale is configured for the host then allow that to
65 // reduce the amount of up-scaling from (b). e.g. if the client:host
66 // DPIs are 2:1 then a desktopScale of 1.5 would reduce the up-scale
67 // to 4:3, while a desktopScale of 3.0 would result in no up-scaling.
68 // 2. If the natural size of the desktop is smaller than the client device
69 // then apply up-scaling by an integer scale factor to avoid excessive
70 // letterboxing.
71 // 3. If shrink-to-fit is configured then:
72 // a. If the natural size exceeds the client size then apply down-scaling
73 // by an arbitrary scale factor.
74 // b. If we're in full-screen mode and the client & host aspect-ratios
75 // are radically different (e.g. the host is actually multi-monitor)
76 // then shrink-to-fit to the shorter dimension, rather than leaving
77 // huge letterboxes; the user can then bump-scroll around the desktop.
78 // 4. If the overall scale factor is fractionally over an integer factor
79 // then reduce it to that integer factor, to avoid blurring.
80
81 // All calculations are performed in device pixels.
82 var clientWidth = clientSizeDips.width * clientPixelRatio;
83 var clientHeight = clientSizeDips.height * clientPixelRatio;
84
85 // 1. Determine a "natural" size at which to display the desktop.
86 var scale = 1.0;
87
88 // Determine the effective host device pixel ratio.
89 // Note that we round up or down to the closest integer pixel ratio.
90 var hostPixelRatioX = Math.round(desktopDpi.x / 96);
91 var hostPixelRatioY = Math.round(desktopDpi.y / 96);
92 var hostPixelRatio = Math.min(hostPixelRatioX, hostPixelRatioY);
93
94 // Allow up-scaling to account for DPI.
95 scale = Math.max(scale, clientPixelRatio / hostPixelRatio);
96
97 // Allow some or all of the up-scaling to be cancelled by the desktopScale.
98 if (desktopScale > 1.0) {
99 scale = Math.max(1.0, scale / desktopScale);
100 }
101
102 // 2. If the host is still much smaller than the client, then up-scale to
103 // avoid wasting space, but only by an integer factor, to avoid blurring.
104 if (desktopSize.width * scale <= clientWidth &&
105 desktopSize.height * scale <= clientHeight) {
106 var scaleX = Math.floor(clientWidth / desktopSize.width);
107 var scaleY = Math.floor(clientHeight / desktopSize.height);
108 scale = Math.min(scaleX, scaleY);
109 base.debug.assert(scale >= 1.0);
110 }
111
112 // 3. Apply shrink-to-fit, if configured.
113 if (shrinkToFit) {
114 var scaleFitWidth = Math.min(scale, clientWidth / desktopSize.width);
115 var scaleFitHeight = Math.min(scale, clientHeight / desktopSize.height);
116 scale = Math.min(scaleFitHeight, scaleFitWidth);
117
118 // If we're running full-screen then try to handle common side-by-side
119 // multi-monitor combinations more intelligently.
120 if (isFullscreen) {
121 // If the host has two monitors each the same size as the client then
122 // scale-to-fit will have the desktop occupy only 50% of the client area,
123 // in which case it would be preferable to down-scale less and let the
124 // user bump-scroll around ("scale-and-pan").
125 // Triggering scale-and-pan if less than 65% of the client area would be
126 // used adds enough fuzz to cope with e.g. 1280x800 client connecting to
127 // a (2x1280)x1024 host nicely.
128 // Note that we don't need to account for scrollbars while fullscreen.
129 if (scale <= scaleFitHeight * 0.65) {
130 scale = scaleFitHeight;
131 }
132 if (scale <= scaleFitWidth * 0.65) {
133 scale = scaleFitWidth;
134 }
135 }
136 }
137
138 // 4. Avoid blurring for close-to-integer up-scaling factors.
139 if (scale > 1.0) {
140 var scaleBlurriness = scale / Math.floor(scale);
141 if (scaleBlurriness < 1.1) {
142 scale = Math.floor(scale);
143 }
144 }
145
146 // Return the necessary plugin dimensions in DIPs.
147 scale = scale / clientPixelRatio;
148 var pluginWidth = Math.round(desktopSize.width * scale);
149 var pluginHeight = Math.round(desktopSize.height * scale);
150 return { width: pluginWidth, height: pluginHeight };
151 };
152
153 }());
OLDNEW
« no previous file with comments | « remoting/webapp/app_remoting/js/app_connected_view.js ('k') | remoting/webapp/base/js/viewport_unittest.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698