Make ScrollView::paint() clip by visibleContentRect
authoraelias@chromium.org <aelias@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Feb 2013 23:47:17 +0000 (23:47 +0000)
committeraelias@chromium.org <aelias@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Feb 2013 23:47:17 +0000 (23:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=108888

Reviewed by Levi Weintraub.

When applyPageScaleFactorInCompositor or fixedVisibleContentRect
are used, frameRect() and visibleContentRect(true).size() are
no longer synonyms, and the latter is the one that should be
used for clipping paints.

New WebFrameTest: pageScaleFactorScalesPaintClip.

Source/WebCore:

* platform/ScrollView.cpp:
(WebCore::ScrollView::paint):

Source/WebKit/chromium:

* tests/WebFrameTest.cpp:

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

Source/WebCore/ChangeLog
Source/WebCore/platform/ScrollView.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/WebFrameTest.cpp

index 78cc0ec..fc7fe18 100644 (file)
@@ -1,3 +1,20 @@
+2013-02-06  Alexandre Elias  <aelias@chromium.org>
+
+        Make ScrollView::paint() clip by visibleContentRect
+        https://bugs.webkit.org/show_bug.cgi?id=108888
+
+        Reviewed by Levi Weintraub.
+
+        When applyPageScaleFactorInCompositor or fixedVisibleContentRect
+        are used, frameRect() and visibleContentRect(true).size() are
+        no longer synonyms, and the latter is the one that should be
+        used for clipping paints.
+
+        New WebFrameTest: pageScaleFactorScalesPaintClip.
+
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::paint):
+
 2013-02-06  Dima Gorbik  <dgorbik@apple.com>
 
         Store the language internally instead of using lang attribute for WebVTT nodes
index a727c4a..f7fe63e 100644 (file)
@@ -1051,14 +1051,9 @@ void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
 
     notifyPageThatContentAreaWillPaint();
 
-    IntRect clipRect = frameRect();
-    if (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar())
-        clipRect.setWidth(clipRect.width() - verticalScrollbar()->width());
-    if (horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar())
-        clipRect.setHeight(clipRect.height() - horizontalScrollbar()->height());
-
     IntRect documentDirtyRect = rect;
-    documentDirtyRect.intersect(clipRect);
+    IntRect visibleAreaWithoutScrollbars(location(), visibleContentRect(false).size());
+    documentDirtyRect.intersect(visibleAreaWithoutScrollbars);
 
     if (!documentDirtyRect.isEmpty()) {
         GraphicsContextStateSaver stateSaver(*context);
@@ -1087,7 +1082,8 @@ void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
     if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) {
         GraphicsContextStateSaver stateSaver(*context);
         IntRect scrollViewDirtyRect = rect;
-        scrollViewDirtyRect.intersect(frameRect());
+        IntRect visibleAreaWithScrollbars(location(), visibleContentRect(true).size());
+        scrollViewDirtyRect.intersect(visibleAreaWithScrollbars);
         context->translate(x(), y());
         scrollViewDirtyRect.moveBy(-location());
 
index dbf0305..50a7666 100644 (file)
@@ -1,3 +1,19 @@
+2013-02-06  Alexandre Elias  <aelias@chromium.org>
+
+        Make ScrollView::paint() clip by visibleContentRect
+        https://bugs.webkit.org/show_bug.cgi?id=108888
+
+        Reviewed by Levi Weintraub.
+
+        When applyPageScaleFactorInCompositor or fixedVisibleContentRect
+        are used, frameRect() and visibleContentRect(true).size() are
+        no longer synonyms, and the latter is the one that should be
+        used for clipping paints.
+
+        New WebFrameTest: pageScaleFactorScalesPaintClip.
+
+        * tests/WebFrameTest.cpp:
+
 2013-02-06  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r142025.
index 2bb352b..c4d96c5 100644 (file)
 #include "Frame.h"
 #include "FrameTestHelpers.h"
 #include "FrameView.h"
+#include "PlatformContextSkia.h"
 #include "Range.h"
 #include "RenderView.h"
 #include "ResourceError.h"
 #include "Settings.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
 #include "URLTestHelpers.h"
 #include "WebDataSource.h"
 #include "WebDocument.h"
@@ -70,6 +73,12 @@ using WebKit::URLTestHelpers::toKURL;
 
 namespace {
 
+#define EXPECT_EQ_RECT(a, b) \
+    EXPECT_EQ(a.x(), b.x()); \
+    EXPECT_EQ(a.y(), b.y()); \
+    EXPECT_EQ(a.width(), b.width()); \
+    EXPECT_EQ(a.height(), b.height());
+
 class WebFrameTest : public testing::Test {
 public:
     WebFrameTest()
@@ -449,6 +458,49 @@ TEST_F(WebFrameTest, pageScaleFactorDoesNotApplyCssTransform)
 }
 #endif
 
+TEST_F(WebFrameTest, pageScaleFactorScalesPaintClip)
+{
+    registerMockedHttpURLLoad("fixed_layout.html");
+
+    FixedLayoutTestWebViewClient client;
+    client.m_screenInfo.deviceScaleFactor = 1;
+    int viewportWidth = 50;
+    int viewportHeight = 50;
+
+    WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebViewAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client));
+    webViewImpl->settings()->setApplyDeviceScaleFactorInCompositor(true);
+    webViewImpl->settings()->setApplyPageScaleFactorInCompositor(true);
+    webViewImpl->enableFixedLayoutMode(true);
+    webViewImpl->settings()->setViewportEnabled(true);
+    webViewImpl->resize(WebSize(viewportWidth, viewportHeight));
+    webViewImpl->layout();
+
+    // Set <1 page scale so that the clip rect should be larger than
+    // the viewport size as passed into resize().
+    webViewImpl->setPageScaleFactor(0.5, WebPoint());
+
+    SkBitmap bitmap;
+    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200);
+    bitmap.allocPixels();
+    bitmap.eraseColor(0);
+    SkCanvas canvas(bitmap);
+
+    WebCore::PlatformContextSkia platformContext(&canvas);
+    platformContext.setTrackOpaqueRegion(true);
+    WebCore::GraphicsContext context(&platformContext);
+
+    EXPECT_EQ_RECT(WebCore::IntRect(0, 0, 0, 0), platformContext.opaqueRegion().asRect());
+
+    WebCore::FrameView* view = webViewImpl->mainFrameImpl()->frameView();
+    WebCore::IntRect paintRect(0, 0, 200, 200);
+    view->paint(&context, paintRect);
+
+    int viewportWidthMinusScrollbar = 50 - (view->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15);
+    int viewportHeightMinusScrollbar = 50 - (view->horizontalScrollbar()->isOverlayScrollbar() ? 0 : 15);
+    WebCore::IntRect clippedRect(0, 0, viewportWidthMinusScrollbar * 2, viewportHeightMinusScrollbar * 2);
+    EXPECT_EQ_RECT(clippedRect, platformContext.opaqueRegion().asRect());
+}
+
 TEST_F(WebFrameTest, CanOverrideMaximumScaleFactor)
 {
     registerMockedHttpURLLoad("no_scale_for_you.html");