Commit 58087bc8 authored by Stephen Chenney's avatar Stephen Chenney Committed by Commit Bot

[Text Decorations] Compute ink_overflow

Text Decorations were not contributing to ink_overflow,
leading to remnants on the screen when invalidated and
causing the mis-sizing of composited layers containing
the decorations.

This change adds ink overflow calculations for LayoutNG
fragment items. Legacy layout is unaffected.

Tests added include both the paint layer sizing concern
and the invalidation concern.

Bug: 896295
Change-Id: I3b8cfd9d9c4f3efafd380e6718fd2eaf22229f27
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2422356Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811524}
parent e2b0a07b
......@@ -547,7 +547,9 @@ void NGFragmentItem::RecalcInkOverflow(
if (IsText()) {
// Re-computing text item is not necessary, because all changes that needs
// to re-compute ink overflow invalidate layout.
// to re-compute ink overflow invalidate layout. Except for box shadows,
// text decorations and outlines that are invalidated before this point in
// the code.
if (IsInkOverflowComputed()) {
*self_and_contents_rect_out = SelfInkOverflow();
return;
......
......@@ -7,6 +7,8 @@
#include "third_party/blink/renderer/core/layout/geometry/logical_rect.h"
#include "third_party/blink/renderer/core/layout/geometry/writing_mode_converter.h"
#include "third_party/blink/renderer/core/layout/line/line_orientation_utils.h"
#include "third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.h"
#include "third_party/blink/renderer/core/paint/text_decoration_info.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/platform/wtf/size_assertions.h"
......@@ -333,6 +335,14 @@ base::Optional<PhysicalRect> NGInkOverflow::ComputeTextInkOverflow(
ink_overflow.Inflate(LayoutUnit::FromFloatCeil(stroke_width / 2.0f));
}
// Following effects, such as shadows, operate on the text decorations,
// so compute text decoration overflow first.
if (!style.AppliedTextDecorations().IsEmpty() && font.PrimaryFont()) {
LayoutRect decoration_rect =
ComputeTextDecorationOverflow(text_info, style, ink_overflow);
ink_overflow.Unite(decoration_rect);
}
const WritingMode writing_mode = style.GetWritingMode();
if (style.GetTextEmphasisMark() != TextEmphasisMark::kNone) {
LayoutUnit emphasis_mark_height =
......@@ -372,4 +382,93 @@ base::Optional<PhysicalRect> NGInkOverflow::ComputeTextInkOverflow(
return local_ink_overflow;
}
LayoutRect NGInkOverflow::ComputeTextDecorationOverflow(
const NGTextFragmentPaintInfo& text_info,
const ComputedStyle& style,
const LayoutRect& ink_overflow) {
// Use a zero offset because all offsets are applied to the ink overflow
// after it has been computed.
PhysicalOffset offset;
TextDecorationInfo decoration_info(offset, offset, ink_overflow.Width(),
style.GetFontBaseline(), style, nullptr);
NGTextDecorationOffset decoration_offset(decoration_info.Style(), style,
nullptr);
const Vector<AppliedTextDecoration>& decorations =
style.AppliedTextDecorations();
// text-underline-position may flip underline and overline.
ResolvedUnderlinePosition underline_position =
decoration_info.UnderlinePosition();
bool flip_underline_and_overline = false;
if (underline_position == ResolvedUnderlinePosition::kOver) {
flip_underline_and_overline = true;
underline_position = ResolvedUnderlinePosition::kUnder;
}
FloatRect accumulated_bound;
for (size_t applied_decoration_index = 0;
applied_decoration_index < decorations.size();
++applied_decoration_index) {
const AppliedTextDecoration& decoration =
decorations[applied_decoration_index];
TextDecoration lines = decoration.Lines();
bool has_underline = EnumHasFlags(lines, TextDecoration::kUnderline);
bool has_overline = EnumHasFlags(lines, TextDecoration::kOverline);
if (flip_underline_and_overline)
std::swap(has_underline, has_overline);
decoration_info.SetDecorationIndex(applied_decoration_index);
float resolved_thickness = decoration_info.ResolvedThickness();
if (has_underline) {
const int paint_underline_offset =
decoration_offset.ComputeUnderlineOffset(
underline_position, decoration_info.Style().ComputedFontSize(),
decoration_info.FontData()->GetFontMetrics(),
decoration.UnderlineOffset(), resolved_thickness);
decoration_info.SetPerLineData(
TextDecoration::kUnderline, paint_underline_offset,
TextDecorationInfo::DoubleOffsetFromThickness(resolved_thickness), 1);
accumulated_bound.Unite(
decoration_info.BoundsForLine(TextDecoration::kUnderline));
}
if (has_overline) {
FontVerticalPositionType position =
flip_underline_and_overline ? FontVerticalPositionType::TopOfEmHeight
: FontVerticalPositionType::TextTop;
const int paint_overline_offset =
decoration_offset.ComputeUnderlineOffsetForUnder(
decoration_info.Style().TextUnderlineOffset(),
decoration_info.Style().ComputedFontSize(), resolved_thickness,
position);
decoration_info.SetPerLineData(
TextDecoration::kOverline, paint_overline_offset,
-TextDecorationInfo::DoubleOffsetFromThickness(resolved_thickness),
1);
accumulated_bound.Unite(
decoration_info.BoundsForLine(TextDecoration::kOverline));
}
if (EnumHasFlags(lines, TextDecoration::kLineThrough)) {
// For increased line thickness, the line-through decoration needs to grow
// in both directions from its origin, subtract half the thickness to keep
// it centered at the same origin.
const float line_through_offset =
2 * decoration_info.Baseline() / 3 - resolved_thickness / 2;
// Floor double_offset in order to avoid double-line gap to appear
// of different size depending on position where the double line
// is drawn because of rounding downstream in
// GraphicsContext::DrawLineForText.
decoration_info.SetPerLineData(
TextDecoration::kLineThrough, line_through_offset,
floorf(TextDecorationInfo::DoubleOffsetFromThickness(
resolved_thickness)),
0);
accumulated_bound.Unite(
decoration_info.BoundsForLine(TextDecoration::kLineThrough));
}
}
return EnclosingLayoutRect(accumulated_bound);
}
} // namespace blink
......@@ -127,6 +127,11 @@ class CORE_EXPORT NGInkOverflow {
#endif
private:
static LayoutRect ComputeTextDecorationOverflow(
const NGTextFragmentPaintInfo& text_info,
const ComputedStyle& style,
const LayoutRect& ink_overflow);
PhysicalRect FromOutsets(const PhysicalSize& size) const;
void CheckType(Type type) const;
......
......@@ -668,16 +668,11 @@ void NGTextFragmentPainter<Cursor>::Paint(const PaintInfo& paint_info,
!text_item.IsEllipsis()) {
PhysicalOffset local_origin = box_rect.offset;
LayoutUnit width = box_rect.Width();
const NGPhysicalBoxFragment* decorating_box = nullptr;
const ComputedStyle* decorating_box_style =
decorating_box ? &decorating_box->Style() : nullptr;
decoration_info.emplace(box_rect.offset, local_origin, width,
style.GetFontBaseline(), style,
decorating_box_style);
NGTextDecorationOffset decoration_offset(
decoration_info->Style(), text_item.Style(), decorating_box);
style.GetFontBaseline(), style, nullptr);
NGTextDecorationOffset decoration_offset(decoration_info->Style(),
text_item.Style(), nullptr);
text_painter.PaintDecorationsExceptLineThrough(
decoration_offset, decoration_info.value(), paint_info,
style.AppliedTextDecorations(), text_style,
......
......@@ -249,9 +249,8 @@ FloatRect TextDecorationInfo::BoundsForLine(TextDecoration line) const {
FloatPoint start_point = StartPoint(line);
switch (DecorationStyle()) {
case ETextDecorationStyle::kDotted:
case ETextDecorationStyle::kDashed: {
case ETextDecorationStyle::kDashed:
return BoundsForDottedOrDashed(line);
}
case ETextDecorationStyle::kWavy:
return BoundsForWavy(line);
case ETextDecorationStyle::kDouble:
......
......@@ -84,10 +84,6 @@ class CORE_EXPORT TextDecorationInfo {
FloatPoint StartPoint(TextDecoration line) const;
float DoubleOffset(TextDecoration line) const;
// Computed bounds for all the decorations in the style passed at
// construction.
FloatRect Bounds() const;
// Compute bounds for the given line and the current decoration.
FloatRect BoundsForLine(TextDecoration line) const;
......@@ -95,6 +91,10 @@ class CORE_EXPORT TextDecorationInfo {
// current decoration.
base::Optional<Path> PrepareWavyStrokePath(TextDecoration line) const;
static float DoubleOffsetFromThickness(float thickness_pixels) {
return thickness_pixels + 1.0f;
}
private:
float ComputeUnderlineThickness(
const TextDecorationThickness& applied_decoration_thickness,
......
......@@ -31,10 +31,6 @@ namespace {
// implementation.
constexpr float kDecorationClipMaxDilation = 13;
float DoubleOffsetFromThickness(float thickness_pixels) {
return thickness_pixels + 1.0f;
}
} // anonymous namespace
TextPainterBase::TextPainterBase(GraphicsContext& context,
......@@ -247,7 +243,7 @@ void TextPainterBase::PaintDecorationsExceptLineThrough(
decoration.UnderlineOffset(), resolved_thickness);
decoration_info.SetPerLineData(
TextDecoration::kUnderline, paint_underline_offset,
DoubleOffsetFromThickness(resolved_thickness), 1);
TextDecorationInfo::DoubleOffsetFromThickness(resolved_thickness), 1);
PaintDecorationUnderOrOverLine(context, decoration_info,
TextDecoration::kUnderline);
}
......@@ -263,7 +259,8 @@ void TextPainterBase::PaintDecorationsExceptLineThrough(
position);
decoration_info.SetPerLineData(
TextDecoration::kOverline, paint_overline_offset,
-DoubleOffsetFromThickness(resolved_thickness), 1);
-TextDecorationInfo::DoubleOffsetFromThickness(resolved_thickness),
1);
PaintDecorationUnderOrOverLine(context, decoration_info,
TextDecoration::kOverline);
}
......@@ -314,7 +311,9 @@ void TextPainterBase::PaintDecorationsOnlyLineThrough(
// GraphicsContext::DrawLineForText.
decoration_info.SetPerLineData(
TextDecoration::kLineThrough, line_through_offset,
floorf(DoubleOffsetFromThickness(resolved_thickness)), 0);
floorf(TextDecorationInfo::DoubleOffsetFromThickness(
resolved_thickness)),
0);
AppliedDecorationPainter decoration_painter(context, decoration_info,
TextDecoration::kLineThrough);
// No skip: ink for line-through,
......
......@@ -27,7 +27,7 @@ class StyleDifference {
kCSSClipChanged = 1 << 5,
// The object needs to issue paint invalidations if it is affected by text
// decorations or properties dependent on color (e.g., border or outline).
// TextDecorationis changes must also invalidate ink overflow.
// TextDecoration changes must also invalidate ink overflow.
kTextDecorationOrColorChanged = 1 << 6,
kBlendModeChanged = 1 << 7,
kMaskChanged = 1 << 8,
......
<!DOCTYPE html>
<html>
<head>
<title>CSS Text Decoration Test: text-decoration-style: dashed invalidation on style change, reference</title>
<link rel="help" href="https://drafts.csswg.org/css-text-decor-4/">
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<style>
div {
display: block;
margin-top: 30px;
margin-bottom: 30px;
will-change: transform;
}
.underline {
text-decoration-line: underline;
text-decoration-color: green;
text-decoration-style: dashed;
text-decoration-thickness: 5px;
}
.overline {
text-decoration-line: overline;
text-decoration-color: green;
text-decoration-style: dashed;
text-decoration-thickness: 5px;
}
.throughline {
text-decoration-line: line-through;
text-decoration-color: green;
text-decoration-style: dashed;
text-decoration-thickness: 5px;
}
</style>
</head>
<body>
<div id="top-underline-div">
There should be no sign of an underline when the test completes.
</div>
<div id="bottom-underline-div" class="underline">
There should be a 5px green dashed underline when the test completes.
</div>
<div id="top-overline-div">
There should be no sign of an overline when the test completes.
</div>
<div id="bottom-overline-div" class="overline">
There should be a 5px green dashed overline when the test completes.
</div>
<div id="top-throughline-div">
There should be no sign of an through-line when the test completes.
</div>
<div id="bottom-throughline-div" class="throughline">
There should be a 5px green dashed through-line when the test completes.
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>CSS Text Decoration Test: text-decoration-style: double invalidation on style change, reference</title>
<link rel="help" href="https://drafts.csswg.org/css-text-decor-4/">
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<style>
div {
display: block;
margin-top: 30px;
margin-bottom: 30px;
will-change: transform;
}
.underline {
text-decoration-line: underline;
text-decoration-color: green;
text-decoration-style: double;
text-decoration-thickness: 5px;
}
.overline {
text-decoration-line: overline;
text-decoration-color: green;
text-decoration-style: double;
text-decoration-thickness: 5px;
}
.throughline {
text-decoration-line: line-through;
text-decoration-color: green;
text-decoration-style: double;
text-decoration-thickness: 5px;
}
</style>
</head>
<body>
<div id="top-underline-div">
There should be no sign of an underline when the test completes.
</div>
<div id="bottom-underline-div" class="underline">
There should be a 5px green double underline when the test completes.
</div>
<div id="top-overline-div">
There should be no sign of an overline when the test completes.
</div>
<div id="bottom-overline-div" class="overline">
There should be a 5px green double overline when the test completes.
</div>
<div id="top-throughline-div">
There should be no sign of an through-line when the test completes.
</div>
<div id="bottom-throughline-div" class="throughline">
There should be a 5px green double through-line when the test completes.
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>CSS Text Decoration Test: text-decoration-style: solid invalidation on style change, reference</title>
<link rel="help" href="https://drafts.csswg.org/css-text-decor-4/">
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<style>
div {
display: block;
margin-top: 30px;
margin-bottom: 30px;
will-change: transform;
}
.underline {
text-decoration-line: underline;
text-decoration-color: green;
text-decoration-style: solid;
text-decoration-thickness: 5px;
}
.overline {
text-decoration-line: overline;
text-decoration-color: green;
text-decoration-style: solid;
text-decoration-thickness: 5px;
}
.throughline {
text-decoration-line: line-through;
text-decoration-color: green;
text-decoration-style: solid;
text-decoration-thickness: 5px;
}
</style>
</head>
<body>
<div id="top-underline-div">
There should be no sign of an underline when the test completes.
</div>
<div id="bottom-underline-div" class="underline">
There should be a 5px green solid underline when the test completes.
</div>
<div id="top-overline-div">
There should be no sign of an overline when the test completes.
</div>
<div id="bottom-overline-div" class="overline">
There should be a 5px green solid overline when the test completes.
</div>
<div id="top-throughline-div">
There should be no sign of an through-line when the test completes.
</div>
<div id="bottom-throughline-div" class="throughline">
There should be a 5px green solid through-line when the test completes.
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>CSS Text Decoration Test: text-decoration-style: solid invalidation on style change, reference</title>
<link rel="help" href="https://drafts.csswg.org/css-text-decor-4/">
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<style>
div {
display: block;
margin-top: 30px;
margin-bottom: 30px;
will-change: transform;
}
.underline {
text-decoration-line: underline;
text-decoration-color: green;
text-decoration-style: wavy;
text-decoration-thickness: 5px;
}
.overline {
text-decoration-line: overline;
text-decoration-color: green;
text-decoration-style: wavy;
text-decoration-thickness: 5px;
}
.throughline {
text-decoration-line: line-through;
text-decoration-color: green;
text-decoration-style: wavy;
text-decoration-thickness: 5px;
}
</style>
</head>
<body>
<div id="top-underline-div">
There should be no sign of an underline when the test completes.
</div>
<div id="bottom-underline-div" class="underline">
There should be a 5px green wavy underline when the test completes.
</div>
<div id="top-overline-div">
There should be no sign of an overline when the test completes.
</div>
<div id="bottom-overline-div" class="overline">
There should be a 5px green wavy overline when the test completes.
</div>
<div id="top-throughline-div">
There should be no sign of an through-line when the test completes.
</div>
<div id="bottom-throughline-div" class="throughline">
There should be a 5px green wavy through-line when the test completes.
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>CSS Text Decoration Test: text-decoration-style: dashed invalidation on style change</title>
<link rel="help" href="https://drafts.csswg.org/css-text-decor-4/">
<meta name="assert" content="text-decoration-style: dashed should be correctly invalidated on style change.">
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<link rel="match" href="reference/text-decoration-invalidation-dashed-ref.html">
<style>
div {
display: block;
margin-top: 30px;
margin-bottom: 30px;
will-change: transform;
}
.underline {
text-decoration-line: underline;
text-decoration-color: green;
text-decoration-style: dashed;
text-decoration-thickness: 5px;
}
.overline {
text-decoration-line: overline;
text-decoration-color: green;
text-decoration-style: dashed;
text-decoration-thickness: 5px;
}
.throughline {
text-decoration-line: line-through;
text-decoration-color: green;
text-decoration-style: dashed;
text-decoration-thickness: 5px;
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/rendering-utils.js"></script>
</head>
<body>
<div id="top-underline-div" class="underline">
There should be no sign of an underline when the test completes.
</div>
<div id="bottom-underline-div" >
There should be a 5px green dashed underline when the test completes.
</div>
<div id="top-overline-div" class="overline">
There should be no sign of an overline when the test completes.
</div>
<div id="bottom-overline-div" >
There should be a 5px green dashed overline when the test completes.
</div>
<div id="top-throughline-div" class="throughline">
There should be no sign of an through-line when the test completes.
</div>
<div id="bottom-throughline-div" >
There should be a 5px green dashed through-line when the test completes.
</div>
</body>
<script>
async function runTest() {
document.getElementById('top-underline-div').classList.remove("underline");
document.getElementById('bottom-underline-div').classList.add("underline");
document.getElementById('top-overline-div').classList.remove("overline");
document.getElementById('bottom-overline-div').classList.add("overline");
document.getElementById('top-throughline-div').classList.remove("throughline");
document.getElementById('bottom-throughline-div').classList.add("throughline");
takeScreenshot();
}
onload = () => {
waitForAtLeastOneFrame().then(() => { runTest() });
}
</script>
</html>
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>CSS Text Decoration Test: text-decoration-style: double invalidation on style change</title>
<link rel="help" href="https://drafts.csswg.org/css-text-decor-4/">
<meta name="assert" content="text-decoration-style: double should be correctly invalidated on style change.">
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<link rel="match" href="reference/text-decoration-invalidation-double-ref.html">
<style>
div {
display: block;
margin-top: 30px;
margin-bottom: 30px;
will-change: transform;
}
.underline {
text-decoration-line: underline;
text-decoration-color: green;
text-decoration-style: double;
text-decoration-thickness: 5px;
}
.overline {
text-decoration-line: overline;
text-decoration-color: green;
text-decoration-style: double;
text-decoration-thickness: 5px;
}
.throughline {
text-decoration-line: line-through;
text-decoration-color: green;
text-decoration-style: double;
text-decoration-thickness: 5px;
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/rendering-utils.js"></script>
</head>
<body>
<div id="top-underline-div" class="underline">
There should be no sign of an underline when the test completes.
</div>
<div id="bottom-underline-div" >
There should be a 5px green double underline when the test completes.
</div>
<div id="top-overline-div" class="overline">
There should be no sign of an overline when the test completes.
</div>
<div id="bottom-overline-div" >
There should be a 5px green double overline when the test completes.
</div>
<div id="top-throughline-div" class="throughline">
There should be no sign of an through-line when the test completes.
</div>
<div id="bottom-throughline-div" >
There should be a 5px green double through-line when the test completes.
</div>
</body>
<script>
async function runTest() {
document.getElementById('top-underline-div').classList.remove("underline");
document.getElementById('bottom-underline-div').classList.add("underline");
document.getElementById('top-overline-div').classList.remove("overline");
document.getElementById('bottom-overline-div').classList.add("overline");
document.getElementById('top-throughline-div').classList.remove("throughline");
document.getElementById('bottom-throughline-div').classList.add("throughline");
takeScreenshot();
}
onload = () => {
waitForAtLeastOneFrame().then(() => { runTest() });
}
</script>
</html>
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>CSS Text Decoration Test: text-decoration-style: solid invalidation on style change</title>
<link rel="help" href="https://drafts.csswg.org/css-text-decor-4/">
<meta name="assert" content="text-decoration-style: solid should be correctly invalidated on style change.">
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<link rel="match" href="reference/text-decoration-invalidation-solid-ref.html">
<style>
div {
display: block;
margin-top: 30px;
margin-bottom: 30px;
will-change: transform;
}
.underline {
text-decoration-line: underline;
text-decoration-color: green;
text-decoration-style: solid;
text-decoration-thickness: 5px;
}
.overline {
text-decoration-line: overline;
text-decoration-color: green;
text-decoration-style: solid;
text-decoration-thickness: 5px;
}
.throughline {
text-decoration-line: line-through;
text-decoration-color: green;
text-decoration-style: solid;
text-decoration-thickness: 5px;
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/rendering-utils.js"></script>
</head>
<body>
<div id="top-underline-div" class="underline">
There should be no sign of an underline when the test completes.
</div>
<div id="bottom-underline-div" >
There should be a 5px green solid underline when the test completes.
</div>
<div id="top-overline-div" class="overline">
There should be no sign of an overline when the test completes.
</div>
<div id="bottom-overline-div" >
There should be a 5px green solid overline when the test completes.
</div>
<div id="top-throughline-div" class="throughline">
There should be no sign of an through-line when the test completes.
</div>
<div id="bottom-throughline-div" >
There should be a 5px green solid through-line when the test completes.
</div>
</body>
<script>
async function runTest() {
document.getElementById('top-underline-div').classList.remove("underline");
document.getElementById('bottom-underline-div').classList.add("underline");
document.getElementById('top-overline-div').classList.remove("overline");
document.getElementById('bottom-overline-div').classList.add("overline");
document.getElementById('top-throughline-div').classList.remove("throughline");
document.getElementById('bottom-throughline-div').classList.add("throughline");
takeScreenshot();
}
onload = () => {
waitForAtLeastOneFrame().then(() => { runTest() });
}
</script>
</html>
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<title>CSS Text Decoration Test: text-decoration-style: wavy invalidation on style change</title>
<link rel="help" href="https://drafts.csswg.org/css-text-decor-4/">
<meta name="assert" content="text-decoration-style: wavy should be correctly invalidated on style change.">
<link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
<link rel="match" href="reference/text-decoration-invalidation-wavy-ref.html">
<style>
div {
display: block;
margin-top: 30px;
margin-bottom: 30px;
will-change: transform;
}
.underline {
text-decoration-line: underline;
text-decoration-color: green;
text-decoration-style: wavy;
text-decoration-thickness: 5px;
}
.overline {
text-decoration-line: overline;
text-decoration-color: green;
text-decoration-style: wavy;
text-decoration-thickness: 5px;
}
.throughline {
text-decoration-line: line-through;
text-decoration-color: green;
text-decoration-style: wavy;
text-decoration-thickness: 5px;
}
</style>
<script src="/common/reftest-wait.js"></script>
<script src="/common/rendering-utils.js"></script>
</head>
<body>
<div id="top-underline-div" class="underline">
There should be no sign of an underline when the test completes.
</div>
<div id="bottom-underline-div" >
There should be a 5px green wavy underline when the test completes.
</div>
<div id="top-overline-div" class="overline">
There should be no sign of an overline when the test completes.
</div>
<div id="bottom-overline-div" >
There should be a 5px green wavy overline when the test completes.
</div>
<div id="top-throughline-div" class="throughline">
There should be no sign of an through-line when the test completes.
</div>
<div id="bottom-throughline-div" >
There should be a 5px green wavy through-line when the test completes.
</div>
</body>
<script>
async function runTest() {
document.getElementById('top-underline-div').classList.remove("underline");
document.getElementById('bottom-underline-div').classList.add("underline");
document.getElementById('top-overline-div').classList.remove("overline");
document.getElementById('bottom-overline-div').classList.add("overline");
document.getElementById('top-throughline-div').classList.remove("throughline");
document.getElementById('bottom-throughline-div').classList.add("throughline");
takeScreenshot();
}
onload = () => {
waitForAtLeastOneFrame().then(() => { runTest() });
}
</script>
</html>
\ No newline at end of file
<!DOCTYPE html>
<style>
div {
display: block;
width: 400px;
height: 100px;
color: blue;
}
#underlineHover:hover {
text-decoration: underline;
}
#underlineNoHover:hover {
text-decoration: underline;
}
</style>
<div id="underlineHover">
<span>When</span> <span>hovered, </span><span>there</span> <span>should</span> <span> be </span> <span>no</span> <span>gaps</span> <span>in</span> <span>the</span> <span>underline.</span>
</div>
<div id="underlineNoHover">
<span>When</span> <span>not hovered, </span><span>there</span> <span>should</span> <span> be </span> <span>no</span> <span>underlines.</span>
</div>
<script src="../../resources/run-after-layout-and-paint.js"></script>
<script>
if (window.eventSender)
eventSender.mouseMoveTo(underlineNoHover.offsetLeft + 10, underlineNoHover.offsetTop + 10);
runAfterLayoutAndPaint(function() {
if (window.eventSender)
eventSender.mouseMoveTo(underlineHover.offsetLeft + 10, underlineHover.offsetTop + 10);
}, true);
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment