1
#! /bin/sh /usr/share/dpatch/dpatch-run
2
## 102_sp_pattern_painter_free.dpatch by Bryce Harrington <bryce@ubuntu.com>
4
## All lines beginning with `## DP:' are a description of the patch.
5
## DP: Fix SIGSEGV in sp_pattern_painter_free that can be reproduced
9
## DP: o render a gear with default settings
10
## DP: o try to create a 3d box
12
## DP: https://bugs.edge.launchpad.net/ubuntu/+source/inkscape/+bug/198608
16
diff -Nurp patched/src/sp-pattern.cpp working/src/sp-pattern.cpp
17
--- patched/src/sp-pattern.cpp 2009-04-07 22:48:39.000000000 -0700
18
+++ working/src/sp-pattern.cpp 2009-04-07 22:51:16.000000000 -0700
19
@@ -57,6 +57,8 @@ struct SPPatPainter {
22
NRPixBlock cached_tile;
24
+ std::map<SPObject *, sigc::connection> *_release_connections;
27
static void sp_pattern_class_init (SPPatternClass *klass);
28
@@ -632,6 +634,19 @@ bool pattern_hasItemChildren (SPPattern
30
static void sp_pat_fill (SPPainter *painter, NRPixBlock *pb);
32
+// item in this pattern is about to be deleted, hide it on our arena and disconnect
34
+sp_pattern_painter_release (SPObject *obj, SPPatPainter *painter)
36
+ std::map<SPObject *, sigc::connection>::iterator iter = painter->_release_connections->find(obj);
37
+ if (iter != painter->_release_connections->end()) {
38
+ iter->second.disconnect();
39
+ painter->_release_connections->erase(obj);
42
+ sp_item_invoke_hide(SP_ITEM(obj), painter->dkey);
46
Creates a painter (i.e. the thing that does actual filling at the given zoom).
47
See (*) below for why the parent_transform may be necessary.
48
@@ -728,7 +743,8 @@ sp_pattern_painter_new (SPPaintServer *p
49
pp->root = NRArenaGroup::create(pp->arena);
52
- for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
53
+ pp->_release_connections = new std::map<SPObject *, sigc::connection>;
54
+ for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
55
if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children
56
for (SPObject *child = sp_object_first_child(SP_OBJECT(pat_i)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
57
if (SP_IS_ITEM (child)) {
58
@@ -736,6 +752,7 @@ sp_pattern_painter_new (SPPaintServer *p
59
cai = sp_item_invoke_show (SP_ITEM (child), pp->arena, pp->dkey, SP_ITEM_REFERENCE_FLAGS);
60
nr_arena_item_append_child (pp->root, cai);
61
nr_arena_item_unref (cai);
62
+ pp->_release_connections->insert(std::make_pair(child, child->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_pattern_painter_release), pp))));
65
break; // do not go further up the chain if children are found
66
@@ -797,22 +814,25 @@ sp_pattern_painter_new (SPPaintServer *p
67
return (SPPainter *) pp;
72
sp_pattern_painter_free (SPPaintServer */*ps*/, SPPainter *painter)
74
SPPatPainter *pp = (SPPatPainter *) painter;
75
- SPPattern *pat = pp->pat;
77
- for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
78
- if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children
79
- for (SPObject *child = sp_object_first_child(SP_OBJECT(pat_i)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
80
- if (SP_IS_ITEM (child)) {
81
- sp_item_invoke_hide (SP_ITEM (child), pp->dkey);
84
- break; // do not go further up the chain if children are found
88
+ ((NRObject *) pp->arena)->unreference();
92
+ // disconnect all connections
93
+ std::map<SPObject *, sigc::connection>::iterator iter;
94
+ for (iter = pp->_release_connections->begin() ; iter!=pp->_release_connections->end() ; iter++) {
95
+ iter->second.disconnect();
97
+ pp->_release_connections->clear();
98
+ delete pp->_release_connections;
100
if ( pp->use_cached_tile ) nr_pixblock_release(&pp->cached_tile);
103
@@ -996,6 +1016,6 @@ sp_pat_fill (SPPainter *painter, NRPixBl
104
nr_pixblock_release (&ppb);