+ attempting to refactor out shared_ptr overuse

This commit is contained in:
artemp 2013-07-16 15:57:13 +01:00
parent d34fdd7fca
commit a7e2c2ea0d
6 changed files with 86 additions and 95 deletions

View file

@ -78,19 +78,17 @@ void check_object_status_and_throw_exception(const T& object)
class cairo_face : private mapnik::noncopyable
{
public:
cairo_face(boost::shared_ptr<freetype_engine> const& engine, face_ptr const& face);
cairo_face(boost::shared_ptr<freetype_engine> const& engine, FT_Face face);
~cairo_face();
cairo_font_face_t * face() const;
private:
class handle
{
public:
handle(boost::shared_ptr<freetype_engine> const& engine, face_ptr const& face)
: engine_(engine), face_(face) {}
handle(boost::shared_ptr<freetype_engine> const& engine)
: engine_(engine) {}
private:
boost::shared_ptr<freetype_engine> engine_;
face_ptr face_;
};
static void destroy(void *data)
@ -100,20 +98,21 @@ private:
}
private:
face_ptr face_;
cairo_font_face_t *c_face_;
};
typedef boost::shared_ptr<cairo_face> cairo_face_ptr;
struct FT_FaceRec_;
class cairo_face_manager : private mapnik::noncopyable
{
public:
cairo_face_manager(boost::shared_ptr<freetype_engine> engine);
cairo_face_ptr get_face(face_ptr face);
cairo_face_ptr get_face(font_face const& face);
private:
typedef std::map<face_ptr,cairo_face_ptr> cairo_face_cache;
typedef std::map<FT_FaceRec_*,cairo_face_ptr> cairo_face_cache;
boost::shared_ptr<freetype_engine> font_engine_;
cairo_face_cache cache_;
};
@ -310,7 +309,7 @@ public:
void set_gradient(cairo_gradient const& pattern, box2d<double> const& bbox);
void add_image(double x, double y, image_data_32 & data, double opacity = 1.0);
void add_image(agg::trans_affine const& tr, image_data_32 & data, double opacity = 1.0);
void set_font_face(cairo_face_manager & manager, face_ptr face);
void set_font_face(cairo_face_manager & manager, font_face const& face);
void set_font_matrix(cairo_matrix_t const& matrix);
void set_matrix(cairo_matrix_t const& matrix);
void transform(cairo_matrix_t const& matrix);

View file

