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