void render(cairo_fill_rule_t fill_rule, cairo_context & context) { value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_); agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_); auto image_transform = get_optional<transform_type>(sym_, keys::image_transform); if (image_transform) { evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_); } composite_mode_e comp_op = get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_); cairo_save_restore guard(context); context.set_operator(comp_op); cairo_renderer_process_visitor_p visitor(image_tr, opacity); cairo_surface_ptr surface(util::apply_visitor(visitor, this->marker_)); coord<double, 2> offset(0, 0); cairo_rectangle_t pattern_surface_extent; if (cairo_recording_surface_get_extents(surface.get(), &pattern_surface_extent)) { offset = pattern_offset(sym_, feature_, prj_trans_, common_, pattern_surface_extent.width, pattern_surface_extent.height); } cairo_pattern pattern(surface); pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_origin(-offset.x, -offset.y); context.set_pattern(pattern); using apply_vertex_converter_type = detail::apply_vertex_converter<VertexConverter, cairo_context>; using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>; apply_vertex_converter_type apply(converter_, context); mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry()); // fill polygon context.set_fill_rule(fill_rule); context.fill(); }
void render_vector_marker(cairo_context & context, svg::svg_path_adapter & svg_path, agg::pod_bvector<svg::path_attributes> const & attributes, box2d<double> const& bbox, agg::trans_affine const& tr, double opacity) { using namespace mapnik::svg; agg::trans_affine transform; for(unsigned i = 0; i < attributes.size(); ++i) { mapnik::svg::path_attributes const& attr = attributes[i]; if (!attr.visibility_flag) continue; cairo_save_restore guard(context); transform = attr.transform; transform *= tr; // TODO - this 'is_valid' check is not used in the AGG renderer and also // appears to lead to bogus results with // tests/data/good_maps/markers_symbolizer_lines_file.xml //if (transform.is_valid() && !transform.is_identity()) if (!transform.is_identity()) { double m[6]; transform.store_to(m); cairo_matrix_t matrix; cairo_matrix_init(&matrix,m[0],m[1],m[2],m[3],m[4],m[5]); context.transform(matrix); } if (attr.fill_flag || attr.fill_gradient.get_gradient_type() != NO_GRADIENT) { context.add_agg_path(svg_path,attr.index); if (attr.even_odd_flag) { context.set_fill_rule(CAIRO_FILL_RULE_EVEN_ODD); } else { context.set_fill_rule(CAIRO_FILL_RULE_WINDING); } if(attr.fill_gradient.get_gradient_type() != NO_GRADIENT) { cairo_gradient g(attr.fill_gradient,attr.fill_opacity * attr.opacity * opacity); context.set_gradient(g,bbox); context.fill(); } else if(attr.fill_flag) { double fill_opacity = attr.fill_opacity * attr.opacity * opacity * attr.fill_color.opacity(); context.set_color(attr.fill_color.r/255.0,attr.fill_color.g/255.0, attr.fill_color.b/255.0, fill_opacity); context.fill(); } } if (attr.stroke_gradient.get_gradient_type() != NO_GRADIENT || attr.stroke_flag) { context.add_agg_path(svg_path,attr.index); if(attr.stroke_gradient.get_gradient_type() != NO_GRADIENT) { context.set_line_width(attr.stroke_width); context.set_line_cap(line_cap_enum(attr.line_cap)); context.set_line_join(line_join_enum(attr.line_join)); context.set_miter_limit(attr.miter_limit); cairo_gradient g(attr.stroke_gradient,attr.fill_opacity * attr.opacity * opacity); context.set_gradient(g,bbox); context.stroke(); } else if (attr.stroke_flag) { double stroke_opacity = attr.stroke_opacity * attr.opacity * opacity * attr.stroke_color.opacity(); context.set_color(attr.stroke_color.r/255.0,attr.stroke_color.g/255.0, attr.stroke_color.b/255.0, stroke_opacity); context.set_line_width(attr.stroke_width); context.set_line_cap(line_cap_enum(attr.line_cap)); context.set_line_join(line_join_enum(attr.line_join)); context.set_miter_limit(attr.miter_limit); context.stroke(); } } } }