diff options
author | Tor Lillqvist <tml@iki.fi> | 2002-11-24 23:54:01 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@src.gnome.org> | 2002-11-24 23:54:01 +0000 |
commit | 08fc500e8dae74025fcae6353c150598b663bd52 (patch) | |
tree | d92f8a1f4d15fbe0d642bc19e4f3fcbc6e89f9cf /gdk/win32/gdkgc-win32.c | |
parent | 65cce90c27fe5ed60ca467ed0ba411355ef1de4c (diff) | |
download | gtk+-08fc500e8dae74025fcae6353c150598b663bd52.tar.gz |
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)
Diffstat (limited to 'gdk/win32/gdkgc-win32.c')
-rw-r--r-- | gdk/win32/gdkgc-win32.c | 269 |
1 files changed, 127 insertions, 142 deletions
diff --git a/gdk/win32/gdkgc-win32.c b/gdk/win32/gdkgc-win32.c index e3dde1efb6..70c1ad2dae 100644 --- a/gdk/win32/gdkgc-win32.c +++ b/gdk/win32/gdkgc-win32.c @@ -25,6 +25,9 @@ * 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 "gdkgc.h" @@ -767,15 +770,12 @@ _gdk_win32_colormap_color (GdkColormap *colormap, } } -static void +static COLORREF predraw_set_foreground (GdkGC *gc, GdkColormap *colormap, gboolean *ok) { COLORREF fg; - LOGBRUSH logbrush; - HPEN hpen; - HBRUSH hbr; GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc; GdkColormapPrivateWin32 *colormap_private; gint k; @@ -800,92 +800,59 @@ predraw_set_foreground (GdkGC *gc, fg = _gdk_win32_colormap_color (colormap, win32_gc->foreground); GDK_NOTE (GC, g_print ("predraw_set_foreground: fg=%06lx\n", 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; - } + return fg; } +/** + * 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 gdk_win32_hdc_get (GdkDrawable *drawable, GdkGC *gc, @@ -894,6 +861,10 @@ gdk_win32_hdc_get (GdkDrawable *drawable, GdkGCWin32 *win32_gc = (GdkGCWin32 *) gc; GdkDrawableImplWin32 *impl = NULL; gboolean ok = TRUE; + COLORREF fg = RGB (0, 0, 0); + LOGBRUSH logbrush; + HPEN hpen; + HBRUSH hbr; g_assert (win32_gc->hdc == NULL); @@ -929,21 +900,62 @@ gdk_win32_hdc_get (GdkDrawable *drawable, } 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 && SelectObject (win32_gc->hdc, hbr) == NULL) + 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_BACKGROUND)) - predraw_set_background (gc, impl->colormap, &ok); - if (ok && (usage & GDK_GC_FONT)) { if (SetBkMode (win32_gc->hdc, TRANSPARENT) == 0) 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; } - 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) 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) 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) && OffsetClipRgn (win32_gc->hdc, 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; } +/** + * 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 gdk_win32_hdc_release (GdkDrawable *drawable, GdkGC *gc, @@ -1032,36 +1027,26 @@ gdk_win32_hdc_release (GdkDrawable *drawable, win32_gc->holdpal = NULL; } + if (usage & LINE_ATTRIBUTES) + if ((hpen = GetCurrentObject (win32_gc->hdc, OBJ_PEN)) == NULL) + WIN32_GDI_FAILED ("GetCurrentObject"); + if (usage & GDK_GC_FOREGROUND) - { - if ((hpen = GetCurrentObject (win32_gc->hdc, OBJ_PEN)) == NULL) - WIN32_GDI_FAILED ("GetCurrentObject"); - - if ((hbr = GetCurrentObject (win32_gc->hdc, OBJ_BRUSH)) == NULL) - WIN32_GDI_FAILED ("GetCurrentObject"); - } + if ((hbr = GetCurrentObject (win32_gc->hdc, OBJ_BRUSH)) == NULL) + WIN32_GDI_FAILED ("GetCurrentObject"); - if (!RestoreDC (win32_gc->hdc, win32_gc->saved_dc)) - WIN32_GDI_FAILED ("RestoreDC"); + GDI_CALL (RestoreDC, (win32_gc->hdc, win32_gc->saved_dc)); if (GDK_IS_PIXMAP_IMPL_WIN32 (impl)) - { - if (!DeleteDC (win32_gc->hdc)) - WIN32_GDI_FAILED ("DeleteDC"); - } + GDI_CALL (DeleteDC, (win32_gc->hdc)); else - { - if (!ReleaseDC (win32_gc->hwnd, win32_gc->hdc)) - WIN32_GDI_FAILED ("ReleaseDC"); - } + GDI_CALL (ReleaseDC, (win32_gc->hwnd, win32_gc->hdc)); if (hpen != NULL) - if (!DeleteObject (hpen)) - WIN32_GDI_FAILED ("DeleteObject"); + GDI_CALL (DeleteObject, (hpen)); if (hbr != NULL) - if (!DeleteObject (hbr)) - WIN32_GDI_FAILED ("DeleteObject"); + GDI_CALL (DeleteObject, (hbr)); win32_gc->hdc = NULL; } |