1 /** @file lvfontglyphcache.cpp
2 @brief font glyph cache implementation
3
4 CoolReader Engine
5
6
7 (c) Vadim Lopatin, 2000-2006
8 This source code is distributed under the terms of
9 GNU General Public License.
10
11 See LICENSE file for details.
12
13 */
14
15 // This file contains copy of class LVFontLocalGlyphCacheA from cr3.2.31
16
17 #include "lvfontglyphcache_a.h"
18 #include "../../include/crlocks.h"
19
20
clear()21 void LVFontLocalGlyphCacheA::clear() {
22 FONT_LOCAL_GLYPH_CACHE_GUARD
23 while (head) {
24 LVFontGlyphCacheItemA *ptr = head;
25 remove(ptr);
26 global_cache->remove(ptr);
27 LVFontGlyphCacheItemA::freeItem(ptr);
28 }
29 }
30
getByChar(lChar32 ch)31 LVFontGlyphCacheItemA *LVFontLocalGlyphCacheA::getByChar(lChar32 ch) {
32 FONT_LOCAL_GLYPH_CACHE_GUARD
33 LVFontGlyphCacheItemA *ptr = head;
34 for (; ptr; ptr = ptr->next_local) {
35 if (ptr->data.ch == ch) {
36 global_cache->refresh(ptr);
37 return ptr;
38 }
39 }
40 return NULL;
41 }
42
43 #if USE_HARFBUZZ==1
getByIndex(lUInt32 index)44 LVFontGlyphCacheItemA* LVFontLocalGlyphCacheA::getByIndex(lUInt32 index)
45 {
46 FONT_LOCAL_GLYPH_CACHE_GUARD
47 LVFontGlyphCacheItemA *ptr = head;
48 for (; ptr; ptr = ptr->next_local) {
49 if (ptr->data.gindex == index) {
50 global_cache->refresh(ptr);
51 return ptr;
52 }
53 }
54 return NULL;
55 }
56 #endif
57
put(LVFontGlyphCacheItemA * item)58 void LVFontLocalGlyphCacheA::put(LVFontGlyphCacheItemA *item) {
59 FONT_LOCAL_GLYPH_CACHE_GUARD
60 global_cache->put(item);
61 item->next_local = head;
62 if (head)
63 head->prev_local = item;
64 if (!tail)
65 tail = item;
66 head = item;
67 }
68
69 /// remove from list, but don't delete
remove(LVFontGlyphCacheItemA * item)70 void LVFontLocalGlyphCacheA::remove(LVFontGlyphCacheItemA *item) {
71 FONT_LOCAL_GLYPH_CACHE_GUARD
72 if (item == head)
73 head = item->next_local;
74 if (item == tail)
75 tail = item->prev_local;
76 if (!head || !tail)
77 return;
78 if (item->prev_local)
79 item->prev_local->next_local = item->next_local;
80 if (item->next_local)
81 item->next_local->prev_local = item->prev_local;
82 item->next_local = NULL;
83 item->prev_local = NULL;
84 }
85
refresh(LVFontGlyphCacheItemA * item)86 void LVFontGlobalGlyphCacheA::refresh(LVFontGlyphCacheItemA *item) {
87 FONT_GLYPH_CACHE_GUARD
88 if (tail != item) {
89 //move to head
90 removeNoLock(item);
91 putNoLock(item);
92 }
93 }
94
put(LVFontGlyphCacheItemA * item)95 void LVFontGlobalGlyphCacheA::put(LVFontGlyphCacheItemA *item) {
96 FONT_GLYPH_CACHE_GUARD
97 putNoLock(item);
98 }
99
putNoLock(LVFontGlyphCacheItemA * item)100 void LVFontGlobalGlyphCacheA::putNoLock(LVFontGlyphCacheItemA *item) {
101 int sz = item->getSize();
102 // remove extra items from tail
103 while (sz + size > max_size) {
104 LVFontGlyphCacheItemA *removed_item = tail;
105 if (!removed_item)
106 break;
107 removeNoLock(removed_item);
108 removed_item->local_cache->remove(removed_item);
109 LVFontGlyphCacheItemA::freeItem(removed_item);
110 }
111 // add new item to head
112 item->next_global = head;
113 if (head)
114 head->prev_global = item;
115 head = item;
116 if (!tail)
117 tail = item;
118 size += sz;
119 }
120
remove(LVFontGlyphCacheItemA * item)121 void LVFontGlobalGlyphCacheA::remove(LVFontGlyphCacheItemA *item) {
122 FONT_GLYPH_CACHE_GUARD
123 removeNoLock(item);
124 }
125
removeNoLock(LVFontGlyphCacheItemA * item)126 void LVFontGlobalGlyphCacheA::removeNoLock(LVFontGlyphCacheItemA *item) {
127 if (item == head)
128 head = item->next_global;
129 if (item == tail)
130 tail = item->prev_global;
131 if (!head || !tail)
132 return;
133 if (item->prev_global)
134 item->prev_global->next_global = item->next_global;
135 if (item->next_global)
136 item->next_global->prev_global = item->prev_global;
137 item->next_global = NULL;
138 item->prev_global = NULL;
139 size -= item->getSize();
140 }
141
clear()142 void LVFontGlobalGlyphCacheA::clear() {
143 FONT_GLYPH_CACHE_GUARD
144 while (head) {
145 LVFontGlyphCacheItemA *ptr = head;
146 remove(ptr);
147 ptr->local_cache->remove(ptr);
148 LVFontGlyphCacheItemA::freeItem(ptr);
149 }
150 }
151
newItem(LVFontLocalGlyphCacheA * local_cache,lChar32 ch,int w,int h)152 LVFontGlyphCacheItemA *LVFontGlyphCacheItemA::newItem(LVFontLocalGlyphCacheA *local_cache, lChar32 ch, int w, int h) {
153 LVFontGlyphCacheItemA *item = (LVFontGlyphCacheItemA *) malloc(sizeof(LVFontGlyphCacheItemA)
154 + (w * h - 1) * sizeof(lUInt8));
155 if (item) {
156 item->data.ch = ch;
157 item->bmp_width = (lUInt16) w;
158 item->bmp_height = (lUInt16) h;
159 item->origin_x = 0;
160 item->origin_y = 0;
161 item->advance = 0;
162 item->prev_global = NULL;
163 item->next_global = NULL;
164 item->prev_local = NULL;
165 item->next_local = NULL;
166 item->local_cache = local_cache;
167 }
168 return item;
169 }
170
171 #if USE_HARFBUZZ==1
newItem(LVFontLocalGlyphCacheA * local_cache,lUInt32 glyph_index,int w,int h)172 LVFontGlyphCacheItemA *LVFontGlyphCacheItemA::newItem(LVFontLocalGlyphCacheA* local_cache, lUInt32 glyph_index, int w, int h)
173 {
174 LVFontGlyphCacheItemA *item = (LVFontGlyphCacheItemA *) malloc(sizeof(LVFontGlyphCacheItemA)
175 + (w * h - 1) * sizeof(lUInt8));
176 if (item) {
177 item->data.gindex = glyph_index;
178 item->bmp_width = (lUInt16) w;
179 item->bmp_height = (lUInt16) h;
180 item->origin_x = 0;
181 item->origin_y = 0;
182 item->advance = 0;
183 item->prev_global = NULL;
184 item->next_global = NULL;
185 item->prev_local = NULL;
186 item->next_local = NULL;
187 item->local_cache = local_cache;
188 }
189 return item;
190 }
191 #endif // USE_HARFBUZZ==1
192
freeItem(LVFontGlyphCacheItemA * item)193 void LVFontGlyphCacheItemA::freeItem(LVFontGlyphCacheItemA *item) {
194 if (item)
195 ::free(item);
196 }
197