1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /** \file
3  * SVG <feFlood> 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 "flood.h"
17 
18 #include "strneq.h"
19 #include "attributes.h"
20 
21 #include "svg/svg.h"
22 #include "svg/svg-color.h"
23 
24 #include "display/nr-filter.h"
25 #include "display/nr-filter-flood.h"
26 
27 #include "xml/repr.h"
28 
SPFeFlood()29 SPFeFlood::SPFeFlood() : SPFilterPrimitive() {
30 	this->color = 0;
31 
32     this->opacity = 1;
33     this->icc = nullptr;
34 }
35 
36 SPFeFlood::~SPFeFlood() = default;
37 
38 /**
39  * Reads the Inkscape::XML::Node, and initializes SPFeFlood variables.  For this to get called,
40  * our name must be associated with a repr via "sp_object_type_register".  Best done through
41  * sp-object-repr.cpp's repr_name_entries array.
42  */
build(SPDocument * document,Inkscape::XML::Node * repr)43 void SPFeFlood::build(SPDocument *document, Inkscape::XML::Node *repr) {
44 	SPFilterPrimitive::build(document, repr);
45 
46 	/*LOAD ATTRIBUTES FROM REPR HERE*/
47 	this->readAttr(SPAttr::FLOOD_OPACITY);
48 	this->readAttr(SPAttr::FLOOD_COLOR);
49 }
50 
51 /**
52  * Drops any allocated memory.
53  */
release()54 void SPFeFlood::release() {
55 	SPFilterPrimitive::release();
56 }
57 
58 /**
59  * Sets a specific value in the SPFeFlood.
60  */
set(SPAttr key,gchar const * value)61 void SPFeFlood::set(SPAttr key, gchar const *value) {
62     gchar const *cend_ptr = nullptr;
63     gchar *end_ptr = nullptr;
64     guint32 read_color;
65     double read_num;
66     bool dirty = false;
67 
68     switch(key) {
69 	/*DEAL WITH SETTING ATTRIBUTES HERE*/
70         case SPAttr::FLOOD_COLOR:
71             cend_ptr = nullptr;
72             read_color = sp_svg_read_color(value, &cend_ptr, 0xffffffff);
73 
74             if (cend_ptr && read_color != this->color){
75                 this->color = read_color;
76                 dirty=true;
77             }
78 
79             if (cend_ptr){
80                 while (g_ascii_isspace(*cend_ptr)) {
81                     ++cend_ptr;
82                 }
83 
84                 if (strneq(cend_ptr, "icc-color(", 10)) {
85                     if (!this->icc) {
86                     	this->icc = new SVGICCColor();
87                     }
88 
89                     if ( ! sp_svg_read_icc_color( cend_ptr, this->icc ) ) {
90                         delete this->icc;
91                         this->icc = nullptr;
92                     }
93 
94                     dirty = true;
95                 }
96             }
97 
98             if (dirty) {
99                 this->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
100             }
101             break;
102         case SPAttr::FLOOD_OPACITY:
103             if (value) {
104                 read_num = g_ascii_strtod(value, &end_ptr);
105 
106                 if (end_ptr != nullptr) {
107                     if (*end_ptr) {
108                         g_warning("Unable to convert \"%s\" to number", value);
109                         read_num = 1;
110                     }
111                 }
112             } else {
113                 read_num = 1;
114             }
115 
116             if (read_num != this->opacity) {
117                 this->opacity = read_num;
118                 this->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
119             }
120             break;
121         default:
122         	SPFilterPrimitive::set(key, value);
123             break;
124     }
125 }
126 
127 /**
128  * Receives update notifications.
129  */
update(SPCtx * ctx,guint flags)130 void SPFeFlood::update(SPCtx *ctx, guint flags) {
131     if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG |
132                  SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
133 
134         /* do something to trigger redisplay, updates? */
135 
136     }
137 
138     SPFilterPrimitive::update(ctx, flags);
139 }
140 
141 /**
142  * Writes its settings to an incoming repr object, if any.
143  */
write(Inkscape::XML::Document * doc,Inkscape::XML::Node * repr,guint flags)144 Inkscape::XML::Node* SPFeFlood::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) {
145     /* TODO: Don't just clone, but create a new repr node and write all
146      * relevant values into it */
147     if (!repr) {
148         repr = this->getRepr()->duplicate(doc);
149     }
150 
151     SPFilterPrimitive::write(doc, repr, flags);
152 
153     return repr;
154 }
155 
build_renderer(Inkscape::Filters::Filter * filter)156 void SPFeFlood::build_renderer(Inkscape::Filters::Filter* filter) {
157     g_assert(filter != nullptr);
158 
159     int primitive_n = filter->add_primitive(Inkscape::Filters::NR_FILTER_FLOOD);
160     Inkscape::Filters::FilterPrimitive *nr_primitive = filter->get_primitive(primitive_n);
161     Inkscape::Filters::FilterFlood *nr_flood = dynamic_cast<Inkscape::Filters::FilterFlood*>(nr_primitive);
162     g_assert(nr_flood != nullptr);
163 
164     this->renderer_common(nr_primitive);
165 
166     nr_flood->set_opacity(this->opacity);
167     nr_flood->set_color(this->color);
168     nr_flood->set_icc(this->icc);
169 }
170 
171 /*
172   Local Variables:
173   mode:c++
174   c-file-style:"stroustrup"
175   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
176   indent-tabs-mode:nil
177   fill-column:99
178   End:
179 */
180 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
181