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);
|
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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue