Implement text-underline-offset and text-decoration-thickness
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2018 01:22:41 +0000 (01:22 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2018 01:22:41 +0000 (01:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190774

Reviewed by Dean Jackson.

Source/WebCore:

Because of our existing infrastructure for text decorations, adding support for these
is fairly simple. This patch updates our existing functions to handle thick & placed
underlines, as well as updating our repaint code to correcly handle repainting them.
It also handles animations.

Tests: animations/text-decoration-thickness.html
       animations/text-underline-offset.html
       fast/css3-text/css3-text-decoration/text-decoration-offset-2.html
       fast/css3-text/css3-text-decoration/text-decoration-offset-3.html
       fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length.html
       fast/css3-text/css3-text-decoration/text-decoration-offset-baseline.html
       fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto.html
       fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length.html
       fast/css3-text/css3-text-decoration/text-decoration-offset-repaint.html
       fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto.html
       fast/css3-text/css3-text-decoration/text-decoration-offset-under-length.html
       fast/css3-text/css3-text-decoration/text-decoration-offset.html
       fast/css3-text/css3-text-decoration/text-decoration-thickness-length.html
       fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint.html

* page/animation/CSSPropertyAnimation.cpp:
(WebCore::blendFunc):
(WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap):
* platform/graphics/FontMetrics.h:
(WebCore::FontMetrics::underlinePosition const):
(WebCore::FontMetrics::setUnderlinePosition):
(WebCore::FontMetrics::underlineThickness const):
(WebCore::FontMetrics::setUnderlineThickness):
* platform/graphics/cocoa/FontCocoa.mm:
(WebCore::Font::platformInit):
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::addToLine):
* rendering/SimpleLineLayout.cpp:
(WebCore::SimpleLineLayout::canUseForStyle):
* rendering/TextDecorationPainter.cpp:
(WebCore::TextDecorationPainter::paintTextDecoration):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeAffectsVisualOverflow const):
* rendering/style/TextDecorationThickness.h:
(WebCore::TextDecorationThickness::resolve const):
* style/InlineTextBoxStyle.cpp:
(WebCore::computeUnderlineOffset):
(WebCore::visualOverflowForDecorations):
* style/InlineTextBoxStyle.h:
(WebCore::textDecorationStrokeThickness): Deleted.

LayoutTests:

* animations/text-decoration-thickness-expected.txt: Added.
* animations/text-decoration-thickness.html: Added.
* animations/text-underline-offset-expected.txt: Added.
* animations/text-underline-offset.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-2-expected-mismatch.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-2.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-3-expected-mismatch.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-3.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-baseline-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-baseline.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-expected-mismatch.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-repaint-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-repaint.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-under-length-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset-under-length.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-offset.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-thickness-length-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-thickness-length.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint-expected.html: Added.
* fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237903 268f45cc-cd09-0410-ab3c-d52691b4dbfc

40 files changed:
LayoutTests/ChangeLog
LayoutTests/animations/text-decoration-thickness-expected.txt [new file with mode: 0644]
LayoutTests/animations/text-decoration-thickness.html [new file with mode: 0644]
LayoutTests/animations/text-underline-offset-expected.txt [new file with mode: 0644]
LayoutTests/animations/text-underline-offset.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-2-expected-mismatch.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-2.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-3-expected-mismatch.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-3.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-baseline-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-baseline.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-expected-mismatch.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-repaint-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-repaint.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-length-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-length.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-length-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-length.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint-expected.html [new file with mode: 0644]
LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/animation/CSSPropertyAnimation.cpp
Source/WebCore/platform/graphics/FontMetrics.h
Source/WebCore/platform/graphics/cocoa/FontCocoa.mm
Source/WebCore/rendering/InlineFlowBox.cpp
Source/WebCore/rendering/SimpleLineLayout.cpp
Source/WebCore/rendering/TextDecorationPainter.cpp
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/TextDecorationThickness.h
Source/WebCore/style/InlineTextBoxStyle.cpp
Source/WebCore/style/InlineTextBoxStyle.h

