<!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>[162217] 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/162217">162217</a></dd>
<dt>Author</dt> <dd>bjonesbe@adobe.com</dd>
<dt>Date</dt> <dd>2014-01-17 13:11:49 -0800 (Fri, 17 Jan 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>[CSS Shapes] Stacked floats with shape-outside should allow inline content to interact with the non-outermost float
https://bugs.webkit.org/show_bug.cgi?id=122576
Reviewed by David Hyatt.
Source/WebCore:
Make inline content interact with stacked floats with shape-outside
per the spec. This means that content can interact with floats on the
line that are not the outermost float.
This refactors ComputeFloatOffsetAdapter into a superclass and two
subclasses: one adaptor for determining the offset for float layout,
and one for determining the offset for inline layout.
The logic in LineWidth::shrinkAvailableWidthForNewFloatIfNeeded has
been updated to handle stacked floats with shape-outside properly and
has been considerably simplified in the process. It was previously
doing a whole bunch of unnecessary work.
Tests: fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000.html
fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001.html
fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002.html
* rendering/FloatingObjects.cpp:
(WebCore::ComputeFloatOffsetAdapter::~ComputeFloatOffsetAdapter):
(WebCore::ComputeFloatOffsetForFloatLayoutAdapter::ComputeFloatOffsetForFloatLayoutAdapter):
(WebCore::ComputeFloatOffsetForFloatLayoutAdapter::~ComputeFloatOffsetForFloatLayoutAdapter):
(WebCore::ComputeFloatOffsetForLineLayoutAdapter::ComputeFloatOffsetForLineLayoutAdapter):
(WebCore::ComputeFloatOffsetForLineLayoutAdapter::~ComputeFloatOffsetForLineLayoutAdapter):
(WebCore::FloatingObjects::logicalLeftOffsetForPositioningFloat):
(WebCore::FloatingObjects::logicalRightOffsetForPositioningFloat):
(WebCore::FloatingObjects::logicalLeftOffset):
(WebCore::FloatingObjects::logicalRightOffset):
(WebCore::ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded):
(WebCore::ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded):
(WebCore::ComputeFloatOffsetForFloatLayoutAdapter<FloatTypeValue>::heightRemaining):
(WebCore::shapeInfoForFloat):
(WebCore::ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded):
(WebCore::ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded):
* rendering/line/LineWidth.cpp:
(WebCore::LineWidth::shrinkAvailableWidthForNewFloatIfNeeded):
* rendering/shapes/ShapeOutsideInfo.cpp:
(WebCore::ShapeOutsideInfo::updateDeltasForContainingBlockLine):
* rendering/shapes/ShapeOutsideInfo.h:
LayoutTests:
Tests for shape-outside on stacked floats and interaction with inline
content.
* fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000-expected.html: Added.
* fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000.html: Added.
* fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001-expected.html: Added.
* fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001.html: Added.
* fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002-expected.html: Added.
* fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002.html: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingFloatingObjectscpp">trunk/Source/WebCore/rendering/FloatingObjects.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderinglineLineWidthcpp">trunk/Source/WebCore/rendering/line/LineWidth.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingshapesShapeOutsideInfocpp">trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingshapesShapeOutsideInfoh">trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked000expectedhtml">trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked000html">trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000.html</a></li>
<li><a href="#trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked001expectedhtml">trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked001html">trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001.html</a></li>
<li><a href="#trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked002expectedhtml">trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked002html">trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (162216 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-01-17 21:10:37 UTC (rev 162216)
+++ trunk/LayoutTests/ChangeLog        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2014-01-17 Bem Jones-Bey <bjonesbe@adobe.com>
+
+ [CSS Shapes] Stacked floats with shape-outside should allow inline content to interact with the non-outermost float
+ https://bugs.webkit.org/show_bug.cgi?id=122576
+
+ Reviewed by David Hyatt.
+
+ Tests for shape-outside on stacked floats and interaction with inline
+ content.
+
+ * fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000-expected.html: Added.
+ * fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000.html: Added.
+ * fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001-expected.html: Added.
+ * fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001.html: Added.
+ * fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002-expected.html: Added.
+ * fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002.html: Added.
+
</ins><span class="cx"> 2014-01-17 Zoltan Horvath <zoltan@webkit.org>
</span><span class="cx">
</span><span class="cx"> [CSS3] Add rendering support for -webkit-text-align-last
</span></span></pre></div>
<a id="trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked000expectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000-expected.html (0 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000-expected.html         (rev 0)
+++ trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000-expected.html        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+<!DOCTYPE html>
+<style>
+.container {
+ width: 200px;
+ height: 100px;
+ font: 100px/1 Ahem, sans-serif;
+ background-color: green;
+ margin-bottom: 50px;
+ color: green;
+}
+</style>
+<body>
+ <p>If two floats affect the same line and the longer float has a shape that makes it short, then the other float should be respected as the offset for the line.</p>
+ <p>You should see two green rectanges. There should be no red.</p>
+ <div class="container">
+ </div>
+ <div class="container">
+ </div>
+</body>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked000html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000.html (0 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000.html         (rev 0)
+++ trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000.html        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+<!DOCTYPE html>
+<style>
+.container {
+ width: 200px;
+ height: 100px;
+ font: 100px/1 Ahem, sans-serif;
+ background-color: red;
+ margin-bottom: 50px;
+ color: green;
+}
+.float-left-long {
+ margin-right: 100px;
+ width: 100px;
+ height: 50px;
+ float: left;
+ background-color: green;
+ -webkit-shape-outside: inset(0 100% 0 0);
+}
+.float-left-short {
+ width: 100px;
+ height: 50px;
+ float: left;
+ background-color: green;
+ clear: left;
+}
+.float-right-long {
+ margin-left: 100px;
+ width: 100px;
+ height: 50px;
+ float: right;
+ background-color: green;
+ -webkit-shape-outside: inset(0 0 0 100%);
+}
+.float-right-short {
+ width: 100px;
+ height: 50px;
+ float: right;
+ background-color: green;
+ clear: right;
+}
+</style>
+<body>
+ <p>If two floats affect the same line and the longer float has a shape that makes it short, then the other float should be respected as the offset for the line.</p>
+ <p>You should see two green rectanges. There should be no red.</p>
+ <div class="container">
+ <div class="float-left-long"></div>
+ <div class="float-left-short"></div>
+ X
+ </div>
+ <div class="container" style="text-align: right">
+ <div class="float-right-long"></div>
+ <div class="float-right-short"></div>
+ X
+ </div>
+</body>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked001expectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001-expected.html (0 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001-expected.html         (rev 0)
+++ trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001-expected.html        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+<!DOCTYPE html>
+<style>
+.container {
+ width: 200px;
+ height: 100px;
+ font: 100px/1 Ahem, sans-serif;
+ background-color: green;
+ margin-bottom: 50px;
+ color: green;
+}
+</style>
+<body>
+ <p>If a shape on a stacked float does not affect the line, then the line should be affected by the shape on the previous stacked float.</p>
+ <p>You should see two green rectanges. There should be no red.</p>
+ <div class="container">
+ </div>
+ <div class="container">
+ </div>
+</body>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked001html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001.html (0 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001.html         (rev 0)
+++ trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001.html        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+<!DOCTYPE html>
+<style>
+.container {
+ width: 200px;
+ height: 100px;
+ font: 50px/1 Ahem, sans-serif;
+ background-color: red;
+ margin-bottom: 50px;
+ color: green;
+}
+.float-left-outer {
+ width: 100px;
+ height: 100px;
+ float: left;
+ background-color: green;
+ -webkit-shape-outside: inset(50% 0 0 0);
+}
+.float-left-inner {
+ margin-top: 50px;
+ width: 100px;
+ height: 50px;
+ float: left;
+ background-color: green;
+ -webkit-shape-outside: inset(0 100% 0 0);
+}
+.float-right-outer {
+ width: 100px;
+ height: 100px;
+ float: right;
+ background-color: green;
+ -webkit-shape-outside: inset(50% 0 0 0);
+}
+.float-right-inner {
+ margin-top: 50px;
+ width: 100px;
+ height: 50px;
+ float: right;
+ background-color: green;
+ -webkit-shape-outside: inset(0 0 0 100%);
+}
+</style>
+<body>
+ <p>If a shape on a stacked float does not affect the line, then the line should be affected by the shape on the previous stacked float.</p>
+ <p>You should see two green rectanges. There should be no red.</p>
+ <div class="container">
+ <div class="float-left-inner"></div>
+ <div class="float-left-outer"></div>
+ XXXX
+ </div>
+ <div class="container" style="text-align: right">
+ <div class="float-right-inner"></div>
+ <div class="float-right-outer"></div>
+ XXXX
+ </div>
+</body>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked002expectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002-expected.html (0 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002-expected.html         (rev 0)
+++ trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002-expected.html        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+<!DOCTYPE html>
+<style>
+.container {
+ width: 200px;
+ height: 100px;
+ font: 100px/1 Ahem, sans-serif;
+ background-color: green;
+ margin-bottom: 50px;
+ color: green;
+}
+</style>
+<body>
+ <p>Shapes should not affact float stacking, but should affect inline content.</p>
+ <p>You should see two green rectanges. There should be no red.</p>
+ <div class="container">
+ </div>
+ <div class="container">
+ </div>
+</body>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastshapesshapeoutsidefloatsshapeoutsidefloatsstacked002html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002.html (0 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002.html         (rev 0)
+++ trunk/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002.html        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+<!DOCTYPE html>
+<style>
+.container {
+ width: 200px;
+ height: 100px;
+ font: 50px/1 Ahem, sans-serif;
+ background-color: red;
+ margin-bottom: 50px;
+ color: green;
+}
+.float-left-inner {
+ width: 100px;
+ height: 100px;
+ float: left;
+ background-color: green;
+ -webkit-shape-outside: inset(0 50% 0 0);
+}
+.float-left-outer {
+ margin-right: 50px;
+ width: 50px;
+ height: 100px;
+ float: left;
+ background-color: green;
+ -webkit-shape-outside: inset(0 50% 0 0);
+}
+.float-right-inner {
+ width: 100px;
+ height: 100px;
+ float: right;
+ background-color: green;
+ -webkit-shape-outside: inset(0 0 0 50%);
+}
+.float-right-outer {
+ margin-left: 50px;
+ width: 50px;
+ height: 100px;
+ float: right;
+ background-color: green;
+ -webkit-shape-outside: inset(0 0 0 50%);
+}
+</style>
+<body>
+ <p>Shapes should not affact float stacking, but should affect inline content.</p>
+ <p>You should see two green rectanges. There should be no red.</p>
+ <div class="container">
+ <div class="float-left-inner"></div>
+ <div class="float-left-outer"></div>
+ X<br/>
+ X
+ </div>
+ <div class="container" style="text-align: right">
+ <div class="float-right-inner"></div>
+ <div class="float-right-outer"></div>
+ X<br/>
+ X
+ </div>
+</body>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (162216 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-01-17 21:10:37 UTC (rev 162216)
+++ trunk/Source/WebCore/ChangeLog        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2014-01-17 Bem Jones-Bey <bjonesbe@adobe.com>
+
+ [CSS Shapes] Stacked floats with shape-outside should allow inline content to interact with the non-outermost float
+ https://bugs.webkit.org/show_bug.cgi?id=122576
+
+ Reviewed by David Hyatt.
+
+ Make inline content interact with stacked floats with shape-outside
+ per the spec. This means that content can interact with floats on the
+ line that are not the outermost float.
+
+ This refactors ComputeFloatOffsetAdapter into a superclass and two
+ subclasses: one adaptor for determining the offset for float layout,
+ and one for determining the offset for inline layout.
+
+ The logic in LineWidth::shrinkAvailableWidthForNewFloatIfNeeded has
+ been updated to handle stacked floats with shape-outside properly and
+ has been considerably simplified in the process. It was previously
+ doing a whole bunch of unnecessary work.
+
+ Tests: fast/shapes/shape-outside-floats/shape-outside-floats-stacked-000.html
+ fast/shapes/shape-outside-floats/shape-outside-floats-stacked-001.html
+ fast/shapes/shape-outside-floats/shape-outside-floats-stacked-002.html
+
+ * rendering/FloatingObjects.cpp:
+ (WebCore::ComputeFloatOffsetAdapter::~ComputeFloatOffsetAdapter):
+ (WebCore::ComputeFloatOffsetForFloatLayoutAdapter::ComputeFloatOffsetForFloatLayoutAdapter):
+ (WebCore::ComputeFloatOffsetForFloatLayoutAdapter::~ComputeFloatOffsetForFloatLayoutAdapter):
+ (WebCore::ComputeFloatOffsetForLineLayoutAdapter::ComputeFloatOffsetForLineLayoutAdapter):
+ (WebCore::ComputeFloatOffsetForLineLayoutAdapter::~ComputeFloatOffsetForLineLayoutAdapter):
+ (WebCore::FloatingObjects::logicalLeftOffsetForPositioningFloat):
+ (WebCore::FloatingObjects::logicalRightOffsetForPositioningFloat):
+ (WebCore::FloatingObjects::logicalLeftOffset):
+ (WebCore::FloatingObjects::logicalRightOffset):
+ (WebCore::ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded):
+ (WebCore::ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded):
+ (WebCore::ComputeFloatOffsetForFloatLayoutAdapter<FloatTypeValue>::heightRemaining):
+ (WebCore::shapeInfoForFloat):
+ (WebCore::ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded):
+ (WebCore::ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded):
+ * rendering/line/LineWidth.cpp:
+ (WebCore::LineWidth::shrinkAvailableWidthForNewFloatIfNeeded):
+ * rendering/shapes/ShapeOutsideInfo.cpp:
+ (WebCore::ShapeOutsideInfo::updateDeltasForContainingBlockLine):
+ * rendering/shapes/ShapeOutsideInfo.h:
+
</ins><span class="cx"> 2014-01-17 Zoltan Horvath <zoltan@webkit.org>
</span><span class="cx">
</span><span class="cx"> [CSS3] Add rendering support for -webkit-text-align-last
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingFloatingObjectscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/FloatingObjects.cpp (162216 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/FloatingObjects.cpp        2014-01-17 21:10:37 UTC (rev 162216)
+++ trunk/Source/WebCore/rendering/FloatingObjects.cpp        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -133,16 +133,16 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ virtual ~ComputeFloatOffsetAdapter() { }
+
</ins><span class="cx"> LayoutUnit lowValue() const { return m_lineTop; }
</span><span class="cx"> LayoutUnit highValue() const { return m_lineBottom; }
</span><span class="cx"> void collectIfNeeded(const IntervalType&);
</span><span class="cx">
</span><span class="cx"> LayoutUnit offset() const { return m_offset; }
</span><del>- LayoutUnit shapeOffset() const;
- LayoutUnit heightRemaining() const;
</del><span class="cx">
</span><del>-private:
- bool updateOffsetIfNeeded(const FloatingObject*);
</del><ins>+protected:
+ virtual bool updateOffsetIfNeeded(const FloatingObject*) = 0;
</ins><span class="cx">
</span><span class="cx"> const RenderBlockFlow& m_renderer;
</span><span class="cx"> LayoutUnit m_lineTop;
</span><span class="lines">@@ -151,6 +151,36 @@
</span><span class="cx"> const FloatingObject* m_outermostFloat;
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+template <FloatingObject::Type FloatTypeValue>
+class ComputeFloatOffsetForFloatLayoutAdapter : public ComputeFloatOffsetAdapter<FloatTypeValue> {
+public:
+ ComputeFloatOffsetForFloatLayoutAdapter(const RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
+ : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBottom, offset)
+ {
+ }
+
+ virtual ~ComputeFloatOffsetForFloatLayoutAdapter() { }
+
+ LayoutUnit heightRemaining() const;
+
+protected:
+ virtual bool updateOffsetIfNeeded(const FloatingObject*) override final;
+};
+
+template <FloatingObject::Type FloatTypeValue>
+class ComputeFloatOffsetForLineLayoutAdapter : public ComputeFloatOffsetAdapter<FloatTypeValue> {
+public:
+ ComputeFloatOffsetForLineLayoutAdapter(const RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
+ : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBottom, offset)
+ {
+ }
+
+ virtual ~ComputeFloatOffsetForLineLayoutAdapter() { }
+
+protected:
+ virtual bool updateOffsetIfNeeded(const FloatingObject*) override final;
+};
+
</ins><span class="cx"> class FindNextFloatLogicalBottomAdapter {
</span><span class="cx"> public:
</span><span class="cx"> typedef FloatingObjectInterval IntervalType;
</span><span class="lines">@@ -357,45 +387,9 @@
</span><span class="cx"> return m_placedFloatsTree;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-#if ENABLE(CSS_SHAPES)
-static inline ShapeOutsideInfo* shapeInfoForFloat(const FloatingObject* floatingObject, const RenderBlockFlow& containingBlock, LayoutUnit lineTop, LayoutUnit lineBottom)
-{
- if (floatingObject) {
- if (ShapeOutsideInfo* shapeOutside = floatingObject->renderer().shapeOutsideInfo()) {
- shapeOutside->updateDeltasForContainingBlockLine(containingBlock, *floatingObject, lineTop, lineBottom - lineTop);
- return shapeOutside;
- }
- }
-
- return nullptr;
-}
-#endif
-
-template<>
-inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::shapeOffset() const
-{
-#if ENABLE(CSS_SHAPES)
- if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_renderer, m_lineTop, m_lineBottom))
- return m_offset + shapeOutside->rightMarginBoxDelta();
-#endif
-
- return m_offset;
-}
-
-template<>
-inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::shapeOffset() const
-{
-#if ENABLE(CSS_SHAPES)
- if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_renderer, m_lineTop, m_lineBottom))
- return m_offset + shapeOutside->leftMarginBoxDelta();
-#endif
-
- return m_offset;
-}
-
</del><span class="cx"> LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
</span><span class="cx"> {
</span><del>- ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
</del><ins>+ ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
</ins><span class="cx"> placedFloatsTree().allOverlapsWithAdapter(adapter);
</span><span class="cx">
</span><span class="cx"> if (heightRemaining)
</span><span class="lines">@@ -406,7 +400,7 @@
</span><span class="cx">
</span><span class="cx"> LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
</span><span class="cx"> {
</span><del>- ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
</del><ins>+ ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop, fixedOffset);
</ins><span class="cx"> placedFloatsTree().allOverlapsWithAdapter(adapter);
</span><span class="cx">
</span><span class="cx"> if (heightRemaining)
</span><span class="lines">@@ -417,22 +411,22 @@
</span><span class="cx">
</span><span class="cx"> LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
</span><span class="cx"> {
</span><del>- ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
</del><ins>+ ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
</ins><span class="cx"> placedFloatsTree().allOverlapsWithAdapter(adapter);
</span><span class="cx">
</span><del>- return adapter.shapeOffset();
</del><ins>+ return adapter.offset();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
</span><span class="cx"> {
</span><del>- ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
</del><ins>+ ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset);
</ins><span class="cx"> placedFloatsTree().allOverlapsWithAdapter(adapter);
</span><span class="cx">
</span><del>- return std::min(fixedOffset, adapter.shapeOffset());
</del><ins>+ return std::min(fixedOffset, adapter.offset());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template<>
</span><del>-inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
</del><ins>+inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
</ins><span class="cx"> {
</span><span class="cx"> LayoutUnit logicalRight = m_renderer.logicalRightForFloat(floatingObject);
</span><span class="cx"> if (logicalRight > m_offset) {
</span><span class="lines">@@ -443,7 +437,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template<>
</span><del>-inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
</del><ins>+inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
</ins><span class="cx"> {
</span><span class="cx"> LayoutUnit logicalLeft = m_renderer.logicalLeftForFloat(floatingObject);
</span><span class="cx"> if (logicalLeft < m_offset) {
</span><span class="lines">@@ -454,6 +448,12 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template <FloatingObject::Type FloatTypeValue>
</span><ins>+LayoutUnit ComputeFloatOffsetForFloatLayoutAdapter<FloatTypeValue>::heightRemaining() const
+{
+ return this->m_outermostFloat ? this->m_renderer.logicalBottomForFloat(this->m_outermostFloat) - this->m_lineTop : LayoutUnit(1);
+}
+
+template <FloatingObject::Type FloatTypeValue>
</ins><span class="cx"> inline void ComputeFloatOffsetAdapter<FloatTypeValue>::collectIfNeeded(const IntervalType& interval)
</span><span class="cx"> {
</span><span class="cx"> const FloatingObject* floatingObject = interval.data();
</span><span class="lines">@@ -469,10 +469,58 @@
</span><span class="cx"> m_outermostFloat = floatingObject;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-template <FloatingObject::Type FloatTypeValue>
-LayoutUnit ComputeFloatOffsetAdapter<FloatTypeValue>::heightRemaining() const
</del><ins>+#if ENABLE(CSS_SHAPES)
+static inline ShapeOutsideInfo* shapeInfoForFloat(const FloatingObject* floatingObject, const RenderBlockFlow& containingBlock, LayoutUnit lineTop, LayoutUnit lineBottom)
</ins><span class="cx"> {
</span><del>- return m_outermostFloat ? m_renderer.logicalBottomForFloat(m_outermostFloat) - m_lineTop : LayoutUnit(1);
</del><ins>+ if (floatingObject) {
+ if (ShapeOutsideInfo* shapeOutside = floatingObject->renderer().shapeOutsideInfo()) {
+ shapeOutside->updateDeltasForContainingBlockLine(containingBlock, *floatingObject, lineTop, lineBottom - lineTop);
+ return shapeOutside;
+ }
+ }
+
+ return nullptr;
</ins><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx">
</span><ins>+template<>
+inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+{
+ LayoutUnit logicalRight = m_renderer.logicalRightForFloat(floatingObject);
+#if ENABLE(CSS_SHAPES)
+ if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(floatingObject, m_renderer, m_lineTop, m_lineBottom)) {
+ if (!shapeOutside->lineOverlapsShape())
+ return false;
+
+ logicalRight += shapeOutside->rightMarginBoxDelta();
+ }
+#endif
+ if (logicalRight > m_offset) {
+ m_offset = logicalRight;
+ return true;
+ }
+
+ return false;
+}
+
+template<>
+inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+{
+ LayoutUnit logicalLeft = m_renderer.logicalLeftForFloat(floatingObject);
+#if ENABLE(CSS_SHAPES)
+ if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(floatingObject, m_renderer, m_lineTop, m_lineBottom)) {
+ if (!shapeOutside->lineOverlapsShape())
+ return false;
+
+ logicalLeft += shapeOutside->leftMarginBoxDelta();
+ }
+#endif
+ if (logicalLeft < m_offset) {
+ m_offset = logicalLeft;
+ return true;
+ }
+
+ return false;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorerenderinglineLineWidthcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/line/LineWidth.cpp (162216 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/line/LineWidth.cpp        2014-01-17 21:10:37 UTC (rev 162216)
+++ trunk/Source/WebCore/rendering/line/LineWidth.cpp        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -100,54 +100,38 @@
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="cx"> #if ENABLE(CSS_SHAPES)
</span><del>- // When floats with shape outside are stacked, the floats are positioned based on the margin box of the float,
- // not the shape's contour. Since we computed the width based on the shape contour when we added the float,
- // when we add a subsequent float on the same line, we need to undo the shape delta in order to position
- // based on the margin box. In order to do this, we need to walk back through the floating object list to find
- // the first previous float that is on the same side as our newFloat.
- ShapeOutsideInfo* previousShapeOutsideInfo = nullptr;
- const FloatingObjectSet& floatingObjectSet = m_block.m_floatingObjects->set();
- auto it = floatingObjectSet.end();
- auto begin = floatingObjectSet.begin();
- LayoutUnit lineHeight = m_block.lineHeight(m_isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
- for (--it; it != begin; --it) {
- FloatingObject* previousFloat = it->get();
- if (previousFloat != newFloat && previousFloat->type() == newFloat->type()) {
- previousShapeOutsideInfo = previousFloat->renderer().shapeOutsideInfo();
- if (previousShapeOutsideInfo)
- previousShapeOutsideInfo->updateDeltasForContainingBlockLine(m_block, *previousFloat, m_block.logicalHeight(), lineHeight);
- break;
- }
- }
-
</del><span class="cx"> ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer().shapeOutsideInfo();
</span><del>- if (shapeOutsideInfo)
</del><ins>+ if (shapeOutsideInfo) {
+ LayoutUnit lineHeight = m_block.lineHeight(m_isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
</ins><span class="cx"> shapeOutsideInfo->updateDeltasForContainingBlockLine(m_block, *newFloat, m_block.logicalHeight(), lineHeight);
</span><ins>+ }
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> if (newFloat->type() == FloatingObject::FloatLeft) {
</span><span class="cx"> float newLeft = m_block.logicalRightForFloat(newFloat);
</span><del>-#if ENABLE(CSS_SHAPES)
- if (previousShapeOutsideInfo)
- newLeft -= previousShapeOutsideInfo->rightMarginBoxDelta();
- if (shapeOutsideInfo)
- newLeft += shapeOutsideInfo->rightMarginBoxDelta();
-#endif
-
</del><span class="cx"> if (shouldIndentText() && m_block.style().isLeftToRightDirection())
</span><span class="cx"> newLeft += floorToInt(m_block.textIndentOffset());
</span><ins>+#if ENABLE(CSS_SHAPES)
+ if (shapeOutsideInfo) {
+ if (shapeOutsideInfo->lineOverlapsShape())
+ newLeft += shapeOutsideInfo->rightMarginBoxDelta();
+ else // If the line doesn't overlap the shape, then we need to act as if this float didn't exist.
+ newLeft = m_left;
+ }
+#endif
</ins><span class="cx"> m_left = std::max<float>(m_left, newLeft);
</span><span class="cx"> } else {
</span><span class="cx"> float newRight = m_block.logicalLeftForFloat(newFloat);
</span><del>-#if ENABLE(CSS_SHAPES)
- if (previousShapeOutsideInfo)
- newRight -= previousShapeOutsideInfo->leftMarginBoxDelta();
- if (shapeOutsideInfo)
- newRight += shapeOutsideInfo->leftMarginBoxDelta();
-#endif
-
</del><span class="cx"> if (shouldIndentText() && !m_block.style().isLeftToRightDirection())
</span><span class="cx"> newRight -= floorToInt(m_block.textIndentOffset());
</span><ins>+#if ENABLE(CSS_SHAPES)
+ if (shapeOutsideInfo) {
+ if (shapeOutsideInfo->lineOverlapsShape())
+ newRight += shapeOutsideInfo->leftMarginBoxDelta();
+ else // If the line doesn't overlap the shape, then we need to act as if this float didn't exist.
+ newRight = m_right;
+ }
+#endif
</ins><span class="cx"> m_right = std::min<float>(m_right, newRight);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingshapesShapeOutsideInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp (162216 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp        2014-01-17 21:10:37 UTC (rev 162216)
+++ trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -79,19 +79,17 @@
</span><span class="cx">
</span><span class="cx"> LayoutUnit rawRightMarginBoxDelta = segments.last().logicalRight - containingBlock.logicalWidthForChild(m_renderer) - containingBlock.marginEndForChild(m_renderer);
</span><span class="cx"> m_rightMarginBoxDelta = clampTo<LayoutUnit>(rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit());
</span><ins>+ m_lineOverlapsShape = true;
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Lines that do not overlap the shape should act as if the float
</span><span class="cx"> // wasn't there for layout purposes. So we set the deltas to remove the
</span><del>- // entire width of the float.
- // FIXME: The latest CSS Shapes spec says that in this case, the
- // content should interact with previously stacked floats on the line
- // as if this outermost float did not exist. Perhaps obviously, this
- // solution cannot do that, and will be revisted with bug 122576.
</del><ins>+ // entire width of the float
</ins><span class="cx"> m_leftMarginBoxDelta = floatMarginBoxWidth;
</span><span class="cx"> m_rightMarginBoxDelta = -floatMarginBoxWidth;
</span><ins>+ m_lineOverlapsShape = false;
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingshapesShapeOutsideInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.h (162216 => 162217)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.h        2014-01-17 21:10:37 UTC (rev 162216)
+++ trunk/Source/WebCore/rendering/shapes/ShapeOutsideInfo.h        2014-01-17 21:11:49 UTC (rev 162217)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> public:
</span><span class="cx"> ShapeOutsideInfo(const RenderBox& renderer)
</span><span class="cx"> : ShapeInfo<RenderBox>(renderer)
</span><ins>+ , m_lineOverlapsShape(false)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -52,6 +53,7 @@
</span><span class="cx">
</span><span class="cx"> LayoutUnit leftMarginBoxDelta() const { return m_leftMarginBoxDelta; }
</span><span class="cx"> LayoutUnit rightMarginBoxDelta() const { return m_rightMarginBoxDelta; }
</span><ins>+ bool lineOverlapsShape() const { return m_lineOverlapsShape; }
</ins><span class="cx">
</span><span class="cx"> void updateDeltasForContainingBlockLine(const RenderBlockFlow&, const FloatingObject&, LayoutUnit lineTop, LayoutUnit lineHeight);
</span><span class="cx">
</span><span class="lines">@@ -84,6 +86,7 @@
</span><span class="cx"> LayoutUnit m_leftMarginBoxDelta;
</span><span class="cx"> LayoutUnit m_rightMarginBoxDelta;
</span><span class="cx"> LayoutUnit m_lineTop;
</span><ins>+ bool m_lineOverlapsShape;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> }
</span></span></pre>
</div>
</div>
</body>
</html>