From f4a68dff88f242845ab96ad9e40ba22f96b394df Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 9 Mar 2012 16:37:11 +0100 Subject: [PATCH] Fix rendering of theme parts on Windows XP It seems XP doesn't handle drawing non-alpha theme parts on alpha destinations. We fix this by using alpha bitmaps only when needed. However this means any non-drawn area by the theme part is now draw black, so we must take more care to only draw where the theme part draws, so we find the theme part size when available. --- gtk/gtkcssimagewin32.c | 12 +++++---- gtk/gtkwin32theme.c | 55 +++++++++++++++++++++++++++++++++----- gtk/gtkwin32themeprivate.h | 4 ++- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/gtk/gtkcssimagewin32.c b/gtk/gtkcssimagewin32.c index 8c79fd6bb8..ca82a08f60 100644 --- a/gtk/gtkcssimagewin32.c +++ b/gtk/gtkcssimagewin32.c @@ -33,21 +33,23 @@ gtk_css_image_win32_draw (GtkCssImage *image, { GtkCssImageWin32 *wimage = GTK_CSS_IMAGE_WIN32 (image); cairo_surface_t *surface; + int dx, dy; surface = _gtk_win32_theme_part_create_surface (wimage->theme, wimage->part, wimage->state, wimage->margins, - width, height); + width, height, &dx, &dy); if (wimage->state2 >= 0) { cairo_surface_t *surface2; cairo_t *cr; + int dx2, dy2; surface2 = _gtk_win32_theme_part_create_surface (wimage->theme, wimage->part2, wimage->state2, wimage->margins, - width, height); + width, height, &dx2, &dy2); cr = cairo_create (surface); - cairo_set_source_surface (cr, surface2, 0, 0); + cairo_set_source_surface (cr, surface2, dx2 - dx, dy2-dy); cairo_paint_with_alpha (cr, wimage->over_alpha); cairo_destroy (cr); @@ -55,8 +57,8 @@ gtk_css_image_win32_draw (GtkCssImage *image, cairo_surface_destroy (surface2); } - cairo_set_source_surface (cr, surface, 0, 0); - cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD); + cairo_set_source_surface (cr, surface, dx, dy); + cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE); cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); diff --git a/gtk/gtkwin32theme.c b/gtk/gtkwin32theme.c index 35fd5db417..b2931ed558 100644 --- a/gtk/gtkwin32theme.c +++ b/gtk/gtkwin32theme.c @@ -184,27 +184,65 @@ _gtk_win32_theme_part_create_surface (HTHEME theme, int state, int margins[4], int width, - int height) + int height, + int *x_offs_out, + int *y_offs_out) { cairo_surface_t *surface; GdkRGBA color; cairo_t *cr; + int x_offs; + int y_offs; #ifdef G_OS_WIN32 HDC hdc; RECT rect; + SIZE size; HRESULT res; +#endif - surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height); - hdc = cairo_win32_surface_get_dc (surface); + x_offs = margins[3]; + y_offs = margins[0]; + + width -= margins[3] + margins[1]; + height -= margins[0] + margins[2]; + +#ifdef G_OS_WIN32 + rect.left = 0; + rect.top = 0; + rect.right = width; + rect.bottom = height; + + hdc = GetDC (NULL); + res = get_theme_part_size (theme, hdc, xp_part, state, &rect, 2, &size); + ReleaseDC (NULL, hdc); + + if (res == S_OK) + { + x_offs += (width - size.cx) / 2; + y_offs += (height - size.cy) / 2; - rect.left = margins[3]; - rect.top = margins[0]; - rect.right = width - margins[1]; - rect.bottom = height - margins[2]; + width = size.cx; + height = size.cy; + + rect.right = width; + rect.bottom = height; + } + + if (is_theme_partially_transparent (theme, xp_part, state)) + surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height); + else + surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_RGB24, width, height); + + hdc = cairo_win32_surface_get_dc (surface); res = draw_theme_background (theme, hdc, xp_part, state, &rect, &rect); + + *x_offs_out = x_offs; + *y_offs_out = y_offs; + if (res == S_OK) return surface; + #else /* !G_OS_WIN32 */ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); #endif /* G_OS_WIN32 */ @@ -218,6 +256,9 @@ _gtk_win32_theme_part_create_surface (HTHEME theme, cairo_destroy (cr); + *x_offs_out = x_offs; + *y_offs_out = y_offs; + return surface; } diff --git a/gtk/gtkwin32themeprivate.h b/gtk/gtkwin32themeprivate.h index 4445f2dea6..309c53c778 100644 --- a/gtk/gtkwin32themeprivate.h +++ b/gtk/gtkwin32themeprivate.h @@ -44,7 +44,9 @@ cairo_surface_t * _gtk_win32_theme_part_create_surface (HTHEME theme, int state, int margins[4], int width, - int height); + int height, + int *x_offs_out, + int *y_offs_out); int _gtk_win32_theme_int_parse (GtkCssParser *parser, GFile *base,