- 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;