summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2014-03-01 09:19:51 +0000
committertavmjong-free <tavmjong@free.fr>2014-03-01 09:19:51 +0000
commitc986b61b956280bfd0b24c1dddf758216e6940f8 (patch)
tree29e4674c3858c7a8964dceb294bb34bb68ff5a9d /src
parentCode cleanup and indentation. (diff)
downloadinkscape-c986b61b956280bfd0b24c1dddf758216e6940f8.tar.gz
inkscape-c986b61b956280bfd0b24c1dddf758216e6940f8.zip
Use viewport when calculating filter primitive region when 'primitiveUnits' set to "userSpaceOnUse".
(bzr r13083)
Diffstat (limited to 'src')
-rw-r--r--src/display/nr-filter-primitive.cpp53
-rw-r--r--src/sp-filter-primitive.cpp29
-rw-r--r--src/sp-filter.cpp20
3 files changed, 67 insertions, 35 deletions
diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp
index 95d5d4b09..b065ac445 100644
--- a/src/display/nr-filter-primitive.cpp
+++ b/src/display/nr-filter-primitive.cpp
@@ -121,30 +121,10 @@ Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units)
fa = *fa_opt;
}
- // This is definitely a hack... but what else to do?
- // Current viewport might not be document viewport... but how to find?
- SPDocument* document = inkscape_active_document();
- SPRoot* root = document->getRoot();
- Geom::Rect viewport;
- if( root->viewBox_set ) {
- viewport = root->viewBox;
- } else {
- // Pick some random values
- viewport = Geom::Rect::from_xywh(0,0,480,360);
- }
-
- /* Update computed values for ex, em, %. For %, assumes primitive unit is objectBoundingBox. */
- /* TODO: fetch somehow the object ex and em lengths; 12, 6 are just dummy values. */
- double len_x = bb.width();
- double len_y = bb.height();
- _subregion_x.update(12, 6, len_x);
- _subregion_y.update(12, 6, len_y);
- _subregion_width.update(12, 6, len_x);
- _subregion_height.update(12, 6, len_y);
// x, y, width, and height are independently defined (i.e. one can be defined, by default, to
- // the filter area while another is defined relative to the bounding box). It is better to keep
- // track of them separately and then compose the Rect at the end.
+ // the filter area (via default value ) while another is defined relative to the bounding
+ // box). It is better to keep track of them separately and then compose the Rect at the end.
double x = 0;
double y = 0;
double width = 0;
@@ -157,10 +137,21 @@ Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units)
if( !_subregion_height._set ) height = fa.height();
if( units.get_primitive_units() == SP_FILTER_UNITS_OBJECTBOUNDINGBOX ) {
+
+ // Update computed values for ex, em, %.
+ // For %, assumes primitive unit is objectBoundingBox.
+ // TODO: fetch somehow the object ex and em lengths; 12, 6 are just dummy values.
+ double len_x = bb.width();
+ double len_y = bb.height();
+ _subregion_x.update(12, 6, len_x);
+ _subregion_y.update(12, 6, len_y);
+ _subregion_width.update(12, 6, len_x);
+ _subregion_height.update(12, 6, len_y);
+
// Values are in terms of fraction of bounding box.
if( _subregion_x._set && (_subregion_x.unit != SVGLength::PERCENT) ) x = bb.min()[X] + bb.width() * _subregion_x.value;
if( _subregion_y._set && (_subregion_y.unit != SVGLength::PERCENT) ) y = bb.min()[Y] + bb.height() * _subregion_y.value;
- if( _subregion_width._set && (_subregion_width.unit != SVGLength::PERCENT) ) width = bb.width() * _subregion_width.value;
+ if( _subregion_width._set && (_subregion_width.unit != SVGLength::PERCENT) ) width = bb.width() * _subregion_width.value;
if( _subregion_height._set && (_subregion_height.unit != SVGLength::PERCENT) ) height = bb.height() * _subregion_height.value;
// Values are in terms of percent
if( _subregion_x._set && (_subregion_x.unit == SVGLength::PERCENT) ) x = bb.min()[X] + _subregion_x.computed;
@@ -168,17 +159,11 @@ Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units)
if( _subregion_width._set && (_subregion_width.unit == SVGLength::PERCENT) ) width = _subregion_width.computed;
if( _subregion_height._set && (_subregion_height.unit == SVGLength::PERCENT) ) height = _subregion_height.computed;
} else {
- // Values are in terms of user space coordinates or percent of viewbox (yuck!),
- // which is usually the size of SVG drawing. Default.
- if( _subregion_x._set && (_subregion_x.unit != SVGLength::PERCENT) ) x = _subregion_x.computed;
- if( _subregion_y._set && (_subregion_y.unit != SVGLength::PERCENT) ) y = _subregion_y.computed;
- if( _subregion_width._set && (_subregion_width.unit != SVGLength::PERCENT) ) width = _subregion_width.computed;
- if( _subregion_height._set && (_subregion_height.unit != SVGLength::PERCENT) ) height = _subregion_height.computed;
- // Percent of viewport
- if( _subregion_x._set && (_subregion_x.unit == SVGLength::PERCENT) ) x = _subregion_x.value * viewport.width();
- if( _subregion_y._set && (_subregion_y.unit == SVGLength::PERCENT) ) y = _subregion_y.value * viewport.height();
- if( _subregion_width._set && (_subregion_width.unit == SVGLength::PERCENT) ) width = _subregion_width.value * viewport.width();
- if( _subregion_height._set && (_subregion_height.unit == SVGLength::PERCENT) ) height = _subregion_height.value * viewport.height();
+ // Values are in terms of user space coordinates or percent of viewport (already calculated in sp-filter-primitive.cpp).
+ if( _subregion_x._set ) x = _subregion_x.computed;
+ if( _subregion_y._set ) y = _subregion_y.computed;
+ if( _subregion_width._set ) width = _subregion_width.computed;
+ if( _subregion_height._set ) height = _subregion_height.computed;
}
return Geom::Rect (Geom::Point(x,y), Geom::Point(x + width, y + height));
diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp
index cb5fdf4f9..ceb91c984 100644
--- a/src/sp-filter-primitive.cpp
+++ b/src/sp-filter-primitive.cpp
@@ -24,6 +24,7 @@
#include "sp-filter-primitive.h"
#include "xml/repr.h"
#include "sp-filter.h"
+#include "sp-item.h"
#include "display/nr-filter-primitive.h"
#include "display/nr-filter-types.h"
@@ -135,6 +136,33 @@ void SPFilterPrimitive::set(unsigned int key, gchar const *value) {
*/
void SPFilterPrimitive::update(SPCtx *ctx, guint flags) {
+ SPItemCtx *ictx = (SPItemCtx *) ctx;
+
+ // Do here since we know viewport (Bounding box case handled during rendering)
+ SPFilter *parent = SP_FILTER(this->parent);
+
+ if( parent->primitiveUnits == 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();
+ }
+ }
+
SPObject::update(ctx, flags);
}
@@ -244,6 +272,7 @@ void sp_filter_primitive_renderer_common(SPFilterPrimitive *sp_prim, Inkscape::F
nr_prim->set_output(sp_prim->image_out);
/* TODO: place here code to handle input images, filter area etc. */
+ // We don't know current viewport or bounding box, this is wrong approach.
nr_prim->set_subregion( sp_prim->x, sp_prim->y, sp_prim->width, sp_prim->height );
// Give renderer access to filter properties
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);
}