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

Changeset 268922 in webkit


Ignore:
Timestamp:
Oct 23, 2020, 5:44:44 AM (6 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Fix inline box relative alignment when line-height is set
https://bugs.webkit.org/show_bug.cgi?id=218107

Reviewed by Antti Koivisto.

Inline box relative vertical alignment logic should use the combination of the layout bounds
and the font metric values of the parent inline box.

The layout bound values (ascent and descent adjusted with half leading) normally match the font metric values,
unless the line-height is set to something other than normal.
In such cases the gap affects the vertical position of the child inline level boxes (e.g. text-top aligns with the
top of the text (use font metrics) and not with the layout bounds).

  • layout/inlineformatting/InlineFormattingContextGeometry.cpp:

(WebCore::Layout::LineBoxBuilder::alignInlineLevelBoxesVerticallyAndComputeLineBoxHeight):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r268919 r268922  
     12020-10-23  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Fix inline box relative alignment when line-height is set
     4        https://bugs.webkit.org/show_bug.cgi?id=218107
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Inline box relative vertical alignment logic should use the combination of the layout bounds
     9        and the font metric values of the parent inline box.
     10
     11        The layout bound values (ascent and descent adjusted with half leading) normally match the font metric values,
     12        unless the line-height is set to something other than normal.
     13        In such cases the gap affects the vertical position of the child inline level boxes (e.g. text-top aligns with the
     14        top of the text (use font metrics) and not with the layout bounds).
     15
     16        * layout/inlineformatting/InlineFormattingContextGeometry.cpp:
     17        (WebCore::Layout::LineBoxBuilder::alignInlineLevelBoxesVerticallyAndComputeLineBoxHeight):
     18
    1192020-10-21  Sergio Villar Senin  <svillar@igalia.com>
    220
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp

    r268864 r268922  
    302302    // 2.2. Layout Within Line Boxes
    303303    // https://www.w3.org/TR/css-inline-3/#line-layout
     304    auto quirks = formattingContext().quirks();
    304305    Vector<LineBox::InlineLevelBox*> lineBoxRelativeInlineLevelBoxes;
    305306    struct AbsoluteTopAndBottom {
     
    311312    auto& rootInlineBox = lineBox.rootInlineBox();
    312313    absoluteLogicalTopAndBottomMap.add(&rootInlineBox, AbsoluteTopAndBottom { { }, rootInlineBox.layoutBounds().height(), &rootInlineBox });
     314    auto maximumOffsetFromRootInlineBoxBaseline = rootInlineBox.isEmpty() ? InlineLayoutUnit() : rootInlineBox.layoutBounds().ascent;
    313315
    314316    auto alignInlineBoxRelativeInlineLevelBoxes = [&] {
     
    324326            auto& parentInlineBox = lineBox.inlineLevelBoxForLayoutBox(layoutBox.parent());
    325327            auto logicalTop = InlineLayoutUnit { };
     328            auto offsetFromParentInlineBoxBaseline = InlineLayoutUnit { };
    326329            switch (verticalAlignment) {
    327330            case VerticalAlign::Baseline:
    328                 logicalTop = parentInlineBox.baseline() - inlineLevelBox->baseline();
    329                 break;
    330             case VerticalAlign::TextTop:
    331                 logicalTop = { };
    332                 break;
    333             case VerticalAlign::TextBottom:
    334                 logicalTop = parentInlineBox.layoutBounds().height() - inlineLevelBox->layoutBounds().height();
    335                 break;
     331                offsetFromParentInlineBoxBaseline = inlineLevelBox->layoutBounds().ascent;
     332                logicalTop = parentInlineBox.baseline() - offsetFromParentInlineBoxBaseline;
     333                break;
     334            case VerticalAlign::TextTop: {
     335                // Note that TextTop aligns with the inline box's font metrics top (ascent) and not the layout bounds top.
     336                auto parentAscent = parentInlineBox.fontMetrics().ascent();
     337                auto parentInlineBoxLogicalTop = parentInlineBox.layoutBounds().ascent - parentAscent;
     338                logicalTop = parentInlineBoxLogicalTop;
     339                offsetFromParentInlineBoxBaseline = parentAscent;
     340                break;
     341            }
     342            case VerticalAlign::TextBottom: {
     343                // Note that TextBottom aligns with the inline box's font metrics bottom (descent) and not the layout bounds bottom.
     344                auto& parentFontMetrics = parentInlineBox.fontMetrics();
     345                auto parentInlineBoxLayoutBounds = parentInlineBox.layoutBounds();
     346                auto parentInlineBoxLogicalBottom = parentInlineBoxLayoutBounds.height() - parentInlineBoxLayoutBounds.descent + parentFontMetrics.descent();
     347                logicalTop = parentInlineBoxLogicalBottom - inlineLevelBox->logicalHeight();
     348                offsetFromParentInlineBoxBaseline = inlineLevelBox->logicalHeight() - parentFontMetrics.descent();
     349                break;
     350            }
    336351            case VerticalAlign::Middle:
    337                 logicalTop = parentInlineBox.baseline() - (inlineLevelBox->layoutBounds().height() / 2 + parentInlineBox.fontMetrics().xHeight() / 2);
     352                offsetFromParentInlineBoxBaseline = (inlineLevelBox->layoutBounds().height() / 2 + parentInlineBox.fontMetrics().xHeight() / 2);
     353                logicalTop = parentInlineBox.baseline() - offsetFromParentInlineBoxBaseline;
    338354                break;
    339355            default:
     
    345361            auto absoluteLogicalTop = parentAbsoluteLogicalTop + logicalTop;
    346362            absoluteLogicalTopAndBottomMap.add(inlineLevelBox.get(), AbsoluteTopAndBottom { absoluteLogicalTop, absoluteLogicalTop + inlineLevelBox->layoutBounds().height(), inlineLevelBox.get() });
     363
     364            auto affectsRootInlineBoxVerticalPostion = isRootInlineBox(parentInlineBox) && quirks.shouldInlineLevelBoxStretchLineBox(lineBox, *inlineLevelBox);
     365            if (affectsRootInlineBoxVerticalPostion)
     366                maximumOffsetFromRootInlineBoxBaseline = std::max(maximumOffsetFromRootInlineBoxBaseline, offsetFromParentInlineBoxBaseline);
    347367        }
    348368    };
     
    351371    auto lineBoxLogicalHeight = InlineLayoutUnit { };
    352372    auto inlineBoxRelativeLogicalHeight = InlineLayoutUnit { };
    353     auto quirks = formattingContext().quirks();
    354     auto maximumBaselineAlignedAscent = rootInlineBox.isEmpty() ? InlineLayoutUnit() : rootInlineBox.layoutBounds().ascent;
    355373    auto computeLineBoxLogicalHeight = [&] {
    356374        // FIXME: Add support for layout bounds based line box height.
     
    363381            minimumLogicalTop = std::min(minimumLogicalTop.valueOr(absoluteLogicalTopAndBottom.top), absoluteLogicalTopAndBottom.top);
    364382            maximumLogicalBottom = std::max(maximumLogicalBottom.valueOr(absoluteLogicalTopAndBottom.bottom), absoluteLogicalTopAndBottom.bottom);
    365             if (inlineLevelBox.verticalAlign() == VerticalAlign::Baseline)
    366                 maximumBaselineAlignedAscent = std::max(maximumBaselineAlignedAscent, inlineLevelBox.layoutBounds().ascent);
    367383        }
    368384        inlineBoxRelativeLogicalHeight = maximumLogicalBottom.valueOr(InlineLayoutUnit()) - minimumLogicalTop.valueOr(InlineLayoutUnit());
     
    379395    auto adjustRootInlineBoxVerticalPosition = [&] {
    380396        // FIXME: Add support for cases when the stretching inline boxes are not baseline aligned.
    381         auto logicalTop = maximumBaselineAlignedAscent - rootInlineBox.layoutBounds().ascent;
    382         rootInlineBox.setLogicalTop(logicalTop);
     397        auto rootInlineBoxLogicalTop = maximumOffsetFromRootInlineBoxBaseline - rootInlineBox.layoutBounds().ascent;
     398        rootInlineBox.setLogicalTop(rootInlineBoxLogicalTop);
    383399    };
    384400    adjustRootInlineBoxVerticalPosition();
Note: See TracChangeset for help on using the changeset viewer.