Simple line layout: ensureLineBoxes for paginated content.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Feb 2017 19:33:02 +0000 (19:33 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Feb 2017 19:33:02 +0000 (19:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=168729
<rdar://problem/30654400>

Reviewed by Antti Koivisto.

This patch sets the layout state bits for paginated subtree layout, when we are switching
over from simple line runs to inline tree.

Not enabled yet.

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::ensureLineBoxes):
* rendering/RenderView.cpp:
(WebCore::RenderView::pushLayoutStateForPagination): LayoutUnit(1) is not the real height, it's just
an indicator that we've got paginated content.
* rendering/RenderView.h:
* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::create):
(WebCore::SimpleLineLayout::Layout::create):
(WebCore::SimpleLineLayout::Layout::Layout):
* rendering/SimpleLineLayout.h:
(WebCore::SimpleLineLayout::Layout::isPaginated):
(WebCore::SimpleLineLayout::Layout::hasPaginationStruts):
* rendering/SimpleLineLayoutFunctions.h:
(WebCore::SimpleLineLayout::computeFlowHeight):
* rendering/SimpleLineLayoutResolver.h:
(WebCore::SimpleLineLayout::RunResolver::Run::computeBaselinePosition):

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBlockFlow.cpp
Source/WebCore/rendering/RenderView.cpp
Source/WebCore/rendering/RenderView.h
Source/WebCore/rendering/SimpleLineLayout.cpp
Source/WebCore/rendering/SimpleLineLayout.h
Source/WebCore/rendering/SimpleLineLayoutFunctions.h
Source/WebCore/rendering/SimpleLineLayoutResolver.h

index dab8957..7cf3fc1 100644 (file)
@@ -1,3 +1,34 @@
+2017-02-22  Zalan Bujtas  <zalan@apple.com>
+
+        Simple line layout: ensureLineBoxes for paginated content.
+        https://bugs.webkit.org/show_bug.cgi?id=168729
+        <rdar://problem/30654400>
+
+        Reviewed by Antti Koivisto.
+
+        This patch sets the layout state bits for paginated subtree layout, when we are switching
+        over from simple line runs to inline tree. 
+
+        Not enabled yet.
+
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::ensureLineBoxes):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::pushLayoutStateForPagination): LayoutUnit(1) is not the real height, it's just
+        an indicator that we've got paginated content.
+        * rendering/RenderView.h:
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::create):
+        (WebCore::SimpleLineLayout::Layout::create):
+        (WebCore::SimpleLineLayout::Layout::Layout):
+        * rendering/SimpleLineLayout.h:
+        (WebCore::SimpleLineLayout::Layout::isPaginated):
+        (WebCore::SimpleLineLayout::Layout::hasPaginationStruts):
+        * rendering/SimpleLineLayoutFunctions.h:
+        (WebCore::SimpleLineLayout::computeFlowHeight):
+        * rendering/SimpleLineLayoutResolver.h:
+        (WebCore::SimpleLineLayout::RunResolver::Run::computeBaselinePosition):
+
 2017-02-22  Per Arne Vollan  <pvollan@apple.com>
 
         [Win] Compile fix.
index 8aa29bc..514a579 100644 (file)
@@ -3700,6 +3700,7 @@ void RenderBlockFlow::ensureLineBoxes()
     setLineLayoutPath(ForceLineBoxesPath);
     if (!m_simpleLineLayout)
         return;
+    bool isPaginated = m_simpleLineLayout->isPaginated();
     m_simpleLineLayout = nullptr;
 
 #if !ASSERT_DISABLED
@@ -3710,7 +3711,12 @@ void RenderBlockFlow::ensureLineBoxes()
     bool relayoutChildren = false;
     LayoutUnit repaintLogicalTop;
     LayoutUnit repaintLogicalBottom;
-    layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+    if (isPaginated) {
+        view().pushLayoutStateForPagination(*this);
+        layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+        view().popLayoutState(*this);
+    } else
+        layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
 
     updateLogicalHeight();
     ASSERT(didNeedLayout || logicalHeight() == oldHeight);
@@ -3944,7 +3950,7 @@ void RenderBlockFlow::checkForPaginationLogicalHeightChange(bool& relayoutChildr
         // enabled and flow thread height is still unknown (i.e. during the first layout pass). When
         // it's unknown, we need to prevent the pagination code from assuming page breaks everywhere
         // and thereby eating every top margin. It should be trivial to clean up and get rid of this
-        // hack once the old multicol implementation is gone.
+        // hack once the old multicol implementation is gone (see also RenderView::pushLayoutStateForPagination).
         pageLogicalHeight = flowThread.isPageLogicalHeightKnown() ? LayoutUnit(1) : LayoutUnit(0);
 
         pageLogicalHeightChanged = flowThread.pageLogicalSizeChanged();
index 6ca38aa..25c22c0 100644 (file)
@@ -1232,6 +1232,15 @@ void RenderView::pushLayoutState(RenderObject& root)
     pushLayoutStateForCurrentFlowThread(root);
 }
 
