Huw Davies : gdi32: Allow SetBitmapBits to set incomplete scanlines.

Alexandre Julliard julliard at winehq.org
Mon Aug 22 13:29:08 CDT 2011


Module: wine
Branch: master
Commit: cb82c45b3a803e24f2f9f10c5857a9ee2a923888
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cb82c45b3a803e24f2f9f10c5857a9ee2a923888

Author: Huw Davies <huw at codeweavers.com>
Date:   Fri Aug 19 16:26:12 2011 +0100

gdi32: Allow SetBitmapBits to set incomplete scanlines.

---

 dlls/gdi32/bitmap.c |   27 ++++++++++++++++++++++-----
 1 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c
index 8117d6d..33d3a53 100644
--- a/dlls/gdi32/bitmap.c
+++ b/dlls/gdi32/bitmap.c
@@ -535,6 +535,7 @@ LONG WINAPI SetBitmapBits(
     int i, src_stride, dst_stride;
     struct bitblt_coords src, dst;
     struct gdi_image_bits src_bits;
+    HRGN clip = NULL;
 
     if (!bits) return 0;
 
@@ -548,17 +549,30 @@ LONG WINAPI SetBitmapBits(
 
     if (bmp->dib) src_stride = get_bitmap_stride( bmp->dib->dsBmih.biWidth, bmp->dib->dsBmih.biBitCount );
     else src_stride = get_bitmap_stride( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel );
+    count = min( count, src_stride * bmp->bitmap.bmHeight );
 
     dst_stride = get_dib_stride( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel );
 
     src.visrect.left   = src.x = 0;
     src.visrect.top    = src.y = 0;
     src.visrect.right  = src.width = bmp->bitmap.bmWidth;
-    src.visrect.bottom = src.height = min( count / src_stride, bmp->bitmap.bmHeight );
+    src.visrect.bottom = src.height = (count + src_stride - 1 ) / src_stride;
     dst = src;
 
-    /* Only set entire lines */
-    count = src.height * src_stride;
+    if (count % src_stride)
+    {
+        HRGN last_row;
+        int extra_pixels = ((count % src_stride) << 3) / bmp->bitmap.bmBitsPixel;
+
+        if ((count % src_stride << 3) % bmp->bitmap.bmBitsPixel)
+            FIXME( "Unhandled partial pixel\n" );
+        clip = CreateRectRgn( src.visrect.left, src.visrect.top,
+                              src.visrect.right, src.visrect.bottom - 1 );
+        last_row = CreateRectRgn( src.visrect.left, src.visrect.bottom - 1,
+                                  src.visrect.left + extra_pixels, src.visrect.bottom );
+        CombineRgn( clip, clip, last_row, RGN_OR );
+        DeleteObject( last_row );
+    }
 
     TRACE("(%p, %d, %p) %dx%d %d bpp fetched height: %d\n",
           hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
@@ -579,8 +593,10 @@ LONG WINAPI SetBitmapBits(
         }
         src_bits.is_copy = TRUE;
         src_bits.free = free_heap_bits;
-        for (i = 0; i < dst.height; i++)
+        for (i = 0; i < count / src_stride; i++)
             memcpy( (char *)src_bits.ptr + i * dst_stride, (char *)bits + i * src_stride, src_stride );
+        if (count % src_stride)
+            memcpy( (char *)src_bits.ptr + i * dst_stride, (char *)bits + i * src_stride, count % src_stride );
     }
 
     /* query the color info */
@@ -604,10 +620,11 @@ LONG WINAPI SetBitmapBits(
         info->bmiHeader.biWidth         = bmp->bitmap.bmWidth;
         info->bmiHeader.biHeight        = -dst.height;
         info->bmiHeader.biSizeImage     = dst.height * dst_stride;
-        err = bmp->funcs->pPutImage( NULL, hbitmap, 0, info, &src_bits, &src, &dst, SRCCOPY );
+        err = bmp->funcs->pPutImage( NULL, hbitmap, clip, info, &src_bits, &src, &dst, SRCCOPY );
     }
     if (err) count = 0;
 
+    if (clip) DeleteObject( clip );
     if (src_bits.free) src_bits.free( &src_bits );
     GDI_ReleaseObj( hbitmap );
     return count;




More information about the wine-cvs mailing list