Title: [267657] trunk
Revision
267657
Author
[email protected]
Date
2020-09-27 06:03:29 -0700 (Sun, 27 Sep 2020)

Log Message

[LFC][IFC] Create inline boxes for hard line breaks(<br>) and word wrap opportunities (<wbr>)
https://bugs.webkit.org/show_bug.cgi?id=217023

Reviewed by Antti Koivisto.

Source/WebCore:

Both hard <br> and the word break opportunity layout boxes generate inline boxes and get computed box geometries.
It enables us to answer questions like element.offsetTop/offsetLeft.

Test: fast/layoutformattingcontext/br-and-wbr-simple.html

* layout/FormattingState.cpp:
(WebCore::Layout::FormattingState::boxGeometry):
* layout/Verification.cpp:
(WebCore::Layout::LayoutContext::verifyAndOutputMismatchingLayoutTree):
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::layoutInFlowContent):
(WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthConstraints):
(WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
* layout/inlineformatting/InlineFormattingContextGeometry.cpp:
(WebCore::Layout::LineBoxBuilder::constructInlineBoxes):
* layout/inlineformatting/InlineLine.h:
(WebCore::Layout::Line::Run::isLineBreak const):
(WebCore::Layout::Line::Run::isSoftLineBreak const):
(WebCore::Layout::Line::Run::isHardLineBreak const):
* layout/tableformatting/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::setUsedGeometryForCells):

LayoutTests:

* fast/layoutformattingcontext/br-and-wbr-simple-expected.html: Added.
* fast/layoutformattingcontext/br-and-wbr-simple.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (267656 => 267657)


--- trunk/LayoutTests/ChangeLog	2020-09-27 12:55:58 UTC (rev 267656)
+++ trunk/LayoutTests/ChangeLog	2020-09-27 13:03:29 UTC (rev 267657)
@@ -1,3 +1,13 @@
+2020-09-27  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Create inline boxes for hard line breaks(<br>) and word wrap opportunities (<wbr>)
+        https://bugs.webkit.org/show_bug.cgi?id=217023
+
+        Reviewed by Antti Koivisto.
+
+        * fast/layoutformattingcontext/br-and-wbr-simple-expected.html: Added.
+        * fast/layoutformattingcontext/br-and-wbr-simple.html: Added.
+
 2020-09-27  Rob Buis  <[email protected]>
 
         Alias WebKitCSSMatrix to DOMMatrix

Added: trunk/LayoutTests/fast/layoutformattingcontext/br-and-wbr-simple-expected.html (0 => 267657)


--- trunk/LayoutTests/fast/layoutformattingcontext/br-and-wbr-simple-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/br-and-wbr-simple-expected.html	2020-09-27 13:03:29 UTC (rev 267657)
@@ -0,0 +1,9 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+  width: 10px;
+  height: 30px;
+  background-color: green;
+}
+</style>
+<div></div>
\ No newline at end of file

Added: trunk/LayoutTests/fast/layoutformattingcontext/br-and-wbr-simple.html (0 => 267657)


--- trunk/LayoutTests/fast/layoutformattingcontext/br-and-wbr-simple.html	                        (rev 0)
+++ trunk/LayoutTests/fast/layoutformattingcontext/br-and-wbr-simple.html	2020-09-27 13:03:29 UTC (rev 267657)
@@ -0,0 +1,11 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+  font-family: Ahem;
+  font-size: 10px;
+  width: 10px;
+  color: black;
+  background-color: green;
+}
+</style>
+<div>first<br>second<wbr>third_line</div>

Modified: trunk/Source/WebCore/ChangeLog (267656 => 267657)


