From 3db4920631ecd4906f629a529c97684316d23055 Mon Sep 17 00:00:00 2001 From: buliabyak Date: Mon, 13 Nov 2006 07:40:25 +0000 Subject: [PATCH] factor out retrieving export hints from selection and document; use that for create_bitmap if no resolution/minsize specified in prefs; for default 90dpi, snap the bitmap to pixel grid; move deleting objects when clipping/masking to the end of function --- src/dialogs/export.cpp | 58 ++--------------- src/selection-chemistry.cpp | 124 ++++++++++++++++++++++++++++++++---- src/selection-chemistry.h | 3 + 3 files changed, 120 insertions(+), 65 deletions(-) diff --git a/src/dialogs/export.cpp b/src/dialogs/export.cpp index 720cebbed..9f1edc7e8 100644 --- a/src/dialogs/export.cpp +++ b/src/dialogs/export.cpp @@ -43,6 +43,7 @@ #include "file.h" #include "macros.h" #include "sp-namedview.h" +#include "selection-chemistry.h" #include "dialog-events.h" #include "../prefs-utils.h" @@ -818,22 +819,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base) case SELECTION_PAGE: case SELECTION_DRAWING: { SPDocument * doc = SP_ACTIVE_DOCUMENT; - Inkscape::XML::Node * repr = sp_document_repr_root(doc); - const gchar * dpi_string; - - filename = repr->attribute("inkscape:export-filename"); - - dpi_string = NULL; - dpi_string = repr->attribute("inkscape:export-xdpi"); - if (dpi_string != NULL) { - xdpi = atof(dpi_string); - } - - dpi_string = NULL; - dpi_string = repr->attribute("inkscape:export-ydpi"); - if (dpi_string != NULL) { - ydpi = atof(dpi_string); - } + sp_document_get_export_hints (doc, &filename, &xdpi, &ydpi); if (filename == NULL) { if (doc_export_name != NULL) { @@ -846,50 +832,14 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base) } case SELECTION_SELECTION: if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - const GSList * reprlst; - bool filename_search = TRUE; - bool xdpi_search = TRUE; - bool ydpi_search = TRUE; - - reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList(); - for(; reprlst != NULL && - filename_search && - xdpi_search && - ydpi_search; - reprlst = reprlst->next) { - const gchar * dpi_string; - Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; - - if (filename_search) { - filename = repr->attribute("inkscape:export-filename"); - if (filename != NULL) - filename_search = FALSE; - } - if (xdpi_search) { - dpi_string = NULL; - dpi_string = repr->attribute("inkscape:export-xdpi"); - if (dpi_string != NULL) { - xdpi = atof(dpi_string); - xdpi_search = FALSE; - } - } - - if (ydpi_search) { - dpi_string = NULL; - dpi_string = repr->attribute("inkscape:export-ydpi"); - if (dpi_string != NULL) { - ydpi = atof(dpi_string); - ydpi_search = FALSE; - } - } - } + sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), &filename, &xdpi, &ydpi); /* If we still don't have a filename -- let's build one that's nice */ if (filename == NULL) { const gchar * id = NULL; - reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList(); + const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList(); for(; reprlst != NULL; reprlst = reprlst->next) { Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; if (repr->attribute("id")) { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 9d3128ebc..58decfad7 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -71,6 +71,7 @@ #include #include "helper/units.h" #include "sp-item.h" +#include "unit-constants.h" using NR::X; using NR::Y; @@ -2283,6 +2284,73 @@ sp_selection_untile() } } +void +sp_selection_get_export_hints (Inkscape::Selection *selection, const char **filename, float *xdpi, float *ydpi) +{ + if (selection->isEmpty()) { + return; + } + + const GSList * reprlst = selection->reprList(); + bool filename_search = TRUE; + bool xdpi_search = TRUE; + bool ydpi_search = TRUE; + + for(; reprlst != NULL && + filename_search && + xdpi_search && + ydpi_search; + reprlst = reprlst->next) { + const gchar * dpi_string; + Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; + + if (filename_search) { + *filename = repr->attribute("inkscape:export-filename"); + if (*filename != NULL) + filename_search = FALSE; + } + + if (xdpi_search) { + dpi_string = NULL; + dpi_string = repr->attribute("inkscape:export-xdpi"); + if (dpi_string != NULL) { + *xdpi = atof(dpi_string); + xdpi_search = FALSE; + } + } + + if (ydpi_search) { + dpi_string = NULL; + dpi_string = repr->attribute("inkscape:export-ydpi"); + if (dpi_string != NULL) { + *ydpi = atof(dpi_string); + ydpi_search = FALSE; + } + } + } +} + +void +sp_document_get_export_hints (SPDocument * doc, const char **filename, float *xdpi, float *ydpi) +{ + Inkscape::XML::Node * repr = sp_document_repr_root(doc); + const gchar * dpi_string; + + *filename = repr->attribute("inkscape:export-filename"); + + dpi_string = NULL; + dpi_string = repr->attribute("inkscape:export-xdpi"); + if (dpi_string != NULL) { + *xdpi = atof(dpi_string); + } + + dpi_string = NULL; + dpi_string = repr->attribute("inkscape:export-ydpi"); + if (dpi_string != NULL) { + *ydpi = atof(dpi_string); + } +} + void sp_selection_create_bitmap_copy () { @@ -2338,18 +2406,35 @@ sp_selection_create_bitmap_copy () // Calculate resolution double res; int const prefs_res = prefs_get_int_attribute ("options.createbitmap", "resolution", 0); + int const prefs_min = prefs_get_int_attribute ("options.createbitmap", "minsize", 0); if (0 < prefs_res) { // If it's given explicitly in prefs, take it res = prefs_res; + } else if (0 < prefs_min) { + // If minsize is given, look up minimum bitmap size (default 250 pixels) and calculate resolution from it + res = PX_PER_IN * prefs_min / MIN ((bbox.x1 - bbox.x0), (bbox.y1 - bbox.y0)); } else { - // Otherwise look up minimum bitmap size (default 250 pixels) and calculate resolution from it - int const prefs_min = prefs_get_int_attribute ("options.createbitmap", "minsize", 250); - res = prefs_min / MIN ((bbox.x1 - bbox.x0), (bbox.y1 - bbox.y0)); + float hint_xdpi = 0, hint_ydpi = 0; + const char *hint_filename; + // take resolution hint from the selected objects + sp_selection_get_export_hints (selection, &hint_filename, &hint_xdpi, &hint_ydpi); + if (hint_xdpi != 0) { + res = hint_xdpi; + } else { + // take resolution hint from the document + sp_document_get_export_hints (document, &hint_filename, &hint_xdpi, &hint_ydpi); + if (hint_xdpi != 0) { + res = hint_xdpi; + } else { + // if all else fails, take the default 90 dpi + res = PX_PER_IN; + } + } } // The width and height of the bitmap in pixels - unsigned width = (unsigned) floor ((bbox.x1 - bbox.x0) * res); - unsigned height =(unsigned) floor ((bbox.y1 - bbox.y0) * res); + unsigned width = (unsigned) floor ((bbox.x1 - bbox.x0) * res / PX_PER_IN); + unsigned height =(unsigned) floor ((bbox.y1 - bbox.y0) * res / PX_PER_IN); // Find out if we have to run a filter const gchar *run = NULL; @@ -2377,7 +2462,12 @@ sp_selection_create_bitmap_copy () // Calculate the matrix that will be applied to the image so that it exactly overlaps the source objects NR::Matrix eek = sp_item_i2d_affine (SP_ITEM(parent_object)); - NR::Matrix t = NR::scale (1/res, -1/res) * NR::translate (bbox.x0, bbox.y1) * eek.inverse(); + NR::Matrix t; + if (res == PX_PER_IN) { // for default 90 dpi, snap it to pixel grid + t = NR::scale (1, -1) * NR::translate ((unsigned) (bbox.x0 + 0.5), (unsigned) (bbox.y1 + 0.5)) * eek.inverse(); + } else { + t = NR::scale (1, -1) * NR::translate (bbox.x0, bbox.y1) * eek.inverse(); + } // Do the export sp_export_png_file(document, filepath, @@ -2403,8 +2493,13 @@ sp_selection_create_bitmap_copy () Inkscape::XML::Node * repr = sp_repr_new ("svg:image"); repr->setAttribute("xlink:href", filename); repr->setAttribute("sodipodi:absref", filepath); - sp_repr_set_svg_double(repr, "width", gdk_pixbuf_get_width(pb)); - sp_repr_set_svg_double(repr, "height", gdk_pixbuf_get_height(pb)); + if (res == PX_PER_IN) { // for default 90 dpi, snap it to pixel grid + sp_repr_set_svg_double(repr, "width", width); + sp_repr_set_svg_double(repr, "height", height); + } else { + sp_repr_set_svg_double(repr, "width", (bbox.x1 - bbox.x0)); + sp_repr_set_svg_double(repr, "height", (bbox.y1 - bbox.y0)); + } // Write transform gchar c[256]; @@ -2476,6 +2571,7 @@ sp_selection_set_mask(bool apply_clip_path, bool apply_to_layer) // create a list of duplicates GSList *mask_items = NULL; GSList *apply_to_items = NULL; + GSList *items_to_delete = NULL; bool topmost = prefs_get_int_attribute ("options.maskobject", "topmost", 1); bool remove_original = prefs_get_int_attribute ("options.maskobject", "remove", 1); @@ -2489,7 +2585,7 @@ sp_selection_set_mask(bool apply_clip_path, bool apply_to_layer) if (remove_original) { SPObject *item = SP_OBJECT (i->data); - item->deleteObject (false); + items_to_delete = g_slist_prepend (items_to_delete, item); } } } else if (!topmost) { @@ -2500,7 +2596,7 @@ sp_selection_set_mask(bool apply_clip_path, bool apply_to_layer) if (remove_original) { SPObject *item = SP_OBJECT (i->data); - item->deleteObject (false); + items_to_delete = g_slist_prepend (items_to_delete, item); } for (i = i->next; i != NULL; i = i->next) { @@ -2517,7 +2613,7 @@ sp_selection_set_mask(bool apply_clip_path, bool apply_to_layer) if (remove_original) { SPObject *item = SP_OBJECT (i->data); - item->deleteObject (false); + items_to_delete = g_slist_prepend (items_to_delete, item); } } @@ -2553,6 +2649,12 @@ sp_selection_set_mask(bool apply_clip_path, bool apply_to_layer) g_slist_free (mask_items); g_slist_free (apply_to_items); + for (GSList *i = items_to_delete; NULL != i; i = i->next) { + SPObject *item = SP_OBJECT (i->data); + item->deleteObject (false); + } + g_slist_free (items_to_delete); + if (apply_clip_path) sp_document_done (document, SP_VERB_OBJECT_SET_CLIPPATH, _("Set clipping path")); else diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index 45e45077a..6bd58e8e5 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -88,6 +88,9 @@ void scroll_to_show_item(SPDesktop *desktop, SPItem *item); void sp_undo (SPDesktop *desktop, SPDocument *doc); void sp_redo (SPDesktop *desktop, SPDocument *doc); +void sp_selection_get_export_hints (Inkscape::Selection *selection, const char **filename, float *xdpi, float *ydpi); +void sp_document_get_export_hints (SPDocument * doc, const char **filename, float *xdpi, float *ydpi); + void sp_selection_create_bitmap_copy (); void sp_selection_set_mask(bool apply_clip_path, bool apply_to_layer); -- 2.30.2