Merge from stable:

2002-11-24  Tor Lillqvist  <tml@iki.fi>

	Merge from stable:

	Implement tiles and stipples for all drawing methids (except the
	deprecated draw_text() and draw_text_wc()).

	* gdk/win32/gdkdrawable-win32.c: Remove the already ifdeffed-out
	code that didn't use generic_draw().

	(generic_draw): When drawing into the mask (for tiled/stippled
	fill styles), copy the line attributes from the actual GC. Also
	ask for text drawing setup if needed. Use differently set up HDCs
	in the normal and tiled/stippled cases.

	(draw_lines, gdk_win32_draw_lines, draw_polygon,
	gdk_win32_draw_polygon, draw_segments, gdk_win32_draw_segments,
	draw_arc, gdk_win32_draw_arc): Use generic_draw(), thus
	implementing tiled and stippled fill styles for lines, polygons,
	segments, and args.

	(gdk_win32_draw_points): Use Rectangle() instead of
	SetPixel(). Rectangle() uses the function (raster op) set for the
	HDC, SetPixel() doesn't.

	(widen_bounds): New function, refactoring.

	* gdk/win32/gdkgc-win32.c: Remove ifdeffed-out code.

	(predraw_set_foreground, gdk_win32_hdc_get): Some code moved
	around. Call SetROP2() only if necessary. Call SetTextColor() only
	if GDK_GC_FOREGROUND flag present. Don't handle
	GDK_OPAQUE_STIPPLED here, has been superseded by the code in
	generic_draw(). Always create a solid brush.

	Remove background color handling from here. The background color
	of a GdkGC is supposed to affect only GDK_OPAQUE_STIPPLED fill
	style, which it is already handled in generic_draw(), and
	GDK_LINE_DOUBLE_DASH lines, which aren't implemented properly
	anyway. Calling SetBkColor() is unnecessary as we always use
	TRANSPARENT text output.

	(gdk_win32_hdc_get, gdk_win32_hdc_release): Add doc comments, as
	these are public functions.

	* gdk/win32/gdkevents-win32.c (synthesize_expose_events): Don't
	synthesize expose events for GDK_INPUT_ONLY windows.
	(gdk_event_translate): On WM_SIZE, call
	gdk_synthesize_window_state() if window was iconified, restored or
	maximized. (#98983, Arnaud Charlet)

	* gtk+/gdk/win32/gdkwindow-win32.c
	(gdk_window_get_frame_extents): Fix typo in setting y.  (#98983,
	Arnaud Charlet)
This commit is contained in:
Tor Lillqvist
2002-11-24 23:54:01 +00:00
committed by Tor Lillqvist
parent 65cce90c27
commit 08fc500e8d
10 changed files with 859 additions and 615 deletions

View File

@ -1,3 +1,58 @@
2002-11-24 Tor Lillqvist <tml@iki.fi>
Merge from stable:
Implement tiles and stipples for all drawing methids (except the
deprecated draw_text() and draw_text_wc()).
* gdk/win32/gdkdrawable-win32.c: Remove the already ifdeffed-out
code that didn't use generic_draw().
(generic_draw): When drawing into the mask (for tiled/stippled
fill styles), copy the line attributes from the actual GC. Also
ask for text drawing setup if needed. Use differently set up HDCs
in the normal and tiled/stippled cases.
(draw_lines, gdk_win32_draw_lines, draw_polygon,
gdk_win32_draw_polygon, draw_segments, gdk_win32_draw_segments,
draw_arc, gdk_win32_draw_arc): Use generic_draw(), thus
implementing tiled and stippled fill styles for lines, polygons,
segments, and args.
(gdk_win32_draw_points): Use Rectangle() instead of
SetPixel(). Rectangle() uses the function (raster op) set for the
HDC, SetPixel() doesn't.
(widen_bounds): New function, refactoring.
* gdk/win32/gdkgc-win32.c: Remove ifdeffed-out code.
(predraw_set_foreground, gdk_win32_hdc_get): Some code moved
around. Call SetROP2() only if necessary. Call SetTextColor() only
if GDK_GC_FOREGROUND flag present. Don't handle
GDK_OPAQUE_STIPPLED here, has been superseded by the code in
generic_draw(). Always create a solid brush.
Remove background color handling from here. The background color
of a GdkGC is supposed to affect only GDK_OPAQUE_STIPPLED fill
style, which it is already handled in generic_draw(), and
GDK_LINE_DOUBLE_DASH lines, which aren't implemented properly
anyway. Calling SetBkColor() is unnecessary as we always use
TRANSPARENT text output.
(gdk_win32_hdc_get, gdk_win32_hdc_release): Add doc comments, as
these are public functions.
* gdk/win32/gdkevents-win32.c (synthesize_expose_events): Don't
synthesize expose events for GDK_INPUT_ONLY windows.
(gdk_event_translate): On WM_SIZE, call
gdk_synthesize_window_state() if window was iconified, restored or
maximized. (#98983, Arnaud Charlet)
* gtk+/gdk/win32/gdkwindow-win32.c
(gdk_window_get_frame_extents): Fix typo in setting y. (#98983,
Arnaud Charlet)
2002-11-23 Matthias Clasen <maclas@gmx.de> 2002-11-23 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap): * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap):

View File

@ -1,3 +1,58 @@
2002-11-24 Tor Lillqvist <tml@iki.fi>
Merge from stable:
Implement tiles and stipples for all drawing methids (except the
deprecated draw_text() and draw_text_wc()).
* gdk/win32/gdkdrawable-win32.c: Remove the already ifdeffed-out
code that didn't use generic_draw().
(generic_draw): When drawing into the mask (for tiled/stippled
fill styles), copy the line attributes from the actual GC. Also
ask for text drawing setup if needed. Use differently set up HDCs
in the normal and tiled/stippled cases.
(draw_lines, gdk_win32_draw_lines, draw_polygon,
gdk_win32_draw_polygon, draw_segments, gdk_win32_draw_segments,
draw_arc, gdk_win32_draw_arc): Use generic_draw(), thus
implementing tiled and stippled fill styles for lines, polygons,
segments, and args.
(gdk_win32_draw_points): Use Rectangle() instead of
SetPixel(). Rectangle() uses the function (raster op) set for the
HDC, SetPixel() doesn't.
(widen_bounds): New function, refactoring.
* gdk/win32/gdkgc-win32.c: Remove ifdeffed-out code.
(predraw_set_foreground, gdk_win32_hdc_get): Some code moved
around. Call SetROP2() only if necessary. Call SetTextColor() only
if GDK_GC_FOREGROUND flag present. Don't handle
GDK_OPAQUE_STIPPLED here, has been superseded by the code in
generic_draw(). Always create a solid brush.
Remove background color handling from here. The background color
of a GdkGC is supposed to affect only GDK_OPAQUE_STIPPLED fill
style, which it is already handled in generic_draw(), and
GDK_LINE_DOUBLE_DASH lines, which aren't implemented properly
anyway. Calling SetBkColor() is unnecessary as we always use
TRANSPARENT text output.
(gdk_win32_hdc_get, gdk_win32_hdc_release): Add doc comments, as
these are public functions.
* gdk/win32/gdkevents-win32.c (synthesize_expose_events): Don't
synthesize expose events for GDK_INPUT_ONLY windows.
(gdk_event_translate): On WM_SIZE, call
gdk_synthesize_window_state() if window was iconified, restored or
maximized. (#98983, Arnaud Charlet)
* gtk+/gdk/win32/gdkwindow-win32.c
(gdk_window_get_frame_extents): Fix typo in setting y. (#98983,
Arnaud Charlet)
2002-11-23 Matthias Clasen <maclas@gmx.de> 2002-11-23 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap): * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap):

View File

@ -1,3 +1,58 @@
2002-11-24 Tor Lillqvist <tml@iki.fi>
Merge from stable:
Implement tiles and stipples for all drawing methids (except the
deprecated draw_text() and draw_text_wc()).
* gdk/win32/gdkdrawable-win32.c: Remove the already ifdeffed-out
code that didn't use generic_draw().
(generic_draw): When drawing into the mask (for tiled/stippled
fill styles), copy the line attributes from the actual GC. Also
ask for text drawing setup if needed. Use differently set up HDCs
in the normal and tiled/stippled cases.
(draw_lines, gdk_win32_draw_lines, draw_polygon,
gdk_win32_draw_polygon, draw_segments, gdk_win32_draw_segments,
draw_arc, gdk_win32_draw_arc): Use generic_draw(), thus
implementing tiled and stippled fill styles for lines, polygons,
segments, and args.
(gdk_win32_draw_points): Use Rectangle() instead of
SetPixel(). Rectangle() uses the function (raster op) set for the
HDC, SetPixel() doesn't.
(widen_bounds): New function, refactoring.
* gdk/win32/gdkgc-win32.c: Remove ifdeffed-out code.
(predraw_set_foreground, gdk_win32_hdc_get): Some code moved
around. Call SetROP2() only if necessary. Call SetTextColor() only
if GDK_GC_FOREGROUND flag present. Don't handle
GDK_OPAQUE_STIPPLED here, has been superseded by the code in
generic_draw(). Always create a solid brush.
Remove background color handling from here. The background color
of a GdkGC is supposed to affect only GDK_OPAQUE_STIPPLED fill
style, which it is already handled in generic_draw(), and
GDK_LINE_DOUBLE_DASH lines, which aren't implemented properly
anyway. Calling SetBkColor() is unnecessary as we always use
TRANSPARENT text output.
(gdk_win32_hdc_get, gdk_win32_hdc_release): Add doc comments, as
these are public functions.
* gdk/win32/gdkevents-win32.c (synthesize_expose_events): Don't
synthesize expose events for GDK_INPUT_ONLY windows.
(gdk_event_translate): On WM_SIZE, call
gdk_synthesize_window_state() if window was iconified, restored or
maximized. (#98983, Arnaud Charlet)
* gtk+/gdk/win32/gdkwindow-win32.c
(gdk_window_get_frame_extents): Fix typo in setting y. (#98983,
Arnaud Charlet)
2002-11-23 Matthias Clasen <maclas@gmx.de> 2002-11-23 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap): * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap):

View File

@ -1,3 +1,58 @@
2002-11-24 Tor Lillqvist <tml@iki.fi>
Merge from stable:
Implement tiles and stipples for all drawing methids (except the
deprecated draw_text() and draw_text_wc()).
* gdk/win32/gdkdrawable-win32.c: Remove the already ifdeffed-out
code that didn't use generic_draw().
(generic_draw): When drawing into the mask (for tiled/stippled
fill styles), copy the line attributes from the actual GC. Also
ask for text drawing setup if needed. Use differently set up HDCs
in the normal and tiled/stippled cases.
(draw_lines, gdk_win32_draw_lines, draw_polygon,
gdk_win32_draw_polygon, draw_segments, gdk_win32_draw_segments,
draw_arc, gdk_win32_draw_arc): Use generic_draw(), thus
implementing tiled and stippled fill styles for lines, polygons,
segments, and args.
(gdk_win32_draw_points): Use Rectangle() instead of
SetPixel(). Rectangle() uses the function (raster op) set for the
HDC, SetPixel() doesn't.
(widen_bounds): New function, refactoring.
* gdk/win32/gdkgc-win32.c: Remove ifdeffed-out code.
(predraw_set_foreground, gdk_win32_hdc_get): Some code moved
around. Call SetROP2() only if necessary. Call SetTextColor() only
if GDK_GC_FOREGROUND flag present. Don't handle
GDK_OPAQUE_STIPPLED here, has been superseded by the code in
generic_draw(). Always create a solid brush.
Remove background color handling from here. The background color
of a GdkGC is supposed to affect only GDK_OPAQUE_STIPPLED fill
style, which it is already handled in generic_draw(), and
GDK_LINE_DOUBLE_DASH lines, which aren't implemented properly
anyway. Calling SetBkColor() is unnecessary as we always use
TRANSPARENT text output.
(gdk_win32_hdc_get, gdk_win32_hdc_release): Add doc comments, as
these are public functions.
* gdk/win32/gdkevents-win32.c (synthesize_expose_events): Don't
synthesize expose events for GDK_INPUT_ONLY windows.
(gdk_event_translate): On WM_SIZE, call
gdk_synthesize_window_state() if window was iconified, restored or
maximized. (#98983, Arnaud Charlet)
* gtk+/gdk/win32/gdkwindow-win32.c
(gdk_window_get_frame_extents): Fix typo in setting y. (#98983,
Arnaud Charlet)
2002-11-23 Matthias Clasen <maclas@gmx.de> 2002-11-23 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap): * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap):

View File

@ -1,3 +1,58 @@
2002-11-24 Tor Lillqvist <tml@iki.fi>
Merge from stable:
Implement tiles and stipples for all drawing methids (except the
deprecated draw_text() and draw_text_wc()).
* gdk/win32/gdkdrawable-win32.c: Remove the already ifdeffed-out
code that didn't use generic_draw().
(generic_draw): When drawing into the mask (for tiled/stippled
fill styles), copy the line attributes from the actual GC. Also
ask for text drawing setup if needed. Use differently set up HDCs
in the normal and tiled/stippled cases.
(draw_lines, gdk_win32_draw_lines, draw_polygon,
gdk_win32_draw_polygon, draw_segments, gdk_win32_draw_segments,
draw_arc, gdk_win32_draw_arc): Use generic_draw(), thus
implementing tiled and stippled fill styles for lines, polygons,
segments, and args.
(gdk_win32_draw_points): Use Rectangle() instead of
SetPixel(). Rectangle() uses the function (raster op) set for the
HDC, SetPixel() doesn't.
(widen_bounds): New function, refactoring.
* gdk/win32/gdkgc-win32.c: Remove ifdeffed-out code.
(predraw_set_foreground, gdk_win32_hdc_get): Some code moved
around. Call SetROP2() only if necessary. Call SetTextColor() only
if GDK_GC_FOREGROUND flag present. Don't handle
GDK_OPAQUE_STIPPLED here, has been superseded by the code in
generic_draw(). Always create a solid brush.
Remove background color handling from here. The background color
of a GdkGC is supposed to affect only GDK_OPAQUE_STIPPLED fill
style, which it is already handled in generic_draw(), and
GDK_LINE_DOUBLE_DASH lines, which aren't implemented properly
anyway. Calling SetBkColor() is unnecessary as we always use
TRANSPARENT text output.
(gdk_win32_hdc_get, gdk_win32_hdc_release): Add doc comments, as
these are public functions.
* gdk/win32/gdkevents-win32.c (synthesize_expose_events): Don't
synthesize expose events for GDK_INPUT_ONLY windows.
(gdk_event_translate): On WM_SIZE, call
gdk_synthesize_window_state() if window was iconified, restored or
maximized. (#98983, Arnaud Charlet)
* gtk+/gdk/win32/gdkwindow-win32.c
(gdk_window_get_frame_extents): Fix typo in setting y. (#98983,
Arnaud Charlet)
2002-11-23 Matthias Clasen <maclas@gmx.de> 2002-11-23 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap): * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap):

View File

@ -1,3 +1,58 @@
2002-11-24 Tor Lillqvist <tml@iki.fi>
Merge from stable:
Implement tiles and stipples for all drawing methids (except the
deprecated draw_text() and draw_text_wc()).
* gdk/win32/gdkdrawable-win32.c: Remove the already ifdeffed-out
code that didn't use generic_draw().
(generic_draw): When drawing into the mask (for tiled/stippled
fill styles), copy the line attributes from the actual GC. Also
ask for text drawing setup if needed. Use differently set up HDCs
in the normal and tiled/stippled cases.
(draw_lines, gdk_win32_draw_lines, draw_polygon,
gdk_win32_draw_polygon, draw_segments, gdk_win32_draw_segments,
draw_arc, gdk_win32_draw_arc): Use generic_draw(), thus
implementing tiled and stippled fill styles for lines, polygons,
segments, and args.
(gdk_win32_draw_points): Use Rectangle() instead of
SetPixel(). Rectangle() uses the function (raster op) set for the
HDC, SetPixel() doesn't.
(widen_bounds): New function, refactoring.
* gdk/win32/gdkgc-win32.c: Remove ifdeffed-out code.
(predraw_set_foreground, gdk_win32_hdc_get): Some code moved
around. Call SetROP2() only if necessary. Call SetTextColor() only
if GDK_GC_FOREGROUND flag present. Don't handle
GDK_OPAQUE_STIPPLED here, has been superseded by the code in
generic_draw(). Always create a solid brush.
Remove background color handling from here. The background color
of a GdkGC is supposed to affect only GDK_OPAQUE_STIPPLED fill
style, which it is already handled in generic_draw(), and
GDK_LINE_DOUBLE_DASH lines, which aren't implemented properly
anyway. Calling SetBkColor() is unnecessary as we always use
TRANSPARENT text output.
(gdk_win32_hdc_get, gdk_win32_hdc_release): Add doc comments, as
these are public functions.
* gdk/win32/gdkevents-win32.c (synthesize_expose_events): Don't
synthesize expose events for GDK_INPUT_ONLY windows.
(gdk_event_translate): On WM_SIZE, call
gdk_synthesize_window_state() if window was iconified, restored or
maximized. (#98983, Arnaud Charlet)
* gtk+/gdk/win32/gdkwindow-win32.c
(gdk_window_get_frame_extents): Fix typo in setting y. (#98983,
Arnaud Charlet)
2002-11-23 Matthias Clasen <maclas@gmx.de> 2002-11-23 Matthias Clasen <maclas@gmx.de>
* gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap): * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_pixmap):

View File

