changeset 1243:c191a562c14a

Added new dw_pixmap_stretch_bitblt() function on Windows and OS/2. Added new strech option to the test program to test this functionality. OS/2 version is untested and I am not sure I got the math right... GTK and Mac versions to come soon.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 19 Oct 2011 08:14:05 +0000
parents 8e37ebb3fab7
children db26b9622769
files dw.def dw.h dwtest.c dww.def os2/dw.c win/dw.c
diffstat 6 files changed, 102 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/dw.def	Wed Oct 19 04:24:14 2011 +0000
+++ b/dw.def	Wed Oct 19 08:14:05 2011 +0000
@@ -213,6 +213,7 @@
   dw_pixmap_new_from_data                @345
   dw_pixmap_set_transparent_color        @346
   dw_pixmap_set_font                     @347
+  dw_pixmap_stretch_bitblt               @348
 
   dw_dialog_new                          @350
   dw_dialog_dismiss                      @351
--- a/dw.h	Wed Oct 19 04:24:14 2011 +0000
+++ b/dw.h	Wed Oct 19 08:14:05 2011 +0000
@@ -1653,6 +1653,7 @@
 void API dw_font_set_default(char *fontname);
 void API dw_flush(void);
 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);
+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);
 HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth);
 HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename);
 HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len);
--- a/dwtest.c	Wed Oct 19 04:24:14 2011 +0000
+++ b/dwtest.c	Wed Oct 19 08:14:05 2011 +0000
@@ -93,6 +93,7 @@
     rendcombo,
     imagexspin,
     imageyspin,
+    imagestretchcheck,
     container_status,
     tree_status,
     stext,
@@ -125,7 +126,7 @@
 HPIXMAP text1pm,text2pm,image;
 HICN fileicon,foldericon;
 int mle_point=-1;
-int image_x = 20, image_y = 20;
+int image_x = 20, image_y = 20, image_stretch = 0;
 
 int font_width = 8;
 int font_height=12;
@@ -354,6 +355,7 @@
 
     image_x = (int)dw_spinbutton_get_pos(imagexspin);
     image_y = (int)dw_spinbutton_get_pos(imageyspin);
+    image_stretch = dw_checkbox_get(imagestretchcheck);
 
     dw_color_foreground_set(DW_CLR_WHITE);
     dw_draw_rect(window, pixmap, TRUE, 0, 0, width, height);
@@ -364,7 +366,10 @@
     dw_draw_text(window, pixmap, 10, 10, "This should be aligned with the edges.");
     if(image)
     {
-        dw_pixmap_bitblt(window, pixmap, image_x, image_y, (int)DW_PIXMAP_WIDTH(image), (int)DW_PIXMAP_HEIGHT(image), 0, image, 0, 0);
+        if(image_stretch)
+            dw_pixmap_stretch_bitblt(window, pixmap, 10, 10, width - 20, height - 20, 0, image, 0, 0, (int)DW_PIXMAP_WIDTH(image), (int)DW_PIXMAP_HEIGHT(image));
+        else
+            dw_pixmap_bitblt(window, pixmap, image_x, image_y, (int)DW_PIXMAP_WIDTH(image), (int)DW_PIXMAP_HEIGHT(image), 0, image, 0, 0);
     }
 
     /* If we aren't drawing direct do a bitblt */
@@ -948,6 +953,8 @@
     dw_spinbutton_set_limits(imageyspin, 2000, 0);
     dw_spinbutton_set_pos(imagexspin, 20);
     dw_spinbutton_set_pos(imageyspin, 20);
+    imagestretchcheck = dw_checkbox_new("Stretch", 1021);
+    dw_box_pack_start( hbox, imagestretchcheck, 25, 25, TRUE, FALSE, 0);
 
     button1 = dw_button_new( "Refresh", 1223L );
     dw_box_pack_start( hbox, button1, 100, 25, FALSE, FALSE, 0);
@@ -1006,6 +1013,7 @@
     dw_signal_connect(textbox2, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(motion_notify_event), (void *)0);
     dw_signal_connect(hscrollbar, DW_SIGNAL_VALUE_CHANGED, DW_SIGNAL_FUNC(scrollbar_valuechanged_callback), (void *)status1);
     dw_signal_connect(vscrollbar, DW_SIGNAL_VALUE_CHANGED, DW_SIGNAL_FUNC(scrollbar_valuechanged_callback), (void *)status1);
+    dw_signal_connect(imagestretchcheck, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(refresh_callback), NULL);
     dw_signal_connect(button1, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(refresh_callback), NULL);
     dw_signal_connect(button2, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(print_callback), NULL);
     dw_signal_connect(rendcombo, DW_SIGNAL_LIST_SELECT, DW_SIGNAL_FUNC(render_select_event_callback), NULL );
--- a/dww.def	Wed Oct 19 04:24:14 2011 +0000
+++ b/dww.def	Wed Oct 19 08:14:05 2011 +0000
@@ -210,6 +210,7 @@
   dw_pixmap_new_from_data                @345
   dw_pixmap_set_transparent_color        @346
   dw_pixmap_set_font                     @347
+  dw_pixmap_stretch_bitblt               @348
 
   dw_dialog_new                          @350
   dw_dialog_dismiss                      @351
--- a/os2/dw.c	Wed Oct 19 04:24:14 2011 +0000
+++ b/os2/dw.c	Wed Oct 19 08:14:05 2011 +0000
@@ -8941,49 +8941,77 @@
  */
 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)
