Add fixedLayoutSize feature to ScrollView to allow for controlling the
layout beyond the constraint of the current viewports dynamic size


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@39580 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 3214990..1d85612 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,35 @@
+2008-12-30  Adam Treat  <treat@kde.org>
+
+        Reviewed by George Staikos.
+
+        Add fixedLayoutSize feature to ScrollView to allow for controlling the
+        layout beyond the constraint of the current viewports dynamic size
+
+        * css/MediaQueryEvaluator.cpp:
+        (WebCore::heightMediaFeatureEval):
+        (WebCore::widthMediaFeatureEval):
+        * dom/Element.cpp:
+        (WebCore::Element::clientWidth):
+        (WebCore::Element::clientHeight):
+        * loader/FrameLoaderClient.cpp:
+        (WebCore::FrameLoaderClient::transitionToCommittedForNewPage):
+        * loader/FrameLoaderClient.h:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::layout):
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::ScrollView):
+        (WebCore::ScrollView::layoutWidth):
+        (WebCore::ScrollView::layoutHeight):
+        (WebCore::ScrollView::fixedLayoutSize):
+        (WebCore::ScrollView::setFixedLayoutSize):
+        (WebCore::ScrollView::useFixedLayout):
+        (WebCore::ScrollView::setUseFixedLayout):
+        * platform/ScrollView.h:
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::viewHeight):
+        (WebCore::RenderView::viewWidth):
+        * rendering/RenderView.h:
+
 2009-01-03  Rob Buis  <rwlbuis@gmail.com>
 
         Reviewed by Darin.
diff --git a/WebCore/css/MediaQueryEvaluator.cpp b/WebCore/css/MediaQueryEvaluator.cpp
index 534b2982..7e71969 100644
--- a/WebCore/css/MediaQueryEvaluator.cpp
+++ b/WebCore/css/MediaQueryEvaluator.cpp
@@ -291,9 +291,9 @@
     FrameView* view = frame->view();
     
     if (value)
-        return value->isPrimitiveValue() && compareValue(view->visibleHeight(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
+        return value->isPrimitiveValue() && compareValue(view->layoutHeight(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
 
-    return view->visibleHeight() != 0;
+    return view->layoutHeight() != 0;
 }
 
 static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix op)
@@ -301,9 +301,9 @@
     FrameView* view = frame->view();
     
     if (value)
-        return value->isPrimitiveValue() && compareValue(view->visibleWidth(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
+        return value->isPrimitiveValue() && compareValue(view->layoutWidth(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
 
-    return view->visibleWidth() != 0;
+    return view->layoutWidth() != 0;
 }
 
 // rest of the functions are trampolines which set the prefix according to the media feature expression used
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 5496589..4163200 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -340,7 +340,7 @@
     if ((!inCompatMode && document()->documentElement() == this) ||
         (inCompatMode && isHTMLElement() && document()->body() == this)) {
         if (FrameView* view = document()->view())
-            return view->visibleWidth();
+            return view->layoutWidth();
     }
     
 
@@ -360,7 +360,7 @@
     if ((!inCompatMode && document()->documentElement() == this) ||
         (inCompatMode && isHTMLElement() && document()->body() == this)) {
         if (FrameView* view = document()->view())
-            return view->visibleHeight();
+            return view->layoutHeight();
     }
     
     if (RenderObject* rend = renderer())
diff --git a/WebCore/loader/FrameLoaderClient.cpp b/WebCore/loader/FrameLoaderClient.cpp
index 15bfe86..2162fcd 100644
--- a/WebCore/loader/FrameLoaderClient.cpp
+++ b/WebCore/loader/FrameLoaderClient.cpp
@@ -42,7 +42,10 @@
 FrameLoaderClient::~FrameLoaderClient()
 {}
 
-void FrameLoaderClient::transitionToCommittedForNewPage(Frame* frame, const IntSize& size, const Color& backgroundColor, bool transparent)
+void FrameLoaderClient::transitionToCommittedForNewPage(Frame* frame,
+                                                        const IntSize& viewportSize,
+                                                        const Color& backgroundColor, bool transparent,
+                                                        const IntSize& fixedLayoutSize, bool useFixedLayout)
 {
     ASSERT(frame);
 
@@ -58,10 +61,13 @@
 
     FrameView* frameView;
     if (isMainFrame)
-        frameView = new FrameView(frame, size);
+        frameView = new FrameView(frame, viewportSize);
     else
         frameView = new FrameView(frame);
 
+    frameView->setFixedLayoutSize(fixedLayoutSize);
+    frameView->setUseFixedLayout(useFixedLayout);
+
     frame->setView(frameView);
     // FrameViews are created with a ref count of 1. Release this ref since we've assigned it to frame.
     frameView->deref();
diff --git a/WebCore/loader/FrameLoaderClient.h b/WebCore/loader/FrameLoaderClient.h
index 4d5ea3a..4bc05b1 100644
--- a/WebCore/loader/FrameLoaderClient.h
+++ b/WebCore/loader/FrameLoaderClient.h
@@ -210,7 +210,7 @@
 #endif
 
     protected:
-        static void transitionToCommittedForNewPage(Frame*, const IntSize&, const Color&, bool);
+        static void transitionToCommittedForNewPage(Frame*, const IntSize&, const Color&, bool, const IntSize &, bool);
     };
 
 } // namespace WebCore
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 20eedbc..6192c0e 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -422,7 +422,7 @@
     if (!m_frame) {
         // FIXME: Do we need to set m_size.width here?
         // FIXME: Should we set m_size.height here too?
-        m_size.setWidth(visibleWidth());
+        m_size.setWidth(layoutWidth());
         return;
     }
     
@@ -446,7 +446,7 @@
     Document* document = m_frame->document();
     if (!document) {
         // FIXME: Should we set m_size.height here too?
-        m_size.setWidth(visibleWidth());
+        m_size.setWidth(layoutWidth());
         return;
     }
 
@@ -499,7 +499,7 @@
                 vMode = ScrollbarAlwaysOff;
                 hMode = ScrollbarAlwaysOff;
             } else if (body->hasTagName(bodyTag)) {
-                if (!d->m_firstLayout && m_size.height() != visibleHeight()
+                if (!d->m_firstLayout && m_size.height() != layoutHeight()
                         && static_cast<RenderBox*>(body->renderer())->stretchesToViewHeight())
                     body->renderer()->setChildNeedsLayout(true);
                 // It's sufficient to just check the X overflow,
@@ -543,7 +543,7 @@
 
         IntSize oldSize = m_size;
 
-        m_size = IntSize(visibleWidth(), visibleHeight());
+        m_size = IntSize(layoutWidth(), layoutHeight());
 
         if (oldSize != m_size)
             d->m_doFullRepaint = true;
@@ -593,8 +593,8 @@
     setCanBlitOnScroll(!useSlowRepaints());
 
     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
-        updateOverflowStatus(visibleWidth() < contentsWidth(),
-                             visibleHeight() < contentsHeight());
+        updateOverflowStatus(layoutWidth() < contentsWidth(),
+                             layoutHeight() < contentsHeight());
 
     if (!d->m_postLayoutTasksTimer.isActive()) {
         // Calls resumeScheduledEvents()
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index f2d1e55..541a04d 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -47,6 +47,7 @@
     , m_scrollbarsSuppressed(false)
     , m_inUpdateScrollbars(false)
     , m_drawPanScrollIcon(false)
+    , m_useFixedLayout(false)
 {
     platformInit();
     if (platformWidget())
@@ -172,6 +173,42 @@
                            max(0, height() - (horizontalScrollbar() && !includeScrollbars ? horizontalScrollbar()->height() : 0))));
 }
 
+int ScrollView::layoutWidth() const
+{
+    return m_fixedLayoutSize.isEmpty() || !m_useFixedLayout ? visibleWidth() : m_fixedLayoutSize.width();
+}
+
+int ScrollView::layoutHeight() const
+{
+    return m_fixedLayoutSize.isEmpty() || !m_useFixedLayout ? visibleHeight() : m_fixedLayoutSize.height();
+}
+
+IntSize ScrollView::fixedLayoutSize() const
+{
+    return m_fixedLayoutSize;
+}
+
+void ScrollView::setFixedLayoutSize(const IntSize& newSize)
+{
+    if (fixedLayoutSize() == newSize)
+        return;
+    m_fixedLayoutSize = newSize;
+    updateScrollbars(scrollOffset());
+}
+
+bool ScrollView::useFixedLayout() const
+{
+    return m_useFixedLayout;
+}
+
+void ScrollView::setUseFixedLayout(bool enable)
+{
+    if (useFixedLayout() == enable)
+        return;
+    m_useFixedLayout = enable;
+    updateScrollbars(scrollOffset());
+}
+
 IntSize ScrollView::contentsSize() const
 {
     if (platformWidget())
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index b2fa582..88306a6 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -113,6 +113,15 @@
     IntRect visibleContentRect(bool includeScrollbars = false) const;
     int visibleWidth() const { return visibleContentRect().width(); }
     int visibleHeight() const { return visibleContentRect().height(); }
+
+    // Methods for getting/setting the size webkit should use to layout the contents.  By default this is the same as the visible
+    // content size.  Explicitly setting a layout size value will cause webkit to layout the contents using this size instead.
+    int layoutWidth() const;
+    int layoutHeight() const;
+    IntSize fixedLayoutSize() const;
+    void setFixedLayoutSize(const IntSize&);
+    bool useFixedLayout() const;
+    void setUseFixedLayout(bool enable);
     
     // Methods for getting/setting the size of the document contained inside the ScrollView (as an IntSize or as individual width and height
     // values).
@@ -238,6 +247,7 @@
     bool m_canBlitOnScroll;
 
     IntSize m_scrollOffset; // FIXME: Would rather store this as a position, but we will wait to make this change until more code is shared.
+    IntSize m_fixedLayoutSize;
     IntSize m_contentsSize;
 
     int m_scrollbarsAvoidingResizer;
@@ -247,6 +257,7 @@
 
     IntPoint m_panScrollIconPoint;
     bool m_drawPanScrollIcon;
+    bool m_useFixedLayout;
 
     void init();
     void destroy();
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index ac626ae..1008599 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -559,16 +559,20 @@
 int RenderView::viewHeight() const
 {
     int height = 0;
-    if (!printing() && m_frameView)
-        height = m_frameView->visibleHeight();
+    if (!printing() && m_frameView) {
+        height = m_frameView->layoutHeight();
+        height = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(height)) : height;
+    }
     return height;
 }
 
 int RenderView::viewWidth() const
 {
     int width = 0;
-    if (!printing() && m_frameView)
-        width = m_frameView->visibleWidth();
+    if (!printing() && m_frameView) {
+        width = m_frameView->layoutWidth();
+        width = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(width)) : width;
+    }
     return width;
 }
 
diff --git a/WebCore/rendering/RenderView.h b/WebCore/rendering/RenderView.h
index a9ff061..96597de 100644
--- a/WebCore/rendering/RenderView.h
+++ b/WebCore/rendering/RenderView.h
@@ -51,7 +51,7 @@
     int docHeight() const;
     int docWidth() const;
 
-    // The same as the FrameView's visibleHeight/visibleWidth but with null check guards.
+    // The same as the FrameView's layoutHeight/layoutWidth but with null check guards.
     int viewHeight() const;
     int viewWidth() const;