1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #ifndef SEEN_SP_GRADIENT_H
3 #define SEEN_SP_GRADIENT_H
4 /*
5  * Authors:
6  *   Lauris Kaplinski <lauris@kaplinski.com>
7  *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
8  *   Jon A. Cruz <jon@joncruz.org>
9  *
10  * Copyrigt  (C) 2010 Jon A. Cruz
11  * Copyright (C) 2007 Johan Engelen
12  * Copyright (C) 1999-2002 Lauris Kaplinski
13  * Copyright (C) 2000-2001 Ximian, Inc.
14  *
15  * Released under GNU GPL v2+, read the file 'COPYING' for more information.
16  */
17 
18 #include <2geom/affine.h>
19 #include <cstddef>
20 #include <glibmm/ustring.h>
21 #include <sigc++/connection.h>
22 #include <vector>
23 
24 #include "sp-paint-server.h"
25 #include "sp-gradient-spread.h"
26 #include "sp-gradient-units.h"
27 #include "sp-gradient-vector.h"
28 #include "sp-mesh-array.h"
29 
30 class SPGradientReference;
31 class SPStop;
32 
33 #define SP_GRADIENT(obj) (dynamic_cast<SPGradient*>((SPObject*)obj))
34 #define SP_IS_GRADIENT(obj) (dynamic_cast<const SPGradient*>((SPObject*)obj) != NULL)
35 
36 enum SPGradientType {
37     SP_GRADIENT_TYPE_UNKNOWN,
38     SP_GRADIENT_TYPE_LINEAR,
39     SP_GRADIENT_TYPE_RADIAL,
40     SP_GRADIENT_TYPE_MESH
41 };
42 
43 enum SPGradientState {
44     SP_GRADIENT_STATE_UNKNOWN,
45     SP_GRADIENT_STATE_VECTOR,
46     SP_GRADIENT_STATE_PRIVATE
47 };
48 
49 enum GrPointType {
50     POINT_LG_BEGIN = 0, //start enum at 0 (for indexing into gr_knot_shapes array for example)
51     POINT_LG_END,
52     POINT_LG_MID,
53     POINT_RG_CENTER,
54     POINT_RG_R1,
55     POINT_RG_R2,
56     POINT_RG_FOCUS,
57     POINT_RG_MID1,
58     POINT_RG_MID2,
59     POINT_MG_CORNER,
60     POINT_MG_HANDLE,
61     POINT_MG_TENSOR,
62     // insert new point types here.
63 
64     POINT_G_INVALID
65 };
66 
67 namespace Inkscape {
68 
69 enum PaintTarget {
70     FOR_FILL,
71     FOR_STROKE
72 };
73 
74 /**
75  * Convenience function to access a common vector of all enum values.
76  */
77 std::vector<PaintTarget> const &allPaintTargets();
78 
79 } // namespace Inkscape
80 
81 /**
82  * Gradient
83  *
84  * Implement spread, stops list
85  * \todo fixme: Implement more here (Lauris)
86  */
87 class SPGradient : public SPPaintServer {
88 public:
89 	SPGradient();
90 	~SPGradient() override;
91 
92 private:
93     /** gradientUnits attribute */
94     SPGradientUnits units;
95     unsigned int units_set : 1;
96 public:
97 
98     /** gradientTransform attribute */
99     Geom::Affine gradientTransform;
100     unsigned int gradientTransform_set : 1;
101 
102 private:
103     /** spreadMethod attribute */
104     SPGradientSpread spread;
105     unsigned int spread_set : 1;
106 
107     /** Gradient stops */
108     unsigned int has_stops : 1;
109 
110     /** Gradient patches */
111     unsigned int has_patches : 1;
112 
113 public:
114     /** Reference (href) */
115     SPGradientReference *ref;
116 
117     /** State in Inkscape gradient system */
118     unsigned int state;
119 
120     /** Linear and Radial Gradients */
121 
122     /** Composed vector */
123     SPGradientVector vector;
124 
125     sigc::connection modified_connection;
126 
127     bool hasStops() const;
128 
129     SPStop* getFirstStop();
130     int getStopCount() const;
131 
132     bool isEquivalent(SPGradient *b);
133     bool isAligned(SPGradient *b);
134 
135     /** Mesh Gradients **************/
136 
137     /** Composed array (for mesh gradients) */
138     SPMeshNodeArray array;
139     SPMeshNodeArray array_smoothed; // Smoothed version of array
140 
141     bool hasPatches() const;
142 
143 
144     /** All Gradients **************/
145     bool isUnitsSet() const;
146     SPGradientUnits getUnits() const;
147     void setUnits(SPGradientUnits units);
148 
149 
150     bool isSpreadSet() const;
151     SPGradientSpread getSpread() const;
152 
153 /**
154  * Returns private vector of given gradient (the gradient at the end of the href chain which has
155  * stops), optionally normalizing it.
156  *
157  * \pre SP_IS_GRADIENT(gradient).
158  * \pre There exists a gradient in the chain that has stops.
159  */
160     SPGradient *getVector(bool force_private = false);
161 
162  /**
163  * Returns private mesh of given gradient (the gradient at the end of the href chain which has
164  * patches), optionally normalizing it.
165  */
166     SPGradient *getArray(bool force_private = false);
167 
168     //static GType getType();
169 
170     /** Forces vector to be built, if not present (i.e. changed) */
171     void ensureVector();
172 
173     /** Forces array (mesh) to be built, if not present (i.e. changed) */
174     void ensureArray();
175 
176     /**
177      * Set spread property of gradient and emit modified.
178      */
179     void setSpread(SPGradientSpread spread);
180 
181     SPGradientSpread fetchSpread();
182     SPGradientUnits fetchUnits();
183 
184     void setSwatch(bool swatch = true);
185 
186     static void gradientRefModified(SPObject *href, unsigned int flags, SPGradient *gradient);
187     static void gradientRefChanged(SPObject *old_ref, SPObject *ref, SPGradient *gr);
188 
189     /* Gradient repr methods */
190     void repr_write_vector();
191     void repr_clear_vector();
192 
193     cairo_pattern_t *create_preview_pattern(double width);
194 
195     /** Transforms to/from gradient position space in given environment */
196     Geom::Affine get_g2d_matrix(Geom::Affine const &ctm,
197                                 Geom::Rect const &bbox) const;
198     Geom::Affine get_gs2d_matrix(Geom::Affine const &ctm,
199                                  Geom::Rect const &bbox) const;
200     void set_gs2d_matrix(Geom::Affine const &ctm, Geom::Rect const &bbox,
201                          Geom::Affine const &gs2d);
202 
203 private:
204     bool invalidateVector();
205     bool invalidateArray();
206     void rebuildVector();
207     void rebuildArray();
208 
209 protected:
210     void build(SPDocument *document, Inkscape::XML::Node *repr) override;
211     void release() override;
212     void modified(unsigned int flags) override;
213     Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override;
214 
215     void child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) override;
216     void remove_child(Inkscape::XML::Node *child) override;
217 
218     void set(SPAttr key, char const *value) override;
219 };
220 
221 void
222 sp_gradient_pattern_common_setup(cairo_pattern_t *cp,
223                                  SPGradient *gr,
224                                  Geom::OptRect const &bbox,
225                                  double opacity);
226 
227 
228 #endif // SEEN_SP_GRADIENT_H
229 
230 /*
231   Local Variables:
232   mode:c++
233   c-file-style:"stroustrup"
234   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
235   indent-tabs-mode:nil
236   fill-column:99
237   End:
238 */
239 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
240