Mark Harmstone : uxtheme: Support images in GetThemeBackgroundRegion.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Mar 16 10:34:24 CDT 2015
Module: wine
Branch: master
Commit: 8fa8a2368494ab667a7f0c0cc145f6e5fe37f5a1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8fa8a2368494ab667a7f0c0cc145f6e5fe37f5a1
Author: Mark Harmstone <hellas at burntcomma.com>
Date: Sun Mar 15 16:59:37 2015 +0000
uxtheme: Support images in GetThemeBackgroundRegion.
---
dlls/uxtheme/draw.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 115 insertions(+), 2 deletions(-)
diff --git a/dlls/uxtheme/draw.c b/dlls/uxtheme/draw.c
index 3ef8d81..19df3c8 100644
--- a/dlls/uxtheme/draw.c
+++ b/dlls/uxtheme/draw.c
@@ -1734,6 +1734,120 @@ HRESULT WINAPI GetThemeBackgroundExtent(HTHEME hTheme, HDC hdc, int iPartId,
return S_OK;
}
+static inline void flush_rgn_data( HRGN rgn, RGNDATA *data )
+{
+ HRGN tmp = ExtCreateRegion( NULL, data->rdh.dwSize + data->rdh.nRgnSize, data );
+
+ CombineRgn( rgn, rgn, tmp, RGN_OR );
+ DeleteObject( tmp );
+ data->rdh.nCount = 0;
+}
+
+static inline void add_row( HRGN rgn, RGNDATA *data, int x, int y, int len )
+{
+ RECT *rect = (RECT *)data->Buffer + data->rdh.nCount;
+
+ if (len <= 0) return;
+ rect->left = x;
+ rect->top = y;
+ rect->right = x + len;
+ rect->bottom = y + 1;
+ data->rdh.nCount++;
+ if (data->rdh.nCount * sizeof(RECT) > data->rdh.nRgnSize - sizeof(RECT))
+ flush_rgn_data( rgn, data );
+}
+
+static HRESULT create_image_bg_region(HTHEME theme, int part, int state, const RECT *rect, HRGN *rgn)
+{
+ RECT r;
+ HDC dc;
+ HBITMAP bmp;
+ HRGN hrgn;
+ BOOL istrans;
+ COLORREF transcolour;
+ HBRUSH transbrush;
+ unsigned int x, y, start;
+ BITMAPINFO bitmapinfo;
+ DWORD *bits;
+ char buffer[4096];
+ RGNDATA *data = (RGNDATA *)buffer;
+
+ if (FAILED(GetThemeBool(theme, part, state, TMT_TRANSPARENT, &istrans)) || !istrans) {
+ *rgn = CreateRectRgn(rect->left, rect->top, rect->right, rect->bottom);
+ return S_OK;
+ }
+
+ r = *rect;
+ OffsetRect(&r, -r.left, -r.top);
+
+ if (FAILED(GetThemeColor(theme, part, state, TMT_TRANSPARENTCOLOR, &transcolour)))
+ transcolour = RGB(255, 0, 255); /* defaults to magenta */
+
+ dc = CreateCompatibleDC(NULL);
+ if (!dc) {
+ WARN("CreateCompatibleDC failed\n");
+ return E_FAIL;
+ }
+
+ bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapinfo.bmiHeader.biWidth = rect->right - rect->left;
+ bitmapinfo.bmiHeader.biHeight = -(rect->bottom - rect->top);
+ bitmapinfo.bmiHeader.biPlanes = 1;
+ bitmapinfo.bmiHeader.biBitCount = 32;
+ bitmapinfo.bmiHeader.biCompression = BI_RGB;
+ bitmapinfo.bmiHeader.biSizeImage = bitmapinfo.bmiHeader.biWidth * bitmapinfo.bmiHeader.biHeight * 4;
+ bitmapinfo.bmiHeader.biXPelsPerMeter = 0;
+ bitmapinfo.bmiHeader.biYPelsPerMeter = 0;
+ bitmapinfo.bmiHeader.biClrUsed = 0;
+ bitmapinfo.bmiHeader.biClrImportant = 0;
+
+ bmp = CreateDIBSection(dc, &bitmapinfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+ if (!bmp) {
+ WARN("CreateDIBSection failed\n");
+ DeleteDC(dc);
+ return E_FAIL;
+ }
+
+ SelectObject(dc, bmp);
+
+ transbrush = CreateSolidBrush(transcolour);
+ FillRect(dc, &r, transbrush);
+ DeleteObject(transbrush);
+
+ if (FAILED(DrawThemeBackground(theme, dc, part, state, &r, NULL))) {
+ WARN("DrawThemeBackground failed\n");
+ DeleteObject(bmp);
+ DeleteDC(dc);
+ return E_FAIL;
+ }
+
+ data->rdh.dwSize = sizeof(data->rdh);
+ data->rdh.iType = RDH_RECTANGLES;
+ data->rdh.nCount = 0;
+ data->rdh.nRgnSize = sizeof(buffer) - sizeof(data->rdh);
+
+ hrgn = CreateRectRgn(0, 0, 0, 0);
+
+ for (y = 0; y < r.bottom; y++, bits += r.right) {
+ x = 0;
+ while (x < r.right) {
+ while (x < r.right && (bits[x] & 0xffffff) == transcolour) x++;
+ start = x;
+ while (x < r.right && !((bits[x] & 0xffffff) == transcolour)) x++;
+ add_row( hrgn, data, rect->left + start, rect->top + y, x - start );
+ }
+ }
+
+ if (data->rdh.nCount > 0) flush_rgn_data(hrgn, data);
+
+ *rgn = hrgn;
+
+ DeleteObject(bmp);
+ DeleteDC(dc);
+
+ return S_OK;
+}
+
/***********************************************************************
* GetThemeBackgroundRegion (UXTHEME.@)
*
@@ -1755,8 +1869,7 @@ HRESULT WINAPI GetThemeBackgroundRegion(HTHEME hTheme, HDC hdc, int iPartId,
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_BGTYPE, &bgtype);
if(bgtype == BT_IMAGEFILE) {
- FIXME("Images not handled yet\n");
- hr = ERROR_CALL_NOT_IMPLEMENTED;
+ hr = create_image_bg_region(hTheme, iPartId, iStateId, pRect, pRegion);
}
else if(bgtype == BT_BORDERFILL) {
*pRegion = CreateRectRgn(pRect->left, pRect->top, pRect->right, pRect->bottom);
More information about the wine-cvs
mailing list