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.
This commit is contained in:
		@ -33,21 +33,23 @@ gtk_css_image_win32_draw (GtkCssImage        *image,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  GtkCssImageWin32 *wimage = GTK_CSS_IMAGE_WIN32 (image);
 | 
					  GtkCssImageWin32 *wimage = GTK_CSS_IMAGE_WIN32 (image);
 | 
				
			||||||
  cairo_surface_t *surface;
 | 
					  cairo_surface_t *surface;
 | 
				
			||||||
 | 
					  int dx, dy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  surface = _gtk_win32_theme_part_create_surface (wimage->theme, wimage->part, wimage->state, wimage->margins,
 | 
					  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)
 | 
					  if (wimage->state2 >= 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      cairo_surface_t *surface2;
 | 
					      cairo_surface_t *surface2;
 | 
				
			||||||
      cairo_t *cr;
 | 
					      cairo_t *cr;
 | 
				
			||||||
 | 
					      int dx2, dy2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      surface2 = _gtk_win32_theme_part_create_surface (wimage->theme, wimage->part2, wimage->state2, wimage->margins,
 | 
					      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);
 | 
					      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_paint_with_alpha (cr, wimage->over_alpha);
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      cairo_destroy (cr);
 | 
					      cairo_destroy (cr);
 | 
				
			||||||
@ -55,8 +57,8 @@ gtk_css_image_win32_draw (GtkCssImage        *image,
 | 
				
			|||||||
      cairo_surface_destroy (surface2);
 | 
					      cairo_surface_destroy (surface2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cairo_set_source_surface (cr, surface, 0, 0);
 | 
					  cairo_set_source_surface (cr, surface, dx, dy);
 | 
				
			||||||
  cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD);
 | 
					  cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_NONE);
 | 
				
			||||||
  cairo_rectangle (cr, 0, 0, width, height);
 | 
					  cairo_rectangle (cr, 0, 0, width, height);
 | 
				
			||||||
  cairo_fill (cr);
 | 
					  cairo_fill (cr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -184,27 +184,65 @@ _gtk_win32_theme_part_create_surface (HTHEME theme,
 | 
				
			|||||||
				      int    state,
 | 
									      int    state,
 | 
				
			||||||
				      int    margins[4],
 | 
									      int    margins[4],
 | 
				
			||||||
				      int    width,
 | 
									      int    width,
 | 
				
			||||||
                                      int    height)
 | 
					                                      int    height,
 | 
				
			||||||
 | 
									      int   *x_offs_out,
 | 
				
			||||||
 | 
									      int   *y_offs_out)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  cairo_surface_t *surface;
 | 
					  cairo_surface_t *surface;
 | 
				
			||||||
  GdkRGBA color;
 | 
					  GdkRGBA color;
 | 
				
			||||||
  cairo_t *cr;
 | 
					  cairo_t *cr;
 | 
				
			||||||
 | 
					  int x_offs;
 | 
				
			||||||
 | 
					  int y_offs;
 | 
				
			||||||
#ifdef G_OS_WIN32
 | 
					#ifdef G_OS_WIN32
 | 
				
			||||||
  HDC hdc;
 | 
					  HDC hdc;
 | 
				
			||||||
  RECT rect;
 | 
					  RECT rect;
 | 
				
			||||||
 | 
					  SIZE size;
 | 
				
			||||||
  HRESULT res;
 | 
					  HRESULT res;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					      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);
 | 
					    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);
 | 
					  hdc = cairo_win32_surface_get_dc (surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  rect.left = margins[3];
 | 
					 | 
				
			||||||
  rect.top = margins[0];
 | 
					 | 
				
			||||||
  rect.right = width - margins[1];
 | 
					 | 
				
			||||||
  rect.bottom = height - margins[2];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  res = draw_theme_background (theme, hdc, xp_part, state, &rect, &rect);
 | 
					  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)
 | 
					  if (res == S_OK)
 | 
				
			||||||
    return surface;
 | 
					    return surface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else /* !G_OS_WIN32 */
 | 
					#else /* !G_OS_WIN32 */
 | 
				
			||||||
  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
 | 
					  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
 | 
				
			||||||
#endif /* G_OS_WIN32 */
 | 
					#endif /* G_OS_WIN32 */
 | 
				
			||||||
@ -218,6 +256,9 @@ _gtk_win32_theme_part_create_surface (HTHEME theme,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  cairo_destroy (cr);
 | 
					  cairo_destroy (cr);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  *x_offs_out = x_offs;
 | 
				
			||||||
 | 
					  *y_offs_out = y_offs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return surface;
 | 
					  return surface;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -44,7 +44,9 @@ cairo_surface_t *  _gtk_win32_theme_part_create_surface  (HTHEME       theme,
 | 
				
			|||||||
                                                          int          state,
 | 
					                                                          int          state,
 | 
				
			||||||
                                                          int          margins[4],
 | 
					                                                          int          margins[4],
 | 
				
			||||||
                                                          int          width,
 | 
					                                                          int          width,
 | 
				
			||||||
                                                          int          height);
 | 
					                                                          int          height,
 | 
				
			||||||
 | 
												  int         *x_offs_out,
 | 
				
			||||||
 | 
												  int         *y_offs_out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int                _gtk_win32_theme_int_parse     (GtkCssParser      *parser,
 | 
					int                _gtk_win32_theme_int_parse     (GtkCssParser      *parser,
 | 
				
			||||||
						   GFile             *base,
 | 
											   GFile             *base,
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user