<!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>[174489] 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/174489">174489</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2014-10-08 18:14:30 -0700 (Wed, 08 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Inline ruby does not get justified correctly
https://bugs.webkit.org/show_bug.cgi?id=137421

Source/WebCore:

Patch by Myles C. Maxfield &lt;litherum@gmail.com&gt; on 2014-10-08
Reviewed by Dave Hyatt.

We justify text in two passes: one counts expansion opportunities within a line,
and the other doles out widths and expansion amounts to constituent inline boxes.
This patch simply modifies both passes to descend into ruby bases. Once it has
done so, we then re-layout the ruby run with the newly found width.

Tests: fast/ruby/ruby-justification-hittest.html
       fast/ruby/ruby-justification.html

* rendering/InlineBox.h:
(WebCore::InlineBox::setExpansion): updateRubyForJustifiedText() has to set the
expansion for an inline box, so make setExpansion() public.
* rendering/RenderBlockLineLayout.cpp:
(WebCore::updateRubyForJustifiedText): Given values that have already been
computed in computeInlineDirectionPositionsForSegment(), adjust the widths and
expansion values for all the various pieces of ruby.
(WebCore::computeExpansionForJustifiedText): Call updateRubyForJustifiedText() if
necessary.
(WebCore::RenderBlockFlow::computeInlineDirectionPositionsForSegment): When
counting expansion opportunities in a line, include ruby bases.
* rendering/RenderRubyRun.h: Fix grammar in comment.
* rendering/RenderText.cpp:
(WebCore::RenderText::stringView): Give default arguments to function.
* rendering/RenderText.h: Ditto.

LayoutTests:

Reviewed by Dave Hyatt.

Test that ruby gets spaces inside the ruby base, and that hit testing the
ruby base gives us correct answers.

