summaryrefslogtreecommitdiffstats
path: root/src/sp-filter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sp-filter.cpp')
-rw-r--r--src/sp-filter.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp
index c3e7d217e..e8319baca 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 <cstring>
@@ -206,10 +207,55 @@ 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) {
+ 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? */
}
+ // 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);
}