update cairo_renderer

This commit is contained in:
artemp 2014-06-05 15:13:01 +01:00
parent 961bc69a1c
commit bbb727e39a
5 changed files with 81 additions and 83 deletions

View file

@ -211,6 +211,7 @@ struct vector_markers_rasterizer_dispatch_grid : mapnik::noncopyable
double scale_factor, double scale_factor,
mapnik::feature_impl const& feature, mapnik::feature_impl const& feature,
attributes const& vars, attributes const& vars,
bool snap_to_pixels,
RendererContext const& renderer_context) RendererContext const& renderer_context)
: buf_(std::get<0>(renderer_context)), : buf_(std::get<0>(renderer_context)),
pixf_(buf_), pixf_(buf_),

View file

@ -78,8 +78,8 @@ struct vector_markers_rasterizer_dispatch : mapnik::noncopyable
double scale_factor, double scale_factor,
feature_impl & feature, feature_impl & feature,
attributes const& vars, attributes const& vars,
RendererContext const& renderer_context, bool snap_to_pixels,
bool snap_to_pixels = false) RendererContext const& renderer_context)
: buf_(std::get<0>(renderer_context)), : buf_(std::get<0>(renderer_context)),
pixf_(buf_), pixf_(buf_),
renb_(pixf_), renb_(pixf_),

View file

@ -50,7 +50,7 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
double smooth = get<value_double>(sym, keys::smooth, feature, common.vars_, false); double smooth = get<value_double>(sym, keys::smooth, feature, common.vars_, false);
// https://github.com/mapnik/mapnik/issues/1316 // https://github.com/mapnik/mapnik/issues/1316
bool snap_pixels = !mapnik::marker_cache::instance().is_uri(filename); bool snap_to_pixels = !mapnik::marker_cache::instance().is_uri(filename);
if (!filename.empty()) if (!filename.empty())
{ {
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance().find(filename, true); boost::optional<marker_ptr> mark = mapnik::marker_cache::instance().find(filename, true);
@ -79,22 +79,21 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
auto image_transform = get_optional<transform_type>(sym, keys::image_transform); auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform); if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform);
box2d<double> bbox = marker_ellipse.bounding_box(); box2d<double> bbox = marker_ellipse.bounding_box();
coord2d center = bbox.center();
vector_dispatch_type rasterizer_dispatch(//std::get<0>(renderer_context), // render_buf agg::trans_affine_translation recenter(-center.x, -center.y);
svg_path, agg::trans_affine marker_trans = recenter * tr;
vector_dispatch_type rasterizer_dispatch(svg_path,
result ? attributes : (*stock_vector_marker)->attributes(), result ? attributes : (*stock_vector_marker)->attributes(),
//std::get<1>(renderer_context), // rasterizer
bbox, bbox,
tr, marker_trans,
sym, sym,
*common.detector_, *common.detector_,
common.scale_factor_, common.scale_factor_,
feature, feature,
common.vars_, common.vars_,
snap_to_pixels,
renderer_context); renderer_context);
//std::get<2>(renderer_context)); // pixmap
vertex_converter<box2d<double>, vector_dispatch_type, markers_symbolizer, vertex_converter<box2d<double>, vector_dispatch_type, markers_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.vars_,common.scale_factor_); converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.vars_,common.scale_factor_);
@ -135,6 +134,7 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
common.scale_factor_, common.scale_factor_,
feature, feature,
common.vars_, common.vars_,
snap_to_pixels,
renderer_context); renderer_context);
vertex_converter<box2d<double>, vector_dispatch_type, markers_symbolizer, vertex_converter<box2d<double>, vector_dispatch_type, markers_symbolizer,
@ -162,12 +162,10 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform); if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform);
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data(); boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
// - clamp sizes to > 4 pixels of interactivity // - clamp sizes to > 4 pixels of interactivity
coord2d center = bbox.center(); coord2d center = bbox.center();
agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine_translation recenter(-center.x, -center.y);
agg::trans_affine marker_trans = recenter * tr; agg::trans_affine marker_trans = recenter * tr;
raster_dispatch_type rasterizer_dispatch(**marker, raster_dispatch_type rasterizer_dispatch(**marker,
marker_trans, marker_trans,
sym, sym,

View file

@ -25,7 +25,7 @@
// mapnik // mapnik
#include <mapnik/noncopyable.hpp> #include <mapnik/noncopyable.hpp>
#include <mapnik/box2d.hpp>
// agg // agg
#include "agg_math.h" #include "agg_math.h"
#include "agg_array.h" #include "agg_array.h"
@ -937,6 +937,10 @@ public:
return vertices_[idx].cmd; return vertices_[idx].cmd;
} }
box2d<double> const& bounding_box() const
{
vertices_.bounding_box();
}
private: private:
Container & vertices_; Container & vertices_;
}; };

View file

