|
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: |
|
16 explicit Key(const GrKey* fontScalarKey) { |
|
17 fFontScalerKey = fontScalarKey; |
|
18 } |
|
19 |
|
20 intptr_t getHash() const { return fFontScalerKey->getHash(); } |
|
21 |
|
22 static bool LessThan(const GrTextStrike& strike, const Key& key) { |
|
23 return *strike.getFontScalerKey() < *key.fFontScalerKey; |
|
24 } |
|
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 |
|
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 GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler, bool useDistanceField) { |
|
52 this->validate(); |
|
53 |
|
54 const Key key(scaler->getKey()); |
|
55 GrTextStrike* strike = fCache.find(key); |
|
56 if (NULL == strike) { |
|
57 strike = this->generateStrike(scaler, key); |
|
58 } else if (strike->fPrev) { |
|
59 // Need to put the strike at the head of its dllist, since that is how |
|
60 // we age the strikes for purging (we purge from the back of the list |
|
61 this->detachStrikeFromList(strike); |
|
62 // attach at the head |
|
63 fHead->fPrev = strike; |
|
64 strike->fNext = fHead; |
|
65 strike->fPrev = NULL; |
|
66 fHead = strike; |
|
67 } |
|
68 strike->fUseDistanceField = useDistanceField; |
|
69 this->validate(); |
|
70 return strike; |
|
71 } |
|
72 |
|
73 /////////////////////////////////////////////////////////////////////////////// |
|
74 |
|
75 /** |
|
76 * This Key just wraps a glyphID, and matches the protocol need for |
|
77 * GrTHashTable |
|
78 */ |
|
79 class GrTextStrike::Key { |
|
80 public: |
|
81 Key(GrGlyph::PackedID id) : fPackedID(id) {} |
|
82 |
|
83 uint32_t getHash() const { return fPackedID; } |
|
84 |
|
85 static bool LessThan(const GrGlyph& glyph, const Key& key) { |
|
86 return glyph.fPackedID < key.fPackedID; |
|
87 } |
|
88 static bool Equals(const GrGlyph& glyph, const Key& key) { |
|
89 return glyph.fPackedID == key.fPackedID; |
|
90 } |
|
91 |
|
92 private: |
|
93 GrGlyph::PackedID fPackedID; |
|
94 }; |
|
95 |
|
96 GrGlyph* GrTextStrike::getGlyph(GrGlyph::PackedID packed, |
|
97 GrFontScaler* scaler) { |
|
98 GrGlyph* glyph = fCache.find(packed); |
|
99 if (NULL == glyph) { |
|
100 glyph = this->generateGlyph(packed, scaler); |
|
101 } |
|
102 return glyph; |
|
103 } |
|
104 |
|
105 #endif |