Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 */
10 #ifndef SkGlyphCache_DEFINED
11 #define SkGlyphCache_DEFINED
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"
21 struct SkDeviceProperties;
22 class SkPaint;
24 class SkGlyphCache_Globals;
26 /** \class SkGlyphCache
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 cahced, or by first generating it and then
32 adding it to the strike.
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);
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.
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);
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);
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);
70 /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to
71 a character code of zero.
72 */
73 SkUnichar glyphToUnichar(uint16_t);
75 /** Returns the number of glyphs for this strike.
76 */
77 unsigned getGlyphCount();
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
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&);
96 /** Return the vertical metrics for this strike.
97 */
98 const SkPaint::FontMetrics& getFontMetrics() const {
99 return fFontMetrics;
100 }
102 const SkDescriptor& getDescriptor() const { return *fDesc; }
104 SkMask::Format getMaskFormat() const {
105 return fScalerContext->getMaskFormat();
106 }
108 bool isSubpixel() const {
109 return fScalerContext->isSubpixel();
110 }
112 /* AuxProc/Data allow a client to associate data with this cache entry.
113 Multiple clients can use this, as their data is keyed with a function
114 pointer. In addition to serving as a key, the function pointer is called
115 with the data when the glyphcache object is deleted, so the client can
116 cleanup their data as well. NOTE: the auxProc must not try to access
117 this glyphcache in any way, since it may be in the process of being
118 deleted.
119 */
121 //! If the proc is found, return true and set *dataPtr to its data
122 bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const;
123 //! Add a proc/data pair to the glyphcache. proc should be non-null
124 void setAuxProc(void (*auxProc)(void*), void* auxData);
126 SkScalerContext* getScalerContext() const { return fScalerContext; }
128 /** Call proc on all cache entries, stopping early if proc returns true.
129 The proc should not create or delete caches, since it could produce
130 deadlock.
131 */
132 static void VisitAllCaches(bool (*proc)(SkGlyphCache*, void*), void* ctx);
134 /** Find a matching cache entry, and call proc() with it. If none is found
135 create a new one. If the proc() returns true, detach the cache and
136 return it, otherwise leave it and return NULL.
137 */
138 static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc,
139 bool (*proc)(const SkGlyphCache*, void*),
140 void* context);
142 /** Given a strike that was returned by either VisitCache() or DetachCache()
143 add it back into the global cache list (after which the caller should
144 not reference it anymore.
145 */
146 static void AttachCache(SkGlyphCache*);
148 /** Detach a strike from the global cache matching the specified descriptor.
149 Once detached, it can be queried/modified by the current thread, and
150 when finished, be reattached to the global cache with AttachCache().
151 While detached, if another request is made with the same descriptor,
152 a different strike will be generated. This is fine. It does mean we
153 can have more than 1 strike for the same descriptor, but that will
154 eventually get purged, and the win is that different thread will never
155 block each other while a strike is being used.
156 */
157 static SkGlyphCache* DetachCache(SkTypeface* typeface,
158 const SkDescriptor* desc) {
159 return VisitCache(typeface, desc, DetachProc, NULL);
160 }
162 #ifdef SK_DEBUG
163 void validate() const;
164 #else
165 void validate() const {}
166 #endif
168 class AutoValidate : SkNoncopyable {
169 public:
170 AutoValidate(const SkGlyphCache* cache) : fCache(cache) {
171 if (fCache) {
172 fCache->validate();
173 }
174 }
175 ~AutoValidate() {
176 if (fCache) {
177 fCache->validate();
178 }
179 }
180 void forget() {
181 fCache = NULL;
182 }
183 private:
184 const SkGlyphCache* fCache;
185 };
187 private:
188 // we take ownership of the scalercontext
189 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*);
190 ~SkGlyphCache();
192 enum MetricsType {
193 kJustAdvance_MetricsType,
194 kFull_MetricsType
195 };
197 SkGlyph* lookupMetrics(uint32_t id, MetricsType);
198 static bool DetachProc(const SkGlyphCache*, void*) { return true; }
200 SkGlyphCache* fNext, *fPrev;
201 SkDescriptor* fDesc;
202 SkScalerContext* fScalerContext;
203 SkPaint::FontMetrics fFontMetrics;
205 enum {
206 kHashBits = 8,
207 kHashCount = 1 << kHashBits,
208 kHashMask = kHashCount - 1
209 };
210 SkGlyph* fGlyphHash[kHashCount];
211 SkTDArray<SkGlyph*> fGlyphArray;
212 SkChunkAlloc fGlyphAlloc;
214 struct CharGlyphRec {
215 uint32_t fID; // unichar + subpixel
216 SkGlyph* fGlyph;
217 };
218 // no reason to use the same kHashCount as fGlyphHash, but we do for now
219 CharGlyphRec fCharToGlyphHash[kHashCount];
221 static inline unsigned ID2HashIndex(uint32_t id) {
222 id ^= id >> 16;
223 id ^= id >> 8;
224 return id & kHashMask;
225 }
227 // used to track (approx) how much ram is tied-up in this cache
228 size_t fMemoryUsed;
230 struct AuxProcRec {
231 AuxProcRec* fNext;
232 void (*fProc)(void*);
233 void* fData;
234 };
235 AuxProcRec* fAuxProcList;
236 void invokeAndRemoveAuxProcs();
238 inline static SkGlyphCache* FindTail(SkGlyphCache* head);
240 friend class SkGlyphCache_Globals;
241 };
243 class SkAutoGlyphCache {
244 public:
245 SkAutoGlyphCache(SkGlyphCache* cache) : fCache(cache) {}
246 SkAutoGlyphCache(SkTypeface* typeface, const SkDescriptor* desc) {
247 fCache = SkGlyphCache::DetachCache(typeface, desc);
248 }
249 SkAutoGlyphCache(const SkPaint& paint,
250 const SkDeviceProperties* deviceProperties,
251 const SkMatrix* matrix) {
252 fCache = paint.detachCache(deviceProperties, matrix);
253 }
254 ~SkAutoGlyphCache() {
255 if (fCache) {
256 SkGlyphCache::AttachCache(fCache);
257 }
258 }
260 SkGlyphCache* getCache() const { return fCache; }
262 void release() {
263 if (fCache) {
264 SkGlyphCache::AttachCache(fCache);
265 fCache = NULL;
266 }
267 }
269 private:
270 SkGlyphCache* fCache;
272 static bool DetachProc(const SkGlyphCache*, void*);
273 };
274 #define SkAutoGlyphCache(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCache)
276 #endif