index 0646377..883bbc6 100644 (file)
@@ -1,3 +1,39 @@
+2018-11-06  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Implement text-underline-offset and text-decoration-thickness
+        https://bugs.webkit.org/show_bug.cgi?id=190774
+
+        Reviewed by Dean Jackson.
+
+        * animations/text-decoration-thickness-expected.txt: Added.
+        * animations/text-decoration-thickness.html: Added.
+        * animations/text-underline-offset-expected.txt: Added.
+        * animations/text-underline-offset.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-2-expected-mismatch.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-2.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-3-expected-mismatch.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-3.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-baseline-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-baseline.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-expected-mismatch.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-repaint-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-repaint.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-under-length-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset-under-length.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-offset.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-thickness-length-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-thickness-length.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint-expected.html: Added.
+        * fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint.html: Added.
+
 2018-11-06  Dean Jackson  <dino@apple.com>
 
         Add some basic pointer events tests
diff --git a/LayoutTests/animations/text-decoration-thickness-expected.txt b/LayoutTests/animations/text-decoration-thickness-expected.txt
new file mode 100644 (file)
index 0000000..d944f34
--- /dev/null
@@ -0,0 +1,5 @@
+Hello
+PASS - "text-decoration-thickness" property for "box" element at 0.5s saw something close to: 16.6666
+PASS - "text-decoration-thickness" property for "box" element at 1s saw something close to: 33.3333
+PASS - "text-decoration-thickness" property for "box" element at 2s saw something close to: 66.6666
+
diff --git a/LayoutTests/animations/text-decoration-thickness.html b/LayoutTests/animations/text-decoration-thickness.html
new file mode 100644 (file)
index 0000000..87295e2
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="resources/animation-test-helpers.js"></script>
+<style>
+@keyframes TheAnimation {
+    from {
+        text-decoration-thickness: 0px;
+    }
+    to {
+        text-decoration-thickness: 100px;
+    }
+}
+
+#box {
+    text-decoration: underline;
+    animation-duration: 3s;
+    animation-timing-function: linear;
+}
+</style>
+</head>
+<body>
+<div id="box">Hello</div>
+<div id="result"></div>
+<script>
+var expectedValues = [
+    // [animation-name, time, element-id, property, expected-value, tolerance]
+    ["TheAnimation", 0.5, "box", "text-decoration-thickness", "16.6666", 5],
+    ["TheAnimation", 1.0, "box", "text-decoration-thickness", "33.3333", 5],
+    ["TheAnimation", 2.0, "box", "text-decoration-thickness", "66.6666", 5],
+];
+
+document.getElementById("box").style.animationName = "TheAnimation";
+runAnimationTest(expectedValues, undefined, undefined, undefined, false, undefined);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/animations/text-underline-offset-expected.txt b/LayoutTests/animations/text-underline-offset-expected.txt
new file mode 100644 (file)
index 0000000..47a5772
--- /dev/null
@@ -0,0 +1,5 @@
+Hello
+PASS - "text-underline-offset" property for "box" element at 0.5s saw something close to: 16.6666
+PASS - "text-underline-offset" property for "box" element at 1s saw something close to: 33.3333
+PASS - "text-underline-offset" property for "box" element at 2s saw something close to: 66.6666
+
diff --git a/LayoutTests/animations/text-underline-offset.html b/LayoutTests/animations/text-underline-offset.html
new file mode 100644 (file)
index 0000000..882321b
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="resources/animation-test-helpers.js"></script>
+<style>
+@keyframes TheAnimation {
+    from {
+        text-underline-offset: 0px;
+    }
+    to {
+        text-underline-offset: 100px;
+    }
+}
+
+#box {
+    text-decoration: underline;
+    animation-duration: 3s;
+    animation-timing-function: linear;
+}
+</style>
+</head>
+<body>
+<div id="box">Hello</div>
+<div id="result"></div>
+<script>
+var expectedValues = [
+    // [animation-name, time, element-id, property, expected-value, tolerance]
+    ["TheAnimation", 0.5, "box", "text-underline-offset", "16.6666", 5],
+    ["TheAnimation", 1.0, "box", "text-underline-offset", "33.3333", 5],
+    ["TheAnimation", 2.0, "box", "text-underline-offset", "66.6666", 5],
+];
+
+document.getElementById("box").style.animationName = "TheAnimation";
+runAnimationTest(expectedValues, undefined, undefined, undefined, false, undefined);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-2-expected-mismatch.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-2-expected-mismatch.html
new file mode 100644 (file)
index 0000000..a2dea42
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: under;">Hello</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-2.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-2.html
new file mode 100644 (file)
index 0000000..f32fb25
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: auto;">Hello</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-3-expected-mismatch.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-3-expected-mismatch.html
new file mode 100644 (file)
index 0000000..2a524d8
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: from-font;">Hello</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-3.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-3.html
new file mode 100644 (file)
index 0000000..a2dea42
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: under;">Hello</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length-expected.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length-expected.html
new file mode 100644 (file)
index 0000000..cc68b2d
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: auto; text-underline-offset: 0px; position: absolute; left: 0px; top: 10px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length.html
new file mode 100644 (file)
index 0000000..b6259bb
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: auto; text-underline-offset: 10px; position: absolute; left: 0px; top: 0px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-baseline-expected.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-baseline-expected.html
new file mode 100644 (file)
index 0000000..5e3b05c
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times';">Hello<div style="display: inline-block; width: 1px; height: 60px;"></div></div>
+<div style="position: absolute; left: 100px; top: 0px; width: 300px; height: 100px; background: black;"></div>
+<div style="position: absolute; left: 0px; top: 60px; width: 300px; height: 3px; background: black;"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-baseline.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-baseline.html
new file mode 100644 (file)
index 0000000..dd2b933
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: auto; text-underline-offset: 0px;">Hello<div style="display: inline-block; width: 1px; height: 60px;"></div></div>
+<div style="position: absolute; left: 100px; top: 0px; width: 300px; height: 100px; background: black;"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-expected-mismatch.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-expected-mismatch.html
new file mode 100644 (file)
index 0000000..2a524d8
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: from-font;">Hello</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto-expected.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto-expected.html
new file mode 100644 (file)
index 0000000..47568d1
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: from-font; text-underline-offset: 0px; position: absolute; left: 0px; top: 0px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto.html
new file mode 100644 (file)
index 0000000..da60650
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: from-font; text-underline-offset: auto; position: absolute; left: 0px; top: 0px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length-expected.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length-expected.html
new file mode 100644 (file)
index 0000000..4c4561f
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: from-font; text-underline-offset: 0px; position: absolute; left: 0px; top: 10px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length.html
new file mode 100644 (file)
index 0000000..ff1b26a
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: from-font; text-underline-offset: 10px; position: absolute; left: 0px; top: 0px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-repaint-expected.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-repaint-expected.html
new file mode 100644 (file)
index 0000000..019809f
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure repaint rects are correct for positioned underlines. The test passes if you don't see anything below.
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-repaint.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-repaint.html
new file mode 100644 (file)
index 0000000..d6c3832
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure repaint rects are correct for positioned underlines. The test passes if you don't see anything below.
+<div id="target" style="font: 48px 'Times'; text-decoration: underline; text-underline-offset: 100px;">Hello</div>
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+window.setTimeout(function() {
+    let target = document.getElementById("target");
+    target.parentElement.removeChild(target);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}, 20);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto-expected.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto-expected.html
new file mode 100644 (file)
index 0000000..779d7ff
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: under; text-underline-offset: 0px; position: absolute; left: 0px; top: 0px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto.html
new file mode 100644 (file)
index 0000000..8923fb4
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: under; text-underline-offset: auto; position: absolute; left: 0px; top: 0px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-length-expected.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-length-expected.html
new file mode 100644 (file)
index 0000000..712f2b5
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: under; text-underline-offset: 0px; position: absolute; left: 0px; top: 10px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-length.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset-under-length.html
new file mode 100644 (file)
index 0000000..cdd6bac
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure the underline is placed in the right vertical place.
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: under; text-underline-offset: 10px; position: absolute; left: 0px; top: 0px; color: transparent; -webkit-text-decoration-color: black;">Hello</div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-offset.html
new file mode 100644 (file)
index 0000000..f32fb25
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div style="font: 48px 'Times'; text-decoration: underline; -webkit-text-decoration-skip: none; text-underline-position: auto;">Hello</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-length-expected.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-length-expected.html
new file mode 100644 (file)
index 0000000..7b42502
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; text-decoration-thickness: 40px; -webkit-text-decoration-skip: none; text-underline-offset: 0px;">Hello<div style="display: inline-block; width: 1px; height: 60px;"></div></div>
+<div style="position: absolute; left: 0px; top: 60px; width: 100px; height: 40px; background: black;"></div>
+<div style="position: absolute; left: 100px; top: 0px; width: 100px; height: 100px; background: black;"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-length.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-length.html
new file mode 100644 (file)
index 0000000..5973a3a
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<div style="position: relative;">
+<div style="font: 48px 'Times'; text-decoration: underline; text-decoration-thickness: 40px; -webkit-text-decoration-skip: none; text-underline-offset: 0px;">Hello<div style="display: inline-block; width: 1px; height: 60px;"></div></div>
+<div style="position: absolute; left: 100px; top: 0px; width: 100px; height: 100px; background: black;"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint-expected.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint-expected.html
new file mode 100644 (file)
index 0000000..328b727
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure repaint rects are correct for thick underlines. The test passes if you don't see anything below.
+</body>
+</html>
diff --git a/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint.html b/LayoutTests/fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint.html
new file mode 100644 (file)
index 0000000..ef3f6f8
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure repaint rects are correct for thick underlines. The test passes if you don't see anything below.
+<div id="target" style="font: 48px 'Times'; text-decoration: underline; text-decoration-thickness: 100px;">Hello</div>
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+window.setTimeout(function() {
+    let target = document.getElementById("target");
+    target.parentElement.removeChild(target);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}, 20);
+</script>
+</body>
+</html>
index c484b88..f82f1ae 100644 (file)
@@ -1,3 +1,56 @@
+2018-11-06  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Implement text-underline-offset and text-decoration-thickness
+        https://bugs.webkit.org/show_bug.cgi?id=190774
+
+        Reviewed by Dean Jackson.
+
+        Because of our existing infrastructure for text decorations, adding support for these
+        is fairly simple. This patch updates our existing functions to handle thick & placed
+        underlines, as well as updating our repaint code to correcly handle repainting them.
+        It also handles animations.
+
+        Tests: animations/text-decoration-thickness.html
+               animations/text-underline-offset.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset-2.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset-3.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset-auto-length.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset-baseline.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-auto.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset-from-font-length.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset-repaint.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset-under-auto.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset-under-length.html
+               fast/css3-text/css3-text-decoration/text-decoration-offset.html
+               fast/css3-text/css3-text-decoration/text-decoration-thickness-length.html
+               fast/css3-text/css3-text-decoration/text-decoration-thickness-repaint.html
+
+        * page/animation/CSSPropertyAnimation.cpp:
+        (WebCore::blendFunc):
+        (WebCore::CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap):
+        * platform/graphics/FontMetrics.h:
+        (WebCore::FontMetrics::underlinePosition const):
+        (WebCore::FontMetrics::setUnderlinePosition):
+        (WebCore::FontMetrics::underlineThickness const):
+        (WebCore::FontMetrics::setUnderlineThickness):
+        * platform/graphics/cocoa/FontCocoa.mm:
+        (WebCore::Font::platformInit):
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::addToLine):
+        * rendering/SimpleLineLayout.cpp:
+        (WebCore::SimpleLineLayout::canUseForStyle):
+        * rendering/TextDecorationPainter.cpp:
+        (WebCore::TextDecorationPainter::paintTextDecoration):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::changeAffectsVisualOverflow const):
+        * rendering/style/TextDecorationThickness.h:
+        (WebCore::TextDecorationThickness::resolve const):
+        * style/InlineTextBoxStyle.cpp:
+        (WebCore::computeUnderlineOffset):
+        (WebCore::visualOverflowForDecorations):
+        * style/InlineTextBoxStyle.h:
+        (WebCore::textDecorationStrokeThickness): Deleted.
+
 2018-11-06  John Wilander  <wilander@apple.com>
 
         Resource Load Statistics: Remove cap on partitioned cache max age if it matches a network reload (redirect-only)
