diff options
| author | Andrius Ramanauskas <knutux@gmail.com> | 2006-04-19 05:14:26 +0000 |
|---|---|---|
| committer | knutux <knutux@users.sourceforge.net> | 2006-04-19 05:14:26 +0000 |
| commit | cd3043cf07c274cd641b8483b55177e9a5cb1e10 (patch) | |
| tree | f860995235a5dc981868ab4f3482e861322ffe01 /src/display | |
| parent | fix name and size (diff) | |
| download | inkscape-cd3043cf07c274cd641b8483b55177e9a5cb1e10.tar.gz inkscape-cd3043cf07c274cd641b8483b55177e9a5cb1e10.zip | |
Rendering optimisation, which gives best results for zoomed in drawings with complex (multi-node) paths. Optimisation focus - eliminating cubicTo and LineTo nodes outside of visible area, so no unneeded calculations is needed and less memory is consumed (this avoids crashes which were occurring previously if zooming into a complex drawing)
(bzr r541)
Diffstat (limited to 'src/display')
| -rw-r--r-- | src/display/canvas-arena.cpp | 2 | ||||
| -rw-r--r-- | src/display/nr-arena-glyphs.cpp | 2 | ||||
| -rw-r--r-- | src/display/nr-arena-item.cpp | 7 | ||||
| -rw-r--r-- | src/display/nr-arena-shape.cpp | 108 | ||||
| -rw-r--r-- | src/display/nr-arena-shape.h | 4 | ||||
| -rw-r--r-- | src/display/nr-arena.cpp | 2 | ||||
| -rw-r--r-- | src/display/nr-gradient-gpl.cpp | 1 | ||||
| -rw-r--r-- | src/display/sp-canvas.cpp | 4 | ||||
| -rw-r--r-- | src/display/sp-canvas.h | 1 | ||||
| -rw-r--r-- | src/display/sp-ctrlline.cpp | 7 |
10 files changed, 112 insertions, 26 deletions
diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 1d77de158..2d192ac1b 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -278,10 +278,12 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) FALSE, FALSE); #ifdef STRICT_RGBA + pb.visible_area = buf->visible_rect; nr_arena_item_invoke_render (arena->root, &area, &pb, 0); nr_blit_pixblock_pixblock (&cb, &pb); nr_pixblock_release (&pb); #else + cb.visible_area = buf->visible_rect; nr_arena_item_invoke_render (arena->root, &area, &cb, 0); #endif diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp index 78ba90c2b..083e7a7f4 100644 --- a/src/display/nr-arena-glyphs.cpp +++ b/src/display/nr-arena-glyphs.cpp @@ -440,6 +440,7 @@ nr_arena_glyphs_group_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, u if (style->fill.type != SP_PAINT_TYPE_NONE || item->arena->rendermode == RENDERMODE_OUTLINE) { NRPixBlock m; nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + m.visible_area = pb->visible_area; /* Render children fill mask */ for (child = group->children; child != NULL; child = child->next) { @@ -479,6 +480,7 @@ nr_arena_glyphs_group_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, u NRPixBlock m; guint32 rgba; nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + m.visible_area = pb->visible_area; /* Render children stroke mask */ for (child = group->children; child != NULL; child = child->next) { ret = nr_arena_glyphs_stroke_mask(NR_ARENA_GLYPHS(child), area, &m); diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp index 7f473ae4d..44068cf9d 100644 --- a/src/display/nr-arena-item.cpp +++ b/src/display/nr-arena-item.cpp @@ -340,6 +340,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area, nr_pixblock_setup_extern (&cpb, NR_PIXBLOCK_MODE_R8G8B8A8P, carea.x0, carea.y0, carea.x1, carea.y1, item->px, 4 * (carea.x1 - carea.x0), TRUE, TRUE); + cpb.visible_area = pb->visible_area; dpb = &cpb; // Set nocache flag for downstream rendering flags |= NR_ARENA_ITEM_RENDER_NO_CACHE; @@ -401,6 +402,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area, /* Setup and render item buffer */ nr_pixblock_setup_fast (&ipb, NR_PIXBLOCK_MODE_R8G8B8A8P, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + ipb.visible_area = pb->visible_area; state = NR_ARENA_ITEM_VIRTUAL (item, render) (item, &carea, &ipb, flags); if (state & NR_ARENA_ITEM_STATE_INVALID) { /* Clean up and return error */ @@ -414,6 +416,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area, if (item->clip || item->mask) { /* Setup mask pixblock */ nr_pixblock_setup_fast (&mpb, NR_PIXBLOCK_MODE_A8, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + mpb.visible_area = pb->visible_area; /* Do clip if needed */ if (item->clip) { state = nr_arena_item_invoke_clip (item->clip, &carea, &mpb); @@ -432,6 +435,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area, NRPixBlock tpb; /* Set up yet another temporary pixblock */ nr_pixblock_setup_fast (&tpb, NR_PIXBLOCK_MODE_R8G8B8A8N, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + tpb.visible_area = pb->visible_area; state = NR_ARENA_ITEM_VIRTUAL (item->mask, render) (item->mask, &carea, &tpb, flags); if (state & NR_ARENA_ITEM_STATE_INVALID) { /* Clean up and return error */ @@ -542,6 +546,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area, /* Setup and render item buffer */ nr_pixblock_setup_fast (&ipb, NR_PIXBLOCK_MODE_R8G8B8A8P, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + ipb.visible_area = pb->visible_area; state = NR_ARENA_ITEM_VIRTUAL (item, render) (item, &carea, &ipb, flags); if (state & NR_ARENA_ITEM_STATE_INVALID) { /* Clean up and return error */ @@ -555,6 +560,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area, if (item->clip || item->mask) { /* Setup mask pixblock */ nr_pixblock_setup_fast (&mpb, NR_PIXBLOCK_MODE_A8, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + mpb.visible_area = pb->visible_area; /* Do clip if needed */ if (item->clip) { state = nr_arena_item_invoke_clip (item->clip, &carea, &mpb); @@ -573,6 +579,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area, NRPixBlock tpb; /* Set up yet another temporary pixblock */ nr_pixblock_setup_fast (&tpb, NR_PIXBLOCK_MODE_R8G8B8A8N, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + tpb.visible_area = pb->visible_area; state = NR_ARENA_ITEM_VIRTUAL (item->mask, render) (item->mask, &carea, &tpb, flags); if (state & NR_ARENA_ITEM_STATE_INVALID) { /* Clean up and return error */ diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index 743a70f9c..4f8acca48 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -97,6 +97,8 @@ nr_arena_shape_init(NRArenaShape *shape) shape->stroke_painter = NULL; shape->cached_fill = NULL; shape->cached_stroke = NULL; + shape->cached_fpartialy = false; + shape->cached_spartialy = false; shape->fill_shp = NULL; shape->stroke_shp = NULL; @@ -184,8 +186,8 @@ nr_arena_shape_set_child_position(NRArenaItem *item, NRArenaItem *child, NRArena nr_arena_item_request_render(child); } -void nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc); -void nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape = false); +void nr_arena_shape_update_stroke(NRArenaShape *shape, NRGC* gc, NRRectL *area); +void nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool force_shape = false); void nr_arena_shape_add_bboxes(NRArenaShape* shape,NRRect &bbox); static guint @@ -301,8 +303,8 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g if ( shape->delayed_shp ) { item->bbox=shape->approx_bbox; } else { - nr_arena_shape_update_stroke(shape,gc); - nr_arena_shape_update_fill(shape,gc); + nr_arena_shape_update_stroke(shape, gc, area); + nr_arena_shape_update_fill(shape, gc, area); bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0; nr_arena_shape_add_bboxes(shape,bbox); @@ -377,19 +379,28 @@ int matrix_is_isometry(NR::Matrix p) { return 0; } +static bool is_inner_area(NRRectL const &outer, NRRectL const &inner) { + return (outer.x0 <= inner.x0 && outer.y0 <= inner.y0 && outer.x1 >= inner.x1 && outer.y1 >= inner.y1); +} + /** force_shape is used for clipping paths, when we need the shape for clipping even if it's not filled */ void -nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape) +nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool force_shape) { - shape->delayed_shp = false; if ((shape->_fill.paint.type() != NRArenaShape::Paint::NONE || force_shape) && ((shape->curve->end > 2) || (shape->curve->bpath[1].code == NR_CURVETO)) ) { if (TRUE || !shape->fill_shp) { NR::Matrix cached_to_new; int isometry = 0; if ( shape->cached_fill ) { - cached_to_new = shape->cached_fctm.inverse()*gc->transform; - isometry = matrix_is_isometry(cached_to_new); + if (shape->cached_fctm == gc->transform) { + isometry = 2; // identity + } else { + cached_to_new = shape->cached_fctm.inverse() * gc->transform; + isometry = matrix_is_isometry(cached_to_new); + } + if (0 != isometry && !is_inner_area(shape->cached_farea, *area)) + isometry = 0; } if ( isometry == 0 ) { if ( shape->cached_fill == NULL ) shape->cached_fill=new Shape; @@ -402,7 +413,13 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape) thePath->LoadArtBPath(shape->curve->bpath,tempMat,true); } - thePath->Convert(1.0); + if (is_inner_area(*area, NR_ARENA_ITEM(shape)->bbox)) { + thePath->Convert(1.0); + shape->cached_fpartialy = false; + } else { + thePath->Convert(area, 1.0); + shape->cached_fpartialy = true; + } thePath->Fill(theShape, 0); @@ -414,6 +431,7 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape) shape->cached_fill->ConvertToShape(theShape, fill_nonZero); } shape->cached_fctm=gc->transform; + shape->cached_farea = *area; delete theShape; delete thePath; if ( shape->fill_shp == NULL ) @@ -421,6 +439,11 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape) shape->fill_shp->Copy(shape->cached_fill); + } else if ( 2 == isometry ) { + if ( shape->fill_shp == NULL ) { + shape->fill_shp = new Shape; + shape->fill_shp->Copy(shape->cached_fill); + } } else { if ( shape->fill_shp == NULL ) @@ -443,17 +466,16 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, bool force_shape) shape->fill_shp->needPointsSorting(); shape->fill_shp->needEdgesSorting(); } + shape->delayed_shp |= shape->cached_fpartialy; } } } void -nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc) +nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc, NRRectL *area) { SPStyle* style = shape->style; - shape->delayed_shp = false; - float const scale = NR_MATRIX_DF_EXPANSION(&gc->transform); if (NR_ARENA_ITEM(shape)->arena->rendermode == RENDERMODE_OUTLINE || @@ -468,8 +490,14 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc) int isometry = 0; if ( shape->cached_stroke ) { - cached_to_new = shape->cached_sctm.inverse() * gc->transform; - isometry = matrix_is_isometry(cached_to_new); + if (shape->cached_sctm == gc->transform) { + isometry = 2; // identity + } else { + cached_to_new = shape->cached_sctm.inverse() * gc->transform; + isometry = matrix_is_isometry(cached_to_new); + } + if (0 != isometry && !is_inner_area(shape->cached_sarea, *area)) + isometry = 0; } if ( isometry == 0 ) { @@ -482,10 +510,20 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc) thePath->LoadArtBPath(shape->curve->bpath, tempMat, true); } - if (NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) - thePath->Convert(1.0); - else - thePath->Convert(4.0); // slightly rougher & faster + // add some padding to the rendering area, so clipped path does not go into a render area + NRRectL padded_area = *area; + padded_area.x0 -= (NR::ICoord)width; + padded_area.x1 += (NR::ICoord)width; + padded_area.y0 -= (NR::ICoord)width; + padded_area.y1 += (NR::ICoord)width; + if (is_inner_area(padded_area, NR_ARENA_ITEM(shape)->bbox)) { + thePath->Convert((NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) ? 1.0 : 4.0); + shape->cached_spartialy = false; + } + else { + thePath->Convert(&padded_area, (NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) ? 1.0 : 4.0); + shape->cached_spartialy = true; + } if (style->stroke_dash.n_dash && NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) { double dlen = 0.0; @@ -555,14 +593,19 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc) } shape->cached_sctm=gc->transform; + shape->cached_sarea = *area; delete thePath; delete theShape; if ( shape->stroke_shp == NULL ) shape->stroke_shp=new Shape; shape->stroke_shp->Copy(shape->cached_stroke); + } else if ( 2 == isometry ) { + if ( shape->stroke_shp == NULL ) { + shape->stroke_shp=new Shape; + shape->stroke_shp->Copy(shape->cached_stroke); + } } else { - if ( shape->stroke_shp == NULL ) shape->stroke_shp=new Shape; shape->stroke_shp->Reset(shape->cached_stroke->numberOfPoints(), shape->cached_stroke->numberOfEdges()); @@ -581,6 +624,7 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc) shape->stroke_shp->needPointsSorting(); shape->stroke_shp->needEdgesSorting(); } + shape->delayed_shp |= shape->cached_spartialy; } } @@ -655,8 +699,9 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned if ( nr_rect_l_test_intersect(area, &item->bbox) ) { NRGC tempGC(NULL); tempGC.transform=shape->ctm; - nr_arena_shape_update_stroke(shape,&tempGC); - nr_arena_shape_update_fill(shape,&tempGC); + shape->delayed_shp = false; + nr_arena_shape_update_stroke(shape,&tempGC,&pb->visible_area); + nr_arena_shape_update_fill(shape,&tempGC,&pb->visible_area); /* NRRect bbox; bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0; nr_arena_shape_add_bboxes(shape,bbox); @@ -665,6 +710,8 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned item->bbox.x1 = (gint32)(bbox.x1 + 1.0F); item->bbox.y1 = (gint32)(bbox.y1 + 1.0F); shape->approx_bbox=item->bbox;*/ + } else { + return item->state; } } @@ -674,6 +721,7 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned guint32 rgba; nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + m.visible_area = pb->visible_area; nr_pixblock_render_shape_mask_or(m,shape->fill_shp); m.empty = FALSE; @@ -704,6 +752,7 @@ nr_arena_shape_render(NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned guint32 rgba; nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + m.visible_area = pb->visible_area; nr_pixblock_render_shape_mask_or(m, shape->stroke_shp); m.empty = FALSE; @@ -750,7 +799,10 @@ nr_arena_shape_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb) if ( nr_rect_l_test_intersect(area, &item->bbox) ) { NRGC tempGC(NULL); tempGC.transform=shape->ctm; - nr_arena_shape_update_fill(shape, &tempGC, true); + shape->delayed_shp = false; + nr_arena_shape_update_fill(shape, &tempGC, &pb->visible_area, true); + } else { + return item->state; } } @@ -759,6 +811,7 @@ nr_arena_shape_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb) /* fixme: We can OR in one step (Lauris) */ nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + m.visible_area = pb->visible_area; nr_pixblock_render_shape_mask_or(m,shape->fill_shp); for (int y = area->y0; y < area->y1; y++) { @@ -786,7 +839,7 @@ nr_arena_shape_pick(NRArenaItem *item, NR::Point p, double delta, unsigned int / if (!shape->curve) return NULL; if (!shape->style) return NULL; if ( shape->delayed_shp ) { - NRRectL area; + NRRectL area, updateArea; area.x0=(int)floor(p[NR::X]); area.x1=(int)ceil(p[NR::X]); area.y0=(int)floor(p[NR::Y]); @@ -800,8 +853,13 @@ nr_arena_shape_pick(NRArenaItem *item, NR::Point p, double delta, unsigned int / if ( nr_rect_l_test_intersect(&area, &item->bbox) ) { NRGC tempGC(NULL); tempGC.transform=shape->ctm; - nr_arena_shape_update_stroke(shape,&tempGC); - nr_arena_shape_update_fill(shape,&tempGC); + updateArea = item->bbox; + if (shape->cached_stroke) + nr_rect_l_intersect (&updateArea, &updateArea, &shape->cached_sarea); + + shape->delayed_shp = false; + nr_arena_shape_update_stroke(shape, &tempGC, &updateArea); + nr_arena_shape_update_fill(shape, &tempGC, &updateArea); /* NRRect bbox; bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0; nr_arena_shape_add_bboxes(shape,bbox); diff --git a/src/display/nr-arena-shape.h b/src/display/nr-arena-shape.h index 9f8eec99a..cd72013f6 100644 --- a/src/display/nr-arena-shape.h +++ b/src/display/nr-arena-shape.h @@ -138,6 +138,10 @@ struct NRArenaShape : public NRArenaItem { // skewing NR::Matrix cached_fctm; NR::Matrix cached_sctm; + NRRectL cached_farea; + NRRectL cached_sarea; + bool cached_fpartialy; + bool cached_spartialy; Shape *cached_fill; Shape *cached_stroke; diff --git a/src/display/nr-arena.cpp b/src/display/nr-arena.cpp index f54bfbb90..a6e33d2dc 100644 --- a/src/display/nr-arena.cpp +++ b/src/display/nr-arena.cpp @@ -109,6 +109,8 @@ nr_arena_render_paintserver_fill (NRPixBlock *pb, NRRectL *area, SPPainter *pain NRPixBlock cb, cb_opa; nr_pixblock_setup_fast (&cb, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE); nr_pixblock_setup_fast (&cb_opa, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE); + cb.visible_area = pb->visible_area; + cb_opa.visible_area = pb->visible_area; /* Need separate gradient buffer (lauris)*/ // do the filling diff --git a/src/display/nr-gradient-gpl.cpp b/src/display/nr-gradient-gpl.cpp index 54a33cfdb..536217649 100644 --- a/src/display/nr-gradient-gpl.cpp +++ b/src/display/nr-gradient-gpl.cpp @@ -271,6 +271,7 @@ nr_lgradient_render_generic (NRLGradientRenderer *lgr, NRPixBlock *pb) (unsigned char *) lgr->vector, 4 * NR_GRADIENT_VECTOR_LENGTH, 0, 0); + spb.visible_area = pb->visible_area; bpp = (pb->mode == NR_PIXBLOCK_MODE_A8) ? 1 : (pb->mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4; for (y = 0; y < height; y++) { diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index b1ed7d3d2..5e19539f3 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1565,6 +1565,10 @@ sp_canvas_paint_rect (SPCanvas *canvas, int xx0, int yy0, int xx1, int yy1) buf.rect.y0 = y0; buf.rect.x1 = x1; buf.rect.y1 = y1; + buf.visible_rect.x0 = draw_x1; + buf.visible_rect.y0 = draw_y1; + buf.visible_rect.x1 = draw_x2; + buf.visible_rect.y1 = draw_y2; GdkColor *color = &widget->style->bg[GTK_STATE_NORMAL]; buf.bg_color = (((color->red & 0xff00) << 8) | (color->green & 0xff00) diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index 86522870a..34ed87ac9 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -52,6 +52,7 @@ struct SPCanvasBuf{ guchar *buf; int buf_rowstride; NRRectL rect; + NRRectL visible_rect; /// Background color, given as 0xrrggbb guint32 bg_color; // If empty, ignore contents of buffer and use a solid area of bg_color diff --git a/src/display/sp-ctrlline.cpp b/src/display/sp-ctrlline.cpp index 6715f890f..463d32336 100644 --- a/src/display/sp-ctrlline.cpp +++ b/src/display/sp-ctrlline.cpp @@ -142,7 +142,12 @@ sp_ctrlline_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int f thePath->MoveTo(NR::Point(cl->s.x, cl->s.y) * affine); thePath->LineTo(NR::Point(cl->e.x, cl->e.y) * affine); - thePath->Convert(1.0); + NRRectL area; + area.x0=item->x1; + area.x1=item->x2; + area.y0=item->y1; + area.y1=item->y2; + thePath->Convert(&area, 1.0); if ( cl->shp == NULL ) cl->shp=new Shape; thePath->Stroke(cl->shp,false,0.5,join_straight,butt_straight,20.0,false); cl->shp->CalcBBox(); |
