1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include <pango/pangowin32.h>
32 #include "gdkinternals.h"
33 #include "gdkprivate-win32.h"
35 static void gdk_win32_draw_rectangle (GdkDrawable *drawable,
42 static void gdk_win32_draw_arc (GdkDrawable *drawable,
51 static void gdk_win32_draw_polygon (GdkDrawable *drawable,
56 static void gdk_win32_draw_text (GdkDrawable *drawable,
63 static void gdk_win32_draw_text_wc (GdkDrawable *drawable,
70 static void gdk_win32_draw_drawable (GdkDrawable *drawable,
79 static void gdk_win32_draw_points (GdkDrawable *drawable,
83 static void gdk_win32_draw_segments (GdkDrawable *drawable,
87 static void gdk_win32_draw_lines (GdkDrawable *drawable,
91 static void gdk_win32_draw_glyphs (GdkDrawable *drawable,
96 PangoGlyphString *glyphs);
97 static void gdk_win32_draw_image (GdkDrawable *drawable,
107 static void gdk_win32_set_colormap (GdkDrawable *drawable,
108 GdkColormap *colormap);
110 static GdkColormap* gdk_win32_get_colormap (GdkDrawable *drawable);
112 static gint gdk_win32_get_depth (GdkDrawable *drawable);
114 static void gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass);
116 static gpointer parent_class = NULL;
119 gdk_drawable_impl_win32_get_type (void)
121 static GType object_type = 0;
125 static const GTypeInfo object_info =
127 sizeof (GdkDrawableImplWin32Class),
128 (GBaseInitFunc) NULL,
129 (GBaseFinalizeFunc) NULL,
130 (GClassInitFunc) gdk_drawable_impl_win32_class_init,
131 NULL, /* class_finalize */
132 NULL, /* class_data */
133 sizeof (GdkDrawableImplWin32),
135 (GInstanceInitFunc) NULL,
138 object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
139 "GdkDrawableImplWin32",
147 gdk_drawable_impl_win32_class_init (GdkDrawableImplWin32Class *klass)
149 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
151 parent_class = g_type_class_peek_parent (klass);
153 drawable_class->create_gc = _gdk_win32_gc_new;
154 drawable_class->draw_rectangle = gdk_win32_draw_rectangle;
155 drawable_class->draw_arc = gdk_win32_draw_arc;
156 drawable_class->draw_polygon = gdk_win32_draw_polygon;
157 drawable_class->draw_text = gdk_win32_draw_text;
158 drawable_class->draw_text_wc = gdk_win32_draw_text_wc;
159 drawable_class->draw_drawable = gdk_win32_draw_drawable;
160 drawable_class->draw_points = gdk_win32_draw_points;
161 drawable_class->draw_segments = gdk_win32_draw_segments;
162 drawable_class->draw_lines = gdk_win32_draw_lines;
163 drawable_class->draw_glyphs = gdk_win32_draw_glyphs;
164 drawable_class->draw_image = gdk_win32_draw_image;
166 drawable_class->set_colormap = gdk_win32_set_colormap;
167 drawable_class->get_colormap = gdk_win32_get_colormap;
169 drawable_class->get_depth = gdk_win32_get_depth;
172 /*****************************************************
173 * Win32 specific implementations of generic functions *
174 *****************************************************/
177 gdk_win32_get_colormap (GdkDrawable *drawable)
179 GdkDrawableImplWin32 *impl;
181 return impl->colormap;
185 gdk_win32_set_colormap (GdkDrawable *drawable,
186 GdkColormap *colormap)
188 GdkDrawableImplWin32 *impl;
190 g_return_if_fail (colormap != NULL);
192 impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
194 if (impl->colormap == colormap)
198 gdk_colormap_unref (impl->colormap);
199 impl->colormap = colormap;
201 gdk_colormap_ref (impl->colormap);
208 gdk_win32_draw_rectangle (GdkDrawable *drawable,
216 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
217 const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
219 HGDIOBJ oldpen, oldbrush;
224 GDK_NOTE (MISC, g_print ("gdk_win32_draw_rectangle: %#x (%d) %s%dx%d@+%d+%d\n",
225 GDK_DRAWABLE_HANDLE (drawable),
227 (filled ? "fill " : ""),
228 width, height, x, y));
230 hdc = gdk_win32_hdc_get (drawable, gc, mask);
234 HBRUSH hbr = GetCurrentObject (hdc, OBJ_BRUSH);
235 HPEN hpen = GetCurrentObject (hdc, OBJ_PEN);
238 GetObject (hbr, sizeof (lbr), &lbr);
239 GetObject (hpen, sizeof (lpen), &lpen);
241 g_print ("current brush: style = %s, color = 0x%.08x\n",
242 (lbr.lbStyle == BS_SOLID ? "SOLID" : "???"),
244 g_print ("current pen: style = %s, width = %d, color = 0x%.08x\n",
245 (lpen.lopnStyle == PS_SOLID ? "SOLID" : "???"),
251 if (gc_private->fill_style == GDK_OPAQUE_STIPPLED)
253 if (!BeginPath (hdc))
254 WIN32_GDI_FAILED ("BeginPath"), ok = FALSE;
256 /* Win9x doesn't support Rectangle calls in a path,
262 pts[1].x = x + width + 1;
264 pts[2].x = x + width + 1;
265 pts[2].y = y + height + 1;
267 pts[3].y = y + height + 1;
270 MoveToEx (hdc, x, y, NULL);
272 if (ok && !Polyline (hdc, pts, 4))
273 WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
275 if (ok && !CloseFigure (hdc))
276 WIN32_GDI_FAILED ("CloseFigure"), ok = FALSE;
278 if (ok && !EndPath (hdc))
279 WIN32_GDI_FAILED ("EndPath"), ok = FALSE;
282 if (!WidenPath (hdc))
283 WIN32_GDI_FAILED ("WidenPath"), ok = FALSE;
285 if (ok && !FillPath (hdc))
286 WIN32_GDI_FAILED ("FillPath"), ok = FALSE;
289 if (!DeleteObject (hbr))
290 WIN32_GDI_FAILED ("DeleteObject");
295 oldpen = SelectObject (hdc, GetStockObject (NULL_PEN));
297 oldbrush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
299 if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
300 WIN32_GDI_FAILED ("Rectangle");
303 SelectObject (hdc, oldpen);
305 SelectObject (hdc, oldbrush);
308 gdk_win32_hdc_release (drawable, gc, mask);
312 gdk_win32_draw_arc (GdkDrawable *drawable,
322 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
323 const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
325 int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
327 GDK_NOTE (MISC, g_print ("gdk_draw_arc: %#x %d,%d,%d,%d %d %d\n",
328 GDK_DRAWABLE_HANDLE (drawable),
329 x, y, width, height, angle1, angle2));
331 /* Seems that drawing arcs with width or height <= 2 fails, at least
334 if (width <= 2 || height <= 2 || angle2 == 0)
337 hdc = gdk_win32_hdc_get (drawable, gc, mask);
339 if (angle2 >= 360*64)
341 nXStartArc = nYStartArc = nXEndArc = nYEndArc = 0;
345 /* The 100. is just an arbitrary value */
346 nXStartArc = x + width/2 + 100. * cos(angle1/64.*2.*G_PI/360.);
347 nYStartArc = y + height/2 + -100. * sin(angle1/64.*2.*G_PI/360.);
348 nXEndArc = x + width/2 + 100. * cos((angle1+angle2)/64.*2.*G_PI/360.);
349 nYEndArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
353 nXEndArc = x + width/2 + 100. * cos(angle1/64.*2.*G_PI/360.);
354 nYEndArc = y + height/2 + -100. * sin(angle1/64.*2.*G_PI/360.);
355 nXStartArc = x + width/2 + 100. * cos((angle1+angle2)/64.*2.*G_PI/360.);
356 nYStartArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
359 /* GDK_OPAQUE_STIPPLED arcs not implemented. */
363 GDK_NOTE (MISC, g_print ("...Pie(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
364 x, y, x+width, y+height,
365 nXStartArc, nYStartArc,
366 nXEndArc, nYEndArc));
367 if (!Pie (hdc, x, y, x+width, y+height,
368 nXStartArc, nYStartArc, nXEndArc, nYEndArc))
369 WIN32_GDI_FAILED ("Pie");
373 GDK_NOTE (MISC, g_print ("...Arc(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
374 x, y, x+width, y+height,
375 nXStartArc, nYStartArc,
376 nXEndArc, nYEndArc));
377 if (!Arc (hdc, x, y, x+width, y+height,
378 nXStartArc, nYStartArc, nXEndArc, nYEndArc))
379 WIN32_GDI_FAILED ("Arc");
381 gdk_win32_hdc_release (drawable, gc, mask);
385 gdk_win32_draw_polygon (GdkDrawable *drawable,
391 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
392 const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
399 GDK_NOTE (MISC, g_print ("gdk_win32_draw_polygon: %#x (%d) %d\n",
400 GDK_DRAWABLE_HANDLE (drawable), gc_private,
406 hdc = gdk_win32_hdc_get (drawable, gc, mask);
407 pts = g_new (POINT, npoints+1);
409 for (i = 0; i < npoints; i++)
411 pts[i].x = points[i].x;
412 pts[i].y = points[i].y;
415 if (gc_private->fill_style == GDK_OPAQUE_STIPPLED)
417 if (!BeginPath (hdc))
418 WIN32_GDI_FAILED ("BeginPath"), ok = FALSE;
421 MoveToEx (hdc, points[0].x, points[0].y, NULL);
423 if (pts[0].x == pts[npoints-1].x && pts[0].y == pts[npoints-1].y)
426 if (ok && !Polyline (hdc, pts, 4))
427 WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
429 if (ok && !CloseFigure (hdc))
430 WIN32_GDI_FAILED ("CloseFigure"), ok = FALSE;
432 if (ok && !EndPath (hdc))
433 WIN32_GDI_FAILED ("EndPath"), ok = FALSE;
436 if (!WidenPath (hdc))
437 WIN32_GDI_FAILED ("WidenPath"), ok = FALSE;
439 if (ok && !FillPath (hdc))
440 WIN32_GDI_FAILED ("FillPath"), ok = FALSE;
443 if (!DeleteObject (hbr))
444 WIN32_GDI_FAILED ("DeleteObject");
448 if (points[0].x != points[npoints-1].x
449 || points[0].y != points[npoints-1].y)
451 pts[npoints].x = points[0].x;
452 pts[npoints].y = points[0].y;
458 if (!Polygon (hdc, pts, npoints))
459 WIN32_GDI_FAILED ("Polygon");
463 if (!Polyline (hdc, pts, npoints))
464 WIN32_GDI_FAILED ("Polyline");
468 gdk_win32_hdc_release (drawable, gc, mask);
478 gdk_draw_text_handler (GdkWin32SingleFont *singlefont,
479 const wchar_t *wcstr,
485 gdk_draw_text_arg *argp = (gdk_draw_text_arg *) arg;
490 if ((oldfont = SelectObject (argp->hdc, singlefont->hfont)) == NULL)
492 WIN32_GDI_FAILED ("SelectObject");
496 if (!TextOutW (argp->hdc, argp->x, argp->y, wcstr, wclen))
497 WIN32_GDI_FAILED ("TextOutW");
498 GetTextExtentPoint32W (argp->hdc, wcstr, wclen, &size);
501 SelectObject (argp->hdc, oldfont);
505 gdk_win32_draw_text (GdkDrawable *drawable,
513 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
514 const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_FONT;
517 gdk_draw_text_arg arg;
519 if (text_length == 0)
522 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
526 arg.hdc = gdk_win32_hdc_get (drawable, gc, mask);
528 GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d,%d) \"%.*s\" (len %d)\n",
529 GDK_DRAWABLE_HANDLE (drawable),
531 (text_length > 10 ? 10 : text_length),
534 if (text_length == 1)
536 /* For single characters, don't try to interpret as UTF-8. */
537 wc = (guchar) text[0];
538 gdk_wchar_text_handle (font, &wc, 1, gdk_draw_text_handler, &arg);
542 wcstr = g_new (wchar_t, text_length);
543 if ((wlen = gdk_nmbstowchar_ts (wcstr, text, text_length, text_length)) == -1)
544 g_warning ("gdk_win32_draw_text: gdk_nmbstowchar_ts failed");
546 gdk_wchar_text_handle (font, wcstr, wlen, gdk_draw_text_handler, &arg);
551 gdk_win32_hdc_release (drawable, gc, mask);
555 gdk_win32_draw_text_wc (GdkDrawable *drawable,
560 const GdkWChar *text,
563 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
564 const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_FONT;
567 gdk_draw_text_arg arg;
569 if (text_length == 0)
572 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
576 arg.hdc = gdk_win32_hdc_get (drawable, gc, mask);
578 GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d,%d) len: %d\n",
579 GDK_DRAWABLE_HANDLE (drawable),
582 if (sizeof (wchar_t) != sizeof (GdkWChar))
584 wcstr = g_new (wchar_t, text_length);
585 for (i = 0; i < text_length; i++)
589 wcstr = (wchar_t *) text;
591 gdk_wchar_text_handle (font, wcstr, text_length,
592 gdk_draw_text_handler, &arg);
594 if (sizeof (wchar_t) != sizeof (GdkWChar))
597 gdk_win32_hdc_release (drawable, gc, mask);
601 gdk_win32_draw_drawable (GdkDrawable *drawable,
611 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
612 GdkDrawableImplWin32 *src_impl = GDK_DRAWABLE_IMPL_WIN32 (src);
616 HRGN src_rgn, draw_rgn, outside_rgn;
618 gint src_width, src_height;
621 GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x @+%d+%d"
622 "src: %#x %dx%d@+%d+%d\n",
623 GDK_DRAWABLE_HANDLE (drawable), xdest, ydest,
624 GDK_PIXMAP_HBITMAP (src),
625 width, height, xsrc, ysrc));
627 hdc = gdk_win32_hdc_get (drawable, gc, 0);
629 gdk_drawable_get_size (src, &src_width, &src_height);
630 src_rgn = CreateRectRgn (0, 0, src_width + 1, src_height + 1);
631 draw_rgn = CreateRectRgn (xsrc, ysrc, xsrc + width + 1, ysrc + height + 1);
633 if (GDK_IS_WINDOW (drawable))
635 /* If we are drawing on a window, calculate the region that is
636 * outside the source pixmap, and invalidate that, causing it to
640 outside_rgn = CreateRectRgnIndirect (&r);
641 if (CombineRgn (outside_rgn, draw_rgn, src_rgn, RGN_DIFF) != NULLREGION)
643 OffsetRgn (outside_rgn, xdest, ydest);
644 GDK_NOTE (MISC, (GetRgnBox (outside_rgn, &r),
645 g_print ("...calling InvalidateRgn, "
646 "bbox: %dx%d@+%d+%d\n",
647 r.right - r.left - 1, r.bottom - r.top - 1,
649 InvalidateRgn (GDK_DRAWABLE_HANDLE (drawable), outside_rgn, TRUE);
651 DeleteObject (outside_rgn);
654 #if 1 /* Don't know if this is necessary */
655 if (CombineRgn (draw_rgn, draw_rgn, src_rgn, RGN_AND) == COMPLEXREGION)
656 g_warning ("gdk_win32_draw_drawable: CombineRgn returned a COMPLEXREGION");
658 GetRgnBox (draw_rgn, &r);
661 || r.right != xsrc + width + 1
662 || r.bottom != ysrc + height + 1)
664 xdest += r.left - xsrc;
666 ydest += r.top - ysrc;
668 width = r.right - xsrc - 1;
669 height = r.bottom - ysrc - 1;
671 GDK_NOTE (MISC, g_print ("... restricted to src: %dx%d@+%d+%d, "
673 width, height, xsrc, ysrc,
678 DeleteObject (src_rgn);
679 DeleteObject (draw_rgn);
681 /* This function is called also to bitblt from a window.
683 if (GDK_IS_PIXMAP (src))
685 if ((srcdc = CreateCompatibleDC (hdc)) == NULL)
686 WIN32_GDI_FAILED ("CreateCompatibleDC"), ok = FALSE;
688 if (ok && (hgdiobj = SelectObject (srcdc, GDK_PIXMAP_HBITMAP (src))) == NULL)
689 WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
691 if (ok && !BitBlt (hdc, xdest, ydest, width, height,
692 srcdc, xsrc, ysrc, SRCCOPY))
693 WIN32_GDI_FAILED ("BitBlt");
695 if (ok && (SelectObject (srcdc, hgdiobj) == NULL))
696 WIN32_GDI_FAILED ("SelectObject");
698 if (srcdc != NULL && !DeleteDC (srcdc))
699 WIN32_GDI_FAILED ("DeleteDC");
701 else if (GDK_DRAWABLE_HANDLE (drawable) == GDK_DRAWABLE_HANDLE (src))
703 /* Blitting inside a window, use ScrollDC */
704 RECT scrollRect, clipRect, emptyRect;
707 scrollRect.left = MIN (xsrc, xdest);
708 scrollRect.top = MIN (ysrc, ydest);
709 scrollRect.right = MAX (xsrc + width + 1, xdest + width + 1);
710 scrollRect.bottom = MAX (ysrc + height + 1, ydest + height + 1);
712 clipRect.left = xdest;
713 clipRect.top = ydest;
714 clipRect.right = xdest + width + 1;
715 clipRect.bottom = ydest + height + 1;
717 SetRectEmpty (&emptyRect);
718 updateRgn = CreateRectRgnIndirect (&emptyRect);
719 if (!ScrollDC (hdc, xdest - xsrc, ydest - ysrc,
720 &scrollRect, &clipRect,
722 WIN32_GDI_FAILED ("ScrollDC"), ok = FALSE;
723 if (ok && !InvalidateRgn (GDK_WINDOW_HWND (drawable), updateRgn, FALSE))
724 WIN32_GDI_FAILED ("InvalidateRgn"), ok = FALSE;
725 if (ok && !UpdateWindow (GDK_WINDOW_HWND (drawable)))
726 WIN32_GDI_FAILED ("UpdateWindow");
727 DeleteObject (updateRgn);
731 if ((srcdc = GetDC (GDK_WINDOW_HWND (src))) == NULL)
732 WIN32_GDI_FAILED ("GetDC"), ok = FALSE;
734 if (ok && !BitBlt (hdc, xdest, ydest, width, height,
735 srcdc, xsrc, ysrc, SRCCOPY))
736 WIN32_GDI_FAILED ("BitBlt");
737 ReleaseDC (GDK_WINDOW_HWND (src), srcdc);
739 gdk_win32_hdc_release (drawable, gc, 0);
743 gdk_win32_draw_points (GdkDrawable *drawable,
750 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
751 GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
754 hdc = gdk_win32_hdc_get (drawable, gc, 0);
756 fg = gdk_colormap_color (impl->colormap, gc_private->foreground);
758 GDK_NOTE (MISC, g_print ("gdk_draw_points: %#x %dx%.06x\n",
759 GDK_DRAWABLE_HANDLE (drawable), npoints, fg));
761 for (i = 0; i < npoints; i++)
762 SetPixel (hdc, points[i].x, points[i].y, fg);
764 gdk_win32_hdc_release (drawable, gc, 0);
768 gdk_win32_draw_segments (GdkDrawable *drawable,
773 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
774 const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
780 GDK_NOTE (MISC, g_print ("gdk_win32_draw_segments: %#x nsegs: %d\n",
781 GDK_DRAWABLE_HANDLE (drawable), nsegs));
783 hdc = gdk_win32_hdc_get (drawable, gc, mask);
785 if (gc_private->fill_style == GDK_OPAQUE_STIPPLED)
787 if (!BeginPath (hdc))
788 WIN32_GDI_FAILED ("BeginPath"), ok = FALSE;
790 for (i = 0; ok && i < nsegs; i++)
792 if (ok && !MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
793 WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
794 if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
795 WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
798 if (ok && gc_private->pen_width <= 1)
799 if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
800 WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
803 if (ok && !EndPath (hdc))
804 WIN32_GDI_FAILED ("EndPath"), ok = FALSE;
806 if (ok && !WidenPath (hdc))
807 WIN32_GDI_FAILED ("WidenPath"), ok = FALSE;
809 if (ok && !FillPath (hdc))
810 WIN32_GDI_FAILED ("FillPath"), ok = FALSE;
813 if (!DeleteObject (hbr))
814 WIN32_GDI_FAILED ("DeleteObject");
818 for (i = 0; ok && i < nsegs; i++)
820 if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
821 WIN32_GDI_FAILED ("MoveToEx"), ok = FALSE;
822 if (ok && !LineTo (hdc, segs[i].x2, segs[i].y2))
823 WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
826 if (ok && gc_private->pen_width <= 1)
827 if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
828 WIN32_GDI_FAILED ("LineTo"), ok = FALSE;
831 gdk_win32_hdc_release (drawable, gc, mask);
835 gdk_win32_draw_lines (GdkDrawable *drawable,
840 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
841 const GdkGCValuesMask mask = GDK_GC_FOREGROUND|GDK_GC_BACKGROUND;
850 hdc = gdk_win32_hdc_get (drawable, gc, mask);
852 pts = g_new (POINT, npoints);
854 for (i = 0; i < npoints; i++)
856 pts[i].x = points[i].x;
857 pts[i].y = points[i].y;
860 if (!Polyline (hdc, pts, npoints))
861 WIN32_GDI_FAILED ("Polyline"), ok = FALSE;
866 if (ok && gc_private->pen_width <= 1)
868 MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
869 if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
870 WIN32_GDI_FAILED ("LineTo");
872 gdk_win32_hdc_release (drawable, gc, mask);
876 gdk_win32_draw_glyphs (GdkDrawable *drawable,
881 PangoGlyphString *glyphs)
883 GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
884 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
885 const GdkGCValuesMask mask = GDK_GC_FOREGROUND;
888 hdc = gdk_win32_hdc_get (drawable, gc, mask);
890 pango_win32_render (hdc, font, glyphs, x, y);
892 gdk_win32_hdc_release (drawable, gc, mask);
896 gdk_win32_draw_image (GdkDrawable *drawable,
906 GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
907 GdkGCWin32 *gc_private = GDK_GC_WIN32 (gc);
908 GdkImagePrivateWin32 *image_private = (GdkImagePrivateWin32 *) image;
909 GdkColormapPrivateWin32 *colormap_private = (GdkColormapPrivateWin32 *) impl->colormap;
914 BITMAPINFOHEADER bmiHeader;
915 WORD bmiIndices[256];
917 static gboolean bmi_inited = FALSE;
921 hdc = gdk_win32_hdc_get (drawable, gc, 0);
923 if (colormap_private && colormap_private->xcolormap->rc_palette)
927 for (i = 0; i < 256; i++)
928 bmi.bmiIndices[i] = i;
932 if (GetObject (image_private->hbitmap, sizeof (DIBSECTION),
933 &ds) != sizeof (DIBSECTION))
934 WIN32_GDI_FAILED ("GetObject"), ok = FALSE;
936 g_print("xdest = %d, ydest = %d, xsrc = %d, ysrc = %d, width = %d, height = %d\n",
937 xdest, ydest, xsrc, ysrc, width, height);
938 g_print("bmWidth = %d, bmHeight = %d, bmBitsPixel = %d, bmBits = %p\n",
939 ds.dsBm.bmWidth, ds.dsBm.bmHeight, ds.dsBm.bmBitsPixel, ds.dsBm.bmBits);
940 g_print("biWidth = %d, biHeight = %d, biBitCount = %d, biClrUsed = %d\n",
941 ds.dsBmih.biWidth, ds.dsBmih.biHeight, ds.dsBmih.biBitCount, ds.dsBmih.biClrUsed);
943 bmi.bmiHeader = ds.dsBmih;
944 /* I have spent hours on getting the parameters to
945 * SetDIBitsToDevice right. I wonder what drugs the guys in
946 * Redmond were on when they designed this API.
948 if (ok && SetDIBitsToDevice (hdc,
951 xsrc, (-ds.dsBmih.biHeight)-height-ysrc,
952 0, -ds.dsBmih.biHeight,
954 (CONST BITMAPINFO *) &bmi,
955 DIB_PAL_COLORS) == 0)
956 WIN32_GDI_FAILED ("SetDIBitsToDevice");
961 if ((memdc = CreateCompatibleDC (hdc)) == NULL)
962 WIN32_GDI_FAILED ("CreateCompatibleDC"), ok = FALSE;
964 if (ok && (oldbitmap = SelectObject (memdc, image_private->hbitmap)) == NULL)
965 WIN32_GDI_FAILED ("SelectObject"), ok = FALSE;
967 if (ok && !BitBlt (hdc, xdest, ydest, width, height,
968 memdc, xsrc, ysrc, SRCCOPY))
969 WIN32_GDI_FAILED ("BitBlt");
971 if (oldbitmap != NULL && SelectObject (memdc, oldbitmap) == NULL)
972 WIN32_GDI_FAILED ("SelectObject");
974 if (memdc != NULL && !DeleteDC (memdc))
975 WIN32_GDI_FAILED ("DeleteDC");
977 gdk_win32_hdc_release (drawable, gc, 0);
981 gdk_win32_get_depth (GdkDrawable *drawable)
983 /* This is a bit bogus but I'm not sure the other way is better */
985 return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_WIN32 (drawable)->wrapper);