SkTypefaceCache.cpp 2.5 KB

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