=== modified file 'src/document.cpp' --- src/document.cpp 2014-03-03 21:34:34 +0000 +++ src/document.cpp 2014-03-11 20:04:32 +0000 @@ -1133,12 +1133,11 @@ sp_document_idle_handler(gpointer data) { SPDocument *doc = static_cast(data); - if (doc->_updateDocument()) { + bool status = !doc->_updateDocument(); // method TRUE if it does NOT need further modification, so invert + if (!status) { doc->modified_id = 0; - return false; - } else { - return true; } + return status; } /** @@ -1552,7 +1551,8 @@ SPGradient *gr = SP_GRADIENT(src); for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) { if (trg && SP_IS_GRADIENT(trg) && src != trg) { - if (gr->isEquivalent(SP_GRADIENT(trg))) { + if (gr->isEquivalent(SP_GRADIENT(trg)) && + gr->isAligned(SP_GRADIENT(trg))) { // Change object references to the existing equivalent gradient change_def_references(src, trg); duplicate = true; === modified file 'src/id-clash.cpp' --- src/id-clash.cpp 2014-02-20 19:22:58 +0000 +++ src/id-clash.cpp 2014-03-11 20:04:32 +0000 @@ -215,9 +215,10 @@ SPObject *cd_obj = current_doc->getObjectById(id); if (cd_obj && SP_IS_GRADIENT(cd_obj)) { - SPGradient *cd_gr = SP_GRADIENT(cd_obj); - if (cd_gr->isEquivalent(SP_GRADIENT(elem))) { - fix_clashing_ids = false; + SPGradient *cd_gr = SP_GRADIENT(cd_obj); + if ( cd_gr->isEquivalent(SP_GRADIENT(elem)) && + cd_gr->isAligned(SP_GRADIENT(elem))) { + fix_clashing_ids = false; } } } === modified file 'src/sp-gradient.cpp' --- src/sp-gradient.cpp 2013-10-21 11:07:45 +0000 +++ src/sp-gradient.cpp 2014-03-13 18:50:00 +0000 @@ -111,28 +111,91 @@ { //TODO Make this work for mesh gradients - if (this->getStopCount() != that->getStopCount()) - return FALSE; - - if (this->hasStops() != that->hasStops()) - return FALSE; - - if (!this->getVector() || !that->getVector()) - return FALSE; - - SPStop *as = this->getVector()->getFirstStop(); - SPStop *bs = that->getVector()->getFirstStop(); - - while (as && bs) { - if (!as->getEffectiveColor().isClose(bs->getEffectiveColor(), 0.001) || - as->offset != bs->offset) { - return FALSE; - } - as = as->getNextStop(); - bs = bs->getNextStop(); - } - - return TRUE; + bool status = FALSE; + + while(1){ // not really a loop, used to avoid deep nesting or multiple exit points from function + if (this->getStopCount() != that->getStopCount()) { break; } + if (this->hasStops() != that->hasStops()) { break; } + if (!this->getVector() || !that->getVector()) { break; } + if ( (SP_IS_LINEARGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) || + (SP_IS_RADIALGRADIENT(this) && SP_IS_RADIALGRADIENT(that)) || + (SP_IS_MESHGRADIENT(this) && SP_IS_MESHGRADIENT(that))) { + /* OK! */ + } + else { break; } + + SPStop *as = this->getVector()->getFirstStop(); + SPStop *bs = that->getVector()->getFirstStop(); + + bool effective = TRUE; + while (effective && (as && bs)) { + if (!as->getEffectiveColor().isClose(bs->getEffectiveColor(), 0.001) || + as->offset != bs->offset) { + effective = FALSE; + break; + } + else { + as = as->getNextStop(); + bs = bs->getNextStop(); + } + } + if(!effective)break; + + status = TRUE; + break; + } + return status; +} + +/** + * return true if this gradient is "aligned" to that gradient. + * Aligned means that they have exactly the same coordinates and transform. + * @param that - A gradient to compare this to + */ +gboolean SPGradient::isAligned(SPGradient *that) +{ + bool status = FALSE; + + while(1){ // not really a loop, used to avoid deep nesting or multiple exit points from function + if(this->gradientTransform_set != that->gradientTransform_set) { break; } + if(this->gradientTransform_set && + (this->gradientTransform != that->gradientTransform)) { break; } + if (SP_IS_LINEARGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) { + SPLinearGradient *sg=SP_LINEARGRADIENT(this); + SPLinearGradient *tg=SP_LINEARGRADIENT(that); + + if( !sg->x1._set || !tg->x1._set || // assume that if these are set so will be all the others + (sg->x1.computed != tg->x1.computed) || + (sg->y1.computed != tg->y1.computed) || + (sg->x2.computed != tg->x2.computed) || + (sg->y2.computed != tg->y2.computed) + ) { break; } + } else if (SP_IS_RADIALGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) { + SPRadialGradient *sg=SP_RADIALGRADIENT(this); + SPRadialGradient *tg=SP_RADIALGRADIENT(that); + if( !sg->cx._set || !tg->cx._set || // assume that if these are set so will be all the others + (sg->cx.computed != tg->cx.computed) || + (sg->cy.computed != tg->cy.computed) || + (sg->r.computed != tg->r.computed ) || + (sg->fx.computed != tg->fx.computed) || + (sg->fy.computed != tg->fy.computed) + ) { break; } + } else if (SP_IS_MESHGRADIENT(this) && SP_IS_MESHGRADIENT(that)) { + SPMeshGradient *sg=SP_MESHGRADIENT(this); + SPMeshGradient *tg=SP_MESHGRADIENT(that); + + if( !sg->x._set || !tg->x._set || + !sg->y._set || !tg->y._set || + (sg->x.computed != tg->x.computed) || + (sg->y.computed != tg->y.computed) + ) { break; } + } else { + break; + } + status = TRUE; + break; + } + return status; } === modified file 'src/sp-gradient.h' --- src/sp-gradient.h 2013-09-15 00:43:49 +0000 +++ src/sp-gradient.h 2014-03-11 20:04:32 +0000 @@ -147,6 +147,7 @@ int getStopCount() const; gboolean isEquivalent(SPGradient *b); + gboolean isAligned(SPGradient *b); /** Mesh Gradients **************/