X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsp-shape.cpp;h=6dba2afb67b2f36a63b0d6f3ecd0ead17c03c4e6;hb=724821145d62dee9f97465c706952582da6e432d;hp=53f161470a196c9d83ef2ecc24f4d7180b5deb77;hpb=4b852b3bade276506da19dddcad943e7e5b3ad46;p=inkscape.git diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 53f161470..6dba2afb6 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -32,7 +32,7 @@ #include "print.h" #include "document.h" #include "style.h" -#include "sp-marker.h" +#include "marker.h" #include "sp-path.h" #include "prefs-utils.h" @@ -88,19 +88,19 @@ sp_shape_get_type (void) static void sp_shape_class_init (SPShapeClass *klass) { - GObjectClass *gobject_class; + GObjectClass *gobject_class; SPObjectClass *sp_object_class; SPItemClass * item_class; SPPathClass * path_class; - gobject_class = (GObjectClass *) klass; + gobject_class = (GObjectClass *) klass; sp_object_class = (SPObjectClass *) klass; item_class = (SPItemClass *) klass; path_class = (SPPathClass *) klass; parent_class = (SPItemClass *)g_type_class_peek_parent (klass); - gobject_class->finalize = sp_shape_finalize; + gobject_class->finalize = sp_shape_finalize; sp_object_class->build = sp_shape_build; sp_object_class->release = sp_shape_release; @@ -111,7 +111,7 @@ sp_shape_class_init (SPShapeClass *klass) item_class->print = sp_shape_print; item_class->show = sp_shape_show; item_class->hide = sp_shape_hide; - item_class->snappoints = sp_shape_snappoints; + item_class->snappoints = sp_shape_snappoints; } /** @@ -238,13 +238,15 @@ sp_shape_update (SPObject *object, SPCtx *ctx, unsigned int flags) if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) { /* This is suboptimal, because changing parent style schedules recalculation */ /* But on the other hand - how can we know that parent does not tie style and transform */ - NR::Rect const paintbox = SP_ITEM(object)->invokeBbox(NR::identity()); + NR::Maybe paintbox = SP_ITEM(object)->getBounds(NR::identity()); for (SPItemView *v = SP_ITEM (shape)->display; v != NULL; v = v->next) { NRArenaShape * const s = NR_ARENA_SHAPE(v->arenaitem); if (flags & SP_OBJECT_MODIFIED_FLAG) { nr_arena_shape_set_path(s, shape->curve, (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)); } - s->setPaintBox(paintbox); + if (paintbox) { + s->setPaintBox(*paintbox); + } } } @@ -616,43 +618,46 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &tr nr_path_matrix_bbox_union(&bp, transform, &cbbox); - SPStyle* style=SP_OBJECT_STYLE (item); - if (style->stroke.type != SP_PAINT_TYPE_NONE) { - double const scale = expansion(transform); - if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord - double const width = MAX(0.125, style->stroke_width.computed * scale); - if ( fabs(cbbox.x1-cbbox.x0) > -0.00001 && fabs(cbbox.y1-cbbox.y0) > -0.00001 ) { - cbbox.x0-=0.5*width; - cbbox.x1+=0.5*width; - cbbox.y0-=0.5*width; - cbbox.y1+=0.5*width; + if ((SPItem::BBoxType) flags != SPItem::GEOMETRIC_BBOX) { + + SPStyle* style=SP_OBJECT_STYLE (item); + if (style->stroke.type != SP_PAINT_TYPE_NONE) { + double const scale = expansion(transform); + if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord + double const width = MAX(0.125, style->stroke_width.computed * scale); + if ( fabs(cbbox.x1-cbbox.x0) > -0.00001 && fabs(cbbox.y1-cbbox.y0) > -0.00001 ) { + cbbox.x0-=0.5*width; + cbbox.x1+=0.5*width; + cbbox.y0-=0.5*width; + cbbox.y1+=0.5*width; + } } } - } - // Union with bboxes of the markers, if any - if (sp_shape_has_markers (shape)) { - for (NArtBpath* bp = SP_CURVE_BPATH(shape->curve); bp->code != NR_END; bp++) { - for (int m = SP_MARKER_LOC_START; m < SP_MARKER_LOC_QTY; m++) { - if (sp_shape_marker_required (shape, m, bp)) { + // Union with bboxes of the markers, if any + if (sp_shape_has_markers (shape)) { + for (NArtBpath* bp = SP_CURVE_BPATH(shape->curve); bp->code != NR_END; bp++) { + for (int m = SP_MARKER_LOC_START; m < SP_MARKER_LOC_QTY; m++) { + if (sp_shape_marker_required (shape, m, bp)) { - SPMarker* marker = SP_MARKER (shape->marker[m]); - SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[m])); + SPMarker* marker = SP_MARKER (shape->marker[m]); + SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[m])); - NR::Matrix tr(sp_shape_marker_get_transform(shape, bp)); + NR::Matrix tr(sp_shape_marker_get_transform(shape, bp)); - if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { - tr = NR::scale(style->stroke_width.computed) * tr; - } + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + tr = NR::scale(style->stroke_width.computed) * tr; + } - // total marker transform - tr = marker_item->transform * marker->c2p * tr * transform; + // total marker transform + tr = marker_item->transform * marker->c2p * tr * transform; - // get bbox of the marker with that transform - NRRect marker_bbox; - sp_item_invoke_bbox (marker_item, &marker_bbox, tr, true); - // union it with the shape bbox - nr_rect_d_union (&cbbox, &cbbox, &marker_bbox); + // get bbox of the marker with that transform + NRRect marker_bbox; + sp_item_invoke_bbox (marker_item, &marker_bbox, tr, true); + // union it with the shape bbox + nr_rect_d_union (&cbbox, &cbbox, &marker_bbox); + } } } } @@ -753,8 +758,10 @@ sp_shape_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flag NRArenaShape * const s = NR_ARENA_SHAPE(arenaitem); nr_arena_shape_set_style(s, object->style); nr_arena_shape_set_path(s, shape->curve, false); - NR::Rect const paintbox = item->invokeBbox(NR::identity()); - s->setPaintBox(paintbox); + NR::Maybe paintbox = item->getBounds(NR::identity()); + if (paintbox) { + s->setPaintBox(*paintbox); + } if (sp_shape_has_markers (shape)) { @@ -1014,6 +1021,11 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p) /* Use the end points of each segment of the path */ NArtBpath const *bp = SP_CURVE_BPATH(shape->curve); + + if (bp->code == NR_MOVETO) { // Indicates the start of a closed subpath, see nr-path-code.h + bp++; //The first point of a closed path is coincident with the end point. Skip the first point as we need only one + } + while (bp->code != NR_END) { *p = bp->c(3) * i2d; bp++;