Title: [293218] trunk
Revision
293218
Author
za...@apple.com
Date
2022-04-22 06:27:43 -0700 (Fri, 22 Apr 2022)

Log Message

Book content is clipped at page boundary when displaying list with bullet points
https://bugs.webkit.org/show_bug.cgi?id=239638
<rdar://89257768>

Reviewed by Antti Koivisto.

Source/WebCore:

Table cell content needs special handling when does not fit the page.

When a table cell's first line does not fit the page, instead of the normal, "let's add a flow level pagination strut"
we have to handle it as a line level strut (not sure why it is implemted this way but this is the expected behavior).
-also implment LineBoxIteratorModernPath::isFirstAfterPageBreak.

Test: fast/multicol/pagination/table-cell-one-line-pagination.html

* layout/integration/inline/InlineIteratorLineBoxModernPath.h:
(WebCore::InlineIterator::LineBoxIteratorModernPath::isFirstAfterPageBreak const):
* layout/integration/inline/LayoutIntegrationLine.h:
(WebCore::LayoutIntegration::Line::Line):
(WebCore::LayoutIntegration::Line::isFirstAfterPageBreak const):
* layout/integration/inline/LayoutIntegrationPagination.cpp:
(WebCore::LayoutIntegration::setPageBreakForLine): According to RenderBlockFlow::adjustLinePositionForPagination, we
have to call setPageBreak, even when the first line does not fit.
(WebCore::LayoutIntegration::makeAdjustedContent):
(WebCore::LayoutIntegration::adjustLinePositionsForPagination):

LayoutTests:

* fast/multicol/pagination/table-cell-one-line-pagination-expected.html: Added.
* fast/multicol/pagination/table-cell-one-line-pagination.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (293217 => 293218)


--- trunk/LayoutTests/ChangeLog	2022-04-22 12:02:18 UTC (rev 293217)
+++ trunk/LayoutTests/ChangeLog	2022-04-22 13:27:43 UTC (rev 293218)
@@ -1,3 +1,14 @@
+2022-04-22  Alan Bujtas  <za...@apple.com>
+
+        Book content is clipped at page boundary when displaying list with bullet points
+        https://bugs.webkit.org/show_bug.cgi?id=239638
+        <rdar://89257768>
+
+        Reviewed by Antti Koivisto.
+
+        * fast/multicol/pagination/table-cell-one-line-pagination-expected.html: Added.
+        * fast/multicol/pagination/table-cell-one-line-pagination.html: Added.
+
 2022-04-22  Tyler Wilcock  <tyle...@apple.com>
 
         AX: The isolated tree is not updated after role changes in AccessibilityRenderObject::updateRoleAfterChildrenCreation()

Added: trunk/LayoutTests/fast/multicol/pagination/table-cell-one-line-pagination-expected.html (0 => 293218)


--- trunk/LayoutTests/fast/multicol/pagination/table-cell-one-line-pagination-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/pagination/table-cell-one-line-pagination-expected.html	2022-04-22 13:27:43 UTC (rev 293218)
@@ -0,0 +1,18 @@
+<style>
+div {
+  font-size: 90px;
+}
+</style>
+<script>
+  if (window.internals)
+    internals.setPagination("LeftToRightPaginated", 0);
+</script>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>

Added: trunk/LayoutTests/fast/multicol/pagination/table-cell-one-line-pagination.html (0 => 293218)


--- trunk/LayoutTests/fast/multicol/pagination/table-cell-one-line-pagination.html	                        (rev 0)
+++ trunk/LayoutTests/fast/multicol/pagination/table-cell-one-line-pagination.html	2022-04-22 13:27:43 UTC (rev 293218)
@@ -0,0 +1,19 @@
+<style>
+div {
+  font-size: 90px;
+  display: table;
+}
+</style>
+<script>
+  if (window.internals)
+    internals.setPagination("LeftToRightPaginated", 0);
+</script>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>
+<div>XXXXXXXX</div>

Modified: trunk/Source/WebCore/ChangeLog (293217 => 293218)


