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">​</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">​</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">​</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