@ -2,7 +2,7 @@
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
* Copyright (C) 2013 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -37,7 +37,7 @@
#include <mapnik/noncopyable.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/pixel_position.hpp>
#include <mapnik/font_util.hpp>
// boost
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
@ -68,13 +68,13 @@ struct glyph_t;
typedef boost::shared_ptr<font_face> face_ptr;
class MAPNIK_DECL font_glyph : private mapnik::noncopyable
class MAPNIK_DECL font_glyph //: private mapnik::noncopyable FIXME
{
public:
font_glyph(face_ptr face, unsigned index)
font_glyph(font_face const& face, unsigned index)
: face_(face), index_(index) {}
face_ptr get_face() const
font_face const& get_face() const
{
return face_;
}
@ -84,13 +84,10 @@ public:
return index_;
}
private:
face_ptr face_;
font_face const& face_;
unsigned index_;
};
typedef boost::shared_ptr<font_glyph> glyph_ptr;
class MAPNIK_DECL font_face_set : private mapnik::noncopyable
{
@ -98,13 +95,13 @@ public:
typedef std::vector<face_ptr> container_type;
typedef container_type::size_type size_type;
font_face_set(void)
font_face_set()
: faces_(),
dimension_cache_() {}
void add(face_ptr face);
size_type size() const;
glyph_ptr get_glyph(unsigned c) const;
font_glyph get_glyph(unsigned c) const;
char_info character_dimensions(unsigned c);
void get_string_info(string_info & info, UnicodeString const& ustr, char_properties *format);
void set_pixel_sizes(unsigned size);

View file

@ -29,14 +29,34 @@
#include <cairo-ft.h>
#include <valarray>
namespace mapnik {
cairo_face::cairo_face(boost::shared_ptr<freetype_engine> const& engine, face_ptr const& face)
: face_(face)
cairo_face_manager::cairo_face_manager(boost::shared_ptr<freetype_engine> engine)
: font_engine_(engine) {}
cairo_face_ptr cairo_face_manager::get_face(font_face const& face)
{
cairo_face_cache::iterator itr = cache_.find((FT_FaceRec_ *const)face.get_face());
cairo_face_ptr entry;
if (itr != cache_.end())
{
entry = itr->second;
}
else
{
entry = boost::make_shared<cairo_face>(font_engine_, face.get_face());
cache_.insert(std::make_pair((FT_FaceRec_ *const)face.get_face(), entry));
}
return entry;
}
cairo_face::cairo_face(boost::shared_ptr<freetype_engine> const& engine, FT_Face face)
{
static cairo_user_data_key_t key;
c_face_ = cairo_ft_font_face_create_for_ft_face(face->get_face(), FT_LOAD_NO_HINTING);
cairo_font_face_set_user_data(c_face_, &key, new handle(engine, face), destroy);
c_face_ = cairo_ft_font_face_create_for_ft_face(face, FT_LOAD_NO_HINTING);
cairo_font_face_set_user_data(c_face_, &key, new handle(engine), destroy);
}
cairo_face::~cairo_face()
@ -363,7 +383,7 @@ void cairo_context::add_image(agg::trans_affine const& tr, image_data_32 & data,
check_object_status_and_throw_exception(*this);
}
void cairo_context::set_font_face(cairo_face_manager & manager, face_ptr face)
void cairo_context::set_font_face(cairo_face_manager & manager, font_face const& face)
{
cairo_set_font_face(cairo_.get(), manager.get_face(face)->face());
}
@ -447,25 +467,21 @@ void cairo_context::add_text(text_path const& path,
double text_size = c->format->text_size * scale_factor;
faces->set_character_sizes(text_size);
glyph_ptr glyph = faces->get_glyph(c->c);
if (glyph)
{
cairo_matrix_t matrix;
matrix.xx = text_size * std::cos(angle);
matrix.xy = text_size * std::sin(angle);
matrix.yx = text_size * -std::sin(angle);
matrix.yy = text_size * std::cos(angle);
matrix.x0 = 0;
matrix.y0 = 0;
set_font_matrix(matrix);
set_font_face(manager, glyph->get_face());
glyph_path(glyph->get_index(), sx + x, sy - y);
set_line_width(2.0 * c->format->halo_radius * scale_factor);
set_line_join(ROUND_JOIN);
set_color(c->format->halo_fill);
stroke();
}
font_glyph glyph = faces->get_glyph(c->c);
cairo_matrix_t matrix;
matrix.xx = text_size * std::cos(angle);
matrix.xy = text_size * std::sin(angle);
matrix.yx = text_size * -std::sin(angle);
matrix.yy = text_size * std::cos(angle);
matrix.x0 = 0;
matrix.y0 = 0;
set_font_matrix(matrix);
set_font_face(manager, glyph.get_face());
glyph_path(glyph.get_index(), sx + x, sy - y);
set_line_width(2.0 * c->format->halo_radius * scale_factor);
set_line_join(ROUND_JOIN);
set_color(c->format->halo_fill);
stroke();
}
path.rewind();
@ -481,22 +497,19 @@ void cairo_context::add_text(text_path const& path,
double text_size = c->format->text_size * scale_factor;
faces->set_character_sizes(text_size);
glyph_ptr glyph = faces->get_glyph(c->c);
font_glyph glyph = faces->get_glyph(c->c);
if (glyph)
{
cairo_matrix_t matrix;
matrix.xx = text_size * std::cos(angle);
matrix.xy = text_size * std::sin(angle);
matrix.yx = text_size * -std::sin(angle);
matrix.yy = text_size * std::cos(angle);
matrix.x0 = 0;
matrix.y0 = 0;
set_font_matrix(matrix);
set_font_face(manager, glyph->get_face());
set_color(c->format->fill);
show_glyph(glyph->get_index(), sx + x, sy - y);
}
cairo_matrix_t matrix;
matrix.xx = text_size * std::cos(angle);
matrix.xy = text_size * std::sin(angle);
matrix.yx = text_size * -std::sin(angle);
matrix.yy = text_size * std::cos(angle);
matrix.x0 = 0;
matrix.y0 = 0;
set_font_matrix(matrix);
set_font_face(manager, glyph.get_face());
set_color(c->format->fill);
show_glyph(glyph.get_index(), sx + x, sy - y);
}
}

View file

@ -95,31 +95,6 @@ struct cairo_save_restore
cairo_context & context_;
};
cairo_face_manager::cairo_face_manager(boost::shared_ptr<freetype_engine> engine)
: font_engine_(engine)
{
}
cairo_face_ptr cairo_face_manager::get_face(face_ptr face)
{
cairo_face_cache::iterator itr = cache_.find(face);
cairo_face_ptr entry;
if (itr != cache_.end())
{
entry = itr->second;
}
else
{
entry = boost::make_shared<cairo_face>(font_engine_, face);
cache_.insert(std::make_pair(face, entry));
}
return entry;
}
cairo_renderer_base::cairo_renderer_base(Map const& m,
cairo_ptr const& cairo,
double scale_factor,

View file

@ -285,16 +285,22 @@ font_face_set::size_type font_face_set::size() const
return faces_.size();
}
glyph_ptr font_face_set::get_glyph(unsigned c) const
font_glyph font_face_set::get_glyph(unsigned c) const
{
FT_UInt g = 0;
font_face * cur_face = 0;
BOOST_FOREACH ( face_ptr const& face, faces_)
{
FT_UInt g = face->get_char(c);
if (g) return boost::make_shared<font_glyph>(face, g);
g = face->get_char(c);
if (g)
{
cur_face = face.get();
break;
}
}
// Final fallback to empty square if nothing better in any font
return boost::make_shared<font_glyph>(*faces_.begin(), 0);
return font_glyph(g > 0 ? * cur_face: *(*faces_.begin()), g);
}
char_info font_face_set::character_dimensions(unsigned int c)
@ -317,8 +323,8 @@ char_info font_face_set::character_dimensions(unsigned int c)
FT_BBox glyph_bbox;
FT_Glyph image;
glyph_ptr glyph = get_glyph(c);
FT_Face face = glyph->get_face()->get_face();
font_glyph glyph = get_glyph(c);
FT_Face face = glyph.get_face().get_face();
matrix.xx = (FT_Fixed)( 1 * 0x10000L );
matrix.xy = (FT_Fixed)( 0 * 0x10000L );
@ -327,7 +333,7 @@ char_info font_face_set::character_dimensions(unsigned int c)
FT_Set_Transform(face, &matrix, &pen);
error = FT_Load_Glyph (face, glyph->get_index(), FT_LOAD_NO_HINTING);
error = FT_Load_Glyph (face, glyph.get_index(), FT_LOAD_NO_HINTING);
if ( error )
return char_info();
@ -560,8 +566,8 @@ box2d<double> text_renderer<T>::prepare_glyphs(text_path const& path)
face_set_ptr faces = font_manager_.get_face_set(c->format->face_name, c->format->fontset);
faces->set_character_sizes(c->format->text_size*scale_factor_);
glyph_ptr glyph = faces->get_glyph(unsigned(c->c));
FT_Face face = glyph->get_face()->get_face();
font_glyph glyph = faces->get_glyph(unsigned(c->c));
FT_Face face = glyph.get_face().get_face();
matrix.xx = (FT_Fixed)( std::cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-std::sin( angle ) * 0x10000L );
@ -570,7 +576,7 @@ box2d<double> text_renderer<T>::prepare_glyphs(text_path const& path)
FT_Set_Transform(face, &matrix, &pen);
error = FT_Load_Glyph(face, glyph->get_index(), FT_LOAD_NO_HINTING);
error = FT_Load_Glyph(face, glyph.get_index(), FT_LOAD_NO_HINTING);
if ( error )
continue;

View file

@ -72,7 +72,8 @@ string_info const& processed_text::get_string_info()
{
if (!p.face_name.empty())
{
throw config_error("Unable to find specified font face '" + p.face_name + "' in font set: '" + p.fontset->get_name() + "'");
throw config_error("Unable to find specified font face '" + p.face_name
+ "' in font set: '" + p.fontset->get_name() + "'");
}
else
{