From 2e50936b13faed8740f3bc42b419a5cc5715309a Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Sat, 30 Jun 2012 17:09:14 +0200 Subject: [PATCH] Use mapnik's face_manager instead of loading the font on our own. --- include/mapnik/font_engine_freetype.hpp | 26 ++++++++++++----- include/mapnik/symbolizer_helpers.hpp | 31 ++------------------ include/mapnik/text/layout.hpp | 6 ++-- include/mapnik/text/shaping.hpp | 10 ++++++- src/symbolizer_helpers.cpp | 38 +++++++++++++++++++++++++ src/text/layout.cpp | 15 +++++++--- src/text/shaping.cpp | 37 +++--------------------- 7 files changed, 87 insertions(+), 76 deletions(-) diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index 7ca982794..ca1af7288 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -71,24 +71,25 @@ class string_info; typedef boost::shared_ptr face_ptr; -class MAPNIK_DECL font_glyph : private boost::noncopyable +class MAPNIK_DECL font_glyph { public: + font_glyph() : face(), index(0) {} + font_glyph(face_ptr face, unsigned index) - : face_(face), index_(index) {} + : face(face), index(index) {} face_ptr get_face() const { - return face_; + return face; } unsigned get_index() const { - return index_; + return index; } -private: - face_ptr face_; - unsigned index_; + face_ptr face; + unsigned index; }; typedef boost::shared_ptr glyph_ptr; @@ -152,6 +153,7 @@ private: class MAPNIK_DECL font_face_set : private boost::noncopyable { public: + typedef std::vector::iterator iterator; font_face_set(void) : faces_(), dimension_cache_() {} @@ -179,6 +181,16 @@ public: return boost::make_shared(*faces_.begin(), 0); } + iterator begin() + { + return faces_.begin(); + } + + iterator end() + { + return faces_.end(); + } + char_info character_dimensions(const unsigned c); void get_string_info(string_info & info, UnicodeString const& ustr, char_properties *format); diff --git a/include/mapnik/symbolizer_helpers.hpp b/include/mapnik/symbolizer_helpers.hpp index 503738926..a97038aed 100644 --- a/include/mapnik/symbolizer_helpers.hpp +++ b/include/mapnik/symbolizer_helpers.hpp @@ -56,28 +56,7 @@ public: CoordTransform const& t, FaceManagerT &font_manager, DetectorT &detector, - box2d const& query_extent) - : sym_(sym), - feature_(feature), - prj_trans_(prj_trans), - t_(t), - font_manager_(font_manager), - detector_(detector), - writer_(sym.get_metawriter()), - dims_(0, 0, width, height), - query_extent_(query_extent), - layout_(), - angle_(0.0), - placement_valid_(false), - points_on_line_(false), - finder_() - { - initialize_geometries(); - if (!geometries_to_process_.size()) return; - placement_ = sym_.get_placement_options()->get_placement_info(scale_factor); - next_placement(); - initialize_points(); - } + box2d const& query_extent); /** Return next placement. * If no more placements are found false is returned. @@ -142,13 +121,7 @@ public: CoordTransform const &t, FaceManagerT &font_manager, DetectorT &detector, - box2d const& query_extent) : - text_symbolizer_helper(sym, feature, prj_trans, width, height, scale_factor, t, font_manager, detector, query_extent), - sym_(sym) - { - this->points_on_line_ = true; - init_marker(); - } + box2d const& query_extent); box2d const& get_marker_extent() const { diff --git a/include/mapnik/text/layout.hpp b/include/mapnik/text/layout.hpp index 754a08595..2050578d9 100644 --- a/include/mapnik/text/layout.hpp +++ b/include/mapnik/text/layout.hpp @@ -3,6 +3,7 @@ //mapnik #include +#include //stl #include @@ -12,7 +13,7 @@ namespace mapnik struct glyph_info { - uint32_t codepoint; + font_glyph glyph; uint32_t byte_position; uint32_t x_advance; }; @@ -20,7 +21,7 @@ struct glyph_info class text_layout { public: - text_layout(); + text_layout(face_manager_freetype & font_manager); inline void add_text(UnicodeString const& str, char_properties const& format) { itemizer.add_text(str, format); @@ -33,6 +34,7 @@ public: private: text_itemizer itemizer; std::vector glyphs_; + face_manager_freetype &font_manager_; }; } diff --git a/include/mapnik/text/shaping.hpp b/include/mapnik/text/shaping.hpp index 550c38d8f..28cbaccdf 100644 --- a/include/mapnik/text/shaping.hpp +++ b/include/mapnik/text/shaping.hpp @@ -7,6 +7,13 @@ class hb_font_t; class hb_buffer_t; class hb_glyph_info_t; +// freetype2 +extern "C" +{ +#include +#include FT_FREETYPE_H +} + namespace mapnik { @@ -14,7 +21,7 @@ class text_shaping { public: //TODO: Get font file from font name - text_shaping(); + text_shaping(FT_Face face); ~text_shaping(); uint32_t process_text(UnicodeString const& text); @@ -27,6 +34,7 @@ protected: hb_font_t *font_; hb_buffer_t *buffer_; + FT_Face face_; }; } //ns mapnik diff --git a/src/symbolizer_helpers.cpp b/src/symbolizer_helpers.cpp index b62e11b35..b04ea6aec 100644 --- a/src/symbolizer_helpers.cpp +++ b/src/symbolizer_helpers.cpp @@ -29,6 +29,30 @@ namespace mapnik { +template +text_symbolizer_helper::text_symbolizer_helper(const text_symbolizer &sym, const Feature &feature, const proj_transform &prj_trans, unsigned width, unsigned height, double scale_factor, const CoordTransform &t, FaceManagerT &font_manager, DetectorT &detector, const box2d &query_extent) + : sym_(sym), + feature_(feature), + prj_trans_(prj_trans), + t_(t), + font_manager_(font_manager), + detector_(detector), + writer_(sym.get_metawriter()), + dims_(0, 0, width, height), + query_extent_(query_extent), + layout_(font_manager), + angle_(0.0), + placement_valid_(false), + points_on_line_(false), + finder_() +{ + initialize_geometries(); + if (!geometries_to_process_.size()) return; + placement_ = sym_.get_placement_options()->get_placement_info(scale_factor); + next_placement(); + initialize_points(); +} + template bool text_symbolizer_helper::next() { @@ -96,6 +120,7 @@ bool text_symbolizer_helper::next_point_placement() point_itr_ = points_.begin(); continue; //Reexecute size check } + return false; //TODO finder_->clear_placements(); finder_->find_point_placement(point_itr_->first, point_itr_->second, angle_); if (!finder_->get_results().empty()) @@ -227,6 +252,7 @@ bool text_symbolizer_helper::next_placement() return false; } placement_->properties.process(layout_, feature_); + layout_.shape_text(); //TODO // info_ = &(text_.get_string_info()); if (placement_->properties.orientation) @@ -257,6 +283,17 @@ placements_type &text_symbolizer_helper::placements() c /*****************************************************************************/ +template +shield_symbolizer_helper::shield_symbolizer_helper(const shield_symbolizer &sym, const Feature &feature, const proj_transform &prj_trans, unsigned width, unsigned height, double scale_factor, const CoordTransform &t, FaceManagerT &font_manager, DetectorT &detector, const box2d &query_extent) + : text_symbolizer_helper( + sym, feature, prj_trans, width, height, + scale_factor, t, font_manager, detector, query_extent), + sym_(sym) +{ + this->points_on_line_ = true; + init_marker(); +} + template bool shield_symbolizer_helper::next() { @@ -417,4 +454,5 @@ agg::trans_affine const& shield_symbolizer_helper::get_ template class text_symbolizer_helper, label_collision_detector4>; template class shield_symbolizer_helper, label_collision_detector4>; + } //namespace diff --git a/src/text/layout.cpp b/src/text/layout.cpp index bf66671a4..9df7b3a34 100644 --- a/src/text/layout.cpp +++ b/src/text/layout.cpp @@ -9,7 +9,8 @@ namespace mapnik { -text_layout::text_layout() +text_layout::text_layout(face_manager_freetype &font_manager) + : font_manager_(font_manager) { } @@ -25,7 +26,12 @@ void text_layout::shape_text() std::list::const_iterator itr = list.begin(), end = list.end(); for (;itr!=end; itr++) { - text_shaping shaper; + 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); hb_buffer_t *buffer = shaper.get_buffer(); @@ -41,7 +47,8 @@ void text_layout::shape_text() { glyph_info tmp; tmp.byte_position = byte_offset + glyphs[i].cluster; - tmp.codepoint = glyphs[i].codepoint; + tmp.glyph.index = glyphs[i].codepoint; + //TODO: tmp.glyph.set_face(); tmp.x_advance = positions[i].x_advance; glyphs_.push_back(tmp); } @@ -52,7 +59,7 @@ void text_layout::shape_text() std::vector::const_iterator itr2 = glyphs_.begin(), end2 = glyphs_.end(); for (;itr2 != end2; itr2++) { - std::cout << "glyph codepoint:" << itr2->codepoint << + std::cout << "glyph codepoint:" << itr2->glyph.index << " cluster: " << itr2->byte_position << " x_advance: "<< itr2->x_advance << "\n"; } diff --git a/src/text/shaping.cpp b/src/text/shaping.cpp index 0e9467f33..b25e93777 100644 --- a/src/text/shaping.cpp +++ b/src/text/shaping.cpp @@ -15,9 +15,10 @@ namespace mapnik { -text_shaping::text_shaping() +text_shaping::text_shaping(FT_Face face) : font_(0), - buffer_ (hb_buffer_create()) + buffer_ (hb_buffer_create()), + face_(face) { load_font(); } @@ -53,38 +54,8 @@ void text_shaping::free_data(void *data) void text_shaping::load_font() { - //TODO: hb_ft_font_create if (font_) return; - - char *font_data; - unsigned int size; - -// std::ifstream file("./unifont-5.1.20080907.ttf" /*TODO*/, std::ios::in|std::ios::binary|std::ios::ate); - std::ifstream file("./DejaVuSans.ttf" /*TODO*/, std::ios::in|std::ios::binary|std::ios::ate); - if (file.is_open()) - { - size = file.tellg(); - font_data = new char[size]; - file.seekg(0, std::ios::beg); - file.read(font_data, size); - file.close(); - } else { - std::cerr << "Could not open font!\n"; - return ;//TODO: Raise exception - } - - - hb_blob_t *blob = hb_blob_create(font_data, size, HB_MEMORY_MODE_WRITABLE, font_data, &free_data); - hb_face_t *face = hb_face_create(blob, 0 /*face_index*/); - hb_blob_destroy(blob); - font_ = hb_font_create(face); -#if 1 - //TODO: Font size - unsigned int upem = hb_face_get_upem(face); - hb_font_set_scale(font_, upem, upem); -#endif - hb_face_destroy(face); - hb_ft_font_set_funcs(font_); + font_ = hb_ft_font_create(face_, NULL); } }