1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9 10 #include "SkTypefaceCache.h" 11 #include "SkAtomics.h" 12 #include "SkMutex.h" 13 14 #define TYPEFACE_CACHE_LIMIT 1024 15 16 SkTypefaceCache::SkTypefaceCache() {} 17 18 void SkTypefaceCache::add(SkTypeface* face) { 19 if (fTypefaces.count() >= TYPEFACE_CACHE_LIMIT) { 20 this->purge(TYPEFACE_CACHE_LIMIT >> 2); 21 } 22 23 fTypefaces.emplace_back(SkRef(face)); 24 } 25 26 SkTypeface* SkTypefaceCache::findByProcAndRef(FindProc proc, void* ctx) const { 27 for (const sk_sp<SkTypeface>& typeface : fTypefaces) { 28 if (proc(typeface.get(), ctx)) { 29 return SkRef(typeface.get()); 30 } 31 } 32 return nullptr; 33 } 34 35 void SkTypefaceCache::purge(int numToPurge) { 36 int count = fTypefaces.count(); 37 int i = 0; 38 while (i < count) { 39 if (fTypefaces[i]->unique()) { 40 fTypefaces.removeShuffle(i); 41 --count; 42 if (--numToPurge == 0) { 43 return; 44 } 45 } else { 46 ++i; 47 } 48 } 49 } 50 51 void SkTypefaceCache::purgeAll() { 52 this->purge(fTypefaces.count()); 53 } 54 55 /////////////////////////////////////////////////////////////////////////////// 56 57 SkTypefaceCache& SkTypefaceCache::Get() { 58 static SkTypefaceCache gCache; 59 return gCache; 60 } 61 62 SkFontID SkTypefaceCache::NewFontID() { 63 static int32_t gFontID; 64 return sk_atomic_inc(&gFontID) + 1; 65 } 66 67 SK_DECLARE_STATIC_MUTEX(gMutex); 68 69 void SkTypefaceCache::Add(SkTypeface* face) { 70 SkAutoMutexAcquire ama(gMutex); 71 Get().add(face); 72 } 73 74 SkTypeface* SkTypefaceCache::FindByProcAndRef(FindProc proc, void* ctx) { 75 SkAutoMutexAcquire ama(gMutex); 76 return Get().findByProcAndRef(proc, ctx); 77 } 78 79 void SkTypefaceCache::PurgeAll() { 80 SkAutoMutexAcquire ama(gMutex); 81 Get().purgeAll(); 82 } 83 84 /////////////////////////////////////////////////////////////////////////////// 85 86 #ifdef SK_DEBUG 87 static bool DumpProc(SkTypeface* face, void* ctx) { 88 SkString n; 89 face->getFamilyName(&n); 90 SkFontStyle s = face->fontStyle(); 91 SkFontID id = face->uniqueID(); 92 SkDebugf("SkTypefaceCache: face %p fontID %d weight %d width %d style %d refcnt %d name %s\n", 93 face, id, s.weight(), s.width(), s.slant(), face->getRefCnt(), n.c_str()); 94 return false; 95 } 96 #endif 97 98 void SkTypefaceCache::Dump() { 99 #ifdef SK_DEBUG 100 (void)Get().findByProcAndRef(DumpProc, nullptr); 101 #endif 102 } 103