1 /*
2 * feOffset filter primitive renderer
3 *
4 * Authors:
5 * Niko Kiirala <niko@kiirala.com>
6 *
7 * Copyright (C) 2007 authors
8 *
9 * Released under GNU GPL, read the file 'COPYING' for more information
10 */
12 #include "display/nr-filter-offset.h"
13 #include "display/nr-filter-slot.h"
14 #include "display/nr-filter-units.h"
15 #include "libnr/nr-blit.h"
16 #include "libnr/nr-pixblock.h"
17 #include "libnr/nr-rect-l.h"
19 namespace Inkscape {
20 namespace Filters {
22 using Geom::X;
23 using Geom::Y;
25 FilterOffset::FilterOffset() :
26 dx(0), dy(0)
27 {}
29 FilterPrimitive * FilterOffset::create() {
30 return new FilterOffset();
31 }
33 FilterOffset::~FilterOffset()
34 {}
36 int FilterOffset::render(FilterSlot &slot, FilterUnits const &units) {
37 NRPixBlock *in = slot.get(_input);
38 // Bail out if source image is missing
39 if (!in) {
40 g_warning("Missing source image for feOffset (in=%d)", _input);
41 return 1;
42 }
44 NRPixBlock *out = new NRPixBlock;
46 Geom::Matrix trans = units.get_matrix_primitiveunits2pb();
47 Geom::Point offset(dx, dy);
48 offset *= trans;
49 offset[X] -= trans[4];
50 offset[Y] -= trans[5];
52 nr_pixblock_setup_fast(out, in->mode,
53 in->area.x0, in->area.y0, in->area.x1, in->area.y1,
54 true);
55 nr_blit_pixblock_pixblock(out, in);
57 out->area.x0 += static_cast<NR::ICoord>(offset[X]);
58 out->area.y0 += static_cast<NR::ICoord>(offset[Y]);
59 out->area.x1 += static_cast<NR::ICoord>(offset[X]);
60 out->area.y1 += static_cast<NR::ICoord>(offset[Y]);
61 out->visible_area = out->area;
63 out->empty = FALSE;
64 slot.set(_output, out);
66 return 0;
67 }
69 void FilterOffset::set_dx(double amount) {
70 dx = amount;
71 }
73 void FilterOffset::set_dy(double amount) {
74 dy = amount;
75 }
77 void FilterOffset::area_enlarge(NRRectL &area, Geom::Matrix const &trans)
78 {
79 Geom::Point offset(dx, dy);
80 offset *= trans;
81 offset[X] -= trans[4];
82 offset[Y] -= trans[5];
84 if (offset[X] > 0) {
85 area.x0 -= static_cast<NR::ICoord>(offset[X]);
86 } else {
87 area.x1 -= static_cast<NR::ICoord>(offset[X]);
88 }
90 if (offset[Y] > 0) {
91 area.y0 -= static_cast<NR::ICoord>(offset[Y]);
92 } else {
93 area.y1 -= static_cast<NR::ICoord>(offset[Y]);
94 }
95 }
97 } /* namespace Filters */
98 } /* namespace Inkscape */
100 /*
101 Local Variables:
102 mode:c++
103 c-file-style:"stroustrup"
104 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
105 indent-tabs-mode:nil
106 fill-column:99
107 End:
108 */
109 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :