Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkTypefaceCache.cpp
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    1024
15
16 SkTypefaceCache::SkTypefaceCache() {}
17
18 SkTypefaceCache::~SkTypefaceCache() {
19     const Rec* curr = fArray.begin();
20     const Rec* stop = fArray.end();
21     while (curr < stop) {
22         curr->fFace->unref();
23         curr += 1;
24     }
25 }
26
27 void SkTypefaceCache::add(SkTypeface* face, const SkFontStyle& requestedStyle) {
28     if (fArray.count() >= TYPEFACE_CACHE_LIMIT) {
29         this->purge(TYPEFACE_CACHE_LIMIT >> 2);
30     }
31
32     Rec* rec = fArray.append();
33     rec->fFace = SkRef(face);
34     rec->fRequestedStyle = requestedStyle;
35 }
36
37 SkTypeface* SkTypefaceCache::findByID(SkFontID fontID) const {
38     const Rec* curr = fArray.begin();
39     const Rec* stop = fArray.end();
40     while (curr < stop) {
41         if (curr->fFace->uniqueID() == fontID) {
42             return curr->fFace;
43         }
44         curr += 1;
45     }
46     return NULL;
47 }
48
49 SkTypeface* SkTypefaceCache::findByProcAndRef(FindProc proc, void* ctx) const {
50     const Rec* curr = fArray.begin();
51     const Rec* stop = fArray.end();
52     while (curr < stop) {
53         SkTypeface* currFace = curr->fFace;
54         if (proc(currFace, curr->fRequestedStyle, ctx)) {
55             return SkRef(currFace);
56         }
57         curr += 1;
58     }
59     return NULL;
60 }
61
62 void SkTypefaceCache::purge(int numToPurge) {
63     int count = fArray.count();
64     int i = 0;
65     while (i < count) {
66         SkTypeface* face = fArray[i].fFace;
67         if (face->unique()) {
68             face->unref();
69             fArray.remove(i);
70             --count;
71             if (--numToPurge == 0) {
72                 return;
73             }
74         } else {
75             ++i;
76         }
77     }
78 }
79
80 void SkTypefaceCache::purgeAll() {
81     this->purge(fArray.count());
82 }
83
84 ///////////////////////////////////////////////////////////////////////////////
85
86 SkTypefaceCache& SkTypefaceCache::Get() {
87     static SkTypefaceCache gCache;
88     return gCache;
89 }
90
91 SkFontID SkTypefaceCache::NewFontID() {
92     static int32_t gFontID;
93     return sk_atomic_inc(&gFontID) + 1;
94 }
95
96 SK_DECLARE_STATIC_MUTEX(gMutex);
97
98 void SkTypefaceCache::Add(SkTypeface* face, const SkFontStyle& requestedStyle) {
99     SkAutoMutexAcquire ama(gMutex);
100     Get().add(face, requestedStyle);
101 }
102
103 SkTypeface* SkTypefaceCache::FindByID(SkFontID fontID) {
104     SkAutoMutexAcquire ama(gMutex);
105     return Get().findByID(fontID);
106 }
107
108 SkTypeface* SkTypefaceCache::FindByProcAndRef(FindProc proc, void* ctx) {
109     SkAutoMutexAcquire ama(gMutex);
110     SkTypeface* typeface = Get().findByProcAndRef(proc, ctx);
111     return typeface;
112 }
113
114 void SkTypefaceCache::PurgeAll() {
115     SkAutoMutexAcquire ama(gMutex);
116     Get().purgeAll();
117 }
118
119 ///////////////////////////////////////////////////////////////////////////////
120
121 #ifdef SK_DEBUG
122 static bool DumpProc(SkTypeface* face, const SkFontStyle& s, void* ctx) {
123     SkDebugf("SkTypefaceCache: face %p fontID %d weight %d width %d style %d refcnt %d\n",
124              face, face->uniqueID(), s.weight(), s.width(), s.slant(), face->getRefCnt());
125     return false;
126 }
127 #endif
128
129 void SkTypefaceCache::Dump() {
130 #ifdef SK_DEBUG
131     SkAutoMutexAcquire ama(gMutex);
132     (void)Get().findByProcAndRef(DumpProc, NULL);
133 #endif
134 }