16 #ifndef AGG_FONT_CACHE_MANAGER_INCLUDED 17 #define AGG_FONT_CACHE_MANAGER_INCLUDED 20 #include "agg_array.h" 28 glyph_data_invalid = 0,
31 glyph_data_outline = 3
41 glyph_data_type data_type;
52 enum block_size_e { block_size = 16384-16 };
56 m_allocator(block_size),
61 void signature(
const char* font_signature)
63 m_font_signature = (
char*)m_allocator.allocate(std::strlen(font_signature) + 1);
64 std::strcpy(m_font_signature, font_signature);
65 std::memset(m_glyphs, 0,
sizeof(m_glyphs));
69 bool font_is(
const char* font_signature)
const 71 return std::strcmp(font_signature, m_font_signature) == 0;
75 const glyph_cache* find_glyph(
unsigned glyph_code)
const 77 unsigned msb = (glyph_code >> 8) & 0xFF;
80 return m_glyphs[msb][glyph_code & 0xFF];
89 glyph_data_type data_type,
94 unsigned msb = (glyph_code >> 8) & 0xFF;
95 if(m_glyphs[msb] == 0)
100 std::memset(m_glyphs[msb], 0,
sizeof(
glyph_cache*) * 256);
103 unsigned lsb = glyph_code & 0xFF;
104 if(m_glyphs[msb][lsb])
return 0;
110 glyph->glyph_index = glyph_index;
111 glyph->data = m_allocator.allocate(data_size);
112 glyph->data_size = data_size;
113 glyph->data_type = data_type;
114 glyph->bounds = bounds;
115 glyph->advance_x = advance_x;
116 glyph->advance_y = advance_y;
117 return m_glyphs[msb][lsb] = glyph;
123 char* m_font_signature;
140 for(i = 0; i < m_num_fonts; ++i)
150 m_max_fonts(max_fonts),
157 void font(
const char* font_signature,
bool reset_cache =
false)
159 int idx = find_font(font_signature);
166 m_fonts[idx]->signature(font_signature);
168 m_cur_font = m_fonts[idx];
172 if(m_num_fonts >= m_max_fonts)
178 m_num_fonts = m_max_fonts - 1;
181 m_fonts[m_num_fonts]->signature(font_signature);
182 m_cur_font = m_fonts[m_num_fonts];
194 const glyph_cache* find_glyph(
unsigned glyph_code)
const 196 if(m_cur_font)
return m_cur_font->find_glyph(glyph_code);
202 unsigned glyph_index,
204 glyph_data_type data_type,
211 return m_cur_font->cache_glyph(glyph_code,
224 int find_font(
const char* font_signature)
227 for(i = 0; i < m_num_fonts; i++)
229 if(m_fonts[i]->font_is(font_signature))
return int(i);
236 unsigned m_max_fonts;
237 unsigned m_num_fonts;
247 glyph_ren_native_mono,
248 glyph_ren_native_gray8,
261 typedef FontEngine font_engine_type;
263 typedef typename font_engine_type::path_adaptor_type path_adaptor_type;
264 typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type;
265 typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type;
266 typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type;
267 typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type;
279 void reset_last_glyph()
281 m_prev_glyph = m_last_glyph = 0;
288 const glyph_cache* gl = m_fonts.find_glyph(glyph_code);
291 m_prev_glyph = m_last_glyph;
292 return m_last_glyph = gl;
296 if(m_engine.prepare_glyph(glyph_code))
298 m_prev_glyph = m_last_glyph;
299 m_last_glyph = m_fonts.cache_glyph(glyph_code,
300 m_engine.glyph_index(),
301 m_engine.data_size(),
302 m_engine.data_type(),
304 m_engine.advance_x(),
305 m_engine.advance_y());
306 m_engine.write_glyph_to(m_last_glyph->data);
320 switch(gl->data_type)
323 case glyph_data_mono:
324 m_mono_adaptor.init(gl->data, gl->data_size, x, y);
327 case glyph_data_gray8:
328 m_gray8_adaptor.init(gl->data, gl->data_size, x, y);
331 case glyph_data_outline:
332 m_path_adaptor.init(gl->data, gl->data_size, x, y, scale);
340 path_adaptor_type& path_adaptor() {
return m_path_adaptor; }
341 gray8_adaptor_type& gray8_adaptor() {
return m_gray8_adaptor; }
342 gray8_scanline_type& gray8_scanline() {
return m_gray8_scanline; }
343 mono_adaptor_type& mono_adaptor() {
return m_mono_adaptor; }
344 mono_scanline_type& mono_scanline() {
return m_mono_scanline; }
347 const glyph_cache* perv_glyph()
const {
return m_prev_glyph; }
348 const glyph_cache* last_glyph()
const {
return m_last_glyph; }
351 bool add_kerning(
double* x,
double* y)
353 if(m_prev_glyph && m_last_glyph)
355 return m_engine.add_kerning(m_prev_glyph->glyph_index,
356 m_last_glyph->glyph_index,
363 void precache(
unsigned from,
unsigned to)
365 for(; from <= to; ++from) glyph(from);
371 m_fonts.font(m_engine.font_signature(),
true);
372 m_change_stamp = m_engine.change_stamp();
373 m_prev_glyph = m_last_glyph = 0;
379 const self_type& operator = (
const self_type&);
384 if(m_change_stamp != m_engine.change_stamp())
386 m_fonts.font(m_engine.font_signature());
387 m_change_stamp = m_engine.change_stamp();
388 m_prev_glyph = m_last_glyph = 0;
393 font_engine_type& m_engine;
399 path_adaptor_type m_path_adaptor;
400 gray8_adaptor_type m_gray8_adaptor;
401 gray8_scanline_type m_gray8_scanline;
402 mono_adaptor_type m_mono_adaptor;
403 mono_scanline_type m_mono_scanline;