index d651d56..b462b9f 100644 (file)
@@ -260,6 +260,20 @@ static inline Visibility blendFunc(const CSSPropertyBlendingClient* anim, Visibi
     return result > 0. ? Visibility::Visible : (to != Visibility::Visible ? to : from);
 }
 
+static inline TextUnderlineOffset blendFunc(const CSSPropertyBlendingClient* anim, const TextUnderlineOffset& from, const TextUnderlineOffset& to, double progress)
+{
+    if (from.isLength() && to.isLength())
+        return TextUnderlineOffset::createWithLength(blendFunc(anim, from.lengthValue(), to.lengthValue(), progress));
+    return TextUnderlineOffset::createWithAuto();
+}
+
+static inline TextDecorationThickness blendFunc(const CSSPropertyBlendingClient* anim, const TextDecorationThickness& from, const TextDecorationThickness& to, double progress)
+{
+    if (from.isLength() && to.isLength())
+        return TextDecorationThickness::createWithLength(blendFunc(anim, from.lengthValue(), to.lengthValue(), progress));
+    return TextDecorationThickness::createWithAuto();
+}
+
 static inline LengthBox blendFunc(const CSSPropertyBlendingClient* anim, const LengthBox& from, const LengthBox& to, double progress)
 {
     LengthBox result(blendFunc(anim, from.top(), to.top(), progress),
@@ -1685,6 +1699,8 @@ CSSPropertyAnimationWrapperMap::CSSPropertyAnimationWrapperMap()
         new PropertyWrapper<FontSelectionValue>(CSSPropertyFontWeight, &RenderStyle::fontWeight, &RenderStyle::setFontWeight),
         new PropertyWrapper<FontSelectionValue>(CSSPropertyFontStretch, &RenderStyle::fontStretch, &RenderStyle::setFontStretch),
         new PropertyWrapperFontStyle(),
+        new PropertyWrapper<TextDecorationThickness>(CSSPropertyTextDecorationThickness, &RenderStyle::textDecorationThickness, &RenderStyle::setTextDecorationThickness),
+        new PropertyWrapper<TextUnderlineOffset>(CSSPropertyTextUnderlineOffset, &RenderStyle::textUnderlineOffset, &RenderStyle::setTextUnderlineOffset),
     };
     const unsigned animatableLonghandPropertiesCount = WTF_ARRAY_LENGTH(animatableLonghandPropertyWrappers);
 
index e8ddecd..b10fe5b 100644 (file)
@@ -102,6 +102,12 @@ public:
     float zeroWidth() const { return m_zeroWidth; }
     void setZeroWidth(float zeroWidth) { m_zeroWidth = zeroWidth; }
 
+    float underlinePosition() const { return m_underlinePosition; }
+    void setUnderlinePosition(float underlinePosition) { m_underlinePosition = underlinePosition; }
+
+    float underlineThickness() const { return m_underlineThickness; }
+    void setUnderlineThickness(float underlineThickness) { m_underlineThickness = underlineThickness; }
+
 private:
     friend class Font;
 
@@ -125,6 +131,8 @@ private:
     float m_zeroWidth { 0 };
     float m_xHeight { 0 };
     float m_capHeight { 0 };
+    float m_underlinePosition { 0 };
+    float m_underlineThickness { 0 };
 };
 
 static inline float scaleEmToUnits(float x, unsigned unitsPerEm)
