From 1706d0d63ed972147eeed6992868f7ea3af8649e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Mon, 21 Apr 2008 09:55:12 -0500 Subject: [PATCH] uxtheme: Speed up UXTHEME_SizedBlt in the ST_TILE by building an appropriately-sized memory bitmap out of the tile instead of iterating with UXTHEME_Blt() directly. --- dlls/uxtheme/draw.c | 72 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/dlls/uxtheme/draw.c b/dlls/uxtheme/draw.c index 73b9615d1f9..ca3d903ce04 100644 --- a/dlls/uxtheme/draw.c +++ b/dlls/uxtheme/draw.c @@ -340,27 +340,67 @@ static inline BOOL UXTHEME_SizedBlt (HDC hdcDst, int nXOriginDst, int nYOriginDs { if (sizingtype == ST_TILE) { - int yOfs = nYOriginDst; - int yRemaining = nHeightDst; - while (yRemaining > 0) + HDC hdcTemp; + BOOL result = FALSE; + + /* Create a DC with a bitmap consisting of a tiling of the source + bitmap, with standard GDI functions. This is faster than an + iteration with UXTHEME_Blt(). */ + hdcTemp = CreateCompatibleDC(hdcSrc); + if (hdcTemp != 0) { - int bltHeight = min (yRemaining, nHeightSrc); - int xOfs = nXOriginDst; - int xRemaining = nWidthDst; + HBITMAP bitmapTemp; + HBITMAP bitmapOrig; + int nWidthTemp, nHeightTemp; + int xOfs, xRemaining; + int yOfs, yRemaining; + int growSize; + + /* Calculate temp dimensions of integer multiples of source dimensions */ + nWidthTemp = ((nWidthDst + nWidthSrc - 1) / nWidthSrc) * nWidthSrc; + nHeightTemp = ((nHeightDst + nHeightSrc - 1) / nHeightSrc) * nHeightSrc; + bitmapTemp = CreateCompatibleBitmap(hdcSrc, nWidthTemp, nHeightTemp); + bitmapOrig = SelectObject(hdcTemp, bitmapTemp); + + /* Initial copy of bitmap */ + BitBlt(hdcTemp, 0, 0, nWidthSrc, nHeightSrc, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY); + + /* Extend bitmap in the X direction. Growth of width is exponential */ + xOfs = nWidthSrc; + xRemaining = nWidthTemp - nWidthSrc; + growSize = nWidthSrc; while (xRemaining > 0) { - int bltWidth = min (xRemaining, nWidthSrc); - if (!UXTHEME_Blt (hdcDst, xOfs, yOfs, bltWidth, bltHeight, - hdcSrc, nXOriginSrc, nYOriginSrc, - transparent, transcolor)) - return FALSE; - xOfs += nWidthSrc; - xRemaining -= nWidthSrc; + growSize = min(growSize, xRemaining); + BitBlt(hdcTemp, xOfs, 0, growSize, nHeightSrc, hdcTemp, 0, 0, SRCCOPY); + xOfs += growSize; + xRemaining -= growSize; + growSize *= 2; } - yOfs += nHeightSrc; - yRemaining -= nHeightSrc; + + /* Extend bitmap in the Y direction. Growth of height is exponential */ + yOfs = nHeightSrc; + yRemaining = nHeightTemp - nHeightSrc; + growSize = nHeightSrc; + while (yRemaining > 0) + { + growSize = min(growSize, yRemaining); + BitBlt(hdcTemp, 0, yOfs, nWidthTemp, growSize, hdcTemp, 0, 0, SRCCOPY); + yOfs += growSize; + yRemaining -= growSize; + growSize *= 2; + } + + /* Use temporary hdc for source */ + result = UXTHEME_Blt (hdcDst, nXOriginDst, nYOriginDst, nWidthDst, nHeightDst, + hdcTemp, 0, 0, + transparent, transcolor); + + SelectObject(hdcTemp, bitmapOrig); + DeleteObject(bitmapTemp); } - return TRUE; + DeleteDC(hdcTemp); + return result; } else {