Title: [182286] trunk
Revision
182286
Author
mmaxfi...@apple.com
Date
2015-04-02 13:29:23 -0700 (Thu, 02 Apr 2015)

Log Message

Disallow ruby base from having leading or trailing expansions
https://bugs.webkit.org/show_bug.cgi?id=142608

Reviewed by David Hyatt.

Source/WebCore:

If we determine that a ruby base should have either a leading or trailing expansion,
we shunt that expansion over to the neighboring RenderText, assuming one exists. This
requires that we teach RenderText how to force leading or trailing expansions if one
wouldn't naturally be present.

Tests: fast/ruby/ruby-expansion-cjk-2.html
       fast/ruby/ruby-expansion-cjk-3.html
       fast/ruby/ruby-expansion-cjk-4.html
       fast/ruby/ruby-expansion-cjk-5.html
       fast/ruby/ruby-expansion-cjk.html

* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::removeChild): Delete contentIsKnownToFollow.
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::expansionBehavior): Support forced leading and trailing
expansions.
* rendering/InlineTextBox.h:
(WebCore::InlineTextBox::expansionBehavior): Moved to .cpp
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlockFlow::updateRubyForJustifiedText): Perform relayout even if
there are no expansions left. This is so that ruby bases with no expansions will get
centered.
(WebCore::expansionBehaviorForInlineTextBox): Update to inspect neighboring rubies.
(WebCore::RenderBlockFlow::computeInlineDirectionPositionsForSegment): Use updated
expansionBehaviorForInlineTextBox(). Also center ruby bases if they have no expansion
opportunities.
(WebCore::RenderBlockFlow::createLineBoxesFromBidiRuns): Use nullptr.
(WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange): Ditto.
* rendering/RenderText.cpp:
(WebCore::RenderText::RenderText): Delete contentIsKnownToFollow.
* rendering/RenderText.h:
(WebCore::RenderText::contentIsKnownToFollow): Deleted.
(WebCore::RenderText::setContentIsKnownToFollow): Deleted.

LayoutTests:

Test combinations of CJK, Latin, ruby-in-ruby, simple text codepath, complex
text codepath, RTL, and LTR codepaths.

* fast/ruby/positioned-ruby-text-expected.txt:
* fast/ruby/positioned-ruby-text.html:
* fast/ruby/resources/green.png: Added.
* fast/ruby/resources/ruby-expansion.svg: Added.
* fast/ruby/ruby-expansion-cjk-2-expected.html: Added.
* fast/ruby/ruby-expansion-cjk-2.html: Added.
* fast/ruby/ruby-expansion-cjk-3-expected.html: Added.
* fast/ruby/ruby-expansion-cjk-3.html: Added.
* fast/ruby/ruby-expansion-cjk-4-expected.html: Added.
* fast/ruby/ruby-expansion-cjk-4.html: Added.
* fast/ruby/ruby-expansion-cjk-5-expected.html: Added.
* fast/ruby/ruby-expansion-cjk-5.html: Added.
* fast/ruby/ruby-expansion-cjk-expected.html: Added.
* fast/ruby/ruby-expansion-cjk.html: Added.
* fast/ruby/ruby-justification-expected.html:
* fast/ruby/ruby-justification.html:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (182285 => 182286)


--- trunk/LayoutTests/ChangeLog	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/LayoutTests/ChangeLog	2015-04-02 20:29:23 UTC (rev 182286)
@@ -1,3 +1,30 @@
+2015-04-02  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Disallow ruby base from having leading or trailing expansions
+        https://bugs.webkit.org/show_bug.cgi?id=142608
+
+        Reviewed by David Hyatt.
+
+        Test combinations of CJK, Latin, ruby-in-ruby, simple text codepath, complex
+        text codepath, RTL, and LTR codepaths.
+
+        * fast/ruby/positioned-ruby-text-expected.txt:
+        * fast/ruby/positioned-ruby-text.html:
+        * fast/ruby/resources/green.png: Added.
+        * fast/ruby/resources/ruby-expansion.svg: Added.
+        * fast/ruby/ruby-expansion-cjk-2-expected.html: Added.
+        * fast/ruby/ruby-expansion-cjk-2.html: Added.
+        * fast/ruby/ruby-expansion-cjk-3-expected.html: Added.
+        * fast/ruby/ruby-expansion-cjk-3.html: Added.
+        * fast/ruby/ruby-expansion-cjk-4-expected.html: Added.
+        * fast/ruby/ruby-expansion-cjk-4.html: Added.
+        * fast/ruby/ruby-expansion-cjk-5-expected.html: Added.
+        * fast/ruby/ruby-expansion-cjk-5.html: Added.
+        * fast/ruby/ruby-expansion-cjk-expected.html: Added.
+        * fast/ruby/ruby-expansion-cjk.html: Added.
+        * fast/ruby/ruby-justification-expected.html:
+        * fast/ruby/ruby-justification.html:
+
 2015-04-02  Alexey Proskuryakov  <a...@apple.com>
 
         Clean up access checks in JSHistoryCustom.cpp

