gdiplus: Implement GdipCloneBitmapArea.

Vincent Povirk madewokherd+8cd9 at gmail.com
Sun Dec 6 20:12:26 CST 2009


For bug 15425.

-- 
Vincent Povirk
-------------- next part --------------
From e7eaa76c2dc92ccc2dd6da9be7007713cc0ccf2e Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Sun, 6 Dec 2009 20:02:35 -0600
Subject: [PATCH 1/2] gdiplus: Implement GdipCloneBitmapArea.

---
 dlls/gdiplus/image.c |   64 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 5b70918..22895c7 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -607,17 +607,73 @@ GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap* bitmap,
 GpStatus WINGDIPAPI GdipCloneBitmapArea(REAL x, REAL y, REAL width, REAL height,
     PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap)
 {
-    FIXME("(%f,%f,%f,%f,%i,%p,%p): stub\n", x, y, width, height, format, srcBitmap, dstBitmap);
+    BitmapData lockeddata_src, lockeddata_dst;
+    int i;
+    UINT row_size;
+    Rect area;
+    GpStatus stat;
 
-    return NotImplemented;
+    TRACE("(%f,%f,%f,%f,%i,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
+
+    if (!srcBitmap || !dstBitmap || srcBitmap->image.type != ImageTypeBitmap ||
+        x < 0 || y < 0 ||
+        x + width > srcBitmap->width || y + height > srcBitmap->height)
+    {
+        TRACE("<-- InvalidParameter\n");
+        return InvalidParameter;
+    }
+
+    if (format == PixelFormatDontCare)
+        format = srcBitmap->format;
+
+    area.X = roundr(x);
+    area.Y = roundr(y);
+    area.Width = roundr(width);
+    area.Height = roundr(height);
+
+    stat = GdipBitmapLockBits(srcBitmap, &area, ImageLockModeRead, format,
+        &lockeddata_src);
+    if (stat != Ok) return stat;
+
+    stat = GdipCreateBitmapFromScan0(lockeddata_src.Width, lockeddata_src.Height,
+        0, lockeddata_src.PixelFormat, NULL, dstBitmap);
+    if (stat == Ok)
+    {
+        stat = GdipBitmapLockBits(*dstBitmap, NULL, ImageLockModeWrite,
+            lockeddata_src.PixelFormat, &lockeddata_dst);
+
+        if (stat == Ok)
+        {
+            /* copy the image data */
+            row_size = (lockeddata_src.Width * PIXELFORMATBPP(lockeddata_src.PixelFormat) +7)/8;
+            for (i=0; i<lockeddata_src.Height; i++)
+                memcpy((BYTE*)lockeddata_dst.Scan0+lockeddata_dst.Stride*i,
+                       (BYTE*)lockeddata_src.Scan0+lockeddata_src.Stride*i,
+                       row_size);
+
+            GdipBitmapUnlockBits(*dstBitmap, &lockeddata_dst);
+        }
+
+        if (stat != Ok)
+            GdipDisposeImage((GpImage*)*dstBitmap);
+    }
+
+    GdipBitmapUnlockBits(srcBitmap, &lockeddata_src);
+
+    if (stat != Ok)
+    {
+        *dstBitmap = NULL;
+    }
+
+    return stat;
 }
 
 GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT x, INT y, INT width, INT height,
     PixelFormat format, GpBitmap* srcBitmap, GpBitmap** dstBitmap)
 {
-    FIXME("(%i,%i,%i,%i,%i,%p,%p): stub\n", x, y, width, height, format, srcBitmap, dstBitmap);
+    TRACE("(%i,%i,%i,%i,%i,%p,%p)\n", x, y, width, height, format, srcBitmap, dstBitmap);
 
-    return NotImplemented;
+    return GdipCloneBitmapArea(x, y, width, height, format, srcBitmap, dstBitmap);
 }
 
 GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
-- 
1.6.3.3


More information about the wine-patches mailing list