- a/Source/WebCore/ChangeLog +43 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2020-08-09  Myles C. Maxfield  <mmaxfield@apple.com>
2
3
        Stop calculating FontCascade::m_requiresShaping unnecessarily
4
        https://bugs.webkit.org/show_bug.cgi?id=215313
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        Ever since r265413, we always perform _some_ shaping.
9
        Therefore, FontCascade::m_requiresShaping should always be true.
10
        So, there's no reason to compute it, then; we can just assume it will just be true.
11
12
        No new tests because there is no behavior change.
13
14
        * layout/inlineformatting/text/TextUtil.cpp:
15
        (WebCore::Layout::TextUtil::width):
16
        * platform/graphics/Font.cpp:
17
        (WebCore::Font::applyTransforms const):
18
        * platform/graphics/Font.h:
19
        * platform/graphics/FontCascade.cpp:
20
        (WebCore::FontCascade::FontCascade):
21
        (WebCore::FontCascade::operator=):
22
        (WebCore::FontCascade::update const):
23
        (WebCore::FontCascade::displayListForTextRun const):
24
        (WebCore::FontCascade::width const):
25
        (WebCore::FontCascade::widthForSimpleText const):
26
        (WebCore::FontCascade::codePath const):
27
        * platform/graphics/FontCascade.h:
28
        (WebCore::FontCascade::enableKerning const):
29
        (WebCore::FontCascade::requiresShaping const): Deleted.
30
        (WebCore::FontCascade::computeRequiresShaping const): Deleted.
31
        * platform/graphics/WidthCache.h:
32
        (WebCore::WidthCache::add):
33
        * platform/graphics/WidthIterator.cpp:
34
        (WebCore::WidthIterator::WidthIterator):
35
        (WebCore::WidthIterator::applyFontTransforms):
36
        * platform/graphics/WidthIterator.h:
37
        * platform/graphics/cocoa/FontCocoa.mm:
38
        (WebCore::Font::applyTransforms const):
39
        * rendering/SimpleLineLayoutTextFragmentIterator.cpp:
40
        (WebCore::SimpleLineLayout::TextFragmentIterator::Style::Style):
41
        (WebCore::SimpleLineLayout::TextFragmentIterator::textWidth const):
42
        * rendering/SimpleLineLayoutTextFragmentIterator.h:
43
1
2020-08-08  Myles C. Maxfield  <mmaxfield@apple.com>
44
2020-08-08  Myles C. Maxfield  <mmaxfield@apple.com>
2
45
3
        Update OriginalAdvancesForCharacterTreatedAsSpace to work correctly in the presence of inserted or removed glyphs
46
        Update OriginalAdvancesForCharacterTreatedAsSpace to work correctly in the presence of inserted or removed glyphs
- a/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp -2 / +1 lines
Lines 57-64 InlineLayoutUnit TextUtil::width(const InlineTextBox& inlineTextBox, unsigned fr a/Source/WebCore/layout/inlineformatting/text/TextUtil.cpp_sec1
57
57
58
    auto text = inlineTextBox.content();
58
    auto text = inlineTextBox.content();
59
    ASSERT(to <= text.length());
59
    ASSERT(to <= text.length());
60
    auto hasKerningOrLigatures = font.enableKerning() || font.requiresShaping();
60
    auto measureWithEndSpace = to < text.length() && text[to] == ' ';
61
    auto measureWithEndSpace = hasKerningOrLigatures && to < text.length() && text[to] == ' ';
62
    if (measureWithEndSpace)
61
    if (measureWithEndSpace)
63
        ++to;
62
        ++to;
64
    float width = 0;
63
    float width = 0;
- a/Source/WebCore/platform/graphics/Font.cpp -1 / +1 lines
Lines 512-518 RefPtr<Font> Font::createScaledFont(const FontDescription& fontDescription, floa a/Source/WebCore/platform/graphics/Font.cpp_sec1
512
}
512
}
513
513
514
#if !PLATFORM(COCOA)
514
#if !PLATFORM(COCOA)
515
void Font::applyTransforms(GlyphBuffer&, unsigned, bool, bool, const AtomString&) const
515
void Font::applyTransforms(GlyphBuffer&, unsigned, bool, const AtomString&) const
516
{
516
{
517
}
517
}
518
#endif
518
#endif
- a/Source/WebCore/platform/graphics/Font.h -1 / +1 lines
Lines 207-213 public: a/Source/WebCore/platform/graphics/Font.h_sec1
207
#endif
207
#endif
208
208
209
    bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
