Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
path-object-set.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2
15#include <glibmm/i18n.h>
16
17#include "attribute-rel-util.h"
18#include "desktop.h"
19#include "document.h"
20#include "document-undo.h"
21#include "message-stack.h"
22#include "preferences.h"
23
24#include "object/object-set.h"
25#include "path/path-outline.h"
26#include "path/path-simplify.h"
27#include "ui/icon-names.h"
28
30
31bool
32ObjectSet::strokesToPaths(bool legacy, bool skip_undo)
33{
34 if (desktop() && isEmpty()) {
35 desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>stroked path(s)</b> to convert stroke to path."));
36 return false;
37 }
38
39 bool did = false;
40
42 if (prefs->getBool("/options/pathoperationsunlink/value", true)) {
43 did = unlinkRecursive(true);
44 }
45
46 // Need to turn on stroke scaling to ensure stroke is scaled when transformed!
47 bool scale_stroke = prefs->getBool("/options/transform/stroke", true);
48 prefs->setBool("/options/transform/stroke", true);
49
50
51 std::vector<SPItem *> my_items(items().begin(), items().end());
52
53 for (auto item : my_items) {
54 // Do not remove the object from the selection here
55 // as we want to keep it selected if the whole operation fails
56 Inkscape::XML::Node *new_node = item_to_paths(item, legacy);
57 if (new_node) {
58 SPObject* new_item = document()->getObjectByRepr(new_node);
59
60 add(new_item); // Add to selection.
61 did = true;
62 }
63 }
64
65 // Reset
66 prefs->setBool("/options/transform/stroke", scale_stroke);
67
68 if (desktop() && !did) {
69 desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No stroked paths</b> in the selection."));
70 }
71
72 if (did && !skip_undo) {
73 Inkscape::DocumentUndo::done(document(), _("Convert stroke to path"), "");
74 } else if (!did && !skip_undo) {
76 }
77
78 return did;
79}
80
81bool
83{
84 if (desktop() && isEmpty()) {
85 desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to simplify."));
86 return false;
87 }
88
90 double threshold = prefs->getDouble("/options/simplifythreshold/value", 0.003);
91 bool justCoalesce = prefs->getBool( "/options/simplifyjustcoalesce/value", false);
92
93 // Keep track of accelerated simplify
94 static gint64 previous_time = 0;
95 static gdouble multiply = 1.0;
96
97 // Get the current time
98 gint64 current_time = g_get_monotonic_time();
99
100 // Was the previous call to this function recent? (<0.5 sec)
101 if (previous_time > 0 && current_time - previous_time < 500000) {
102
103 // add to the threshold 1/2 of its original value
104 multiply += 0.5;
105 threshold *= multiply;
106
107 } else {
108 // reset to the default
109 multiply = 1;
110 }
111
112 // Remember time for next call
113 previous_time = current_time;
114
115 // set "busy" cursor
116 if (desktop()) {
118 }
119
120 Geom::OptRect selectionBbox = visualBounds();
121 if (!selectionBbox) {
122 std::cerr << "ObjectSet::: selection has no visual bounding box!" << std::endl;
123 return false;
124 }
125 double size = L2(selectionBbox->dimensions());
126
127 int pathsSimplified = 0;
128 std::vector<SPItem *> my_items(items().begin(), items().end());
129 for (auto item : my_items) {
130 pathsSimplified += path_simplify(item, threshold, justCoalesce, size);
131 }
132
133 if (pathsSimplified > 0 && !skip_undo) {
134 DocumentUndo::done(document(), _("Simplify"), INKSCAPE_ICON("path-simplify"));
135 }
136
137 if (desktop()) {
139 if (pathsSimplified > 0) {
140 desktop()->messageStack()->flashF(Inkscape::NORMAL_MESSAGE, _("<b>%d</b> paths simplified."), pathsSimplified);
141 } else {
142 desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to simplify in the selection."));
143 }
144 }
145
146 return (pathsSimplified > 0);
147}
148
149/*
150 Local Variables:
151 mode:c++
152 c-file-style:"stroustrup"
153 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
154 indent-tabs-mode:nil
155 fill-column:99
156 End:
157*/
158// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Utility functions related to parsing and validation of XML attributes.
Axis-aligned rectangle that can be empty.
Definition rect.h:203
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
static void cancel(SPDocument *document)
MessageId flash(MessageType type, char const *message)
Temporarily pushes a message onto the stack.
MessageId flashF(MessageType type, char const *format,...) G_GNUC_PRINTF(3
temporarily pushes a message onto the stack using printf-like formatting
SPDesktop * desktop()
Returns the desktop the selection is bound to.
Definition object-set.h:390
SPItemRange items()
Returns a range of selected SPItems.
Definition object-set.h:255
bool add(SPObject *object, bool nosignal=false)
Add an SPObject to the set of selected objects.
bool strokesToPaths(bool legacy=false, bool skip_undo=false)
bool isEmpty()
Returns true if no items are selected.
int size()
Returns size of the selection.
SPDocument * document()
Returns the document the selection is bound to.
Definition object-set.h:397
bool unlinkRecursive(const bool skip_undo=false, const bool force=false, const bool silent=false)
Recursively unlink any clones present in the current selection, including clones which are used to cl...
bool simplifyPaths(bool skip_undo=false)
Geom::OptRect visualBounds() const
Preference storage class.
Definition preferences.h:61
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
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.
void setBool(Glib::ustring const &pref_path, bool value)
Set a Boolean value.
Interface for refcounted XML nodes.
Definition node.h:80
Inkscape::MessageStack * messageStack() const
Definition desktop.h:160
void clearWaitingCursor()
Definition desktop.cpp:1166
void setWaitingCursor()
Definition desktop.cpp:1155
SPObject * getObjectByRepr(Inkscape::XML::Node *repr) const
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
Editable view implementation.
TODO: insert short description here.
Macro for icon names used in Inkscape.
SPItem * item
Geom::Point end
Raw stack of active status messages.
@ ERROR_MESSAGE
Definition message.h:29
@ NORMAL_MESSAGE
Definition message.h:26
@ WARNING_MESSAGE
Definition message.h:28
Inkscape::XML::Node * item_to_paths(SPItem *item, bool legacy, SPItem *context)
Replace item by path objects (a.k.a.
Two related object to path operations:
int path_simplify(SPItem *item, float threshold, bool justCoalesce, double size)
Simplify paths (reduce node count).
Singleton class to access the preferences file in a convenient way.