diff --git a/include/mapnik/text/face.hpp b/include/mapnik/text/face.hpp index f1629044a..e362184e0 100644 --- a/include/mapnik/text/face.hpp +++ b/include/mapnik/text/face.hpp @@ -48,8 +48,7 @@ namespace mapnik class font_face : boost::noncopyable { public: - font_face(FT_Face face) - : face_(face) {} + font_face(FT_Face face); std::string family_name() const { @@ -66,32 +65,18 @@ public: return face_; } - unsigned get_char(unsigned c) const - { - return FT_Get_Char_Index(face_, c); - } + double get_char_height() const; - bool set_pixel_sizes(unsigned size) - { - if (! FT_Set_Pixel_Sizes( face_, 0, size )) - return true; - return false; - } + bool set_character_sizes(float size); - bool set_character_sizes(float size) - { - if ( !FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0)) - return true; - return false; - } - - void glyph_dimensions(glyph_info &glyph); + void glyph_dimensions(glyph_info &glyph) const; ~font_face(); private: FT_Face face_; - std::map dimension_cache_; + mutable std::map dimension_cache_; + mutable double char_height_; }; diff --git a/src/text/face.cpp b/src/text/face.cpp index fe4694ef6..39b94dc6f 100644 --- a/src/text/face.cpp +++ b/src/text/face.cpp @@ -32,7 +32,28 @@ extern "C" namespace mapnik { -void font_face::glyph_dimensions(glyph_info &glyph) +font_face::font_face(FT_Face face) + : face_(face), dimension_cache_(), char_height_(0.) +{ +} + +double font_face::get_char_height() const +{ + if (char_height_ != 0.0) return char_height_; + glyph_info tmp; + tmp.glyph_index = FT_Get_Char_Index(face_, 'X'); + glyph_dimensions(tmp); + char_height_ = tmp.height(); + return char_height_; +} + +bool font_face::set_character_sizes(float size) +{ + char_height_ = 0.; + return !FT_Set_Char_Size(face_,0,(FT_F26Dot6)(size * (1<<6)),0,0); +} + +void font_face::glyph_dimensions(glyph_info &glyph) const { //TODO //Check if char is already in cache @@ -64,8 +85,8 @@ void font_face::glyph_dimensions(glyph_info &glyph) FT_Glyph_Get_CBox(image, ft_glyph_bbox_pixels, &glyph_bbox); FT_Done_Glyph(image); - glyph.ymin = glyph_bbox.yMin; //TODO: Which data format? 26.6, integer? - glyph.ymax = glyph_bbox.yMax; //TODO: Which data format? 26.6, integer? + glyph.ymin = glyph_bbox.yMin; //pixels! + glyph.ymax = glyph_bbox.yMax; glyph.line_height = face_->size->metrics.height/64.0; //TODO: dimension_cache_.insert(std::pair(c, dim)); diff --git a/src/text/itemizer.cpp b/src/text/itemizer.cpp index 42687887c..30deaa547 100644 --- a/src/text/itemizer.cpp +++ b/src/text/itemizer.cpp @@ -51,7 +51,6 @@ std::list const& text_itemizer::itemize(unsigned start, unsigned end) // format itemiziation is done by add_text() itemize_direction(start, end); itemize_script(); - std::cout << "Itemizer: direction: "<< direction_runs.size() << " script: " << script_runs.size() << "\n"; create_item_list(); return output; } diff --git a/src/text/layout.cpp b/src/text/layout.cpp index d5b7a9180..c89d07b7c 100644 --- a/src/text/layout.cpp +++ b/src/text/layout.cpp @@ -122,7 +122,8 @@ void text_layout::shape_text(text_line_ptr line, unsigned start, unsigned end) 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 - line->update_max_char_height(itr->format->text_size /*TODO*/); + + line->update_max_char_height(face->get_char_height()); shaper.process_text(text, itr->start, itr->end, itr->rtl == UBIDI_RTL, itr->script); hb_buffer_t *buffer = shaper.get_buffer(); diff --git a/src/text/placement_finder_ng.cpp b/src/text/placement_finder_ng.cpp index 44b1941cd..20ca349d2 100644 --- a/src/text/placement_finder_ng.cpp +++ b/src/text/placement_finder_ng.cpp @@ -48,6 +48,7 @@ bool placement_finder_ng::next_position() valid_ = false; return false; } + info_->properties.process(layout_, feature_); layout_.layout(info_->properties.wrap_width, info_->properties.text_ratio); @@ -143,7 +144,8 @@ pixel_position placement_finder_ng::alignment_offset() const glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos) { glyph_positions_ptr glyphs = boost::make_shared(); - if (!layout_.size()) return glyphs; //No data + if (!layout_.size()) return glyphs; /* No data. Don't return NULL pointer, which would mean + that not enough space was available. */ //TODO: Verify enough space is available. For point placement the bounding box is enough! @@ -163,7 +165,6 @@ glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos text_layout::const_iterator line_itr = layout_.begin(), line_end = layout_.end(); for (; line_itr != line_end; line_itr++) { -// text_line *line_itr; y -= (*line_itr)->height(); //Automatically handles first line differently // reset to begining of line position if (jalign_ == J_LEFT) @@ -176,7 +177,6 @@ glyph_positions_ptr placement_finder_ng::find_point_placement(pixel_position pos text_line::const_iterator glyph_itr = (*line_itr)->begin(), glyph_end = (*line_itr)->end(); for (; glyph_itr != glyph_end; glyph_itr++) { -// glyph_info *glyph_itr; glyphs->push_back(*glyph_itr, pixel_position(x, y), angle_); //TODO: Store cosa, sina instead x += glyph_itr->width + glyph_itr->format->character_spacing; } diff --git a/src/text/shaping.cpp b/src/text/shaping.cpp index 8eea6ce4c..eef1a31b0 100644 --- a/src/text/shaping.cpp +++ b/src/text/shaping.cpp @@ -58,7 +58,9 @@ uint32_t text_shaping::process_text(UnicodeString const& text, unsigned start, u hb_buffer_set_unicode_funcs(buffer_, hb_icu_get_unicode_funcs()); uint32_t length = text.length(); - std::cout << "process_text: length: " << length << " start: " << start << " end: " << end << "rtl:" << rtl << "\n"; + std::string s; + text.toUTF8String(s); + std::cout << "process_text: length: " << length << " start: " << start << " end: " << end << "rtl:" << rtl << "text: '"<