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;
|
typedef boost::shared_ptr<font_face> face_ptr;
|
||||||
|
|
||||||
class MAPNIK_DECL font_glyph : private boost::noncopyable
|
class MAPNIK_DECL font_glyph
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
font_glyph() : face(), index(0) {}
|
||||||
|
|
||||||
font_glyph(face_ptr face, unsigned index)
|
font_glyph(face_ptr face, unsigned index)
|
||||||
: face_(face), index_(index) {}
|
: face(face), index(index) {}
|
||||||
|
|
||||||
face_ptr get_face() const
|
face_ptr get_face() const
|
||||||
{
|
{
|
||||||
return face_;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_index() const
|
unsigned get_index() const
|
||||||
{
|
{
|
||||||
return index_;
|
return index;
|
||||||
}
|
}
|
||||||
private:
|
face_ptr face;
|
||||||
face_ptr face_;
|
unsigned index;
|
||||||
unsigned index_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::shared_ptr<font_glyph> glyph_ptr;
|
typedef boost::shared_ptr<font_glyph> glyph_ptr;
|
||||||
|
@ -152,6 +153,7 @@ private:
|
||||||
class MAPNIK_DECL font_face_set : private boost::noncopyable
|
class MAPNIK_DECL font_face_set : private boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef std::vector<face_ptr>::iterator iterator;
|
||||||
font_face_set(void)
|
font_face_set(void)
|
||||||
: faces_(),
|
: faces_(),
|
||||||
dimension_cache_() {}
|
dimension_cache_() {}
|
||||||
|
@ -179,6 +181,16 @@ public:
|
||||||
return boost::make_shared<font_glyph>(*faces_.begin(), 0);
|
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);
|
char_info character_dimensions(const unsigned c);
|
||||||
|
|
||||||
void get_string_info(string_info & info, UnicodeString const& ustr, char_properties *format);
|
void get_string_info(string_info & info, UnicodeString const& ustr, char_properties *format);
|
||||||
|
|
|
@ -56,28 +56,7 @@ public:
|
||||||
CoordTransform const& t,
|
CoordTransform const& t,
|
||||||
FaceManagerT &font_manager,
|
FaceManagerT &font_manager,
|
||||||
DetectorT &detector,
|
DetectorT &detector,
|
||||||
box2d<double> const& query_extent)
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return next placement.
|
/** Return next placement.
|
||||||
* If no more placements are found false is returned.
|
* If no more placements are found false is returned.
|
||||||
|
@ -142,13 +121,7 @@ public:
|
||||||
CoordTransform const &t,
|
CoordTransform const &t,
|
||||||
FaceManagerT &font_manager,
|
FaceManagerT &font_manager,
|
||||||
DetectorT &detector,
|
DetectorT &detector,
|
||||||
box2d<double> const& query_extent) :
|
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& get_marker_extent() const
|
box2d<double> const& get_marker_extent() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
//mapnik
|
//mapnik
|
||||||
#include <mapnik/text/itemizer.hpp>
|
#include <mapnik/text/itemizer.hpp>
|
||||||
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
|
||||||
//stl
|
//stl
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -12,7 +13,7 @@ namespace mapnik
|
||||||
|
|
||||||
struct glyph_info
|
struct glyph_info
|
||||||
{
|
{
|
||||||
uint32_t codepoint;
|
font_glyph glyph;
|
||||||
uint32_t byte_position;
|
uint32_t byte_position;
|
||||||
uint32_t x_advance;
|
uint32_t x_advance;
|
||||||
};
|
};
|
||||||
|
@ -20,7 +21,7 @@ struct glyph_info
|
||||||
class text_layout
|
class text_layout
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
text_layout();
|
text_layout(face_manager_freetype & font_manager);
|
||||||
inline void add_text(UnicodeString const& str, char_properties const& format)
|
inline void add_text(UnicodeString const& str, char_properties const& format)
|
||||||
{
|
{
|
||||||
itemizer.add_text(str, format);
|
itemizer.add_text(str, format);
|
||||||
|
@ -33,6 +34,7 @@ public:
|
||||||
private:
|
private:
|
||||||
text_itemizer itemizer;
|
text_itemizer itemizer;
|
||||||
std::vector<glyph_info> glyphs_;
|
std::vector<glyph_info> glyphs_;
|
||||||
|
face_manager_freetype &font_manager_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,13 @@ class hb_font_t;
|
||||||
class hb_buffer_t;
|
class hb_buffer_t;
|
||||||
class hb_glyph_info_t;
|
class hb_glyph_info_t;
|
||||||
|
|
||||||
|
// freetype2
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
}
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -14,7 +21,7 @@ class text_shaping
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//TODO: Get font file from font name
|
//TODO: Get font file from font name
|
||||||
text_shaping();
|
text_shaping(FT_Face face);
|
||||||
~text_shaping();
|
~text_shaping();
|
||||||
|
|
||||||
uint32_t process_text(UnicodeString const& text);
|
uint32_t process_text(UnicodeString const& text);
|
||||||
|
@ -27,6 +34,7 @@ protected:
|
||||||
|
|
||||||
hb_font_t *font_;
|
hb_font_t *font_;
|
||||||
hb_buffer_t *buffer_;
|
hb_buffer_t *buffer_;
|
||||||
|
FT_Face face_;
|
||||||
};
|
};
|
||||||
} //ns mapnik
|
} //ns mapnik
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,30 @@
|
||||||
|
|
||||||
namespace mapnik {
|
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>
|
template <typename FaceManagerT, typename DetectorT>
|
||||||
bool text_symbolizer_helper<FaceManagerT, DetectorT>::next()
|
bool text_symbolizer_helper<FaceManagerT, DetectorT>::next()
|
||||||
{
|
{
|
||||||
|
@ -96,6 +120,7 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_point_placement()
|
||||||
point_itr_ = points_.begin();
|
point_itr_ = points_.begin();
|
||||||
continue; //Reexecute size check
|
continue; //Reexecute size check
|
||||||
}
|
}
|
||||||
|
return false; //TODO
|
||||||
finder_->clear_placements();
|
finder_->clear_placements();
|
||||||
finder_->find_point_placement(point_itr_->first, point_itr_->second, angle_);
|
finder_->find_point_placement(point_itr_->first, point_itr_->second, angle_);
|
||||||
if (!finder_->get_results().empty())
|
if (!finder_->get_results().empty())
|
||||||
|
@ -227,6 +252,7 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_placement()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
placement_->properties.process(layout_, feature_);
|
placement_->properties.process(layout_, feature_);
|
||||||
|
layout_.shape_text();
|
||||||
//TODO
|
//TODO
|
||||||
// info_ = &(text_.get_string_info());
|
// info_ = &(text_.get_string_info());
|
||||||
if (placement_->properties.orientation)
|
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>
|
template <typename FaceManagerT, typename DetectorT>
|
||||||
bool shield_symbolizer_helper<FaceManagerT, DetectorT>::next()
|
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 text_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4>;
|
||||||
template class shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4>;
|
template class shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4>;
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
namespace mapnik
|
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();
|
std::list<text_item>::const_iterator itr = list.begin(), end = list.end();
|
||||||
for (;itr!=end; itr++)
|
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);
|
uint32_t bytes = shaper.process_text(itr->str);
|
||||||
hb_buffer_t *buffer = shaper.get_buffer();
|
hb_buffer_t *buffer = shaper.get_buffer();
|
||||||
|
|
||||||
|
@ -41,7 +47,8 @@ void text_layout::shape_text()
|
||||||
{
|
{
|
||||||
glyph_info tmp;
|
glyph_info tmp;
|
||||||
tmp.byte_position = byte_offset + glyphs[i].cluster;
|
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;
|
tmp.x_advance = positions[i].x_advance;
|
||||||
glyphs_.push_back(tmp);
|
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();
|
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->codepoint <<
|
std::cout << "glyph codepoint:" << itr2->glyph.index <<
|
||||||
" cluster: " << itr2->byte_position <<
|
" cluster: " << itr2->byte_position <<
|
||||||
" x_advance: "<< itr2->x_advance << "\n";
|
" 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),
|
: font_(0),
|
||||||
buffer_ (hb_buffer_create())
|
buffer_ (hb_buffer_create()),
|
||||||
|
face_(face)
|
||||||
{
|
{
|
||||||
load_font();
|
load_font();
|
||||||
}
|
}
|
||||||
|
@ -53,38 +54,8 @@ void text_shaping::free_data(void *data)
|
||||||
|
|
||||||
void text_shaping::load_font()
|
void text_shaping::load_font()
|
||||||
{
|
{
|
||||||
//TODO: hb_ft_font_create
|
|
||||||
if (font_) return;
|
if (font_) return;
|
||||||
|
font_ = hb_ft_font_create(face_, NULL);
|
||||||
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_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue