1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkGlyphCache_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGlyphCache_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBitmap.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkChunkAlloc.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDescriptor.h" 16bbe50131413098bffed9186660c41f047d881596bungeman@google.com#include "SkGlyph.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalerContext.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 19227b516f233df5870d79d3f8dcbdaa02336b7356mike@reedtribe.org#include "SkTDArray.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.comstruct SkDeviceProperties; 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkPaint; 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkGlyphCache_Globals; 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkGlyphCache 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com This class represents a strike: a specific combination of typeface, size, 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix, etc., and holds the glyphs for that strike. Calling any of the 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com getUnichar.../getGlyphID... methods will return the requested glyph, 3153e1e4d88a06db62898a3bf75751c042729d7160commit-bot@chromium.org either instantly if it is already cached, or by first generating it and then 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com adding it to the strike. 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The strikes are held in a global list, available to all threads. To interact 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com with one, call either VisitCache() or DetachCache(). 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkGlyphCache { 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns a glyph with valid fAdvance and fDevKern fields. 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The remaining fields may be valid, but that is not guaranteed. If you 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com require those, call getUnicharMetrics or getGlyphIDMetrics instead. 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& getUnicharAdvance(SkUnichar); 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& getGlyphIDAdvance(uint16_t); 4598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns a glyph with all fields valid except fImage and fPath, which 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com may be null. If they are null, call findImage or findPath for those. 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If they are not null, then they are valid. 4998539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com This call is potentially slower than the matching ...Advance call. If 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com you only need the fAdvance/fDevKern fields, call those instead. 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& getUnicharMetrics(SkUnichar); 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& getGlyphIDMetrics(uint16_t); 5598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** These are variants that take the device position of the glyph. Call 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com these only if you are drawing in subpixel mode. Passing 0, 0 is 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com effectively the same as calling the variants w/o the extra params, tho 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a tiny bit slower. 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y); 6398539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the glyphID for the specified Unichar. If the char has already 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com been seen, use the existing cache entry. If not, ask the scalercontext 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to compute it for us. 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t unicharToGlyph(SkUnichar); 6998539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 709d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to 719d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com a character code of zero. 729d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com */ 739d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkUnichar glyphToUnichar(uint16_t); 749d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 750bc7bf5fe418191473f8325d89dd9e74be3ff928ctguil@chromium.org /** Returns the number of glyphs for this strike. 760bc7bf5fe418191473f8325d89dd9e74be3ff928ctguil@chromium.org */ 770bc7bf5fe418191473f8325d89dd9e74be3ff928ctguil@chromium.org unsigned getGlyphCount(); 780bc7bf5fe418191473f8325d89dd9e74be3ff928ctguil@chromium.org 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the image associated with the glyph. If it has not been generated 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this will trigger that. 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const void* findImage(const SkGlyph&); 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the Path associated with the glyph. If it has not been generated 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this will trigger that. 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath* findPath(const SkGlyph&); 87762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org /** Return the distance field associated with the glyph. If it has not been generated 88762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org this will trigger that. 89762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org */ 90762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org const void* findDistanceField(const SkGlyph&); 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the vertical metrics for this strike. 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 940a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com const SkPaint::FontMetrics& getFontMetrics() const { 950a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com return fFontMetrics; 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 97f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 98f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com const SkDescriptor& getDescriptor() const { return *fDesc; } 99f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 10098539c607b05f7e25406ae873bf1b24154a36a6freed@google.com SkMask::Format getMaskFormat() const { 10198539c607b05f7e25406ae873bf1b24154a36a6freed@google.com return fScalerContext->getMaskFormat(); 10298539c607b05f7e25406ae873bf1b24154a36a6freed@google.com } 10398539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 104abf00aaaa0262905ad19b0a0ed654c87276490fcreed@google.com bool isSubpixel() const { 105abf00aaaa0262905ad19b0a0ed654c87276490fcreed@google.com return fScalerContext->isSubpixel(); 106abf00aaaa0262905ad19b0a0ed654c87276490fcreed@google.com } 107abf00aaaa0262905ad19b0a0ed654c87276490fcreed@google.com 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* AuxProc/Data allow a client to associate data with this cache entry. 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Multiple clients can use this, as their data is keyed with a function 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pointer. In addition to serving as a key, the function pointer is called 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com with the data when the glyphcache object is deleted, so the client can 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com cleanup their data as well. NOTE: the auxProc must not try to access 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this glyphcache in any way, since it may be in the process of being 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com deleted. 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 11698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com //! If the proc is found, return true and set *dataPtr to its data 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const; 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com //! Add a proc/data pair to the glyphcache. proc should be non-null 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setAuxProc(void (*auxProc)(void*), void* auxData); 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12215eeca00684b4d5baad8e47c5b2f77404b978cb0djsollen@google.com SkScalerContext* getScalerContext() const { return fScalerContext; } 12315eeca00684b4d5baad8e47c5b2f77404b978cb0djsollen@google.com 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Find a matching cache entry, and call proc() with it. If none is found 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com create a new one. If the proc() returns true, detach the cache and 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return it, otherwise leave it and return NULL. 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 12890808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc, 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool (*proc)(const SkGlyphCache*, void*), 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* context); 13198539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Given a strike that was returned by either VisitCache() or DetachCache() 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com add it back into the global cache list (after which the caller should 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com not reference it anymore. 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static void AttachCache(SkGlyphCache*); 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Detach a strike from the global cache matching the specified descriptor. 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Once detached, it can be queried/modified by the current thread, and 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com when finished, be reattached to the global cache with AttachCache(). 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com While detached, if another request is made with the same descriptor, 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a different strike will be generated. This is fine. It does mean we 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com can have more than 1 strike for the same descriptor, but that will 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com eventually get purged, and the win is that different thread will never 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com block each other while a strike is being used. 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 14790808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com static SkGlyphCache* DetachCache(SkTypeface* typeface, 14890808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com const SkDescriptor* desc) { 14990808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com return VisitCache(typeface, desc, DetachProc, NULL); 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 152f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#ifdef SK_DEBUG 153f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com void validate() const; 154f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#else 155f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com void validate() const {} 156f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#endif 157f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 158f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com class AutoValidate : SkNoncopyable { 159f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com public: 160f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com AutoValidate(const SkGlyphCache* cache) : fCache(cache) { 161f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (fCache) { 162f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fCache->validate(); 163f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 164f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 165f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com ~AutoValidate() { 166f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (fCache) { 167f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fCache->validate(); 168f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 169f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 170f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com void forget() { 171f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com fCache = NULL; 172f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 173f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com private: 174f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com const SkGlyphCache* fCache; 175f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com }; 17698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1784b60dbe661feadc276f911ee6dfc2058e5aea7careed@google.com // we take ownership of the scalercontext 1794b60dbe661feadc276f911ee6dfc2058e5aea7careed@google.com SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkGlyphCache(); 18198539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum MetricsType { 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kJustAdvance_MetricsType, 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kFull_MetricsType 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyph* lookupMetrics(uint32_t id, MetricsType); 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static bool DetachProc(const SkGlyphCache*, void*) { return true; } 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* fNext, *fPrev; 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDescriptor* fDesc; 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalerContext* fScalerContext; 1930a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com SkPaint::FontMetrics fFontMetrics; 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum { 196262ff953a7f7e9e07b8fa9a792ade920aa5dd926reed@google.com kHashBits = 8, 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kHashCount = 1 << kHashBits, 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kHashMask = kHashCount - 1 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyph* fGlyphHash[kHashCount]; 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDArray<SkGlyph*> fGlyphArray; 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkChunkAlloc fGlyphAlloc; 20398539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com struct CharGlyphRec { 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t fID; // unichar + subpixel 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyph* fGlyph; 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // no reason to use the same kHashCount as fGlyphHash, but we do for now 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com CharGlyphRec fCharToGlyphHash[kHashCount]; 21098539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static inline unsigned ID2HashIndex(uint32_t id) { 212b8b619a15874f376196e3e6a8190ba4e3df0058breed@google.com id ^= id >> 16; 213b8b619a15874f376196e3e6a8190ba4e3df0058breed@google.com id ^= id >> 8; 214b8b619a15874f376196e3e6a8190ba4e3df0058breed@google.com return id & kHashMask; 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21698539c607b05f7e25406ae873bf1b24154a36a6freed@google.com 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // used to track (approx) how much ram is tied-up in this cache 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t fMemoryUsed; 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com struct AuxProcRec { 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com AuxProcRec* fNext; 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void (*fProc)(void*); 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void* fData; 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com AuxProcRec* fAuxProcList; 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void invokeAndRemoveAuxProcs(); 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inline static SkGlyphCache* FindTail(SkGlyphCache* head); 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class SkGlyphCache_Globals; 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2332d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthclass SkAutoGlyphCacheBase { 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2352d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkGlyphCache* getCache() const { return fCache; } 2362d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 2372d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth void release() { 238d11f0e0173b349bfac3c98f6d32c10dc7e1ba1famike@reedtribe.org if (fCache) { 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache::AttachCache(fCache); 2402d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fCache = NULL; 241d11f0e0173b349bfac3c98f6d32c10dc7e1ba1famike@reedtribe.org } 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2442d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthprotected: 2452d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // Hide the constructors so we can't create one of these directly. 2462d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth // Create SkAutoGlyphCache or SkAutoGlyphCacheNoCache instead. 2472d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheBase(SkGlyphCache* cache) : fCache(cache) {} 2482d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheBase(SkTypeface* typeface, const SkDescriptor* desc) { 2492d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fCache = SkGlyphCache::DetachCache(typeface, desc); 2502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 2512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheBase(const SkPaint& paint, 2522d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkDeviceProperties* deviceProperties, 2532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMatrix* matrix) { 2542d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fCache = NULL; 2552d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 2562d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheBase() { 2572d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fCache = NULL; 2582d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 2592d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth ~SkAutoGlyphCacheBase() { 260d11f0e0173b349bfac3c98f6d32c10dc7e1ba1famike@reedtribe.org if (fCache) { 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache::AttachCache(fCache); 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2644d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth 265919ed4c73633e92bfc6694161360c5c3f45728e8scroggo SkGlyphCache* fCache; 266919ed4c73633e92bfc6694161360c5c3f45728e8scroggo 2672d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthprivate: 268919ed4c73633e92bfc6694161360c5c3f45728e8scroggo static bool DetachProc(const SkGlyphCache*, void*); 269919ed4c73633e92bfc6694161360c5c3f45728e8scroggo}; 2702d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 2712d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthclass SkAutoGlyphCache : public SkAutoGlyphCacheBase { 2722d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthpublic: 2732d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCache(SkGlyphCache* cache) : SkAutoGlyphCacheBase(cache) {} 2742d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCache(SkTypeface* typeface, const SkDescriptor* desc) : 2752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheBase(typeface, desc) {} 2762d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCache(const SkPaint& paint, 2772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkDeviceProperties* deviceProperties, 2782d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMatrix* matrix) { 2792d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fCache = paint.detachCache(deviceProperties, matrix, false); 2802d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 2812d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 2822d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthprivate: 2832d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCache() : SkAutoGlyphCacheBase() {} 2842d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth}; 285919ed4c73633e92bfc6694161360c5c3f45728e8scroggo#define SkAutoGlyphCache(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCache) 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2872d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthclass SkAutoGlyphCacheNoGamma : public SkAutoGlyphCacheBase { 2882d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthpublic: 2892d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheNoGamma(SkGlyphCache* cache) : SkAutoGlyphCacheBase(cache) {} 2902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheNoGamma(SkTypeface* typeface, const SkDescriptor* desc) : 2912d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheBase(typeface, desc) {} 2922d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheNoGamma(const SkPaint& paint, 2932d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkDeviceProperties* deviceProperties, 2942d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMatrix* matrix) { 2952d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fCache = paint.detachCache(deviceProperties, matrix, true); 2962d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth } 2972d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 2982d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthprivate: 2992d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} 3002d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth}; 3012d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamma) 3022d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 304