diff options
author | Raph Levien <raph@google.com> | 2012-05-02 10:41:14 -0700 |
---|---|---|
committer | Raph Levien <raph@google.com> | 2012-05-02 12:00:12 -0700 |
commit | 1637dcd16cd314574a58602337a2c7222130b1b9 (patch) | |
tree | 06171194995ad686062a4dc4fbc7ac0ad51dd4c0 /core/jni | |
parent | b294435b5c6e0fee8c431ed3f6d77427d3d79dde (diff) | |
download | frameworks_base-1637dcd16cd314574a58602337a2c7222130b1b9.zip frameworks_base-1637dcd16cd314574a58602337a2c7222130b1b9.tar.gz frameworks_base-1637dcd16cd314574a58602337a2c7222130b1b9.tar.bz2 |
Use paint typeface for shaping when it supports the requested script.
This is a hackish but workable fix for bug 6415796.
Change-Id: Iaba91e1e53e688a3ee05a1fdb68fd05102e369f2
Diffstat (limited to 'core/jni')
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.cpp | 68 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.h | 3 |
2 files changed, 46 insertions, 25 deletions
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index 0d36edf..2bd36c3 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -739,18 +739,18 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* chars #endif } - -size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { - // Reset kerning - mShaperItem.kerning_applied = false; - - // Update Harfbuzz Shaper - mShaperItem.item.bidiLevel = isRTL; - - SkTypeface* typeface = paint->getTypeface(); - +/** + * Return the first typeface in the logical change, starting with this typeface, + * that contains the specified unichar, or NULL if none is found. + * + * Note that this function does _not_ increment the reference count on the typeface, as the + * assumption is that its lifetime is managed elsewhere - in particular, the fallback typefaces + * for the default font live in a global cache. + */ +SkTypeface* TextLayoutShaper::typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface, + SkUnichar unichar, HB_Script script) { // Set the correct Typeface depending on the script - switch (mShaperItem.item.script) { + switch (script) { case HB_Script_Arabic: typeface = getCachedTypeface(&mArabicTypeface, TYPEFACE_ARABIC); #if DEBUG_GLYPHS @@ -815,32 +815,31 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { break; default: - if (!typeface) { - typeface = mDefaultTypeface; -#if DEBUG_GLYPHS - ALOGD("Using Default Typeface"); -#endif - } else { #if DEBUG_GLYPHS + if (typeface) { ALOGD("Using Paint Typeface"); -#endif } +#endif break; } + return typeface; +} - mShapingPaint.setTypeface(typeface); - mShaperItem.face = getCachedHBFace(typeface); +size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { + // Reset kerning + mShaperItem.kerning_applied = false; -#if DEBUG_GLYPHS - ALOGD("Run typeface = %p, uniqueID = %d, hb_face = %p", - typeface, typeface->uniqueID(), mShaperItem.face); -#endif + // Update Harfbuzz Shaper + mShaperItem.item.bidiLevel = isRTL; + + SkTypeface* typeface = paint->getTypeface(); // Get the glyphs base count for offsetting the glyphIDs returned by Harfbuzz // This is needed as the Typeface used for shaping can be not the default one // when we are shaping any script that needs to use a fallback Font. // If we are a "common" script we dont need to shift size_t baseGlyphCount = 0; + SkUnichar firstUnichar = 0; switch (mShaperItem.item.script) { case HB_Script_Arabic: case HB_Script_Hebrew: @@ -850,7 +849,7 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { case HB_Script_Thai:{ const uint16_t* text16 = (const uint16_t*)(mShaperItem.string + mShaperItem.item.pos); const uint16_t* text16End = text16 + mShaperItem.item.length; - SkUnichar firstUnichar = SkUTF16_NextUnichar(&text16); + firstUnichar = SkUTF16_NextUnichar(&text16); while (firstUnichar == ' ' && text16 < text16End) { firstUnichar = SkUTF16_NextUnichar(&text16); } @@ -861,6 +860,25 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { break; } + // We test the baseGlyphCount to see if the typeface supports the requested script + if (baseGlyphCount != 0) { + typeface = typefaceForUnichar(paint, typeface, firstUnichar, mShaperItem.item.script); + } + + if (!typeface) { + typeface = mDefaultTypeface; +#if DEBUG_GLYPHS + ALOGD("Using Default Typeface"); +#endif + } + mShapingPaint.setTypeface(typeface); + mShaperItem.face = getCachedHBFace(typeface); + +#if DEBUG_GLYPHS + ALOGD("Run typeface = %p, uniqueID = %d, hb_face = %p", + typeface, typeface->uniqueID(), mShaperItem.face); +#endif + // Shape assert(mShaperItem.item.length > 0); // Harfbuzz will overwrite other memory if length is 0. ensureShaperItemGlyphArrays(mShaperItem.item.length * 3 / 2); diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h index 3c834a4..7d7caac 100644 --- a/core/jni/android/graphics/TextLayoutCache.h +++ b/core/jni/android/graphics/TextLayoutCache.h @@ -217,6 +217,9 @@ private: */ UnicodeString mBuffer; + SkTypeface* typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface, + SkUnichar unichar, HB_Script script); + size_t shapeFontRun(const SkPaint* paint, bool isRTL); void computeValues(const SkPaint* paint, const UChar* chars, |