* fast/ruby/ruby-justification-expected.html: Added.
* fast/ruby/ruby-justification-hittest-expected.txt: Added.
* fast/ruby/ruby-justification-hittest.html: Added.
* fast/ruby/ruby-justification.html: Added.
* platform/mac/fast/ruby/bopomofo-rl-expected.txt: Ruby text gets the CSS
property text-align: justify, which worked prior to this patch. However, this
patch now justifies ruby bases, so now if there is text that is both a ruby
base and ruby text (such as ruby in ruby) it correctly gets justified. This
test does such, and therefore needs to be rebaselined.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmacfastrubybopomoforlexpectedtxt">trunk/LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFonth">trunk/Source/WebCore/platform/graphics/Font.h</a></li>
<li><a href="#trunkSourceWebCorerenderingInlineBoxh">trunk/Source/WebCore/rendering/InlineBox.h</a></li>
<li><a href="#trunkSourceWebCorerenderingInlineTextBoxh">trunk/Source/WebCore/rendering/InlineTextBox.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockLineLayoutcpp">trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBoxcpp">trunk/Source/WebCore/rendering/RenderBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderRubyBasecpp">trunk/Source/WebCore/rendering/RenderRubyBase.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderRubyRunh">trunk/Source/WebCore/rendering/RenderRubyRun.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTextcpp">trunk/Source/WebCore/rendering/RenderText.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderTexth">trunk/Source/WebCore/rendering/RenderText.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastrubyrubyjustificationexpectedhtml">trunk/LayoutTests/fast/ruby/ruby-justification-expected.html</a></li>
<li><a href="#trunkLayoutTestsfastrubyrubyjustificationhittestexpectedtxt">trunk/LayoutTests/fast/ruby/ruby-justification-hittest-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastrubyrubyjustificationhittesthtml">trunk/LayoutTests/fast/ruby/ruby-justification-hittest.html</a></li>
<li><a href="#trunkLayoutTestsfastrubyrubyjustificationhtml">trunk/LayoutTests/fast/ruby/ruby-justification.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/LayoutTests/ChangeLog        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2014-10-08  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Inline ruby does not get justified correctly
+        https://bugs.webkit.org/show_bug.cgi?id=137421
+
+        Reviewed by Dave Hyatt.
+
+        Test that ruby gets spaces inside the ruby base, and that hit testing the
+        ruby base gives us correct answers.
+
+        * fast/ruby/ruby-justification-expected.html: Added.
+        * fast/ruby/ruby-justification-hittest-expected.txt: Added.
+        * fast/ruby/ruby-justification-hittest.html: Added.
+        * fast/ruby/ruby-justification.html: Added.
+        * platform/mac/fast/ruby/bopomofo-rl-expected.txt: Ruby text gets the CSS
+        property text-align: justify, which worked prior to this patch. However, this
+        patch now justifies ruby bases, so now if there is text that is both a ruby
+        base and ruby text (such as ruby in ruby) it correctly gets justified. This
+        test does such, and therefore needs to be rebaselined.
+
</ins><span class="cx"> 2014-10-08  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         New baselines for iOS compositing tests.
</span></span></pre></div>
<a id="trunkLayoutTestsfastrubyrubyjustificationexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/ruby/ruby-justification-expected.html (0 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/ruby/ruby-justification-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-justification-expected.html        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+This test makes sure that ruby inside text-align: justify has its contents justified.
+&lt;div style=&quot;text-align: justify; font-size: 16px;&quot;&gt;
+&lt;div&gt;
+abcdefg abcdefg mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;div&gt;
+abcdefg abcdefg abcdefg mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;div&gt;
+abcdefg &lt;ruby&gt;abcdefg&lt;rt&gt;&lt;span style=&quot;color: transparent;&quot;&gt;a&lt;/span&gt;&lt;/ruby&gt; abcdefg mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;/div&gt;
+&lt;div style=&quot;font-family: Ahem; font-size: 16px;&quot;&gt;
+&lt;ruby&gt;abcdefg&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;abcdefg&lt;rt&gt;a&lt;/ruby&gt; mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;div style=&quot;text-align: right;&quot;&gt;
+a
+&lt;/div&gt;
+&lt;div style=&quot;text-align: justify;&quot;&gt;
+abcdefg abcdefg mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastrubyrubyjustificationhittestexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/ruby/ruby-justification-hittest-expected.txt (0 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/ruby/ruby-justification-hittest-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-justification-hittest-expected.txt        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+This test makes sure that hit testing works with ruby inside text-align: justify.
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS right is 792
+PASS document.elementFromPoint(right - 1, bottom - 1).id is &quot;ruby&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+abcdefg abcdefga mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
</ins></span></pre></div>
<a id="trunkLayoutTestsfastrubyrubyjustificationhittesthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/ruby/ruby-justification-hittest.html (0 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/ruby/ruby-justification-hittest.html                                (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-justification-hittest.html        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div style=&quot;text-align: justify; font-family: Ahem;&quot;&gt;
+&lt;ruby id=&quot;ruby&quot;&gt;abcdefg abcdefg&lt;rt&gt;a&lt;/ruby&gt; mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;script&gt;
+description(&quot;This test makes sure that hit testing works with ruby inside text-align: justify.&quot;);
+var ruby = document.getElementById(&quot;ruby&quot;);
+var boundingRect = ruby.getBoundingClientRect();
+var right = boundingRect.right;
+var bottom = boundingRect.bottom;
+shouldBe(&quot;right&quot;, &quot;792&quot;);
+shouldBeEqualToString(&quot;document.elementFromPoint(right - 1, bottom - 1).id&quot;, &quot;ruby&quot;);
+&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastrubyrubyjustificationhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/ruby/ruby-justification.html (0 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/ruby/ruby-justification.html                                (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-justification.html        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+This test makes sure that ruby inside text-align: justify has its contents justified.
+&lt;div style=&quot;text-align: justify; font-size: 16px;&quot;&gt;
+&lt;div&gt;
+&lt;ruby&gt;abcdefg abcdefg&lt;rt&gt; &lt;/ruby&gt; mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;div&gt;
+&lt;ruby&gt;abcdefg abcdefg&lt;rt&gt; &lt;/ruby&gt; abcdefg mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;div&gt;
+&lt;ruby&gt;abcdefg abcdefg&lt;rt&gt;&lt;span style=&quot;color: transparent;&quot;&gt;a&lt;/span&gt;&lt;/ruby&gt; abcdefg mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;div style=&quot;font-family: Ahem;&quot;&gt;
+&lt;ruby&gt;abcdefg abcdefg&lt;rt&gt;a&lt;/ruby&gt; mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;div&gt;
+&lt;ruby&gt;abcdefg abcdefg&lt;rt style=&quot;text-align: right; font-size: 16px;&quot;&gt;a&lt;/ruby&gt; mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+&lt;/div&gt;
+&lt;/div&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmacfastrubybopomoforlexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.txt (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.txt        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.txt        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -19,14 +19,14 @@
</span><span class="cx">               text run at (8,0) width 32: &quot;\x{4E16}&quot;
</span><span class="cx">         RenderRubyRun (anonymous) at (0,32) size 48x32
</span><span class="cx">           RenderRubyText {RT} at (0,0) size 8x32
</span><del>-            RenderRuby (inline) {RUBY} at (0,0) size 8x16
-              RenderRubyRun (anonymous) at (0,8) size 8x16
-                RenderRubyText {RT} at (-8,0) size 8x16
-                  RenderText {#text} at (0,4) size 8x8
-                    text run at (0,4) width 8: &quot;\x{2CB}&quot;
-                RenderRubyBase (anonymous) at (0,0) size 8x16
-                  RenderText {#text} at (0,0) size 8x16
-                    text run at (0,0) width 16: &quot;\x{3115}\x{3124}&quot;
</del><ins>+            RenderRuby (inline) {RUBY} at (0,0) size 8x24
+              RenderRubyRun (anonymous) at (0,4) size 8x24
+                RenderRubyText {RT} at (-8,0) size 8x24
+                  RenderText {#text} at (0,8) size 8x8
+                    text run at (0,8) width 8: &quot;\x{2CB}&quot;
+                RenderRubyBase (anonymous) at (0,0) size 8x24
+                  RenderText {#text} at (0,0) size 8x24
+                    text run at (0,0) width 24: &quot;\x{3115}\x{3124}&quot;
</ins><span class="cx">           RenderRubyBase (anonymous) at (0,0) size 48x32
</span><span class="cx">             RenderText {#text} at (8,0) size 32x32
</span><span class="cx">               text run at (8,0) width 32: &quot;\x{4E0A}&quot;
</span><span class="lines">@@ -45,14 +45,14 @@
</span><span class="cx">               text run at (8,0) width 32: &quot;\x{7121}&quot;
</span><span class="cx">         RenderRubyRun (anonymous) at (0,96) size 48x32
</span><span class="cx">           RenderRubyText {RT} at (0,0) size 8x32
</span><del>-            RenderRuby (inline) {RUBY} at (0,0) size 8x16
-              RenderRubyRun (anonymous) at (0,8) size 8x16
-                RenderRubyText {RT} at (-8,0) size 8x16
-                  RenderText {#text} at (0,4) size 8x8
-                    text run at (0,4) width 8: &quot;\x{2CA}&quot;
-                RenderRubyBase (anonymous) at (0,0) size 8x16
-                  RenderText {#text} at (0,0) size 8x16
-                    text run at (0,0) width 16: &quot;\x{310B}\x{3122}&quot;
</del><ins>+            RenderRuby (inline) {RUBY} at (0,0) size 8x24
+              RenderRubyRun (anonymous) at (0,4) size 8x24
+                RenderRubyText {RT} at (-8,0) size 8x24
+                  RenderText {#text} at (0,8) size 8x8
+                    text run at (0,8) width 8: &quot;\x{2CA}&quot;
+                RenderRubyBase (anonymous) at (0,0) size 8x24
+                  RenderText {#text} at (0,0) size 8x24
+                    text run at (0,0) width 24: &quot;\x{310B}\x{3122}&quot;
</ins><span class="cx">           RenderRubyBase (anonymous) at (0,0) size 48x32
</span><span class="cx">             RenderText {#text} at (8,0) size 32x32
</span><span class="cx">               text run at (8,0) width 32: &quot;\x{96E3}&quot;
</span><span class="lines">@@ -78,27 +78,27 @@
</span><span class="cx">               text run at (8,0) width 32: &quot;\x{53EA}&quot;
</span><span class="cx">         RenderRubyRun (anonymous) at (0,192) size 48x32
</span><span class="cx">           RenderRubyText {RT} at (0,0) size 8x32
</span><del>-            RenderRuby (inline) {RUBY} at (0,0) size 8x16
-              RenderRubyRun (anonymous) at (0,8) size 8x16
-                RenderRubyText {RT} at (-8,0) size 8x16
-                  RenderText {#text} at (0,4) size 8x8
-                    text run at (0,4) width 8: &quot;\x{2CB}&quot;
-                RenderRubyBase (anonymous) at (0,0) size 8x16
-                  RenderText {#text} at (0,0) size 8x16
-                    text run at (0,0) width 16: &quot;\x{3106}\x{311A}&quot;
</del><ins>+            RenderRuby (inline) {RUBY} at (0,0) size 8x24
+              RenderRubyRun (anonymous) at (0,4) size 8x24
+                RenderRubyText {RT} at (-8,0) size 8x24
+                  RenderText {#text} at (0,8) size 8x8
+                    text run at (0,8) width 8: &quot;\x{2CB}&quot;
+                RenderRubyBase (anonymous) at (0,0) size 8x24
+                  RenderText {#text} at (0,0) size 8x24
+                    text run at (0,0) width 24: &quot;\x{3106}\x{311A}&quot;
</ins><span class="cx">           RenderRubyBase (anonymous) at (0,0) size 48x32
</span><span class="cx">             RenderText {#text} at (8,0) size 32x32
</span><span class="cx">               text run at (8,0) width 32: &quot;\x{6015}&quot;
</span><span class="cx">         RenderRubyRun (anonymous) at (0,224) size 48x32
</span><span class="cx">           RenderRubyText {RT} at (0,0) size 8x32
</span><del>-            RenderRuby (inline) {RUBY} at (0,0) size 8x16
-              RenderRubyRun (anonymous) at (0,8) size 8x16
-                RenderRubyText {RT} at (-8,0) size 8x16
-                  RenderText {#text} at (0,4) size 8x8
-                    text run at (0,4) width 8: &quot;\x{2C7}&quot;
-                RenderRubyBase (anonymous) at (0,0) size 8x16
-                  RenderText {#text} at (0,0) size 8x16
-                    text run at (0,0) width 16: &quot;\x{3127}\x{3121}&quot;
</del><ins>+            RenderRuby (inline) {RUBY} at (0,0) size 8x24
+              RenderRubyRun (anonymous) at (0,4) size 8x24
+                RenderRubyText {RT} at (-8,0) size 8x24
+                  RenderText {#text} at (0,8) size 8x8
+                    text run at (0,8) width 8: &quot;\x{2C7}&quot;
+                RenderRubyBase (anonymous) at (0,0) size 8x24
+                  RenderText {#text} at (0,0) size 8x24
+                    text run at (0,0) width 24: &quot;\x{3127}\x{3121}&quot;
</ins><span class="cx">           RenderRubyBase (anonymous) at (0,0) size 48x32
</span><span class="cx">             RenderText {#text} at (8,0) size 32x32
</span><span class="cx">               text run at (8,0) width 32: &quot;\x{6709}&quot;
</span><span class="lines">@@ -111,14 +111,14 @@
</span><span class="cx">               text run at (8,0) width 32: &quot;\x{5FC3}&quot;
</span><span class="cx">         RenderRubyRun (anonymous) at (0,288) size 48x32
</span><span class="cx">           RenderRubyText {RT} at (0,0) size 8x32
</span><del>-            RenderRuby (inline) {RUBY} at (0,0) size 8x16
-              RenderRubyRun (anonymous) at (0,8) size 8x16
-                RenderRubyText {RT} at (-8,0) size 8x16
-                  RenderText {#text} at (0,4) size 8x8
-                    text run at (0,4) width 8: &quot;\x{2CA}&quot;
-                RenderRubyBase (anonymous) at (0,0) size 8x16
-                  RenderText {#text} at (0,0) size 8x16
-                    text run at (0,0) width 16: &quot;\x{3116}\x{3123}&quot;
</del><ins>+            RenderRuby (inline) {RUBY} at (0,0) size 8x24
+              RenderRubyRun (anonymous) at (0,4) size 8x24
+                RenderRubyText {RT} at (-8,0) size 8x24
+                  RenderText {#text} at (0,8) size 8x8
+                    text run at (0,8) width 8: &quot;\x{2CA}&quot;
+                RenderRubyBase (anonymous) at (0,0) size 8x24
+                  RenderText {#text} at (0,0) size 8x24
+                    text run at (0,0) width 24: &quot;\x{3116}\x{3123}&quot;
</ins><span class="cx">           RenderRubyBase (anonymous) at (0,0) size 48x32
</span><span class="cx">             RenderText {#text} at (8,0) size 32x32
</span><span class="cx">               text run at (8,0) width 32: &quot;\x{4EBA}&quot;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/ChangeLog        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -1,3 +1,34 @@
</span><ins>+2014-10-08  Myles C. Maxfield  &lt;litherum@gmail.com&gt;
+
+        Inline ruby does not get justified correctly
+        https://bugs.webkit.org/show_bug.cgi?id=137421
+
+        Reviewed by Dave Hyatt.
+
+        We justify text in two passes: one counts expansion opportunities within a line,
+        and the other doles out widths and expansion amounts to constituent inline boxes.
+        This patch simply modifies both passes to descend into ruby bases. Once it has
+        done so, we then re-layout the ruby run with the newly found width.
+
+        Tests: fast/ruby/ruby-justification-hittest.html
+               fast/ruby/ruby-justification.html
+
+        * rendering/InlineBox.h:
+        (WebCore::InlineBox::setExpansion): updateRubyForJustifiedText() has to set the
+        expansion for an inline box, so make setExpansion() public.
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::updateRubyForJustifiedText): Given values that have already been
+        computed in computeInlineDirectionPositionsForSegment(), adjust the widths and
+        expansion values for all the various pieces of ruby.
+        (WebCore::computeExpansionForJustifiedText): Call updateRubyForJustifiedText() if
+        necessary.
+        (WebCore::RenderBlockFlow::computeInlineDirectionPositionsForSegment): When
+        counting expansion opportunities in a line, include ruby bases.
+        * rendering/RenderRubyRun.h: Fix grammar in comment.
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::stringView): Give default arguments to function.
+        * rendering/RenderText.h: Ditto.
+
</ins><span class="cx"> 2014-10-08  Dean Jackson  &lt;dino@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         PopupMenus should indicate if they are using a custom rendering
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFonth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/Font.h (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/Font.h        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/platform/graphics/Font.h        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -201,6 +201,9 @@
</span><span class="cx">     static bool isCJKIdeograph(UChar32);
</span><span class="cx">     static bool isCJKIdeographOrSymbol(UChar32);
</span><span class="cx"> 
</span><ins>+    // BEWARE: If isAfterExpansion is true after this function call, then the returned value includes a trailing opportunity
+    // which may or may not actually be present. RenderBlockFlow::computeInlineDirectionPositionsForSegment() compensates
+    // for this by decrementing the returned value if isAfterExpansion is true at the end of a line.
</ins><span class="cx">     static unsigned expansionOpportunityCount(const StringView&amp;, TextDirection, bool&amp; isAfterExpansion);
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT static void setShouldUseSmoothing(bool);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingInlineBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/InlineBox.h (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/InlineBox.h        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/rendering/InlineBox.h        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -269,6 +269,13 @@
</span><span class="cx">     bool dirOverride() const { return m_bitfields.dirOverride(); }
</span><span class="cx">     void setDirOverride(bool dirOverride) { m_bitfields.setDirOverride(dirOverride); }
</span><span class="cx"> 
</span><ins>+    void setExpansion(float newExpansion)
+    {
+        m_logicalWidth -= m_expansion;
+        m_expansion = newExpansion;
+        m_logicalWidth += m_expansion;
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     InlineBox* m_next; // The next element on the same line as us.
</span><span class="cx">     InlineBox* m_prev; // The previous element on the same line as us.
</span><span class="lines">@@ -400,7 +407,6 @@
</span><span class="cx">     bool canHaveLeadingExpansion() const { return m_bitfields.hasSelectedChildrenOrCanHaveLeadingExpansion(); }
</span><span class="cx">     void setCanHaveLeadingExpansion(bool canHaveLeadingExpansion) { m_bitfields.setHasSelectedChildrenOrCanHaveLeadingExpansion(canHaveLeadingExpansion); }
</span><span class="cx">     float expansion() const { return m_expansion; }
</span><del>-    void setExpansion(float expansion) { m_expansion = expansion; }
</del><span class="cx">     
</span><span class="cx">     // For InlineFlowBox and InlineTextBox
</span><span class="cx">     bool extracted() const { return m_bitfields.extracted(); }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingInlineTextBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/InlineTextBox.h (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/InlineTextBox.h        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/rendering/InlineTextBox.h        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -133,13 +133,6 @@
</span><span class="cx"> public:
</span><span class="cx">     virtual bool isLineBreak() const override final;
</span><span class="cx"> 
</span><del>-    void setExpansion(float newExpansion)
-    {
-        m_logicalWidth -= expansion();
-        InlineBox::setExpansion(newExpansion);
-        m_logicalWidth += newExpansion;
-    }
-
</del><span class="cx"> private:
</span><span class="cx">     virtual bool isInlineTextBox() const override final { return true; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockLineLayoutcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -38,6 +38,8 @@
</span><span class="cx"> #include &quot;RenderFlowThread.h&quot;
</span><span class="cx"> #include &quot;RenderLineBreak.h&quot;
</span><span class="cx"> #include &quot;RenderRegion.h&quot;
</span><ins>+#include &quot;RenderRubyBase.h&quot;
+#include &quot;RenderRubyText.h&quot;
</ins><span class="cx"> #include &quot;RenderView.h&quot;
</span><span class="cx"> #include &quot;SVGRootInlineBox.h&quot;
</span><span class="cx"> #include &quot;Settings.h&quot;
</span><span class="lines">@@ -544,8 +546,42 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, Vector&lt;unsigned, 16&gt;&amp; expansionOpportunities, unsigned expansionOpportunityCount, float&amp; totalLogicalWidth, float availableLogicalWidth)
</del><ins>+static inline void updateRubyForJustifiedText(RenderRubyRun&amp; rubyRun, BidiRun&amp; r, const Vector&lt;unsigned, 16&gt;&amp; expansionOpportunities, unsigned&amp; expansionOpportunityCount, float&amp; totalLogicalWidth, float availableLogicalWidth, size_t&amp; i)
</ins><span class="cx"> {
</span><ins>+    if (!rubyRun.rubyBase() || !rubyRun.rubyBase()-&gt;firstRootBox() || rubyRun.rubyBase()-&gt;firstRootBox()-&gt;nextRootBox() || !r.renderer().style().collapseWhiteSpace())
+        return;
+
+    auto&amp; rubyBase = *rubyRun.rubyBase();
+    auto&amp; rootBox = *rubyBase.firstRootBox();
+
+    float totalExpansion = 0;
+    unsigned totalOpportunitiesInRun = 0;
+    for (auto* leafChild = rootBox.firstLeafChild(); leafChild; leafChild = leafChild-&gt;nextLeafChild()) {
+        if (!leafChild-&gt;isInlineTextBox())
+            continue;
+
+        unsigned opportunitiesInRun = expansionOpportunities[i++];
+        ASSERT(opportunitiesInRun &lt;= expansionOpportunityCount);
+        auto expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
+        totalExpansion += expansion;
+        totalOpportunitiesInRun += opportunitiesInRun;
+    }
+
+    if (totalOpportunitiesInRun) {
+        ASSERT(!rubyRun.hasOverrideWidth());
+        rubyRun.setOverrideLogicalContentWidth(rubyRun.logicalWidth() + totalExpansion);
+        rubyRun.setNeedsLayout(MarkOnlyThis);
+        rubyRun.layoutBlock(true);
+        rubyRun.clearOverrideLogicalContentWidth();
+        r.box()-&gt;setExpansion(totalExpansion);
+
+        totalLogicalWidth += totalExpansion;
+        expansionOpportunityCount -= totalOpportunitiesInRun;
+    }
+}
+
+static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, const Vector&lt;unsigned, 16&gt;&amp; expansionOpportunities, unsigned expansionOpportunityCount, float totalLogicalWidth, float availableLogicalWidth)
+{
</ins><span class="cx">     if (!expansionOpportunityCount || availableLogicalWidth &lt;= totalLogicalWidth)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -567,9 +603,11 @@
</span><span class="cx">                 totalLogicalWidth += expansion;
</span><span class="cx">             }
</span><span class="cx">             expansionOpportunityCount -= opportunitiesInRun;
</span><del>-            if (!expansionOpportunityCount)
-                break;
-        }
</del><ins>+        } else if (r-&gt;renderer().isRubyRun())
+            updateRubyForJustifiedText(toRenderRubyRun(r-&gt;renderer()), *r, expansionOpportunities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth, i);
+
+        if (!expansionOpportunityCount)
+            break;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -695,7 +733,27 @@
</span><span class="cx"> 
</span><span class="cx">             setLogicalWidthForTextRun(lineBox, r, &amp;renderText, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache, wordMeasurements);
</span><span class="cx">         } else {
</span><del>-            isAfterExpansion = false;
</del><ins>+            bool encounteredJustifiedRuby = false;
+            if (r-&gt;renderer().isRubyRun() &amp;&amp; textAlign == JUSTIFY &amp;&amp; r != trailingSpaceRun &amp;&amp; toRenderRubyRun(r-&gt;renderer()).rubyBase()) {
+                auto* rubyBase = toRenderRubyRun(r-&gt;renderer()).rubyBase();
+                if (rubyBase-&gt;firstRootBox() &amp;&amp; !rubyBase-&gt;firstRootBox()-&gt;nextRootBox() &amp;&amp; r-&gt;renderer().style().collapseWhiteSpace()) {
+                    for (auto* leafChild = rubyBase-&gt;firstRootBox()-&gt;firstLeafChild(); leafChild; leafChild = leafChild-&gt;nextLeafChild()) {
+                        if (!leafChild-&gt;isInlineTextBox())
+                            continue;
+                        if (!isAfterExpansion)
+                            toInlineTextBox(leafChild)-&gt;setCanHaveLeadingExpansion(true);
+                        encounteredJustifiedRuby = true;
+                        auto&amp; renderText = downcast&lt;RenderText&gt;(leafChild-&gt;renderer());
+                        unsigned opportunitiesInRun = Font::expansionOpportunityCount(renderText.stringView(), leafChild-&gt;direction(), isAfterExpansion);
+                        expansionOpportunities.append(opportunitiesInRun);
+                        expansionOpportunityCount += opportunitiesInRun;
+                    }
+                }
+            }
+
+            if (!encounteredJustifiedRuby)
+                isAfterExpansion = false;
+
</ins><span class="cx">             if (!r-&gt;renderer().isRenderInline()) {
</span><span class="cx">                 RenderBox&amp; renderBox = toRenderBox(r-&gt;renderer());
</span><span class="cx">                 if (renderBox.isRubyRun())
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.cpp        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -2285,7 +2285,7 @@
</span><span class="cx">     // width.  Use the width from the style context.
</span><span class="cx">     // FIXME: Account for block-flow in flexible boxes.
</span><span class="cx">     // https://bugs.webkit.org/show_bug.cgi?id=46418
</span><del>-    if (hasOverrideWidth() &amp;&amp; (style().borderFit() == BorderFitLines || parent()-&gt;isFlexibleBoxIncludingDeprecated())) {
</del><ins>+    if (hasOverrideWidth() &amp;&amp; (isRubyRun() || style().borderFit() == BorderFitLines || parent()-&gt;isFlexibleBoxIncludingDeprecated())) {
</ins><span class="cx">         computedValues.m_extent = overrideLogicalContentWidth() + borderAndPaddingLogicalWidth();
</span><span class="cx">         return;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderRubyBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderRubyBase.cpp (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderRubyBase.cpp        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/rendering/RenderRubyBase.cpp        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -143,7 +143,7 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderRubyBase::adjustInlineDirectionLineBounds(int expansionOpportunityCount, float&amp; logicalLeft, float&amp; logicalWidth) const
</span><span class="cx"> {
</span><del>-    int maxPreferredLogicalWidth = this-&gt;maxPreferredLogicalWidth();
</del><ins>+    LayoutUnit maxPreferredLogicalWidth = rubyRun() &amp;&amp; rubyRun()-&gt;hasOverrideWidth() ? rubyRun()-&gt;overrideLogicalContentWidth() : this-&gt;maxPreferredLogicalWidth();
</ins><span class="cx">     if (maxPreferredLogicalWidth &gt;= logicalWidth)
</span><span class="cx">         return;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderRubyRunh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderRubyRun.h (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderRubyRun.h        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/rendering/RenderRubyRun.h        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx"> class RenderRubyBase;
</span><span class="cx"> class RenderRubyText;
</span><span class="cx"> 
</span><del>-// RenderRubyRun are 'inline-block/table' like objects,and wrap a single pairing of a ruby base with its ruby text(s).
</del><ins>+// RenderRubyRuns are 'inline-block/table' like objects, and wrap a single pairing of a ruby base with its ruby text(s).
</ins><span class="cx"> // See RenderRuby.h for further comments on the structure
</span><span class="cx"> 
</span><span class="cx"> class RenderRubyRun final : public RenderBlockFlow {
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderText.cpp (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderText.cpp        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/rendering/RenderText.cpp        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -1529,6 +1529,8 @@
</span><span class="cx"> 
</span><span class="cx"> StringView RenderText::stringView(int start, int stop) const
</span><span class="cx"> {
</span><ins>+    if (stop == -1)
+        stop = textLength();
</ins><span class="cx">     ASSERT(static_cast&lt;unsigned&gt;(start) &lt;= length());
</span><span class="cx">     ASSERT(static_cast&lt;unsigned&gt;(stop) &lt;= length());
</span><span class="cx">     ASSERT(start &lt;= stop);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderTexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderText.h (174488 => 174489)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderText.h        2014-10-09 01:05:55 UTC (rev 174488)
+++ trunk/Source/WebCore/rendering/RenderText.h        2014-10-09 01:14:30 UTC (rev 174489)
</span><span class="lines">@@ -156,7 +156,7 @@
</span><span class="cx">     void deleteLineBoxesBeforeSimpleLineLayout();
</span><span class="cx">     const SimpleLineLayout::Layout* simpleLineLayout() const;
</span><span class="cx"> 
</span><del>-    StringView stringView(int start, int stop) const;
</del><ins>+    StringView stringView(int start = 0, int stop = -1) const;
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     virtual void computePreferredLogicalWidths(float leadWidth);
</span></span></pre>
</div>
</div>

</body>
</html>