Code

remove memory boundries on bitmap renderer, optimize memory usage
[inkscape.git] / src / helper / pixbuf-ops.cpp
index f50062d2dab062152625d4167191643269e9b40d..7ce5c7dd2779a3c97023f65745ba716dc03651f8 100644 (file)
@@ -1,10 +1,10 @@
-#define __SP_PIXBUF_OPS_C__
-
 /*
  * Helpers for SPItem -> gdk_pixbuf related stuff
  *
  * Authors:
  *   John Cliff <simarilius@yahoo.com>
+ *   Jon A. Cruz <jon@joncruz.org>
+ *   Abhishek Sharma
  *
  * Copyright (C) 2008 John Cliff
  *
 
 #include "pixbuf-ops.h"
 
+// TODO look for copy-n-past duplication of this function:
 /**
  * Hide all items that are not listed in list, recursively, skipping groups and defs.
  */
-static void
-hide_other_items_recursively(SPObject *o, GSList *list, unsigned dkey)
+static void hide_other_items_recursively(SPObject *o, GSList *list, unsigned dkey)
 {
     if ( SP_IS_ITEM(o)
          && !SP_IS_DEFS(o)
@@ -51,12 +51,12 @@ hide_other_items_recursively(SPObject *o, GSList *list, unsigned dkey)
          && !SP_IS_USE(o)
          && !g_slist_find(list, o) )
     {
-        sp_item_invoke_hide(SP_ITEM(o), dkey);
+        SP_ITEM(o)->invoke_hide(dkey);
     }
 
     // recurse
     if (!g_slist_find(list, o)) {
-        for (SPObject *child = sp_object_first_child(o) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
+        for ( SPObject *child = o->firstChild() ; child; child = child->getNext() ) {
             hide_other_items_recursively(child, list, dkey);
         }
     }
@@ -91,6 +91,19 @@ sp_export_jpg_file(SPDocument *doc, gchar const *filename,
      else return false;
 }
 
+/**
+    generates a bitmap from given items
+    the bitmap is stored in RAM and not written to file
+    @param x0
+    @param y0
+    @param x1
+    @param y1
+    @param width
+    @param height
+    @param xdpi
+    @param ydpi
+    @return the created GdkPixbuf structure or NULL if no memory is allocable
+*/
 GdkPixbuf*
 sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/,
                             double x0, double y0, double x1, double y1,
@@ -104,16 +117,16 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/,
      /* Create new arena for offscreen rendering*/
      NRArena *arena = NRArena::create();
      nr_arena_set_renderoffscreen(arena);
-     unsigned dkey = sp_item_display_key_new(1);
+     unsigned dkey = SPItem::display_key_new(1);
 
-     sp_document_ensure_up_to_date (doc);
+     doc->ensureUpToDate();
 
      Geom::Rect screen=Geom::Rect(Geom::Point(x0,y0), Geom::Point(x1, y1));
 
      double padding = 1.0;
 
      Geom::Point origin(screen.min()[Geom::X],
-                      sp_document_height(doc) - screen[Geom::Y].extent() - screen.min()[Geom::Y]);
+                      doc->getHeight() - screen[Geom::Y].extent() - screen.min()[Geom::Y]);
 
      origin[Geom::X] = origin[Geom::X] + (screen[Geom::X].extent() * ((1 - padding) / 2));
      origin[Geom::Y] = origin[Geom::Y] + (screen[Geom::Y].extent() * ((1 - padding) / 2));
@@ -122,7 +135,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/,
      Geom::Matrix affine = scale * Geom::Translate(-origin * scale);
 
      /* Create ArenaItems and set transform */
-     NRArenaItem *root = sp_item_invoke_show(SP_ITEM(sp_document_root(doc)), arena, dkey, SP_ITEM_SHOW_DISPLAY);
+     NRArenaItem *root = SP_ITEM(doc->getRoot())->invoke_show( arena, dkey, SP_ITEM_SHOW_DISPLAY);
      nr_arena_item_set_transform(NR_ARENA_ITEM(root), affine);
 
      NRGC gc(NULL);
@@ -131,7 +144,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/,
      // 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);
+         hide_other_items_recursively(doc->getRoot(), items_only, dkey);
      }
 
      NRRectL final_bbox;
@@ -164,6 +177,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/,
          dtc[2] = NR_RGBA32_B(bgcolor);
          dtc[3] = NR_RGBA32_A(bgcolor);
 
+         // fill pixelblock using background colour
          for (gsize fy = 0; fy < height; fy++) {
              guchar *p = NR_PIXBLOCK_PX(&B) + fy * (gsize)B.rs;
              for (unsigned int fx = 0; fx < width; fx++) {
@@ -186,7 +200,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/,
     {
         g_warning("sp_generate_internal_bitmap: not enough memory to create pixel buffer. Need %lld.", size);
     }
-     sp_item_invoke_hide (SP_ITEM(sp_document_root(doc)), dkey);
+     SP_ITEM(doc->getRoot())->invoke_hide(dkey);
      nr_object_unref((NRObject *) arena);
 
 //    gdk_pixbuf_save (pixbuf, "C:\\temp\\internal.jpg", "jpeg", NULL, "quality","100", NULL);