@ -25,8 +25,6 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/. * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/ */
#define USE_GENERIC_DRAW
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <glib.h> #include <glib.h>
@ -41,6 +39,9 @@
#define ROP3_DPSao 0x00EA02E9 #define ROP3_DPSao 0x00EA02E9
#define ROP3_DSna 0x00220326 #define ROP3_DSna 0x00220326
#define LINE_ATTRIBUTES (GDK_GC_LINE_WIDTH|GDK_GC_LINE_STYLE| \
GDK_GC_CAP_STYLE|GDK_GC_JOIN_STYLE)
static void gdk_win32_draw_rectangle (GdkDrawable *drawable, static void gdk_win32_draw_rectangle (GdkDrawable *drawable,
GdkGC *gc, GdkGC *gc,
gboolean filled, gboolean filled,
@ -414,7 +415,7 @@ generic_draw (GdkDrawable *drawable,
{ {
GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable); GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc); GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
HDC hdc = gdk_win32_hdc_get (drawable, gc, mask); HDC hdc;
va_list args; va_list args;
va_start (args, region); va_start (args, region);
@ -432,6 +433,8 @@ generic_draw (GdkDrawable *drawable,
gcwin32->values_mask & GDK_GC_STIPPLE && gcwin32->values_mask & GDK_GC_STIPPLE &&
gcwin32->stipple != NULL))) gcwin32->stipple != NULL)))
{ {
const GdkGCValuesMask blitting_mask = 0;
GdkGCValuesMask drawing_mask = GDK_GC_FOREGROUND;
gint ts_x_origin = 0, ts_y_origin = 0; gint ts_x_origin = 0, ts_y_origin = 0;
gint width = region->extents.x2 - region->extents.x1; gint width = region->extents.x2 - region->extents.x1;
@ -448,11 +451,16 @@ generic_draw (GdkDrawable *drawable,
GdkGC *tile_gc = gdk_gc_new (tile_pixmap); GdkGC *tile_gc = gdk_gc_new (tile_pixmap);
HDC mask_hdc; HDC mask_hdc;
HDC tile_hdc = CreateCompatibleDC (hdc); HDC tile_hdc;
HGDIOBJ old_mask_hbm; HGDIOBJ old_mask_hbm;
HGDIOBJ old_tile_hbm; HGDIOBJ old_tile_hbm;
GdkGCValues gcvalues;
hdc = gdk_win32_hdc_get (drawable, gc, blitting_mask);
tile_hdc = CreateCompatibleDC (hdc);
if (gcwin32->values_mask & GDK_GC_TS_X_ORIGIN) if (gcwin32->values_mask & GDK_GC_TS_X_ORIGIN)
ts_x_origin = gc->ts_x_origin; ts_x_origin = gc->ts_x_origin;
if (gcwin32->values_mask & GDK_GC_TS_Y_ORIGIN) if (gcwin32->values_mask & GDK_GC_TS_Y_ORIGIN)
@ -471,10 +479,32 @@ generic_draw (GdkDrawable *drawable,
fg.pixel = 1; fg.pixel = 1;
gdk_gc_set_foreground (mask_gc, &fg); gdk_gc_set_foreground (mask_gc, &fg);
mask_hdc = gdk_win32_hdc_get (mask_pixmap, mask_gc, GDK_GC_FOREGROUND); /* If the drawing function uses line attributes, set them as in
* the real GC.
*/
if (mask & LINE_ATTRIBUTES)
{
gdk_gc_get_values (gc, &gcvalues);
if (gcvalues.line_width != 0 ||
gcvalues.line_style != GDK_LINE_SOLID ||
gcvalues.cap_style != GDK_CAP_BUTT ||
gcvalues.join_style != GDK_JOIN_MITER)
gdk_gc_set_line_attributes (mask_gc,
gcvalues.line_width,
gcvalues.line_style,
gcvalues.cap_style,
gcvalues.join_style);
drawing_mask |= LINE_ATTRIBUTES;
}
/* Ditto, if the drawing function draws text, set up for that. */
if (mask & GDK_GC_FONT)
drawing_mask |= GDK_GC_FONT;
mask_hdc = gdk_win32_hdc_get (mask_pixmap, mask_gc, drawing_mask);
(*function) (GDK_GC_WIN32 (mask_gc), mask_hdc, (*function) (GDK_GC_WIN32 (mask_gc), mask_hdc,
region->extents.x1, region->extents.y1, args); region->extents.x1, region->extents.y1, args);
gdk_win32_hdc_release (mask_pixmap, mask_gc, GDK_GC_FOREGROUND); gdk_win32_hdc_release (mask_pixmap, mask_gc, drawing_mask);
if (gcwin32->fill_style == GDK_TILED) if (gcwin32->fill_style == GDK_TILED)
{ {
@ -615,12 +645,31 @@ generic_draw (GdkDrawable *drawable,
GDI_CALL (DeleteDC, (tile_hdc)); GDI_CALL (DeleteDC, (tile_hdc));
gdk_drawable_unref (mask_pixmap); gdk_drawable_unref (mask_pixmap);
gdk_drawable_unref (tile_pixmap); gdk_drawable_unref (tile_pixmap);
gdk_win32_hdc_release (drawable, gc, blitting_mask);
} }
else else
{
hdc = gdk_win32_hdc_get (drawable, gc, mask);
(*function) (gcwin32, hdc, 0, 0, args); (*function) (gcwin32, hdc, 0, 0, args);
va_end (args);
gdk_win32_hdc_release (drawable, gc, mask); gdk_win32_hdc_release (drawable, gc, mask);
}
va_end (args);
}
static GdkRegion *
widen_bounds (GdkRectangle *bounds,
gint pen_width)
{
if (pen_width == 0)
pen_width = 1;
bounds->x -= pen_width;
bounds->y -= pen_width;
bounds->width += 2 * pen_width;
bounds->height += 2 * pen_width;
return gdk_region_rectangle (bounds);
} }
static void static void
@ -631,13 +680,13 @@ draw_rectangle (GdkGCWin32 *gcwin32,
va_list args) va_list args)
{ {
HGDIOBJ old_pen_or_brush; HGDIOBJ old_pen_or_brush;
gint filled; gboolean filled;
gint x; gint x;
gint y; gint y;
gint width; gint width;
gint height; gint height;
filled = va_arg (args, gint); filled = va_arg (args, gboolean);
x = va_arg (args, gint); x = va_arg (args, gint);
y = va_arg (args, gint); y = va_arg (args, gint);
width = va_arg (args, gint); width = va_arg (args, gint);
@ -690,11 +739,8 @@ gdk_win32_draw_rectangle (GdkDrawable *drawable,
gint width, gint width,
gint height) gint height)
{ {
#ifdef USE_GENERIC_DRAW
GdkRectangle bounds; GdkRectangle bounds;
GdkRegion *region; GdkRegion *region;
gint pen_width;
GDK_NOTE (MISC, g_print ("gdk_win32_draw_rectangle: %s (%p) %s%dx%d@+%d+%d\n", GDK_NOTE (MISC, g_print ("gdk_win32_draw_rectangle: %s (%p) %s%dx%d@+%d+%d\n",
_gdk_win32_drawable_description (drawable), _gdk_win32_drawable_description (drawable),
@ -702,157 +748,45 @@ gdk_win32_draw_rectangle (GdkDrawable *drawable,
(filled ? "fill " : ""), (filled ? "fill " : ""),
width, height, x, y)); width, height, x, y));
pen_width = GDK_GC_WIN32 (gc)->pen_width; bounds.x = x;
if (pen_width == 0) bounds.y = y;
pen_width = 1; bounds.width = width;
bounds.height = height;
region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
bounds.x = x - pen_width; generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
bounds.y = y - pen_width;
bounds.width = width + 2 * pen_width;
bounds.height = height + 2 * pen_width;
region = gdk_region_rectangle (&bounds);
generic_draw (drawable, gc, GDK_GC_FOREGROUND|GDK_GC_BACKGROUND,
draw_rectangle, region, filled, x, y, width, height); draw_rectangle, region, filled, x, y, width, height);
gdk_region_destroy (region); gdk_region_destroy (region);
#else /* !USE_GENERIC_DRAW */
GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
HDC hdc;
HGDIOBJ old_pen_or_brush;
POINT pts[4];
gboolean ok = TRUE;
GDK_NOTE (MISC, g_print ("gdk_win32_draw_rectangle: %s (%p) %s%dx%d@+%d+%d\n",
_gdk_win32_drawable_description (drawable),
gcwin32,
(filled ? "fill " : ""),
width, height, x, y));
if (filled
&& (gcwin32->values_mask & GDK_GC_TILE)
&& (gcwin32->tile)
&& (gcwin32->values_mask & GDK_GC_FILL)
&& (gcwin32->fill_style == GDK_TILED))
{
draw_tiles (drawable, gc, SRCCOPY,
gcwin32->tile,
x, y,
gc->ts_x_origin,
gc->ts_y_origin,
width, height);
return;
}
hdc = gdk_win32_hdc_get (drawable, gc, mask);
if (gcwin32->fill_style == GDK_OPAQUE_STIPPLED)
{
if (!BeginPath (hdc))
WIN32_GDI_FAILED ("BeginPath"), ok = FALSE;
/* Win9x doesn't support Rectangle calls in a path,
* thus use Polyline.
*/
pts[0].x = x;
pts[0].y = y;
pts[1].x = x + width + 1;
pts[1].y = y;
pts[2].x = x + width + 1;
pts[2].y = y + height + 1;
pts[3].x = x;
pts[3].y = y + height + 1;
if (ok)
MoveToEx (hdc, x, y, NULL);
if (ok && !Polyline (hdc, pts, 4))
WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
if (ok && !CloseFigure (hdc))
WIN32_GDI_FAILED ("CloseFigure"), ok = FALSE;
if (ok && !EndPath (hdc))
WIN32_GDI_FAILED ("EndPath"), ok = FALSE;
if (ok && !filled)
if (!WidenPath (hdc))
WIN32_GDI_FAILED ("WidenPath"), ok = FALSE;
if (ok && !FillPath (hdc))
WIN32_GDI_FAILED ("FillPath"), ok = FALSE;
}
else
{
if (!filled && gcwin32->pen_dashes && !IS_WIN_NT ())
{
ok = ok && render_line_vertical (hdc, x, y, y+height+1,
gcwin32->pen_width,
gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
ok = ok && render_line_horizontal (hdc, x, x+width+1, y,
gcwin32->pen_width,
gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
ok = ok && render_line_vertical (hdc, x+width+1, y, y+height+1,
gcwin32->pen_width,
gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
ok = ok && render_line_horizontal (hdc, x, x+width+1, y+height+1,
gcwin32->pen_width,
gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
}
else
{
if (filled)
old_pen_or_brush = SelectObject (hdc, GetStockObject (NULL_PEN));
else
old_pen_or_brush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
if (old_pen_or_brush == NULL)
WIN32_GDI_FAILED ("SelectObject");
if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
WIN32_GDI_FAILED ("Rectangle");
if (old_pen_or_brush)
SelectObject (hdc, old_pen_or_brush);
}
}
gdk_win32_hdc_release (drawable, gc, mask);
#endif /* !USE_GENERIC_DRAW */
} }
static void static void
gdk_win32_draw_arc (GdkDrawable *drawable, draw_arc (GdkGCWin32 *gcwin32,
GdkGC *gc, HDC hdc,
gboolean filled, gint x_offset,
gint x, gint y_offset,
gint y, va_list args)
gint width,
gint height,
gint angle1,
gint angle2)
{ {
const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND; HGDIOBJ old_pen;
HDC hdc; gboolean filled;
gint x;
gint y;
gint width;
gint height;
gint angle1;
gint angle2;
int nXStartArc, nYStartArc, nXEndArc, nYEndArc; int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
GDK_NOTE (MISC, g_print ("gdk_draw_arc: %s %d,%d,%d,%d %d %d\n", filled = va_arg (args, gboolean);
_gdk_win32_drawable_description (drawable), x = va_arg (args, gint);
x, y, width, height, angle1, angle2)); y = va_arg (args, gint);
width = va_arg (args, gint);
height = va_arg (args, gint);
angle1 = va_arg (args, gint);
angle2 = va_arg (args, gint);
/* Seems that drawing arcs with width or height <= 2 fails, at least x -= x_offset;
* with my TNT card. y -= y_offset;
*/
if (width <= 2 || height <= 2 || angle2 == 0)
return;
hdc = gdk_win32_hdc_get (drawable, gc, mask);
if (angle2 >= 360*64) if (angle2 >= 360*64)
{ {
@ -874,17 +808,16 @@ gdk_win32_draw_arc (GdkDrawable *drawable,
nYStartArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.); nYStartArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
} }
/* GDK_OPAQUE_STIPPLED arcs not implemented. */
if (filled) if (filled)
{ {
old_pen = SelectObject (hdc, GetStockObject (NULL_PEN));
GDK_NOTE (MISC, g_print ("...Pie(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n", GDK_NOTE (MISC, g_print ("...Pie(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
x, y, x+width, y+height, x, y, x+width, y+height,
nXStartArc, nYStartArc, nXStartArc, nYStartArc,
nXEndArc, nYEndArc)); nXEndArc, nYEndArc));
if (!Pie (hdc, x, y, x+width, y+height, GDI_CALL (Pie, (hdc, x, y, x+width, y+height,
nXStartArc, nYStartArc, nXEndArc, nYEndArc)) nXStartArc, nYStartArc, nXEndArc, nYEndArc));
WIN32_GDI_FAILED ("Pie"); GDI_CALL (SelectObject, (hdc, old_pen));
} }
else else
{ {
@ -892,11 +825,71 @@ gdk_win32_draw_arc (GdkDrawable *drawable,
x, y, x+width, y+height, x, y, x+width, y+height,
nXStartArc, nYStartArc, nXStartArc, nYStartArc,
nXEndArc, nYEndArc)); nXEndArc, nYEndArc));
if (!Arc (hdc, x, y, x+width, y+height, GDI_CALL (Arc, (hdc, x, y, x+width, y+height,
nXStartArc, nYStartArc, nXEndArc, nYEndArc)) nXStartArc, nYStartArc, nXEndArc, nYEndArc));
WIN32_GDI_FAILED ("Arc");
} }
gdk_win32_hdc_release (drawable, gc, mask); }
static void
gdk_win32_draw_arc (GdkDrawable *drawable,
GdkGC *gc,
gboolean filled,
gint x,
gint y,
gint width,
gint height,
gint angle1,
gint angle2)
{
GdkRectangle bounds;
GdkRegion *region;
GDK_NOTE (MISC, g_print ("gdk_win32_draw_arc: %s %d,%d,%d,%d %d %d\n",
_gdk_win32_drawable_description (drawable),
x, y, width, height, angle1, angle2));
if (width <= 2 || height <= 2 || angle2 == 0)
return;
bounds.x = x;
bounds.y = y;
bounds.width = width;
bounds.height = height;
region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
draw_arc, region, filled, x, y, width, height, angle1, angle2);
gdk_region_destroy (region);
}
static void
draw_polygon (GdkGCWin32 *gcwin32,
HDC hdc,
gint x_offset,
gint y_offset,
va_list args)
{
gboolean filled;
POINT *pts;
gint npoints;
gint i;
filled = va_arg (args, gboolean);
pts = va_arg (args, POINT *);
npoints = va_arg (args, gint);
if (x_offset != 0 || y_offset != 0)
for (i = 0; i < npoints; i++)
{
pts[i].x -= x_offset;
pts[i].y -= y_offset;
}
if (filled)
GDI_CALL (Polygon, (hdc, pts, npoints));
else
GDI_CALL (Polyline, (hdc, pts, npoints));
} }
static void static void
@ -906,80 +899,50 @@ gdk_win32_draw_polygon (GdkDrawable *drawable,
GdkPoint *points, GdkPoint *points,
gint npoints) gint npoints)
{ {
GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc); GdkRectangle bounds;
const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND; GdkRegion *region;
HDC hdc;
POINT *pts; POINT *pts;
gboolean ok = TRUE;
int i; int i;
GDK_NOTE (MISC, g_print ("gdk_win32_draw_polygon: %s (%p) %d\n", GDK_NOTE (MISC, g_print ("gdk_win32_draw_polygon: %s %d points\n",
_gdk_win32_drawable_description (drawable), _gdk_win32_drawable_description (drawable),
gcwin32,
npoints)); npoints));
if (npoints < 2) if (npoints < 2)
return; return;
hdc = gdk_win32_hdc_get (drawable, gc, mask); bounds.x = G_MAXINT;
bounds.y = G_MAXINT;
bounds.width = 0;
bounds.height = 0;
pts = g_new (POINT, npoints+1); pts = g_new (POINT, npoints+1);
for (i = 0; i < npoints; i++) for (i = 0; i < npoints; i++)
{ {
bounds.x = MIN (bounds.x, points[i].x);
bounds.y = MIN (bounds.y, points[i].y);
bounds.width = MAX (bounds.width, points[i].x - bounds.x);
bounds.height = MAX (bounds.height, points[i].y - bounds.y);
pts[i].x = points[i].x; pts[i].x = points[i].x;
pts[i].y = points[i].y; pts[i].y = points[i].y;
} }
if (gcwin32->fill_style == GDK_OPAQUE_STIPPLED) if (points[0].x != points[npoints-1].x ||
{ points[0].y != points[npoints-1].y)
if (!BeginPath (hdc))
WIN32_GDI_FAILED ("BeginPath"), ok = FALSE;
if (ok)
MoveToEx (hdc, points[0].x, points[0].y, NULL);
if (pts[0].x == pts[npoints-1].x && pts[0].y == pts[npoints-1].y)
npoints--;
if (ok && !Polyline (hdc, pts, 4))
WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
if (ok && !CloseFigure (hdc))
WIN32_GDI_FAILED ("CloseFigure"), ok = FALSE;
if (ok && !EndPath (hdc))
WIN32_GDI_FAILED ("EndPath"), ok = FALSE;
if (ok && !filled)
if (!WidenPath (hdc))
WIN32_GDI_FAILED ("WidenPath"), ok = FALSE;
if (ok && !FillPath (hdc))
WIN32_GDI_FAILED ("FillPath"), ok = FALSE;
}
else
{
if (points[0].x != points[npoints-1].x
|| points[0].y != points[npoints-1].y)
{ {
pts[npoints].x = points[0].x; pts[npoints].x = points[0].x;
pts[npoints].y = points[0].y; pts[npoints].y = points[0].y;
npoints++; npoints++;
} }
if (filled) region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
{
if (!Polygon (hdc, pts, npoints)) generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
WIN32_GDI_FAILED ("Polygon"); draw_polygon, region, filled, pts, npoints);
}
else gdk_region_destroy (region);
{
if (!Polyline (hdc, pts, npoints))
WIN32_GDI_FAILED ("Polyline");
}
}
g_free (pts); g_free (pts);
gdk_win32_hdc_release (drawable, gc, mask);
} }
typedef struct typedef struct
@ -1038,7 +1001,7 @@ gdk_win32_draw_text (GdkDrawable *drawable,
arg.y = y; arg.y = y;
arg.hdc = gdk_win32_hdc_get (drawable, gc, mask); arg.hdc = gdk_win32_hdc_get (drawable, gc, mask);
GDK_NOTE (MISC, g_print ("gdk_draw_text: %s (%d,%d) \"%.*s\" (len %d)\n", GDK_NOTE (MISC, g_print ("gdk_win32_draw_text: %s (%d,%d) \"%.*s\" (len %d)\n",
_gdk_win32_drawable_description (drawable), _gdk_win32_drawable_description (drawable),
x, y, x, y,
(text_length > 10 ? 10 : text_length), (text_length > 10 ? 10 : text_length),
@ -1087,7 +1050,7 @@ gdk_win32_draw_text_wc (GdkDrawable *drawable,
arg.y = y; arg.y = y;
arg.hdc = gdk_win32_hdc_get (drawable, gc, mask); arg.hdc = gdk_win32_hdc_get (drawable, gc, mask);
GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %s (%d,%d) len: %d\n", GDK_NOTE (MISC, g_print ("gdk_win32_draw_text_wc: %s (%d,%d) len: %d\n",
_gdk_win32_drawable_description (drawable), _gdk_win32_drawable_description (drawable),
x, y, text_length)); x, y, text_length));
@ -1134,78 +1097,56 @@ gdk_win32_draw_points (GdkDrawable *drawable,
gint npoints) gint npoints)
{ {
HDC hdc; HDC hdc;
COLORREF fg; HGDIOBJ old_pen;
GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc);
GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
int i; int i;
hdc = gdk_win32_hdc_get (drawable, gc, 0); hdc = gdk_win32_hdc_get (drawable, gc, GDK_GC_FOREGROUND);
fg = _gdk_win32_colormap_color (impl->colormap, gcwin32->foreground); GDK_NOTE (MISC, g_print ("gdk_win32_draw_points: %s %d points\n",
GDK_NOTE (MISC, g_print ("gdk_draw_points: %s %dx%.06x\n",
_gdk_win32_drawable_description (drawable), _gdk_win32_drawable_description (drawable),
npoints, (guint) fg)); npoints));
/* The X11 version uses XDrawPoint(), which doesn't use the fill
* mode, so don't use generic_draw. But we should use the current
* function, so we can't use SetPixel(). Draw single-pixel
* rectangles (sigh).
*/
old_pen = SelectObject (hdc, GetStockObject (NULL_PEN));
for (i = 0; i < npoints; i++) for (i = 0; i < npoints; i++)
SetPixel (hdc, points[i].x, points[i].y, fg); Rectangle (hdc, points[i].x, points[i].y,
points[i].x + 2, points[i].y + 2);
gdk_win32_hdc_release (drawable, gc, 0); SelectObject (hdc, old_pen);
gdk_win32_hdc_release (drawable, gc, GDK_GC_FOREGROUND);
} }
static void static void
gdk_win32_draw_segments (GdkDrawable *drawable, draw_segments (GdkGCWin32 *gcwin32,
GdkGC *gc, HDC hdc,
GdkSegment *segs, gint x_offset,
gint nsegs) gint y_offset,
va_list args)
{ {
GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc); GdkSegment *segs;
const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND; gint nsegs;
HDC hdc; gint i;
gboolean ok = TRUE;
int i;
GDK_NOTE (MISC, g_print ("gdk_win32_draw_segments: %s nsegs: %d\n", segs = va_arg (args, GdkSegment *);
_gdk_win32_drawable_description (drawable), nsegs)); nsegs = va_arg (args, gint);
hdc = gdk_win32_hdc_get (drawable, gc, mask); if (x_offset != 0 || y_offset != 0)
for (i = 0; i < nsegs; i++)
if (gcwin32->fill_style == GDK_OPAQUE_STIPPLED)
{ {
if (!BeginPath (hdc)) segs[i].x1 -= x_offset;
WIN32_GDI_FAILED ("BeginPath"), ok = FALSE; segs[i].y1 -= y_offset;
segs[i].x2 -= x_offset;
for (i = 0; ok && i < nsegs; i++) segs[i].y2 -= y_offset;
{
if (ok && !MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
/* Draw end pixel */
if (ok && gcwin32->pen_width <= 1)
if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
} }
if (ok && !EndPath (hdc))
WIN32_GDI_FAILED ("EndPath"), ok = FALSE;
if (ok && !WidenPath (hdc))
WIN32_GDI_FAILED ("WidenPath"), ok = FALSE;
if (ok && !FillPath (hdc))
WIN32_GDI_FAILED ("FillPath"), ok = FALSE;
}
else
{
if (gcwin32->pen_dashes && !IS_WIN_NT ()) if (gcwin32->pen_dashes && !IS_WIN_NT ())
{ {
/* code very similar to the IMHO questionable optimization for (i = 0; i < nsegs; i++)
* below. This one draws dashed vertical/horizontal lines
* with the limited Win9x GDI. --hb
*/
for (i = 0; ok && i < nsegs; i++)
{ {
if (segs[i].x1 == segs[i].x2) if (segs[i].x1 == segs[i].x2)
{ {
@ -1216,7 +1157,7 @@ gdk_win32_draw_segments (GdkDrawable *drawable,
else else
y1 = segs[i].y2, y2 = segs[i].y1; y1 = segs[i].y2, y2 = segs[i].y1;
ok = render_line_vertical (hdc, render_line_vertical (hdc,
segs[i].x1, y1, y2, segs[i].x1, y1, y2,
gcwin32->pen_width, gcwin32->pen_width,
gcwin32->pen_dashes, gcwin32->pen_dashes,
@ -1231,82 +1172,126 @@ gdk_win32_draw_segments (GdkDrawable *drawable,
else else
x1 = segs[i].x2, x2 = segs[i].x1; x1 = segs[i].x2, x2 = segs[i].x1;
ok = render_line_horizontal (hdc, render_line_horizontal (hdc,
x1, x2, segs[i].y1, x1, x2, segs[i].y1,
gcwin32->pen_width, gcwin32->pen_width,
gcwin32->pen_dashes, gcwin32->pen_dashes,
gcwin32->pen_num_dashes); gcwin32->pen_num_dashes);
} }
else else
{ GDI_CALL (MoveToEx, (hdc, segs[i].x1, segs[i].y1, NULL)) &&
if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL)) GDI_CALL (LineTo, (hdc, segs[i].x2, segs[i].y2)) &&
WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE; (gcwin32->pen_width <= 1 &&
if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2)) GDI_CALL (LineTo, (hdc, segs[i].x2 + 1, segs[i].y2 + 1)));
WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
/* Draw end pixel */
if (ok && gcwin32->pen_width <= 1)
if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
}
} }
} }
else else
{ {
const gboolean maybe_patblt = for (i = 0; i < nsegs; i++)
gcwin32->rop2 == R2_COPYPEN && GDI_CALL (MoveToEx, (hdc, segs[i].x1, segs[i].y1, NULL)) &&
gcwin32->pen_width <= 1 && GDI_CALL (LineTo, (hdc, segs[i].x2, segs[i].y2)) &&
(gcwin32->pen_style & PS_STYLE_MASK) == PS_SOLID; (gcwin32->pen_width <= 1 &&
GDI_CALL (LineTo, (hdc, segs[i].x2 + 1, segs[i].y2 + 1)));
}
}
for (i = 0; ok && i < nsegs; i++) static void
gdk_win32_draw_segments (GdkDrawable *drawable,
GdkGC *gc,
GdkSegment *segs,
gint nsegs)
{
GdkRectangle bounds;
GdkRegion *region;
gint i;
GDK_NOTE (MISC, g_print ("gdk_win32_draw_segments: %s %d segs\n",
_gdk_win32_drawable_description (drawable),
nsegs));
bounds.x = G_MAXINT;
bounds.y = G_MAXINT;
bounds.width = 0;
bounds.height = 0;
for (i = 0; i < nsegs; i++)
{ {
/* PatBlt() is much faster than LineTo(), says bounds.x = MIN (bounds.x, segs[i].x1);
* jpe@archaeopteryx.com. Hmm. Use it if we have a solid bounds.x = MIN (bounds.x, segs[i].x2);
* colour pen, then we know that the brush is also solid and bounds.y = MIN (bounds.y, segs[i].y1);
* of the same colour. bounds.y = MIN (bounds.y, segs[i].y2);
*/ bounds.width = MAX (bounds.width, segs[i].x1 - bounds.x);
if (maybe_patblt && segs[i].x1 == segs[i].x2) bounds.width = MAX (bounds.width, segs[i].x2 - bounds.x);
bounds.height = MAX (bounds.height, segs[i].y1 - bounds.y);
bounds.height = MAX (bounds.height, segs[i].y2 - bounds.y);
}
region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
draw_segments, region, segs, nsegs);
gdk_region_destroy (region);
}
static void
draw_lines (GdkGCWin32 *gcwin32,
HDC hdc,
gint x_offset,
gint y_offset,
va_list args)
{
POINT *pts;
gint npoints;
gint i;
pts = va_arg (args, POINT *);
npoints = va_arg (args, gint);
if (x_offset != 0 || y_offset != 0)
for (i = 0; i < npoints; i++)
{
pts[i].x -= x_offset;
pts[i].y -= y_offset;
}
if (gcwin32->pen_dashes && !IS_WIN_NT ())
{
for (i = 0; i < npoints - 1; i++)
{
if (pts[i].x == pts[i+1].x)
{ {
int y1, y2; int y1, y2;
if (pts[i].y > pts[i+1].y)
if (segs[i].y1 <= segs[i].y2) y1 = pts[i+1].y, y2 = pts[i].y;
y1 = segs[i].y1, y2 = segs[i].y2;
else else
y1 = segs[i].y2, y2 = segs[i].y1; y1 = pts[i].y, y2 = pts[i+1].y;
if (!PatBlt (hdc, segs[i].x1, y1, render_line_vertical (hdc, pts[i].x, y1, y2,
1, y2 - y1 + 1, PATCOPY)) gcwin32->pen_width,
WIN32_GDI_FAILED ("PatBlt"), ok = FALSE; gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
} }
else if (maybe_patblt && segs[i].y1 == segs[i].y2) else if (pts[i].y == pts[i+1].y)
{ {
int x1, x2; int x1, x2;
if (pts[i].x > pts[i+1].x)
if (segs[i].x1 <= segs[i].x2) x1 = pts[i+1].x, x2 = pts[i].x;
x1 = segs[i].x1, x2 = segs[i].x2;
else else
x1 = segs[i].x2, x2 = segs[i].x1; x1 = pts[i].x, x2 = pts[i+1].x;
if (!PatBlt (hdc, x1, segs[i].y1, render_line_horizontal (hdc, x1, x2, pts[i].y,
x2 - x1 + 1, 1, PATCOPY)) gcwin32->pen_width,
WIN32_GDI_FAILED ("PatBlt"), ok = FALSE; gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
} }
else else
{ GDI_CALL (MoveToEx, (hdc, pts[i].x, pts[i].y, NULL)) &&
if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL)) GDI_CALL (LineTo, (hdc, pts[i+1].x, pts[i+1].y));
WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
/* Draw end pixel */
if (ok && gcwin32->pen_width <= 1)
if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
} }
} }
} else
} GDI_CALL (Polyline, (hdc, pts, npoints));
gdk_win32_hdc_release (drawable, gc, mask);
} }
static void static void
@ -1315,82 +1300,42 @@ gdk_win32_draw_lines (GdkDrawable *drawable,
GdkPoint *points, GdkPoint *points,
gint npoints) gint npoints)
{ {
GdkGCWin32 *gcwin32 = GDK_GC_WIN32 (gc); GdkRectangle bounds;
const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND; GdkRegion *region;
HDC hdc;
POINT *pts; POINT *pts;
int i; int i;
gboolean ok = TRUE;
GDK_NOTE (MISC, g_print ("gdk_win32_draw_lines: %s %d points\n",
_gdk_win32_drawable_description (drawable),
npoints));
if (npoints < 2) if (npoints < 2)
return; return;
hdc = gdk_win32_hdc_get (drawable, gc, mask); bounds.x = G_MAXINT;
bounds.y = G_MAXINT;
bounds.width = 0;
bounds.height = 0;
if (gcwin32->pen_dashes && !IS_WIN_NT ())
{
for (i = 0; i < npoints - 1; i++)
{
if (points[i].x == points[i+1].x)
{
int y1, y2;
if (points[i].y > points[i+1].y)
y1 = points[i+1].y, y2 = points[i].y;
else
y1 = points[i].y, y2 = points[i+1].y;
render_line_vertical (hdc, points[i].x, y1, y2,
gcwin32->pen_width,
gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
}
else if (points[i].y == points[i+1].y)
{
int x1, x2;
if (points[i].x > points[i+1].x)
x1 = points[i+1].x, x2 = points[i].x;
else
x1 = points[i].x, x2 = points[i+1].x;
render_line_horizontal (hdc, x1, x2, points[i].y,
gcwin32->pen_width,
gcwin32->pen_dashes,
gcwin32->pen_num_dashes);
}
else
{
if (!MoveToEx (hdc, points[i].x, points[i].y, NULL))
WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
if (ok && !LineTo (hdc, points[i+1].x, points[i+1].y))
WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
}
}
}
else
{
pts = g_new (POINT, npoints); pts = g_new (POINT, npoints);
for (i = 0; i < npoints; i++) for (i = 0; i < npoints; i++)
{ {
bounds.x = MIN (bounds.x, points[i].x);
bounds.y = MIN (bounds.y, points[i].y);
bounds.width = MAX (bounds.width, points[i].x - bounds.x);
bounds.height = MAX (bounds.height, points[i].y - bounds.y);
pts[i].x = points[i].x; pts[i].x = points[i].x;
pts[i].y = points[i].y; pts[i].y = points[i].y;
} }
if (!Polyline (hdc, pts, npoints)) region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
generic_draw (drawable, gc, GDK_GC_FOREGROUND|LINE_ATTRIBUTES,
draw_lines, region, pts, npoints);
gdk_region_destroy (region);
g_free (pts); g_free (pts);
/* Draw end pixel */
if (ok && gcwin32->pen_width <= 1)
{
MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
WIN32_GDI_FAILED ("LineTo");
}
}
gdk_win32_hdc_release (drawable, gc, mask);
} }
static void static void
@ -1413,13 +1358,6 @@ draw_glyphs (GdkGCWin32 *gcwin32,
x -= x_offset; x -= x_offset;
y -= y_offset; y -= y_offset;
/* HB: Maybe there should be a GDK_GC_PANGO flag for hdc_get */
/* default write mode is transparent (leave background) */
GDI_CALL (SetBkMode, (hdc, TRANSPARENT));
if (GDI_ERROR == SetTextAlign (hdc, TA_LEFT|TA_BASELINE|TA_NOUPDATECP))
WIN32_GDI_FAILED ("SetTextAlign");
pango_win32_render (hdc, font, glyphs, x, y); pango_win32_render (hdc, font, glyphs, x, y);
} }
@ -1431,8 +1369,6 @@ gdk_win32_draw_glyphs (GdkDrawable *drawable,
gint y, gint y,
PangoGlyphString *glyphs) PangoGlyphString *glyphs)
{ {
#ifdef USE_GENERIC_DRAW
GdkRectangle bounds; GdkRectangle bounds;
GdkRegion *region; GdkRegion *region;
PangoRectangle ink_rect; PangoRectangle ink_rect;
@ -1445,31 +1381,10 @@ gdk_win32_draw_glyphs (GdkDrawable *drawable,
bounds.height = PANGO_PIXELS (ink_rect.height) + 2; bounds.height = PANGO_PIXELS (ink_rect.height) + 2;
region = gdk_region_rectangle (&bounds); region = gdk_region_rectangle (&bounds);
generic_draw (drawable, gc, GDK_GC_FOREGROUND, generic_draw (drawable, gc, GDK_GC_FOREGROUND|GDK_GC_FONT,
draw_glyphs, region, font, x, y, glyphs); draw_glyphs, region, font, x, y, glyphs);
gdk_region_destroy (region); gdk_region_destroy (region);
#else
const GdkGCValuesMask mask = GDK_GC_FOREGROUND;
HDC hdc;
hdc = gdk_win32_hdc_get (drawable, gc, mask);
/* HB: Maybe there should be a GDK_GC_PANGO flag for hdc_get */
/* default write mode is transparent (leave background) */
if (SetBkMode (hdc, TRANSPARENT) == 0)
WIN32_GDI_FAILED ("SetBkMode");
if (GDI_ERROR == SetTextAlign (hdc, TA_LEFT|TA_BASELINE|TA_NOUPDATECP))
WIN32_GDI_FAILED ("SetTextAlign");
pango_win32_render (hdc, font, glyphs, x, y);
gdk_win32_hdc_release (drawable, gc, mask);
#endif
} }
static void static void

View File

@ -1368,7 +1368,9 @@ synthesize_expose_events (GdkWindow *window)
g_list_free (head); g_list_free (head);
if (!(hdc = GetDC (impl->handle))) if (((GdkWindowObject *) window)->input_only)
;
else if (!(hdc = GetDC (impl->handle)))
WIN32_GDI_FAILED ("GetDC"); WIN32_GDI_FAILED ("GetDC");
else else
{ {
@ -2979,6 +2981,11 @@ gdk_event_translate (GdkDisplay *display,
if (k_grab_window == window) if (k_grab_window == window)
gdk_keyboard_ungrab (msg->time); gdk_keyboard_ungrab (msg->time);
if (window && GDK_WINDOW_IS_MAPPED (window))
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_MAXIMIZED,
GDK_WINDOW_STATE_ICONIFIED);
return_val = !GDK_WINDOW_DESTROYED (window); return_val = !GDK_WINDOW_DESTROYED (window);
} }
else if ((msg->wParam == SIZE_RESTORED else if ((msg->wParam == SIZE_RESTORED
@ -2988,9 +2995,6 @@ gdk_event_translate (GdkDisplay *display,
#endif #endif
) )
{ {
if (LOWORD (msg->lParam) == 0)
break;
event->configure.type = GDK_CONFIGURE; event->configure.type = GDK_CONFIGURE;
event->configure.window = window; event->configure.window = window;
pt.x = 0; pt.x = 0;
@ -3005,6 +3009,16 @@ gdk_event_translate (GdkDisplay *display,
GDK_WINDOW_IMPL_WIN32 (private->impl)->width = event->configure.width; GDK_WINDOW_IMPL_WIN32 (private->impl)->width = event->configure.width;
GDK_WINDOW_IMPL_WIN32 (private->impl)->height = event->configure.height; GDK_WINDOW_IMPL_WIN32 (private->impl)->height = event->configure.height;
if (msg->wParam == SIZE_RESTORED)
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_ICONIFIED |
GDK_WINDOW_STATE_MAXIMIZED,
0);
else if (msg->wParam == SIZE_MAXIMIZED)
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_ICONIFIED,
GDK_WINDOW_STATE_MAXIMIZED);
if (private->resize_count > 1) if (private->resize_count > 1)
private->resize_count -= 1; private->resize_count -= 1;

View File

@ -25,6 +25,9 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/. * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/ */
#define LINE_ATTRIBUTES (GDK_GC_LINE_WIDTH|GDK_GC_LINE_STYLE| \
GDK_GC_CAP_STYLE|GDK_GC_JOIN_STYLE)
#include <string.h> #include <string.h>
#include "gdkgc.h" #include "gdkgc.h"
@ -767,15 +770,12 @@ _gdk_win32_colormap_color (GdkColormap *colormap,
} }
} }
static void static COLORREF
predraw_set_foreground (GdkGC *gc, predraw_set_foreground (GdkGC *gc,
GdkColormap *colormap, GdkColormap *colormap,
gboolean *ok) gboolean *ok)
{ {
COLORREF fg; COLORREF fg;
LOGBRUSH logbrush;
HPEN hpen;
HBRUSH hbr;
GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc; GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc;
GdkColormapPrivateWin32 *colormap_private; GdkColormapPrivateWin32 *colormap_private;
gint k; gint k;
@ -800,92 +800,59 @@ predraw_set_foreground (GdkGC *gc,
fg = _gdk_win32_colormap_color (colormap, win32_gc->foreground); fg = _gdk_win32_colormap_color (colormap, win32_gc->foreground);
GDK_NOTE (GC, g_print ("predraw_set_foreground: fg=%06lx\n", fg)); GDK_NOTE (GC, g_print ("predraw_set_foreground: fg=%06lx\n", fg));
return fg;
if (SetTextColor (win32_gc->hdc, fg) == CLR_INVALID)
WIN32_GDI_FAILED ("SetTextColor"), *ok = FALSE;
/* Create and select pen and brush. */
logbrush.lbStyle = BS_SOLID;
logbrush.lbColor = fg;
logbrush.lbHatch = 0;
if (win32_gc->pen_num_dashes > 0 && !IS_WIN_NT ())
{
/* The Win9x GDI is rather limited so we either draw dotted
* lines ourselve (only horizontal and vertical) or let them
* be drawn solid to avoid implementing a whole line renderer
*/
if (*ok && (hpen = ExtCreatePen (
(win32_gc->pen_style & ~(PS_STYLE_MASK)) | PS_SOLID,
(win32_gc->pen_width > 0 ? win32_gc->pen_width : 1),
&logbrush,
0, NULL)) == NULL)
WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE;
}
else
{
if (*ok && (hpen = ExtCreatePen (win32_gc->pen_style,
(win32_gc->pen_width > 0 ? win32_gc->pen_width : 1),
&logbrush,
win32_gc->pen_num_dashes,
win32_gc->pen_dashes)) == NULL)
WIN32_GDI_FAILED ("ExtCreatePen"), *ok = FALSE;
}
if (*ok && SelectObject (win32_gc->hdc, hpen) == NULL)
WIN32_GDI_FAILED ("SelectObject"), *ok = FALSE;
switch (win32_gc->fill_style)
{
case GDK_OPAQUE_STIPPLED:
if (*ok && (hbr = CreatePatternBrush (GDK_PIXMAP_HBITMAP (win32_gc->stipple))) == NULL)
WIN32_GDI_FAILED ("CreatePatternBrush"), *ok = FALSE;
if (*ok && win32_gc->values_mask & (GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN) &&
!SetBrushOrgEx(win32_gc->hdc,
win32_gc->values_mask & GDK_GC_TS_X_ORIGIN ? gc->ts_x_origin : 0,
win32_gc->values_mask & GDK_GC_TS_Y_ORIGIN ? gc->ts_y_origin : 0,
NULL))
WIN32_GDI_FAILED ("SetBrushOrgEx"), *ok = FALSE;
break;
case GDK_SOLID:
default:
if (*ok && (hbr = CreateSolidBrush (fg)) == NULL)
WIN32_GDI_FAILED ("CreateSolidBrush"), *ok = FALSE;
break;
}
if (*ok)
{
HBRUSH old_hbr = SelectObject (win32_gc->hdc, hbr);
if (old_hbr == NULL)
WIN32_GDI_FAILED ("SelectObject"), *ok = FALSE;
}
}
static void
predraw_set_background (GdkGC *gc,
GdkColormap *colormap,
gboolean *ok)
{
GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc;
if (win32_gc->values_mask & GDK_GC_BACKGROUND)
{
COLORREF bg = _gdk_win32_colormap_color (colormap, win32_gc->background);
if (SetBkColor (win32_gc->hdc, bg) == CLR_INVALID)
WIN32_GDI_FAILED ("SetBkColor"), *ok = FALSE;
}
else
{
if (!SetBkMode (win32_gc->hdc, TRANSPARENT))
WIN32_GDI_FAILED ("SetBkMode"), *ok = FALSE;
}
} }
/**
* gdk_win32_hdc_get:
* @drawable: destination #GdkDrawable
* @gc: #GdkGC to use for drawing on @drawable
* @usage: mask indicating what properties needs to be set up
*
* Allocates a Windows device context handle (HDC) for drawing into
* @drawable, and sets it up appropriately according to @usage.
*
* Each #GdkGC can at one time have only one HDC associated with it.
*
* The following flags in @mask are handled:
*
* If %GDK_GC_FOREGROUND is set in @mask, a solid brush of the
* foreground color in @gc is selected into the HDC. The text color of
* the HDC is also set. If the @drawable has a palette (256-color
* mode), the palette is selected and realized.
*
* If any of the line attribute flags (%GDK_GC_LINE_WIDTH,
* %GDK_GC_LINE_STYLE, %GDK_GC_CAP_STYLE and %GDK_GC_JOIN_STYLE) is
* set in @mask, a solid pen of the foreground color and appropriate
* width and stule is created and selected into the HDC. Note that the
* dash properties are not completely implemented.
*
* If the %GDK_GC_FONT flag is set, the background mix mode is set to
* %TRANSPARENT. and the text alignment is set to
* %TA_BASELINE|%TA_LEFT. Note that no font gets selected into the HDC
* by this function.
*
* Some things are done regardless of @mask: If the function in @gc is
* any other than %GDK_COPY, the raster operation of the HDC is
* set. If @gc has a clip mask, the clip region of the HDC is set.
*
* Note that the fill style, tile, stipple, and tile and stipple
* origins in the @gc are ignored by this function. (In general, tiles
* and stipples can't be implemented directly on Win32; you need to do
* multiple pass drawing and blitting to implement tiles or
* stipples. GDK does just that when you call the GDK drawing
* functions with a GC that asks for tiles or stipples.)
*
* When the HDC is no longer used, it should be released by calling
* <function>gdk_win32_hdc_release()</function> with the same
* parameters.
*
* If you modify the HDC by calling <function>SelectObject</function>
* you should undo those modifications before calling
* <function>gdk_win32_hdc_release()</function>.
*
* Return value: The HDC.
**/
HDC HDC
gdk_win32_hdc_get (GdkDrawable *drawable, gdk_win32_hdc_get (GdkDrawable *drawable,
GdkGC *gc, GdkGC *gc,
@ -894,6 +861,10 @@ gdk_win32_hdc_get (GdkDrawable *drawable,
GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc; GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc;
GdkDrawableImplWin32 *impl = NULL; GdkDrawableImplWin32 *impl = NULL;
gboolean ok = TRUE; gboolean ok = TRUE;
COLORREF fg = RGB (0, 0, 0);
LOGBRUSH logbrush;
HPEN hpen;
HBRUSH hbr;
g_assert (win32_gc->hdc == NULL); g_assert (win32_gc->hdc == NULL);
@ -929,21 +900,62 @@ gdk_win32_hdc_get (GdkDrawable *drawable,
} }
if (ok && (usage & GDK_GC_FOREGROUND)) if (ok && (usage & GDK_GC_FOREGROUND))
predraw_set_foreground (gc, impl->colormap, &ok); {
fg = predraw_set_foreground (gc, impl->colormap, &ok);
if (ok && (hbr = CreateSolidBrush (fg)) == NULL)
WIN32_GDI_FAILED ("CreateSolidBrush"), ok = FALSE;
if (ok && (usage & GDK_GC_BACKGROUND)) if (ok && SelectObject (win32_gc->hdc, hbr) == NULL)
predraw_set_background (gc, impl->colormap, &ok); WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
if (ok && SetTextColor (win32_gc->hdc, fg) == CLR_INVALID)
WIN32_GDI_FAILED ("SetTextColor"), ok = FALSE;
}
if (ok && (usage & LINE_ATTRIBUTES))
{
/* Create and select pen */
logbrush.lbStyle = BS_SOLID;
logbrush.lbColor = fg;
logbrush.lbHatch = 0;
if (win32_gc->pen_num_dashes > 0 && !IS_WIN_NT ())
{
/* The Win9x GDI is rather limited so we either draw dashed
* lines ourselves (only horizontal and vertical) or let them be
* drawn solid to avoid implementing a whole line renderer.
*/
if ((hpen = ExtCreatePen (
(win32_gc->pen_style & ~(PS_STYLE_MASK)) | PS_SOLID,
MAX (win32_gc->pen_width, 1),
&logbrush,
0, NULL)) == NULL)
WIN32_GDI_FAILED ("ExtCreatePen"), ok = FALSE;
}
else
{
if ((hpen = ExtCreatePen (win32_gc->pen_style,
MAX (win32_gc->pen_width, 1),
&logbrush,
win32_gc->pen_num_dashes,
win32_gc->pen_dashes)) == NULL)
WIN32_GDI_FAILED ("ExtCreatePen"), ok = FALSE;
}
if (ok && SelectObject (win32_gc->hdc, hpen) == NULL)
WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
}
if (ok && (usage & GDK_GC_FONT)) if (ok && (usage & GDK_GC_FONT))
{ {
if (SetBkMode (win32_gc->hdc, TRANSPARENT) == 0) if (SetBkMode (win32_gc->hdc, TRANSPARENT) == 0)
WIN32_GDI_FAILED ("SetBkMode"), ok = FALSE; WIN32_GDI_FAILED ("SetBkMode"), ok = FALSE;
if (ok && SetTextAlign (win32_gc->hdc, TA_BASELINE) == GDI_ERROR) if (ok && SetTextAlign (win32_gc->hdc, TA_BASELINE|TA_LEFT|TA_NOUPDATECP) == GDI_ERROR)
WIN32_GDI_FAILED ("SetTextAlign"), ok = FALSE; WIN32_GDI_FAILED ("SetTextAlign"), ok = FALSE;
} }
if (ok && (win32_gc->values_mask & GDK_GC_FUNCTION)) if (ok && win32_gc->rop2 != R2_COPYPEN)
if (SetROP2 (win32_gc->hdc, win32_gc->rop2) == 0) if (SetROP2 (win32_gc->hdc, win32_gc->rop2) == 0)
WIN32_GDI_FAILED ("SetROP2"), ok = FALSE; WIN32_GDI_FAILED ("SetROP2"), ok = FALSE;
@ -954,33 +966,6 @@ gdk_win32_hdc_get (GdkDrawable *drawable,
if (SelectClipRgn (win32_gc->hdc, win32_gc->hcliprgn) == ERROR) if (SelectClipRgn (win32_gc->hdc, win32_gc->hcliprgn) == ERROR)
WIN32_API_FAILED ("SelectClipRgn"), ok = FALSE; WIN32_API_FAILED ("SelectClipRgn"), ok = FALSE;
#if 0 /* No, this is totally bogus. The stipple should replicate in x
* and y directions, not be just one copy of the bitmap. We must
* handle stipples elsewhere.
*/
/* Combine the fillmode-stipple with the clip region */
if (ok &&
(win32_gc->values_mask & GDK_GC_STIPPLE) &&
(win32_gc->values_mask & GDK_GC_FILL) &&
(win32_gc->fill_style == GDK_STIPPLED))
{
HRGN hstipplergn;
if ((hstipplergn = _gdk_win32_bitmap_to_hrgn (win32_gc->stipple)) == NULL)
;
else if (win32_gc->values_mask & (GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN) &&
OffsetRgn (hstipplergn,
win32_gc->values_mask & GDK_GC_TS_X_ORIGIN ? gc->ts_x_origin : 0,
win32_gc->values_mask & GDK_GC_TS_Y_ORIGIN ? gc->ts_y_origin : 0) == ERROR)
WIN32_API_FAILED ("OffsetRgn");
else if (ExtSelectClipRgn (win32_gc->hdc, hstipplergn, RGN_AND) == ERROR)
WIN32_API_FAILED ("ExtSelectClipRgn");
if (hstipplergn != NULL && !DeleteObject (hstipplergn))
WIN32_API_FAILED ("DeleteObject");
}
#endif
if (ok && win32_gc->values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN) && if (ok && win32_gc->values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN) &&
OffsetClipRgn (win32_gc->hdc, OffsetClipRgn (win32_gc->hdc,
win32_gc->values_mask & GDK_GC_CLIP_X_ORIGIN ? gc->clip_x_origin : 0, win32_gc->values_mask & GDK_GC_CLIP_X_ORIGIN ? gc->clip_x_origin : 0,
@ -995,6 +980,16 @@ gdk_win32_hdc_get (GdkDrawable *drawable,
return win32_gc->hdc; return win32_gc->hdc;
} }
/**
* gdk_win32_hdc_release:
* @drawable: destination #GdkDrawable
* @gc: #GdkGC to use for drawing on @drawable
* @usage: mask indicating what properties were set up
*
* This function deallocates the Windows device context allocated by
* <funcion>gdk_win32_hdc_get()</function>. It should be called with
* the same parameters.
**/
void void
gdk_win32_hdc_release (GdkDrawable *drawable, gdk_win32_hdc_release (GdkDrawable *drawable,
GdkGC *gc, GdkGC *gc,
@ -1032,36 +1027,26 @@ gdk_win32_hdc_release (GdkDrawable *drawable,
win32_gc->holdpal = NULL; win32_gc->holdpal = NULL;
} }
if (usage & GDK_GC_FOREGROUND) if (usage & LINE_ATTRIBUTES)
{
if ((hpen = GetCurrentObject (win32_gc->hdc, OBJ_PEN)) == NULL) if ((hpen = GetCurrentObject (win32_gc->hdc, OBJ_PEN)) == NULL)
WIN32_GDI_FAILED ("GetCurrentObject"); WIN32_GDI_FAILED ("GetCurrentObject");
if (usage & GDK_GC_FOREGROUND)
if ((hbr = GetCurrentObject (win32_gc->hdc, OBJ_BRUSH)) == NULL) if ((hbr = GetCurrentObject (win32_gc->hdc, OBJ_BRUSH)) == NULL)
WIN32_GDI_FAILED ("GetCurrentObject"); WIN32_GDI_FAILED ("GetCurrentObject");
}
if (!RestoreDC (win32_gc->hdc, win32_gc->saved_dc)) GDI_CALL (RestoreDC, (win32_gc->hdc, win32_gc->saved_dc));
WIN32_GDI_FAILED ("RestoreDC");
if (GDK_IS_PIXMAP_IMPL_WIN32 (impl)) if (GDK_IS_PIXMAP_IMPL_WIN32 (impl))
{ GDI_CALL (DeleteDC, (win32_gc->hdc));
if (!DeleteDC (win32_gc->hdc))
WIN32_GDI_FAILED ("DeleteDC");
}
else else
{ GDI_CALL (ReleaseDC, (win32_gc->hwnd, win32_gc->hdc));
if (!ReleaseDC (win32_gc->hwnd, win32_gc->hdc))
WIN32_GDI_FAILED ("ReleaseDC");
}
if (hpen != NULL) if (hpen != NULL)
if (!DeleteObject (hpen)) GDI_CALL (DeleteObject, (hpen));
WIN32_GDI_FAILED ("DeleteObject");
if (hbr != NULL) if (hbr != NULL)
if (!DeleteObject (hbr)) GDI_CALL (DeleteObject, (hbr));
WIN32_GDI_FAILED ("DeleteObject");
win32_gc->hdc = NULL; win32_gc->hdc = NULL;
} }

View File

@ -1850,7 +1850,7 @@ gdk_window_get_frame_extents (GdkWindow *window,
WIN32_API_FAILED ("GetWindowRect"); WIN32_API_FAILED ("GetWindowRect");
rect->x = r.left; rect->x = r.left;
rect->y = r.right; rect->y = r.top;
rect->width = r.right - r.left; rect->width = r.right - r.left;
rect->height = r.bottom - r.top; rect->height = r.bottom - r.top;
} }