From 328fad57dbfb65e3bd31062021d5cc3081e68515 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 22 Jul 2011 04:09:27 +0200 Subject: Replace direct use of Cairo contexts and surfaces in the rendering tree with wrappers which keep some extra information about the surface, amd NRRect and NRRectL use with Geom::Rect and Geom::IntRect. Should simplify implementing filter primitive subregions. (bzr r10347.1.17) --- src/sp-pattern.cpp | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index d1e7671ed..3a3d01ebd 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -22,6 +22,8 @@ #include "macros.h" #include "svg/svg.h" #include "display/cairo-utils.h" +#include "display/drawing-context.h" +#include "display/drawing-surface.h" #include "display/nr-arena.h" #include "display/nr-arena-group.h" #include "attributes.h" @@ -658,9 +660,8 @@ sp_pattern_create_pattern(SPPaintServer *ps, } ps2user = Geom::Translate (pattern_x (pat), pattern_y (pat)) * ps2user; - Geom::Point p(pattern_x(pat), pattern_y(pat)); - Geom::Point pd(pattern_width(pat), pattern_height(pat)); - Geom::Rect pattern_tile(p, p + pd); + Geom::Rect pattern_tile = Geom::Rect::from_xywh(pattern_x(pat), pattern_y(pat), + pattern_width(pat), pattern_height(pat)); if (pattern_patternUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { // interpret x, y, width, height in relation to bbox @@ -674,34 +675,24 @@ sp_pattern_create_pattern(SPPaintServer *ps, // oversample the pattern slightly // TODO: find optimum value - Geom::Point c(pattern_tile.dimensions()*ps2user.descrim()*full.descrim()*1.2); + Geom::Point c(pattern_tile.dimensions()*ps2user.descrim()*full.descrim()*1.1); c[Geom::X] = ceil(c[Geom::X]); c[Geom::Y] = ceil(c[Geom::Y]); - Geom::Affine t = Geom::Scale(c) * Geom::Scale(pattern_tile.dimensions()).inverse(); - - NRRectL one_tile; - one_tile.x0 = (int) floor(pattern_tile[Geom::X].min()); - one_tile.y0 = (int) floor(pattern_tile[Geom::Y].min()); - one_tile.x1 = (int) ceil(pattern_tile[Geom::X].max()); - one_tile.y1 = (int) ceil(pattern_tile[Geom::Y].max()); - - cairo_surface_t *target = cairo_get_target(base_ct); - cairo_surface_t *temp = cairo_surface_create_similar(target, CAIRO_CONTENT_COLOR_ALPHA, - c[Geom::X], c[Geom::Y]); - cairo_t *ct = cairo_create(temp); - // scale into a coord system where the surface w,h are equal to tile w,h - ink_cairo_transform(ct, t); + + Geom::IntRect one_tile = pattern_tile.roundOutwards(); + Inkscape::DrawingSurface temp(pattern_tile, c.ceil()); + Inkscape::DrawingContext ct(temp); // render pattern. if (needs_opacity) { - cairo_push_group(ct); // this group is for pattern + opacity + ct.pushGroup(); // this group is for pattern + opacity } // TODO: make sure there are no leaks. NRGC gc(NULL); gc.transform = vb2ps; - nr_arena_item_invoke_update (root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_ALL); - nr_arena_item_invoke_render (ct, root, &one_tile, NULL, 0); + nr_arena_item_invoke_update (root, Geom::IntRect::infinite(), &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_ALL); + nr_arena_item_invoke_render (ct, root, one_tile, 0); for (SPObject *child = shown->firstChild() ; child != NULL; child = child->getNext() ) { if (SP_IS_ITEM (child)) { SP_ITEM(child)->invoke_hide(dkey); @@ -711,16 +702,14 @@ sp_pattern_create_pattern(SPPaintServer *ps, nr_object_unref(arena); if (needs_opacity) { - cairo_pop_group_to_source(ct); // pop raw pattern - cairo_paint_with_alpha(ct, opacity); // apply opacity + ct.popGroupToSource(); // pop raw pattern + ct.paint(opacity); // apply opacity } - cairo_pattern_t *cp = cairo_pattern_create_for_surface(temp); - cairo_destroy(ct); - cairo_surface_destroy(temp); + cairo_pattern_t *cp = cairo_pattern_create_for_surface(temp.raw()); // Apply transformation to user space. Also compensate for oversampling. - ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * t); + ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * temp.drawingTransform()); cairo_pattern_set_extend(cp, CAIRO_EXTEND_REPEAT); return cp; -- cgit v1.2.3