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 16SkTypefaceCache::SkTypefaceCache() {} 17 18void 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 26SkTypeface* 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 35void 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 51void SkTypefaceCache::purgeAll() { 52 this->purge(fTypefaces.count()); 53} 54 55/////////////////////////////////////////////////////////////////////////////// 56 57SkTypefaceCache& SkTypefaceCache::Get() { 58 static SkTypefaceCache gCache; 59 return gCache; 60} 61 62SkFontID SkTypefaceCache::NewFontID() { 63 static int32_t gFontID; 64 return sk_atomic_inc(&gFontID) + 1; 65} 66 67SK_DECLARE_STATIC_MUTEX(gMutex); 68 69void SkTypefaceCache::Add(SkTypeface* face) { 70 SkAutoMutexAcquire ama(gMutex); 71 Get().add(face); 72} 73 74SkTypeface* SkTypefaceCache::FindByProcAndRef(FindProc proc, void* ctx) { 75 SkAutoMutexAcquire ama(gMutex); 76 return Get().findByProcAndRef(proc, ctx); 77} 78 79void SkTypefaceCache::PurgeAll() { 80 SkAutoMutexAcquire ama(gMutex); 81 Get().purgeAll(); 82} 83 84/////////////////////////////////////////////////////////////////////////////// 85 86#ifdef SK_DEBUG 87static 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 98void SkTypefaceCache::Dump() { 99#ifdef SK_DEBUG 100 (void)Get().findByProcAndRef(DumpProc, nullptr); 101#endif 102} 103