Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
nr-filter-primitive.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * SVG filters rendering
4 *
5 * Author:
6 * Niko Kiirala <niko@kiirala.com>
7 * Tavmjong Bah <tavmjong@free.fr> (primitive subregion)
8 *
9 * Copyright (C) 2006 Niko Kiirala
10 *
11 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
12 */
14
15#include "style.h"
16
17#include "display/nr-filter-slot.h" // for FilterSlot
18#include "display/nr-filter-types.h" // for FilterSlotType
19#include "display/nr-filter-units.h" // for FilterUnits
20#include "object/sp-filter-units.h" // for SPFilterUnits
21#include "svg/svg-length.h" // for SVGLength
22
23namespace Inkscape {
24namespace Filters {
25
27{
30
31 // Primitive subregion, should default to the union of all subregions of referenced nodes
32 // (i.e. other filter primitives except feTile). If no referenced nodes, defaults to filter
33 // region expressed in percent. At the moment, we do not check referenced nodes.
34
35 // We must keep track if a value is set or not, if not set then the region defaults to 0%, 0%,
36 // 100%, 100% ("x", "y", "width", "height") of the -> filter <- region. If set, then
37 // percentages are in terms of bounding box or viewbox, depending on value of "primitiveUnits".
38
39 // NB: SVGLength.set takes prescaled percent values: 1 means 100%
44
46}
47
49
51{
52 // passthrough
54 slot.set(_output, in);
55}
56
58{
59 set_input(0, slot);
60}
61
62void FilterPrimitive::set_input(int input, int slot)
63{
64 if (input == 0) _input = slot;
65}
66
68{
69 if (slot >= 0) _output = slot;
70}
71
72// We need to copy reference even if unset as we need to know if
73// someone has unset a value.
75{
76 _subregion_x = length;
77}
78
80{
81 _subregion_y = length;
82}
83
85{
86 _subregion_width = length;
87}
88
90{
91 _subregion_height = length;
92}
93
102
104{
105 Geom::OptRect const fa_opt = units.get_filter_area();
106 if (!fa_opt) {
107 std::cerr << "FilterPrimitive::filter_primitive_area: filter area undefined." << std::endl;
108 return Geom::Rect::from_xywh(0, 0, 0, 0);
109 }
110 Geom::Rect fa = *fa_opt;
111
112 // x, y, width, and height are independently defined (i.e. one can be defined, by default, to
113 // the filter area (via default value ) while another is defined relative to the bounding
114 // box). It is better to keep track of them separately and then compose the Rect at the end.
115 double x = 0;
116 double y = 0;
117 double width = 0;
118 double height = 0;
119
120 // If subregion not set, by special case use filter region.
121 if (!_subregion_x._set) x = fa.left();
122 if (!_subregion_y._set) y = fa.top();
123 if (!_subregion_width._set) width = fa.width();
124 if (!_subregion_height._set) height = fa.height();
125
127
128 Geom::OptRect const bb_opt = units.get_item_bbox();
129 if (!bb_opt) {
130 std::cerr << "FilterPrimitive::filter_primitive_area: bounding box undefined and 'primitiveUnits' is 'objectBoundingBox'." << std::endl;
131 return Geom::Rect();
132 }
133 Geom::Rect bb = *bb_opt;
134
135 // Update computed values for ex, em, %.
136 // For %, assumes primitive unit is objectBoundingBox.
137 // TODO: fetch somehow the object ex and em lengths; 12, 6 are just dummy values.
138 auto const len_x = bb.width();
139 auto const len_y = bb.height();
140
141 auto compute = [] (SVGLength length, double scale) {
142 length.update(12, 6, scale);
143 return length.computed;
144 };
145
146 auto const subregion_x_computed = compute(_subregion_x, len_x);
147 auto const subregion_y_computed = compute(_subregion_y, len_y);
148 auto const subregion_w_computed = compute(_subregion_width, len_x);
149 auto const subregion_h_computed = compute(_subregion_height, len_y);
150
151 // Values are in terms of fraction of bounding box.
156 // Values are in terms of percent
157 if (_subregion_x._set && _subregion_x.unit == SVGLength::PERCENT) x = bb.left() + subregion_x_computed;
158 if (_subregion_y._set && _subregion_y.unit == SVGLength::PERCENT) y = bb.top() + subregion_y_computed;
159 if (_subregion_width._set && _subregion_width.unit == SVGLength::PERCENT) width = subregion_w_computed;
160 if (_subregion_height._set && _subregion_height.unit == SVGLength::PERCENT) height = subregion_h_computed;
161 } else {
162 // Values are in terms of user space coordinates or percent of viewport (already calculated in sp-filter-primitive.cpp).
167 }
168
169 return Geom::Rect::from_xywh(x, y, width, height);
170}
171
173{
174 if (style) {
176 } else {
178 }
179}
180
181} // namespace Filters
182} // namespace Inkscape
183
184/*
185 Local Variables:
186 mode:c++
187 c-file-style:"stroustrup"
188 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
189 indent-tabs-mode:nil
190 fill-column:99
191 End:
192*/
193// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
double scale
Definition aa.cpp:228
static CRect from_xywh(Coord x, Coord y, Coord w, Coord h)
Create rectangle from origin and dimensions.
C top() const
Return top coordinate of the rectangle (+Y is downwards).
C left() const
Return leftmost coordinate of the rectangle (+X is to the right).
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
Axis-aligned rectangle that can be empty.
Definition rect.h:203
Axis aligned, non-empty rectangle.
Definition rect.h:92
void set_width(SVGLength const &length)
virtual void set_output(int slot)
Sets the slot number 'slot' to be used as output from filter primitive 'primitive' If output slot for...
Geom::Rect filter_primitive_area(FilterUnits const &units) const
Returns the filter primitive area in user coordinate system.
virtual void render_cairo(FilterSlot &slot) const
void setStyle(SPStyle const *style)
Sets style for access to properties used by filter primitives.
void set_subregion(SVGLength const &x, SVGLength const &y, SVGLength const &width, SVGLength const &height)
void set_x(SVGLength const &length)
Sets the filter primitive subregion.
virtual void set_input(int slot)
Sets the input slot number 'slot' to be used as input in rendering filter primitive 'primitive' For f...
void set_y(SVGLength const &length)
void set_height(SVGLength const &length)
cairo_surface_t * getcairo(int slot)
Returns the pixblock in specified slot.
void set(int slot, cairo_surface_t *s)
Sets or re-sets the pixblock associated with given slot.
SPFilterUnits get_primitive_units() const
Gets Primitive Units (userSpaceOnUse or objectBoundingBox)
Geom::OptRect get_filter_area() const
Gets the filter effects area in user coordinates.
Geom::OptRect get_item_bbox() const
Gets the item bounding box in user coordinates.
An SVG style object.
Definition style.h:45
T< SPAttr::COLOR_INTERPOLATION_FILTERS, SPIEnum< SPColorInterpolation > > color_interpolation_filters
color-interpolation-filters
Definition style.h:229
SVG length type.
Definition svg-length.h:22
float value
Definition svg-length.h:47
bool _set
Definition svg-length.h:41
void unset(Unit u=NONE, float v=0, float c=0)
Unit unit
Definition svg-length.h:44
float computed
Definition svg-length.h:50
struct _cairo_surface cairo_surface_t
Helper class to stream background task notifications as a series of messages.
TODO: insert short description here.
TODO: insert short description here.
@ SP_FILTER_UNITS_OBJECTBOUNDINGBOX
@ SP_CSS_COLOR_INTERPOLATION_AUTO
SPStyle - a style object for SPItem objects.
double height
double width