Module: wine Branch: master Commit: b9411ba374e9570f99bdc23b8769d7ccb64ad1c1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b9411ba374e9570f99bdc23b87...
Author: Evan Stade estade@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 */