Implement rudimentary Bopomofo Ruby support (ruby-position:inter-character)
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Aug 2014 18:18:54 +0000 (18:18 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Aug 2014 18:18:54 +0000 (18:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=136137
<rdar://problem/12567545>

Reviewed by Sam Weinig.

Source/WebCore:

Added fast/ruby/bopomofo.html and fast/ruby/bopomofo-rl.html.

* css/CSSParser.cpp:
(WebCore::isValidKeywordPropertyAndValue):
* css/CSSPrimitiveValueMappings.h:
(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
(WebCore::CSSPrimitiveValue::operator RubyPosition):
* css/CSSPropertyNames.in:
* css/CSSValueKeywords.in:
Add support for the new inter-character value for ruby-position and also
add support for a new font-size keyword, -webkit-ruby-text, that is used
to set a smart initial font size based off the type of ruby being presented.

* css/DeprecatedStyleBuilder.cpp:
(WebCore::ApplyPropertyFontSize::determineRubyTextSizeMultiplier):
(WebCore::ApplyPropertyFontSize::applyValue):
Determine the Ruby text size multiplier when -webkit-ruby-text is specified
as the font size. For ruby-position of before/after, we use 50% of the parent
font size. For inter-character ruby, we default to 25% instead. If inter-character
Ruby is nested, we assume it's to display tone marks, and we use 100% to ensure
the tone mark is the same size and does not get smaller.

* css/StyleResolver.cpp:
(WebCore::StyleResolver::adjustStyleForInterCharacterRuby):
(WebCore::StyleResolver::applyMatchedProperties):
* css/StyleResolver.h:
ruby-position is now the highest priority CSS property, and it is resolved
before all other properties to ensure that its value can be checked when
determining a smart default font size. adjustStyleForInterCharacterRuby is a new
function called to auto-adjust inter-character ruby text to be vertical writing mode when
encountered inside horizontal documents.

* css/html.css:
(ruby > rt):
Change the font-size from 50% to -webkit-ruby-text to allow us to customize it as
needed depending on what kind of Ruby we want to show.

* rendering/RenderRubyRun.cpp:
(WebCore::RenderRubyRun::layout):
* rendering/RenderRubyRun.h:
Add layout code to properly position vertical ruby text relative to a horizontal base.

* rendering/style/RenderStyleConstants.h:
Add the new inter-character constant for ruby-position.

* rendering/style/StyleRareInheritedData.h:
Increase the number of storage bits for RubyPosition from 1 to 2 now that we support 3 values.

LayoutTests:

* fast/ruby/bopomofo-rl.html: Added.
* fast/ruby/bopomofo.html: Added.
* platform/mac/fast/ruby/bopomofo-expected.png: Added.
* platform/mac/fast/ruby/bopomofo-expected.txt: Added.
* platform/mac/fast/ruby/bopomofo-rl-expected.png: Added.
* platform/mac/fast/ruby/bopomofo-rl-expected.txt: Added.

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

20 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/ruby/bopomofo-rl.html [new file with mode: 0644]
LayoutTests/fast/ruby/bopomofo.html [new file with mode: 0644]
LayoutTests/platform/mac/fast/ruby/bopomofo-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/ruby/bopomofo-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSPrimitiveValueMappings.h
Source/WebCore/css/CSSPropertyNames.in
Source/WebCore/css/CSSValueKeywords.in
Source/WebCore/css/DeprecatedStyleBuilder.cpp
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/css/html.css
Source/WebCore/rendering/RenderRubyRun.cpp
Source/WebCore/rendering/RenderRubyRun.h
Source/WebCore/rendering/style/RenderStyleConstants.h
Source/WebCore/rendering/style/StyleRareInheritedData.h

index 7ba98b6..a59d110 100644 (file)
@@ -1,3 +1,18 @@
+2014-08-21  David Hyatt  <hyatt@apple.com>
+
+        Implement rudimentary Bopomofo Ruby support (ruby-position:inter-character)
+        https://bugs.webkit.org/show_bug.cgi?id=136137
+        <rdar://problem/12567545>
+
+        Reviewed by Sam Weinig.
+
+        * fast/ruby/bopomofo-rl.html: Added.
+        * fast/ruby/bopomofo.html: Added.
+        * platform/mac/fast/ruby/bopomofo-expected.png: Added.
+        * platform/mac/fast/ruby/bopomofo-expected.txt: Added.
+        * platform/mac/fast/ruby/bopomofo-rl-expected.png: Added.
+        * platform/mac/fast/ruby/bopomofo-rl-expected.txt: Added.
+
 2014-08-21  Antti Koivisto  <antti@apple.com>
 
         Animated GIFs scrolled out of view still cause titlebar blur to update, on tumblr.com page
diff --git a/LayoutTests/fast/ruby/bopomofo-rl.html b/LayoutTests/fast/ruby/bopomofo-rl.html
new file mode 100644 (file)
index 0000000..c5fa6e6
--- /dev/null
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8" />
+<style>
+ruby { -webkit-ruby-position: inter-character;  }
+</style>
+</head>
+<body style="line-height:1.5;margin-right:20px;font-family:'STHeiti'; -webkit-writing-mode:vertical-rl">
+
+<ruby style="font-size:32px">世<rp>(</rp><rt><ruby>ㄕ<rt class="tone">ˋ</rt></ruby></rt><rp>)</rp>上<rp>(</rp><rt><ruby>ㄕㄤ<rt class="tone">ˋ</rt></ruby></rt><rp>)</rp>無<rp>(</rp><rt><ruby>ㄨ<rt class="tone">ˊ</rt></ruby></rt><rp>)</rp>難<rp>(</rp><rt><ruby>ㄋㄢ<rt class="tone">ˊ</rt></ruby></rt><rp>)</rp>事<rp>(</rp><rt><ruby>ㄕ<rt class="tone">ˋ</rt></ruby></rt><rp>)</rp>只<rp>(</rp><rt>ㄓˇ</rt><rp>)</rp>怕<rp>(</rp><rt><ruby>ㄆㄚ<rt class="tone">ˋ</rt></ruby></rt><rp>)</rp>有<rp>(</rp><rt><ruby>ㄧㄡ<rt class="tone">ˇ</rt></ruby></rt><rp>)</rp>心<rp>(</rp><rt>ㄒㄧㄣ</rt><rp>)</rp>人<rp>(</rp><rt><ruby>ㄖㄣ<rt class="tone">ˊ</rt></ruby></rt><rp>)</rp></ruby>
\ No newline at end of file
diff --git a/LayoutTests/fast/ruby/bopomofo.html b/LayoutTests/fast/ruby/bopomofo.html
new file mode 100644 (file)
index 0000000..18425ac
--- /dev/null
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8" />
+<style>
+ruby { -webkit-ruby-position: inter-character;  }
+</style>
+</head>
+<body style="line-height:1.5;font-family:'STHeiti';">
+
+<ruby style="font-size:32px">世<rp>(</rp><rt><ruby>ㄕ<rt class="tone">ˋ</rt></ruby></rt><rp>)</rp>上<rp>(</rp><rt><ruby>ㄕㄤ<rt class="tone">ˋ</rt></ruby></rt><rp>)</rp>無<rp>(</rp><rt><ruby>ㄨ<rt class="tone">ˊ</rt></ruby></rt><rp>)</rp>難<rp>(</rp><rt><ruby>ㄋㄢ<rt class="tone">ˊ</rt></ruby></rt><rp>)</rp>事<rp>(</rp><rt><ruby>ㄕ<rt class="tone">ˋ</rt></ruby></rt><rp>)</rp>只<rp>(</rp><rt>ㄓˇ</rt><rp>)</rp>怕<rp>(</rp><rt><ruby>ㄆㄚ<rt class="tone">ˋ</rt></ruby></rt><rp>)</rp>有<rp>(</rp><rt><ruby>ㄧㄡ<rt class="tone">ˇ</rt></ruby></rt><rp>)</rp>心<rp>(</rp><rt>ㄒㄧㄣ</rt><rp>)</rp>人<rp>(</rp><rt><ruby>ㄖㄣ<rt class="tone">ˊ</rt></ruby></rt><rp>)</rp></ruby>
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/ruby/bopomofo-expected.png b/LayoutTests/platform/mac/fast/ruby/bopomofo-expected.png
new file mode 100644 (file)
index 0000000..1f01916
Binary files /dev/null and b/LayoutTests/platform/mac/fast/ruby/bopomofo-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/ruby/bopomofo-expected.txt b/LayoutTests/platform/mac/fast/ruby/bopomofo-expected.txt
new file mode 100644 (file)
index 0000000..0f87d51
--- /dev/null
@@ -0,0 +1,124 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x64
+  RenderBlock {HTML} at (0,0) size 800x64
+    RenderBody {BODY} at (8,8) size 784x48
+      RenderRuby (inline) {RUBY} at (0,0) size 464x32
+        RenderRubyRun (anonymous) at (0,0) size 48x48
+          RenderRubyText {RT} at (32,20) size 8x8
+            RenderRuby (inline) {RUBY} at (0,0) size 8x8
+              RenderRubyRun (anonymous) at (0,0) size 8x8
+                RenderRubyText {RT} at (8,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{2CB}"
+                RenderRubyBase (anonymous) at (0,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{3115}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{4E16}"
+        RenderRubyRun (anonymous) at (48,0) size 48x48
+          RenderRubyText {RT} at (32,16) size 8x16
+            RenderRuby (inline) {RUBY} at (0,0) size 8x16
+              RenderRubyRun (anonymous) at (0,0) size 8x16
+                RenderRubyText {RT} at (8,0) size 8x16
+                  RenderText {#text} at (0,4) size 8x8
+                    text run at (0,4) width 8: "\x{2CB}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{3115}\x{3124}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{4E0A}"
+        RenderRubyRun (anonymous) at (96,0) size 48x48
+          RenderRubyText {RT} at (32,20) size 8x8
+            RenderRuby (inline) {RUBY} at (0,0) size 8x8
+              RenderRubyRun (anonymous) at (0,0) size 8x8
+                RenderRubyText {RT} at (8,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{2CA}"
+                RenderRubyBase (anonymous) at (0,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{3128}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{7121}"
+        RenderRubyRun (anonymous) at (144,0) size 48x48
+          RenderRubyText {RT} at (32,16) size 8x16
+            RenderRuby (inline) {RUBY} at (0,0) size 8x16
+              RenderRubyRun (anonymous) at (0,0) size 8x16
+                RenderRubyText {RT} at (8,0) size 8x16
+                  RenderText {#text} at (0,4) size 8x8
+                    text run at (0,4) width 8: "\x{2CA}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{310B}\x{3122}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{96E3}"
+        RenderRubyRun (anonymous) at (192,0) size 48x48
+          RenderRubyText {RT} at (32,20) size 8x8
+            RenderRuby (inline) {RUBY} at (0,0) size 8x8
+              RenderRubyRun (anonymous) at (0,0) size 8x8
+                RenderRubyText {RT} at (8,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{2CB}"
+                RenderRubyBase (anonymous) at (0,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{3115}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{4E8B}"
+        RenderRubyRun (anonymous) at (240,0) size 40x48
+          RenderRubyText {RT} at (32,16) size 8x16
+            RenderText {#text} at (0,0) size 8x16
+              text run at (0,0) width 16: "\x{3113}\x{2C7}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{53EA}"
+        RenderRubyRun (anonymous) at (280,0) size 48x48
+          RenderRubyText {RT} at (32,16) size 8x16
+            RenderRuby (inline) {RUBY} at (0,0) size 8x16
+              RenderRubyRun (anonymous) at (0,0) size 8x16
+                RenderRubyText {RT} at (8,0) size 8x16
+                  RenderText {#text} at (0,4) size 8x8
+                    text run at (0,4) width 8: "\x{2CB}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{3106}\x{311A}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{6015}"
+        RenderRubyRun (anonymous) at (328,0) size 48x48
+          RenderRubyText {RT} at (32,16) size 8x16
+            RenderRuby (inline) {RUBY} at (0,0) size 8x16
+              RenderRubyRun (anonymous) at (0,0) size 8x16
+                RenderRubyText {RT} at (8,0) size 8x16
+                  RenderText {#text} at (0,4) size 8x8
+                    text run at (0,4) width 8: "\x{2C7}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{3127}\x{3121}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{6709}"
+        RenderRubyRun (anonymous) at (376,0) size 40x48
+          RenderRubyText {RT} at (32,12) size 8x24
+            RenderText {#text} at (0,0) size 8x24
+              text run at (0,0) width 24: "\x{3112}\x{3127}\x{3123}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{5FC3}"
+        RenderRubyRun (anonymous) at (416,0) size 48x48
+          RenderRubyText {RT} at (32,16) size 8x16
+            RenderRuby (inline) {RUBY} at (0,0) size 8x16
+              RenderRubyRun (anonymous) at (0,0) size 8x16
+                RenderRubyText {RT} at (8,0) size 8x16
+                  RenderText {#text} at (0,4) size 8x8
+                    text run at (0,4) width 8: "\x{2CA}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{3116}\x{3123}"
+          RenderRubyBase (anonymous) at (0,0) size 32x48
+            RenderText {#text} at (0,8) size 32x32
+              text run at (0,8) width 32: "\x{4EBA}"
diff --git a/LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.png b/LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.png
new file mode 100644 (file)
index 0000000..8e7db77
Binary files /dev/null and b/LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.png differ
diff --git a/LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.txt b/LayoutTests/platform/mac/fast/ruby/bopomofo-rl-expected.txt
new file mode 100644 (file)
index 0000000..c968f4f
--- /dev/null
@@ -0,0 +1,124 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (724,0) size 76x600
+  RenderBlock {HTML} at (0,0) size 76x600
+    RenderBody {BODY} at (20,8) size 48x584
+      RenderRuby (inline) {RUBY} at (0,0) size 32x320
+        RenderRubyRun (anonymous) at (0,0) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            RenderRuby (inline) {RUBY} at (0,0) size 8x8
+              RenderRubyRun (anonymous) at (0,12) size 8x8
+                RenderRubyText {RT} at (-8,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{2CB}"
+                RenderRubyBase (anonymous) at (0,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{3115}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{4E16}"
+        RenderRubyRun (anonymous) at (0,32) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            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: "\x{2CB}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{3115}\x{3124}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{4E0A}"
+        RenderRubyRun (anonymous) at (0,64) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            RenderRuby (inline) {RUBY} at (0,0) size 8x8
+              RenderRubyRun (anonymous) at (0,12) size 8x8
+                RenderRubyText {RT} at (-8,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{2CA}"
+                RenderRubyBase (anonymous) at (0,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{3128}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{7121}"
+        RenderRubyRun (anonymous) at (0,96) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            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: "\x{2CA}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{310B}\x{3122}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{96E3}"
+        RenderRubyRun (anonymous) at (0,128) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            RenderRuby (inline) {RUBY} at (0,0) size 8x8
+              RenderRubyRun (anonymous) at (0,12) size 8x8
+                RenderRubyText {RT} at (-8,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{2CB}"
+                RenderRubyBase (anonymous) at (0,0) size 8x8
+                  RenderText {#text} at (0,0) size 8x8
+                    text run at (0,0) width 8: "\x{3115}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{4E8B}"
+        RenderRubyRun (anonymous) at (0,160) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            RenderText {#text} at (0,4) size 8x24
+              text run at (0,4) width 24: "\x{3113}\x{2C7}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{53EA}"
+        RenderRubyRun (anonymous) at (0,192) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            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: "\x{2CB}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{3106}\x{311A}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{6015}"
+        RenderRubyRun (anonymous) at (0,224) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            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: "\x{2C7}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{3127}\x{3121}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{6709}"
+        RenderRubyRun (anonymous) at (0,256) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            RenderText {#text} at (0,1) size 8x30
+              text run at (0,1) width 29: "\x{3112}\x{3127}\x{3123}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{5FC3}"
+        RenderRubyRun (anonymous) at (0,288) size 48x32
+          RenderRubyText {RT} at (0,0) size 8x32
+            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: "\x{2CA}"
+                RenderRubyBase (anonymous) at (0,0) size 8x16
+                  RenderText {#text} at (0,0) size 8x16
+                    text run at (0,0) width 16: "\x{3116}\x{3123}"
+          RenderRubyBase (anonymous) at (0,0) size 48x32
+            RenderText {#text} at (8,0) size 32x32
+              text run at (8,0) width 32: "\x{4EBA}"
index c436474..8dda880 100644 (file)
@@ -1,3 +1,59 @@
+2014-08-21  David Hyatt  <hyatt@apple.com>
+
+        Implement rudimentary Bopomofo Ruby support (ruby-position:inter-character)
+        https://bugs.webkit.org/show_bug.cgi?id=136137
+        <rdar://problem/12567545>
+
+        Reviewed by Sam Weinig.
+
+        Added fast/ruby/bopomofo.html and fast/ruby/bopomofo-rl.html.
+
+        * css/CSSParser.cpp:
+        (WebCore::isValidKeywordPropertyAndValue):
+        * css/CSSPrimitiveValueMappings.h:
+        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
+        (WebCore::CSSPrimitiveValue::operator RubyPosition):
+        * css/CSSPropertyNames.in:
+        * css/CSSValueKeywords.in:
+        Add support for the new inter-character value for ruby-position and also
+        add support for a new font-size keyword, -webkit-ruby-text, that is used
+        to set a smart initial font size based off the type of ruby being presented.
+
+        * css/DeprecatedStyleBuilder.cpp:
+        (WebCore::ApplyPropertyFontSize::determineRubyTextSizeMultiplier):
+        (WebCore::ApplyPropertyFontSize::applyValue):
+        Determine the Ruby text size multiplier when -webkit-ruby-text is specified
+        as the font size. For ruby-position of before/after, we use 50% of the parent
+        font size. For inter-character ruby, we default to 25% instead. If inter-character
+        Ruby is nested, we assume it's to display tone marks, and we use 100% to ensure
+        the tone mark is the same size and does not get smaller.
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::adjustStyleForInterCharacterRuby):
+        (WebCore::StyleResolver::applyMatchedProperties):
+        * css/StyleResolver.h:
+        ruby-position is now the highest priority CSS property, and it is resolved
+        before all other properties to ensure that its value can be checked when
+        determining a smart default font size. adjustStyleForInterCharacterRuby is a new
+        function called to auto-adjust inter-character ruby text to be vertical writing mode when
+        encountered inside horizontal documents.
+
+        * css/html.css:
+        (ruby > rt):
+        Change the font-size from 50% to -webkit-ruby-text to allow us to customize it as
+        needed depending on what kind of Ruby we want to show.
+
+        * rendering/RenderRubyRun.cpp:
+        (WebCore::RenderRubyRun::layout):
+        * rendering/RenderRubyRun.h:
+        Add layout code to properly position vertical ruby text relative to a horizontal base.
+
+        * rendering/style/RenderStyleConstants.h:
+        Add the new inter-character constant for ruby-position.
+
+        * rendering/style/StyleRareInheritedData.h:
+        Increase the number of storage bits for RubyPosition from 1 to 2 now that we support 3 values.
+
 2014-08-22  Jon Lee  <jonlee@apple.com>
 
         Fix iOS build due to r172832 and move RUBBER_BANDING out of FeatureDefines.h
index 5b28648..3a0a653 100644 (file)
@@ -973,7 +973,7 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int
         break;
 
     case CSSPropertyWebkitRubyPosition:
-        if (valueID == CSSValueBefore || valueID == CSSValueAfter)
+        if (valueID == CSSValueBefore || valueID == CSSValueAfter || valueID == CSSValueInterCharacter)
             return true;
         break;
 
index 214f5e5..32643ce 100644 (file)
@@ -3256,6 +3256,9 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(RubyPosition position)
     case RubyPositionAfter:
         m_value.valueID = CSSValueAfter;
         break;
+    case RubyPositionInterCharacter:
+        m_value.valueID = CSSValueInterCharacter;
+        break;
     }
 }
 
@@ -3268,6 +3271,8 @@ template<> inline CSSPrimitiveValue::operator RubyPosition() const
         return RubyPositionBefore;
     case CSSValueAfter:
         return RubyPositionAfter;
+    case CSSValueInterCharacter:
+        return RubyPositionInterCharacter;
     default:
         break;
     }
index 64af49f..5af3f5f 100644 (file)
@@ -38,6 +38,9 @@ zoom
 // line height needs to be right after the above high-priority properties
 line-height [Inherited]
 
+// Keep this in between the highest priority props and the lower ones.
+-webkit-ruby-position [Inherited]
+
 // The remaining properties are listed in alphabetical order
 background
 background-attachment
@@ -386,7 +389,6 @@ isolation
 -webkit-perspective-origin-y
 -webkit-print-color-adjust [Inherited]
 -webkit-rtl-ordering [Inherited]
--webkit-ruby-position [Inherited]
 #if defined(ENABLE_CSS_SCROLL_SNAP)
 -webkit-scroll-snap-points-x
 -webkit-scroll-snap-points-y
index a324e6f..ff6dcda 100644 (file)
@@ -101,8 +101,10 @@ large
 x-large
 xx-large
 -webkit-xxx-large
+-webkit-ruby-text
 smaller
 larger
+
 //
 // CSS_PROP_FONT_STRETCH:
 //
@@ -934,6 +936,7 @@ horizontal-bt
 // -webkit-ruby-position
 after
 before
+inter-character
 
 // -webkit-text-emphasis-position
 over
index dcb639e..4c2e110 100644 (file)
@@ -39,8 +39,8 @@
 #include "ClipPathOperation.h"
 #include "CursorList.h"
 #include "Document.h"
-#include "Element.h"
 #include "Frame.h"
+#include "HTMLElement.h"
 #include "Pair.h"
 #include "Rect.h"
 #include "RenderStyle.h"
@@ -56,6 +56,8 @@
 
 namespace WebCore {
 
+using namespace HTMLNames;
+
 enum ExpandValueBehavior {SuppressValue = 0, ExpandValue};
 template <ExpandValueBehavior expandValue, CSSPropertyID one = CSSPropertyInvalid, CSSPropertyID two = CSSPropertyInvalid, CSSPropertyID three = CSSPropertyInvalid, CSSPropertyID four = CSSPropertyInvalid, CSSPropertyID five = CSSPropertyInvalid>
 class ApplyPropertyExpanding {
@@ -817,6 +819,25 @@ public:
         return;
     }
 
+    static float determineRubyTextSizeMultiplier(StyleResolver* styleResolver)
+    {
+        if (styleResolver->style()->rubyPosition() != RubyPositionInterCharacter)
+            return 0.5f;
+        
+        Element* element = styleResolver->state().element();
+        if (element == nullptr)
+            return 0.25f;
+        
+        // FIXME: This hack is to ensure tone marks are the same size as
+        // the bopomofo. This code will go away if we make a special renderer
+        // for the tone marks eventually.
+        for (const Element* currElement = element->parentElement(); currElement; currElement = currElement->parentElement()) {
+            if (currElement->hasTagName(rtTag))
+                return 1.0f;
+        }
+        return 0.25f;
+    }
+    
     static void applyValue(CSSPropertyID, StyleResolver* styleResolver, CSSValue* value)
     {
         if (!value->isPrimitiveValue())
@@ -855,11 +876,15 @@ public:
             case CSSValueSmaller:
                 size = smallerFontSize(parentSize);
                 break;
-            default:
+            case CSSValueWebkitRubyText: {
+                float rubyTextSizeMultiplier = determineRubyTextSizeMultiplier(styleResolver);
+                size = rubyTextSizeMultiplier * parentSize;
+                break;
+            } default:
                 return;
             }
 
-            fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize && (ident == CSSValueLarger || ident == CSSValueSmaller));
+            fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize && (ident == CSSValueLarger || ident == CSSValueSmaller || ident == CSSValueWebkitRubyText));
         } else {
             fontDescription.setIsAbsoluteSize(parentIsAbsoluteSize
                                               || !(primitiveValue->isPercentage() || primitiveValue->isFontRelativeLength()));
index 3925ec5..3154b86 100644 (file)
@@ -1146,6 +1146,16 @@ static bool isScrollableOverflow(EOverflow overflow)
 }
 #endif
 
+void StyleResolver::adjustStyleForInterCharacterRuby()
+{
+    RenderStyle* style = m_state.style();
+    if (style->rubyPosition() != RubyPositionInterCharacter || !m_state.element() || !m_state.element()->hasTagName(rtTag))
+        return;
+    style->setTextAlign(CENTER);
+    if (style->isHorizontalWritingMode())
+        style->setWritingMode(LeftToRightWritingMode);
+}
+
 void StyleResolver::adjustRenderStyle(RenderStyle& style, const RenderStyle& parentStyle, Element *e)
 {
     // Cache our original display.
@@ -1696,7 +1706,12 @@ void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const
             || !cascade.addMatches(matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly))
             return applyMatchedProperties(matchResult, element, DoNotUseMatchedPropertiesCache);
 
+        applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition);
+        adjustStyleForInterCharacterRuby();
+
+        // Start by applying properties that other properties may depend on.
         applyCascadedProperties(cascade, firstCSSProperty, CSSPropertyLineHeight);
+    
         updateFont();
         applyCascadedProperties(cascade, CSSPropertyBackground, lastCSSProperty);
 
@@ -1712,6 +1727,11 @@ void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const
 
     state.setLineHeightValue(nullptr);
 
+    applyCascadedProperties(cascade, CSSPropertyWebkitRubyPosition, CSSPropertyWebkitRubyPosition);
+    
+    // Adjust the font size to be smaller if ruby-position is inter-character.
+    adjustStyleForInterCharacterRuby();
+
     // Start by applying properties that other properties may depend on.
     applyCascadedProperties(cascade, firstCSSProperty, CSSPropertyLineHeight);
 
index 9e1736f..2fa5c9e 100644 (file)
@@ -301,7 +301,9 @@ private:
 #if ENABLE(CSS_GRID_LAYOUT)
     std::unique_ptr<GridPosition> adjustNamedGridItemPosition(const NamedGridAreaMap&, const NamedGridLinesMap&, const GridPosition&, GridPositionSide) const;
 #endif
-
+    
+    void adjustStyleForInterCharacterRuby();
+    
     bool fastRejectSelector(const RuleData&) const;
 
     enum ShouldUseMatchedPropertiesCache { DoNotUseMatchedPropertiesCache = 0, UseMatchedPropertiesCache };
index 6dc210d..88b966b 100644 (file)
@@ -1163,7 +1163,7 @@ rt {
 
 ruby > rt {
     display: block;
-    font-size: 50%;
+    font-size: -webkit-ruby-text;
     text-align: start;
 }
 
index b2b1f75..337c5a6 100644 (file)
@@ -248,8 +248,26 @@ void RenderRubyRun::layout()
         firstLineRubyTextTop = rt->firstRootBox()->logicalTopLayoutOverflow();
         lastLineRubyTextBottom = rootBox->logicalBottomLayoutOverflow();
     }
-
-    if (style().isFlippedLinesWritingMode() == (style().rubyPosition() == RubyPositionAfter)) {
+    
+    if (isHorizontalWritingMode() && rt->style().rubyPosition() == RubyPositionInterCharacter) {
+        // Bopomofo. We need to move the RenderRubyText over to the right side and center it
+        // vertically relative to the base.
+        setWidth(width() + rt->layoutOverflowRect().maxX());
+        if (RenderRubyBase* rb = rubyBase()) {
+            LayoutUnit firstLineTop = 0;
+            LayoutUnit lastLineBottom = logicalHeight();
+            RootInlineBox* rootBox = rb->firstRootBox();
+            if (rootBox)
+                firstLineTop = rootBox->logicalTopLayoutOverflow();
+            firstLineTop += rb->logicalTop();
+            if (rootBox)
+                lastLineBottom = rootBox->logicalBottomLayoutOverflow();
+            lastLineBottom += rb->logicalTop();
+            rt->setX(rb->x() + rb->width());
+            LayoutUnit extent = lastLineBottom - firstLineTop;
+            rt->setY(firstLineTop + (extent - rt->height()) / 2);
+        }
+    } else if (style().isFlippedLinesWritingMode() == (style().rubyPosition() == RubyPositionAfter)) {
         LayoutUnit firstLineTop = 0;
         if (RenderRubyBase* rb = rubyBase()) {
             RootInlineBox* rootBox = rb->firstRootBox();
index 6022662..2fe15b9 100644 (file)
@@ -66,7 +66,7 @@ public:
     void getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, int& startOverhang, int& endOverhang) const;
 
     static RenderRubyRun* staticCreateRubyRun(const RenderObject* parentRuby);
-
+    
 protected:
     RenderRubyBase* createRubyBase() const;
 
index 78e1258..c25e939 100644 (file)
@@ -538,7 +538,7 @@ enum LineSnap { LineSnapNone, LineSnapBaseline, LineSnapContain };
 
 enum LineAlign { LineAlignNone, LineAlignEdges };
 
-enum RubyPosition { RubyPositionBefore, RubyPositionAfter };
+enum RubyPosition { RubyPositionBefore, RubyPositionAfter, RubyPositionInterCharacter };
 
 #if ENABLE(CSS_GRID_LAYOUT)
 static const size_t GridAutoFlowBits = 5;
index 0ed60b2..3a5fa00 100644 (file)
@@ -123,7 +123,7 @@ public:
 #endif // CSS3_TEXT
     unsigned m_textDecorationSkip : 5; // TextDecorationSkip
     unsigned m_textUnderlinePosition : 3; // TextUnderlinePosition
-    unsigned m_rubyPosition : 1; // RubyPosition
+    unsigned m_rubyPosition : 2; // RubyPosition
 
 #if PLATFORM(IOS)
     unsigned touchCalloutEnabled : 1;