author | Matt Brubeck <mbrubeck@mozilla.com> |
Wed, 22 Aug 2012 13:18:10 -0700 | |
changeset 107779 | 39803b4c2b9d0bf3011379ec6079b2cf5878af27 |
parent 107778 | ab874d12dcde471855f0a5de5b40d3400018f86d |
child 107780 | 9108fa673bfee54a3611fd0c261134c51160b0d8 |
push id | 23509 |
push user | ryanvm@gmail.com |
push date | Sat, 22 Sep 2012 12:28:38 +0000 |
treeherder | mozilla-central@b461a7cd250e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | dbaron, jwir3, mfinkle, roc |
bugs | 716575 |
milestone | 18.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
content/base/public/nsContentUtils.h | file | annotate | diff | comparison | revisions | |
content/base/src/nsContentUtils.cpp | file | annotate | diff | comparison | revisions |
--- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -1544,16 +1544,21 @@ public: * * NOTE: If the site is optimized for mobile (via the doctype), this * will return viewport information that specifies default information. */ static ViewportInfo GetViewportInfo(nsIDocument* aDocument, 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; } static void LeaveMicroTask(); static bool IsInMicroTask() { return sMicroTaskLevel != 0; } static uint32_t MicroTaskLevel() { return sMicroTaskLevel; } static void SetMicroTaskLevel(uint32_t aLevel) { sMicroTaskLevel = aLevel; }
--- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -7,16 +7,18 @@ /* A namespace class for static layout utilities. */ #include "mozilla/Util.h" #include "jsapi.h" #include "jsdbgapi.h" #include "jsfriendapi.h" +#include <math.h> + #include "Layers.h" #include "nsJSUtils.h" #include "nsCOMPtr.h" #include "nsAString.h" #include "nsPrintfCString.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptContext.h" #include "nsDOMCID.h" @@ -5169,44 +5171,64 @@ nsContentUtils::GetViewportInfo(nsIDocum if (widthStr.IsEmpty() && (heightStr.EqualsLiteral("device-height") || scaleFloat == 1.0)) { 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; + } } } width = NS_MIN(width, kViewportMaxWidth); width = NS_MAX(width, kViewportMinWidth); // 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); height = NS_MAX(height, kViewportMinHeight); // We need to perform a conversion, but only if the initial or maximum // scale were set explicitly by the user. if (!scaleStr.IsEmpty() && NS_SUCCEEDED(scaleErrorCode)) { @@ -5233,16 +5255,38 @@ nsContentUtils::GetViewportInfo(nsIDocum ret.defaultZoom = scaleFloat; ret.minZoom = scaleMinFloat; ret.maxZoom = scaleMaxFloat; ret.autoSize = autoSize; 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, const nsAString &viewportInfo) { /* We never fail. */ nsresult rv = NS_OK; aDocument->SetHeaderData(nsGkAtoms::viewport, viewportInfo);