Skip to content

Commit 9439da8

Browse files
authored
Merge pull request #117 from pkb/glyph_cache_fix
Fixed crash caused by incorrect comparison of glyph keys in glyph cache
2 parents 85ee41f + b3db949 commit 9439da8

File tree

4 files changed

+158
-187
lines changed

4 files changed

+158
-187
lines changed

crengine/include/lvfont.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ enum font_antialiasing_t {
3535
font_aa_all
3636
};
3737

38-
class LVFontGlyphCacheItem;
38+
struct LVFontGlyphCacheItem;
3939

4040
/** \brief base class for fonts
4141

crengine/src/private/lvfontglyphcache.cpp

Lines changed: 83 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -13,121 +13,7 @@
1313
*/
1414

1515
#include "lvfontglyphcache.h"
16-
#include "../../include/crlocks.h"
1716

18-
#if USE_GLYPHCACHE_HASHTABLE == 1
19-
inline lUInt32 getHash(GlyphCacheItemData data)
20-
{
21-
return getHash(*((lUInt32*)&data));
22-
}
23-
24-
inline bool operator==(GlyphCacheItemData data1, GlyphCacheItemData data2)
25-
{
26-
return (*((lUInt32*)&data1)) == (*((lUInt32*)&data2));
27-
}
28-
#endif
29-
30-
void LVFontLocalGlyphCache::clear() {
31-
FONT_LOCAL_GLYPH_CACHE_GUARD
32-
#if USE_GLYPHCACHE_HASHTABLE == 1
33-
LVHashTable<GlyphCacheItemData, struct LVFontGlyphCacheItem*>::iterator it = hashTable.forwardIterator();
34-
LVHashTable<GlyphCacheItemData, struct LVFontGlyphCacheItem*>::pair* pair;
35-
while ((pair = it.next()))
36-
{
37-
global_cache->remove(pair->value);
38-
LVFontGlyphCacheItem::freeItem(pair->value);
39-
}
40-
hashTable.clear();
41-
#else
42-
while (head) {
43-
LVFontGlyphCacheItem *ptr = head;
44-
remove(ptr);
45-
global_cache->remove(ptr);
46-
LVFontGlyphCacheItem::freeItem(ptr);
47-
}
48-
#endif
49-
}
50-
51-
LVFontGlyphCacheItem *LVFontLocalGlyphCache::get(lChar16 ch) {
52-
FONT_LOCAL_GLYPH_CACHE_GUARD
53-
#if USE_GLYPHCACHE_HASHTABLE == 1
54-
LVFontGlyphCacheItem *ptr = 0;
55-
GlyphCacheItemData data;
56-
data.ch = ch;
57-
if (hashTable.get(data, ptr))
58-
return ptr;
59-
#else
60-
LVFontGlyphCacheItem *ptr = head;
61-
for (; ptr; ptr = ptr->next_local) {
62-
if (ptr->data.ch == ch) {
63-
global_cache->refresh(ptr);
64-
return ptr;
65-
}
66-
}
67-
#endif
68-
return NULL;
69-
}
70-
71-
#if USE_HARFBUZZ==1
72-
LVFontGlyphCacheItem*LVFontLocalGlyphCache::getByIndex(lUInt32 index)
73-
{
74-
FONT_LOCAL_GLYPH_CACHE_GUARD
75-
#if USE_GLYPHCACHE_HASHTABLE == 1
76-
LVFontGlyphCacheItem *ptr = 0;
77-
GlyphCacheItemData data;
78-
data.gindex = index;
79-
if (hashTable.get(data, ptr))
80-
return ptr;
81-
#else
82-
LVFontGlyphCacheItem *ptr = head;
83-
for (; ptr; ptr = ptr->next_local) {
84-
if (ptr->data.gindex == index) {
85-
global_cache->refresh(ptr);
86-
return ptr;
87-
}
88-
}
89-
#endif
90-
return NULL;
91-
}
92-
#endif
93-
94-
void LVFontLocalGlyphCache::put(LVFontGlyphCacheItem *item) {
95-
FONT_LOCAL_GLYPH_CACHE_GUARD
96-
global_cache->put(item);
97-
#if USE_GLYPHCACHE_HASHTABLE == 1
98-
hashTable.set(item->data, item);
99-
#else
100-
item->next_local = head;
101-
if (head)
102-
head->prev_local = item;
103-
if (!tail)
104-
tail = item;
105-
head = item;
106-
#endif
107-
}
108-
109-
/// remove from list, but don't delete
110-
void LVFontLocalGlyphCache::remove(LVFontGlyphCacheItem *item) {
111-
FONT_LOCAL_GLYPH_CACHE_GUARD
112-
#if USE_GLYPHCACHE_HASHTABLE == 1
113-
hashTable.remove(item->data);
114-
#else
115-
if (item == head)
116-
head = item->next_local;
117-
if (item == tail)
118-
tail = item->prev_local;
119-
if (!head || !tail)
120-
return;
121-
if (item->prev_local)
122-
item->prev_local->next_local = item->next_local;
123-
if (item->next_local)
124-
item->next_local->prev_local = item->prev_local;
125-
item->next_local = NULL;
126-
item->prev_local = NULL;
127-
#endif
128-
}
129-
130-
#if USE_GLYPHCACHE_HASHTABLE != 1
13117
void LVFontGlobalGlyphCache::refresh(LVFontGlyphCacheItem *item) {
13218
FONT_GLYPH_CACHE_GUARD
13319
if (tail != item) {
@@ -136,7 +22,6 @@ void LVFontGlobalGlyphCache::refresh(LVFontGlyphCacheItem *item) {
13622
putNoLock(item);
13723
}
13824
}
139-
#endif
14025

14126
void LVFontGlobalGlyphCache::put(LVFontGlyphCacheItem *item) {
14227
FONT_GLYPH_CACHE_GUARD
@@ -195,32 +80,12 @@ void LVFontGlobalGlyphCache::clear() {
19580
}
19681
}
19782

198-
LVFontGlyphCacheItem *LVFontGlyphCacheItem::newItem(LVFontLocalGlyphCache *local_cache, lChar16 ch, int w, int h) {
199-
LVFontGlyphCacheItem *item = (LVFontGlyphCacheItem *) malloc(sizeof(LVFontGlyphCacheItem)
200-
+ (w * h - 1) * sizeof(lUInt8));
201-
if (item) {
202-
item->data.ch = ch;
203-
item->bmp_width = (lUInt16) w;
204-
item->bmp_height = (lUInt16) h;
205-
item->origin_x = 0;
206-
item->origin_y = 0;
207-
item->advance = 0;
208-
item->prev_global = NULL;
209-
item->next_global = NULL;
210-
item->prev_local = NULL;
211-
item->next_local = NULL;
212-
item->local_cache = local_cache;
213-
}
214-
return item;
215-
}
216-
217-
#if USE_HARFBUZZ==1
218-
LVFontGlyphCacheItem *LVFontGlyphCacheItem::newItem(LVFontLocalGlyphCache* local_cache, lUInt32 glyph_index, int w, int h)
83+
LVFontGlyphCacheItem *LVFontGlyphCacheItem::newItem(LVFontLocalGlyphCache* local_cache, LVFontGlyphCacheKeyType ch_or_index, int w, int h)
21984
{
22085
LVFontGlyphCacheItem *item = (LVFontGlyphCacheItem *) malloc(sizeof(LVFontGlyphCacheItem)
22186
+ (w * h - 1) * sizeof(lUInt8));
22287
if (item) {
223-
item->data.gindex = glyph_index;
88+
item->data = ch_or_index;
22489
item->bmp_width = (lUInt16) w;
22590
item->bmp_height = (lUInt16) h;
22691
item->origin_x = 0;
@@ -234,9 +99,89 @@ LVFontGlyphCacheItem *LVFontGlyphCacheItem::newItem(LVFontLocalGlyphCache* local
23499
}
235100
return item;
236101
}
237-
#endif // USE_HARFBUZZ==1
238102

239103
void LVFontGlyphCacheItem::freeItem(LVFontGlyphCacheItem *item) {
240104
if (item)
241105
::free(item);
242106
}
107+
108+
LVFontGlyphCacheItem *LVLocalGlyphCacheHashTableStorage::get(lUInt32 ch)
109+
{
110+
LVFontGlyphCacheItem *ptr = 0;
111+
if (hashTable.get(ch, ptr))
112+
m_global_cache->refresh(ptr);
113+
return ptr;
114+
}
115+
116+
void LVLocalGlyphCacheHashTableStorage::put(LVFontGlyphCacheItem *item)
117+
{
118+
m_global_cache->put(item);
119+
hashTable.set(item->data, item);
120+
}
121+
122+
void LVLocalGlyphCacheHashTableStorage::remove(LVFontGlyphCacheItem *item)
123+
{
124+
hashTable.remove(item->data);
125+
}
126+
127+
void LVLocalGlyphCacheHashTableStorage::clear()
128+
{
129+
FONT_LOCAL_GLYPH_CACHE_GUARD
130+
131+
LVHashTable<lUInt32, struct LVFontGlyphCacheItem*>::iterator it = hashTable.forwardIterator();
132+
LVHashTable<lUInt32, struct LVFontGlyphCacheItem*>::pair* pair;
133+
while( (pair = it.next()) ) {
134+
m_global_cache->remove(pair->value);
135+
LVFontGlyphCacheItem::freeItem(pair->value);
136+
}
137+
hashTable.clear();
138+
}
139+
140+
LVFontGlyphCacheItem *LVLocalGlyphCacheListStorage::get(lUInt32 ch)
141+
{
142+
LVFontGlyphCacheItem *ptr = head;
143+
for (; ptr; ptr = ptr->next_local) {
144+
if (ptr->data == ch) {
145+
m_global_cache->refresh(ptr);
146+
return ptr;
147+
}
148+
}
149+
return NULL;
150+
}
151+
152+
void LVLocalGlyphCacheListStorage::put(LVFontGlyphCacheItem *item)
153+
{
154+
m_global_cache->put(item);
155+
item->next_local = head;
156+
if (head)
157+
head->prev_local = item;
158+
if (!tail)
159+
tail = item;
160+
head = item;
161+
}
162+
163+
void LVLocalGlyphCacheListStorage::remove(LVFontGlyphCacheItem *item)
164+
{
165+
if (item == head)
166+
head = item->next_local;
167+
if (item == tail)
168+
tail = item->prev_local;
169+
if (!head || !tail)
170+
return;
171+
if (item->prev_local)
172+
item->prev_local->next_local = item->next_local;
173+
if (item->next_local)
174+
item->next_local->prev_local = item->prev_local;
175+
item->next_local = NULL;
176+
item->prev_local = NULL;
177+
}
178+
179+
void LVLocalGlyphCacheListStorage::clear()
180+
{
181+
while (head) {
182+
LVFontGlyphCacheItem *ptr = head;
183+
remove(ptr);
184+
m_global_cache->remove(ptr);
185+
LVFontGlyphCacheItem::freeItem(ptr);
186+
}
187+
}

0 commit comments

Comments
 (0)