Title: [292226] trunk
Revision
292226
Author
za...@apple.com
Date
2022-04-01 11:41:29 -0700 (Fri, 01 Apr 2022)

Log Message

[Ruby] Statically positioned out-of-flow block boxes are mispositioned
https://bugs.webkit.org/show_bug.cgi?id=238653

Reviewed by Antti Koivisto.

Source/WebCore:

A statically positioned out-of-flow ruby base e.g.
  <div>A<ruby><rb style="position: absolute">B</rb></ruby></div>
and
  <div>A<span style="position: absolute">B</span></div>
should match layout where <rb> box's top is aligned with current line box's top position
(as if <rb> was inflow, which then puts "A" and "B" (somewhat) next to each other vertically).

However since we wrap such content (<rb>) inside an inline-block type anonymous box (RenderRubyBase), in practice
we match instead this:
  <div>A
    <span style="display: inline-block">
      <span style="position: absolute">B</span>
    </span>
  </div>
where <rb>'s top is now aligned with the top of the wrapper inline-block box's top.
But this inline-block box sits on the line box's baseline with the height of 0 (it's inflow empty)
which makes the <rb> aligned with the line box's baseline instead of its top (and now "B" in below "A" under the baseline).

This patch fixes this by making sure that the (inflow empty) inline-block box's baseline is computed as if it had inflow content.

Test: fast/ruby/ruby-with-out-of-flow-base-content.html

* rendering/RenderRubyBase.cpp:
(WebCore::RenderRubyBase::isEmptyOrHasInFlowContent const):
* rendering/RenderRubyBase.h:
* rendering/RenderRubyRun.cpp:
(WebCore::RenderRubyRun::baselinePosition const):
* rendering/RenderRubyRun.h:

LayoutTests:

* TestExpectations:
* fast/ruby/ruby-with-out-of-flow-base-content-expected.html: Added.
* fast/ruby/ruby-with-out-of-flow-base-content.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (292225 => 292226)


--- trunk/LayoutTests/ChangeLog	2022-04-01 17:43:40 UTC (rev 292225)
+++ trunk/LayoutTests/ChangeLog	2022-04-01 18:41:29 UTC (rev 292226)
@@ -1,3 +1,14 @@
+2022-04-01  Alan Bujtas  <za...@apple.com>
+
+        [Ruby] Statically positioned out-of-flow block boxes are mispositioned
+        https://bugs.webkit.org/show_bug.cgi?id=238653
+
+        Reviewed by Antti Koivisto.
+
+        * TestExpectations:
+        * fast/ruby/ruby-with-out-of-flow-base-content-expected.html: Added.
+        * fast/ruby/ruby-with-out-of-flow-base-content.html: Added.
+
 2022-04-01  Ryan Haddad  <ryanhad...@apple.com>
 
         REGRESSION(r292072): [ Mac iOS ] http/tests/webAPIStatistics/canvas-read-and-write-data-collection.html is a constant text failure

Modified: trunk/LayoutTests/TestExpectations (292225 => 292226)


--- trunk/LayoutTests/TestExpectations	2022-04-01 17:43:40 UTC (rev 292225)
+++ trunk/LayoutTests/TestExpectations	2022-04-01 18:41:29 UTC (rev 292226)
@@ -4649,8 +4649,6 @@
 imported/w3c/web-platform-tests/css/css-contain/contain-inline-size-vertical-rl-.html [ ImageOnlyFailure ]
 # webkit-ruby-text
 imported/w3c/web-platform-tests/css/css-contain/contain-layout-017.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/css-contain/contain-paint-005.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/css-contain/contain-paint-006.html [ ImageOnlyFailure ]
 imported/w3c/web-platform-tests/css/css-contain/contain-paint-008.html [ ImageOnlyFailure ]
 imported/w3c/web-platform-tests/css/css-contain/contain-paint-021.html [ ImageOnlyFailure ]
 imported/w3c/web-platform-tests/css/css-contain/contain-paint-clip-015.html [ ImageOnlyFailure ]

Added: trunk/LayoutTests/fast/ruby/ruby-with-out-of-flow-base-content-expected.html (0 => 292226)


--- trunk/LayoutTests/fast/ruby/ruby-with-out-of-flow-base-content-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-with-out-of-flow-base-content-expected.html	2022-04-01 18:41:29 UTC (rev 292226)
@@ -0,0 +1,11 @@
+<style>
+body {
+  font-family: Ahem;
+  font-size: 20px;
+}
+span {
+  position: absolute;
+}
+</style>
+<div>X<span>XXX</span></div>
+<div>X<span>XXX</span></div>

Added: trunk/LayoutTests/fast/ruby/ruby-with-out-of-flow-base-content.html (0 => 292226)


--- trunk/LayoutTests/fast/ruby/ruby-with-out-of-flow-base-content.html	                        (rev 0)
+++ trunk/LayoutTests/fast/ruby/ruby-with-out-of-flow-base-content.html	2022-04-01 18:41:29 UTC (rev 292226)
@@ -0,0 +1,8 @@
+<style>
+body {
+  font-family: Ahem;
+  font-size: 20px;
+}
+</style>
+<div>X<ruby><rb style="position: absolute">XXX</rb></ruby></div>
+<div>X<ruby><rb><span style="position: absolute">XXX</rb></ruby></div>

Modified: trunk/Source/WebCore/ChangeLog (292225 => 292226)


