Skip to content
Permalink
Browse files
computeUnderlineOffset should not take InlineIterator::LineBoxIterator
https://bugs.webkit.org/show_bug.cgi?id=241488

Reviewed by Antti Koivisto.

Let's precompute the text run's offset value so that we don't have to pass in a LineBoxIterator to computeUnderlineOffset.

* Source/WebCore/rendering/TextDecorationPainter.cpp:
(WebCore::TextDecorationPainter::paintBackgroundDecorations):
* Source/WebCore/style/InlineTextBoxStyle.cpp:
(WebCore::textRunLogicalOffsetFromLineBottom):
(WebCore::computeUnderlineOffset):
(WebCore::visualOverflowForDecorations):
* Source/WebCore/style/InlineTextBoxStyle.h:

Canonical link: https://commits.webkit.org/251459@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295453 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
alanbaradlay committed Jun 10, 2022
1 parent fee8624 commit 7fd49d14866d6156bf7cf8e66093baef07272025
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 35 deletions.
@@ -282,11 +282,10 @@ void TextDecorationPainter::paintBackgroundDecorations(const TextRun& textRun, c
auto defaultGap = m_lineStyle.computedFontSize() / textDecorationBaseFontSize;
float offset = computeUnderlineOffset({ m_lineStyle
, defaultGap
, &m_textBox->renderer()
, m_textBox->lineBox()->baselineType()
, m_textBox->logicalTop()
, m_textBox->logicalBottom()
, m_textBox->lineBox()
, UnderlineOffsetArguments::TextUnderlinePositionUnder { m_textBox->lineBox()->baselineType(),
m_textBox->logicalBottom() - m_textBox->logicalTop(),
textRunLogicalOffsetFromLineBottom(m_textBox)
}
});
float wavyOffset = m_styles.underlineStyle == TextDecorationStyle::Wavy ? m_wavyOffset : 0;
FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness));
@@ -103,7 +103,21 @@ static const RenderElement* enclosingRendererWithTextDecoration(const RenderText

return current;
}


float textRunLogicalOffsetFromLineBottom(const InlineIterator::TextBoxIterator& textRun)
{
float offset = 0.f;
auto* decorationRenderer = enclosingRendererWithTextDecoration(textRun->renderer(), TextDecorationLine::Underline, textRun->lineBox()->isFirst());
if (textRun->renderer().style().isFlippedLinesWritingMode()) {
auto minLogicalTop = minLogicalTopForTextDecorationLine(textRun->lineBox(), textRun->logicalTop(), decorationRenderer, TextDecorationLine::Underline);
offset = textRun->logicalTop() - minLogicalTop;
} else {
offset = maxLogicalBottomForTextDecorationLine(textRun->lineBox(), textRun->logicalBottom(), decorationRenderer, TextDecorationLine::Underline);
offset -= textRun->logicalBottom();
}
return offset;
}

