⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 267657 in webkit


Ignore:
Timestamp:
Sep 27, 2020, 6:03:29 AM (6 years ago)
Author:
Alan Bujtas
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.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r267654 r267657  
     12020-09-27  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Create inline boxes for hard line breaks(<br>) and word wrap opportunities (<wbr>)
     4        https://bugs.webkit.org/show_bug.cgi?id=217023
     5
     6        Reviewed by Antti Koivisto.
     7
     8        * fast/layoutformattingcontext/br-and-wbr-simple-expected.html: Added.
     9        * fast/layoutformattingcontext/br-and-wbr-simple.html: Added.
     10
    1112020-09-27  Rob Buis  <rbuis@igalia.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r267654 r267657  
     12020-09-27  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Create inline boxes for hard line breaks(<br>) and word wrap opportunities (<wbr>)
     4        https://bugs.webkit.org/show_bug.cgi?id=217023
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Both hard <br> and the word break opportunity layout boxes generate inline boxes and get computed box geometries.
     9        It enables us to answer questions like element.offsetTop/offsetLeft.
     10
     11        Test: fast/layoutformattingcontext/br-and-wbr-simple.html
     12
     13        * layout/FormattingState.cpp:
     14        (WebCore::Layout::FormattingState::boxGeometry):
     15        * layout/Verification.cpp:
     16        (WebCore::Layout::LayoutContext::verifyAndOutputMismatchingLayoutTree):
     17        * layout/inlineformatting/InlineFormattingContext.cpp:
     18        (WebCore::Layout::InlineFormattingContext::layoutInFlowContent):
     19        (WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthConstraints):
     20        (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
     21        * layout/inlineformatting/InlineFormattingContextGeometry.cpp:
     22        (WebCore::Layout::LineBoxBuilder::constructInlineBoxes):
     23        * layout/inlineformatting/InlineLine.h:
     24        (WebCore::Layout::Line::Run::isLineBreak const):
     25        (WebCore::Layout::Line::Run::isSoftLineBreak const):
     26        (WebCore::Layout::Line::Run::isHardLineBreak const):
     27        * layout/tableformatting/TableFormattingContext.cpp:
     28        (WebCore::Layout::TableFormattingContext::setUsedGeometryForCells):
     29
    1302020-09-27  Rob Buis  <rbuis@igalia.com>
    231
  • trunk/Source/WebCore/layout/FormattingState.cpp

    r267076 r267657  
    5353    // Should never need to mutate a display box outside of the formatting context.
    5454    ASSERT(&layoutState().establishedFormattingState(layoutBox.formattingContextRoot()) == this);
    55     // Anonymous text wrappers/line break boxes should not need display boxes.
    56     ASSERT(!layoutBox.isInlineTextBox() && (!layoutBox.isLineBreakBox() || layoutBox.isOutOfFlowPositioned()));
     55    // Anonymous text wrappers do not need display boxes.
     56    ASSERT(!layoutBox.isInlineTextBox());
    5757    return layoutState().ensureGeometryForBox(layoutBox);
    5858}
  • trunk/Source/WebCore/layout/Verification.cpp

    r267565 r267657  
    335335    TextStream stream;
    336336    auto& layoutRoot = layoutState.root();
    337     auto mismatchingGeometry = verifyAndOutputSubtree(stream, layoutState, rootRenderer, layoutRoot);
    338     if (!mismatchingGeometry)
    339         return;
    340337#if ENABLE(TREE_DEBUGGING)
    341338    showRenderTree(&rootRenderer);
    342339    showLayoutTree(layoutRoot, &layoutState);
    343340#endif
     341    auto mismatchingGeometry = verifyAndOutputSubtree(stream, layoutState, rootRenderer, layoutRoot);
     342    if (!mismatchingGeometry)
     343        return;
    344344    WTFLogAlways("%s", stream.release().utf8().data());
    345345    ASSERT_NOT_REACHED();
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp

    r267637 r267657  
    114114                computeHeightAndMargin(*layoutBox, constraints.horizontal);
    115115            }
     116        } else if (layoutBox->isLineBreakBox()) {
     117            auto& boxGeometry = formattingState().boxGeometry(*layoutBox);
     118            boxGeometry.setHorizontalMargin({ });
     119            boxGeometry.setBorder({ });
     120            boxGeometry.setPadding({ });
     121            boxGeometry.setContentBoxWidth({ });
     122            boxGeometry.setVerticalMargin({ });
    116123        } else if (layoutBox->isInlineBox()) {
    117             // Text wrapper boxes (anonymous inline level boxes) and <br>s don't have box geometries (they only generate runs).
    118             if (!layoutBox->isInlineTextBox() && !layoutBox->isLineBreakBox()) {
     124            // Text wrapper boxes (anonymous inline level boxes) don't have box geometries (they only generate runs).
     125            if (!layoutBox->isInlineTextBox()) {
    119126                // Inline boxes (<span>) can't get sized/positioned yet. At this point we can only compute their margins, borders and padding.
    120127                computeBorderAndPadding(*layoutBox, constraints.horizontal);
     
    207214    // In order to compute the max/min widths, we need to compute margins, borders and padding for certain inline boxes first.
    208215    while (layoutBox) {
    209         if (layoutBox->isInlineTextBox() || layoutBox->isLineBreakBox()) {
     216        if (layoutBox->isInlineTextBox()) {
    210217            layoutBox = nextInlineLevelBoxToLayout(*layoutBox, root());
    211218            continue;
     
    428435        // Create the inline runs on the current line. This is mostly text and atomic inline runs.
    429436        for (auto& lineRun : lineContent.runs) {
     437            // FIXME: We should not need to construct a line run for <br>.
    430438            if (lineRun.isText() || lineRun.isLineBreak())
    431439                formattingState.addLineRun({ lineIndex, lineRun.layoutBox(), lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
     
    461469                boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
    462470                continue;
     471            }
     472            if (layoutBox.isLineBreakBox()) {
     473                boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
     474                boxGeometry.setContentBoxHeight(toLayoutUnit(inlineBox->logicalHeight()));
    463475            }
    464476            auto marginBoxWidth = inlineBox->logicalWidth();
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp

    r267557 r267657  
    226226    for (auto& run : runs) {
    227227        auto& inlineLevelBox = run.layoutBox();
     228        auto logicalLeft = horizontalAligmentOffset + run.logicalLeft();
    228229        if (run.isBox()) {
    229             auto logicalLeft = horizontalAligmentOffset + run.logicalLeft();
    230230            auto& inlineLevelBoxGeometry = formattingContext().geometryForBox(inlineLevelBox);
    231231            auto logicalHeight = inlineLevelBoxGeometry.marginBoxHeight();
     
    254254            lineBox.addInlineBox(WTFMove(inlineBox));
    255255        } else if (run.isContainerStart()) {
    256             auto logicalLeft = horizontalAligmentOffset + run.logicalLeft();
    257256            auto initialLogicalWidth = lineBox.logicalWidth() - run.logicalLeft();
    258257            ASSERT(initialLogicalWidth >= 0);
     
    262261            auto& inlineBox = lineBox.inlineBoxForLayoutBox(inlineLevelBox);
    263262            inlineBox.setLogicalWidth(run.logicalRight() - inlineBox.logicalLeft());
    264         } else if (run.isText() || run.isLineBreak()) {
     263        } else if (run.isText() || run.isSoftLineBreak()) {
    265264            auto& parentBox = inlineLevelBox.parent();
    266265            auto& parentInlineBox = &parentBox == &rootBox() ? lineBox.rootInlineBox() : lineBox.inlineBoxForLayoutBox(parentBox);
     
    270269                adjustVerticalGeometryForNonEmptyInlineBox(parentInlineBox);
    271270            }
    272         }
     271        } else if (run.isHardLineBreak()) {
     272            auto inlineBox = LineBox::InlineBox::createBoxForInlineBox(inlineLevelBox, logicalLeft, { });
     273            inlineBox->setIsNonEmpty();
     274            adjustVerticalGeometryForNonEmptyInlineBox(*inlineBox);
     275            lineBox.addInlineBox(WTFMove(inlineBox));
     276        } else if (run.isWordBreakOpportunity())
     277            lineBox.addInlineBox(LineBox::InlineBox::createBoxForInlineBox(inlineLevelBox, logicalLeft, { }));
     278        else
     279            ASSERT_NOT_REACHED();
    273280    }
    274281}
  • trunk/Source/WebCore/layout/inlineformatting/InlineLine.h

    r267637 r267657  
    6666        bool isText() const { return m_type == InlineItem::Type::Text; }
    6767        bool isBox() const { return m_type == InlineItem::Type::Box; }
    68         bool isLineBreak() const { return m_type == InlineItem::Type::HardLineBreak || m_type == InlineItem::Type::SoftLineBreak; }
     68        bool isLineBreak() const { return isHardLineBreak() || isSoftLineBreak(); }
     69        bool isSoftLineBreak() const  { return m_type == InlineItem::Type::SoftLineBreak; }
     70        bool isHardLineBreak() const { return m_type == InlineItem::Type::HardLineBreak; }
    6971        bool isWordBreakOpportunity() const { return m_type == InlineItem::Type::WordBreakOpportunity; }
    7072        bool isContainerStart() const { return m_type == InlineItem::Type::ContainerStart; }
  • trunk/Source/WebCore/layout/tableformatting/TableFormattingContext.cpp

    r267325 r267657  
    125125                auto& formattingState = layoutState().establishedFormattingState(cellBox);
    126126                for (auto* child = cellBox.firstInFlowOrFloatingChild(); child; child = child->nextInFlowOrFloatingSibling()) {
    127                     if (child->isAnonymous() || child->isLineBreakBox())
     127                    if (child->isInlineTextBox())
    128128                        continue;
    129129                    formattingState.boxGeometry(*child).moveVertically(intrinsicPaddingTop);
Note: See TracChangeset for help on using the changeset viewer.