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);
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;

View file

@ -26,6 +26,7 @@
//mapnik
#include <mapnik/text/evaluated_format_properties_ptr.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/noncopyable.hpp>
// stl
#include <string>
@ -36,18 +37,28 @@
#include <unicode/unistr.h>
#include <unicode/uscript.h>
#include <unicode/ubidi.h>
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

View file

@ -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;