Loading core/jni/android/graphics/TextLayoutCache.cpp +37 −156 Original line number Diff line number Diff line Loading @@ -345,26 +345,10 @@ TextLayoutShaper::TextLayoutShaper() : mShaperItemGlyphArraySize(0) { void TextLayoutShaper::init() { mDefaultTypeface = SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, SkTypeface::kNormal); mArabicTypeface = NULL; mHebrewRegularTypeface = NULL; mHebrewBoldTypeface = NULL; mBengaliTypeface = NULL; mThaiTypeface = NULL; mDevanagariRegularTypeface = NULL; mTamilRegularTypeface = NULL; mTamilBoldTypeface = NULL; } void TextLayoutShaper::unrefTypefaces() { SkSafeUnref(mDefaultTypeface); SkSafeUnref(mArabicTypeface); SkSafeUnref(mHebrewRegularTypeface); SkSafeUnref(mHebrewBoldTypeface); SkSafeUnref(mBengaliTypeface); SkSafeUnref(mThaiTypeface); SkSafeUnref(mDevanagariRegularTypeface); SkSafeUnref(mTamilRegularTypeface); SkSafeUnref(mTamilBoldTypeface); } TextLayoutShaper::~TextLayoutShaper() { Loading Loading @@ -750,113 +734,30 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* chars * 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 (script) { case HB_Script_Arabic: typeface = getCachedTypeface(&mArabicTypeface, HB_Script_Arabic, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Arabic Typeface"); #endif break; case HB_Script_Hebrew: if (typeface) { switch (typeface->style()) { case SkTypeface::kBold: case SkTypeface::kBoldItalic: typeface = getCachedTypeface(&mHebrewBoldTypeface, HB_Script_Hebrew, SkTypeface::kBold); #if DEBUG_GLYPHS ALOGD("Using Hebrew Bold/BoldItalic Typeface"); #endif break; case SkTypeface::kNormal: case SkTypeface::kItalic: default: typeface = getCachedTypeface(&mHebrewRegularTypeface, HB_Script_Hebrew, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Hebrew Regular/Italic Typeface"); #endif break; } } else { typeface = getCachedTypeface(&mHebrewRegularTypeface, HB_Script_Hebrew, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Hebrew Regular Typeface"); #endif } break; case HB_Script_Bengali: typeface = getCachedTypeface(&mBengaliTypeface, HB_Script_Bengali, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Bengali Typeface"); #endif break; case HB_Script_Thai: typeface = getCachedTypeface(&mThaiTypeface, HB_Script_Thai, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Thai Typeface"); #endif break; case HB_Script_Devanagari: typeface = getCachedTypeface(&mDevanagariRegularTypeface, HB_Script_Devanagari, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Devanagari Regular Typeface"); #endif break; case HB_Script_Tamil: SkTypeface* TextLayoutShaper::typefaceForScript(const SkPaint* paint, SkTypeface* typeface, HB_Script script) { SkTypeface::Style currentStyle = SkTypeface::kNormal; if (typeface) { switch (typeface->style()) { case SkTypeface::kBold: case SkTypeface::kBoldItalic: typeface = getCachedTypeface(&mTamilBoldTypeface, HB_Script_Tamil, SkTypeface::kBold); #if DEBUG_GLYPHS ALOGD("Using Tamil Bold Typeface"); #endif break; case SkTypeface::kNormal: case SkTypeface::kItalic: default: typeface = getCachedTypeface(&mTamilRegularTypeface, HB_Script_Tamil, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Tamil Regular Typeface"); #endif break; currentStyle = typeface->style(); } } else { typeface = getCachedTypeface(&mTamilRegularTypeface, HB_Script_Tamil, SkTypeface::kNormal); typeface = SkCreateTypefaceForScript(script, currentStyle); #if DEBUG_GLYPHS ALOGD("Using Tamil Regular Typeface"); ALOGD("Using Harfbuzz Script %d, Style %d", script, currentStyle); #endif return typeface; } break; bool TextLayoutShaper::isComplexScript(HB_Script script) { switch (script) { case HB_Script_Common: case HB_Script_Greek: case HB_Script_Cyrillic: case HB_Script_Hangul: case HB_Script_Inherited: return false; default: #if DEBUG_GLYPHS if (typeface) { ALOGD("Using Paint Typeface"); return true; } #endif break; } return typeface; } size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { Loading @@ -874,13 +775,7 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { // 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: case HB_Script_Bengali: case HB_Script_Devanagari: case HB_Script_Tamil: case HB_Script_Thai:{ if (isComplexScript(mShaperItem.item.script)) { const uint16_t* text16 = (const uint16_t*) (mShaperItem.string + mShaperItem.item.pos); const uint16_t* text16End = text16 + mShaperItem.item.length; firstUnichar = SkUTF16_NextUnichar(&text16); Loading @@ -888,23 +783,27 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { firstUnichar = SkUTF16_NextUnichar(&text16); } baseGlyphCount = paint->getBaseGlyphCount(firstUnichar); break; } default: 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); typeface = typefaceForScript(paint, typeface, mShaperItem.item.script); if (!typeface) { typeface = mDefaultTypeface; SkSafeRef(typeface); #if DEBUG_GLYPHS ALOGD("Using Default Typeface"); #endif } } else { if (!typeface) { typeface = mDefaultTypeface; #if DEBUG_GLYPHS ALOGD("Using Default Typeface"); #endif } SkSafeRef(typeface); } mShapingPaint.setTypeface(typeface); mShaperItem.face = getCachedHBFace(typeface); Loading @@ -912,6 +811,7 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { ALOGD("Run typeface = %p, uniqueID = %d, hb_face = %p", typeface, typeface->uniqueID(), mShaperItem.face); #endif SkSafeUnref(typeface); // Shape assert(mShaperItem.item.length > 0); // Harfbuzz will overwrite other memory if length is 0. Loading Loading @@ -960,25 +860,6 @@ void TextLayoutShaper::deleteShaperItemGlyphArrays() { delete[] mShaperItem.log_clusters; } SkTypeface* TextLayoutShaper::getCachedTypeface(SkTypeface** typeface, HB_Script script, SkTypeface::Style style) { if (!*typeface) { *typeface = SkCreateTypefaceForScript(script, style); // CreateFromFile(path) can return NULL if the path is non existing if (!*typeface) { #if DEBUG_GLYPHS ALOGD("No font for Harfbuzz script %d, will use default font", script); #endif return mDefaultTypeface; } (*typeface)->ref(); #if DEBUG_GLYPHS ALOGD("Created SkTypeface for Harfbuzz script %d with uniqueID = %d", script, (*typeface)->uniqueID()); #endif } return *typeface; } HB_Face TextLayoutShaper::getCachedHBFace(SkTypeface* typeface) { SkFontID fontId = typeface->uniqueID(); ssize_t index = mCachedHBFaces.indexOfKey(fontId); Loading core/jni/android/graphics/TextLayoutCache.h +4 −11 Original line number Diff line number Diff line Loading @@ -189,17 +189,9 @@ private: SkPaint mShapingPaint; /** * Skia typefaces cached for shaping * Skia default typeface to be returned if we cannot resolve script */ SkTypeface* mDefaultTypeface; SkTypeface* mArabicTypeface; SkTypeface* mHebrewRegularTypeface; SkTypeface* mHebrewBoldTypeface; SkTypeface* mBengaliTypeface; SkTypeface* mThaiTypeface; SkTypeface* mDevanagariRegularTypeface; SkTypeface* mTamilRegularTypeface; SkTypeface* mTamilBoldTypeface; /** * Cache of Harfbuzz faces Loading @@ -224,8 +216,8 @@ private: void init(); void unrefTypefaces(); SkTypeface* typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface, SkUnichar unichar, HB_Script script); SkTypeface* typefaceForScript(const SkPaint* paint, SkTypeface* typeface, HB_Script script); size_t shapeFontRun(const SkPaint* paint, bool isRTL); Loading @@ -245,6 +237,7 @@ private: bool doShaping(size_t size); void createShaperItemGlyphArrays(size_t size); void deleteShaperItemGlyphArrays(); bool isComplexScript(HB_Script script); }; // TextLayoutShaper Loading Loading
core/jni/android/graphics/TextLayoutCache.cpp +37 −156 Original line number Diff line number Diff line Loading @@ -345,26 +345,10 @@ TextLayoutShaper::TextLayoutShaper() : mShaperItemGlyphArraySize(0) { void TextLayoutShaper::init() { mDefaultTypeface = SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, SkTypeface::kNormal); mArabicTypeface = NULL; mHebrewRegularTypeface = NULL; mHebrewBoldTypeface = NULL; mBengaliTypeface = NULL; mThaiTypeface = NULL; mDevanagariRegularTypeface = NULL; mTamilRegularTypeface = NULL; mTamilBoldTypeface = NULL; } void TextLayoutShaper::unrefTypefaces() { SkSafeUnref(mDefaultTypeface); SkSafeUnref(mArabicTypeface); SkSafeUnref(mHebrewRegularTypeface); SkSafeUnref(mHebrewBoldTypeface); SkSafeUnref(mBengaliTypeface); SkSafeUnref(mThaiTypeface); SkSafeUnref(mDevanagariRegularTypeface); SkSafeUnref(mTamilRegularTypeface); SkSafeUnref(mTamilBoldTypeface); } TextLayoutShaper::~TextLayoutShaper() { Loading Loading @@ -750,113 +734,30 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* chars * 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 (script) { case HB_Script_Arabic: typeface = getCachedTypeface(&mArabicTypeface, HB_Script_Arabic, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Arabic Typeface"); #endif break; case HB_Script_Hebrew: if (typeface) { switch (typeface->style()) { case SkTypeface::kBold: case SkTypeface::kBoldItalic: typeface = getCachedTypeface(&mHebrewBoldTypeface, HB_Script_Hebrew, SkTypeface::kBold); #if DEBUG_GLYPHS ALOGD("Using Hebrew Bold/BoldItalic Typeface"); #endif break; case SkTypeface::kNormal: case SkTypeface::kItalic: default: typeface = getCachedTypeface(&mHebrewRegularTypeface, HB_Script_Hebrew, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Hebrew Regular/Italic Typeface"); #endif break; } } else { typeface = getCachedTypeface(&mHebrewRegularTypeface, HB_Script_Hebrew, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Hebrew Regular Typeface"); #endif } break; case HB_Script_Bengali: typeface = getCachedTypeface(&mBengaliTypeface, HB_Script_Bengali, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Bengali Typeface"); #endif break; case HB_Script_Thai: typeface = getCachedTypeface(&mThaiTypeface, HB_Script_Thai, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Thai Typeface"); #endif break; case HB_Script_Devanagari: typeface = getCachedTypeface(&mDevanagariRegularTypeface, HB_Script_Devanagari, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Devanagari Regular Typeface"); #endif break; case HB_Script_Tamil: SkTypeface* TextLayoutShaper::typefaceForScript(const SkPaint* paint, SkTypeface* typeface, HB_Script script) { SkTypeface::Style currentStyle = SkTypeface::kNormal; if (typeface) { switch (typeface->style()) { case SkTypeface::kBold: case SkTypeface::kBoldItalic: typeface = getCachedTypeface(&mTamilBoldTypeface, HB_Script_Tamil, SkTypeface::kBold); #if DEBUG_GLYPHS ALOGD("Using Tamil Bold Typeface"); #endif break; case SkTypeface::kNormal: case SkTypeface::kItalic: default: typeface = getCachedTypeface(&mTamilRegularTypeface, HB_Script_Tamil, SkTypeface::kNormal); #if DEBUG_GLYPHS ALOGD("Using Tamil Regular Typeface"); #endif break; currentStyle = typeface->style(); } } else { typeface = getCachedTypeface(&mTamilRegularTypeface, HB_Script_Tamil, SkTypeface::kNormal); typeface = SkCreateTypefaceForScript(script, currentStyle); #if DEBUG_GLYPHS ALOGD("Using Tamil Regular Typeface"); ALOGD("Using Harfbuzz Script %d, Style %d", script, currentStyle); #endif return typeface; } break; bool TextLayoutShaper::isComplexScript(HB_Script script) { switch (script) { case HB_Script_Common: case HB_Script_Greek: case HB_Script_Cyrillic: case HB_Script_Hangul: case HB_Script_Inherited: return false; default: #if DEBUG_GLYPHS if (typeface) { ALOGD("Using Paint Typeface"); return true; } #endif break; } return typeface; } size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { Loading @@ -874,13 +775,7 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { // 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: case HB_Script_Bengali: case HB_Script_Devanagari: case HB_Script_Tamil: case HB_Script_Thai:{ if (isComplexScript(mShaperItem.item.script)) { const uint16_t* text16 = (const uint16_t*) (mShaperItem.string + mShaperItem.item.pos); const uint16_t* text16End = text16 + mShaperItem.item.length; firstUnichar = SkUTF16_NextUnichar(&text16); Loading @@ -888,23 +783,27 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { firstUnichar = SkUTF16_NextUnichar(&text16); } baseGlyphCount = paint->getBaseGlyphCount(firstUnichar); break; } default: 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); typeface = typefaceForScript(paint, typeface, mShaperItem.item.script); if (!typeface) { typeface = mDefaultTypeface; SkSafeRef(typeface); #if DEBUG_GLYPHS ALOGD("Using Default Typeface"); #endif } } else { if (!typeface) { typeface = mDefaultTypeface; #if DEBUG_GLYPHS ALOGD("Using Default Typeface"); #endif } SkSafeRef(typeface); } mShapingPaint.setTypeface(typeface); mShaperItem.face = getCachedHBFace(typeface); Loading @@ -912,6 +811,7 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) { ALOGD("Run typeface = %p, uniqueID = %d, hb_face = %p", typeface, typeface->uniqueID(), mShaperItem.face); #endif SkSafeUnref(typeface); // Shape assert(mShaperItem.item.length > 0); // Harfbuzz will overwrite other memory if length is 0. Loading Loading @@ -960,25 +860,6 @@ void TextLayoutShaper::deleteShaperItemGlyphArrays() { delete[] mShaperItem.log_clusters; } SkTypeface* TextLayoutShaper::getCachedTypeface(SkTypeface** typeface, HB_Script script, SkTypeface::Style style) { if (!*typeface) { *typeface = SkCreateTypefaceForScript(script, style); // CreateFromFile(path) can return NULL if the path is non existing if (!*typeface) { #if DEBUG_GLYPHS ALOGD("No font for Harfbuzz script %d, will use default font", script); #endif return mDefaultTypeface; } (*typeface)->ref(); #if DEBUG_GLYPHS ALOGD("Created SkTypeface for Harfbuzz script %d with uniqueID = %d", script, (*typeface)->uniqueID()); #endif } return *typeface; } HB_Face TextLayoutShaper::getCachedHBFace(SkTypeface* typeface) { SkFontID fontId = typeface->uniqueID(); ssize_t index = mCachedHBFaces.indexOfKey(fontId); Loading
core/jni/android/graphics/TextLayoutCache.h +4 −11 Original line number Diff line number Diff line Loading @@ -189,17 +189,9 @@ private: SkPaint mShapingPaint; /** * Skia typefaces cached for shaping * Skia default typeface to be returned if we cannot resolve script */ SkTypeface* mDefaultTypeface; SkTypeface* mArabicTypeface; SkTypeface* mHebrewRegularTypeface; SkTypeface* mHebrewBoldTypeface; SkTypeface* mBengaliTypeface; SkTypeface* mThaiTypeface; SkTypeface* mDevanagariRegularTypeface; SkTypeface* mTamilRegularTypeface; SkTypeface* mTamilBoldTypeface; /** * Cache of Harfbuzz faces Loading @@ -224,8 +216,8 @@ private: void init(); void unrefTypefaces(); SkTypeface* typefaceForUnichar(const SkPaint* paint, SkTypeface* typeface, SkUnichar unichar, HB_Script script); SkTypeface* typefaceForScript(const SkPaint* paint, SkTypeface* typeface, HB_Script script); size_t shapeFontRun(const SkPaint* paint, bool isRTL); Loading @@ -245,6 +237,7 @@ private: bool doShaping(size_t size); void createShaperItemGlyphArrays(size_t size); void deleteShaperItemGlyphArrays(); bool isComplexScript(HB_Script script); }; // TextLayoutShaper Loading