Title: [289609] trunk
Revision
289609
Author
mmaxfi...@apple.com
Date
2022-02-11 00:40:49 -0800 (Fri, 11 Feb 2022)

Log Message

Tab characters and ch units do not obey synthetic bold width adjustments correctly
https://bugs.webkit.org/show_bug.cgi?id=236172

Reviewed by Alan Bujtas.

Source/WebCore:

It turns out we have a lot of places where code wants to know the synthetic-bold-expanded
width of characters. One place is 'tab-width: <integer>' and another is the 'ch' unit.
However, WidthIterator and ComplexTextController don't want the synthetic-bold-expanded
widths, because they explicitly apply synthetic bold after shaping.

This patch adds a 2-value enum argument to the Font::widthForGlyph() function, so callers
can pass in which behavior they want. The function has a default value to include the
synthetic bold expansion.

I then audited every call site of this function, and passed in the correct enum value.
Doing this led me to discover two bugs where the wrong behavior was being used, and this
patch fixes them and adds tests for them.

Tests: fast/text/ch-unit-synthetic-bold.html
       fast/text/tab-width-synthetic-bold-complex.html
       fast/text/tab-width-synthetic-bold.html

* layout/formattingContexts/inline/text/TextUtil.cpp:
(WebCore::Layout::fallbackFontsForRunWithIterator):
* platform/graphics/ComplexTextController.cpp:
(WebCore::ComplexTextController::adjustGlyphsAndAdvances):
(WebCore::ComplexTextController::ComplexTextRun::ComplexTextRun):
* platform/graphics/Font.cpp:
(WebCore::Font::platformGlyphInit):
* platform/graphics/Font.h:
(WebCore::Font::spaceWidth const):
(WebCore::Font::widthForGlyph const):
* platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::widthForSimpleText const):
* platform/graphics/FontCascade.h:
(WebCore::FontCascade::tabWidth const):
* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::advanceInternal):
(WebCore::WidthIterator::calculateAdditionalWidth const):

LayoutTests:

3 new tests. Also, the changes in ignored-properties-001-expected.txt are a revert of the rebaseline in
r281687. That rebaseline was wrong, so this undoes it.

* fast/text/ch-unit-synthetic-bold-expected.html: Added.
* fast/text/ch-unit-synthetic-bold.html: Added.
* fast/text/tab-width-synthetic-bold-complex-expected.html: Added.
* fast/text/tab-width-synthetic-bold-complex.html: Added.
* fast/text/tab-width-synthetic-bold-expected.html: Added.
* fast/text/tab-width-synthetic-bold.html: Added.
* platform/ios/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt:
* platform/mac-catalina/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt:
* platform/mac-mojave/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt:
* platform/mac/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (289608 => 289609)


--- trunk/LayoutTests/ChangeLog	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/LayoutTests/ChangeLog	2022-02-11 08:40:49 UTC (rev 289609)
@@ -1,3 +1,24 @@
+2022-02-11  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Tab characters and ch units do not obey synthetic bold width adjustments correctly
+        https://bugs.webkit.org/show_bug.cgi?id=236172
+
+        Reviewed by Alan Bujtas.
+
+        3 new tests. Also, the changes in ignored-properties-001-expected.txt are a revert of the rebaseline in
+        r281687. That rebaseline was wrong, so this undoes it.
+
+        * fast/text/ch-unit-synthetic-bold-expected.html: Added.
+        * fast/text/ch-unit-synthetic-bold.html: Added.
+        * fast/text/tab-width-synthetic-bold-complex-expected.html: Added.
+        * fast/text/tab-width-synthetic-bold-complex.html: Added.
+        * fast/text/tab-width-synthetic-bold-expected.html: Added.
+        * fast/text/tab-width-synthetic-bold.html: Added.
+        * platform/ios/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt:
+        * platform/mac-catalina/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt:
+        * platform/mac-mojave/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt:
+        * platform/mac/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt:
+
 2022-02-11  Diego Pino Garcia  <dp...@igalia.com>
 
         [GTK] Remove several stale WPT offscreen canvas tests

