| Differences between
and this patch
- a/Source/WebCore/ChangeLog +27 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2016-09-09  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 Simon Fraser.
7
8
        Most of the glyphs in a GlyphPage are never read from. Therefore, we can get a performance boost
9
        by not populating as many items in the GlyphPage. Because of the performance characteristics of
10
        CTFontGetGlyphsForCharacters(), a better size for a GlyphPage is 16 items. This, coupled with
11
        using CTFontGetUnsummedAdvancesForGlyphsAndStyle(), causes between a 0.01%-0.5% speedup on PLT.
12
13
        No new tests because there is no behavior change.
14
15
        * platform/graphics/Font.cpp:
16
        (WebCore::Font::initCharWidths):
17
        (WebCore::Font::platformGlyphInit):
18
        (WebCore::createAndFillGlyphPage):
19
        * platform/graphics/Font.h:
20
        (WebCore::Font::widthForGlyph):
21
        * platform/graphics/GlyphMetricsMap.h:
22
        * platform/graphics/GlyphPage.h:
23
        * platform/graphics/cocoa/FontCocoa.mm:
24
        * platform/spi/cocoa/CoreTextSPI.h:
25
        (WebCore::Font::platformWidthForGlyph):
26
        (WebCore::canUseFastGlyphAdvanceGetter): Deleted.
27
1
2016-09-09  Antti Koivisto  <antti@apple.com>
28
2016-09-09  Antti Koivisto  <antti@apple.com>
2
29
3
        v3: WebContent crash due to RELEASE_ASSERT in WebCore: WebCore::StyleResolver::styleForElement
30
        v3: WebContent crash due to RELEASE_ASSERT in WebCore: WebCore::StyleResolver::styleForElement
- a/Source/WebCore/platform/graphics/Font.cpp -54 / +57 lines
Lines 81-92 Font::Font(const FontPlatformData& platformData, bool isCustomFont, bool isLoadi a/Source/WebCore/platform/graphics/Font.cpp_sec1
81
// Estimates of avgCharWidth and maxCharWidth for platforms that don't support accessing these values from the font.
81
// Estimates of avgCharWidth and maxCharWidth for platforms that don't support accessing these values from the font.
82
void Font::initCharWidths()
82
void Font::initCharWidths()
83
{
83
{
84
    auto* glyphPageZero = glyphPage(0);
84
    auto* glyphPageZero = glyphPage(GlyphPage::pageNumberForCodePoint('0'));
85
85
86
    // Treat the width of a '0' as the avgCharWidth.
86
    // Treat the width of a '0' as the avgCharWidth.
87
    if (m_avgCharWidth <= 0.f && glyphPageZero) {
87
    if (m_avgCharWidth <= 0.f && glyphPageZero) {
88
        static const UChar32 digitZeroChar = '0';
88
        Glyph digitZeroGlyph = glyphPageZero->glyphDataForCharacter('0').glyph;
89
        Glyph digitZeroGlyph = glyphPageZero->glyphDataForCharacter(digitZeroChar).glyph;
90
        if (digitZeroGlyph)
89
        if (digitZeroGlyph)
91
            m_avgCharWidth = widthForGlyph(digitZeroGlyph);
90
            m_avgCharWidth = widthForGlyph(digitZeroGlyph);
92
    }
91
    }
Lines 102-123 void Font::initCharWidths() a/Source/WebCore/platform/graphics/Font.cpp_sec2
102
void Font::platformGlyphInit()
101
void Font::platformGlyphInit()
103
{
102
{
104
    auto* glyphPageZero = glyphPage(0);
103
    auto* glyphPageZero = glyphPage(0);
105
    if (!glyphPageZero) {
104
    auto* glyphPageCharacterZero = glyphPage(GlyphPage::pageNumberForCodePoint('0'));
106
        determinePitch();
105
    auto* glyphPageSpace = glyphPage(GlyphPage::pageNumberForCodePoint(space));
107
        return;
108
    }
109
106
110
    // Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0,
107
    // Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0,
111
    // are mapped to the ZERO WIDTH SPACE glyph.
108
    // are mapped to the ZERO WIDTH SPACE glyph.
112
    m_zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph;
109
    if (glyphPageZero)
110
        m_zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph;
113
111
114
    // Nasty hack to determine if we should round or ceil space widths.
112
    // 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 
113
    // 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.
114
    // every character and the space are the same width. Otherwise we round.
117
    m_spaceGlyph = glyphPageZero->glyphDataForCharacter(' ').glyph;
115
    if (glyphPageSpace)
116
        m_spaceGlyph = glyphPageSpace->glyphDataForCharacter(space).glyph;
118
    float width = widthForGlyph(m_spaceGlyph);
117
    float width = widthForGlyph(m_spaceGlyph);
119
    m_spaceWidth = width;
118
    m_spaceWidth = width;
120
    m_zeroGlyph = glyphPageZero->glyphDataForCharacter('0').glyph;
119
    if (glyphPageCharacterZero)
120
        m_zeroGlyph = glyphPageCharacterZero->glyphDataForCharacter('0').glyph;
121
    m_fontMetrics.setZeroWidth(widthForGlyph(m_zeroGlyph));
121
    m_fontMetrics.setZeroWidth(widthForGlyph(m_zeroGlyph));
122
    determinePitch();
122
    determinePitch();
123
    m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
123
    m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
Lines 152-207 static RefPtr<GlyphPage> createAndFillGlyphPage(unsigned pageNumber, const Font& a/Source/WebCore/platform/graphics/Font.cpp_sec3
152
    // FIXME: Times New Roman contains Arabic glyphs, but Core Text doesn't know how to shape them. See <rdar://problem/9823975>.
152
    // FIXME: Times New Roman contains Arabic glyphs, but Core Text doesn't know how to shape them. See <rdar://problem/9823975>.
153
    // Once we have the fix for <rdar://problem/9823975> then remove this code together with Font::shouldNotBeUsedForArabic()
153
    // Once we have the fix for <rdar://problem/9823975> then remove this code together with Font::shouldNotBeUsedForArabic()
154
    // in <rdar://problem/12096835>.
154
    // in <rdar://problem/12096835>.
155
    if (pageNumber == 6 && font.shouldNotBeUsedForArabic())
155
    if (GlyphPage::pageNumberIsUsedForArabic(pageNumber) && font.shouldNotBeUsedForArabic())
156
        return nullptr;
156
        return nullptr;
157
#endif
157
#endif
158
158
159
    unsigned start = pageNumber * GlyphPage::size;
159
    unsigned glyphPageSize = GlyphPage::sizeForPageNumber(pageNumber);
160
    UChar buffer[GlyphPage::size * 2 + 2];
160
161
    unsigned start = GlyphPage::startingCodePointInPageNumber(pageNumber);
162
    unsigned end = start + glyphPageSize;
163
    Vector<UChar> buffer(glyphPageSize * 2 + 2);
161
    unsigned bufferLength;
164
    unsigned bufferLength;
162
    // Fill in a buffer with the entire "page" of characters that we want to look up glyphs for.
165
    // Fill in a buffer with the entire "page" of characters that we want to look up glyphs for.
163
    if (U_IS_BMP(start)) {
166
    if (U_IS_BMP(start)) {
164
        bufferLength = GlyphPage::size;
167
        bufferLength = glyphPageSize;
165
        for (unsigned i = 0; i < GlyphPage::size; i++)
168
        for (unsigned i = 0; i < bufferLength; i++)
166
            buffer[i] = start + i;
169
            buffer[i] = start + i;
167
170
168
        if (!start) {
171
        // Code points 0x0 - 0x20 and 0x7F - 0xA0 are control character and shouldn't render. Map them to ZERO WIDTH SPACE.
169
            // Control characters must not render at all.
172
        auto overwriteCodePoints = [&](unsigned minimum, unsigned maximum, UChar newCodePoint) {
170
            for (unsigned i = 0; i < 0x20; ++i)
173
            unsigned begin = std::max(start, minimum);
171
                buffer[i] = zeroWidthSpace;
174
            unsigned complete = std::min(end, maximum);
172
            for (unsigned i = 0x7F; i < 0xA0; i++)
175
            for (unsigned i = begin; i < complete; ++i)
173
                buffer[i] = zeroWidthSpace;
176
                buffer[i - start] = newCodePoint;
174
            buffer[softHyphen] = zeroWidthSpace;
177
        };
175
178
176
            // \n, \t, and nonbreaking space must render as a space.
179
        auto overwriteCodePoint = [&](UChar codePoint, UChar newCodePoint) {
177
            buffer[(int)'\n'] = ' ';
180
            if (codePoint >= start && codePoint < end)
178
            buffer[(int)'\t'] = ' ';
181
                buffer[codePoint - start] = newCodePoint;
179
            buffer[noBreakSpace] = ' ';
182
        };
180
        } else if (start == (leftToRightMark & ~(GlyphPage::size - 1))) {
183
181
            // LRM, RLM, LRE, RLE, ZWNJ, ZWJ, and PDF must not render at all.
184
        overwriteCodePoints(0x0, 0x20, zeroWidthSpace);
182
            buffer[leftToRightMark - start] = zeroWidthSpace;
185
        overwriteCodePoints(0x7F, 0xA0, zeroWidthSpace);
183
            buffer[rightToLeftMark - start] = zeroWidthSpace;
186
        overwriteCodePoint(softHyphen, zeroWidthSpace);
184
            buffer[leftToRightEmbed - start] = zeroWidthSpace;
187
        overwriteCodePoint('\n', space);
185
            buffer[rightToLeftEmbed - start] = zeroWidthSpace;
188
        overwriteCodePoint('\t', space);
186
            buffer[leftToRightOverride - start] = zeroWidthSpace;
189
        overwriteCodePoint(noBreakSpace, space);
187
            buffer[rightToLeftOverride - start] = zeroWidthSpace;
190
        overwriteCodePoint(leftToRightMark, zeroWidthSpace);
188
            buffer[leftToRightIsolate - start] = zeroWidthSpace;
191
        overwriteCodePoint(rightToLeftMark, zeroWidthSpace);
189
            buffer[rightToLeftIsolate - start] = zeroWidthSpace;
192
        overwriteCodePoint(leftToRightEmbed, zeroWidthSpace);
190
            buffer[zeroWidthNonJoiner - start] = zeroWidthSpace;
193
        overwriteCodePoint(rightToLeftEmbed, zeroWidthSpace);
191
            buffer[zeroWidthJoiner - start] = zeroWidthSpace;
194
        overwriteCodePoint(leftToRightOverride, zeroWidthSpace);
192
            buffer[popDirectionalFormatting - start] = zeroWidthSpace;
195
        overwriteCodePoint(rightToLeftOverride, zeroWidthSpace);
193
            buffer[popDirectionalIsolate - start] = zeroWidthSpace;
196
        overwriteCodePoint(leftToRightIsolate, zeroWidthSpace);
194
            buffer[firstStrongIsolate - start] = zeroWidthSpace;
197
        overwriteCodePoint(rightToLeftIsolate, zeroWidthSpace);
195
        } else if (start == (objectReplacementCharacter & ~(GlyphPage::size - 1))) {
198
        overwriteCodePoint(zeroWidthNonJoiner, zeroWidthSpace);
196
            // Object replacement character must not render at all.
199
        overwriteCodePoint(zeroWidthJoiner, zeroWidthSpace);
197
            buffer[objectReplacementCharacter - start] = zeroWidthSpace;
200
        overwriteCodePoint(popDirectionalFormatting, zeroWidthSpace);
198
        } else if (start == (zeroWidthNoBreakSpace & ~(GlyphPage::size - 1))) {
201
        overwriteCodePoint(popDirectionalIsolate, zeroWidthSpace);
199
            // ZWNBS/BOM must not render at all.
202
        overwriteCodePoint(firstStrongIsolate, zeroWidthSpace);
200
            buffer[zeroWidthNoBreakSpace - start] = zeroWidthSpace;
203
        overwriteCodePoint(objectReplacementCharacter, zeroWidthSpace);
201
        }
204
        overwriteCodePoint(zeroWidthNoBreakSpace, zeroWidthSpace);
202
    } else {
205
    } else {
203
        bufferLength = GlyphPage::size * 2;
206
        bufferLength = glyphPageSize * 2;
204
        for (unsigned i = 0; i < GlyphPage::size; i++) {
207
        for (unsigned i = 0; i < glyphPageSize; i++) {
205
            int c = i + start;
208
            int c = i + start;
206
            buffer[i * 2] = U16_LEAD(c);
209
            buffer[i * 2] = U16_LEAD(c);
207
            buffer[i * 2 + 1] = U16_TRAIL(c);
210
            buffer[i * 2 + 1] = U16_TRAIL(c);
Lines 215-221 static RefPtr<GlyphPage> createAndFillGlyphPage(unsigned pageNumber, const Font& a/Source/WebCore/platform/graphics/Font.cpp_sec4
215
    // for only 128 out of 256 characters.
218
    // for only 128 out of 256 characters.
216
    Ref<GlyphPage> glyphPage = GlyphPage::create(font);
219
    Ref<GlyphPage> glyphPage = GlyphPage::create(font);
217
220
218
    bool haveGlyphs = fillGlyphPage(glyphPage, buffer, bufferLength, font);
221
    bool haveGlyphs = fillGlyphPage(glyphPage, buffer.data(), bufferLength, font);
219
    if (!haveGlyphs)
222
    if (!haveGlyphs)
220
        return nullptr;
223
        return nullptr;
221
224
Lines 238-244 const GlyphPage* Font::glyphPage(unsigned pageNumber) const a/Source/WebCore/platform/graphics/Font.cpp_sec5
238
241
239
Glyph Font::glyphForCharacter(UChar32 character) const
242
Glyph Font::glyphForCharacter(UChar32 character) const
240
{
243
{
241
    auto* page = glyphPage(character / GlyphPage::size);
244
    auto* page = glyphPage(GlyphPage::pageNumberForCodePoint(character));
242
    if (!page)
245
    if (!page)
243
        return 0;
246
        return 0;
244
    return page->glyphForCharacter(character);
247
    return page->glyphForCharacter(character);
Lines 246-252 Glyph Font::glyphForCharacter(UChar32 character) const a/Source/WebCore/platform/graphics/Font.cpp_sec6
246
249
247
GlyphData Font::glyphDataForCharacter(UChar32 character) const
250
GlyphData Font::glyphDataForCharacter(UChar32 character) const
248
{
251
{
249
    auto* page = glyphPage(character / GlyphPage::size);
252
    auto* page = glyphPage(GlyphPage::pageNumberForCodePoint(character));
250
    if (!page)
253
    if (!page)
251
        return GlyphData();
254
        return GlyphData();
252
    return page->glyphDataForCharacter(character);
255
    return page->glyphDataForCharacter(character);
- 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/FontCascadeFonts.cpp -3 / +3 lines
Lines 48-61 public: a/Source/WebCore/platform/graphics/FontCascadeFonts.cpp_sec1
48
48
49
    GlyphData glyphDataForCharacter(UChar32 c) const
49
    GlyphData glyphDataForCharacter(UChar32 c) const
50
    {
50
    {
51
        unsigned index = GlyphPage::indexForCharacter(c);
51
        unsigned index = GlyphPage::indexForCodePoint(c);
52
        ASSERT_WITH_SECURITY_IMPLICATION(index < GlyphPage::size);
52
        ASSERT_WITH_SECURITY_IMPLICATION(index < GlyphPage::size);
53
        return { m_glyphs[index], m_fonts[index] };
53
        return { m_glyphs[index], m_fonts[index] };
54
    }
54
    }
55
55
56
    void setGlyphDataForCharacter(UChar32 c, GlyphData glyphData)
56
    void setGlyphDataForCharacter(UChar32 c, GlyphData glyphData)
57
    {
57
    {
58
        setGlyphDataForIndex(GlyphPage::indexForCharacter(c), glyphData);
58
        setGlyphDataForIndex(GlyphPage::indexForCodePoint(c), glyphData);
59
    }
59
    }
60
60
61
private:
61
private:
Lines 428-434 GlyphData FontCascadeFonts::glyphDataForCharacter(UChar32 c, const FontCascadeDe a/Source/WebCore/platform/graphics/FontCascadeFonts.cpp_sec2
428
    if (variant != NormalVariant)
428
    if (variant != NormalVariant)
429
        return glyphDataForVariant(c, description, variant, 0);
429
        return glyphDataForVariant(c, description, variant, 0);
430
430
431
    const unsigned pageNumber = c / GlyphPage::size;
431
    const unsigned pageNumber = GlyphPage::pageNumberForCodePoint(c);
432
432
433
    auto& cacheEntry = pageNumber ? m_cachedPages.add(pageNumber, GlyphPageCacheEntry()).iterator->value : m_cachedPageZero;
433
    auto& cacheEntry = pageNumber ? m_cachedPages.add(pageNumber, GlyphPageCacheEntry()).iterator->value : m_cachedPageZero;
434
434
- a/Source/WebCore/platform/graphics/GlyphMetricsMap.h -1 / +1 lines
Lines 54-60 private: a/Source/WebCore/platform/graphics/GlyphMetricsMap.h_sec1
54
    class GlyphMetricsPage {
54
    class GlyphMetricsPage {
55
        WTF_MAKE_FAST_ALLOCATED;
55
        WTF_MAKE_FAST_ALLOCATED;
56
    public:
56
    public:
57
        static const size_t size = 256; // Usually covers Latin-1 in a single page.
57
        static const size_t size = 16;
58
58
59
        GlyphMetricsPage() = default;
59
        GlyphMetricsPage() = default;
60
        explicit GlyphMetricsPage(const T& initialValue)
60
        explicit GlyphMetricsPage(const T& initialValue)
- a/Source/WebCore/platform/graphics/GlyphPage.h -5 / +10 lines
Lines 57-63 struct GlyphData { a/Source/WebCore/platform/graphics/GlyphPage.h_sec1
57
57
58
// A GlyphPage contains a fixed-size set of GlyphData mappings for a contiguous
58
// A GlyphPage contains a fixed-size set of GlyphData mappings for a contiguous
59
// range of characters in the Unicode code space. GlyphPages are indexed
59
// range of characters in the Unicode code space. GlyphPages are indexed
60
// starting from 0 and incrementing for each 256 glyphs.
60
// starting from 0 and incrementing for each "size" number of glyphs.
61
class GlyphPage : public RefCounted<GlyphPage> {
61
class GlyphPage : public RefCounted<GlyphPage> {
62
public:
62
public:
63
    static Ref<GlyphPage> create(const Font& font)
63
    static Ref<GlyphPage> create(const Font& font)
Lines 72-88 public: a/Source/WebCore/platform/graphics/GlyphPage.h_sec2
72
72
73
    static unsigned count() { return s_count; }
73
    static unsigned count() { return s_count; }
74
74
75
    static const size_t size = 256; // Covers Latin-1 in a single page.
75
    static const unsigned size = 16;
76
    static unsigned indexForCharacter(UChar32 c) { return c % GlyphPage::size; }
76
77
    static unsigned sizeForPageNumber(unsigned) { return 16; }
78
    static unsigned indexForCodePoint(UChar32 c) { return c % size; }
79
    static unsigned pageNumberForCodePoint(UChar32 c) { return c / size; }
80
    static UChar32 startingCodePointInPageNumber(unsigned pageNumber) { return pageNumber * size; }
81
    static bool pageNumberIsUsedForArabic(unsigned pageNumber) { return startingCodePointInPageNumber(pageNumber) >= 0x600 && startingCodePointInPageNumber(pageNumber) + sizeForPageNumber(pageNumber) < 0x700; }
77
82
78
    GlyphData glyphDataForCharacter(UChar32 c) const
83
    GlyphData glyphDataForCharacter(UChar32 c) const
79
    {
84
    {
80
        return glyphDataForIndex(indexForCharacter(c));
85
        return glyphDataForIndex(indexForCodePoint(c));
81
    }
86
    }
82
87
83
    Glyph glyphForCharacter(UChar32 c) const
88
    Glyph glyphForCharacter(UChar32 c) const
84
    {
89
    {
85
        return glyphForIndex(indexForCharacter(c));
90
        return glyphForIndex(indexForCodePoint(c));
86
    }
91
    }
87
92
88
    GlyphData glyphDataForIndex(unsigned index) const
93
    GlyphData glyphDataForIndex(unsigned index) const
- a/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm -1 / +17 lines
Lines 596-601 FloatRect Font::platformBoundsForGlyph(Glyph glyph) const a/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm_sec1
596
    return boundingBox;
596
    return boundingBox;
597
}
597
}
598
598
599
#if !((PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000))
599
static inline Optional<CGSize> advanceForColorBitmapFont(const FontPlatformData& platformData, Glyph glyph)
600
static inline Optional<CGSize> advanceForColorBitmapFont(const FontPlatformData& platformData, Glyph glyph)
600
{
601
{
601
    CTFontRef font = platformData.font();
602
    CTFontRef font = platformData.font();
Lines 617-632 static inline bool canUseFastGlyphAdvanceGetter(const FontPlatformData& platform a/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm_sec2
617
    }
618
    }
618
    return true;
619
    return true;
619
}
620
}
621
#endif
620
622
621
float Font::platformWidthForGlyph(Glyph glyph) const
623
float Font::platformWidthForGlyph(Glyph glyph) const
622
{
624
{
623
    CGSize advance = CGSizeZero;
625
    CGSize advance = CGSizeZero;
624
    bool horizontal = platformData().orientation() == Horizontal;
626
    bool horizontal = platformData().orientation() == Horizontal;
627
    CGFontRenderingStyle style = kCGFontRenderingStyleAntialiasing | kCGFontRenderingStyleSubpixelPositioning | kCGFontRenderingStyleSubpixelQuantization | kCGFontAntialiasingStyleUnfiltered;
628
629
#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000)
630
    if (platformData().size()) {
631
        CTFontOrientation orientation = horizontal || m_isBrokenIdeographFallback ? kCTFontOrientationHorizontal : kCTFontOrientationVertical;
632
        // FIXME: Remove this special-casing when <rdar://problem/28197291> is fixed.
633
        if (CTFontIsAppleColorEmoji(m_platformData.ctFont()))
634
            CTFontGetAdvancesForGlyphs(m_platformData.ctFont(), orientation, &glyph, &advance, 1);
635
        else
636
            CTFontGetUnsummedAdvancesForGlyphsAndStyle(m_platformData.ctFont(), orientation, style, &glyph, &advance, 1);
637
    }
638
639
#else
640
625
    bool populatedAdvance = false;
641
    bool populatedAdvance = false;
626
    if ((horizontal || m_isBrokenIdeographFallback) && canUseFastGlyphAdvanceGetter(this->platformData(), glyph, advance, populatedAdvance)) {
642
    if ((horizontal || m_isBrokenIdeographFallback) && canUseFastGlyphAdvanceGetter(this->platformData(), glyph, advance, populatedAdvance)) {
627
        float pointSize = platformData().size();
643
        float pointSize = platformData().size();
628
        CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
644
        CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
629
        CGFontRenderingStyle style = kCGFontRenderingStyleAntialiasing | kCGFontRenderingStyleSubpixelPositioning | kCGFontRenderingStyleSubpixelQuantization | kCGFontAntialiasingStyleUnfiltered;
630
        if (!CGFontGetGlyphAdvancesForStyle(platformData().cgFont(), &m, style, &glyph, 1, &advance)) {
645
        if (!CGFontGetGlyphAdvancesForStyle(platformData().cgFont(), &m, style, &glyph, 1, &advance)) {
631
            RetainPtr<CFStringRef> fullName = adoptCF(CGFontCopyFullName(platformData().cgFont()));
646
            RetainPtr<CFStringRef> fullName = adoptCF(CGFontCopyFullName(platformData().cgFont()));
632
            LOG_ERROR("Unable to cache glyph widths for %@ %f", fullName.get(), pointSize);
647
            LOG_ERROR("Unable to cache glyph widths for %@ %f", fullName.get(), pointSize);
Lines 634-639 float Font::platformWidthForGlyph(Glyph glyph) const a/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm_sec3
634
        }
649
        }
635
    } else if (!populatedAdvance && platformData().size())
650
    } else if (!populatedAdvance && platformData().size())
636
        CTFontGetAdvancesForGlyphs(m_platformData.ctFont(), horizontal ? kCTFontOrientationHorizontal : kCTFontOrientationVertical, &glyph, &advance, 1);
651
        CTFontGetAdvancesForGlyphs(m_platformData.ctFont(), horizontal ? kCTFontOrientationHorizontal : kCTFontOrientationVertical, &glyph, &advance, 1);
652
#endif
637
653
638
    return advance.width + m_syntheticBoldOffset;
654
    return advance.width + m_syntheticBoldOffset;
639
}
655
}
- a/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h +1 lines
Lines 71-76 CTLineRef CTLineCreateWithUniCharProvider(CTUniCharProviderCallback provide, CTU a/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h_sec1
71
void CTRunGetBaseAdvancesAndOrigins(CTRunRef, CFRange, CGSize baseAdvances[], CGPoint origins[]);
71
void CTRunGetBaseAdvancesAndOrigins(CTRunRef, CFRange, CGSize baseAdvances[], CGPoint origins[]);
72
CTTypesetterRef CTTypesetterCreateWithUniCharProviderAndOptions(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon, CFDictionaryRef options);
72
CTTypesetterRef CTTypesetterCreateWithUniCharProviderAndOptions(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon, CFDictionaryRef options);
73
bool CTFontGetVerticalGlyphsForCharacters(CTFontRef, const UniChar characters[], CGGlyph glyphs[], CFIndex count);
73
bool CTFontGetVerticalGlyphsForCharacters(CTFontRef, const UniChar characters[], CGGlyph glyphs[], CFIndex count);
74
void CTFontGetUnsummedAdvancesForGlyphsAndStyle(CTFontRef, CTFontOrientation, CGFontRenderingStyle, const CGGlyph[], CGSize advances[], CFIndex count);
74
75
75
CTFontDescriptorRef CTFontDescriptorCreateForUIType(CTFontUIFontType, CGFloat size, CFStringRef language);
76
CTFontDescriptorRef CTFontDescriptorCreateForUIType(CTFontUIFontType, CGFloat size, CFStringRef language);
76
CTFontDescriptorRef CTFontDescriptorCreateWithTextStyle(CFStringRef style, CFStringRef size, CFStringRef language);
77
CTFontDescriptorRef CTFontDescriptorCreateWithTextStyle(CFStringRef style, CFStringRef size, CFStringRef language);

Return to Bug 161119