Bug 561455 - Change the ratio of CSS/viewport px to physical pixels on high density screens [r=mfinkle r=stechz]
authorMatt Brubeck <mbrubeck@mozilla.com>
Wed, 05 May 2010 15:51:55 -0400
changeset 49673 4fd6757c3c644f301b697af1a69349d51980cecc
parent 49672 7d8e9c2de0cbda0c5361bac2c43fed29c6ff591a
child 49674 e199d7e0ddd23ca6829753f771e05f5329c12749
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, stechz
bugs561455
Bug 561455 - Change the ratio of CSS/viewport px to physical pixels on high density screens [r=mfinkle r=stechz]
toolkit/content/Geometry.jsm
--- a/toolkit/content/Geometry.jsm
+++ b/toolkit/content/Geometry.jsm
@@ -118,29 +118,35 @@ let Util = {
   },
 
   makeURLAbsolute: function makeURLAbsolute(base, url) {
     // Note:  makeURI() will throw if url is not a valid URI
     return makeURI(url, null, makeURI(base)).spec;
   },
 
   getViewportMetadata: function getViewportMetadata(browser) {
+    let dpiScale = gPrefService.getIntPref("zoom.dpiScale") / 100;
+
+    // Device size in CSS pixels:
+    let deviceWidth  = window.innerWidth  / dpiScale;
+    let deviceHeight = window.innerHeight / dpiScale;
+
     let doctype = browser.contentDocument.doctype;
     if (doctype && /(WAP|WML|Mobile)/.test(doctype.publicId))
-      return { reason: "doctype", result: true, scale: 1.0 };
+      return { reason: "doctype", result: true, defaultZoom: dpiScale, width: deviceWidth };
 
     let windowUtils = browser.contentWindow
                              .QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIDOMWindowUtils);
     let handheldFriendly = windowUtils.getDocumentMetadata("HandheldFriendly");
     if (handheldFriendly == "true")
-      return { reason: "handheld", result: true, scale: 1.0 };
+      return { reason: "handheld", defaultZoom: dpiScale, width: deviceWidth };
 
     if (browser.contentDocument instanceof XULDocument)
-      return { reason: "chrome", result: true, scale: 1.0, autoSize: true, allowZoom: false };
+      return { reason: "chrome", defaultZoom: 1.0, autoSize: true, allowZoom: false };
 
     // viewport details found here
     // http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html
     // http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html
     
     // Note: These values will be NaN if parseFloat or parseInt doesn't find a number.
     // Remember that NaN is contagious: Math.max(1, NaN) == Math.min(1, NaN) == NaN.
     let viewportScale = parseFloat(windowUtils.getDocumentMetadata("viewport-initial-scale"));
@@ -152,42 +158,51 @@ let Util = {
     viewportScale    = Util.clamp(viewportScale,    kViewportMinScale, kViewportMaxScale);
     viewportMinScale = Util.clamp(viewportMinScale, kViewportMinScale, kViewportMaxScale);
     viewportMaxScale = Util.clamp(viewportMaxScale, kViewportMinScale, kViewportMaxScale);
 
     // If initial scale is 1.0 and width is not set, assume width=device-width
     if (viewportScale == 1.0 && !viewportWidthStr)
       viewportWidthStr = "device-width";
 
-    let viewportWidth = viewportWidthStr == "device-width" ? window.innerWidth : parseInt(viewportWidthStr);
-    let viewportHeight = viewportHeightStr == "device-height" ? window.innerHeight : parseInt(viewportHeightStr);
+    let viewportWidth = viewportWidthStr == "device-width" ? deviceWidth
+      : Util.clamp(parseInt(viewportWidthStr), kViewportMinWidth, kViewportMaxWidth);
+    let viewportHeight = viewportHeightStr == "device-height" ? deviceHeight
+      : Util.clamp(parseInt(viewportHeightStr), kViewportMinHeight, kViewportMaxHeight);
 
-    viewportWidth  = Util.clamp(viewportWidth,  kViewportMinWidth,  kViewportMaxWidth);
-    viewportHeight = Util.clamp(viewportHeight, kViewportMinHeight, kViewportMaxHeight);
- 
+    // Zoom level is the final (device pixel : CSS pixel) ratio for content.
+    // Since web content specifies scale as (reference pixel : CSS pixel) ratio,
+    // multiply the requested scale by a constant (device pixel : reference pixel)
+    // factor to account for high DPI devices.
+    //
+    // See bug 561445 or any of the examples of chrome/tests/browser_viewport_XX.html
+    // for more information and examples.
+    let defaultZoom = viewportScale    * dpiScale;
+    let minZoom     = viewportMinScale * dpiScale;
+    let maxZoom     = viewportMaxScale * dpiScale;
+
     // If (scale * width) < device-width, increase the width (bug 561413).
-    let maxInitialScale = viewportScale || viewportMaxScale;
-    if (maxInitialScale && viewportWidth)
-      viewportWidth = Math.max(viewportWidth, window.innerWidth / maxInitialScale);
+    let maxInitialZoom = defaultZoom || maxZoom;
+    if (maxInitialZoom && viewportWidth)
+      viewportWidth = Math.max(viewportWidth, window.innerWidth / maxInitialZoom);
 
     if (viewportScale > 0 || viewportWidth > 0 || viewportHeight > 0 || viewportMinScale > 0 || viewportMaxScale > 0) {
       return {
         reason: "viewport",
-        result: true,
-        scale: viewportScale,
-        minScale: viewportMinScale,
-        maxScale: viewportMaxScale,
+        defaultZoom: defaultZoom,
+        minZoom: minZoom,
+        maxZoom: maxZoom,
         width: viewportWidth,
         height: viewportHeight,
         autoSize: viewportWidthStr == "device-width" || viewportHeightStr == "device-height",
         allowZoom: windowUtils.getDocumentMetadata("viewport-user-scalable") != "no"
       };
     }
 
-    return { reason: "", result: false, allowZoom: true };
+    return { reason: null, allowZoom: true };
   },
 
   clamp: function(num, min, max) {
     return Math.max(min, Math.min(max, num));
   },
 
   /**
    * Determines whether a home page override is needed.