Code

more unreffing temporary styles properly
[inkscape.git] / src / sp-item.cpp
index ab1f6e24205d9a26ad8df51b0718c2f8950b1247..fbcc7b4a895b006c0538c9b5e917425a3d6596d9 100644 (file)
@@ -674,9 +674,9 @@ NR::Maybe<NR::Rect> SPItem::getBounds(NR::Matrix const &transform,
 }
 
 void
-sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const clear)
+sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const clear, SPItem::BBoxType type)
 {
-    sp_item_invoke_bbox_full(item, bbox, transform, 0, clear);
+    sp_item_invoke_bbox_full(item, bbox, transform, type, clear);
 }
 
 /** Calls \a item's subclass' bounding box method; clips it by the bbox of clippath, if any; and
@@ -743,31 +743,36 @@ unsigned sp_item_pos_in_parent(SPItem *item)
 }
 
 void
-sp_item_bbox_desktop(SPItem *item, NRRect *bbox)
+sp_item_bbox_desktop(SPItem *item, NRRect *bbox, SPItem::BBoxType type)
 {
     g_assert(item != NULL);
     g_assert(SP_IS_ITEM(item));
     g_assert(bbox != NULL);
 
-    sp_item_invoke_bbox(item, bbox, sp_item_i2d_affine(item), TRUE);
+    sp_item_invoke_bbox(item, bbox, sp_item_i2d_affine(item), TRUE, type);
 }
 
-NR::Maybe<NR::Rect> sp_item_bbox_desktop(SPItem *item)
+NR::Maybe<NR::Rect> sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type)
 {
     NRRect ret;
-    sp_item_invoke_bbox(item, &ret, sp_item_i2d_affine(item), TRUE);
+    sp_item_invoke_bbox(item, &ret, sp_item_i2d_affine(item), TRUE, type);
     return ret.upgrade();
 }
 
 static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p)
 {
     NR::Maybe<NR::Rect> bbox = item->getBounds(sp_item_i2d_affine(item));
-    /* Just a pair of opposite corners of the bounding box suffices given that we don't yet
+    /* Just the corners of the bounding box suffices given that we don't yet
        support angled guide lines. */
 
     if (bbox) {
-        *p = bbox->min();
-        *p = bbox->max();
+        NR::Point p1, p2;
+        p1 = bbox->min();
+        p2 = bbox->max();
+        *p = p1;
+        *p = NR::Point(p1[NR::X], p2[NR::Y]);
+        *p = p2;
+        *p = NR::Point(p1[NR::Y], p2[NR::X]);
     }
 }
 
@@ -1060,6 +1065,10 @@ sp_item_adjust_stroke_width_recursive(SPItem *item, double expansion)
 {
     sp_item_adjust_stroke (item, expansion);
 
+// A clone's child is the ghost of its original - we must not touch it, skip recursion
+    if (item && SP_IS_USE(item))
+        return;
+
     for (SPObject *o = SP_OBJECT(item)->children; o != NULL; o = o->next) {
         if (SP_IS_ITEM(o))
             sp_item_adjust_stroke_width_recursive(SP_ITEM(o), expansion);
@@ -1088,18 +1097,16 @@ sp_item_adjust_rects_recursive(SPItem *item, NR::Matrix advertized_transform)
 void
 sp_item_adjust_paint_recursive (SPItem *item, NR::Matrix advertized_transform, NR::Matrix t_ancestors, bool is_pattern)
 {
-// A clone must not touch the style (it's that of its parent!) and has no children, so quit now
-    if (item && SP_IS_USE(item))
-        return;
-
 // _Before_ full pattern/gradient transform: t_paint * t_item * t_ancestors
 // _After_ full pattern/gradient transform: t_paint_new * t_item * t_ancestors * advertised_transform
 // By equating these two expressions we get t_paint_new = t_paint * paint_delta, where:
     NR::Matrix t_item = sp_item_transform_repr (item);
     NR::Matrix paint_delta = t_item * t_ancestors * advertized_transform * t_ancestors.inverse() * t_item.inverse();
 
-// Within text, we do not fork gradients, and so must not recurse to avoid double compensation
-    if (!(item && SP_IS_TEXT(item))) {
+// Within text, we do not fork gradients, and so must not recurse to avoid double compensation;
+// also we do not recurse into clones, because a clone's child is the ghost of its original - 
+// we must not touch it
+    if (!(item && (SP_IS_TEXT(item) || SP_IS_USE(item)))) {
         for (SPObject *o = SP_OBJECT(item)->children; o != NULL; o = o->next) {
             if (SP_IS_ITEM(o)) {
 // At the level of the transformed item, t_ancestors is identity;