summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: aaacc83)
raw | patch | inline | side by side (parent: aaacc83)
author | ishmal <ishmal@users.sourceforge.net> | |
Mon, 17 Jul 2006 18:24:12 +0000 (18:24 +0000) | ||
committer | ishmal <ishmal@users.sourceforge.net> | |
Mon, 17 Jul 2006 18:24:12 +0000 (18:24 +0000) |
diff --git a/src/dialogs/export.cpp b/src/dialogs/export.cpp
index a141053dcb4e0ec5979e9fd0478d8d929e7490f8..8c6a8402e0a42c9348374b6734fe380b7bbf1c8c 100644 (file)
--- a/src/dialogs/export.cpp
+++ b/src/dialogs/export.cpp
#include "io/sys.h"
+#include "helper/png-write.h"
+
#define SP_EXPORT_MIN_SIZE 1.0
diff --git a/src/file.cpp b/src/file.cpp
index 3c8adf87be749048fb48dfb84d22c0c39b81b5e8..a9c9184f69f7f165211d4eda9f6c0aa9e7808cc4 100644 (file)
--- a/src/file.cpp
+++ b/src/file.cpp
## E X P O R T
######################*/
+//#define NEW_EXPORT_DIALOG
+
+
+
+#ifdef NEW_EXPORT_DIALOG
+
+static Inkscape::UI::Dialog::FileExportDialog *exportDialogInstance = NULL;
+
/**
- *
+ * Display an Export dialog, export as the selected type if OK pressed
*/
-void
+bool
sp_file_export_dialog(void *widget)
{
- sp_export_dialog();
-}
+ //# temp hack for 'doc' until we can switch to this dialog
+ SPDocument *doc = SP_ACTIVE_DOCUMENT;
-#include <display/nr-arena-item.h>
-#include <display/nr-arena.h>
+ Glib::ustring export_path;
+ Glib::ustring export_loc;
-struct SPEBP {
- int width, height, sheight;
- guchar r, g, b, a;
- NRArenaItem *root; // the root arena item to show; it is assumed that all unneeded items are hidden
- guchar *px;
- unsigned (*status)(float, void *);
- void *data;
-};
+ Inkscape::XML::Node *repr = sp_document_repr_root(doc);
+ Inkscape::Extension::Output *extension;
-/**
- *
- */
-static int
-sp_export_get_rows(guchar const **rows, int row, int num_rows, void *data)
-{
- struct SPEBP *ebp = (struct SPEBP *) data;
+ //# Get the default extension name
+ Glib::ustring default_extension;
+ char *attr = (char *)repr->attribute("inkscape:output_extension");
+ if (!attr)
+ attr = (char *)prefs_get_string_attribute("dialogs.save_as", "default");
+ if (attr)
+ default_extension = attr;
+ //g_message("%s: extension name: '%s'", __FUNCTION__, default_extension);
- if (ebp->status) {
- if (!ebp->status((float) row / ebp->height, ebp->data)) return 0;
- }
+ if (doc->uri == NULL)
+ {
+ char formatBuf[256];
+
+ Glib::ustring filename_extension = ".svg";
+ extension = dynamic_cast<Inkscape::Extension::Output *>
+ (Inkscape::Extension::db.get(default_extension.c_str()));
+ //g_warning("%s: extension ptr: 0x%x", __FUNCTION__, (unsigned int)extension);
+ if (extension)
+ filename_extension = extension->get_extension();
+
+ attr = (char *)prefs_get_string_attribute("dialogs.save_as", "path");
+ if (attr)
+ export_path = attr;
+
+ if (!Inkscape::IO::file_test(export_path.c_str(),
+ (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+ export_path = "";
+
+ if (export_path.size()<1)
+ export_path = g_get_home_dir();
+
+ export_loc = export_path;
+ export_loc.append(G_DIR_SEPARATOR_S);
+ snprintf(formatBuf, 255, _("drawing%s"), filename_extension.c_str());
+ export_loc.append(formatBuf);
- num_rows = MIN(num_rows, ebp->sheight);
- num_rows = MIN(num_rows, ebp->height - row);
-
- /* Set area of interest */
- NRRectL bbox;
- bbox.x0 = 0;
- bbox.y0 = row;
- bbox.x1 = ebp->width;
- bbox.y1 = row + num_rows;
- /* Update to renderable state */
- NRGC gc(NULL);
- nr_matrix_set_identity(&gc.transform);
-
- nr_arena_item_invoke_update(ebp->root, &bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE);
-
- NRPixBlock pb;
- nr_pixblock_setup_extern(&pb, NR_PIXBLOCK_MODE_R8G8B8A8N,
- bbox.x0, bbox.y0, bbox.x1, bbox.y1,
- ebp->px, 4 * ebp->width, FALSE, FALSE);
-
- for (int r = 0; r < num_rows; r++) {
- guchar *p = NR_PIXBLOCK_PX(&pb) + r * pb.rs;
- for (int c = 0; c < ebp->width; c++) {
- *p++ = ebp->r;
- *p++ = ebp->g;
- *p++ = ebp->b;
- *p++ = ebp->a;
}
- }
+ else
+ {
+ export_path = Glib::path_get_dirname(doc->uri);
+ }
- /* Render */
- nr_arena_item_invoke_render(ebp->root, &bbox, &pb, 0);
+ // convert save_loc from utf-8 to locale
+ // is this needed any more, now that everything is handled in
+ // Inkscape::IO?
+ Glib::ustring export_path_local = Glib::filename_from_utf8(export_path);
+ if ( export_path_local.size() > 0)
+ export_path = export_path_local;
- for (int r = 0; r < num_rows; r++) {
- rows[r] = NR_PIXBLOCK_PX(&pb) + r * pb.rs;
- }
+ //# Show the SaveAs dialog
+ if (!exportDialogInstance)
+ exportDialogInstance =
+ Inkscape::UI::Dialog::FileExportDialog::create(
+ export_path,
+ Inkscape::UI::Dialog::EXPORT_TYPES,
+ (char const *) _("Select file to export to"),
+ default_extension
+ );
- nr_pixblock_release(&pb);
+ bool success = exportDialogInstance->show();
+ if (!success)
+ return success;
- return num_rows;
-}
+ Glib::ustring fileName = exportDialogInstance->getFilename();
-/**
-Hide all items which are not listed in list, recursively, skipping groups and defs
-*/
-void
-hide_other_items_recursively(SPObject *o, GSList *list, unsigned dkey)
-{
- if (SP_IS_ITEM(o)
- && !SP_IS_DEFS(o)
- && !SP_IS_ROOT(o)
- && !SP_IS_GROUP(o)
- && !g_slist_find(list, o))
- {
- sp_item_invoke_hide(SP_ITEM(o), dkey);
- }
+ Inkscape::Extension::Extension *selectionType =
+ exportDialogInstance->getSelectionType();
- // recurse
- if (!g_slist_find(list, o)) {
- for (SPObject *child = sp_object_first_child(o) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
- hide_other_items_recursively(child, list, dkey);
- }
+
+ if (fileName.size() > 0) {
+ Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
+
+ if ( newFileName.size()>0 )
+ fileName = newFileName;
+ else
+ g_warning( "Error converting save filename to UTF-8." );
+
+ success = file_save(doc, fileName, selectionType, TRUE);
+
+ if (success)
+ prefs_set_recent_file(SP_DOCUMENT_URI(doc), SP_DOCUMENT_NAME(doc));
+
+ export_path = fileName;
+ prefs_set_string_attribute("dialogs.save_as", "path", export_path.c_str());
+
+ return success;
}
+
+
+ return false;
}
-/**
- * Render the SVG drawing onto a PNG raster image, then save to
- * a file. Returns TRUE if succeeded in writing the file,
- * FALSE otherwise.
- */
-int
-sp_export_png_file(SPDocument *doc, gchar const *filename,
- double x0, double y0, double x1, double y1,
- unsigned width, unsigned height, double xdpi, double ydpi,
- unsigned long bgcolor,
- unsigned (*status)(float, void *),
- void *data, bool force_overwrite,
- GSList *items_only)
-{
- int write_status = TRUE;
- g_return_val_if_fail(doc != NULL, FALSE);
- g_return_val_if_fail(filename != NULL, FALSE);
- g_return_val_if_fail(width >= 1, FALSE);
- g_return_val_if_fail(height >= 1, FALSE);
- if (!force_overwrite && !sp_ui_overwrite_file(filename)) {
- return FALSE;
- }
- sp_document_ensure_up_to_date(doc);
-
- /* Go to document coordinates */
- gdouble t = y0;
- y0 = sp_document_height(doc) - y1;
- y1 = sp_document_height(doc) - t;
-
- /*
- * 1) a[0] * x0 + a[2] * y1 + a[4] = 0.0
- * 2) a[1] * x0 + a[3] * y1 + a[5] = 0.0
- * 3) a[0] * x1 + a[2] * y1 + a[4] = width
- * 4) a[1] * x0 + a[3] * y0 + a[5] = height
- * 5) a[1] = 0.0;
- * 6) a[2] = 0.0;
- *
- * (1,3) a[0] * x1 - a[0] * x0 = width
- * a[0] = width / (x1 - x0)
- * (2,4) a[3] * y0 - a[3] * y1 = height
- * a[3] = height / (y0 - y1)
- * (1) a[4] = -a[0] * x0
- * (2) a[5] = -a[3] * y1
- */
-
- NRMatrix affine;
- affine.c[0] = width / (x1 - x0);
- affine.c[1] = 0.0;
- affine.c[2] = 0.0;
- affine.c[3] = height / (y1 - y0);
- affine.c[4] = -affine.c[0] * x0;
- affine.c[5] = -affine.c[3] * y0;
-
- //SP_PRINT_MATRIX("SVG2PNG", &affine);
-
- struct SPEBP ebp;
- ebp.width = width;
- ebp.height = height;
- ebp.r = NR_RGBA32_R(bgcolor);
- ebp.g = NR_RGBA32_G(bgcolor);
- ebp.b = NR_RGBA32_B(bgcolor);
- ebp.a = NR_RGBA32_A(bgcolor);
-
- /* Create new arena */
- NRArena *arena = NRArena::create();
- unsigned dkey = sp_item_display_key_new(1);
-
- /* Create ArenaItems and set transform */
- ebp.root = sp_item_invoke_show(SP_ITEM(sp_document_root(doc)), arena, dkey, SP_ITEM_SHOW_DISPLAY);
- nr_arena_item_set_transform(NR_ARENA_ITEM(ebp.root), NR::Matrix(&affine));
-
- // We show all and then hide all items we don't want, instead of showing only requested items,
- // because that would not work if the shown item references something in defs
- if (items_only) {
- hide_other_items_recursively(sp_document_root(doc), items_only, dkey);
- }
- ebp.status = status;
- ebp.data = data;
- if ((width < 256) || ((width * height) < 32768)) {
- ebp.px = nr_pixelstore_64K_new(FALSE, 0);
- ebp.sheight = 65536 / (4 * width);
- write_status = sp_png_write_rgba_striped(filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp);
- nr_pixelstore_64K_free(ebp.px);
- } else {
- ebp.px = g_new(guchar, 4 * 64 * width);
- ebp.sheight = 64;
- write_status = sp_png_write_rgba_striped(filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp);
- g_free(ebp.px);
- }
- // Hide items
- sp_item_invoke_hide(SP_ITEM(sp_document_root(doc)), dkey);
+#else
+
+
- /* Free Arena and ArenaItem */
- nr_arena_item_unref(ebp.root);
- nr_object_unref((NRObject *) arena);
- return write_status;
+/**
+ *
+ */
+bool
+sp_file_export_dialog(void *widget)
+{
+ sp_export_dialog();
+ return true;
}
+#endif
/*######################
## P R I N T
diff --git a/src/file.h b/src/file.h
index 0395434c91bde0faf9f96e96c422eb5c43efb7c0..f86dc5a21be0bff21e1aa1f2b65bd4686f1eb699 100644 (file)
--- a/src/file.h
+++ b/src/file.h
######################*/
/**
- * Displays a "Save as" dialog for the user, with an
+ * Displays a FileExportDialog for the user, with an
* additional type selection, to allow the user to export
* the a document as a given type.
*/
-void sp_file_export_dialog (void *widget);
+bool sp_file_export_dialog (void *widget);
-/**
- * Export the given document as a Portable Network Graphics (PNG)
- * file. Returns FALSE if an error was encountered while writing
- * the file, TRUE otherwise.
- */
-int sp_export_png_file (SPDocument *doc, const gchar *filename,
- double x0, double y0, double x1, double y1,
- unsigned int width, unsigned int height, double xdpi, double ydpi,
- unsigned long bgcolor,
- unsigned int (*status) (float, void *), void *data, bool force_overwrite = false, GSList *items_only = NULL);
/*######################
index c90121860e973bb6fac8c06abf3d714bae149ace..44a977df7ff3180a876057100f31d33a4407e7c0 100644 (file)
--- a/src/helper/png-write.cpp
+++ b/src/helper/png-write.cpp
# include "config.h"
#endif
+#include <interface.h>
+#include <libnr/nr-pixops.h>
#include <glib/gmessages.h>
#include <png.h>
#include "png-write.h"
#include "io/sys.h"
+#include <display/nr-arena-item.h>
+#include <display/nr-arena.h>
+#include <document.h>
+#include <sp-item.h>
+#include <sp-root.h>
+#include <sp-defs.h>
/* This is an example of how to use libpng to read and write PNG files.
* The file libpng.txt is much more verbose then this. If you have not
@@ -204,3 +212,197 @@ sp_png_write_rgba_striped (const gchar *filename, int width, int height, double
return TRUE;
}
+
+
+struct SPEBP {
+ int width, height, sheight;
+ guchar r, g, b, a;
+ NRArenaItem *root; // the root arena item to show; it is assumed that all unneeded items are hidden
+ guchar *px;
+ unsigned (*status)(float, void *);
+ void *data;
+};
+
+
+/**
+ *
+ */
+static int
+sp_export_get_rows(guchar const **rows, int row, int num_rows, void *data)
+{
+ struct SPEBP *ebp = (struct SPEBP *) data;
+
+ if (ebp->status) {
+ if (!ebp->status((float) row / ebp->height, ebp->data)) return 0;
+ }
+
+ num_rows = MIN(num_rows, ebp->sheight);
+ num_rows = MIN(num_rows, ebp->height - row);
+
+ /* Set area of interest */
+ NRRectL bbox;
+ bbox.x0 = 0;
+ bbox.y0 = row;
+ bbox.x1 = ebp->width;
+ bbox.y1 = row + num_rows;
+ /* Update to renderable state */
+ NRGC gc(NULL);
+ nr_matrix_set_identity(&gc.transform);
+
+ nr_arena_item_invoke_update(ebp->root, &bbox, &gc,
+ NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE);
+
+ NRPixBlock pb;
+ nr_pixblock_setup_extern(&pb, NR_PIXBLOCK_MODE_R8G8B8A8N,
+ bbox.x0, bbox.y0, bbox.x1, bbox.y1,
+ ebp->px, 4 * ebp->width, FALSE, FALSE);
+
+ for (int r = 0; r < num_rows; r++) {
+ guchar *p = NR_PIXBLOCK_PX(&pb) + r * pb.rs;
+ for (int c = 0; c < ebp->width; c++) {
+ *p++ = ebp->r;
+ *p++ = ebp->g;
+ *p++ = ebp->b;
+ *p++ = ebp->a;
+ }
+ }
+
+ /* Render */
+ nr_arena_item_invoke_render(ebp->root, &bbox, &pb, 0);
+
+ for (int r = 0; r < num_rows; r++) {
+ rows[r] = NR_PIXBLOCK_PX(&pb) + r * pb.rs;
+ }
+
+ nr_pixblock_release(&pb);
+
+ return num_rows;
+}
+
+/**
+Hide all items which are not listed in list, recursively, skipping groups and defs
+*/
+static void
+hide_other_items_recursively(SPObject *o, GSList *list, unsigned dkey)
+{
+ if (SP_IS_ITEM(o)
+ && !SP_IS_DEFS(o)
+ && !SP_IS_ROOT(o)
+ && !SP_IS_GROUP(o)
+ && !g_slist_find(list, o))
+ {
+ sp_item_invoke_hide(SP_ITEM(o), dkey);
+ }
+
+ // recurse
+ if (!g_slist_find(list, o)) {
+ for (SPObject *child = sp_object_first_child(o) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
+ hide_other_items_recursively(child, list, dkey);
+ }
+ }
+}
+
+
+/**
+ * Render the SVG drawing onto a PNG raster image, then save to
+ * a file. Returns TRUE if succeeded in writing the file,
+ * FALSE otherwise.
+ */
+int
+sp_export_png_file(SPDocument *doc, gchar const *filename,
+ double x0, double y0, double x1, double y1,
+ unsigned width, unsigned height, double xdpi, double ydpi,
+ unsigned long bgcolor,
+ unsigned (*status)(float, void *),
+ void *data, bool force_overwrite,
+ GSList *items_only)
+{
+ int write_status = TRUE;
+ g_return_val_if_fail(doc != NULL, FALSE);
+ g_return_val_if_fail(filename != NULL, FALSE);
+ g_return_val_if_fail(width >= 1, FALSE);
+ g_return_val_if_fail(height >= 1, FALSE);
+
+ if (!force_overwrite && !sp_ui_overwrite_file(filename)) {
+ return FALSE;
+ }
+
+ sp_document_ensure_up_to_date(doc);
+
+ /* Go to document coordinates */
+ gdouble t = y0;
+ y0 = sp_document_height(doc) - y1;
+ y1 = sp_document_height(doc) - t;
+
+ /*
+ * 1) a[0] * x0 + a[2] * y1 + a[4] = 0.0
+ * 2) a[1] * x0 + a[3] * y1 + a[5] = 0.0
+ * 3) a[0] * x1 + a[2] * y1 + a[4] = width
+ * 4) a[1] * x0 + a[3] * y0 + a[5] = height
+ * 5) a[1] = 0.0;
+ * 6) a[2] = 0.0;
+ *
+ * (1,3) a[0] * x1 - a[0] * x0 = width
+ * a[0] = width / (x1 - x0)
+ * (2,4) a[3] * y0 - a[3] * y1 = height
+ * a[3] = height / (y0 - y1)
+ * (1) a[4] = -a[0] * x0
+ * (2) a[5] = -a[3] * y1
+ */
+
+ NRMatrix affine;
+ affine.c[0] = width / (x1 - x0);
+ affine.c[1] = 0.0;
+ affine.c[2] = 0.0;
+ affine.c[3] = height / (y1 - y0);
+ affine.c[4] = -affine.c[0] * x0;
+ affine.c[5] = -affine.c[3] * y0;
+
+ //SP_PRINT_MATRIX("SVG2PNG", &affine);
+
+ struct SPEBP ebp;
+ ebp.width = width;
+ ebp.height = height;
+ ebp.r = NR_RGBA32_R(bgcolor);
+ ebp.g = NR_RGBA32_G(bgcolor);
+ ebp.b = NR_RGBA32_B(bgcolor);
+ ebp.a = NR_RGBA32_A(bgcolor);
+
+ /* Create new arena */
+ NRArena *arena = NRArena::create();
+ unsigned dkey = sp_item_display_key_new(1);
+
+ /* Create ArenaItems and set transform */
+ ebp.root = sp_item_invoke_show(SP_ITEM(sp_document_root(doc)), arena, dkey, SP_ITEM_SHOW_DISPLAY);
+ nr_arena_item_set_transform(NR_ARENA_ITEM(ebp.root), NR::Matrix(&affine));
+
+ // We show all and then hide all items we don't want, instead of showing only requested items,
+ // because that would not work if the shown item references something in defs
+ if (items_only) {
+ hide_other_items_recursively(sp_document_root(doc), items_only, dkey);
+ }
+
+ ebp.status = status;
+ ebp.data = data;
+
+ if ((width < 256) || ((width * height) < 32768)) {
+ ebp.px = nr_pixelstore_64K_new(FALSE, 0);
+ ebp.sheight = 65536 / (4 * width);
+ write_status = sp_png_write_rgba_striped(filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp);
+ nr_pixelstore_64K_free(ebp.px);
+ } else {
+ ebp.px = g_new(guchar, 4 * 64 * width);
+ ebp.sheight = 64;
+ write_status = sp_png_write_rgba_striped(filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp);
+ g_free(ebp.px);
+ }
+
+ // Hide items
+ sp_item_invoke_hide(SP_ITEM(sp_document_root(doc)), dkey);
+
+ /* Free Arena and ArenaItem */
+ nr_arena_item_unref(ebp.root);
+ nr_object_unref((NRObject *) arena);
+ return write_status;
+}
+
diff --git a/src/helper/png-write.h b/src/helper/png-write.h
index f8011f53e3a7e4bda25bdb4969eb726df4cc6f09..bd4f31699c40038288914431564ab77a1554bec2 100644 (file)
--- a/src/helper/png-write.h
+++ b/src/helper/png-write.h
int (* get_rows) (guchar const **rows, int row, int num_rows, void *data),
void *data);
+/**
+ * Export the given document as a Portable Network Graphics (PNG)
+ * file. Returns FALSE if an error was encountered while writing
+ * the file, TRUE otherwise.
+ */
+int sp_export_png_file (SPDocument *doc, const gchar *filename,
+ double x0, double y0, double x1, double y1,
+ unsigned int width, unsigned int height, double xdpi, double ydpi,
+ unsigned long bgcolor,
+ unsigned int (*status) (float, void *), void *data, bool force_overwrite = false, GSList *items_only = NULL);
+
#endif