| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be found
in the LICENSE file. |
| 5 * found in the LICENSE file. | |
| 6 */ | 5 */ |
| 7 | 6 |
| 8 #ifndef SkGlyphCache_DEFINED | 7 #ifndef SkGlyphCache_DEFINED |
| 9 #define SkGlyphCache_DEFINED | 8 #define SkGlyphCache_DEFINED |
| 10 | 9 |
| 11 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
| 12 #include "SkChecksum.h" | 11 #include "SkChecksum.h" |
| 13 #include "SkChunkAlloc.h" | 12 #include "SkChunkAlloc.h" |
| 14 #include "SkDescriptor.h" | 13 #include "SkDescriptor.h" |
| 15 #include "SkGlyph.h" | 14 #include "SkGlyph.h" |
| 16 #include "SkScalerContext.h" | 15 #include "SkScalerContext.h" |
| 17 #include "SkTemplates.h" | 16 #include "SkTemplates.h" |
| 18 #include "SkTDArray.h" | 17 #include "SkTDArray.h" |
| 19 | 18 |
| 20 class SkPaint; | 19 class SkPaint; |
| 21 | 20 |
| 22 class SkGlyphCache_Globals; | 21 class SkGlyphCache_Globals; |
| 23 | 22 |
| 24 // Enable this locally to add stats for hash-table hit rates. It also extends th
e dump() | 23 // Enable this locally to add stats for hash-table hit rates. It also extends th
e dump() output |
| 25 // output to show those stats. | 24 // to show those stats. |
| 26 //#define SK_GLYPHCACHE_TRACK_HASH_STATS | 25 //#define SK_GLYPHCACHE_TRACK_HASH_STATS |
| 27 | 26 |
| 28 /** \class SkGlyphCache | 27 /** \class SkGlyphCache |
| 29 | 28 |
| 30 This class represents a strike: a specific combination of typeface, size, | 29 This class represents a strike: a specific combination of typeface, size, ma
trix, etc., and |
| 31 matrix, etc., and holds the glyphs for that strike. Calling any of the | 30 holds the glyphs for that strike. Calling any of the getUnichar.../getGlyphI
D... methods will |
| 32 getUnichar.../getGlyphID... methods will return the requested glyph, | 31 return the requested glyph, either instantly if it is already cached, or by
first generating |
| 33 either instantly if it is already cached, or by first generating it and then | 32 it and then adding it to the strike. |
| 34 adding it to the strike. | |
| 35 | 33 |
| 36 The strikes are held in a global list, available to all threads. To interact | 34 The strikes are held in a global list, available to all threads. To interact
with one, call |
| 37 with one, call either VisitCache() or DetachCache(). | 35 either VisitCache() or DetachCache(). |
| 38 */ | 36 */ |
| 39 class SkGlyphCache { | 37 class SkGlyphCache { |
| 40 public: | 38 public: |
| 41 /** Returns a glyph with valid fAdvance and fDevKern fields. | 39 /** Returns a glyph with valid fAdvance and fDevKern fields. The remaining f
ields may be |
| 42 The remaining fields may be valid, but that is not guaranteed. If you | 40 valid, but that is not guaranteed. If you require those, call getUnichar
Metrics or |
| 43 require those, call getUnicharMetrics or getGlyphIDMetrics instead. | 41 getGlyphIDMetrics instead. |
| 44 */ | 42 */ |
| 45 const SkGlyph& getUnicharAdvance(SkUnichar); | 43 const SkGlyph& getUnicharAdvance(SkUnichar); |
| 46 const SkGlyph& getGlyphIDAdvance(uint16_t); | 44 const SkGlyph& getGlyphIDAdvance(uint16_t); |
| 47 | 45 |
| 48 /** Returns a glyph with all fields valid except fImage and fPath, which | 46 /** Returns a glyph with all fields valid except fImage and fPath, which may
be null. If they |
| 49 may be null. If they are null, call findImage or findPath for those. | 47 are null, call findImage or findPath for those. If they are not null, th
en they are valid. |
| 50 If they are not null, then they are valid. | |
| 51 | 48 |
| 52 This call is potentially slower than the matching ...Advance call. If | 49 This call is potentially slower than the matching ...Advance call. If yo
u only need the |
| 53 you only need the fAdvance/fDevKern fields, call those instead. | 50 fAdvance/fDevKern fields, call those instead. |
| 54 */ | 51 */ |
| 55 const SkGlyph& getUnicharMetrics(SkUnichar); | 52 const SkGlyph& getUnicharMetrics(SkUnichar); |
| 56 const SkGlyph& getGlyphIDMetrics(uint16_t); | 53 const SkGlyph& getGlyphIDMetrics(uint16_t); |
| 57 | 54 |
| 58 /** These are variants that take the device position of the glyph. Call | 55 /** These are variants that take the device position of the glyph. Call thes
e only if you are |
| 59 these only if you are drawing in subpixel mode. Passing 0, 0 is | 56 drawing in subpixel mode. Passing 0, 0 is effectively the same as callin
g the variants |
| 60 effectively the same as calling the variants w/o the extra params, tho | 57 w/o the extra params, though a tiny bit slower. |
| 61 a tiny bit slower. | |
| 62 */ | 58 */ |
| 63 const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y); | 59 const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y); |
| 64 const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y); | 60 const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y); |
| 65 | 61 |
| 66 /** Return the glyphID for the specified Unichar. If the char has already | 62 /** Return the glyphID for the specified Unichar. If the char has already be
en seen, use the |
| 67 been seen, use the existing cache entry. If not, ask the scalercontext | 63 existing cache entry. If not, ask the scalercontext to compute it for us
. |
| 68 to compute it for us. | |
| 69 */ | 64 */ |
| 70 uint16_t unicharToGlyph(SkUnichar); | 65 uint16_t unicharToGlyph(SkUnichar); |
| 71 | 66 |
| 72 /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to | 67 /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to a char
acter code of zero. |
| 73 a character code of zero. | |
| 74 */ | 68 */ |
| 75 SkUnichar glyphToUnichar(uint16_t); | 69 SkUnichar glyphToUnichar(uint16_t); |
| 76 | 70 |
| 77 /** Returns the number of glyphs for this strike. | 71 /** Returns the number of glyphs for this strike. |
| 78 */ | 72 */ |
| 79 unsigned getGlyphCount(); | 73 unsigned getGlyphCount(); |
| 80 | 74 |
| 81 /** Return the image associated with the glyph. If it has not been generated | 75 /** Return the image associated with the glyph. If it has not been generated
this will |
| 82 this will trigger that. | 76 trigger that. |
| 83 */ | 77 */ |
| 84 const void* findImage(const SkGlyph&); | 78 const void* findImage(const SkGlyph&); |
| 85 /** Return the Path associated with the glyph. If it has not been generated | 79 |
| 86 this will trigger that. | 80 /** Return the Path associated with the glyph. If it has not been generated
this will trigger |
| 81 that. |
| 87 */ | 82 */ |
| 88 const SkPath* findPath(const SkGlyph&); | 83 const SkPath* findPath(const SkGlyph&); |
| 89 | 84 |
| 90 /** Return the vertical metrics for this strike. | 85 /** Return the vertical metrics for this strike. |
| 91 */ | 86 */ |
| 92 const SkPaint::FontMetrics& getFontMetrics() const { | 87 const SkPaint::FontMetrics& getFontMetrics() const { |
| 93 return fFontMetrics; | 88 return fFontMetrics; |
| 94 } | 89 } |
| 95 | 90 |
| 96 const SkDescriptor& getDescriptor() const { return *fDesc; } | 91 const SkDescriptor& getDescriptor() const { return *fDesc; } |
| 97 | 92 |
| 98 SkMask::Format getMaskFormat() const { | 93 SkMask::Format getMaskFormat() const { |
| 99 return fScalerContext->getMaskFormat(); | 94 return fScalerContext->getMaskFormat(); |
| 100 } | 95 } |
| 101 | 96 |
| 102 bool isSubpixel() const { | 97 bool isSubpixel() const { |
| 103 return fScalerContext->isSubpixel(); | 98 return fScalerContext->isSubpixel(); |
| 104 } | 99 } |
| 105 | 100 |
| 106 void dump() const; | 101 void dump() const; |
| 107 | 102 |
| 108 /* AuxProc/Data allow a client to associate data with this cache entry. | 103 /* AuxProc/Data allow a client to associate data with this cache entry. Mul
tiple clients can |
| 109 Multiple clients can use this, as their data is keyed with a function | 104 use this, as their data is keyed with a function pointer. In addition to
serving as a |
| 110 pointer. In addition to serving as a key, the function pointer is called | 105 key, the function pointer is called with the data when the glyphcache ob
ject is deleted, |
| 111 with the data when the glyphcache object is deleted, so the client can | 106 so the client can cleanup their data as well. |
| 112 cleanup their data as well. NOTE: the auxProc must not try to access | 107 NOTE: the auxProc must not try to access this glyphcache in any way, sin
ce it may be in |
| 113 this glyphcache in any way, since it may be in the process of being | 108 the process of being deleted. |
| 114 deleted. | |
| 115 */ | 109 */ |
| 116 | 110 |
| 117 //! If the proc is found, return true and set *dataPtr to its data | 111 //! If the proc is found, return true and set *dataPtr to its data |
| 118 bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const; | 112 bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const; |
| 113 |
| 119 //! Add a proc/data pair to the glyphcache. proc should be non-null | 114 //! Add a proc/data pair to the glyphcache. proc should be non-null |
| 120 void setAuxProc(void (*auxProc)(void*), void* auxData); | 115 void setAuxProc(void (*auxProc)(void*), void* auxData); |
| 121 | 116 |
| 122 SkScalerContext* getScalerContext() const { return fScalerContext; } | 117 SkScalerContext* getScalerContext() const { return fScalerContext; } |
| 123 | 118 |
| 124 /** Find a matching cache entry, and call proc() with it. If none is found | 119 /** Find a matching cache entry, and call proc() with it. If none is found c
reate a new one. |
| 125 create a new one. If the proc() returns true, detach the cache and | 120 If the proc() returns true, detach the cache and return it, otherwise le
ave it and return |
| 126 return it, otherwise leave it and return NULL. | 121 NULL. |
| 127 */ | 122 */ |
| 128 static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc, | 123 static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc, |
| 129 bool (*proc)(const SkGlyphCache*, void*), | 124 bool (*proc)(const SkGlyphCache*, void*), |
| 130 void* context); | 125 void* context); |
| 131 | 126 |
| 132 /** Given a strike that was returned by either VisitCache() or DetachCache() | 127 /** Given a strike that was returned by either VisitCache() or DetachCache()
add it back into |
| 133 add it back into the global cache list (after which the caller should | 128 the global cache list (after which the caller should not reference it an
ymore. |
| 134 not reference it anymore. | |
| 135 */ | 129 */ |
| 136 static void AttachCache(SkGlyphCache*); | 130 static void AttachCache(SkGlyphCache*); |
| 137 | 131 |
| 138 /** Detach a strike from the global cache matching the specified descriptor. | 132 /** Detach a strike from the global cache matching the specified descriptor.
Once detached, |
| 139 Once detached, it can be queried/modified by the current thread, and | 133 it can be queried/modified by the current thread, and when finished, be
reattached to the |
| 140 when finished, be reattached to the global cache with AttachCache(). | 134 global cache with AttachCache(). While detached, if another request is m
ade with the same |
| 141 While detached, if another request is made with the same descriptor, | 135 descriptor, a different strike will be generated. This is fine. It does
mean we can have |
| 142 a different strike will be generated. This is fine. It does mean we | 136 more than 1 strike for the same descriptor, but that will eventually get
purged, and the |
| 143 can have more than 1 strike for the same descriptor, but that will | 137 win is that different thread will never block each other while a strike
is being used. |
| 144 eventually get purged, and the win is that different thread will never | |
| 145 block each other while a strike is being used. | |
| 146 */ | 138 */ |
| 147 static SkGlyphCache* DetachCache(SkTypeface* typeface, | 139 static SkGlyphCache* DetachCache(SkTypeface* typeface, const SkDescriptor* d
esc) { |
| 148 const SkDescriptor* desc) { | |
| 149 return VisitCache(typeface, desc, DetachProc, NULL); | 140 return VisitCache(typeface, desc, DetachProc, NULL); |
| 150 } | 141 } |
| 151 | 142 |
| 152 static void Dump(); | 143 static void Dump(); |
| 153 | 144 |
| 154 #ifdef SK_DEBUG | 145 #ifdef SK_DEBUG |
| 155 void validate() const; | 146 void validate() const; |
| 156 #else | 147 #else |
| 157 void validate() const {} | 148 void validate() const {} |
| 158 #endif | 149 #endif |
| (...skipping 11 matching lines...) Expand all Loading... |
| 170 } | 161 } |
| 171 } | 162 } |
| 172 void forget() { | 163 void forget() { |
| 173 fCache = NULL; | 164 fCache = NULL; |
| 174 } | 165 } |
| 175 private: | 166 private: |
| 176 const SkGlyphCache* fCache; | 167 const SkGlyphCache* fCache; |
| 177 }; | 168 }; |
| 178 | 169 |
| 179 private: | 170 private: |
| 180 // we take ownership of the scalercontext | 171 friend class SkGlyphCache_Globals; |
| 181 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); | |
| 182 ~SkGlyphCache(); | |
| 183 | 172 |
| 184 enum MetricsType { | 173 enum MetricsType { |
| 185 kJustAdvance_MetricsType, | 174 kJustAdvance_MetricsType, |
| 186 kFull_MetricsType | 175 kFull_MetricsType |
| 187 }; | 176 }; |
| 188 | 177 |
| 189 // Return the SkGlyph* associated with MakeID. The id parameter is the combi
ned glyph/x/y | |
| 190 // id generated by MakeID. If it is just a glyph id then x and y are assuemd
to be zero. | |
| 191 SkGlyph* lookupByCombinedID(uint32_t id, MetricsType type); | |
| 192 | |
| 193 // Return a SkGlyph* associated with unicode id and position x and y. | |
| 194 SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed
y = 0); | |
| 195 | |
| 196 // Return the index of id in the fGlyphArray. If it does | |
| 197 // not exist, create a new one using MetricsType. | |
| 198 uint16_t lookupMetrics(uint32_t id, MetricsType type); | |
| 199 static bool DetachProc(const SkGlyphCache*, void*) { return true; } | |
| 200 | |
| 201 SkGlyphCache* fNext, *fPrev; | |
| 202 SkDescriptor* fDesc; | |
| 203 SkScalerContext* fScalerContext; | |
| 204 SkPaint::FontMetrics fFontMetrics; | |
| 205 | |
| 206 enum { | 178 enum { |
| 207 kHashBits = 8, | 179 kHashBits = 8, |
| 208 kHashCount = 1 << kHashBits, | 180 kHashCount = 1 << kHashBits, |
| 209 kHashMask = kHashCount - 1 | 181 kHashMask = kHashCount - 1 |
| 210 }; | 182 }; |
| 211 | 183 |
| 212 // A quick lookup to avoid the binary search looking for glyphs in fGlyphArr
ay. | |
| 213 uint16_t fGlyphHash[kHashCount]; | |
| 214 // Contains the SkGlyphs that are used by fGlyphHash and fCharToGlyphHash. T
he zero element | |
| 215 // is reserved for a sentinel SkGlyph that reduces the logic to check for co
llisions in the | |
| 216 // hash arrays. The zero element has an fID of SkGlyph::kImpossibleID which
never matches | |
| 217 // any combined id generated for a char or a glyph. | |
| 218 SkTDArray<SkGlyph> fGlyphArray; | |
| 219 SkChunkAlloc fGlyphAlloc; | |
| 220 | |
| 221 struct CharGlyphRec { | 184 struct CharGlyphRec { |
| 222 uint32_t fID; // unichar + subpixel | 185 uint32_t fID; // unichar + subpixel |
| 223 uint16_t fGlyphIndex; | 186 uint16_t fGlyphIndex; |
| 224 }; | 187 }; |
| 225 | 188 |
| 226 // no reason to use the same kHashCount as fGlyphHash, but we do for now | 189 struct AuxProcRec { |
| 227 // Dynamically allocated when chars are encountered. | 190 AuxProcRec* fNext; |
| 228 SkAutoTArray<CharGlyphRec> fCharToGlyphHash; | 191 void (*fProc)(void*); |
| 192 void* fData; |
| 193 }; |
| 194 |
| 195 // SkGlyphCache takes ownership of the scalercontext. |
| 196 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); |
| 197 ~SkGlyphCache(); |
| 198 |
| 199 // Return the SkGlyph* associated with MakeID. The id parameter is the |
| 200 // combined glyph/x/y id generated by MakeID. If it is just a glyph id |
| 201 // then x and y are assumed to be zero. |
| 202 SkGlyph* lookupByCombinedID(uint32_t id, MetricsType type); |
| 203 |
| 204 // Return a SkGlyph* associated with unicode id and position x and y. |
| 205 SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed
y = 0); |
| 206 |
| 207 // Return the index of id in the fGlyphArray. If it does not exist, |
| 208 // create a new one using MetricsType. |
| 209 uint16_t lookupMetrics(uint32_t id, MetricsType type); |
| 210 static bool DetachProc(const SkGlyphCache*, void*) { return true; } |
| 229 | 211 |
| 230 // The id arg is a combined id generated by MakeID. | 212 // The id arg is a combined id generated by MakeID. |
| 231 CharGlyphRec* getCharGlyphRec(uint32_t id); | 213 CharGlyphRec* getCharGlyphRec(uint32_t id); |
| 232 void adjustCaches(int insertion_index); | 214 void adjustCaches(int insertion_index); |
| 233 | 215 |
| 234 static inline unsigned ID2HashIndex(uint32_t h) { | 216 static inline unsigned ID2HashIndex(uint32_t h) { |
| 235 return SkChecksum::CheapMix(h) & kHashMask; | 217 return SkChecksum::CheapMix(h) & kHashMask; |
| 236 } | 218 } |
| 237 | 219 |
| 220 void invokeAndRemoveAuxProcs(); |
| 221 |
| 222 inline static SkGlyphCache* FindTail(SkGlyphCache* head); |
| 223 |
| 224 SkGlyphCache* fNext, *fPrev; |
| 225 SkDescriptor* fDesc; |
| 226 SkScalerContext* fScalerContext; |
| 227 SkPaint::FontMetrics fFontMetrics; |
| 228 |
| 229 // A quick lookup to avoid the binary search looking for glyphs in fGlyphArr
ay. |
| 230 uint16_t fGlyphHash[kHashCount]; |
| 231 |
| 232 // Contains the SkGlyphs that are used by fGlyphHash and fCharToGlyphHash. T
he ~0 element is |
| 233 // reserved for a sentinel SkGlyph that reduces the logic to check for colli
sions in the hash |
| 234 // arrays. The ~0 element has an fID of SkGlyph::kImpossibleID which never m
atches any |
| 235 // combined id generated for a char or a glyph. |
| 236 SkTDArray<SkGlyph> fGlyphArray; |
| 237 SkChunkAlloc fGlyphAlloc; |
| 238 |
| 239 // no reason to use the same kHashCount as fGlyphHash, but we do for now |
| 240 // Dynamically allocated when chars are encountered. |
| 241 SkAutoTArray<CharGlyphRec> fCharToGlyphHash; |
| 242 |
| 238 // used to track (approx) how much ram is tied-up in this cache | 243 // used to track (approx) how much ram is tied-up in this cache |
| 239 size_t fMemoryUsed; | 244 size_t fMemoryUsed; |
| 240 | 245 |
| 241 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | 246 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS |
| 242 int fHashHitCount; | 247 int fHashHitCount; |
| 243 int fHashMissCount; | 248 int fHashMissCount; |
| 244 #endif | 249 #endif |
| 245 | 250 |
| 246 struct AuxProcRec { | |
| 247 AuxProcRec* fNext; | |
| 248 void (*fProc)(void*); | |
| 249 void* fData; | |
| 250 }; | |
| 251 AuxProcRec* fAuxProcList; | 251 AuxProcRec* fAuxProcList; |
| 252 void invokeAndRemoveAuxProcs(); | |
| 253 | |
| 254 inline static SkGlyphCache* FindTail(SkGlyphCache* head); | |
| 255 | |
| 256 friend class SkGlyphCache_Globals; | |
| 257 }; | 252 }; |
| 258 | 253 |
| 259 class SkAutoGlyphCacheBase { | 254 class SkAutoGlyphCacheBase { |
| 260 public: | 255 public: |
| 261 SkGlyphCache* getCache() const { return fCache; } | 256 SkGlyphCache* getCache() const { return fCache; } |
| 262 | 257 |
| 263 void release() { | 258 void release() { |
| 264 if (fCache) { | 259 if (fCache) { |
| 265 SkGlyphCache::AttachCache(fCache); | 260 SkGlyphCache::AttachCache(fCache); |
| 266 fCache = NULL; | 261 fCache = NULL; |
| 267 } | 262 } |
| 268 } | 263 } |
| 269 | 264 |
| 270 protected: | 265 protected: |
| 271 // Hide the constructors so we can't create one of these directly. | 266 // Hide the constructors so we can't create one of these directly. Create Sk
AutoGlyphCache or |
| 272 // Create SkAutoGlyphCache or SkAutoGlyphCacheNoCache instead. | 267 // SkAutoGlyphCacheNoCache instead. |
| 273 SkAutoGlyphCacheBase(SkGlyphCache* cache) : fCache(cache) {} | 268 SkAutoGlyphCacheBase(SkGlyphCache* cache) : fCache(cache) {} |
| 274 SkAutoGlyphCacheBase(SkTypeface* typeface, const SkDescriptor* desc) { | 269 SkAutoGlyphCacheBase(SkTypeface* typeface, const SkDescriptor* desc) { |
| 275 fCache = SkGlyphCache::DetachCache(typeface, desc); | 270 fCache = SkGlyphCache::DetachCache(typeface, desc); |
| 276 } | 271 } |
| 277 SkAutoGlyphCacheBase(const SkPaint& /*paint*/, | 272 SkAutoGlyphCacheBase(const SkPaint& /*paint*/, |
| 278 const SkSurfaceProps* /*surfaceProps*/, | 273 const SkSurfaceProps* /*surfaceProps*/, |
| 279 const SkMatrix* /*matrix*/) { | 274 const SkMatrix* /*matrix*/) { |
| 280 fCache = NULL; | 275 fCache = NULL; |
| 281 } | 276 } |
| 282 SkAutoGlyphCacheBase() { | 277 SkAutoGlyphCacheBase() { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 const SkMatrix* matrix) { | 315 const SkMatrix* matrix) { |
| 321 fCache = paint.detachCache(surfaceProps, matrix, true); | 316 fCache = paint.detachCache(surfaceProps, matrix, true); |
| 322 } | 317 } |
| 323 | 318 |
| 324 private: | 319 private: |
| 325 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} | 320 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} |
| 326 }; | 321 }; |
| 327 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm
a) | 322 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm
a) |
| 328 | 323 |
| 329 #endif | 324 #endif |
| OLD | NEW |