gfx/skia/trunk/src/core/SkGlyphCache.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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

mercurial