--- trunk/Source/WebCore/ChangeLog	2022-04-22 12:02:18 UTC (rev 293217)
+++ trunk/Source/WebCore/ChangeLog	2022-04-22 13:27:43 UTC (rev 293218)
@@ -1,3 +1,30 @@
+2022-04-22  Alan Bujtas  <za...@apple.com>
+
+        Book content is clipped at page boundary when displaying list with bullet points
+        https://bugs.webkit.org/show_bug.cgi?id=239638
+        <rdar://89257768>
+
+        Reviewed by Antti Koivisto.
+
+        Table cell content needs special handling when does not fit the page.
+
+        When a table cell's first line does not fit the page, instead of the normal, "let's add a flow level pagination strut"
+        we have to handle it as a line level strut (not sure why it is implemted this way but this is the expected behavior).
+        -also implment LineBoxIteratorModernPath::isFirstAfterPageBreak.
+
+        Test: fast/multicol/pagination/table-cell-one-line-pagination.html
+
+        * layout/integration/inline/InlineIteratorLineBoxModernPath.h:
+        (WebCore::InlineIterator::LineBoxIteratorModernPath::isFirstAfterPageBreak const):
+        * layout/integration/inline/LayoutIntegrationLine.h:
+        (WebCore::LayoutIntegration::Line::Line):
+        (WebCore::LayoutIntegration::Line::isFirstAfterPageBreak const):
+        * layout/integration/inline/LayoutIntegrationPagination.cpp:
+        (WebCore::LayoutIntegration::setPageBreakForLine): According to RenderBlockFlow::adjustLinePositionForPagination, we
+        have to call setPageBreak, even when the first line does not fit.
+        (WebCore::LayoutIntegration::makeAdjustedContent):
+        (WebCore::LayoutIntegration::adjustLinePositionsForPagination):
+
 2022-04-22  Antti Koivisto  <an...@apple.com>
 
         Bail out from text decoration computation if none is requested

Modified: trunk/Source/WebCore/layout/integration/inline/InlineIteratorLineBoxModernPath.h (293217 => 293218)


--- trunk/Source/WebCore/layout/integration/inline/InlineIteratorLineBoxModernPath.h	2022-04-22 12:02:18 UTC (rev 293217)
+++ trunk/Source/WebCore/layout/integration/inline/InlineIteratorLineBoxModernPath.h	2022-04-22 13:27:43 UTC (rev 293218)
@@ -68,7 +68,7 @@
     const RenderBlockFlow& containingBlock() const { return m_inlineContent->containingBlock(); }
 
     RenderFragmentContainer* containingFragment() const { return nullptr; }
-    bool isFirstAfterPageBreak() const { return false; }
+    bool isFirstAfterPageBreak() const { return line().isFirstAfterPageBreak(); }
 
     void traverseNext()
     {

Modified: trunk/Source/WebCore/layout/integration/inline/LayoutIntegrationLine.h (293217 => 293218)


--- trunk/Source/WebCore/layout/integration/inline/LayoutIntegrationLine.h	2022-04-22 12:02:18 UTC (rev 293217)
+++ trunk/Source/WebCore/layout/integration/inline/LayoutIntegrationLine.h	2022-04-22 13:27:43 UTC (rev 293218)
@@ -36,7 +36,7 @@
 class Line {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    Line(size_t firstBoxIndex, size_t boxCount, const FloatRect& lineBoxRect, float enclosingContentTop, float enclosingContentBottom, const FloatRect& scrollableOverflow, const FloatRect& inkOverflow, float baseline, FontBaseline baselineType, float contentLogicalOffset, float contentLogicalWidth, bool isHorizontal)
+    Line(size_t firstBoxIndex, size_t boxCount, const FloatRect& lineBoxRect, float enclosingContentTop, float enclosingContentBottom, const FloatRect& scrollableOverflow, const FloatRect& inkOverflow, float baseline, FontBaseline baselineType, float contentLogicalOffset, float contentLogicalWidth, bool isHorizontal, bool isFirstAfterPageBreak = false)
         : m_firstBoxIndex(firstBoxIndex)
         , m_boxCount(boxCount)
         , m_lineBoxRect(lineBoxRect)
@@ -49,6 +49,7 @@
         , m_contentLogicalWidth(contentLogicalWidth)
         , m_baselineType(baselineType)
         , m_isHorizontal(isHorizontal)
+        , m_isFirstAfterPageBreak(isFirstAfterPageBreak)
     {
     }
 
@@ -76,6 +77,8 @@
     float contentLogicalOffset() const { return m_contentLogicalOffset; }
     float contentLogicalWidth() const { return m_contentLogicalWidth; }
 
+    bool isFirstAfterPageBreak() const { return m_isFirstAfterPageBreak; }
+
 private:
     size_t m_firstBoxIndex { 0 };
     size_t m_boxCount { 0 };
@@ -93,6 +96,8 @@
     float m_contentLogicalWidth { 0 };
     FontBaseline m_baselineType { AlphabeticBaseline };
     bool m_isHorizontal { true };
+    // FIXME: This is to match paginated legacy lines. Move it to some other, paginated related structure.
+    bool m_isFirstAfterPageBreak { false };
 };
 
 }

Modified: trunk/Source/WebCore/layout/integration/inline/LayoutIntegrationPagination.cpp (293217 => 293218)


--- trunk/Source/WebCore/layout/integration/inline/LayoutIntegrationPagination.cpp	2022-04-22 12:02:18 UTC (rev 293217)
+++ trunk/Source/WebCore/layout/integration/inline/LayoutIntegrationPagination.cpp	2022-04-22 13:27:43 UTC (rev 293218)
@@ -30,6 +30,7 @@
 
 #include "FontCascade.h"
 #include "RenderBlockFlow.h"
+#include "RenderTableCell.h"
 
 namespace WebCore {
 namespace LayoutIntegration {
@@ -87,24 +88,28 @@
     return offset + flow.pageRemainingLogicalHeightForOffset(lineBreakPosition, RenderBlockFlow::ExcludePageBoundary);
 }
 
-static void setPageBreakForLine(unsigned lineBreakIndex, PaginatedLines& lines, RenderBlockFlow& flow, Vector<Strut>& struts,
-    bool atTheTopOfColumnOrPage, bool lineDoesNotFit)
+static void setPageBreakForLine(unsigned lineBreakIndex, PaginatedLines& lines, RenderBlockFlow& flow, Vector<Strut>& struts, bool atTheTopOfColumnOrPage, bool lineDoesNotFit, bool& isPageBreakWithLineStrut)
 {
     auto line = lines.at(lineBreakIndex);
     auto remainingLogicalHeight = flow.pageRemainingLogicalHeightForOffset(line.top, RenderBlockFlow::ExcludePageBoundary);
+
+    if (atTheTopOfColumnOrPage)
+        flow.setPageBreak(line.top, line.height);
+    else
+        flow.setPageBreak(line.top, line.height - remainingLogicalHeight);
+
     auto& style = flow.style();
     auto firstLineDoesNotFit = !lineBreakIndex && line.height < flow.pageLogicalHeightForOffset(line.top);
     auto moveOrphanToNextColumn = lineDoesNotFit && !style.hasAutoOrphans() && style.orphans() > (short)lineBreakIndex;
-    if (firstLineDoesNotFit || moveOrphanToNextColumn) {
+    // Special table cell handling. See RenderBlockFlow::adjustLinePositionForPagination for details.
+    if ((firstLineDoesNotFit || moveOrphanToNextColumn) && !is<RenderTableCell>(flow)) {
         auto firstLine = lines.first();
         auto firstLineUpperOverhang = std::max(LayoutUnit(-firstLine.top), 0_lu);
         flow.setPaginationStrut(line.top + remainingLogicalHeight + firstLineUpperOverhang);
+        isPageBreakWithLineStrut = false;
         return;
     }
-    if (atTheTopOfColumnOrPage)
-        flow.setPageBreak(line.top, line.height);
-    else
-        flow.setPageBreak(line.top, line.height - remainingLogicalHeight);
+    isPageBreakWithLineStrut = true;
     struts.append({ lineBreakIndex, computeOffsetAfterLineBreak(lines[lineBreakIndex].top, !lineBreakIndex, atTheTopOfColumnOrPage, flow) });
 }
 
@@ -117,7 +122,7 @@
     flow.updateMinimumPageHeight(0, LayoutUnit(inlineContent.lines[minimumLineCount - 1].lineBoxBottom()));
 }
 
-static std::unique_ptr<InlineContent> makeAdjustedContent(const InlineContent& inlineContent, Vector<float> adjustments)
+static std::unique_ptr<InlineContent> makeAdjustedContent(const InlineContent& inlineContent, Vector<float> adjustments, Vector<bool> isFirstLineAfterPageBreakList)
 {
     auto moveVertically = [](FloatRect rect, float offset) {
         rect.move(FloatSize(0, offset));
@@ -124,8 +129,7 @@
         return rect;
     };
 
-    auto adjustedLine = [&](const Line& line, float offset)
-    {
+    auto adjustedLine = [&] (auto& line, auto offset, auto isFirstAfterPageBreak) {
         return Line {
             line.firstBoxIndex(),
             line.boxCount(),
@@ -138,12 +142,12 @@
             line.baselineType(),
             line.contentLogicalOffset(),
             line.contentLogicalWidth(),
-            line.isHorizontal()
+            line.isHorizontal(),
+            isFirstAfterPageBreak
         };
     };
 
-    auto adjustedBox = [&](const InlineDisplay::Box& box, float offset)
-    {
+    auto adjustedBox = [&](auto& box, auto offset) {
         auto adjustedBox = box;
         adjustedBox.moveVertically(offset);
         return adjustedBox;
@@ -152,7 +156,7 @@
     auto adjustedContent = makeUnique<InlineContent>(inlineContent.lineLayout());
 
     for (size_t lineIndex = 0; lineIndex < inlineContent.lines.size(); ++lineIndex)
-        adjustedContent->lines.append(adjustedLine(inlineContent.lines[lineIndex], adjustments[lineIndex]));
+        adjustedContent->lines.append(adjustedLine(inlineContent.lines[lineIndex], adjustments[lineIndex], isFirstLineAfterPageBreakList[lineIndex]));
 
     for (auto& box : inlineContent.boxes)
         adjustedContent->boxes.append(adjustedBox(box, adjustments[box.lineIndex()]));
@@ -172,7 +176,8 @@
     auto widows = flow.style().hasAutoWidows() ? 1 : std::max<int>(flow.style().widows(), 1);
     auto orphans = flow.style().hasAutoOrphans() ? 1 : std::max<int>(flow.style().orphans(), 1);
     PaginatedLines lines;
-    for (unsigned lineIndex = 0; lineIndex < lineCount; ++lineIndex) {
+    auto isFirstLineAfterPageBreakList = Vector<bool>(lineCount, false);
+    for (size_t lineIndex = 0; lineIndex < lineCount; ++lineIndex) {
         auto line = computeLineTopAndBottomWithOverflow(flow, inlineContent.lines, lineIndex, struts);
         lines.append(line);
         auto remainingHeight = flow.pageRemainingLogicalHeightForOffset(line.top, RenderBlockFlow::ExcludePageBoundary);
@@ -182,7 +187,9 @@
             auto lineBreakIndex = computeLineBreakIndex(lineIndex, lineCount, orphans, widows, struts);
             // Are we still at the top of the column/page?
             atTheTopOfColumnOrPage = atTheTopOfColumnOrPage ? lineIndex == lineBreakIndex : false;
-            setPageBreakForLine(lineBreakIndex, lines, flow, struts, atTheTopOfColumnOrPage, lineDoesNotFit);
+            auto isPageBreakWithLineStrut = false;
+            setPageBreakForLine(lineBreakIndex, lines, flow, struts, atTheTopOfColumnOrPage, lineDoesNotFit, isPageBreakWithLineStrut);
+            isFirstLineAfterPageBreakList[lineIndex] = isPageBreakWithLineStrut;
             // Recompute line positions that we already visited but widow break pushed them to a new page.
             for (auto i = lineBreakIndex; i < lines.size(); ++i)
                 lines.at(i) = computeLineTopAndBottomWithOverflow(flow, inlineContent.lines, i, struts);
@@ -198,7 +205,7 @@
             adjustments[lineIndex] += strut.offset;
     }
 
-    return makeAdjustedContent(inlineContent, adjustments);
+    return makeAdjustedContent(inlineContent, adjustments, isFirstLineAfterPageBreakList);
 }
 
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to