Skip to content

Commit

Permalink
[IFC][Ruby] Add support for non-normal line-height values
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=264205

Reviewed by Antti Koivisto.

* Source/WebCore/layout/formattingContexts/inline/InlineLevelBox.h:
* Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:
(WebCore::Layout::LineBoxBuilder::setLayoutBoundsForInlineBox const):
(WebCore::Layout::LineBoxBuilder::setVerticalPropertiesForInlineLevelBox const):
* Source/WebCore/layout/formattingContexts/inline/ruby/RubyFormattingContext.cpp:
(WebCore::Layout::RubyFormattingContext::applyAnnotationContributionToLayoutBounds const):
(WebCore::Layout::RubyFormattingContext::annotationContributionToLayoutBounds): Deleted.
* Source/WebCore/layout/formattingContexts/inline/ruby/RubyFormattingContext.h:

Canonical link: https://commits.webkit.org/270244@main
  • Loading branch information
alanbaradlay committed Nov 5, 2023
1 parent a53d9e0 commit 3945b83
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class InlineLevelBox {
friend class LineBoxBuilder;
friend class LineBoxVerticalAligner;
friend class InlineFormattingUtils;
friend class RubyFormattingContext;

const InlineRect& logicalRect() const { return m_logicalRect; }
InlineLayoutUnit logicalTop() const { return m_logicalRect.top(); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,11 +218,6 @@ void LineBoxBuilder::setLayoutBoundsForInlineBox(InlineLevelBox& inlineBox, Font
descent += halfLeading;
}
}
if (inlineBox.layoutBox().isRubyBase()) {
auto [over, under] = RubyFormattingContext { formattingContext() }.annotationContributionToLayoutBounds(inlineBox.layoutBox());
ascent += over;
descent += under;
}
return { ascent, descent };
}();

Expand Down Expand Up @@ -275,6 +270,8 @@ void LineBoxBuilder::setVerticalPropertiesForInlineLevelBox(const LineBox& lineB
// With text-box-trim, the inline box top is not always where the content starts.
auto fontMetricBasedAscent = primaryFontMetricsForInlineBox(inlineLevelBox, lineBox.baselineType()).ascent;
inlineLevelBox.setInlineBoxContentOffsetForTextBoxTrim(fontMetricBasedAscent - ascentAndDescent.ascent);
if (inlineLevelBox.layoutBox().isRubyBase())
RubyFormattingContext { formattingContext() }.applyAnnotationContributionToLayoutBounds(inlineLevelBox);
return;
}
if (inlineLevelBox.isLineBreakBox()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,15 +226,41 @@ InlineLayoutSize RubyFormattingContext::sizeAnnotationBox(const Box& rubyBaseLay
return { logicalAnnotationBoxGeometry.contentBoxHeight(), logicalAnnotationBoxGeometry.marginBoxWidth() };
}

RubyFormattingContext::OverUnder RubyFormattingContext::annotationContributionToLayoutBounds(const Box& rubyBaseLayoutBox)
void RubyFormattingContext::applyAnnotationContributionToLayoutBounds(InlineLevelBox& rubyBaseInlineBox) const
{
// In order to ensure consistent spacing of lines, documents with ruby typically ensure that the line-height is
// large enough to accommodate ruby between lines of text. Therefore, ordinarily, ruby annotation containers and ruby annotation
// boxes do not contribute to the measured height of a line’s inline contents;
// line-height calculations are performed using only the ruby base container, exactly as if it were a normal inline.
// However, if the line-height specified on the ruby container is less than the distance between the top of the top ruby annotation
// container and the bottom of the bottom ruby annotation container, then additional leading is added on the appropriate side(s).

auto& rubyBaseLayoutBox = rubyBaseInlineBox.layoutBox();
ASSERT(rubyBaseLayoutBox.isRubyBase());
auto* annotationBox = rubyBaseLayoutBox.associatedRubyAnnotationBox();
if (!isInterlinearAnnotation(annotationBox))
return { };
return;

auto over = InlineLayoutUnit { };
auto under = InlineLayoutUnit { };
auto annotationBoxLogicalHeight = InlineLayoutUnit { parentFormattingContext().geometryForBox(*annotationBox).marginBoxHeight() };
if (annotationBox->style().rubyPosition() == RubyPosition::Before)
return { annotationBoxLogicalHeight, { } };
return { { }, annotationBoxLogicalHeight };
over = annotationBoxLogicalHeight;
else
under = annotationBoxLogicalHeight;

auto layoutBounds = rubyBaseInlineBox.layoutBounds();
if (rubyBaseInlineBox.isPreferredLineHeightFontMetricsBased()) {
layoutBounds.ascent += over;
layoutBounds.descent += under;
} else {
auto& fontMetrics = rubyBaseLayoutBox.style().metricsOfPrimaryFont();
auto ascent = fontMetrics.floatAscent() + over;
auto descent = fontMetrics.floatDescent() + under;
if (layoutBounds.height() < ascent + descent)
layoutBounds = { ascent , descent };
}
rubyBaseInlineBox.setLayoutBounds(layoutBounds);
}

static inline InlineLayoutUnit halfOfAFullWidthCharacter(const Box& annotationBox)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,7 @@ class RubyFormattingContext {
};
InlineLayoutResult layoutInlineAxis(const InlineItemRange&, const InlineItemList&, Line&, InlineLayoutUnit availableWidth);

struct OverUnder {
InlineLayoutUnit over { 0.f };
InlineLayoutUnit under { 0.f };
};
OverUnder annotationContributionToLayoutBounds(const Box& rubyBaseLayoutBox);
void applyAnnotationContributionToLayoutBounds(InlineLevelBox& rubyBaseInlineBox) const;
InlineLayoutPoint placeAnnotationBox(const Box& rubyBaseLayoutBox);
InlineLayoutSize sizeAnnotationBox(const Box& rubyBaseLayoutBox);

Expand Down

0 comments on commit 3945b83

Please sign in to comment.