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

Side by Side Diff: remoting/webapp/crd/js/desktop_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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview 6 * @fileoverview
7 * Provides view port management utilities below for a desktop remoting session. 7 * Provides view port management utilities below for a desktop remoting session.
8 * - Enabling bump scrolling 8 * - Enabling bump scrolling
9 * - Resizing the viewport to fit the host desktop 9 * - Resizing the viewport to fit the host desktop
10 * - Resizing the host desktop to fit the client viewport. 10 * - Resizing the host desktop to fit the client viewport.
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 remoting.DesktopViewport.prototype.updateDimensions_ = function() { 323 remoting.DesktopViewport.prototype.updateDimensions_ = function() {
324 var dimensions = this.hostDesktop_.getDimensions(); 324 var dimensions = this.hostDesktop_.getDimensions();
325 if (dimensions.width === 0 || dimensions.height === 0) { 325 if (dimensions.width === 0 || dimensions.height === 0) {
326 return; 326 return;
327 } 327 }
328 328
329 var desktopSize = { width: dimensions.width, 329 var desktopSize = { width: dimensions.width,
330 height: dimensions.height }; 330 height: dimensions.height };
331 var desktopDpi = { x: dimensions.xDpi, 331 var desktopDpi = { x: dimensions.xDpi,
332 y: dimensions.yDpi }; 332 y: dimensions.yDpi };
333 var newSize = remoting.DesktopViewport.choosePluginSize( 333 var newSize = remoting.Viewport.choosePluginSize(
334 this.getClientArea(), window.devicePixelRatio, 334 this.getClientArea(), window.devicePixelRatio,
335 desktopSize, desktopDpi, this.hostOptions_.desktopScale, 335 desktopSize, desktopDpi, this.hostOptions_.desktopScale,
336 remoting.fullscreen.isActive(), this.hostOptions_.shrinkToFit); 336 remoting.fullscreen.isActive(), this.hostOptions_.shrinkToFit);
337 337
338 // Resize the plugin if necessary. 338 // Resize the plugin if necessary.
339 console.log('plugin dimensions:' + newSize.width + 'x' + newSize.height); 339 console.log('plugin dimensions:' + newSize.width + 'x' + newSize.height);
340 this.pluginElement_.style.width = newSize.width + 'px'; 340 this.pluginElement_.style.width = newSize.width + 'px';
341 this.pluginElement_.style.height = newSize.height + 'px'; 341 this.pluginElement_.style.height = newSize.height + 'px';
342 }; 342 };
343 343
344 /**
345 * Helper function accepting client and host dimensions, and returning a chosen
346 * size for the plugin element, in DIPs.
347 *
348 * @param {{width: number, height: number}} clientSizeDips Available client
349 * dimensions, in DIPs.
350 * @param {number} clientPixelRatio Number of physical pixels per client DIP.
351 * @param {{width: number, height: number}} desktopSize Size of the host desktop
352 * in physical pixels.
353 * @param {{x: number, y: number}} desktopDpi DPI of the host desktop in both
354 * dimensions.
355 * @param {number} desktopScale The scale factor configured for the host.
356 * @param {boolean} isFullscreen True if full-screen mode is active.
357 * @param {boolean} shrinkToFit True if shrink-to-fit should be applied.
358 * @return {{width: number, height: number}} Chosen plugin dimensions, in DIPs.
359 */
360 remoting.DesktopViewport.choosePluginSize = function(
361 clientSizeDips, clientPixelRatio, desktopSize, desktopDpi, desktopScale,
362 isFullscreen, shrinkToFit) {
363 base.debug.assert(clientSizeDips.width > 0);
364 base.debug.assert(clientSizeDips.height > 0);
365 base.debug.assert(clientPixelRatio >= 1.0);
366 base.debug.assert(desktopSize.width > 0);
367 base.debug.assert(desktopSize.height > 0);
368 base.debug.assert(desktopDpi.x > 0);
369 base.debug.assert(desktopDpi.y > 0);
370 base.debug.assert(desktopScale > 0);
371
372 // We have the following goals in sizing the desktop display at the client:
373 // 1. Avoid losing detail by down-scaling beyond 1:1 host:device pixels.
374 // 2. Avoid up-scaling if that will cause the client to need scrollbars.
375 // 3. Avoid introducing blurriness with non-integer up-scaling factors.
376 // 4. Avoid having huge "letterboxes" around the desktop, if it's really
377 // small.
378 // 5. Compensate for mismatched DPIs, so that the behaviour of features like
379 // shrink-to-fit matches their "natural" rather than their pixel size.
380 // e.g. with shrink-to-fit active a 1024x768 low-DPI host on a 640x480
381 // high-DPI client will be up-scaled to 1280x960, rather than displayed
382 // at 1:1 host:physical client pixels.
383 //
384 // To determine the ideal size we follow a four-stage process:
385 // 1. Determine the "natural" size at which to display the desktop.
386 // a. Initially assume 1:1 mapping of desktop to client device pixels.
387 // b. If host DPI is less than the client's then up-scale accordingly.
388 // c. If desktopScale is configured for the host then allow that to
389 // reduce the amount of up-scaling from (b). e.g. if the client:host
390 // DPIs are 2:1 then a desktopScale of 1.5 would reduce the up-scale
391 // to 4:3, while a desktopScale of 3.0 would result in no up-scaling.
392 // 2. If the natural size of the desktop is smaller than the client device
393 // then apply up-scaling by an integer scale factor to avoid excessive
394 // letterboxing.
395 // 3. If shrink-to-fit is configured then:
396 // a. If the natural size exceeds the client size then apply down-scaling
397 // by an arbitrary scale factor.
398 // b. If we're in full-screen mode and the client & host aspect-ratios
399 // are radically different (e.g. the host is actually multi-monitor)
400 // then shrink-to-fit to the shorter dimension, rather than leaving
401 // huge letterboxes; the user can then bump-scroll around the desktop.
402 // 4. If the overall scale factor is fractionally over an integer factor
403 // then reduce it to that integer factor, to avoid blurring.
404
405 // All calculations are performed in device pixels.
406 var clientWidth = clientSizeDips.width * clientPixelRatio;
407 var clientHeight = clientSizeDips.height * clientPixelRatio;
408
409 // 1. Determine a "natural" size at which to display the desktop.
410 var scale = 1.0;
411
412 // Determine the effective host device pixel ratio.
413 // Note that we round up or down to the closest integer pixel ratio.
414 var hostPixelRatioX = Math.round(desktopDpi.x / 96);
415 var hostPixelRatioY = Math.round(desktopDpi.y / 96);
416 var hostPixelRatio = Math.min(hostPixelRatioX, hostPixelRatioY);
417
418 // Allow up-scaling to account for DPI.
419 scale = Math.max(scale, clientPixelRatio / hostPixelRatio);
420
421 // Allow some or all of the up-scaling to be cancelled by the desktopScale.
422 if (desktopScale > 1.0) {
423 scale = Math.max(1.0, scale / desktopScale);
424 }
425
426 // 2. If the host is still much smaller than the client, then up-scale to
427 // avoid wasting space, but only by an integer factor, to avoid blurring.
428 if (desktopSize.width * scale <= clientWidth &&
429 desktopSize.height * scale <= clientHeight) {
430 var scaleX = Math.floor(clientWidth / desktopSize.width);
431 var scaleY = Math.floor(clientHeight / desktopSize.height);
432 scale = Math.min(scaleX, scaleY);
433 base.debug.assert(scale >= 1.0);
434 }
435
436 // 3. Apply shrink-to-fit, if configured.
437 if (shrinkToFit) {
438 var scaleFitWidth = Math.min(scale, clientWidth / desktopSize.width);
439 var scaleFitHeight = Math.min(scale, clientHeight / desktopSize.height);
440 scale = Math.min(scaleFitHeight, scaleFitWidth);
441
442 // If we're running full-screen then try to handle common side-by-side
443 // multi-monitor combinations more intelligently.
444 if (isFullscreen) {
445 // If the host has two monitors each the same size as the client then
446 // scale-to-fit will have the desktop occupy only 50% of the client area,
447 // in which case it would be preferable to down-scale less and let the
448 // user bump-scroll around ("scale-and-pan").
449 // Triggering scale-and-pan if less than 65% of the client area would be
450 // used adds enough fuzz to cope with e.g. 1280x800 client connecting to
451 // a (2x1280)x1024 host nicely.
452 // Note that we don't need to account for scrollbars while fullscreen.
453 if (scale <= scaleFitHeight * 0.65) {
454 scale = scaleFitHeight;
455 }
456 if (scale <= scaleFitWidth * 0.65) {
457 scale = scaleFitWidth;
458 }
459 }
460 }
461
462 // 4. Avoid blurring for close-to-integer up-scaling factors.
463 if (scale > 1.0) {
464 var scaleBlurriness = scale / Math.floor(scale);
465 if (scaleBlurriness < 1.1) {
466 scale = Math.floor(scale);
467 }
468 }
469
470 // Return the necessary plugin dimensions in DIPs.
471 scale = scale / clientPixelRatio;
472 var pluginWidth = Math.round(desktopSize.width * scale);
473 var pluginHeight = Math.round(desktopSize.height * scale);
474 return { width: pluginWidth, height: pluginHeight };
475 };
476
477 /** @private */ 344 /** @private */
478 remoting.DesktopViewport.prototype.resetScroll_ = function() { 345 remoting.DesktopViewport.prototype.resetScroll_ = function() {
479 this.pluginContainer_.style.marginTop = '0px'; 346 this.pluginContainer_.style.marginTop = '0px';
480 this.pluginContainer_.style.marginLeft = '0px'; 347 this.pluginContainer_.style.marginLeft = '0px';
481 }; 348 };
482 349
483 /** 350 /**
484 * Sets and stores the scale factor to apply to host sizing requests. 351 * Sets and stores the scale factor to apply to host sizing requests.
485 * The desktopScale applies to the dimensions reported to the host, not 352 * The desktopScale applies to the dimensions reported to the host, not
486 * to the client DPI reported to it. 353 * to the client DPI reported to it.
487 * 354 *
488 * @param {number} desktopScale Scale factor to apply. 355 * @param {number} desktopScale Scale factor to apply.
489 */ 356 */
490 remoting.DesktopViewport.prototype.setDesktopScale = function(desktopScale) { 357 remoting.DesktopViewport.prototype.setDesktopScale = function(desktopScale) {
491 this.hostOptions_.desktopScale = desktopScale; 358 this.hostOptions_.desktopScale = desktopScale;
492 359
493 // onResize() will update the plugin size and scrollbars for the new 360 // onResize() will update the plugin size and scrollbars for the new
494 // scaled plugin dimensions, and send a client resolution notification. 361 // scaled plugin dimensions, and send a client resolution notification.
495 this.onResize(); 362 this.onResize();
496 363
497 // Save the new desktop scale setting. 364 // Save the new desktop scale setting.
498 this.hostOptions_.save(); 365 this.hostOptions_.save();
499 }; 366 };
500 367
501 }()); 368 }());
OLDNEW
« no previous file with comments | « remoting/webapp/base/js/viewport_unittest.js ('k') | remoting/webapp/crd/js/desktop_viewport_unittest.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698