ruby-align: Implement the layout behavior
... and make the status "experimental".
The main logic is ApplyRubyAlign() in ruby_utils.cc. We already have
alignment logic. So this CL just adjusts it for ruby-align values.
* LineBreaker::AddRubyColumnResult() should set LineStyle to pass
<ruby>'s style.
* GetOverhang() should return an empty AnnotationOverhang instance
for ruby-align:space-between and an end-only instance for
ruby-align:start.
* Move out space-around tests from css-ruby/ruby-align-00*.html because
Firefox and Chrome have different justification opportunity counts
for "X X X".
Bug: 40249572
Change-Id: I78af66e853356301135dc03bd1ab82c1a0e6ca31
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5595788
Reviewed-by: Koji Ishii <kojii@chromium.org>
Auto-Submit: Kent Tamura <tkent@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1309784}
diff --git a/third_party/blink/renderer/core/layout/inline/line_breaker.cc b/third_party/blink/renderer/core/layout/inline/line_breaker.cc
index 5dff553..b73f54c 100644
--- a/third_party/blink/renderer/core/layout/inline/line_breaker.cc
+++ b/third_party/blink/renderer/core/layout/inline/line_breaker.cc
@@ -3453,6 +3453,7 @@
auto* data = MakeGarbageCollected<InlineItemResultRubyColumn>();
column_result->ruby_column = data;
data->base_line = base_line_info;
+ data->base_line.OverrideLineStyle(*current_style_);
data->base_line.SetIsRubyBase();
data->base_line.UpdateTextAlign();
if (data->base_line.MayHaveRubyOverhang()) {
diff --git a/third_party/blink/renderer/core/layout/inline/ruby_utils.cc b/third_party/blink/renderer/core/layout/inline/ruby_utils.cc
index be826e9..11f1670 100644
--- a/third_party/blink/renderer/core/layout/inline/ruby_utils.cc
+++ b/third_party/blink/renderer/core/layout/inline/ruby_utils.cc
@@ -190,6 +190,15 @@
if (item.IsRubyColumn()) {
DCHECK(RuntimeEnabledFeatures::RubyLineBreakableEnabled());
const InlineItemResultRubyColumn& column = *item.ruby_column;
+ ERubyAlign ruby_align = column.base_line.LineStyle().RubyAlign();
+ switch (ruby_align) {
+ case ERubyAlign::kSpaceBetween:
+ return overhang;
+ case ERubyAlign::kStart:
+ case ERubyAlign::kSpaceAround:
+ case ERubyAlign::kCenter:
+ break;
+ }
LayoutUnit half_width_of_annotation_font;
for (const auto& annotation_line : column.annotation_line_list) {
if (annotation_line.Width() == item.inline_size) {
@@ -201,8 +210,16 @@
if (half_width_of_annotation_font == LayoutUnit()) {
return overhang;
}
- std::optional<LayoutUnit> inset = ComputeRubyBaseInset(
- item.inline_size - column.base_line.Width(), column.base_line);
+ LayoutUnit space = item.inline_size - column.base_line.Width();
+ if (space <= LayoutUnit()) {
+ return overhang;
+ }
+ if (ruby_align == ERubyAlign::kStart) {
+ overhang.end = std::min(space, half_width_of_annotation_font);
+ return overhang;
+ }
+ std::optional<LayoutUnit> inset =
+ ComputeRubyBaseInset(space, column.base_line);
if (!inset) {
return overhang;
}
@@ -390,16 +407,35 @@
if (space <= LayoutUnit()) {
return {LayoutUnit(), LayoutUnit()};
}
+
+ ERubyAlign ruby_align = line_info.LineStyle().RubyAlign();
ETextAlign text_align = line_info.TextAlign();
- // Handle `space-around`.
+ switch (ruby_align) {
+ case ERubyAlign::kSpaceAround:
+ // We respect to the text-align value as ever if ruby-align is the
+ // initial value.
+ break;
+ case ERubyAlign::kSpaceBetween:
+ on_start_edge = true;
+ on_end_edge = true;
+ text_align = ETextAlign::kJustify;
+ break;
+ case ERubyAlign::kStart:
+ return IsLtr(line_info.BaseDirection())
+ ? std::make_pair(LayoutUnit(), space)
+ : std::make_pair(space, LayoutUnit());
+ case ERubyAlign::kCenter:
+ return {space / 2, space / 2};
+ }
+
+ // Handle `space-around` and `space-between`.
if (text_align == ETextAlign::kJustify) {
- JustificationTarget target = JustificationTarget::kNormal;
- if (line_info.IsRubyBase()) {
- target = JustificationTarget::kRubyBase;
+ JustificationTarget target;
+ if (on_start_edge && on_end_edge) {
// Switch to `space-between` if this needs to align both edges.
- if (on_start_edge && on_end_edge) {
- target = JustificationTarget::kNormal;
- }
+ target = JustificationTarget::kNormal;
+ } else if (line_info.IsRubyBase()) {
+ target = JustificationTarget::kRubyBase;
} else {
DCHECK(line_info.IsRubyText());
target = JustificationTarget::kRubyText;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 1c9f333a..4db3b0b5 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -993,7 +993,7 @@
{
// crbug.com/40249572
name: "CssRubyAlign",
- status: "test",
+ status: "experimental",
depends_on: ["RubyLineBreakable"],
},
{
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index a7cd93a7..f333295f 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2344,10 +2344,8 @@
crbug.com/27659 external/wpt/css/css-ruby/improperly-contained-annotation-001.html [ Failure ]
crbug.com/27659 external/wpt/css/css-ruby/rb-display-001.html [ Failure ]
crbug.com/27659 external/wpt/css/css-ruby/rt-display-001.html [ Failure ]
-crbug.com/27659 external/wpt/css/css-ruby/ruby-align-001.html [ Failure ]
crbug.com/27659 external/wpt/css/css-ruby/ruby-align-001a.html [ Failure ]
-crbug.com/27659 external/wpt/css/css-ruby/ruby-align-002.html [ Failure ]
-crbug.com/27659 external/wpt/css/css-ruby/ruby-align-002a.html [ Failure ]
+crbug.com/27659 external/wpt/css/css-ruby/ruby-align-space-around.html [ Failure ]
crbug.com/27659 external/wpt/css/css-ruby/ruby-annotation-pairing-001.html [ Failure ]
crbug.com/27659 external/wpt/css/css-ruby/ruby-base-container-abs.html [ Failure ]
crbug.com/27659 external/wpt/css/css-ruby/ruby-base-container-float.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001-ref.html
index eb368b3a..4497858 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001-ref.html
@@ -12,6 +12,3 @@
<div>X X X</div>
<div style="text-align: center">X X X</div>
<div style="text-align-last: justify">X X X</div>
-<!-- 8px = (width: 160px - 5 * font-size: 16px) /
- (1 + justification opportunities: 4) / 2 -->
-<div style="text-align-last: justify; padding: 0 8px">X X X</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001.html b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001.html
index 13c96f5..c611a56 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001.html
@@ -20,7 +20,4 @@
</ruby><br>
<ruby style="ruby-align: space-between">
<rb>X X X<rt><div></div></rt>
-</ruby><br>
-<ruby style="ruby-align: space-around">
- <rb>X X X<rt><div></div></rt>
</ruby>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001a.html b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001a.html
index 6e652f1..a2c492bb 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001a.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-001a.html
@@ -20,7 +20,4 @@
</ruby><br>
<ruby>
<rb style="ruby-align: space-between">X X X<rt><div></div></rt>
-</ruby><br>
-<ruby>
- <rb style="ruby-align: space-around">X X X<rt><div></div></rt>
</ruby>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002-ref.html
index e4dd3c8..b0d7ec4 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002-ref.html
@@ -20,9 +20,4 @@
</ruby><br>
<ruby>
<rb></rb><rt><div style="text-align-last: justify">X X X</div></rt>
-</ruby><br>
-<!-- 8px = (width: 160px - 5 * font-size: 16px) /
- (1 + justification opportunities: 4) / 2 -->
-<ruby>
- <rb></rb><rt><div style="text-align-last: justify; padding: 0 8px">X X X</div></rt>
</ruby>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002.html b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002.html
index ec40be5..22e43e4 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002.html
@@ -22,7 +22,4 @@
</ruby><br>
<ruby style="ruby-align: space-between">
<rb><div></div><rt>X X X</rt>
-</ruby><br>
-<ruby style="ruby-align: space-around">
- <rb><div></div><rt>X X X</rt>
</ruby>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002a.html b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002a.html
index dfb7ae3..21838c9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002a.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-002a.html
@@ -22,7 +22,4 @@
</ruby><br>
<ruby>
<rb><div></div><rt style="ruby-align: space-between">X X X</rt>
-</ruby><br>
-<ruby>
- <rb><div></div><rt style="ruby-align: space-around">X X X</rt>
</ruby>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-space-around-ref.html b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-space-around-ref.html
new file mode 100644
index 0000000..8eec06f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-space-around-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>Tests for ruby-align</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="stylesheet" href="/fonts/ahem.css">
+<link rel="stylesheet" href="support/ruby-common.css">
+<style>
+ div { width: 160px; box-sizing: border-box; }
+
+ .annotation-test ruby { line-height: 0; }
+ .annotation-test rt { font-size: 100%; }
+ .annotation-test rb { font-size: 0; }
+ .annotation-test rt > div { width: 160px; box-sizing: border-box; }
+</style>
+<body style="font: 16px/3 Ahem">
+<!-- 8px = (width: 160px - 5 * font-size: 16px) /
+ (1 + justification opportunities: 4) / 2 -->
+<div style="text-align-last: justify; padding: 0 8px">X X X</div>
+<div style="text-align-last: justify; padding: 0 8px">X X X</div>
+
+<div class="annotation-test">
+<!-- 8px = (width: 160px - 5 * font-size: 16px) /
+ (1 + justification opportunities: 4) / 2 -->
+<ruby>
+ <rb></rb><rt><div style="text-align-last: justify; padding: 0 8px">X X X</div></rt>
+</ruby><br>
+<ruby>
+ <rb></rb><rt><div style="text-align-last: justify; padding: 0 8px">X X X</div></rt>
+</ruby>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-space-around.html b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-space-around.html
new file mode 100644
index 0000000..dfc1b6a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ruby/ruby-align-space-around.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>Tests for ruby-align</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-ruby-1/#ruby-align-property">
+<link rel="match" href="ruby-align-space-around-ref.html">
+<link rel="stylesheet" href="/fonts/ahem.css">
+<link rel="stylesheet" href="support/ruby-common.css">
+<style>
+ ruby { line-height: 0; }
+ rt > div { width: 160px; }
+
+ .annotation-test ruby { line-height: 0; }
+ .annotation-test rt { font-size: 100%; }
+ .annotation-test rb { font-size: 0; }
+ .annotation-test rb > div { width: 160px; }
+</style>
+<body style="font: 16px/3 Ahem">
+<ruby style="ruby-align: space-around">
+ <rb>X X X<rt><div></div></rt>
+</ruby><br>
+<ruby>
+ <rb style="ruby-align: space-around">X X X<rt><div></div></rt>
+</ruby>
+
+<div class="annotation-test">
+<ruby style="ruby-align: space-around">
+ <rb><div></div><rt>X X X</rt>
+</ruby><br>
+<ruby>
+ <rb><div></div><rt style="ruby-align: space-around">X X X</rt>
+</ruby>
+</div>