@@ -35,18 +35,13 @@ namespace android {
3535#define TYPEFACE_BENGALI " /system/fonts/Lohit-Bengali.ttf"
3636#define TYPEFACE_THAI " /system/fonts/DroidSansThai.ttf"
3737
38- #if USE_TEXT_LAYOUT_CACHE
39-
40- ANDROID_SINGLETON_STATIC_INSTANCE (TextLayoutCache);
41-
42- #endif
43-
44- ANDROID_SINGLETON_STATIC_INSTANCE (TextLayoutEngine);
38+ ANDROID_SINGLETON_STATIC_INSTANCE (TextLayoutEngine);
4539
4640// --------------------------------------------------------------------------------------------------
4741
48- TextLayoutCache::TextLayoutCache () :
49- mCache (GenerationCache<TextLayoutCacheKey, sp<TextLayoutCacheValue> >::kUnlimitedCapacity ),
42+ TextLayoutCache::TextLayoutCache (TextLayoutShaper* shaper) :
43+ mShaper (shaper),
44+ mCache (GenerationCache<TextLayoutCacheKey, sp<TextLayoutValue> >::kUnlimitedCapacity ),
5045 mSize (0 ), mMaxSize (MB(DEFAULT_TEXT_LAYOUT_CACHE_SIZE_IN_MB)),
5146 mCacheHitCount (0 ), mNanosecondsSaved (0 ) {
5247 init ();
@@ -75,7 +70,7 @@ void TextLayoutCache::init() {
7570/* *
7671 * Callbacks
7772 */
78- void TextLayoutCache::operator ()(TextLayoutCacheKey& text, sp<TextLayoutCacheValue >& desc) {
73+ void TextLayoutCache::operator ()(TextLayoutCacheKey& text, sp<TextLayoutValue >& desc) {
7974 size_t totalSizeToDelete = text.getSize () + desc->getSize ();
8075 mSize -= totalSizeToDelete;
8176 if (mDebugEnabled ) {
@@ -93,7 +88,7 @@ void TextLayoutCache::clear() {
9388/*
9489 * Caching
9590 */
96- sp<TextLayoutCacheValue > TextLayoutCache::getValue (const SkPaint* paint,
91+ sp<TextLayoutValue > TextLayoutCache::getValue (const SkPaint* paint,
9792 const jchar* text, jint start, jint count, jint contextCount, jint dirFlags) {
9893 AutoMutex _l (mLock );
9994 nsecs_t startTime = 0 ;
@@ -105,18 +100,18 @@ sp<TextLayoutCacheValue> TextLayoutCache::getValue(const SkPaint* paint,
105100 TextLayoutCacheKey key (paint, text, start, count, contextCount, dirFlags);
106101
107102 // Get value from cache if possible
108- sp<TextLayoutCacheValue > value = mCache .get (key);
103+ sp<TextLayoutValue > value = mCache .get (key);
109104
110105 // Value not found for the key, we need to add a new value in the cache
111106 if (value == NULL ) {
112107 if (mDebugEnabled ) {
113108 startTime = systemTime (SYSTEM_TIME_MONOTONIC);
114109 }
115110
116- value = new TextLayoutCacheValue (contextCount);
111+ value = new TextLayoutValue (contextCount);
117112
118113 // Compute advances and store them
119- TextLayoutEngine::getInstance (). computeValues (value.get (), paint,
114+ mShaper -> computeValues (value.get (), paint,
120115 reinterpret_cast <const UChar*>(text), start, count,
121116 size_t (contextCount), int (dirFlags));
122117
@@ -312,31 +307,33 @@ size_t TextLayoutCacheKey::getSize() const {
312307/* *
313308 * TextLayoutCacheValue
314309 */
315- TextLayoutCacheValue::TextLayoutCacheValue (size_t contextCount) :
310+ TextLayoutValue::TextLayoutValue (size_t contextCount) :
316311 mTotalAdvance(0 ), mElapsedTime(0 ) {
317312 // Give a hint for advances and glyphs vectors size
318313 mAdvances .setCapacity (contextCount);
319314 mGlyphs .setCapacity (contextCount);
320315}
321316
322- size_t TextLayoutCacheValue ::getSize () const {
323- return sizeof (TextLayoutCacheValue ) + sizeof (jfloat) * mAdvances .capacity () +
317+ size_t TextLayoutValue ::getSize () const {
318+ return sizeof (TextLayoutValue ) + sizeof (jfloat) * mAdvances .capacity () +
324319 sizeof (jchar) * mGlyphs .capacity ();
325320}
326321
327- void TextLayoutCacheValue ::setElapsedTime (uint32_t time) {
322+ void TextLayoutValue ::setElapsedTime (uint32_t time) {
328323 mElapsedTime = time;
329324}
330325
331- uint32_t TextLayoutCacheValue ::getElapsedTime () {
326+ uint32_t TextLayoutValue ::getElapsedTime () {
332327 return mElapsedTime ;
333328}
334329
335- TextLayoutEngine::TextLayoutEngine () : mShaperItemGlyphArraySize(0 ) {
330+ TextLayoutShaper::TextLayoutShaper () : mShaperItemGlyphArraySize(0 ) {
336331 mDefaultTypeface = SkFontHost::CreateTypeface (NULL , NULL , NULL , 0 , SkTypeface::kNormal );
337332 mArabicTypeface = NULL ;
338333 mHebrewRegularTypeface = NULL ;
339334 mHebrewBoldTypeface = NULL ;
335+ mBengaliTypeface = NULL ;
336+ mThaiTypeface = NULL ;
340337
341338 mFontRec .klass = &harfbuzzSkiaClass;
342339 mFontRec .userData = 0 ;
@@ -355,12 +352,17 @@ TextLayoutEngine::TextLayoutEngine() : mShaperItemGlyphArraySize(0) {
355352 mShaperItem .font ->userData = &mShapingPaint ;
356353}
357354
358- TextLayoutEngine::~TextLayoutEngine () {
359- // FIXME should free fonts and caches but since this class is a singleton,
360- // we don't bother at the moment
355+ TextLayoutShaper::~TextLayoutShaper () {
356+ SkSafeUnref (mDefaultTypeface );
357+ SkSafeUnref (mArabicTypeface );
358+ SkSafeUnref (mHebrewRegularTypeface );
359+ SkSafeUnref (mHebrewBoldTypeface );
360+ SkSafeUnref (mBengaliTypeface );
361+ SkSafeUnref (mThaiTypeface );
362+ deleteShaperItemGlyphArrays ();
361363}
362364
363- void TextLayoutEngine ::computeValues (TextLayoutCacheValue * value, const SkPaint* paint, const UChar* chars,
365+ void TextLayoutShaper ::computeValues (TextLayoutValue * value, const SkPaint* paint, const UChar* chars,
364366 size_t start, size_t count, size_t contextCount, int dirFlags) {
365367
366368 computeValues (paint, chars, start, count, contextCount, dirFlags,
@@ -371,7 +373,7 @@ void TextLayoutEngine::computeValues(TextLayoutCacheValue* value, const SkPaint*
371373#endif
372374}
373375
374- void TextLayoutEngine ::computeValues (const SkPaint* paint, const UChar* chars,
376+ void TextLayoutShaper ::computeValues (const SkPaint* paint, const UChar* chars,
375377 size_t start, size_t count, size_t contextCount, int dirFlags,
376378 Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
377379 Vector<jchar>* const outGlyphs) {
@@ -513,7 +515,7 @@ static void logGlyphs(HB_ShaperItem shaperItem) {
513515 }
514516}
515517
516- void TextLayoutEngine ::computeRunValues (const SkPaint* paint, const UChar* chars,
518+ void TextLayoutShaper ::computeRunValues (const SkPaint* paint, const UChar* chars,
517519 size_t count, bool isRTL,
518520 Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
519521 Vector<jchar>* const outGlyphs) {
@@ -719,7 +721,7 @@ void TextLayoutEngine::computeRunValues(const SkPaint* paint, const UChar* chars
719721}
720722
721723
722- size_t TextLayoutEngine ::shapeFontRun (const SkPaint* paint, bool isRTL) {
724+ size_t TextLayoutShaper ::shapeFontRun (const SkPaint* paint, bool isRTL) {
723725 // Reset kerning
724726 mShaperItem .kerning_applied = false ;
725727
@@ -833,14 +835,14 @@ size_t TextLayoutEngine::shapeFontRun(const SkPaint* paint, bool isRTL) {
833835 return baseGlyphCount;
834836}
835837
836- void TextLayoutEngine ::ensureShaperItemGlyphArrays (size_t size) {
838+ void TextLayoutShaper ::ensureShaperItemGlyphArrays (size_t size) {
837839 if (size > mShaperItemGlyphArraySize ) {
838840 deleteShaperItemGlyphArrays ();
839841 createShaperItemGlyphArrays (size);
840842 }
841843}
842844
843- void TextLayoutEngine ::createShaperItemGlyphArrays (size_t size) {
845+ void TextLayoutShaper ::createShaperItemGlyphArrays (size_t size) {
844846#if DEBUG_GLYPHS
845847 ALOGD (" Creating Glyph Arrays with size = %d" , size);
846848#endif
@@ -858,15 +860,15 @@ void TextLayoutEngine::createShaperItemGlyphArrays(size_t size) {
858860 mShaperItem .log_clusters = new unsigned short [size];
859861}
860862
861- void TextLayoutEngine ::deleteShaperItemGlyphArrays () {
863+ void TextLayoutShaper ::deleteShaperItemGlyphArrays () {
862864 delete[] mShaperItem .glyphs ;
863865 delete[] mShaperItem .attributes ;
864866 delete[] mShaperItem .advances ;
865867 delete[] mShaperItem .offsets ;
866868 delete[] mShaperItem .log_clusters ;
867869}
868870
869- SkTypeface* TextLayoutEngine ::getCachedTypeface (SkTypeface** typeface, const char path[]) {
871+ SkTypeface* TextLayoutShaper ::getCachedTypeface (SkTypeface** typeface, const char path[]) {
870872 if (!*typeface) {
871873 *typeface = SkTypeface::CreateFromFile (path);
872874 // CreateFromFile(path) can return NULL if the path is non existing
@@ -884,7 +886,7 @@ SkTypeface* TextLayoutEngine::getCachedTypeface(SkTypeface** typeface, const cha
884886 return *typeface;
885887}
886888
887- HB_Face TextLayoutEngine ::getCachedHBFace (SkTypeface* typeface) {
889+ HB_Face TextLayoutShaper ::getCachedHBFace (SkTypeface* typeface) {
888890 SkFontID fontId = typeface->uniqueID ();
889891 ssize_t index = mCachedHBFaces .indexOfKey (fontId);
890892 if (index >= 0 ) {
@@ -900,4 +902,36 @@ HB_Face TextLayoutEngine::getCachedHBFace(SkTypeface* typeface) {
900902 return face;
901903}
902904
905+ TextLayoutEngine::TextLayoutEngine () {
906+ mShaper = new TextLayoutShaper ();
907+ #if USE_TEXT_LAYOUT_CACHE
908+ mTextLayoutCache = new TextLayoutCache (mShaper );
909+ #else
910+ mTextLayoutCache = NULL ;
911+ #endif
912+ }
913+
914+ TextLayoutEngine::~TextLayoutEngine () {
915+ delete mTextLayoutCache ;
916+ delete mShaper ;
917+ }
918+
919+ sp<TextLayoutValue> TextLayoutEngine::getValue (const SkPaint* paint, const jchar* text,
920+ jint start, jint count, jint contextCount, jint dirFlags) {
921+ sp<TextLayoutValue> value;
922+ #if USE_TEXT_LAYOUT_CACHE
923+ value = mTextLayoutCache ->getValue (paint, text, start, count,
924+ contextCount, dirFlags);
925+ if (value == NULL ) {
926+ ALOGE (" Cannot get TextLayoutCache value for text = '%s'" ,
927+ String8 (text + start, count).string ());
928+ }
929+ #else
930+ value = new TextLayoutValue (count);
931+ mShaper ->computeValues (value.get (), paint,
932+ reinterpret_cast <const UChar*>(text), start, count, contextCount, dirFlags);
933+ #endif
934+ return value;
935+ }
936+
903937} // namespace android
0 commit comments