changeset 1245:3a2ffe3a7eae

Implemented dw_pixmap_stretch_bitblt() on GTK3... GTK2 support for printing contexts is there but not tested. GTK2 pixmap/drawable support to come if possible.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 19 Oct 2011 09:40:23 +0000
parents db26b9622769
children c228c90f95cb
files gtk/dw.c gtk3/dw.c
diffstat 2 files changed, 102 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/gtk/dw.c	Wed Oct 19 08:55:24 2011 +0000
+++ b/gtk/dw.c	Wed Oct 19 09:40:23 2011 +0000
@@ -8588,13 +8588,14 @@
 
 #if GTK_CHECK_VERSION(2,10,0)
 /* Cairo version of dw_pixmap_bitblt() from GTK3, use if either pixmap is a cairo surface */
-void _cairo_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
+void _cairo_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight)
 {
    int _locked_by_me = FALSE;
    cairo_t *cr = NULL;
+   int retval = DW_ERROR_GENERAL;
 
    if((!dest && (!destp || !destp->image)) || (!src && (!srcp || (!srcp->image && !srcp->pixmap))))
-      return;
+      return retval;
 
    DW_MUTEX_LOCK;
    if(dest)
@@ -8604,7 +8605,7 @@
       if(!window || !GDK_IS_WINDOW(window))
       {
          DW_MUTEX_UNLOCK;
-         return;
+         return retval;
       }
       cr = gdk_cairo_create(window);
    }
@@ -8613,38 +8614,49 @@
 
    if(cr)
    {
+      double xscale = 1, yscale = 1;
+      
+      if(srcwidth != -1 && srcheight != -1)
+      {
+         xscale = (double)width / (double)srcwidth;
+         yscale = (double)height / (double)srcheight;
+         cairo_scale(cr, xscale, yscale);
+      }
+      
 #if GTK_CHECK_VERSION(2,24,0)
       if(src)
          gdk_cairo_set_source_window (cr, gtk_widget_get_window(src), xdest -xsrc, ydest - ysrc);
       else
 #endif
       if(srcp && srcp->image)
-         cairo_set_source_surface (cr, srcp->image, xdest - xsrc, ydest - ysrc);
+         cairo_set_source_surface (cr, srcp->image, (xdest - xsrc) / xscale, (ydest - ysrc) / yscale);
       else if(srcp && srcp->pixmap && !srcp->bitmap)
-         gdk_cairo_set_source_pixmap (cr, srcp->pixmap, xdest - xsrc, ydest - ysrc);
+         gdk_cairo_set_source_pixmap (cr, srcp->pixmap, (xdest - xsrc) / xscale, (ydest - ysrc) / yscale);
       else if(srcp && srcp->pixmap && srcp->bitmap)
       {
          cairo_pattern_t *mask_pattern;
          
          /* hack to get the mask pattern */
-         gdk_cairo_set_source_pixmap(cr, srcp->bitmap, xdest, ydest);
+         gdk_cairo_set_source_pixmap(cr, srcp->bitmap, xdest / xscale, ydest / yscale);
          mask_pattern = cairo_get_source(cr);
          cairo_pattern_reference(mask_pattern);
 
-         gdk_cairo_set_source_pixmap(cr, srcp->pixmap, xdest - xsrc, ydest - ysrc);
-         cairo_rectangle(cr, xdest, ydest, width, height);
+         gdk_cairo_set_source_pixmap(cr, srcp->pixmap, (xdest - xsrc) / xscale, (ydest - ysrc) / yscale);
+         cairo_rectangle(cr, xdest / xscale, ydest / yscale, width, height);
          cairo_clip(cr);
          cairo_mask(cr, mask_pattern);
          cairo_destroy(cr);
          DW_MUTEX_UNLOCK;
-         return;
-      }
-
-      cairo_rectangle(cr, xdest, ydest, width, height);
+         return DW_ERROR_NONE;
+      }
+
+      cairo_rectangle(cr, xdest / xscale, ydest / yscale, width, height);
       cairo_fill(cr);
       cairo_destroy(cr);
-   }
-   DW_MUTEX_UNLOCK;
+      retval = DW_ERROR_NONE;
+   }
+   DW_MUTEX_UNLOCK;
+   return retval;
 }
 #endif
 
@@ -8662,7 +8674,30 @@
  *       xsrc: X coordinate of source.
  *       ysrc: Y coordinate of source.
  */
-void dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
+void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
+{
+    dw_pixmap_stretch_bitblt(dest, destp, xdest, ydest, width, height, src, srcp, xsrc, ysrc, -1, -1);
+}
+
+/*
+ * Copies from one surface to another allowing for stretching.
+ * Parameters:
+ *       dest: Destination window handle.
+ *       destp: Destination pixmap. (choose only one).
+ *       xdest: X coordinate of destination.
+ *       ydest: Y coordinate of destination.
+ *       width: Width of the target area.
+ *       height: Height of the target area.
+ *       src: Source window handle.
+ *       srcp: Source pixmap. (choose only one).
+ *       xsrc: X coordinate of source.
+ *       ysrc: Y coordinate of source.
+ *       srcwidth: Width of area to copy.
+ *       srcheight: Height of area to copy.
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight)
 {
    /* Ok, these #ifdefs are going to get a bit confusing because
     * when using gdk-pixbuf, pixmaps are really pixbufs, so we
@@ -8671,17 +8706,15 @@
     */
    int _locked_by_me = FALSE;
    GdkGC *gc = NULL;
+   int retval = DW_ERROR_GENERAL;
 
 #if GTK_CHECK_VERSION(2,10,0)
    if((destp && destp->image) || (srcp && srcp->image))
-   {
-      _cairo_pixmap_bitblt(dest, destp, xdest, ydest, width, height, src, srcp, xsrc, ysrc);
-      return;
-   }
+      return _cairo_pixmap_bitblt(dest, destp, xdest, ydest, width, height, src, srcp, xsrc, ysrc, srcwidth, srcheight);
 #endif
    
    if((!dest && (!destp || !destp->pixmap)) || (!src && (!srcp || !srcp->pixmap)))
-      return;
+      return retval;
 
    DW_MUTEX_LOCK;
    if(dest)
@@ -8713,8 +8746,10 @@
          gdk_gc_set_clip_origin( gc, 0, 0 );
       }
       gdk_gc_unref( gc );
-   }
-   DW_MUTEX_UNLOCK;
+      retval = DW_ERROR_NONE;
+   }
+   DW_MUTEX_UNLOCK;
+   return retval;
 }
 
 /*
--- a/gtk3/dw.c	Wed Oct 19 08:55:24 2011 +0000
+++ b/gtk3/dw.c	Wed Oct 19 09:40:23 2011 +0000
@@ -7318,18 +7318,37 @@
  *       xsrc: X coordinate of source.
  *       ysrc: Y coordinate of source.
  */
-void dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
-{
-   /* Ok, these #ifdefs are going to get a bit confusing because
-    * when using gdk-pixbuf, pixmaps are really pixbufs, so we
-    * have to use the pixbuf functions on them, and thus convoluting
-    * the code here a bit. -Brian
-    */
+void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
+{
+    dw_pixmap_stretch_bitblt(dest, destp, xdest, ydest, width, height, src, srcp, xsrc, ysrc, -1, -1);
+}
+
+/*
+ * Copies from one surface to another allowing for stretching.
+ * Parameters:
+ *       dest: Destination window handle.
+ *       destp: Destination pixmap. (choose only one).
+ *       xdest: X coordinate of destination.
+ *       ydest: Y coordinate of destination.
+ *       width: Width of the target area.
+ *       height: Height of the target area.
+ *       src: Source window handle.
+ *       srcp: Source pixmap. (choose only one).
+ *       xsrc: X coordinate of source.
+ *       ysrc: Y coordinate of source.
+ *       srcwidth: Width of area to copy.
+ *       srcheight: Height of area to copy.
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight)
+{
    int _locked_by_me = FALSE;
    cairo_t *cr = NULL;
+   int retval = DW_ERROR_GENERAL;
 
    if((!dest && (!destp || !destp->image)) || (!src && (!srcp || !srcp->image)))
-      return;
+      return retval;
 
    DW_MUTEX_LOCK;
    if(dest)
@@ -7339,7 +7358,7 @@
       if(!window || !GDK_IS_WINDOW(window))
       {
          DW_MUTEX_UNLOCK;
-         return;
+         return retval;
       }
       cr = gdk_cairo_create(window);
    }
@@ -7348,16 +7367,27 @@
 
    if(cr)
    {
+      double xscale = 1, yscale = 1;
+      
+      if(srcwidth != -1 && srcheight != -1)
+      {
+         xscale = (double)width / (double)srcwidth;
+         yscale = (double)height / (double)srcheight;
+         cairo_scale(cr, xscale, yscale);
+      }
+      
       if(src)
-         gdk_cairo_set_source_window (cr, gtk_widget_get_window(src), xdest -xsrc, ydest - ysrc);
+         gdk_cairo_set_source_window (cr, gtk_widget_get_window(src), (xdest + xsrc) / xscale, (ydest + ysrc) / yscale);
       else if(srcp)
-         cairo_set_source_surface (cr, srcp->image, xdest - xsrc, ydest - ysrc);
-
-      cairo_rectangle(cr, xdest, ydest, width, height);
+         cairo_set_source_surface (cr, srcp->image, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale);
+         
+      cairo_rectangle(cr, xdest / xscale, ydest / yscale, width, height);
       cairo_fill(cr);
       cairo_destroy(cr);
-   }
-   DW_MUTEX_UNLOCK;
+      retval = DW_ERROR_NONE;
+   }
+   DW_MUTEX_UNLOCK;
+   return retval;
 }
 
 /*