Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
sp-flowregion.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Authors: see git history
6 *
7 * Copyright (C) 2018 Authors
8 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
9 */
10/*
11 */
12
13#include "sp-flowregion.h"
14
15#include <glibmm/i18n.h>
16
17#include "sp-desc.h"
18#include "sp-shape.h"
19#include "sp-text.h"
20#include "sp-title.h"
21#include "sp-use.h"
22#include "style.h"
23
24#include "display/curve.h"
25#include "livarot/Path.h"
26#include "livarot/Shape.h"
27#include "xml/document.h"
28
29class SPDesc;
30class SPTitle;
31
32static std::unique_ptr<Shape> shape_union(std::unique_ptr<Shape> base_shape, std::unique_ptr<Shape> add_shape);
33static std::unique_ptr<Shape> extract_shape(SPItem *item);
34
41
42/* fixme: hide (Lauris) */
43
46
47 this->requestModified(SP_OBJECT_MODIFIED_FLAG);
48}
49
50
51void SPFlowregion::update(SPCtx *ctx, unsigned int flags) {
52 SPItemCtx *ictx = reinterpret_cast<SPItemCtx *>(ctx);
53 SPItemCtx cctx = *ictx;
54
55 unsigned childflags = flags;
56 if (flags & SP_OBJECT_MODIFIED_FLAG) {
57 childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
58 }
59 childflags &= SP_OBJECT_MODIFIED_CASCADE;
60
61 std::vector<SPObject*>l;
62
63 for (auto& child: children) {
65 l.push_back(&child);
66 }
67
68 for (auto child:l) {
69 g_assert(child != nullptr);
70 auto item = cast<SPItem>(child);
71
72 if (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
73 if (item) {
74 SPItem const &chi = *item;
75 cctx.i2doc = chi.transform * ictx->i2doc;
76 cctx.i2vp = chi.transform * ictx->i2vp;
77 child->updateDisplay((SPCtx *)&cctx, childflags);
78 } else {
79 child->updateDisplay(ctx, childflags);
80 }
81 }
82
84 }
85
86 SPItem::update(ctx, flags);
87
89}
90
92{
93 computed.clear();
94 for (auto &child : children) {
95 if (auto item = cast<SPItem>(&child)) {
96 computed.push_back(extract_shape(item));
97 }
98 }
99}
100
101void SPFlowregion::modified(guint flags) {
102 if (flags & SP_OBJECT_MODIFIED_FLAG) {
103 flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
104 }
105
106 flags &= SP_OBJECT_MODIFIED_CASCADE;
107
108 std::vector<SPObject *>l;
109
110 for (auto& child: children) {
112 l.push_back(&child);
113 }
114
115 for (auto child:l) {
116 g_assert(child != nullptr);
117
118 if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
119 child->emitModified(flags);
120 }
121
123 }
124}
125
127 if (flags & SP_OBJECT_WRITE_BUILD) {
128 if ( repr == nullptr ) {
129 repr = xml_doc->createElement("svg:flowRegion");
130 }
131
132 std::vector<Inkscape::XML::Node *> l;
133 for (auto& child: children) {
134 if (!is<SPTitle>(&child) && !is<SPDesc>(&child)) {
135 Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, nullptr, flags);
136
137 if (crepr) {
138 l.push_back(crepr);
139 }
140 }
141 }
142
143 for (auto i = l.rbegin(); i != l.rend(); ++i) {
144 repr->addChild(*i, nullptr);
146 }
147
148 for (auto& child: children) {
149 if (!is<SPTitle>(&child) && !is<SPDesc>(&child)) {
150 child.updateRepr(flags);
151 }
152 }
153 }
154
155 SPItem::write(xml_doc, repr, flags);
156
157 updateComputed(); // copied from update(), see LP Bug 1339305
158
159 return repr;
160}
161
162const char* SPFlowregion::typeName() const {
163 return "text-flow";
164}
165
166const char* SPFlowregion::displayName() const {
167 // TRANSLATORS: "Flow region" is an area where text is allowed to flow
168 return _("Flow Region");
169}
170
176
177/* fixme: hide (Lauris) */
178
184
185
186void SPFlowregionExclude::update(SPCtx *ctx, unsigned int flags) {
187 SPItemCtx *ictx = reinterpret_cast<SPItemCtx *>(ctx);
188 SPItemCtx cctx = *ictx;
189
190 SPItem::update(ctx, flags);
191
192 if (flags & SP_OBJECT_MODIFIED_FLAG) {
193 flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
194 }
195
196 flags &= SP_OBJECT_MODIFIED_CASCADE;
197
198 std::vector<SPObject *> l;
199
200 for (auto& child: children) {
202 l.push_back(&child);
203 }
204
205 for(auto child:l) {
206 g_assert(child != nullptr);
207
208 if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
209 auto item = cast<SPItem>(child);
210 if (item) {
211 SPItem const &chi = *item;
212 cctx.i2doc = chi.transform * ictx->i2doc;
213 cctx.i2vp = chi.transform * ictx->i2vp;
214 child->updateDisplay((SPCtx *)&cctx, flags);
215 } else {
216 child->updateDisplay(ctx, flags);
217 }
218 }
219
221 }
222
224}
225
227{
228 _computed.reset();
229 for (auto &child : children) {
230 if (auto *item = cast<SPItem>(&child)) {
232 }
233 }
234}
235
237 if (flags & SP_OBJECT_MODIFIED_FLAG) {
238 flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
239 }
240
241 flags &= SP_OBJECT_MODIFIED_CASCADE;
242
243 std::vector<SPObject*> l;
244
245 for (auto& child: children) {
247 l.push_back(&child);
248 }
249
250 for (auto child:l) {
251 g_assert(child != nullptr);
252
253 if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
254 child->emitModified(flags);
255 }
256
258 }
259}
260
262 if (flags & SP_OBJECT_WRITE_BUILD) {
263 if ( repr == nullptr ) {
264 repr = xml_doc->createElement("svg:flowRegionExclude");
265 }
266
267 std::vector<Inkscape::XML::Node *> l;
268
269 for (auto& child: children) {
270 Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, nullptr, flags);
271
272 if (crepr) {
273 l.push_back(crepr);
274 }
275 }
276
277 for (auto i = l.rbegin(); i != l.rend(); ++i) {
278 repr->addChild(*i, nullptr);
280 }
281
282 } else {
283 for (auto& child: children) {
284 child.updateRepr(flags);
285 }
286 }
287
288 SPItem::write(xml_doc, repr, flags);
289
290 return repr;
291}
292
293const char* SPFlowregionExclude::typeName() const {
294 return "text-flow";
295}
296
298 /* TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the
299 * flow excluded region. flowRegionExclude in SVG 1.2: see
300 * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and
301 * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. */
302 return _("Flow Excluded Region");
303}
304
305static std::unique_ptr<Shape> shape_union(std::unique_ptr<Shape> base_shape, std::unique_ptr<Shape> add_shape)
306{
307 if (!base_shape) {
308 base_shape = std::make_unique<Shape>();
309 }
310 if (!base_shape->hasEdges()) {
311 base_shape->Copy(add_shape.get());
312 } else if (add_shape && add_shape->hasEdges()) {
313 auto temp = std::make_unique<Shape>();
314 temp->Booleen(add_shape.get(), base_shape.get(), bool_op_union);
315 base_shape = std::move(temp);
316 }
317 return base_shape;
318}
319
320static std::unique_ptr<Shape> extract_shape(SPItem *item)
321{
322 Geom::Affine tr_mat;
323 auto *shape_source = item;
324 if (auto use = cast<SPUse>(item)) {
325 shape_source = use->child;
326 tr_mat = use->getRelativeTransform(item->parent);
327 } else {
328 tr_mat = item->transform;
329 }
330
331 std::optional<Geom::PathVector> curve;
332 if (auto shape = cast<SPShape>(shape_source)) {
333 if (!shape->curve()) {
334 shape->set_shape();
335 }
336 curve = ptr_to_opt(shape->curve());
337 } else if (auto text = cast<SPText>(shape_source)) {
338 curve = text->getNormalizedBpath();
339 }
340
341 if (!curve) {
342 return {};
343 }
344 Path temp;
345 temp.LoadPathVector(*curve, tr_mat, true);
346 temp.Convert(0.25);
347
348 Shape n_shp;
349 temp.Fill(&n_shp, 0);
350
351 auto result = std::make_unique<Shape>();
352 SPStyle *style = shape_source->style;
353 result->ConvertToShape(&n_shp,
355 return result;
356}
357
358/*
359 Local Variables:
360 mode:c++
361 c-file-style:"stroustrup"
362 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
363 indent-tabs-mode:nil
364 fill-column:99
365 End:
366*/
367// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
@ fill_oddEven
Definition LivarotDefs.h:69
@ fill_nonZero
Definition LivarotDefs.h:70
@ bool_op_union
Definition LivarotDefs.h:78
TODO: insert short description here.
TODO: insert short description here.
3x3 matrix representing an affine transformation.
Definition affine.h:70
Interface for refcounted XML nodes.
Definition node.h:80
virtual void addChild(Node *child, Node *after)=0
Insert another node as a child of this node.
Path and its polyline approximation.
Definition Path.h:93
void Fill(Shape *dest, int pathID=-1, bool justAdd=false, bool closeIfNeeded=true, bool invert=false)
Fills the shape with the polyline approximation stored in this object.
void LoadPathVector(Geom::PathVector const &pv, Geom::Affine const &tr, bool doTransformation)
Load a lib2geom Geom::PathVector in this path object.
void Convert(double treshhold)
Creates a polyline approximation of the path.
std::unique_ptr< Shape > _computed
const char * typeName() const override
The item's type name, not node tag name.
const char * displayName() const override
The item's type name as a translated human string.
void remove_child(Inkscape::XML::Node *child) override
void child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) override
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
void update(SPCtx *ctx, unsigned int flags) override
void modified(guint flags) override
void modified(guint flags) override
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
std::vector< std::unique_ptr< Shape > > computed
void updateComputed()
const char * typeName() const override
The item's type name, not node tag name.
const char * displayName() const override
The item's type name as a translated human string.
void remove_child(Inkscape::XML::Node *child) override
void child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) override
void update(SPCtx *ctx, unsigned int flags) override
Base class for visual SVG elements.
Definition sp-item.h:109
void update(SPCtx *ctx, unsigned int flags) override
Definition sp-item.cpp:779
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
Definition sp-item.cpp:850
Geom::Affine transform
Definition sp-item.h:138
Inkscape::XML::Node * repr
Definition sp-object.h:193
void requestModified(unsigned int flags)
Requests that a modification notification signal be emitted later (e.g.
virtual void remove_child(Inkscape::XML::Node *child)
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
Definition sp-object.h:248
SPObject * parent
Definition sp-object.h:189
virtual void child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
ChildrenList children
Definition sp-object.h:907
An SVG style object.
Definition style.h:45
T< SPAttr::FILL_RULE, SPIEnum< SPWindRule > > fill_rule
fill-rule: 0 nonzero, 1 evenodd
Definition style.h:244
A class to store/manipulate directed graphs.
Definition Shape.h:65
Css & result
auto ptr_to_opt(T const &p)
Create a std::optional<T> from a (generalised) pointer to T.
Definition curve.h:90
SPItem * item
static R & release(R &r)
Decrements the reference count of a anchored object.
Ocnode * child[8]
Definition quantize.cpp:33
Ocnode ** ref
Definition quantize.cpp:32
static std::unique_ptr< Shape > shape_union(std::unique_ptr< Shape > base_shape, std::unique_ptr< Shape > add_shape)
static std::unique_ptr< Shape > extract_shape(SPItem *item)
TODO: insert short description here.
SPObject * sp_object_unref(SPObject *object, SPObject *owner)
Decrease reference count of object, with possible debugging and finalization.
SPObject * sp_object_ref(SPObject *object, SPObject *owner)
Increase reference count of object, with possible debugging.
Interface for XML documents.
Definition document.h:43
virtual Node * createElement(char const *name)=0
Unused.
Definition sp-object.h:94
Contains transformations to document/viewport and the viewport size.
Definition sp-item.h:92
Geom::Affine i2doc
Item to document transformation.
Definition sp-item.h:94
Geom::Affine i2vp
Item to viewport transformation.
Definition sp-item.h:100
Definition curve.h:24
@ SP_WIND_RULE_EVENODD
Definition style-enums.h:26
SPStyle - a style object for SPItem objects.
Interface for XML documents.