zero-copy text_item insertion

This commit is contained in:
Dane Springmeyer 2014-10-11 19:12:15 -07:00
parent b455cc9098
commit 477d6cc7ee
3 changed files with 27 additions and 22 deletions

View file

@ -76,12 +76,12 @@ static void shape_text(text_line & line,
hb_buffer_pre_allocate(buffer.get(), length); hb_buffer_pre_allocate(buffer.get(), length);
mapnik::value_unicode_string const& text = itemizer.text(); mapnik::value_unicode_string const& text = itemizer.text();
font_feature_settings_ptr features = list.front().format->font_feature_settings; font_feature_settings_ptr features = list.front().format_->font_feature_settings;
for (auto const& text_item : list) for (auto const& text_item : list)
{ {
face_set_ptr face_set = font_manager.get_face_set(text_item.format->face_name, text_item.format->fontset); face_set_ptr face_set = font_manager.get_face_set(text_item.format_->face_name, text_item.format_->fontset);
double size = text_item.format->text_size * scale_factor; double size = text_item.format_->text_size * scale_factor;
face_set->set_unscaled_character_sizes(); face_set->set_unscaled_character_sizes();
std::size_t num_faces = face_set->size(); std::size_t num_faces = face_set->size();
std::size_t pos = 0; std::size_t pos = 0;
@ -90,7 +90,7 @@ static void shape_text(text_line & line,
++pos; ++pos;
hb_buffer_clear_contents(buffer.get()); hb_buffer_clear_contents(buffer.get());
hb_buffer_add_utf16(buffer.get(), uchar_to_utf16(text.getBuffer()), text.length(), text_item.start, text_item.end - text_item.start); hb_buffer_add_utf16(buffer.get(), uchar_to_utf16(text.getBuffer()), text.length(), text_item.start, text_item.end - text_item.start);
hb_buffer_set_direction(buffer.get(), (text_item.rtl == UBIDI_RTL)?HB_DIRECTION_RTL:HB_DIRECTION_LTR); hb_buffer_set_direction(buffer.get(), (text_item.dir == UBIDI_RTL)?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
hb_buffer_set_script(buffer.get(), _icu_script_to_script(text_item.script)); hb_buffer_set_script(buffer.get(), _icu_script_to_script(text_item.script));
hb_font_t *font(hb_ft_font_create(face->get_face(), nullptr)); hb_font_t *font(hb_ft_font_create(face->get_face(), nullptr));
hb_shape(font, buffer.get(), features->get_features(), features->count()); hb_shape(font, buffer.get(), features->get_features(), features->count());
@ -127,7 +127,7 @@ static void shape_text(text_line & line,
if (face->glyph_dimensions(g)) if (face->glyph_dimensions(g))
{ {
g.face = face; g.face = face;
g.format = text_item.format; g.format = text_item.format_;
g.scale_multiplier = size / face->get_face()->units_per_EM; g.scale_multiplier = size / face->get_face()->units_per_EM;
//Overwrite default advance with better value provided by HarfBuzz //Overwrite default advance with better value provided by HarfBuzz
g.unscaled_advance = pos.x_advance; g.unscaled_advance = pos.x_advance;

View file

@ -26,6 +26,7 @@
//mapnik //mapnik
#include <mapnik/text/evaluated_format_properties_ptr.hpp> #include <mapnik/text/evaluated_format_properties_ptr.hpp>
#include <mapnik/value_types.hpp> #include <mapnik/value_types.hpp>
#include <mapnik/noncopyable.hpp>
// stl // stl
#include <string> #include <string>
@ -36,18 +37,28 @@
#include <unicode/unistr.h> #include <unicode/unistr.h>
#include <unicode/uscript.h> #include <unicode/uscript.h>
#include <unicode/ubidi.h> #include <unicode/ubidi.h>
namespace mapnik namespace mapnik
{ {
struct text_item struct text_item : noncopyable
{ {
// First char (UTF16 offset) text_item(unsigned s,
unsigned start = 0u; unsigned e,
// Char _after_ the last char (UTF16 offset) UScriptCode sc,
unsigned end = 0u; UBiDiDirection d,
UScriptCode script = USCRIPT_INVALID_CODE; evaluated_format_properties_ptr f)
UBiDiDirection rtl = UBIDI_LTR; : start(s),
evaluated_format_properties_ptr format; end(e),
script(sc),
dir(d),
format_(f) {}
text_item( text_item && ) = default;
unsigned start; // First char (UTF16 offset)
unsigned end; // Char _after_ the last char (UTF16 offset)
UScriptCode script;
UBiDiDirection dir;
evaluated_format_properties_ptr format_;
}; };
// This class splits text into parts which all have the same // This class splits text into parts which all have the same

View file

@ -177,21 +177,15 @@ void text_itemizer::create_item_list()
{ {
assert(script_itr != script_runs_.end()); assert(script_itr != script_runs_.end());
assert(format_itr != format_runs_.end()); assert(format_itr != format_runs_.end());
text_item item; unsigned start = position;
item.start = position;
position = std::min(script_itr->end, std::min(format_itr->end, end)); position = std::min(script_itr->end, std::min(format_itr->end, end));
item.end = position;
item.format = format_itr->data;
item.script = script_itr->data;
item.rtl = dir_run.data;
if (dir_run.data == UBIDI_LTR) if (dir_run.data == UBIDI_LTR)
{ {
output_.push_back(item); output_.emplace_back(start,position,script_itr->data,dir_run.data,format_itr->data);
} }
else else
{ {
rtl_insertion_point = output_.insert(rtl_insertion_point, item); rtl_insertion_point = output_.emplace(rtl_insertion_point,start,position,script_itr->data,dir_run.data,format_itr->data);
} }
if (script_itr->end == position) ++script_itr; if (script_itr->end == position) ++script_itr;
if (format_itr->end == position) ++format_itr; if (format_itr->end == position) ++format_itr;