Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
export.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/* Authors:
3 * Lauris Kaplinski <lauris@kaplinski.com>
4 * bulia byak <buliabyak@users.sf.net>
5 * Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
6 * Peter Bostrom
7 * Jon A. Cruz <jon@joncruz.org>
8 * Abhishek Sharma
9 * Kris De Gussem <Kris.DeGussem@gmail.com>
10 * Anshudhar Kumar Singh <anshudhar2001@gmail.com>
11 *
12 * Copyright (C) 1999-2007, 2012, 2021 Authors
13 * Copyright (C) 2001-2002 Ximian, Inc.
14 *
15 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
16 */
17
18#include "export.h"
19
20#include <glibmm/i18n.h>
21#include <gtkmm/notebook.h>
22
23#include "desktop.h"
24#include "inkscape.h"
25
26#include "extension/output.h"
27#include "helper/png-write.h"
28#include "io/resource.h"
29#include "io/sys.h" // for sanitizeString, file_test
30#include "object/object-set.h" // for ObjectSet
31#include "object/sp-page.h" // for SPPage
32#include "object/sp-root.h" // for SPRoot
33#include "object/weakptr.h" // for SPWeakPtr
34#include "ui/builder-utils.h"
36#include "ui/interface.h"
37
38namespace Inkscape::UI::Dialog {
39
41 : DialogBase("/dialogs/export/", "Export")
42 , builder(create_builder("dialog-export.glade"))
43 , container (get_widget<Gtk::Box> (builder, "export-box"))
44 , export_notebook (get_widget<Gtk::Notebook> (builder, "export-notebook"))
45 // Initialise Single Export and its objects
46 , single_image (get_derived_widget<SingleExport>(builder, "single-image"))
47 // Initialise Batch Export and its objects
48 , batch_export (get_derived_widget<BatchExport> (builder, "batch-export"))
49{
51
53
54 container.signal_realize().connect([=, this]() {
56 notebook_signal = export_notebook.signal_switch_page().connect(sigc::mem_fun(*this, &Export::onNotebookPageSwitch));
57 });
58 container.signal_unrealize().connect([this]() {
59 notebook_signal.disconnect();
60 });
61}
62
63Export::~Export() = default;
64
65// Set current page based on preference/last visited page
67{
68 pages[BATCH_EXPORT] = export_notebook.page_num(*batch_export.get_parent());
69 pages[SINGLE_IMAGE] = export_notebook.page_num(*single_image.get_parent());
70 export_notebook.set_current_page(pages[SINGLE_IMAGE]);
71}
72
78
80{
85 // Called previously, but we need post-desktop call too
87}
88
90{
91 auto current_page = export_notebook.get_current_page();
92 if (current_page == pages[SINGLE_IMAGE]) {
94 }
95 if (current_page == pages[BATCH_EXPORT]) {
97 }
98}
99void Export::selectionModified(Inkscape::Selection *selection, unsigned flags)
100{
101 auto current_page = export_notebook.get_current_page();
102 if (current_page == pages[SINGLE_IMAGE]) {
104 }
105 if (current_page == pages[BATCH_EXPORT]) {
107 }
108}
109
110void Export::onNotebookPageSwitch(Widget *page, unsigned page_number)
111{
112 auto desktop = getDesktop();
113 if (desktop) {
115
116 if (page_number == pages[SINGLE_IMAGE]) {
118 }
119 if (page_number == pages[BATCH_EXPORT]) {
121 }
122 }
123}
124
135std::string Export::absolutizePath(SPDocument *doc, const std::string &filename)
136{
137 std::string path;
138 // Make relative paths go from the document location, if possible:
139 if (!Glib::path_is_absolute(filename) && doc->getDocumentFilename()) {
140 auto dirname = Glib::path_get_dirname(doc->getDocumentFilename());
141 if (!dirname.empty()) {
142 path = Glib::build_filename(dirname, filename);
143 }
144 }
145 if (path.empty()) {
146 path = filename;
147 }
148 return path;
149}
150
151bool Export::unConflictFilename(SPDocument *doc, std::string &filename, std::string const extension)
152{
153 std::string path = absolutizePath(doc, filename);
154 std::string test_filename = path + extension;
155 if (!Inkscape::IO::file_test(test_filename.c_str(), G_FILE_TEST_EXISTS)) {
156 filename = test_filename;
157 return true;
158 }
159 for (int i = 1; i <= 100; i++) {
160 test_filename = path + "_copy_" + std::to_string(i) + extension;
161 if (!Inkscape::IO::file_test(test_filename.c_str(), G_FILE_TEST_EXISTS)) {
162 filename = test_filename;
163 return true;
164 }
165 }
166 return false;
167}
168
175bool Export::checkOrCreateDirectory(std::string const &filename)
176{
177 SPDesktop *desktop = SP_ACTIVE_DESKTOP;
178 if (!desktop) {
179 return false;
180 }
181
182 std::string path = absolutizePath(desktop->getDocument(), filename);
183 std::string dirname = Glib::path_get_dirname(path);
184
185 if (dirname.empty() || !Inkscape::IO::file_test(dirname.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
186 if (g_mkdir_with_parents(dirname.c_str(), S_IRWXU) != 0) {
187 Glib::ustring safeDir = Inkscape::IO::sanitizeString(dirname.c_str());
188 Glib::ustring error = g_strdup_printf(_("Directory <b>%s</b> does not exist and can't be created.\n"), safeDir.c_str());
190 sp_ui_error_dialog(error.c_str());
191 return false;
192 }
193 }
194 return true;
195}
196
204 Geom::Rect const &area, unsigned long int const &width, unsigned long int const &height,
205 float const &dpi, guint32 bg_color, Glib::ustring const &filename, bool overwrite,
206 unsigned (*callback)(float, void *), void *data,
207 Inkscape::Extension::Output *extension, std::vector<SPItem const *> *items)
208{
209 SPDesktop *desktop = SP_ACTIVE_DESKTOP;
210 if (!desktop)
211 return false;
213
214 if (area.hasZeroArea() || width == 0 || height == 0) {
215 desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The chosen area to be exported is invalid."));
216 sp_ui_error_dialog(_("The chosen area to be exported is invalid"));
217 return false;
218 }
219 if (filename.empty()) {
220 desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You have to enter a filename."));
221 sp_ui_error_dialog(_("You have to enter a filename"));
222 return false;
223 }
224
225 if (!extension || !extension->is_raster()) {
226 desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Raster Export Error"));
227 sp_ui_error_dialog(_("Raster export Method is used for NON RASTER EXTENSION"));
228 return false;
229 }
230
231 float pHYs = extension->get_param_float("png_phys", dpi);
232 if (pHYs < 0.01) pHYs = dpi;
233
234 bool use_interlacing = extension->get_param_bool("png_interlacing", false);
235 int antialiasing = extension->get_param_int("png_antialias", 2); // Cairo anti aliasing
236 int zlib = extension->get_param_int("png_compression", 1); // Default is 6 for png, but 1 for non-png
237 auto val = extension->get_param_int("png_bitdepth", 99); // corresponds to RGBA 8
238
239 int bit_depth = pow(2, (val & 0x0F));
240 int color_type = (val & 0xF0) >> 4;
241
242 std::string path = absolutizePath(doc, Glib::filename_from_utf8(filename));
243
244 // Do the over-write protection now, since the png is just a temp file.
245 if (!overwrite && !sp_ui_overwrite_file(path)) {
246 return false;
247 }
248
249 auto fn = Glib::path_get_basename(path);
252 auto png_filename = path;
253 {
254 // Select the extension and set the filename to a temporary file
255 int tempfd_out = Glib::file_open_tmp(png_filename, "ink_ext_");
256 close(tempfd_out);
257 }
258
259 // Export Start Here
260 std::vector<SPItem const *> selected;
261 if (items && items->size() > 0) {
262 selected = *items;
263 }
264
266 desktop->getDocument(), Glib::filename_to_utf8(png_filename).c_str(), area, width, height, pHYs,
267 pHYs, // previously xdpi, ydpi.
268 bg_color, callback, data, true, selected, use_interlacing, color_type, bit_depth, zlib, antialiasing);
269
270 bool failed = result == EXPORT_ERROR; // || prog_dialog->get_stopped();
271
272 if (failed) {
273 Glib::ustring safeFile = Inkscape::IO::sanitizeString(Glib::filename_to_utf8(path).c_str());
274 Glib::ustring error = g_strdup_printf(_("Could not export to filename <b>%s</b>.\n"), safeFile.c_str());
275
277 sp_ui_error_dialog(error.c_str());
278 return false;
279 } else if (result == EXPORT_OK) {
280 // Don't ask for preferences on every run.
281 try {
282 extension->export_raster(doc, png_filename, path.c_str(), false);
284 return false;
285 }
286 } else {
287 // Extensions have their own error popup, so this only tracks failures in the png step
288 desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Export aborted."));
289 return false;
290 }
291
292 Glib::ustring safeFile = Inkscape::IO::sanitizeString(path.c_str());
293 desktop->messageStack()->flashF(Inkscape::INFORMATION_MESSAGE, _("Drawing exported to <b>%s</b>."),
294 safeFile.c_str());
295
296 unlink(png_filename.c_str());
297 return true;
298}
299
302 Glib::ustring const &filename,
303 bool overwrite, Geom::Rect const &area)
304{
305 doc->ensureUpToDate();
307 doc->fitToRect(area, false);
309 auto page = doc->getPageManager().getFirstPage();
310 return exportVector(extension, doc, filename, overwrite, {}, {page});
311}
312
315 Glib::ustring const &filename,
316 bool overwrite, const std::vector<SPItem const *> &items, SPPage const *page)
317{
318 std::vector<SPPage const *> pages;
319 if (page)
320 pages.push_back(page);
321 return exportVector(extension, doc, filename, overwrite, items, pages);
322}
323
331 Inkscape::Extension::Output *extension, SPDocument *copy_doc,
332 Glib::ustring const &filename,
333 bool overwrite, const std::vector<SPItem const *> &items, const std::vector<SPPage const *> &pages)
334{
335 SPDesktop *desktop = SP_ACTIVE_DESKTOP;
336 if (!desktop)
337 return false;
338
339 if (filename.empty()) {
340 desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You have to enter a filename."));
341 sp_ui_error_dialog(_("You have to enter a filename"));
342 return false;
343 }
344
345 if (!extension || extension->is_raster()) {
346 desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Vector Export Error"));
347 sp_ui_error_dialog(_("Vector export Method is used for RASTER EXTENSION"));
348 return false;
349 }
350
351 std::string path = absolutizePath(copy_doc, Glib::filename_from_utf8(filename));
352 Glib::ustring safeFile = Inkscape::IO::sanitizeString(path.c_str());
353
354 // Do the over-write protection now
355 if (!overwrite && !sp_ui_overwrite_file(path)) {
356 return false;
357 }
358 copy_doc->ensureUpToDate();
359
360 std::vector<SPItem const *> objects = items;
361 std::set<std::string> obj_ids;
362 std::set<std::string> page_ids;
363 for (auto page : pages) {
364 if (auto _id = page->getId()) {
365 page_ids.insert(std::string(_id));
366 }
367 // If page then our item set is limited to the overlapping items
368 auto page_items = page->getOverlappingItems(true, true);
369
370 if (items.empty()) {
371 // Items is page_items, remove all items not in this page.
372 objects.insert(objects.end(), page_items.begin(), page_items.end());
373 } else {
374 for (auto &item : page_items) {
375 item->getIds(obj_ids);
376 }
377 }
378 }
379
380 // Delete any pages not specified, delete all pages if none specified
381 auto &pm = copy_doc->getPageManager();
382
383 // Make weak pointers to pages, since deletePage() can delete more than just the requested page.
384 std::vector<SPWeakPtr<SPPage>> copy_pages;
385 copy_pages.reserve(pm.getPageCount());
386 for (auto *page : pm.getPages()) {
387 copy_pages.emplace_back(page);
388 }
389
390 // We refuse to delete anything if everything would be deleted.
391 for (auto &page : copy_pages) {
392 if (page) {
393 auto _id = page->getId();
394 if (_id && page_ids.find(_id) == page_ids.end()) {
395 pm.deletePage(page.get(), false);
396 }
397 }
398 }
399
400 // Page export ALWAYS restricts, even if nothing would be on the page.
401 if (!objects.empty() || !pages.empty()) {
402 std::vector<SPObject *> objects_to_export;
403 Inkscape::ObjectSet object_set(copy_doc);
404 for (auto &object : objects) {
405 auto _id = object->getId();
406 if (!_id || (!obj_ids.empty() && obj_ids.find(_id) == obj_ids.end())) {
407 // This item is off the page so can be ignored for export
408 continue;
409 }
410
411 SPObject *obj = copy_doc->getObjectById(_id);
412 if (!obj) {
413 Glib::ustring error = g_strdup_printf(_("Could not export to filename <b>%s</b>. (missing object)\n"), safeFile.c_str());
414
416 sp_ui_error_dialog(error.c_str());
417
418 return false;
419 }
420 copy_doc->ensureUpToDate();
421
422 object_set.add(obj, true);
423 objects_to_export.push_back(obj);
424 }
425
426 copy_doc->getRoot()->cropToObjects(objects_to_export);
427
428 if (pages.empty()) {
429 object_set.fitCanvas(false, true);
430 }
431 }
432
433 // Remove all unused definitions
434 copy_doc->vacuumDocument();
435
436 try {
437 extension->save(copy_doc, path.c_str());
439 Glib::ustring safeFile = Inkscape::IO::sanitizeString(path.c_str());
440 Glib::ustring error = g_strdup_printf(_("Could not export to filename <b>%s</b>.\n"), safeFile.c_str());
441
443 sp_ui_error_dialog(error.c_str());
444
445 return false;
446 }
447
448 desktop->messageStack()->flashF(Inkscape::INFORMATION_MESSAGE, _("Drawing exported to <b>%s</b>."),
449 safeFile.c_str());
450 return true;
451}
452
453std::string Export::filePathFromObject(SPDocument *doc, SPObject *obj, const std::string &file_entry_text)
454{
455 Glib::ustring id = _("bitmap");
456 if (obj && obj->getId()) {
457 id = obj->getId();
458 }
459 return prependDirectory(Glib::filename_from_utf8(id), file_entry_text, doc);
460}
461
482// FIXME change type of name...?
483std::string Export::prependDirectory(const std::string &name, const std::string &orig, SPDocument *doc)
484{
485 if (Glib::path_is_absolute(name) || name.empty())
486 return name;
487
488 if (Glib::path_get_basename(name) != name) {
489 return name;
490 }
491
492 std::string directory;
493
494 if (!orig.empty()) {
495 directory = Glib::path_get_dirname(orig);
496 // Note: Glib::path_get_dirname() returns "." if there is no directory component
497 }
498 if (directory.empty() || directory == ".") {
499 /* Grab document directory */
500 const gchar *docFilename = doc->getDocumentFilename();
501 if (docFilename) {
502 directory = Glib::path_get_dirname(docFilename);
503 }
504 }
505 if (directory.empty() || directory == ".") {
507 }
508
509 return Glib::build_filename(directory, name);
510}
511
512std::string Export::defaultFilename(SPDocument *doc, const std::string &filename_entry_text,
513 const std::string &extension)
514{
515 std::string filename;
516 if (doc && doc->getDocumentFilename()) {
517 filename = doc->getDocumentFilename();
518 //appendExtensionToFilename(filename, extension);
519 } else if (doc) {
520 filename = prependDirectory(Glib::filename_from_utf8(_("bitmap")), filename_entry_text, doc);
521 filename = filename + extension;
522 }
523 return filename;
524}
525
527 if (object) {
528 object->setAttribute("inkscape:export-bgcolor", color.toString());
529 }
530}
531
533 if (object) {
534 if (auto c = Inkscape::Colors::Color::parse(object->getAttribute("inkscape:export-bgcolor"))) {
535 return *c;
536 }
537 }
538 return default_color;
539}
540
541} // namespace Inkscape::UI::Dialog
542
543/*
544 Local Variables:
545 mode:c++
546 c-file-style:"stroustrup"
547 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
548 indent-tabs-mode:nil
549 fill-column:99
550 End:
551*/
552// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Gtk builder utilities.
uint64_t page
Definition canvas.cpp:171
Axis aligned, non-empty rectangle.
Definition rect.h:92
bool hasZeroArea(Coord eps=EPSILON) const
Check whether the rectangle has zero area up to specified tolerance.
Definition rect.h:113
std::string toString(bool opacity=true) const
Format the color as a css string and return it.
Definition color.cpp:106
int get_param_int(char const *name) const
Gets a parameter identified by name with the integer placed in value.
double get_param_float(char const *name) const
Gets a float parameter identified by name with the double placed in value.
bool get_param_bool(char const *name) const
Gets a parameter identified by name with the bool placed in value.
Generic failure for an undescribed reason.
Definition output.h:34
void export_raster(const SPDocument *doc, std::string png_filename, gchar const *filename, bool detachbase)
Save a rendered png as a raster output.
Definition output.cpp:237
bool is_raster() const
Definition output.h:63
void save(SPDocument *doc, gchar const *filename, bool detachbase=false)
Save a document as a file.
Definition output.cpp:215
MessageId flash(MessageType type, char const *message)
Temporarily pushes a message onto the stack.
MessageId flashF(MessageType type, char const *format,...) G_GNUC_PRINTF(3
temporarily pushes a message onto the stack using printf-like formatting
bool add(SPObject *object, bool nosignal=false)
Add an SPObject to the set of selected objects.
bool fitCanvas(bool with_margins, bool skip_undo=false)
void disablePages()
Disables multi page supply by removing all the page objects.
SPPage * getFirstPage() const
void enablePages()
Enables multi page support by turning the document viewBox into the first page.
void deletePage(SPPage *page, bool contents=false)
Delete the given page.
static Preferences * get()
Access the singleton Preferences object.
The set of selected SPObjects for a given document and layer model.
Definition selection.h:80
void setApp(InkscapeApplication *app)
void setDesktop(SPDesktop *desktop)
void selectionModified(Inkscape::Selection *selection, guint flags)
void selectionChanged(Inkscape::Selection *selection)
void setDocument(SPDocument *document)
DialogBase is the base class for the dialog system.
Definition dialog-base.h:40
SPDocument * getDocument() const
Definition dialog-base.h:81
InkscapeApplication * getApp() const
Definition dialog-base.h:80
SPDesktop * getDesktop() const
Definition dialog-base.h:77
static bool exportRaster(Geom::Rect const &area, unsigned long int const &width, unsigned long int const &height, float const &dpi, guint32 bg_color, Glib::ustring const &filename, bool overwrite, unsigned(*callback)(float, void *), void *data, Inkscape::Extension::Output *extension, std::vector< SPItem const * > *items=nullptr)
Export to raster graphics.
Definition export.cpp:203
SingleExport & single_image
Definition export.h:63
static bool exportVector(Inkscape::Extension::Output *extension, SPDocument *doc, Glib::ustring const &filename, bool overwrite, Geom::Rect const &area)
Definition export.cpp:300
Gtk::Notebook & export_notebook
Definition export.h:62
void selectionModified(Inkscape::Selection *selection, unsigned flags) override
Definition export.cpp:99
void selectionChanged(Inkscape::Selection *selection) override
Definition export.cpp:89
void documentReplaced() override
Definition export.cpp:73
static std::string prependDirectory(const std::string &name, const std::string &orig, SPDocument *doc=nullptr)
Adds the full directory path to the final part of a file name.
Definition export.cpp:483
static bool unConflictFilename(SPDocument *doc, std::string &filename, std::string const extension)
Definition export.cpp:151
sigc::scoped_connection notebook_signal
Definition export.h:72
std::map< notebook_page, int > pages
Definition export.h:70
static std::string absolutizePath(SPDocument *doc, const std::string &filename)
Convert path to absolute path.
Definition export.cpp:135
Inkscape::Preferences * prefs
Definition export.h:66
void onNotebookPageSwitch(Widget *page, unsigned page_number)
Definition export.cpp:110
static std::string filePathFromObject(SPDocument *doc, SPObject *obj, const std::string &file_entry_text)
Definition export.cpp:453
static bool checkOrCreateDirectory(std::string const &filename)
Checks if the directory exists and if not, tries to create the directory and if failed,...
Definition export.cpp:175
void desktopReplaced() override
Called when the desktop has certainly changed.
Definition export.cpp:79
BatchExport & batch_export
Definition export.h:64
static std::string defaultFilename(SPDocument *doc, const std::string &filename_entry_text, const std::string &extension)
Definition export.cpp:512
void selectionChanged(Inkscape::Selection *selection)
void setDesktop(SPDesktop *desktop)
void selectionModified(Inkscape::Selection *selection, guint flags)
void setDocument(SPDocument *document)
void setApp(InkscapeApplication *app)
To do: update description of desktop.
Definition desktop.h:149
SPDocument * getDocument() const
Definition desktop.h:189
Inkscape::MessageStack * messageStack() const
Definition desktop.h:160
Inkscape::Selection * getSelection() const
Definition desktop.h:188
Typed SVG document implementation.
Definition document.h:101
SPRoot * getRoot()
Returns our SPRoot.
Definition document.h:200
char const * getDocumentFilename() const
Definition document.h:229
SPObject * getObjectById(std::string const &id) const
void fitToRect(Geom::Rect const &rect, bool with_margins=false)
Given a Geom::Rect that may, for example, correspond to the bbox of an object, this function fits the...
Definition document.cpp:992
unsigned int vacuumDocument()
Remove unused definitions etc.
Inkscape::PageManager & getPageManager()
Definition document.h:162
int ensureUpToDate(unsigned int object_modified_tag=0)
Repeatedly works on getting the document updated, since sometimes it takes more than one pass to get ...
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
char const * getId() const
Returns the objects current ID string.
char const * getAttribute(char const *name) const
void cropToObjects(std::vector< SPObject * > except_objects)
Removes objects which are not related to given list of objects.
void getIds(std::set< std::string > &ret) const
Accumulate this id and all it's descendants ids.
Css & result
double c[8][4]
Geom::Point orig
Editable view implementation.
unsigned int guint32
SPItem * item
void sp_ui_error_dialog(char const *message)
Definition interface.cpp:56
bool sp_ui_overwrite_file(std::string const &filename)
If necessary, ask the user if a file may be overwritten.
Definition interface.cpp:74
Definition desktop.h:50
std::string homedir_path()
Definition resource.cpp:513
Glib::ustring sanitizeString(char const *str)
Definition sys.cpp:183
bool file_test(char const *utf8name, GFileTest test)
Definition sys.cpp:116
Dialog code.
Definition desktop.h:117
Inkscape::Colors::Color get_export_bg_color(SPObject *object, Inkscape::Colors::Color const &default_color)
Definition export.cpp:532
void set_export_bg_color(SPObject *object, Inkscape::Colors::Color const &color)
Definition export.cpp:526
static constexpr int height
W & get_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id)
W & get_derived_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id, Args &&... args)
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
static void append(std::vector< T > &target, std::vector< T > &&source)
@ INFORMATION_MESSAGE
Definition message.h:30
@ ERROR_MESSAGE
Definition message.h:29
ExportResult sp_export_png_file(SPDocument *doc, gchar const *filename, double x0, double y0, double x1, double y1, unsigned long int width, unsigned long int height, double xdpi, double ydpi, unsigned long bgcolor, unsigned int(*status)(float, void *), void *data, bool force_overwrite, const std::vector< SPItem const * > &items_only, bool interlace, int color_type, int bit_depth, int zlib, int antialiasing)
Export the given document as a Portable Network Graphics (PNG) file.
ExportResult
Definition png-write.h:26
@ EXPORT_ERROR
Definition png-write.h:27
@ EXPORT_OK
Definition png-write.h:28
Inkscape::IO::Resource - simple resource API.
GList * items
static Inkscape::Colors::Color default_color(SPItem *item)
Find default color based on colors in existing fill.
SPPage – a page object.
SPRoot: SVG <svg> implementation.
static const Point data[]
double width
Glib::ustring name
Definition toolbars.cpp:55
Glib::RefPtr< Gtk::Builder > builder