Modified: trunk/LayoutTests/fast/ruby/positioned-ruby-text-expected.txt (182285 => 182286)


--- trunk/LayoutTests/fast/ruby/positioned-ruby-text-expected.txt	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/LayoutTests/fast/ruby/positioned-ruby-text-expected.txt	2015-04-02 20:29:23 UTC (rev 182286)
@@ -1,7 +1,7 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x51
-  RenderBlock {HTML} at (0,0) size 800x51 [color=#FFFFFF]
+  RenderBlock {HTML} at (0,0) size 800x51
     RenderBody {BODY} at (8,8) size 784x35
       RenderRuby (inline) {RUBY} at (0,0) size 784x10
         RenderRubyRun (anonymous) at (0,5) size 784x30
@@ -12,5 +12,5 @@
             RenderText {#text} at (0,0) size 784x30
               text run at (0,0) width 784: "Attempt to create a positioned ruby text element. Non-static position is not"
               text run at (0,10) width 784: "supported for ruby text, which should be apparent from the resulting render"
-              text run at (0,20) width 50: "tree."
+              text run at (367,20) width 50: "tree."
       RenderText {#text} at (0,0) size 0x0

Modified: trunk/LayoutTests/fast/ruby/positioned-ruby-text.html (182285 => 182286)


--- trunk/LayoutTests/fast/ruby/positioned-ruby-text.html	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/LayoutTests/fast/ruby/positioned-ruby-text.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -1,4 +1,4 @@
 <!DOCTYPE html>
-<html style="font-family: ahem; font-size: 10px; -webkit-font-smoothing: none; color: white;">
+<html style="font-family: ahem; font-size: 10px; -webkit-font-smoothing: none;">
 <ruby>Attempt to create a positioned ruby text element. Non-static position is not supported for ruby text, which should be apparent from the resulting render tree.<rt style="position: fixed">rubytext</rt></ruby>
 </html>

Added: trunk/LayoutTests/fast/ruby/resources/green.png (0 => 182286)


--- trunk/LayoutTests/fast/ruby/resources/green.png	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/resources/green.png	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,4 @@
+\x89PNG
+
++IHDRd2\x90\xFB\xEC\xFDPLTE\xFF4^\xC0\xA8IDAT(c`\xA3`h\xBC\xDD\xE3\x90IEND\xAEB`\x82
\ No newline at end of file

Added: trunk/LayoutTests/fast/ruby/resources/ruby-expansion.svg (0 => 182286)


--- trunk/LayoutTests/fast/ruby/resources/ruby-expansion.svg	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/resources/ruby-expansion.svg	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,13 @@
+<?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">
+<defs>
+<font id="Litherum" horiz-adv-x="1024">
+<font-face font-family="Litherum" units-per-em="1024" ascent="1024" descent="0"/>
+<glyph unicode="a" horiz-adv-x="1024" d="M0 0v1024h1024v-1024z"/>
+<glyph unicode="&#x304e;" horiz-adv-x="1024" d="M0 0v1024h1024v-1024z"/>
+<glyph unicode="&#x5e2;" horiz-adv-x="1024" d="M0 0v1024h1024v-1024z"/>
+<glyph unicode="&#x62a;" horiz-adv-x="1024" d="M0 0v1024h1024v-1024z"/>
+</font>
+</defs>
+</svg>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-2-expected.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-2-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-2-expected.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<head>
+</head>
+<body>
+<div style="position: absolute; left: 0px; top: 0px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 200px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 380px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 120px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 180px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 360px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 80px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 240px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 220px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 81px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 400px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 360px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 200px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 81px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 380px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 80px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 480px; width: 100%;">
+<div style="position: absolute; width: 300px; height: 20px; left: 0px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 300px; height: 20px; right: 00px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 130px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 380px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; right: 129px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+</body>
+</html>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-2.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-2.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-2.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8"/>
+<style>
+@font-face {
+    font-family: 'Litherum';
+    src: url("resources/ruby-expansion.svg#Litherum") format(svg);
+}
+</style>
+</head>
+<body style="text-align: justify; font: 40px Litherum; margin: 0px; -webkit-font-smoothing: none;">
+<div dir="rtl">&#x5e2;<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>&#x5e2; aaaaaaaaaaaaaaaaaaaa</div>
+<div dir="rtl">&#x5e2;&#x5e2;<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>&#x5e2; aaaaaaaaaaaaaaaaaaaa</div>
+<div dir="rtl">&#x5e2;<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>&#x5e2;&#x5e2; aaaaaaaaaaaaaaaaaaaa</div>
+<div dir="rtl">&#x5e2;&#x5e2;<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>&#x5e2;&#x5e2; aaaaaaaaaaaaaaaaaaaa</div>
+<div><ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaa</rt></ruby>a<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaa</rt></ruby> aaaaaaaaaaaaaaaaaaaa</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-3-expected.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-3-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-3-expected.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<head>
+</head>
+<body>
+<div style="position: absolute; left: 0px; top: 0px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 199px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 40px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 166px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; right: 166px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 40px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 120px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 265px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 40px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 210px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 80px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 40px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 240px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 135px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 40px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 80px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 550px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 40px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 360px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 199px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; left: 0px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 40px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 166px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; right: 166px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 40px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 480px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 135px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; left: 0px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 40px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 80px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 550px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 40px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+</body>
+</html>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-3.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-3.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-3.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8"/>
+<style>
+@font-face {
+    font-family: 'Litherum';
+    src: url("resources/ruby-expansion.svg#Litherum") format(svg);
+}
+</style>
+</head>
+<body style="text-align: justify; font: 40px Litherum; margin: 0px; -webkit-font-smoothing: none;">
+<div dir="rtl"><span style="color: green;">&#x5e2;</span>&#x5e2;<ruby><rb><span style="color: green;">&#x304e;</span>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby><span style="color: green;">&#x5e2;</span>&#x5e2; aaaaaaaaaaaaaaaaaaaa</div>
+<div dir="rtl"><span style="color: green;">&#x5e2;</span>&#x5e2;<ruby><rb><span style="color: green;">&#x5e2;</span>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby><span style="color: green;">&#x5e2;</span>&#x5e2; aaaaaaaaaaaaaaaaaaaa</div>
+<div dir="rtl"><span style="color: green;">&#x5e2;</span>&#x5e2;<ruby><rb><span style="color: green;">&#x304e;</span>&#x5e2;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby><span style="color: green;">&#x5e2;</span>&#x5e2; aaaaaaaaaaaaaaaaaaaa</div>
+<div><span style="color: green;">a</span>a<ruby><rb><span style="color: green;">&#x304e;</span>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby><span style="color: green;">a</span>a aaaaaaaaaaaaaaaaaaaa</div>
+<div><span style="color: green;">a</span>a<ruby><rb><span style="color: green;">a</span>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby><span style="color: green;">a</span>a aaaaaaaaaaaaaaaaaaaa</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-4-expected.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-4-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-4-expected.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8"/>
+<style>
+@font-face {
+    font-family: 'Litherum';
+    src: url("resources/ruby-expansion.svg#Litherum") format(svg);
+}
+</style>
+</head>
+<body style="text-align: justify; font-size: 40px; margin: 0px; -webkit-font-smoothing: none;">
+<div>e&#x300;a&#x300;<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>e&#x300;a&#x300; <span style="font-family: Litherum;">aaaaaaaaaaaaaaaaaaaa</span></div>
+<div style="font-family: Litherum;">
+<div style="position: absolute; left: 0px; top: 126px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 199px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 40px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 166px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 41px; height: 41px; right: 166px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 40px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: green;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 239px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 200px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 400px; height: 20px; left: 199px; top: 21px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 0px; top: 40px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 120px; top: 40px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 193px; top: 40px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; right: 193px; top: 40px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; right: 119px; top: 40px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 40px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 91px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 380px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 100px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 100px; height: 50px; left: 0px; top: 10px; background: rgb(0, 255, 0);"></div>
+<div style="position: absolute; width: 41px; height: 41px; right: 479px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-4.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-4.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-4.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8"/>
+<style>
+@font-face {
+    font-family: 'Litherum';
+    src: url("resources/ruby-expansion.svg#Litherum") format(svg);
+}
+</style>
+</head>
+<body style="text-align: justify; font-size: 40px; margin: 0px; -webkit-font-smoothing: none;">
+<div>&#xe8;&#xe0;<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>&#xe8;&#xe0; <span style="font-family: Litherum;">aaaaaaaaaaaaaaaaaaaa</span></div>
+<div style="font-family: Litherum;">
+<div dir="rtl"><span style="color: green;">&#x62a;</span>&#x62a;<ruby><rb><span style="color: green;">&#x304e;</span>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby><span style="color: green;">&#x62a;</span>&#x62a; aaaaaaaaaaaaaaaaaaaa</div>
+<div>a<ruby><rb>&#x304e;<ruby><rb>&#x304e;&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>a <span style="font-family: Litherum;">aaaaaaaaaaaaaaaaaaaa</span></div>
+<div><img src="" <span style="font-family: Litherum;">aaaaaaaaaaaaaaaaaaaa</span></div>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-5-expected.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-5-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-5-expected.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8"/>
+</head>
+<body style="text-align: justify; font: 40px Litherum; margin: 0px; -webkit-font-smoothing: none;">
+<div style="position: absolute; left: 0px; top: 0px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; right: 100px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 480px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 100px; height: 50px; right: 0px; top: 10px; background: rgb(0, 255, 0);"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-5.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-5.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-5.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8"/>
+<style>
+@font-face {
+    font-family: 'Litherum';
+    src: url("resources/ruby-expansion.svg#Litherum") format(svg);
+}
+</style>
+</head>
+<body style="text-align: justify; font: 40px Litherum; margin: 0px; -webkit-font-smoothing: none;">
+<div>a<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby><img src="" <span style="font-family: Litherum;">aaaaaaaaaaaaaaaaaaaa</span></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-expected.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk-expected.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<head>
+</head>
+<body>
+<div style="position: absolute; left: 0px; top: 0px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 200px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 380px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 120px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 199px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 153px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 606px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 240px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 199px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 153px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 606px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 360px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 200px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 81px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 41px; height: 41px; left: 380px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 80px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+<div style="position: absolute; left: 0px; top: 480px; width: 100%;">
+<div style="position: absolute; width: 400px; height: 20px; left: 70px; top: 0px; background: black;"></div>
+<div style="position: absolute; width: 81px; height: 41px; left: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 81px; height: 41px; left: 230px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 81px; height: 41px; left: 460px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 40px; height: 41px; right: 0px; top: 19px; background: black;"></div>
+<div style="position: absolute; width: 800px; height: 41px; left: 0px; top: 70px; background: black;"></div>
+</div>
+
+</body>
+</html>

Added: trunk/LayoutTests/fast/ruby/ruby-expansion-cjk.html (0 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-expansion-cjk.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-expansion-cjk.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8"/>
+<style>
+@font-face {
+    font-family: 'Litherum';
+    src: url("resources/ruby-expansion.svg#Litherum") format(svg);
+}
+</style>
+</head>
+<body style="text-align: justify; font: 40px Litherum; margin: 0px; -webkit-font-smoothing: none;">
+<div>&#x304e;<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>&#x304e;aaaaaaaaaaaaaaaaaaaa</div>
+<div>&#x304e;<ruby><rb>a&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>&#x304e;aaaaaaaaaaaaaaaaaaaa</div>
+<div>&#x304e;<ruby><rb>&#x304e;a</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>&#x304e;aaaaaaaaaaaaaaaaaaaa</div>
+<div>aa<ruby><rb>&#x304e;</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>aa aaaaaaaaaaaaaaaaaaaa</div>
+<div>aa<ruby><rb>aa</rb><rt>aaaaaaaaaaaaaaaaaaaa</rt></ruby>aa a aaaaaaaaaaaaaaaaaaaa</div>
+</body>
+</html>

Modified: trunk/LayoutTests/fast/ruby/ruby-justification-expected.html (182285 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-justification-expected.html	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/LayoutTests/fast/ruby/ruby-justification-expected.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -13,7 +13,7 @@
 abcdefg <ruby>a<rt><span style="color: transparent;">a</span></ruby> abcdefg mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
 </div>
 <div>
-a<span style="background: green;">&#x685c;</span>b mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+a<span">&#x685c;</span>b mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
 </div>
 </div>
 <div style="font-family: Ahem; font-size: 16px;">

Modified: trunk/LayoutTests/fast/ruby/ruby-justification.html (182285 => 182286)


--- trunk/LayoutTests/fast/ruby/ruby-justification.html	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/LayoutTests/fast/ruby/ruby-justification.html	2015-04-02 20:29:23 UTC (rev 182286)
@@ -13,7 +13,7 @@
 abcdefg <ruby>a<rt><span style="color: transparent;">aaaaaaaaaaaaaaaaaaaaaaa</span></ruby> abcdefg mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
 </div>
 <div>
-a<ruby><rb style="background: green;">&#x685c;</rb><rt> </ruby>b mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+a<ruby><rb>&#x685c;</rb><rt> </ruby>b mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
 </div>
 <div style="font-family: Ahem;">
 <ruby>abcdefg abcdefg<rt>a</ruby> mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm

Modified: trunk/Source/WebCore/ChangeLog (182285 => 182286)


--- trunk/Source/WebCore/ChangeLog	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/Source/WebCore/ChangeLog	2015-04-02 20:29:23 UTC (rev 182286)
@@ -1,3 +1,44 @@
+2015-04-02  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Disallow ruby base from having leading or trailing expansions
+        https://bugs.webkit.org/show_bug.cgi?id=142608
+
+        Reviewed by David Hyatt.
+
+        If we determine that a ruby base should have either a leading or trailing expansion,
+        we shunt that expansion over to the neighboring RenderText, assuming one exists. This
+        requires that we teach RenderText how to force leading or trailing expansions if one
+        wouldn't naturally be present.
+
+        Tests: fast/ruby/ruby-expansion-cjk-2.html
+               fast/ruby/ruby-expansion-cjk-3.html
+               fast/ruby/ruby-expansion-cjk-4.html
+               fast/ruby/ruby-expansion-cjk-5.html
+               fast/ruby/ruby-expansion-cjk.html
+
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::removeChild): Delete contentIsKnownToFollow.
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::expansionBehavior): Support forced leading and trailing
+        expansions.
+        * rendering/InlineTextBox.h:
+        (WebCore::InlineTextBox::expansionBehavior): Moved to .cpp
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlockFlow::updateRubyForJustifiedText): Perform relayout even if
+        there are no expansions left. This is so that ruby bases with no expansions will get
+        centered.
+        (WebCore::expansionBehaviorForInlineTextBox): Update to inspect neighboring rubies.
+        (WebCore::RenderBlockFlow::computeInlineDirectionPositionsForSegment): Use updated
+        expansionBehaviorForInlineTextBox(). Also center ruby bases if they have no expansion
+        opportunities.
+        (WebCore::RenderBlockFlow::createLineBoxesFromBidiRuns): Use nullptr.
+        (WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange): Ditto.
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::RenderText): Delete contentIsKnownToFollow.
+        * rendering/RenderText.h:
+        (WebCore::RenderText::contentIsKnownToFollow): Deleted.
+        (WebCore::RenderText::setContentIsKnownToFollow): Deleted.
+
 2015-04-02  Alexey Proskuryakov  <a...@apple.com>
 
         Clean up access checks in JSHistoryCustom.cpp

Modified: trunk/Source/WebCore/rendering/InlineFlowBox.cpp (182285 => 182286)


--- trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/Source/WebCore/rendering/InlineFlowBox.cpp	2015-04-02 20:29:23 UTC (rev 182286)
@@ -179,14 +179,6 @@
     if (!isDirty())
         dirtyLineBoxes();
 
-    if (child->prevLeafChild() && is<InlineTextBox>(child->prevLeafChild())) {
-        if (is<InlineTextBox>(child))
-            downcast<InlineTextBox>(child->prevLeafChild())->renderer().setContentIsKnownToFollow(downcast<InlineTextBox>(child)->renderer().contentIsKnownToFollow());
-        // FIXME: Handle the case where we remove the last inline box, and it's not a text box. If we're trying to share
-        // expansion opportunites both inside and outside a replaced element (such as for ruby bases), we need to search
-        // outside the current inline box tree to determine if there is content that follows the new last inline item.
-    }
-
     root().childRemoved(child);
 
     if (child == m_firstChild)

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (182285 => 182286)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2015-04-02 20:29:23 UTC (rev 182286)
@@ -1394,6 +1394,27 @@
     return run;
 }
 
+ExpansionBehavior InlineTextBox::expansionBehavior() const
+{
+    ExpansionBehavior leadingBehavior;
+    if (forceLeadingExpansion())
+        leadingBehavior = ForceLeadingExpansion;
+    else if (canHaveLeadingExpansion())
+        leadingBehavior = AllowLeadingExpansion;
+    else
+        leadingBehavior = ForbidLeadingExpansion;
+
+    ExpansionBehavior trailingBehavior;
+    if (forceTrailingExpansion())
+        trailingBehavior = ForceTrailingExpansion;
+    else if (expansion() && nextLeafChild() && !nextLeafChild()->isLineBreak())
+        trailingBehavior = AllowTrailingExpansion;
+    else
+        trailingBehavior = ForbidTrailingExpansion;
+
+    return leadingBehavior | trailingBehavior;
+}
+
 #if ENABLE(TREE_DEBUGGING)
 
 const char* InlineTextBox::boxName() const

Modified: trunk/Source/WebCore/rendering/InlineTextBox.h (182285 => 182286)


--- trunk/Source/WebCore/rendering/InlineTextBox.h	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/Source/WebCore/rendering/InlineTextBox.h	2015-04-02 20:29:23 UTC (rev 182286)
@@ -166,11 +166,7 @@
 
     void computeRectForReplacementMarker(RenderedDocumentMarker&, const RenderStyle&, const FontCascade&);
 
-    ExpansionBehavior expansionBehavior() const
-    {
-        return (canHaveLeadingExpansion() ? AllowLeadingExpansion : ForbidLeadingExpansion)
-            | (renderer().contentIsKnownToFollow() || (expansion() && nextLeafChild() && !nextLeafChild()->isLineBreak()) ? AllowTrailingExpansion : ForbidTrailingExpansion);
-    }
+    ExpansionBehavior expansionBehavior() const;
 
     void behavesLikeText() const = delete;
 

Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (182285 => 182286)


--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2015-04-02 20:29:23 UTC (rev 182286)
@@ -570,33 +570,29 @@
         totalOpportunitiesInRun += opportunitiesInRun;
     }
 
-    if (totalOpportunitiesInRun) {
-        ASSERT(!rubyRun.hasOverrideWidth());
-        float newBaseWidth = rubyRun.logicalWidth() + totalExpansion + marginStartForChild(rubyRun) + marginEndForChild(rubyRun);
-        float newRubyRunWidth = rubyRun.logicalWidth() + totalExpansion;
-        rubyBase.setInitialOffset((newRubyRunWidth - newBaseWidth) / 2);
-        rubyRun.setOverrideLogicalContentWidth(newRubyRunWidth);
-        rubyRun.setNeedsLayout(MarkOnlyThis);
-        rootBox.markDirty();
-        if (RenderRubyText* rubyText = rubyRun.rubyText()) {
-            if (RootInlineBox* textRootBox = rubyText->firstRootBox())
-                textRootBox->markDirty();
-        }
-        rubyRun.layoutBlock(true);
-        rubyRun.clearOverrideLogicalContentWidth();
-        r.box()->setExpansion(newRubyRunWidth - r.box()->logicalWidth());
+    ASSERT(!rubyRun.hasOverrideWidth());
+    float newBaseWidth = rubyRun.logicalWidth() + totalExpansion + marginStartForChild(rubyRun) + marginEndForChild(rubyRun);
+    float newRubyRunWidth = rubyRun.logicalWidth() + totalExpansion;
+    rubyBase.setInitialOffset((newRubyRunWidth - newBaseWidth) / 2);
+    rubyRun.setOverrideLogicalContentWidth(newRubyRunWidth);
+    rubyRun.setNeedsLayout(MarkOnlyThis);
+    rootBox.markDirty();
+    if (RenderRubyText* rubyText = rubyRun.rubyText()) {
+        if (RootInlineBox* textRootBox = rubyText->firstRootBox())
+            textRootBox->markDirty();
+    }
+    rubyRun.layoutBlock(true);
+    rubyRun.clearOverrideLogicalContentWidth();
+    r.box()->setExpansion(newRubyRunWidth - r.box()->logicalWidth());
 
-        // This relayout caused the size of the RenderRubyText and the RenderRubyBase to change, dependent on the line's current expansion. Next time we relayout the
-        // RenderRubyRun, make sure that we relayout the RenderRubyBase and RenderRubyText as well.
-        rubyBase.setNeedsLayout(MarkOnlyThis);
-        if (RenderRubyText* rubyText = rubyRun.rubyText())
-            rubyText->setNeedsLayout(MarkOnlyThis);
-        if (rubyBase.lastLeafChild() && is<RenderText>(rubyBase.lastLeafChild()) && r.box() && r.box()->nextLeafChild() && !r.box()->nextLeafChild()->isLineBreak())
-            downcast<RenderText>(rubyBase.lastLeafChild())->setContentIsKnownToFollow(true);
+    // This relayout caused the size of the RenderRubyText and the RenderRubyBase to change, dependent on the line's current expansion. Next time we relayout the
+    // RenderRubyRun, make sure that we relayout the RenderRubyBase and RenderRubyText as well.
+    rubyBase.setNeedsLayout(MarkOnlyThis);
+    if (RenderRubyText* rubyText = rubyRun.rubyText())
+        rubyText->setNeedsLayout(MarkOnlyThis);
 
-        totalLogicalWidth += totalExpansion;
-        expansionOpportunityCount -= totalOpportunitiesInRun;
-    }
+    totalLogicalWidth += totalExpansion;
+    expansionOpportunityCount -= totalOpportunitiesInRun;
 }
 
 void RenderBlockFlow::computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun* trailingSpaceRun, const Vector<unsigned, 16>& expansionOpportunities, unsigned expansionOpportunityCount, float totalLogicalWidth, float availableLogicalWidth)
@@ -723,10 +719,59 @@
     lineBox->placeBoxesInInlineDirection(lineLogicalLeft, needsWordSpacing);
 }
 
-static inline ExpansionBehavior expansionBehaviorForInlineTextBox(bool isAfterExpansion)
+static inline ExpansionBehavior expansionBehaviorForInlineTextBox(RenderBlockFlow& block, InlineTextBox& textBox, BidiRun* previousRun, BidiRun* nextRun, ETextAlign textAlign, bool isAfterExpansion)
 {
-    ExpansionBehavior result = AllowTrailingExpansion;
-    result |= isAfterExpansion ? ForbidLeadingExpansion : AllowLeadingExpansion;
+    ExpansionBehavior result = 0;
+    bool setLeadingExpansion = false;
+    bool setTrailingExpansion = false;
+    if (textAlign == JUSTIFY) {
+        // If the next box is ruby, and we're justifying, and the first box in the ruby base has a leading expansion, and we are a text box, then
+        // force a trailing expansion.
+        if (nextRun && is<RenderRubyRun>(nextRun->renderer()) && downcast<RenderRubyRun>(nextRun->renderer()).rubyBase() && nextRun->renderer().style().collapseWhiteSpace()) {
+            auto& rubyBase = *downcast<RenderRubyRun>(nextRun->renderer()).rubyBase();
+            if (rubyBase.firstRootBox() && !rubyBase.firstRootBox()->nextRootBox()) {
+                if (auto* leafChild = rubyBase.firstRootBox()->firstLeafChild()) {
+                    if (is<InlineTextBox>(*leafChild)) {
+                        // FIXME: This leadingExpansionOpportunity doesn't actually work because it doesn't perform the UBA
+                        if (FontCascade::leadingExpansionOpportunity(downcast<RenderText>(leafChild->renderer()).stringView(), leafChild->direction())) {
+                            setTrailingExpansion = true;
+                            result |= ForceTrailingExpansion;
+                        }
+                    }
+                }
+            }
+        }
+        // Same thing, except if we're following a ruby
+        if (previousRun && is<RenderRubyRun>(previousRun->renderer()) && downcast<RenderRubyRun>(previousRun->renderer()).rubyBase() && previousRun->renderer().style().collapseWhiteSpace()) {
+            auto& rubyBase = *downcast<RenderRubyRun>(previousRun->renderer()).rubyBase();
+            if (rubyBase.firstRootBox() && !rubyBase.firstRootBox()->nextRootBox()) {
+                if (auto* leafChild = rubyBase.firstRootBox()->lastLeafChild()) {
+                    if (is<InlineTextBox>(*leafChild)) {
+                        // FIXME: This leadingExpansionOpportunity doesn't actually work because it doesn't perform the UBA
+                        if (FontCascade::trailingExpansionOpportunity(downcast<RenderText>(leafChild->renderer()).stringView(), leafChild->direction())) {
+                            setLeadingExpansion = true;
+                            result |= ForceLeadingExpansion;
+                        }
+                    }
+                }
+            }
+        }
+        // If we're the first box inside a ruby base, forbid a leading expansion, and vice-versa
+        if (is<RenderRubyBase>(block)) {
+            RenderRubyBase& rubyBase = downcast<RenderRubyBase>(block);
+            if (&textBox == rubyBase.firstRootBox()->firstLeafChild()) {
+                setLeadingExpansion = true;
+                result |= ForbidLeadingExpansion;
+            } if (&textBox == rubyBase.firstRootBox()->lastLeafChild()) {
+                setTrailingExpansion = true;
+                result |= ForbidTrailingExpansion;
+            }
+        }
+    }
+    if (!setLeadingExpansion)
+        result |= isAfterExpansion ? ForbidLeadingExpansion : AllowLeadingExpansion;
+    if (!setTrailingExpansion)
+        result |= AllowTrailingExpansion;
     return result;
 }
 
@@ -771,9 +816,9 @@
     unsigned expansionOpportunityCount = 0;
     bool isAfterExpansion = is<RenderRubyBase>(*this) ? downcast<RenderRubyBase>(*this).isAfterExpansion() : true;
     Vector<unsigned, 16> expansionOpportunities;
-    RenderObject* previousObject = nullptr;
 
     BidiRun* run = firstRun;
+    BidiRun* previousRun = nullptr;
     for (; run; run = run->next()) {
         if (!run->box() || run->renderer().isOutOfFlowPositioned() || run->box()->isLineBreak()) {
             continue; // Positioned objects are only participating to figure out their
@@ -784,7 +829,7 @@
             auto& renderText = downcast<RenderText>(run->renderer());
             auto& textBox = downcast<InlineTextBox>(*run->box());
             if (textAlign == JUSTIFY && run != trailingSpaceRun) {
-                ExpansionBehavior expansionBehavior = expansionBehaviorForInlineTextBox(isAfterExpansion);
+                ExpansionBehavior expansionBehavior = expansionBehaviorForInlineTextBox(*this, textBox, previousRun, run->next(), textAlign, isAfterExpansion);
                 applyExpansionBehavior(textBox, expansionBehavior);
                 unsigned opportunitiesInRun;
                 std::tie(opportunitiesInRun, isAfterExpansion) = FontCascade::expansionOpportunityCount(renderText.stringView(run->m_start, run->m_stop), run->box()->direction(), expansionBehavior);
@@ -811,7 +856,7 @@
                         auto& textBox = downcast<InlineTextBox>(*leafChild);
                         encounteredJustifiedRuby = true;
                         auto& renderText = downcast<RenderText>(leafChild->renderer());
-                        ExpansionBehavior expansionBehavior = expansionBehaviorForInlineTextBox(isAfterExpansion);
+                        ExpansionBehavior expansionBehavior = expansionBehaviorForInlineTextBox(*rubyBase, textBox, nullptr, nullptr, textAlign, isAfterExpansion);
                         applyExpansionBehavior(textBox, expansionBehavior);
                         unsigned opportunitiesInRun;
                         std::tie(opportunitiesInRun, isAfterExpansion) = FontCascade::expansionOpportunityCount(renderText.stringView(), leafChild->direction(), expansionBehavior);
@@ -827,36 +872,24 @@
             if (!is<RenderInline>(run->renderer())) {
                 auto& renderBox = downcast<RenderBox>(run->renderer());
                 if (is<RenderRubyRun>(renderBox))
-                    setMarginsForRubyRun(run, downcast<RenderRubyRun>(renderBox), previousObject, lineInfo);
+                    setMarginsForRubyRun(run, downcast<RenderRubyRun>(renderBox), previousRun ? &previousRun->renderer() : nullptr, lineInfo);
                 run->box()->setLogicalWidth(logicalWidthForChild(renderBox));
                 totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
             }
         }
 
         totalLogicalWidth += run->box()->logicalWidth();
-        previousObject = &run->renderer();
+        previousRun = run;
     }
 
     if (isAfterExpansion && !expansionOpportunities.isEmpty()) {
-        bool shouldShareExpansionsWithContainingLine = true;
-        if (is<RenderRubyBase>(*this)) {
-            if (RenderRubyRun* rubyRun = downcast<RenderRubyBase>(*this).rubyRun()) {
-                if (RenderElement* rubyElement = rubyRun->parent()) {
-                    if (rubyElement->style().display() == INLINE) {
-                        if (RenderBlock* containingBlock = rubyElement->containingBlock()) {
-                            if (containingBlock->style().textAlign() == JUSTIFY)
-                                shouldShareExpansionsWithContainingLine = false;
-                        }
-                    }
-                }
-            }
-        }
-        if (shouldShareExpansionsWithContainingLine) {
-            expansionOpportunities.last()--;
-            expansionOpportunityCount--;
-        }
+        expansionOpportunities.last()--;
+        expansionOpportunityCount--;
     }
 
+    if (is<RenderRubyBase>(*this) && !expansionOpportunityCount)
+        textAlign = CENTER;
+
     updateLogicalWidthForAlignment(textAlign, lineBox, trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth, expansionOpportunityCount);
 
     computeExpansionForJustifiedText(firstRun, trailingSpaceRun, expansionOpportunities, expansionOpportunityCount, totalLogicalWidth, availableLogicalWidth);
@@ -1057,14 +1090,14 @@
 RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements)
 {
     if (!bidiRuns.runCount())
-        return 0;
+        return nullptr;
 
     // FIXME: Why is this only done when we had runs?
     lineInfo.setLastLine(!end.renderer());
 
     RootInlineBox* lineBox = constructLine(bidiRuns, lineInfo);
     if (!lineBox)
-        return 0;
+        return nullptr;
 
     lineBox->setBidiLevel(bidiLevel);
     lineBox->setEndsWithBreak(lineInfo.previousLineBrokeCleanly());
@@ -1255,7 +1288,7 @@
             constructBidiRunsForSegment(resolver, bidiRuns, end, override, layoutState.lineInfo().previousLineBrokeCleanly());
             ASSERT(resolver.position() == end);
 
-            BidiRun* trailingSpaceRun = !layoutState.lineInfo().previousLineBrokeCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0;
+            BidiRun* trailingSpaceRun = !layoutState.lineInfo().previousLineBrokeCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : nullptr;
 
             if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) {
                 bidiRuns.logicallyLastRun()->m_hasHyphen = true;

Modified: trunk/Source/WebCore/rendering/RenderText.cpp (182285 => 182286)


--- trunk/Source/WebCore/rendering/RenderText.cpp	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/Source/WebCore/rendering/RenderText.cpp	2015-04-02 20:29:23 UTC (rev 182286)
@@ -180,7 +180,6 @@
     , m_knownToHaveNoOverflowAndNoFallbackFonts(false)
     , m_useBackslashAsYenSymbol(false)
     , m_originalTextDiffersFromRendered(false)
-    , m_contentIsKnownToFollow(false)
 #if ENABLE(IOS_TEXT_AUTOSIZING)
     , m_candidateComputedTextSize(0)
 #endif

Modified: trunk/Source/WebCore/rendering/RenderText.h (182285 => 182286)


--- trunk/Source/WebCore/rendering/RenderText.h	2015-04-02 19:53:32 UTC (rev 182285)
+++ trunk/Source/WebCore/rendering/RenderText.h	2015-04-02 20:29:23 UTC (rev 182286)
@@ -165,9 +165,6 @@
 
     LayoutUnit topOfFirstText() const;
 
-    bool contentIsKnownToFollow() { return m_contentIsKnownToFollow; }
-    void setContentIsKnownToFollow(bool contentIsKnownToFollow) { m_contentIsKnownToFollow = contentIsKnownToFollow; }
-
 protected:
     virtual void computePreferredLogicalWidths(float leadWidth);
     virtual void willBeDestroyed() override;
@@ -218,7 +215,6 @@
     mutable unsigned m_knownToHaveNoOverflowAndNoFallbackFonts : 1;
     unsigned m_useBackslashAsYenSymbol : 1;
     unsigned m_originalTextDiffersFromRendered : 1;
-    unsigned m_contentIsKnownToFollow : 1;
 
 #if ENABLE(IOS_TEXT_AUTOSIZING)
     // FIXME: This should probably be part of the text sizing structures in Document instead. That would save some memory.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to