summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
authorRussell Brenner <russellbrenner@google.com>2011-08-18 13:39:43 -0700
committerRussell Brenner <russellbrenner@google.com>2011-08-23 13:16:00 -0700
commit6afb175cd4fceab68383533f7f8539100067c5c9 (patch)
tree5bc9241bd6f51577eaa37d74e2ca8e97a57d2ee2 /Source/WebCore/platform/graphics
parent55488a4e70941dc7d313c02041395e9a75d8b150 (diff)
downloadexternal_webkit-6afb175cd4fceab68383533f7f8539100067c5c9.zip
external_webkit-6afb175cd4fceab68383533f7f8539100067c5c9.tar.gz
external_webkit-6afb175cd4fceab68383533f7f8539100067c5c9.tar.bz2
Add Harfbuzz support for fallback fonts (redux)
When Skia resorts to fallback fonts for non-latin characters, it retains the font ID of originally requested font, concealing the fact that a fallback was invoked. Harfbuzz needs to know the fallback font ID to read the correct GSUB/GPOS tables from the fallback font file so that these complex languages can be properly rendered. This change uses the script recognized by Harfbuzz as a means to surmise the fallback font that would be used by Skia and then injects that font file as a replacement for the originally requested font. Fallback fonts are loaded once and reused multiple times. An earlier implementation did not cache fonts in this way, causing large pages to run out of files for mmap streaming. Bug: 5087744 Change-Id: I61222829209d9bd6df465d37923ccff3681c2c54
Diffstat (limited to 'Source/WebCore/platform/graphics')
-rw-r--r--Source/WebCore/platform/graphics/android/FontAndroid.cpp81
-rw-r--r--Source/WebCore/platform/graphics/android/FontPlatformData.h2
-rw-r--r--Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp12
3 files changed, 90 insertions, 5 deletions
diff --git a/Source/WebCore/platform/graphics/android/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
index b56e37c..31589e3 100644
--- a/Source/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -426,7 +426,21 @@ public:
}
private:
+ enum CustomScript {
+ Hindi,
+ Thai,
+ Naskh,
+ Hebrew,
+ HebrewBold,
+ NUM_SCRIPTS
+ };
+
+ static const char* paths[NUM_SCRIPTS];
+ static const FontPlatformData* s_fallbackPlatformData[NUM_SCRIPTS];
+
void setupFontForScriptRun();
+ const FontPlatformData* setupComplexFont(CustomScript script,
+ const FontPlatformData& platformData);
HB_FontRec* allocHarfbuzzFont();
void deleteGlyphArrays();
void createGlyphArrays(int);
@@ -468,6 +482,18 @@ private:
};
+// Indexed using enum CustomScript
+const char* TextRunWalker::paths[] = {
+ "/system/fonts/Lohit_Hindi.ttf",
+ "/system/fonts/DroidSansThai.ttf",
+ "/system/fonts/DroidNaskh-Regular.ttf",
+ "/system/fonts/DroidSansHebrew-Regular.ttf",
+ "/system/fonts/DroidSansHebrew-Bold.ttf"
+};
+
+// Indexed using enum CustomScript
+const FontPlatformData* TextRunWalker::s_fallbackPlatformData[] = {};
+
TextRunWalker::TextRunWalker(const TextRun& run, unsigned startingX, const Font* font)
: m_font(font)
, m_startingX(startingX)
@@ -620,15 +646,60 @@ void TextRunWalker::setWordAndLetterSpacing(int wordSpacingAdjustment,
setLetterSpacingAdjustment(letterSpacingAdjustment);
}
+const FontPlatformData* TextRunWalker::setupComplexFont(
+ CustomScript script,
+ const FontPlatformData& platformData)
+{
+ if (!s_fallbackPlatformData[script]) {
+ SkTypeface* typeface = SkTypeface::CreateFromFile(paths[script]);
+ s_fallbackPlatformData[script] = new FontPlatformData(platformData, typeface);
+ SkSafeUnref(typeface);
+ }
+
+ // If we couldn't allocate a new FontPlatformData, revert to the one passed
+ if (!s_fallbackPlatformData[script])
+ return &platformData;
+
+ return s_fallbackPlatformData[script];
+}
+
void TextRunWalker::setupFontForScriptRun()
{
- const FontData* fontData = m_font->glyphDataForCharacter(
- m_item.string[m_item.item.pos], false).fontData;
+ const FontData* fontData = m_font->glyphDataForCharacter(m_run[0], false).fontData;
const FontPlatformData& platformData =
fontData->fontDataForCharacter(' ')->platformData();
- m_item.face = platformData.harfbuzzFace();
- void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData);
- m_item.font->userData = opaquePlatformData;
+ const FontPlatformData* complexPlatformData = &platformData;
+
+ switch (m_item.item.script) {
+ case HB_Script_Devanagari:
+ complexPlatformData = setupComplexFont(Hindi, platformData);
+ break;
+ case HB_Script_Thai:
+ complexPlatformData = setupComplexFont(Thai, platformData);
+ break;
+ case HB_Script_Arabic:
+ complexPlatformData = setupComplexFont(Naskh, platformData);
+ break;
+ case HB_Script_Hebrew:
+ switch (platformData.typeface()->style()) {
+ case SkTypeface::kBold:
+ case SkTypeface::kBoldItalic:
+ complexPlatformData = setupComplexFont(HebrewBold, platformData);
+ break;
+ case SkTypeface::kNormal:
+ case SkTypeface::kItalic:
+ default:
+ complexPlatformData = setupComplexFont(Hebrew, platformData);
+ break;
+ }
+ break;
+ default:
+ // HB_Script_Common; includes Ethiopic
+ complexPlatformData = &platformData;
+ break;
+ }
+ m_item.face = complexPlatformData->harfbuzzFace();
+ m_item.font->userData = const_cast<FontPlatformData*>(complexPlatformData);
}
HB_FontRec* TextRunWalker::allocHarfbuzzFont()
diff --git a/Source/WebCore/platform/graphics/android/FontPlatformData.h b/Source/WebCore/platform/graphics/android/FontPlatformData.h
index 3313aca..56ce6e9 100644
--- a/Source/WebCore/platform/graphics/android/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/android/FontPlatformData.h
@@ -55,6 +55,7 @@ public:
FontPlatformData(SkTypeface*, float textSize, bool fakeBold, bool fakeItalic);
FontPlatformData(const FontPlatformData& src, float textSize);
FontPlatformData(float size, bool syntheticBold, bool syntheticOblique);
+ FontPlatformData(const FontPlatformData& src, SkTypeface* typeface);
~FontPlatformData();
@@ -87,6 +88,7 @@ public:
#endif
HB_FaceRec_* harfbuzzFace() const;
+ SkTypeface* typeface() const { return mTypeface; }
private:
class RefCountedHarfbuzzFace : public RefCounted<RefCountedHarfbuzzFace> {
diff --git a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp b/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
index 337a94d..8e77b5b 100644
--- a/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
@@ -127,6 +127,18 @@ FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
trace(5);
}
+FontPlatformData::FontPlatformData(const FontPlatformData& src, SkTypeface* tf)
+ : mTypeface(tf), mTextSize(src.mTextSize), mFakeBold(src.mFakeBold),
+ mFakeItalic(src.mFakeItalic)
+{
+ if (hashTableDeletedFontValue() != mTypeface) {
+ SkSafeRef(mTypeface);
+ }
+
+ inc_count();
+ trace(6);
+}
+
FontPlatformData::~FontPlatformData()
{
dec_count();