--- trunk/Source/WebCore/ChangeLog	2022-04-01 17:43:40 UTC (rev 292225)
+++ trunk/Source/WebCore/ChangeLog	2022-04-01 18:41:29 UTC (rev 292226)
@@ -1,3 +1,39 @@
+2022-04-01  Alan Bujtas  <za...@apple.com>
+
+        [Ruby] Statically positioned out-of-flow block boxes are mispositioned
+        https://bugs.webkit.org/show_bug.cgi?id=238653
+
+        Reviewed by Antti Koivisto.
+
+        A statically positioned out-of-flow ruby base e.g.
+          <div>A<ruby><rb style="position: absolute">B</rb></ruby></div>
+        and
+          <div>A<span style="position: absolute">B</span></div>
+        should match layout where <rb> box's top is aligned with current line box's top position
+        (as if <rb> was inflow, which then puts "A" and "B" (somewhat) next to each other vertically).
+
+        However since we wrap such content (<rb>) inside an inline-block type anonymous box (RenderRubyBase), in practice
+        we match instead this:
+          <div>A
+            <span style="display: inline-block">
+              <span style="position: absolute">B</span>
+            </span>
+          </div>
+        where <rb>'s top is now aligned with the top of the wrapper inline-block box's top.
+        But this inline-block box sits on the line box's baseline with the height of 0 (it's inflow empty)
+        which makes the <rb> aligned with the line box's baseline instead of its top (and now "B" in below "A" under the baseline).
+
+        This patch fixes this by making sure that the (inflow empty) inline-block box's baseline is computed as if it had inflow content.
+
+        Test: fast/ruby/ruby-with-out-of-flow-base-content.html
+
+        * rendering/RenderRubyBase.cpp:
+        (WebCore::RenderRubyBase::isEmptyOrHasInFlowContent const):
+        * rendering/RenderRubyBase.h:
+        * rendering/RenderRubyRun.cpp:
+        (WebCore::RenderRubyRun::baselinePosition const):
+        * rendering/RenderRubyRun.h:
+
 2022-04-01  Andres Gonzalez  <andresg...@apple.com>
 
         Add AXObjectCache::treeData() to retrieve serialized representation of the AX trees.

Modified: trunk/Source/WebCore/rendering/RenderRubyBase.cpp (292225 => 292226)


--- trunk/Source/WebCore/rendering/RenderRubyBase.cpp	2022-04-01 17:43:40 UTC (rev 292225)
+++ trunk/Source/WebCore/rendering/RenderRubyBase.cpp	2022-04-01 18:41:29 UTC (rev 292226)
@@ -31,6 +31,8 @@
 #include "config.h"
 
 #include "RenderRubyBase.h"
+
+#include "RenderChildIterator.h"
 #include "RenderRubyRun.h"
 #include "RenderRubyText.h"
 #include <wtf/IsoMallocInlines.h>
@@ -91,4 +93,20 @@
         run->setCachedPriorCharacters(lineBreakIterator.lastCharacter(), lineBreakIterator.secondToLastCharacter());
 }
 
+bool RenderRubyBase::isEmptyOrHasInFlowContent() const
+{
+    auto* firstChild = this->firstChild();
+    if (!firstChild || !is<RenderElement>(*firstChild))
+        return true;
+
+    if (firstChild->isOutOfFlowPositioned())
+        return false;
+
+    for (auto& child : childrenOfType<RenderObject>(*downcast<RenderElement>(firstChild))) {
+        if (!child.isOutOfFlowPositioned())
+            return true;
+    }
+    return false;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderRubyBase.h (292225 => 292226)


--- trunk/Source/WebCore/rendering/RenderRubyBase.h	2022-04-01 17:43:40 UTC (rev 292225)
+++ trunk/Source/WebCore/rendering/RenderRubyBase.h	2022-04-01 18:41:29 UTC (rev 292226)
@@ -59,6 +59,8 @@
     
     void cachePriorCharactersIfNeeded(const LazyLineBreakIterator&) override;
 
+    bool isEmptyOrHasInFlowContent() const;
+
 private:
     bool isRubyBase() const override { return true; }
     bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;

Modified: trunk/Source/WebCore/rendering/RenderRubyRun.cpp (292225 => 292226)


--- trunk/Source/WebCore/rendering/RenderRubyRun.cpp	2022-04-01 17:43:40 UTC (rev 292225)
+++ trunk/Source/WebCore/rendering/RenderRubyRun.cpp	2022-04-01 18:41:29 UTC (rev 292226)
@@ -202,6 +202,16 @@
     computeOverflow(clientLogicalBottom());
 }
 
+LayoutUnit RenderRubyRun::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode lineDirectionMode, LinePositionMode linePositionMode) const
+{
+    // The (inline-block type) ruby base wrapper box fails to produce the correct
+    // baseline when the base is, or has out-of-flow content only.
+    if (!rubyBase() || rubyBase()->isEmptyOrHasInFlowContent())
+        return RenderBlockFlow::baselinePosition(baselineType, firstLine, lineDirectionMode, linePositionMode);
+    auto& style = firstLine ? firstLineStyle() : this->style();
+    return LayoutUnit { style.metricsOfPrimaryFont().ascent(baselineType) };
+}
+
 static bool shouldOverhang(bool firstLine, const RenderObject* renderer, const RenderRubyBase& rubyBase)
 {
     if (!renderer || !renderer->isText())

Modified: trunk/Source/WebCore/rendering/RenderRubyRun.h (292225 => 292226)


--- trunk/Source/WebCore/rendering/RenderRubyRun.h	2022-04-01 17:43:40 UTC (rev 292225)
+++ trunk/Source/WebCore/rendering/RenderRubyRun.h	2022-04-01 18:41:29 UTC (rev 292226)
@@ -54,6 +54,7 @@
     void layoutExcludedChildren(bool relayoutChildren) override;
     void layout() override;
     void layoutBlock(bool relayoutChildren, LayoutUnit pageHeight = 0_lu) override;
+    LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const final;
 
     bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to