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