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