• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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