Use UTF16 directly to avoid reencoding and allow easy mapping of chars to glyphs.
This commit is contained in:
parent
89b727d2fc
commit
91d80dc7c1
3 changed files with 16 additions and 17 deletions
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue