Changeset 70688 in webkit


Ignore:
Timestamp:
Oct 27, 2010 12:31:47 PM (13 years ago)
Author:
Martin Robinson
Message:

2010-10-27 Martin Robinson <mrobinson@igalia.com>

Reviewed by Gustavo Noronha Silva.

[Cairo] Font fallback determination is very ineffecient
https://bugs.webkit.org/show_bug.cgi?id=42052

Added a test which verifies the correct result rendering with a custom
font that is missing many glyphs.

  • platform/gtk/fonts/custom-font-missing-glyphs-expected.checksum: Added.
  • platform/gtk/fonts/custom-font-missing-glyphs-expected.png: Added.
  • platform/gtk/fonts/custom-font-missing-glyphs-expected.txt: Added.
  • platform/gtk/fonts/custom-font-missing-glyphs.html: Added.
  • platform/gtk/fonts/resources/mostly-empty-font.ttf: Added. A font that I created in fotnforge which is composed of empty glyphs, except for 'A' which has a lonely polyhedron for a glyph.

2010-10-27 Martin Robinson <mrobinson@igalia.com>

Reviewed by Gustavo Noronha Silva.

[Cairo] Font fallback determination is very ineffecient
https://bugs.webkit.org/show_bug.cgi?id=42052

When choosing a fallback font in FontCache::getFontDataForCharacters, use FontConfig's
mechanism for searching the fallback list directly, instead of scanning the list manually.
If the font is a custom font or any other font with no FontConfig pattern associated with
it, as FontConfig for a font that can supply the missing glyphs.

Test: platform/gtk/fonts/custom-font-missing-glyphs.html

  • platform/graphics/cairo/FontCacheFreeType.cpp: (WebCore::createFontConfigPatternForCharacters): Added this helper which turns a collection of unicode characters into a FontConfig pattern. (WebCore::findBestFontGivenFallbacks): Using a FontConfig pattern created with th above helper and a FcFontSet of fallback fonts, this helper will find a font in the set which fulfills the requirments. (WebCore::FontCache::getFontDataForCharacters): Given an existing font with missing glyphs, either find an appropriate fallback font from the list of FontConfig fallbacks or ask FontConfig directly for an appropriate font.
  • platform/graphics/cairo/FontPlatformDataFreeType.h: Made a member mutable, as it is initialized lazily.
