Skip to content
Permalink
Browse files
Should be able to compute decoration overflow without InlineIterator:…
…:TextBoxIterator

https://bugs.webkit.org/show_bug.cgi?id=241490

Reviewed by Antti Koivisto.

This patch enables IFC codebase to compute visual overflow for decoration (even when TextBoxIterator is not available).

* Source/WebCore/rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeAffectsVisualOverflow const):
* Source/WebCore/style/InlineTextBoxStyle.cpp:
(WebCore::visualOverflowForDecorations):
* Source/WebCore/style/InlineTextBoxStyle.h:

Canonical link: https://commits.webkit.org/251461@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295455 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
alanbaradlay committed Jun 10, 2022
1 parent 4d8b4bc commit dc4feb5c1c28b94c39990286a3c4d20d7d35ab04
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 25 deletions.
@@ -685,7 +685,7 @@ inline bool RenderStyle::changeAffectsVisualOverflow(const RenderStyle& other) c
// is specified. We can take an early out here.
if (textUnderlinePosition() == TextUnderlinePosition::Under || other.textUnderlinePosition() == TextUnderlinePosition::Under)
return true;
return visualOverflowForDecorations(*this, { }) != visualOverflowForDecorations(other, { });
return visualOverflowForDecorations(*this) != visualOverflowForDecorations(other);
}

auto hasOutlineInVisualOverflow = this->hasOutlineInVisualOverflow();
@@ -172,22 +172,20 @@ WavyStrokeParameters getWavyStrokeParameters(float fontSize)
return result;
}

GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const InlineIterator::TextBoxIterator& textRun)
GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, std::optional<float> underlineOffset)
{
ASSERT(!textRun || textRun->style() == lineStyle);

auto decoration = lineStyle.textDecorationsInEffect();
if (decoration.isEmpty())
return GlyphOverflow();

float strokeThickness = lineStyle.textDecorationThickness().resolve(lineStyle.computedFontSize(), lineStyle.metricsOfPrimaryFont());
WavyStrokeParameters wavyStrokeParameters;
float wavyOffset = 0;

TextDecorationStyle decorationStyle = lineStyle.textDecorationStyle();
float height = lineStyle.fontCascade().metricsOfPrimaryFont().floatHeight();
GlyphOverflow overflowResult;

if (decorationStyle == TextDecorationStyle::Wavy) {
wavyStrokeParameters = getWavyStrokeParameters(lineStyle.computedFontPixelSize());
wavyOffset = wavyOffsetFromDecoration();
@@ -198,27 +196,13 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
// These metrics must match where underlines get drawn.
// FIXME: Share the code in TextDecorationPainter::paintBackgroundDecorations() so we can just query it for the painted geometry.
if (decoration & TextDecorationLine::Underline) {
// Compensate for the integral ceiling in GraphicsContext::computeLineBoundsAndAntialiasingModeForText()
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.
ASSERT(textRun || lineStyle.textUnderlinePosition() != TextUnderlinePosition::Under);
if (!textRun)
underlineOffset += computeUnderlineOffset({ lineStyle, defaultGap });
else {
underlineOffset += computeUnderlineOffset({ lineStyle
, defaultGap
, UnderlineOffsetArguments::TextUnderlinePositionUnder { textRun->lineBox()->baselineType(), textRun->logicalBottom() - textRun->logicalTop(), textRunLogicalOffsetFromLineBottom(textRun) }
});
}

ASSERT(underlineOffset);
if (decorationStyle == TextDecorationStyle::Wavy) {
overflowResult.extendBottom(underlineOffset + wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness - height);
overflowResult.extendTop(-(underlineOffset + wavyOffset - wavyStrokeParameters.controlPointDistance - strokeThickness));
overflowResult.extendBottom(*underlineOffset + wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness - height);
overflowResult.extendTop(-(*underlineOffset + wavyOffset - wavyStrokeParameters.controlPointDistance - strokeThickness));
} else {
overflowResult.extendBottom(underlineOffset + strokeThickness - height);
overflowResult.extendTop(-underlineOffset);
overflowResult.extendBottom(*underlineOffset + strokeThickness - height);
overflowResult.extendTop(-*underlineOffset);
}
}
if (decoration & TextDecorationLine::Overline) {
@@ -250,5 +234,34 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
}
return overflowResult;
}

GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const InlineIterator::TextBoxIterator& textRun)
{
ASSERT(!textRun || textRun->style() == lineStyle);

if (!lineStyle.textDecorationsInEffect().contains(TextDecorationLine::Underline))
return visualOverflowForDecorations(lineStyle, std::optional<float> { });

// Compensate for the integral ceiling in GraphicsContext::computeLineBoundsAndAntialiasingModeForText()
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.
ASSERT(textRun || lineStyle.textUnderlinePosition() != TextUnderlinePosition::Under);
if (!textRun)
underlineOffset += computeUnderlineOffset({ lineStyle, defaultGap });
else {
underlineOffset += computeUnderlineOffset({ lineStyle
, defaultGap
, UnderlineOffsetArguments::TextUnderlinePositionUnder { textRun->lineBox()->baselineType(), textRun->logicalBottom() - textRun->logicalTop(), textRunLogicalOffsetFromLineBottom(textRun) }
});
}
return visualOverflowForDecorations(lineStyle, underlineOffset);
}

GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle)
{
return visualOverflowForDecorations(lineStyle, InlineIterator::TextBoxIterator { });
}

}
@@ -53,7 +53,9 @@ struct WavyStrokeParameters {
float step { 0 };
};
WavyStrokeParameters getWavyStrokeParameters(float fontSize);
GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle);
GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const InlineIterator::TextBoxIterator&);
GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, std::optional<float> underlineOffset);

struct UnderlineOffsetArguments {
const RenderStyle& lineStyle;

0 comments on commit dc4feb5

Please sign in to comment.