diff options
Diffstat (limited to 'src/io/file-export-cmd.cpp')
| -rw-r--r-- | src/io/file-export-cmd.cpp | 231 |
1 files changed, 118 insertions, 113 deletions
diff --git a/src/io/file-export-cmd.cpp b/src/io/file-export-cmd.cpp index 6528c7bfe..f9ee8e4a0 100644 --- a/src/io/file-export-cmd.cpp +++ b/src/io/file-export-cmd.cpp @@ -341,124 +341,146 @@ InkFileExportCmd::do_export_png(SPDocument *doc, std::string filename_in) objects.push_back(Glib::ustring()); // So we do loop at least once for root. } - for (auto object : objects) { + for (auto object_id : objects) { - std::string filename_out = get_filename_out(filename_in, object); + std::string filename_out = get_filename_out(filename_in, object_id); 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; - } + // Find export object. (Either root or object with specified id.) + SPObject *object = doc->getRoot(); + if (!object_id.empty()) { + object = doc->getObjectById(object_id); + } - if (o) { - if (!SP_IS_ITEM (o)) { - std::cerr << "InkFileExportCmd::do_export_png: " - << "Object with id=\"" << object - << "\" is not a visible item. Skipping." << std::endl; - continue; - } + if (!object) { + std::cerr << "InkFileExport::do_export_png: " + << "Object with id=\"" << object + << "\" was not found in the document. Skipping." << std::endl; + continue; + } - items.push_back(SP_ITEM(o)); + if (!SP_IS_ITEM (object)) { + std::cerr << "InkFileExportCmd::do_export_png: " + << "Object with id=\"" << object_id + << "\" is not a visible item. Skipping." << std::endl; + continue; + } - if (export_id_only) { - std::cerr << "Exporting only object with id=\"" - << object << "\"; all other objects hidden." << std::endl; - } + items.push_back(SP_ITEM(object)); // There is only one item, why do this? - if (export_use_hints) { - - // Retrieve export filename hint. - const gchar *fn_hint = o->getRepr()->attribute("inkscape:export-filename"); - if (fn_hint) { - filename_out = fn_hint; - filename_from_hint = true; - } else { - std::cerr << "InkFileExport::do_export_png: " - << "Export filename hint not found for object " << object << ". Skipping." << std::endl; - continue; - } - - // 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." << std::endl; - } else { - dpi = atof(dpi_hint); - } - } else { - std::cerr << "InkFileExport::do_export_png: " - << "Export DPI hint not found for the object." << std::endl; - } - } + if (export_id_only) { + std::cerr << "Exporting only object with id=\"" + << object_id << "\"; all other objects hidden." << std::endl; + } - // Write object bbox to area. - doc->ensureUpToDate(); - Geom::OptRect areaMaybe = static_cast<SPItem *>(o_area)->desktopVisualBounds(); - if (areaMaybe) { - area = *areaMaybe; - } else { + // Find file name and dpi from hints. + if (export_use_hints) { + + // Retrieve export filename hint. + const gchar *fn_hint = object->getRepr()->attribute("inkscape:export-filename"); + if (fn_hint) { + filename_out = fn_hint; + filename_from_hint = true; + } else { + std::cerr << "InkFileExport::do_export_png: " + << "Export filename hint not found for object " << object_id << ". Skipping." << std::endl; + continue; + } + + // Retrieve export dpi hint. Only xdpi as ydpi is always the same now. + const gchar *dpi_hint = object->getRepr()->attribute("inkscape:export-xdpi"); + if (dpi_hint) { + if (export_dpi || export_width || export_height) { std::cerr << "InkFileExport::do_export_png: " - << "Unable to determine a valid bounding box. Skipping." << std::endl; - continue; + << "Using bitmap dimensions from the command line " + << "(--export-dpi, --export-width, or --export-height). " + << "DPI hint " << dpi_hint << " is ignored." << std::endl; + } else { + dpi = atof(dpi_hint); } } else { std::cerr << "InkFileExport::do_export_png: " - << "Object with id=\"" << object - << "\" was not found in the document. Skipping." << std::endl; + << "Export DPI hint not found for the object." << std::endl; + } + } + + // ------------------------- File name ------------------------- + + // Check we have a filename. + if (filename_out.empty()) { + std::cerr << "InkFileExport::do_export_png: " + << "No valid export filename given and no filename hint. Skipping." << std::endl; + continue; + } + + 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(filename_out); + if (!Glib::file_test(directory, Glib::FILE_TEST_IS_DIR)) { + std::cerr << "File path " << filename_out << " includes directory that doesn't exist. Skipping." << std::endl; + continue; + } + + // -------------------------- DPI ------------------------------- + + 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]. Skipping."; continue; } } + // default dpi + if (dpi == 0.0) { + dpi = Inkscape::Util::Quantity::convert(1, "in", "px"); + } + + // ------------------------- Area ------------------------------- + + Geom::Rect area; + doc->ensureUpToDate(); + + // Three choices: 1. Command-line export_area 2. Page area 3. Drawing area if (!export_area.empty()) { + // Export area command-line + /* 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.c_str()); - return 1; + return 1; // If it fails once, it will fail for all objects. } area = Geom::Rect(Geom::Interval(x0,x1), Geom::Interval(y0,y1)); - } else if (export_area_page || !(!object.empty() || export_area_drawing)) { + } else if (export_area_page || (!export_area_drawing && object_id.empty())) { - /* Export the whole page: note: Inkscape uses 'page' in all menus and dialogs, not 'canvas' */ - doc->ensureUpToDate(); + // Export area page (explicit or if no object is given). 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_out.empty()) { - std::cerr << "InkFileExport::do_export_png: " - << "No valid export filename given and no filename hint. Skipping." << std::endl; - continue; - } + } else { - if (export_dpi != 0.0 && dpi == 0.0) { - dpi = export_dpi; - if ((dpi < 0.1) || (dpi > 10000.0)) { + // Export area drawing (explicit or if object is given). + Geom::OptRect areaMaybe = static_cast<SPItem *>(object)->desktopVisualBounds(); + if (areaMaybe) { + area = *areaMaybe; + } else { std::cerr << "InkFileExport::do_export_png: " - << "DPI value " << export_dpi - << " out of range [0.1 - 10000.0]. Skipping."; + << "Unable to determine a valid bounding box. Skipping." << std::endl; continue; } } @@ -466,11 +488,9 @@ InkFileExportCmd::do_export_png(SPDocument *doc, std::string filename_in) if (export_area_snap) { area = area.roundOutwards(); } + // End finding area. - // default dpi - if (dpi == 0.0) { - dpi = Inkscape::Util::Quantity::convert(1, "in", "px"); - } + // -------------------------- Width and Height --------------------------------- unsigned long int width = 0; unsigned long int height = 0; @@ -499,23 +519,13 @@ InkFileExportCmd::do_export_png(SPDocument *doc, std::string filename_in) height = (unsigned long int) (Inkscape::Util::Quantity::convert(area.height(), "px", "in") * dpi + 0.5); } - 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(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; + if ((width < 1) || (height < 1) || (width > PNG_UINT_31_MAX) || (height > PNG_UINT_31_MAX)) { + std::cerr << "InkFileExport::do_export_png: Dimensions " << width << "x" << height << " are out of range (1 to " << PNG_UINT_31_MAX << ")." << std::endl; continue; } + // ---------------------- Generate the PNG ------------------------------- + // Do we really need to print this? std::cerr << "Background RRGGBBAA: " << std::hex << bgcolor << std::dec << std::endl; std::cerr << "Area " @@ -523,17 +533,12 @@ InkFileExportCmd::do_export_png(SPDocument *doc, std::string filename_in) << 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()); // But there was only one item! - 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; - continue; - } + 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: Dimensions " << width << "x" << height << " are out of range (1 to " << PNG_UINT_31_MAX << ")." << std::endl; + std::cerr << "InkFileExport::do_export_png: Failed to export to " << filename_out << std::endl; continue; } |
