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