+void RenderView::pushLayoutStateForPagination(RenderBlockFlow& layoutRoot)
+{
+    pushLayoutState(layoutRoot);
+    ASSERT(m_layoutState);
+    m_layoutState->m_isPaginated = true;
+    // This is just a flag for known page height (see RenderBlockFlow::checkForPaginationLogicalHeightChange).
+    m_layoutState->m_pageLogicalHeight = 1;
+}
+
 IntSize RenderView::viewportSizeForCSSViewportUnits() const
 {
     return frameView().viewportSizeForCSSViewportUnits();
index d1aaa6c..2e54355 100644 (file)
@@ -132,6 +132,7 @@ public:
 
     // Subtree push/pop
     void pushLayoutState(RenderObject&);
+    void pushLayoutStateForPagination(RenderBlockFlow&);
     void popLayoutState(RenderObject&) { return popLayoutState(); } // Just doing this to keep popLayoutState() private and to make the subtree calls symmetrical.
 
     // Returns true if layoutState should be used for its cached offset and clip.
index b756ab0..4b8d9a7 100644 (file)
@@ -1045,20 +1045,22 @@ std::unique_ptr<Layout> create(RenderBlockFlow& flow)
     Layout::RunVector runs;
     createTextRuns(runs, flow, lineCount);
     Layout::SimplePaginationStruts struts;
-    if (flow.view().layoutState() && flow.view().layoutState()->isPaginated())
+    auto isPaginated = flow.view().layoutState() && flow.view().layoutState()->isPaginated();
+    if (isPaginated)
         adjustLinePositionsForPagination(runs, struts, flow, lineCount);
-    return Layout::create(runs, struts, lineCount);
+    return Layout::create(runs, struts, lineCount, isPaginated);
 }
 
-std::unique_ptr<Layout> Layout::create(const RunVector& runVector, SimplePaginationStruts& struts, unsigned lineCount)
+std::unique_ptr<Layout> Layout::create(const RunVector& runVector, SimplePaginationStruts& struts, unsigned lineCount, bool isPaginated)
 {
     void* slot = WTF::fastMalloc(sizeof(Layout) + sizeof(Run) * runVector.size());
-    return std::unique_ptr<Layout>(new (NotNull, slot) Layout(runVector, struts, lineCount));
+    return std::unique_ptr<Layout>(new (NotNull, slot) Layout(runVector, struts, lineCount, isPaginated));
 }
 
-Layout::Layout(const RunVector& runVector, SimplePaginationStruts& struts, unsigned lineCount)
+Layout::Layout(const RunVector& runVector, SimplePaginationStruts& struts, unsigned lineCount, bool isPaginated)
     : m_lineCount(lineCount)
     , m_runCount(runVector.size())
+    , m_isPaginated(isPaginated)
     , m_paginationStruts(WTFMove(struts))
 {
     memcpy(m_runs, runVector.data(), m_runCount * sizeof(Run));
index 4d3ab24..13e5956 100644 (file)
@@ -76,20 +76,22 @@ class Layout {
 public:
     using RunVector = Vector<Run, 10>;
     using SimplePaginationStruts = Vector<SimplePaginationStrut, 4>;
-    static std::unique_ptr<Layout> create(const RunVector&, SimplePaginationStruts&, unsigned lineCount);
+    static std::unique_ptr<Layout> create(const RunVector&, SimplePaginationStruts&, unsigned lineCount, bool isPaginated);
 
     unsigned lineCount() const { return m_lineCount; }
 
     unsigned runCount() const { return m_runCount; }
     const Run& runAt(unsigned i) const { return m_runs[i]; }
 
-    bool isPaginated() const { return !m_paginationStruts.isEmpty(); }
+    bool isPaginated() const { return m_isPaginated; }
+    bool hasPaginationStruts() const { return !m_paginationStruts.isEmpty(); }
     const SimplePaginationStruts& struts() const { return m_paginationStruts; }
 private:
-    Layout(const RunVector&, SimplePaginationStruts&, unsigned lineCount);
+    Layout(const RunVector&, SimplePaginationStruts&, unsigned lineCount, bool isPaginated);
 
     unsigned m_lineCount;
     unsigned m_runCount;
+    bool m_isPaginated;
     SimplePaginationStruts m_paginationStruts;
     Run m_runs[0];
 };
index 689bd05..7b30839 100644 (file)
@@ -74,7 +74,7 @@ namespace SimpleLineLayout {
 inline LayoutUnit computeFlowHeight(const RenderBlockFlow& flow, const Layout& layout)
 {
     auto flowHeight = lineHeightFromFlow(flow) * layout.lineCount();
-    if (!layout.isPaginated())
+    if (!layout.hasPaginationStruts())
         return flowHeight;
     for (auto& strutEntry : layout.struts())
         flowHeight += strutEntry.offset;
index 868127c..ce242cb 100644 (file)
@@ -221,7 +221,7 @@ inline float RunResolver::Run::computeBaselinePosition() const
 {
     auto& resolver = m_iterator.resolver();
     auto offset = resolver.m_borderAndPaddingBefore + resolver.m_lineHeight * lineIndex();
-    if (!resolver.m_layout.isPaginated())
+    if (!resolver.m_layout.hasPaginationStruts())
         return offset + resolver.m_baseline;
     for (auto& strutEntry : resolver.m_layout.struts()) {
         if (strutEntry.lineBreak > lineIndex())