⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 283390 in webkit


Ignore:
Timestamp:
Oct 1, 2021, 12:38:16 PM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Add a dedicated function to set the line break box's vertical geometry
https://bugs.webkit.org/show_bug.cgi?id=231080

Reviewed by Antti Koivisto.

Line break boxes should use the parent inline box's font-metrics when computing vertical geometry.
It also makes the code read better as we don't use a function called "setInitialVerticalGeometryForInlineBox()" to set vertical geometry on a non-inline box (line break box).

  • layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:

(WebCore::Layout::computedHeightAndLayoutBounds):
(WebCore::Layout::LineBoxBuilder::setVerticalGeometryForLineBreakBox const):
(WebCore::Layout::LineBoxBuilder::setInitialVerticalGeometryForInlineBox const):
(WebCore::Layout::LineBoxBuilder::constructAndAlignInlineLevelBoxes):

  • layout/formattingContexts/inline/InlineLineBoxBuilder.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r283377 r283390  
     12021-10-01  Alan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Add a dedicated function to set the line break box's vertical geometry
     4        https://bugs.webkit.org/show_bug.cgi?id=231080
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Line break boxes should use the parent inline box's font-metrics when computing vertical geometry.
     9        It also makes the code read better as we don't use a function called "setInitialVerticalGeometryForInlineBox()" to set vertical geometry on a non-inline box (line break box).
     10
     11        * layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:
     12        (WebCore::Layout::computedHeightAndLayoutBounds):
     13        (WebCore::Layout::LineBoxBuilder::setVerticalGeometryForLineBreakBox const):
     14        (WebCore::Layout::LineBoxBuilder::setInitialVerticalGeometryForInlineBox const):
     15        (WebCore::Layout::LineBoxBuilder::constructAndAlignInlineLevelBoxes):
     16        * layout/formattingContexts/inline/InlineLineBoxBuilder.h:
     17
    1182021-10-01  Youenn Fablet  <youenn@apple.com>
    219
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp

    r283314 r283390  
    193193}
    194194
    195 void LineBoxBuilder::setInitialVerticalGeometryForInlineBox(InlineLevelBox& inlineLevelBox) const
    196 {
    197     ASSERT(inlineLevelBox.isInlineBox() || inlineLevelBox.isLineBreakBox());
    198     auto& primaryFontMetrics = inlineLevelBox.primaryFontMetrics();
    199     InlineLayoutUnit ascent = primaryFontMetrics.ascent();
    200     InlineLayoutUnit descent = primaryFontMetrics.descent();
     195struct HeightAndLayoutBounds {
     196    InlineLayoutUnit ascent { 0 };
     197    InlineLayoutUnit descent { 0 };
     198    InlineLevelBox::LayoutBounds layoutBounds { };
     199};
     200static auto computedHeightAndLayoutBounds(const FontMetrics& fontMetrics, std::optional<InlineLayoutUnit> preferredLineHeight)
     201{
     202    InlineLayoutUnit ascent = fontMetrics.ascent();
     203    InlineLayoutUnit descent = fontMetrics.descent();
    201204    auto logicalHeight = ascent + descent;
    202     // We need floor/ceil to match legacy layout integral positioning.
    203     inlineLevelBox.setBaseline(floorf(ascent));
    204     inlineLevelBox.setDescent(ceilf(descent));
    205     inlineLevelBox.setLogicalHeight(logicalHeight);
    206 
    207     if (inlineLevelBox.isPreferredLineHeightFontMetricsBased()) {
     205
     206    if (preferredLineHeight) {
    208207        // If line-height computes to normal and either text-edge is leading or this is the root inline box,
    209208        // the font’s line gap metric may also be incorporated into A and D by adding half to each side as half-leading.
     
    211210        // Since text-edge is not supported yet and the initial value is leading, we should just apply it to
    212211        // all inline boxes.
    213         auto halfLineGap = (primaryFontMetrics.lineSpacing() - logicalHeight) / 2;
    214         ascent += halfLineGap;
    215         descent += halfLineGap;
    216     } else {
    217         auto preferredLineHeight = inlineLevelBox.preferredLineHeight();
    218         InlineLayoutUnit halfLeading = (preferredLineHeight - (ascent + descent)) / 2;
    219         ascent += halfLeading;
    220         descent += halfLeading;
     212        auto halfLeading = (*preferredLineHeight - logicalHeight) / 2;
     213        return HeightAndLayoutBounds { ascent, descent, { ascent + halfLeading, descent + halfLeading } };
    221214    }
     215    // Preferred line height is purely font metrics based (i.e glyphs stretch the line).
     216    auto halfLineGap = (fontMetrics.lineSpacing() - logicalHeight) / 2;
     217    return HeightAndLayoutBounds { ascent, descent, { ascent + halfLineGap, descent + halfLineGap } };
     218}
     219
     220void LineBoxBuilder::setVerticalGeometryForLineBreakBox(InlineLevelBox& lineBreakBox, const InlineLevelBox& parentInlineBox) const
     221{
    222222    // We need floor/ceil to match legacy layout integral positioning.
    223     inlineLevelBox.setLayoutBounds(InlineLevelBox::LayoutBounds { floorf(ascent), ceilf(descent) });
     223    ASSERT(lineBreakBox.isLineBreakBox());
     224    ASSERT(parentInlineBox.isInlineBox());
     225
     226    auto& fontMetrics = parentInlineBox.primaryFontMetrics();
     227    auto preferredLineHeight = parentInlineBox.isPreferredLineHeightFontMetricsBased() ? std::nullopt : std::make_optional(parentInlineBox.preferredLineHeight());
     228    auto heightAndLayoutBounds = computedHeightAndLayoutBounds(fontMetrics, preferredLineHeight);
     229
     230    lineBreakBox.setBaseline(floorf(heightAndLayoutBounds.ascent));
     231    lineBreakBox.setDescent(ceilf(heightAndLayoutBounds.descent));
     232    lineBreakBox.setLogicalHeight(heightAndLayoutBounds.ascent + heightAndLayoutBounds.descent);
     233    lineBreakBox.setLayoutBounds({ floorf(heightAndLayoutBounds.layoutBounds.ascent), ceilf(heightAndLayoutBounds.layoutBounds.descent) });
     234}
     235
     236void LineBoxBuilder::setInitialVerticalGeometryForInlineBox(InlineLevelBox& inlineBox) const
     237{
     238    // We need floor/ceil to match legacy layout integral positioning.
     239    ASSERT(inlineBox.isInlineBox());
     240
     241    auto& fontMetrics = inlineBox.primaryFontMetrics();
     242    auto preferredLineHeight = inlineBox.isPreferredLineHeightFontMetricsBased() ? std::nullopt : std::make_optional(inlineBox.preferredLineHeight());
     243    auto heightAndLayoutBounds = computedHeightAndLayoutBounds(fontMetrics, preferredLineHeight);
     244
     245    inlineBox.setBaseline(floorf(heightAndLayoutBounds.ascent));
     246    inlineBox.setDescent(ceilf(heightAndLayoutBounds.descent));
     247    inlineBox.setLogicalHeight(heightAndLayoutBounds.ascent + heightAndLayoutBounds.descent);
     248    inlineBox.setLayoutBounds({ floorf(heightAndLayoutBounds.layoutBounds.ascent), ceilf(heightAndLayoutBounds.layoutBounds.descent) });
    224249}
    225250
     
    378403        if (run.isHardLineBreak()) {
    379404            auto lineBreakBox = InlineLevelBox::createLineBreakBox(layoutBox, style, logicalLeft);
    380             setInitialVerticalGeometryForInlineBox(lineBreakBox);
     405            auto& parentInlineBox = lineBox.inlineLevelBoxForLayoutBox(layoutBox.parent());
     406            setVerticalGeometryForLineBreakBox(lineBreakBox, parentInlineBox);
    381407            updateCanUseSimplifiedAlignment(lineBreakBox);
    382408            lineBox.addInlineLevelBox(WTFMove(lineBreakBox));
  • trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h

    r283260 r283390  
    5353private:
    5454    void setInitialVerticalGeometryForInlineBox(InlineLevelBox&) const;
     55    void setVerticalGeometryForLineBreakBox(InlineLevelBox& lineBreakBox, const InlineLevelBox& parentInlineBox) const;
    5556    void adjustVerticalGeometryForInlineBoxWithFallbackFonts(InlineLevelBox&, const TextUtil::FallbackFontList&) const;
    5657    InlineLayoutUnit constructAndAlignInlineLevelBoxes(LineBox&, const Line::RunList&, size_t lineIndex);
Note: See TracChangeset for help on using the changeset viewer.