Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
nr-filter-composite.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * feComposite filter effect renderer
4 *
5 * Authors:
6 * Niko Kiirala <niko@kiirala.com>
7 *
8 * Copyright (C) 2007 authors
9 *
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11 */
12
13#include <cmath>
14
16#include "display/cairo-utils.h"
20
21namespace Inkscape {
22namespace Filters {
23
26 , k1(0)
27 , k2(0)
28 , k3(0)
29 , k4(0)
30 , _input2(Inkscape::Filters::NR_FILTER_SLOT_NOT_SET) {}
31
33
34struct ComposeArithmetic
35{
36 ComposeArithmetic(double k1, double k2, double k3, double k4)
37 : _k1(round(k1 * 255))
38 , _k2(round(k2 * 255*255))
39 , _k3(round(k3 * 255*255))
40 , _k4(round(k4 * 255*255*255)) {}
41
42 guint32 operator()(guint32 in1, guint32 in2)
43 {
44 EXTRACT_ARGB32(in1, aa, ra, ga, ba)
45 EXTRACT_ARGB32(in2, ab, rb, gb, bb)
46
47 gint32 ao = _k1*aa*ab + _k2*aa + _k3*ab + _k4;
48 gint32 ro = _k1*ra*rb + _k2*ra + _k3*rb + _k4;
49 gint32 go = _k1*ga*gb + _k2*ga + _k3*gb + _k4;
50 gint32 bo = _k1*ba*bb + _k2*ba + _k3*bb + _k4;
51
52 ao = pxclamp(ao, 0, 255*255*255); // r, g and b are premultiplied, so should be clamped to the alpha channel
53 ro = (pxclamp(ro, 0, ao) + (255*255/2)) / (255*255);
54 go = (pxclamp(go, 0, ao) + (255*255/2)) / (255*255);
55 bo = (pxclamp(bo, 0, ao) + (255*255/2)) / (255*255);
56 ao = (ao + (255*255/2)) / (255*255);
57
58 ASSEMBLE_ARGB32(pxout, ao, ro, go, bo)
59 return pxout;
60 }
61
62private:
63 gint32 _k1, _k2, _k3, _k4;
64};
65
67{
68 cairo_surface_t *input1 = slot.getcairo(_input);
69 cairo_surface_t *input2 = slot.getcairo(_input2);
70
71 // We may need to transform input surface to correct color interpolation space. The input surface
72 // might be used as input to another primitive but it is likely that all the primitives in a given
73 // filter use the same color interpolation space so we don't copy the input before converting.
76
79
81 slot.set_primitive_area(_output, vp); // Needed for tiling
82
83 if (op == COMPOSITE_ARITHMETIC) {
84 ink_cairo_surface_blend(input1, input2, out, ComposeArithmetic(k1, k2, k3, k4));
85 } else {
86 ink_cairo_surface_blit(input2, out);
87 cairo_t *ct = cairo_create(out);
88 cairo_set_source_surface(ct, input1, 0, 0);
89 switch(op) {
90 case COMPOSITE_IN:
91 cairo_set_operator(ct, CAIRO_OPERATOR_IN);
92 break;
93 case COMPOSITE_OUT:
94 cairo_set_operator(ct, CAIRO_OPERATOR_OUT);
95 break;
96 case COMPOSITE_ATOP:
97 cairo_set_operator(ct, CAIRO_OPERATOR_ATOP);
98 break;
99 case COMPOSITE_XOR:
100 cairo_set_operator(ct, CAIRO_OPERATOR_XOR);
101 break;
103 cairo_set_operator(ct, CAIRO_OPERATOR_ADD);
104 break;
105 case COMPOSITE_OVER:
107 default:
108 // OVER is the default operator
109 break;
110 }
111 cairo_paint(ct);
112 cairo_destroy(ct);
113 }
114
115 slot.set(_output, out);
116 cairo_surface_destroy(out);
117}
118
120{
121 return true;
122}
123
125{
126 _input = input;
127}
128
129void FilterComposite::set_input(int input, int slot)
130{
131 if (input == 0) _input = slot;
132 if (input == 1) _input2 = slot;
133}
134
136{
137 if (op_ == COMPOSITE_DEFAULT) {
139 } else if (op_ != COMPOSITE_ENDOPERATOR) {
140 op = op_;
141 }
142}
143
144void FilterComposite::set_arithmetic(double k1_, double k2_, double k3_, double k4_)
145{
146 if (!std::isfinite(k1) || !std::isfinite(k2) || !std::isfinite(k3) || !std::isfinite(k4)) {
147 g_warning("Non-finite parameter for feComposite arithmetic operator");
148 return;
149 }
150 k1 = k1_;
151 k2 = k2_;
152 k3 = k3_;
153 k4 = k4_;
154}
155
157{
158 return 1.1;
159}
160
161} // namespace Filters
162} // namespace Inkscape
163
164/*
165 Local Variables:
166 mode:c++
167 c-file-style:"stroustrup"
168 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
169 indent-tabs-mode:nil
170 fill-column:99
171 End:
172*/
173// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Cairo software blending templates.
G_GNUC_CONST gint32 pxclamp(gint32 v, gint32 low, gint32 high)
void ink_cairo_surface_blend(cairo_surface_t *in1, cairo_surface_t *in2, cairo_surface_t *out, Blend &&blend)
Blend two surfaces using the supplied functor.
void ink_cairo_surface_blit(cairo_surface_t *src, cairo_surface_t *dest)
cairo_surface_t * ink_cairo_surface_create_output(cairo_surface_t *image, cairo_surface_t *bg)
void set_cairo_surface_ci(cairo_surface_t *surface, SPColorInterpolation ci)
Set the color_interpolation_value for a Cairo surface.
Cairo integration helpers.
3x3 matrix representing an affine transformation.
Definition affine.h:70
Axis aligned, non-empty rectangle.
Definition rect.h:92
double complexity(Geom::Affine const &ctm) const override
void set_arithmetic(double k1, double k2, double k3, double k4)
void set_input(int input) override
Sets the input slot number 'slot' to be used as input in rendering filter primitive 'primitive' For f...
bool can_handle_affine(Geom::Affine const &) const override
Indicate whether the filter primitive can handle the given affine.
void render_cairo(FilterSlot &) const override
void set_operator(FeCompositeOperator op)
Geom::Rect filter_primitive_area(FilterUnits const &units) const
Returns the filter primitive area in user coordinate system.
void set_primitive_area(int slot, Geom::Rect &area)
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.
FilterUnits const & get_units() const
FeCompositeOperator
Definition composite.h:19
@ COMPOSITE_OUT
Definition composite.h:25
@ COMPOSITE_ATOP
Definition composite.h:26
@ COMPOSITE_ENDOPERATOR
Definition composite.h:30
@ COMPOSITE_LIGHTER
Definition composite.h:29
@ COMPOSITE_DEFAULT
Definition composite.h:22
@ COMPOSITE_IN
Definition composite.h:24
@ COMPOSITE_ARITHMETIC
Definition composite.h:28
@ COMPOSITE_XOR
Definition composite.h:27
@ COMPOSITE_OVER
Definition composite.h:23
unsigned int guint32
struct _cairo_surface cairo_surface_t
Helper class to stream background task notifications as a series of messages.
signed int gint32
struct _cairo cairo_t
Definition path-cairo.h:16