1 :
2 : /*
3 : * Copyright 2011 Google Inc.
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 :
11 : #include "SkTypefaceCache.h"
12 : #include "SkThread.h"
13 :
14 : #define TYPEFACE_CACHE_LIMIT 128
15 :
16 0 : void SkTypefaceCache::add(SkTypeface* face, SkTypeface::Style requestedStyle) {
17 0 : if (fArray.count() >= TYPEFACE_CACHE_LIMIT) {
18 0 : this->purge(TYPEFACE_CACHE_LIMIT >> 2);
19 : }
20 :
21 0 : Rec* rec = fArray.append();
22 0 : rec->fFace = face;
23 0 : rec->fRequestedStyle = requestedStyle;
24 0 : face->ref();
25 0 : }
26 :
27 0 : SkTypeface* SkTypefaceCache::findByID(SkFontID fontID) const {
28 0 : const Rec* curr = fArray.begin();
29 0 : const Rec* stop = fArray.end();
30 0 : while (curr < stop) {
31 0 : if (curr->fFace->uniqueID() == fontID) {
32 0 : return curr->fFace;
33 : }
34 0 : curr += 1;
35 : }
36 0 : return NULL;
37 : }
38 :
39 0 : SkTypeface* SkTypefaceCache::findByProc(FindProc proc, void* ctx) const {
40 0 : const Rec* curr = fArray.begin();
41 0 : const Rec* stop = fArray.end();
42 0 : while (curr < stop) {
43 0 : if (proc(curr->fFace, curr->fRequestedStyle, ctx)) {
44 0 : return curr->fFace;
45 : }
46 0 : curr += 1;
47 : }
48 0 : return NULL;
49 : }
50 :
51 0 : void SkTypefaceCache::purge(int numToPurge) {
52 0 : int count = fArray.count();
53 0 : int i = 0;
54 0 : while (i < count) {
55 0 : SkTypeface* face = fArray[i].fFace;
56 0 : if (1 == face->getRefCnt()) {
57 0 : face->unref();
58 0 : fArray.remove(i);
59 0 : --count;
60 0 : if (--numToPurge == 0) {
61 0 : return;
62 : }
63 : } else {
64 0 : ++i;
65 : }
66 : }
67 : }
68 :
69 0 : void SkTypefaceCache::purgeAll() {
70 0 : this->purge(fArray.count());
71 0 : }
72 :
73 : ///////////////////////////////////////////////////////////////////////////////
74 :
75 0 : SkTypefaceCache& SkTypefaceCache::Get() {
76 0 : static SkTypefaceCache gCache;
77 0 : return gCache;
78 : }
79 :
80 0 : SkFontID SkTypefaceCache::NewFontID() {
81 : static int32_t gFontID;
82 0 : return sk_atomic_inc(&gFontID) + 1;
83 : }
84 :
85 1464 : static SkMutex gMutex;
86 :
87 0 : void SkTypefaceCache::Add(SkTypeface* face, SkTypeface::Style requestedStyle) {
88 0 : SkAutoMutexAcquire ama(gMutex);
89 0 : Get().add(face, requestedStyle);
90 0 : }
91 :
92 0 : SkTypeface* SkTypefaceCache::FindByID(SkFontID fontID) {
93 0 : SkAutoMutexAcquire ama(gMutex);
94 0 : return Get().findByID(fontID);
95 : }
96 :
97 0 : SkTypeface* SkTypefaceCache::FindByProc(FindProc proc, void* ctx) {
98 0 : SkAutoMutexAcquire ama(gMutex);
99 0 : return Get().findByProc(proc, ctx);
100 : }
101 :
102 0 : void SkTypefaceCache::PurgeAll() {
103 0 : Get().purgeAll();
104 0 : }
105 :
106 : ///////////////////////////////////////////////////////////////////////////////
107 :
108 : #ifdef SK_DEBUG
109 0 : static bool DumpProc(SkTypeface* face, SkTypeface::Style style, void* ctx) {
110 : SkDebugf("SkTypefaceCache: face %p fontID %d style %d refcnt %d\n",
111 0 : face, face->uniqueID(), style, face->getRefCnt());
112 0 : return false;
113 : }
114 : #endif
115 :
116 0 : void SkTypefaceCache::Dump() {
117 : #ifdef SK_DEBUG
118 0 : SkAutoMutexAcquire ama(gMutex);
119 0 : (void)Get().findByProc(DumpProc, NULL);
120 : #endif
121 4392 : }
122 :
|