Basic FreeType renderer implementation.
[gdipp.git] / gdipp_server / glyph_cache.cpp
blob744443a7eff23aaa67428effaab13f1da2ee6477
1 #include "stdafx.h"
2 #include "glyph_cache.h"
3 #include "gdipp_lib/lock.h"
4 #include "gdipp_server/global.h"
6 namespace gdipp
9 glyph_cache::string_id_type glyph_cache::get_string_id(const wchar_t *string, unsigned int count, bool is_glyph_index)
11 string_id_type string_id;
12 #ifdef _M_X64
13 MurmurHash3_x64_128(string, count * sizeof(wchar_t), is_glyph_index, &string_id);
14 #else
15 MurmurHash3_x86_128(string, count * sizeof(wchar_t), is_glyph_index, &string_id);
16 #endif // _M_X64
18 return string_id;
21 glyph_cache::char_id_type glyph_cache::get_char_id(uint128_t render_trait, FT_UInt index, bool is_glyph_index)
24 character ID:
25 * low 64 bits: low 64 bits of render_trait
26 * high 64 bits:
27 high low
28 | 31 | 1 | 32 |
29 | render_trait (65 - 96 bit) | is_glyph_index | index |
31 char_id_type char_id = render_trait;
32 char_id.second = (char_id.second << 33) | (static_cast<uint64_t>(is_glyph_index) << 32) | index;
33 return char_id;
36 glyph_cache::~glyph_cache()
38 for (std::map<char_id_type, const FT_Glyph>::const_iterator glyph_iter = _glyph_store.begin(); glyph_iter != _glyph_store.end(); ++glyph_iter)
39 FT_Done_Glyph(glyph_iter->second);
41 for (std::map<uint128_t, trait_to_run_map>::const_iterator str_iter = _glyph_run_store.begin(); str_iter != _glyph_run_store.end(); ++str_iter)
43 for (trait_to_run_map::const_iterator trait_iter = str_iter->second.begin(); trait_iter != str_iter->second.end(); ++trait_iter)
44 delete trait_iter->second;
48 void glyph_cache::initialize()
50 _glyph_run_lru.resize(min(1 << server_cache_size, 16777216));
53 const FT_Glyph glyph_cache::lookup_glyph(char_id_type char_id) const
55 std::map<char_id_type, const FT_Glyph>::const_iterator glyph_iter = _glyph_store.find(char_id);
56 if (glyph_iter == _glyph_store.end())
58 lock l(lock::SERVER_GLYPH_CACHE);
59 glyph_iter = _glyph_store.find(char_id);
60 if (glyph_iter == _glyph_store.end())
61 return NULL;
64 return glyph_iter->second;
67 bool glyph_cache::store_glyph(char_id_type char_id, const FT_Glyph glyph)
69 lock l(lock::SERVER_GLYPH_CACHE);
71 const std::pair<std::map<char_id_type, const FT_Glyph>::const_iterator, bool> glyph_insert_ret = _glyph_store.insert(std::pair<uint128_t, const FT_Glyph>(char_id, glyph));
73 return glyph_insert_ret.second;
76 const glyph_run *glyph_cache::lookup_glyph_run(uint128_t string_id, uint128_t render_trait) const
78 lock l(lock::SERVER_GLYPH_RUN_CACHE);
80 std::map<uint128_t, trait_to_run_map>::const_iterator str_iter = _glyph_run_store.find(string_id);
81 if (str_iter == _glyph_run_store.end())
82 return NULL;
84 trait_to_run_map::const_iterator trait_iter = str_iter->second.find(render_trait);
85 if (trait_iter == str_iter->second.end())
86 return NULL;
88 return trait_iter->second;
91 bool glyph_cache::store_glyph_run(uint128_t string_id, uint128_t render_trait, glyph_run *a_glyph_run)
93 lock l(lock::SERVER_GLYPH_RUN_CACHE);
95 bool b_ret;
96 uint128_t erased_str;
98 b_ret = _glyph_run_lru.access(string_id, erased_str);
99 if (b_ret)
101 // the string is evicted from LRU cache
102 // erase all cached glyph run that is under the evicted string ID
104 std::map<uint128_t, trait_to_run_map>::iterator str_iter = _glyph_run_store.find(erased_str);
105 assert(str_iter != _glyph_run_store.end());
107 for (trait_to_run_map::const_iterator trait_iter = str_iter->second.begin(); trait_iter != str_iter->second.end(); ++trait_iter)
108 delete trait_iter->second;
110 _glyph_run_store.erase(str_iter);
113 // after eviction, insert new glyph_run
114 const std::pair<std::map<uint128_t, trait_to_run_map>::iterator, bool> str_insert_ret = _glyph_run_store.insert(std::pair<uint128_t, trait_to_run_map>(string_id, trait_to_run_map()));
115 const std::pair<trait_to_run_map::const_iterator, bool> trait_insert_ret = str_insert_ret.first->second.insert(std::pair<uint128_t, glyph_run *>(render_trait, a_glyph_run));
117 return trait_insert_ret.second;