Code

Fix Bug #675309 - crash when unlinking an orphaned clone
[inkscape.git] / src / helper / png-write.cpp
index aa6434baec66e555c0114c9582c3c3f66b395797..754372f23b35e40b22d22c2d2961c0a96090dac4 100644 (file)
@@ -19,6 +19,7 @@
 #include <interface.h>
 #include <libnr/nr-pixops.h>
 #include <libnr/nr-translate-scale-ops.h>
+#include <2geom/rect.h>
 #include <glib/gmessages.h>
 #include <png.h>
 #include "png-write.h"
@@ -29,8 +30,8 @@
 #include <sp-item.h>
 #include <sp-root.h>
 #include <sp-defs.h>
-#include "prefs-utils.h"
-#include "dialogs/rdf.h"
+#include "preferences.h"
+#include "rdf.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
@@ -132,6 +133,7 @@ sp_png_write_rgba_striped(SPDocument *doc,
     png_uint_32 r;
 
     g_return_val_if_fail(filename != NULL, false);
+    g_return_val_if_fail(data != NULL, false);
 
     /* open the file */
 
@@ -221,7 +223,7 @@ sp_png_write_rgba_striped(SPDocument *doc,
                 }
             } else {
                 g_warning("Unable to find entity [%s]", pngToDc[i + 1]);
-            }            
+            }
         }
 
 
@@ -325,7 +327,7 @@ sp_export_get_rows(guchar const **rows, int row, int num_rows, void *data)
     bbox.y1 = row + num_rows;
     /* Update to renderable state */
     NRGC gc(NULL);
-    gc.transform.set_identity();
+    gc.transform.setIdentity();
 
     nr_arena_item_invoke_update(ebp->root, &bbox, &gc,
            NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE);
@@ -386,9 +388,20 @@ hide_other_items_recursively(SPObject *o, GSList *list, unsigned dkey)
  *
  * \return true if succeeded (or if no action was taken), false if an error occurred.
  */
+bool 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,
+                   GSList *items_only)
+{
+    return sp_export_png_file(doc, filename, Geom::Rect(Geom::Point(x0,y0),Geom::Point(x1,y1)),
+                              width, height, xdpi, ydpi, bgcolor, status, data, force_overwrite, items_only);
+}
 bool
 sp_export_png_file(SPDocument *doc, gchar const *filename,
-                   double x0, double y0, double x1, double y1,
+                   Geom::Rect const &area,
                    unsigned long width, unsigned long height, double xdpi, double ydpi,
                    unsigned long bgcolor,
                    unsigned (*status)(float, void *),
@@ -399,6 +412,7 @@ sp_export_png_file(SPDocument *doc, gchar const *filename,
     g_return_val_if_fail(filename != NULL, false);
     g_return_val_if_fail(width >= 1, false);
     g_return_val_if_fail(height >= 1, false);
+    g_return_val_if_fail(!area.hasZeroArea(), false);
 
     if (!force_overwrite && !sp_ui_overwrite_file(filename)) {
         /* Remark: We return true so as not to invoke an error dialog in case export is cancelled
@@ -408,20 +422,12 @@ sp_export_png_file(SPDocument *doc, gchar const *filename,
         return true;
     }
 
-    // export with maximum blur rendering quality
-    int saved_quality = prefs_get_int_attribute("options.blurquality", "value", 0);
-    prefs_set_int_attribute("options.blurquality", "value", 2);
-
     sp_document_ensure_up_to_date(doc);
 
-    /* Go to document coordinates */
-    {
-        gdouble const t = y0;
-        y0 = sp_document_height(doc) - y1;
-        y1 = sp_document_height(doc) - t;
-    }
+    /* Calculate translation by transforming to document coordinates (flipping Y)*/
+    Geom::Point translation = Geom::Point(-area[Geom::X][0], area[Geom::Y][1] - sp_document_height(doc));
 
-    /*
+    /*  This calculation is only valid when assumed that (x0,y0)= area.corner(0) and (x1,y1) = area.corner(2)
      * 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
@@ -437,9 +443,9 @@ sp_export_png_file(SPDocument *doc, gchar const *filename,
      * (2) a[5] = -a[3] * y1
      */
 
-    Geom::Matrix const affine(Geom::Translate(-x0, -y0)
-                            * Geom::Scale(width / (x1 - x0),
-                                        height / (y1 - y0)));
+    Geom::Matrix const affine(Geom::Translate(translation)
+                            * Geom::Scale(width / area.width(),
+                                        height / area.height()));
 
     //SP_PRINT_MATRIX("SVG2PNG", &affine);
 
@@ -453,6 +459,8 @@ sp_export_png_file(SPDocument *doc, gchar const *filename,
 
     /* Create new arena */
     NRArena *const arena = NRArena::create();
+    // export with maximum blur rendering quality
+    nr_arena_set_renderoffscreen(arena);
     unsigned const dkey = sp_item_display_key_new(1);
 
     /* Create ArenaItems and set transform */
@@ -475,8 +483,8 @@ sp_export_png_file(SPDocument *doc, gchar const *filename,
         write_status = sp_png_write_rgba_striped(doc, 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;
+        ebp.px = g_try_new(guchar, 4 * ebp.sheight * width);
         write_status = sp_png_write_rgba_striped(doc, filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp);
         g_free(ebp.px);
     }
@@ -487,9 +495,6 @@ sp_export_png_file(SPDocument *doc, gchar const *filename,
     /* Free arena */
     nr_object_unref((NRObject *) arena);
 
-    // restore saved blur quality
-    prefs_set_int_attribute("options.blurquality", "value", saved_quality);
-
     return write_status;
 }
 
@@ -503,4 +508,4 @@ sp_export_png_file(SPDocument *doc, gchar const *filename,
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :