Use mapnik's face_manager instead of loading the font on our own.
This commit is contained in:
parent
63e8b6d6db
commit
2e50936b13
7 changed files with 87 additions and 76 deletions
|
@ -71,24 +71,25 @@ class string_info;
|
|||
|
||||
typedef boost::shared_ptr<font_face> 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<font_glyph> glyph_ptr;
|
||||
|
@ -152,6 +153,7 @@ private:
|
|||
class MAPNIK_DECL font_face_set : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
typedef std::vector<face_ptr>::iterator iterator;
|
||||
font_face_set(void)
|
||||
: faces_(),
|
||||
dimension_cache_() {}
|
||||
|
@ -179,6 +181,16 @@ public:
|
|||
return boost::make_shared<font_glyph>(*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);
|
||||
|
|
|
@ -56,28 +56,7 @@ public:
|
|||
CoordTransform const& t,
|
||||
FaceManagerT &font_manager,
|
||||
DetectorT &detector,
|
||||
box2d<double> 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<double> 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<double> const& query_extent) :
|
||||
text_symbolizer_helper<FaceManagerT, DetectorT>(sym, feature, prj_trans, width, height, scale_factor, t, font_manager, detector, query_extent),
|
||||
sym_(sym)
|
||||
{
|
||||
this->points_on_line_ = true;
|
||||
init_marker();
|
||||
}
|
||||
box2d<double> const& query_extent);
|
||||
|
||||
box2d<double> const& get_marker_extent() const
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
//mapnik
|
||||
#include <mapnik/text/itemizer.hpp>
|
||||
#include <mapnik/font_engine_freetype.hpp>
|
||||
|
||||
//stl
|
||||
#include <vector>
|
||||
|
@ -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<glyph_info> glyphs_;
|
||||
face_manager_freetype &font_manager_;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,13 @@ class hb_font_t;
|
|||
class hb_buffer_t;
|
||||
class hb_glyph_info_t;
|
||||
|
||||
// freetype2
|
||||
extern "C"
|
||||
{
|
||||
#include <ft2build.h>
|
||||
#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
|
||||
|
||||
|
|
|
@ -29,6 +29,30 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
text_symbolizer_helper<FaceManagerT, DetectorT>::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<double> &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 <typename FaceManagerT, typename DetectorT>
|
||||
bool text_symbolizer_helper<FaceManagerT, DetectorT>::next()
|
||||
{
|
||||
|
@ -96,6 +120,7 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::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<FaceManagerT, DetectorT>::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<FaceManagerT, DetectorT>::placements() c
|
|||
/*****************************************************************************/
|
||||
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
shield_symbolizer_helper<FaceManagerT, DetectorT>::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<double> &query_extent)
|
||||
: text_symbolizer_helper<FaceManagerT, DetectorT>(
|
||||
sym, feature, prj_trans, width, height,
|
||||
scale_factor, t, font_manager, detector, query_extent),
|
||||
sym_(sym)
|
||||
{
|
||||
this->points_on_line_ = true;
|
||||
init_marker();
|
||||
}
|
||||
|
||||
template <typename FaceManagerT, typename DetectorT>
|
||||
bool shield_symbolizer_helper<FaceManagerT, DetectorT>::next()
|
||||
{
|
||||
|
@ -417,4 +454,5 @@ agg::trans_affine const& shield_symbolizer_helper<FaceManagerT, DetectorT>::get_
|
|||
|
||||
template class text_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4>;
|
||||
template class shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4>;
|
||||
|
||||
} //namespace
|
||||
|
|
|
@ -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<text_item>::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<glyph_info>::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";
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue