diff options
Diffstat (limited to 'core/jni/android/graphics/TextLayoutCache.cpp')
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.cpp | 68 |
1 files changed, 43 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); |