From f3268bc85d510202a440615c2f1f66bb08262194 Mon Sep 17 00:00:00 2001 From: Anshudhar Date: Wed, 16 Jun 2021 16:58:21 +0530 Subject: [PATCH] modified svg export action --- src/io/file-export-cmd.cpp | 73 ++++++++++++++++++++++++++++++-------- src/object/sp-object.cpp | 42 ++++++++++++++++++++++ src/object/sp-object.h | 38 ++++++++++---------- 3 files changed, 119 insertions(+), 34 deletions(-) diff --git a/src/io/file-export-cmd.cpp b/src/io/file-export-cmd.cpp index 3be680838f..271842232b 100644 --- a/src/io/file-export-cmd.cpp +++ b/src/io/file-export-cmd.cpp @@ -367,33 +367,75 @@ int InkFileExportCmd::do_export_svg(SPDocument *doc, std::string const &filename objects.emplace_back(); // So we do loop at least once for root. } - for (auto object : objects) { + if(export_id_only){ + for (auto object : objects) { + std::string filename_out = get_filename_out(filename_in, Glib::filename_from_utf8(object)); + if (filename_out.empty()) { + return 1; + } + SPDocument *copy_doc = (doc->copy()).get(); - std::string filename_out = get_filename_out(filename_in, Glib::filename_from_utf8(object)); - if (filename_out.empty()) { - return 1; - } + if(!object.empty()) { + copy_doc->ensureUpToDate(); - if(!object.empty()) { + // "crop" the document to the specified object, cleaning as we go. + SPObject *obj = copy_doc->getObjectById(object); + if (obj == nullptr) { + std::cerr << "InkFileExportCmd::do_export_svg: Object " << object << " not found in document, nothing to export." << std::endl; + return 1; + } + if (export_id_only) { + // If -j then remove all other objects to complete the "crop" + copy_doc->getRoot()->cropToObject(obj); + } + if (!(export_area_page || export_area_drawing)) { + Inkscape::ObjectSet s(copy_doc); + s.set(obj); + s.fitCanvas(export_margin ? true : false); + } + } + g_assert(std::string(extension.get_extension()) == ".svg"); + try { + Inkscape::Extension::save(dynamic_cast(&extension), copy_doc, + filename_out.c_str(), false, false, false, + export_plain_svg ? Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY + : Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG); + } catch (Inkscape::Extension::Output::save_failed &e) { + std::cerr << "InkFileExportCmd::do_export_svg: Failed to save " << (export_plain_svg ? "" : "Inkscape") + << " SVG to: " << filename_out << std::endl; + return 1; + } + } + } else { + std::vector objects_list_export_id; + Inkscape::ObjectSet s(doc); + + for (auto object : objects) { doc->ensureUpToDate(); - - // "crop" the document to the specified object, cleaning as we go. SPObject *obj = doc->getObjectById(object); if (obj == nullptr) { std::cerr << "InkFileExportCmd::do_export_svg: Object " << object << " not found in document, nothing to export." << std::endl; return 1; } - if (export_id_only) { - // If -j then remove all other objects to complete the "crop" - doc->getRoot()->cropToObject(obj); - } if (!(export_area_page || export_area_drawing)) { - Inkscape::ObjectSet s(doc); - s.set(obj); - s.fitCanvas(export_margin ? true : false); + s.add(obj,true); } + objects_list_export_id.push_back(obj); } + std::string filename_out = get_filename_out(filename_in, Glib::filename_from_utf8("object")); + if (filename_out.empty()) { + std::cerr << "InkFileExportCmd::do_export_svg: FileName" << std::endl; + return 1; + } + + doc->getRoot()->cropToObjects(objects_list_export_id); + if (!(export_area_page || export_area_drawing)) { + s.fitCanvas(export_margin ? true : false); + } + g_assert(std::string(extension.get_extension()) == ".svg"); + + try { Inkscape::Extension::save(dynamic_cast(&extension), doc, filename_out.c_str(), false, false, false, @@ -405,6 +447,7 @@ int InkFileExportCmd::do_export_svg(SPDocument *doc, std::string const &filename return 1; } } + return 0; } diff --git a/src/object/sp-object.cpp b/src/object/sp-object.cpp index d04339c6fd..c816131b65 100644 --- a/src/object/sp-object.cpp +++ b/src/object/sp-object.cpp @@ -522,6 +522,48 @@ void SPObject::cropToObject(SPObject *except) } } +// Removes objects which are not related to given list of objects. +// Use Case: Group[MyRect1 , MyRect2] , MyRect3 +// List Provided: MyRect1, MyRect3 +// Output doc: Group[MyRect1], MyRect3 +// List Provided: MyRect1, Group +// Output doc: Group[MyRect1, MyRect2] (notice MyRect2 is not deleted as it is related to Group) + +void SPObject::cropToObjects(std::vector except_objects) +{ + if(except_objects.empty()){ + return; + } + std::vector toDelete; + for (auto& child: children) { + if (SP_IS_ITEM(&child)) { + std::vector except_in_child; + bool child_delete_flag = true; + for (auto except : except_objects) { + if(&child == except){ + child_delete_flag = false; + except_in_child.clear(); + break; + } + if (child.isAncestorOf(except)) { + except_in_child.push_back(except); + child_delete_flag = false; + } + } + if(child_delete_flag){ + sp_object_ref(&child, nullptr); + toDelete.push_back(&child); + }else{ + child.cropToObjects(except_in_child); + } + } + } + for (auto & i : toDelete) { + i->deleteObject(true, true); + sp_object_unref(i, nullptr); + } +} + void SPObject::attach(SPObject *object, SPObject *prev) { //g_return_if_fail(parent != NULL); diff --git a/src/object/sp-object.h b/src/object/sp-object.h index 43cd9c2dec..9c7bb05f21 100644 --- a/src/object/sp-object.h +++ b/src/object/sp-object.h @@ -460,25 +460,25 @@ public: * Removes all children except for the given object, it's children and it's ancesstors. */ void cropToObject(SPObject *except); - - /** - * Connects a slot to be called when an object is deleted. - * - * This connects a slot to an object's internal delete signal, which is invoked when the object - * is deleted - * - * The signal is mainly useful for e.g. knowing when to break hrefs or dissociate clones. - * - * @param slot the slot to connect - * - * @see SPObject::deleteObject - */ - sigc::connection connectDelete(sigc::slot slot) { - return _delete_signal.connect(slot); - } - - sigc::connection connectPositionChanged(sigc::slot slot) { - return _position_changed_signal.connect(slot); + void cropToObjects(std::vector except_objects); + + /** + * Connects a slot to be called when an object is deleted. + * + * This connects a slot to an object's internal delete signal, which is invoked when the object + * is deleted + * + * The signal is mainly useful for e.g. knowing when to break hrefs or dissociate clones. + * + * @param slot the slot to connect + * + * @see SPObject::deleteObject + */ + sigc::connection connectDelete(sigc::slot slot) { return _delete_signal.connect(slot); } + + sigc::connection connectPositionChanged(sigc::slot slot) + { + return _position_changed_signal.connect(slot); } /** -- GitLab