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-matrix.h"
17 #include "libnr/nr-pixblock.h"
18 #include "libnr/nr-point.h"
19 #include "libnr/nr-point-matrix-ops.h"
20 #include "libnr/nr-rect-l.h"
22 namespace NR {
24 FilterOffset::FilterOffset() :
25 dx(0), dy(0)
26 {}
28 FilterPrimitive * FilterOffset::create() {
29 return new FilterOffset();
30 }
32 FilterOffset::~FilterOffset()
33 {}
35 int FilterOffset::render(FilterSlot &slot, FilterUnits const &units) {
36 NRPixBlock *in = slot.get(_input);
37 // Bail out if source image is missing
38 if (!in) {
39 g_warning("Missing source image for feOffset (in=%d)", _input);
40 return 1;
41 }
43 NRPixBlock *out = new NRPixBlock;
45 Matrix trans = units.get_matrix_primitiveunits2pb();
46 Point offset(dx, dy);
47 offset *= trans;
48 offset[X] -= trans[4];
49 offset[Y] -= trans[5];
51 nr_pixblock_setup_fast(out, in->mode,
52 in->area.x0, in->area.y0, in->area.x1, in->area.y1,
53 true);
54 nr_blit_pixblock_pixblock(out, in);
56 out->area.x0 += static_cast<NR::ICoord>(offset[X]);
57 out->area.y0 += static_cast<NR::ICoord>(offset[Y]);
58 out->area.x1 += static_cast<NR::ICoord>(offset[X]);
59 out->area.y1 += static_cast<NR::ICoord>(offset[Y]);
60 out->visible_area = out->area;
62 out->empty = FALSE;
63 slot.set(_output, out);
65 return 0;
66 }
68 void FilterOffset::set_dx(double amount) {
69 dx = amount;
70 }
72 void FilterOffset::set_dy(double amount) {
73 dy = amount;
74 }
76 void FilterOffset::area_enlarge(NRRectL &area, Matrix const &trans)
77 {
78 Point offset(dx, dy);
79 offset *= trans;
80 offset[X] -= trans[4];
81 offset[Y] -= trans[5];
83 if (offset[X] > 0) {
84 area.x0 -= static_cast<NR::ICoord>(offset[X]);
85 } else {
86 area.x1 -= static_cast<NR::ICoord>(offset[X]);
87 }
89 if (offset[Y] > 0) {
90 area.y0 -= static_cast<NR::ICoord>(offset[Y]);
91 } else {
92 area.y1 -= static_cast<NR::ICoord>(offset[Y]);
93 }
94 }
96 } /* namespace NR */
98 /*
99 Local Variables:
100 mode:c++
101 c-file-style:"stroustrup"
102 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
103 indent-tabs-mode:nil
104 fill-column:99
105 End:
106 */
107 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :