Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 
      9 
     10 #include "SkTypefaceCache.h"
     11 #include "SkAtomics.h"
     12 #include "SkMutex.h"
     13 
     14 #define TYPEFACE_CACHE_LIMIT    1024
     15 
     16 SkTypefaceCache::SkTypefaceCache() {}
     17 
     18 void SkTypefaceCache::add(SkTypeface* face) {
     19     if (fTypefaces.count() >= TYPEFACE_CACHE_LIMIT) {
     20         this->purge(TYPEFACE_CACHE_LIMIT >> 2);
     21     }
     22 
     23     fTypefaces.emplace_back(SkRef(face));
     24 }
     25 
     26 SkTypeface* SkTypefaceCache::findByProcAndRef(FindProc proc, void* ctx) const {
     27     for (const sk_sp<SkTypeface>& typeface : fTypefaces) {
     28         if (proc(typeface.get(), ctx)) {
     29             return SkRef(typeface.get());
     30         }
     31     }
     32     return nullptr;
     33 }
     34 
     35 void SkTypefaceCache::purge(int numToPurge) {
     36     int count = fTypefaces.count();
     37     int i = 0;
     38     while (i < count) {
     39         if (fTypefaces[i]->unique()) {
     40             fTypefaces.removeShuffle(i);
     41             --count;
     42             if (--numToPurge == 0) {
     43                 return;
     44             }
     45         } else {
     46             ++i;
     47         }
     48     }
     49 }
     50 
     51 void SkTypefaceCache::purgeAll() {
     52     this->purge(fTypefaces.count());
     53 }
     54 
     55 ///////////////////////////////////////////////////////////////////////////////
     56 
     57 SkTypefaceCache& SkTypefaceCache::Get() {
     58     static SkTypefaceCache gCache;
     59     return gCache;
     60 }
     61 
     62 SkFontID SkTypefaceCache::NewFontID() {
     63     static int32_t gFontID;
     64     return sk_atomic_inc(&gFontID) + 1;
     65 }
     66 
     67 SK_DECLARE_STATIC_MUTEX(gMutex);
     68 
     69 void SkTypefaceCache::Add(SkTypeface* face) {
     70     SkAutoMutexAcquire ama(gMutex);
     71     Get().add(face);
     72 }
     73 
     74 SkTypeface* SkTypefaceCache::FindByProcAndRef(FindProc proc, void* ctx) {
     75     SkAutoMutexAcquire ama(gMutex);
     76     return Get().findByProcAndRef(proc, ctx);
     77 }
     78 
     79 void SkTypefaceCache::PurgeAll() {
     80     SkAutoMutexAcquire ama(gMutex);
     81     Get().purgeAll();
     82 }
     83 
     84 ///////////////////////////////////////////////////////////////////////////////
     85 
     86 #ifdef SK_DEBUG
     87 static bool DumpProc(SkTypeface* face, void* ctx) {
     88     SkString n;
     89     face->getFamilyName(&n);
     90     SkFontStyle s = face->fontStyle();
     91     SkFontID id = face->uniqueID();
     92     SkDebugf("SkTypefaceCache: face %p fontID %d weight %d width %d style %d refcnt %d name %s\n",
     93              face, id, s.weight(), s.width(), s.slant(), face->getRefCnt(), n.c_str());
     94     return false;
     95 }
     96 #endif
     97 
     98 void SkTypefaceCache::Dump() {
     99 #ifdef SK_DEBUG
    100     (void)Get().findByProcAndRef(DumpProc, nullptr);
    101 #endif
    102 }
    103