From 2b00f3b9bdfa55829ce5521f3de15b83b14b654a Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 28 Feb 2014 11:09:32 +0100 Subject: Use viewport when calculating filter region when filterUnits set to "userSpaceOnUse", fixes #229246. (bzr r13073) --- src/sp-filter.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/sp-filter.cpp') diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index c3e7d217e..0e3d2d5ce 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -28,6 +28,7 @@ using std::pair; #include "sp-filter.h" #include "sp-filter-reference.h" #include "sp-filter-primitive.h" +#include "sp-item.h" #include "uri.h" #include "xml/repr.h" #include @@ -206,6 +207,33 @@ void SPFilter::update(SPCtx *ctx, guint flags) { if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + SPItemCtx *ictx = (SPItemCtx *) ctx; + + // Do here since we know viewport (Bounding box case handled during rendering) + // Note: This only works for root viewport since this routine is not called after + // setting a new viewport. A true fix requires a strategy like SPItemView or SPMarkerView. + if(this->filterUnits == SP_FILTER_UNITS_USERSPACEONUSE) { + std::cout << " userSpaceOnUse" << std::endl; + if (this->x.unit == SVGLength::PERCENT) { + this->x._set = true; + this->x.computed = this->x.value * ictx->viewport.width(); + } + + if (this->y.unit == SVGLength::PERCENT) { + this->y._set = true; + this->y.computed = this->y.value * ictx->viewport.height(); + } + + if (this->width.unit == SVGLength::PERCENT) { + this->width._set = true; + this->width.computed = this->width.value * ictx->viewport.width(); + } + + if (this->height.unit == SVGLength::PERCENT) { + this->height._set = true; + this->height.computed = this->height.value * ictx->viewport.height(); + } + } /* do something to trigger redisplay, updates? */ } -- cgit v1.2.3 From c986b61b956280bfd0b24c1dddf758216e6940f8 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 1 Mar 2014 10:19:51 +0100 Subject: Use viewport when calculating filter primitive region when 'primitiveUnits' set to "userSpaceOnUse". (bzr r13083) --- src/sp-filter.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/sp-filter.cpp') diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index 0e3d2d5ce..e8319baca 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -213,7 +213,6 @@ void SPFilter::update(SPCtx *ctx, guint flags) { // Note: This only works for root viewport since this routine is not called after // setting a new viewport. A true fix requires a strategy like SPItemView or SPMarkerView. if(this->filterUnits == SP_FILTER_UNITS_USERSPACEONUSE) { - std::cout << " userSpaceOnUse" << std::endl; if (this->x.unit == SVGLength::PERCENT) { this->x._set = true; this->x.computed = this->x.value * ictx->viewport.width(); @@ -238,6 +237,25 @@ void SPFilter::update(SPCtx *ctx, guint flags) { } + // Update filter primitives in order to update filter primitive area + // (SPObject::ActionUpdate is not actually used) + unsigned childflags = flags; + + if (flags & SP_OBJECT_MODIFIED_FLAG) { + childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } + childflags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList *l = g_slist_reverse(this->childList(true, SPObject::ActionUpdate)); + while (l) { + SPObject *child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if( SP_IS_FILTER_PRIMITIVE( child ) ) { + child->updateDisplay(ctx, childflags); + } + sp_object_unref(child); + } + SPObject::update(ctx, flags); } -- cgit v1.2.3