index d9a699f..5d43000 100644 (file)
@@ -198,6 +198,8 @@ void Font::platformInit()
     m_fontMetrics.setLineGap(lineGap);
     m_fontMetrics.setXHeight(xHeight);
     m_fontMetrics.setLineSpacing(lineSpacing);
+    m_fontMetrics.setUnderlinePosition(-CTFontGetUnderlinePosition(m_platformData.font()));
+    m_fontMetrics.setUnderlineThickness(CTFontGetUnderlineThickness(m_platformData.font()));
 }
 
 void Font::platformCharWidthInit()
index 09501f7..d745811 100644 (file)
@@ -163,7 +163,7 @@ void InlineFlowBox::addToLine(InlineBox* child)
                 const auto* textBox = downcast<InlineTextBox>(child);
                 hasMarkers = textBox->hasMarkers();
             }
-            if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMark::None || childStyle->hasPositiveStrokeWidth() || hasMarkers)
+            if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMark::None || childStyle->hasPositiveStrokeWidth() || hasMarkers || !childStyle->textUnderlineOffset().isAuto() || !childStyle->textDecorationThickness().isAuto() || childStyle->textUnderlinePosition() != TextUnderlinePosition::Auto)
                 child->clearKnownToHaveNoOverflow();
         } else if (child->renderer().isReplaced()) {
             const RenderBox& box = downcast<RenderBox>(child->renderer());
index e3fea3f..f10fc46 100644 (file)
@@ -201,7 +201,7 @@ static AvoidanceReasonFlags canUseForStyle(const RenderStyle& style, IncludeReas
     AvoidanceReasonFlags reasons = { };
     if (style.textOverflow() == TextOverflow::Ellipsis)
         SET_REASON_AND_RETURN_IF_NEEDED(FlowHasTextOverflow, reasons, includeReasons);
-    if ((style.textDecorationsInEffect() & TextDecoration::Underline) && style.textUnderlinePosition() == TextUnderlinePosition::Under)
+    if ((style.textDecorationsInEffect() & TextDecoration::Underline) && (style.textUnderlinePosition() != TextUnderlinePosition::Auto || !style.textUnderlineOffset().isAuto() || !style.textDecorationThickness().isAuto()))
         SET_REASON_AND_RETURN_IF_NEEDED(FlowHasUnsupportedUnderlineDecoration, reasons, includeReasons);
     // Non-visible overflow should be pretty easy to support.
     if (style.overflowX() != Overflow::Visible || style.overflowY() != Overflow::Visible)
index 858e2f7..bfc9ee5 100644 (file)
@@ -211,7 +211,7 @@ TextDecorationPainter::TextDecorationPainter(GraphicsContext& context, OptionSet
 void TextDecorationPainter::paintTextDecoration(const TextRun& textRun, const FloatPoint& textOrigin, const FloatPoint& boxOrigin)
 {
     const auto& fontMetrics = m_lineStyle.fontMetrics();
-    float textDecorationThickness = textDecorationStrokeThickness(m_lineStyle.computedFontPixelSize());
+    float textDecorationThickness = m_lineStyle.textDecorationThickness().resolve(m_lineStyle.computedFontSize(), fontMetrics);
     FloatPoint localOrigin = boxOrigin;
 
     auto paintDecoration = [&] (TextDecoration decoration, TextDecorationStyle style, const Color& color, const FloatRect& rect) {
@@ -285,7 +285,9 @@ void TextDecorationPainter::paintTextDecoration(const TextRun& textRun, const Fl
 
         // These decorations should match the visual overflows computed in visualOverflowForDecorations().
         if (m_decorations.contains(TextDecoration::Underline)) {
-            int offset = computeUnderlineOffset(m_lineStyle.textUnderlinePosition(), m_lineStyle.fontMetrics(), m_inlineTextBox, textDecorationThickness);
+            float textDecorationBaseFontSize = 16;
+            auto defaultGap = m_lineStyle.computedFontSize() / textDecorationBaseFontSize;
+            int offset = computeUnderlineOffset(m_lineStyle.textUnderlinePosition(), m_lineStyle.textUnderlineOffset(), m_lineStyle.fontMetrics(), m_inlineTextBox, defaultGap);
             float wavyOffset = m_styles.underlineStyle == TextDecorationStyle::Wavy ? m_wavyOffset : 0;
             FloatRect rect(localOrigin, FloatSize(m_width, textDecorationThickness));
             rect.move(0, offset + wavyOffset);
index c852588..cfdb7b5 100644 (file)
@@ -536,14 +536,11 @@ inline bool RenderStyle::changeAffectsVisualOverflow(const RenderStyle& other) c
         return true;
 
     if (m_inheritedFlags.textDecorations != other.m_inheritedFlags.textDecorations
-        || m_visualData->textDecoration != other.m_visualData->textDecoration
-        || m_rareNonInheritedData->textDecorationStyle != other.m_rareNonInheritedData->textDecorationStyle) {
-        // Underlines are always drawn outside of their textbox bounds when text-underline-position: under;
-        // 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);
+        || m_rareNonInheritedData->textDecorationStyle != other.m_rareNonInheritedData->textDecorationStyle
+        || m_rareInheritedData->textDecorationThickness != other.m_rareInheritedData->textDecorationThickness
+        || m_rareInheritedData->textUnderlineOffset != other.m_rareInheritedData->textUnderlineOffset
+        || m_rareInheritedData->textUnderlinePosition != other.m_rareInheritedData->textUnderlinePosition) {
+        return true;
     }
 
     if (hasOutlineInVisualOverflow() != other.hasOutlineInVisualOverflow())
index 98070fc..96b3b4b 100644 (file)
@@ -75,6 +75,18 @@ public:
         return m_length;
     }
 
+    float resolve(float fontSize, const FontMetrics& metrics) const
+    {
+        if (isAuto()) {
+            const float textDecorationBaseFontSize = 16;
+            return fontSize / textDecorationBaseFontSize;
+        }
+        if (isFromFont())
+            return metrics.underlineThickness();
+        ASSERT(isLength());
+        return m_length;
+    }
+
     bool operator==(const TextDecorationThickness& other) const
     {
         switch (m_type) {
index 587545a..1355f52 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace WebCore {
     
-int computeUnderlineOffset(TextUnderlinePosition underlinePosition, const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, int textDecorationThickness)
+int computeUnderlineOffset(TextUnderlinePosition underlinePosition, TextUnderlineOffset underlineOffset, const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, int textDecorationThickness)
 {
     // This represents the gap between the baseline and the closest edge of the underline.
     int gap = std::max<int>(1, ceilf(textDecorationThickness / 2.0));
@@ -48,7 +48,7 @@ int computeUnderlineOffset(TextUnderlinePosition underlinePosition, const FontMe
     // case.
     
     auto resolvedUnderlinePosition = underlinePosition;
-    if (resolvedUnderlinePosition == TextUnderlinePosition::Auto) {
+    if (resolvedUnderlinePosition == TextUnderlinePosition::Auto && underlineOffset.isAuto()) {
         if (inlineTextBox)
             resolvedUnderlinePosition = inlineTextBox->root().baselineType() == IdeographicBaseline ? TextUnderlinePosition::Under : TextUnderlinePosition::Auto;
         else
@@ -57,8 +57,11 @@ int computeUnderlineOffset(TextUnderlinePosition underlinePosition, const FontMe
     
     switch (resolvedUnderlinePosition) {
     case TextUnderlinePosition::Auto:
+        if (underlineOffset.isAuto())
+            return fontMetrics.ascent() + gap;
+        return fontMetrics.ascent() + underlineOffset.lengthValue();
     case TextUnderlinePosition::FromFont:
-        return fontMetrics.ascent() + gap;
+        return fontMetrics.ascent() + fontMetrics.underlinePosition() + underlineOffset.lengthOr(0);
     case TextUnderlinePosition::Under: {
         ASSERT(inlineTextBox);
         // Position underline relative to the bottom edge of the lowest element's content box.
@@ -75,7 +78,7 @@ int computeUnderlineOffset(TextUnderlinePosition underlinePosition, const FontMe
             rootBox.maxLogicalBottomForTextDecorationLine(offset, decorationRenderer, TextDecoration::Underline);
             offset -= inlineTextBox->logicalBottom();
         }
-        return inlineTextBox->logicalHeight() + gap + std::max<float>(offset, 0);
+        return inlineTextBox->logicalHeight() + gap + std::max<float>(offset, 0) + underlineOffset.lengthOr(0);
     }
     }
 
@@ -105,7 +108,7 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
     if (decoration.isEmpty())
         return GlyphOverflow();
 
-    float strokeThickness = textDecorationStrokeThickness(lineStyle.computedFontPixelSize());
+    float strokeThickness = lineStyle.textDecorationThickness().resolve(lineStyle.computedFontSize(), lineStyle.fontMetrics());
     WavyStrokeParameters wavyStrokeParameters;
     float wavyOffset = 0;
         
@@ -124,7 +127,9 @@ GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const I
     if (decoration & TextDecoration::Underline) {
         // Compensate for the integral ceiling in GraphicsContext::computeLineBoundsAndAntialiasingModeForText()
         int underlineOffset = 1;
-        underlineOffset += computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), inlineTextBox, strokeThickness);
+        float textDecorationBaseFontSize = 16;
+        auto defaultGap = lineStyle.computedFontSize() / textDecorationBaseFontSize;
+        underlineOffset += computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.textUnderlineOffset(), lineStyle.fontMetrics(), inlineTextBox, defaultGap);
         if (decorationStyle == TextDecorationStyle::Wavy) {
             extendIntToFloat(overflowResult.bottom, underlineOffset + wavyOffset + wavyStrokeParameters.controlPointDistance + strokeThickness - height);
             extendIntToFloat(overflowResult.top, -(underlineOffset + wavyOffset - wavyStrokeParameters.controlPointDistance - strokeThickness));
index cb06fd1..8730b2c 100644 (file)
@@ -33,12 +33,6 @@ namespace WebCore {
 class InlineTextBox;
 class RenderStyle;
 
-inline float textDecorationStrokeThickness(float fontSize)
-{
-    const float textDecorationBaseFontSize = 16;
-    return fontSize / textDecorationBaseFontSize;
-}
-
 inline float wavyOffsetFromDecoration()
 {
     return 1;
@@ -57,6 +51,6 @@ struct WavyStrokeParameters {
 };
 WavyStrokeParameters getWavyStrokeParameters(float fontSize);
 GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, const InlineTextBox*);
-int computeUnderlineOffset(TextUnderlinePosition, const FontMetrics&, const InlineTextBox*, int textDecorationThickness);
+int computeUnderlineOffset(TextUnderlinePosition, TextUnderlineOffset, const FontMetrics&, const InlineTextBox*, int textDecorationThickness);
     
 } // namespace WebCore