1
2 /*
3 * Copyright 2010 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 #ifndef GrTextStrike_impl_DEFINED
12 #define GrTextStrike_impl_DEFINED
13
14 class GrFontCache::Key {
15 public:
Key(const GrKey * fontScalarKey)16 explicit Key(const GrKey* fontScalarKey) {
17 fFontScalerKey = fontScalarKey;
18 }
19
getHash()20 intptr_t getHash() const { return fFontScalerKey->getHash(); }
21
LessThan(const GrTextStrike & strike,const Key & key)22 static bool LessThan(const GrTextStrike& strike, const Key& key) {
23 return *strike.getFontScalerKey() < *key.fFontScalerKey;
24 }
Equals(const GrTextStrike & strike,const Key & key)25 static bool Equals(const GrTextStrike& strike, const Key& key) {
26 return *strike.getFontScalerKey() == *key.fFontScalerKey;
27 }
28
29 private:
30 const GrKey* fFontScalerKey;
31 };
32
detachStrikeFromList(GrTextStrike * strike)33 void GrFontCache::detachStrikeFromList(GrTextStrike* strike) {
34 if (strike->fPrev) {
35 SkASSERT(fHead != strike);
36 strike->fPrev->fNext = strike->fNext;
37 } else {
38 SkASSERT(fHead == strike);
39 fHead = strike->fNext;
40 }
41
42 if (strike->fNext) {
43 SkASSERT(fTail != strike);
44 strike->fNext->fPrev = strike->fPrev;
45 } else {
46 SkASSERT(fTail == strike);
47 fTail = strike->fPrev;
48 }
49 }
50
51 #if SK_DISTANCEFIELD_FONTS
getStrike(GrFontScaler * scaler,bool useDistanceField)52 GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler, bool useDistanceField) {
53 #else
54 GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler) {
55 #endif
56 this->validate();
57
58 const Key key(scaler->getKey());
59 GrTextStrike* strike = fCache.find(key);
60 if (NULL == strike) {
61 strike = this->generateStrike(scaler, key);
62 } else if (strike->fPrev) {
63 // Need to put the strike at the head of its dllist, since that is how
64 // we age the strikes for purging (we purge from the back of the list
65 this->detachStrikeFromList(strike);
66 // attach at the head
67 fHead->fPrev = strike;
68 strike->fNext = fHead;
69 strike->fPrev = NULL;
70 fHead = strike;
71 }
72 #if SK_DISTANCEFIELD_FONTS
73 strike->fUseDistanceField = useDistanceField;
74 #endif
75 this->validate();
76 return strike;
77 }
78
79 ///////////////////////////////////////////////////////////////////////////////
80
81 /**
82 * This Key just wraps a glyphID, and matches the protocol need for
83 * GrTHashTable
84 */
85 class GrTextStrike::Key {
86 public:
87 Key(GrGlyph::PackedID id) : fPackedID(id) {}
88
89 uint32_t getHash() const { return fPackedID; }
90
91 static bool LessThan(const GrGlyph& glyph, const Key& key) {
92 return glyph.fPackedID < key.fPackedID;
93 }
94 static bool Equals(const GrGlyph& glyph, const Key& key) {
95 return glyph.fPackedID == key.fPackedID;
96 }
97
98 private:
99 GrGlyph::PackedID fPackedID;
100 };
101
102 GrGlyph* GrTextStrike::getGlyph(GrGlyph::PackedID packed,
103 GrFontScaler* scaler) {
104 GrGlyph* glyph = fCache.find(packed);
105 if (NULL == glyph) {
106 glyph = this->generateGlyph(packed, scaler);
107 }
108 return glyph;
109 }
110
111 #endif
112