Added: trunk/LayoutTests/fast/text/ch-unit-synthetic-bold-expected.html (0 => 289609)


--- trunk/LayoutTests/fast/text/ch-unit-synthetic-bold-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/ch-unit-synthetic-bold-expected.html	2022-02-11 08:40:49 UTC (rev 289609)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure that the <code>ch</code> unit, which is supposed to be as wide as the <code>0</code> character, is in fact that wide, even if the font is using synthetic bold. The test passes if the width of the green box matches in both cases.
+<div>
+<div style="font: bold 16px 'Monaco'; display: inline-block; background: green; color: transparent;">0000000000</div>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/text/ch-unit-synthetic-bold.html (0 => 289609)


--- trunk/LayoutTests/fast/text/ch-unit-synthetic-bold.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/ch-unit-synthetic-bold.html	2022-02-11 08:40:49 UTC (rev 289609)
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure that the <code>ch</code> unit, which is supposed to be as wide as the <code>0</code> character, is in fact that wide, even if the font is using synthetic bold. The test passes if the width of the green box matches in both cases.
+<div style="font: bold 16px 'Monaco'; background: green; width: 10ch; color: transparent;">a</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/text/tab-width-synthetic-bold-complex-expected.html (0 => 289609)


--- trunk/LayoutTests/fast/text/tab-width-synthetic-bold-complex-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/tab-width-synthetic-bold-complex-expected.html	2022-02-11 08:40:49 UTC (rev 289609)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure that, when the width of a tab is set to be a multiple of the space width, that the space width includes the synthetic bold expansion. The test passes if the width of the green box matches in both cases.
+<div>
+<pre style="font: bold 16px 'Monaco'; display: inline-block; background: green; tab-size: 16;">                </pre>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/text/tab-width-synthetic-bold-complex.html (0 => 289609)


--- trunk/LayoutTests/fast/text/tab-width-synthetic-bold-complex.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/tab-width-synthetic-bold-complex.html	2022-02-11 08:40:49 UTC (rev 289609)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure that, when the width of a tab is set to be a multiple of the space width, that the space width includes the synthetic bold expansion. The test passes if the width of the green box matches in both cases.
+<div>
+<pre style="font: bold 16px 'Monaco'; font-feature-settings: 'ABCD'; display: inline-block; background: green; tab-size: 16;">&#x9;</pre>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/text/tab-width-synthetic-bold-expected.html (0 => 289609)


--- trunk/LayoutTests/fast/text/tab-width-synthetic-bold-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/tab-width-synthetic-bold-expected.html	2022-02-11 08:40:49 UTC (rev 289609)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure that, when the width of a tab is set to be a multiple of the space width, that the space width includes the synthetic bold expansion. The test passes if the width of the green box matches in both cases.
+<div>
+<pre style="font: bold 16px 'Monaco'; display: inline-block; background: green; tab-size: 16;">                </pre>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/text/tab-width-synthetic-bold.html (0 => 289609)


--- trunk/LayoutTests/fast/text/tab-width-synthetic-bold.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/tab-width-synthetic-bold.html	2022-02-11 08:40:49 UTC (rev 289609)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+This test makes sure that, when the width of a tab is set to be a multiple of the space width, that the space width includes the synthetic bold expansion. The test passes if the width of the green box matches in both cases.
+<div>
+<pre style="font: bold 16px 'Monaco'; display: inline-block; background: green; tab-size: 16;">&#x9;</pre>
+</div>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt (289608 => 289609)


--- trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/LayoutTests/platform/gtk/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:40:49 UTC (rev 289609)
@@ -24,7 +24,7 @@
 PASS menclose preferred width calculation is not affected by width: 100px !important; height: 200px !important;
 PASS menclose layout is not affected by width: 100px !important; height: 200px !important;
 PASS merror preferred width calculation is not affected by writing-mode: vertical-rl;
-FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 8 +/- 1 but got 0
+FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 9 +/- 1 but got 0
 PASS merror preferred width calculation is not affected by white-space: normal;
 PASS merror layout is not affected by white-space: normal;
 PASS merror preferred width calculation is not affected by float: right;

Modified: trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt (289608 => 289609)


--- trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:40:49 UTC (rev 289609)
@@ -24,7 +24,7 @@
 PASS menclose preferred width calculation is not affected by width: 100px !important; height: 200px !important;
 PASS menclose layout is not affected by width: 100px !important; height: 200px !important;
 PASS merror preferred width calculation is not affected by writing-mode: vertical-rl;
-FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 8.03125 +/- 1 but got 0
+FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 9.03125 +/- 1 but got 0
 PASS merror preferred width calculation is not affected by white-space: normal;
 PASS merror layout is not affected by white-space: normal;
 PASS merror preferred width calculation is not affected by float: right;

Modified: trunk/LayoutTests/platform/mac/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt (289608 => 289609)


--- trunk/LayoutTests/platform/mac/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/LayoutTests/platform/mac/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:40:49 UTC (rev 289609)
@@ -24,7 +24,7 @@
 PASS menclose preferred width calculation is not affected by width: 100px !important; height: 200px !important;
 PASS menclose layout is not affected by width: 100px !important; height: 200px !important;
 PASS merror preferred width calculation is not affected by writing-mode: vertical-rl;
-FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 8.03125 +/- 1 but got 0
+FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 9.03125 +/- 1 but got 0
 PASS merror preferred width calculation is not affected by white-space: normal;
 PASS merror layout is not affected by white-space: normal;
 PASS merror preferred width calculation is not affected by float: right;

Modified: trunk/LayoutTests/platform/mac-catalina/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt (289608 => 289609)


--- trunk/LayoutTests/platform/mac-catalina/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/LayoutTests/platform/mac-catalina/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:40:49 UTC (rev 289609)
@@ -24,7 +24,7 @@
 PASS menclose preferred width calculation is not affected by width: 100px !important; height: 200px !important;
 PASS menclose layout is not affected by width: 100px !important; height: 200px !important;
 PASS merror preferred width calculation is not affected by writing-mode: vertical-rl;
-FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 8.03125 +/- 1 but got 0
+FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 9.03125 +/- 1 but got 0
 PASS merror preferred width calculation is not affected by white-space: normal;
 PASS merror layout is not affected by white-space: normal;
 PASS merror preferred width calculation is not affected by float: right;

Modified: trunk/LayoutTests/platform/mac-mojave/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt (289608 => 289609)


--- trunk/LayoutTests/platform/mac-mojave/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/LayoutTests/platform/mac-mojave/imported/w3c/web-platform-tests/mathml/relations/css-styling/ignored-properties-001-expected.txt	2022-02-11 08:40:49 UTC (rev 289609)
@@ -24,7 +24,7 @@
 PASS menclose preferred width calculation is not affected by width: 100px !important; height: 200px !important;
 PASS menclose layout is not affected by width: 100px !important; height: 200px !important;
 PASS merror preferred width calculation is not affected by writing-mode: vertical-rl;
-FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 8.03125 +/- 1 but got 0
+FAIL merror layout is not affected by writing-mode: vertical-rl; assert_approx_equals: inline position (child 1) expected 9.03125 +/- 1 but got 0
 PASS merror preferred width calculation is not affected by white-space: normal;
 PASS merror layout is not affected by white-space: normal;
 PASS merror preferred width calculation is not affected by float: right;

Modified: trunk/Source/WebCore/ChangeLog (289608 => 289609)


