Evan Stade : gdiplus: Added GdipCreateTextureIA.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Aug 10 07:31:18 CDT 2007


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

Author: Evan Stade <estade at gmail.com>
Date:   Thu Aug  9 18:25:14 2007 -0700

gdiplus: Added GdipCreateTextureIA.

---

 dlls/gdiplus/brush.c           |  122 ++++++++++++++++++++++++++++++++++++++++
 dlls/gdiplus/gdiplus.spec      |    2 +-
 dlls/gdiplus/gdiplus_private.h |    4 +
 include/gdiplusflat.h          |    2 +
 include/gdiplusgpstubs.h       |    2 +
 5 files changed, 131 insertions(+), 1 deletions(-)

diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c
index 1c17560..9d8699d 100644
--- a/dlls/gdiplus/brush.c
+++ b/dlls/gdiplus/brush.c
@@ -16,10 +16,17 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include <stdarg.h>
+
 #include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
 #include "wingdi.h"
 
+#define COBJMACROS
 #include "objbase.h"
+#include "olectl.h"
+#include "ole2.h"
 
 #include "gdiplus.h"
 #include "gdiplus_private.h"
@@ -242,6 +249,121 @@ GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB color, GpSolidFill **sf)
     return Ok;
 }
 
+/* FIXME: imageattr ignored */
+GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
+    GDIPCONST GpImageAttributes *imageattr, REAL x, REAL y, REAL width,
+    REAL height, GpTexture **texture)
+{
+    HDC hdc;
+    OLE_HANDLE hbm;
+    HBITMAP old = NULL;
+    BITMAPINFO bmi;
+    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;
+
+    if(!image || !texture || x < 0.0 || y < 0.0 || width < 0.0 || height < 0.0)
+        return InvalidParameter;
+
+    if(image->type != ImageTypeBitmap){
+        FIXME("not implemented for image type %d\n", image->type);
+        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;
+
+    IPicture_get_Handle(image->picture, &hbm);
+    if(!hbm)   return GenericError;
+    IPicture_get_CurDC(image->picture, &hdc);
+    bm_is_selected = (hdc != 0);
+
+    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    bmi.bmiHeader.biBitCount = 0;
+
+    if(!bm_is_selected){
+        hdc = CreateCompatibleDC(0);
+        old = SelectObject(hdc, (HBITMAP)hbm);
+    }
+
+    /* fill out bmi */
+    GetDIBits(hdc, (HBITMAP)hbm, 0, 0, NULL, &bmi, DIB_RGB_COLORS);
+
+    bytespp = bmi.bmiHeader.biBitCount / 8;
+    abs_height = abs(bmi.bmiHeader.biHeight);
+
+    if(n_x > bmi.bmiHeader.biWidth || n_x + n_width > bmi.bmiHeader.biWidth ||
+       n_y > abs_height || n_y + n_height > abs_height)
+        return InvalidParameter;
+
+    dibits = GdipAlloc(bmi.bmiHeader.biSizeImage);
+
+    if(dibits)  /* this is not a good place to error out */
+        GetDIBits(hdc, (HBITMAP)hbm, 0, abs_height, dibits, &bmi, DIB_RGB_COLORS);
+
+    if(!bm_is_selected){
+        SelectObject(hdc, old);
+        DeleteDC(hdc);
+    }
+
+    if(!dibits)
+        return OutOfMemory;
+
+    image_stride = (bmi.bmiHeader.biWidth * bytespp + 3) & ~3;
+    stride = (n_width * bytespp + 3) & ~3;
+    buff = GdipAlloc(sizeof(BITMAPINFOHEADER) + stride * n_height);
+    if(!buff){
+        GdipFree(dibits);
+        return OutOfMemory;
+    }
+
+    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 = bmi.bmiHeader.biBitCount;
+    bmih->biClrUsed = 0;
+    bmih->biPlanes = 1;
+
+    /* image is flipped */
+    if(bmi.bmiHeader.biHeight > 0){
+        dibits += bmi.bmiHeader.biSizeImage;
+        image_stride *= -1;
+        textbits += stride * (n_height - 1);
+        stride *= -1;
+    }
+
+    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) return OutOfMemory;
+
+    (*texture)->brush.lb.lbStyle = BS_DIBPATTERNPT;
+    (*texture)->brush.lb.lbColor = DIB_RGB_COLORS;
+    (*texture)->brush.lb.lbHatch = (ULONG_PTR)buff;
+
+    (*texture)->brush.gdibrush = CreateBrushIndirect(&(*texture)->brush.lb);
+    (*texture)->brush.bt = BrushTypeTextureFill;
+
+    GdipFree(dibits);
+    GdipFree(buff);
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipGetBrushType(GpBrush *brush, GpBrushType *type)
 {
     if(!brush || !type)  return InvalidParameter;
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec
index 9296354..c8059ca 100644
--- a/dlls/gdiplus/gdiplus.spec
+++ b/dlls/gdiplus/gdiplus.spec
@@ -134,7 +134,7 @@
 @ stub GdipCreateTexture2
 @ stub GdipCreateTexture2I
 @ stub GdipCreateTexture
-@ stub GdipCreateTextureIA
+@ stdcall GdipCreateTextureIA(ptr ptr long long long long ptr)
 @ stub GdipCreateTextureIAI
 @ stdcall GdipDeleteBrush(ptr)
 @ stub GdipDeleteCachedBitmap
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 8555db7..485394e 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -115,6 +115,10 @@ struct GpLineGradient{
     BOOL gamma;
 };
 
+struct GpTexture{
+    GpBrush brush;
+};
+
 struct GpPath{
     GpFillMode fill;
     GpPathData pathdata;
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index 2060e28..aa05914 100644
--- a/include/gdiplusflat.h
+++ b/include/gdiplusflat.h
@@ -104,6 +104,8 @@ GpStatus WINGDIPAPI GdipCreatePathGradient(GDIPCONST GpPointF*,INT,GpWrapMode,
 GpStatus WINGDIPAPI GdipCreatePathGradientFromPath(GDIPCONST GpPath*,
     GpPathGradient**);
 GpStatus WINGDIPAPI GdipCreateSolidFill(ARGB,GpSolidFill**);
+GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage*,GDIPCONST GpImageAttributes*,
+    REAL,REAL,REAL,REAL,GpTexture**);
 GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush*);
 GpStatus WINGDIPAPI GdipGetBrushType(GpBrush*,GpBrushType*);
 GpStatus WINGDIPAPI GdipGetLineGammaCorrection(GpLineGradient*,BOOL*);
diff --git a/include/gdiplusgpstubs.h b/include/gdiplusgpstubs.h
index 6628dbc..253dd1f 100644
--- a/include/gdiplusgpstubs.h
+++ b/include/gdiplusgpstubs.h
@@ -35,6 +35,7 @@ class GpImageAttributes {};
 class GpBitmap : public GpImage {};
 class GpPathGradient : public GpBrush {};
 class GpLineGradient : public GpBrush {};
+class GpTexture : public GpBrush {};
 
 #else /* end of c++ declarations */
 
@@ -52,6 +53,7 @@ typedef struct GpImageAttributes GpImageAttributes;
 typedef struct GpBitmap GpBitmap;
 typedef struct GpPathGradient GpPathGradient;
 typedef struct GpLineGradient GpLineGradient;
+typedef struct GpTexture GpTexture;
 
 #endif /* end of c declarations */
 




More information about the wine-cvs mailing list