Skip to content

Commit

Permalink
[IFC][Ruby] Fix fast/ruby/bopomofo-rl.html
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=266335

Reviewed by Antti Koivisto.

Annotation box alignment should follow ruby base alignment flow:
1. run justify alignment after line breaking (using Line::Runs)
2. offset justified runs (space-around) during display content building

* Source/WebCore/layout/formattingContexts/inline/InlineContentAligner.cpp:
(WebCore::Layout::InlineContentAligner::applyRubyAnnotationAlignmentOffset):
(WebCore::Layout::InlineContentAligner::applyRubyAlignOnAnnotationBox): Deleted.
* Source/WebCore/layout/formattingContexts/inline/InlineContentAligner.h:
* Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::LineBuilder::layoutInlineContent):
(WebCore::Layout::LineBuilder::placeInlineAndFloatContent):
* Source/WebCore/layout/formattingContexts/inline/LineLayoutResult.h:
* Source/WebCore/layout/formattingContexts/inline/display/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::processRubyContent):
* Source/WebCore/layout/formattingContexts/inline/ruby/RubyFormattingContext.cpp:
(WebCore::Layout::RubyFormattingContext::applyRubyAlignOnAnnotationBox):
(WebCore::Layout::RubyFormattingContext::applyAnnotationAlignmentOffset):
* Source/WebCore/layout/formattingContexts/inline/ruby/RubyFormattingContext.h:

Canonical link: https://commits.webkit.org/271980@main
  • Loading branch information
alanbaradlay committed Dec 13, 2023
1 parent cfd1072 commit b4b989c
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -272,18 +272,6 @@ InlineLayoutUnit InlineContentAligner::applyRubyAlignSpaceAround(Line::RunList&
return extraExpansionOpportunitySpace / 2;
}

InlineLayoutUnit InlineContentAligner::applyRubyAlignOnAnnotationBox(Line::RunList& runs, InlineLayoutUnit spaceToDistribute)
{
auto accumulatedExpansion = applyTextAlignJustify(runs, spaceToDistribute, { });
if (accumulatedExpansion)
return accumulatedExpansion;

auto centerOffset = spaceToDistribute / 2;
for (auto& run : runs)
run.moveHorizontally(centerOffset);
return spaceToDistribute;
}

void InlineContentAligner::applyRubyBaseAlignmentOffset(InlineDisplay::Boxes& displayBoxes, const HashMap<const Box*, InlineLayoutUnit>& alignmentOffsetList, AdjustContentOnlyInsideRubyBase adjustContentOnlyInsideRubyBase, InlineFormattingContext& inlineFormattingContext)
{
ASSERT(!alignmentOffsetList.isEmpty());
Expand All @@ -309,6 +297,12 @@ void InlineContentAligner::applyRubyBaseAlignmentOffset(InlineDisplay::Boxes& di
expandInlineBoxWithDescendants(0, displayBoxes, alignmentOffsetList, inlineFormattingContext);
}

void InlineContentAligner::applyRubyAnnotationAlignmentOffset(InlineDisplay::Boxes& displayBoxes, InlineLayoutUnit alignmentOffset, InlineFormattingContext& inlineFormattingContext)
{
for (size_t index = 0; index < displayBoxes.size(); ++index)
shiftDisplayBox(displayBoxes[index], alignmentOffset, inlineFormattingContext);
}

}
}

Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,10 @@ class InlineContentAligner {
static InlineLayoutUnit applyTextAlignJustify(Line::RunList&, InlineLayoutUnit spaceToDistribute, size_t hangingTrailingWhitespaceLength);

static InlineLayoutUnit applyRubyAlignSpaceAround(Line::RunList&, WTF::Range<size_t>, InlineLayoutUnit spaceToDistribute);
// FIXME: This is a workaround until after we generate inline boxes for annotation content.
static InlineLayoutUnit applyRubyAlignOnAnnotationBox(Line::RunList&, InlineLayoutUnit spaceToDistribute);

enum class AdjustContentOnlyInsideRubyBase : bool { No, Yes };
static void applyRubyBaseAlignmentOffset(InlineDisplay::Boxes&, const HashMap<const Box*, InlineLayoutUnit>& alignmentOffsetList, AdjustContentOnlyInsideRubyBase, InlineFormattingContext&);
static void applyRubyAnnotationAlignmentOffset(InlineDisplay::Boxes&, InlineLayoutUnit alignmentOffset, InlineFormattingContext&);

private:
static InlineLayoutUnit applyExpansionOnRange(Line::RunList&, WTF::Range<size_t>, const ExpansionInfo&, InlineLayoutUnit spaceToDistribute);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ struct LineContent {
bool endsWithHyphen { false };
size_t partialTrailingContentLength { 0 };
std::optional<InlineLayoutUnit> overflowLogicalWidth { };
HashMap<const Box*, InlineLayoutUnit> rubyAlignmentOffsetList { };
HashMap<const Box*, InlineLayoutUnit> rubyBaseAlignmentOffsetList { };
InlineLayoutUnit rubyAnnotationOffset { 0.f };
};

static inline StringBuilder toString(const Line::RunList& runs)
Expand Down Expand Up @@ -261,7 +262,7 @@ LineLayoutResult LineBuilder::layoutInlineContent(const LineInput& lineInput, co
, { !result.isHangingTrailingContentWhitespace, result.hangingTrailingContentWidth }
, { WTFMove(visualOrderList), inlineBaseDirection }
, { isFirstFormattedLine() ? LineLayoutResult::IsFirstLast::FirstFormattedLine::WithinIFC : LineLayoutResult::IsFirstLast::FirstFormattedLine::No, isLastLine }
, WTFMove(lineContent.rubyAlignmentOffsetList)
, { WTFMove(lineContent.rubyBaseAlignmentOffsetList), lineContent.rubyAnnotationOffset }
, lineContent.endsWithHyphen
, result.nonSpanningInlineLevelBoxCount
, { }
Expand Down Expand Up @@ -508,15 +509,15 @@ LineContent LineBuilder::placeInlineAndFloatContent(const InlineItemRange& needs
return;

auto spaceToDistribute = horizontalAvailableSpace - m_line.contentLogicalWidth() + (m_line.isHangingTrailingContentWhitespace() ? m_line.hangingTrailingContentWidth() : 0.f);
if (m_line.hasRubyContent()) {
lineContent.rubyAlignmentOffsetList = RubyFormattingContext::applyRubyAlign(m_line, formattingContext());
return;
}
if (root().isRubyAnnotationBox() && rootStyle.textAlign() == RenderStyle::initialTextAlign()) {
InlineContentAligner::applyRubyAlignOnAnnotationBox(m_line.runs(), spaceToDistribute);
lineContent.rubyAnnotationOffset = RubyFormattingContext::applyRubyAlignOnAnnotationBox(m_line, spaceToDistribute, formattingContext());
m_line.inflateContentLogicalWidth(spaceToDistribute);
return;
}
if (m_line.hasRubyContent()) {
lineContent.rubyBaseAlignmentOffsetList = RubyFormattingContext::applyRubyAlign(m_line, formattingContext());
return;
}
// Text is justified according to the method specified by the text-justify property,
// in order to exactly fill the line box. Unless otherwise specified by text-align-last,
// the last line before a forced break or the end of the block is start-aligned.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ struct LineLayoutResult {
};
IsFirstLast isFirstLast { };

HashMap<const Box*, InlineLayoutUnit> rubyAlignemntOffsetList { };
struct Ruby {
HashMap<const Box*, InlineLayoutUnit> baseAlignmentOffsetList { };
InlineLayoutUnit annotationAlignmentOffset { 0.f };
};
Ruby ruby { };

// Misc
bool endsWithHyphen { false };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1130,11 +1130,14 @@ size_t InlineDisplayContentBuilder::processRubyBase(size_t rubyBaseStart, Inline

void InlineDisplayContentBuilder::processRubyContent(InlineDisplay::Boxes& displayBoxes, const LineLayoutResult& lineLayoutResult)
{
if (root().isRubyAnnotationBox())
RubyFormattingContext::applyAnnotationAlignmentOffset(displayBoxes, lineLayoutResult.ruby.annotationAlignmentOffset, formattingContext());

if (!m_hasSeenRubyBase)
return;

auto rubyBasesMayHaveCollapsed = !lineLayoutResult.directionality.visualOrderList.isEmpty();
RubyFormattingContext::applyAlignmentOffsetList(displayBoxes, lineLayoutResult.rubyAlignemntOffsetList, rubyBasesMayHaveCollapsed ? RubyFormattingContext::RubyBasesMayNeedResizing::Yes : RubyFormattingContext::RubyBasesMayNeedResizing::No, formattingContext());
RubyFormattingContext::applyAlignmentOffsetList(displayBoxes, lineLayoutResult.ruby.baseAlignmentOffsetList, rubyBasesMayHaveCollapsed ? RubyFormattingContext::RubyBasesMayNeedResizing::Yes : RubyFormattingContext::RubyBasesMayNeedResizing::No, formattingContext());

Vector<WTF::Range<size_t>> interlinearRubyColumnRangeList;
Vector<size_t> rubyBaseStartIndexListWithAnnotation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,25 @@ HashMap<const Box*, InlineLayoutUnit> RubyFormattingContext::applyRubyAlign(Line
return alignmentOffsetList;
}

InlineLayoutUnit RubyFormattingContext::applyRubyAlignOnAnnotationBox(Line& line, InlineLayoutUnit spaceToDistribute, const InlineFormattingContext&)
{
return InlineContentAligner::applyRubyAlignSpaceAround(line.runs(), { 0, line.runs().size() }, spaceToDistribute);
}

void RubyFormattingContext::applyAlignmentOffsetList(InlineDisplay::Boxes& displayBoxes, const HashMap<const Box*, InlineLayoutUnit>& alignmentOffsetList, RubyBasesMayNeedResizing rubyBasesMayNeedResizing, InlineFormattingContext& inlineFormattingContext)
{
if (alignmentOffsetList.isEmpty())
return;
InlineContentAligner::applyRubyBaseAlignmentOffset(displayBoxes, alignmentOffsetList, rubyBasesMayNeedResizing == RubyBasesMayNeedResizing::No ? InlineContentAligner::AdjustContentOnlyInsideRubyBase::Yes : InlineContentAligner::AdjustContentOnlyInsideRubyBase::No, inlineFormattingContext);
}

void RubyFormattingContext::applyAnnotationAlignmentOffset(InlineDisplay::Boxes& displayBoxes, InlineLayoutUnit alignmentOffset, InlineFormattingContext& inlineFormattingContext)
{
if (!alignmentOffset)
return;
InlineContentAligner::applyRubyAnnotationAlignmentOffset(displayBoxes, alignmentOffset, inlineFormattingContext);
}

InlineLayoutUnit RubyFormattingContext::baseEndAdditionalVisualWidth(const Box& rubyBaseLayoutBox, const InlineDisplay::Box&, InlineLayoutUnit baseContentWidth, const InlineFormattingContext& inlineFormattingContext)
{
if (!hasInterCharacterAnnotation(rubyBaseLayoutBox)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class RubyFormattingContext {
static InlineLayoutUnit annotationBoxLogicalWidth(const Box& rubyBaseLayoutBox, const InlineFormattingContext&);
static InlineLayoutUnit baseEndAdditionalLogicalWidth(const Box& rubyBaseLayoutBox, const Line::RunList&, const InlineContentBreaker::ContinuousContent::RunList&, const InlineFormattingContext&);
static HashMap<const Box*, InlineLayoutUnit> applyRubyAlign(Line&, const InlineFormattingContext&);
static InlineLayoutUnit applyRubyAlignOnAnnotationBox(Line&, InlineLayoutUnit spaceToDistribute, const InlineFormattingContext&);

// Line box building
static void applyAnnotationContributionToLayoutBounds(LineBox&, const InlineFormattingContext&);
Expand All @@ -58,6 +59,7 @@ class RubyFormattingContext {

enum class RubyBasesMayNeedResizing : bool { No, Yes };
static void applyAlignmentOffsetList(InlineDisplay::Boxes&, const HashMap<const Box*, InlineLayoutUnit>& alignmentOffsetList, RubyBasesMayNeedResizing, InlineFormattingContext&);
static void applyAnnotationAlignmentOffset(InlineDisplay::Boxes&, InlineLayoutUnit alignmentOffset, InlineFormattingContext&);

// Miscellaneous helpers
static bool hasInterlinearAnnotation(const Box& rubyBaseLayoutBox);
Expand Down

0 comments on commit b4b989c

Please sign in to comment.