209
    bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
210
    void applyTransforms(GlyphBuffer&, unsigned beginningIndex, bool enableKerning, bool requiresShaping, const AtomString& locale) const;
210
    void applyTransforms(GlyphBuffer&, unsigned beginningIndex, bool enableKerning, const AtomString& locale) const;
211
211
212
#if PLATFORM(WIN)
212
#if PLATFORM(WIN)
213
    SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
213
    SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
- a/Source/WebCore/platform/graphics/FontCascade.cpp -10 / +5 lines
Lines 83-89 FontCascade::FontCascade(FontCascadeDescription&& fd, float letterSpacing, float a/Source/WebCore/platform/graphics/FontCascade.cpp_sec1
83
    , m_wordSpacing(wordSpacing)
83
    , m_wordSpacing(wordSpacing)
84
    , m_useBackslashAsYenSymbol(useBackslashAsYenSignForFamily(m_fontDescription.firstFamily()))
84
    , m_useBackslashAsYenSymbol(useBackslashAsYenSignForFamily(m_fontDescription.firstFamily()))
85
    , m_enableKerning(computeEnableKerning())
85
    , m_enableKerning(computeEnableKerning())
86
    , m_requiresShaping(computeRequiresShaping())
87
{
86
{
88
}
87
}
89
88
Lines 91-97 FontCascade::FontCascade(FontCascadeDescription&& fd, float letterSpacing, float a/Source/WebCore/platform/graphics/FontCascade.cpp_sec2
91
FontCascade::FontCascade(const FontPlatformData& fontData, FontSmoothingMode fontSmoothingMode)
90
FontCascade::FontCascade(const FontPlatformData& fontData, FontSmoothingMode fontSmoothingMode)
92
    : m_fonts(FontCascadeFonts::createForPlatformFont(fontData))
91
    : m_fonts(FontCascadeFonts::createForPlatformFont(fontData))
93
    , m_enableKerning(computeEnableKerning())
92
    , m_enableKerning(computeEnableKerning())
94
    , m_requiresShaping(computeRequiresShaping())
95
{
93
{
96
    m_fontDescription.setFontSmoothing(fontSmoothingMode);
94
    m_fontDescription.setFontSmoothing(fontSmoothingMode);
97
#if PLATFORM(IOS_FAMILY)
95
#if PLATFORM(IOS_FAMILY)
Lines 109-115 FontCascade::FontCascade(const FontCascade& other) a/Source/WebCore/platform/graphics/FontCascade.cpp_sec3
109
    , m_wordSpacing(other.m_wordSpacing)
107
    , m_wordSpacing(other.m_wordSpacing)
110
    , m_useBackslashAsYenSymbol(other.m_useBackslashAsYenSymbol)
108
    , m_useBackslashAsYenSymbol(other.m_useBackslashAsYenSymbol)
111
    , m_enableKerning(computeEnableKerning())
109
    , m_enableKerning(computeEnableKerning())
112
    , m_requiresShaping(computeRequiresShaping())
113
{
110
{
114
}
111
}
115
112
Lines 121-127 FontCascade& FontCascade::operator=(const FontCascade& other) a/Source/WebCore/platform/graphics/FontCascade.cpp_sec4
121
    m_wordSpacing = other.m_wordSpacing;
118
    m_wordSpacing = other.m_wordSpacing;
122
    m_useBackslashAsYenSymbol = other.m_useBackslashAsYenSymbol;
119
    m_useBackslashAsYenSymbol = other.m_useBackslashAsYenSymbol;
123
    m_enableKerning = other.m_enableKerning;
120
    m_enableKerning = other.m_enableKerning;
124
    m_requiresShaping = other.m_requiresShaping;
125
    return *this;
121
    return *this;
126
}
122
}
127
123
Lines 282-288 void FontCascade::update(RefPtr<FontSelector>&& fontSelector) const a/Source/WebCore/platform/graphics/FontCascade.cpp_sec5
282
    m_fonts = retrieveOrAddCachedFonts(m_fontDescription, WTFMove(fontSelector));
278
    m_fonts = retrieveOrAddCachedFonts(m_fontDescription, WTFMove(fontSelector));
283
    m_useBackslashAsYenSymbol = useBackslashAsYenSignForFamily(firstFamily());
279
    m_useBackslashAsYenSymbol = useBackslashAsYenSignForFamily(firstFamily());
284
    m_enableKerning = computeEnableKerning();
280
    m_enableKerning = computeEnableKerning();
285
    m_requiresShaping = computeRequiresShaping();
286
}
281
}
287
282
288
GlyphBuffer FontCascade::layoutText(CodePath codePathToUse, const TextRun& run, unsigned from, unsigned to, ForTextEmphasisOrNot forTextEmphasis) const
283
GlyphBuffer FontCascade::layoutText(CodePath codePathToUse, const TextRun& run, unsigned from, unsigned to, ForTextEmphasisOrNot forTextEmphasis) const
Lines 331-337 std::unique_ptr<DisplayList::DisplayList> FontCascade::displayListForTextRun(Gra a/Source/WebCore/platform/graphics/FontCascade.cpp_sec6
331
    
326
    
332
    // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
327
    // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
333
    CodePath codePathToUse = codePath(run);
328
    CodePath codePathToUse = codePath(run);
334
    if (codePathToUse != Complex && (enableKerning() || requiresShaping()) && (from || destination != run.length()))
329
    if (codePathToUse != Complex && (from || destination != run.length()))
335
        codePathToUse = Complex;
330
        codePathToUse = Complex;
336
331
337
    auto glyphBuffer = layoutText(codePathToUse, run, from, destination);
332
    auto glyphBuffer = layoutText(codePathToUse, run, from, destination);
Lines 407-413 float FontCascade::width(const TextRun& run, HashSet<const Font*>* fallbackFonts a/Source/WebCore/platform/graphics/FontCascade.cpp_sec7
407
    }
402
    }
408
403
409
    bool hasWordSpacingOrLetterSpacing = wordSpacing() || letterSpacing();
404
    bool hasWordSpacingOrLetterSpacing = wordSpacing() || letterSpacing();
410
    float* cacheEntry = m_fonts->widthCache().add(run, std::numeric_limits<float>::quiet_NaN(), enableKerning() || requiresShaping(), hasWordSpacingOrLetterSpacing, glyphOverflow);
405
    float* cacheEntry = m_fonts->widthCache().add(run, std::numeric_limits<float>::quiet_NaN(), hasWordSpacingOrLetterSpacing, glyphOverflow);
411
    if (cacheEntry && !std::isnan(*cacheEntry))
406
    if (cacheEntry && !std::isnan(*cacheEntry))
412
        return *cacheEntry;
407
        return *cacheEntry;
413
408
Lines 445-451 float FontCascade::widthForSimpleText(StringView text) const a/Source/WebCore/platform/graphics/FontCascade.cpp_sec8
445
        glyphBuffer.add(glyph, font, glyphWidth, i);
440
        glyphBuffer.add(glyph, font, glyphWidth, i);
446
    }
441
    }
447
442
448
    font.applyTransforms(glyphBuffer, 0, enableKerning(), requiresShaping(), fontDescription().computedLocale());
443
    font.applyTransforms(glyphBuffer, 0, enableKerning(), fontDescription().computedLocale());
449
    // This is needed only to match the result of the slow path.
444
    // This is needed only to match the result of the slow path.
