| Differences between
and this patch
- a/Source/WebCore/ChangeLog +27 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2016-08-23  Myles C. Maxfield  <mmaxfield@apple.com>
2
3
        [Cocoa] Improve performance of glyph advance metrics gathering
4
        https://bugs.webkit.org/show_bug.cgi?id=161119
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        No new tests (OOPS!).
9
10
        * platform/graphics/Font.cpp:
11
        (WebCore::Font::platformGlyphInit):
12
        * platform/graphics/Font.h:
13
        (WebCore::Font::widthForGlyph):
14
        * platform/graphics/GlyphPage.h:
15
        (WebCore::GlyphData::GlyphData):
16
        (WebCore::GlyphPage::advanceForCharacter):
17
        (WebCore::GlyphPage::glyphDataForIndex):
18
        (WebCore::GlyphPage::advanceForIndex):
19
        (WebCore::GlyphPage::setGlyphForIndex):
20
        * platform/graphics/WidthIterator.cpp:
21
        (WebCore::WidthIterator::advanceInternal):
22
        * platform/graphics/cocoa/FontCocoa.mm:
23
        (WebCore::Font::platformWidthForGlyph):
24
        * platform/graphics/mac/GlyphPageMac.cpp:
25
        (WebCore::GlyphPage::fill):
26
        * platform/spi/cocoa/CoreTextSPI.h:
27
1
2016-08-23  Alex Christensen  <achristensen@webkit.org>
28
2016-08-23  Alex Christensen  <achristensen@webkit.org>
2
29
3
        Fix clean Windows build.
30
        Fix clean Windows build.
- a/Source/WebCore/platform/graphics/Font.cpp -1 / +1 lines
Lines 114-120 void Font::platformGlyphInit() a/Source/WebCore/platform/graphics/Font.cpp_sec1
114
    // Nasty hack to determine if we should round or ceil space widths.
114
    // Nasty hack to determine if we should round or ceil space widths.
115
    // If the font is monospace or fake monospace we ceil to ensure that 
115
    // If the font is monospace or fake monospace we ceil to ensure that 
116
    // every character and the space are the same width. Otherwise we round.
116
    // every character and the space are the same width. Otherwise we round.
117
    m_spaceGlyph = glyphPageZero->glyphDataForCharacter(' ').glyph;
117
    m_spaceGlyph = glyphPageZero->glyphDataForCharacter(space).glyph;
118
    float width = widthForGlyph(m_spaceGlyph);
118
    float width = widthForGlyph(m_spaceGlyph);
119
    m_spaceWidth = width;
119
    m_spaceWidth = width;
120
    m_zeroGlyph = glyphPageZero->glyphDataForCharacter('0').glyph;
120
    m_zeroGlyph = glyphPageZero->glyphDataForCharacter('0').glyph;
- a/Source/WebCore/platform/graphics/Font.h -2 / +2 lines
Lines 337-349 ALWAYS_INLINE float Font::widthForGlyph(Glyph glyph) const a/Source/WebCore/platform/graphics/Font.h_sec1
337
        return width;
337
        return width;
338
338
339
#if ENABLE(OPENTYPE_VERTICAL)
339
#if ENABLE(OPENTYPE_VERTICAL)
340
    if (m_verticalData)
340
    if (m_verticalData) {
341
#if USE(CG) || USE(CAIRO)
341
#if USE(CG) || USE(CAIRO)
342
        width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset;
342
        width = m_verticalData->advanceHeight(this, glyph) + m_syntheticBoldOffset;
343
#else
343
#else
344
        width = m_verticalData->advanceHeight(this, glyph);
344
        width = m_verticalData->advanceHeight(this, glyph);
345
#endif
345
#endif
346
    else
346
    } else
347
#endif
347
#endif
348
        width = platformWidthForGlyph(glyph);
348
        width = platformWidthForGlyph(glyph);
349
349
- a/Source/WebCore/platform/graphics/GlyphPage.h -7 / +28 lines
Lines 43-51 class Font; a/Source/WebCore/platform/graphics/GlyphPage.h_sec1
43
// Holds the glyph index and the corresponding Font information for a given
43
// Holds the glyph index and the corresponding Font information for a given
44
// character.
44
// character.
45
struct GlyphData {
45
struct GlyphData {
46
    GlyphData(Glyph g = 0, const Font* f = 0)
46
    GlyphData(Glyph g = 0, const Font* f = nullptr, Optional<float> advance = Nullopt)
47
        : glyph(g)
47
        : glyph(g)
48
        , font(f)
48
        , font(f)
49
        , advance(advance)
49
    {
50
    {
50
    }
51
    }
51
52
Lines 53-58 struct GlyphData { a/Source/WebCore/platform/graphics/GlyphPage.h_sec2
53
54
54
    Glyph glyph;
55
    Glyph glyph;
55
    const Font* font;
56
    const Font* font;
57
    Optional<float> advance;
56
};
58
};
57
59
58
// A GlyphPage contains a fixed-size set of GlyphData mappings for a contiguous
60
// A GlyphPage contains a fixed-size set of GlyphData mappings for a contiguous
Lines 72-78 public: a/Source/WebCore/platform/graphics/GlyphPage.h_sec3
72
74
73
    static unsigned count() { return s_count; }
75
    static unsigned count() { return s_count; }
74
76
75
    static const size_t size = 256; // Covers Latin-1 in a single page.
77
    static constexpr size_t size = 256; // Covers Latin-1 in a single page.
76
    static unsigned indexForCharacter(UChar32 c) { return c % GlyphPage::size; }
78
    static unsigned indexForCharacter(UChar32 c) { return c % GlyphPage::size; }
77
79
78
    GlyphData glyphDataForCharacter(UChar32 c) const
80
    GlyphData glyphDataForCharacter(UChar32 c) const
Lines 85-94 public: a/Source/WebCore/platform/graphics/GlyphPage.h_sec4
85
        return glyphForIndex(indexForCharacter(c));
87
        return glyphForIndex(indexForCharacter(c));
86
    }
88
    }
87
89
90
    Optional<float> advanceForCharacter(UChar32 c) const
91
    {
92
        return advanceForIndex(indexForCharacter(c));
93
    }
94
88
    GlyphData glyphDataForIndex(unsigned index) const
95
    GlyphData glyphDataForIndex(unsigned index) const
89
    {
96
    {
90
        Glyph glyph = glyphForIndex(index);
97
        Glyph glyph = glyphForIndex(index);
91
        return GlyphData(glyph, glyph ? &m_font : nullptr);
98
        return GlyphData(glyph, glyph ? &m_font : nullptr, advanceForIndex(index));
92
    }
99
    }
93
100
94
    Glyph glyphForIndex(unsigned index) const
101
    Glyph glyphForIndex(unsigned index) const
Lines 97-107 public: a/Source/WebCore/platform/graphics/GlyphPage.h_sec5
97
        return m_glyphs[index];
104
        return m_glyphs[index];
98
    }
105
    }
99
106
100
    // FIXME: Pages are immutable after initialization. This should be private.
107
    Optional<float> advanceForIndex(unsigned index) const
101
    void setGlyphForIndex(unsigned index, Glyph glyph)
102
    {
108
    {
103
        ASSERT_WITH_SECURITY_IMPLICATION(index < size);
109
        ASSERT_WITH_SECURITY_IMPLICATION(index < size);
104
        m_glyphs[index] = glyph;
110
        if (m_advances.isEmpty())
111
            return Nullopt;
112
        return m_advances[index];
105
    }
113
    }
106
114
107
    const Font& font() const
115
    const Font& font() const
Lines 119-126 private: a/Source/WebCore/platform/graphics/GlyphPage.h_sec6
119
        ++s_count;
127
        ++s_count;
120
    }
128
    }
121
129
130
    // FIXME: Pages are immutable after initialization. This should be private.
131
    void setGlyphForIndex(unsigned index, Glyph glyph, Optional<float> advance = Nullopt)
132
    {
133
        ASSERT_WITH_SECURITY_IMPLICATION(index < size);
134
        m_glyphs[index] = glyph;
135
        if (advance) {
136
            if (m_advances.isEmpty())
137
                m_advances.fill(0, size);
138
            m_advances[index] = advance.value();
139
        }
140
    }
141
122
    const Font& m_font;
142
    const Font& m_font;
123
    Glyph m_glyphs[size] { };
143
    std::array<Glyph, size> m_glyphs { };
144
    Vector<float> m_advances;
124
145
125
    WEBCORE_EXPORT static unsigned s_count;
146
    WEBCORE_EXPORT static unsigned s_count;
126
};
147
};
- a/Source/WebCore/platform/graphics/WidthIterator.cpp -1 / +3 lines
Lines 207-213 inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph a/Source/WebCore/platform/graphics/WidthIterator.cpp_sec1
207
        if (character == '\t' && m_run.allowTabs())
207
        if (character == '\t' && m_run.allowTabs())
208
            width = m_font->tabWidth(*font, m_run.tabSize(), m_run.xPos() + m_runWidthSoFar + widthSinceLastRounding);
208
            width = m_font->tabWidth(*font, m_run.tabSize(), m_run.xPos() + m_runWidthSoFar + widthSinceLastRounding);
209
        else {
209
        else {
210
            width = font->widthForGlyph(glyph);
210
            width = glyphData.advance.valueOrCompute([&] {
211
                return font->widthForGlyph(glyph);
212
            });
211
213
212
            // SVG uses horizontalGlyphStretch(), when textLength is used to stretch/squeeze text.
214
            // SVG uses horizontalGlyphStretch(), when textLength is used to stretch/squeeze text.
213
            width *= m_run.horizontalGlyphStretch();
215
            width *= m_run.horizontalGlyphStretch();
- a/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm -12 / +1 lines
Lines 622-639 float Font::platformWidthForGlyph(Glyph glyph) const a/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm_sec1
622
{
622
{
623
    CGSize advance = CGSizeZero;
623
    CGSize advance = CGSizeZero;
624
    bool horizontal = platformData().orientation() == Horizontal;
624
    bool horizontal = platformData().orientation() == Horizontal;
625
    bool populatedAdvance = false;
625
    CTFontGetAdvancesForGlyphs(m_platformData.ctFont(), horizontal ? kCTFontOrientationHorizontal : kCTFontOrientationVertical, &glyph, &advance, 1);
626
    if ((horizontal || m_isBrokenIdeographFallback) && canUseFastGlyphAdvanceGetter(this->platformData(), glyph, advance, populatedAdvance)) {
627
        float pointSize = platformData().size();
628
        CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
629
        CGFontRenderingStyle style = kCGFontRenderingStyleAntialiasing | kCGFontRenderingStyleSubpixelPositioning | kCGFontRenderingStyleSubpixelQuantization | kCGFontAntialiasingStyleUnfiltered;
630
        if (!CGFontGetGlyphAdvancesForStyle(platformData().cgFont(), &m, style, &glyph, 1, &advance)) {
631
            RetainPtr<CFStringRef> fullName = adoptCF(CGFontCopyFullName(platformData().cgFont()));
632
            LOG_ERROR("Unable to cache glyph widths for %@ %f", fullName.get(), pointSize);
633
            advance.width = 0;
634
        }
635
    } else if (!populatedAdvance && platformData().size())
636
        CTFontGetAdvancesForGlyphs(m_platformData.ctFont(), horizontal ? kCTFontOrientationHorizontal : kCTFontOrientationVertical, &glyph, &advance, 1);
637
626
638
    return advance.width + m_syntheticBoldOffset;
627
    return advance.width + m_syntheticBoldOffset;
639
}
628
}
- a/Source/WebCore/platform/graphics/mac/GlyphPageMac.cpp -6 / +14 lines
Lines 63-77 bool GlyphPage::fill(UChar* buffer, unsigned bufferLength) a/Source/WebCore/platform/graphics/mac/GlyphPageMac.cpp_sec1
63
    ASSERT(bufferLength == GlyphPage::size || bufferLength == 2 * GlyphPage::size);
63
    ASSERT(bufferLength == GlyphPage::size || bufferLength == 2 * GlyphPage::size);
64
64
65
    const Font& font = this->font();
65
    const Font& font = this->font();
66
    Vector<CGGlyph, 512> glyphs(bufferLength);
66
    Vector<CGGlyph> glyphs(bufferLength);
67
    unsigned glyphStep;
67
    memset(glyphs.data(), 0, sizeof(CGGlyph) * bufferLength);
68
    if (!shouldUseCoreText(buffer, bufferLength, font)) {
68
    if (!shouldUseCoreText(buffer, bufferLength, font)) {
69
        // We pass in either 256 or 512 UTF-16 characters: 256 for U+FFFF and less, 512 (double character surrogates)
69
        // We pass in either 256 or 512 UTF-16 characters: 256 for U+FFFF and less, 512 (double character surrogates)
70
        // for U+10000 and above. It is indeed possible to get back 512 glyphs back from the API, so the glyph buffer
70
        // for U+10000 and above. It is indeed possible to get back 512 glyphs back from the API, so the glyph buffer
71
        // we pass in must be 512. If we get back more than 256 glyphs though we'll ignore all the ones after 256,
71
        // we pass in must be 512. If we get back more than 256 glyphs though we'll ignore all the ones after 256,
72
        // this should not happen as the only time we pass in 512 characters is when they are surrogates.
72
        // this should not happen as the only time we pass in 512 characters is when they are surrogates.
73
        CGFontGetGlyphsForUnichars(font.platformData().cgFont(), buffer, glyphs.data(), bufferLength);
73
        CGFontGetGlyphsForUnichars(font.platformData().cgFont(), buffer, glyphs.data(), bufferLength);
74
        glyphStep = 1;
75
    } else {
74
    } else {
76
        // Because we know the implementation of shouldUseCoreText(), if the font isn't for text combine and it isn't a system font,
75
        // Because we know the implementation of shouldUseCoreText(), if the font isn't for text combine and it isn't a system font,
77
        // we know it must have vertical glyphs.
76
        // we know it must have vertical glyphs.
Lines 82-94 bool GlyphPage::fill(UChar* buffer, unsigned bufferLength) a/Source/WebCore/platform/graphics/mac/GlyphPageMac.cpp_sec2
82
81
83
        // When buffer consists of surrogate pairs, CTFontGetVerticalGlyphsForCharacters and CTFontGetGlyphsForCharacters
82
        // When buffer consists of surrogate pairs, CTFontGetVerticalGlyphsForCharacters and CTFontGetGlyphsForCharacters
84
        // place the glyphs at indices corresponding to the first character of each pair.
83
        // place the glyphs at indices corresponding to the first character of each pair.
85
        glyphStep = bufferLength / GlyphPage::size;
84
        unsigned glyphStep = bufferLength / GlyphPage::size;
85
        if (glyphStep != 1) {
86
            for (unsigned i = 0; i < GlyphPage::size; ++i)
87
                glyphs[i] = glyphs[i * glyphStep];
88
        }
86
    }
89
    }
87
90
91
    Vector<CGSize> advances(GlyphPage::size);
92
    CTFontOrientation orientation = font.platformData().orientation() == Horizontal ? kCTFontOrientationHorizontal : kCTFontOrientationVertical;
93
    CGFontRenderingStyle style = kCGFontRenderingStyleAntialiasing | kCGFontRenderingStyleSubpixelPositioning | kCGFontRenderingStyleSubpixelQuantization | kCGFontAntialiasingStyleUnfiltered;
94
    CTFontGetUnsummedAdvancesForGlyphsAndStyle(font.platformData().ctFont(), orientation, style, glyphs.data(), advances.data(), GlyphPage::size);
95
88
    bool haveGlyphs = false;
96
    bool haveGlyphs = false;
89
    for (unsigned i = 0; i < GlyphPage::size; ++i) {
97
    for (unsigned i = 0; i < GlyphPage::size; ++i) {
90
        if (glyphs[i * glyphStep]) {
98
        if (glyphs[i]) {
91
            setGlyphForIndex(i, glyphs[i * glyphStep]);
99
            setGlyphForIndex(i, glyphs[i], advances[i].width);
92
            haveGlyphs = true;
100
            haveGlyphs = true;
93
        }
101
        }
94
    }
102
    }
- a/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h -23 / +13 lines
Lines 42-47 enum { a/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h_sec1
42
    kCTFontUIFontSystemUltraLight = 104,
42
    kCTFontUIFontSystemUltraLight = 104,
43
};
43
};
44
44
45
typedef CF_OPTIONS(uint32_t, CTFontTransformOptions)
46
{
47
    kCTFontTransformApplyShaping = (1 << 0),
48
    kCTFontTransformApplyPositioning = (1 << 1)
49
};
50
51
typedef CF_OPTIONS(uint32_t, CTFontDescriptorOptions)
52
{
53
    kCTFontDescriptorOptionSystemUIFont = 1 << 1,
54
    kCTFontDescriptorOptionPreferAppleSystemFont = kCTFontOptionsPreferSystemFont
55
};
56
45
#endif
57
#endif
46
58
47
extern "C" {
59
extern "C" {
Lines 52-98 typedef void (*CTUniCharDisposeCallback)(const UniChar* chars, void* refCon); a/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h_sec2
52
extern const CFStringRef kCTFontReferenceURLAttribute;
64
extern const CFStringRef kCTFontReferenceURLAttribute;
53
extern const CFStringRef kCTFontOpticalSizeAttribute;
65
extern const CFStringRef kCTFontOpticalSizeAttribute;
54
66
55
#if PLATFORM(COCOA)
56
#if !USE(APPLE_INTERNAL_SDK)
57
typedef CF_OPTIONS(uint32_t, CTFontTransformOptions)
58
{
59
    kCTFontTransformApplyShaping = (1 << 0),
60
    kCTFontTransformApplyPositioning = (1 << 1)
61
};
62
#endif
63
bool CTFontTransformGlyphs(CTFontRef, CGGlyph glyphs[], CGSize advances[], CFIndex count, CTFontTransformOptions);
67
bool CTFontTransformGlyphs(CTFontRef, CGGlyph glyphs[], CGSize advances[], CFIndex count, CTFontTransformOptions);
64
#endif
65
68
66
CGSize CTRunGetInitialAdvance(CTRunRef run);
69
CGSize CTRunGetInitialAdvance(CTRunRef run);
67
CTLineRef CTLineCreateWithUniCharProvider(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon);
70
CTLineRef CTLineCreateWithUniCharProvider(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon);
68
CTTypesetterRef CTTypesetterCreateWithUniCharProviderAndOptions(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon, CFDictionaryRef options);
71
CTTypesetterRef CTTypesetterCreateWithUniCharProviderAndOptions(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon, CFDictionaryRef options);
69
bool CTFontGetVerticalGlyphsForCharacters(CTFontRef, const UniChar characters[], CGGlyph glyphs[], CFIndex count);
72
bool CTFontGetVerticalGlyphsForCharacters(CTFontRef, const UniChar characters[], CGGlyph glyphs[], CFIndex count);
73
void CTFontGetUnsummedAdvancesForGlyphsAndStyle(CTFontRef, CTFontOrientation, CGFontRenderingStyle, const CGGlyph[], CGSize advances[], CFIndex count);
70
74
71
CTFontDescriptorRef CTFontDescriptorCreateForUIType(CTFontUIFontType, CGFloat size, CFStringRef language);
75
CTFontDescriptorRef CTFontDescriptorCreateForUIType(CTFontUIFontType, CGFloat size, CFStringRef language);
72
CTFontDescriptorRef CTFontDescriptorCreateWithTextStyle(CFStringRef style, CFStringRef size, CFStringRef language);
76
CTFontDescriptorRef CTFontDescriptorCreateWithTextStyle(CFStringRef style, CFStringRef size, CFStringRef language);
73
CTFontDescriptorRef CTFontDescriptorCreateCopyWithSymbolicTraits(CTFontDescriptorRef original, CTFontSymbolicTraits symTraitValue, CTFontSymbolicTraits symTraitMask);
77
CTFontDescriptorRef CTFontDescriptorCreateCopyWithSymbolicTraits(CTFontDescriptorRef original, CTFontSymbolicTraits symTraitValue, CTFontSymbolicTraits symTraitMask);
74
CFBitVectorRef CTFontCopyGlyphCoverageForFeature(CTFontRef, CFDictionaryRef feature);
78
CFBitVectorRef CTFontCopyGlyphCoverageForFeature(CTFontRef, CFDictionaryRef feature);
75
79
76
#if PLATFORM(COCOA)
77
#if !USE(APPLE_INTERNAL_SDK)
78
typedef CF_OPTIONS(uint32_t, CTFontDescriptorOptions)
79
{
80
    kCTFontDescriptorOptionSystemUIFont = 1 << 1,
81
    kCTFontDescriptorOptionPreferAppleSystemFont = kCTFontOptionsPreferSystemFont
82
};
83
84
CTFontDescriptorRef CTFontDescriptorCreateWithAttributesAndOptions(CFDictionaryRef attributes, CTFontDescriptorOptions);
80
CTFontDescriptorRef CTFontDescriptorCreateWithAttributesAndOptions(CFDictionaryRef attributes, CTFontDescriptorOptions);
85
81
86
extern const CFStringRef kCTFontDescriptorTextStyleAttribute;
82
extern const CFStringRef kCTFontDescriptorTextStyleAttribute;
87
extern const CFStringRef kCTFontUIFontDesignTrait;
83
extern const CFStringRef kCTFontUIFontDesignTrait;
88
#endif
89
#endif
90
84
91
bool CTFontDescriptorIsSystemUIFont(CTFontDescriptorRef);
85
bool CTFontDescriptorIsSystemUIFont(CTFontDescriptorRef);
92
CTFontRef CTFontCreateForCSS(CFStringRef name, uint16_t weight, CTFontSymbolicTraits, CGFloat size);
86
CTFontRef CTFontCreateForCSS(CFStringRef name, uint16_t weight, CTFontSymbolicTraits, CGFloat size);
93
CTFontRef CTFontCreateForCharactersWithLanguage(CTFontRef currentFont, const UTF16Char *characters, CFIndex length, CFStringRef language, CFIndex *coveredLength);
87
CTFontRef CTFontCreateForCharactersWithLanguage(CTFontRef currentFont, const UTF16Char *characters, CFIndex length, CFStringRef language, CFIndex *coveredLength);
94
88
95
#if PLATFORM(COCOA)
96
extern const CFStringRef kCTUIFontTextStyleShortHeadline;
89
extern const CFStringRef kCTUIFontTextStyleShortHeadline;
97
extern const CFStringRef kCTUIFontTextStyleShortBody;
90
extern const CFStringRef kCTUIFontTextStyleShortBody;
98
extern const CFStringRef kCTUIFontTextStyleShortSubhead;
91
extern const CFStringRef kCTUIFontTextStyleShortSubhead;
Lines 118-131 extern const CGFloat kCTFontWeightSemibold; a/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h_sec3
118
extern const CGFloat kCTFontWeightBold;
111
extern const CGFloat kCTFontWeightBold;
119
extern const CGFloat kCTFontWeightHeavy;
112
extern const CGFloat kCTFontWeightHeavy;
120
extern const CGFloat kCTFontWeightBlack;
113
extern const CGFloat kCTFontWeightBlack;
121
#endif
122
114
123
#if PLATFORM(IOS)
124
extern const CFStringRef kCTUIFontTextStyleTitle1;
115
extern const CFStringRef kCTUIFontTextStyleTitle1;
125
extern const CFStringRef kCTUIFontTextStyleTitle2;
116
extern const CFStringRef kCTUIFontTextStyleTitle2;
126
extern const CFStringRef kCTUIFontTextStyleTitle3;
117
extern const CFStringRef kCTUIFontTextStyleTitle3;
127
CTFontDescriptorRef CTFontCreatePhysicalFontDescriptorForCharactersWithLanguage(CTFontRef currentFont, const UTF16Char* characters, CFIndex length, CFStringRef language, CFIndex* coveredLength);
118
CTFontDescriptorRef CTFontCreatePhysicalFontDescriptorForCharactersWithLanguage(CTFontRef currentFont, const UTF16Char* characters, CFIndex length, CFStringRef language, CFIndex* coveredLength);
128
#endif
129
119
130
CTFontRef CTFontCreatePhysicalFontForCharactersWithLanguage(CTFontRef, const UTF16Char* characters, CFIndex length, CFStringRef language, CFIndex* coveredLength);
120
CTFontRef CTFontCreatePhysicalFontForCharactersWithLanguage(CTFontRef, const UTF16Char* characters, CFIndex length, CFStringRef language, CFIndex* coveredLength);
131
bool CTFontIsAppleColorEmoji(CTFontRef);
121
bool CTFontIsAppleColorEmoji(CTFontRef);
- a/Source/WebCore/rendering/mathml/MathOperator.cpp -45 / +100 lines
Lines 94-100 void MathOperator::setOperator(const RenderStyle& style, UChar baseCharacter, Ty a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec1
94
94
95
void MathOperator::reset(const RenderStyle& style)
95
void MathOperator::reset(const RenderStyle& style)
96
{
96
{
97
    m_stretchType = StretchType::Unstretched;
97
    m_variantOrAssembly = Nullopt;
98
    m_maxPreferredWidth = 0;
98
    m_maxPreferredWidth = 0;
99
    m_width = 0;
99
    m_width = 0;
100
    m_ascent = 0;
100
    m_ascent = 0;
Lines 131-138 void MathOperator::setSizeVariant(const GlyphData& sizeVariant) a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec2
131
{
131
{
132
    ASSERT(sizeVariant.font);
132
    ASSERT(sizeVariant.font);
133
    ASSERT(sizeVariant.font->mathData());
133
    ASSERT(sizeVariant.font->mathData());
134
    m_stretchType = StretchType::SizeVariant;
134
    m_variantOrAssembly = sizeVariant;
135
    m_variant = sizeVariant;
136
    m_width = advanceWidthForGlyph(sizeVariant);
135
    m_width = advanceWidthForGlyph(sizeVariant);
137
    getAscentAndDescentForGlyph(sizeVariant, m_ascent, m_descent);
136
    getAscentAndDescentForGlyph(sizeVariant, m_ascent, m_descent);
138
}
137
}
Lines 140-167 void MathOperator::setSizeVariant(const GlyphData& sizeVariant) a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec3
140
void MathOperator::setGlyphAssembly(const GlyphAssemblyData& assemblyData)
139
void MathOperator::setGlyphAssembly(const GlyphAssemblyData& assemblyData)
141
{
140
{
142
    ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator);
141
    ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator);
143
    m_stretchType = StretchType::GlyphAssembly;
142
    m_variantOrAssembly = assemblyData;
144
    m_assembly = assemblyData;
145
    if (m_operatorType == Type::VerticalOperator) {
143
    if (m_operatorType == Type::VerticalOperator) {
146
        m_width = 0;
144
        m_width = 0;
147
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(m_assembly.topOrRight));
145
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(assemblyData.topOrRight));
148
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(m_assembly.extension));
146
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(assemblyData.extension));
149
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(m_assembly.bottomOrLeft));
147
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(assemblyData.bottomOrLeft));
150
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(m_assembly.middle));
148
        m_width = std::max<LayoutUnit>(m_width, advanceWidthForGlyph(assemblyData.middle));
151
    } else {
149
    } else {
152
        m_ascent = 0;
150
        m_ascent = 0;
153
        m_descent = 0;
151
        m_descent = 0;
154
        LayoutUnit ascent, descent;
152
        LayoutUnit ascent, descent;
155
        getAscentAndDescentForGlyph(m_assembly.bottomOrLeft, ascent, descent);
153
        getAscentAndDescentForGlyph(assemblyData.bottomOrLeft, ascent, descent);
156
        m_ascent = std::max(m_ascent, ascent);
154
        m_ascent = std::max(m_ascent, ascent);
157
        m_descent = std::max(m_descent, descent);
155
        m_descent = std::max(m_descent, descent);
158
        getAscentAndDescentForGlyph(m_assembly.extension, ascent, descent);
156
        getAscentAndDescentForGlyph(assemblyData.extension, ascent, descent);
159
        m_ascent = std::max(m_ascent, ascent);
157
        m_ascent = std::max(m_ascent, ascent);
160
        m_descent = std::max(m_descent, descent);
158
        m_descent = std::max(m_descent, descent);
161
        getAscentAndDescentForGlyph(m_assembly.topOrRight, ascent, descent);
159
        getAscentAndDescentForGlyph(assemblyData.topOrRight, ascent, descent);
162
        m_ascent = std::max(m_ascent, ascent);
160
        m_ascent = std::max(m_ascent, ascent);
163
        m_descent = std::max(m_descent, descent);
161
        m_descent = std::max(m_descent, descent);
164
        getAscentAndDescentForGlyph(m_assembly.middle, ascent, descent);
162
        getAscentAndDescentForGlyph(assemblyData.middle, ascent, descent);
165
        m_ascent = std::max(m_ascent, ascent);
163
        m_ascent = std::max(m_ascent, ascent);
166
        m_descent = std::max(m_descent, descent);
164
        m_descent = std::max(m_descent, descent);
167
    }
