Author: gadamopoulos Date: Fri Aug 12 11:15:26 2011 New Revision: 53196
URL: http://svn.reactos.org/svn/reactos?rev=53196&view=rev Log: [uxtheme] - Implement GetThemeBackgroundRegion for BT_IMAGEFILE background type
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/draw.c
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/draw.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win3... ============================================================================== --- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/draw.c [iso-8859-1] (original) +++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/draw.c [iso-8859-1] Fri Aug 12 11:15:26 2011 @@ -1731,6 +1731,150 @@ return S_OK; }
+ +static HBITMAP UXTHEME_DrawThemePartToDib(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCRECT pRect) +{ + HDC hdcMem; + BITMAPINFO bmi = {0}; + HBITMAP hbmp, hbmpOld; + HBRUSH hbrBack; + + hdcMem = CreateCompatibleDC(0); + + bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); + bmi.bmiHeader.biWidth = pRect->right; + bmi.bmiHeader.biHeight = -pRect->bottom; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + hbmp = CreateDIBSection(hdcMem, &bmi, DIB_RGB_COLORS , NULL, 0, 0); + + hbmpOld = (HBITMAP)SelectObject(hdcMem, hbmp); + + /* FIXME: use an internal function that doesn't do transparent blt */ + hbrBack = CreateSolidBrush(RGB(255,0,255)); + + FillRect(hdcMem, pRect, hbrBack); + + DrawThemeBackground(hTheme, hdcMem, iPartId, iStateId, pRect, NULL); + + DeleteObject(hbrBack); + SelectObject(hdcMem, hbmpOld); + DeleteObject(hdcMem); + + return hbmp; +} + +#define PT_IN_RECT(lprc,x,y) ( x >= lprc->left && x < lprc->right && \ + y >= lprc->top && y < lprc->bottom) + +static HRGN UXTHEME_RegionFromDibBits(RGBQUAD* pBuffer, RGBQUAD* pclrTransparent, LPCRECT pRect) +{ + int x, y, xstart; + int cMaxRgnRects, cRgnDataSize, cRgnRects; + RECT* prcCurrent; + PRGNDATA prgnData; + ULONG clrTransparent, *pclrCurrent; + HRGN hrgnRet; + + pclrCurrent = (PULONG)pBuffer; + clrTransparent = *(PULONG)pclrTransparent; + + /* Create a region and pre-allocate memory enough for 3 spaces in one row*/ + cRgnRects = 0; + cMaxRgnRects = 4* (pRect->bottom-pRect->top); + cRgnDataSize = sizeof(RGNDATA) + cMaxRgnRects * sizeof(RECT); + + /* Allocate the region data */ + prgnData = (PRGNDATA)HeapAlloc(GetProcessHeap(), 0, cRgnDataSize); + + prcCurrent = (PRECT)prgnData->Buffer; + + /* Calculate the region rects */ + y=0; + /* Scan each line of the bitmap */ + while(y<pRect->bottom) + { + x=0; + /* Scan each pixel */ + while (x<pRect->right) + { + /* Check if the pixel is not transparent and it is in the requested rect */ + if(*pclrCurrent != clrTransparent && PT_IN_RECT(pRect,x,y)) + { + xstart = x; + /* Find the end of the opaque row of pixels */ + while (x<pRect->right) + { + if(*pclrCurrent == clrTransparent || !PT_IN_RECT(pRect,x,y)) + break; + x++; + pclrCurrent++; + } + + /* Add the scaned line to the region */ + SetRect(prcCurrent, xstart, y,x,y+1); + prcCurrent++; + cRgnRects++; + + /* Increase the size of the buffer if it is full */ + if(cRgnRects == cMaxRgnRects) + { + cMaxRgnRects *=2; + cRgnDataSize = sizeof(RGNDATA) + cMaxRgnRects * sizeof(RECT); + prgnData = (PRGNDATA)HeapReAlloc(GetProcessHeap(), + 0, + prgnData, + cRgnDataSize); + prcCurrent = (RECT*)prgnData->Buffer + cRgnRects; + } + } + else + { + x++; + pclrCurrent++; + } + } + y++; + } + + /* Fill the region data header */ + prgnData->rdh.dwSize = sizeof(prgnData->rdh); + prgnData->rdh.iType = RDH_RECTANGLES; + prgnData->rdh.nCount = cRgnRects; + prgnData->rdh.nRgnSize = cRgnDataSize; + prgnData->rdh.rcBound = *pRect; + + /* Create the region*/ + hrgnRet = ExtCreateRegion (NULL, cRgnDataSize, prgnData); + + /* Free the region data*/ + HeapFree(GetProcessHeap(),0,prgnData); + + /* return the region*/ + return hrgnRet; +} + +HRESULT UXTHEME_GetImageBackBackgroundRegion(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCRECT pRect, HRGN *pRegion) +{ + HBITMAP hbmp; + DIBSECTION dib; + RGBQUAD clrTransparent = {0xFF,0x0, 0xFF,0x0}; + + /* Draw the theme part to a dib */ + hbmp = UXTHEME_DrawThemePartToDib(hTheme, hdc, iPartId, iStateId, pRect); + + /* Retrieve the info of the dib section */ + GetObject(hbmp, sizeof (DIBSECTION), &dib); + + /* Convert the bits of the dib section to a region */ + *pRegion = UXTHEME_RegionFromDibBits((RGBQUAD*)dib.dsBm.bmBits, &clrTransparent, pRect); + + /* Free the temp bitmap */ + DeleteObject(hbmp); + + return S_OK; +} + /*********************************************************************** * GetThemeBackgroundRegion (UXTHEME.@) * @@ -1752,8 +1896,7 @@
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_BGTYPE, &bgtype); if(bgtype == BT_IMAGEFILE) { - FIXME("Images not handled yet\n"); - hr = ERROR_CALL_NOT_IMPLEMENTED; + hr = UXTHEME_GetImageBackBackgroundRegion(hTheme, hdc, iPartId, iStateId, pRect, pRegion); } else if(bgtype == BT_BORDERFILL) { *pRegion = CreateRectRgn(pRect->left, pRect->top, pRect->right, pRect->bottom);