X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=inline;f=src%2Fdisplay%2Fnr-arena-shape.cpp;h=bd6ca1df8c18e270447fbaeb614721b0f6f766f4;hb=af8d2404ed87b64d2fbd83794c360fd9b09bd83a;hp=2e15ac5aa902d580bf840c70d0138161007a74a2;hpb=5a51e21c14cf2a43aa5e5615be208fc19dae6270;p=inkscape.git diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index 2e15ac5aa..bd6ca1df8 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -32,6 +32,7 @@ #include "prefs-utils.h" #include "sp-filter.h" #include "sp-gaussian-blur.h" +#include "inkscape-cairo.h" #include @@ -48,7 +49,7 @@ static void nr_arena_shape_remove_child(NRArenaItem *item, NRArenaItem *child); static void nr_arena_shape_set_child_position(NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); static guint nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset); -static unsigned int nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); +static unsigned int nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); static guint nr_arena_shape_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb); static NRArenaItem *nr_arena_shape_pick(NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); @@ -725,90 +726,12 @@ nr_arena_shape_add_bboxes(NRArenaShape* shape, NRRect &bbox) } } -/** Feeds path-creating calls to the cairo context translating them from the SPCurve, with the given transform and shift */ -static void -feed_curve_to_cairo (cairo_t *ct, SPCurve *curve, NR::Matrix trans, NR::Point shift) -{ - NR::Point lastX(0,0); - bool closed = false; - NArtBpath *bpath = SP_CURVE_BPATH(curve); - for (int i = 0; bpath[i].code != NR_END; i++) { - switch (bpath[i].code) { - case NR_MOVETO_OPEN: - case NR_MOVETO: - if (closed) cairo_close_path(ct); - closed = (bpath[i].code == NR_MOVETO); - lastX[NR::X] = bpath[i].x3; - lastX[NR::Y] = bpath[i].y3; - lastX *= trans; - lastX -= shift; - cairo_move_to(ct, lastX[NR::X], lastX[NR::Y]); - break; - - case NR_LINETO: - lastX[NR::X] = bpath[i].x3; - lastX[NR::Y] = bpath[i].y3; - lastX *= trans; - lastX -= shift; - cairo_line_to(ct, lastX[NR::X], lastX[NR::Y]); - break; - - case NR_CURVETO: { - NR::Point tm1, tm2, tm3; - tm1[0]=bpath[i].x1; - tm1[1]=bpath[i].y1; - tm2[0]=bpath[i].x2; - tm2[1]=bpath[i].y2; - tm3[0]=bpath[i].x3; - tm3[1]=bpath[i].y3; - tm1 *= trans; - tm2 *= trans; - tm3 *= trans; - tm1 -= shift; - tm2 -= shift; - tm3 -= shift; - cairo_curve_to (ct, tm1[NR::X], tm1[NR::Y], tm2[NR::X], tm2[NR::Y], tm3[NR::X], tm3[NR::Y]); - break; - } - - default: - break; - } - } -} - -/** Creates a cairo context to render to the given pixblock on the given area */ -cairo_t * -nr_create_cairo_context (NRRectL *area, NRPixBlock *pb) -{ - if (!nr_rect_l_test_intersect (&pb->area, area)) - return NULL; - - NRRectL clip; - nr_rect_l_intersect (&clip, &pb->area, area); - unsigned char *dpx = NR_PIXBLOCK_PX (pb) + (clip.y0 - pb->area.y0) * pb->rs + NR_PIXBLOCK_BPP (pb) * (clip.x0 - pb->area.x0); - int width = area->x1 - area->x0; - int height = area->y1 - area->y0; - // even though cairo cannot draw in nonpremul mode, select ARGB32 for R8G8B8A8N as the closest; later eliminate R8G8B8A8N everywhere - cairo_surface_t* cst = cairo_image_surface_create_for_data - (dpx, - ((pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P || pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N) ? CAIRO_FORMAT_ARGB32 : (pb->mode == NR_PIXBLOCK_MODE_R8G8B8? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_A8)), - width, - height, - pb->rs); - cairo_t *ct = cairo_create (cst); - - return ct; -} - // cairo outline rendering: static unsigned int -cairo_arena_shape_render_outline(NRArenaItem *item, NRRectL *area, NRPixBlock *pb) +cairo_arena_shape_render_outline(cairo_t *ct, NRArenaItem *item, NR::Point shift) { NRArenaShape *shape = NR_ARENA_SHAPE(item); - cairo_t *ct = nr_create_cairo_context (area, pb); - if (!ct) return item->state; @@ -819,17 +742,10 @@ cairo_arena_shape_render_outline(NRArenaItem *item, NRRectL *area, NRPixBlock *p cairo_set_tolerance(ct, 1.25); // low quality, but good enough for outline mode cairo_new_path(ct); - feed_curve_to_cairo (ct, shape->curve, NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0)); + feed_curve_to_cairo (ct, SP_CURVE_BPATH(shape->curve), NR::Matrix(shape->ctm), shift); cairo_stroke(ct); - cairo_surface_t *cst = cairo_get_target(ct); - cairo_destroy (ct); - cairo_surface_finish (cst); - cairo_surface_destroy (cst); - - pb->empty = FALSE; - return item->state; } @@ -908,7 +824,7 @@ cairo_arena_shape_render_stroke(NRArenaItem *item, NRRectL *area, NRPixBlock *pb cairo_set_tolerance(ct, 0.1); cairo_new_path(ct); - feed_curve_to_cairo (ct, shape->curve, NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0)); + feed_curve_to_cairo (ct, SP_CURVE_BPATH(shape->curve), NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0)); cairo_stroke(ct); @@ -925,7 +841,7 @@ cairo_arena_shape_render_stroke(NRArenaItem *item, NRRectL *area, NRPixBlock *pb * Renders the item. Markers are just composed into the parent buffer. */ static unsigned int -nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags) +nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags) { NRArenaShape *shape = NR_ARENA_SHAPE(item); @@ -935,7 +851,8 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == RENDERMODE_OUTLINE); if (outline) { - return cairo_arena_shape_render_outline (item, area, pb); + pb->empty = FALSE; + return cairo_arena_shape_render_outline (ct, item, NR::Point(pb->area.x0, pb->area.y0)); } if ( shape->delayed_shp ) { @@ -1055,7 +972,7 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned /* Just compose children into parent buffer */ for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { unsigned int ret; - ret = nr_arena_item_invoke_render(child, area, pb, flags); + ret = nr_arena_item_invoke_render(ct, child, area, pb, flags); if (ret & NR_ARENA_ITEM_STATE_INVALID) return ret; } @@ -1080,7 +997,7 @@ cairo_arena_shape_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb) cairo_new_path(ct); - feed_curve_to_cairo (ct, shape->curve, NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0)); + feed_curve_to_cairo (ct, SP_CURVE_BPATH(shape->curve), NR::Matrix(shape->ctm), NR::Point(area->x0, area->y0)); cairo_fill(ct);