165
    }
Lines 439-445 void MathOperator::stretchTo(const RenderStyle& style, LayoutUnit targetSize) a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec4
439
{
437
{
440
    ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator);
438
    ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator);
441
    calculateStretchyData(style, false, targetSize);
439
    calculateStretchyData(style, false, targetSize);
442
    if (m_stretchType == StretchType::GlyphAssembly) {
440
    if (isAssembly()) {
443
        if (m_operatorType == Type::VerticalOperator) {
441
        if (m_operatorType == Type::VerticalOperator) {
444
            m_ascent = targetSize;
442
            m_ascent = targetSize;
445
            m_descent = 0;
443
            m_descent = 0;
Lines 503-510 LayoutRect MathOperator::paintGlyph(const RenderStyle& style, PaintInfo& info, c a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec5
503
void MathOperator::fillWithVerticalExtensionGlyph(const RenderStyle& style, PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to)
501
void MathOperator::fillWithVerticalExtensionGlyph(const RenderStyle& style, PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to)
504
{
502
{
505
    ASSERT(m_operatorType == Type::VerticalOperator);
503
    ASSERT(m_operatorType == Type::VerticalOperator);
506
    ASSERT(m_stretchType == StretchType::GlyphAssembly);
504
    ASSERT(isAssembly());
507
    ASSERT(m_assembly.extension.font);
505
    auto& assembly = this->assembly();
506
    ASSERT(assembly.extension.font);
508
    ASSERT(from.y() <= to.y());
507
    ASSERT(from.y() <= to.y());
509
508
510
    // If there is no space for the extension glyph, we don't need to do anything.
509
    // If there is no space for the extension glyph, we don't need to do anything.
Lines 513-519 void MathOperator::fillWithVerticalExtensionGlyph(const RenderStyle& style, Pain a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec6
513
512
514
    GraphicsContextStateSaver stateSaver(info.context());
513
    GraphicsContextStateSaver stateSaver(info.context());
515
514
516
    FloatRect glyphBounds = boundsForGlyph(m_assembly.extension);
515
    FloatRect glyphBounds = boundsForGlyph(assembly.extension);
517
516
518
    // Clipping the extender region here allows us to draw the bottom extender glyph into the
517
    // Clipping the extender region here allows us to draw the bottom extender glyph into the
519
    // regions of the bottom glyph without worrying about overdraw (hairy pixels) and simplifies later clipping.
518
    // regions of the bottom glyph without worrying about overdraw (hairy pixels) and simplifies later clipping.
Lines 529-535 void MathOperator::fillWithVerticalExtensionGlyph(const RenderStyle& style, Pain a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec7
529
528
530
    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
529
    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
531
    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxY() < to.y() && extensionCount < kMaximumExtensionCount; extensionCount++) {
530
    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxY() < to.y() && extensionCount < kMaximumExtensionCount; extensionCount++) {
532
        lastPaintedGlyphRect = paintGlyph(style, info, m_assembly.extension, glyphOrigin, TrimTopAndBottom);
531
        lastPaintedGlyphRect = paintGlyph(style, info, assembly.extension, glyphOrigin, TrimTopAndBottom);
533
        glyphOrigin.setY(glyphOrigin.y() + lastPaintedGlyphRect.height());
532
        glyphOrigin.setY(glyphOrigin.y() + lastPaintedGlyphRect.height());
534
533
535
        // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle
534
        // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle
Lines 542-549 void MathOperator::fillWithVerticalExtensionGlyph(const RenderStyle& style, Pain a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec8
542
void MathOperator::fillWithHorizontalExtensionGlyph(const RenderStyle& style, PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to)
541
void MathOperator::fillWithHorizontalExtensionGlyph(const RenderStyle& style, PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to)
543
{
542
{
544
    ASSERT(m_operatorType == Type::HorizontalOperator);
543
    ASSERT(m_operatorType == Type::HorizontalOperator);
545
    ASSERT(m_stretchType == StretchType::GlyphAssembly);
544
    ASSERT(isAssembly());
546
    ASSERT(m_assembly.extension.font);
545
    auto& assembly = this->assembly();
546
    ASSERT(assembly.extension.font);
547
    ASSERT(from.x() <= to.x());
547
    ASSERT(from.x() <= to.x());
548
    ASSERT(from.y() == to.y());
548
    ASSERT(from.y() == to.y());
549
549
Lines 567-573 void MathOperator::fillWithHorizontalExtensionGlyph(const RenderStyle& style, Pa a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec9
567
567
568
    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
568
    // In practice, only small stretch sizes are requested but we limit the number of glyphs to avoid hangs.
569
    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxX() < to.x() && extensionCount < kMaximumExtensionCount; extensionCount++) {
569
    for (unsigned extensionCount = 0; lastPaintedGlyphRect.maxX() < to.x() && extensionCount < kMaximumExtensionCount; extensionCount++) {
570
        lastPaintedGlyphRect = paintGlyph(style, info, m_assembly.extension, glyphOrigin, TrimLeftAndRight);
570
        lastPaintedGlyphRect = paintGlyph(style, info, assembly.extension, glyphOrigin, TrimLeftAndRight);
571
        glyphOrigin.setX(glyphOrigin.x() + lastPaintedGlyphRect.width());
571
        glyphOrigin.setX(glyphOrigin.x() + lastPaintedGlyphRect.width());
572
572
573
        // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle
573
        // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle
Lines 580-607 void MathOperator::fillWithHorizontalExtensionGlyph(const RenderStyle& style, Pa a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec10
580
void MathOperator::paintVerticalGlyphAssembly(const RenderStyle& style, PaintInfo& info, const LayoutPoint& paintOffset)
580
void MathOperator::paintVerticalGlyphAssembly(const RenderStyle& style, PaintInfo& info, const LayoutPoint& paintOffset)
581
{
581
{
582
    ASSERT(m_operatorType == Type::VerticalOperator);
582
    ASSERT(m_operatorType == Type::VerticalOperator);
583
    ASSERT(m_stretchType == StretchType::GlyphAssembly);
583
    ASSERT(isAssembly());
584
    ASSERT(m_assembly.topOrRight.font);
584
    auto& assembly = this->assembly();
585
    ASSERT(m_assembly.bottomOrLeft.font);
585
    ASSERT(assembly.topOrRight.font);
586
    ASSERT(assembly.bottomOrLeft.font);
586
587
587
    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
588
    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
588
    LayoutPoint operatorTopLeft = paintOffset;
589
    LayoutPoint operatorTopLeft = paintOffset;
589
    FloatRect topGlyphBounds = boundsForGlyph(m_assembly.topOrRight);
590
    FloatRect topGlyphBounds = boundsForGlyph(assembly.topOrRight);
590
    LayoutPoint topGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() - topGlyphBounds.y());
591
    LayoutPoint topGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() - topGlyphBounds.y());
591
    LayoutRect topGlyphPaintRect = paintGlyph(style, info, m_assembly.topOrRight, topGlyphOrigin, TrimBottom);
592
    LayoutRect topGlyphPaintRect = paintGlyph(style, info, assembly.topOrRight, topGlyphOrigin, TrimBottom);
592
593
593
    FloatRect bottomGlyphBounds = boundsForGlyph(m_assembly.bottomOrLeft);
594
    FloatRect bottomGlyphBounds = boundsForGlyph(assembly.bottomOrLeft);
594
    LayoutPoint bottomGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() + stretchSize() - (bottomGlyphBounds.height() + bottomGlyphBounds.y()));
595
    LayoutPoint bottomGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() + stretchSize() - (bottomGlyphBounds.height() + bottomGlyphBounds.y()));
595
    LayoutRect bottomGlyphPaintRect = paintGlyph(style, info, m_assembly.bottomOrLeft, bottomGlyphOrigin, TrimTop);
596
    LayoutRect bottomGlyphPaintRect = paintGlyph(style, info, assembly.bottomOrLeft, bottomGlyphOrigin, TrimTop);
596
597
597
    if (m_assembly.middle.font) {
598
    if (assembly.middle.font) {
598
        // Center the glyph origin between the start and end glyph paint extents. Then shift it half the paint height toward the bottom glyph.
599
        // Center the glyph origin between the start and end glyph paint extents. Then shift it half the paint height toward the bottom glyph.
599
        FloatRect middleGlyphBounds = boundsForGlyph(m_assembly.middle);
600
        FloatRect middleGlyphBounds = boundsForGlyph(assembly.middle);
600
        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), topGlyphOrigin.y());
601
        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), topGlyphOrigin.y());
601
        middleGlyphOrigin.moveBy(LayoutPoint(0, (bottomGlyphPaintRect.y() - topGlyphPaintRect.maxY()) / 2.0));
602
        middleGlyphOrigin.moveBy(LayoutPoint(0, (bottomGlyphPaintRect.y() - topGlyphPaintRect.maxY()) / 2.0));
602
        middleGlyphOrigin.moveBy(LayoutPoint(0, middleGlyphBounds.height() / 2.0));
603
        middleGlyphOrigin.moveBy(LayoutPoint(0, middleGlyphBounds.height() / 2.0));
603
604
604
        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, m_assembly.middle, middleGlyphOrigin, TrimTopAndBottom);
605
        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, assembly.middle, middleGlyphOrigin, TrimTopAndBottom);
605
        fillWithVerticalExtensionGlyph(style, info, topGlyphPaintRect.minXMaxYCorner(), middleGlyphPaintRect.minXMinYCorner());
606
        fillWithVerticalExtensionGlyph(style, info, topGlyphPaintRect.minXMaxYCorner(), middleGlyphPaintRect.minXMinYCorner());
606
        fillWithVerticalExtensionGlyph(style, info, middleGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner());
607
        fillWithVerticalExtensionGlyph(style, info, middleGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner());
607
    } else
608
    } else
Lines 611-635 void MathOperator::paintVerticalGlyphAssembly(const RenderStyle& style, PaintInf a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec11
611
void MathOperator::paintHorizontalGlyphAssembly(const RenderStyle& style, PaintInfo& info, const LayoutPoint& paintOffset)
612
void MathOperator::paintHorizontalGlyphAssembly(const RenderStyle& style, PaintInfo& info, const LayoutPoint& paintOffset)
612
{
613
{
613
    ASSERT(m_operatorType == Type::HorizontalOperator);
614
    ASSERT(m_operatorType == Type::HorizontalOperator);
614
    ASSERT(m_stretchType == StretchType::GlyphAssembly);
615
    ASSERT(isAssembly());
615
    ASSERT(m_assembly.bottomOrLeft.font);
616
    auto& assembly = this->assembly();
616
    ASSERT(m_assembly.topOrRight.font);
617
    ASSERT(assembly.bottomOrLeft.font);
618
    ASSERT(assembly.topOrRight.font);
617
619
618
    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
620
    // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box.
619
    LayoutPoint operatorTopLeft = paintOffset;
621
    LayoutPoint operatorTopLeft = paintOffset;
620
    LayoutUnit baselineY = operatorTopLeft.y() + m_ascent;
622
    LayoutUnit baselineY = operatorTopLeft.y() + m_ascent;
621
    LayoutPoint leftGlyphOrigin(operatorTopLeft.x(), baselineY);
623
    LayoutPoint leftGlyphOrigin(operatorTopLeft.x(), baselineY);
622
    LayoutRect leftGlyphPaintRect = paintGlyph(style, info, m_assembly.bottomOrLeft, leftGlyphOrigin, TrimRight);
624
    LayoutRect leftGlyphPaintRect = paintGlyph(style, info, assembly.bottomOrLeft, leftGlyphOrigin, TrimRight);
623
625
624
    FloatRect rightGlyphBounds = boundsForGlyph(m_assembly.topOrRight);
626
    FloatRect rightGlyphBounds = boundsForGlyph(assembly.topOrRight);
625
    LayoutPoint rightGlyphOrigin(operatorTopLeft.x() + stretchSize() - rightGlyphBounds.width(), baselineY);
627
    LayoutPoint rightGlyphOrigin(operatorTopLeft.x() + stretchSize() - rightGlyphBounds.width(), baselineY);
626
    LayoutRect rightGlyphPaintRect = paintGlyph(style, info, m_assembly.topOrRight, rightGlyphOrigin, TrimLeft);
628
    LayoutRect rightGlyphPaintRect = paintGlyph(style, info, assembly.topOrRight, rightGlyphOrigin, TrimLeft);
627
629
628
    if (m_assembly.middle.font) {
630
    if (assembly.middle.font) {
629
        // Center the glyph origin between the start and end glyph paint extents.
631
        // Center the glyph origin between the start and end glyph paint extents.
630
        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), baselineY);
632
        LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), baselineY);
631
        middleGlyphOrigin.moveBy(LayoutPoint((rightGlyphPaintRect.x() - leftGlyphPaintRect.maxX()) / 2.0, 0));
633
        middleGlyphOrigin.moveBy(LayoutPoint((rightGlyphPaintRect.x() - leftGlyphPaintRect.maxX()) / 2.0, 0));
632
        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, m_assembly.middle, middleGlyphOrigin, TrimLeftAndRight);
634
        LayoutRect middleGlyphPaintRect = paintGlyph(style, info, assembly.middle, middleGlyphOrigin, TrimLeftAndRight);
633
        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(leftGlyphPaintRect.maxX(), baselineY), LayoutPoint(middleGlyphPaintRect.x(), baselineY));
635
        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(leftGlyphPaintRect.maxX(), baselineY), LayoutPoint(middleGlyphPaintRect.x(), baselineY));
634
        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(middleGlyphPaintRect.maxX(), baselineY), LayoutPoint(rightGlyphPaintRect.x(), baselineY));
636
        fillWithHorizontalExtensionGlyph(style, info, LayoutPoint(middleGlyphPaintRect.maxX(), baselineY), LayoutPoint(rightGlyphPaintRect.x(), baselineY));
635
    } else
637
    } else
Lines 656-662 void MathOperator::paint(const RenderStyle& style, PaintInfo& info, const Layout a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec12
656
        }
658
        }
657
    }
