<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[169089] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/169089">169089</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2014-05-19 17:45:52 -0700 (Mon, 19 May 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Text decorations do not contribute to visual overflow
https://bugs.webkit.org/show_bug.cgi?id=132773
Patch by Myles C. Maxfield <litherum@gmail.com> on 2014-05-19
Reviewed by Antti Koivisto.
Source/WebCore:
This patch creates a function, visualOverflowForDecorations, which computes
how much visual overflow to add around a text box due to text decorations. Most of the time,
text decorations are fully contained within the text box, so the result is usually 0.
This function exists within style/InlineTextBoxStyle.cpp, which is an added file. This is
so that it can be called from setLogicalWidthForTextRun() inside RenderBlockLineLayout.cpp
and from RenderStyle::changeAffectsVisualOverflow(). The former case passes in the full
InlineTextBox and the latter case just passes in a RenderStyle (because the InlineTextBox
is unavailable.)
This patch also modifies RenderTableSection::spannedColumns() to fix an off-by-one error
that was causing table borders to not be drawn when they existed right on the edge of
a repaint rect.
Tests: fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html
Tests: fast/repaint/border-collapse-table-off-by-one-expected.html
* WebCore.vcxproj/WebCore.vcxproj: Adding reference to new InlineTextBoxStyle.cpp file
* WebCore.vcxproj/WebCore.vcxproj.filters: Adding reference to new InlineTextBoxStyle files
* WebCore.xcodeproj/project.pbxproj: Adding reference to new InlineTextBoxStyle files
* rendering/InlineTextBox.cpp:
(WebCore::computeUnderlineOffset): Moved to InlineTextBox.cpp
(WebCore::getWavyStrokeParameters): Moved to InlineTextBox.cpp
(WebCore::InlineTextBox::paintDecoration): Update to use newly refactored functions
* rendering/RenderBlockLineLayout.cpp:
(WebCore::setLogicalWidthForTextRun): Call visualOverflowForDecorations()
* rendering/RenderTableSection.cpp:
* rendering/RenderTableSelection.cpp: Fix off-by-one error when the boundary of a repaint
rect lies exactly on top of a table column position
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeAffectsVisualOverflow): Inspects shadows and text decorations
(WebCore::RenderStyle::changeRequiresLayout): Calls changeAffectsVisualOverflow()
(WebCore::RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline): Moved code from here
to changeAffectsVisualOverflow().
* rendering/style/RenderStyle.h: Function signature
* style/InlineTextBoxStyle.cpp: Added.
(WebCore::computeUnderlineOffset): Moved from InlineTextBox.cpp
(WebCore::getWavyStrokeParameters): Moved from InlineTextBox.cpp
(WebCore::extendIntToFloat): Convenience function for dealing with the fact that
underline bounding boxes use floats and GlyphOverflow uses ints
(WebCore::visualOverflowForDecorations): Given
vertical overflow bounds, possibly extend those to include location of
decorations.
* style/InlineTextBoxStyle.h: Added. Function signatures.
(WebCore::textDecorationStrokeThickness): Refactored from InlineTextBox.cpp
(WebCore::wavyOffsetFromDecoration): Refactored from InlineTextBox.cpp
* platform/graphics/Font.h:
(WebCore::GlyphOverflow::isEmpty): Convenience function
(WebCore::GlyphOverflow::extendTo): Convenience function
LayoutTests:
This first test makes sure that repaint rects are extended to include text decorations that may
lie outside of the text layout rects. It compares text with an underline to text that has
had underline applied to it in a timer.
The second test triggers an off-by-one error in collapsed table borders where a border was not
being drawn if it lay right on top of a repaint rect.
* fast/css3-text/css3-text-decoration/repaint/resources/Litherum.svg: Added. This font has a
descent of 0 (so it will not intersect underlines).
* fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html: Added.
Apply the underline without any timeout.
* fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html: Added.
Apply the underline with a timeout.
* fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed-expected.html: Added.
Draw text without decorations.
* fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed.html: Added.
Draw text with decorations which contribute to overflow, then remove those decorations on a timer.
* fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered-expected.html: Added.
Draw text as if the final state of the decorations had always existed.
* fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered.html: Added.
Make sure that modifying decorations that contribute to overflow redraw properly.
* fast/repaint/border-collapse-table-off-by-one-expected.html: Added.
* fast/repaint/border-collapse-table-off-by-one.html: Added. Trigger the off-by-one error in
RenderTableSection.cpp</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxproj">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj</a></li>
<li><a href="#trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters">trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFonth">trunk/Source/WebCore/platform/graphics/Font.h</a></li>
<li><a href="#trunkSourceWebCorerenderingInlineTextBoxcpp">trunk/Source/WebCore/rendering/InlineTextBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockLineLayoutcpp">trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTableSectioncpp">trunk/Source/WebCore/rendering/RenderTableSection.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTableSectionh">trunk/Source/WebCore/rendering/RenderTableSection.h</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleRenderStylecpp">trunk/Source/WebCore/rendering/style/RenderStyle.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingstyleRenderStyleh">trunk/Source/WebCore/rendering/style/RenderStyle.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/resources/</li>
<li><a href="#trunkLayoutTestsfastcss3textcss3textdecorationrepaintresourcesLitherumsvg">trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/resources/Litherum.svg</a></li>
<li><a href="#trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectalteredexpectedhtml">trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectalteredhtml">trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered.html</a></li>
<li><a href="#trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectexpectedhtml">trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectremovedexpectedhtml">trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectremovedhtml">trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed.html</a></li>
<li><a href="#trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrecthtml">trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html</a></li>
<li><a href="#trunkLayoutTestsfastrepaintbordercollapsetableoffbyoneexpectedhtml">trunk/LayoutTests/fast/repaint/border-collapse-table-off-by-one-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastrepaintbordercollapsetableoffbyonehtml">trunk/LayoutTests/fast/repaint/border-collapse-table-off-by-one.html</a></li>
<li><a href="#trunkSourceWebCorestyleInlineTextBoxStylecpp">trunk/Source/WebCore/style/InlineTextBoxStyle.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleInlineTextBoxStyleh">trunk/Source/WebCore/style/InlineTextBoxStyle.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/LayoutTests/ChangeLog        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2014-05-19 Myles C. Maxfield <litherum@gmail.com>
+
+ Text decorations do not contribute to visual overflow
+ https://bugs.webkit.org/show_bug.cgi?id=132773
+
+ Reviewed by Antti Koivisto.
+
+ This first test makes sure that repaint rects are extended to include text decorations that may
+ lie outside of the text layout rects. It compares text with an underline to text that has
+ had underline applied to it in a timer.
+
+ The second test triggers an off-by-one error in collapsed table borders where a border was not
+ being drawn if it lay right on top of a repaint rect.
+
+ * fast/css3-text/css3-text-decoration/repaint/resources/Litherum.svg: Added. This font has a
+ descent of 0 (so it will not intersect underlines).
+ * fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html: Added.
+ Apply the underline without any timeout.
+ * fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html: Added.
+ Apply the underline with a timeout.
+ * fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed-expected.html: Added.
+ Draw text without decorations.
+ * fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed.html: Added.
+ Draw text with decorations which contribute to overflow, then remove those decorations on a timer.
+ * fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered-expected.html: Added.
+ Draw text as if the final state of the decorations had always existed.
+ * fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered.html: Added.
+ Make sure that modifying decorations that contribute to overflow redraw properly.
+ * fast/repaint/border-collapse-table-off-by-one-expected.html: Added.
+ * fast/repaint/border-collapse-table-off-by-one.html: Added. Trigger the off-by-one error in
+ RenderTableSection.cpp
+
</ins><span class="cx"> 2014-05-19 Chris Fleizach <cfleizach@apple.com>
</span><span class="cx">
</span><span class="cx"> AX: VoiceOver sees the WebArea out of order when topContentInset is used
</span></span></pre></div>
<a id="trunkLayoutTestsfastcss3textcss3textdecorationrepaintresourcesLitherumsvg"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/resources/Litherum.svg (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/resources/Litherum.svg         (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/resources/Litherum.svg        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="Litherum" horiz-adv-x="1024">
+<font-face units-per-em="14" ascent="14" descent="0"/>
+<glyph unicode="|" horiz-adv-x="14" d="M0 0v14h14v-14z"/>
+<glyph unicode="-" horiz-adv-x="266" d="M0 0v14h266v-14z"/>
+</font>
+</defs>
+</svg>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectalteredexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered-expected.html (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered-expected.html         (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered-expected.html        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: 'Litherum';
+ src: url("./resources/Litherum.svg") format(svg)
+}
+div {
+ font-family: 'Litherum';
+ -webkit-text-decoration-skip: none;
+ -webkit-text-decoration-color: green;
+ width: 1px;
+ height: 1px;
+}
+</style>
+</head>
+<body>
+This test makes sure that underlines contribute to visual overflow properly.
+The SVG font has a descent of 0, which means that underlines will
+lie outside of the glyph boundaries. The test makes sure of two things:
+<ol>
+<li>(Left box) That moving a decoration that contributes to overflow from
+the top of a line to the bottom is redrawn as if it was always on the bottom
+side</li>
+<li>(Right box) That moving a decoration that contributes to overflow to a position where
+it does not contribute to overflow anymore redraws as if it had never
+contributed to overflow</li>
+</ol>
+<div style="position: relative; height: 45px;">
+<div id="wavyoverline" style="font-size: 100px; position: absolute; left: 60px; top: 20px; text-decoration: underline; -webkit-text-underline-position: under">|</div>
+<div id="underline" style="font-size: 100px; position: absolute; left: 180px; top: 20px; text-decoration: line-through;">|</div>
+</div>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectalteredhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered.html (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered.html         (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-altered.html        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: 'Litherum';
+ src: url("./resources/Litherum.svg") format(svg)
+}
+div {
+ font-family: 'Litherum';
+ -webkit-text-decoration-skip: none;
+ -webkit-text-decoration-color: green;
+ width: 1px;
+ height: 1px;
+}
+</style>
+</head>
+<body>
+This test makes sure that underlines contribute to visual overflow properly.
+The SVG font has a descent of 0, which means that underlines will
+lie outside of the glyph boundaries. The test makes sure of two things:
+<ol>
+<li>(Left box) That moving a decoration that contributes to overflow from
+the top of a line to the bottom is redrawn as if it was always on the bottom
+side</li>
+<li>(Right box) That moving a decoration that contributes to overflow to a position where
+it does not contribute to overflow anymore redraws as if it had never
+contributed to overflow</li>
+</ol>
+<div style="position: relative; height: 45px;">
+<div id="wavyoverline" style="font-size: 100px; position: absolute; left: 60px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: overline; -webkit-text-underline-position: under">|</div>
+<div id="underline" style="font-size: 100px; position: absolute; left: 180px; top: 20px; text-decoration: underline; -webkit-text-underline-position: under">|</div>
+</div>
+<script>
+function applyUnderline() {
+ document.getElementById('wavyoverline').style.textDecoration = "underline";
+ document.getElementById('wavyoverline').style.webkitTextDecorationStyle = "solid";
+ document.getElementById('underline').style.textDecoration = "line-through";
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+
+if (window.testRunner)
+ testRunner.waitUntilDone();
+window.setTimeout(applyUnderline, 17);
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html         (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: 'Litherum';
+ src: url("./resources/Litherum.svg") format(svg)
+}
+div {
+ font-family: 'Litherum';
+ -webkit-text-decoration-skip: none;
+ -webkit-text-decoration-color: green;
+ width: 1px;
+ height: 1px;
+}
+</style>
+</head>
+<body>
+This test makes sure that underlines contribute to visual overflow.
+The SVG font has a descent of 0, which means that underlines will
+lie outside of the glyph boundaries. The test makes sure that
+drawing underlined text ends up the same as drawing text that has
+had the underline retroactively applied to it with javascript.
+<div style="position: relative; height: 45px;">
+<div id="underline" style="position: absolute; left: 0px; top: 0px; text-decoration: underline;">|</div>
+<div id="underlineunder" style="position: absolute; left: 20px; top: 0px; -webkit-text-underline-position: under; text-decoration: underline">|</div>
+<div id="linethrough" style="position: absolute; left: 40px; top: 0px; text-decoration: line-through;">|</div>
+<div id="overline" style="position: absolute; left: 60px; top: 0px; text-decoration: overline;">|</div>
+
+<div id="wavyunderline" style="position: absolute; left: 0px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: underline;">|</div>
+<div id="wavyunderlineunder" style="position: absolute; left: 20px; top: 20px; -webkit-text-underline-position: under; -webkit-text-decoration-style: wavy; text-decoration: underline;">|</div>
+<div id="wavylinethrough" style="font-size: 1px; position: absolute; left: 40px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: line-through;">-</div>
+<div id="wavyoverline" style="position: absolute; left: 60px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: overline;">|</div>
+</div>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectremovedexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed-expected.html (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed-expected.html         (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed-expected.html        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: 'Litherum';
+ src: url("./resources/Litherum.svg") format(svg)
+}
+div {
+ font-family: 'Litherum';
+ -webkit-text-decoration-skip: none;
+ -webkit-text-decoration-color: green;
+ width: 1px;
+ height: 1px;
+}
+</style>
+</head>
+<body>
+This test makes sure that underlines contribute to visual overflow properly.
+The SVG font has a descent of 0, which means that underlines will
+lie outside of the glyph boundaries. The test makes sure that
+removing decorations which contribute to visual overflow matches how the
+text would have been drawn as if the decorations had never existed.
+<div style="position: relative; height: 45px;">
+<div id="underline" style="position: absolute; left: 0px; top: 0px;">|</div>
+<div id="underlineunder" style="position: absolute; left: 20px; top: 0px; -webkit-text-underline-position: under;">|</div>
+<div id="linethrough" style="position: absolute; left: 40px; top: 0px;">|</div>
+<div id="overline" style="position: absolute; left: 60px; top: 0px;">|</div>
+
+<div id="wavyunderline" style="position: absolute; left: 0px; top: 20px; -webkit-text-decoration-style: wavy;">|</div>
+<div id="wavyunderlineunder" style="position: absolute; left: 20px; top: 20px; -webkit-text-underline-position: under; -webkit-text-decoration-style: wavy;">|</div>
+<div id="wavylinethrough" style="font-size: 1px; position: absolute; left: 40px; top: 20px; -webkit-text-decoration-style: wavy;">-</div>
+<div id="wavyoverline" style="position: absolute; left: 60px; top: 20px; -webkit-text-decoration-style: wavy;">|</div>
+</div>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrectremovedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed.html (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed.html         (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-removed.html        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: 'Litherum';
+ src: url("./resources/Litherum.svg") format(svg)
+}
+div {
+ font-family: 'Litherum';
+ -webkit-text-decoration-skip: none;
+ -webkit-text-decoration-color: green;
+ width: 1px;
+ height: 1px;
+}
+</style>
+</head>
+<body>
+This test makes sure that underlines contribute to visual overflow properly.
+The SVG font has a descent of 0, which means that underlines will
+lie outside of the glyph boundaries. The test makes sure that
+removing decorations which contribute to visual overflow matches how the
+text would have been drawn as if the decorations had never existed.
+<div style="position: relative; height: 45px;">
+<div id="underline" style="position: absolute; left: 0px; top: 0px; text-decoration: underline;">|</div>
+<div id="underlineunder" style="position: absolute; left: 20px; top: 0px; -webkit-text-underline-position: under; text-decoration: underline">|</div>
+<div id="linethrough" style="position: absolute; left: 40px; top: 0px; text-decoration: line-through;">|</div>
+<div id="overline" style="position: absolute; left: 60px; top: 0px; text-decoration: overline;">|</div>
+
+<div id="wavyunderline" style="position: absolute; left: 0px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: underline;">|</div>
+<div id="wavyunderlineunder" style="position: absolute; left: 20px; top: 20px; -webkit-text-underline-position: under; -webkit-text-decoration-style: wavy; text-decoration: underline;">|</div>
+<div id="wavylinethrough" style="font-size: 1px; position: absolute; left: 40px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: line-through;">-</div>
+<div id="wavyoverline" style="position: absolute; left: 60px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: overline;">|</div>
+</div>
+<script>
+function applyUnderline() {
+ document.getElementById('underline').style.textDecoration = "none";
+ document.getElementById('underlineunder').style.textDecoration = "none";
+ document.getElementById('linethrough').style.textDecoration = "none";
+ document.getElementById('overline').style.textDecoration = "none";
+ document.getElementById('wavyunderline').style.textDecoration = "none";
+ document.getElementById('wavyunderlineunder').style.textDecoration = "none";
+ document.getElementById('wavylinethrough').style.textDecoration = "none";
+ document.getElementById('wavyoverline').style.textDecoration = "none";
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+
+if (window.testRunner)
+ testRunner.waitUntilDone();
+window.setTimeout(applyUnderline, 17);
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastcss3textcss3textdecorationrepaintunderlineoutsideoflayoutrecthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html         (rev 0)
+++ trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+ font-family: 'Litherum';
+ src: url("./resources/Litherum.svg") format(svg)
+}
+div {
+ font-family: 'Litherum';
+ -webkit-text-decoration-skip: none;
+ -webkit-text-decoration-color: green;
+ width: 1px;
+ height: 1px;
+}
+</style>
+</head>
+<body>
+This test makes sure that underlines contribute to visual overflow.
+The SVG font has a descent of 0, which means that underlines will
+lie outside of the glyph boundaries. The test makes sure that
+drawing underlined text ends up the same as drawing text that has
+had the underline retroactively applied to it with javascript.
+<div style="position: relative; height: 45px;">
+<div id="underline" style="position: absolute; left: 0px; top: 0px;">|</div>
+<div id="underlineunder" style="position: absolute; left: 20px; top: 0px; -webkit-text-underline-position: under;">|</div>
+<div id="linethrough" style="position: absolute; left: 40px; top: 0px;">|</div>
+<div id="overline" style="position: absolute; left: 60px; top: 0px;">|</div>
+
+<div id="wavyunderline" style="position: absolute; left: 0px; top: 20px; -webkit-text-decoration-style: wavy;">|</div>
+<div id="wavyunderlineunder" style="position: absolute; left: 20px; top: 20px; -webkit-text-underline-position: under; -webkit-text-decoration-style: wavy;">|</div>
+<div id="wavylinethrough" style="font-size: 1px; position: absolute; left: 40px; top: 20px; -webkit-text-decoration-style: wavy;">-</div>
+<div id="wavyoverline" style="position: absolute; left: 60px; top: 20px; -webkit-text-decoration-style: wavy;">|</div>
+</div>
+<script>
+function applyUnderline() {
+ document.getElementById('underline').style.textDecoration = "underline";
+ document.getElementById('underlineunder').style.textDecoration = "underline";
+ document.getElementById('linethrough').style.textDecoration = "line-through";
+ document.getElementById('overline').style.textDecoration = "overline";
+ document.getElementById('wavyunderline').style.textDecoration = "underline";
+ document.getElementById('wavyunderlineunder').style.textDecoration = "underline";
+ document.getElementById('wavylinethrough').style.textDecoration = "line-through";
+ document.getElementById('wavyoverline').style.textDecoration = "overline";
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+
+if (window.testRunner)
+ testRunner.waitUntilDone();
+window.setTimeout(applyUnderline, 17);
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastrepaintbordercollapsetableoffbyoneexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/repaint/border-collapse-table-off-by-one-expected.html (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/repaint/border-collapse-table-off-by-one-expected.html         (rev 0)
+++ trunk/LayoutTests/fast/repaint/border-collapse-table-off-by-one-expected.html        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+table {
+ border-collapse: collapse;
+}
+a:link,
+a:visited,
+a:link:hover,
+a:visited:hover {
+ text-decoration: underline;
+}
+</style>
+</head>
+<body>
+This next test makes sure that grown repaint rects interact nicely with table border-collapse:collapse.
+<table border="1">
+<tbody>
+<tr>
+<td>C</td>
+<td><a id="l" href="http://www.apple.com/">1</a></td>
+</tr>
+</tbody>
+</table>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastrepaintbordercollapsetableoffbyonehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/repaint/border-collapse-table-off-by-one.html (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/repaint/border-collapse-table-off-by-one.html         (rev 0)
+++ trunk/LayoutTests/fast/repaint/border-collapse-table-off-by-one.html        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<style>
+table {
+ border-collapse: collapse;
+}
+a:link,
+a:visited,
+a:link:hover,
+a:visited:hover {
+ text-decoration: none;
+}
+</style>
+</head>
+<body>
+This next test makes sure that grown repaint rects interact nicely with table border-collapse:collapse.
+<table border="1">
+<tbody>
+<tr>
+<td>C</td>
+<td><a id="l" href="http://www.apple.com/">1</a></td>
+</tr>
+</tbody>
+</table>
+<script>
+function applyUnderline() {
+ document.getElementById('l').style.textDecoration = "underline";
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+
+if (window.testRunner)
+ testRunner.waitUntilDone();
+window.setTimeout(applyUnderline, 17);
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/CMakeLists.txt        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -2477,6 +2477,7 @@
</span><span class="cx"> storage/StorageThread.cpp
</span><span class="cx"> storage/StorageTracker.cpp
</span><span class="cx">
</span><ins>+ style/InlineTextBoxStyle.cpp
</ins><span class="cx"> style/StyleFontSizeFunctions.cpp
</span><span class="cx"> style/StyleResolveForDocument.cpp
</span><span class="cx"> style/StyleResolveTree.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/ChangeLog        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -1,3 +1,60 @@
</span><ins>+2014-05-19 Myles C. Maxfield <litherum@gmail.com>
+
+ Text decorations do not contribute to visual overflow
+ https://bugs.webkit.org/show_bug.cgi?id=132773
+
+ Reviewed by Antti Koivisto.
+
+ This patch creates a function, visualOverflowForDecorations, which computes
+ how much visual overflow to add around a text box due to text decorations. Most of the time,
+ text decorations are fully contained within the text box, so the result is usually 0.
+
+ This function exists within style/InlineTextBoxStyle.cpp, which is an added file. This is
+ so that it can be called from setLogicalWidthForTextRun() inside RenderBlockLineLayout.cpp
+ and from RenderStyle::changeAffectsVisualOverflow(). The former case passes in the full
+ InlineTextBox and the latter case just passes in a RenderStyle (because the InlineTextBox
+ is unavailable.)
+
+ This patch also modifies RenderTableSection::spannedColumns() to fix an off-by-one error
+ that was causing table borders to not be drawn when they existed right on the edge of
+ a repaint rect.
+
+ Tests: fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html
+ Tests: fast/repaint/border-collapse-table-off-by-one-expected.html
+
+ * WebCore.vcxproj/WebCore.vcxproj: Adding reference to new InlineTextBoxStyle.cpp file
+ * WebCore.vcxproj/WebCore.vcxproj.filters: Adding reference to new InlineTextBoxStyle files
+ * WebCore.xcodeproj/project.pbxproj: Adding reference to new InlineTextBoxStyle files
+ * rendering/InlineTextBox.cpp:
+ (WebCore::computeUnderlineOffset): Moved to InlineTextBox.cpp
+ (WebCore::getWavyStrokeParameters): Moved to InlineTextBox.cpp
+ (WebCore::InlineTextBox::paintDecoration): Update to use newly refactored functions
+ * rendering/RenderBlockLineLayout.cpp:
+ (WebCore::setLogicalWidthForTextRun): Call visualOverflowForDecorations()
+ * rendering/RenderTableSection.cpp:
+ * rendering/RenderTableSelection.cpp: Fix off-by-one error when the boundary of a repaint
+ rect lies exactly on top of a table column position
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::changeAffectsVisualOverflow): Inspects shadows and text decorations
+ (WebCore::RenderStyle::changeRequiresLayout): Calls changeAffectsVisualOverflow()
+ (WebCore::RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline): Moved code from here
+ to changeAffectsVisualOverflow().
+ * rendering/style/RenderStyle.h: Function signature
+ * style/InlineTextBoxStyle.cpp: Added.
+ (WebCore::computeUnderlineOffset): Moved from InlineTextBox.cpp
+ (WebCore::getWavyStrokeParameters): Moved from InlineTextBox.cpp
+ (WebCore::extendIntToFloat): Convenience function for dealing with the fact that
+ underline bounding boxes use floats and GlyphOverflow uses ints
+ (WebCore::visualOverflowForDecorations): Given
+ vertical overflow bounds, possibly extend those to include location of
+ decorations.
+ * style/InlineTextBoxStyle.h: Added. Function signatures.
+ (WebCore::textDecorationStrokeThickness): Refactored from InlineTextBox.cpp
+ (WebCore::wavyOffsetFromDecoration): Refactored from InlineTextBox.cpp
+ * platform/graphics/Font.h:
+ (WebCore::GlyphOverflow::isEmpty): Convenience function
+ (WebCore::GlyphOverflow::extendTo): Convenience function
+
</ins><span class="cx"> 2014-05-19 Alex Christensen <achristensen@webkit.org>
</span><span class="cx">
</span><span class="cx"> Unreviewed build fix after r169082
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -17647,6 +17647,7 @@
</span><span class="cx"> <ClCompile Include="..\storage\StorageSyncManager.cpp" />
</span><span class="cx"> <ClCompile Include="..\storage\StorageThread.cpp" />
</span><span class="cx"> <ClCompile Include="..\storage\StorageTracker.cpp" />
</span><ins>+ <ClCompile Include="..\style\InlineTextBoxStyle.cpp" />
</ins><span class="cx"> <ClCompile Include="..\style\StyleFontSizeFunctions.cpp" />
</span><span class="cx"> <ClCompile Include="..\style\StyleResolveForDocument.cpp" />
</span><span class="cx"> <ClCompile Include="..\style\StyleResolveTree.cpp" />
</span><span class="lines">@@ -21039,6 +21040,7 @@
</span><span class="cx"> <ClInclude Include="..\storage\StorageSyncManager.h" />
</span><span class="cx"> <ClInclude Include="..\storage\StorageThread.h" />
</span><span class="cx"> <ClInclude Include="..\storage\StorageTracker.h" />
</span><ins>+ <ClInclude Include="..\style\InlineTextBoxStyle.h" />
</ins><span class="cx"> <ClInclude Include="..\style\StyleFontSizeFunctions.h" />
</span><span class="cx"> <ClInclude Include="..\style\StyleResolveForDocument.h" />
</span><span class="cx"> <ClInclude Include="..\style\StyleResolveTree.h" />
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorevcxprojWebCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -6778,6 +6778,9 @@
</span><span class="cx"> <ClCompile Include="..\dom\InlineStyleSheetOwner.cpp">
</span><span class="cx"> <Filter>dom</Filter>
</span><span class="cx"> </ClCompile>
</span><ins>+ <ClCompile Include="..\style\InlineTextBoxStyle.cpp">
+ <Filter>css</Filter>
+ </ClCompile>
</ins><span class="cx"> <ClCompile Include="..\style\StyleFontSizeFunctions.cpp">
</span><span class="cx"> <Filter>css</Filter>
</span><span class="cx"> </ClCompile>
</span><span class="lines">@@ -14628,6 +14631,9 @@
</span><span class="cx"> <ClInclude Include="..\style\StyleResolveTree.h">
</span><span class="cx"> <Filter>css</Filter>
</span><span class="cx"> </ClInclude>
</span><ins>+ <ClInclude Include="..\style\InlineTextBoxStyle.h">
+ <Filter>css</Filter>
+ </ClInclude>
</ins><span class="cx"> <ClInclude Include="..\style\StyleFontSizeFunctions.h">
</span><span class="cx"> <Filter>css</Filter>
</span><span class="cx"> </ClInclude>
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -904,6 +904,8 @@
</span><span class="cx">                 1AF8E1C3125673E000230FF7 /* ProxyServerCFNet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AF8E1C1125673E000230FF7 /* ProxyServerCFNet.cpp */; };
</span><span class="cx">                 1AFE11990CBFFCC4003017FA /* JSSQLResultSetRowList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFE11970CBFFCC4003017FA /* JSSQLResultSetRowList.cpp */; };
</span><span class="cx">                 1AFE119A0CBFFCC4003017FA /* JSSQLResultSetRowList.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AFE11980CBFFCC4003017FA /* JSSQLResultSetRowList.h */; };
</span><ins>+                1C010700192594DF008A4201 /* InlineTextBoxStyle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C0106FE192594DF008A4201 /* InlineTextBoxStyle.cpp */; };
+                1C010701192594DF008A4201 /* InlineTextBoxStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C0106FF192594DF008A4201 /* InlineTextBoxStyle.h */; };
</ins><span class="cx">                 1C11CCB50AA6093700DADB20 /* DOMNotation.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85CA96E80A9624E900690CCF /* DOMNotation.h */; };
</span><span class="cx">                 1C11CCB60AA6093700DADB20 /* DOMComment.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85089CD10A98C42700A275AA /* DOMComment.h */; };
</span><span class="cx">                 1C11CCB70AA6093700DADB20 /* DOMNamedNodeMap.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 8518DD760A9CF31B0091B7A6 /* DOMNamedNodeMap.h */; };
</span><span class="lines">@@ -7836,6 +7838,8 @@
</span><span class="cx">                 1AF8E1C1125673E000230FF7 /* ProxyServerCFNet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyServerCFNet.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 1AFE11970CBFFCC4003017FA /* JSSQLResultSetRowList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSQLResultSetRowList.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 1AFE11980CBFFCC4003017FA /* JSSQLResultSetRowList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSQLResultSetRowList.h; sourceTree = "<group>"; };
</span><ins>+                1C0106FE192594DF008A4201 /* InlineTextBoxStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineTextBoxStyle.cpp; sourceTree = "<group>"; };
+                1C0106FF192594DF008A4201 /* InlineTextBoxStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineTextBoxStyle.h; sourceTree = "<group>"; };
</ins><span class="cx">                 1C18DA56181AF6A500C4EF22 /* TextPainter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextPainter.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 1C18DA57181AF6A500C4EF22 /* TextPainter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextPainter.h; sourceTree = "<group>"; };
</span><span class="cx">                 1C21E57A183ED1FF001C289D /* IOSurfacePool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IOSurfacePool.cpp; path = ../cg/IOSurfacePool.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -21708,6 +21712,8 @@
</span><span class="cx">                                 E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */,
</span><span class="cx">                                 E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */,
</span><span class="cx">                                 E4DEAA1617A93DC3000E0430 /* StyleResolveTree.h */,
</span><ins>+                                1C0106FE192594DF008A4201 /* InlineTextBoxStyle.cpp */,
+                                1C0106FF192594DF008A4201 /* InlineTextBoxStyle.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = style;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -24982,6 +24988,7 @@
</span><span class="cx">                                 E1C36D350EB0A094007410BC /* JSWorkerGlobalScopeBase.h in Headers */,
</span><span class="cx">                                 E1C362EF0EAF2AA9007410BC /* JSWorkerLocation.h in Headers */,
</span><span class="cx">                                 E1271A580EEECDE400F61213 /* JSWorkerNavigator.h in Headers */,
</span><ins>+                                1C010701192594DF008A4201 /* InlineTextBoxStyle.h in Headers */,
</ins><span class="cx">                                 BC348BD40DB7F804004ABAB9 /* JSXMLHttpRequest.h in Headers */,
</span><span class="cx">                                 BC60DA3A0D2A302800B9918F /* JSXMLHttpRequestException.h in Headers */,
</span><span class="cx">                                 F916C48E0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.h in Headers */,
</span><span class="lines">@@ -28284,6 +28291,7 @@
</span><span class="cx">                                 B2FA3D380AB75A6F000E5AC4 /* JSSVGAnimatedAngle.cpp in Sources */,
</span><span class="cx">                                 B2FA3D3A0AB75A6F000E5AC4 /* JSSVGAnimatedBoolean.cpp in Sources */,
</span><span class="cx">                                 B2FA3D3C0AB75A6F000E5AC4 /* JSSVGAnimatedEnumeration.cpp in Sources */,
</span><ins>+                                1C010700192594DF008A4201 /* InlineTextBoxStyle.cpp in Sources */,
</ins><span class="cx">                                 B2FA3D3E0AB75A6F000E5AC4 /* JSSVGAnimatedInteger.cpp in Sources */,
</span><span class="cx">                                 B2FA3D400AB75A6F000E5AC4 /* JSSVGAnimatedLength.cpp in Sources */,
</span><span class="cx">                                 B2FA3D420AB75A6F000E5AC4 /* JSSVGAnimatedLengthList.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFonth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/Font.h (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/Font.h        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/platform/graphics/Font.h        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -69,6 +69,24 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ inline bool isEmpty()
+ {
+ return !left && !right && !top && !bottom;
+ }
+
+ inline void extendTo(const GlyphOverflow& other)
+ {
+ left = std::max(left, other.left);
+ right = std::max(right, other.right);
+ top = std::max(top, other.top);
+ bottom = std::max(bottom, other.bottom);
+ }
+
+ bool operator!=(const GlyphOverflow& other)
+ {
+ return left != other.left || right != other.right || top != other.top || bottom != other.bottom;
+ }
+
</ins><span class="cx"> int left;
</span><span class="cx"> int right;
</span><span class="cx"> int top;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingInlineTextBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/InlineTextBox.cpp        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include "GraphicsContext.h"
</span><span class="cx"> #include "HitTestResult.h"
</span><span class="cx"> #include "ImageBuffer.h"
</span><ins>+#include "InlineTextBoxStyle.h"
</ins><span class="cx"> #include "Page.h"
</span><span class="cx"> #include "PaintInfo.h"
</span><span class="cx"> #include "RenderedDocumentMarker.h"
</span><span class="lines">@@ -821,29 +822,6 @@
</span><span class="cx"> return strokeStyle;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition, const FontMetrics& fontMetrics, const InlineTextBox* inlineTextBox, const int textDecorationThickness)
-{
- // Compute the gap between the font and the underline. Use at least one
- // pixel gap, if underline is thick then use a bigger gap.
- const int gap = std::max<int>(1, ceilf(textDecorationThickness / 2.0));
-
- // According to the specification TextUnderlinePositionAuto should default to 'alphabetic' for horizontal text
- // and to 'under Left' for vertical text (e.g. japanese). We support only horizontal text for now.
- switch (underlinePosition) {
- case TextUnderlinePositionAlphabetic:
- case TextUnderlinePositionAuto:
- return fontMetrics.ascent() + gap; // Position underline near the alphabetic baseline.
- case TextUnderlinePositionUnder: {
- // Position underline relative to the under edge of the lowest element's content box.
- const float offset = inlineTextBox->root().maxLogicalTop() - inlineTextBox->logicalTop();
- return inlineTextBox->logicalHeight() + gap + std::max<float>(offset, 0);
- }
- }
-
- ASSERT_NOT_REACHED();
- return fontMetrics.ascent() + gap;
-}
-
</del><span class="cx"> static void adjustStepToDecorationLength(float& step, float& controlPointDistance, float length)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(step > 0);
</span><span class="lines">@@ -862,21 +840,6 @@
</span><span class="cx"> controlPointDistance += adjustment;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static void getWavyStrokeParameters(float strokeThickness, float& controlPointDistance, float& step)
-{
- // Distance between decoration's axis and Bezier curve's control points.
- // The height of the curve is based on this distance. Use a minimum of 6 pixels distance since
- // the actual curve passes approximately at half of that distance, that is 3 pixels.
- // The minimum height of the curve is also approximately 3 pixels. Increases the curve's height
- // as strockThickness increases to make the curve looks better.
- controlPointDistance = 3 * std::max<float>(2, strokeThickness);
-
- // Increment used to form the diamond shape between start point (p1), control
- // points and end point (p2) along the axis of the decoration. Makes the
- // curve wider as strockThickness increases to make the curve looks better.
- step = 2 * std::max<float>(2, strokeThickness);
-}
-
</del><span class="cx"> /*
</span><span class="cx"> * Draw one cubic Bezier curve and repeat the same pattern long the the decoration's axis.
</span><span class="cx"> * The start point (p1), controlPoint1, controlPoint2 and end point (p2) of the Bezier curve
</span><span class="lines">@@ -1000,8 +963,7 @@
</span><span class="cx"> // Use a special function for underlines to get the positioning exactly right.
</span><span class="cx"> bool isPrinting = renderer().document().printing();
</span><span class="cx">
</span><del>- const float textDecorationBaseFontSize = 16;
- float textDecorationThickness = renderer().style().fontSize() / textDecorationBaseFontSize;
</del><ins>+ float textDecorationThickness = textDecorationStrokeThickness(renderer().style().fontSize());
</ins><span class="cx"> context.setStrokeThickness(textDecorationThickness);
</span><span class="cx">
</span><span class="cx"> bool linesAreOpaque = !isPrinting && (!(decoration & TextDecorationUnderline) || underline.alpha() == 255) && (!(decoration & TextDecorationOverline) || overline.alpha() == 255) && (!(decoration & TextDecorationLineThrough) || linethrough.alpha() == 255);
</span><span class="lines">@@ -1047,13 +1009,13 @@
</span><span class="cx"> shadow = shadow->next();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- float wavyOffset = 2.f;
</del><ins>+ float wavyOffset = wavyOffsetFromDecoration();
</ins><span class="cx">
</span><span class="cx"> context.setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle));
</span><ins>+ // These decorations should match the visual overflows computed in visualOverflowForDecorations()
</ins><span class="cx"> if (decoration & TextDecorationUnderline) {
</span><span class="cx"> context.setStrokeColor(underline, colorSpace);
</span><del>- TextUnderlinePosition underlinePosition = lineStyle.textUnderlinePosition();
- const int underlineOffset = computeUnderlineOffset(underlinePosition, lineStyle.fontMetrics(), this, textDecorationThickness);
</del><ins>+ const int underlineOffset = computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), this, textDecorationThickness);
</ins><span class="cx">
</span><span class="cx"> switch (decorationStyle) {
</span><span class="cx"> case TextDecorationStyleWavy: {
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockLineLayoutcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include "InlineElementBox.h"
</span><span class="cx"> #include "InlineIterator.h"
</span><span class="cx"> #include "InlineTextBox.h"
</span><ins>+#include "InlineTextBoxStyle.h"
</ins><span class="cx"> #include "LineLayoutState.h"
</span><span class="cx"> #include "Logging.h"
</span><span class="cx"> #include "RenderBlockFlow.h"
</span><span class="lines">@@ -524,7 +525,12 @@
</span><span class="cx"> copyToVector(fallbackFonts, it->value.first);
</span><span class="cx"> run->box()->parent()->clearDescendantsHaveSameLineHeightAndBaseline();
</span><span class="cx"> }
</span><del>- if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) {
</del><ins>+
+ // Include text decoration visual overflow as part of the glyph overflow.
+ if (renderer->style().textDecorationsInEffect() != TextDecorationNone)
+ glyphOverflow.extendTo(visualOverflowForDecorations(run->box()->lineStyle(), toInlineTextBox(run->box())));
+
+ if (!glyphOverflow.isEmpty()) {
</ins><span class="cx"> ASSERT(run->box()->behavesLikeText());
</span><span class="cx"> GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->box()), std::make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator;
</span><span class="cx"> it->value.second = glyphOverflow;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTableSectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTableSection.cpp (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTableSection.cpp        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/rendering/RenderTableSection.cpp        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -1035,7 +1035,7 @@
</span><span class="cx"> if (m_forceSlowPaintPathWithOverflowingCell)
</span><span class="cx"> return fullTableRowSpan();
</span><span class="cx">
</span><del>- CellSpan coveredRows = spannedRows(damageRect);
</del><ins>+ CellSpan coveredRows = spannedRows(damageRect, IncludeAllIntersectingCells);
</ins><span class="cx">
</span><span class="cx"> // To repaint the border we might need to repaint first or last row even if they are not spanned themselves.
</span><span class="cx"> if (coveredRows.start() >= m_rowPos.size() - 1 && m_rowPos[m_rowPos.size() - 1] + table()->outerBorderAfter() >= damageRect.y())
</span><span class="lines">@@ -1052,7 +1052,7 @@
</span><span class="cx"> if (m_forceSlowPaintPathWithOverflowingCell)
</span><span class="cx"> return fullTableColumnSpan();
</span><span class="cx">
</span><del>- CellSpan coveredColumns = spannedColumns(damageRect);
</del><ins>+ CellSpan coveredColumns = spannedColumns(damageRect, IncludeAllIntersectingCells);
</ins><span class="cx">
</span><span class="cx"> const Vector<int>& columnPos = table()->columnPositions();
</span><span class="cx"> // To repaint the border we might need to repaint first or last column even if they are not spanned themselves.
</span><span class="lines">@@ -1065,10 +1065,12 @@
</span><span class="cx"> return coveredColumns;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-CellSpan RenderTableSection::spannedRows(const LayoutRect& flippedRect) const
</del><ins>+CellSpan RenderTableSection::spannedRows(const LayoutRect& flippedRect, ShouldIncludeAllIntersectingCells shouldIncludeAllIntersectionCells) const
</ins><span class="cx"> {
</span><span class="cx"> // Find the first row that starts after rect top.
</span><span class="cx"> unsigned nextRow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), flippedRect.y()) - m_rowPos.begin();
</span><ins>+ if (shouldIncludeAllIntersectionCells == IncludeAllIntersectingCells && nextRow && m_rowPos[nextRow - 1] == flippedRect.y())
+ --nextRow;
</ins><span class="cx">
</span><span class="cx"> if (nextRow == m_rowPos.size())
</span><span class="cx"> return CellSpan(m_rowPos.size() - 1, m_rowPos.size() - 1); // After all rows.
</span><span class="lines">@@ -1088,7 +1090,7 @@
</span><span class="cx"> return CellSpan(startRow, endRow);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-CellSpan RenderTableSection::spannedColumns(const LayoutRect& flippedRect) const
</del><ins>+CellSpan RenderTableSection::spannedColumns(const LayoutRect& flippedRect, ShouldIncludeAllIntersectingCells shouldIncludeAllIntersectionCells) const
</ins><span class="cx"> {
</span><span class="cx"> const Vector<int>& columnPos = table()->columnPositions();
</span><span class="cx">
</span><span class="lines">@@ -1098,6 +1100,8 @@
</span><span class="cx"> // upper_bound on the other hand properly returns the cell on the logical bottom/right, which also
</span><span class="cx"> // matches the behavior of other browsers.
</span><span class="cx"> unsigned nextColumn = std::upper_bound(columnPos.begin(), columnPos.end(), flippedRect.x()) - columnPos.begin();
</span><ins>+ if (shouldIncludeAllIntersectionCells == IncludeAllIntersectingCells && nextColumn && columnPos[nextColumn - 1] == flippedRect.x())
+ --nextColumn;
</ins><span class="cx">
</span><span class="cx"> if (nextColumn == columnPos.size())
</span><span class="cx"> return CellSpan(columnPos.size() - 1, columnPos.size() - 1); // After all columns.
</span><span class="lines">@@ -1521,8 +1525,8 @@
</span><span class="cx"> hitTestRect.moveBy(-adjustedLocation);
</span><span class="cx">
</span><span class="cx"> LayoutRect tableAlignedRect = logicalRectForWritingModeAndDirection(hitTestRect);
</span><del>- CellSpan rowSpan = spannedRows(tableAlignedRect);
- CellSpan columnSpan = spannedColumns(tableAlignedRect);
</del><ins>+ CellSpan rowSpan = spannedRows(tableAlignedRect, DoNotIncludeAllIntersectingCells);
+ CellSpan columnSpan = spannedColumns(tableAlignedRect, DoNotIncludeAllIntersectingCells);
</ins><span class="cx">
</span><span class="cx"> // Now iterate over the spanned rows and columns.
</span><span class="cx"> for (unsigned hitRow = rowSpan.start(); hitRow < rowSpan.end(); ++hitRow) {
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTableSectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderTableSection.h (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderTableSection.h        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/rendering/RenderTableSection.h        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -254,6 +254,11 @@
</span><span class="cx"> virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+ enum ShouldIncludeAllIntersectingCells {
+ IncludeAllIntersectingCells,
+ DoNotIncludeAllIntersectingCells
+ };
+
</ins><span class="cx"> virtual const char* renderName() const override { return (isAnonymous() || isPseudoElement()) ? "RenderTableSection (anonymous)" : "RenderTableSection"; }
</span><span class="cx">
</span><span class="cx"> virtual bool canHaveChildren() const override { return true; }
</span><span class="lines">@@ -303,8 +308,12 @@
</span><span class="cx">
</span><span class="cx"> // These two functions take a rectangle as input that has been flipped by logicalRectForWritingModeAndDirection.
</span><span class="cx"> // The returned span of rows or columns is end-exclusive, and empty if start==end.
</span><del>- CellSpan spannedRows(const LayoutRect& flippedRect) const;
- CellSpan spannedColumns(const LayoutRect& flippedRect) const;
</del><ins>+ // The IncludeAllIntersectingCells argument is used to determine which cells to include when
+ // an edge of the flippedRect lies exactly on a cell boundary. Using IncludeAllIntersectingCells
+ // will return both cells, and using DoNotIncludeAllIntersectingCells will return only the cell
+ // that hittesting should return.
+ CellSpan spannedRows(const LayoutRect& flippedRect, ShouldIncludeAllIntersectingCells) const;
+ CellSpan spannedColumns(const LayoutRect& flippedRect, ShouldIncludeAllIntersectingCells) const;
</ins><span class="cx">
</span><span class="cx"> void setLogicalPositionForCell(RenderTableCell*, unsigned effectiveColumn) const;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleRenderStylecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #include "FloatRoundedRect.h"
</span><span class="cx"> #include "Font.h"
</span><span class="cx"> #include "FontSelector.h"
</span><ins>+#include "InlineTextBoxStyle.h"
</ins><span class="cx"> #include "Pagination.h"
</span><span class="cx"> #include "QuotesData.h"
</span><span class="cx"> #include "RenderObject.h"
</span><span class="lines">@@ -382,6 +383,26 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+inline bool RenderStyle::changeAffectsVisualOverflow(const RenderStyle& other) const
+{
+ if (rareNonInheritedData.get() != other.rareNonInheritedData.get()
+ && !rareNonInheritedData->shadowDataEquivalent(*other.rareNonInheritedData.get()))
+ return true;
+
+ if (inherited_flags._text_decorations != other.inherited_flags._text_decorations
+ || visual->textDecoration != other.visual->textDecoration
+ || rareNonInheritedData->m_textDecorationStyle != other.rareNonInheritedData->m_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() == TextUnderlinePositionUnder
+ || other.textUnderlinePosition() == TextUnderlinePositionUnder)
+ return true;
+ return visualOverflowForDecorations(*this, nullptr) != visualOverflowForDecorations(other, nullptr);
+ }
+
+ return false;
+}
+
</ins><span class="cx"> bool RenderStyle::changeRequiresLayout(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const
</span><span class="cx"> {
</span><span class="cx"> if (m_box->width() != other->m_box->width()
</span><span class="lines">@@ -404,6 +425,10 @@
</span><span class="cx"> if (surround->padding != other->surround->padding)
</span><span class="cx"> return true;
</span><span class="cx">
</span><ins>+ // FIXME: We should add an optimized form of layout that just recomputes visual overflow.
+ if (changeAffectsVisualOverflow(*other))
+ return true;
+
</ins><span class="cx"> if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
</span><span class="cx"> if (rareNonInheritedData->m_appearance != other->rareNonInheritedData->m_appearance
</span><span class="cx"> || rareNonInheritedData->marginBeforeCollapse != other->rareNonInheritedData->marginBeforeCollapse
</span><span class="lines">@@ -434,10 +459,6 @@
</span><span class="cx"> || rareNonInheritedData->m_justifyContent != other->rareNonInheritedData->m_justifyContent)
</span><span class="cx"> return true;
</span><span class="cx">
</span><del>- // FIXME: We should add an optimized form of layout that just recomputes visual overflow.
- if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get()))
- return true;
-
</del><span class="cx"> if (!rareNonInheritedData->reflectionDataEquivalent(*other->rareNonInheritedData.get()))
</span><span class="cx"> return true;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingstyleRenderStyleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (169088 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/style/RenderStyle.h        2014-05-20 00:43:59 UTC (rev 169088)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -1936,6 +1936,7 @@
</span><span class="cx"> static ptrdiff_t noninheritedFlagsMemoryOffset() { return OBJECT_OFFSETOF(RenderStyle, noninherited_flags); }
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+ bool changeAffectsVisualOverflow(const RenderStyle&) const;
</ins><span class="cx"> bool changeRequiresLayout(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
</span><span class="cx"> bool changeRequiresPositionedLayoutOnly(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
</span><span class="cx"> bool changeRequiresLayerRepaint(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
</span></span></pre></div>
<a id="trunkSourceWebCorestyleInlineTextBoxStylecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/style/InlineTextBoxStyle.cpp (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/InlineTextBoxStyle.cpp         (rev 0)
+++ trunk/Source/WebCore/style/InlineTextBoxStyle.cpp        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,135 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InlineTextBoxStyle.h"
+
+#include "Font.h"
+#include "InlineTextBox.h"
+#include "RootInlineBox.h"
+
+namespace WebCore {
+
+int computeUnderlineOffset(TextUnderlinePosition underlinePosition, const FontMetrics& fontMetrics, 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));
+
+ // According to the specification TextUnderlinePositionAuto should default to 'alphabetic' for horizontal text
+ // and to 'under Left' for vertical text (e.g. japanese). We support only horizontal text for now.
+ switch (underlinePosition) {
+ case TextUnderlinePositionAlphabetic:
+ case TextUnderlinePositionAuto:
+ return fontMetrics.ascent() + gap;
+ case TextUnderlinePositionUnder: {
+ ASSERT(inlineTextBox);
+ // Position underline relative to the bottom edge of the lowest element's content box.
+ float offset = inlineTextBox->root().maxLogicalTop() - inlineTextBox->logicalTop();
+ return inlineTextBox->logicalHeight() + gap + std::max<float>(offset, 0);
+ }
+ }
+
+ ASSERT_NOT_REACHED();
+ return fontMetrics.ascent() + gap;
+}
+
+void getWavyStrokeParameters(float strokeThickness, float& controlPointDistance, float& step)
+{
+ // Distance between decoration's axis and Bezier curve's control points.
+ // The height of the curve is based on this distance. Use a minimum of 6 pixels distance since
+ // the actual curve passes approximately at half of that distance, that is 3 pixels.
+ // The minimum height of the curve is also approximately 3 pixels. Increases the curve's height
+ // as strokeThickness increases to make the curve look better.
+ controlPointDistance = 3 * std::max<float>(2, strokeThickness);
+
+ // Increment used to form the diamond shape between start point (p1), control
+ // points and end point (p2) along the axis of the decoration. Makes the
+ // curve wider as strokeThickness increases to make the curve look better.
+ step = 2 * std::max<float>(2, strokeThickness);
+}
+
+static inline void extendIntToFloat(int& extendMe, float extendTo)
+{
+ extendMe = std::max(extendMe, static_cast<int>(ceilf(extendTo)));
+}
+
+GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, InlineTextBox* inlineTextBox)
+{
+ ASSERT(!inlineTextBox || inlineTextBox->lineStyle() == lineStyle);
+
+ TextDecoration decoration = lineStyle.textDecorationsInEffect();
+ if (decoration == TextDecorationNone)
+ return GlyphOverflow();
+
+ float strokeThickness = textDecorationStrokeThickness(lineStyle.fontSize());
+ float controlPointDistance;
+ float step;
+ float wavyOffset;
+
+ TextDecorationStyle decorationStyle = lineStyle.textDecorationStyle();
+ float height = lineStyle.font().fontMetrics().floatHeight();
+ GlyphOverflow overflowResult;
+
+ if (decorationStyle == TextDecorationStyleWavy) {
+ getWavyStrokeParameters(strokeThickness, controlPointDistance, step);
+ wavyOffset = wavyOffsetFromDecoration();
+ overflowResult.left = strokeThickness;
+ overflowResult.right = strokeThickness;
+ }
+
+ // These metrics must match where underlines get drawn.
+ if (decoration & TextDecorationUnderline) {
+ float underlineOffset = computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), inlineTextBox, strokeThickness);
+ if (decorationStyle == TextDecorationStyleWavy) {
+ extendIntToFloat(overflowResult.bottom, underlineOffset + wavyOffset + controlPointDistance + strokeThickness - height);
+ extendIntToFloat(overflowResult.top, -(underlineOffset + wavyOffset - controlPointDistance - strokeThickness));
+ } else {
+ extendIntToFloat(overflowResult.bottom, underlineOffset + strokeThickness - height);
+ extendIntToFloat(overflowResult.top, -underlineOffset);
+ }
+ }
+ if (decoration & TextDecorationOverline) {
+ if (decorationStyle == TextDecorationStyleWavy) {
+ extendIntToFloat(overflowResult.bottom, -wavyOffset + controlPointDistance + strokeThickness - height);
+ extendIntToFloat(overflowResult.top, wavyOffset + controlPointDistance + strokeThickness);
+ } else {
+ extendIntToFloat(overflowResult.bottom, strokeThickness - height);
+ // top is untouched
+ }
+ }
+ if (decoration & TextDecorationLineThrough) {
+ float baseline = lineStyle.fontMetrics().floatAscent();
+ if (decorationStyle == TextDecorationStyleWavy) {
+ extendIntToFloat(overflowResult.bottom, 2 * baseline / 3 + controlPointDistance + strokeThickness - height);
+ extendIntToFloat(overflowResult.top, -(2 * baseline / 3 - controlPointDistance - strokeThickness));
+ } else {
+ extendIntToFloat(overflowResult.bottom, 2 * baseline / 3 + strokeThickness - height);
+ extendIntToFloat(overflowResult.top, -(2 * baseline / 3));
+ }
+ }
+ return overflowResult;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCorestyleInlineTextBoxStyleh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/style/InlineTextBoxStyle.h (0 => 169089)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/InlineTextBoxStyle.h         (rev 0)
+++ trunk/Source/WebCore/style/InlineTextBoxStyle.h        2014-05-20 00:45:52 UTC (rev 169089)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InlineTextBoxStyle_h
+#define InlineTextBoxStyle_h
+
+#include "Font.h"
+#include "RenderStyle.h"
+
+namespace WebCore {
+
+class InlineTextBox;
+
+inline float textDecorationStrokeThickness(float fontSize)
+{
+ const float textDecorationBaseFontSize = 16;
+ return fontSize / textDecorationBaseFontSize;
+}
+
+inline float wavyOffsetFromDecoration()
+{
+ return 2;
+}
+
+GlyphOverflow visualOverflowForDecorations(const RenderStyle& lineStyle, InlineTextBox*);
+void getWavyStrokeParameters(float strokeThickness, float& controlPointDistance, float& step);
+int computeUnderlineOffset(TextUnderlinePosition, const FontMetrics&, InlineTextBox*, int textDecorationThickness);
+
+}
+
+#endif
</ins></span></pre>
</div>
</div>
</body>
</html>