summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gradient-chemistry.cpp12
-rw-r--r--src/gradient-drag.cpp16
-rw-r--r--src/gradient-drag.h2
-rw-r--r--src/sp-gradient.cpp86
-rw-r--r--src/sp-item.cpp5
-rw-r--r--src/sp-mesh-array.cpp115
-rw-r--r--src/sp-mesh-array.h11
-rw-r--r--src/sp-mesh-patch.cpp31
-rw-r--r--src/sp-mesh-patch.h11
-rw-r--r--src/sp-mesh-row.cpp31
-rw-r--r--src/sp-mesh-row.h11
-rw-r--r--src/sp-mesh.cpp39
-rw-r--r--src/sp-rect.cpp36
-rw-r--r--src/sp-stop.cpp1
14 files changed, 310 insertions, 97 deletions
diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp
index 4521d72fd..28fdda483 100644
--- a/src/gradient-chemistry.cpp
+++ b/src/gradient-chemistry.cpp
@@ -271,7 +271,7 @@ static SPGradient *sp_gradient_fork_private_if_necessary(SPGradient *gr, SPGradi
repr_new->setAttribute("x2", repr->attribute("x2"));
repr_new->setAttribute("y2", repr->attribute("y2"));
} else {
- std::cout << "sp_gradient_fork_private_if_necessary: mesh not implemented" << std::endl;
+ std::cerr << "sp_gradient_fork_private_if_necessary: mesh not implemented" << std::endl;
}
return gr_new;
@@ -861,6 +861,7 @@ void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint
switch (point_type) {
case POINT_MG_CORNER: {
+ // Update mesh array (which is not updated automatically when stop is changed?)
gchar const* color_str = sp_repr_css_property( stop, "stop-color", NULL );
if( color_str ) {
SPColor color( 0 );
@@ -880,9 +881,14 @@ void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint
mg->array.corners[ point_i ]->opacity = opacity;
changed = true;
}
+ // Update stop
if( changed ) {
- gradient->requestModified(SP_OBJECT_MODIFIED_FLAG);
- mg->array.write( mg );
+ SPStop *stopi = mg->array.corners[ point_i ]->stop;
+ if (stopi) {
+ sp_repr_css_change(stopi->getRepr(), stop, "style");
+ } else {
+ std::cerr << "sp_item_gradient_stop_set_style: null stopi" << std::endl;
+ }
}
break;
}
diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp
index 5b91bdc9f..7bc302e61 100644
--- a/src/gradient-drag.cpp
+++ b/src/gradient-drag.cpp
@@ -901,7 +901,7 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui
dragger->point = p;
dragger->fireDraggables (false, scale_radial);
dragger->updateDependencies(false);
- dragger->updateHandles( p_old, MG_NODE_NO_SCALE );
+ dragger->moveMeshHandles( p_old, MG_NODE_NO_SCALE );
}
}
@@ -1076,7 +1076,7 @@ static void gr_knot_ungrabbed_handler(SPKnot *knot, unsigned int state, gpointer
} else {
dragger->fireDraggables (true);
}
- dragger->updateHandles( dragger->point_original, MG_NODE_NO_SCALE );
+ dragger->moveMeshHandles( dragger->point_original, MG_NODE_NO_SCALE );
for (std::set<GrDragger *>::const_iterator it = dragger->parent->selected.begin(); it != dragger->parent->selected.end() ; ++it ) {
if (*it == dragger)
@@ -1306,9 +1306,8 @@ bool GrDragger::mayMerge(GrDraggable *da2)
* Ooops, needs to be reimplemented.
*/
void
-GrDragger::updateHandles ( Geom::Point pc_old, MeshNodeOperation op )
+GrDragger::moveMeshHandles ( Geom::Point pc_old, MeshNodeOperation op )
{
-
// This routine might more properly be in mesh-context.cpp but moving knots is
// handled here rather than there.
@@ -1946,6 +1945,7 @@ void GrDrag::addDraggersLinear(SPLinearGradient *lg, SPItem *item, Inkscape::Pai
*/
void GrDrag::addDraggersMesh(SPMesh *mg, SPItem *item, Inkscape::PaintTarget fill_or_stroke)
{
+ mg->ensureArray();
std::vector< std::vector< SPMeshNode* > > nodes = mg->array.nodes;
// Show/hide mesh on fill/stroke. This doesn't work at the moment... and prevents node color updating.
@@ -1963,7 +1963,7 @@ void GrDrag::addDraggersMesh(SPMesh *mg, SPItem *item, Inkscape::PaintTarget fil
// Make sure we have at least one patch defined.
if( mg->array.patch_rows() == 0 || mg->array.patch_columns() == 0 ) {
- std::cout << "Empty Mesh, No Draggers to Add" << std::endl;
+ std::cerr << "Empty Mesh, No Draggers to Add" << std::endl;
return;
}
@@ -2018,14 +2018,14 @@ void GrDrag::addDraggersMesh(SPMesh *mg, SPItem *item, Inkscape::PaintTarget fil
}
default:
- std::cout << "Bad Mesh draggable type" << std::endl;
+ std::cerr << "Bad Mesh draggable type" << std::endl;
break;
}
}
}
}
- mg->array.drag_valid = true;
+ mg->array.draggers_valid = true;
}
/**
@@ -2348,7 +2348,7 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia
d->knot->moveto(d->point);
d->fireDraggables (write_repr, scale_radial);
- d->updateHandles( p_old, MG_NODE_NO_SCALE );
+ d->moveMeshHandles( p_old, MG_NODE_NO_SCALE );
d->updateDependencies(write_repr);
}
}
diff --git a/src/gradient-drag.h b/src/gradient-drag.h
index b07f748a7..9737af0bf 100644
--- a/src/gradient-drag.h
+++ b/src/gradient-drag.h
@@ -105,7 +105,7 @@ struct GrDragger {
void updateDependencies(bool write_repr);
/* Update handles/tensors when mesh corner moved */
- void updateHandles( Geom::Point pc_old, MeshNodeOperation op );
+ void moveMeshHandles( Geom::Point pc_old, MeshNodeOperation op );
bool mayMerge(GrDragger *other);
bool mayMerge(GrDraggable *da2);
diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp
index f24e25ab1..5c0fdfe2b 100644
--- a/src/sp-gradient.cpp
+++ b/src/sp-gradient.cpp
@@ -22,6 +22,7 @@
*/
#define noSP_GRADIENT_VERBOSE
+//#define OBJECT_TRACE
#include <cstring>
#include <string>
@@ -228,7 +229,7 @@ SPGradient::SPGradient() : SPPaintServer(), units(),
state(2),
vector() {
- this->has_patches = 0;
+ this->has_patches = 0;
this->ref = new SPGradientReference(this);
this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(SPGradient::gradientRefChanged), this));
@@ -318,6 +319,12 @@ void SPGradient::release()
*/
void SPGradient::set(unsigned key, gchar const *value)
{
+#ifdef OBJECT_TRACE
+ std::stringstream temp;
+ temp << "SPGradient::set: " << key << " " << (value?value:"null");
+ objectTrace( temp.str() );
+#endif
+
switch (key) {
case SP_ATTR_GRADIENTUNITS:
if (value) {
@@ -409,6 +416,10 @@ void SPGradient::set(unsigned key, gchar const *value)
SPPaintServer::set(key, value);
break;
}
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPGradient::set", false );
+#endif
}
/**
@@ -498,29 +509,24 @@ void SPGradient::remove_child(Inkscape::XML::Node *child)
*/
void SPGradient::modified(guint flags)
{
+#ifdef OBJECT_TRACE
+ objectTrace( "SPGradient::modified" );
+#endif
+
if (flags & SP_OBJECT_CHILD_MODIFIED_FLAG) {
- // CPPIFY
- // This comparison has never worked (i. e. always evaluated to false),
- // the right value would have been SP_TYPE_MESH
- //if( this->get_type() != SP_GRADIENT_TYPE_MESH ) {
-// if (!SP_IS_MESH(this)) {
-// this->invalidateVector();
-// } else {
-// this->invalidateArray();
-// }
- this->invalidateVector();
+ if (SP_IS_MESH(this)) {
+ this->invalidateArray();
+ } else {
+ this->invalidateVector();
+ }
}
if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
- // CPPIFY
- // see above
- //if( this->get_type() != SP_GRADIENT_TYPE_MESH ) {
-// if (!SP_IS_MESH(this)) {
-// this->ensureVector();
-// } else {
-// this->ensureArray();
-// }
- this->ensureVector();
+ if (SP_IS_MESH(this)) {
+ this->ensureArray();
+ } else {
+ this->ensureVector();
+ }
}
if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
@@ -546,6 +552,10 @@ void SPGradient::modified(guint flags)
sp_object_unref(child);
}
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPGradient::modified", false );
+#endif
}
SPStop* SPGradient::getFirstStop()
@@ -576,6 +586,10 @@ int SPGradient::getStopCount() const
*/
Inkscape::XML::Node *SPGradient::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
+#ifdef OBJECT_TRACE
+ objectTrace( "SPGradient::write" );
+#endif
+
SPPaintServer::write(xml_doc, repr, flags);
if (flags & SP_OBJECT_WRITE_BUILD) {
@@ -646,6 +660,9 @@ Inkscape::XML::Node *SPGradient::write(Inkscape::XML::Document *xml_doc, Inkscap
repr->setAttribute( "osb:paint", 0 );
}
+#ifdef OBJECT_TRACE
+ objectTrace( "SPGradient::write", false );
+#endif
return repr;
}
@@ -898,7 +915,7 @@ bool SPGradient::invalidateArray()
if (array.built) {
array.built = false;
- array.clear();
+ // array.clear();
ret = true;
}
@@ -1014,33 +1031,6 @@ void SPGradient::rebuildArray()
}
array.read( SP_MESH( this ) );
-
- has_patches = false;
- for (auto& ro: children) {
- if (SP_IS_MESHROW(&ro)) {
- has_patches = true;
- // std::cout << " Has Patches" << std::endl;
- break;
- }
- }
-
- // MESH_FIXME: TO PROPERLY COPY
- SPGradient *reffed = ref->getObject();
- if ( !hasPatches() && reffed ) {
- std::cout << "SPGradient::rebuildArray(): reffed array NOT IMPLEMENTED!!!" << std::endl;
- /* Copy array from referenced gradient */
- array.built = true; // Prevent infinite recursion.
- reffed->ensureArray();
- // if (!reffed->array.nodes.empty()) {
- // array.built = reffed->array.built;
- // for( uint i = 0; i < reffed->array.nodes.size(); ++i ) {
- // array.nodes[i].assign(reffed->array.nodes[i].begin(), reffed->array.nodes[i].end());
-
- // // FILL ME
- // }
- // return;
- // }
- }
}
Geom::Affine
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index e03b715c0..d161562fd 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -59,6 +59,7 @@
#define noSP_ITEM_DEBUG_IDLE
+//#define OBJECT_TRACE
static SPItemView* sp_item_view_list_remove(SPItemView *list,
SPItemView *view);
@@ -691,6 +692,10 @@ void SPItem::update(SPCtx* ctx, guint flags) {
void SPItem::modified(unsigned int /*flags*/)
{
+#ifdef OBJECT_TRACE
+ objectTrace( "SPItem::modified" );
+ objectTrace( "SPItem::modified", false );
+#endif
}
Inkscape::XML::Node* SPItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp
index 0dd89ac96..41a95a41a 100644
--- a/src/sp-mesh-array.cpp
+++ b/src/sp-mesh-array.cpp
@@ -574,6 +574,59 @@ void SPMeshPatchI::setOpacity( guint i, gdouble opacity ) {
};
+/**
+ Return stop pointer for corner of patch.
+*/
+SPStop* SPMeshPatchI::getStopPtr( guint i ) {
+
+ assert( i < 4 );
+
+ SPStop* stop = nullptr;
+ switch ( i ) {
+ case 0:
+ stop = (*nodes)[ row ][ col ]->stop;
+ break;
+ case 1:
+ stop = (*nodes)[ row ][ col+3 ]->stop;
+ break;
+ case 2:
+ stop = (*nodes)[ row+3 ][ col+3 ]->stop;
+ break;
+ case 3:
+ stop = (*nodes)[ row+3 ][ col ]->stop;
+ break;
+ }
+
+ return stop;
+};
+
+
+/**
+ Set stop pointer for corner of patch.
+*/
+void SPMeshPatchI::setStopPtr( guint i, SPStop* stop ) {
+
+ assert( i < 4 );
+
+ switch ( i ) {
+ case 0:
+ (*nodes)[ row ][ col ]->stop = stop;
+ break;
+ case 1:
+ (*nodes)[ row ][ col+3 ]->stop = stop;
+ break;
+ case 2:
+ (*nodes)[ row+3 ][ col+3 ]->stop = stop;
+ break;
+ case 3:
+ (*nodes)[ row+3 ][ col ]->stop = stop;
+ break;
+
+ }
+
+};
+
+
SPMeshNodeArray::SPMeshNodeArray( SPMesh *mg ) {
read( mg );
@@ -586,7 +639,7 @@ SPMeshNodeArray::SPMeshNodeArray( const SPMeshNodeArray& rhs ) {
built = false;
mg = NULL;
- drag_valid = false;
+ draggers_valid = false;
nodes = rhs.nodes; // This only copies the pointers but it does size the vector of vectors.
@@ -607,7 +660,7 @@ SPMeshNodeArray& SPMeshNodeArray::operator=( const SPMeshNodeArray& rhs ) {
built = false;
mg = NULL;
- drag_valid = false;
+ draggers_valid = false;
nodes = rhs.nodes; // This only copies the pointers but it does size the vector of vectors.
@@ -620,12 +673,34 @@ SPMeshNodeArray& SPMeshNodeArray::operator=( const SPMeshNodeArray& rhs ) {
return *this;
};
-
-void SPMeshNodeArray::read( SPMesh *mg_in ) {
+// Fill array with data from mesh objects.
+// Returns true of array's dimensions unchanged.
+bool SPMeshNodeArray::read( SPMesh *mg_in ) {
mg = mg_in;
- clear();
+ // Count rows and columns, if unchanged reuse array to keep draggers valid.
+ unsigned cols = 0;
+ unsigned rows = 0;
+ for (auto& ro: mg->children) {
+ if (SP_IS_MESHROW(&ro)) {
+ ++rows;
+ if (rows == 1 ) {
+ for (auto& po: ro.children) {
+ if (SP_IS_MESHPATCH(&po)) {
+ ++cols;
+ }
+ }
+ }
+ }
+ }
+ bool same_size = true;
+ if (cols != patch_columns() || rows != patch_rows() ) {
+ // Draggers will be invalidated.
+ same_size = false;
+ clear();
+ draggers_valid = false;
+ }
Geom::Point current_p( mg->x.computed, mg->y.computed );
// std::cout << "SPMeshNodeArray::read: p: " << current_p << std::endl;
@@ -701,7 +776,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) {
dp = Geom::Point( x, y );
new_patch.setPoint( istop, 3, current_p + dp );
} else {
- std::cout << "Failed to read l" << std::endl;
+ std::cerr << "Failed to read l" << std::endl;
}
}
// To facilitate some side operations, set handles to 1/3 and
@@ -723,7 +798,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) {
p = Geom::Point( x, y );
new_patch.setPoint( istop, 3, p );
} else {
- std::cout << "Failed to read L" << std::endl;
+ std::cerr << "Failed to read L" << std::endl;
}
}
// To facilitate some side operations, set handles to 1/3 and
@@ -743,7 +818,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) {
p += current_p;
new_patch.setPoint( istop, i, p );
} else {
- std::cout << "Failed to read c: " << i << std::endl;
+ std::cerr << "Failed to read c: " << i << std::endl;
}
}
break;
@@ -756,13 +831,13 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) {
p = Geom::Point( x, y );
new_patch.setPoint( istop, i, p );
} else {
- std::cout << "Failed to read C: " << i << std::endl;
+ std::cerr << "Failed to read C: " << i << std::endl;
}
}
break;
default:
// should not reach
- std::cout << "Path Error: unhandled path type: " << path_type << std::endl;
+ std::cerr << "Path Error: unhandled path type: " << path_type << std::endl;
}
current_p = new_patch.getPoint( istop, 3 );
@@ -774,6 +849,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) {
double opacity = stop->opacity;
new_patch.setColor( istop, color );
new_patch.setOpacity( istop, opacity );
+ new_patch.setStopPtr( istop, stop );
}
}
@@ -797,7 +873,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) {
if( !os.fail() ) {
new_patch.setTensorPoint( i, new_patch.getPoint( i, 0 ) + Geom::Point( x, y ) );
} else {
- std::cout << "Failed to read p: " << i << std::endl;
+ std::cerr << "Failed to read p: " << i << std::endl;
break;
}
}
@@ -830,9 +906,9 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) {
// std::cout << "SPMeshNodeArray::Read: result:" << std::endl;
// print();
- drag_valid = false;
built = true;
+ return same_size;
};
/**
@@ -967,10 +1043,10 @@ void SPMeshNodeArray::write( SPMesh *mg ) {
break;
case 'z':
case 'Z':
- std::cout << "sp_mesh_repr_write: bad path type" << path_type << std::endl;
+ std::cout << "SPMeshNodeArray::write(): bad path type" << path_type << std::endl;
break;
default:
- std::cout << "sp_mesh_repr_write: unhandled path type" << path_type << std::endl;
+ std::cout << "SPMeshNodeArray::write(): unhandled path type" << path_type << std::endl;
}
stop->setAttribute("path", is.str().c_str());
// std::cout << "SPMeshNodeArray::write: path: " << is.str().c_str() << std::endl;
@@ -1415,6 +1491,7 @@ void SPMeshNodeArray::print() {
<< " Node edge: " << nodes[i][j]->node_edge
<< " Set: " << nodes[i][j]->set
<< " Path type: " << nodes[i][j]->path_type
+ << " Stop: " << nodes[i][j]->stop
<< std::endl;
} else {
std::cout << "Error: missing mesh node." << std::endl;
@@ -1776,7 +1853,9 @@ guint SPMeshNodeArray::patch_rows() {
Number of patch columns.
*/
guint SPMeshNodeArray::patch_columns() {
-
+ if (nodes.empty()) {
+ return 0;
+ }
return nodes[0].size()/3;
}
@@ -2345,7 +2424,11 @@ guint SPMeshNodeArray::color_pick( std::vector<guint> icorners, SPItem* item ) {
*/
void SPMeshNodeArray::update_handles( guint corner, std::vector< guint > /*selected*/, Geom::Point p_old, MeshNodeOperation /*op*/ )
{
- assert( drag_valid );
+ if (!draggers_valid) {
+ std::cerr << "SPMeshNodeArray::update_handles: Draggers not valid!" << std::endl;
+ return;
+ }
+ // assert( draggers_valid );
// std::cout << "SPMeshNodeArray::update_handles: "
// << " corner: " << corner
diff --git a/src/sp-mesh-array.h b/src/sp-mesh-array.h
index b078b221e..eb01304a2 100644
--- a/src/sp-mesh-array.h
+++ b/src/sp-mesh-array.h
@@ -85,6 +85,7 @@ enum MeshNodeOperation {
MG_NODE_SCALE_HANDLE
};
+class SPStop;
class SPMeshNode {
public:
@@ -95,6 +96,7 @@ public:
draggable = -1;
path_type = 'u';
opacity = 0.0;
+ stop = nullptr;
}
NodeType node_type;
unsigned int node_edge;
@@ -104,6 +106,7 @@ public:
char path_type;
SPColor color;
double opacity;
+ SPStop *stop; // Stop corresponding to node.
};
@@ -133,6 +136,8 @@ public:
void setColor( unsigned int i, SPColor c );
double getOpacity( unsigned int i );
void setOpacity( unsigned int i, double o );
+ SPStop* getStopPtr( unsigned int i );
+ void setStopPtr( unsigned int i, SPStop* );
};
class SPMesh;
@@ -147,7 +152,7 @@ public:
public:
// Draggables to nodes
- bool drag_valid;
+ bool draggers_valid;
std::vector< SPMeshNode* > corners;
std::vector< SPMeshNode* > handles;
std::vector< SPMeshNode* > tensors;
@@ -156,7 +161,7 @@ public:
friend class SPMeshPatchI;
- SPMeshNodeArray() { built = false; mg = NULL; drag_valid = false; };
+ SPMeshNodeArray() { built = false; mg = NULL; draggers_valid = false; };
SPMeshNodeArray( SPMesh *mg );
SPMeshNodeArray( const SPMeshNodeArray& rhs );
SPMeshNodeArray& operator=(const SPMeshNodeArray& rhs);
@@ -164,7 +169,7 @@ public:
~SPMeshNodeArray() { clear(); };
bool built;
- void read( SPMesh *mg );
+ bool read( SPMesh *mg );
void write( SPMesh *mg );
void create( SPMesh *mg, SPItem *item, Geom::OptRect bbox );
void clear();
diff --git a/src/sp-mesh-patch.cpp b/src/sp-mesh-patch.cpp
index 9727ffef6..9a173a8db 100644
--- a/src/sp-mesh-patch.cpp
+++ b/src/sp-mesh-patch.cpp
@@ -57,7 +57,6 @@ SPMeshpatch* SPMeshpatch::getPrevMeshpatch()
/*
* Mesh Patch
*/
-
SPMeshpatch::SPMeshpatch() : SPObject() {
this->tensor_string = NULL;
}
@@ -74,7 +73,6 @@ void SPMeshpatch::build(SPDocument* doc, Inkscape::XML::Node* repr) {
/**
* Virtual build: set meshpatch attributes from its associated XML node.
*/
-
void SPMeshpatch::set(unsigned int key, const gchar* value) {
switch (key) {
case SP_ATTR_TENSOR: {
@@ -91,9 +89,36 @@ void SPMeshpatch::set(unsigned int key, const gchar* value) {
}
/**
- * Virtual set: set attribute to value.
+ * modified
*/
+void SPMeshpatch::modified(unsigned int flags) {
+ flags &= SP_OBJECT_MODIFIED_CASCADE;
+ GSList *l = NULL;
+
+ for (auto& child: children) {
+ sp_object_ref(&child);
+ l = g_slist_prepend(l, &child);
+ }
+
+ l = g_slist_reverse(l);
+
+ while (l) {
+ SPObject *child = SP_OBJECT(l->data);
+ l = g_slist_remove(l, child);
+
+ if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
+ child->emitModified(flags);
+ }
+
+ sp_object_unref(child);
+ }
+}
+
+
+/**
+ * Virtual set: set attribute to value.
+ */
Inkscape::XML::Node* SPMeshpatch::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) {
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
repr = xml_doc->createElement("svg:meshpatch");
diff --git a/src/sp-mesh-patch.h b/src/sp-mesh-patch.h
index 88d6325c3..e018b81ea 100644
--- a/src/sp-mesh-patch.h
+++ b/src/sp-mesh-patch.h
@@ -21,8 +21,8 @@
/** Gradient Meshpatch. */
class SPMeshpatch : public SPObject {
public:
- SPMeshpatch();
- virtual ~SPMeshpatch();
+ SPMeshpatch();
+ virtual ~SPMeshpatch();
SPMeshpatch* getNextMeshpatch();
SPMeshpatch* getPrevMeshpatch();
@@ -31,9 +31,10 @@ public:
//SVGLength ty[4]; // Tensor points
protected:
- virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
- virtual void set(unsigned int key, const char* value);
- virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags);
+ virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
+ virtual void set(unsigned int key, const char* value);
+ virtual void modified(unsigned int flags);
+ virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags);
};
#endif /* !SEEN_SP_MESHPATCH_H */
diff --git a/src/sp-mesh-row.cpp b/src/sp-mesh-row.cpp
index 90173da8c..5ac349c27 100644
--- a/src/sp-mesh-row.cpp
+++ b/src/sp-mesh-row.cpp
@@ -65,17 +65,44 @@ void SPMeshrow::build(SPDocument* doc, Inkscape::XML::Node* repr) {
SPObject::build(doc, repr);
}
+
/**
* Virtual build: set meshrow attributes from its associated XML node.
*/
-
void SPMeshrow::set(unsigned int /*key*/, const gchar* /*value*/) {
}
/**
- * Virtual set: set attribute to value.
+ * modified
*/
+void SPMeshrow::modified(unsigned int flags) {
+ flags &= SP_OBJECT_MODIFIED_CASCADE;
+ GSList *l = NULL;
+
+ for (auto& child: children) {
+ sp_object_ref(&child);
+ l = g_slist_prepend(l, &child);
+ }
+
+ l = g_slist_reverse(l);
+
+ while (l) {
+ SPObject *child = SP_OBJECT(l->data);
+ l = g_slist_remove(l, child);
+
+ if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
+ child->emitModified(flags);
+ }
+
+ sp_object_unref(child);
+ }
+}
+
+
+/**
+ * Virtual set: set attribute to value.
+ */
Inkscape::XML::Node* SPMeshrow::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) {
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
repr = xml_doc->createElement("svg:meshrow");
diff --git a/src/sp-mesh-row.h b/src/sp-mesh-row.h
index ffb3efa6b..40335e2b9 100644
--- a/src/sp-mesh-row.h
+++ b/src/sp-mesh-row.h
@@ -19,16 +19,17 @@
/** Gradient Meshrow. */
class SPMeshrow : public SPObject {
public:
- SPMeshrow();
- virtual ~SPMeshrow();
+ SPMeshrow();
+ virtual ~SPMeshrow();
SPMeshrow* getNextMeshrow();
SPMeshrow* getPrevMeshrow();
protected:
- virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
- virtual void set(unsigned int key, const char* value);
- virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags);
+ virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
+ virtual void set(unsigned int key, const char* value);
+ virtual void modified(unsigned int flags);
+ virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags);
};
#endif /* !SEEN_SP_MESHROW_H */
diff --git a/src/sp-mesh.cpp b/src/sp-mesh.cpp
index 5a6f2bd8e..1cdb2f1cc 100644
--- a/src/sp-mesh.cpp
+++ b/src/sp-mesh.cpp
@@ -9,16 +9,34 @@
* Mesh Gradient
*/
//#define MESH_DEBUG
+//#define OBJECT_TRACE
+
SPMesh::SPMesh() : SPGradient(), type( SP_MESH_TYPE_COONS ), type_set(false) {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMesh::SPMesh" );
+#endif
+
// Start coordinate of mesh
this->x.unset(SVGLength::NONE, 0.0, 0.0);
this->y.unset(SVGLength::NONE, 0.0, 0.0);
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMesh::SPMesh", false );
+#endif
}
SPMesh::~SPMesh() {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMesh::~SPMesh (empty function)" );
+ objectTrace( "SPMesh::~SPMesh", false );
+#endif
}
void SPMesh::build(SPDocument *document, Inkscape::XML::Node *repr) {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMesh::build" );
+#endif
+
SPGradient::build(document, repr);
// Start coordinate of mesh
@@ -26,10 +44,18 @@ void SPMesh::build(SPDocument *document, Inkscape::XML::Node *repr) {
this->readAttr( "y" );
this->readAttr( "type" );
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMesh::build", false );
+#endif
}
void SPMesh::set(unsigned key, gchar const *value) {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMesh::set" );
+#endif
+
switch (key) {
case SP_ATTR_X:
if (!this->x.read(value)) {
@@ -70,14 +96,18 @@ void SPMesh::set(unsigned key, gchar const *value) {
SPGradient::set(key, value);
break;
}
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMesh::set", false );
+#endif
}
/**
* Write mesh gradient attributes to associated repr.
*/
Inkscape::XML::Node* SPMesh::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
-#ifdef MESH_DEBUG
- std::cout << "sp_mesh_write() ***************************" << std::endl;
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMesh::write", false );
#endif
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
@@ -108,6 +138,9 @@ Inkscape::XML::Node* SPMesh::write(Inkscape::XML::Document *xml_doc, Inkscape::X
SPGradient::write(xml_doc, repr, flags);
+#ifdef OBJECT_TRACE
+ objectTrace( "SPMesh::write", false );
+#endif
return repr;
}
@@ -132,7 +165,7 @@ cairo_pattern_t* SPMesh::pattern_new(cairo_t * /*ct*/,
using Geom::Y;
#ifdef MESH_DEBUG
- std::cout << "sp_mesh_create_pattern: (" << bbox->x0 << "," << bbox->y0 << ") (" << bbox->x1 << "," << bbox->y1 << ") " << opacity << std::endl;
+ std::cout << "sp_mesh_create_pattern: " << (*bbox) << " " << opacity << std::endl;
#endif
this->ensureArray();
diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp
index 40107096f..88dad5354 100644
--- a/src/sp-rect.cpp
+++ b/src/sp-rect.cpp
@@ -28,6 +28,7 @@
#define noRECT_VERBOSE
+//#define OBJECT_TRACE
SPRect::SPRect() : SPShape() {
}
@@ -36,6 +37,10 @@ SPRect::~SPRect() {
}
void SPRect::build(SPDocument* doc, Inkscape::XML::Node* repr) {
+#ifdef OBJECT_TRACE
+ objectTrace( "SPRect::build" );
+#endif
+
SPShape::build(doc, repr);
this->readAttr("x");
@@ -44,9 +49,20 @@ void SPRect::build(SPDocument* doc, Inkscape::XML::Node* repr) {
this->readAttr("height");
this->readAttr("rx");
this->readAttr("ry");
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPRect::build", false );
+#endif
}
void SPRect::set(unsigned key, gchar const *value) {
+
+#ifdef OBJECT_TRACE
+ std::stringstream temp;
+ temp << "SPRect::set: " << key << " " << (value?value:"null");
+ objectTrace( temp.str() );
+#endif
+
/* fixme: We need real error processing some time */
// We must update the SVGLengths immediately or nodes may be misplaced after they are moved.
@@ -104,9 +120,17 @@ void SPRect::set(unsigned key, gchar const *value) {
SPShape::set(key, value);
break;
}
+#ifdef OBJECT_TRACE
+ objectTrace( "SPRect::set", false );
+#endif
}
void SPRect::update(SPCtx* ctx, unsigned int flags) {
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPRect::update", true, flags );
+#endif
+
if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
SPItemCtx const *ictx = reinterpret_cast<SPItemCtx const *>(ctx);
@@ -127,9 +151,17 @@ void SPRect::update(SPCtx* ctx, unsigned int flags) {
}
SPShape::update(ctx, flags);
+#ifdef OBJECT_TRACE
+ objectTrace( "SPRect::update", false, flags );
+#endif
}
Inkscape::XML::Node * SPRect::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
+
+#ifdef OBJECT_TRACE
+ objectTrace( "SPRect::write", true, flags );
+#endif
+
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
repr = xml_doc->createElement("svg:rect");
}
@@ -151,6 +183,10 @@ Inkscape::XML::Node * SPRect::write(Inkscape::XML::Document *xml_doc, Inkscape::
this->set_shape(); // evaluate SPCurve
SPShape::write(xml_doc, repr, flags);
+#ifdef OBJECT_TRACE
+ objectTrace( "SPRect::write", false, flags );
+#endif
+
return repr;
}
diff --git a/src/sp-stop.cpp b/src/sp-stop.cpp
index d31946b94..58746c951 100644
--- a/src/sp-stop.cpp
+++ b/src/sp-stop.cpp
@@ -114,6 +114,7 @@ void SPStop::set(unsigned int key, const gchar* value) {
// std::cout << "Got Curve" << std::endl;
//curve->unref();
//}
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
}
break;
}