[Chromium] Implement target-densityDpi viewport property emulation
authormnaganov@chromium.org <mnaganov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Apr 2013 09:19:11 +0000 (09:19 +0000)
committermnaganov@chromium.org <mnaganov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Apr 2013 09:19:11 +0000 (09:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=110835

The value is only used in the Chromium port, when the corresponding
setting is enabled.

This is needed for supporting existing WebView-based applications
that rely on this property.

Reviewed by Adam Barth.

Source/WebCore:

* dom/ViewportArguments.cpp:
(WebCore::findTargetDensityDPIValue):
(WebCore):
(WebCore::setViewportFeature):
* dom/ViewportArguments.h:
(WebCore::ViewportArguments::ViewportArguments):
(ViewportArguments):
(WebCore::ViewportArguments::operator==):

Source/WebKit/chromium:

* public/WebSettings.h:
(WebSettings):
* src/ChromeClientImpl.cpp:
(WebKit):
(WebKit::calculateTargetDensityDPIFactor):
(WebKit::ChromeClientImpl::dispatchViewportPropertiesDidChange):
* src/WebSettingsImpl.cpp:
(WebKit::WebSettingsImpl::WebSettingsImpl):
(WebKit::WebSettingsImpl::setSupportDeprecatedTargetDensityDPI):
(WebKit):
* src/WebSettingsImpl.h:
(WebSettingsImpl):
(WebKit::WebSettingsImpl::supportDeprecatedTargetDensityDPI):
* tests/WebFrameTest.cpp:
* tests/data/viewport-target-densitydpi-high.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@147529 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/dom/ViewportArguments.cpp
Source/WebCore/dom/ViewportArguments.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebSettings.h
Source/WebKit/chromium/src/ChromeClientImpl.cpp
Source/WebKit/chromium/src/WebSettingsImpl.cpp
Source/WebKit/chromium/src/WebSettingsImpl.h
Source/WebKit/chromium/tests/WebFrameTest.cpp
Source/WebKit/chromium/tests/data/viewport-target-densitydpi-high.html [new file with mode: 0644]

index 8151fdf..dec7ad2 100644 (file)
@@ -1,3 +1,25 @@
+2013-04-03  Mikhail Naganov  <mnaganov@chromium.org>
+
+        [Chromium] Implement target-densityDpi viewport property emulation
+        https://bugs.webkit.org/show_bug.cgi?id=110835
+
+        The value is only used in the Chromium port, when the corresponding
+        setting is enabled.
+
+        This is needed for supporting existing WebView-based applications
+        that rely on this property.
+
+        Reviewed by Adam Barth.
+
+        * dom/ViewportArguments.cpp:
+        (WebCore::findTargetDensityDPIValue):
+        (WebCore):
+        (WebCore::setViewportFeature):
+        * dom/ViewportArguments.h:
+        (WebCore::ViewportArguments::ViewportArguments):
+        (ViewportArguments):
+        (WebCore::ViewportArguments::operator==):
+
 2013-04-03  Mike West  <mkwst@chromium.org>
 
         Extract URL that doesn't inherit a parent's SecurityOrigin out into a constant.
index 3d242d6..c94afec 100644 (file)
@@ -382,6 +382,25 @@ static float findUserScalableValue(const String& keyString, const String& valueS
     return 1;
 }
 
+static float findTargetDensityDPIValue(const String& keyString, const String& valueString, Document* document)
+{
+    if (equalIgnoringCase(valueString, "device-dpi"))
+        return ViewportArguments::ValueDeviceDPI;
+    if (equalIgnoringCase(valueString, "low-dpi"))
+        return ViewportArguments::ValueLowDPI;
+    if (equalIgnoringCase(valueString, "medium-dpi"))
+        return ViewportArguments::ValueMediumDPI;
+    if (equalIgnoringCase(valueString, "high-dpi"))
+        return ViewportArguments::ValueHighDPI;
+
+    bool ok;
+    float value = numericPrefix(keyString, valueString, document, &ok);
+    if (!ok || value < 70 || value > 400)
+        return ViewportArguments::ValueAuto;
+
+    return value;
+}
+
 void setViewportFeature(const String& keyString, const String& valueString, Document* document, void* data)
 {
     ViewportArguments* arguments = static_cast<ViewportArguments*>(data);
@@ -398,9 +417,10 @@ void setViewportFeature(const String& keyString, const String& valueString, Docu
         arguments->maxZoom = findScaleValue(keyString, valueString, document);
     else if (keyString == "user-scalable")
         arguments->userZoom = findUserScalableValue(keyString, valueString, document);
-    else if (keyString == "target-densitydpi")
+    else if (keyString == "target-densitydpi") {
+        arguments->deprecatedTargetDensityDPI = findTargetDensityDPIValue(keyString, valueString, document);
         reportViewportWarning(document, TargetDensityDpiUnsupported, String(), String());
-    else
+    else
         reportViewportWarning(document, UnrecognizedViewportArgumentKeyError, keyString, String());
 }
 
index 54ce70a..17af05e 100644 (file)
@@ -73,7 +73,11 @@ struct ViewportArguments {
         ValueDeviceWidth = -2,
         ValueDeviceHeight = -3,
         ValuePortrait = -4,
-        ValueLandscape = -5
+        ValueLandscape = -5,
+        ValueDeviceDPI = -6,
+        ValueLowDPI = -7,
+        ValueMediumDPI = -8,
+        ValueHighDPI = -9
     };
 
     ViewportArguments(Type type = Implicit)
@@ -89,6 +93,7 @@ struct ViewportArguments {
         , maxZoom(ValueAuto)
         , userZoom(ValueAuto)
         , orientation(ValueAuto)
+        , deprecatedTargetDensityDPI(ValueAuto)
     {
     }
 
@@ -106,6 +111,7 @@ struct ViewportArguments {
     float maxZoom;
     float userZoom;
     float orientation;
+    float deprecatedTargetDensityDPI; // Only used for Android WebView
 
     bool operator==(const ViewportArguments& other) const
     {
@@ -121,7 +127,8 @@ struct ViewportArguments {
             && minZoom == other.minZoom
             && maxZoom == other.maxZoom
             && userZoom == other.userZoom
-            && orientation == other.orientation;
+            && orientation == other.orientation
+            && deprecatedTargetDensityDPI == other.deprecatedTargetDensityDPI;
     }
 
     bool operator!=(const ViewportArguments& other) const
index b1e8d82..bddf755 100644 (file)
@@ -1,3 +1,32 @@
+2013-04-03  Mikhail Naganov  <mnaganov@chromium.org>
+
+        [Chromium] Implement target-densityDpi viewport property emulation
+        https://bugs.webkit.org/show_bug.cgi?id=110835
+
+        The value is only used in the Chromium port, when the corresponding
+        setting is enabled.
+
+        This is needed for supporting existing WebView-based applications
+        that rely on this property.
+
+        Reviewed by Adam Barth.
+
+        * public/WebSettings.h:
+        (WebSettings):
+        * src/ChromeClientImpl.cpp:
+        (WebKit):
+        (WebKit::calculateTargetDensityDPIFactor):
+        (WebKit::ChromeClientImpl::dispatchViewportPropertiesDidChange):
+        * src/WebSettingsImpl.cpp:
+        (WebKit::WebSettingsImpl::WebSettingsImpl):
+        (WebKit::WebSettingsImpl::setSupportDeprecatedTargetDensityDPI):
+        (WebKit):
+        * src/WebSettingsImpl.h:
+        (WebSettingsImpl):
+        (WebKit::WebSettingsImpl::supportDeprecatedTargetDensityDPI):
+        * tests/WebFrameTest.cpp:
+        * tests/data/viewport-target-densitydpi-high.html: Added.
+
 2013-04-02  James Craig  <james@cookiecrook.com>
 
         AXRoleDescripton for DL is "list"; should be "description list"
index cfb7c6f..e146a9f 100644 (file)
@@ -153,6 +153,7 @@ public:
     virtual void setShrinksStandaloneImagesToFit(bool) = 0;
     virtual void setSmartInsertDeleteEnabled(bool) = 0;
     virtual void setStandardFontFamily(const WebString&, UScriptCode = USCRIPT_COMMON) = 0;
+    virtual void setSupportDeprecatedTargetDensityDPI(bool) = 0;
     virtual void setSupportsMultipleWindows(bool) = 0;
     virtual void setSyncXHRInDocumentsEnabled(bool) = 0;
     virtual void setTextAreasAreResizable(bool) = 0;
index ea92f9d..e2ec815 100644 (file)
@@ -624,6 +624,21 @@ void ChromeClientImpl::setToolTip(const String& tooltipText, TextDirection dir)
         tooltipText, textDirection);
 }
 
+
+static float calculateTargetDensityDPIFactor(const ViewportArguments& arguments, float deviceScaleFactor)
+{
+    float targetDPI = -1.0f;
+    if (arguments.deprecatedTargetDensityDPI == ViewportArguments::ValueLowDPI)
+        targetDPI = 120.0f;
+    else if (arguments.deprecatedTargetDensityDPI == ViewportArguments::ValueMediumDPI)
+        targetDPI = 160.0f;
+    else if (arguments.deprecatedTargetDensityDPI == ViewportArguments::ValueHighDPI)
+        targetDPI = 240.0f;
+    else if (arguments.deprecatedTargetDensityDPI != ViewportArguments::ValueAuto && arguments.deprecatedTargetDensityDPI != ViewportArguments::ValueDeviceDPI)
+        targetDPI = arguments.deprecatedTargetDensityDPI;
+    return targetDPI > 0 ? (deviceScaleFactor * 120.0f) / targetDPI : 1.0f;
+}
+
 void ChromeClientImpl::dispatchViewportPropertiesDidChange(const ViewportArguments& arguments) const
 {
 #if ENABLE(VIEWPORT)
@@ -647,6 +662,14 @@ void ChromeClientImpl::dispatchViewportPropertiesDidChange(const ViewportArgumen
     if (arguments.zoom == ViewportArguments::ValueAuto && !m_webView->settingsImpl()->initializeAtMinimumPageScale())
         computed.initialScale = 1.0f;
 
+    if (m_webView->settingsImpl()->supportDeprecatedTargetDensityDPI()) {
+        float targetDensityDPIFactor = calculateTargetDensityDPIFactor(arguments, deviceScaleFactor);
+        computed.initialScale *= targetDensityDPIFactor;
+        computed.minimumScale *= targetDensityDPIFactor;
+        computed.maximumScale *= targetDensityDPIFactor;
+        computed.layoutSize.scale(1.0f / targetDensityDPIFactor);
+    }
+
     m_webView->setInitialPageScaleFactor(computed.initialScale);
     m_webView->setFixedLayoutSize(flooredIntSize(computed.layoutSize));
     m_webView->setDeviceScaleFactor(deviceScaleFactor);
index bed0c33..8db96dc 100644 (file)
@@ -57,6 +57,7 @@ WebSettingsImpl::WebSettingsImpl(Settings* settings)
     , m_autoZoomFocusedNodeToLegibleScale(false)
     , m_deferredImageDecodingEnabled(false)
     , m_doubleTapToZoomEnabled(false)
+    , m_supportDeprecatedTargetDensityDPI(false)
 {
     ASSERT(settings);
 }
@@ -194,6 +195,11 @@ void WebSettingsImpl::setJavaScriptCanOpenWindowsAutomatically(bool canOpenWindo
     m_settings->setJavaScriptCanOpenWindowsAutomatically(canOpenWindows);
 }
 
+void WebSettingsImpl::setSupportDeprecatedTargetDensityDPI(bool supportDeprecatedTargetDensityDPI)
+{
+    m_supportDeprecatedTargetDensityDPI = supportDeprecatedTargetDensityDPI;
+}
+
 void WebSettingsImpl::setSupportsMultipleWindows(bool supportsMultipleWindows)
 {
     m_settings->setSupportsMultipleWindows(supportsMultipleWindows);
index 73dbd4a..66d66d8 100644 (file)
@@ -149,6 +149,7 @@ public:
     virtual void setShrinksStandaloneImagesToFit(bool);
     virtual void setSmartInsertDeleteEnabled(bool);
     virtual void setStandardFontFamily(const WebString&, UScriptCode = USCRIPT_COMMON);
+    virtual void setSupportDeprecatedTargetDensityDPI(bool);
     virtual void setSupportsMultipleWindows(bool);
     virtual void setSyncXHRInDocumentsEnabled(bool);
     virtual void setTextAreasAreResizable(bool);
@@ -180,6 +181,7 @@ public:
     bool gestureTapHighlightEnabled() const { return m_gestureTapHighlightEnabled; }
     bool doubleTapToZoomEnabled() const { return m_doubleTapToZoomEnabled; }
     bool perTilePaintingEnabled() const { return m_perTilePaintingEnabled; }
+    bool supportDeprecatedTargetDensityDPI() const { return m_supportDeprecatedTargetDensityDPI; }
 
 private:
     WebCore::Settings* m_settings;
@@ -193,6 +195,7 @@ private:
     bool m_deferredImageDecodingEnabled;
     bool m_doubleTapToZoomEnabled;
     bool m_perTilePaintingEnabled;
+    bool m_supportDeprecatedTargetDensityDPI;
 };
 
 } // namespace WebKit
index 005801c..31c262d 100644 (file)
@@ -573,6 +573,29 @@ TEST_F(WebFrameTest, pageScaleFactorDoesNotApplyCssTransform)
     EXPECT_EQ(980, webViewImpl->page()->mainFrame()->contentRenderer()->unscaledDocumentRect().width());
     EXPECT_EQ(980, webViewImpl->mainFrameImpl()->frameView()->contentsSize().width());
 }
+
+TEST_F(WebFrameTest, targetDensityDpiHigh)
+{
+    registerMockedHttpURLLoad("viewport-target-densitydpi-high.html");
+
+    FixedLayoutTestWebViewClient client;
+    client.m_screenInfo.deviceScaleFactor = 4.0f / 3.0f;
+    int viewportWidth = 640;
+    int viewportHeight = 480;
+
+    m_webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "viewport-target-densitydpi-high.html", true, 0, &client);
+    m_webView->settings()->setApplyDeviceScaleFactorInCompositor(true);
+    m_webView->settings()->setApplyPageScaleFactorInCompositor(true);
+    m_webView->enableFixedLayoutMode(true);
+    m_webView->settings()->setViewportEnabled(true);
+    m_webView->settings()->setSupportDeprecatedTargetDensityDPI(true);
+    m_webView->resize(WebSize(viewportWidth, viewportHeight));
+
+    // high-dpi = 240, device-dpi = 160
+    EXPECT_EQ(viewportWidth * (240.0f / 160.0f), m_webView->fixedLayoutSize().width);
+    EXPECT_EQ(viewportHeight * (240.0f / 160.0f), m_webView->fixedLayoutSize().height);
+    EXPECT_EQ(160.0f / 240.0f, m_webView->pageScaleFactor());
+}
 #endif
 
 TEST_F(WebFrameTest, pageScaleFactorScalesPaintClip)
diff --git a/Source/WebKit/chromium/tests/data/viewport-target-densitydpi-high.html b/Source/WebKit/chromium/tests/data/viewport-target-densitydpi-high.html
new file mode 100644 (file)
index 0000000..759c56a
--- /dev/null
@@ -0,0 +1,8 @@
+<html>
+  <head>
+    <meta name='viewport' content='width=device-width,target-densityDpi=high-dpi' />
+  </head>
+  <body>
+    A page with a viewport.
+  </body>
+</html>