| Differences between
and this patch
- a/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp -1 / +1 lines
Lines 880-886 void InlineDisplayContentBuilder::collectInkOverflowForTextDecorations(DisplayBo a/Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp_sec1
880
            if (!logicalBottomForTextDecoration)
880
            if (!logicalBottomForTextDecoration)
881
                logicalBottomForTextDecoration = logicalBottomForTextDecorationContent(boxes, isHorizontalWritingMode);
881
                logicalBottomForTextDecoration = logicalBottomForTextDecorationContent(boxes, isHorizontalWritingMode);
882
            auto textRunLogicalOffsetFromLineBottom = *logicalBottomForTextDecoration - (isHorizontalWritingMode ? displayBox.bottom() : displayBox.right());
882
            auto textRunLogicalOffsetFromLineBottom = *logicalBottomForTextDecoration - (isHorizontalWritingMode ? displayBox.bottom() : displayBox.right());
883
            return visualOverflowForDecorations(style, { displayLine.baselineType(), displayBox.height(), textRunLogicalOffsetFromLineBottom });
883
            return visualOverflowForDecorations(style, displayLine.baselineType(), { displayBox.height(), textRunLogicalOffsetFromLineBottom });
884
        }();
884
        }();
885
885
886
        if (!decorationOverflow.isEmpty()) {
886
        if (!decorationOverflow.isEmpty()) {
- a/Source/WebCore/style/InlineTextBoxStyle.cpp -33 / +51 lines
Lines 39-44 namespace WebCore { a/Source/WebCore/style/InlineTextBoxStyle.cpp_sec1
39
39
40
struct UnderlineOffsetArguments {
40
struct UnderlineOffsetArguments {
41
    const RenderStyle& lineStyle;
41
    const RenderStyle& lineStyle;
42
    TextUnderlinePosition resolvedUnderlinePosition { TextUnderlinePosition::Auto };
42
    float defaultGap { 0 };
43
    float defaultGap { 0 };
43
    std::optional<TextUnderlinePositionUnder> textUnderlinePositionUnder { };
44
    std::optional<TextUnderlinePositionUnder> textUnderlinePositionUnder { };
44
};
45
};
Lines 130-140 static inline float defaultGap(const RenderStyle& style) a/Source/WebCore/style/InlineTextBoxStyle.cpp_sec2
130
    return style.computedFontSize() / textDecorationBaseFontSize;
131
    return style.computedFontSize() / textDecorationBaseFontSize;
131
}
132
}
132
133
133
static float computeUnderlineOffset(const UnderlineOffsetArguments& context)
134
static inline TextUnderlinePosition resolvedUnderlinePosition(const RenderStyle& decoratingBoxStyle, std::optional<FontBaseline> baselineType)
135
{
136
    auto underlinePosition = decoratingBoxStyle.textUnderlinePosition();
137
    if (underlinePosition == TextUnderlinePosition::Auto && decoratingBoxStyle.textUnderlineOffset().isAuto()) {
138
        if (baselineType)
139
            return *baselineType == IdeographicBaseline ? TextUnderlinePosition::Under : TextUnderlinePosition::Auto;
140
        return TextUnderlinePosition::Auto;
141
    }
142
    return underlinePosition;
143
}
144
145
static float computedUnderlineOffset(const UnderlineOffsetArguments& context)
134
{
146
{
135
    // This represents the gap between the baseline and the closest edge of the underline.
147
    // This represents the gap between the baseline and the closest edge of the underline.
136
    float gap = std::max<int>(1, std::ceil(context.defaultGap / 2.0f));
148
    auto gap = std::max(1.f, std::ceil(context.defaultGap / 2.f));
137
    
149
138
    // FIXME: The code for visual overflow detection passes in a null inline text box. This means it is now
150
    // FIXME: The code for visual overflow detection passes in a null inline text box. This means it is now
139
    // broken for the case where auto needs to behave like "under".
151
    // broken for the case where auto needs to behave like "under".
140
    
152
    
Lines 142-178 static float computeUnderlineOffset(const UnderlineOffsetArguments& context) a/Source/WebCore/style/InlineTextBoxStyle.cpp_sec3
142
    // scripts where it would not be appropriate (e.g., ideographs).
154
    // scripts where it would not be appropriate (e.g., ideographs).
143
    // Strictly speaking this can occur whenever the line contains ideographs
155
    // Strictly speaking this can occur whenever the line contains ideographs
144
    // even if it is horizontal, but detecting this has performance implications. For now we only work with
156
    // even if it is horizontal, but detecting this has performance implications. For now we only work with
145
    // vertical text, since we already determined the baseline type to be ideographic in that
157
    // vertical text, since we already determined the baseline type to be ideographic in that case.
146
    // case.
147
    auto underlinePosition = context.lineStyle.textUnderlinePosition();
148
    auto underlineOffset = context.lineStyle.textUnderlineOffset();
158
    auto underlineOffset = context.lineStyle.textUnderlineOffset();
149
    auto& fontMetrics = context.lineStyle.metricsOfPrimaryFont();
159
    auto& fontMetrics = context.lineStyle.metricsOfPrimaryFont();
150
160
151
    auto resolvedUnderlinePosition = underlinePosition;
161
    float computedUnderlineOffset = fontMetrics.ascent() + gap;
152
    if (resolvedUnderlinePosition == TextUnderlinePosition::Auto && underlineOffset.isAuto()) {
162
    switch (context.resolvedUnderlinePosition) {
153
        if (context.textUnderlinePositionUnder)
154
            resolvedUnderlinePosition = context.textUnderlinePositionUnder->baselineType == IdeographicBaseline ? TextUnderlinePosition::Under : TextUnderlinePosition::Auto;
155
        else
156
            resolvedUnderlinePosition = TextUnderlinePosition::Auto;
157
    }
158
159
    switch (resolvedUnderlinePosition) {
160
    case TextUnderlinePosition::Auto:
163
    case TextUnderlinePosition::Auto:
161
        if (underlineOffset.isAuto())
164
        computedUnderlineOffset = fontMetrics.ascent() + underlineOffset.lengthOr(gap);
162
            return fontMetrics.ascent() + gap;
165
        break;
163
        return fontMetrics.ascent() + underlineOffset.lengthValue();
164
    case TextUnderlinePosition::FromFont:
166
    case TextUnderlinePosition::FromFont:
165
        return fontMetrics.ascent() + fontMetrics.underlinePosition() + underlineOffset.lengthOr(0);
167
        computedUnderlineOffset = fontMetrics.ascent() + fontMetrics.underlinePosition() + underlineOffset.lengthOr(0.f);
168
        break;
166
    case TextUnderlinePosition::Under: {
169
    case TextUnderlinePosition::Under: {
167
        ASSERT(context.textUnderlinePositionUnder);
170
        ASSERT(context.textUnderlinePositionUnder);
168
        // Position underline relative to the bottom edge of the lowest element's content box.
171
        // Position underline relative to the bottom edge of the lowest element's content box.
169
        auto desiredOffset = context.textUnderlinePositionUnder->textRunLogicalHeight + gap + std::max(context.textUnderlinePositionUnder->textRunOffsetFromBottomMost, 0.0f) + underlineOffset.lengthOr(0);
172
        auto desiredOffset = context.textUnderlinePositionUnder->textRunLogicalHeight + gap + std::max(context.textUnderlinePositionUnder->textRunOffsetFromBottomMost, 0.f) + underlineOffset.lengthOr(0.f);
170
        return std::max<float>(desiredOffset, fontMetrics.ascent());
173
        computedUnderlineOffset = std::max<float>(desiredOffset, fontMetrics.ascent());
174
        break;
171
    }
175
    }
176
    default:
177
        ASSERT_NOT_REACHED();
178
        break;
172
    }
179
    }
173
180
174
    ASSERT_NOT_REACHED();
181
    return computedUnderlineOffset;
175
    return fontMetrics.ascent() + gap;
176
}
182
}
177
183
178
WavyStrokeParameters getWavyStrokeParameters(float fontSize)
184
WavyStrokeParameters getWavyStrokeParameters(float fontSize)
Lines 254-269 static GlyphOverflow computedVisualOverflowForDecorations(const RenderStyle& lin a/Source/WebCore/style/InlineTextBoxStyle.cpp_sec4
254
GlyphOverflow visualOverflowForDecorations(const InlineIterator::LineBoxIterator& lineBox, const RenderText& renderer, float textBoxLogicalTop, float textBoxLogicalBottom)
260
GlyphOverflow visualOverflowForDecorations(const InlineIterator::LineBoxIterator& lineBox, const RenderText& renderer, float textBoxLogicalTop, float textBoxLogicalBottom)
255
{
261
{
256
    auto& style = lineBox->isFirst() ? renderer.firstLineStyle() : renderer.style();
262
    auto& style = lineBox->isFirst() ? renderer.firstLineStyle() : renderer.style();
263
    auto underlinePositionValue = resolvedUnderlinePosition(style, lineBox->baselineType());
264
    auto textUnderlinePositionUnder = std::optional<TextUnderlinePositionUnder> { };
265
266
    if (underlinePositionValue == TextUnderlinePosition::Under) {
267
        auto textRunOffset = textRunOffsetFromBottomMost(lineBox, renderer, textBoxLogicalTop, textBoxLogicalBottom);
268
        textUnderlinePositionUnder = TextUnderlinePositionUnder { textBoxLogicalBottom - textBoxLogicalTop, textRunOffset };
269
    }
270
257
    auto underlineOffset = style.textDecorationsInEffect().contains(TextDecorationLine::Underline)
271
    auto underlineOffset = style.textDecorationsInEffect().contains(TextDecorationLine::Underline)
258
        ? std::make_optional(computeUnderlineOffset({ style, defaultGap(style), TextUnderlinePositionUnder { lineBox->baselineType(), textBoxLogicalBottom - textBoxLogicalTop, textRunOffsetFromBottomMost(lineBox, renderer, textBoxLogicalTop, textBoxLogicalBottom) } }))
272
        ? std::make_optional(computedUnderlineOffset({ style, underlinePositionValue, defaultGap(style), textUnderlinePositionUnder }))
259
        : std::nullopt;
273
        : std::nullopt;
260
    return computedVisualOverflowForDecorations(style, underlineOffset);
274
    return computedVisualOverflowForDecorations(style, underlineOffset);
261
}
275
}
262
276
263
GlyphOverflow visualOverflowForDecorations(const RenderStyle& style, TextUnderlinePositionUnder textUnderlinePositionUnder)
277
GlyphOverflow visualOverflowForDecorations(const RenderStyle& style, FontBaseline baselineType, TextUnderlinePositionUnder textUnderlinePositionUnder)
264
{
278
{
265
    auto underlineOffset = style.textDecorationsInEffect().contains(TextDecorationLine::Underline)
279
    auto underlineOffset = style.textDecorationsInEffect().contains(TextDecorationLine::Underline)
266
        ? std::make_optional(computeUnderlineOffset({ style, defaultGap(style), textUnderlinePositionUnder }))
280
        ? std::make_optional(computedUnderlineOffset({ style, resolvedUnderlinePosition(style, baselineType), defaultGap(style), textUnderlinePositionUnder }))
267
        : std::nullopt;
281
        : std::nullopt;
268
    return computedVisualOverflowForDecorations(style, underlineOffset);
282
    return computedVisualOverflowForDecorations(style, underlineOffset);
269
}
283
}
Lines 271-289 GlyphOverflow visualOverflowForDecorations(const RenderStyle& style, TextUnderli a/Source/WebCore/style/InlineTextBoxStyle.cpp_sec5
271
GlyphOverflow visualOverflowForDecorations(const RenderStyle& style)
285
GlyphOverflow visualOverflowForDecorations(const RenderStyle& style)
272
{
286
{
273
    auto underlineOffset = style.textDecorationsInEffect().contains(TextDecorationLine::Underline)
287
    auto underlineOffset = style.textDecorationsInEffect().contains(TextDecorationLine::Underline)
274
        ? std::make_optional(computeUnderlineOffset({ style, defaultGap(style), { } }))
288
        ? std::make_optional(computedUnderlineOffset({ style, resolvedUnderlinePosition(style, { }), defaultGap(style), { } }))
275
        : std::nullopt;
289
        : std::nullopt;
276
    return computedVisualOverflowForDecorations(style, underlineOffset);
290
    return computedVisualOverflowForDecorations(style, underlineOffset);
277
}
291
}
278
292
279
float underlineOffsetForTextBoxPainting(const RenderStyle& style, const InlineIterator::TextBoxIterator& textBox)
293
float underlineOffsetForTextBoxPainting(const RenderStyle& style, const InlineIterator::TextBoxIterator& textBox)
280
{
294
{
281
    auto textUnderlinePositionUnder = TextUnderlinePositionUnder {
295
    auto lineBox = textBox->lineBox();
282
        textBox->lineBox()->baselineType(),
296
    auto textUnderlinePositionUnder = std::optional<TextUnderlinePositionUnder> { };
283
        textBox->logicalBottom() - textBox->logicalTop(),
297
    auto underlinePositionValue = resolvedUnderlinePosition(style, lineBox->baselineType());
284
        textRunOffsetFromBottomMost(textBox->lineBox(), textBox->renderer(), textBox->logicalTop(), textBox->logicalBottom())
298
285
    };
299
    if (underlinePositionValue == TextUnderlinePosition::Under) {
286
    return computeUnderlineOffset({ style , defaultGap(style), textUnderlinePositionUnder });
300
        auto textRunOffset = textRunOffsetFromBottomMost(lineBox, textBox->renderer(), textBox->logicalTop(), textBox->logicalBottom());
301
        textUnderlinePositionUnder = TextUnderlinePositionUnder { textBox->logicalBottom() - textBox->logicalTop(), textRunOffset };
302
    }
303
304
    return computedUnderlineOffset({ style, underlinePositionValue, defaultGap(style), textUnderlinePositionUnder });
287
}
305
}
288
306
289
}
307
}
- a/Source/WebCore/style/InlineTextBoxStyle.h -2 / +1 lines
Lines 55-68 struct WavyStrokeParameters { a/Source/WebCore/style/InlineTextBoxStyle.h_sec1
55
WavyStrokeParameters getWavyStrokeParameters(float fontSize);
55
WavyStrokeParameters getWavyStrokeParameters(float fontSize);
56
56
57
struct TextUnderlinePositionUnder {
57
struct TextUnderlinePositionUnder {
58
    FontBaseline baselineType { AlphabeticBaseline };
59
    float textRunLogicalHeight { 0 };
58
    float textRunLogicalHeight { 0 };
60
    // This offset value is the distance between the current text run's logical bottom and the lowest position of all the text runs
59
    // This offset value is the distance between the current text run's logical bottom and the lowest position of all the text runs
61
    // on line that belong to the same decoration box.
60
    // on line that belong to the same decoration box.
62
    float textRunOffsetFromBottomMost { 0 };
61
    float textRunOffsetFromBottomMost { 0 };
63
};
62
};
64
GlyphOverflow visualOverflowForDecorations(const RenderStyle&);
63
GlyphOverflow visualOverflowForDecorations(const RenderStyle&);
65
GlyphOverflow visualOverflowForDecorations(const RenderStyle&, TextUnderlinePositionUnder);
64
GlyphOverflow visualOverflowForDecorations(const RenderStyle&, FontBaseline, TextUnderlinePositionUnder);
66
GlyphOverflow visualOverflowForDecorations(const InlineIterator::LineBoxIterator&, const RenderText&, float textBoxLogicalTop, float textBoxLogicalBottom);
65
GlyphOverflow visualOverflowForDecorations(const InlineIterator::LineBoxIterator&, const RenderText&, float textBoxLogicalTop, float textBoxLogicalBottom);
67
66
68
float underlineOffsetForTextBoxPainting(const RenderStyle&, const InlineIterator::TextBoxIterator&);
67
float underlineOffsetForTextBoxPainting(const RenderStyle&, const InlineIterator::TextBoxIterator&);

Return to Bug 243621