https://bugs.webkit.org/show_bug.cgi?id=45993, convert printing to the new pagination...
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Sep 2010 02:13:48 +0000 (02:13 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Sep 2010 02:13:48 +0000 (02:13 +0000)
Reviewed by Simon Fraser.

WebCore:

Make printing store the page height in the RenderView and push that into the layout state to
use the new pagination model.  The old pagination model is retained because it is still used
for embedded WebViews.

* page/FrameView.cpp:
(WebCore::FrameView::reset):
(WebCore::FrameView::layout):
(WebCore::FrameView::forceLayout):
(WebCore::FrameView::forceLayoutForPagination):
(WebCore::FrameView::adjustPageHeight):
* page/FrameView.h:
* page/PrintContext.cpp:
(WebCore::PrintContext::computePageRectsWithPageSizeInternal):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintChildren):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::calcHeight):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::paintReplaced):
* rendering/RenderLineBoxList.cpp:
(WebCore::RenderLineBoxList::paint):
* rendering/RenderVideo.cpp:
(WebCore::RenderVideo::paintReplaced):
* rendering/RenderView.cpp:
(WebCore::RenderView::RenderView):
(WebCore::RenderView::layout):
(WebCore::RenderView::paint):
(WebCore::RenderView::setBestTruncatedAt):
* rendering/RenderView.h:
(WebCore::RenderView::popLayoutState):
(WebCore::RenderView::pageHeight):
(WebCore::RenderView::setPageHeight):
(WebCore::RenderView::bestTruncatedAt):
(WebCore::RenderView::truncatedAt):
(WebCore::RenderView::setTruncatedAt):
(WebCore::RenderView::printRect):
(WebCore::RenderView::setPrintRect):
(WebCore::RenderView::pushLayoutState):
(WebCore::LayoutStateMaintainer::LayoutStateMaintainer):
(WebCore::LayoutStateMaintainer::push):
(WebCore::LayoutStateMaintainer::pop):

WebKit/mac:

Make printing store the page height in the RenderView and push that into the layout state to
use the new pagination model.  The old pagination model is retained because it is still used
for embedded WebViews.

* WebView/WebHTMLView.mm:
(-[WebHTMLView _adjustedBottomOfPageWithTop:bottom:limit:]):

LayoutTests:

Remove the overflow test, since the new model treats overflow:auto/scroll as unsplittable.

* printing/page-break-always-for-overflow-expected.txt: Removed.
* printing/page-break-always-for-overflow.html: Removed.

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

19 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac/printing/media-queries-print-expected.txt
LayoutTests/printing/page-break-always-for-overflow-expected.txt [deleted file]
LayoutTests/printing/page-break-always-for-overflow.html [deleted file]
LayoutTests/printing/page-break-margin-collapsed-expected.txt
WebCore/ChangeLog
WebCore/WebCore.exp.in
WebCore/page/FrameView.cpp
WebCore/page/FrameView.h
WebCore/page/PrintContext.cpp
WebCore/rendering/RenderBlock.cpp
WebCore/rendering/RenderBox.cpp
WebCore/rendering/RenderImage.cpp
WebCore/rendering/RenderLineBoxList.cpp
WebCore/rendering/RenderVideo.cpp
WebCore/rendering/RenderView.cpp
WebCore/rendering/RenderView.h
WebKit/mac/ChangeLog
WebKit/mac/WebView/WebHTMLView.mm

index 09175aa..0f06a0e 100644 (file)
@@ -1,3 +1,14 @@
+2010-09-17  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        https://bugs.webkit.org/show_bug.cgi?id=45993, convert printing to the new pagination model.
+
+        Remove the overflow test, since the new model treats overflow:auto/scroll as unsplittable.
+
+        * printing/page-break-always-for-overflow-expected.txt: Removed.
+        * printing/page-break-always-for-overflow.html: Removed.
+
 2010-09-17  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Simon Fraser.
index 5c81bed..48e407a 100644 (file)
@@ -1,8 +1,8 @@
-layer at (0,0) size 1000x600
-  RenderView at (0,0) size 1000x600
-layer at (0,0) size 1000x600
-  RenderBlock {HTML} at (0,0) size 1000x600
-    RenderBody {BODY} at (8,8) size 984x584
+layer at (0,0) size 1000x134
+  RenderView at (0,0) size 1000x134
+layer at (0,0) size 1000x134
+  RenderBlock {HTML} at (0,0) size 1000x134
+    RenderBody {BODY} at (8,8) size 984x118
       RenderBlock {DIV} at (0,0) size 100x100 [bgcolor=#008000]
       RenderBlock (anonymous) at (0,100) size 984x18
         RenderInline {SPAN} at (0,0) size 533x18
diff --git a/LayoutTests/printing/page-break-always-for-overflow-expected.txt b/LayoutTests/printing/page-break-always-for-overflow-expected.txt
deleted file mode 100644 (file)
index ddfeb31..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-Test page-break-{before,after}:always for overflow:{visible,hidden,scroll,auto} elements.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-
-PASS: page number of "test-page-break-before:always-for-overflow:visible" is 1
-PASS: page number of "test-page-break-before:always-for-overflow:hidden" is 2
-PASS: page number of "test-page-break-before:always-for-overflow:scroll" is 3
-PASS: page number of "test-page-break-before:always-for-overflow:auto" is 4
-PASS: page number of "test-page-break-after:always-for-overflow:visible" is 4
-PASS: page number of "test-page-break-after:always-for-overflow:hidden" is 5
-PASS: page number of "test-page-break-after:always-for-overflow:scroll" is 6
-PASS: page number of "test-page-break-after:always-for-overflow:auto" is 7
-PASS: page number of "test-last-page" is 8
-All tests passed
-
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/LayoutTests/printing/page-break-always-for-overflow.html b/LayoutTests/printing/page-break-always-for-overflow.html
deleted file mode 100644 (file)
index 73a34f5..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<link rel="stylesheet" href="../fast/js/resources/js-test-style.css">
-<script src="../fast/js/resources/js-test-pre.js"></script>
-<script src="resources/paged-media-test-utils.js"></script>
-</head>
-<body>
-<p id="description"></p>
-<div id="console"></div>
-<div id="sandbox"></div>
-<script src="script-tests/page-break-always-for-overflow.js"></script>
-<script>runPrintingTest(test);</script>
-<script src="../fast/js/resources/js-test-post.js"></script>
-</body>
-</html>
index e544c57..ccbe10d 100644 (file)
@@ -5,7 +5,8 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 
 PASS: page number of "page1" is 1
-FAIL: expected page number of "page2" is 2. Was 134
+PASS: page number of "page2" is 2
+All tests passed
 
 PASS successfullyParsed is true
 
index e3e1ebf..0adc824 100644 (file)
@@ -1,3 +1,51 @@
+2010-09-17  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        https://bugs.webkit.org/show_bug.cgi?id=45993, convert printing to the new pagination model.
+
+        Make printing store the page height in the RenderView and push that into the layout state to
+        use the new pagination model.  The old pagination model is retained because it is still used
+        for embedded WebViews.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::reset):
+        (WebCore::FrameView::layout):
+        (WebCore::FrameView::forceLayout):
+        (WebCore::FrameView::forceLayoutForPagination):
+        (WebCore::FrameView::adjustPageHeight):
+        * page/FrameView.h:
+        * page/PrintContext.cpp:
+        (WebCore::PrintContext::computePageRectsWithPageSizeInternal):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintChildren):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::calcHeight):
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::paintReplaced):
+        * rendering/RenderLineBoxList.cpp:
+        (WebCore::RenderLineBoxList::paint):
+        * rendering/RenderVideo.cpp:
+        (WebCore::RenderVideo::paintReplaced):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::RenderView):
+        (WebCore::RenderView::layout):
+        (WebCore::RenderView::paint):
+        (WebCore::RenderView::setBestTruncatedAt):
+        * rendering/RenderView.h:
+        (WebCore::RenderView::popLayoutState):
+        (WebCore::RenderView::pageHeight):
+        (WebCore::RenderView::setPageHeight):
+        (WebCore::RenderView::bestTruncatedAt):
+        (WebCore::RenderView::truncatedAt):
+        (WebCore::RenderView::setTruncatedAt):
+        (WebCore::RenderView::printRect):
+        (WebCore::RenderView::setPrintRect):
+        (WebCore::RenderView::pushLayoutState):
+        (WebCore::LayoutStateMaintainer::LayoutStateMaintainer):
+        (WebCore::LayoutStateMaintainer::push):
+        (WebCore::LayoutStateMaintainer::pop):
+
 2010-09-17  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Simon Fraser.