--- trunk/Source/WebCore/ChangeLog	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/Source/WebCore/ChangeLog	2022-02-11 08:40:49 UTC (rev 289609)
@@ -1,3 +1,45 @@
+2022-02-11  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Tab characters and ch units do not obey synthetic bold width adjustments correctly
+        https://bugs.webkit.org/show_bug.cgi?id=236172
+
+        Reviewed by Alan Bujtas.
+
+        It turns out we have a lot of places where code wants to know the synthetic-bold-expanded
+        width of characters. One place is 'tab-width: <integer>' and another is the 'ch' unit.
+        However, WidthIterator and ComplexTextController don't want the synthetic-bold-expanded
+        widths, because they explicitly apply synthetic bold after shaping.
+
+        This patch adds a 2-value enum argument to the Font::widthForGlyph() function, so callers
+        can pass in which behavior they want. The function has a default value to include the
+        synthetic bold expansion.
+
+        I then audited every call site of this function, and passed in the correct enum value.
+        Doing this led me to discover two bugs where the wrong behavior was being used, and this
+        patch fixes them and adds tests for them.
+
+        Tests: fast/text/ch-unit-synthetic-bold.html
+               fast/text/tab-width-synthetic-bold-complex.html
+               fast/text/tab-width-synthetic-bold.html
+
+        * layout/formattingContexts/inline/text/TextUtil.cpp:
+        (WebCore::Layout::fallbackFontsForRunWithIterator):
+        * platform/graphics/ComplexTextController.cpp:
+        (WebCore::ComplexTextController::adjustGlyphsAndAdvances):
+        (WebCore::ComplexTextController::ComplexTextRun::ComplexTextRun):
+        * platform/graphics/Font.cpp:
+        (WebCore::Font::platformGlyphInit):
+        * platform/graphics/Font.h:
+        (WebCore::Font::spaceWidth const):
+        (WebCore::Font::widthForGlyph const):
+        * platform/graphics/FontCascade.cpp:
+        (WebCore::FontCascade::widthForSimpleText const):
+        * platform/graphics/FontCascade.h:
+        (WebCore::FontCascade::tabWidth const):
+        * platform/graphics/WidthIterator.cpp:
+        (WebCore::WidthIterator::advanceInternal):
+        (WebCore::WidthIterator::calculateAdditionalWidth const):
+
 2022-02-11  Nikolas Zimmermann  <nzimmerm...@igalia.com>
 
         [LBSE] Begin stub implementation of transform support for SVG layers

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp (289608 => 289609)


--- trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/text/TextUtil.cpp	2022-02-11 08:40:49 UTC (rev 289609)
@@ -121,7 +121,8 @@
             auto glyphData = fontCascade.glyphDataForCharacter(character, isRTL);
             if (glyphData.glyph && glyphData.font && glyphData.font != &primaryFont) {
                 auto isNonSpacingMark = U_MASK(u_charType(character)) & U_GC_MN_MASK;
-                if (isNonSpacingMark || glyphData.font->widthForGlyph(glyphData.glyph))
+                // If we include the synthetic bold expansion, then even zero-width glyphs will have their fonts added.
+                if (isNonSpacingMark || glyphData.font->widthForGlyph(glyphData.glyph, Font::SyntheticBoldInclusion::Exclude))
                     fallbackFonts.add(glyphData.font);
             }
         };

Modified: trunk/Source/WebCore/platform/graphics/ComplexTextController.cpp (289608 => 289609)


--- trunk/Source/WebCore/platform/graphics/ComplexTextController.cpp	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/Source/WebCore/platform/graphics/ComplexTextController.cpp	2022-02-11 08:40:49 UTC (rev 289609)
@@ -693,7 +693,8 @@
         const CGGlyph* glyphs = complexTextRun.glyphs();
         const FloatSize* advances = complexTextRun.baseAdvances();
 
-        float spaceWidth = font.spaceWidth();
+        // Lower in this function, synthetic bold is blanket-applied to everything, so no need to double-apply it here.
+        float spaceWidth = font.spaceWidth(Font::SyntheticBoldInclusion::Exclude);
         const UChar* cp = complexTextRun.characters();
         FloatPoint glyphOrigin;
         unsigned lastCharacterIndex = m_run.ltr() ? std::numeric_limits<unsigned>::min() : std::numeric_limits<unsigned>::max();
@@ -714,8 +715,8 @@
             CGGlyph glyph = glyphs[i];
             FloatSize advance = treatAsSpace ? FloatSize(spaceWidth, advances[i].height()) : advances[i];
 
-            if (ch == '\t' && m_run.allowTabs())
-                advance.setWidth(m_font.tabWidth(font, m_run.tabSize(), m_run.xPos() + m_totalAdvance.width()));
+            if (ch == tabCharacter && m_run.allowTabs())
+                advance.setWidth(m_font.tabWidth(font, m_run.tabSize(), m_run.xPos() + m_totalAdvance.width(), Font::SyntheticBoldInclusion::Exclude));
             else if (FontCascade::treatAsZeroWidthSpace(ch) && !treatAsSpace) {
                 advance.setWidth(0);
                 glyph = font.spaceGlyph();
@@ -844,7 +845,8 @@
 
     // Synthesize a run of missing glyphs.
     m_glyphs.fill(0, m_glyphCount);
-    m_baseAdvances.fill(FloatSize(m_font.widthForGlyph(0), 0), m_glyphCount);
+    // Synthetic bold will be handled later in adjustGlyphsAndAdvances().
+    m_baseAdvances.fill(FloatSize(m_font.widthForGlyph(0, Font::SyntheticBoldInclusion::Exclude), 0), m_glyphCount);
 }
 
 ComplexTextController::ComplexTextRun::ComplexTextRun(const Vector<FloatSize>& advances, const Vector<FloatPoint>& origins, const Vector<Glyph>& glyphs, const Vector<unsigned>& stringIndices, FloatSize initialAdvance, const Font& font, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd, bool ltr)

Modified: trunk/Source/WebCore/platform/graphics/Font.cpp (289608 => 289609)


--- trunk/Source/WebCore/platform/graphics/Font.cpp	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/Source/WebCore/platform/graphics/Font.cpp	2022-02-11 08:40:49 UTC (rev 289609)
@@ -165,15 +165,11 @@
     } else
         m_fontMetrics.setIdeogramWidth(platformData().size());
 
-    m_spaceWidth = widthForGlyph(m_spaceGlyph);
+    m_spaceWidth = widthForGlyph(m_spaceGlyph, SyntheticBoldInclusion::Exclude); // spaceWidth() handles adding in the synthetic bold.
     auto amountToAdjustLineGap = std::min(m_fontMetrics.floatLineGap(), 0.0f);
     m_fontMetrics.setLineGap(m_fontMetrics.floatLineGap() - amountToAdjustLineGap);
     m_fontMetrics.setLineSpacing(m_fontMetrics.floatLineSpacing() - amountToAdjustLineGap);
     determinePitch();
-    // Nasty hack to determine if we should round or ceil space widths.
-    // If the font is monospace or fake monospace we ceil to ensure that
-    // every character and the space are the same width. Otherwise we round.
-    m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(m_spaceWidth) : roundf(m_spaceWidth);
 }
 
 Font::~Font()

Modified: trunk/Source/WebCore/platform/graphics/Font.h (289608 => 289609)


--- trunk/Source/WebCore/platform/graphics/Font.h	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/Source/WebCore/platform/graphics/Font.h	2022-02-11 08:40:49 UTC (rev 289609)
@@ -138,22 +138,19 @@
 
     FloatRect boundsForGlyph(Glyph) const;
 
-    // If you're calling this, you need to care about synthetic bold.
-    // This function returns the width before adding in the synthetic bold offset.
-    // This is because these widths are fed as an input to shaping, which needs to consume the true widths.
-    // Then, the synthetic bold offset is applied after shaping.
-    // If you're not going through WidthIterator or ComplexTextController (and thus potentially executing shaping yourself),
-    // then you need to decide whether or not you need to add syntheticBoldOffset() to the result of your widthForGlyph() call.
-    float widthForGlyph(Glyph) const;
+    // Should the result of this function include the results of synthetic bold?
+    enum class SyntheticBoldInclusion {
+        Incorporate,
+        Exclude
+    };
+    float widthForGlyph(Glyph, SyntheticBoldInclusion = SyntheticBoldInclusion::Incorporate) const;
 
     const Path& pathForGlyph(Glyph) const; // Don't store the result of this! The hash map is free to rehash at any point, leaving this reference dangling.
-    FloatRect platformBoundsForGlyph(Glyph) const;
-    float platformWidthForGlyph(Glyph) const;
-    Path platformPathForGlyph(Glyph) const;
 
-    // If you're calling this, you need to care about synthetic bold.
-    // See the comment just above widthForGlyph().
-    float spaceWidth() const { return m_spaceWidth; }
+    float spaceWidth(SyntheticBoldInclusion SyntheticBoldInclusion = SyntheticBoldInclusion::Incorporate) const
+    {
+        return m_spaceWidth + (SyntheticBoldInclusion == SyntheticBoldInclusion::Incorporate ? syntheticBoldOffset() : 0);
+    }
 
     float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
 
@@ -236,6 +233,10 @@
     float widthForGDIGlyph(Glyph) const;
 #endif
 
+    FloatRect platformBoundsForGlyph(Glyph) const;
+    float platformWidthForGlyph(Glyph) const;
+    Path platformPathForGlyph(Glyph) const;
+
 #if PLATFORM(COCOA)
     class ComplexColorFormatGlyphs {
     public:
@@ -324,7 +325,6 @@
     Visibility m_visibility; // @font-face's internal timer can cause us to show fonts even when a font is being downloaded.
 
     float m_spaceWidth { 0 };
-    float m_adjustedSpaceWidth { 0 };
 
     float m_syntheticBoldOffset { 0 };
 
@@ -369,7 +369,7 @@
     return bounds;
 }
 
-ALWAYS_INLINE float Font::widthForGlyph(Glyph glyph) const
+ALWAYS_INLINE float Font::widthForGlyph(Glyph glyph, SyntheticBoldInclusion SyntheticBoldInclusion) const
 {
     // The optimization of returning 0 for the zero-width-space glyph is incorrect for the LastResort font,
     // used in place of the actual font when isLoading() is true on both macOS and iOS.
@@ -380,7 +380,7 @@
 
     float width = m_glyphToWidthMap.metricsForGlyph(glyph);
     if (width != cGlyphSizeUnknown)
-        return width;
+        return width + (SyntheticBoldInclusion == SyntheticBoldInclusion::Incorporate ? syntheticBoldOffset() : 0);
 
 #if ENABLE(OPENTYPE_VERTICAL)
     if (m_verticalData)
@@ -390,7 +390,7 @@
         width = platformWidthForGlyph(glyph);
 
     m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
-    return width;
+    return width + (SyntheticBoldInclusion == SyntheticBoldInclusion::Incorporate ? syntheticBoldOffset() : 0);
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/FontCascade.cpp (289608 => 289609)


--- trunk/Source/WebCore/platform/graphics/FontCascade.cpp	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.cpp	2022-02-11 08:40:49 UTC (rev 289609)
@@ -316,6 +316,7 @@
     auto& font = primaryFont();
     for (unsigned i = 0; i < text.length(); ++i) {
         auto glyph = glyphDataForCharacter(text[i], false).glyph;
+        ASSERT(!font.syntheticBoldOffset()); // This function should only be called when RenderText::computeCanUseSimplifiedTextMeasuring() returns true, and that function requires no synthetic bold.
         auto glyphWidth = font.widthForGlyph(glyph);
         beforeWidth += glyphWidth;
         glyphBuffer.add(glyph, font, glyphWidth, i);

Modified: trunk/Source/WebCore/platform/graphics/FontCascade.h (289608 => 289609)


--- trunk/Source/WebCore/platform/graphics/FontCascade.h	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.h	2022-02-11 08:40:49 UTC (rev 289609)
@@ -168,8 +168,7 @@
     bool isPlatformFont() const { return m_fonts->isForPlatformFont(); }
 
     const FontMetrics& metricsOfPrimaryFont() const { return primaryFont().fontMetrics(); }
-    float tabWidth(const Font&, const TabSize&, float) const;
-    float tabWidth(const TabSize& tabSize, float position) const { return tabWidth(primaryFont(), tabSize, position); }
+    float tabWidth(const Font&, const TabSize&, float, Font::SyntheticBoldInclusion) const;
     bool hasValidAverageCharWidth() const;
     bool fastAverageCharWidthIfAvailable(float &width) const; // returns true on success
 
@@ -373,13 +372,20 @@
     return m_fonts ? m_fonts->fontSelector() : nullptr;
 }
 
-inline float FontCascade::tabWidth(const Font& font, const TabSize& tabSize, float position) const
+inline float FontCascade::tabWidth(const Font& font, const TabSize& tabSize, float position, Font::SyntheticBoldInclusion syntheticBoldInclusion) const
 {
     float baseTabWidth = tabSize.widthInPixels(font.spaceWidth());
+    float result = 0;
     if (!baseTabWidth)
-        return letterSpacing();
-    float tabDeltaWidth = baseTabWidth - fmodf(position, baseTabWidth);
-    return (tabDeltaWidth < font.spaceWidth() / 2) ? baseTabWidth : tabDeltaWidth;
+        result = letterSpacing();
+    else {
+        float tabDeltaWidth = baseTabWidth - fmodf(position, baseTabWidth);
+        result = (tabDeltaWidth < font.spaceWidth() / 2) ? baseTabWidth : tabDeltaWidth;
+    }
+    // If our caller passes in SyntheticBoldInclusion::Exclude, that means they're going to apply synthetic bold themselves later.
+    // However, regardless of that, the space characters that are fed into the width calculation need to have their correct width, including the synthetic bold.
+    // So, we've already got synthetic bold applied, so if we're supposed to exclude it, we need to subtract it out here.
+    return result - (syntheticBoldInclusion == Font::SyntheticBoldInclusion::Exclude ? font.syntheticBoldOffset() : 0);
 }
 
 }

Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.cpp (289608 => 289609)


--- trunk/Source/WebCore/platform/graphics/WidthIterator.cpp	2022-02-11 08:32:35 UTC (rev 289608)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.cpp	2022-02-11 08:40:49 UTC (rev 289609)
@@ -306,7 +306,7 @@
         const Font& font = glyphData.font ? *glyphData.font : primaryFont;
 
         previousWidth = width;
-        width = font.widthForGlyph(glyph);
+        width = font.widthForGlyph(glyph, Font::SyntheticBoldInclusion::Exclude); // We apply synthetic bold after shaping, in applyCSSVisibilityRules().
 
         if (&font != lastFontData)
             commitCurrentFontRange(glyphBuffer, lastGlyphCount, currentCharacterIndex, lastFontData, font, primaryFont, character, widthOfCurrentFontRange, width, charactersTreatedAsSpace);
@@ -314,7 +314,7 @@
             widthOfCurrentFontRange += width;
 
         if (FontCascade::treatAsSpace(character))
-            charactersTreatedAsSpace.constructAndAppend(currentCharacterIndex, character == space, previousWidth, character == tabCharacter ? width : font.spaceWidth());
+            charactersTreatedAsSpace.constructAndAppend(currentCharacterIndex, character == space, previousWidth, character == tabCharacter ? width : font.spaceWidth(Font::SyntheticBoldInclusion::Exclude));
 
         if (m_accountForGlyphBounds) {
             bounds = font.boundsForGlyph(glyph);
@@ -354,7 +354,8 @@
 
     if (character == tabCharacter && m_run.allowTabs()) {
         auto& font = glyphBuffer.fontAt(trailingGlyphIndex);
-        auto newWidth = m_font.tabWidth(font, m_run.tabSize(), position);
+        // Synthetic bold will be handled in applyCSSVisibilityRules() later.
+        auto newWidth = m_font.tabWidth(font, m_run.tabSize(), position, Font::SyntheticBoldInclusion::Exclude);
         auto currentWidth = width(glyphBuffer.advanceAt(trailingGlyphIndex));
         rightAdditionalWidth += newWidth - currentWidth;
     }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to