Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/uxtheme/draw.c | 88 ++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 29 deletions(-)
diff --git a/dlls/uxtheme/draw.c b/dlls/uxtheme/draw.c index 424e08c4183..866200f7fa8 100644 --- a/dlls/uxtheme/draw.c +++ b/dlls/uxtheme/draw.c @@ -149,7 +149,8 @@ HRESULT WINAPI DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, * * Select the image to use */ -static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, BOOL glyph) +static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, + const RECT *pRect, BOOL glyph, int *imageDpi) { PTHEME_PROPERTY tp; int imageselecttype = IST_NONE; @@ -160,6 +161,9 @@ static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, HDC hdc, int iPartId, else image = TMT_IMAGEFILE;
+ if (imageDpi) + *imageDpi = 96; + if((tp=MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_FILENAME, image))) return tp; GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_IMAGESELECTTYPE, &imageselecttype); @@ -172,6 +176,10 @@ static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, HDC hdc, int iPartId, if(SUCCEEDED(GetThemeInt(hTheme, iPartId, iStateId, i + TMT_MINDPI1, &reqdpi))) { if(reqdpi != 0 && screendpi >= reqdpi) { TRACE("Using %d DPI, image %d\n", reqdpi, i + TMT_IMAGEFILE1); + + if (imageDpi) + *imageDpi = reqdpi; + return MSSTYLES_FindProperty(hTheme, iPartId, iStateId, TMT_FILENAME, i + TMT_IMAGEFILE1); } } @@ -228,15 +236,18 @@ static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, HDC hdc, int iPartId, * * Load image for part/state */ -static HRESULT UXTHEME_LoadImage(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, BOOL glyph, - HBITMAP *hBmp, RECT *bmpRect, BOOL* hasImageAlpha) +static HRESULT UXTHEME_LoadImage(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, + const RECT *pRect, BOOL glyph, HBITMAP *hBmp, RECT *bmpRect, + BOOL *hasImageAlpha, int *imageDpi) { int imagelayout = IL_HORIZONTAL; int imagecount = 1; int imagenum; BITMAP bmp; WCHAR szPath[MAX_PATH]; - PTHEME_PROPERTY tp = UXTHEME_SelectImage(hTheme, hdc, iPartId, iStateId, pRect, glyph); + PTHEME_PROPERTY tp; + + tp = UXTHEME_SelectImage(hTheme, hdc, iPartId, iStateId, pRect, glyph, imageDpi); if(!tp) { FIXME("Couldn't determine image for part/state %d/%d, invalid theme?\n", iPartId, iStateId); return E_PROP_ID_UNSUPPORTED; @@ -484,8 +495,8 @@ static HRESULT UXTHEME_DrawImageGlyph(HTHEME hTheme, HDC hdc, int iPartId, POINT topleft; BOOL hasAlpha;
- hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, TRUE, - &bmpSrc, &rcSrc, &hasAlpha); + hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, TRUE, &bmpSrc, &rcSrc, &hasAlpha, + NULL); if(FAILED(hr)) return hr; hdcSrc = CreateCompatibleDC(hdc); if(!hdcSrc) { @@ -554,30 +565,50 @@ static HRESULT get_image_part_size (HTHEME hTheme, HDC hdc, int iPartId, int iStateId, RECT *prc, THEMESIZE eSize, POINT *psz) { + int imageDpi, dstDpi; HRESULT hr = S_OK; HBITMAP bmpSrc; RECT rcSrc; BOOL hasAlpha;
- hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, prc, FALSE, - &bmpSrc, &rcSrc, &hasAlpha); + hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, prc, FALSE, &bmpSrc, &rcSrc, &hasAlpha, + &imageDpi); if (FAILED(hr)) return hr;
switch (eSize) { case TS_DRAW: + { + int sizingType = ST_STRETCH, scalingType = TSST_NONE; + POINT srcSize; + + srcSize.x = rcSrc.right - rcSrc.left; + srcSize.y = rcSrc.bottom - rcSrc.top; + + GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_SIZINGTYPE, &sizingType); + if (sizingType == ST_TRUESIZE) + { + GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_TRUESIZESCALINGTYPE, &scalingType); + if (scalingType == TSST_DPI) + { + dstDpi = GetDeviceCaps(hdc, LOGPIXELSY); + if (dstDpi && dstDpi != imageDpi) + { + srcSize.x = MulDiv(srcSize.x, dstDpi, imageDpi); + srcSize.y = MulDiv(srcSize.y, dstDpi, imageDpi); + } + } + } + *psz = srcSize; + if (prc != NULL) { POINT dstSize; - POINT srcSize; - int sizingtype = ST_STRETCH; BOOL uniformsizing = FALSE;
dstSize.x = prc->right - prc->left; dstSize.y = prc->bottom - prc->top; - srcSize.x = rcSrc.right-rcSrc.left; - srcSize.y = rcSrc.bottom-rcSrc.top; - + GetThemeBool(hTheme, iPartId, iStateId, TMT_UNIFORMSIZING, &uniformsizing); if(uniformsizing) { /* Scale height and width equally */ @@ -586,9 +617,9 @@ static HRESULT get_image_part_size (HTHEME hTheme, HDC hdc, int iPartId, else dstSize.x = MulDiv (srcSize.x, dstSize.y, srcSize.y); } - - GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_SIZINGTYPE, &sizingtype); - if(sizingtype == ST_TRUESIZE) { + + if (sizingType == ST_TRUESIZE) + { int truesizestretchmark = 100;
/* Whatever TrueSizeStretchMark does - it does not seem to @@ -599,13 +630,11 @@ static HRESULT get_image_part_size (HTHEME hTheme, HDC hdc, int iPartId, /* Only stretch when target exceeds source by truesizestretchmark percent */ GetThemeInt(hTheme, iPartId, iStateId, TMT_TRUESIZESTRETCHMARK, &truesizestretchmark); #endif - if(dstSize.x < 0 || dstSize.y < 0 || - (MulDiv(srcSize.x, 100, dstSize.x) > truesizestretchmark && - MulDiv(srcSize.y, 100, dstSize.y) > truesizestretchmark)) { - memcpy (psz, &dstSize, sizeof (SIZE)); - } - else { - memcpy (psz, &srcSize, sizeof (SIZE)); + if (scalingType == TSST_SIZE || dstSize.x < 0 || dstSize.y < 0 + || (MulDiv(srcSize.x, 100, dstSize.x) > truesizestretchmark + && MulDiv(srcSize.y, 100, dstSize.y) > truesizestretchmark)) + { + *psz = dstSize; } } else @@ -613,9 +642,10 @@ static HRESULT get_image_part_size (HTHEME hTheme, HDC hdc, int iPartId, psz->x = abs(dstSize.x); psz->y = abs(dstSize.y); } - break; } - /* else fall through */ + + break; + } case TS_MIN: /* FIXME: couldn't figure how native uxtheme computes min size */ case TS_TRUE: @@ -649,8 +679,8 @@ static HRESULT UXTHEME_DrawImageBackground(HTHEME hTheme, HDC hdc, int iPartId, COLORREF transparentcolor = 0; BOOL hasAlpha;
- hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, FALSE, - &bmpSrc, &rcSrc, &hasAlpha); + hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, FALSE, &bmpSrc, &rcSrc, &hasAlpha, + NULL); if(FAILED(hr)) return hr; hdcSrc = CreateCompatibleDC(hdc); if(!hdcSrc) { @@ -2078,8 +2108,8 @@ BOOL WINAPI IsThemeBackgroundPartiallyTransparent(HTHEME hTheme, int iPartId,
if (bgtype != BT_IMAGEFILE) return FALSE;
- if(FAILED (UXTHEME_LoadImage (hTheme, 0, iPartId, iStateId, &rect, FALSE, - &bmpSrc, &rcSrc, &hasAlpha))) + if (FAILED(UXTHEME_LoadImage(hTheme, 0, iPartId, iStateId, &rect, FALSE, &bmpSrc, &rcSrc, + &hasAlpha, NULL))) return FALSE;
get_transparency (hTheme, iPartId, iStateId, hasAlpha, &transparent,