+{
    HPS hpsdest;
    HPS hpssrc;
    POINTL ptl[4];
-   int destheight, srcheight;
-
+   int dheight, sheight;
+   int count = 3;
+   
    if(dest)
    {
       hpsdest = WinGetPS(dest);
-      destheight = _get_height(dest);
+      dheight = _get_height(dest);
    }
    else if(destp)
    {
       hpsdest = destp->hps;
-      destheight = destp->height;
+      dheight = destp->height;
    }
    else
-      return;
+      return DW_ERROR_GENERAL;
 
    if(src)
    {
       hpssrc = WinGetPS(src);
-      srcheight = _get_height(src);
+      sheight = _get_height(src);
    }
    else if(srcp)
    {
       hpssrc = srcp->hps;
-      srcheight = srcp->height;
+      sheight = srcp->height;
    }
    else
    {
       if(!destp)
          WinReleasePS(hpsdest);
-      return;
+      return DW_ERROR_GENERAL;
    }
 
    ptl[0].x = xdest;
-   ptl[0].y = (destheight - ydest) - height;
+   ptl[0].y = (dheight - ydest) - height;
    ptl[1].x = ptl[0].x + width;
-   ptl[1].y = destheight - ydest;
+   ptl[1].y = dheight - ydest;
    ptl[2].x = xsrc;
-   ptl[2].y = srcheight - (ysrc + height);
-   ptl[3].x = ptl[2].x + width;
-   ptl[3].y = ptl[2].y + height;
+   ptl[2].y = sheight - (ysrc + height);
+   if(srcwidth != -1 && srcheigth != -1)
+   {
+      count = 4;
+      ptl[3].x = ptl[2].x + srcwidth;
+      ptl[3].y = ptl[2].y + srcheight;
+   }
 
    /* Handle transparency if requested */
    if(srcp && srcp->transcolor != DW_CLR_DEFAULT)
@@ -8994,19 +9022,20 @@
        GpiQueryAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, (PBUNDLE)&oldIb);
        newIb.usBackMixMode = BM_SRCTRANSPARENT;
        GpiSetAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, 0, (PBUNDLE)&newIb);
-       GpiBitBlt(hpsdest, hpssrc, 4, ptl, ROP_SRCCOPY, BBO_IGNORE);
+       GpiBitBlt(hpsdest, hpssrc, count, ptl, ROP_SRCCOPY, BBO_IGNORE);
        GpiSetAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, 0, (PBUNDLE)&oldIb);
    }
    else
    {
        /* Otherwise use the regular BitBlt call */
-       GpiBitBlt(hpsdest, hpssrc, 4, ptl, ROP_SRCCOPY, BBO_IGNORE);
+       GpiBitBlt(hpsdest, hpssrc, count, ptl, ROP_SRCCOPY, BBO_IGNORE);
    }
 
    if(!destp)
       WinReleasePS(hpsdest);
    if(!srcp)
       WinReleasePS(hpssrc);
+   return DW_ERROR_NONE;
 }
 
 /* Run DosBeep() in a separate thread so it doesn't block */
--- a/win/dw.c	Wed Oct 19 04:24:14 2011 +0000
+++ b/win/dw.c	Wed Oct 19 08:14:05 2011 +0000
@@ -9024,43 +9024,82 @@
  */
 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)
+{
    HDC hdcdest;
    HDC hdcsrc;
    static BLENDFUNCTION bf = { AC_SRC_OVER, 0, 0xFF, AC_SRC_ALPHA };
-
+   int swidth = srcwidth, sheight = srcheight;
+
+   /* Do some sanity checks */
    if ( dest )
       hdcdest = GetDC( dest );
    else if ( destp )
       hdcdest = destp->hdc;
    else
-      return;
+      return DW_ERROR_GENERAL;
 
    if ( src )
       hdcsrc = GetDC( src );
    else if ( srcp )
       hdcsrc = srcp->hdc;
    else
-      return;
+      return DW_ERROR_GENERAL;
+
+   if((srcheight == -1 || srcwidth == -1) && srcheight != srcwidth)
+      return DW_ERROR_GENERAL;
+
+   if(srcheight == -1 && srcwidth == -1)
+   {
+       swidth = width;
+       sheight = height;
+   }
 
    /* If it is a 32bpp bitmap (with alpha) use AlphaBlend unless it fails */
-   if ( srcp && srcp->depth == 32 && AlphaBlend( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, width, height, bf ) )
+   if ( srcp && srcp->depth == 32 && AlphaBlend( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, swidth, sheight, bf ) )
    {
         /* Don't do anything */
    }
    /* Otherwise perform special bitblt with manual transparency */
    else if ( srcp && srcp->transcolor != DW_RGB_TRANSPARENT )
    {
-      TransparentBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, width, height, RGB( DW_RED_VALUE(srcp->transcolor), DW_GREEN_VALUE(srcp->transcolor), DW_BLUE_VALUE(srcp->transcolor)) );
+      TransparentBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, swidth, sheight, RGB( DW_RED_VALUE(srcp->transcolor), DW_GREEN_VALUE(srcp->transcolor), DW_BLUE_VALUE(srcp->transcolor)) );
    }
    else
    {
       /* Finally fall back to the classic BitBlt */
-      BitBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, SRCCOPY );
+      if( srcwidth == -1 && srcheight == -1)
+         BitBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, SRCCOPY );
+      else
+         StretchBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, swidth, sheight, SRCCOPY );
    }
    if ( !destp )
       ReleaseDC( dest, hdcdest );
    if ( !srcp )
       ReleaseDC( src, hdcsrc );
+
+   return DW_ERROR_NONE;
 }
 
 /* Run Beep() in a separate thread so it doesn't block */