• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkTypefaceCache()16 SkTypefaceCache::SkTypefaceCache() {}
17 
add(SkTypeface * face)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 
findByProcAndRef(FindProc proc,void * ctx) const26 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 
purge(int numToPurge)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 
purgeAll()51 void SkTypefaceCache::purgeAll() {
52     this->purge(fTypefaces.count());
53 }
54 
55 ///////////////////////////////////////////////////////////////////////////////
56 
Get()57 SkTypefaceCache& SkTypefaceCache::Get() {
58     static SkTypefaceCache gCache;
59     return gCache;
60 }
61 
NewFontID()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 
Add(SkTypeface * face)69 void SkTypefaceCache::Add(SkTypeface* face) {
70     SkAutoMutexAcquire ama(gMutex);
71     Get().add(face);
72 }
73 
FindByProcAndRef(FindProc proc,void * ctx)74 SkTypeface* SkTypefaceCache::FindByProcAndRef(FindProc proc, void* ctx) {
75     SkAutoMutexAcquire ama(gMutex);
76     return Get().findByProcAndRef(proc, ctx);
77 }
78 
PurgeAll()79 void SkTypefaceCache::PurgeAll() {
80     SkAutoMutexAcquire ama(gMutex);
81     Get().purgeAll();
82 }
83 
84 ///////////////////////////////////////////////////////////////////////////////
85 
86 #ifdef SK_DEBUG
DumpProc(SkTypeface * face,void * ctx)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 
Dump()98 void SkTypefaceCache::Dump() {
99 #ifdef SK_DEBUG
100     (void)Get().findByProcAndRef(DumpProc, nullptr);
101 #endif
102 }
103