Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
sp-ellipse.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * SVG <ellipse> and related implementations
4 *
5 * Authors:
6 * Lauris Kaplinski <lauris@kaplinski.com>
7 * Mitsuru Oka
8 * bulia byak <buliabyak@users.sf.net>
9 * Abhishek Sharma
10 *
11 * Copyright (C) 1999-2002 Lauris Kaplinski
12 * Copyright (C) 2000-2001 Ximian, Inc.
13 * Copyright (C) 2013 Tavmjong Bah
14 *
15 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
16 */
17
18#include <glibmm/i18n.h>
19
20#include <2geom/angle.h>
21#include <2geom/circle.h>
22#include <2geom/path-sink.h>
23
24#include "attributes.h"
25#include "preferences.h"
26#include "snap-candidate.h"
27#include "snap-preferences.h" // for SnapPreferences
28#include "sp-ellipse.h"
29#include "style.h"
30
31#include "display/curve.h"
32#include "svg/svg.h"
33
34#define SP_2PI (2 * M_PI)
35
44
46= default;
47
48/*
49 * Ellipse and rect is the only SP object who's repr element tag name changes
50 * during it's lifetime. During undo and redo these changes can cause
51 * the SP object to become unstuck from the repr's true state.
52 */
53void SPGenericEllipse::tag_name_changed(gchar const* oldname, gchar const* newname)
54{
55 const std::string typeString = newname;
56 if (typeString == "svg:circle") {
58 } else if (typeString == "svg:ellipse") {
60 } else if (typeString == "svg:path") {
62 } else {
64 }
65}
66
68{
69 // std::cout << "SPGenericEllipse::build: Entrance: " << this->type
70 // << " (" << g_quark_to_string(repr->code()) << ")" << std::endl;
71
72 switch ( type ) {
82 break;
83
85 this->readAttr(SPAttr::CX);
86 this->readAttr(SPAttr::CY);
87 this->readAttr(SPAttr::R);
88 break;
89
91 this->readAttr(SPAttr::CX);
92 this->readAttr(SPAttr::CY);
93 this->readAttr(SPAttr::RX);
94 this->readAttr(SPAttr::RY);
95 break;
96
97 default:
98 std::cerr << "SPGenericEllipse::build() unknown defined type." << std::endl;
99 }
100
101 // std::cout << " cx: " << cx.write() << std::endl;
102 // std::cout << " cy: " << cy.write() << std::endl;
103 // std::cout << " rx: " << rx.write() << std::endl;
104 // std::cout << " ry: " << ry.write() << std::endl;
106}
107
108void SPGenericEllipse::set(SPAttr key, gchar const *value)
109{
110 // There are multiple ways to set internal cx, cy, rx, and ry (via SVG attributes or Sodipodi
111 // attributes) thus we don't want to unset them if a read fails (e.g., when we explicitly clear
112 // an attribute by setting it to NULL).
113
114 // We must update the SVGLengths immediately or nodes may be misplaced after they are moved.
115 double const w = viewport.width();
116 double const h = viewport.height();
117 double const d = hypot(w, h) / sqrt(2); // diagonal
118 double const em = style->font_size.computed;
119 double const ex = em * 0.5;
120
121 switch (key) {
122 case SPAttr::CX:
124 cx.readOrUnset(value);
125 cx.update( em, ex, w );
126 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
127 break;
128
129 case SPAttr::CY:
131 cy.readOrUnset(value);
132 cy.update( em, ex, h );
133 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
134 break;
135
136 case SPAttr::RX:
138 rx.readOrUnset(value);
139 rx.update( em, ex, w );
140 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
141 break;
142
143 case SPAttr::RY:
145 ry.readOrUnset(value);
146 ry.update( em, ex, h );
147 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
148 break;
149
150 case SPAttr::R:
151 rx.readOrUnset(value);
152 rx.update( em, ex, d );
153 ry = rx;
154 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
155 break;
156
158 if (value) {
159 sp_svg_number_read_d(value, &this->start);
160 } else {
161 this->start = 0;
162 }
163 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
164 break;
165
167 if (value) {
168 sp_svg_number_read_d(value, &this->end);
169 } else {
170 this->end = 2 * M_PI;
171 }
172 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
173 break;
174
176 // This is for reading in old files.
177 if ((!value) || strcmp(value,"true")) {
178 // We rely on this to reset arc_type when changing an arc to
179 // an ellipse/circle, so it is drawn as a closed path.
180 // A clone will not even change it's this->type
182 } else {
184 }
185 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
186 break;
187
189 // To read in old files that use 'open', we need to not set if value is null.
190 // We could also check inkscape version.
191 if (value) {
192 if (!strcmp(value,"arc")) {
194 } else if (!strcmp(value,"chord")) {
196 } else {
198 }
199 }
200 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
201 break;
202
203 default:
204 SPShape::set(key, value);
205 break;
206 }
207}
208
209void SPGenericEllipse::update(SPCtx *ctx, guint flags)
210{
211 // std::cout << "\nSPGenericEllipse::update: Entrance" << std::endl;
212 if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
213 Geom::Rect const &viewbox = ((SPItemCtx const *) ctx)->viewport;
214
215 double const dx = viewbox.width();
216 double const dy = viewbox.height();
217 double const dr = hypot(dx, dy) / sqrt(2);
218 double const em = this->style->font_size.computed;
219 double const ex = em * 0.5; // fixme: get from pango or libnrtype
220
221 this->cx.update(em, ex, dx);
222 this->cy.update(em, ex, dy);
223 this->rx.update(em, ex, dr);
224 this->ry.update(em, ex, dr);
225
226 this->set_shape();
227 }
228
229 SPShape::update(ctx, flags);
230 // std::cout << "SPGenericEllipse::update: Exit\n" << std::endl;
231}
232
234{
235 // std::cout << "\nSPGenericEllipse::write: Entrance ("
236 // << (repr == NULL ? " NULL" : g_quark_to_string(repr->code()))
237 // << ")" << std::endl;
238
241 new_type = SP_GENERIC_ELLIPSE_ARC;
242 } else if ( rx.computed == ry.computed ) {
243 new_type = SP_GENERIC_ELLIPSE_CIRCLE;
244 } else {
246 }
247 // std::cout << " new_type: " << new_type << std::endl;
248
249 if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
250
251 switch ( new_type ) {
252
254 repr = xml_doc->createElement("svg:path");
255 break;
257 repr = xml_doc->createElement("svg:circle");
258 break;
260 repr = xml_doc->createElement("svg:ellipse");
261 break;
263 default:
264 std::cerr << "SPGenericEllipse::write(): unknown type." << std::endl;
265 }
266 }
267
268 if (type != new_type) {
269 switch (new_type) {
271 repr->setCodeUnsafe(g_quark_from_string("svg:path"));
272 break;
274 repr->setCodeUnsafe(g_quark_from_string("svg:circle"));
275 break;
277 repr->setCodeUnsafe(g_quark_from_string("svg:ellipse"));
278 break;
279 default:
280 std::cerr << "SPGenericEllipse::write(): unknown type." << std::endl;
281 }
282 type = new_type;
283 }
284
285 // std::cout << " type: " << g_quark_to_string( repr->code() ) << std::endl;
286 // std::cout << " cx: " << cx.write() << " " << cx.computed
287 // << " cy: " << cy.write() << " " << cy.computed
288 // << " rx: " << rx.write() << " " << rx.computed
289 // << " ry: " << ry.write() << " " << ry.computed << std::endl;
290
291 // remember these attributes because removeAttribute() may unset them
292 auto const save_cx = cx;
293 auto const save_cy = cy;
294 auto const save_rx = rx;
295 auto const save_ry = ry;
296
297 switch ( type ) {
300
301 repr->removeAttribute("cx");
302 repr->removeAttribute("cy");
303 repr->removeAttribute("rx");
304 repr->removeAttribute("ry");
305 repr->removeAttribute("r");
306
307 if (flags & SP_OBJECT_WRITE_EXT) {
308
309 repr->setAttribute("sodipodi:type", "arc");
310 repr->setAttributeSvgLength("sodipodi:cx", save_cx);
311 repr->setAttributeSvgLength("sodipodi:cy", save_cy);
312 repr->setAttributeSvgLength("sodipodi:rx", save_rx);
313 repr->setAttributeSvgLength("sodipodi:ry", save_ry);
314
315 // write start and end only if they are non-trivial; otherwise remove
316 if (_isSlice()) {
317 repr->setAttributeSvgDouble("sodipodi:start", start);
318 repr->setAttributeSvgDouble("sodipodi:end", end);
319
320 switch ( arc_type ) {
322 repr->removeAttribute("sodipodi:open"); // For backwards compat.
323 repr->setAttribute("sodipodi:arc-type", "slice");
324 break;
326 // A chord's path isn't "open" but its fill most closely resembles an arc.
327 repr->setAttribute("sodipodi:open", "true"); // For backwards compat.
328 repr->setAttribute("sodipodi:arc-type", "chord");
329 break;
331 repr->setAttribute("sodipodi:open", "true"); // For backwards compat.
332 repr->setAttribute("sodipodi:arc-type", "arc");
333 break;
334 default:
335 std::cerr << "SPGenericEllipse::write: unknown arc-type." << std::endl;
336 }
337 } else {
338 repr->removeAttribute("sodipodi:end");
339 repr->removeAttribute("sodipodi:start");
340 repr->removeAttribute("sodipodi:open");
341 repr->removeAttribute("sodipodi:arc-type");
342 }
343 }
344
345 // write d=
347 break;
348
350 repr->removeAttribute("rx");
351 repr->removeAttribute("ry");
352 repr->removeAttribute("sodipodi:cx");
353 repr->removeAttribute("sodipodi:cy");
354 repr->removeAttribute("sodipodi:rx");
355 repr->removeAttribute("sodipodi:ry");
356 repr->removeAttribute("sodipodi:end");
357 repr->removeAttribute("sodipodi:start");
358 repr->removeAttribute("sodipodi:open");
359 repr->removeAttribute("sodipodi:arc-type");
360 repr->removeAttribute("sodipodi:type");
361 repr->removeAttribute("d");
362 repr->setAttributeSvgLength("cx", save_cx);
363 repr->setAttributeSvgLength("cy", save_cy);
364 repr->setAttributeSvgLength("r", save_rx);
365 break;
366
368 repr->removeAttribute("r");
369 repr->removeAttribute("sodipodi:cx");
370 repr->removeAttribute("sodipodi:cy");
371 repr->removeAttribute("sodipodi:rx");
372 repr->removeAttribute("sodipodi:ry");
373 repr->removeAttribute("sodipodi:end");
374 repr->removeAttribute("sodipodi:start");
375 repr->removeAttribute("sodipodi:open");
376 repr->removeAttribute("sodipodi:arc-type");
377 repr->removeAttribute("sodipodi:type");
378 repr->removeAttribute("d");
379 repr->setAttributeSvgLength("cx", save_cx);
380 repr->setAttributeSvgLength("cy", save_cy);
381 repr->setAttributeSvgLength("rx", save_rx);
382 repr->setAttributeSvgLength("ry", save_ry);
383 break;
384
385 default:
386 std::cerr << "SPGenericEllipse::write: unknown type." << std::endl;
387 }
388
389 set_shape(); // evaluate SPCurve
390
391 SPShape::write(xml_doc, repr, flags);
392
393 return repr;
394}
395
396const char *SPGenericEllipse::typeName() const
397{
398 switch (type) {
401 return "arc";
404 default:
405 return "circle"; //
406 }
407}
408
410{
411 switch ( type ) {
414 if (_isSlice()) {
415 switch ( arc_type ) {
417 return _("Slice");
418 break;
420 return _("Chord");
421 break;
423 return _("Arc");
424 break;
425 }
426 } // fallback to ellipse
428 return _("Ellipse");
430 return _("Circle");
431 default:
432 return "Unknown ellipse: ERROR";
433 }
434}
435
436// Create path for rendering shape on screen
438{
439 // std::cout << "SPGenericEllipse::set_shape: Entrance" << std::endl;
440 if (checkBrokenPathEffect()) {
441 return;
442 }
443 if (this->rx.computed <= Geom::EPSILON || this->ry.computed <= Geom::EPSILON) {
444 setCurveInsync(nullptr);
445 return;
446 }
447
448 this->normalize();
449
450 // For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations.
451 Geom::Circle circle(0, 0, 1);
452
453 if (!this->_isSlice()) {
454 start = 0.0;
455 end = 2.0*M_PI;
456 }
457 double incr = end - start; // arc angle
458 if (incr < 0.0) incr += 2.0*M_PI;
459
460 int numsegs = 1 + int(incr*2.0/M_PI); // number of arc segments
461 if (numsegs > 4) numsegs = 4;
462
463 incr = incr/numsegs; // limit arc angle to less than 90 degrees
464 Geom::Path path(Geom::Point::polar(start));
466 for (int seg = 0; seg < numsegs; seg++) {
467 arc = circle.arc(Geom::Point::polar(start + seg*incr), Geom::Point::polar(start + (seg + 0.5)*incr), Geom::Point::polar(start + (seg + 1.0)*incr));
468 path.append(*arc);
469 delete arc;
470 }
472 pb.append(path);
473 if (this->_isSlice() && this->arc_type == SP_GENERIC_ELLIPSE_ARC_TYPE_SLICE) {
474 pb.lineTo(Geom::Point(0, 0));
475 }
476
478 pb.closePath();
479 } else {
480 pb.flush();
481 }
482
483 auto c = SPCurve(pb.peek());
484
485 // gchar *str = sp_svg_write_path(curve->get_pathvector());
486 // std::cout << " path: " << str << std::endl;
487 // g_free(str);
488
489 // Stretching / moving the calculated shape to fit the actual dimensions.
491 c.transform(aff);
493}
494
496{
498 return xform;
499 }
500
501 /* Calculate ellipse start in parent coords. */
502 Geom::Point pos(Geom::Point(this->cx.computed, this->cy.computed) * xform);
503
504 /* This function takes care of translation and scaling, we return whatever parts we can't
505 handle. */
506 Geom::Affine ret(Geom::Affine(xform).withoutTranslation());
507 gdouble const sw = hypot(ret[0], ret[1]);
508 gdouble const sh = hypot(ret[2], ret[3]);
509
510 if (sw > 1e-9) {
511 ret[0] /= sw;
512 ret[1] /= sw;
513 } else {
514 ret[0] = 1.0;
515 ret[1] = 0.0;
516 }
517
518 if (sh > 1e-9) {
519 ret[2] /= sh;
520 ret[3] /= sh;
521 } else {
522 ret[2] = 0.0;
523 ret[3] = 1.0;
524 }
525
526 if (this->rx._set) {
527 this->rx.scale( sw );
528 }
529
530 if (this->ry._set) {
531 this->ry.scale( sh );
532 }
533
534 /* Find start in item coords */
535 pos = pos * ret.inverse();
536 this->cx = pos[Geom::X];
537 this->cy = pos[Geom::Y];
538
539 this->set_shape();
540
541 // Adjust stroke width
542 if (!g_strcmp0(getAttribute("sodipodi:arc-type"), "slice") ||
543 !g_strcmp0(getAttribute("sodipodi:arc-type"), "chord") ||
544 !g_strcmp0(getAttribute("sodipodi:arc-type"), "arc"))
545 {
546 double const expansion = transform.descrim();
548 }
549 this->adjust_stroke(sqrt(fabs(sw * sh)));
550
551 // Adjust pattern fill
552 this->adjust_pattern(xform * ret.inverse());
553
554 // Adjust gradient fill
555 this->adjust_gradient(xform * ret.inverse());
556
557 return ret;
558}
559
560void SPGenericEllipse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) const
561{
562 // CPPIFY: is this call necessary?
563 const_cast<SPGenericEllipse*>(this)->normalize();
564
565 Geom::Affine const i2dt = this->i2dt_affine();
566
567 // Snap to the 4 quadrant points of the ellipse, but only if the arc
568 // spans far enough to include them
570 for (double angle = 0; angle < SP_2PI; angle += M_PI_2) {
571 if (Geom::AngleInterval(this->start, this->end, true).contains(angle)) {
572 Geom::Point pt = this->getPointAtAngle(angle) * i2dt;
574 }
575 }
576 }
577
578 double cx = this->cx.computed;
579 double cy = this->cy.computed;
580
581
582 bool slice = this->_isSlice();
583
584 // Add the centre, if we have a closed slice or when explicitly asked for
585 if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice &&
586 this->arc_type == SP_GENERIC_ELLIPSE_ARC_TYPE_SLICE) {
587 Geom::Point pt = Geom::Point(cx, cy) * i2dt;
589 }
590
592 Geom::Point pt = Geom::Point(cx, cy) * i2dt;
594 }
595
596 // And if we have a slice, also snap to the endpoints
597 if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && slice) {
598 // Add the start point, if it's not coincident with a quadrant point
599 if (!Geom::are_near(std::fmod(this->start, M_PI_2), 0)) {
600 Geom::Point pt = this->getPointAtAngle(this->start) * i2dt;
602 }
603
604 // Add the end point, if it's not coincident with a quadrant point
605 if (!Geom::are_near(std::fmod(this->end, M_PI_2), 0)) {
606 Geom::Point pt = this->getPointAtAngle(this->end) * i2dt;
608 }
609 }
610}
611
613{
614 if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
615 this->set_shape();
616 }
617
618 SPShape::modified(flags);
619}
620
624
626{
627 Geom::AngleInterval a(this->start, this->end, true);
628
629 this->start = a.initialAngle().radians0();
630 this->end = a.finalAngle().radians0();
631}
632
634{
635 return Geom::Point::polar(arg) * Geom::Scale(rx.computed, ry.computed) * Geom::Translate(cx.computed, cy.computed);
636}
637
638/*
639 * set_elliptical_path_attribute:
640 *
641 * Convert center to endpoint parameterization and set it to repr.
642 *
643 * See SVG 1.0 Specification W3C Recommendation
644 * ``F.6 Elliptical arc implementation notes'' for more detail.
645 */
647{
648 // Make sure our pathvector is up to date.
649 this->set_shape();
650
651 if (_curve) {
652 repr->setAttribute("d", sp_svg_write_path(_curve->get_pathvector()));
653 } else {
654 repr->removeAttribute("d");
655 }
656
657 return true;
658}
659
660void SPGenericEllipse::position_set(gdouble x, gdouble y, gdouble rx, gdouble ry)
661{
662 this->cx = x;
663 this->cy = y;
664 this->rx = rx;
665 this->ry = ry;
666
668
669 // those pref values are in degrees, while we want radians
670 if (prefs->getDouble("/tools/shapes/arc/start", 0.0) != 0) {
671 this->start = Geom::Angle::from_degrees(prefs->getDouble("/tools/shapes/arc/start", 0.0)).radians0();
672 }
673
674 if (prefs->getDouble("/tools/shapes/arc/end", 0.0) != 0) {
675 this->end = Geom::Angle::from_degrees(prefs->getDouble("/tools/shapes/arc/end", 0.0)).radians0();
676 }
677
678 this->arc_type = (GenericEllipseArcType)prefs->getInt("/tools/shapes/arc/arc_type", 0);
679 if (this->type != SP_GENERIC_ELLIPSE_ARC && _isSlice()) {
680 // force an update while creating shapes, so correct rendering is shown initially
681 updateRepr();
682 }
683
684 this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
685}
686
688{
689 Geom::AngleInterval a(this->start, this->end, true);
690
691 return !(Geom::are_near(a.extent(), 0) || Geom::are_near(a.extent(), SP_2PI));
692}
693
695static double vectorStretch(Geom::Point const &n, Geom::Affine const &trans)
696{
697 return (n * trans.withoutTranslation()).length();
698}
699
701{
702 if (rx_ == 0) {
703 rx.unset();
704 } else {
705 rx = rx_ / vectorStretch({1, 0}, i2doc_affine());
706 }
707 updateRepr();
708}
709
711{
712 if (ry_ == 0) {
713 ry.unset();
714 } else {
715 ry = ry_ / vectorStretch({0, 1}, i2doc_affine());
716 }
717 updateRepr();
718}
719
721{
722 if (!rx._set) {
723 return 0;
724 }
725 return rx.computed * vectorStretch({1, 0}, i2doc_affine());
726}
727
729{
730 if (!ry._set) {
731 return 0;
732 }
733 return ry.computed * vectorStretch({0, 1}, i2doc_affine());
734}
735
736/*
737 Local Variables:
738 mode:c++
739 c-file-style:"stroustrup"
740 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
741 indent-tabs-mode:nil
742 fill-column:99
743 End:
744*/
745// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
Various trigoniometric helper functions.
Lookup dictionary for attributes/properties.
SPAttr
Definition attributes.h:27
@ SODIPODI_CY
@ SODIPODI_END
@ SODIPODI_OPEN
@ SODIPODI_CX
@ SODIPODI_START
@ SODIPODI_ARC_TYPE
@ SODIPODI_RX
@ SODIPODI_RY
Circle shape.
3x3 matrix representing an affine transformation.
Definition affine.h:70
Coord descrim() const
Calculate the descriminant.
Definition affine.cpp:434
Affine inverse() const
Compute the inverse matrix.
Definition affine.cpp:388
Affine withoutTranslation() const
Definition affine.h:169
Directed angular interval.
Definition angle.h:188
Angle finalAngle() const
Get the end angle.
Definition angle.h:231
Coord extent() const
Extent of the angle interval.
Definition angle.h:342
Angle initialAngle() const
Get the start angle.
Definition angle.h:229
static Angle from_degrees(Coord d)
Create an angle from its measure in degrees.
Definition angle.h:136
Coord radians0() const
Get the angle as positive radians.
Definition angle.h:112
Set of all points at a fixed distance from the center.
Definition circle.h:55
Elliptical arc curve.
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
Store paths to a PathVector.
Definition path-sink.h:226
PathVector const & peek() const
Retrieve the path.
Definition path-sink.h:236
void append(Path const &other)
Definition path-sink.h:181
void lineTo(Point const &p) override
Output a line segment.
Definition path-sink.h:137
void flush() override
Flush any internal state of the generator.
Definition path-sink.h:196
void closePath() override
Close the current path with a line segment.
Definition path-sink.h:189
Sequence of contiguous curves, aka spline.
Definition path.h:353
void append(Curve *curve)
Add a new curve to the end of the path.
Definition path.h:750
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
Scaling from the origin.
Definition transforms.h:150
Translation by a vector.
Definition transforms.h:115
Preference storage class.
Definition preferences.h:66
double getDouble(Glib::ustring const &pref_path, double def=0.0, Glib::ustring const &unit="")
Retrieve a floating point value.
static Preferences * get()
Access the singleton Preferences object.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
Storing of snapping preferences.
bool isTargetSnappable(Inkscape::SnapTargetType const target) const
Interface for refcounted XML nodes.
Definition node.h:80
bool setAttributeSvgLength(Util::const_char_ptr key, SVGLength const &val)
Definition node.cpp:131
virtual void setCodeUnsafe(int code)=0
Set the integer GQuark code for the name of the node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
Definition node.cpp:25
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
Wrapper around a Geom::PathVector object.
Definition curve.h:26
Typed SVG document implementation.
Definition document.h:103
~SPGenericEllipse() override
const char * displayName() const override
The item's type name as a translated human string.
Geom::Point getPointAtAngle(double arg) const
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
void modified(unsigned int flags) override
double getVisibleRy() const
void setVisibleRy(double ry)
void update_patheffect(bool write) override
void tag_name_changed(gchar const *oldname, gchar const *newname) override
void normalize()
Makes sure that start and end lie between 0 and 2 * PI.
void set_shape() override
void position_set(double x, double y, double rx, double ry)
bool set_elliptical_path_attribute(Inkscape::XML::Node *repr)
Geom::Affine set_transform(Geom::Affine const &xform) override
bool _isSlice() const
Determines whether the shape is a part of an ellipse.
void update(SPCtx *ctx, unsigned int flags) override
void setVisibleRx(double rx)
void build(SPDocument *document, Inkscape::XML::Node *repr) override
void set(SPAttr key, char const *value) override
const char * typeName() const override
The item's type name, not node tag name.
double getVisibleRx() const
GenericEllipseType type
Definition sp-ellipse.h:54
GenericEllipseArcType arc_type
Definition sp-ellipse.h:55
void snappoints(std::vector< Inkscape::SnapCandidatePoint > &p, Inkscape::SnapPreferences const *snapprefs) const override
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
Definition sp-item.cpp:1821
void adjust_gradient(Geom::Affine const &postmul, bool set=false)
Definition sp-item.cpp:1426
void adjust_stroke_width_recursive(double ex)
Recursively scale stroke width in item and its children by expansion.
Definition sp-item.cpp:1515
Geom::Affine transform
Definition sp-item.h:138
Geom::Rect viewport
Definition sp-item.h:140
void adjust_pattern(Geom::Affine const &postmul, bool set=false, PaintServerTransform=TRANSFORM_BOTH)
Definition sp-item.cpp:1380
void adjust_stroke(double ex)
Definition sp-item.cpp:1472
Geom::Affine i2doc_affine() const
Returns the accumulated transformation of the item and all its ancestors, including root's viewport.
Definition sp-item.cpp:1816
bool hasPathEffectOnClipOrMaskRecursive(SPLPEItem *shape) const
returns true when any LPE apply to clip or mask.
bool pathEffectsEnabled() const
bool optimizeTransforms()
returns false when LPE write unoptimiced
Inkscape::XML::Node * repr
Definition sp-object.h:193
SPDocument * document
Definition sp-object.h:188
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
Definition sp-object.h:248
Inkscape::XML::Node * updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT)
Updates the object's repr based on the object's state.
void readAttr(char const *key)
Read value of key attribute from XML node into object.
char const * getAttribute(char const *name) const
void requestDisplayUpdate(unsigned int flags)
Queues an deferred update of this object's display.
Base class for shapes, including <path> element.
Definition sp-shape.h:38
void update(SPCtx *ctx, unsigned int flags) override
Definition sp-shape.cpp:125
void setCurveInsync(SPCurve const *)
Definition sp-shape.cpp:958
bool prepareShapeForLPE(SPCurve const *c)
Definition sp-shape.cpp:479
void modified(unsigned int flags) override
Definition sp-shape.cpp:427
void set(SPAttr key, char const *value) override
Definition sp-shape.cpp:115
void build(SPDocument *document, Inkscape::XML::Node *repr) override
Definition sp-shape.cpp:63
void update_patheffect(bool write) override
Definition sp-shape.cpp:650
std::shared_ptr< SPCurve const > _curve
Definition sp-shape.h:70
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
Definition sp-shape.cpp:120
bool checkBrokenPathEffect()
Definition sp-shape.cpp:459
T< SPAttr::FONT_SIZE, SPIFontSize > font_size
Size of the font.
Definition style.h:116
void scale(double scale)
void readOrUnset(char const *str, Unit u=NONE, float v=0, float c=0)
bool _set
Definition svg-length.h:41
void unset(Unit u=NONE, float v=0, float c=0)
float computed
Definition svg-length.h:50
void update(double em, double ex, double scale)
const double w
Definition conic-4.cpp:19
double c[8][4]
constexpr Coord EPSILON
Default "acceptably small" value.
Definition coord.h:84
@ Y
Definition coord.h:48
@ X
Definition coord.h:48
Geom::Point start
Geom::Point end
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
@ SNAPSOURCE_NODE_CUSP
Definition snap-enums.h:37
@ SNAPSOURCE_OBJECT_MIDPOINT
Definition snap-enums.h:53
@ SNAPSOURCE_ELLIPSE_QUADRANT_POINT
Definition snap-enums.h:42
@ SNAPTARGET_NODE_CUSP
Definition snap-enums.h:83
@ SNAPTARGET_ELLIPSE_QUADRANT_POINT
Definition snap-enums.h:92
@ SNAPTARGET_OBJECT_MIDPOINT
Definition snap-enums.h:115
static cairo_user_data_key_t key
callback interface for SVG path data
Singleton class to access the preferences file in a convenient way.
Some utility classes to store various kinds of snap candidates.
static double vectorStretch(Geom::Point const &n, Geom::Affine const &trans)
Returns the ratio in which a unit vector n is stretched by transform.
GenericEllipseArcType
Definition sp-ellipse.h:30
@ SP_GENERIC_ELLIPSE_ARC_TYPE_CHORD
Definition sp-ellipse.h:33
@ SP_GENERIC_ELLIPSE_ARC_TYPE_SLICE
Definition sp-ellipse.h:31
@ SP_GENERIC_ELLIPSE_ARC_TYPE_ARC
Definition sp-ellipse.h:32
GenericEllipseType
Definition sp-ellipse.h:23
@ SP_GENERIC_ELLIPSE_CIRCLE
Definition sp-ellipse.h:26
@ SP_GENERIC_ELLIPSE_UNDEFINED
Definition sp-ellipse.h:24
@ SP_GENERIC_ELLIPSE_ARC
Definition sp-ellipse.h:25
@ SP_GENERIC_ELLIPSE_ELLIPSE
Definition sp-ellipse.h:27
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
SPStyle - a style object for SPItem objects.
unsigned int sp_svg_number_read_d(gchar const *str, double *val)
static void sp_svg_write_path(Inkscape::SVG::PathString &str, Geom::Path const &p, bool normalize=false)
Definition svg-path.cpp:109