@ -419,13 +419,12 @@ void cairo_renderer_base::render_box(box2d<double> const& b)
context_.stroke(); context_.stroke();
} }
void render_vector_marker(cairo_context & context, pixel_position const& pos, mapnik::svg_storage_type & vmarker, void render_vector_marker(cairo_context & context, pixel_position const& pos,
svg::svg_path_adapter & svg_path, box2d<double> const& bbox,
agg::pod_bvector<svg::path_attributes> const & attributes, agg::pod_bvector<svg::path_attributes> const & attributes,
agg::trans_affine const& tr, double opacity, bool recenter) agg::trans_affine const& tr, double opacity, bool recenter)
{ {
using namespace mapnik::svg; using namespace mapnik::svg;
box2d<double> bbox = vmarker.bounding_box();
agg::trans_affine mtx = tr; agg::trans_affine mtx = tr;
if (recenter) if (recenter)
@ -459,9 +458,6 @@ void render_vector_marker(cairo_context & context, pixel_position const& pos, ma
context.transform(matrix); context.transform(matrix);
} }
vertex_stl_adapter<svg_path_storage> stl_storage(vmarker.source());
svg_path_adapter svg_path(stl_storage);
if (attr.fill_flag || attr.fill_gradient.get_gradient_type() != NO_GRADIENT) if (attr.fill_flag || attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
{ {
context.add_agg_path(svg_path,attr.index); context.add_agg_path(svg_path,attr.index);
@ -533,8 +529,11 @@ void cairo_renderer_base::render_marker(pixel_position const& pos,
{ {
agg::trans_affine marker_tr = tr; agg::trans_affine marker_tr = tr;
marker_tr *=agg::trans_affine_scaling(common_.scale_factor_); marker_tr *=agg::trans_affine_scaling(common_.scale_factor_);
box2d<double> bbox = vmarker->bounding_box();
agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes(); agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes();
render_vector_marker(context_, pos, *vmarker, attributes, marker_tr, opacity, recenter); svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(vmarker->source());
svg::svg_path_adapter svg_path(stl_storage);
render_vector_marker(context_, pos, svg_path, bbox, attributes, marker_tr, opacity, recenter);
} }
} }
else if (marker.is_bitmap()) else if (marker.is_bitmap())
@ -773,29 +772,31 @@ void cairo_renderer_base::process(raster_symbolizer const& sym,
namespace detail { namespace detail {
template <typename Context, typename SvgPath, typename Attributes, typename Detector> template <typename RendererContext, typename SvgPath, typename Attributes, typename Detector>
struct markers_dispatch struct markers_dispatch : mapnik::noncopyable
{ {
markers_dispatch(Context & ctx, markers_dispatch(SvgPath & marker,
SvgPath & marker,
Attributes const& attributes, Attributes const& attributes,
Detector & detector,
markers_symbolizer const& sym,
box2d<double> const& bbox, box2d<double> const& bbox,
agg::trans_affine const& marker_trans, agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
double scale_factor,
feature_impl const& feature, feature_impl const& feature,
mapnik::attributes const& vars, mapnik::attributes const& vars,
double scale_factor) bool snap_to_pixels,
:ctx_(ctx), RendererContext const& renderer_context)
marker_(marker), :marker_(marker),
attributes_(attributes), attributes_(attributes),
detector_(detector),
sym_(sym),
bbox_(bbox), bbox_(bbox),
marker_trans_(marker_trans), marker_trans_(marker_trans),
sym_(sym),
detector_(detector),
scale_factor_(scale_factor),
feature_(feature), feature_(feature),
vars_(vars), vars_(vars),
scale_factor_(scale_factor) {} ctx_(std::get<0>(renderer_context))
{}
template <typename T> template <typename T>
@ -815,18 +816,15 @@ struct markers_dispatch
double y = 0; double y = 0;
if (path.type() == geometry_type::types::LineString) if (path.type() == geometry_type::types::LineString)
{ {
if (!label::middle_point(path, x, y)) if (!label::middle_point(path, x, y)) return;
return;
} }
else if (placement_method == MARKER_INTERIOR_PLACEMENT) else if (placement_method == MARKER_INTERIOR_PLACEMENT)
{ {
if (!label::interior_position(path, x, y)) if (!label::interior_position(path, x, y)) return;
return;
} }
else else
{ {
if (!label::centroid(path, x, y)) if (!label::centroid(path, x, y)) return;
return;
} }
coord2d center = bbox_.center(); coord2d center = bbox_.center();
agg::trans_affine matrix = agg::trans_affine_translation(-center.x, -center.y); agg::trans_affine matrix = agg::trans_affine_translation(-center.x, -center.y);
@ -838,7 +836,7 @@ struct markers_dispatch
if (allow_overlap || if (allow_overlap ||
detector_.has_placement(transformed_bbox)) detector_.has_placement(transformed_bbox))
{ {
render_vector_marker(ctx_, pixel_position(x,y), marker_, attributes_, marker_trans_, opacity, true); render_vector_marker(ctx_, pixel_position(x,y), marker_, bbox_, attributes_, marker_trans_, opacity, true);
if (!ignore_placement) if (!ignore_placement)
{ {
@ -857,13 +855,12 @@ struct markers_dispatch
{ {
agg::trans_affine matrix = marker_trans_; agg::trans_affine matrix = marker_trans_;
matrix.rotate(angle); matrix.rotate(angle);
render_vector_marker(ctx_, pixel_position(x,y),marker_, attributes_, matrix, opacity, true); render_vector_marker(ctx_, pixel_position(x,y),marker_, bbox_, attributes_, matrix, opacity, true);
} }
} }
} }
Context & ctx_;
SvgPath & marker_; SvgPath & marker_;
Attributes const& attributes_; Attributes const& attributes_;
Detector & detector_; Detector & detector_;
@ -873,30 +870,33 @@ struct markers_dispatch
feature_impl const& feature_; feature_impl const& feature_;
attributes const& vars_; attributes const& vars_;
double scale_factor_; double scale_factor_;
cairo_context & ctx_;
}; };
template <typename Context, typename ImageMarker, typename Detector> template <typename RendererContext, typename ImageMarker, typename Detector>
struct markers_dispatch_2 struct markers_dispatch_2 : mapnik::noncopyable
{ {
markers_dispatch_2(Context & ctx,
ImageMarker & marker, //typedef typename std::tuple_element<0,RendererContext>::type CairoContext;
Detector & detector,
markers_symbolizer const& sym, markers_dispatch_2(ImageMarker & marker,
box2d<double> const& bbox,
agg::trans_affine const& marker_trans, agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
//box2d<double> const& bbox,
double scale_factor,
feature_impl const& feature, feature_impl const& feature,
mapnik::attributes const& vars, mapnik::attributes const& vars,
double scale_factor) RendererContext const& renderer_context)
:ctx_(ctx), :marker_(marker),
marker_(marker),
detector_(detector), detector_(detector),
sym_(sym), sym_(sym),
bbox_(bbox), bbox_(std::get<1>(renderer_context)),
marker_trans_(marker_trans), marker_trans_(marker_trans),
feature_(feature), feature_(feature),
vars_(vars), vars_(vars),
scale_factor_(scale_factor) {} scale_factor_(scale_factor),
ctx_(std::get<0>(renderer_context)) {}
template <typename T> template <typename T>
void add_path(T & path) void add_path(T & path)
@ -964,7 +964,7 @@ struct markers_dispatch_2
} }
} }
Context & ctx_; cairo_context & ctx_;
ImageMarker & marker_; ImageMarker & marker_;
Detector & detector_; Detector & detector_;
markers_symbolizer const& sym_; markers_symbolizer const& sym_;
@ -981,29 +981,24 @@ void cairo_renderer_base::process(markers_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
typedef agg::pod_bvector<svg::path_attributes> svg_attribute_type; typedef agg::pod_bvector<svg::path_attributes> svg_attribute_type;
typedef detail::markers_dispatch_2<cairo_context, mapnik::image_data_32,
label_collision_detector4> raster_dispatch_type;
typedef detail::markers_dispatch<cairo_context, mapnik::svg_storage_type, svg_attribute_type,
label_collision_detector4> vector_dispatch_type;
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
context_.set_operator(comp_op); context_.set_operator(comp_op);
box2d<double> clip_box = common_.query_extent_; box2d<double> clip_box = common_.query_extent_;
render_markers_symbolizer( auto renderer_context = std::tie(context_, clip_box);
typedef decltype(renderer_context) RendererContextType;
typedef detail::markers_dispatch<RendererContextType, svg::path_adapter<svg::vertex_stl_adapter<svg::svg_path_storage> > , svg_attribute_type,
label_collision_detector4> vector_dispatch_type;
typedef detail::markers_dispatch_2<RendererContextType, mapnik::image_data_32,
label_collision_detector4> raster_dispatch_type;
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
sym, feature, prj_trans, common_, clip_box, sym, feature, prj_trans, common_, clip_box,
[&](svg::svg_path_adapter &, svg_attribute_type const &attr, svg_storage_type &marker, renderer_context);
box2d<double> const &bbox, agg::trans_affine const &marker_trans,
bool) -> vector_dispatch_type {
return vector_dispatch_type(context_, marker, attr, *common_.detector_, sym, bbox,
marker_trans, feature, common_.vars_, common_.scale_factor_);
},
[&](image_data_32 &marker, agg::trans_affine const &marker_trans,
box2d<double> const &bbox) -> raster_dispatch_type {
return raster_dispatch_type(context_, marker, *common_.detector_, sym, bbox,
marker_trans, feature, common_.vars_, common_.scale_factor_);
});
} }
void cairo_renderer_base::process(text_symbolizer const& sym, void cairo_renderer_base::process(text_symbolizer const& sym,