[shotwell] Paint image background for transparent images



commit 6d1786b36a93298a35e19d6dd3ec95569de9bd2a
Author: Jens Georg <mail jensge org>
Date:   Thu Apr 20 21:44:50 2017 +0200

    Paint image background for transparent images
    
    Fixes issue with images that have black foreground and transparent background
    by painting stippled background pattern.
    
    Signed-off-by: Jens Georg <mail jensge org>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=716708

 configure.ac                          |    2 +-
 src/Page.vala                         |   15 ++++++---------
 src/editing_tools/EditingTools.vala   |   26 ++------------------------
 src/editing_tools/StraightenTool.vala |    5 +----
 src/util/image.vala                   |   31 +++++++++++++++++++++++++++++++
 5 files changed, 41 insertions(+), 38 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 028cbc7..7087bb9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -105,7 +105,7 @@ dnl Check for required packages
 dnl ***********************************************************************
 PKG_CHECK_MODULES(SHOTWELL, [
                              gee-0.8 >= 0.8.5
-                             gexiv2 >= 0.10.4
+                             gexiv2 >= 0.10.3
                              gio-unix-2.0 >= 2.20
                              glib-2.0 >= 2.40.0
                              gmodule-2.0 >= 2.24.0
diff --git a/src/Page.vala b/src/Page.vala
index cda204c..3a74451 100644
--- a/src/Page.vala
+++ b/src/Page.vala
@@ -2048,9 +2048,7 @@ public abstract class SinglePhotoPage : Page {
 
         int draw_y = (pixmap_dim.height - view_rect.height) / 2;
         draw_y = draw_y.clamp(0, int.MAX);
-        
-        Gdk.cairo_set_source_pixbuf(pixmap_ctx, zoomed, draw_x, draw_y);
-        pixmap_ctx.paint();
+        paint_pixmap_with_background(pixmap_ctx, zoomed, draw_x, draw_y);
     }
 
     protected void on_interactive_zoom(ZoomState interactive_zoom_state) {
@@ -2237,7 +2235,7 @@ public abstract class SinglePhotoPage : Page {
         // when the resize is completed, do a high-quality repaint
         repaint();
     }
-    
+
     private bool on_canvas_exposed(Cairo.Context exposed_ctx) {
         // draw pixmap onto canvas unless it's not been instantiated, in which case draw black
         // (so either old image or contents of another page is not left on screen)
@@ -2257,7 +2255,7 @@ public abstract class SinglePhotoPage : Page {
     
     protected virtual void updated_pixbuf(Gdk.Pixbuf pixbuf, UpdateReason reason, Dimensions old_dim) {
     }
-    
+
     protected virtual void paint(Cairo.Context ctx, Dimensions ctx_dim) {
         if (is_zoom_supported() && (!static_zoom_state.is_default())) {
             set_source_color_from_string(ctx, "#000");
@@ -2268,12 +2266,11 @@ public abstract class SinglePhotoPage : Page {
         } else if (!transition_clock.paint(ctx, ctx_dim.width, ctx_dim.height)) {
             // transition is not running, so paint the full image on a black background
             set_source_color_from_string(ctx, "#000");
-            
+
             ctx.rectangle(0, 0, pixmap_dim.width, pixmap_dim.height);
             ctx.fill();
-            
-            Gdk.cairo_set_source_pixbuf(ctx, scaled, scaled_pos.x, scaled_pos.y);
-            ctx.paint();
+
+            paint_pixmap_with_background(ctx, scaled, scaled_pos.x, scaled_pos.y);
         }
     }
     
diff --git a/src/editing_tools/EditingTools.vala b/src/editing_tools/EditingTools.vala
index d160f23..0fc0b7e 100644
--- a/src/editing_tools/EditingTools.vala
+++ b/src/editing_tools/EditingTools.vala
@@ -265,29 +265,7 @@ public abstract class PhotoCanvas {
         default_ctx.fill();
 
         // paint the actual image
-        Gdk.cairo_set_source_pixbuf(default_ctx, pixbuf, scaled_position.x, scaled_position.y);
-        default_ctx.rectangle(scaled_position.x, scaled_position.y,
-            pixbuf.get_width(), pixbuf.get_height());
-        default_ctx.fill();
-        default_ctx.restore();
-    }
-
-    public void paint_pixbuf_area(Gdk.Pixbuf pixbuf, Box source_area) {
-        default_ctx.save();
-        if (pixbuf.get_has_alpha()) {
-            set_source_color_from_string(default_ctx, "#000");
-            default_ctx.rectangle(scaled_position.x + source_area.left,
-                scaled_position.y + source_area.top,
-                source_area.get_width(), source_area.get_height());
-            default_ctx.fill();
-
-        }
-        Gdk.cairo_set_source_pixbuf(default_ctx, pixbuf, scaled_position.x,
-            scaled_position.y);
-        default_ctx.rectangle(scaled_position.x + source_area.left,
-            scaled_position.y + source_area.top,
-            source_area.get_width(), source_area.get_height());
-        default_ctx.fill();
+        paint_pixmap_with_background(default_ctx, pixbuf, scaled_position.x, scaled_position.y);
         default_ctx.restore();
     }
 
@@ -460,7 +438,7 @@ public abstract class PhotoCanvas {
         Cairo.Surface surface = new Cairo.Surface.similar(default_ctx.get_target(),
             Cairo.Content.COLOR_ALPHA, pos.width, pos.height);
         Cairo.Context ctx = new Cairo.Context(surface);
-        Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 0, 0);
+        paint_pixmap_with_background(ctx, pixbuf, 0, 0);
         ctx.paint();
         return surface;
     }
diff --git a/src/editing_tools/StraightenTool.vala b/src/editing_tools/StraightenTool.vala
index 5c0eb98..023b636 100644
--- a/src/editing_tools/StraightenTool.vala
+++ b/src/editing_tools/StraightenTool.vala
@@ -292,10 +292,7 @@ public class StraightenTool : EditingTool {
         // copy image data from photo into a cairo surface.
         photo_surf = new Cairo.ImageSurface(Cairo.Format.ARGB32, low_res_tmp.width, low_res_tmp.height);
         Cairo.Context ctx = new Cairo.Context(photo_surf);
-        Gdk.cairo_set_source_pixbuf(ctx, low_res_tmp, 0, 0);
-        ctx.rectangle(0, 0, low_res_tmp.width, low_res_tmp.height);
-        ctx.fill();
-        ctx.paint();
+        paint_pixmap_with_background(ctx, low_res_tmp, 0, 0);
 
         // prepare rotation surface and context. we paint a rotated,
         // low-res copy of the image into it, followed by a faint grid.
diff --git a/src/util/image.vala b/src/util/image.vala
index 4adafae..09de328 100644
--- a/src/util/image.vala
+++ b/src/util/image.vala
@@ -446,6 +446,37 @@ Gdk.Point derotate_point_arb(Gdk.Point source_point, int img_w, int img_h, doubl
     return rotate_point_arb(source_point, img_w, img_h, angle, true);
 }
 
+private static Cairo.Surface background_surface = null;
+
+private Cairo.Surface get_background_surface() {
+    if (background_surface == null) {
+        background_surface = new Cairo.ImageSurface(Cairo.Format.RGB24, 16, 16);
+        var ctx = new Cairo.Context(background_surface);
+        ctx.set_operator(Cairo.Operator.SOURCE);
+        set_source_color_from_string(ctx, "#808080");
+        ctx.rectangle(0,0,8,8);
+        ctx.rectangle(8,8,8,8);
+        ctx.fill();
+        set_source_color_from_string(ctx, "#cccccc");
+        ctx.rectangle(0,8,8,8);
+        ctx.rectangle(8,0,8,8);
+        ctx.fill();
+    }
+
+    return background_surface;
+}
+
+public void paint_pixmap_with_background (Cairo.Context ctx, Gdk.Pixbuf pixbuf, int x, int y) {
+    if (pixbuf.get_has_alpha()) {
+        ctx.set_source_surface(get_background_surface(), 0, 0);
+        ctx.get_source().set_extend(Cairo.Extend.REPEAT);
+        ctx.rectangle(x, y, pixbuf.width, pixbuf.height);
+        ctx.fill();
+    }
+
+    Gdk.cairo_set_source_pixbuf(ctx, pixbuf, x, y);
+    ctx.paint();
+}
 
 // Force an axially-aligned box to be inside a rotated rectangle.
 Box clamp_inside_rotated_image(Box src, int img_w, int img_h, double angle_deg,


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