Title: [281241] trunk
Revision
281241
Author
an...@apple.com
Date
2021-08-19 09:08:54 -0700 (Thu, 19 Aug 2021)

Log Message

TextDecorationPainter should not depend on LegacyInlineTextBox
https://bugs.webkit.org/show_bug.cgi?id=228814

Reviewed by Alan Bujtas.

Source/WebCore:

Use the inline iterator instead.

* layout/integration/LayoutIntegrationLineIterator.h:
(WebCore::LayoutIntegration::LineIterator::isFirst const):
(WebCore::LayoutIntegration::PathLine::baselineType const):
* layout/integration/LayoutIntegrationLineIteratorLegacyPath.h:
(WebCore::LayoutIntegration::LineIteratorLegacyPath::baselineType const):
* layout/integration/LayoutIntegrationLineIteratorModernPath.h:
(WebCore::LayoutIntegration::LineIteratorModernPath::baselineType const):
* layout/integration/LayoutIntegrationRunIterator.cpp:
(WebCore::LayoutIntegration::RunIterator::line const):
(WebCore::LayoutIntegration::PathRun::line const):
(WebCore::LayoutIntegration::PathRun::style const):
(WebCore::LayoutIntegration::textRunFor):
* layout/integration/LayoutIntegrationRunIterator.h:
(WebCore::LayoutIntegration::PathTextRun::renderer const):
* layout/integration/LayoutIntegrationRunIteratorModernPath.h:
* rendering/LegacyInlineFlowBox.cpp:
(WebCore::LegacyInlineFlowBox::maxLogicalBottomForTextDecorationLine const): Deleted.
(WebCore::LegacyInlineFlowBox::minLogicalTopForTextDecorationLine const): Deleted.
* rendering/LegacyInlineFlowBox.h:
* rendering/LegacyInlineTextBox.cpp:
(WebCore::LegacyInlineTextBox::paintMarkedTextDecoration):
* rendering/LegacyLineLayout.cpp:
(WebCore::setLogicalWidthForTextRun):
* rendering/RenderElement.cpp:
(WebCore::RenderElement::enclosingRendererWithTextDecoration const): Deleted.
* rendering/RenderElement.h:
* rendering/TextDecorationPainter.cpp:
(WebCore::TextDecorationPainter::paintTextDecoration):
* rendering/TextDecorationPainter.h:
(WebCore::TextDecorationPainter::setTextRunIterator):
(WebCore::TextDecorationPainter::setInlineTextBox): Deleted.
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeAffectsVisualOverflow const):
* style/InlineTextBoxStyle.cpp:
(WebCore::isAncestorAndWithinBlock):
(WebCore::minLogicalTopForTextDecorationLine):
(WebCore::maxLogicalBottomForTextDecorationLine):

Moved from LegacyInlineFlowBox.

(WebCore::enclosingRendererWithTextDecoration):

Moved from RenderElement.

(WebCore::computeUnderlineOffset):
(WebCore::visualOverflowForDecorations):
* style/InlineTextBoxStyle.h:

LayoutTests:

Fix the expected results to not depend on inline culling (which this patch ignores).

* fast/text/text-underline-first-line-decoration-expected.html:
* fast/text/text-underline-vertical-first-line-decoration-expected.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (281240 => 281241)


