From b9411ba374e9570f99bdc23b8769d7ccb64ad1c1 Mon Sep 17 00:00:00 2001 From: Evan Stade Date: Thu, 9 Aug 2007 18:25:14 -0700 Subject: [PATCH] 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 deletion(-) diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c index 1c175600619..9d8699d4c53 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 + #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 9296354a21d..c8059ca42ca 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 8555db73878..485394ecf68 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 2060e28e982..aa059141033 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 6628dbcfdd1..253dd1f1cf8 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 */