Index: src/gpu/GrFontCache.h |
diff --git a/src/gpu/GrTextStrike.h b/src/gpu/GrFontCache.h |
similarity index 68% |
rename from src/gpu/GrTextStrike.h |
rename to src/gpu/GrFontCache.h |
index 09d7323179543950840c1f937e342fcc4dc9c2f0..6ee39d0c47ff035d3485f25248e84f38abe2105e 100644 |
--- a/src/gpu/GrTextStrike.h |
+++ b/src/gpu/GrFontCache.h |
@@ -34,7 +34,14 @@ public: |
const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; } |
GrFontCache* getFontCache() const { return fFontCache; } |
- inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*); |
+ inline GrGlyph* getGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler) { |
+ GrGlyph* glyph = fCache.find(packed); |
+ if (NULL == glyph) { |
+ glyph = this->generateGlyph(packed, scaler); |
+ } |
+ return glyph; |
+ } |
+ |
// returns true if glyph (or glyph+padding for distance field) |
// is too large to ever fit in texture atlas subregions (GrPlots) |
bool glyphTooLargeForAtlas(GrGlyph*); |
@@ -79,7 +86,26 @@ public: |
GrFontCache(GrGpu*); |
~GrFontCache(); |
- inline GrTextStrike* getStrike(GrFontScaler*, bool useDistanceField); |
+ inline GrTextStrike* getStrike(GrFontScaler* scaler, bool useDistanceField) { |
+ this->validate(); |
+ |
+ GrTextStrike* strike = fCache.find(*(scaler->getKey())); |
+ if (NULL == strike) { |
+ strike = this->generateStrike(scaler); |
+ } else if (strike->fPrev) { |
+ // Need to put the strike at the head of its dllist, since that is how |
+ // we age the strikes for purging (we purge from the back of the list) |
+ this->detachStrikeFromList(strike); |
+ // attach at the head |
+ fHead->fPrev = strike; |
+ strike->fNext = fHead; |
+ strike->fPrev = NULL; |
+ fHead = strike; |
+ } |
+ strike->fUseDistanceField = useDistanceField; |
+ this->validate(); |
+ return strike; |
+ } |
// add to texture atlas that matches this format |
GrPlot* addToAtlas(GrMaskFormat format, GrAtlas::ClientPlotUsage* usage, |
@@ -132,7 +158,25 @@ private: |
GrAtlas* fAtlases[kAtlasCount]; |
GrTextStrike* generateStrike(GrFontScaler*); |
- inline void detachStrikeFromList(GrTextStrike*); |
+ |
+ inline void detachStrikeFromList(GrTextStrike* strike) { |
+ if (strike->fPrev) { |
+ SkASSERT(fHead != strike); |
+ strike->fPrev->fNext = strike->fNext; |
+ } else { |
+ SkASSERT(fHead == strike); |
+ fHead = strike->fNext; |
+ } |
+ |
+ if (strike->fNext) { |
+ SkASSERT(fTail != strike); |
+ strike->fNext->fPrev = strike->fPrev; |
+ } else { |
+ SkASSERT(fTail == strike); |
+ fTail = strike->fPrev; |
+ } |
+ } |
+ |
void purgeStrike(GrTextStrike* strike); |
}; |