PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
FontCache::FontCacheManager Class Reference

#include <FontCache.h>

Public Member Functions

TTF_Font * GetFont (const FontCacheKey &key, const std::string &full_path)
 
void ReleaseFont (const FontCacheKey &key)
 
void GetStats (int &unique_fonts, int &total_refs, int &cache_hits, int &cache_misses)
 
void PrintCache ()
 Print cache contents to stdout (for debugging)
 

Static Public Member Functions

static FontCacheManagerGetInstance ()
 Get singleton instance.
 

Detailed Description

Singleton font cache manager Eliminates duplicate TTF_Font objects for fonts that differ only in color

Example: font_red = MakeFont("DejaVuSans.ttf", normal, 24, red, white) font_blue = MakeFont("DejaVuSans.ttf", normal, 24, blue, white)

Without cache: 2 separate TTF_Font objects (~66KB) With cache: 1 shared TTF_Font object (~33KB) - 50% memory savings

The cache automatically manages TTF_Font lifecycle via reference counting.

Definition at line 46 of file FontCache.h.

Member Function Documentation

◆ GetFont()

TTF_Font * FontCache::FontCacheManager::GetFont ( const FontCacheKey key,
const std::string &  full_path 
)

Get or create TTF_Font for given key

Parameters
keyFont cache key (filename, style, size)
full_pathFull filesystem path to font file
Returns
TTF_Font pointer (may be shared), or nullptr on error

If font already in cache, increments ref count and returns existing font. Otherwise, loads font from disk, adds to cache, and returns new font.

Definition at line 42 of file FontCache.cpp.

42 {
43 // Look for font in cache
44 auto it = mCache.find(key);
45
46 if (it != mCache.end()) {
47 // Cache hit - font already loaded, increment ref count
48 it->second.ref_count++;
49 mCacheHits++;
50 return it->second.ttf_font;
51 }
52
53 // Cache miss - need to load font from disk
54 mCacheMisses++;
55
56 // Load font directly using TTF_OpenFont (no RWops/buffer needed)
57 // Modern systems can handle many open file descriptors
58 TTF_Font* new_font = TTF_OpenFont(full_path.c_str(), key.size);
59
60 if (!new_font) {
61 std::cerr << "[FontCache] ERROR: Failed to load font: " << full_path
62 << " - " << TTF_GetError() << std::endl;
63 return nullptr;
64 }
65
66 // Set font style (bold, italic, etc.)
67 TTF_SetFontStyle(new_font, key.style);
68
69 // Add to cache with ref count = 1
70 mCache.insert(std::make_pair(key, CachedTTFFont(new_font)));
71
72 return new_font;
73}

References FontCache::FontCacheKey::size, and FontCache::FontCacheKey::style.

Referenced by PlatformFont::PlatformFont(), PlatformFont::PlatformFont(), PlatformFont::SetFontSize(), and PlatformFont::SetFontStyle().

◆ GetInstance()

FontCacheManager & FontCache::FontCacheManager::GetInstance ( )
static

Get singleton instance.

Definition at line 33 of file FontCache.cpp.

33 {
34 static FontCacheManager instance;
35 return instance;
36}

Referenced by PlatformFont::PlatformFont(), PlatformFont::PlatformFont(), PlatformFont::SetFontSize(), PlatformFont::SetFontStyle(), and PlatformFont::~PlatformFont().

◆ GetStats()

void FontCache::FontCacheManager::GetStats ( int &  unique_fonts,
int &  total_refs,
int &  cache_hits,
int &  cache_misses 
)

Get cache statistics for debugging

Parameters
unique_fontsNumber of unique TTF_Font objects in cache
total_refsTotal reference count across all fonts
cache_hitsNumber of cache hits since program start
cache_missesNumber of cache misses since program start

Definition at line 119 of file FontCache.cpp.

120 {
121 unique_fonts = mCache.size();
122 total_refs = 0;
123
124 // Sum up all reference counts
125 for (const auto& pair : mCache) {
126 total_refs += pair.second.ref_count;
127 }
128
129 cache_hits = mCacheHits;
130 cache_misses = mCacheMisses;
131}

◆ PrintCache()

void FontCache::FontCacheManager::PrintCache ( )

Print cache contents to stdout (for debugging)

Definition at line 137 of file FontCache.cpp.

137 {
138 std::cout << "\n=== Font Cache Contents ===" << std::endl;
139 std::cout << "Unique fonts in cache: " << mCache.size() << std::endl;
140 std::cout << "Total cache hits: " << mCacheHits << std::endl;
141 std::cout << "Total cache misses: " << mCacheMisses << std::endl;
142
143 if (mCache.empty()) {
144 std::cout << "(cache is empty)" << std::endl;
145 } else {
146 std::cout << "\nCached fonts:" << std::endl;
147 for (const auto& pair : mCache) {
148 std::cout << " " << pair.first.filename
149 << " (style=" << pair.first.style
150 << ", size=" << pair.first.size
151 << ") refs=" << pair.second.ref_count << std::endl;
152 }
153 }
154 std::cout << "==========================\n" << std::endl;
155}

◆ ReleaseFont()

void FontCache::FontCacheManager::ReleaseFont ( const FontCacheKey key)

Release font reference

Parameters
keyFont cache key

Decrements ref count. If ref count reaches 0, closes TTF_Font and removes from cache. Should be called from PlatformFont destructor.

Definition at line 79 of file FontCache.cpp.

79 {
80 auto it = mCache.find(key);
81
82 if (it == mCache.end()) {
83 // This shouldn't happen if PlatformFont is correctly managing keys
84 std::cerr << "[FontCache] WARNING: Attempted to release non-cached font: "
85 << key.filename << " (style=" << key.style << ", size=" << key.size << ")"
86 << std::endl;
87 return;
88 }
89
90 // Decrement ref count
91 it->second.ref_count--;
92
93 #ifdef FONT_CACHE_DEBUG
94 std::cout << "[FontCache] RELEASE: " << key.filename
95 << " (style=" << key.style << ", size=" << key.size << ")"
96 << " refs=" << it->second.ref_count << std::endl;
97 #endif
98
99 // If no more references, close font and remove from cache
100 if (it->second.ref_count <= 0) {
101 if (it->second.ttf_font) {
102 TTF_CloseFont(it->second.ttf_font);
103 }
104
105 #ifdef FONT_CACHE_DEBUG
106 std::cout << "[FontCache] DELETED: " << key.filename
107 << " (style=" << key.style << ", size=" << key.size << ")"
108 << " cache_size=" << (mCache.size() - 1) << std::endl;
109 #endif
110
111 mCache.erase(it);
112 }
113}

References FontCache::FontCacheKey::filename, FontCache::FontCacheKey::size, and FontCache::FontCacheKey::style.

Referenced by PlatformFont::SetFontSize(), PlatformFont::SetFontStyle(), and PlatformFont::~PlatformFont().


The documentation for this class was generated from the following files: