diff --git a/include/mapnik/text/harfbuzz_shaper.hpp b/include/mapnik/text/harfbuzz_shaper.hpp index 8ba5d19ee..0f23bc844 100644 --- a/include/mapnik/text/harfbuzz_shaper.hpp +++ b/include/mapnik/text/harfbuzz_shaper.hpp @@ -93,6 +93,19 @@ static void shape_text(text_line & line, std::size_t pos = 0; font_feature_settings const& ff_settings = text_item.format_->ff_settings; int ff_count = safe_cast(ff_settings.count()); + + // rendering information for a single glyph + struct glyph_face_info + { + face_ptr face; + hb_glyph_info_t glyph; + hb_glyph_position_t position; + }; + // this table is filled with information for rendering each glyph, so that + // several font faces can be used in a single text_item + std::vector glyphinfos; + unsigned valid_glyphs = 0; + for (auto const& face : *face_set) { ++pos; @@ -112,20 +125,29 @@ static void shape_text(text_line & line, unsigned num_glyphs = hb_buffer_get_length(buffer.get()); + // if the number of rendered glyphs has increased, we need to resize the table + if (num_glyphs > glyphinfos.size()) + { + glyphinfos.resize(num_glyphs); + } + hb_glyph_info_t *glyphs = hb_buffer_get_glyph_infos(buffer.get(), nullptr); hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer.get(), nullptr); - bool font_has_all_glyphs = true; // Check if all glyphs are valid. for (unsigned i=0; iglyph_dimensions(g)) + if (theface->glyph_dimensions(g)) { - g.face = face; - g.scale_multiplier = size / face->get_face()->units_per_EM; + g.face = theface; + g.scale_multiplier = size / theface->get_face()->units_per_EM; //Overwrite default advance with better value provided by HarfBuzz g.unscaled_advance = gpos.x_advance; g.offset.set(gpos.x_offset * g.scale_multiplier, gpos.y_offset * g.scale_multiplier);