Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
path-simplify.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Authors:
6 * see git history
7 * Created by fred on Fri Dec 05 2003.
8 * tweaked endlessly by bulia byak <buliabyak@users.sf.net>
9 *
10 * Copyright (C) 2018 Authors
11 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
12 */
13
14#ifdef HAVE_CONFIG_H
15#endif
16
17#include <vector>
18
19#include "path-simplify.h"
20#include "path-util.h"
21
22#include "document-undo.h"
23#include "preferences.h"
24
25#include "livarot/Path.h"
26
28#include "object/sp-path.h"
29
31
32// Return number of paths simplified (can be greater than one if group).
33int
34path_simplify(SPItem *item, float threshold, bool justCoalesce, double size)
35{
36 //If this is a group, do the children instead
37 auto group = cast<SPGroup>(item);
38 if (group) {
39 int pathsSimplified = 0;
40 std::vector<SPItem*> items = group->item_list();
41 for (auto item : items) {
42 pathsSimplified += path_simplify(item, threshold, justCoalesce, size);
43 }
44 return pathsSimplified;
45 }
46
47 auto path = cast<SPPath>(item);
48 if (!path) {
49 return 0;
50 }
51
52 std::string orig_path_str;
53 if (path->getRepr()->attribute("d")) {
54 orig_path_str = path->getRepr()->attribute("d");
55 }
56
57 int nodes_before_simplify = path->nodesInPath();
58
59 // There is actually no option in the preferences dialog for this!
61 bool simplifyIndividualPaths = prefs->getBool("/options/simplifyindividualpaths/value");
62 if (simplifyIndividualPaths) {
64 if (itemBbox) {
65 size = L2(itemBbox->dimensions());
66 } else {
67 size = 0;
68 }
69 }
70
71 // Correct virtual size by full transform (bug #166937).
73
74 // Save the transform, to re-apply it after simplification.
75 Geom::Affine const transform(item->transform);
76
77 /*
78 reset the transform, effectively transforming the item by transform.inverse();
79 this is necessary so that the item is transformed twice back and forth,
80 allowing all compensations to cancel out regardless of the preferences
81 */
83
84 // SPLivarot: Start -----------------
85
86 // Get path to simplify (note that the path *before* LPE calculation is needed)
87 auto orig = Path_for_item_before_LPE(item, false);
88 if (!orig) {
89 return 0;
90 }
91
92 if ( justCoalesce ) {
93 orig->Coalesce(threshold * size);
94 } else {
95 orig->ConvertEvenLines(threshold * size);
96 orig->Simplify(threshold * size);
97 }
98
99 // Path
100 auto simplified_path_str = orig->svg_dump_path();
101
102 // SPLivarot: End -------------------
103
104 char const *patheffect = item->getRepr()->attribute("inkscape:path-effect");
105 if (patheffect) {
106 item->setAttribute("inkscape:original-d", simplified_path_str.c_str());
107 } else {
108 item->setAttribute("d", simplified_path_str.c_str());
109 }
110
111 // reapply the transform
112 item->doWriteTransform(transform);
113
114 // remove irrelevant old nodetypes attibute
115 item->removeAttribute("sodipodi:nodetypes");
116
117 int nodes_after_simplify = path->nodesInPath();
118
119 if (nodes_before_simplify < nodes_after_simplify) {
120 if (patheffect) {
121 item->setAttribute("inkscape:original-d", orig_path_str.c_str());
122 } else {
123 item->setAttribute("d", orig_path_str.c_str());
124 }
125 return 0;
126 }
127
128 return 1;
129}
130
131/*
132 Local Variables:
133 mode:c++
134 c-file-style:"stroustrup"
135 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
136 indent-tabs-mode:nil
137 fill-column:99
138 End:
139*/
140// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
TODO: insert short description here.
3x3 matrix representing an affine transformation.
Definition affine.h:70
Coord descrim() const
Calculate the descriminant.
Definition affine.cpp:434
Axis-aligned rectangle that can be empty.
Definition rect.h:203
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.
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
Base class for visual SVG elements.
Definition sp-item.h:109
Geom::OptRect documentVisualBounds() const
Get item's visual bbox in document coordinate system.
Definition sp-item.cpp:1025
Geom::Affine transform
Definition sp-item.h:138
Geom::Affine i2doc_affine() const
Returns the accumulated transformation of the item and all its ancestors, including root's viewport.
Definition sp-item.cpp:1823
void doWriteTransform(Geom::Affine const &transform, Geom::Affine const *adv=nullptr, bool compensate=true)
Set a new transform on an object.
Definition sp-item.cpp:1665
void setAttribute(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
void removeAttribute(char const *key)
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
Geom::Point orig
TODO: insert short description here.
SPItem * item
Affine identity()
Create an identity matrix.
Definition affine.h:210
int path_simplify(SPItem *item, float threshold, bool justCoalesce, double size)
Simplify paths (reduce node count).
std::unique_ptr< Path > Path_for_item_before_LPE(SPItem *item, bool doTransformation, bool transformFull)
Creates a Livarot Path object from the SPItem.
Definition path-util.cpp:45
Path utilities.
int size
Singleton class to access the preferences file in a convenient way.
GList * items