summaryrefslogtreecommitdiffstats
path: root/src/io
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2018-11-19 16:05:51 +0000
committerTavmjong Bah <tavmjong@free.fr>2018-11-19 16:05:51 +0000
commit43169155e4e6f099a5c09e58a560f911d9250464 (patch)
treefedab2008903617563de4e0622eb77cef45c87a0 /src/io
parentRebase (diff)
downloadinkscape-43169155e4e6f099a5c09e58a560f911d9250464.tar.gz
inkscape-43169155e4e6f099a5c09e58a560f911d9250464.zip
Allow multiple semi-colon separated entries in --export-id; each entry will be exported to its own file.
Using a semi-colon allows the future possibility of allowing the user to use a comma separated entry to select more than one object to export at the same time.
Diffstat (limited to 'src/io')
-rw-r--r--src/io/file-export-cmd.cpp620
-rw-r--r--src/io/file-export-cmd.h10
2 files changed, 347 insertions, 283 deletions
diff --git a/src/io/file-export-cmd.cpp b/src/io/file-export-cmd.cpp
index 46847634b..07366574d 100644
--- a/src/io/file-export-cmd.cpp
+++ b/src/io/file-export-cmd.cpp
@@ -62,57 +62,37 @@ InkFileExportCmd::InkFileExportCmd()
void
InkFileExportCmd::do_export(SPDocument* doc, std::string filename_in)
{
-
- std::string filename_out = get_filename_out(filename_in);
-
- // We need a valid file name to write to unless we're using PNG export hints.
- if (!(export_type == "png" && export_use_hints)) {
-
- // Check for file name.
- if (filename_out.empty()) {
- std::cerr << "InkFileExportCmd::do_export: Could not determine ouput file name!" << std::endl;
- return;
- }
-
- // Check if directory exists.
- std::string directory = Glib::path_get_dirname(filename_out);
- if (!Glib::file_test(directory, Glib::FILE_TEST_IS_DIR)) {
- std::cerr << "InkFileExportCmd::do_export: File path includes directory that does not exist! " << directory << std::endl;
- return;
- }
- }
-
if (export_type == "svg") {
- do_export_svg(doc, filename_out);
+ do_export_svg(doc, filename_in);
} else if (export_type == "png") {
- do_export_png(doc, filename_out);
+ do_export_png(doc, filename_in);
} else if (export_type == "ps") {
- do_export_ps_pdf(doc, filename_out, "image/x-postscript");
+ do_export_ps_pdf(doc, filename_in, "image/x-postscript");
} else if (export_type == "eps") {
- do_export_ps_pdf(doc, filename_out, "image/x-e-postscript");
+ do_export_ps_pdf(doc, filename_in, "image/x-e-postscript");
} else if (export_type == "pdf") {
- do_export_ps_pdf(doc, filename_out, "application/pdf");
+ do_export_ps_pdf(doc, filename_in, "application/pdf");
} else if (export_type == "emf") {
- do_export_win_metafile(doc, filename_out, "image/x-emf");
+ do_export_win_metafile(doc, filename_in, "image/x-emf");
} else if (export_type == "wmf") {
- do_export_win_metafile(doc, filename_out, "image/x-wmf");
+ do_export_win_metafile(doc, filename_in, "image/x-wmf");
} else if (export_type == "xaml") {
- do_export_win_metafile(doc, filename_out, "text/xml+xaml");
+ do_export_win_metafile(doc, filename_in, "text/xml+xaml");
} else {
@@ -120,8 +100,10 @@ InkFileExportCmd::do_export(SPDocument* doc, std::string filename_in)
}
}
+
+// File names use std::string. HTML5 and presumably SVG 2 allows UTF-8 characters. Do we need to convert "object_id" here?
std::string
-InkFileExportCmd::get_filename_out(std::string filename_in)
+InkFileExportCmd::get_filename_out(std::string filename_in, std::string object_id)
{
if (export_type != "svg" &&
@@ -140,6 +122,7 @@ InkFileExportCmd::get_filename_out(std::string filename_in)
// Writing to pipe.
if (export_filename == "-") {
+ // No need to check if valid file name.
return export_filename;
}
@@ -171,17 +154,35 @@ InkFileExportCmd::get_filename_out(std::string filename_in)
}
std::string extension = filename_in.substr(extension_pos+1);
- if (export_type == extension) {
- if (export_overwrite) {
- return filename_in;
- } else {
- // Add extra characters to filename.
- filename_in.insert(extension_pos, "_out");
- return filename_in;
- }
+ if (export_overwrite && export_type == extension) {
+ return filename_in;
} else {
- return (filename_in.substr(0,extension_pos+1) + export_type);
+ std::string tag;
+ if (export_type == extension) {
+ tag = "_out";
+ }
+ if (!object_id.empty()) {
+ tag = "_" + object_id;
+ }
+ return (filename_in.substr(0,extension_pos) + tag + "." + export_type);
}
+
+ // We need a valid file name to write to unless we're using PNG export hints.
+ // if (!(export_type == "png" && export_use_hints)) {
+
+ // // Check for file name.
+ // if (filename_out.empty()) {
+ // std::cerr << "InkFileExportCmd::do_export: Could not determine ouput file name!" << std::endl;
+ // return (std::string());
+ // }
+
+ // // Check if directory exists.
+ // std::string directory = Glib::path_get_dirname(filename_out);
+ // if (!Glib::file_test(directory, Glib::FILE_TEST_IS_DIR)) {
+ // std::cerr << "InkFileExportCmd::do_export: File path includes directory that does not exist! " << directory << std::endl;
+ // return (std::string());
+ // }
+ // }
}
/**
@@ -190,8 +191,9 @@ InkFileExportCmd::get_filename_out(std::string filename_in)
* \param doc Document to export.
*/
int
-InkFileExportCmd::do_export_svg(SPDocument* doc, std::string filename_out)
+InkFileExportCmd::do_export_svg(SPDocument* doc, std::string filename_in)
{
+ // Start with options that are once per document.
if (export_text_to_path) {
std::vector<SPItem*> items;
SPRoot *root = doc->getRoot();
@@ -229,45 +231,59 @@ InkFileExportCmd::do_export_svg(SPDocument* doc, std::string filename_out)
fit_canvas_to_drawing(doc, export_margin != 0 ? true : false);
}
- if(!export_id.empty()) {
- doc->ensureUpToDate();
- // "crop" the document to the specified object, cleaning as we go.
- SPObject *obj = doc->getObjectById(export_id);
- if (export_id_only) {
- // If -j then remove all other objects to complete the "crop"
- doc->getRoot()->cropToObject(obj);
- }
- Inkscape::ObjectSet s(doc);
- s.set(obj);
- if (!export_area_page) {
- s.fitCanvas(export_margin ? true : false);
- }
+ // Export each object in list (or root if empty). Use ';' so in future it could be possible to selected multiple objects to export together.
+ std::vector<Glib::ustring> objects = Glib::Regex::split_simple("\\s*;\\s*", export_id);
+ if (objects.empty()) {
+ objects.push_back(Glib::ustring()); // So we do loop at least once for root.
}
- int ret = 0;
- if (export_plain_svg) {
+ for (auto object : objects) {
- try {
- Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.plain"), doc, filename_out.c_str(), false,
- false, false, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY);
- } catch (Inkscape::Extension::Output::save_failed &e) {
- std::cerr << "InkFileExportCmd::do_export_svg: Failed to save SVG to: " << filename_out << std::endl;
- ret = 1;
+ std::string filename_out = get_filename_out(filename_in, object);
+ if (filename_out.empty()) {
+ return 1;
}
- } else {
+ if(!object.empty()) {
+ doc->ensureUpToDate();
- // Export as inkscape SVG.
- try {
- Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.inkscape"), doc, filename_out.c_str(), false,
- false, false, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG);
- } catch (Inkscape::Extension::Output::save_failed &e) {
- std::cerr << "InkFileExportCmd::do_export_svg: Failed to save Inkscape SVG to: " << filename_out << std::endl;
- ret = 1;
+ // "crop" the document to the specified object, cleaning as we go.
+ SPObject *obj = doc->getObjectById(object);
+ if (export_id_only) {
+ // If -j then remove all other objects to complete the "crop"
+ doc->getRoot()->cropToObject(obj);
+ }
+ Inkscape::ObjectSet s(doc);
+ s.set(obj);
+ if (!export_area_page) {
+ s.fitCanvas(export_margin ? true : false);
+ }
+ }
+
+ if (export_plain_svg) {
+
+ try {
+ Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.plain"), doc, filename_out.c_str(), false,
+ false, false, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY);
+ } catch (Inkscape::Extension::Output::save_failed &e) {
+ std::cerr << "InkFileExportCmd::do_export_svg: Failed to save SVG to: " << filename_out << std::endl;
+ return 1;
+ }
+
+ } else {
+
+ // Export as inkscape SVG.
+ try {
+ Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.inkscape"), doc, filename_out.c_str(), false,
+ false, false, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG);
+ } catch (Inkscape::Extension::Output::save_failed &e) {
+ std::cerr << "InkFileExportCmd::do_export_svg: Failed to save Inkscape SVG to: " << filename_out << std::endl;
+ return 1;
+ }
}
}
- return ret;
+ return 0;
}
@@ -279,223 +295,249 @@ InkFileExportCmd::do_export_svg(SPDocument* doc, std::string filename_out)
int
InkFileExportCmd::do_export_png(SPDocument *doc, std::string filename_in)
{
- std::string filename = filename_in;
-
bool filename_from_hint = false;
gdouble dpi = 0.0;
if (export_use_hints && (export_id.empty() && !export_area_drawing)) {
- g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
+ std::cerr << "InkFileExportCmd: "
+ << "--export-use-hints can only be used with --export-id or --export-area-drawing; ignored." << std::endl;;
}
- std::vector<SPItem*> items;
+ // Export each object in list (or root if empty). Use ';' so in future it could be possible to selected multiple objects to export together.
+ std::vector<Glib::ustring> objects = Glib::Regex::split_simple("\\s*;\\s*", export_id);
+ if (objects.empty()) {
+ objects.push_back(Glib::ustring()); // So we do loop at least once for root.
+ }
- // Find export area.
- Geom::Rect area;
- if (!export_id.empty() || export_area_drawing) {
+ for (auto object : objects) {
- SPObject *o = nullptr;
- SPObject *o_area = nullptr;
- if (!export_id.empty() && export_area_drawing) {
- o = doc->getObjectById(export_id);
- o_area = doc->getRoot();
- } else if (!export_id.empty()) {
- o = doc->getObjectById(export_id);
- o_area = o;
- } else if (export_area_drawing) {
- o = doc->getRoot();
- o_area = o;
- }
+ std::string filename_out = get_filename_out(filename_in, object);
- if (o) {
- if (!SP_IS_ITEM (o)) {
- g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", export_id);
- return 1;
+ std::vector<SPItem*> items;
+
+ // Find export area.
+ Geom::Rect area;
+ if (!object.empty() || export_area_drawing) {
+
+ SPObject *o = nullptr;
+ SPObject *o_area = nullptr;
+ if (!object.empty() && export_area_drawing) {
+ o = doc->getObjectById(object);
+ o_area = doc->getRoot();
+ } else if (!object.empty()) {
+ o = doc->getObjectById(object);
+ o_area = o;
+ } else if (export_area_drawing) {
+ o = doc->getRoot();
+ o_area = o;
}
- items.push_back(SP_ITEM(o));
+ if (o) {
+ if (!SP_IS_ITEM (o)) {
+ std::cerr << "InkFileExportCmd::do_export_png: "
+ << "Object with id=" << object
+ << " is not a visible item. Nothing exported." << std::endl;
+ return 1;
+ }
- if (export_id_only) {
-// do_print_message("Exporting only object with id=\"%s\"; all other objects hidden\n", export_id);
- }
+ items.push_back(SP_ITEM(o));
- if (export_use_hints) {
+ if (export_id_only) {
+ std::cout << "Exporting only object with id=\""
+ << object << "\"; all other objects hidden." << std::endl;
+ }
- // retrieve export filename hint
- const gchar *fn_hint = o->getRepr()->attribute("inkscape:export-filename");
- if (fn_hint) {
- if (!filename.empty()) {
- g_warning ("Using export filename from the command line. Filename hint %s is ignored.", fn_hint);
+ if (export_use_hints) {
+
+ // Retrieve export filename hint.
+ const gchar *fn_hint = o->getRepr()->attribute("inkscape:export-filename");
+ if (fn_hint) {
+ if (!filename_out.empty()) {
+ std::cerr << "InkFileExport::do_export_png: "
+ << "Using export filename from the command line."
+ << " Filename hint " << fn_hint << " is ignored.";
+ } else {
+ filename_out = fn_hint;
+ filename_from_hint = true;
+ }
} else {
- filename = fn_hint;
- filename_from_hint = true;
+ std::cerr << "InkFileExport::do_export_png: "
+ << "Export filename hint not found for the object.";
}
- } else {
- g_warning ("Export filename hint not found for the object.");
- }
- // retrieve export dpi hints
- const gchar *dpi_hint = o->getRepr()->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
- if (dpi_hint) {
- if (export_dpi || export_width || export_height) {
- g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
+ // Retrieve export dpi hint. Only xdpi as ydpi is always the same now.
+ const gchar *dpi_hint = o->getRepr()->attribute("inkscape:export-xdpi");
+ if (dpi_hint) {
+ if (export_dpi || export_width || export_height) {
+ std::cerr << "InkFileExport::do_export_png: "
+ << "Using bitmap dimensions from the command line "
+ << "(--export-dpi, --export-width, or --export-height). "
+ << "DPI hint " << dpi_hint << " is ignored.";
+ } else {
+ dpi = atof(dpi_hint);
+ }
} else {
- dpi = atof(dpi_hint);
+ std::cerr << "InkFileExport::do_export_png: "
+ << "Export DPI hint not found for the object.";
}
+ }
+
+ // Write object bbox to area.
+ doc->ensureUpToDate();
+ Geom::OptRect areaMaybe = static_cast<SPItem *>(o_area)->desktopVisualBounds();
+ if (areaMaybe) {
+ area = *areaMaybe;
} else {
- g_warning ("Export DPI hint not found for the object.");
+ std::cerr << "InkFileExport::do_export_png: "
+ << "Unable to determine a valid bounding box. Nothing exported.";
+ return 1;
}
+ } else {
+ std::cerr << "InkFileExport::do_export_png: "
+ << "Object with id=\"" << object
+ << "\" was not found in the document. Nothing exported.";
+ return 1;
}
+ }
- // write object bbox to area
- doc->ensureUpToDate();
- Geom::OptRect areaMaybe = static_cast<SPItem *>(o_area)->desktopVisualBounds();
- if (areaMaybe) {
- area = *areaMaybe;
- } else {
- g_warning("Unable to determine a valid bounding box. Nothing exported.");
+ if (!export_area.empty()) {
+
+ /* Try to parse area (given in SVG pixels) */
+ gdouble x0,y0,x1,y1;
+ if (sscanf(export_area.c_str(), "%lg:%lg:%lg:%lg", &x0, &y0, &x1, &y1) != 4) {
+ g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", export_area);
return 1;
}
- } else {
- g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", export_id);
- return 1;
+ area = Geom::Rect(Geom::Interval(x0,x1), Geom::Interval(y0,y1));
+
+ } else if (export_area_page || !(!object.empty() || export_area_drawing)) {
+
+ /* Export the whole page: note: Inkscape uses 'page' in all menus and dialogs, not 'canvas' */
+ doc->ensureUpToDate();
+ Geom::Point origin(doc->getRoot()->x.computed, doc->getRoot()->y.computed);
+ area = Geom::Rect(origin, origin + doc->getDimensions());
}
- }
+ // End finding area.
- if (!export_area.empty()) {
- /* Try to parse area (given in SVG pixels) */
- gdouble x0,y0,x1,y1;
- if (sscanf(export_area.c_str(), "%lg:%lg:%lg:%lg", &x0, &y0, &x1, &y1) != 4) {
- g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", export_area);
+ // Check we have a filename.
+ if (filename_out.empty()) {
+ std::cerr << "InkFileExport::do_export_png: "
+ << "No valid export filename given and no filename hint. Nothing exported.";
return 1;
}
- area = Geom::Rect(Geom::Interval(x0,x1), Geom::Interval(y0,y1));
- } else if (export_area_page || !(!export_id.empty() || export_area_drawing)) {
- /* Export the whole page: note: Inkscape uses 'page' in all menus and dialogs, not 'canvas' */
- doc->ensureUpToDate();
- Geom::Point origin(doc->getRoot()->x.computed, doc->getRoot()->y.computed);
- area = Geom::Rect(origin, origin + doc->getDimensions());
- }
- // End finding area.
- // Check we have a filename.
- if (filename.empty()) {
- g_warning ("No export filename given and no filename hint. Nothing exported.");
- return 1;
- }
-
- if (export_dpi != 0.0 && dpi == 0.0) {
- dpi = export_dpi;
- if ((dpi < 0.1) || (dpi > 10000.0)) {
- g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", export_dpi);
- return 1;
+ if (export_dpi != 0.0 && dpi == 0.0) {
+ dpi = export_dpi;
+ if ((dpi < 0.1) || (dpi > 10000.0)) {
+ std::cerr << "InkFileExport::do_export_png: "
+ << "DPI value " << export_dpi
+ << " out of range [0.1 - 10000.0]. Nothing exported.";
+ return 1;
+ }
}
-// do_print_message("DPI: %g\n", dpi);
- }
- if (export_area_snap) {
- area = area.roundOutwards();
- }
+ if (export_area_snap) {
+ area = area.roundOutwards();
+ }
- // default dpi
- if (dpi == 0.0) {
- dpi = Inkscape::Util::Quantity::convert(1, "in", "px");
- }
+ // default dpi
+ if (dpi == 0.0) {
+ dpi = Inkscape::Util::Quantity::convert(1, "in", "px");
+ }
- unsigned long int width = 0;
- unsigned long int height = 0;
+ unsigned long int width = 0;
+ unsigned long int height = 0;
- if (export_width != 0) {
- errno=0;
- width = export_width;
- if ((width < 1) || (width > PNG_UINT_31_MAX) || (errno == ERANGE) ) {
- g_warning("Export width %lu out of range (1 - %lu). Nothing exported.", width, (unsigned long int)PNG_UINT_31_MAX);
- return 1;
+ if (export_width != 0) {
+ width = export_width;
+ if ((width < 1) || (width > PNG_UINT_31_MAX)) {
+ std::cerr << "InkFileExport::do_export_png: "
+ << "Export width " << width << " out of range (1 to " << PNG_UINT_31_MAX << ")." << std::endl;
+ return 1;
+ }
+ dpi = (gdouble) Inkscape::Util::Quantity::convert(width, "in", "px") / area.width();
+ } else {
+ width = (unsigned long int) (Inkscape::Util::Quantity::convert(area.width(), "px", "in") * dpi + 0.5);
}
- dpi = (gdouble) Inkscape::Util::Quantity::convert(width, "in", "px") / area.width();
- } else {
- width = (unsigned long int) (Inkscape::Util::Quantity::convert(area.width(), "px", "in") * dpi + 0.5);
- }
- if (export_height != 0) {
- errno=0;
- height = export_height;
- if ((height < 1) || (height > PNG_UINT_31_MAX)) {
- g_warning("Export height %lu out of range (1 - %lu). Nothing exported.", height, (unsigned long int)PNG_UINT_31_MAX);
- return 1;
+ if (export_height != 0) {
+ height = export_height;
+ if ((height < 1) || (height > PNG_UINT_31_MAX)) {
+ std::cerr << "InkFileExport::do_export_png: "
+ << "Export height " << height << " out of range (1 to " << PNG_UINT_31_MAX << ")" << std::endl;
+ return 1;
+ }
+ dpi = (gdouble) Inkscape::Util::Quantity::convert(height, "in", "px") / area.height();
+ } else {
+ height = (unsigned long int) (Inkscape::Util::Quantity::convert(area.height(), "px", "in") * dpi + 0.5);
}
- dpi = (gdouble) Inkscape::Util::Quantity::convert(height, "in", "px") / area.height();
- } else {
- height = (unsigned long int) (Inkscape::Util::Quantity::convert(area.height(), "px", "in") * dpi + 0.5);
- }
- guint32 bgcolor = 0x00000000;
- if (!export_background.empty()) {
- // override the page color
- bgcolor = sp_svg_read_color(export_background.c_str(), 0xffffff00);
- bgcolor |= 0xff; // default is no opacity
- } else {
- // read from namedview
- Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
- if (nv && nv->attribute("pagecolor")){
- bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
- }
- if (nv && nv->attribute("inkscape:pageopacity")){
- double opacity = 1.0;
- sp_repr_get_double (nv, "inkscape:pageopacity", &opacity);
- bgcolor |= SP_COLOR_F_TO_U(opacity);
+ guint32 bgcolor = 0x00000000;
+ if (!export_background.empty()) {
+ // override the page color
+ bgcolor = sp_svg_read_color(export_background.c_str(), 0xffffff00);
+ bgcolor |= 0xff; // default is no opacity
+ } else {
+ // read from namedview
+ Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
+ if (nv && nv->attribute("pagecolor")){
+ bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
+ }
+ if (nv && nv->attribute("inkscape:pageopacity")){
+ double opacity = 1.0;
+ sp_repr_get_double (nv, "inkscape:pageopacity", &opacity);
+ bgcolor |= SP_COLOR_F_TO_U(opacity);
+ }
}
- }
- bgcolor &= (guint32) 0xffffff00;
+ bgcolor &= (guint32) 0xffffff00;
- if (export_background_opacity > 1.0) {
- float value = CLAMP (export_background_opacity, 1.0f, 255.0f);
- bgcolor |= (guint32) floor(value);
- } else {
- float value = CLAMP (export_background_opacity, 0.0f, 1.0f);
- bgcolor |= SP_COLOR_F_TO_U(value);
- }
+ if (export_background_opacity > 1.0) {
+ float value = CLAMP (export_background_opacity, 1.0f, 255.0f);
+ bgcolor |= (guint32) floor(value);
+ } else {
+ float value = CLAMP (export_background_opacity, 0.0f, 1.0f);
+ bgcolor |= SP_COLOR_F_TO_U(value);
+ }
- std::string path = filename; // File names are std::string, not Glib::ustring!
- if (filename_from_hint) {
- //Make relative paths go from the document location, if possible:
- if (!Glib::path_is_absolute(filename) && doc->getURI()) {
- std::string dirname = Glib::path_get_dirname(doc->getURI());
- if (!dirname.empty()) {
- path = Glib::build_filename(dirname, filename);
+ if (filename_from_hint) {
+ //Make relative paths go from the document location, if possible:
+ if (!Glib::path_is_absolute(filename_out) && doc->getURI()) {
+ std::string dirname = Glib::path_get_dirname(doc->getURI());
+ if (!dirname.empty()) {
+ filename_out = Glib::build_filename(dirname, filename_out);
+ }
}
}
- }
- // Check if directory exists
- std::string directory = Glib::path_get_dirname(path);
- if (!Glib::file_test(directory, Glib::FILE_TEST_IS_DIR)) {
- std::cerr << "File path " << path << " includes directory that doesn't exist." << std::endl;
- return 1;
- }
+ // Check if directory exists
+ std::string directory = Glib::path_get_dirname(filename_out);
+ if (!Glib::file_test(directory, Glib::FILE_TEST_IS_DIR)) {
+ std::cerr << "File path " << filename_out << " includes directory that doesn't exist." << std::endl;
+ return 1;
+ }
- // Do we really need to print this?
- std::cerr << "Background RRGGBBAA: " << std::hex << bgcolor << std::dec << std::endl;
- std::cerr << "Area "
- << area[Geom::X][0] << ":" << area[Geom::Y][0] << ":"
- << area[Geom::X][1] << ":" << area[Geom::Y][1] << " exported to "
- << width << " x " << height << " pixels (" << dpi << " dpi)" << std::endl;
+ // Do we really need to print this?
+ std::cout << "Background RRGGBBAA: " << std::hex << bgcolor << std::dec << std::endl;
+ std::cout << "Area "
+ << area[Geom::X][0] << ":" << area[Geom::Y][0] << ":"
+ << area[Geom::X][1] << ":" << area[Geom::Y][1] << " exported to "
+ << width << " x " << height << " pixels (" << dpi << " dpi)" << std::endl;
- reverse(items.begin(),items.end());
+ reverse(items.begin(),items.end());
- if ((width >= 1) && (height >= 1) && (width <= PNG_UINT_31_MAX) && (height <= PNG_UINT_31_MAX)) {
- if( sp_export_png_file(doc, path.c_str(), area, width, height, dpi,
- dpi, bgcolor, nullptr, nullptr, true, export_id_only ? items : std::vector<SPItem*>()) == 1 ) {
-// do_print_message("Bitmap saved as: %s\n", filename.c_str());
+ if ((width >= 1) && (height >= 1) && (width <= PNG_UINT_31_MAX) && (height <= PNG_UINT_31_MAX)) {
+ if( sp_export_png_file(doc, filename_out.c_str(), area, width, height, dpi,
+ dpi, bgcolor, nullptr, nullptr, true, export_id_only ? items : std::vector<SPItem*>()) == 1 ) {
+ } else {
+ std::cerr << "InkFileExport::do_export_png: Failed to export to " << filename_out << std::endl;
+ return 1;
+ }
} else {
- g_warning("Bitmap failed to save to: %s", filename.c_str());
+ std::cerr << "InkFileExport::do_export_png: Dimensions " << width << "x" << height << " are out of range (1 to " << PNG_UINT_31_MAX << ")." << std::endl;
return 1;
}
- } else {
- g_warning("Calculated bitmap dimensions %lu %lu are out of range (1 - %lu). Nothing exported.", width, height, (unsigned long int)PNG_UINT_31_MAX);
- return 1;
- }
+ } // End loop over objects.
return 0;
}
@@ -508,7 +550,7 @@ InkFileExportCmd::do_export_png(SPDocument *doc, std::string filename_in)
* \param mime MIME type to export as.
*/
int
-InkFileExportCmd::do_export_ps_pdf(SPDocument* doc, std::string filename, std::string mime_type)
+InkFileExportCmd::do_export_ps_pdf(SPDocument* doc, std::string filename_in, std::string mime_type)
{
// Check if we support mime type.
Inkscape::Extension::DB::OutputList o;
@@ -523,43 +565,7 @@ InkFileExportCmd::do_export_ps_pdf(SPDocument* doc, std::string filename, std::s
return 1;
}
- // Export only object with given id.
- if (!export_id.empty()) {
- SPObject *o = doc->getObjectById(export_id);
- if (o == nullptr) {
- g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", export_id);
- return 1;
- }
- (*i)->set_param_string ("exportId", export_id.c_str());
- } else {
- (*i)->set_param_string ("exportId", "");
- }
-
- // Set export area.
- if (export_area_page && export_area_drawing) {
- g_warning ("You cannot use --export-area-page and --export-area-drawing at the same time; only the former will take effect.");
- export_area_drawing = false;
- }
-
- if (export_area_drawing) {
- (*i)->set_param_optiongroup ("area", "drawing");
- }
-
- if (export_area_page) {
- if (export_type == "eps") {
- g_warning ("EPS cannot have its bounding box extend beyond its content, so if your drawing is smaller than the page, --export-area-page will clip it to drawing.");
- }
- (*i)->set_param_optiongroup ("area", "page");
- }
-
- if (!export_area_drawing && !export_area_page && export_id.empty()) {
- // neither is set, set page as default for ps/pdf and drawing for eps
- if (export_type == "eps") {
- try {
- (*i)->set_param_optiongroup("area", "drawing");
- } catch (...) {}
- }
- }
+ // Start with options that are once per document.
// Set export options.
if (export_text_to_path) {
@@ -630,11 +636,67 @@ InkFileExportCmd::do_export_ps_pdf(SPDocument* doc, std::string filename, std::s
? "PostScript level 3" : "PostScript level 2");
}
- try {
- (*i)->save(doc, filename.c_str());
- } catch(...) {
- std::cerr << "Failed to save PS/EPS/PDF to: " << filename << std::endl;
+
+ // Export each object in list (or root if empty). Use ';' so in future it could be possible to selected multiple objects to export together.
+ std::vector<Glib::ustring> objects = Glib::Regex::split_simple("\\s*;\\s*", export_id);
+ if (objects.empty()) {
+ objects.push_back(Glib::ustring()); // So we do loop at least once for root.
+ }
+
+ for (auto object : objects) {
+
+ std::string filename_out = get_filename_out(filename_in, object);
+ if (filename_out.empty()) {
+ return 1;
+ }
+
+ // Export only object with given id.
+ if (!object.empty()) {
+ SPObject *o = doc->getObjectById(object);
+ if (o == nullptr) {
+ std::cerr << "InkFileExportCmd::do_export_ps_pdf: Object " << object << " not found in document, nothing to export." << std::endl;
+ return 1;
+ }
+ (*i)->set_param_string ("exportId", object.c_str());
+ } else {
+ (*i)->set_param_string ("exportId", "");
+ }
+
+ // Set export area.
+ if (export_area_page && export_area_drawing) {
+ std::cerr << "You cannot use --export-area-page and --export-area-drawing at the same time; only the former will take effect." << std::endl;;
+ export_area_drawing = false;
+ }
+
+ if (export_area_drawing) {
+ (*i)->set_param_optiongroup ("area", "drawing");
+ }
+
+ if (export_area_page) {
+ if (export_type == "eps") {
+ std::cerr << "EPS cannot have its bounding box extend beyond its content, so if your drawing is smaller than the page, --export-area-page will clip it to drawing." << std::endl;
+ }
+ (*i)->set_param_optiongroup ("area", "page");
+ }
+
+ if (!export_area_drawing && !export_area_page) {
+ // Neither is set.
+ if (export_type == "eps" || !object.empty()) {
+ // Default to drawing for EPS or if object is specified (latter matches behavior for other export types).
+ (*i)->set_param_optiongroup("area", "drawing");
+ } else {
+ (*i)->set_param_optiongroup("area", "page");
+ }
+ }
+
+ try {
+ (*i)->save(doc, filename_out.c_str());
+ } catch(...) {
+ std::cerr << "Failed to save PS/EPS/PDF to: " << filename_out << std::endl;
+ return 1;
+ }
}
+
return 0;
}
@@ -646,8 +708,10 @@ InkFileExportCmd::do_export_ps_pdf(SPDocument* doc, std::string filename, std::s
* \param mime MIME type to export as (should be "image/x-emf" or "image/x-wmf")
*/
int
-InkFileExportCmd::do_export_win_metafile(SPDocument* doc, std::string filename, std::string mime_type)
+InkFileExportCmd::do_export_win_metafile(SPDocument* doc, std::string filename_in, std::string mime_type)
{
+ std::string filename_out = get_filename_out(filename_in);
+
// Check if we support mime type.
Inkscape::Extension::DB::OutputList o;
Inkscape::Extension::db.get_output_list(o);
@@ -662,7 +726,7 @@ InkFileExportCmd::do_export_win_metafile(SPDocument* doc, std::string filename,
return 1;
}
- (*i)->save(doc, filename.c_str());
+ (*i)->save(doc, filename_out.c_str());
return 0;
}
diff --git a/src/io/file-export-cmd.h b/src/io/file-export-cmd.h
index 0f7dd994b..0e8647db2 100644
--- a/src/io/file-export-cmd.h
+++ b/src/io/file-export-cmd.h
@@ -26,11 +26,11 @@ public:
private:
- std::string get_filename_out(std::string filename_in="");
- int do_export_svg( SPDocument* doc, std::string filename_out);
- int do_export_png( SPDocument* doc, std::string filename_out);
- int do_export_ps_pdf(SPDocument* doc, std::string filename_out, std::string mime_type);
- int do_export_win_metafile(SPDocument* doc, std::string filename_out, std::string mime_type);
+ std::string get_filename_out(std::string filename_in="", std::string object_id="");
+ int do_export_svg( SPDocument* doc, std::string filename_in);
+ int do_export_png( SPDocument* doc, std::string filename_in);
+ int do_export_ps_pdf(SPDocument* doc, std::string filename_in, std::string mime_type);
+ int do_export_win_metafile(SPDocument* doc, std::string filename_in, std::string mime_type);
public:
// Should be private, but this is just temporary code (I hope!).