From 91d80dc7c1e7e7aa6fca57f8f2e23e62d970a26e Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Sat, 30 Jun 2012 18:32:59 +0200 Subject: [PATCH] Use UTF16 directly to avoid reencoding and allow easy mapping of chars to glyphs. --- include/mapnik/text/layout.hpp | 2 +- src/text/layout.cpp | 23 +++++++++++------------ src/text/shaping.cpp | 8 ++++---- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/include/mapnik/text/layout.hpp b/include/mapnik/text/layout.hpp index 2050578d9..2965b7281 100644 --- a/include/mapnik/text/layout.hpp +++ b/include/mapnik/text/layout.hpp @@ -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; }; diff --git a/src/text/layout.cpp b/src/text/layout.cpp index 3f555421a..607ac61dc 100644 --- a/src/text/layout.cpp +++ b/src/text/layout.cpp @@ -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 const& list = itemizer.itemize(); std::list::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::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"; } } diff --git a/src/text/shaping.cpp b/src/text/shaping.cpp index c25ffca4f..180e4cdcc 100644 --- a/src/text/shaping.cpp +++ b/src/text/shaping.cpp @@ -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)