1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /** \file
3 * SVG <feComponentTransfer> implementation.
4 *
5 */
6 /*
7 * Authors:
8 * hugo Rodrigues <haa.rodrigues@gmail.com>
9 * Abhishek Sharma
10 *
11 * Copyright (C) 2006 Hugo Rodrigues
12 *
13 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
14 */
15
16 #include "attributes.h"
17 #include "document.h"
18
19 // In same directory
20 #include "componenttransfer.h"
21 #include "componenttransfer-funcnode.h"
22
23 #include "display/nr-filter.h"
24
25 #include "xml/repr.h"
26
SPFeComponentTransfer()27 SPFeComponentTransfer::SPFeComponentTransfer()
28 : SPFilterPrimitive(), renderer(nullptr)
29 {
30 }
31
32 SPFeComponentTransfer::~SPFeComponentTransfer() = default;
33
34 /**
35 * Reads the Inkscape::XML::Node, and initializes SPFeComponentTransfer variables. For this to get called,
36 * our name must be associated with a repr via "sp_object_type_register". Best done through
37 * sp-object-repr.cpp's repr_name_entries array.
38 */
build(SPDocument * document,Inkscape::XML::Node * repr)39 void SPFeComponentTransfer::build(SPDocument *document, Inkscape::XML::Node *repr) {
40 SPFilterPrimitive::build(document, repr);
41
42 /*LOAD ATTRIBUTES FROM REPR HERE*/
43
44 //do we need this?
45 //document->addResource("feComponentTransfer", object);
46 }
47
sp_feComponentTransfer_children_modified(SPFeComponentTransfer * sp_componenttransfer)48 static void sp_feComponentTransfer_children_modified(SPFeComponentTransfer *sp_componenttransfer)
49 {
50 if (sp_componenttransfer->renderer) {
51 bool set[4] = {false, false, false, false};
52 for(auto& node: sp_componenttransfer->children) {
53 int i = 4;
54
55 SPFeFuncNode *funcNode = SP_FEFUNCNODE(&node);
56 if(!funcNode) {
57 continue;
58 }
59
60 switch (funcNode->channel) {
61 case SPFeFuncNode::R:
62 i = 0;
63 break;
64 case SPFeFuncNode::G:
65 i = 1;
66 break;
67 case SPFeFuncNode::B:
68 i = 2;
69 break;
70 case SPFeFuncNode::A:
71 i = 3;
72 break;
73 }
74
75 if (i == 4) {
76 g_warning("Unrecognized channel for component transfer.");
77 break;
78 }
79 sp_componenttransfer->renderer->type[i] = ((SPFeFuncNode *) &node)->type;
80 sp_componenttransfer->renderer->tableValues[i] = ((SPFeFuncNode *) &node)->tableValues;
81 sp_componenttransfer->renderer->slope[i] = ((SPFeFuncNode *) &node)->slope;
82 sp_componenttransfer->renderer->intercept[i] = ((SPFeFuncNode *) &node)->intercept;
83 sp_componenttransfer->renderer->amplitude[i] = ((SPFeFuncNode *) &node)->amplitude;
84 sp_componenttransfer->renderer->exponent[i] = ((SPFeFuncNode *) &node)->exponent;
85 sp_componenttransfer->renderer->offset[i] = ((SPFeFuncNode *) &node)->offset;
86 set[i] = true;
87 }
88 // Set any types not explicitly set to the identity transform
89 for(int i=0;i<4;i++) {
90 if (!set[i]) {
91 sp_componenttransfer->renderer->type[i] = Inkscape::Filters::COMPONENTTRANSFER_TYPE_IDENTITY;
92 }
93 }
94 }
95 }
96
97 /**
98 * Callback for child_added event.
99 */
child_added(Inkscape::XML::Node * child,Inkscape::XML::Node * ref)100 void SPFeComponentTransfer::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) {
101 SPFilterPrimitive::child_added(child, ref);
102
103 sp_feComponentTransfer_children_modified(this);
104 this->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
105 }
106
107 /**
108 * Callback for remove_child event.
109 */
remove_child(Inkscape::XML::Node * child)110 void SPFeComponentTransfer::remove_child(Inkscape::XML::Node *child) {
111 SPFilterPrimitive::remove_child(child);
112
113 sp_feComponentTransfer_children_modified(this);
114 this->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
115 }
116
117 /**
118 * Drops any allocated memory.
119 */
release()120 void SPFeComponentTransfer::release() {
121 SPFilterPrimitive::release();
122 }
123
124 /**
125 * Sets a specific value in the SPFeComponentTransfer.
126 */
set(SPAttr key,gchar const * value)127 void SPFeComponentTransfer::set(SPAttr key, gchar const *value) {
128 switch(key) {
129 /*DEAL WITH SETTING ATTRIBUTES HERE*/
130 default:
131 SPFilterPrimitive::set(key, value);
132 break;
133 }
134 }
135
136 /**
137 * Receives update notifications.
138 */
update(SPCtx * ctx,guint flags)139 void SPFeComponentTransfer::update(SPCtx *ctx, guint flags) {
140 if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
141 SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
142
143 /* do something to trigger redisplay, updates? */
144
145 }
146
147 SPFilterPrimitive::update(ctx, flags);
148 }
149
150 /**
151 * Writes its settings to an incoming repr object, if any.
152 */
write(Inkscape::XML::Document * doc,Inkscape::XML::Node * repr,guint flags)153 Inkscape::XML::Node* SPFeComponentTransfer::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) {
154 /* TODO: Don't just clone, but create a new repr node and write all
155 * relevant values into it */
156 if (!repr) {
157 repr = this->getRepr()->duplicate(doc);
158 }
159
160 SPFilterPrimitive::write(doc, repr, flags);
161
162 return repr;
163 }
164
build_renderer(Inkscape::Filters::Filter * filter)165 void SPFeComponentTransfer::build_renderer(Inkscape::Filters::Filter* filter) {
166 g_assert(filter != nullptr);
167
168 int primitive_n = filter->add_primitive(Inkscape::Filters::NR_FILTER_COMPONENTTRANSFER);
169 Inkscape::Filters::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
170 Inkscape::Filters::FilterComponentTransfer *nr_componenttransfer = dynamic_cast<Inkscape::Filters::FilterComponentTransfer*>(nr_primitive);
171 g_assert(nr_componenttransfer != nullptr);
172
173 this->renderer = nr_componenttransfer;
174 this->renderer_common(nr_primitive);
175
176
177 sp_feComponentTransfer_children_modified(this); //do we need it?!
178 }
179
180 /*
181 Local Variables:
182 mode:c++
183 c-file-style:"stroustrup"
184 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
185 indent-tabs-mode:nil
186 fill-column:99
187 End:
188 */
189 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
190