--- trunk/Source/WebCore/ChangeLog	2020-09-27 12:55:58 UTC (rev 267656)
+++ trunk/Source/WebCore/ChangeLog	2020-09-27 13:03:29 UTC (rev 267657)
@@ -1,3 +1,32 @@
+2020-09-27  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Create inline boxes for hard line breaks(<br>) and word wrap opportunities (<wbr>)
+        https://bugs.webkit.org/show_bug.cgi?id=217023
+
+        Reviewed by Antti Koivisto.
+
+        Both hard <br> and the word break opportunity layout boxes generate inline boxes and get computed box geometries.
+        It enables us to answer questions like element.offsetTop/offsetLeft.
+
+        Test: fast/layoutformattingcontext/br-and-wbr-simple.html
+
+        * layout/FormattingState.cpp:
+        (WebCore::Layout::FormattingState::boxGeometry):
+        * layout/Verification.cpp:
+        (WebCore::Layout::LayoutContext::verifyAndOutputMismatchingLayoutTree):
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::layoutInFlowContent):
+        (WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthConstraints):
+        (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
+        * layout/inlineformatting/InlineFormattingContextGeometry.cpp:
+        (WebCore::Layout::LineBoxBuilder::constructInlineBoxes):
+        * layout/inlineformatting/InlineLine.h:
+        (WebCore::Layout::Line::Run::isLineBreak const):
+        (WebCore::Layout::Line::Run::isSoftLineBreak const):
+        (WebCore::Layout::Line::Run::isHardLineBreak const):
+        * layout/tableformatting/TableFormattingContext.cpp:
+        (WebCore::Layout::TableFormattingContext::setUsedGeometryForCells):
+
 2020-09-27  Rob Buis  <[email protected]>
 
         Alias WebKitCSSMatrix to DOMMatrix

Modified: trunk/Source/WebCore/layout/FormattingState.cpp (267656 => 267657)


--- trunk/Source/WebCore/layout/FormattingState.cpp	2020-09-27 12:55:58 UTC (rev 267656)
+++ trunk/Source/WebCore/layout/FormattingState.cpp	2020-09-27 13:03:29 UTC (rev 267657)
@@ -52,8 +52,8 @@
 {
     // Should never need to mutate a display box outside of the formatting context.
     ASSERT(&layoutState().establishedFormattingState(layoutBox.formattingContextRoot()) == this);
-    // Anonymous text wrappers/line break boxes should not need display boxes.
-    ASSERT(!layoutBox.isInlineTextBox() && (!layoutBox.isLineBreakBox() || layoutBox.isOutOfFlowPositioned()));
+    // Anonymous text wrappers do not need display boxes.
+    ASSERT(!layoutBox.isInlineTextBox());
     return layoutState().ensureGeometryForBox(layoutBox);
 }
 

Modified: trunk/Source/WebCore/layout/Verification.cpp (267656 => 267657)


--- trunk/Source/WebCore/layout/Verification.cpp	2020-09-27 12:55:58 UTC (rev 267656)
+++ trunk/Source/WebCore/layout/Verification.cpp	2020-09-27 13:03:29 UTC (rev 267657)
@@ -334,13 +334,13 @@
 {
     TextStream stream;
     auto& layoutRoot = layoutState.root();
-    auto mismatchingGeometry = verifyAndOutputSubtree(stream, layoutState, rootRenderer, layoutRoot);
-    if (!mismatchingGeometry)
-        return;
 #if ENABLE(TREE_DEBUGGING)
     showRenderTree(&rootRenderer);
     showLayoutTree(layoutRoot, &layoutState);
 #endif
+    auto mismatchingGeometry = verifyAndOutputSubtree(stream, layoutState, rootRenderer, layoutRoot);
+    if (!mismatchingGeometry)
+        return;
     WTFLogAlways("%s", stream.release().utf8().data());
     ASSERT_NOT_REACHED();
 }

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (267656 => 267657)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2020-09-27 12:55:58 UTC (rev 267656)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2020-09-27 13:03:29 UTC (rev 267657)
@@ -113,9 +113,16 @@
                 computeWidthAndMargin(*layoutBox, constraints.horizontal);
                 computeHeightAndMargin(*layoutBox, constraints.horizontal);
             }
