Vincent Povirk : gdiplus: Use GdipCloneBitmapArea to get bitmap areas for texture brushes.

Alexandre Julliard julliard at winehq.org
Mon Feb 15 10:06:11 CST 2010


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

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Thu Feb 11 16:30:56 2010 -0600

gdiplus: Use GdipCloneBitmapArea to get bitmap areas for texture brushes.

---

 dlls/gdiplus/brush.c |  140 ++++++++++++-------------------------------------
 1 files changed, 35 insertions(+), 105 deletions(-)

diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c
index 0d32c0f..a533aca 100644
--- a/dlls/gdiplus/brush.c
+++ b/dlls/gdiplus/brush.c
@@ -784,18 +784,15 @@ GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
     GDIPCONST GpImageAttributes *imageattr, REAL x, REAL y, REAL width,
     REAL height, GpTexture **texture)
 {
-    HDC hdc;
-    HBITMAP hbm, old = NULL;
-    BITMAPINFO *pbmi;
-    BITMAPINFOHEADER *bmih;
-    INT n_x, n_y, n_width, n_height, abs_height, stride, image_stride, i, bytespp;
-    BOOL bm_is_selected;
-    BYTE *dibits, *buff, *textbits;
+    HBITMAP hbm;
     GpStatus status;
+    GpImage *new_image=NULL;
 
     TRACE("(%p, %p, %.2f, %.2f, %.2f, %.2f, %p)\n", image, imageattr, x, y, width, height,
            texture);
 
+    *texture = NULL;
+
     if(!image || !texture || x < 0.0 || y < 0.0 || width < 0.0 || height < 0.0)
         return InvalidParameter;
 
@@ -804,121 +801,54 @@ GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
         return NotImplemented;
     }
 
-    n_x = roundr(x);
-    n_y = roundr(y);
-    n_width = roundr(width);
-    n_height = roundr(height);
-
-    if(n_x + n_width > ((GpBitmap*)image)->width ||
-       n_y + n_height > ((GpBitmap*)image)->height)
-        return InvalidParameter;
-
-    hbm = ((GpBitmap*)image)->hbitmap;
-    if(!hbm)   return GenericError;
-    hdc = ((GpBitmap*)image)->hdc;
-    bm_is_selected = (hdc != 0);
-
-    pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
-    if (!pbmi)
-        return OutOfMemory;
-    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    pbmi->bmiHeader.biBitCount = 0;
-
-    if(!bm_is_selected){
-        hdc = CreateCompatibleDC(0);
-        old = SelectObject(hdc, hbm);
-    }
-
-    /* fill out bmi */
-    GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
-
-    bytespp = pbmi->bmiHeader.biBitCount / 8;
-    abs_height = abs(pbmi->bmiHeader.biHeight);
-
-    if(n_x > pbmi->bmiHeader.biWidth || n_x + n_width > pbmi->bmiHeader.biWidth ||
-       n_y > abs_height || n_y + n_height > abs_height){
-        GdipFree(pbmi);
-        return InvalidParameter;
-    }
-
-    dibits = GdipAlloc(pbmi->bmiHeader.biSizeImage);
-
-    if(dibits)  /* this is not a good place to error out */
-        GetDIBits(hdc, hbm, 0, abs_height, dibits, pbmi, DIB_RGB_COLORS);
-
-    if(!bm_is_selected){
-        SelectObject(hdc, old);
-        DeleteDC(hdc);
-    }
-
-    if(!dibits){
-        GdipFree(pbmi);
-        return OutOfMemory;
-    }
-
-    image_stride = (pbmi->bmiHeader.biWidth * bytespp + 3) & ~3;
-    stride = (n_width * bytespp + 3) & ~3;
-    buff = GdipAlloc(sizeof(BITMAPINFOHEADER) + stride * n_height);
-    if(!buff){
-        GdipFree(pbmi);
-        GdipFree(dibits);
-        return OutOfMemory;
-    }
+    status = GdipCloneBitmapArea(x, y, width, height, PixelFormatDontCare, (GpBitmap*)image, (GpBitmap**)&new_image);
+    if (status != Ok)
+        return status;
 
-    bmih = (BITMAPINFOHEADER*)buff;
-    textbits = (BYTE*) (bmih + 1);
-    bmih->biSize = sizeof(BITMAPINFOHEADER);
-    bmih->biWidth = n_width;
-    bmih->biHeight = n_height;
-    bmih->biCompression = BI_RGB;
-    bmih->biSizeImage = stride * n_height;
-    bmih->biBitCount = pbmi->bmiHeader.biBitCount;
-    bmih->biClrUsed = 0;
-    bmih->biPlanes = 1;
-
-    /* image is flipped */
-    if(pbmi->bmiHeader.biHeight > 0){
-        dibits += image_stride * (pbmi->bmiHeader.biHeight - 1);
-        image_stride *= -1;
-        textbits += stride * (n_height - 1);
-        stride *= -1;
+    hbm = ((GpBitmap*)new_image)->hbitmap;
+    if(!hbm)
+    {
+        status = GenericError;
+        goto exit;
     }
 
-    GdipFree(pbmi);
-
-    for(i = 0; i < n_height; i++)
-        memcpy(&textbits[i * stride],
-               &dibits[n_x * bytespp + (n_y + i) * image_stride],
-               abs(stride));
-
     *texture = GdipAlloc(sizeof(GpTexture));
     if (!*texture){
-        GdipFree(dibits);
-        GdipFree(buff);
-        return OutOfMemory;
+        status = OutOfMemory;
+        goto exit;
     }
 
     if((status = GdipCreateMatrix(&(*texture)->transform)) != Ok){
-        GdipFree(*texture);
-        GdipFree(dibits);
-        GdipFree(buff);
-        return status;
+        goto exit;
     }
 
-    (*texture)->brush.lb.lbStyle = BS_DIBPATTERNPT;
-    (*texture)->brush.lb.lbColor = DIB_RGB_COLORS;
-    (*texture)->brush.lb.lbHatch = (ULONG_PTR)buff;
+    (*texture)->brush.lb.lbStyle = BS_PATTERN;
+    (*texture)->brush.lb.lbColor = 0;
+    (*texture)->brush.lb.lbHatch = (ULONG_PTR)hbm;
 
     (*texture)->brush.gdibrush = CreateBrushIndirect(&(*texture)->brush.lb);
     (*texture)->brush.bt = BrushTypeTextureFill;
     (*texture)->wrap = imageattr->wrap;
 
-    GdipFree(dibits);
-    GdipFree(buff);
+exit:
+    GdipDisposeImage(new_image);
 
-    TRACE("<-- %p\n", *texture);
+    if (status == Ok)
+    {
+        TRACE("<-- %p\n", *texture);
+    }
+    else
+    {
+        if (*texture)
+        {
+            GdipDeleteMatrix((*texture)->transform);
+            GdipFree(*texture);
+            *texture = NULL;
+        }
+        TRACE("<-- error %u\n", status);
+    }
 
-    return Ok;
+    return status;
 }
 
 /******************************************************************************




More information about the wine-cvs mailing list