diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2014-03-01 09:19:51 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2014-03-01 09:19:51 +0000 |
| commit | c986b61b956280bfd0b24c1dddf758216e6940f8 (patch) | |
| tree | 29e4674c3858c7a8964dceb294bb34bb68ff5a9d /src | |
| parent | Code cleanup and indentation. (diff) | |
| download | inkscape-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.cpp | 53 | ||||
| -rw-r--r-- | src/sp-filter-primitive.cpp | 29 | ||||
| -rw-r--r-- | src/sp-filter.cpp | 20 |
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); } |