Location:
trunk
Files:
5 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r70686 r70688  
     12010-10-27  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Gustavo Noronha Silva.
     4
     5        [Cairo] Font fallback determination is very ineffecient
     6        https://bugs.webkit.org/show_bug.cgi?id=42052
     7
     8        Added a test which verifies the correct result rendering with a custom
     9        font that is missing many glyphs.
     10
     11        * platform/gtk/fonts/custom-font-missing-glyphs-expected.checksum: Added.
     12        * platform/gtk/fonts/custom-font-missing-glyphs-expected.png: Added.
     13        * platform/gtk/fonts/custom-font-missing-glyphs-expected.txt: Added.
     14        * platform/gtk/fonts/custom-font-missing-glyphs.html: Added.
     15        * platform/gtk/fonts/resources/mostly-empty-font.ttf: Added. A font that I
     16        created in fotnforge which is composed of empty glyphs, except for 'A' which
     17        has a lonely polyhedron for a glyph.
     18
    1192010-10-27  Renata Hodovan  <reni@inf.u-szeged.hu>
    220
  • trunk/WebCore/ChangeLog

    r70682 r70688  
     12010-10-27  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Gustavo Noronha Silva.
     4
     5        [Cairo] Font fallback determination is very ineffecient
     6        https://bugs.webkit.org/show_bug.cgi?id=42052
     7
     8        When choosing a fallback font in FontCache::getFontDataForCharacters, use FontConfig's
     9        mechanism for searching the fallback list directly, instead of scanning the list manually.
     10        If the font is a custom font or any other font with no FontConfig pattern associated with
     11        it, as FontConfig for a font that can supply the missing glyphs.
     12
     13        Test: platform/gtk/fonts/custom-font-missing-glyphs.html
     14
     15        * platform/graphics/cairo/FontCacheFreeType.cpp:
     16        (WebCore::createFontConfigPatternForCharacters): Added this helper which turns
     17        a collection of unicode characters into a FontConfig pattern.
     18        (WebCore::findBestFontGivenFallbacks): Using a FontConfig pattern created with th
     19        above helper and a FcFontSet of fallback fonts, this helper will find a font in
     20        the set which fulfills the requirments.
     21        (WebCore::FontCache::getFontDataForCharacters): Given an existing font with missing
     22        glyphs, either find an appropriate fallback font from the list of FontConfig fallbacks
     23        or ask FontConfig directly for an appropriate font.
     24        * platform/graphics/cairo/FontPlatformDataFreeType.h: Made a member mutable, as it is
     25        initialized lazily.
     26
    1272010-10-27  Alexander Pavlov  <apavlov@chromium.org>
    228
  • trunk/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp

    r69528 r70688  
    4242}
    4343
     44FcPattern* createFontConfigPatternForCharacters(const UChar* characters, int length)
     45{
     46    FcPattern* pattern = FcPatternCreate();
     47
     48    FcCharSet* fontConfigCharSet = FcCharSetCreate();
     49    for (int i = 0; i < length; ++i) {
     50        if (U16_IS_SURROGATE(characters[i]) && U16_IS_SURROGATE_LEAD(characters[i])
     51                && i != length - 1 && U16_IS_TRAIL(characters[i + 1])) {
     52            FcCharSetAddChar(fontConfigCharSet, U16_GET_SUPPLEMENTARY(characters[i], characters[i+1]));
     53            i++;
     54        } else
     55            FcCharSetAddChar(fontConfigCharSet, characters[i]);
     56    }
     57    FcPatternAddCharSet(pattern, FC_CHARSET, fontConfigCharSet);
     58    FcCharSetDestroy(fontConfigCharSet);
     59
     60    FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
     61    FcConfigSubstitute(0, pattern, FcMatchPattern);
     62    FcDefaultSubstitute(pattern);
     63    return pattern;
     64}
     65
     66FcPattern* findBestFontGivenFallbacks(const FontPlatformData& fontData, FcPattern* pattern)
     67{
     68    if (!fontData.m_pattern)
     69        return 0;
     70
     71    if (!fontData.m_fallbacks) {
     72        FcResult fontConfigResult;
     73        fontData.m_fallbacks = FcFontSort(0, fontData.m_pattern.get(), FcTrue, 0, &fontConfigResult);
     74    }
     75
     76    if (!fontData.m_fallbacks)
     77        return 0;
     78
     79    FcFontSet* sets[] = { fontData.m_fallbacks };
     80    FcResult fontConfigResult;
     81    return FcFontSetMatch(0, sets, 1, pattern, &fontConfigResult);
     82}
     83
    4484const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length)
    4585{
    46     FcResult fresult;
    47     FontPlatformData* prim = const_cast<FontPlatformData*>(&font.primaryFont()->platformData());
     86    PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(createFontConfigPatternForCharacters(characters, length));
     87    const FontPlatformData& fontData = font.primaryFont()->platformData();
    4888
    49     // FIXME: This should not happen, apparently. We are null-checking
    50     // for now just to avoid crashing.
    51     if (!prim || !prim->m_pattern)
    52         return 0;
    53 
    54     if (!prim->m_fallbacks)
    55         prim->m_fallbacks = FcFontSort(0, prim->m_pattern.get(), FcTrue, 0, &fresult);
    56 
    57     FcFontSet* fs = prim->m_fallbacks;
    58 
    59     for (int i = 0; i < fs->nfont; i++) {
    60         PlatformRefPtr<FcPattern> fin = adoptPlatformRef(FcFontRenderPrepare(0, prim->m_pattern.get(), fs->fonts[i]));
    61         cairo_font_face_t* fontFace = cairo_ft_font_face_create_for_pattern(fin.get());
    62         FontPlatformData alternateFont(fontFace, font.fontDescription().computedPixelSize(), false, false);
    63         cairo_font_face_destroy(fontFace);
    64         alternateFont.m_pattern = fin;
    65         SimpleFontData* sfd = getCachedFontData(&alternateFont);
    66         if (sfd->containsCharacters(characters, length))
    67             return sfd;
     89    PlatformRefPtr<FcPattern> fallbackPattern = adoptPlatformRef(findBestFontGivenFallbacks(fontData, pattern.get()));
     90    if (fallbackPattern) {
     91        FontPlatformData alternateFontData(fallbackPattern.get(), font.fontDescription());
     92        return getCachedFontData(&alternateFontData);
    6893    }
    6994
    70     return 0;
     95    FcResult fontConfigResult;
     96    PlatformRefPtr<FcPattern> resultPattern = adoptPlatformRef(FcFontMatch(0, pattern.get(), &fontConfigResult));
     97    if (!resultPattern)
     98        return 0;
     99    FontPlatformData alternateFontData(resultPattern.get(), font.fontDescription());
     100    return getCachedFontData(&alternateFontData);
    71101}
    72102
  • trunk/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h

    r69320 r70688  
    8787
    8888    PlatformRefPtr<FcPattern> m_pattern;
    89     FcFontSet* m_fallbacks;
     89    mutable FcFontSet* m_fallbacks; // Initialized lazily.
    9090    float m_size;
    9191    bool m_syntheticBold;
Note: See TracChangeset for help on using the changeset viewer.