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 struct glyph_info
{ {
font_glyph glyph; 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; uint32_t x_advance;
}; };

View file

@ -21,18 +21,17 @@ void text_layout::break_lines()
void text_layout::shape_text() void text_layout::shape_text()
{ {
glyphs_.reserve(itemizer.get_text().length()); //Preallocate memory 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& list = itemizer.itemize();
std::list<text_item>::const_iterator itr = list.begin(), end = list.end(); std::list<text_item>::const_iterator itr = list.begin(), end = list.end();
for (;itr!=end; itr++) for (;itr!=end; itr++)
{ {
face_set_ptr face_set = font_manager_.get_face_set(itr->format.face_name, itr->format.fontset); 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_set->set_character_sizes(itr->format.text_size);
face_ptr face = *(face_set->begin()); //TODO: Implement font sets correctly 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 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(); hb_buffer_t *buffer = shaper.get_buffer();
unsigned num_glyphs = hb_buffer_get_length(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); hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer, NULL);
std::string s; 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++) for (unsigned i=0; i<num_glyphs; i++)
{ {
glyph_info tmp; glyph_info tmp;
tmp.byte_position = byte_offset + glyphs[i].cluster; tmp.char_index = offset + glyphs[i].cluster;
tmp.glyph.index = glyphs[i].codepoint; tmp.glyph.index = glyphs[i].codepoint;
//TODO: tmp.glyph.set_face(); tmp.glyph.face = face;
tmp.x_advance = positions[i].x_advance; tmp.x_advance = positions[i].x_advance;
glyphs_.push_back(tmp); glyphs_.push_back(tmp);
} }
byte_offset += bytes; offset += chars;
} }
std::string s; std::cout << "text_length: unicode chars: " << itemizer.get_text().length() << " glyphs: " << glyphs_.size() << "\n";
std::cout << "text_length: unicode chars: " << itemizer.get_text().length() << " bytes: " <<itemizer.get_text().toUTF8String(s).length() << " glyphs: " << glyphs_.size() << "\n";
std::vector<glyph_info>::const_iterator itr2 = glyphs_.begin(), end2 = glyphs_.end(); std::vector<glyph_info>::const_iterator itr2 = glyphs_.begin(), end2 = glyphs_.end();
for (;itr2 != end2; itr2++) for (;itr2 != end2; itr2++)
{ {
std::cout << "glyph codepoint:" << itr2->glyph.index << std::cout << "'" << (char) itemizer.get_text().charAt(itr2->char_index) <<
" cluster: " << itr2->byte_position << "' glyph codepoint:" << itr2->glyph.index <<
" x_advance: "<< itr2->x_advance << "\n"; " 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; if (!font_) return 0;
hb_buffer_reset(buffer_); hb_buffer_reset(buffer_);
std::string s; uint32_t length = text.length();
text.toUTF8String(s);
hb_buffer_add_utf8(buffer_, s.c_str(), s.length(), 0, -1); 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_direction(buffer_, rtl?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
hb_buffer_set_script(buffer_, hb_icu_script_to_script(script)); hb_buffer_set_script(buffer_, hb_icu_script_to_script(script));
#if 0 #if 0
hb_buffer_set_language(buffer, hb_language_from_string (language, -1)); hb_buffer_set_language(buffer, hb_language_from_string (language, -1));
#endif #endif
hb_shape(font_, buffer_, 0 /*features*/, 0 /*num_features*/); hb_shape(font_, buffer_, 0 /*features*/, 0 /*num_features*/);
return s.length(); return length;
} }
void text_shaping::free_data(void *data) void text_shaping::free_data(void *data)