450
    // Same glyph widths but different floating point arithmetic can produce different run width.
445
    // Same glyph widths but different floating point arithmetic can produce different run width.
451
    float runWidthDifferenceWithTransformApplied = -runWidth;
446
    float runWidthDifferenceWithTransformApplied = -runWidth;
Lines 618-624 FontCascade::CodePath FontCascade::codePath(const TextRun& run, Optional<unsigne a/Source/WebCore/platform/graphics/FontCascade.cpp_sec9
618
613
619
#if !USE(FREETYPE)
614
#if !USE(FREETYPE)
620
    // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
615
    // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
621
    if ((enableKerning() || requiresShaping()) && (from.valueOr(0) || to.valueOr(run.length()) != run.length()))
616
    if (from.valueOr(0) || to.valueOr(run.length()) != run.length())
622
        return Complex;
617
        return Complex;
623
#else
618
#else
624
    UNUSED_PARAM(from);
619
    UNUSED_PARAM(from);
Lines 633-639 FontCascade::CodePath FontCascade::codePath(const TextRun& run, Optional<unsigne a/Source/WebCore/platform/graphics/FontCascade.cpp_sec10
633
628
634
#else
629
#else
635
630
636
    if (run.length() > 1 && (enableKerning() || requiresShaping()))
631
    if (run.length() > 1)
637
        return Complex;
632
        return Complex;
638
#endif
633
#endif
639
634
- a/Source/WebCore/platform/graphics/FontCascade.h -13 lines
Lines 135-141 public: a/Source/WebCore/platform/graphics/FontCascade.h_sec1
135
    FontRenderingMode renderingMode() const { return m_fontDescription.renderingMode(); }
135
    FontRenderingMode renderingMode() const { return m_fontDescription.renderingMode(); }
136
136
137
    bool enableKerning() const { return m_enableKerning; }
137
    bool enableKerning() const { return m_enableKerning; }
138
    bool requiresShaping() const { return m_requiresShaping; }
139
138
140
    const AtomString& firstFamily() const { return m_fontDescription.firstFamily(); }
139
    const AtomString& firstFamily() const { return m_fontDescription.firstFamily(); }
141
    unsigned familyCount() const { return m_fontDescription.familyCount(); }
140
    unsigned familyCount() const { return m_fontDescription.familyCount(); }
Lines 291-307 private: a/Source/WebCore/platform/graphics/FontCascade.h_sec2
291
        return advancedTextRenderingMode();
290
        return advancedTextRenderingMode();
292
    }
291
    }
293
292
294
    bool computeRequiresShaping() const
295
    {
296
#if PLATFORM(COCOA) || USE(FREETYPE)
297
        if (!m_fontDescription.variantSettings().isAllNormal())
298
            return true;
299
        if (m_fontDescription.featureSettings().size())
300
            return true;
301
#endif
302
        return advancedTextRenderingMode();
303
    }
304
305
    static int syntheticObliqueAngle() { return 14; }
293
    static int syntheticObliqueAngle() { return 14; }
306
294
307
#if PLATFORM(WIN) && USE(CG)
295
#if PLATFORM(WIN) && USE(CG)
Lines 319-325 private: a/Source/WebCore/platform/graphics/FontCascade.h_sec3
319
    float m_wordSpacing { 0 };
307
    float m_wordSpacing { 0 };
320
    mutable bool m_useBackslashAsYenSymbol { false };
308
    mutable bool m_useBackslashAsYenSymbol { false };
321
    mutable bool m_enableKerning { false }; // Computed from m_fontDescription.
309
    mutable bool m_enableKerning { false }; // Computed from m_fontDescription.
322
    mutable bool m_requiresShaping { false }; // Computed from m_fontDescription.
323
};
310
};
324
311
325
void invalidateFontCascadeCache();
312
void invalidateFontCascadeCache();
- a/Source/WebCore/platform/graphics/WidthCache.h -4 / +1 lines
Lines 133-145 public: a/Source/WebCore/platform/graphics/WidthCache.h_sec1
133
        return addSlowCase(text, entry);
133
        return addSlowCase(text, entry);
134
    }
134
    }
135
135
136
    float* add(const TextRun& run, float entry, bool hasKerningOrLigatures, bool hasWordSpacingOrLetterSpacing, GlyphOverflow* glyphOverflow)
136
    float* add(const TextRun& run, float entry, bool hasWordSpacingOrLetterSpacing, GlyphOverflow* glyphOverflow)
137
    {
137
    {
138
        if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
138
        if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
139
            return nullptr;
139
            return nullptr;
140
        // The width cache is not really profitable unless we're doing expensive glyph transformations.
141
        if (!hasKerningOrLigatures)
142
            return nullptr;
143
        // Word spacing and letter spacing can change the width of a word.
140
        // Word spacing and letter spacing can change the width of a word.
144
        if (hasWordSpacingOrLetterSpacing)
141
        if (hasWordSpacingOrLetterSpacing)
145
            return nullptr;
142
            return nullptr;
- a/Source/WebCore/platform/graphics/WidthIterator.cpp -2 / +1 lines
Lines 43-49 WidthIterator::WidthIterator(const FontCascade& font, const TextRun& run, HashSe a/Source/WebCore/platform/graphics/WidthIterator.cpp_sec1
43
    , m_isAfterExpansion((run.expansionBehavior() & LeftExpansionMask) == ForbidLeftExpansion)
43
    , m_isAfterExpansion((run.expansionBehavior() & LeftExpansionMask) == ForbidLeftExpansion)
44
    , m_accountForGlyphBounds(accountForGlyphBounds)
44
    , m_accountForGlyphBounds(accountForGlyphBounds)
45
    , m_enableKerning(font.enableKerning())
45
    , m_enableKerning(font.enableKerning())
46
    , m_requiresShaping(font.requiresShaping())
47
    , m_forTextEmphasis(forTextEmphasis)
46
    , m_forTextEmphasis(forTextEmphasis)
48
{
47
{
49
    if (!m_expansion)
48
    if (!m_expansion)
Lines 106-112 inline float WidthIterator::applyFontTransforms(GlyphBuffer& glyphBuffer, bool l a/Source/WebCore/platform/graphics/WidthIterator.cpp_sec2
106
    if (!ltr)
105
    if (!ltr)
107
        glyphBuffer.reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount);
106
        glyphBuffer.reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount);
108
107
109
    font.applyTransforms(glyphBuffer, lastGlyphCount, m_enableKerning, m_requiresShaping, m_font.fontDescription().computedLocale());
108
    font.applyTransforms(glyphBuffer, lastGlyphCount, m_enableKerning, m_font.fontDescription().computedLocale());
110
    glyphBufferSize = glyphBuffer.size();
109
    glyphBufferSize = glyphBuffer.size();
111
110
112
    for (unsigned i = lastGlyphCount; i < glyphBufferSize; ++i)
111
    for (unsigned i = lastGlyphCount; i < glyphBufferSize; ++i)
- a/Source/WebCore/platform/graphics/WidthIterator.h -1 lines
Lines 78-84 private: a/Source/WebCore/platform/graphics/WidthIterator.h_sec1
78
    bool m_isAfterExpansion { false };
78
    bool m_isAfterExpansion { false };
79
    bool m_accountForGlyphBounds { false };
79
    bool m_accountForGlyphBounds { false };
80
    bool m_enableKerning { false };
80
    bool m_enableKerning { false };
81
    bool m_requiresShaping { false };
82
    bool m_forTextEmphasis { false };
81
    bool m_forTextEmphasis { false };
83
};
82
};
84
83
- a/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm -2 / +1 lines
Lines 544-553 RefPtr<Font> Font::platformCreateScaledFont(const FontDescription&, float scaleF a/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm_sec1
544
    return createDerivativeFont(scaledFont.get(), size, m_platformData.orientation(), fontTraits, m_platformData.syntheticBold(), m_platformData.syntheticOblique());
544
    return createDerivativeFont(scaledFont.get(), size, m_platformData.orientation(), fontTraits, m_platformData.syntheticBold(), m_platformData.syntheticOblique());
545
}
545
}
546
546
547
void Font::applyTransforms(GlyphBuffer& glyphBuffer, unsigned beginningIndex, bool enableKerning, bool requiresShaping, const AtomString& locale) const
547
void Font::applyTransforms(GlyphBuffer& glyphBuffer, unsigned beginningIndex, bool enableKerning, const AtomString& locale) const
548
{
548
{
549
    // FIXME: Implement GlyphBuffer initial advance.
549
    // FIXME: Implement GlyphBuffer initial advance.
550
    UNUSED_PARAM(requiresShaping);
551
    CTFontTransformOptions options = (enableKerning ? kCTFontTransformApplyPositioning : 0) | kCTFontTransformApplyShaping;
550
    CTFontTransformOptions options = (enableKerning ? kCTFontTransformApplyPositioning : 0) | kCTFontTransformApplyShaping;
552
#if USE(CTFONTTRANSFORMGLYPHSWITHLANGUAGE)
551
#if USE(CTFONTTRANSFORMGLYPHSWITHLANGUAGE)
553
    auto handler = ^(CFRange range, CGGlyph** newGlyphsPointer, CGSize** newAdvancesPointer) {
552
    auto handler = ^(CFRange range, CGGlyph** newGlyphsPointer, CGSize** newAdvancesPointer) {
- a/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp -2 / +1 lines
Lines 38-44 namespace SimpleLineLayout { a/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp_sec1
38
TextFragmentIterator::Style::Style(const RenderStyle& style)
38
TextFragmentIterator::Style::Style(const RenderStyle& style)
39
    : font(style.fontCascade())
39
    : font(style.fontCascade())
40
    , textAlign(style.textAlign())
40
    , textAlign(style.textAlign())
41
    , hasKerningOrLigatures(font.enableKerning() || font.requiresShaping())
42
    , collapseWhitespace(style.collapseWhiteSpace())
41
    , collapseWhitespace(style.collapseWhiteSpace())
43
    , preserveNewline(style.preserveNewline())
42
    , preserveNewline(style.preserveNewline())
44
    , wrapLines(style.autoWrap())
43
    , wrapLines(style.autoWrap())
Lines 247-253 float TextFragmentIterator::textWidth(unsigned from, unsigned to, float xPositio a/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.cpp_sec2
247
    if (m_style.font.isFixedPitch())
246
    if (m_style.font.isFixedPitch())
248
        return downcast<RenderText>(segment.renderer).width(segmentFrom, segmentTo - segmentFrom, m_style.font, xPosition, nullptr, nullptr);
247
        return downcast<RenderText>(segment.renderer).width(segmentFrom, segmentTo - segmentFrom, m_style.font, xPosition, nullptr, nullptr);
249
248
250
    bool measureWithEndSpace = m_style.hasKerningOrLigatures && m_style.collapseWhitespace
249
    bool measureWithEndSpace = m_style.collapseWhitespace
251
        && segmentTo < segment.text.length() && segment.text[segmentTo] == ' ';
250
        && segmentTo < segment.text.length() && segment.text[segmentTo] == ' ';
252
    if (measureWithEndSpace)
251
    if (measureWithEndSpace)
253
        ++segmentTo;
252
        ++segmentTo;
- a/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h -1 lines
Lines 107-113 public: a/Source/WebCore/rendering/SimpleLineLayoutTextFragmentIterator.h_sec1
107
107
108
        const FontCascade& font;
108
        const FontCascade& font;
109
        TextAlignMode textAlign;
109
        TextAlignMode textAlign;
110
        bool hasKerningOrLigatures;
111
        bool collapseWhitespace;
110
        bool collapseWhitespace;
112
        bool preserveNewline;
111
        bool preserveNewline;
113
        bool wrapLines;
112
        bool wrapLines;

Return to Bug 215313