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

Changeset 281680 in webkit


Ignore:
Timestamp:
Aug 26, 2021, 8:08:57 PM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][Integration] Use the line runs to check for legacy integral positioning
https://bugs.webkit.org/show_bug.cgi?id=228069
<rdar://problem/81087857>

Reviewed by Antti Koivisto.

Now that the line runs list has all the inline boxes (including spanning inline boxes), we
can use this list to check for legacy integral positioning and not directly iterating the LineBox's non-rootinlinebox list.
While this may be a bit more expensive, the legacy positioning is temporary and will be removed shortly.

This is in preparation for keeping the inline box structure private to the layout code.

  • layout/integration/LayoutIntegrationInlineContentBuilder.cpp:

(WebCore::LayoutIntegration::InlineContentBuilder::build const):
(WebCore::LayoutIntegration::InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns const):

  • layout/integration/LayoutIntegrationInlineContentBuilder.h:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r281662 r281680  
     12021-08-26  Alan Bujtas  <zalan@apple.com>
     2
     3        [LFC][Integration] Use the line runs to check for legacy integral positioning
     4        https://bugs.webkit.org/show_bug.cgi?id=228069
     5        <rdar://problem/81087857>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Now that the line runs list has all the inline boxes (including spanning inline boxes), we
     10        can use this list to check for legacy integral positioning and not directly iterating the LineBox's non-rootinlinebox list.
     11        While this may be a bit more expensive, the legacy positioning is temporary and will be removed shortly.
     12
     13        This is in preparation for keeping the inline box structure private to the layout code.
     14
     15        * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
     16        (WebCore::LayoutIntegration::InlineContentBuilder::build const):
     17        (WebCore::LayoutIntegration::InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns const):
     18        * layout/integration/LayoutIntegrationInlineContentBuilder.h:
     19
    1202021-08-26  Alan Bujtas  <zalan@apple.com>
    221
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp

    r281575 r281680  
    623623                    // Only hard linebreaks have associated layout boxes.
    624624                    auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
    625                     formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreak, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
     625                    formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreakBox, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
    626626
    627627                    auto& boxGeometry = formattingState.boxGeometry(layoutBox);
     
    630630                    boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
    631631                } else
    632                     formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreak, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
     632                    formattingState.addLineRun({ lineIndex, LineRun::Type::SoftLineBreak, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
    633633                continue;
    634634            }
     
    651651                auto& boxGeometry = formattingState.boxGeometry(layoutBox);
    652652                auto inlineBoxLogicalRect = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
    653                 formattingState.addLineRun({ lineIndex, LineRun::Type::InlineBox, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
     653                formattingState.addLineRun({ lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
    654654                inlineBoxStartSet.add(&layoutBox);
    655655                continue;
     
    686686            }
    687687            // Middle or end of the inline box. Let's stretch the box as needed.
    688             formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::InlineBox, layoutBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
     688            formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
    689689
    690690            auto enclosingBorderBoxRect = BoxGeometry::borderBoxRect(boxGeometry);
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h

    r281575 r281680  
    6262    enum class Type {
    6363        Text,
    64         LineBreak,
     64        SoftLineBreak,
     65        LineBreakBox,
    6566        AtomicInlineLevelBox,
    66         InlineBox,
     67        NonRootInlineBox,
    6768        RootInlineBox,
    6869        GenericInlineLevelBox
     
    7273
    7374    bool isText() const { return m_type == Type::Text; }
    74     bool isLineBreak() const { return m_type == Type::LineBreak; }
     75    bool isSoftLineBreak() const { return m_type == Type::SoftLineBreak; }
     76    bool isLineBreakBox() const { return m_type == Type::LineBreakBox; }
     77    bool isLineBreak() const { return isSoftLineBreak() || isLineBreakBox(); }
    7578    bool isAtomicInlineLevelBox() const { return m_type == Type::AtomicInlineLevelBox; }
    76     bool isInlineBox() const { return m_type == Type::InlineBox || isRootInlineBox(); }
     79    bool isInlineBox() const { return isNonRootInlineBox() || isRootInlineBox(); }
     80    bool isNonRootInlineBox() const { return m_type == Type::NonRootInlineBox; }
    7781    bool isRootInlineBox() const { return m_type == Type::RootInlineBox; }
     82    bool isGenericInlineLevelBox() const { return m_type == Type::GenericInlineLevelBox; }
     83    bool isInlineLevelBox() const { return isAtomicInlineLevelBox() || isLineBreakBox() || isInlineBox() || isGenericInlineLevelBox(); }
     84    bool isNonRootInlineLevelBox() const { return isInlineLevelBox() && !isRootInlineBox(); }
    7885    Type type() const { return m_type; }
    7986
  • trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp

    r281575 r281680  
    165165void InlineContentBuilder::build(const Layout::InlineFormattingState& inlineFormattingState, InlineContent& inlineContent) const
    166166{
    167     auto lineLevelVisualAdjustmentsForRuns = computeLineLevelVisualAdjustmentsForRuns(inlineFormattingState);
     167    auto lineLevelVisualAdjustmentsForRuns = computeLineLevelVisualAdjustmentsForRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns());
    168168    createDisplayLineRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns(), inlineContent, lineLevelVisualAdjustmentsForRuns);
    169169    createDisplayLines(inlineFormattingState.lines(), inlineContent, lineLevelVisualAdjustmentsForRuns);
    170170}
    171171
    172 InlineContentBuilder::LineLevelVisualAdjustmentsForRunsList InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineFormattingState& inlineFormattingState) const
    173 {
    174     auto& lines = inlineFormattingState.lines();
     172InlineContentBuilder::LineLevelVisualAdjustmentsForRunsList InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineLines& lines, const Layout::InlineLineRuns& lineRuns) const
     173{
     174    auto lineLevelVisualAdjustmentsForRuns = LineLevelVisualAdjustmentsForRunsList { lines.size() };
    175175    auto& rootStyle = m_layoutState.root().style();
     176
     177    auto inlineLevelBoxPreventsIntegralPosition = std::optional<bool> { };
     178    size_t lineIndexToCheck = 0;
     179    for (auto& lineRun : lineRuns) {
     180        auto lineIndex = lineRun.lineIndex();
     181        auto& layoutBox = lineRun.layoutBox();
     182
     183        if (lineIndexToCheck != lineIndex) {
     184            auto lineNeedsIntegralPositioning = [&] {
     185                if (!inlineLevelBoxPreventsIntegralPosition.has_value()) {
     186                    // This line does not have any non-root inline boxes.
     187                    // Lines like this with root inline box only force integral positioning.
     188                    return true;
     189                }
     190                return !*inlineLevelBoxPreventsIntegralPosition;
     191            };
     192            lineLevelVisualAdjustmentsForRuns[lineIndexToCheck].needsIntegralPosition = lineNeedsIntegralPositioning();
     193            lineIndexToCheck = lineIndex;
     194            inlineLevelBoxPreventsIntegralPosition = { };
     195        }
     196
     197        if (!lineRun.isNonRootInlineLevelBox() || (inlineLevelBoxPreventsIntegralPosition.has_value() && *inlineLevelBoxPreventsIntegralPosition))
     198            continue;
     199
     200        auto inlineLevelBoxPreventsLegacyIntegralVerticalPosition = [&] {
     201            ASSERT(lineRun.isNonRootInlineLevelBox());
     202            // Legacy inline tree integral rounds the vertical position for certain content (see LegacyInlineFlowBox::placeBoxesInBlockDirection and ::addToLine).
     203            // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
     204            auto contentPreventsIntegralSnapping = lineRun.isAtomicInlineLevelBox() || (lineRun.isLineBreakBox() && !m_layoutState.inStandardsMode());
     205            if (contentPreventsIntegralSnapping)
     206                return true;
     207
     208            auto& inlineLevelBoxStyle = layoutBox.style();
     209            auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineLevelBoxStyle.lineHeight() || inlineLevelBoxStyle.verticalAlign() != VerticalAlign::Baseline;
     210            if (stylePreventsIntegralSnapping)
     211                return true;
     212
     213            auto& rootFontMetrics = rootStyle.fontCascade().fontMetrics();
     214            auto& inlineLevelBoxFontMetrics = inlineLevelBoxStyle.fontCascade().fontMetrics();
     215            auto fontPreventsIntegralSnapping = !rootFontMetrics.hasIdenticalAscentDescentAndLineGap(inlineLevelBoxFontMetrics);
     216            return fontPreventsIntegralSnapping;
     217        };
     218        inlineLevelBoxPreventsIntegralPosition = inlineLevelBoxPreventsLegacyIntegralVerticalPosition();
     219    }
     220    lineLevelVisualAdjustmentsForRuns[lineIndexToCheck].needsIntegralPosition = !inlineLevelBoxPreventsIntegralPosition.has_value() || !*inlineLevelBoxPreventsIntegralPosition;
     221
    176222    auto shouldCheckHorizontalOverflowForContentReplacement = rootStyle.overflowX() == Overflow::Hidden && rootStyle.textOverflow() != TextOverflow::Clip;
    177 
    178     auto lineLevelVisualAdjustmentsForRuns = LineLevelVisualAdjustmentsForRunsList { lines.size() };
     223    if (!shouldCheckHorizontalOverflowForContentReplacement)
     224        return lineLevelVisualAdjustmentsForRuns;
     225
    179226    for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) {
    180         auto lineNeedsLegacyIntegralVerticalPosition = [&] {
    181             // Legacy inline tree integral rounds the vertical position for certain content (see LegacyInlineFlowBox::placeBoxesInBlockDirection and ::addToLine).
    182             auto& nonRootInlineLevelBoxList = inlineFormattingState.lineBoxes()[lineIndex].nonRootInlineLevelBoxes();
    183             if (nonRootInlineLevelBoxList.isEmpty()) {
    184                 // This is text content only with root inline box.
    185                 return true;
    186             }
    187             for (auto& inlineLevelBox : nonRootInlineLevelBoxList) {
    188                 // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
    189                 auto contentPreventsIntegralSnapping = inlineLevelBox.isAtomicInlineLevelBox() || (inlineLevelBox.isLineBreakBox() && !m_layoutState.inStandardsMode());
    190                 if (contentPreventsIntegralSnapping)
    191                     return false;
    192 
    193                 auto& inlineLevelBoxStyle = inlineLevelBox.style();
    194                 auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineLevelBoxStyle.lineHeight() || inlineLevelBoxStyle.verticalAlign() != VerticalAlign::Baseline;
    195                 if (stylePreventsIntegralSnapping)
    196                     return false;
    197 
    198                 auto& rootFontMetrics = rootStyle.fontCascade().fontMetrics();
    199                 auto& inlineLevelBoxFontMetrics = inlineLevelBoxStyle.fontCascade().fontMetrics();
    200                 auto fontPreventsIntegralSnapping = !rootFontMetrics.hasIdenticalAscentDescentAndLineGap(inlineLevelBoxFontMetrics);
    201                 if (fontPreventsIntegralSnapping)
    202                     return false;
    203             }
    204             return true;
    205         };
    206         lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition = lineNeedsLegacyIntegralVerticalPosition();
    207         if (shouldCheckHorizontalOverflowForContentReplacement) {
    208             auto& line = lines[lineIndex];
    209             auto lineBoxLogicalWidth = line.lineBoxLogicalRect().width();
    210             auto overflowWidth = lineOverflowWidth(m_blockFlow, lineBoxLogicalWidth, line.contentLogicalWidth());
    211             lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement = overflowWidth > lineBoxLogicalWidth;
    212         }
     227        auto& line = lines[lineIndex];
     228        auto lineBoxLogicalWidth = line.lineBoxLogicalRect().width();
     229        auto overflowWidth = lineOverflowWidth(m_blockFlow, lineBoxLogicalWidth, line.contentLogicalWidth());
     230        lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement = overflowWidth > lineBoxLogicalWidth;
    213231    }
    214232    return lineLevelVisualAdjustmentsForRuns;
  • trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h

    r281575 r281680  
    5050    using LineLevelVisualAdjustmentsForRunsList = Vector<LineLevelVisualAdjustmentsForRuns>;
    5151
    52     LineLevelVisualAdjustmentsForRunsList computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineFormattingState&) const;
     52    LineLevelVisualAdjustmentsForRunsList computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineLines&, const Layout::InlineLineRuns&) const;
    5353    void createDisplayLineRuns(const Layout::InlineLines&, const Layout::InlineLineRuns&, InlineContent&, const LineLevelVisualAdjustmentsForRunsList&) const;
    5454    void createDisplayLines(const Layout::InlineLines&, InlineContent&, const LineLevelVisualAdjustmentsForRunsList&) const;
Note: See TracChangeset for help on using the changeset viewer.