659
    }
658
660
659
    if (m_stretchType == StretchType::GlyphAssembly) {
661
    if (isAssembly()) {
660
        if (m_operatorType == Type::VerticalOperator)
662
        if (m_operatorType == Type::VerticalOperator)
661
            paintVerticalGlyphAssembly(style, info, paintOffset);
663
            paintVerticalGlyphAssembly(style, info, paintOffset);
662
        else
664
        else
Lines 665-677 void MathOperator::paint(const RenderStyle& style, PaintInfo& info, const Layout a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec13
665
    }
667
    }
666
668
667
    GlyphData glyphData;
669
    GlyphData glyphData;
668
    ASSERT(m_stretchType == StretchType::Unstretched || m_stretchType == StretchType::SizeVariant);
670
    ASSERT(!m_variantOrAssembly || isVariant());
669
    if (m_stretchType == StretchType::Unstretched) {
671
    if (!m_variantOrAssembly) {
670
        if (!getBaseGlyph(style, glyphData))
672
        if (!getBaseGlyph(style, glyphData))
671
            return;
673
            return;
672
    } else if (m_stretchType == StretchType::SizeVariant) {
674
    } else if (isVariant()) {
673
        ASSERT(m_variant.font);
675
        auto& variant = this->variant();
674
        glyphData = m_variant;
676
        ASSERT(variant.font);
677
        glyphData = variant;
675
    }
678
    }
676
    GlyphBuffer buffer;
679
    GlyphBuffer buffer;
677
    buffer.add(glyphData.glyph, glyphData.font, advanceWidthForGlyph(glyphData));
680
    buffer.add(glyphData.glyph, glyphData.font, advanceWidthForGlyph(glyphData));
Lines 681-686 void MathOperator::paint(const RenderStyle& style, PaintInfo& info, const Layout a/Source/WebCore/rendering/mathml/MathOperator.cpp_sec14
681
    paintInfo.context().drawGlyphs(style.fontCascade(), *glyphData.font, buffer, 0, 1, operatorOrigin);
684
    paintInfo.context().drawGlyphs(style.fontCascade(), *glyphData.font, buffer, 0, 1, operatorOrigin);
682
}
685
}
683
686
687
bool MathOperator::isVariant() const
688
{
689
    if (!m_variantOrAssembly)
690
        return false;
691
692
    bool result = false;
693
    auto visitor = WTF::makeVisitor(
694
        [&](GlyphData&) { result = true; },
695
        [&](GlyphAssemblyData&) { result = false; }
696
    );
697
    std::experimental::visit(visitor, m_variantOrAssembly);
698
    return result;
699
}
700
701
bool MathOperator::isAssembly() const
702
{
703
    if (!m_variantOrAssembly)
704
        return false;
705
706
    bool result = false;
707
    auto visitor = WTF::makeVisitor(
708
        [&](GlyphData&) { result = false; },
709
        [&](GlyphAssemblyData&) { result = true; }
710
    );
711
    std::experimental::visit(visitor, m_variantOrAssembly);
712
    return result;
713
}
714
715
GlyphData& MathOperator::variant()
716
{
717
    ASSERT(m_variantOrAssembly);
718
    GlyphData* result = nullptr;
719
    auto visitor = WTF::makeVisitor(
720
        [&](GlyphData& m_variant) { result = &m_variant; },
721
        [&](GlyphAssemblyData&) { CRASH_WITH_SECURITY_IMPLICATION(); }
722
    );
723
    std::experimental::visit(visitor, m_variantOrAssembly.value());
724
    return *result;
725
}
726
727
GlyphAssemblyData& MathOperator::assembly()
728
{
729
    ASSERT(m_variantOrAssembly);
730
    GlyphAssemblyData* result = nullptr;
731
    auto visitor = WTF::makeVisitor(
732
        [&](GlyphData&) { CRASH_WITH_SECURITY_IMPLICATION() },
733
        [&](GlyphAssemblyData&, m_assembly) { result = &m_assembly; }
734
    );
735
    std::experimental::visit(visitor, m_variantOrAssembly.value());
736
    return *result;
737
}
738
684
}
739
}
685
740
686
#endif
741
#endif
- a/Source/WebCore/rendering/mathml/MathOperator.h -6 / +8 lines
Lines 31-36 a/Source/WebCore/rendering/mathml/MathOperator.h_sec1
31
#include "OpenTypeMathData.h"
31
#include "OpenTypeMathData.h"
32
#include "PaintInfo.h"
32
#include "PaintInfo.h"
33
#include <unicode/utypes.h>
33
#include <unicode/utypes.h>
34
#include <wtf/Optional.h>
35
#include <wtf/Variant.h>
34
36
35
namespace WebCore {
37
namespace WebCore {
36
38
Lines 61-67 private: a/Source/WebCore/rendering/mathml/MathOperator.h_sec2
61
        GlyphData bottomOrLeft;
63
        GlyphData bottomOrLeft;
62
        GlyphData middle;
64
        GlyphData middle;
63
    };
65
    };
