1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /**
3  * @file
4  * SVG <hatch> implementation
5  */
6 /*
7  * Authors:
8  *   Tomasz Boczkowski <penginsbacon@gmail.com>
9  *   Jon A. Cruz <jon@joncruz.org>
10  *
11  * Copyright (C) 2014 Tomasz Boczkowski
12  *
13  * Released under GNU GPL v2+, read the file 'COPYING' for more information.
14  */
15 
16 #ifndef SEEN_SP_HATCH_H
17 #define SEEN_SP_HATCH_H
18 
19 #include <list>
20 #include <cstddef>
21 #include <glibmm/ustring.h>
22 #include <sigc++/connection.h>
23 
24 #include "svg/svg-length.h"
25 #include "svg/svg-angle.h"
26 #include "sp-paint-server.h"
27 #include "uri-references.h"
28 
29 class SPHatchReference;
30 class SPHatchPath;
31 class SPItem;
32 
33 namespace Inkscape {
34 
35 class Drawing;
36 class DrawingPattern;
37 
38 namespace XML {
39 
40 class Node;
41 
42 }
43 }
44 
45 #define SP_HATCH(obj) (dynamic_cast<SPHatch *>((SPObject *)obj))
46 #define SP_IS_HATCH(obj) (dynamic_cast<const SPHatch *>((SPObject *)obj) != NULL)
47 
48 class SPHatch : public SPPaintServer {
49 public:
50     enum HatchUnits {
51         UNITS_USERSPACEONUSE,
52         UNITS_OBJECTBOUNDINGBOX
53     };
54 
55     class RenderInfo {
56     public:
57         RenderInfo();
58         ~RenderInfo();
59 
60         Geom::Affine child_transform;
61         Geom::Affine pattern_to_user_transform;
62         Geom::Rect tile_rect;
63 
64         int overflow_steps;
65         Geom::Affine overflow_step_transform;
66         Geom::Affine overflow_initial_transform;
67     };
68 
69     SPHatch();
70     ~SPHatch() override;
71 
72     // Reference (href)
73     Glib::ustring href;
74     SPHatchReference *ref;
75 
76     gdouble x() const;
77     gdouble y() const;
78     gdouble pitch() const;
79     gdouble rotate() const;
80     HatchUnits hatchUnits() const;
81     HatchUnits hatchContentUnits() const;
82     Geom::Affine const &hatchTransform() const;
83     SPHatch *rootHatch(); //TODO: const
84 
85     std::vector<SPHatchPath *> hatchPaths();
86     std::vector<SPHatchPath const *> hatchPaths() const;
87 
88     SPHatch *clone_if_necessary(SPItem *item, const gchar *property);
89     void transform_multiply(Geom::Affine postmul, bool set);
90 
91     bool isValid() const override;
92 
93     Inkscape::DrawingPattern *show(Inkscape::Drawing &drawing, unsigned int key, Geom::OptRect bbox) override;
94     void hide(unsigned int key) override;
95     cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity) override;
96 
97     RenderInfo calculateRenderInfo(unsigned key) const;
98     Geom::Interval bounds() const;
99     void setBBox(unsigned int key, Geom::OptRect const &bbox) override;
100 
101 protected:
102     void build(SPDocument* doc, Inkscape::XML::Node* repr) override;
103     void release() override;
104     void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) override;
105     void set(SPAttr key, const gchar* value) override;
106     void update(SPCtx* ctx, unsigned int flags) override;
107     void modified(unsigned int flags) override;
108 
109 private:
110     class View {
111     public:
112         View(Inkscape::DrawingPattern *arenaitem, int key);
113         //Do not delete arenaitem in destructor.
114 
115         ~View();
116 
117         Inkscape::DrawingPattern *arenaitem;
118         Geom::OptRect bbox;
119         unsigned int key;
120     };
121 
122     typedef std::vector<SPHatchPath *>::iterator ChildIterator;
123     typedef std::vector<SPHatchPath const *>::const_iterator ConstChildIterator;
124     typedef std::list<View>::iterator ViewIterator;
125     typedef std::list<View>::const_iterator ConstViewIterator;
126 
127     static bool _hasHatchPatchChildren(SPHatch const* hatch);
128 
129     void _updateView(View &view);
130     RenderInfo _calculateRenderInfo(View const &view) const;
131     Geom::OptInterval _calculateStripExtents(Geom::OptRect const &bbox) const;
132 
133     /**
134     Count how many times hatch is used by the styles of o and its descendants
135     */
136     guint _countHrefs(SPObject *o) const;
137 
138     /**
139      * Gets called when the hatch is reattached to another <hatch>
140      */
141     void _onRefChanged(SPObject *old_ref, SPObject *ref);
142 
143     /**
144      * Gets called when the referenced <hatch> is changed
145      */
146     void _onRefModified(SPObject *ref, guint flags);
147 
148     // patternUnits and patternContentUnits attribute
149     HatchUnits _hatchUnits : 1;
150     bool _hatchUnits_set : 1;
151     HatchUnits _hatchContentUnits : 1;
152     bool _hatchContentUnits_set : 1;
153 
154     // hatchTransform attribute
155     Geom::Affine _hatchTransform;
156     bool _hatchTransform_set : 1;
157 
158     // Strip
159     SVGLength _x;
160     SVGLength _y;
161     SVGLength _pitch;
162     SVGAngle _rotate;
163 
164     sigc::connection _modified_connection;
165 
166     std::list<View> _display;
167 };
168 
169 
170 class SPHatchReference : public Inkscape::URIReference {
171 public:
SPHatchReference(SPObject * obj)172     SPHatchReference (SPObject *obj)
173         : URIReference(obj)
174     {}
175 
getObject()176     SPHatch *getObject() const {
177         return reinterpret_cast<SPHatch *>(URIReference::getObject());
178     }
179 
180 protected:
_acceptObject(SPObject * obj)181     bool _acceptObject(SPObject *obj) const override {
182         return dynamic_cast<SPHatch *>(obj) != nullptr && URIReference::_acceptObject(obj);
183     }
184 };
185 
186 #endif // SEEN_SP_HATCH_H
187 
188 /*
189   Local Variables:
190   mode:c++
191   c-file-style:"stroustrup"
192   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
193   indent-tabs-mode:nil
194   fill-column:99
195   End:
196 */
197 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
198