summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/android/FontAndroid.cpp
diff options
context:
space:
mode:
authorRussell Brenner <russellbrenner@google.com>2011-08-09 17:16:42 -0700
committerRussell Brenner <russellbrenner@google.com>2011-08-16 14:22:10 -0700
commitcfcbe02678eabf19b6b904be61d9991d4515ecb6 (patch)
tree140dd8f6a945b66dd96a090f04f2629500c510df /Source/WebCore/platform/graphics/android/FontAndroid.cpp
parenta19896cc5d9573a17b6ec206befb3b4ec6b2256b (diff)
downloadexternal_webkit-cfcbe02678eabf19b6b904be61d9991d4515ecb6.zip
external_webkit-cfcbe02678eabf19b6b904be61d9991d4515ecb6.tar.gz
external_webkit-cfcbe02678eabf19b6b904be61d9991d4515ecb6.tar.bz2
Add Harfbuzz support for system fallback fonts
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. Bug: 5087744 Change-Id: I3a3469bcd589ee796c9b5a828fb47d40ecb38738
Diffstat (limited to 'Source/WebCore/platform/graphics/android/FontAndroid.cpp')
-rw-r--r--Source/WebCore/platform/graphics/android/FontAndroid.cpp47
1 files changed, 42 insertions, 5 deletions
diff --git a/Source/WebCore/platform/graphics/android/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
index b56e37c..332e571 100644
--- a/Source/WebCore/platform/graphics/android/FontAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/FontAndroid.cpp
@@ -427,6 +427,7 @@ public:
private:
void setupFontForScriptRun();
+ void setupComplexFont(const char* fontName, const FontPlatformData& platformData);
HB_FontRec* allocHarfbuzzFont();
void deleteGlyphArrays();
void createGlyphArrays(int);
@@ -465,6 +466,7 @@ private:
// each word break we accumulate error. This is the
// number of pixels that we are behind so far.
unsigned m_letterSpacing; // pixels to be added after each glyph.
+ FontPlatformData* m_complexPlatformData;
};
@@ -479,6 +481,7 @@ TextRunWalker::TextRunWalker(const TextRun& run, unsigned startingX, const Font*
, m_padPerWordBreak(0)
, m_padError(0)
, m_letterSpacing(0)
+ , m_complexPlatformData(0)
{
// Do not use |run| inside this constructor. Use |m_run| instead.
@@ -507,6 +510,7 @@ TextRunWalker::~TextRunWalker()
fastFree(m_item.font);
deleteGlyphArrays();
delete[] m_item.log_clusters;
+ delete m_complexPlatformData;
}
bool TextRunWalker::isWordBreak(unsigned index, bool isRTL)
@@ -620,15 +624,48 @@ void TextRunWalker::setWordAndLetterSpacing(int wordSpacingAdjustment,
setLetterSpacingAdjustment(letterSpacingAdjustment);
}
+void TextRunWalker::setupComplexFont(const char* filename,
+ const FontPlatformData& platformData)
+{
+ delete m_complexPlatformData;
+
+ SkTypeface* typeface = SkTypeface::CreateFromFile(filename);
+ m_complexPlatformData = new FontPlatformData(platformData, typeface);
+ SkSafeUnref(typeface);
+ m_item.face = m_complexPlatformData->harfbuzzFace();
+ m_item.font->userData = m_complexPlatformData;
+}
+
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;
+
+ if (m_item.item.script == HB_Script_Devanagari) {
+ setupComplexFont("/system/fonts/Lohit_Hindi.ttf", platformData);
+ } else if (m_item.item.script == HB_Script_Thai) {
+ setupComplexFont("/system/fonts/DroidSansThai.ttf", platformData);
+ } else if (m_item.item.script == HB_Script_Arabic) {
+ setupComplexFont("/system/fonts/DroidNaskh-Regular.ttf", platformData);
+ } else if (m_item.item.script == HB_Script_Hebrew) {
+ switch (platformData.typeface()->style()) {
+ case SkTypeface::kBold:
+ case SkTypeface::kBoldItalic:
+ setupComplexFont("/system/fonts/DroidSansHebrew-Bold.ttf", platformData);
+ break;
+ case SkTypeface::kNormal:
+ case SkTypeface::kItalic:
+ default:
+ setupComplexFont("/system/fonts/DroidSansHebrew-Regular.ttf", platformData);
+ break;
+ }
+ } else {
+ // HB_Script_Common; includes Ethiopic
+ m_item.face = platformData.harfbuzzFace();
+ void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData);
+ m_item.font->userData = opaquePlatformData;
+ }
}
HB_FontRec* TextRunWalker::allocHarfbuzzFont()