From 8fb68b79fbd00c9ce833ef0fb6c2cc7e200c1e33 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Wed, 22 Aug 2012 13:18:10 -0700 Subject: [PATCH] Bug 716575 (3/4) - Move viewport pixel ratio calculations into the platform [r=dbaron,jwir3,mfinkle,roc] --- content/base/public/nsContentUtils.h | 5 ++ content/base/src/nsContentUtils.cpp | 82 +++++++++++++++++++++------- 2 files changed, 68 insertions(+), 19 deletions(-) diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 907ae89c204..ca4e0dff120 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -1549,6 +1549,11 @@ public: uint32_t aDisplayWidth, uint32_t aDisplayHeight); + /** + * The device-pixel-to-CSS-px ratio used to adjust meta viewport values. + */ + static double GetDevicePixelsPerMetaViewportPixel(nsIWidget* aWidget); + // Call EnterMicroTask when you're entering JS execution. // Usually the best way to do this is to use nsAutoMicroTask. static void EnterMicroTask() { ++sMicroTaskLevel; } diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 5d622ccd64f..dc56b99f6d3 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -12,6 +12,8 @@ #include "jsdbgapi.h" #include "jsfriendapi.h" +#include + #include "Layers.h" #include "nsJSUtils.h" #include "nsCOMPtr.h" @@ -5174,12 +5176,44 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument, autoSize = true; } - uint32_t width = widthStr.ToInteger(&errorCode); - if (NS_FAILED(errorCode)) { - if (autoSize) { - width = aDisplayWidth; - } else { - width = Preferences::GetInt("browser.viewport.desktopWidth", 0); + // Now convert the scale into device pixels per CSS pixel. + nsIWidget *widget = WidgetForDocument(aDocument); + double pixelRatio = widget ? GetDevicePixelsPerMetaViewportPixel(widget) : 1.0; + scaleFloat *= pixelRatio; + scaleMinFloat *= pixelRatio; + scaleMaxFloat *= pixelRatio; + + uint32_t width, height; + if (autoSize) { + // aDisplayWidth and aDisplayHeight are in device pixels; convert them to + // CSS pixels for the viewport size. + width = aDisplayWidth / pixelRatio; + height = aDisplayHeight / pixelRatio; + } else { + nsresult widthErrorCode, heightErrorCode; + width = widthStr.ToInteger(&widthErrorCode); + height = heightStr.ToInteger(&heightErrorCode); + + // If width or height has not been set to a valid number by this point, + // fall back to a default value. + bool validWidth = (!widthStr.IsEmpty() && NS_SUCCEEDED(widthErrorCode) && width > 0); + bool validHeight = (!heightStr.IsEmpty() && NS_SUCCEEDED(heightErrorCode) && height > 0); + + if (!validWidth) { + if (validHeight && aDisplayWidth > 0 && aDisplayHeight > 0) { + width = uint32_t((height * aDisplayWidth) / aDisplayHeight); + } else { + width = Preferences::GetInt("browser.viewport.desktopWidth", + kViewportDefaultScreenWidth); + } + } + + if (!validHeight) { + if (aDisplayWidth > 0 && aDisplayHeight > 0) { + height = uint32_t((width * aDisplayHeight) / aDisplayWidth); + } else { + height = width; + } } } @@ -5189,19 +5223,7 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument, // Also recalculate the default zoom, if it wasn't specified in the metadata, // and the width is specified. if (scaleStr.IsEmpty() && !widthStr.IsEmpty()) { - scaleFloat = NS_MAX(scaleFloat, (float)(aDisplayWidth/width)); - } - - uint32_t height = heightStr.ToInteger(&errorCode); - - if (NS_FAILED(errorCode)) { - height = width * ((float)aDisplayHeight / aDisplayWidth); - } - - // If height was provided by the user, but width wasn't, then we should - // calculate the width. - if (widthStr.IsEmpty() && !heightStr.IsEmpty()) { - width = (uint32_t) ((height * aDisplayWidth) / aDisplayHeight); + scaleFloat = NS_MAX(scaleFloat, float(aDisplayWidth) / float(width)); } height = NS_MIN(height, kViewportMaxHeight); @@ -5237,6 +5259,28 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument, return ret; } +/* static */ +double +nsContentUtils::GetDevicePixelsPerMetaViewportPixel(nsIWidget* aWidget) +{ + int32_t prefValue = Preferences::GetInt("browser.viewport.scaleRatio", 0); + if (prefValue > 0) { + return double(prefValue) / 100.0; + } + + float dpi = aWidget->GetDPI(); + if (dpi < 200.0) { + // Includes desktop displays, LDPI and MDPI Android devices + return 1.0; + } + if (dpi < 300.0) { + // Includes Nokia N900, and HDPI Android devices + return 1.5; + } + // For very high-density displays like the iPhone 4, use an integer ratio. + return floor(dpi / 150.0); +} + /* static */ nsresult nsContentUtils::ProcessViewportInfo(nsIDocument *aDocument,