• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright 2011 Google Inc.
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8     http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15  */
16 
17 
18 #include "SkTypefaceCache.h"
19 #include "SkThread.h"
20 
21 #define TYPEFACE_CACHE_LIMIT    128
22 
add(SkTypeface * face,SkTypeface::Style requestedStyle)23 void SkTypefaceCache::add(SkTypeface* face, SkTypeface::Style requestedStyle) {
24     if (fArray.count() >= TYPEFACE_CACHE_LIMIT) {
25         this->purge(TYPEFACE_CACHE_LIMIT >> 2);
26     }
27 
28     Rec* rec = fArray.append();
29     rec->fFace = face;
30     rec->fRequestedStyle = requestedStyle;
31     face->ref();
32 }
33 
findByID(SkFontID fontID) const34 SkTypeface* SkTypefaceCache::findByID(SkFontID fontID) const {
35     const Rec* curr = fArray.begin();
36     const Rec* stop = fArray.end();
37     while (curr < stop) {
38         if (curr->fFace->uniqueID() == fontID) {
39             return curr->fFace;
40         }
41         curr += 1;
42     }
43     return NULL;
44 }
45 
findByProc(FindProc proc,void * ctx) const46 SkTypeface* SkTypefaceCache::findByProc(FindProc proc, void* ctx) const {
47     const Rec* curr = fArray.begin();
48     const Rec* stop = fArray.end();
49     while (curr < stop) {
50         if (proc(curr->fFace, curr->fRequestedStyle, ctx)) {
51             return curr->fFace;
52         }
53         curr += 1;
54     }
55     return NULL;
56 }
57 
purge(int numToPurge)58 void SkTypefaceCache::purge(int numToPurge) {
59     int count = fArray.count();
60     int i = 0;
61     while (i < count) {
62         SkTypeface* face = fArray[i].fFace;
63         if (1 == face->getRefCnt()) {
64             face->unref();
65             fArray.remove(i);
66             --count;
67             if (--numToPurge == 0) {
68                 return;
69             }
70         } else {
71             ++i;
72         }
73     }
74 }
75 
76 ///////////////////////////////////////////////////////////////////////////////
77 
Get()78 SkTypefaceCache& SkTypefaceCache::Get() {
79     static SkTypefaceCache gCache;
80     return gCache;
81 }
82 
NewFontID()83 SkFontID SkTypefaceCache::NewFontID() {
84     static int32_t gFontID;
85     return sk_atomic_inc(&gFontID) + 1;
86 }
87 
88 static SkMutex gMutex;
89 
Add(SkTypeface * face,SkTypeface::Style requestedStyle)90 void SkTypefaceCache::Add(SkTypeface* face, SkTypeface::Style requestedStyle) {
91     SkAutoMutexAcquire ama(gMutex);
92     Get().add(face, requestedStyle);
93 }
94 
FindByID(SkFontID fontID)95 SkTypeface* SkTypefaceCache::FindByID(SkFontID fontID) {
96     SkAutoMutexAcquire ama(gMutex);
97     return Get().findByID(fontID);
98 }
99 
FindByProc(FindProc proc,void * ctx)100 SkTypeface* SkTypefaceCache::FindByProc(FindProc proc, void* ctx) {
101     SkAutoMutexAcquire ama(gMutex);
102     return Get().findByProc(proc, ctx);
103 }
104 
105 ///////////////////////////////////////////////////////////////////////////////
106 
107 #ifdef SK_DEBUG
DumpProc(SkTypeface * face,SkTypeface::Style style,void * ctx)108 static bool DumpProc(SkTypeface* face, SkTypeface::Style style, void* ctx) {
109     SkDebugf("SkTypefaceCache: face %p fontID %d style %d refcnt %d\n",
110              face, face->uniqueID(), style, face->getRefCnt());
111     return false;
112 }
113 #endif
114 
Dump()115 void SkTypefaceCache::Dump() {
116 #ifdef SK_DEBUG
117     SkAutoMutexAcquire ama(gMutex);
118     (void)Get().findByProc(DumpProc, NULL);
119 #endif
120 }
121 
122