index 375fcf6..55e3d3f 100644 (file)
@@ -768,7 +768,7 @@ __ZN7WebCore9FrameView14setMarginWidthEi
 __ZN7WebCore9FrameView14setNeedsLayoutEv
 __ZN7WebCore9FrameView14setTransparentEb
 __ZN7WebCore9FrameView15setMarginHeightEi
-__ZN7WebCore9FrameView16adjustPageHeightEPffff
+__ZN7WebCore9FrameView26adjustPageHeightDeprecatedEPffff
 __ZN7WebCore9FrameView16setPaintBehaviorEj
 __ZN7WebCore9FrameView18updateControlTintsEv
 __ZN7WebCore9FrameView20enterCompositingModeEv
index d9de614..0907fe5 100644 (file)
@@ -205,7 +205,6 @@ void FrameView::reset()
     m_wasScrolledByUser = false;
     m_lastLayoutSize = IntSize();
     m_lastZoomFactor = 1.0f;
-    m_pageHeight = 0;
     m_deferringRepaints = 0;
     m_repaintCount = 0;
     m_repaintRects.clear();
@@ -770,7 +769,7 @@ void FrameView::layout(bool allowSubtree)
 
     if (subtree) {
         RenderView* view = root->view();
-        view->popLayoutState();
+        view->popLayoutState(root);
         if (disableLayoutState)
             view->enableLayoutState();
     }
@@ -2076,12 +2075,6 @@ void FrameView::flushDeferredRepaints()
 void FrameView::forceLayout(bool allowSubtree)
 {
     layout(allowSubtree);
-    // We cannot unschedule a pending relayout, since the force can be called with
-    // a tiny rectangle from a drawRect update.  By unscheduling we in effect
-    // "validate" and stop the necessary full repaint from occurring.  Basically any basic
-    // append/remove DHTML is broken by this call.  For now, I have removed the optimization
-    // until we have a better invalidation stategy. -dwh
-    //unscheduleRelayout();
 }
 
 void FrameView::forceLayoutForPagination(const FloatSize& pageSize, float maximumShrinkFactor, Frame::AdjustViewSizeOrNot shouldAdjustViewSize)
