From 477d6cc7ee2536c028602637172c0793e09f5a2e Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Sat, 11 Oct 2014 19:12:15 -0700 Subject: [PATCH] zero-copy text_item insertion --- include/mapnik/text/harfbuzz_shaper.hpp | 10 ++++----- include/mapnik/text/itemizer.hpp | 27 +++++++++++++++++-------- src/text/itemizer.cpp | 12 +++-------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/include/mapnik/text/harfbuzz_shaper.hpp b/include/mapnik/text/harfbuzz_shaper.hpp index c78974b5c..a2b60bf3a 100644 --- a/include/mapnik/text/harfbuzz_shaper.hpp +++ b/include/mapnik/text/harfbuzz_shaper.hpp @@ -76,12 +76,12 @@ static void shape_text(text_line & line, hb_buffer_pre_allocate(buffer.get(), length); 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) { - 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; + 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; face_set->set_unscaled_character_sizes(); std::size_t num_faces = face_set->size(); std::size_t pos = 0; @@ -90,7 +90,7 @@ static void shape_text(text_line & line, ++pos; 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_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_font_t *font(hb_ft_font_create(face->get_face(), nullptr)); 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)) { g.face = face; - g.format = text_item.format; + g.format = text_item.format_; g.scale_multiplier = size / face->get_face()->units_per_EM; //Overwrite default advance with better value provided by HarfBuzz g.unscaled_advance = pos.x_advance; diff --git a/include/mapnik/text/itemizer.hpp b/include/mapnik/text/itemizer.hpp index ec2f66d89..047de6947 100644 --- a/include/mapnik/text/itemizer.hpp +++ b/include/mapnik/text/itemizer.hpp @@ -26,6 +26,7 @@ //mapnik #include #include +#include // stl #include @@ -36,18 +37,28 @@ #include #include #include + namespace mapnik { -struct text_item +struct text_item : noncopyable { - // First char (UTF16 offset) - unsigned start = 0u; - // Char _after_ the last char (UTF16 offset) - unsigned end = 0u; - UScriptCode script = USCRIPT_INVALID_CODE; - UBiDiDirection rtl = UBIDI_LTR; - evaluated_format_properties_ptr format; + text_item(unsigned s, + unsigned e, + UScriptCode sc, + UBiDiDirection d, + evaluated_format_properties_ptr f) + : start(s), + 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 diff --git a/src/text/itemizer.cpp b/src/text/itemizer.cpp index 29101b893..90be8d61f 100644 --- a/src/text/itemizer.cpp +++ b/src/text/itemizer.cpp @@ -177,21 +177,15 @@ void text_itemizer::create_item_list() { assert(script_itr != script_runs_.end()); assert(format_itr != format_runs_.end()); - text_item item; - item.start = position; + unsigned start = position; 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) { - output_.push_back(item); + output_.emplace_back(start,position,script_itr->data,dir_run.data,format_itr->data); } 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 (format_itr->end == position) ++format_itr;