Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkGlyphCache.h
1
2 /*
3  * Copyright 2006 The Android Open Source Project
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 #ifndef SkGlyphCache_DEFINED
11 #define SkGlyphCache_DEFINED
12
13 #include "SkBitmap.h"
14 #include "SkChunkAlloc.h"
15 #include "SkDescriptor.h"
16 #include "SkGlyph.h"
17 #include "SkScalerContext.h"
18 #include "SkTemplates.h"
19 #include "SkTDArray.h"
20
21 struct SkDeviceProperties;
22 class SkPaint;
23
24 class SkGlyphCache_Globals;
25
26 /** \class SkGlyphCache
27
28     This class represents a strike: a specific combination of typeface, size,
29     matrix, etc., and holds the glyphs for that strike. Calling any of the
30     getUnichar.../getGlyphID... methods will return the requested glyph,
31     either instantly if it is already cached, or by first generating it and then
32     adding it to the strike.
33
34     The strikes are held in a global list, available to all threads. To interact
35     with one, call either VisitCache() or DetachCache().
36 */
37 class SkGlyphCache {
38 public:
39     /** Returns a glyph with valid fAdvance and fDevKern fields.
40         The remaining fields may be valid, but that is not guaranteed. If you
41         require those, call getUnicharMetrics or getGlyphIDMetrics instead.
42     */
43     const SkGlyph& getUnicharAdvance(SkUnichar);
44     const SkGlyph& getGlyphIDAdvance(uint16_t);
45
46     /** Returns a glyph with all fields valid except fImage and fPath, which
47         may be null. If they are null, call findImage or findPath for those.
48         If they are not null, then they are valid.
49
50         This call is potentially slower than the matching ...Advance call. If
51         you only need the fAdvance/fDevKern fields, call those instead.
52     */
53     const SkGlyph& getUnicharMetrics(SkUnichar);
54     const SkGlyph& getGlyphIDMetrics(uint16_t);
55
56     /** These are variants that take the device position of the glyph. Call
57         these only if you are drawing in subpixel mode. Passing 0, 0 is
58         effectively the same as calling the variants w/o the extra params, tho
59         a tiny bit slower.
60     */
61     const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y);
62     const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y);
63
64     /** Return the glyphID for the specified Unichar. If the char has already
65         been seen, use the existing cache entry. If not, ask the scalercontext
66         to compute it for us.
67     */
68     uint16_t unicharToGlyph(SkUnichar);
69
70     /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to
71         a character code of zero.
72     */
73     SkUnichar glyphToUnichar(uint16_t);
74
75     /** Returns the number of glyphs for this strike.
76     */
77     unsigned getGlyphCount();
78
79 #ifdef SK_BUILD_FOR_ANDROID
80     /** Returns the base glyph count for this strike.
81     */
82     unsigned getBaseGlyphCount(SkUnichar charCode) const {
83         return fScalerContext->getBaseGlyphCount(charCode);
84     }
85 #endif
86
87     /** Return the image associated with the glyph. If it has not been generated
88         this will trigger that.
89     */
90     const void* findImage(const SkGlyph&);
91     /** Return the Path associated with the glyph. If it has not been generated
92         this will trigger that.
93     */
94     const SkPath* findPath(const SkGlyph&);
95     /** Return the distance field associated with the glyph. If it has not been generated
96      this will trigger that.
97      */
98     const void* findDistanceField(const SkGlyph&);
99
100     /** Return the vertical metrics for this strike.
101     */
102     const SkPaint::FontMetrics& getFontMetrics() const {
103         return fFontMetrics;
104     }
105
106     const SkDescriptor& getDescriptor() const { return *fDesc; }
107
108     SkMask::Format getMaskFormat() const {
109         return fScalerContext->getMaskFormat();
110     }
111
112     bool isSubpixel() const {
113         return fScalerContext->isSubpixel();
114     }
115
116     /*  AuxProc/Data allow a client to associate data with this cache entry.
117         Multiple clients can use this, as their data is keyed with a function
118         pointer. In addition to serving as a key, the function pointer is called
119         with the data when the glyphcache object is deleted, so the client can
120         cleanup their data as well. NOTE: the auxProc must not try to access
121         this glyphcache in any way, since it may be in the process of being
122         deleted.
123     */
124
125     //! If the proc is found, return true and set *dataPtr to its data
126     bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const;
127     //! Add a proc/data pair to the glyphcache. proc should be non-null
128     void setAuxProc(void (*auxProc)(void*), void* auxData);
129
130     SkScalerContext* getScalerContext() const { return fScalerContext; }
131
132     /** Call proc on all cache entries, stopping early if proc returns true.
133         The proc should not create or delete caches, since it could produce
134         deadlock.
135     */
136     static void VisitAllCaches(bool (*proc)(SkGlyphCache*, void*), void* ctx);
137
138     /** Find a matching cache entry, and call proc() with it. If none is found
139         create a new one. If the proc() returns true, detach the cache and
140         return it, otherwise leave it and return NULL.
141     */
142     static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc,
143                                     bool (*proc)(const SkGlyphCache*, void*),
144                                     void* context);
145
146     /** Given a strike that was returned by either VisitCache() or DetachCache()
147         add it back into the global cache list (after which the caller should
148         not reference it anymore.
149     */
150     static void AttachCache(SkGlyphCache*);
151
152     /** Detach a strike from the global cache matching the specified descriptor.
153         Once detached, it can be queried/modified by the current thread, and
154         when finished, be reattached to the global cache with AttachCache().
155         While detached, if another request is made with the same descriptor,
156         a different strike will be generated. This is fine. It does mean we
157         can have more than 1 strike for the same descriptor, but that will
158         eventually get purged, and the win is that different thread will never
159         block each other while a strike is being used.
160     */
161     static SkGlyphCache* DetachCache(SkTypeface* typeface,
162                                      const SkDescriptor* desc) {
163         return VisitCache(typeface, desc, DetachProc, NULL);
164     }
165
166 #ifdef SK_DEBUG
167     void validate() const;
168 #else
169     void validate() const {}
170 #endif
171
172     class AutoValidate : SkNoncopyable {
173     public:
174         AutoValidate(const SkGlyphCache* cache) : fCache(cache) {
175             if (fCache) {
176                 fCache->validate();
177             }
178         }
179         ~AutoValidate() {
180             if (fCache) {
181                 fCache->validate();
182             }
183         }
184         void forget() {
185             fCache = NULL;
186         }
187     private:
188         const SkGlyphCache* fCache;
189     };
190
191 private:
192     // we take ownership of the scalercontext
193     SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*);
194     ~SkGlyphCache();
195
196     enum MetricsType {
197         kJustAdvance_MetricsType,
198         kFull_MetricsType
199     };
200
201     SkGlyph* lookupMetrics(uint32_t id, MetricsType);
202     static bool DetachProc(const SkGlyphCache*, void*) { return true; }
203
204     SkGlyphCache*       fNext, *fPrev;
205     SkDescriptor*       fDesc;
206     SkScalerContext*    fScalerContext;
207     SkPaint::FontMetrics fFontMetrics;
208
209     enum {
210         kHashBits   = 8,
211         kHashCount  = 1 << kHashBits,
212         kHashMask   = kHashCount - 1
213     };
214     SkGlyph*            fGlyphHash[kHashCount];
215     SkTDArray<SkGlyph*> fGlyphArray;
216     SkChunkAlloc        fGlyphAlloc;
217
218     struct CharGlyphRec {
219         uint32_t    fID;    // unichar + subpixel
220         SkGlyph*    fGlyph;
221     };
222     // no reason to use the same kHashCount as fGlyphHash, but we do for now
223     CharGlyphRec    fCharToGlyphHash[kHashCount];
224
225     static inline unsigned ID2HashIndex(uint32_t id) {
226         id ^= id >> 16;
227         id ^= id >> 8;
228         return id & kHashMask;
229     }
230
231     // used to track (approx) how much ram is tied-up in this cache
232     size_t  fMemoryUsed;
233
234     struct AuxProcRec {
235         AuxProcRec* fNext;
236         void (*fProc)(void*);
237         void* fData;
238     };
239     AuxProcRec* fAuxProcList;
240     void invokeAndRemoveAuxProcs();
241
242     inline static SkGlyphCache* FindTail(SkGlyphCache* head);
243
244     friend class SkGlyphCache_Globals;
245 };
246
247 class SkAutoGlyphCache {
248 public:
249     SkAutoGlyphCache(SkGlyphCache* cache) : fCache(cache) {}
250     SkAutoGlyphCache(SkTypeface* typeface, const SkDescriptor* desc) {
251         fCache = SkGlyphCache::DetachCache(typeface, desc);
252     }
253     SkAutoGlyphCache(const SkPaint& paint,
254                      const SkDeviceProperties* deviceProperties,
255                      const SkMatrix* matrix) {
256         fCache = paint.detachCache(deviceProperties, matrix);
257     }
258     ~SkAutoGlyphCache() {
259         if (fCache) {
260             SkGlyphCache::AttachCache(fCache);
261         }
262     }
263
264     SkGlyphCache* getCache() const { return fCache; }
265
266     void release() {
267         if (fCache) {
268             SkGlyphCache::AttachCache(fCache);
269             fCache = NULL;
270         }
271     }
272
273 private:
274     SkGlyphCache*   fCache;
275
276     static bool DetachProc(const SkGlyphCache*, void*);
277 };
278 #define SkAutoGlyphCache(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCache)
279
280 #endif