@@ -2091,8 +2084,8 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, float maximu
     RenderView *root = toRenderView(m_frame->document()->renderer());
     if (root) {
         int pageW = ceilf(pageSize.width());
-        m_pageHeight = pageSize.height() ? pageSize.height() : visibleHeight();
         root->setWidth(pageW);
+        root->setPageHeight(pageSize.height());
         root->setNeedsLayoutAndPrefWidthsRecalc();
         forceLayout();
 
@@ -2104,7 +2097,7 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, float maximu
         if (rightmostPos > pageSize.width()) {
             pageW = std::min<int>(rightmostPos, ceilf(pageSize.width() * maximumShrinkFactor));
             if (pageSize.height())
-                m_pageHeight = pageW / pageSize.width() * pageSize.height();
+                root->setPageHeight(pageW / pageSize.width() * pageSize.height());
             root->setWidth(pageW);
             root->setNeedsLayoutAndPrefWidthsRecalc();
             forceLayout();
@@ -2113,10 +2106,9 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, float maximu
 
     if (shouldAdjustViewSize)
         adjustViewSize();
-    m_pageHeight = 0;
 }
 
-void FrameView::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
+void FrameView::adjustPageHeightDeprecated(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
 {
     RenderView* root = m_frame->contentRenderer();
     if (root) {
@@ -2124,10 +2116,12 @@ void FrameView::adjustPageHeight(float *newBottom, float oldTop, float oldBottom
         GraphicsContext context((PlatformGraphicsContext*)0);
         root->setTruncatedAt((int)floorf(oldBottom));
         IntRect dirtyRect(0, (int)floorf(oldTop), root->rightLayoutOverflow(), (int)ceilf(oldBottom - oldTop));
+        root->setPrintRect(dirtyRect);
         root->layer()->paint(&context, dirtyRect);
         *newBottom = root->bestTruncatedAt();
         if (*newBottom == 0)
             *newBottom = oldBottom;
+        root->setPrintRect(IntRect());
     } else
         *newBottom = oldBottom;
 }
index 96b6209..22c05be 100644 (file)
@@ -200,9 +200,24 @@ public:
 
     void forceLayout(bool allowSubtree = false);
     void forceLayoutForPagination(const FloatSize& pageSize, float maximumShrinkFactor, Frame::AdjustViewSizeOrNot);
-    int pageHeight() const { return m_pageHeight; }
 
-    void adjustPageHeight(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
+    // FIXME: This method is retained because of embedded WebViews in AppKit.  When a WebView is embedded inside
+    // some enclosing view with auto-pagination, no call happens to resize the view.  The new pagination model
+    // needs the view to resize as a result of the breaks, but that means that the enclosing view has to potentially
+    // resize around that view.  Auto-pagination uses the bounds of the actual view that's being printed to determine
+    // the edges of the print operation, so the resize is necessary if the enclosing view's bounds depend on the
+    // web document's bounds.
+    // 
+    // This is already a problem if the view needs to be a different size because of printer fonts or because of print stylesheets.
+    // Mail/Dictionary work around this problem by using the _layoutForPrinting SPI
+    // to at least get print stylesheets and printer fonts into play, but since WebKit doesn't know about the page offset or
+    // page size, it can't actually paginate correctly during _layoutForPrinting.
+    //
+    // We can eventually move Mail to a newer SPI that would let them opt in to the layout-time pagination model,
+    // but that doesn't solve the general problem of how other AppKit views could opt in to the better model.
+    //
+    // NO OTHER PLATFORM BESIDES MAC SHOULD USE THIS METHOD.
+    void adjustPageHeightDeprecated(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
 
     bool scrollToFragment(const KURL&);
     bool scrollToAnchor(const String&);
@@ -330,8 +345,6 @@ private:
     String m_mediaType;
     String m_mediaTypeWhenNotPrinting;
 
-    int m_pageHeight;
-
     unsigned m_enqueueEvents;
     Vector<ScheduledEvent*> m_scheduledEvents;
     
index 7b0179d..8cc7dd6 100644 (file)
@@ -95,26 +95,22 @@ void PrintContext::computePageRectsWithPageSizeInternal(const FloatSize& pageSiz
 {
     if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
         return;
+
     RenderView* root = toRenderView(m_frame->document()->renderer());
 
-    const float pageWidth = pageSizeInPixels.width();
-    const float docWidth = root->layer()->width();
-    const float docHeight = root->layer()->height();
-    float currPageHeight = pageSizeInPixels.height();
-
-    // always return at least one page, since empty files should print a blank page
-    float printedPagesHeight = 0;
-    do {
-        float proposedBottom = std::min(docHeight, printedPagesHeight + pageSizeInPixels.height());
-        m_frame->view()->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
-        currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
+    int docWidth = root->layer()->width();
+    int docHeight = root->layer()->height();
+    int pageWidth = pageSizeInPixels.width();
+    int pageHeight = pageSizeInPixels.height();
+
+    unsigned pageCount = ceilf((float)docHeight / pageHeight);
+    for (unsigned i = 0; i < pageCount; ++i) {
         if (allowHorizontalMultiPages) {
-            for (float curWidth = 0; curWidth < docWidth; curWidth += pageWidth)
-                m_pageRects.append(IntRect(curWidth, (int)printedPagesHeight, (int)pageWidth, (int)currPageHeight));
+            for (int currWidth = 0; currWidth < docWidth; currWidth += pageWidth)
+                m_pageRects.append(IntRect(currWidth, i * pageHeight, pageWidth, pageHeight));
         } else
-            m_pageRects.append(IntRect(0, (int)printedPagesHeight, (int)pageWidth, (int)currPageHeight));
-        printedPagesHeight += currPageHeight;
-    } while (printedPagesHeight < docHeight);
+            m_pageRects.append(IntRect(0, i * pageHeight, pageWidth, pageHeight));
+    }
 }
 
 void PrintContext::begin(float width, float height)
index a569d0c..cc99cb7 100644 (file)
@@ -2208,14 +2208,14 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
     info.phase = newPhase;
     info.updatePaintingRootForChildren(this);
     
+    // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
+    // NSViews.  Do not add any more code for this.
     RenderView* renderView = view();
     bool usePrintRect = !renderView->printRect().isEmpty();
     
-    bool checkPageBreaks = document()->paginated() && !document()->settings()->paginateDuringLayoutEnabled();
-
     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {        
         // Check for page-break-before: always, and if it's set, break and bail.
-        bool checkBeforeAlways = !childrenInline() && (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
+        bool checkBeforeAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakBefore() == PBALWAYS);
         if (checkBeforeAlways
             && (ty + child->y()) > paintInfo.rect.y()
             && (ty + child->y()) < paintInfo.rect.bottom()) {
@@ -2238,7 +2238,7 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
             child->paint(info, tx, ty);
 
         // Check for page-break-after: always, and if it's set, break and bail.
-        bool checkAfterAlways = !childrenInline() && (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
+        bool checkAfterAlways = !childrenInline() && (usePrintRect && child->style()->pageBreakAfter() == PBALWAYS);
         if (checkAfterAlways
             && (ty + child->y() + child->height()) > paintInfo.rect.y()
             && (ty + child->y() + child->height()) < paintInfo.rect.bottom()) {
@@ -5907,7 +5907,8 @@ int RenderBlock::applyBeforeBreak(RenderBox* child, int yPos)
 {
     // FIXME: Add page break checking here when we support printing.
     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
-    bool checkBeforeAlways = checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS;
+    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageHeight; // FIXME: Once columns can print we have to check this.
+    bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
     if (checkBeforeAlways && inNormalFlow(child)) {
         if (checkColumnBreaks)
             view()->layoutState()->addForcedColumnBreak(yPos);
@@ -5920,7 +5921,8 @@ int RenderBlock::applyAfterBreak(RenderBox* child, int yPos, MarginInfo& marginI
 {
     // FIXME: Add page break checking here when we support printing.
     bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
-    bool checkAfterAlways = checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS;
+    bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageHeight; // FIXME: Once columns can print we have to check this.
+    bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
     if (checkAfterAlways && inNormalFlow(child)) {
         marginInfo.setBottomQuirk(true); // Cause margins to be discarded for any following content.
         if (checkColumnBreaks)
index d90c1f8..58b150a 100644 (file)
@@ -1515,11 +1515,11 @@ void RenderBox::calcHeight()
     // is specified. When we're printing, we also need this quirk if the body or root has a percentage 
     // height since we don't set a height in RenderView when we're printing. So without this quirk, the 
     // height has nothing to be a percentage of, and it ends up being 0. That is bad.
-    bool paginatedContentNeedsBaseHeight = document()->paginated() && h.isPercent()
+    bool paginatedContentNeedsBaseHeight = document()->printing() && h.isPercent()
         && (isRoot() || (isBody() && document()->documentElement()->renderer()->style()->height().isPercent()));
     if (stretchesToViewHeight() || paginatedContentNeedsBaseHeight) {
         int margins = collapsedMarginTop() + collapsedMarginBottom();
-        int visHeight = document()->printing() ? view()->frameView()->pageHeight() : view()->viewHeight();
+        int visHeight = document()->printing() ? view()->pageHeight() : view()->viewHeight();
         if (isRoot())
             setHeight(max(height(), visHeight - margins));
         else {
index fcd779c..f7611b6 100644 (file)
@@ -214,9 +214,6 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
     int leftPad = paddingLeft();
     int topPad = paddingTop();
 
-    if (document()->printing() && !view()->printImages())
-        return;
-
     GraphicsContext* context = paintInfo.context;
 
     if (!m_imageResource->hasImage() || m_imageResource->errorOccurred()) {
index c1b81a5..45e66eb 100644 (file)
@@ -159,6 +159,8 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
     if (!firstLineBox())
         return;
 
+    // FIXME: Paint-time pagination is obsolete and is now only used by embedded WebViews inside AppKit
+    // NSViews.  Do not add any more code for this.
     RenderView* v = renderer->view();
     bool usePrintRect = !v->printRect().isEmpty();
     
index 25d786a..3dfee7b 100644 (file)
@@ -188,9 +188,6 @@ void RenderVideo::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
     MediaPlayer* mediaPlayer = player();
     bool displayingPoster = videoElement()->shouldDisplayPosterImage();
 
-    if (displayingPoster && document()->printing() && !view()->printImages())
-        return;
-
     if (!displayingPoster) {
         if (!mediaPlayer)
             return;
index d52d549..c6b058e 100644 (file)
@@ -48,11 +48,8 @@ RenderView::RenderView(Node* node, FrameView* view)
     , m_selectionEnd(0)
     , m_selectionStartPos(-1)
     , m_selectionEndPos(-1)
-    , m_printImages(true)
     , m_maximalOutlineSize(0)
-    , m_bestTruncatedAt(0)
-    , m_truncatorWidth(0)
-    , m_forcedPageBreak(false)
+    , m_pageHeight(0)
     , m_layoutState(0)
     , m_layoutStateDisableCount(0)
 {
@@ -100,6 +97,9 @@ void RenderView::calcPrefWidths()
 
 void RenderView::layout()
 {
+    if (!document()->paginated())
+        setPageHeight(0);
+
     if (printing())
         m_minPrefWidth = m_maxPrefWidth = width();
 
@@ -117,6 +117,7 @@ void RenderView::layout()
     LayoutState state;
     // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
     state.m_clipped = false;
+    state.m_pageHeight = m_pageHeight;
     m_layoutState = &state;
 
     if (needsLayout())
@@ -126,7 +127,6 @@ void RenderView::layout()
     m_overflow.clear();
     addLayoutOverflow(IntRect(0, 0, docWidth(), docHeight()));
 
-
     ASSERT(layoutDelta() == IntSize());
     ASSERT(m_layoutStateDisableCount == 0);
     ASSERT(m_layoutState == &state);
@@ -154,12 +154,6 @@ void RenderView::paint(PaintInfo& paintInfo, int tx, int ty)
 {
     // If we ever require layout but receive a paint anyway, something has gone horribly wrong.
     ASSERT(!needsLayout());
-
-    // Cache the print rect because the dirty rect could get changed during painting.
-    if (document()->paginated())
-        setPrintRect(paintInfo.rect);
-    else
-        setPrintRect(IntRect());
     paintObject(paintInfo, tx, ty);
 }
 
@@ -668,29 +662,6 @@ float RenderView::zoomFactor() const
     return frame ? frame->pageZoomFactor() : 1;
 }
 
-// The idea here is to take into account what object is moving the pagination point, and
-// thus choose the best place to chop it.
-void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
-{
-    // Nobody else can set a page break once we have a forced break.
-    if (m_forcedPageBreak)
-        return;
-
-    // Forced breaks always win over unforced breaks.
-    if (forcedBreak) {
-        m_forcedPageBreak = true;
-        m_bestTruncatedAt = y;
-        return;
-    }
-
-    // Prefer the widest object that tries to move the pagination point
-    IntRect boundingBox = forRenderer->borderBoundingBox();
-    if (boundingBox.width() > m_truncatorWidth) {
-        m_truncatorWidth = boundingBox.width();
-        m_bestTruncatedAt = y;
-    }
-}
-
 void RenderView::pushLayoutState(RenderObject* root)
 {
     ASSERT(m_layoutStateDisableCount == 0);
@@ -724,6 +695,31 @@ void RenderView::updateHitTestResult(HitTestResult& result, const IntPoint& poin
     }
 }
 
+// FIXME: This function is obsolete and only used by embedded WebViews inside AppKit NSViews.
+// Do not add callers of this function!
+// The idea here is to take into account what object is moving the pagination point, and
+// thus choose the best place to chop it.
+void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
+{
+    // Nobody else can set a page break once we have a forced break.
+    if (m_legacyPrinting.m_forcedPageBreak)
+        return;
+
+    // Forced breaks always win over unforced breaks.
+    if (forcedBreak) {
+        m_legacyPrinting.m_forcedPageBreak = true;
+        m_legacyPrinting.m_bestTruncatedAt = y;
+        return;
+    }
+
+    // Prefer the widest object that tries to move the pagination point
+    IntRect boundingBox = forRenderer->borderBoundingBox();
+    if (boundingBox.width() > m_legacyPrinting.m_truncatorWidth) {
+        m_legacyPrinting.m_truncatorWidth = boundingBox.width();
+        m_legacyPrinting.m_bestTruncatedAt = y;
+    }
+}
+
 #if USE(ACCELERATED_COMPOSITING)
 bool RenderView::usesCompositing() const
 {
index e1f6128..d7213c7 100644 (file)
@@ -77,17 +77,6 @@ public:
     void selectionStartEnd(int& startPos, int& endPos) const;
 
     bool printing() const;
-    void setPrintImages(bool enable) { m_printImages = enable; }
-    bool printImages() const { return m_printImages; }
-
-    IntRect printRect() const { return m_printRect; }
-    void setPrintRect(const IntRect& r) { m_printRect = r; }
-
-    void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_forcedPageBreak = false; }
-    void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
-    int bestTruncatedAt() const { return m_bestTruncatedAt; }
-    
-    int truncatedAt() const { return m_truncatedAt; }
 
     virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
     virtual void absoluteQuads(Vector<FloatQuad>&);
@@ -120,23 +109,9 @@ public:
 
     bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); }
 
-    void pushLayoutState(RenderBox* renderer, const IntSize& offset, int pageHeight = 0, ColumnInfo* colInfo = 0)
-    {
-        // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
-        if (!doingFullRepaint() || renderer->hasColumns() || m_layoutState->isPaginated())
-            m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, colInfo);
-    }
-
+    // Subtree push/pop
     void pushLayoutState(RenderObject*);
-
-    void popLayoutState()
-    {
-        LayoutState* state = m_layoutState;
-        if (doingFullRepaint() && !m_layoutState->isPaginated())
-            return;
-        m_layoutState = state->m_next;
-        state->destroy(renderArena());
-    }
+    void popLayoutState(RenderObject*) { return popLayoutState(); } // Just doing this to keep popLayoutState() private and to make the subtree calls symmetrical.
 
     bool shouldDisableLayoutStateForSubtree(RenderObject*) const;
 
@@ -153,6 +128,30 @@ public:
 
     virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
 
+    unsigned pageHeight() const { return m_pageHeight; }
+    void setPageHeight(unsigned height)
+    {
+        if (m_pageHeight != height) {
+            m_pageHeight = height;
+            markDescendantBlocksAndLinesForLayout();
+        }
+    }
+
+    // FIXME: These functions are deprecated. No code should be added that uses these.
+    int bestTruncatedAt() const { return m_legacyPrinting.m_bestTruncatedAt; }
+    void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
+    int truncatedAt() const { return m_legacyPrinting.m_truncatedAt; }
+    void setTruncatedAt(int y)
+    { 
+        m_legacyPrinting.m_truncatedAt = y;
+        m_legacyPrinting.m_bestTruncatedAt = 0;
+        m_legacyPrinting.m_truncatorWidth = 0;
+        m_legacyPrinting.m_forcedPageBreak = false;
+    }
+    const IntRect& printRect() const { return m_legacyPrinting.m_printRect; }
+    void setPrintRect(const IntRect& r) { m_legacyPrinting.m_printRect = r; }
+    // End deprecated functions.
+
     // Notifications that this view became visible in a window, or will be
     // removed from the window.
     void didMoveOnscreen();
@@ -173,6 +172,26 @@ private:
     int docHeight() const;
     int docWidth() const;
 
+    // These functions may only be accessed by LayoutStateMaintainer.
+    bool pushLayoutState(RenderBox* renderer, const IntSize& offset, int pageHeight = 0, ColumnInfo* colInfo = 0)
+    {
+        // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
+        if (!doingFullRepaint() || renderer->hasColumns() || m_layoutState->isPaginated()) {
+            m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, colInfo);
+            return true;
+        }
+        return false;
+    }
+
+    void popLayoutState()
+    {
+        LayoutState* state = m_layoutState;
+        m_layoutState = state->m_next;
+        state->destroy(renderArena());
+    }
+    
+    friend class LayoutStateMaintainer;
+        
 protected:
     FrameView* m_frameView;
 
@@ -181,21 +200,31 @@ protected:
     int m_selectionStartPos;
     int m_selectionEndPos;
 
-    // used to ignore viewport width when printing to the printer
-    bool m_printImages;
-    int m_truncatedAt;
+    // FIXME: Only used by embedded WebViews inside AppKit NSViews.  Find a way to remove.
+    struct LegacyPrinting {
+        LegacyPrinting()
+            : m_bestTruncatedAt(0)
+            , m_truncatedAt(0)
+            , m_truncatorWidth(0)
+            , m_forcedPageBreak(false)
+        { }
+
+        int m_bestTruncatedAt;
+        int m_truncatedAt;
+        int m_truncatorWidth;
+        IntRect m_printRect;
+        bool m_forcedPageBreak;
+    };
+    LegacyPrinting m_legacyPrinting;
+    // End deprecated members.
 
     int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
-    IntRect m_printRect; // Used when printing.
 
     typedef HashSet<RenderWidget*> RenderWidgetSet;
-
     RenderWidgetSet m_widgets;
-
+    
 private:
-    int m_bestTruncatedAt;
-    int m_truncatorWidth;
-    bool m_forcedPageBreak;
+    unsigned m_pageHeight;
     LayoutState* m_layoutState;
     unsigned m_layoutStateDisableCount;
 #if USE(ACCELERATED_COMPOSITING)
@@ -228,6 +257,7 @@ public:
         , m_disabled(disableState)
         , m_didStart(false)
         , m_didEnd(false)
+        , m_didCreateLayoutState(false)
     {
         push(root, offset, pageHeight, colInfo);
     }
@@ -238,6 +268,7 @@ public:
         , m_disabled(false)
         , m_didStart(false)
         , m_didEnd(false)
+        , m_didCreateLayoutState(false)
     {
     }
     
@@ -250,8 +281,8 @@ public:
     {
         ASSERT(!m_didStart);
         // We push state even if disabled, because we still need to store layoutDelta
-        m_view->pushLayoutState(root, offset, pageHeight, colInfo);
-        if (m_disabled)
+        m_didCreateLayoutState = m_view->pushLayoutState(root, offset, pageHeight, colInfo);
+        if (m_disabled && m_didCreateLayoutState)
             m_view->disableLayoutState();
         m_didStart = true;
     }
@@ -260,9 +291,12 @@ public:
     {
         if (m_didStart) {
             ASSERT(!m_didEnd);
-            m_view->popLayoutState();
-            if (m_disabled)
-                m_view->enableLayoutState();
+            if (m_didCreateLayoutState) {
+                m_view->popLayoutState();
+                if (m_disabled)
+                    m_view->enableLayoutState();
+            }
+            
             m_didEnd = true;
         }
     }
@@ -274,6 +308,7 @@ private:
     bool m_disabled : 1;        // true if the offset and clip part of layoutState is disabled
     bool m_didStart : 1;        // true if we did a push or disable
     bool m_didEnd : 1;          // true if we popped or re-enabled
+    bool m_didCreateLayoutState : 1; // true if we actually made a layout state.
 };
 
 } // namespace WebCore
index 4fbe201..2159ee5 100644 (file)
@@ -1,3 +1,16 @@
+2010-09-17  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        https://bugs.webkit.org/show_bug.cgi?id=45993, convert printing to the new pagination model.
+
+        Make printing store the page height in the RenderView and push that into the layout state to
+        use the new pagination model.  The old pagination model is retained because it is still used
+        for embedded WebViews.
+
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView _adjustedBottomOfPageWithTop:bottom:limit:]):
+
 2010-09-17  Darin Adler  <darin@apple.com>
 
         Reviewed by Sam Weinig.
index e125d64..02d32d9 100644 (file)
@@ -2302,7 +2302,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
         return bottom;
 
     float newBottom;
-    view->adjustPageHeight(&newBottom, top, bottom, bottomLimit);
+    view->adjustPageHeightDeprecated(&newBottom, top, bottom, bottomLimit);
 
 #ifdef __LP64__
     // If the new bottom is equal to the old bottom (when both are treated as floats), we just return the original