static void
_tiling_surface_finish (cairo_surface_t *observer,
			cairo_surface_t *target,
			void *closure)
{
    struct trace *args = closure;
    cairo_surface_t *surface;
    cairo_content_t content;
    cairo_rectangle_t r;
    int width, height;
    int x, y, w, h;

    cairo_recording_surface_get_extents (target, &r);
    w = r.width;
    h = r.height;

    content = cairo_surface_get_content (target);

    for (y = 0; y < h; y += args->tile_size) {
	height = args->tile_size;
	if (y + height > h)
	    height = h - y;

	for (x = 0; x < w; x += args->tile_size) {
	    cairo_t *cr;

	    width = args->tile_size;
	    if (x + width > w)
		width = w - x;

	    /* XXX to correctly observe the playback we would need
	     * to replay the target onto the observer directly.
	     */
	    surface = args->target->create_similar (args->surface,
						    content, width, height);

	    cr = cairo_create (surface);
	    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
	    cairo_set_source_surface (cr, target, -x, -y);
	    cairo_paint (cr);
	    cairo_destroy (cr);

	    cairo_surface_destroy (surface);
	}
    }
}
Ejemplo n.º 2
0
    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();
    }