64
    enum class StretchType { Unstretched, SizeVariant, GlyphAssembly };
65
    enum GlyphPaintTrimming {
66
    enum GlyphPaintTrimming {
66
        TrimTop,
67
        TrimTop,
67
        TrimBottom,
68
        TrimBottom,
Lines 87-99 private: a/Source/WebCore/rendering/mathml/MathOperator.h_sec3
87
    void paintVerticalGlyphAssembly(const RenderStyle&, PaintInfo&, const LayoutPoint&);
88
    void paintVerticalGlyphAssembly(const RenderStyle&, PaintInfo&, const LayoutPoint&);
88
    void paintHorizontalGlyphAssembly(const RenderStyle&, PaintInfo&, const LayoutPoint&);
89
    void paintHorizontalGlyphAssembly(const RenderStyle&, PaintInfo&, const LayoutPoint&);
89
90
91
    bool isVariant() const;
92
    bool isAssembly() const;
93
    GlyphData& variant();
94
    GlyphAssemblyData& assembly();
95
90
    UChar m_baseCharacter { 0 };
96
    UChar m_baseCharacter { 0 };
91
    Type m_operatorType { Type::NormalOperator };
97
    Type m_operatorType { Type::NormalOperator };
92
    StretchType m_stretchType { StretchType::Unstretched };
98
    Optional<std::experimental::variant<GlyphData, GlyphAssemblyData>> m_variantOrAssembly;
93
    union {
94
        GlyphData m_variant;
95
        GlyphAssemblyData m_assembly;
96
    };
97
    LayoutUnit m_maxPreferredWidth { 0 };
99
    LayoutUnit m_maxPreferredWidth { 0 };
98
    LayoutUnit m_width { 0 };
100
    LayoutUnit m_width { 0 };
99
    LayoutUnit m_ascent { 0 };
101
    LayoutUnit m_ascent { 0 };

Return to Bug 161119