[dia/dia-0-96] merged from git diff {384bad9, 30a5ac7a} > rev-3957.diff



commit bec402cc1f71cb84cce1a32fa0ea4fd9690ab2bb
Author: Hans Breuer <hans breuer org>
Date:   Mon Apr 13 14:45:06 2009 +0200

    merged from git diff {384bad9,30a5ac7a} > rev-3957.diff
    
    2008-04-25  Hans Breuer  <hans breuer org>
    
    * lib/diagdkrenderer.c dia_image.[ch] : don't use dia_image_draw()
    for up-scaling of images to reduce memory consumption (bug #439885)
---
 ChangeLog            |    6 ++++++
 lib/dia_image.c      |    9 +++++++++
 lib/dia_image.h      |    2 ++
 lib/diagdkrenderer.c |   37 ++++++++++++++++++++++++++++++++++---
 4 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e0d8531..0066d78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,12 @@
 	a new sheet the struct was not properly passed, same for new object
 	Together this should fix bug #393526
 
+[merged from git diff {384bad9,30a5ac7a} > rev-3957.diff]
+2008-04-25  Hans Breuer  <hans breuer org>
+
+	* lib/diagdkrenderer.c dia_image.[ch] : don't use dia_image_draw()
+	for up-scaling of images to reduce memory consumption (bug #439885)
+
 2008-03-16  Hans Breuer  <hans breuer org>
 
 	* lib/libdia.def : added missing exports
diff --git a/lib/dia_image.c b/lib/dia_image.c
index aa6ff1b..d05b0ad 100644
--- a/lib/dia_image.c
+++ b/lib/dia_image.c
@@ -202,6 +202,15 @@ dia_image_rowstride(DiaImage image)
 {
   return gdk_pixbuf_get_rowstride(image->image);
 }
+/** Direct const access to the underlying GdkPixbuf
+ * @param image An image object
+ * @returns The pixbuf
+ */
+const GdkPixbuf* 
+dia_image_pixbuf (DiaImage image)
+{
+  return image->image;
+}
 
 /** Get the raw RGB data from an image.
  * @param image An image object.
diff --git a/lib/dia_image.h b/lib/dia_image.h
index 0ed6731..b3cc120 100644
--- a/lib/dia_image.h
+++ b/lib/dia_image.h
@@ -20,6 +20,7 @@
 
 #include "diatypes.h"
 #include <gdk/gdktypes.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
 
 #include "geometry.h"
 
@@ -51,6 +52,7 @@ guint8 *dia_image_mask_data(DiaImage image);
  */
 const guint8 *dia_image_rgba_data(DiaImage image);
 const char *dia_image_filename(DiaImage image);
+const GdkPixbuf* dia_image_pixbuf (DiaImage image);
 
 #endif /* DIA_IMAGE_H */
 
diff --git a/lib/diagdkrenderer.c b/lib/diagdkrenderer.c
index ee4b355..672ae77 100644
--- a/lib/diagdkrenderer.c
+++ b/lib/diagdkrenderer.c
@@ -807,14 +807,45 @@ draw_image (DiaRenderer *object,
     self_class->fill_rect(object, point, &lr, renderer->highlight_color);
   } else {
     int real_width, real_height, real_x, real_y;
-  
+    const GdkPixbuf *org = dia_image_pixbuf (image);
+    int org_width = gdk_pixbuf_get_width(org);
+    int org_height = gdk_pixbuf_get_height(org);
+    
     real_width = dia_transform_length(renderer->transform, width);
     real_height = dia_transform_length(renderer->transform, height);
     dia_transform_coords(renderer->transform, point->x, point->y,
 			 &real_x, &real_y);
 
-    dia_image_draw(image,  renderer->pixmap, renderer->gc, real_x, real_y,
-		   real_width, real_height);
+    if (real_width == org_width && real_height == org_height) {
+      gdk_draw_pixbuf(renderer->pixmap, renderer->gc, org,
+		      0, 0, real_x, real_y, real_width, real_height, 
+		      GDK_RGB_DITHER_NORMAL, 0, 0);
+    } else if (real_width > org_width || real_height > org_height) {
+      /* don't use dia_image_draw for big zooms, it scales the whole pixbuf even if not needed */
+      int sub_width = real_width - (real_x >= 0 ? 0 : -real_x);
+      int sub_height = real_height - (real_y >= 0 ? 0 : -real_y);
+
+      if (sub_height > 0 && sub_width > 0) {
+        GdkPixbuf *scaled = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (org),
+                                            gdk_pixbuf_get_has_alpha (org),
+					    gdk_pixbuf_get_bits_per_sample (org),
+					    sub_width, sub_height);
+        double scale_x = (double)real_width/org_width;
+        double scale_y = (double)real_height/org_height;
+        gdk_pixbuf_scale (org, scaled,
+                          0, 0, sub_width, sub_height,
+			  real_x >= 0 ? 0 : real_x, real_y >= 0 ? 0 : real_y,
+			  scale_x, scale_y, GDK_INTERP_TILES);
+        gdk_draw_pixbuf(renderer->pixmap, renderer->gc, scaled,
+		        0, 0, real_x >= 0 ? real_x : 0, real_y >= 0 ? real_y : 0, 
+		        sub_width, sub_height, GDK_RGB_DITHER_NORMAL, 0, 0);
+        g_object_unref (scaled);
+      }
+    } else {
+      /* otherwise still using the caching variant */
+      dia_image_draw(image,  renderer->pixmap, renderer->gc, real_x, real_y,
+		     real_width, real_height);
+    }
   }
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]