Use UTF16 directly to avoid reencoding and allow easy mapping of chars to glyphs.

This commit is contained in:
Hermann Kraus 2012-06-30 18:32:59 +02:00
parent 89b727d2fc
commit 91d80dc7c1
3 changed files with 16 additions and 17 deletions

View file

@ -14,7 +14,7 @@ namespace mapnik
struct glyph_info
{
font_glyph glyph;
uint32_t byte_position;
uint32_t char_index; //Position in the string of all characters i.e. before itemizing
uint32_t x_advance;
};

View file

@ -21,18 +21,17 @@ void text_layout::break_lines()
void text_layout::shape_text()
{
glyphs_.reserve(itemizer.get_text().length()); //Preallocate memory
uint32_t byte_offset = 0;
uint32_t offset = 0; //in utf16 code points
std::list<text_item> const& list = itemizer.itemize();
std::list<text_item>::const_iterator itr = list.begin(), end = list.end();
for (;itr!=end; itr++)
{
face_set_ptr face_set = font_manager_.get_face_set(itr->format.face_name, itr->format.fontset);
//TODO: Difference pixel_sizes, char_sizes
face_set->set_character_sizes(itr->format.text_size);
face_ptr face = *(face_set->begin()); //TODO: Implement font sets correctly
text_shaping shaper(face->get_face()); //TODO: Make this more efficient by caching this object in font_face
uint32_t bytes = shaper.process_text(itr->str, itr->rtl == UBIDI_DEFAULT_RTL, itr->script);
uint32_t chars = shaper.process_text(itr->str, itr->rtl == UBIDI_DEFAULT_RTL, itr->script);
hb_buffer_t *buffer = shaper.get_buffer();
unsigned num_glyphs = hb_buffer_get_length(buffer);
@ -41,27 +40,27 @@ void text_layout::shape_text()
hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer, NULL);
std::string s;
std::cout << "Processing item '" << itr->str.toUTF8String(s) << "' (" << uscript_getName(itr->script) << "," << itr->str.length() << "," << num_glyphs << ")\n";
std::cout << "Processing item '" << itr->str.toUTF8String(s) << "' (" << uscript_getName(itr->script) << "," << itr->str.length() << "," << num_glyphs << "," << itr->rtl << ")\n";
for (unsigned i=0; i<num_glyphs; i++)
{
glyph_info tmp;
tmp.byte_position = byte_offset + glyphs[i].cluster;
tmp.char_index = offset + glyphs[i].cluster;
tmp.glyph.index = glyphs[i].codepoint;
//TODO: tmp.glyph.set_face();
tmp.glyph.face = face;
tmp.x_advance = positions[i].x_advance;
glyphs_.push_back(tmp);
}
byte_offset += bytes;
offset += chars;
}
std::string s;
std::cout << "text_length: unicode chars: " << itemizer.get_text().length() << " bytes: " <<itemizer.get_text().toUTF8String(s).length() << " glyphs: " << glyphs_.size() << "\n";
std::cout << "text_length: unicode chars: " << itemizer.get_text().length() << " glyphs: " << glyphs_.size() << "\n";
std::vector<glyph_info>::const_iterator itr2 = glyphs_.begin(), end2 = glyphs_.end();
for (;itr2 != end2; itr2++)
{
std::cout << "glyph codepoint:" << itr2->glyph.index <<
" cluster: " << itr2->byte_position <<
" x_advance: "<< itr2->x_advance << "\n";
std::cout << "'" << (char) itemizer.get_text().charAt(itr2->char_index) <<
"' glyph codepoint:" << itr2->glyph.index <<
" cluster: " << itr2->char_index <<
" x_advance: "<< itr2->x_advance/64.0 << "\n";
}
}

View file

@ -36,16 +36,16 @@ uint32_t text_shaping::process_text(UnicodeString const& text, bool rtl, UScript
if (!font_) return 0;
hb_buffer_reset(buffer_);
std::string s;
text.toUTF8String(s);
hb_buffer_add_utf8(buffer_, s.c_str(), s.length(), 0, -1);
uint32_t length = text.length();
hb_buffer_add_utf16(buffer_, text.getBuffer(), length, 0, -1);
hb_buffer_set_direction(buffer_, rtl?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
hb_buffer_set_script(buffer_, hb_icu_script_to_script(script));
#if 0
hb_buffer_set_language(buffer, hb_language_from_string (language, -1));
#endif
hb_shape(font_, buffer_, 0 /*features*/, 0 /*num_features*/);
return s.length();
return length;
}
void text_shaping::free_data(void *data)