Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
sp-marker.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * SVG <marker> implementation
4 *
5 * Authors:
6 * Lauris Kaplinski <lauris@kaplinski.com>
7 * Bryce Harrington <bryce@bryceharrington.org>
8 * Abhishek Sharma
9 * Jon A. Cruz <jon@joncruz.org>
10 *
11 * Copyright (C) 1999-2003 Lauris Kaplinski
12 * 2004-2006 Bryce Harrington
13 * 2008 Johan Engelen
14 *
15 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
16 */
17
18#include "sp-marker.h"
19
20#include <cstring>
21
22#include <glib/gi18n.h>
23
24#include <2geom/affine.h>
25#include <2geom/transforms.h>
26
27#include "attributes.h"
28#include "document-undo.h"
29#include "document.h"
30#include "preferences.h"
31#include "sp-defs.h"
32
35#include "object/object-set.h"
37#include "svg/svg.h"
38#include "ui/icon-names.h"
39#include "xml/document.h" // for Document
40
43
44struct SPMarkerView
45{
46 std::vector<DrawingItemPtr<Inkscape::DrawingItem>> items;
47};
48
50 markerUnits_set(0),
51 markerUnits(0),
52 refX(),
53 refY(),
54 markerWidth(),
55 markerHeight(),
56 orient_set(0),
57 orient_mode(MARKER_ORIENT_ANGLE)
58{
59 // cppcheck-suppress useInitializationList
60 orient = 0;
61}
62
68SPMarker::~SPMarker() = default;
69
93
94
108
109 for (auto &it : views_map) {
110 SPGroup::hide(it.first);
111 }
112 views_map.clear();
113
115}
116
117void SPMarker::set(SPAttr key, const gchar* value) {
118 switch (key) {
120 this->markerUnits_set = FALSE;
122
123 if (value) {
124 if (!strcmp (value, "strokeWidth")) {
125 this->markerUnits_set = TRUE;
126 } else if (!strcmp (value, "userSpaceOnUse")) {
128 this->markerUnits_set = TRUE;
129 }
130 }
131
132 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
133 break;
134
135 case SPAttr::REFX:
136 this->refX.readOrUnset(value);
137 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
138 break;
139
140 case SPAttr::REFY:
141 this->refY.readOrUnset(value);
142 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
143 break;
144
146 this->markerWidth.readOrUnset(value, SVGLength::NONE, 3.0, 3.0);
147 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
148 break;
149
151 this->markerHeight.readOrUnset(value, SVGLength::NONE, 3.0, 3.0);
152 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
153 break;
154
155 case SPAttr::ORIENT:
156 this->orient_set = FALSE;
158 this->orient = 0.0;
159
160 if (value) {
161 if (!strcmp (value, "auto")) {
163 this->orient_set = TRUE;
164 } else if (!strcmp (value, "auto-start-reverse")) {
166 this->orient_set = TRUE;
167 } else {
168 orient.readOrUnset(value);
169 if (orient._set) {
171 this->orient_set = orient._set;
172 }
173 }
174 }
175 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
176 break;
177
178 case SPAttr::VIEWBOX:
179 set_viewBox( value );
180 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
181 break;
182
185 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
186 break;
187
188 default:
189 SPGroup::set(key, value);
190 break;
191 }
192}
193
194void SPMarker::update(SPCtx *ctx, guint flags) {
195
196 SPItemCtx ictx;
197
198 // Copy parent context
199 ictx.flags = ctx->flags;
200
201 // Initialize transformations
202 ictx.i2doc = Geom::identity();
203 ictx.i2vp = Geom::identity();
204
205 // Set up viewport
206 ictx.viewport = Geom::Rect::from_xywh(0, 0, this->markerWidth.computed, this->markerHeight.computed);
207
208 SPItemCtx rctx = get_rctx( &ictx );
209
210 // Shift according to refX, refY
211 Geom::Point ref( this->refX.computed, this->refY.computed );
212 ref *= c2p;
213 this->c2p = this->c2p * Geom::Translate( -ref );
214
215 // And invoke parent method
216 SPGroup::update((SPCtx *) &rctx, flags);
217
218 // As last step set additional transform of drawing group
219 for (auto &it : views_map) {
220 for (auto &item : it.second.items) {
221 if (item) {
222 auto g = cast<Inkscape::DrawingGroup>(item.get());
223 g->setChildTransform(c2p);
224 }
225 }
226 }
227}
228
230 if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
231 repr = xml_doc->createElement("svg:marker");
232 }
233
234 if (this->markerUnits_set) {
236 repr->setAttribute("markerUnits", "strokeWidth");
237 } else {
238 repr->setAttribute("markerUnits", "userSpaceOnUse");
239 }
240 } else {
241 repr->removeAttribute("markerUnits");
242 }
243
244 if (this->refX._set) {
245 repr->setAttributeSvgDouble("refX", this->refX.computed);
246 } else {
247 repr->removeAttribute("refX");
248 }
249
250 if (this->refY._set) {
251 repr->setAttributeSvgDouble("refY", this->refY.computed);
252 } else {
253 repr->removeAttribute("refY");
254 }
255
256 if (this->markerWidth._set) {
257 repr->setAttributeSvgDouble("markerWidth", this->markerWidth.computed);
258 } else {
259 repr->removeAttribute("markerWidth");
260 }
261
262 if (this->markerHeight._set) {
263 repr->setAttributeSvgDouble("markerHeight", this->markerHeight.computed);
264 } else {
265 repr->removeAttribute("markerHeight");
266 }
267
268 if (this->orient_set) {
269 if (this->orient_mode == MARKER_ORIENT_AUTO) {
270 repr->setAttribute("orient", "auto");
271 } else if (this->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) {
272 repr->setAttribute("orient", "auto-start-reverse");
273 } else {
274 repr->setAttributeCssDouble("orient", this->orient.computed);
275 }
276 } else {
277 repr->removeAttribute("orient");
278 }
279
280 this->write_viewBox(repr);
281 this->write_preserveAspectRatio(repr);
282
283 SPGroup::write(xml_doc, repr, flags);
284
285 return repr;
286}
287
288Inkscape::DrawingItem* SPMarker::show(Inkscape::Drawing &/*drawing*/, unsigned int /*key*/, unsigned int /*flags*/) {
289 // Markers in tree are never shown directly even if outside of <defs>.
290 return nullptr;
291}
292
293Inkscape::DrawingItem* SPMarker::private_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) {
294 return SPGroup::show(drawing, key, flags);
295}
296
297void SPMarker::hide(unsigned int key) {
298 // CPPIFY: correct?
300}
301
305Geom::Affine SPMarker::get_marker_transform(Geom::Affine const &base, double linewidth, bool start_marker) const
306{
307 // Default is MARKER_ORIENT_AUTO
308 Geom::Affine result = base;
309
311 if (start_marker) {
312 result = Geom::Rotate::from_degrees( 180.0 ) * base;
313 }
314 } else if (this->orient_mode != MARKER_ORIENT_AUTO) {
315 /* fixme: Orient units (Lauris) */
317 result *= Geom::Translate(base.translation());
318 }
319
321 result = Geom::Scale(linewidth) * result;
322 }
323 return result;
324}
325
326/*
327- used to validate the marker item before passing it into the shape editor from the marker-tool.
328- sets any missing properties that are needed before editing starts.
329*/
330void sp_validate_marker(SPMarker *sp_marker, SPDocument *doc) {
331
332 if (!doc || !sp_marker) return;
333
334 doc->ensureUpToDate();
335
336 // calculate the marker bounds to set any missing viewBox information
337 std::vector<SPObject*> items = const_cast<SPMarker*>(sp_marker)->childList(false, SPObject::ActionBBox);
338
340 for (auto *i : items) {
341 auto item = cast<SPItem>(i);
343 }
344
345 Geom::Rect bounds(r->min() * doc->dt2doc(), r->max() * doc->dt2doc());
346
347 if(!sp_marker->refX._set) {
348 sp_marker->setAttribute("refX", "0.0");
349 }
350
351 if(!sp_marker->refY._set) {
352 sp_marker->setAttribute("refY", "0.0");
353 }
354
355 if(!sp_marker->orient._set) {
356 sp_marker->setAttribute("orient", "0.0");
357 }
358
359 double xScale = 1;
360 double yScale = 1;
361
362 if(sp_marker->viewBox_set) {
363 // check if the X direction has any existing scale factor
364 if(sp_marker->viewBox.width() > 0) {
365 double existingXScale = sp_marker->markerWidth.computed/sp_marker->viewBox.width();
366 xScale = (existingXScale >= 0? existingXScale: 1);
367 }
368
369 // check if the Y direction has any existing scale factor
370 if(sp_marker->viewBox.height() > 0) {
371 double existingYScale = sp_marker->markerHeight.computed/sp_marker->viewBox.height();
372 yScale = (existingYScale >= 0? existingYScale: 1);
373 }
374
375 // only enforce uniform scale if the preserveAspectRatio is not set yet or if it does not equal "none"
376 if((!sp_marker->aspect_set) || (sp_marker->aspect_align != SP_ASPECT_NONE)) {
377 // set the scale to the smaller option if both xScale and yScale exist
378 if(xScale > yScale) {
379 xScale = yScale;
380 } else {
381 yScale = xScale;
382 }
383 }
384 } else {
386 os << "0 0 " << bounds.dimensions()[Geom::X] << " " << bounds.dimensions()[Geom::Y];
387 sp_marker->setAttribute("viewBox", os.str().c_str());
388 }
389
390 sp_marker->setAttributeDouble("markerWidth", sp_marker->viewBox.width() * xScale);
391 sp_marker->setAttributeDouble("markerHeight", sp_marker->viewBox.height() * yScale);
392
393 if(!sp_marker->aspect_set) {
394 // feedback from UX expert indicates that uniform scaling should be used by default;
395 // marker tool should respect aspect ratio setting too (without Ctrl key modifier?)
396 sp_marker->setAttribute("preserveAspectRatio", "xMidYMid");
397 }
398}
399
401}
402
403/* fixme: Remove link if zero-sized (Lauris) */
404
416// If marker views are always created in order, then this function could be eliminated
417// by doing the push_back in sp_marker_show_instance.
418void
419sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size)
420{
421 auto it = marker->views_map.find(key);
422 if (it != marker->views_map.end()) {
423 if (it->second.items.size() != size ) {
424 // Need to change size of vector! (We should not really need to do this.)
425 marker->hide(key);
426 it->second.items.clear();
427 for (unsigned int i = 0; i < size; ++i) {
428 it->second.items.push_back(nullptr);
429 }
430 }
431 } else {
432 marker->views_map[key] = SPMarkerView();
433 for (unsigned int i = 0; i < size; ++i) {
434 marker->views_map[key].items.push_back(nullptr);
435 }
436 }
437}
438
445 unsigned int loc, unsigned int pos, unsigned int z_order,
446 Geom::Affine const &marker_transform, float linewidth)
447{
448 // Do not show marker if linewidth == 0 and markerUnits == strokeWidth
449 // otherwise Cairo will fail to render anything on the tile
450 // that contains the "degenerate" marker.
451 if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH && linewidth == 0) {
452 return nullptr;
453 }
454
455 auto key = parent->key() + ITEM_KEY_MARKERS + loc;
456 auto it = marker->views_map.find(key);
457 if (it == marker->views_map.end()) {
458 // Key not found
459 return nullptr;
460 }
461
462 SPMarkerView *view = &it->second;
463 if (pos >= view->items.size() ) {
464 // Position index too large, doesn't exist.
465 return nullptr;
466 }
467
468 // If not already created
469 if (!view->items[pos]) {
470
471 /* Parent class ::show method */
472 view->items[pos].reset(marker->private_show(parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS));
473
474 if (view->items[pos]) {
475 parent->appendChild(view->items[pos].get());
476 if (auto g = cast<Inkscape::DrawingGroup>(view->items[pos].get())) {
477 g->setChildTransform(marker->c2p);
478 }
479 }
480 }
481
482 if (view->items[pos]) {
483 view->items[pos]->setTransform(marker_transform);
484 view->items[pos]->setZOrder(z_order);
485 }
486
487 return view->items[pos].get();
488}
489
495void
496sp_marker_hide (SPMarker *marker, unsigned int key)
497{
498 marker->hide(key);
499 marker->views_map.erase(key);
500}
501
502
503const gchar *generate_marker(std::vector<Inkscape::XML::Node*> &reprs, Geom::Rect bounds, SPDocument *document, Geom::Point center, Geom::Affine move)
504{
505 Inkscape::XML::Document *xml_doc = document->getReprDoc();
506 Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr();
507
508 Inkscape::XML::Node *repr = xml_doc->createElement("svg:marker");
509
510 // Uncommenting this will make the marker fixed-size independent of stroke width.
511 // Commented out for consistency with standard markers which scale when you change
512 // stroke width:
513 //repr->setAttribute("markerUnits", "userSpaceOnUse");
514
515 repr->setAttributeSvgDouble("markerWidth", bounds.dimensions()[Geom::X]);
516 repr->setAttributeSvgDouble("markerHeight", bounds.dimensions()[Geom::Y]);
517 repr->setAttributeSvgDouble("refX", center[Geom::X]);
518 repr->setAttributeSvgDouble("refY", center[Geom::Y]);
519
520 repr->setAttribute("orient", "auto");
521
522 defsrepr->appendChild(repr);
523 const gchar *mark_id = repr->attribute("id");
524 SPObject *mark_object = document->getObjectById(mark_id);
525
526 for (auto node : reprs){
527 auto copy = cast<SPItem>(mark_object->appendChildRepr(node));
528
529 Geom::Affine dup_transform;
530 if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform))
531 dup_transform = Geom::identity();
532 dup_transform *= move;
533
534 copy->doWriteTransform(dup_transform);
535 }
536
538 return mark_id;
539}
540
542{
543 if (marker->hrefcount < 2) {
544 return marker;
545 }
546
548 gboolean colorStock = prefs->getBool("/options/markers/colorStockMarkers", true);
549 gboolean colorCustom = prefs->getBool("/options/markers/colorCustomMarkers", false);
550 const gchar *stock = marker->getRepr()->attribute("inkscape:isstock");
551 gboolean isStock = (!stock || !strcmp(stock,"true"));
552
553 if (isStock ? !colorStock : !colorCustom) {
554 return marker;
555 }
556
557 SPDocument *doc = marker->document;
558 Inkscape::XML::Document *xml_doc = doc->getReprDoc();
559 // Turn off garbage-collectable or it might be collected before we can use it
560 marker->removeAttribute("inkscape:collect");
561 Inkscape::XML::Node *mark_repr = marker->getRepr()->duplicate(xml_doc);
562 doc->getDefs()->getRepr()->addChild(mark_repr, nullptr);
563 if (!mark_repr->attribute("inkscape:stockid")) {
564 mark_repr->setAttribute("inkscape:stockid", mark_repr->attribute("id"));
565 }
566 marker->setAttribute("inkscape:collect", "always");
567
568 SPObject *marker_new = static_cast<SPObject *>(doc->getObjectByRepr(mark_repr));
569 Inkscape::GC::release(mark_repr);
570 return marker_new;
571}
572
573void sp_marker_set_orient(SPMarker* marker, const char* value) {
574 if (!marker || !value) return;
575
576 marker->setAttribute("orient", value);
577
578 if (marker->document) {
579 DocumentUndo::maybeDone(marker->document, "marker", _("Set marker orientation"), INKSCAPE_ICON("dialog-fill-and-stroke"));
580 }
581}
582
583void sp_marker_set_size(SPMarker* marker, double sx, double sy) {
584 if (!marker) return;
585
586 marker->setAttributeDouble("markerWidth", sx);
587 marker->setAttributeDouble("markerHeight", sy);
588
589 if (marker->document) {
590 DocumentUndo::maybeDone(marker->document, "marker", _("Set marker size"), INKSCAPE_ICON("dialog-fill-and-stroke"));
591 }
592}
593
594void sp_marker_scale_with_stroke(SPMarker* marker, bool scale_with_stroke) {
595 if (!marker) return;
596
597 marker->setAttribute("markerUnits", scale_with_stroke ? "strokeWidth" : "userSpaceOnUse");
598
599 if (marker->document) {
600 DocumentUndo::maybeDone(marker->document, "marker", _("Set marker scale with stroke"), INKSCAPE_ICON("dialog-fill-and-stroke"));
601 }
602}
603
604void sp_marker_set_offset(SPMarker* marker, double dx, double dy) {
605 if (!marker) return;
606
607 marker->setAttributeDouble("refX", dx);
608 marker->setAttributeDouble("refY", dy);
609
610 if (marker->document) {
611 DocumentUndo::maybeDone(marker->document, "marker", _("Set marker offset"), INKSCAPE_ICON("dialog-fill-and-stroke"));
612 }
613}
614
616 if (!marker) return;
617
618 marker->setAttribute("preserveAspectRatio", uniform ? "xMidYMid" : "none");
619
620 if (marker->document) {
621 DocumentUndo::maybeDone(marker->document, "marker", _("Set marker uniform scaling"), INKSCAPE_ICON("dialog-fill-and-stroke"));
622 }
623}
624
626 if (!marker) return;
627
628 ObjectSet set(marker->document);
629 set.addList(marker->item_list());
630 Geom::OptRect bbox = set.visualBounds();
631 if (bbox) {
632 set.scaleRelative(bbox->midpoint(), Geom::Scale(-1.0, 1.0));
633 if (marker->document) {
634 DocumentUndo::maybeDone(marker->document, "marker", _("Flip marker horizontally"), INKSCAPE_ICON("dialog-fill-and-stroke"));
635 }
636 }
637}
638
639/*
640 Local Variables:
641 mode:c++
642 c-file-style:"stroustrup"
643 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
644 indent-tabs-mode:nil
645 fill-column:99
646 End:
647*/
648// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
3x3 affine transformation matrix.
Lookup dictionary for attributes/properties.
SPAttr
Definition attributes.h:27
@ PRESERVEASPECTRATIO
@ MARKERHEIGHT
@ MARKERUNITS
@ MARKERWIDTH
Geom::IntRect bounds
Definition canvas.cpp:182
3x3 matrix representing an affine transformation.
Definition affine.h:70
Point translation() const
Gets the translation imparted by the Affine.
Definition affine.cpp:41
void unionWith(CRect const &b)
Enlarge the rectangle to contain the argument.
static CRect from_xywh(Coord x, Coord y, Coord w, Coord h)
Create rectangle from origin and dimensions.
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
CPoint dimensions() const
Get rectangle's width and height as a point.
Axis-aligned rectangle that can be empty.
Definition rect.h:203
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
static Rotate from_degrees(Coord deg)
Construct a rotation from its angle in degrees.
Definition transforms.h:218
Scaling from the origin.
Definition transforms.h:150
Translation by a vector.
Definition transforms.h:115
A thin wrapper around std::ostringstream, but writing floating point numbers in the format required b...
static void maybeDone(SPDocument *document, const gchar *keyconst, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
SVG drawing item for display.
unsigned key() const
Preference storage class.
Definition preferences.h:66
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
static Preferences * get()
Access the singleton Preferences object.
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.
virtual void appendChild(Node *child)=0
Append a node as the last child of this node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
Definition node.cpp:25
virtual Node * duplicate(Document *doc) const =0
Create a duplicate of this node.
bool setAttributeCssDouble(Util::const_char_ptr key, double val)
Set a property attribute to val [slightly rounded], in the format required for CSS properties: in par...
Definition node.cpp:102
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
void removeAttribute(Inkscape::Util::const_char_ptr key)
Remove an attribute of this node.
Definition node.h:280
bool setAttributeSvgDouble(Util::const_char_ptr key, double val)
For attributes where an exponent is allowed.
Definition node.cpp:111
Typed SVG document implementation.
Definition document.h:103
const Geom::Affine & dt2doc() const
Desktop to document coordinate transformation.
Definition document.h:270
SPObject * getObjectById(std::string const &id) const
SPDefs * getDefs()
Return the main defs object for the document.
Definition document.cpp:245
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
Definition document.h:213
int ensureUpToDate(unsigned int object_modified_tag=0)
Repeatedly works on getting the document updated, since sometimes it takes more than one pass to get ...
SPObject * getObjectByRepr(Inkscape::XML::Node *repr) const
void release() override
Inkscape::DrawingItem * show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) override
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
void set(SPAttr key, char const *value) override
void build(SPDocument *document, Inkscape::XML::Node *repr) override
std::vector< SPItem * > item_list()
void hide(unsigned int key) override
void update(SPCtx *ctx, unsigned int flags) override
Geom::OptRect desktopVisualBounds() const
Get item's visual bbox in desktop coordinate system.
Definition sp-item.cpp:1049
SVGLength refY
Definition sp-marker.h:53
void release() override
Removes, releases and unrefs all children of object.
unsigned int markerUnits
Definition sp-marker.h:49
SVGLength refX
Definition sp-marker.h:52
std::map< unsigned int, SPMarkerView > views_map
Definition sp-marker.h:72
SVGLength markerWidth
Definition sp-marker.h:56
unsigned int orient_set
Definition sp-marker.h:60
SVGLength markerHeight
Definition sp-marker.h:57
unsigned int markerUnits_set
Definition sp-marker.h:48
Inkscape::DrawingItem * show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) override
virtual Inkscape::DrawingItem * private_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags)
void hide(unsigned int key) override
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) override
void print(SPPrintContext *ctx) override
void set(SPAttr key, gchar const *value) override
Geom::Affine get_marker_transform(Geom::Affine const &base, double linewidth, bool for_display=false) const
Calculate the transformation for this marker.
markerOrient orient_mode
Definition sp-marker.h:61
~SPMarker() override
Initializes an SPMarker object.
void update(SPCtx *ctx, guint flags) override
SVGAngle orient
Definition sp-marker.h:62
void build(SPDocument *document, Inkscape::XML::Node *repr) override
Virtual build callback for SPMarker.
Definition sp-marker.cpp:80
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
Inkscape::XML::Node * repr
Definition sp-object.h:193
void setAttributeDouble(Inkscape::Util::const_char_ptr key, double value)
void setAttribute(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
void removeAttribute(char const *key)
SPDocument * document
Definition sp-object.h:188
void readAttr(char const *key)
Read value of key attribute from XML node into object.
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
SPObject * appendChildRepr(Inkscape::XML::Node *repr)
Append repr as child of this object.
unsigned int hrefcount
Definition sp-object.h:186
void requestDisplayUpdate(unsigned int flags)
Queues an deferred update of this object's display.
void set_viewBox(const gchar *value)
Definition viewbox.cpp:50
unsigned int aspect_align
Definition viewbox.h:39
Geom::Rect viewBox
Definition viewbox.h:35
bool aspect_set
Definition viewbox.h:38
Geom::Affine c2p
Definition viewbox.h:43
void set_preserveAspectRatio(const gchar *value)
Definition viewbox.cpp:98
void write_preserveAspectRatio(Inkscape::XML::Node *repr) const
Write preserveAspectRatio attribute to XML, if set.
Definition viewbox.cpp:305
SPItemCtx get_rctx(const SPItemCtx *ictx, double scale_none=1.0)
Definition viewbox.cpp:260
void write_viewBox(Inkscape::XML::Node *repr) const
Write viewBox attribute to XML, if set.
Definition viewbox.cpp:289
bool viewBox_set
Definition viewbox.h:34
double computed
Definition svg-angle.h:45
bool _set
Definition svg-angle.h:36
void readOrUnset(gchar const *str, Unit u=Unit::NONE, double v=0, double c=0)
Definition svg-angle.cpp:64
void readOrUnset(char const *str, Unit u=NONE, float v=0, float c=0)
bool _set
Definition svg-length.h:41
float computed
Definition svg-length.h:50
TODO: insert short description here.
Css & result
static char const *const parent
Definition dir-util.cpp:70
TODO: insert short description here.
Group belonging to an SVG drawing element.
@ SP_ASPECT_NONE
Definition enums.h:42
@ SP_MARKER_UNITS_USERSPACEONUSE
Definition enums.h:71
@ SP_MARKER_UNITS_STROKEWIDTH
Definition enums.h:70
@ Y
Definition coord.h:48
@ X
Definition coord.h:48
Macro for icon names used in Inkscape.
SPItem * item
Inkscape::XML::Node * node
Affine identity()
Create an identity matrix.
Definition affine.h:210
static R & release(R &r)
Decrements the reference count of a anchored object.
static cairo_user_data_key_t key
int size
Singleton class to access the preferences file in a convenient way.
Ocnode ** ref
Definition quantize.cpp:32
GList * items
@ ITEM_KEY_MARKERS
Definition sp-item.h:72
const gchar * generate_marker(std::vector< Inkscape::XML::Node * > &reprs, Geom::Rect bounds, SPDocument *document, Geom::Point center, Geom::Affine move)
void sp_marker_set_orient(SPMarker *marker, const char *value)
void sp_marker_hide(SPMarker *marker, unsigned int key)
Hides/removes all views of the given marker that have key 'key'.
void sp_marker_scale_with_stroke(SPMarker *marker, bool scale_with_stroke)
void sp_validate_marker(SPMarker *sp_marker, SPDocument *doc)
SPObject * sp_marker_fork_if_necessary(SPObject *marker)
Inkscape::DrawingItem * sp_marker_show_instance(SPMarker *marker, Inkscape::DrawingItem *parent, unsigned int loc, unsigned int pos, unsigned int z_order, Geom::Affine const &marker_transform, float linewidth)
Shows an instance of a marker.
void sp_marker_set_offset(SPMarker *marker, double dx, double dy)
void sp_marker_set_uniform_scale(SPMarker *marker, bool uniform)
void sp_marker_set_size(SPMarker *marker, double sx, double sy)
void sp_marker_show_dimension(SPMarker *marker, unsigned int key, unsigned int size)
Removes any SPMarkerViews that a marker has with a specific key.
void sp_marker_flip_horizontally(SPMarker *marker)
@ MARKER_ORIENT_ANGLE
Definition sp-marker.h:36
@ MARKER_ORIENT_AUTO
Definition sp-marker.h:37
@ MARKER_ORIENT_AUTO_START_REVERSE
Definition sp-marker.h:38
Interface for XML documents.
Definition document.h:43
virtual Node * createElement(char const *name)=0
Unused.
Definition sp-object.h:94
unsigned int flags
Definition sp-object.h:95
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
Geom::Rect viewport
Viewport size.
Definition sp-item.h:97
bool sp_svg_transform_read(gchar const *str, Geom::Affine *transform)
double uniform()
Affine transformation classes.
Interface for XML documents.