zero-copy text_item insertion
This commit is contained in:
parent
b455cc9098
commit
477d6cc7ee
3 changed files with 27 additions and 22 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue