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