+        } else if (layoutBox->isLineBreakBox()) {
+            auto& boxGeometry = formattingState().boxGeometry(*layoutBox);
+            boxGeometry.setHorizontalMargin({ });
+            boxGeometry.setBorder({ });
+            boxGeometry.setPadding({ });
+            boxGeometry.setContentBoxWidth({ });
+            boxGeometry.setVerticalMargin({ });
         } else if (layoutBox->isInlineBox()) {
-            // Text wrapper boxes (anonymous inline level boxes) and <br>s don't have box geometries (they only generate runs).
-            if (!layoutBox->isInlineTextBox() && !layoutBox->isLineBreakBox()) {
+            // Text wrapper boxes (anonymous inline level boxes) don't have box geometries (they only generate runs).
+            if (!layoutBox->isInlineTextBox()) {
                 // Inline boxes (<span>) can't get sized/positioned yet. At this point we can only compute their margins, borders and padding.
                 computeBorderAndPadding(*layoutBox, constraints.horizontal);
                 computeHorizontalMargin(*layoutBox, constraints.horizontal);
@@ -206,7 +213,7 @@
     auto* layoutBox = root().firstInFlowOrFloatingChild();
     // In order to compute the max/min widths, we need to compute margins, borders and padding for certain inline boxes first.
     while (layoutBox) {
-        if (layoutBox->isInlineTextBox() || layoutBox->isLineBreakBox()) {
+        if (layoutBox->isInlineTextBox()) {
             layoutBox = nextInlineLevelBoxToLayout(*layoutBox, root());
             continue;
         }
@@ -427,6 +434,7 @@
         auto lineIndex = formattingState.lines().size();
         // Create the inline runs on the current line. This is mostly text and atomic inline runs.
         for (auto& lineRun : lineContent.runs) {
+            // FIXME: We should not need to construct a line run for <br>.
             if (lineRun.isText() || lineRun.isLineBreak())
                 formattingState.addLineRun({ lineIndex, lineRun.layoutBox(), lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
             else if (lineRun.isBox())
@@ -461,6 +469,10 @@
                 boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
                 continue;
             }
+            if (layoutBox.isLineBreakBox()) {
+                boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
+                boxGeometry.setContentBoxHeight(toLayoutUnit(inlineBox->logicalHeight()));
+            }
             auto marginBoxWidth = inlineBox->logicalWidth();
             auto contentBoxWidth = marginBoxWidth - (boxGeometry.marginStart() + boxGeometry.borderLeft() + boxGeometry.paddingLeft().valueOr(0));
             // Non-atomic inline level boxes may or may not be wrapped and have geometries on multiple lines.

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp (267656 => 267657)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2020-09-27 12:55:58 UTC (rev 267656)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2020-09-27 13:03:29 UTC (rev 267657)
@@ -225,8 +225,8 @@
 
     for (auto& run : runs) {
         auto& inlineLevelBox = run.layoutBox();
+        auto logicalLeft = horizontalAligmentOffset + run.logicalLeft();
         if (run.isBox()) {
-            auto logicalLeft = horizontalAligmentOffset + run.logicalLeft();
             auto& inlineLevelBoxGeometry = formattingContext().geometryForBox(inlineLevelBox);
             auto logicalHeight = inlineLevelBoxGeometry.marginBoxHeight();
             auto baseline = logicalHeight;
@@ -253,7 +253,6 @@
                 inlineBox->setIsNonEmpty();
             lineBox.addInlineBox(WTFMove(inlineBox));
         } else if (run.isContainerStart()) {
-            auto logicalLeft = horizontalAligmentOffset + run.logicalLeft();
             auto initialLogicalWidth = lineBox.logicalWidth() - run.logicalLeft();
             ASSERT(initialLogicalWidth >= 0);
             lineBox.addInlineBox(LineBox::InlineBox::createBoxForInlineBox(inlineLevelBox, logicalLeft, initialLogicalWidth));
@@ -261,7 +260,7 @@
             // Adjust the logical width when the inline level container closes on this line.
             auto& inlineBox = lineBox.inlineBoxForLayoutBox(inlineLevelBox);
             inlineBox.setLogicalWidth(run.logicalRight() - inlineBox.logicalLeft());
-        } else if (run.isText() || run.isLineBreak()) {
+        } else if (run.isText() || run.isSoftLineBreak()) {
             auto& parentBox = inlineLevelBox.parent();
             auto& parentInlineBox = &parentBox == &rootBox() ? lineBox.rootInlineBox() : lineBox.inlineBoxForLayoutBox(parentBox);
             if (parentInlineBox.isEmpty()) {
@@ -269,7 +268,15 @@
                 parentInlineBox.setIsNonEmpty();
                 adjustVerticalGeometryForNonEmptyInlineBox(parentInlineBox);
             }
-        }
+        } else if (run.isHardLineBreak()) {
+            auto inlineBox = LineBox::InlineBox::createBoxForInlineBox(inlineLevelBox, logicalLeft, { });
+            inlineBox->setIsNonEmpty();
+            adjustVerticalGeometryForNonEmptyInlineBox(*inlineBox);
+            lineBox.addInlineBox(WTFMove(inlineBox));
+        } else if (run.isWordBreakOpportunity())
+            lineBox.addInlineBox(LineBox::InlineBox::createBoxForInlineBox(inlineLevelBox, logicalLeft, { }));
+        else
+            ASSERT_NOT_REACHED();
     }
 }
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLine.h (267656 => 267657)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.h	2020-09-27 12:55:58 UTC (rev 267656)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.h	2020-09-27 13:03:29 UTC (rev 267657)
@@ -65,7 +65,9 @@
     struct Run {
         bool isText() const { return m_type == InlineItem::Type::Text; }
         bool isBox() const { return m_type == InlineItem::Type::Box; }
-        bool isLineBreak() const { return m_type == InlineItem::Type::HardLineBreak || m_type == InlineItem::Type::SoftLineBreak; }
+        bool isLineBreak() const { return isHardLineBreak() || isSoftLineBreak(); }
+        bool isSoftLineBreak() const  { return m_type == InlineItem::Type::SoftLineBreak; }
+        bool isHardLineBreak() const { return m_type == InlineItem::Type::HardLineBreak; }
         bool isWordBreakOpportunity() const { return m_type == InlineItem::Type::WordBreakOpportunity; }
         bool isContainerStart() const { return m_type == InlineItem::Type::ContainerStart; }
         bool isContainerEnd() const { return m_type == InlineItem::Type::ContainerEnd; }

Modified: trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp (267656 => 267657)


--- trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp	2020-09-27 12:55:58 UTC (rev 267656)
+++ trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp	2020-09-27 13:03:29 UTC (rev 267657)
@@ -124,7 +124,7 @@
                 // the padding box to vertically align the table cell content.
                 auto& formattingState = layoutState().establishedFormattingState(cellBox);
                 for (auto* child = cellBox.firstInFlowOrFloatingChild(); child; child = child->nextInFlowOrFloatingSibling()) {
-                    if (child->isAnonymous() || child->isLineBreakBox())
+                    if (child->isInlineTextBox())
                         continue;
                     formattingState.boxGeometry(*child).moveVertically(intrinsicPaddingTop);
                 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to