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 Library 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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library 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-1999. 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/.
31 #include "gdkdrawable.h"
32 #include "gdkprivate.h"
33 #include "gdkwindow.h"
37 #define G_PI 3.14159265358979323846
40 /* Manipulation of drawables
43 gdk_drawable_set_data (GdkDrawable *drawable,
46 GDestroyNotify destroy_func)
48 g_dataset_set_data_full (drawable, key, data, destroy_func);
52 gdk_drawable_get_data (GdkDrawable *drawable,
55 g_dataset_get_data (drawable, key);
59 gdk_drawable_get_type (GdkDrawable *drawable)
61 g_return_val_if_fail (drawable != NULL, (GdkDrawableType) -1);
63 return GDK_DRAWABLE_TYPE (drawable);
67 gdk_drawable_get_size (GdkDrawable *drawable,
71 GdkDrawablePrivate *drawable_private;
73 g_return_if_fail (drawable != NULL);
75 drawable_private = (GdkDrawablePrivate*) drawable;
78 *width = drawable_private->width;
80 *height = drawable_private->height;
84 gdk_drawable_set_colormap (GdkDrawable *drawable,
85 GdkColormap *colormap)
87 GdkDrawablePrivate *drawable_private;
88 GdkColormapPrivate *colormap_private;
90 g_return_if_fail (drawable != NULL);
91 g_return_if_fail (colormap != NULL);
93 drawable_private = (GdkDrawablePrivate*) drawable;
94 colormap_private = (GdkColormapPrivate*) colormap;
96 if (!GDK_DRAWABLE_DESTROYED (drawable))
98 if (GDK_IS_WINDOW (drawable))
100 g_return_if_fail (colormap_private->visual !=
101 ((GdkColormapPrivate*)(drawable_private->colormap))->visual);
103 GDK_NOTE (MISC, g_print ("gdk_drawable_set_colormap: %#x %#x\n",
104 GDK_DRAWABLE_XID (drawable),
105 colormap_private->xcolormap));
107 if (drawable_private->colormap)
108 gdk_colormap_unref (drawable_private->colormap);
109 drawable_private->colormap = colormap;
110 gdk_colormap_ref (drawable_private->colormap);
112 if (GDK_IS_WINDOW (drawable) &&
113 drawable_private->window_type != GDK_WINDOW_TOPLEVEL)
114 gdk_window_add_colormap_windows (drawable);
119 gdk_drawable_get_colormap (GdkDrawable *drawable)
121 GdkDrawablePrivate *drawable_private;
123 g_return_val_if_fail (drawable != NULL, NULL);
124 drawable_private = (GdkDrawablePrivate*) drawable;
126 if (!GDK_DRAWABLE_DESTROYED (drawable))
128 if (drawable_private->colormap == NULL)
129 return gdk_colormap_get_system (); /* XXX ??? */
131 return drawable_private->colormap;
138 gdk_drawable_get_visual (GdkDrawable *drawable)
140 GdkColormap *colormap;
142 g_return_val_if_fail (drawable != NULL, NULL);
144 colormap = gdk_drawable_get_colormap (drawable);
145 return colormap ? gdk_colormap_get_visual (colormap) : NULL;
149 gdk_draw_point (GdkDrawable *drawable,
154 GdkDrawablePrivate *drawable_private;
155 GdkGCPrivate *gc_private;
158 g_return_if_fail (drawable != NULL);
159 g_return_if_fail (gc != NULL);
161 if (GDK_DRAWABLE_DESTROYED (drawable))
163 drawable_private = (GdkDrawablePrivate*) drawable;
164 gc_private = (GdkGCPrivate*) gc;
166 hdc = gdk_gc_predraw (drawable_private, gc_private);
168 /* We use LineTo because SetPixel wants the COLORREF directly,
169 * and doesn't use the current pen, which is what we want.
171 if (!MoveToEx (hdc, x, y, NULL))
172 g_warning ("gdk_draw_point: MoveToEx failed");
173 if (!LineTo (hdc, x + 1, y))
174 g_warning ("gdk_draw_point: LineTo failed");
176 gdk_gc_postdraw (drawable_private, gc_private);
180 gdk_draw_line (GdkDrawable *drawable,
187 GdkDrawablePrivate *drawable_private;
188 GdkGCPrivate *gc_private;
191 g_return_if_fail (drawable != NULL);
192 g_return_if_fail (gc != NULL);
194 if (GDK_DRAWABLE_DESTROYED (drawable))
196 drawable_private = (GdkDrawablePrivate*) drawable;
197 gc_private = (GdkGCPrivate*) gc;
199 hdc = gdk_gc_predraw (drawable_private, gc_private);
201 GDK_NOTE (MISC, g_print ("gdk_draw_line: %#x (%d) +%d+%d..+%d+%d\n",
202 drawable_private->xwindow, gc_private,
205 MoveToEx (hdc, x1, y1, NULL);
206 if (!LineTo (hdc, x2, y2))
207 g_warning ("gdk_draw_line: LineTo #1 failed");
208 /* LineTo doesn't draw the last point, so if we have a pen width of 1,
209 * we draw the end pixel separately... With wider pens we don't care.
210 * //HB: But the NT developers don't read their API documentation ...
212 if (gc_private->pen_width == 1
213 && GetVersion () > 0x80000000)
214 if (!LineTo (hdc, x2 + 1, y2))
215 g_warning ("gdk_draw_line: LineTo #2 failed");
216 gdk_gc_postdraw (drawable_private, gc_private);
220 gdk_draw_rectangle (GdkDrawable *drawable,
228 GdkDrawablePrivate *drawable_private;
229 GdkGCPrivate *gc_private;
231 HGDIOBJ oldpen, oldbrush;
233 g_return_if_fail (drawable != NULL);
234 g_return_if_fail (gc != NULL);
236 if (GDK_DRAWABLE_DESTROYED (drawable))
238 drawable_private = (GdkDrawablePrivate*) drawable;
239 gc_private = (GdkGCPrivate*) gc;
242 width = drawable_private->width;
244 height = drawable_private->height;
246 hdc = gdk_gc_predraw (drawable_private, gc_private);
248 GDK_NOTE (MISC, g_print ("gdk_draw_rectangle: %#x (%d) %s%dx%d@+%d+%d\n",
249 drawable_private->xwindow,
251 (filled ? "fill " : ""),
252 width, height, x, y));
256 HBRUSH hbr = GetCurrentObject (hdc, OBJ_BRUSH);
257 HPEN hpen = GetCurrentObject (hdc, OBJ_PEN);
260 GetObject (hbr, sizeof (lbr), &lbr);
261 GetObject (hpen, sizeof (lpen), &lpen);
263 g_print ("current brush: style = %s, color = 0x%.08x\n",
264 (lbr.lbStyle == BS_SOLID ? "SOLID" : "???"),
266 g_print ("current pen: style = %s, width = %d, color = 0x%.08x\n",
267 (lpen.lopnStyle == PS_SOLID ? "SOLID" : "???"),
274 oldpen = SelectObject (hdc, GetStockObject (NULL_PEN));
276 oldbrush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
278 if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
279 g_warning ("gdk_draw_rectangle: Rectangle failed");
282 SelectObject (hdc, oldpen);
284 SelectObject (hdc, oldbrush);
286 gdk_gc_postdraw (drawable_private, gc_private);
290 gdk_draw_arc (GdkDrawable *drawable,
300 GdkDrawablePrivate *drawable_private;
301 GdkGCPrivate *gc_private;
303 int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
305 g_return_if_fail (drawable != NULL);
306 g_return_if_fail (gc != NULL);
308 if (GDK_DRAWABLE_DESTROYED (drawable))
310 drawable_private = (GdkDrawablePrivate*) drawable;
311 gc_private = (GdkGCPrivate*) gc;
314 width = drawable_private->width;
316 height = drawable_private->height;
318 GDK_NOTE (MISC, g_print ("gdk_draw_arc: %#x %d,%d,%d,%d %d %d\n",
319 drawable_private->xwindow,
320 x, y, width, height, angle1, angle2));
322 if (width != 0 && height != 0 && angle2 != 0)
324 hdc = gdk_gc_predraw (drawable_private, gc_private);
326 if (angle2 >= 360*64)
328 nXStartArc = nYStartArc = nXEndArc = nYEndArc = 0;
332 /* The 100. is just an arbitrary value */
333 nXStartArc = x + width/2 + 100. * cos(angle1/64.*2.*G_PI/360.);
334 nYStartArc = y + height/2 + -100. * sin(angle1/64.*2.*G_PI/360.);
335 nXEndArc = x + width/2 + 100. * cos((angle1+angle2)/64.*2.*G_PI/360.);
336 nYEndArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
340 nXEndArc = x + width/2 + 100. * cos(angle1/64.*2.*G_PI/360.);
341 nYEndArc = y + height/2 + -100. * sin(angle1/64.*2.*G_PI/360.);
342 nXStartArc = x + width/2 + 100. * cos((angle1+angle2)/64.*2.*G_PI/360.);
343 nYStartArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
348 GDK_NOTE (MISC, g_print ("...Pie(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
349 x, y, x+width, y+height,
350 nXStartArc, nYStartArc,
351 nXEndArc, nYEndArc));
352 Pie (hdc, x, y, x+width, y+height,
353 nXStartArc, nYStartArc, nXEndArc, nYEndArc);
357 GDK_NOTE (MISC, g_print ("...Arc(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
358 x, y, x+width, y+height,
359 nXStartArc, nYStartArc,
360 nXEndArc, nYEndArc));
361 Arc (hdc, x, y, x+width, y+height,
362 nXStartArc, nYStartArc, nXEndArc, nYEndArc);
364 gdk_gc_postdraw (drawable_private, gc_private);
369 gdk_draw_polygon (GdkDrawable *drawable,
375 GdkDrawablePrivate *drawable_private;
376 GdkGCPrivate *gc_private;
381 g_return_if_fail (drawable != NULL);
382 g_return_if_fail (gc != NULL);
384 if (GDK_DRAWABLE_DESTROYED (drawable))
386 drawable_private = (GdkDrawablePrivate*) drawable;
387 gc_private = (GdkGCPrivate*) gc;
389 GDK_NOTE (MISC, g_print ("gdk_draw_polygon: %#x (%d) %d\n",
390 drawable_private->xwindow, gc_private,
396 hdc = gdk_gc_predraw (drawable_private, gc_private);
397 pts = g_malloc ((npoints+1) * sizeof (POINT));
399 for (i = 0; i < npoints; i++)
401 pts[i].x = points[i].x;
402 pts[i].y = points[i].y;
405 if ((points[0].x != points[npoints-1].x) ||
406 (points[0].y != points[npoints-1].y))
408 pts[npoints].x = points[0].x;
409 pts[npoints].y = points[0].y;
414 if (!Polygon (hdc, pts, npoints))
415 g_warning ("gdk_draw_polygon: Polygon failed");
419 if (!Polyline (hdc, pts, npoints))
420 g_warning ("gdk_draw_polygon: Polyline failed");
423 gdk_gc_postdraw (drawable_private, gc_private);
429 gdk_draw_string (GdkDrawable *drawable,
436 gdk_draw_text (drawable, font, gc, x, y, string, strlen (string));
441 * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
444 gdk_draw_text (GdkDrawable *drawable,
452 GdkDrawablePrivate *drawable_private;
453 GdkFontPrivate *font_private;
454 GdkGCPrivate *gc_private;
461 g_return_if_fail (drawable != NULL);
462 g_return_if_fail (font != NULL);
463 g_return_if_fail (gc != NULL);
464 g_return_if_fail (text != NULL);
466 if (GDK_DRAWABLE_DESTROYED (drawable))
469 if (text_length == 0)
472 drawable_private = (GdkDrawablePrivate*) drawable;
473 gc_private = (GdkGCPrivate*) gc;
474 font_private = (GdkFontPrivate*) font;
476 if (font->type == GDK_FONT_FONT)
478 hdc = gdk_gc_predraw (drawable_private, gc_private);
479 xfont = (HFONT) font_private->xfont;
481 GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
482 "+%d+%d font: %#x \"%.*s\" length: %d\n",
483 drawable_private->xwindow,
484 gc_private, gc_private->xgc,
486 (text_length > 10 ? 10 : text_length),
489 if ((oldfont = SelectObject (hdc, xfont)) == NULL)
490 g_warning ("gdk_draw_text: SelectObject failed");
491 if (font_private->cpinfo.MaxCharSize > 1)
493 wcstr = g_new (wchar_t, text_length);
494 if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
496 wcstr, text_length)) == 0)
497 g_warning ("gdk_draw_text: MultiByteToWideChar failed");
498 else if (!TextOutW (hdc, x, y, wcstr, wlen))
499 g_warning ("gdk_draw_text: TextOutW failed");
504 if (!TextOutA (hdc, x, y, text, text_length))
505 g_warning ("gdk_draw_text: TextOutA failed");
508 SelectObject (hdc, oldfont);
509 gdk_gc_postdraw (drawable_private, gc_private);
512 g_error ("undefined font type");
516 gdk_draw_text_wc (GdkDrawable *drawable,
521 const GdkWChar *text,
524 GdkDrawablePrivate *drawable_private;
525 GdkFontPrivate *font_private;
526 GdkGCPrivate *gc_private;
531 g_return_if_fail (drawable != NULL);
532 g_return_if_fail (font != NULL);
533 g_return_if_fail (gc != NULL);
534 g_return_if_fail (text != NULL);
536 if (GDK_DRAWABLE_DESTROYED (drawable))
539 if (text_length == 0)
542 drawable_private = (GdkDrawablePrivate*) drawable;
543 gc_private = (GdkGCPrivate*) gc;
544 font_private = (GdkFontPrivate*) font;
546 if (font->type == GDK_FONT_FONT)
552 hdc = gdk_gc_predraw (drawable_private, gc_private);
553 xfont = (HFONT) font_private->xfont;
555 GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
556 "+%d+%d font: %#x length: %d\n",
557 drawable_private->xwindow,
558 gc_private, gc_private->xgc,
562 if ((oldfont = SelectObject (hdc, xfont)) == NULL)
563 g_warning ("gdk_draw_text_wc: SelectObject failed");
564 #if 0 /* No. Don't use TextOutW directly. Compare to the X11 version,
565 * it uses plain XDrawString for GDK_FONT_FONT fonts, too.
566 * TextOutW by definition interprets the string as Unicode.
567 * We don't have that, but either chars from some single-byte codepage
570 wcstr = g_new (wchar_t, text_length);
571 for (i = 0; i < text_length; i++)
573 if (!TextOutW (hdc, x, y, wcstr, text_length))
574 g_warning ("gdk_draw_text_wc: TextOutW failed");
577 str = g_new (guchar, text_length);
578 for (i = 0; i < text_length; i++)
580 if (font_private->cpinfo.MaxCharSize > 1)
582 wcstr = g_new (wchar_t, text_length);
583 if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
585 wcstr, text_length)) == 0)
586 g_warning ("gdk_draw_text: MultiByteToWideChar failed");
587 else if (!TextOutW (hdc, x, y, wcstr, wlen))
588 g_warning ("gdk_draw_text_wc: TextOutW failed");
593 if (!TextOutA (hdc, x, y, str, text_length))
594 g_warning ("gdk_draw_text_wc: TextOutA failed");
599 SelectObject (hdc, oldfont);
600 gdk_gc_postdraw (drawable_private, gc_private);
603 g_error ("undefined font type");
607 gdk_draw_pixmap (GdkDrawable *drawable,
617 GdkDrawablePrivate *drawable_private;
618 GdkDrawablePrivate *src_private;
619 GdkGCPrivate *gc_private;
623 HRGN src_rgn, draw_rgn, outside_rgn;
626 g_return_if_fail (drawable != NULL);
627 g_return_if_fail (src != NULL);
628 g_return_if_fail (gc != NULL);
630 if (GDK_DRAWABLE_DESTROYED (drawable) || GDK_DRAWABLE_DESTROYED (src))
632 drawable_private = (GdkDrawablePrivate*) drawable;
633 src_private = (GdkDrawablePrivate*) src;
634 gc_private = (GdkGCPrivate*) gc;
637 width = src_private->width; /* Or should we subtract xsrc? */
639 height = src_private->height; /* Ditto? */
641 GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x "
642 "src: %#x %dx%d@+%d+%d"
643 " dest: %#x @+%d+%d\n",
644 drawable_private->xwindow,
645 src_private->xwindow,
646 width, height, xsrc, ysrc,
647 drawable_private->xwindow, xdest, ydest));
649 hdc = gdk_gc_predraw (drawable_private, gc_private);
651 src_rgn = CreateRectRgn (0, 0, src_private->width + 1, src_private->height + 1);
652 draw_rgn = CreateRectRgn (xsrc, ysrc, xsrc + width + 1, ysrc + height + 1);
654 outside_rgn = CreateRectRgnIndirect (&r);
656 if (drawable_private->window_type != GDK_DRAWABLE_PIXMAP)
658 /* If we are drawing on a window, calculate the region that is
659 * outside the source pixmap, and invalidate that, causing it to
662 if (CombineRgn (outside_rgn, draw_rgn, src_rgn, RGN_DIFF) != NULLREGION)
664 OffsetRgn (outside_rgn, xdest, ydest);
665 GDK_NOTE (MISC, (GetRgnBox (outside_rgn, &r),
666 g_print ("...calling InvalidateRgn, "
667 "bbox: %dx%d@+%d+%d\n",
668 r.right - r.left - 1, r.bottom - r.top - 1,
670 InvalidateRgn (drawable_private->xwindow, outside_rgn, TRUE);
674 #if 1 /* Don't know if this is necessary */
675 if (CombineRgn (draw_rgn, draw_rgn, src_rgn, RGN_AND) == COMPLEXREGION)
676 g_warning ("gdk_draw_pixmap: CombineRgn returned a COMPLEXREGION");
678 GetRgnBox (draw_rgn, &r);
681 || r.right != xsrc + width + 1
682 || r.bottom != ysrc + height + 1)
684 xdest += r.left - xsrc;
686 ydest += r.top - ysrc;
688 width = r.right - xsrc - 1;
689 height = r.bottom - ysrc - 1;
691 GDK_NOTE (MISC, g_print ("... restricted to src: %dx%d@+%d+%d, "
693 width, height, xsrc, ysrc,
698 DeleteObject (src_rgn);
699 DeleteObject (draw_rgn);
700 DeleteObject (outside_rgn);
702 /* Strangely enough, this function is called also to bitblt
705 if (src_private->window_type == GDK_DRAWABLE_PIXMAP)
707 if ((srcdc = CreateCompatibleDC (hdc)) == NULL)
708 g_warning ("gdk_draw_pixmap: CreateCompatibleDC failed");
710 if ((hgdiobj = SelectObject (srcdc, src_private->xwindow)) == NULL)
711 g_warning ("gdk_draw_pixmap: SelectObject #1 failed");
713 if (!BitBlt (hdc, xdest, ydest, width, height,
714 srcdc, xsrc, ysrc, SRCCOPY))
715 g_warning ("gdk_draw_pixmap: BitBlt failed");
717 if ((SelectObject (srcdc, hgdiobj) == NULL))
718 g_warning ("gdk_draw_pixmap: SelectObject #2 failed");
720 if (!DeleteDC (srcdc))
721 g_warning ("gdk_draw_pixmap: DeleteDC failed");
725 if (drawable_private->xwindow == src_private->xwindow)
727 /* Blitting inside a window, use ScrollDC */
728 RECT scrollRect, clipRect, emptyRect;
731 scrollRect.left = MIN (xsrc, xdest);
732 scrollRect.top = MIN (ysrc, ydest);
733 scrollRect.right = MAX (xsrc + width + 1, xdest + width + 1);
734 scrollRect.bottom = MAX (ysrc + height + 1, ydest + height + 1);
736 clipRect.left = xdest;
737 clipRect.top = ydest;
738 clipRect.right = xdest + width + 1;
739 clipRect.bottom = ydest + height + 1;
741 SetRectEmpty (&emptyRect);
742 updateRgn = CreateRectRgnIndirect (&emptyRect);
743 if (!ScrollDC (hdc, xdest - xsrc, ydest - ysrc,
744 &scrollRect, &clipRect,
746 g_warning ("gdk_draw_pixmap: ScrollDC failed");
747 if (!InvalidateRgn (drawable_private->xwindow, updateRgn, FALSE))
748 g_warning ("gdk_draw_pixmap: InvalidateRgn failed");
749 if (!UpdateWindow (drawable_private->xwindow))
750 g_warning ("gdk_draw_pixmap: UpdateWindow failed");
754 if ((srcdc = GetDC (src_private->xwindow)) == NULL)
755 g_warning ("gdk_draw_pixmap: GetDC failed");
757 if (!BitBlt (hdc, xdest, ydest, width, height,
758 srcdc, xsrc, ysrc, SRCCOPY))
759 g_warning ("gdk_draw_pixmap: BitBlt failed");
760 ReleaseDC (src_private->xwindow, srcdc);
763 gdk_gc_postdraw (drawable_private, gc_private);
767 gdk_draw_image (GdkDrawable *drawable,
777 GdkImagePrivate *image_private;
779 g_return_if_fail (drawable != NULL);
780 g_return_if_fail (image != NULL);
781 g_return_if_fail (gc != NULL);
783 image_private = (GdkImagePrivate*) image;
785 g_return_if_fail (image_private->image_put != NULL);
788 width = image->width;
790 height = image->height;
792 (* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
793 xdest, ydest, width, height);
797 gdk_draw_points (GdkDrawable *drawable,
802 GdkDrawablePrivate *drawable_private;
803 GdkGCPrivate *gc_private;
807 g_return_if_fail (drawable != NULL);
808 g_return_if_fail ((points != NULL) && (npoints > 0));
809 g_return_if_fail (gc != NULL);
811 if (GDK_DRAWABLE_DESTROYED (drawable))
813 drawable_private = (GdkDrawablePrivate*) drawable;
814 gc_private = (GdkGCPrivate*) gc;
816 hdc = gdk_gc_predraw (drawable_private, gc_private);
818 GDK_NOTE (MISC, g_print ("gdk_draw_points: %#x destdc: (%d) %#x "
820 drawable_private->xwindow, gc_private, hdc,
823 for (i = 0; i < npoints; i++)
825 if (!MoveToEx (hdc, points[i].x, points[i].y, NULL))
826 g_warning ("gdk_draw_points: MoveToEx failed");
827 if (!LineTo (hdc, points[i].x + 1, points[i].y))
828 g_warning ("gdk_draw_points: LineTo failed");
830 gdk_gc_postdraw (drawable_private, gc_private);
834 gdk_draw_segments (GdkDrawable *drawable,
839 GdkDrawablePrivate *drawable_private;
840 GdkGCPrivate *gc_private;
847 g_return_if_fail (drawable != NULL);
848 g_return_if_fail (segs != NULL);
849 g_return_if_fail (gc != NULL);
851 if (GDK_DRAWABLE_DESTROYED (drawable))
853 drawable_private = (GdkDrawablePrivate*) drawable;
854 gc_private = (GdkGCPrivate*) gc;
856 hdc = gdk_gc_predraw (drawable_private, gc_private);
858 for (i = 0; i < nsegs; i++)
860 if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
861 g_warning ("gdk_draw_segments: MoveToEx failed");
862 if (!LineTo (hdc, segs[i].x2, segs[i].y2))
863 g_warning ("gdk_draw_segments: LineTo #1 failed");
866 if (gc_private->pen_width == 1)
867 if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
868 g_warning ("gdk_draw_segments: LineTo #2 failed");
870 gdk_gc_postdraw (drawable_private, gc_private);
874 gdk_draw_lines (GdkDrawable *drawable,
879 GdkDrawablePrivate *drawable_private;
880 GdkGCPrivate *gc_private;
888 g_return_if_fail (drawable != NULL);
889 g_return_if_fail (points != NULL);
890 g_return_if_fail (gc != NULL);
892 if (GDK_DRAWABLE_DESTROYED (drawable))
894 drawable_private = (GdkDrawablePrivate*) drawable;
895 gc_private = (GdkGCPrivate*) gc;
897 hdc = gdk_gc_predraw (drawable_private, gc_private);
899 pts = g_malloc (npoints * sizeof (POINT));
901 for (i = 0; i < npoints; i++)
903 pts[i].x = points[i].x;
904 pts[i].y = points[i].y;
907 if (!Polyline (hdc, pts, npoints))
908 g_warning ("gdk_draw_lines: Polyline(,,%d) failed", npoints);
913 if (gc_private->pen_width == 1)
915 MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
916 if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
917 g_warning ("gdk_draw_lines: LineTo failed");
920 MoveToEx (hdc, points[0].x, points[0].y, NULL);
921 for (i = 1; i < npoints; i++)
922 if (!LineTo (hdc, points[i].x, points[i].y))
923 g_warning ("gdk_draw_lines: LineTo #1 failed");
926 if (gc_private->pen_width == 1)
927 if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
928 g_warning ("gdk_draw_lines: LineTo #2 failed");
930 gdk_gc_postdraw (drawable_private, gc_private);