Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp (141907 => 141908)
--- trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp 2013-02-05 19:26:52 UTC (rev 141907)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp 2013-02-05 19:38:19 UTC (rev 141908)
@@ -46,6 +46,15 @@
namespace WebCore {
+struct HarfBuzzFontData {
+ HarfBuzzFontData(WTF::HashMap<uint32_t, uint16_t>* glyphCacheForFaceCacheEntry, cairo_scaled_font_t* cairoScaledFont)
+ : m_glyphCacheForFaceCacheEntry(glyphCacheForFaceCacheEntry)
+ , m_cairoScaledFont(cairoScaledFont)
+ { }
+ WTF::HashMap<uint32_t, uint16_t>* m_glyphCacheForFaceCacheEntry;
+ cairo_scaled_font_t* m_cairoScaledFont;
+};
+
class CairoFtFaceLocker {
public:
CairoFtFaceLocker(cairo_scaled_font_t* cairoScaledFont) : m_scaledFont(cairoScaledFont) { };
@@ -92,26 +101,30 @@
static hb_bool_t harfBuzzGetGlyph(hb_font_t*, void* fontData, hb_codepoint_t unicode, hb_codepoint_t, hb_codepoint_t* glyph, void*)
{
- FontPlatformData* platformData = reinterpret_cast<FontPlatformData*>(fontData);
- cairo_scaled_font_t* scaledFont = platformData->scaledFont();
+ HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
+ cairo_scaled_font_t* scaledFont = hbFontData->m_cairoScaledFont;
ASSERT(scaledFont);
- cairo_glyph_t* glyphs = 0;
- int numGlyphs = 0;
- CString utf8Codepoint = UTF8Encoding().encode(reinterpret_cast<UChar*>(&unicode), 1, QuestionMarksForUnencodables);
- if (CAIRO_STATUS_SUCCESS != cairo_scaled_font_text_to_glyphs(scaledFont, 0, 0, utf8Codepoint.data(), utf8Codepoint.length(), &glyphs, &numGlyphs, 0, 0, 0))
- return false;
- if (!numGlyphs)
- return false;
- *glyph = glyphs[0].index;
- cairo_glyph_free(glyphs);
- return true;
+ WTF::HashMap<uint32_t, uint16_t>::AddResult result = hbFontData->m_glyphCacheForFaceCacheEntry->add(unicode, 0);
+ if (result.isNewEntry) {
+ cairo_glyph_t* glyphs = 0;
+ int numGlyphs = 0;
+ CString utf8Codepoint = UTF8Encoding().encode(reinterpret_cast<UChar*>(&unicode), 1, QuestionMarksForUnencodables);
+ if (cairo_scaled_font_text_to_glyphs(scaledFont, 0, 0, utf8Codepoint.data(), utf8Codepoint.length(), &glyphs, &numGlyphs, 0, 0, 0) != CAIRO_STATUS_SUCCESS)
+ return false;
+ if (!numGlyphs)
+ return false;
+ result.iterator->value = glyphs[0].index;
+ cairo_glyph_free(glyphs);
+ }
+ *glyph = result.iterator->value;
+ return !!*glyph;
}
static hb_position_t harfBuzzGetGlyphHorizontalAdvance(hb_font_t*, void* fontData, hb_codepoint_t glyph, void*)
{
- FontPlatformData* platformData = reinterpret_cast<FontPlatformData*>(fontData);
- cairo_scaled_font_t* scaledFont = platformData->scaledFont();
+ HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
+ cairo_scaled_font_t* scaledFont = hbFontData->m_cairoScaledFont;
ASSERT(scaledFont);
hb_position_t advance = 0;
@@ -128,8 +141,8 @@
static hb_bool_t harfBuzzGetGlyphExtents(hb_font_t*, void* fontData, hb_codepoint_t glyph, hb_glyph_extents_t* extents, void*)
{
- FontPlatformData* platformData = reinterpret_cast<FontPlatformData*>(fontData);
- cairo_scaled_font_t* scaledFont = platformData->scaledFont();
+ HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
+ cairo_scaled_font_t* scaledFont = hbFontData->m_cairoScaledFont;
ASSERT(scaledFont);
CairoGetGlyphWidthAndExtents(scaledFont, glyph, 0, extents);
@@ -182,6 +195,12 @@
return hb_blob_create(reinterpret_cast<const char*>(buffer), tableSize, HB_MEMORY_MODE_WRITABLE, buffer, fastFree);
}
+static void destroyHarfBuzzFontData(void* userData)
+{
+ HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(userData);
+ delete hbFontData;
+}
+
hb_face_t* HarfBuzzFace::createFace()
{
hb_face_t* face = hb_face_create_for_tables(harfBuzzCairoGetTable, m_platformData->scaledFont(), 0);
@@ -192,7 +211,8 @@
hb_font_t* HarfBuzzFace::createFont()
{
hb_font_t* font = hb_font_create(m_face);
- hb_font_set_funcs(font, harfBuzzCairoTextGetFontFuncs(), m_platformData, 0);
+ HarfBuzzFontData* hbFontData = new HarfBuzzFontData(m_glyphCacheForFaceCacheEntry, m_platformData->scaledFont());
+ hb_font_set_funcs(font, harfBuzzCairoTextGetFontFuncs(), hbFontData, destroyHarfBuzzFontData);
const float size = m_platformData->size();
if (floorf(size) == size)
hb_font_set_ppem(font, size, size);