--- trunk/LayoutTests/ChangeLog	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/LayoutTests/ChangeLog	2021-08-19 16:08:54 UTC (rev 281241)
@@ -1,3 +1,15 @@
+2021-08-19  Antti Koivisto  <an...@apple.com>
+
+        TextDecorationPainter should not depend on LegacyInlineTextBox
+        https://bugs.webkit.org/show_bug.cgi?id=228814
+
+        Reviewed by Alan Bujtas.
+
+        Fix the expected results to not depend on inline culling (which this patch ignores).
+
+        * fast/text/text-underline-first-line-decoration-expected.html:
+        * fast/text/text-underline-vertical-first-line-decoration-expected.html:
+
 2021-08-19  Ayumi Kojima  <ayumi_koj...@apple.com>
 
         [ Win EWS ] fast/forms/* tests are flaky crashing FAULTING_IP:  WebKit!WebCore::FontCache::lastResortFallbackFont+ec [C:\cygwin\home\buildbot\worker\Windows-EWS\build\Source\WebCore\platform\graphics\win\FontCacheWin.cpp @ 424].

Modified: trunk/LayoutTests/fast/text/text-underline-first-line-decoration-expected.html (281240 => 281241)


--- trunk/LayoutTests/fast/text/text-underline-first-line-decoration-expected.html	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/LayoutTests/fast/text/text-underline-first-line-decoration-expected.html	2021-08-19 16:08:54 UTC (rev 281241)
@@ -8,6 +8,6 @@
 </p>
 
 <p class="decorate" style="font-size:24px; float:left;-webkit-text-underline-position:under; border:1px dotted orange">
-<span style="text-decoration:underline">The first line <span style="vertical-align:-20px">has a decoration,</span> but not </span><img style="vertical-align:-100px; height:20px;width:20px;background-color:lime"><span style="text-decoration:underline"> under the image.</span><br>
+<span style="text-decoration:underline">The first line <span style="vertical-align:-20px">has a decoration,</span> but not </span><img style="vertical-align:-100px; height:20px;width:20px;background-color:lime"><span style="text-decoration:underline"> under the image.<span style="vertical-align:-20px">&ZeroWidthSpace;</span></span><br>
 The second line should not.
 </p>

Modified: trunk/LayoutTests/fast/text/text-underline-vertical-first-line-decoration-expected.html (281240 => 281241)


--- trunk/LayoutTests/fast/text/text-underline-vertical-first-line-decoration-expected.html	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/LayoutTests/fast/text/text-underline-vertical-first-line-decoration-expected.html	2021-08-19 16:08:54 UTC (rev 281241)
@@ -8,11 +8,11 @@
 </p>
 
 <p class="decorate" style="-webkit-writing-mode:vertical-lr; margin-right:10px; font-size:24px; float:left;-webkit-text-underline-position:under; border:1px dotted orange">
-<span style="text-decoration:underline">The first line <span style="vertical-align:-20px">has a decoration,</span> but not </span><img style="vertical-align:-100px; height:20px;width:20px;background-color:lime"><span style="text-decoration:underline"> under the image.</span><br>
+<span style="text-decoration:underline">The first line <span style="vertical-align:-20px">has a decoration,</span> but not </span><img style="vertical-align:-100px; height:20px;width:20px;background-color:lime"><span style="text-decoration:underline"> under the image.<span style="vertical-align:-20px">&ZeroWidthSpace;</span></span><br>
 The second line should not.
 </p>
 
 <p class="decorate" style="-webkit-writing-mode:vertical-rl; margin-right:10px; font-size:24px; float:left;-webkit-text-underline-position:under; border:1px dotted orange">
-<span style="text-decoration:underline">The first line <span style="vertical-align:-20px">has a decoration,</span> but not </span><img style="vertical-align:-100px; height:20px;width:20px;background-color:lime"><span style="text-decoration:underline"> under the image.</span><br>
+<span style="text-decoration:underline">The first line <span style="vertical-align:-20px">has a decoration,</span> but not </span><img style="vertical-align:-100px; height:20px;width:20px;background-color:lime"><span style="text-decoration:underline"> under the image.<span style="vertical-align:-20px">&ZeroWidthSpace;</span></span><br>
 The second line should not.
 </p>

Modified: trunk/Source/WebCore/ChangeLog (281240 => 281241)


--- trunk/Source/WebCore/ChangeLog	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/ChangeLog	2021-08-19 16:08:54 UTC (rev 281241)
@@ -1,5 +1,62 @@
 2021-08-19  Antti Koivisto  <an...@apple.com>
 
+        TextDecorationPainter should not depend on LegacyInlineTextBox
+        https://bugs.webkit.org/show_bug.cgi?id=228814
+
+        Reviewed by Alan Bujtas.
+
+        Use the inline iterator instead.
+
+        * layout/integration/LayoutIntegrationLineIterator.h:
+        (WebCore::LayoutIntegration::LineIterator::isFirst const):
+        (WebCore::LayoutIntegration::PathLine::baselineType const):
+        * layout/integration/LayoutIntegrationLineIteratorLegacyPath.h:
+        (WebCore::LayoutIntegration::LineIteratorLegacyPath::baselineType const):
+        * layout/integration/LayoutIntegrationLineIteratorModernPath.h:
+        (WebCore::LayoutIntegration::LineIteratorModernPath::baselineType const):
+        * layout/integration/LayoutIntegrationRunIterator.cpp:
+        (WebCore::LayoutIntegration::RunIterator::line const):
+        (WebCore::LayoutIntegration::PathRun::line const):
+        (WebCore::LayoutIntegration::PathRun::style const):
+        (WebCore::LayoutIntegration::textRunFor):
+        * layout/integration/LayoutIntegrationRunIterator.h:
+        (WebCore::LayoutIntegration::PathTextRun::renderer const):
+        * layout/integration/LayoutIntegrationRunIteratorModernPath.h:
+        * rendering/LegacyInlineFlowBox.cpp:
+        (WebCore::LegacyInlineFlowBox::maxLogicalBottomForTextDecorationLine const): Deleted.
+        (WebCore::LegacyInlineFlowBox::minLogicalTopForTextDecorationLine const): Deleted.
+        * rendering/LegacyInlineFlowBox.h:
+        * rendering/LegacyInlineTextBox.cpp:
+        (WebCore::LegacyInlineTextBox::paintMarkedTextDecoration):
+        * rendering/LegacyLineLayout.cpp:
+        (WebCore::setLogicalWidthForTextRun):
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::enclosingRendererWithTextDecoration const): Deleted.
+        * rendering/RenderElement.h:
+        * rendering/TextDecorationPainter.cpp:
+        (WebCore::TextDecorationPainter::paintTextDecoration):
+        * rendering/TextDecorationPainter.h:
+        (WebCore::TextDecorationPainter::setTextRunIterator):
+        (WebCore::TextDecorationPainter::setInlineTextBox): Deleted.
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::changeAffectsVisualOverflow const):
+        * style/InlineTextBoxStyle.cpp:
+        (WebCore::isAncestorAndWithinBlock):
+        (WebCore::minLogicalTopForTextDecorationLine):
+        (WebCore::maxLogicalBottomForTextDecorationLine):
+
+        Moved from LegacyInlineFlowBox.
+
+        (WebCore::enclosingRendererWithTextDecoration):
+
+        Moved from RenderElement.
+
+        (WebCore::computeUnderlineOffset):
+        (WebCore::visualOverflowForDecorations):
+        * style/InlineTextBoxStyle.h:
+
+2021-08-19  Antti Koivisto  <an...@apple.com>
+
         Move MarkedTextStyle into StyledMarkedText scope
         https://bugs.webkit.org/show_bug.cgi?id=228956
 

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIterator.h (281240 => 281241)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIterator.h	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIterator.h	2021-08-19 16:08:54 UTC (rev 281241)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "FontBaseline.h"
 #include "LayoutIntegrationLineIteratorLegacyPath.h"
 #include "LayoutIntegrationLineIteratorModernPath.h"
 #include <wtf/Variant.h>
@@ -70,6 +71,8 @@
 
     bool isHorizontal() const;
 
+    FontBaseline baselineType() const;
+
     const RenderBlockFlow& containingBlock() const;
     const LegacyRootInlineBox* legacyRootInlineBox() const;
 
@@ -92,6 +95,8 @@
     LineIterator next() const;
     LineIterator previous() const;
 
+    bool isFirst() const { return !previous(); }
+
     explicit operator bool() const { return !atEnd(); }
 
     bool operator==(const LineIterator&) const;
@@ -224,6 +229,13 @@
     });
 }
 
+inline FontBaseline PathLine::baselineType() const
+{
+    return WTF::switchOn(m_pathVariant, [](const auto& path) {
+        return path.baselineType();
+    });
+}
+
 inline const RenderBlockFlow& PathLine::containingBlock() const
 {
     return WTF::switchOn(m_pathVariant, [](const auto& path) -> const RenderBlockFlow& {

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIteratorLegacyPath.h (281240 => 281241)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIteratorLegacyPath.h	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIteratorLegacyPath.h	2021-08-19 16:08:54 UTC (rev 281241)
@@ -57,6 +57,7 @@
     float contentLogicalRight() const { return m_rootInlineBox->logicalRight(); }
     float logicalHeight() const { return m_rootInlineBox->logicalHeight(); }
     bool isHorizontal() const { return m_rootInlineBox->isHorizontal(); }
+    FontBaseline baselineType() const { return m_rootInlineBox->baselineType(); }
 
     const RenderBlockFlow& containingBlock() const { return m_rootInlineBox->blockFlow(); }
     const LegacyRootInlineBox* legacyRootInlineBox() const { return m_rootInlineBox; }

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIteratorModernPath.h (281240 => 281241)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIteratorModernPath.h	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineIteratorModernPath.h	2021-08-19 16:08:54 UTC (rev 281241)
@@ -67,6 +67,7 @@
     float y() const { return lineBoxTop(); }
     float logicalHeight() const { return lineBoxBottom() - lineBoxTop(); }
     bool isHorizontal() const { return true; }
+    FontBaseline baselineType() const { return AlphabeticBaseline; }
 
     const RenderBlockFlow& containingBlock() const { return m_inlineContent->containingBlock(); }
     const LegacyRootInlineBox* legacyRootInlineBox() const { return nullptr; }

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIterator.cpp (281240 => 281241)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIterator.cpp	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIterator.cpp	2021-08-19 16:08:54 UTC (rev 281241)
@@ -74,7 +74,12 @@
 
 LineIterator RunIterator::line() const
 {
-    return WTF::switchOn(m_run.m_pathVariant, [](const RunIteratorLegacyPath& path) {
+    return m_run.line();
+}
+
+LineIterator PathRun::line() const
+{
+    return WTF::switchOn(m_pathVariant, [](const RunIteratorLegacyPath& path) {
         return LineIterator(LineIteratorLegacyPath(&path.rootInlineBox()));
     }
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
@@ -85,6 +90,11 @@
     );
 }
 
+const RenderStyle& PathRun::style() const
+{
+    return line().isFirst() ? renderer().firstLineStyle() : renderer().style();
+}
+
 TextRunIterator::TextRunIterator(PathRun::PathVariant&& pathVariant)
     : RunIterator(WTFMove(pathVariant))
 {
@@ -180,6 +190,11 @@
     return firstTextRunFor(text);
 }
 
+TextRunIterator textRunFor(const LegacyInlineTextBox* legacyInlineTextBox)
+{
+    return { RunIteratorLegacyPath { legacyInlineTextBox } };
+}
+
 TextRunRange textRunsFor(const RenderText& text)
 {
     return { firstTextRunFor(text) };

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIterator.h (281240 => 281241)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIterator.h	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIterator.h	2021-08-19 16:08:54 UTC (rev 281241)
@@ -34,6 +34,7 @@
 
 class RenderLineBreak;
 class RenderObject;
+class RenderStyle;
 class RenderText;
 
 namespace LayoutIntegration {
@@ -79,6 +80,7 @@
     bool isLeftToRightDirection() const { return direction() == TextDirection::LTR; }
 
     const RenderObject& renderer() const;
+    const RenderStyle& style() const;
 
     // For intermediate porting steps only.
     LegacyInlineBox* legacyInlineBox() const;
@@ -87,6 +89,8 @@
     friend class RunIterator;
     friend class TextRunIterator;
 
+    LineIterator line() const;
+
     // To help with debugging.
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
     const RunIteratorModernPath& modernPath() const;
@@ -113,6 +117,7 @@
     bool isSelectable(unsigned start, unsigned end) const;
     LayoutRect selectionRect(unsigned start, unsigned end) const;
 
+    const RenderText& renderer() const { return downcast<RenderText>(PathRun::renderer()); }
     LegacyInlineTextBox* legacyInlineBox() const { return downcast<LegacyInlineTextBox>(PathRun::legacyInlineBox()); }
 };
 
@@ -195,6 +200,7 @@
 
 TextRunIterator firstTextRunFor(const RenderText&);
 TextRunIterator firstTextRunInTextOrderFor(const RenderText&);
+TextRunIterator textRunFor(const LegacyInlineTextBox*);
 TextRunRange textRunsFor(const RenderText&);
 RunIterator runFor(const RenderLineBreak&);
 RunIterator runFor(const RenderBox&);

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIteratorModernPath.h (281240 => 281241)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIteratorModernPath.h	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationRunIteratorModernPath.h	2021-08-19 16:08:54 UTC (rev 281241)
@@ -202,6 +202,7 @@
     }
 
 private:
+    friend class PathRun;
     friend class RunIterator;
 
     TextBoxSelectableRange selectableRange() const

Modified: trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp (281240 => 281241)


--- trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp	2021-08-19 16:08:54 UTC (rev 281241)
@@ -798,48 +798,6 @@
     }
 }
 
-void LegacyInlineFlowBox::maxLogicalBottomForTextDecorationLine(float& maxLogicalBottom, const RenderElement* decorationRenderer, OptionSet<TextDecoration> textDecoration) const
-{
-    for (auto* child = firstChild(); child; child = child->nextOnLine()) {
-        if (child->renderer().isOutOfFlowPositioned())
-            continue; // Positioned placeholders don't affect calculations.
-        
-        if (!(child->lineStyle().textDecorationsInEffect() & textDecoration))
-            continue; // If the text decoration isn't in effect on the child, then it must be outside of |decorationRenderer|'s hierarchy.
-        
-        if (decorationRenderer && decorationRenderer->isRenderInline() && !isAncestorAndWithinBlock(downcast<RenderInline>(*decorationRenderer), &child->renderer()))
-            continue;
-        
-        if (is<LegacyInlineFlowBox>(*child))
-            downcast<LegacyInlineFlowBox>(*child).maxLogicalBottomForTextDecorationLine(maxLogicalBottom, decorationRenderer, textDecoration);
-        else {
-            if (child->isInlineTextBox() || child->lineStyle().textDecorationSkip().isEmpty())
-                maxLogicalBottom = std::max<float>(maxLogicalBottom, child->logicalBottom());
-        }
-    }
-}
-
-void LegacyInlineFlowBox::minLogicalTopForTextDecorationLine(float& minLogicalTop, const RenderElement* decorationRenderer, OptionSet<TextDecoration> textDecoration) const
-{
-    for (auto* child = firstChild(); child; child = child->nextOnLine()) {
-        if (child->renderer().isOutOfFlowPositioned())
-            continue; // Positioned placeholders don't affect calculations.
-        
-        if (!(child->lineStyle().textDecorationsInEffect() & textDecoration))
-            continue; // If the text decoration isn't in effect on the child, then it must be outside of |decorationRenderer|'s hierarchy.
-        
-        if (decorationRenderer && decorationRenderer->isRenderInline() && !isAncestorAndWithinBlock(downcast<RenderInline>(*decorationRenderer), &child->renderer()))
-            continue;
-        
-        if (is<LegacyInlineFlowBox>(*child))
-            downcast<LegacyInlineFlowBox>(*child).minLogicalTopForTextDecorationLine(minLogicalTop, decorationRenderer, textDecoration);
-        else {
-            if (child->isInlineTextBox() || child->lineStyle().textDecorationSkip().isEmpty())
-                minLogicalTop = std::min<float>(minLogicalTop, child->logicalTop());
-        }
-    }
-}
-
 void LegacyInlineFlowBox::flipLinesInBlockDirection(LayoutUnit lineTop, LayoutUnit lineBottom)
 {
     // Flip the box on the line such that the top is now relative to the lineBottom instead of the lineTop.

Modified: trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h (281240 => 281241)


--- trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/rendering/LegacyInlineFlowBox.h	2021-08-19 16:08:54 UTC (rev 281241)
@@ -296,9 +296,6 @@
 
     void computeReplacedAndTextLineTopAndBottom(LayoutUnit& lineTop, LayoutUnit& lineBottom) const;
 
-    void maxLogicalBottomForTextDecorationLine(float& maxLogicalBottom, const RenderElement* decorationRenderer, OptionSet<TextDecoration>) const;
-    void minLogicalTopForTextDecorationLine(float& minLogicalTop, const RenderElement* decorationRenderer, OptionSet<TextDecoration>) const;
-
 private:
     bool isInlineFlowBox() const final { return true; }
     void boxModelObject() const = delete;

Modified: trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp (281240 => 281241)


--- trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/rendering/LegacyInlineTextBox.cpp	2021-08-19 16:08:54 UTC (rev 281241)
@@ -872,7 +872,7 @@
     auto textDecorations = lineStyle().textDecorationsInEffect();
     textDecorations.add(TextDecorationPainter::textDecorationsInEffectForStyle(markedText.style.textDecorationStyles));
     TextDecorationPainter decorationPainter { context, textDecorations, renderer(), isFirstLine(), lineFont(), markedText.style.textDecorationStyles };
-    decorationPainter.setInlineTextBox(this);
+    decorationPainter.setTextRunIterator(LayoutIntegration::textRunFor(this));
     decorationPainter.setWidth(snappedSelectionRect.width());
     decorationPainter.setIsHorizontal(isHorizontal());
     if (markedText.style.textShadow) {

Modified: trunk/Source/WebCore/rendering/LegacyLineLayout.cpp (281240 => 281241)


--- trunk/Source/WebCore/rendering/LegacyLineLayout.cpp	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/rendering/LegacyLineLayout.cpp	2021-08-19 16:08:54 UTC (rev 281241)
@@ -32,6 +32,7 @@
 #include "HTMLParserIdioms.h"
 #include "InlineIterator.h"
 #include "InlineTextBoxStyle.h"
+#include "LayoutIntegrationRunIterator.h"
 #include "LegacyInlineElementBox.h"
 #include "LegacyInlineTextBox.h"
 #include "LineLayoutState.h"
@@ -546,7 +547,7 @@
 
     // Include text decoration visual overflow as part of the glyph overflow.
     if (!renderer.style().textDecorationsInEffect().isEmpty())
-        glyphOverflow.extendTo(visualOverflowForDecorations(run->box()->lineStyle(), downcast<LegacyInlineTextBox>(run->box())));
+        glyphOverflow.extendTo(visualOverflowForDecorations(run->box()->lineStyle(), LayoutIntegration::textRunFor(downcast<LegacyInlineTextBox>(run->box()))));
 
     if (!glyphOverflow.isEmpty()) {
         ASSERT(run->box()->behavesLikeText());

Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (281240 => 281241)


--- trunk/Source/WebCore/rendering/RenderElement.cpp	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp	2021-08-19 16:08:54 UTC (rev 281241)
@@ -1733,24 +1733,6 @@
     return absoluteAnchorRect(insideFixed);
 }
 
-const RenderElement* RenderElement::enclosingRendererWithTextDecoration(OptionSet<TextDecoration> textDecoration, bool firstLine) const
-{
-    const RenderElement* current = this;
-    do {
-        if (current->isRenderBlock())
-            return current;
-        if (!current->isRenderInline() || current->isRubyText())
-            return nullptr;
-        
-        const RenderStyle& styleToUse = firstLine ? current->firstLineStyle() : current->style();
-        if (styleToUse.textDecoration() & textDecoration)
-            return current;
-        current = current->parent();
-    } while (current && (!current->element() || (!is<HTMLAnchorElement>(*current->element()) && !current->element()->hasTagName(HTMLNames::fontTag))));
-
-    return current;
-}
-
 void RenderElement::drawLineForBoxSide(GraphicsContext& graphicsContext, const FloatRect& rect, BoxSide side, Color color, BorderStyle borderStyle, float adjacentWidth1, float adjacentWidth2, bool antialias) const
 {
     auto drawBorderRect = [&graphicsContext] (const FloatRect& rect)

Modified: trunk/Source/WebCore/rendering/RenderElement.h (281240 => 281241)


--- trunk/Source/WebCore/rendering/RenderElement.h	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/rendering/RenderElement.h	2021-08-19 16:08:54 UTC (rev 281241)
@@ -221,7 +221,6 @@
     bool hasCounterNodeMap() const { return m_hasCounterNodeMap; }
     void setHasCounterNodeMap(bool f) { m_hasCounterNodeMap = f; }
 
-    const RenderElement* enclosingRendererWithTextDecoration(OptionSet<TextDecoration>, bool firstLine) const;
     void drawLineForBoxSide(GraphicsContext&, const FloatRect&, BoxSide, Color, BorderStyle, float adjacentWidth1, float adjacentWidth2, bool antialias = false) const;
 
 #if ENABLE(TEXT_AUTOSIZING)

Modified: trunk/Source/WebCore/rendering/TextDecorationPainter.cpp (281240 => 281241)


--- trunk/Source/WebCore/rendering/TextDecorationPainter.cpp	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/rendering/TextDecorationPainter.cpp	2021-08-19 16:08:54 UTC (rev 281241)
@@ -288,7 +288,7 @@
         if (m_decorations.contains(TextDecoration::Underline)) {
             float textDecorationBaseFontSize = 16;
             auto defaultGap = m_lineStyle.computedFontSize() / textDecorationBaseFontSize;
-            float offset = computeUnderlineOffset(m_lineStyle.textUnderlinePosition(), m_lineStyle.textUnderlineOffset(), m_lineStyle.fontMetrics(), m_inlineTextBox, defaultGap);
+            float offset = computeUnderlineOffset(m_lineStyle.textUnderlinePosition(), m_lineStyle.textUnderlineOffset(), m_lineStyle.fontMetrics(), m_textRun, defaultGap);
             float wavyOffset = m_styles.underlineStyle == TextDecorationStyle::Wavy ? m_wavyOffset : 0;
             FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness));
             rect.move(0, offset + wavyOffset);

Modified: trunk/Source/WebCore/rendering/TextDecorationPainter.h (281240 => 281241)


--- trunk/Source/WebCore/rendering/TextDecorationPainter.h	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/rendering/TextDecorationPainter.h	2021-08-19 16:08:54 UTC (rev 281241)
@@ -24,6 +24,7 @@
 
 #include "Color.h"
 #include "FloatPoint.h"
+#include "LayoutIntegrationRunIterator.h"
 #include "RenderStyleConstants.h"
 #include <wtf/OptionSet.h>
 
@@ -45,7 +46,7 @@
     struct Styles;
     TextDecorationPainter(GraphicsContext&, OptionSet<TextDecoration> decorations, const RenderText&, bool isFirstLine, const FontCascade&, std::optional<Styles> = std::nullopt);
     
-    void setInlineTextBox(const LegacyInlineTextBox* inlineTextBox) { m_inlineTextBox = inlineTextBox; }
+    void setTextRunIterator(LayoutIntegration::TextRunIterator textRun) { m_textRun = textRun; }
     void setIsHorizontal(bool isHorizontal) { m_isHorizontal = isHorizontal; }
     void setWidth(float width) { m_width = width; }
     void setTextShadow(const ShadowData* textShadow) { m_shadow = textShadow; }
@@ -78,7 +79,7 @@
     bool m_isHorizontal { true };
     const ShadowData* m_shadow { nullptr };
     const FilterOperations* m_shadowColorFilter { nullptr };
-    const LegacyInlineTextBox* m_inlineTextBox { nullptr };
+    LayoutIntegration::TextRunIterator m_textRun;
     const FontCascade& m_font;
 
     Styles m_styles;

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (281240 => 281241)


--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2021-08-19 16:08:54 UTC (rev 281241)
@@ -638,7 +638,7 @@
         // is specified. We can take an early out here.
         if (textUnderlinePosition() == TextUnderlinePosition::Under || other.textUnderlinePosition() == TextUnderlinePosition::Under)
             return true;
-        return visualOverflowForDecorations(*this, nullptr) != visualOverflowForDecorations(other, nullptr);
+        return visualOverflowForDecorations(*this, { }) != visualOverflowForDecorations(other, { });
     }
 
     if (hasOutlineInVisualOverflow() != other.hasOutlineInVisualOverflow())

Modified: trunk/Source/WebCore/style/InlineTextBoxStyle.cpp (281240 => 281241)


--- trunk/Source/WebCore/style/InlineTextBoxStyle.cpp	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/style/InlineTextBoxStyle.cpp	2021-08-19 16:08:54 UTC (rev 281241)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc.  All rights reserved.
+ * Copyright (C) 2014-2021 Apple Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,13 +27,81 @@
 #include "InlineTextBoxStyle.h"
 
 #include "FontCascade.h"
+#include "HTMLAnchorElement.h"
+#include "HTMLNames.h"
+#include "LayoutIntegrationLineIterator.h"
+#include "LayoutIntegrationRunIterator.h"
 #include "LegacyInlineTextBox.h"
 #include "LegacyRootInlineBox.h"
+#include "RenderInline.h"
 #include "TextUnderlineOffset.h"
 
 namespace WebCore {
+
+static bool isAncestorAndWithinBlock(const RenderInline& ancestor, const RenderObject* child)
+{
+    const RenderObject* object = child;
+    while (object && (!object->isRenderBlock() || object->isInline())) {
+        if (object == &ancestor)
+            return true;
+        object = object->parent();
+    }
+    return false;
+}
+
+static void minLogicalTopForTextDecorationLine(const LayoutIntegration::LineIterator& line, float& minLogicalTop, const RenderElement* decorationRenderer, OptionSet<TextDecoration> textDecoration)
+{
+    for (auto run = line.firstRun(); run; run.traverseNextOnLine()) {
+        if (run->renderer().isOutOfFlowPositioned())
+            continue; // Positioned placeholders don't affect calculations.
+
+        if (!(run->style().textDecorationsInEffect() & textDecoration))
+            continue; // If the text decoration isn't in effect on the child, then it must be outside of |decorationRenderer|'s hierarchy.
+
+        if (decorationRenderer && decorationRenderer->isRenderInline() && !isAncestorAndWithinBlock(downcast<RenderInline>(*decorationRenderer), &run->renderer()))
+            continue;
+
+        if (run->isText() || run->style().textDecorationSkip().isEmpty())
+            minLogicalTop = std::min<float>(minLogicalTop, run->logicalTop());
+    }
+}
+
+static void maxLogicalBottomForTextDecorationLine(const LayoutIntegration::LineIterator& line, float& maxLogicalBottom, const RenderElement* decorationRenderer, OptionSet<TextDecoration> textDecoration)
+{
+    for (auto run = line.firstRun(); run; run.traverseNextOnLine()) {
+        if (run->renderer().isOutOfFlowPositioned())
+            continue; // Positioned placeholders don't affect calculations.
+
+        if (!(run->style().textDecorationsInEffect() & textDecoration))
+            continue; // If the text decoration isn't in effect on the child, then it must be outside of |decorationRenderer|'s hierarchy.
+
+        if (decorationRenderer && decorationRenderer->isRenderInline() && !isAncestorAndWithinBlock(downcast<RenderInline>(*decorationRenderer), &run->renderer()))
+            continue;
+
+        if (run->isText() || run->style().textDecorationSkip().isEmpty())
+            maxLogicalBottom = std::max<float>(maxLogicalBottom, run->logicalBottom());
+    }
+}
+
+static const RenderElement* enclosingRendererWithTextDecoration(const RenderText& renderer, OptionSet<TextDecoration> textDecoration, bool firstLine)
+{
+    const RenderElement* current = renderer.parent();
+    do {
+        if (current->isRenderBlock())
+            return current;
+        if (!current->isRenderInline() || current->isRubyText())
+            return nullptr;
+
+        const RenderStyle& styleToUse = firstLine ? current->firstLineStyle() : current->style();
+        if (styleToUse.textDecoration() & textDecoration)
+            return current;
+        current = current->parent();
+    } while (current && (!current->element() || (!is<HTMLAnchorElement>(*current->element()) && !current->element()->hasTagName(HTMLNames::fontTag))));
+
+    return current;
+}
     
-float computeUnderlineOffset(TextUnderlinePosition underlinePosition, TextUnderlineOffset underlineOffset, const FontMetrics& fontMetrics, const LegacyInlineTextBox* inlineTextBox, float defaultGap)
+float computeUnderlineOffset(TextUnderlinePosition underlinePosition, TextUnderlineOffset underlineOffset, const FontMetrics& fontMetrics, const LayoutIntegration::TextRunIterator& textRun, float defaultGap)
 {
     // This represents the gap between the baseline and the closest edge of the underline.
     float gap = std::max<int>(1, std::ceil(defaultGap / 2.0f));
@@ -50,8 +118,8 @@
     
     auto resolvedUnderlinePosition = underlinePosition;
     if (resolvedUnderlinePosition == TextUnderlinePosition::Auto && underlineOffset.isAuto()) {
-        if (inlineTextBox)
-            resolvedUnderlinePosition = inlineTextBox->root().baselineType() == IdeographicBaseline ? TextUnderlinePosition::Under : TextUnderlinePosition::Auto;
+        if (textRun)
+            resolvedUnderlinePosition = textRun.line()->baselineType() == IdeographicBaseline ? TextUnderlinePosition::Under : TextUnderlinePosition::Auto;
         else
             resolvedUnderlinePosition = TextUnderlinePosition::Auto;
     }
@@ -64,22 +132,22 @@
     case TextUnderlinePosition::FromFont:
         return fontMetrics.ascent() + fontMetrics.underlinePosition() + underlineOffset.lengthOr(0);
     case TextUnderlinePosition::Under: {
-        ASSERT(inlineTextBox);
+        ASSERT(textRun);
         // Position underline relative to the bottom edge of the lowest element's content box.
-        const LegacyRootInlineBox& rootBox = inlineTextBox->root();
-        const RenderElement* decorationRenderer = inlineTextBox->parent()->renderer().enclosingRendererWithTextDecoration(TextDecoration::Underline, inlineTextBox->isFirstLine());
+        auto line = textRun.line();
+        auto* decorationRenderer = enclosingRendererWithTextDecoration(textRun->renderer(), TextDecoration::Underline, line.isFirst());
         
         float offset;
-        if (inlineTextBox->renderer().style().isFlippedLinesWritingMode()) {
-            offset = inlineTextBox->logicalTop();
-            rootBox.minLogicalTopForTextDecorationLine(offset, decorationRenderer, TextDecoration::Underline);
-            offset = inlineTextBox->logicalTop() - offset;
+        if (textRun->renderer().style().isFlippedLinesWritingMode()) {
+            offset = textRun->logicalTop();
+            minLogicalTopForTextDecorationLine(line, offset, decorationRenderer, TextDecoration::Underline);
+            offset = textRun->logicalTop() - offset;
         } else {
-            offset = inlineTextBox->logicalBottom();
-            rootBox.maxLogicalBottomForTextDecorationLine(offset, decorationRenderer, TextDecoration::Underline);
-            offset -= inlineTextBox->logicalBottom();
+            offset = textRun->logicalBottom();
+            maxLogicalBottomForTextDecorationLine(line, offset, decorationRenderer, TextDecoration::Underline);
+            offset -= textRun->logicalBottom();
         }
-        auto desiredOffset = inlineTextBox->logicalHeight() + gap + std::max(offset, 0.0f) + underlineOffset.lengthOr(0);
+        auto desiredOffset = textRun->logicalHeight() + gap + std::max(offset, 0.0f) + underlineOffset.lengthOr(0);
         return std::max<float>(desiredOffset, fontMetrics.ascent());
     }
     }
@@ -97,9 +165,9 @@
     return result;
 }
 
-GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const LegacyInlineTextBox* inlineTextBox)
+GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const LayoutIntegration::TextRunIterator& textRun)
 {
-    ASSERT(!inlineTextBox || inlineTextBox->lineStyle() == lineStyle);
+    ASSERT(!textRun || textRun->style() == lineStyle);
     
     auto decoration = lineStyle.textDecorationsInEffect();
     if (decoration.isEmpty())
@@ -127,7 +195,7 @@
         int underlineOffset = 1;
         float textDecorationBaseFontSize = 16;
         auto defaultGap = lineStyle.computedFontSize() / textDecorationBaseFontSize;
-        underlineOffset += computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.textUnderlineOffset(), lineStyle.fontMetrics(), inlineTextBox, defaultGap);
+        underlineOffset += computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.textUnderlineOffset(), lineStyle.fontMetrics(), textRun, defaultGap);
         if (decorationStyle == TextDecorationStyle::Wavy) {
             overflowResult.extendBottom(underlineOffset + wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness - height);
             overflowResult.extendTop(-(underlineOffset + wavyOffset - wavyStrokeParameters.controlPointDistance - strokeThickness));

Modified: trunk/Source/WebCore/style/InlineTextBoxStyle.h (281240 => 281241)


--- trunk/Source/WebCore/style/InlineTextBoxStyle.h	2021-08-19 16:05:09 UTC (rev 281240)
+++ trunk/Source/WebCore/style/InlineTextBoxStyle.h	2021-08-19 16:08:54 UTC (rev 281241)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc.  All rights reserved.
+ * Copyright (C) 2014-2021 Apple Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "FontCascade.h"
+#include "LayoutIntegrationRunIterator.h"
 #include "RenderStyleConstants.h"
 
 namespace WebCore {
@@ -51,7 +52,7 @@
     float step { 0 };
 };
 WavyStrokeParameters getWavyStrokeParameters(float fontSize);
-GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const LegacyInlineTextBox*);
-float computeUnderlineOffset(TextUnderlinePosition, TextUnderlineOffset, const FontMetrics&, const LegacyInlineTextBox*, float textDecorationThickness);
+GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const LayoutIntegration::TextRunIterator&);
+float computeUnderlineOffset(TextUnderlinePosition, TextUnderlineOffset, const FontMetrics&, const LayoutIntegration::TextRunIterator&, float textDecorationThickness);
     
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to