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