win32: Fix up toolbar rendering on XP

It seems XP doesn't correctly set the alpha when rendering toolbar
buttons on an alpha target, we fix this up afterwards if necessary.
This commit is contained in:
Alexander Larsson
2012-03-13 17:10:44 +01:00
parent 94f1ed3031
commit e9f070db0f

View File

@ -31,6 +31,7 @@
static HINSTANCE uxtheme_dll = NULL; static HINSTANCE uxtheme_dll = NULL;
static gboolean use_xp_theme = FALSE; static gboolean use_xp_theme = FALSE;
static HTHEME needs_alpha_fixup = NULL;
typedef HRESULT (FAR PASCAL *GetThemeSysFontFunc) (HTHEME hTheme, int iFontID, OUT LOGFONTW *plf); typedef HRESULT (FAR PASCAL *GetThemeSysFontFunc) (HTHEME hTheme, int iFontID, OUT LOGFONTW *plf);
typedef int (FAR PASCAL *GetThemeSysSizeFunc) (HTHEME hTheme, int iSizeId); typedef int (FAR PASCAL *GetThemeSysSizeFunc) (HTHEME hTheme, int iSizeId);
@ -77,6 +78,7 @@ static GHashTable *hthemes_by_class = NULL;
static void static void
_gtk_win32_theme_init (void) _gtk_win32_theme_init (void)
{ {
OSVERSIONINFO version;
char *buf; char *buf;
char dummy; char dummy;
int n, k; int n, k;
@ -132,6 +134,11 @@ _gtk_win32_theme_init (void)
} }
hthemes_by_class = g_hash_table_new (g_str_hash, g_str_equal); hthemes_by_class = g_hash_table_new (g_str_hash, g_str_equal);
memset (&version, 0, sizeof (version));
version.dwOSVersionInfoSize = sizeof (version);
if (GetVersionEx (&version) && version.dwMajorVersion == 5)
needs_alpha_fixup = _gtk_win32_lookup_htheme_by_classname ("toolbar");
} }
HTHEME HTHEME
@ -193,6 +200,7 @@ _gtk_win32_theme_part_create_surface (HTHEME theme,
cairo_t *cr; cairo_t *cr;
int x_offs; int x_offs;
int y_offs; int y_offs;
gboolean has_alpha;
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
HDC hdc; HDC hdc;
RECT rect; RECT rect;
@ -228,7 +236,8 @@ _gtk_win32_theme_part_create_surface (HTHEME theme,
rect.bottom = height; rect.bottom = height;
} }
if (is_theme_partially_transparent (theme, xp_part, state)) has_alpha = is_theme_partially_transparent (theme, xp_part, state);
if (has_alpha)
surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height); surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height);
else else
surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_RGB24, width, height); surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_RGB24, width, height);
@ -237,6 +246,22 @@ _gtk_win32_theme_part_create_surface (HTHEME theme,
res = draw_theme_background (theme, hdc, xp_part, state, &rect, &rect); res = draw_theme_background (theme, hdc, xp_part, state, &rect, &rect);
/* XP Can't handle rendering some parts on an alpha target */
if (theme == needs_alpha_fixup && has_alpha) {
cairo_surface_t *img = cairo_win32_surface_get_image (surface);
guint32 *data = (guint32 *)cairo_image_surface_get_data (img);
GdiFlush ();
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
if (data[i+j*width] != 0)
data[i+j*width] |= 0xff000000;
}
}
}
*x_offs_out = x_offs; *x_offs_out = x_offs;
*y_offs_out = y_offs; *y_offs_out = y_offs;