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
14class GrFontCache::Key {
15public:
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
29private:
30    const GrKey* fFontScalerKey;
31};
32
33void 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
51GrTextStrike* 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 */
79class GrTextStrike::Key {
80public:
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
92private:
93    GrGlyph::PackedID fPackedID;
94};
95
96GrGlyph* 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
106