use std::vector<std::vector<T>> instead of std::map<unsigned,std::vector> to simplify lookups

This commit is contained in:
artemp 2017-02-17 16:52:31 +01:00
parent 20cafae780
commit fbdff42d47

View file

@ -104,8 +104,9 @@ static void shape_text(text_line & line,
// this table is filled with information for rendering each glyph, so that // this table is filled with information for rendering each glyph, so that
// several font faces can be used in a single text_item // several font faces can be used in a single text_item
std::size_t pos = 0; std::size_t pos = 0;
std::map<unsigned, std::vector<glyph_face_info>> glyphinfos; std::vector<std::vector<glyph_face_info>> glyphinfos;
glyphinfos.resize(text.length());
for (auto const& face : *face_set) for (auto const& face : *face_set)
{ {
++pos; ++pos;
@ -147,35 +148,28 @@ static void shape_text(text_line & line,
{ {
in_cluster = true; in_cluster = true;
} }
if (glyphinfos.size() > cluster)
// if we have a valid codepoint, save rendering info.
auto itr = glyphinfos.find(cluster);
bool status = true;
if (itr == glyphinfos.end())
{ {
std::vector<glyph_face_info> v = {{ face, glyphs[i], positions[i] }}; auto & c = glyphinfos[cluster];
std::tie(itr, status) = glyphinfos.insert(std::make_pair(cluster, v)); if (c.empty())
}
if (status)
{
if (itr->second.front().glyph.codepoint == 0)
{ {
itr->second.front() = { face, glyphs[i], positions[i] }; c.push_back({face, glyphs[i], positions[i]});
}
if (c.front().glyph.codepoint == 0)
{
c.front() = { face, glyphs[i], positions[i] };
} }
else if (in_cluster) else if (in_cluster)
{ {
itr->second.push_back({ face, glyphs[i], positions[i] }); c.push_back({ face, glyphs[i], positions[i] });
} }
} }
} }
bool all_set = true; bool all_set = true;
for (auto c : clusters) for (auto c_id : clusters)
{ {
auto itr = glyphinfos.find(c); auto const& c = glyphinfos[c_id];
if (itr == glyphinfos.end() || itr->second.empty() || (itr->second.front().glyph.codepoint == 0)) if (c.empty() || c.front().glyph.codepoint == 0)
{ {
all_set = false; all_set = false;
break; break;
@ -187,34 +181,31 @@ static void shape_text(text_line & line,
continue; continue;
} }
double max_glyph_height = 0; double max_glyph_height = 0;
for (auto const& c : clusters) for (auto const& c_id : clusters)
{ {
auto itr = glyphinfos.find(c); auto const& c = glyphinfos[c_id];
if (itr != glyphinfos.end()) for (auto const& info : c)
{ {
for (auto const& info : itr->second) face_ptr theface = face;
auto & gpos = info.position;
auto & glyph = info.glyph;
if (info.glyph.codepoint != 0)
{ {
face_ptr theface = face; theface = info.face;
auto & gpos = info.position; }
auto & glyph = info.glyph; unsigned char_index = glyph.cluster;
if (info.glyph.codepoint != 0) glyph_info g(glyph.codepoint,char_index,text_item.format_);
{ if (theface->glyph_dimensions(g))
theface = info.face; {
} g.face = theface;
unsigned char_index = glyph.cluster; g.scale_multiplier = size / theface->get_face()->units_per_EM;
glyph_info g(glyph.codepoint,char_index,text_item.format_); //Overwrite default advance with better value provided by HarfBuzz
if (theface->glyph_dimensions(g)) g.unscaled_advance = gpos.x_advance;
{ g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier);
g.face = theface; double tmp_height = g.height();
g.scale_multiplier = size / theface->get_face()->units_per_EM; if (tmp_height > max_glyph_height) max_glyph_height = tmp_height;
//Overwrite default advance with better value provided by HarfBuzz width_map[char_index] += g.advance();
g.unscaled_advance = gpos.x_advance; line.add_glyph(std::move(g), scale_factor);
g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier);
double tmp_height = g.height();
if (tmp_height > max_glyph_height) max_glyph_height = tmp_height;
width_map[char_index] += g.advance();
line.add_glyph(std::move(g), scale_factor);
}
} }
} }
} }