16#include <glibmm/i18n.h>
46 std::vector<gchar const*> attrsRemoved;
48 const gchar* attrName = g_quark_to_string(it.key);
49 if ((strncmp(
"inkscape:", attrName, 9) == 0) || (strncmp(
"sodipodi:", attrName, 9) == 0)) {
50 attrsRemoved.push_back(attrName);
54 for (
auto & it : attrsRemoved) {
59 std::vector<Inkscape::XML::Node *> nodesRemoved;
61 if((strncmp(
"inkscape:",
child->name(), 9) == 0) || strncmp(
"sodipodi:",
child->name(), 9) == 0) {
62 nodesRemoved.push_back(
child);
67 for (
auto & it : nodesRemoved) {
80 std::vector<Inkscape::XML::Node *> nodesRemoved;
82 if((strncmp(
"i:pgf",
child->name(), 5) == 0)) {
83 nodesRemoved.push_back(
child);
84 g_warning(
"An Adobe proprietary tag was found which is known to cause issues. It was removed before saving.");
89 for (
auto & it : nodesRemoved) {
108 Glib::ustring
const &property)
121 static Glib::RefPtr<Glib::Regex> regex = Glib::Regex::create(
"url\\(#([^\\)]*)\\)");
122 Glib::MatchInfo matchInfo;
123 regex->match(value, matchInfo);
125 if (matchInfo.matches()) {
127 auto marker_name = matchInfo.fetch(1).raw();
132 if (strncmp(marker->
attribute(
"orient"),
"auto-start-reverse", 17)==0) {
135 auto marker_name_reversed = marker_name +
"_reversed";
139 if (!marker_reversed) {
146 marker_reversed->
setAttribute(g_quark_to_string(iter.key), iter.value);
150 marker_reversed->
setAttribute(
"id", marker_name_reversed);
154 const char* refX = marker_reversed->
attribute(
"refX");
155 const char* refY = marker_reversed->
attribute(
"refY");
156 std::string transform =
"rotate(180";
176 marker_reversed->
addChild(group,
nullptr);
181 group->
addChild(new_child,
nullptr);
182 new_child->release();
186 defs->
addChild(marker_reversed, marker);
191 std::string marker_url(
"url(#" + marker_name_reversed +
")");
195 if (property ==
"marker") {
196 std::string marker_old_url(
"url(#" + marker_name +
")");
213 std::string value(
"url(#");
218 std::vector<Inkscape::XML::Node *> to_fix_fill_stroke =
221 for (
auto it: to_fix_fill_stroke) {
229 Glib::ustring marker_fixed_id = repr->
attribute(
"id");
231 marker_fixed_id +=
"_F" +
fill;
234 marker_fixed_id +=
"_S" +
stroke;
239 gchar *normalized_id = g_strdup(marker_fixed_id.c_str());
240 g_strdelimit(normalized_id,
"#%",
'-');
241 g_strdelimit(normalized_id,
"(), \n\t\r",
'.');
242 marker_fixed_id = normalized_id;
243 g_free(normalized_id);
263 if (fill2 ==
"context-fill" ) {
266 if (fill2 ==
"context-stroke" ) {
271 if (stroke2 ==
"context-fill" ) {
274 if (stroke2 ==
"context-stroke" ) {
286 Glib::ustring marker_value =
"url(#" + marker_fixed_id +
")";
299 if (strncmp(
"svg:marker", repr->
name(), 10) == 0) {
303 std::cerr <<
"remove_marker_context_paint: <marker> without 'id'!" << std::endl;
308 bool need_to_fix =
false;
317 if (
fill ==
"context-fill" ||
318 fill ==
"context-stroke" ||
319 stroke ==
"context-fill" ||
320 stroke ==
"context-stroke" ) {
348 if (strncmp(
"svg:text", repr->
name(), 8) == 0) {
355 if (text ==
nullptr) {
356 std::cerr <<
"insert_text_fallback: bad cast" << std::endl;
387 std::vector<Inkscape::XML::Node *> old_children;
389 old_children.push_back(
child);
415 double line_x = line_anchor_point[
Geom::X];
416 double line_y = line_anchor_point[
Geom::Y];
452 Glib::ustring trailing_whitespace;
455 while (it != it_line_end) {
467 std::swap(attrs.
dx, attrs.
dy);
471 Glib::ustring::iterator span_text_start_iter;
475 Glib::ustring style_text = (is<SPString>(source_obj) ? source_obj->
parent : source_obj)
476 ->style->writeIfDiff(text->
style);
477 if (!style_text.empty()) {
484 span_tspan = line_tspan;
491 auto str = cast<SPString>(source_obj);
493 Glib::ustring *
string = &(str->string);
495 Glib::ustring::iterator span_text_end_iter;
497 if (span_end_obj != source_obj) {
499 span_text_end_iter = span_text_start_iter;
501 ++span_text_end_iter;
503 span_text_end_iter =
string->end();
506 if (span_text_start_iter != span_text_end_iter) {
507 Glib::ustring new_string;
508 while (span_text_start_iter != span_text_end_iter)
509 new_string += *span_text_start_iter++;
511 if (it == it_last_span && trim) {
513 const auto s = new_string.find_last_not_of(
" \t");
514 trailing_whitespace = new_string.substr(s+1, new_string.length());
515 new_string.erase(s+1);
534 if (trim && trailing_whitespace.length() != 0) {
553 for (
auto i: old_children) {
573 if (defs ==
nullptr) {
578 bool has_mesh =
false;
580 if (strncmp(
"svg:meshgradient",
child->name(), 16) == 0) {
588 if (has_mesh && script ==
nullptr) {
597#include "extension/internal/polyfill/mesh_compressed.include"
611 if (defs ==
nullptr) {
616 bool has_hatch =
false;
618 if (strncmp(
"svg:hatch",
child->name(), 16) == 0) {
626 if (has_hatch && script ==
nullptr) {
635#include "extension/internal/polyfill/hatch_compressed.include"
652 if (
auto child_item = cast<SPItem>(
child)) {
676 if (
auto child_item = cast<SPItem>(
child)) {
696const Glib::ustring
SECTION = NC_(
"Action Section",
"Processing");
701 {
"doc.set-svg-version-1", N_(
"Set SVG Version to 1.1"),
SECTION, N_(
"Set the document's SVG version to 1.1") },
702 {
"doc.set-svg-version-2", N_(
"Set SVG Version to 2.0"),
SECTION, N_(
"Set the document's SVG version to 2.0") },
703 {
"doc.set-inkscape-version", N_(
"Set Inkscape Version"),
SECTION, N_(
"Add the Inkscape version to the document") },
704 {
"doc.prune-inkscape-namespaces", N_(
"Prune Inkscape Namespaces"),
SECTION, N_(
"Remove any Inkscape-specific SVG data") },
705 {
"doc.prune-proprietary-namespaces", N_(
"Prune Proprietary Namespaces"),
SECTION, N_(
"Remove any known proprietary SVG data") },
707 {
"doc.reverse-auto-start-markers", N_(
"Reverse Auto Start Markers"),
SECTION, N_(
"Remove auto start positions from markers") },
708 {
"doc.remove-all-transforms", N_(
"Try to Remove All Transforms"),
SECTION, N_(
"Attempt to remove all transforms from all shapes") },
709 {
"doc.remove-marker-context-paint", N_(
"Remove Marker Context Paint"),
SECTION, N_(
"Remove context paints from markers") },
711 {
"doc.insert-text-fallback", N_(
"Insert Text Fallback"),
SECTION, N_(
"Replace SVG2 text with SVG1.1 text") },
712 {
"doc.insert-mesh-polyfill", N_(
"Insert Mesh Polyfill"),
SECTION, N_(
"Insert JavaScript for rendering meshes") },
713 {
"doc.insert-hatch-polyfill", N_(
"Insert Hatch Polyfill"),
SECTION, N_(
"Insert JavaScript for rendering hatches") },
715 {
"doc.all-clones-to-objects", N_(
"Unlink All Clones"),
SECTION, N_(
"Recursively unlink all clones and symbols") },
716 {
"doc.all-objects-to-paths", N_(
"All Objects to Paths"),
SECTION, N_(
"Turn all shapes recursively into path elements") },
717 {
"doc.add-strokes-to-paths", N_(
"All Strokes to Paths"),
SECTION, N_(
"Turn all strokes recursively into fill-only paths") },
718 {
"doc.normalize-all-paths", N_(
"Normalize Path Data"),
SECTION, N_(
"Make all paths absolute and predictable") },
720 {
"doc.insert-bounding-boxes", N_(
"Annotate all Bounding Boxes"),
SECTION, N_(
"Annotate every shape and group with its current bounding box (not kept up to date)") },
721 {
"doc.insert-path-data", N_(
"Annotate all Shape Paths"),
SECTION, N_(
"Annotate every non-path shape with their equivalent path string (not kept up to date)") },
723 {
"doc.vacuum-defs", N_(
"Clean up Document"),
SECTION, N_(
"Remove unused definitions (gradients, etc.)") },
732 group->add_action(
"set-svg-version-2", [doc]() {
735 rdoc->setAttribute(
"version",
"2.0");
737 group->add_action(
"set-svg-version-1", [doc]() {
741 group->add_action(
"set-inkscape-version", [doc]() {
747 group->add_action(
"reverse-auto-start-markers", [doc]() {
752 group->add_action(
"remove-all-transforms", [doc]() {
760 group->add_action(
"all-clones-to-objects", [doc]() {
763 selection.unlinkRecursive(
true,
false,
true);
765 group->add_action(
"all-objects-to-paths", [doc]() {
766 std::vector<SPItem*> selected;
767 std::vector<Inkscape::XML::Node*> to_select;
770 group->add_action(
"add-strokes-to-paths", [doc]() {
776 group->add_action(
"vacuum-defs", [doc]() { doc->
vacuumDocument(); });
void insert_hatch_polyfill(Inkscape::XML::Node *repr)
void insert_bounding_boxes(SPItem *item)
Appends a visual box, and an optional geometric box to each SPItem recursively.
const Glib::ustring SECTION
void prune_inkscape_from_node(Inkscape::XML::Node *repr)
void normalize_all_paths(Inkscape::XML::Node *node)
Makes paths more predictable for better processing.
void insert_text_fallback(Inkscape::XML::Node *repr, const SPDocument *original_doc, Inkscape::XML::Node *defs)
void insert_mesh_polyfill(Inkscape::XML::Node *repr)
void add_actions_processing(SPDocument *doc)
static void remove_marker_auto_start_reverse(Inkscape::XML::Node *repr, Inkscape::XML::Node *defs, Glib::ustring const &property)
Create new markers where necessary to simulate the SVG 2 marker attribute 'orient' value 'auto-start-...
static void prune_proprietary_from_node(Inkscape::XML::Node *repr)
std::vector< std::vector< Glib::ustring > > doc_svg_processing_actions
void insert_path_data(SPItem *item)
Appends the shape path, if available, to any SPShape recursively.
void remove_marker_context_paint(Inkscape::XML::Node *repr, Inkscape::XML::Node *defs, Glib::ustring property)
TODO: insert short description here.
Two-dimensional point that doubles as a vector.
static InkscapeApplication * instance()
Singleton instance.
Holds a position within the glyph output of Layout.
void simulateLayoutUsingKerning(iterator const &from, iterator const &to, OptionalTextTagAttrs *result) const
Returns kerning information which could cause the current output to be exactly reproduced if the lett...
bool isHidden(iterator const &it) const
Returns true if the text at it is hidden (i.e.
Geom::Point characterAnchorPoint(iterator const &it) const
For latin text, the left side of the character, on the baseline.
int iteratorToCharIndex(iterator const &it) const
Returns the character index from the start of the flow represented by the given iterator.
iterator end() const
Returns an iterator pointing just past the end of the last glyph, which is also just past the end of ...
void getSourceOfCharacter(iterator const &it, SPObject **source, Glib::ustring::iterator *text_iterator=nullptr) const
Discovers where the character pointed to by it came from, by retrieving the object that was passed to...
iterator begin() const
Returns an iterator pointing at the first glyph of the flowed output.
Interface for refcounted XML nodes.
virtual Node * next()=0
Get the next sibling of this node.
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.
virtual char const * name() const =0
Get the name of the element node.
virtual const AttributeVector & attributeList() const =0
Get a list of the node's attributes.
double getAttributeDouble(Util::const_char_ptr key, double default_value=0.0) const
void setAttributeOrRemoveIfEmpty(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
Change an attribute of this node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
virtual Node * duplicate(Document *doc) const =0
Create a duplicate of this node.
virtual Node * firstChild()=0
Get the first child of this node.
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.
virtual Document * document()=0
Get the node's associated document.
virtual void removeChild(Node *child)=0
Remove a child of this node.
virtual unsigned childCount() const =0
Get the number of children of this node.
virtual NodeType type() const =0
Get the type of the node.
bool setAttributeSvgDouble(Util::const_char_ptr key, double val)
For attributes where an exponent is allowed.
virtual Node * root()=0
Get the root node of this node's document.
Typed SVG document implementation.
Glib::RefPtr< Gio::SimpleActionGroup > getActionGroup()
SPRoot * getRoot()
Returns our SPRoot.
SPObject * getObjectById(std::string const &id) const
Inkscape::XML::Node * getReprRoot()
unsigned int vacuumDocument()
Remove unused definitions etc.
const SPDocument * getOriginalDocument() const
SPDefs * getDefs()
Return the main defs object for the document.
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
Geom::Scale getDocumentScale(bool computed=true) const
Returns document scale as defined by width/height (in pixels) and viewBox (real world to user-units).
void removeTransformsRecursively(SPObject const *root) override
Base class for visual SVG elements.
void setHidden(bool hidden)
Geom::OptRect geometricBounds(Geom::Affine const &transform=Geom::identity()) const
Get item's geometric bounding box in this item's coordinate system.
Geom::Affine i2doc_affine() const
Returns the accumulated transformation of the item and all its ancestors, including root's viewport.
Geom::OptRect visualBounds(Geom::Affine const &transform=Geom::identity(), bool wfilter=true, bool wclip=true, bool wmask=true) const
Get item's visual bounding box in this item's coordinate system.
SPObject is an abstract base class of all of the document nodes at the SVG document level.
void setAttributeOrRemoveIfEmpty(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
void setAttribute(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
std::vector< SPObject * > childList(bool add_ref, Action action=ActionGeneral)
Retrieves the children as a std vector object, optionally ref'ing the children in the process,...
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
T< SPAttr::TEXT_ANCHOR, SPIEnum< SPTextAnchor > > text_anchor
Anchor of the text (svg1.1 10.9.1)
bool has_inline_size() const
bool has_shape_inside() const
void rebuildLayout()
Completely recalculates the layout.
Inkscape::Text::Layout layout
bool is_horizontal() const
void writeTo(Inkscape::XML::Node *node) const
Write out all the contents of attributes to the given node.
std::shared_ptr< Css const > css
Inkscape::XML::Node * node
Mini static library that contains the version of Inkscape.
static R & release(R &r)
Decrements the reference count of a anchored object.
@ ELEMENT_NODE
Regular element node, e.g. <group />.
char const * version_string
full version string
bool sp_item_list_to_curves(const std::vector< SPItem * > &items, std::vector< SPItem * > &selected, std::vector< Inkscape::XML::Node * > &to_select, bool skip_all_lpeitems)
bool item_find_paths(const SPItem *item, Geom::PathVector &fill, Geom::PathVector &stroke, bool bbox_only)
Given an item, find a path representing the fill and a path representing the stroke.
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:
SPCSSAttr * sp_repr_css_attr_inherited(Node const *repr, gchar const *attr)
Creates a new SPCSSAttr with one attribute whose value is determined by cascading.
void sp_repr_css_set(Node *repr, SPCSSAttr *css, gchar const *attr)
Sets an attribute (e.g.
void sp_repr_css_attr_unref(SPCSSAttr *css)
Unreferences an SPCSSAttr (will be garbage collected if no references remain).
SPCSSAttr * sp_repr_css_attr(Node const *repr, gchar const *attr)
Creates a new SPCSSAttr with one attribute (i.e.
char const * sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval)
Returns a character string of the value of a given style property or a default value if the attribute...
void sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name)
Set a style property to "inkscape:unset".
void sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value)
Set a style property to a new value (e.g.
Inkscape::XML::Node * sp_repr_lookup_child(Inkscape::XML::Node *repr, gchar const *key, gchar const *value)
Find an element node using an unique attribute.
Inkscape::XML::Node const * sp_repr_lookup_name(Inkscape::XML::Node const *repr, gchar const *name, gint maxdepth)
std::vector< Inkscape::XML::Node * > sp_repr_lookup_property_many(Inkscape::XML::Node *repr, Glib::ustring const &property, Glib::ustring const &value, int maxdepth)
SVG <image> implementation.
SPRoot: SVG <svg> implementation.
The optional attributes which can be applied to a SVG text or related tag.
std::vector< SVGLength > dy
std::vector< SVGLength > dx
virtual Node * createTextNode(char const *content)=0
virtual Node * createElement(char const *name)=0
@ SP_CSS_TEXT_ANCHOR_START
SPStyle - a style object for SPItem objects.
Geom::PathVector sp_svg_read_pathv(char const *str)
static void sp_svg_write_path(Inkscape::SVG::PathString &str, Geom::Path const &p, bool normalize=false)