Title: [290207] trunk/Source/WebCore
Revision
290207
Author
[email protected]
Date
2022-02-19 08:16:06 -0800 (Sat, 19 Feb 2022)

Log Message

[LFC][IFC] Add support for ideographic baseline with font fallback
https://bugs.webkit.org/show_bug.cgi?id=236872

Reviewed by Antti Koivisto.

Let's use the pre-collected fallback fonts to adjust the inline box layout bounds with their ideographic baselines.
This is in preparation for enabling vertical text.

* layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:
(WebCore::Layout::LineBoxBuilder::adjustLayoutBoundsWithFallbackFonts const):
(WebCore::Layout::LineBoxBuilder::collectFallbackFonts):
(WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes):
(WebCore::Layout::LineBoxBuilder::adjustIdeographicBaselineIfApplicable):
* layout/formattingContexts/inline/InlineLineBoxBuilder.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (290206 => 290207)


--- trunk/Source/WebCore/ChangeLog	2022-02-19 14:45:45 UTC (rev 290206)
+++ trunk/Source/WebCore/ChangeLog	2022-02-19 16:16:06 UTC (rev 290207)
@@ -1,3 +1,20 @@
+2022-02-19  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] Add support for ideographic baseline with font fallback
+        https://bugs.webkit.org/show_bug.cgi?id=236872
+
+        Reviewed by Antti Koivisto.
+
+        Let's use the pre-collected fallback fonts to adjust the inline box layout bounds with their ideographic baselines.
+        This is in preparation for enabling vertical text.
+
+        * layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:
+        (WebCore::Layout::LineBoxBuilder::adjustLayoutBoundsWithFallbackFonts const):
+        (WebCore::Layout::LineBoxBuilder::collectFallbackFonts):
+        (WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes):
+        (WebCore::Layout::LineBoxBuilder::adjustIdeographicBaselineIfApplicable):
+        * layout/formattingContexts/inline/InlineLineBoxBuilder.h:
+
 2022-02-19  Philippe Normand  <[email protected]>
 
         [WPE][GTK] Enable Thunder and remove old Clearkey CDM/Decryptor

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp (290206 => 290207)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp	2022-02-19 14:45:45 UTC (rev 290206)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp	2022-02-19 16:16:06 UTC (rev 290207)
@@ -116,7 +116,7 @@
     return lineBox;
 }
 
-void LineBoxBuilder::adjustLayoutBoundsWithFallbackFonts(InlineLevelBox& inlineBox, const TextUtil::FallbackFontList& fallbackFontsForContent) const
+void LineBoxBuilder::adjustLayoutBoundsWithFallbackFonts(InlineLevelBox& inlineBox, const TextUtil::FallbackFontList& fallbackFontsForContent, FontBaseline fontBaseline) const
 {
     ASSERT(!fallbackFontsForContent.isEmpty());
     ASSERT(inlineBox.isInlineBox());
@@ -134,8 +134,8 @@
     auto shouldUseLineGapToAdjustAscentDescent = inlineBox.isRootInlineBox() || isTextEdgeLeading;
     for (auto* font : fallbackFontsForContent) {
         auto& fontMetrics = font->fontMetrics();
-        InlineLayoutUnit ascent = fontMetrics.ascent();
-        InlineLayoutUnit descent = fontMetrics.descent();
+        InlineLayoutUnit ascent = fontMetrics.ascent(fontBaseline);
+        InlineLayoutUnit descent = fontMetrics.descent(fontBaseline);
         if (shouldUseLineGapToAdjustAscentDescent) {
             auto logicalHeight = ascent + descent;
             auto halfLineGap = (fontMetrics.lineSpacing() - logicalHeight) / 2;
@@ -151,8 +151,9 @@
     inlineBox.setLayoutBounds({ std::max(layoutBounds.ascent, floorf(maxAscent)), std::max(layoutBounds.descent, ceilf(maxDescent)) });
 }
 
-TextUtil::FallbackFontList LineBoxBuilder::collectFallbackFonts(const Line::Run& run, const RenderStyle& style)
+TextUtil::FallbackFontList LineBoxBuilder::collectFallbackFonts(const InlineLevelBox& parentInlineBox, const Line::Run& run, const RenderStyle& style)
 {
+    ASSERT(parentInlineBox.isInlineBox());
     auto& inlineTextBox = downcast<InlineTextBox>(run.layoutBox());
     if (inlineTextBox.canUseSimplifiedContentMeasuring()) {
         // Simplified text measuring works with primary font only.
@@ -163,15 +164,14 @@
     if (fallbackFonts.isEmpty())
         return { };
 
-    auto fallbackFontsHaveVerticalGlyph = [&] {
-        for (auto* font : fallbackFonts) {
-            if (font->hasVerticalGlyphs())
-                return true;
-        }
-        return false;
-    };
-    // Adjust non-empty inline box height when glyphs from the non-primary font stretch the box.
-    m_fallbackFontRequiresIdeographicBaseline = m_fallbackFontRequiresIdeographicBaseline || fallbackFontsHaveVerticalGlyph();
+    auto fallbackFontsForInlineBoxes = m_fallbackFontsForInlineBoxes.get(&parentInlineBox);
+    auto numberOfFallbackFontsForInlineBox = fallbackFontsForInlineBoxes.size();
+    for (auto* font : fallbackFonts) {
+        fallbackFontsForInlineBoxes.add(font);
+        m_fallbackFontRequiresIdeographicBaseline = m_fallbackFontRequiresIdeographicBaseline || font->hasVerticalGlyphs();
+    }
+    if (fallbackFontsForInlineBoxes.size() != numberOfFallbackFontsForInlineBox)
+        m_fallbackFontsForInlineBoxes.set(&parentInlineBox, fallbackFontsForInlineBoxes);
     return fallbackFonts;
 }
 
@@ -331,9 +331,9 @@
         if (run.isText()) {
             auto& parentInlineBox = lineBox.inlineLevelBoxForLayoutBox(layoutBox.parent());
             parentInlineBox.setHasContent();
-            if (auto fallbackFonts = collectFallbackFonts(run, style); !fallbackFonts.isEmpty()) {
+            if (auto fallbackFonts = collectFallbackFonts(parentInlineBox, run, style); !fallbackFonts.isEmpty()) {
                 // Adjust non-empty inline box height when glyphs from the non-primary font stretch the box.
-                adjustLayoutBoundsWithFallbackFonts(parentInlineBox, fallbackFonts);
+                adjustLayoutBoundsWithFallbackFonts(parentInlineBox, fallbackFonts, AlphabeticBaseline);
             }
             continue;
         }
@@ -387,20 +387,36 @@
         return;
 
     lineBox.setBaselineType(IdeographicBaseline);
-    setBaselineAndLayoutBounds(rootInlineBox, layoutBoundsPrimaryMetricsForInlineBox(rootInlineBox, IdeographicBaseline));
-    for (auto& inlineLevelBox : lineBox.nonRootInlineLevelBoxes()) {
+
+    auto adjustLayoutBoundsWithIdeographicBaseline = [&] (auto& inlineLevelBox) {
+        auto initiatesLayoutBoundsChange = inlineLevelBox.isInlineBox() || inlineLevelBox.isAtomicInlineLevelBox() || inlineLevelBox.isLineBreakBox();
+        if (!initiatesLayoutBoundsChange)
+            return;
+
+        auto layoutBoundsPrimaryMetrics = LayoutBoundsMetrics { };
         if (inlineLevelBox.isInlineBox())
-            setBaselineAndLayoutBounds(inlineLevelBox, layoutBoundsPrimaryMetricsForInlineBox(inlineLevelBox, IdeographicBaseline));
-        else if (inlineLevelBox.isLineBreakBox()) {
-            auto& parentInlineBox = lineBox.inlineLevelBoxForLayoutBox(inlineLevelBox.layoutBox().parent());
-            setBaselineAndLayoutBounds(inlineLevelBox, layoutBoundsPrimaryMetricsForInlineBox(parentInlineBox, IdeographicBaseline));
-        } else if (inlineLevelBox.isAtomicInlineLevelBox()) {
+            layoutBoundsPrimaryMetrics = layoutBoundsPrimaryMetricsForInlineBox(inlineLevelBox, IdeographicBaseline);
+        else if (inlineLevelBox.isAtomicInlineLevelBox()) {
             auto inlineLevelBoxHeight = inlineLevelBox.layoutBounds().height();
             InlineLayoutUnit ideographicBaseline = roundToInt(inlineLevelBoxHeight / 2);
             // Move the baseline position but keep the same logical height.
-            setBaselineAndLayoutBounds(inlineLevelBox, { ideographicBaseline, inlineLevelBoxHeight - ideographicBaseline });
+            layoutBoundsPrimaryMetrics = { ideographicBaseline, inlineLevelBoxHeight - ideographicBaseline };
+        } else if (inlineLevelBox.isLineBreakBox()) {
+            auto& parentInlineBox = lineBox.inlineLevelBoxForLayoutBox(inlineLevelBox.layoutBox().parent());
+            layoutBoundsPrimaryMetrics = layoutBoundsPrimaryMetricsForInlineBox(parentInlineBox, IdeographicBaseline);
         }
-    }
+        setBaselineAndLayoutBounds(inlineLevelBox, layoutBoundsPrimaryMetrics);
+
+        auto needsFontFallbackAdjustment = inlineLevelBox.isInlineBox() || inlineLevelBox.isLineBreakBox();
+        if (needsFontFallbackAdjustment) {
+            if (auto fallbackFonts = m_fallbackFontsForInlineBoxes.get(&inlineLevelBox); !fallbackFonts.isEmpty())
+                adjustLayoutBoundsWithFallbackFonts(inlineLevelBox, fallbackFonts, IdeographicBaseline);
+        }
+    };
+
+    adjustLayoutBoundsWithIdeographicBaseline(rootInlineBox);
+    for (auto& inlineLevelBox : lineBox.nonRootInlineLevelBoxes())
+        adjustLayoutBoundsWithIdeographicBaseline(inlineLevelBox);
 }
 
 }

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h (290206 => 290207)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h	2022-02-19 14:45:45 UTC (rev 290206)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.h	2022-02-19 16:16:06 UTC (rev 290207)
@@ -47,8 +47,8 @@
 
 private:
     void setBaselineAndLayoutBounds(InlineLevelBox&, const LayoutBoundsMetrics&) const;
-    void adjustLayoutBoundsWithFallbackFonts(InlineLevelBox&, const TextUtil::FallbackFontList&) const;
-    TextUtil::FallbackFontList collectFallbackFonts(const Line::Run&, const RenderStyle&);
+    void adjustLayoutBoundsWithFallbackFonts(InlineLevelBox&, const TextUtil::FallbackFontList& fallbackFontsForContent, FontBaseline) const;
+    TextUtil::FallbackFontList collectFallbackFonts(const InlineLevelBox& parentInlineBox, const Line::Run&, const RenderStyle&);
 
     void constructInlineLevelBoxes(LineBox&, const LineBuilder::LineContent&, size_t lineIndex);
     void adjustIdeographicBaselineIfApplicable(LineBox&, size_t lineIndex);
@@ -60,6 +60,7 @@
 private:
     const InlineFormattingContext& m_inlineFormattingContext;
     bool m_fallbackFontRequiresIdeographicBaseline { false };
+    HashMap<const InlineLevelBox*, TextUtil::FallbackFontList> m_fallbackFontsForInlineBoxes;
 };
 
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to