Skip to content

Commit

Permalink
[IFC][Ruby] Fix adjacent base/annotation overhang
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=263806

Reviewed by Antti Koivisto.

Overhanging pulls content from right to left (changes visual geometry) and in case of multiple (adjacent) base/annotation pairs
we have to have up-to-date geometry all the way to be able to do overlap checking. We can either do it
by passing in the accumulated shift to overlap checking functions (rather cumbersome) or update
the geometry for all subsequent display boxes before running the overlap test (see FIXME).

* Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::applyRubyOverhang):

Canonical link: https://commits.webkit.org/269887@main
  • Loading branch information
alanbaradlay committed Oct 28, 2023
1 parent 4172b60 commit 19fa8bf
Showing 1 changed file with 27 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1087,41 +1087,34 @@ void InlineDisplayContentBuilder::applyRubyOverhang(InlineDisplay::Boxes& boxes)

auto isHorizontalWritingMode = root().style().isHorizontalWritingMode();
auto rubyFormattingContext = RubyFormattingContext { formattingContext() };
auto accumulatedShift = InlineLayoutUnit { };
size_t currentRubyBaseIndex = 0;

for (auto index = m_interlinearRubyColumnRangeList[0].begin(); index < boxes.size(); ++index) {

if (currentRubyBaseIndex == m_interlinearRubyColumnRangeList.size()) {
isHorizontalWritingMode ? boxes[index].moveHorizontally(-accumulatedShift) : boxes[index].moveVertically(-accumulatedShift);
continue;
}

auto handleOverhangBefore = [&] {
if (index != m_interlinearRubyColumnRangeList[currentRubyBaseIndex].begin())
return;
auto& rubyBaseLayoutBox = boxes[index].layoutBox();
ASSERT(rubyBaseLayoutBox.isRubyBase());
ASSERT(isInterlinearAnnotationBox(rubyBaseLayoutBox.associatedRubyAnnotationBox()));
accumulatedShift += rubyFormattingContext.overhangForAnnotationBefore(rubyBaseLayoutBox, index, boxes);
auto& annotationBoxGeometry = formattingContext().geometryForBox(*rubyBaseLayoutBox.associatedRubyAnnotationBox());
isHorizontalWritingMode ? annotationBoxGeometry.moveHorizontally(LayoutUnit { -accumulatedShift }) : annotationBoxGeometry.moveVertically(LayoutUnit { -accumulatedShift });
};
handleOverhangBefore();

isHorizontalWritingMode ? boxes[index].moveHorizontally(LayoutUnit { -accumulatedShift }) : boxes[index].moveVertically(LayoutUnit { -accumulatedShift });

auto handleOverhangAfter = [&] {
if (index != m_interlinearRubyColumnRangeList[currentRubyBaseIndex].end())
return;
auto rubyBaseIndex = m_interlinearRubyColumnRangeList[currentRubyBaseIndex].begin();
auto& rubyBaseLayoutBox = boxes[rubyBaseIndex].layoutBox();
ASSERT(rubyBaseLayoutBox.isRubyBase());
ASSERT(isInterlinearAnnotationBox(rubyBaseLayoutBox.associatedRubyAnnotationBox()));
accumulatedShift += rubyFormattingContext.overhangForAnnotationAfter(rubyBaseLayoutBox, rubyBaseIndex, index, boxes);
++currentRubyBaseIndex;
for (auto startEndPair : m_interlinearRubyColumnRangeList) {
auto rubyBaseIndex = startEndPair.begin();
auto& rubyBaseLayoutBox = boxes[rubyBaseIndex].layoutBox();
ASSERT(rubyBaseLayoutBox.isRubyBase());
ASSERT(isInterlinearAnnotationBox(rubyBaseLayoutBox.associatedRubyAnnotationBox()));

auto beforeOverhang = rubyFormattingContext.overhangForAnnotationBefore(rubyBaseLayoutBox, rubyBaseIndex, boxes);
auto afterOverhang = rubyFormattingContext.overhangForAnnotationAfter(rubyBaseLayoutBox, rubyBaseIndex, startEndPair.end(), boxes);

// FIXME: If this turns out to be a pref bottleneck, make sure we pass in the accumulated shift to overhangForAnnotationBefore/after and
// offset all box geometry as we check for overlap.
auto moveBoxRangeToVisualLeft = [&](auto start, auto end, auto shiftValue) {
for (auto index = start; index <= end; ++index) {
isHorizontalWritingMode ? boxes[index].moveHorizontally(LayoutUnit { -shiftValue }) : boxes[index].moveVertically(LayoutUnit { -shiftValue });
auto updateAnnotationGeometryIfNeeded = [&] {
auto& layoutBox = boxes[index].layoutBox();
if (!layoutBox.isRubyBase() || !rubyBaseLayoutBox.associatedRubyAnnotationBox())
return;
auto& annotationBoxGeometry = formattingContext().geometryForBox(*layoutBox.associatedRubyAnnotationBox());
isHorizontalWritingMode ? annotationBoxGeometry.moveHorizontally(LayoutUnit { -shiftValue }) : annotationBoxGeometry.moveVertically(LayoutUnit { -shiftValue });
};
updateAnnotationGeometryIfNeeded();
}
};
handleOverhangAfter();
if (beforeOverhang)
moveBoxRangeToVisualLeft(rubyBaseIndex, boxes.size() - 1, beforeOverhang);
if (afterOverhang)
moveBoxRangeToVisualLeft(startEndPair.end() + 1, boxes.size() - 1, afterOverhang);
}
}

Expand Down

0 comments on commit 19fa8bf

Please sign in to comment.