float computeUnderlineOffset(const UnderlineOffsetArguments& context)
{
// This represents the gap between the baseline and the closest edge of the underline.
@@ -124,12 +138,12 @@ float computeUnderlineOffset(const UnderlineOffsetArguments& context)

auto resolvedUnderlinePosition = underlinePosition;
if (resolvedUnderlinePosition == TextUnderlinePosition::Auto && underlineOffset.isAuto()) {
if (context.renderer)
resolvedUnderlinePosition = context.baselineType == IdeographicBaseline ? TextUnderlinePosition::Under : TextUnderlinePosition::Auto;
if (context.textUnderlinePositionUnder)
resolvedUnderlinePosition = context.textUnderlinePositionUnder->baselineType == IdeographicBaseline ? TextUnderlinePosition::Under : TextUnderlinePosition::Auto;
else
resolvedUnderlinePosition = TextUnderlinePosition::Auto;
}

switch (resolvedUnderlinePosition) {
case TextUnderlinePosition::Auto:
if (underlineOffset.isAuto())
@@ -138,28 +152,17 @@ float computeUnderlineOffset(const UnderlineOffsetArguments& context)
case TextUnderlinePosition::FromFont:
return fontMetrics.ascent() + fontMetrics.underlinePosition() + underlineOffset.lengthOr(0);
case TextUnderlinePosition::Under: {
ASSERT(context.lineBox && context.renderer);
ASSERT(context.textUnderlinePositionUnder);
// Position underline relative to the bottom edge of the lowest element's content box.
auto* decorationRenderer = enclosingRendererWithTextDecoration(*context.renderer, TextDecorationLine::Underline, context.lineBox->isFirst());

float offset;
if (context.renderer->style().isFlippedLinesWritingMode()) {
auto minLogicalTop = minLogicalTopForTextDecorationLine(context.lineBox, context.textRunLogicalTop, decorationRenderer, TextDecorationLine::Underline);
offset = context.textRunLogicalTop - minLogicalTop;
} else {
offset = maxLogicalBottomForTextDecorationLine(context.lineBox, context.textRunLogicalBottom, decorationRenderer, TextDecorationLine::Underline);
offset -= context.textRunLogicalBottom;
}
auto textRunLogicalHeight = context.textRunLogicalBottom - context.textRunLogicalTop;
auto desiredOffset = textRunLogicalHeight + gap + std::max(offset, 0.0f) + underlineOffset.lengthOr(0);
auto desiredOffset = context.textUnderlinePositionUnder->textRunLogicalHeight + gap + std::max(context.textUnderlinePositionUnder->textRunOffsetFromLineBottom, 0.0f) + underlineOffset.lengthOr(0);
return std::max<float>(desiredOffset, fontMetrics.ascent());
}
}

ASSERT_NOT_REACHED();
return fontMetrics.ascent() + gap;
}

WavyStrokeParameters getWavyStrokeParameters(float fontSize)
{
WavyStrokeParameters result;
@@ -199,18 +202,14 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
int underlineOffset = 1;
float textDecorationBaseFontSize = 16;
auto defaultGap = lineStyle.computedFontSize() / textDecorationBaseFontSize;
// FIXME: RenderStyle calls us with empty textRun but only when TextUnderlinePosition is not Under.
// FIXME: RenderStyle calls us with empty textRun but only when TextUnderlinePosition is not Under.
ASSERT(textRun || lineStyle.textUnderlinePosition() != TextUnderlinePosition::Under);
if (!textRun)
underlineOffset += computeUnderlineOffset({ lineStyle, defaultGap });
else {
underlineOffset += computeUnderlineOffset({ lineStyle
, defaultGap
, &textRun->renderer()
, textRun->lineBox()->baselineType()
, textRun->logicalTop()
, textRun->logicalBottom()
, textRun->lineBox()
, UnderlineOffsetArguments::TextUnderlinePositionUnder { textRun->lineBox()->baselineType(), textRun->logicalBottom() - textRun->logicalTop(), textRunLogicalOffsetFromLineBottom(textRun) }
});
}

@@ -58,12 +58,14 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
struct UnderlineOffsetArguments {
const RenderStyle& lineStyle;
float defaultGap { 0 };
const RenderText* renderer { nullptr };
FontBaseline baselineType { AlphabeticBaseline };
float textRunLogicalTop { 0 };
float textRunLogicalBottom { 0 };
InlineIterator::LineBoxIterator lineBox { };
struct TextUnderlinePositionUnder {
FontBaseline baselineType { AlphabeticBaseline };
float textRunLogicalHeight { 0 };
float textRunOffsetFromLineBottom { 0 };
};
std::optional<TextUnderlinePositionUnder> textUnderlinePositionUnder { };
};
float computeUnderlineOffset(const UnderlineOffsetArguments&);

float textRunLogicalOffsetFromLineBottom(const InlineIterator::TextBoxIterator&);

} // namespace WebCore

0 comments on commit 7fd49d1

Please sign in to comment.