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 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
474 drawable_private = (GdkDrawablePrivate*) drawable;
475 gc_private = (GdkGCPrivate*) gc;
476 font_private = (GdkFontPrivate*) 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");
492 wcstr = g_new (wchar_t, text_length);
493 if ((wlen = gdk_nmbstowchar_ts (wcstr, text, text_length, text_length)) == -1)
494 g_warning ("gdk_draw_text: gdk_nmbstowchar_ts failed");
495 else if (!TextOutW (hdc, x, y, wcstr, wlen))
496 g_warning ("gdk_draw_text: TextOutW failed");
499 SelectObject (hdc, oldfont);
500 gdk_gc_postdraw (drawable_private, gc_private);
504 gdk_draw_text_wc (GdkDrawable *drawable,
509 const GdkWChar *text,
514 GdkDrawablePrivate *drawable_private;
515 GdkFontPrivate *font_private;
516 GdkGCPrivate *gc_private;
521 g_return_if_fail (drawable != NULL);
522 g_return_if_fail (font != NULL);
523 g_return_if_fail (gc != NULL);
524 g_return_if_fail (text != NULL);
526 if (GDK_DRAWABLE_DESTROYED (drawable))
529 if (text_length == 0)
532 g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
534 drawable_private = (GdkDrawablePrivate*) drawable;
535 gc_private = (GdkGCPrivate*) gc;
536 font_private = (GdkFontPrivate*) font;
538 hdc = gdk_gc_predraw (drawable_private, gc_private);
540 GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
541 "+%d+%d font: %#x length: %d\n",
542 drawable_private->xwindow,
543 gc_private, gc_private->xgc,
544 x, y, font_private->xfont,
547 if ((oldfont = SelectObject (hdc, font_private->xfont)) == NULL)
548 g_warning ("gdk_draw_text_wc: SelectObject failed");
549 if (sizeof (wchar_t) != sizeof (GdkWChar))
551 wcstr = g_new (wchar_t, text_length);
552 for (i = 0; i < text_length; i++)
556 wcstr = (wchar_t *) text;
558 if (!TextOutW (hdc, x, y, wcstr, text_length))
559 g_warning ("gdk_draw_text_wc: TextOutW failed");
561 if (sizeof (wchar_t) != sizeof (GdkWChar))
564 SelectObject (hdc, oldfont);
565 gdk_gc_postdraw (drawable_private, gc_private);
569 gdk_draw_pixmap (GdkDrawable *drawable,
579 GdkDrawablePrivate *drawable_private;
580 GdkDrawablePrivate *src_private;
581 GdkGCPrivate *gc_private;
585 HRGN src_rgn, draw_rgn, outside_rgn;
588 g_return_if_fail (drawable != NULL);
589 g_return_if_fail (src != NULL);
590 g_return_if_fail (gc != NULL);
592 if (GDK_DRAWABLE_DESTROYED (drawable) || GDK_DRAWABLE_DESTROYED (src))
594 drawable_private = (GdkDrawablePrivate*) drawable;
595 src_private = (GdkDrawablePrivate*) src;
596 gc_private = (GdkGCPrivate*) gc;
599 width = src_private->width; /* Or should we subtract xsrc? */
601 height = src_private->height; /* Ditto? */
603 GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x "
604 "src: %#x %dx%d@+%d+%d"
605 " dest: %#x @+%d+%d\n",
606 drawable_private->xwindow,
607 src_private->xwindow,
608 width, height, xsrc, ysrc,
609 drawable_private->xwindow, xdest, ydest));
611 hdc = gdk_gc_predraw (drawable_private, gc_private);
613 src_rgn = CreateRectRgn (0, 0, src_private->width + 1, src_private->height + 1);
614 draw_rgn = CreateRectRgn (xsrc, ysrc, xsrc + width + 1, ysrc + height + 1);
616 outside_rgn = CreateRectRgnIndirect (&r);
618 if (drawable_private->window_type != GDK_DRAWABLE_PIXMAP)
620 /* If we are drawing on a window, calculate the region that is
621 * outside the source pixmap, and invalidate that, causing it to
624 if (CombineRgn (outside_rgn, draw_rgn, src_rgn, RGN_DIFF) != NULLREGION)
626 OffsetRgn (outside_rgn, xdest, ydest);
627 GDK_NOTE (MISC, (GetRgnBox (outside_rgn, &r),
628 g_print ("...calling InvalidateRgn, "
629 "bbox: %dx%d@+%d+%d\n",
630 r.right - r.left - 1, r.bottom - r.top - 1,
632 InvalidateRgn (drawable_private->xwindow, outside_rgn, TRUE);
636 #if 1 /* Don't know if this is necessary */
637 if (CombineRgn (draw_rgn, draw_rgn, src_rgn, RGN_AND) == COMPLEXREGION)
638 g_warning ("gdk_draw_pixmap: CombineRgn returned a COMPLEXREGION");
640 GetRgnBox (draw_rgn, &r);
643 || r.right != xsrc + width + 1
644 || r.bottom != ysrc + height + 1)
646 xdest += r.left - xsrc;
648 ydest += r.top - ysrc;
650 width = r.right - xsrc - 1;
651 height = r.bottom - ysrc - 1;
653 GDK_NOTE (MISC, g_print ("... restricted to src: %dx%d@+%d+%d, "
655 width, height, xsrc, ysrc,
660 DeleteObject (src_rgn);
661 DeleteObject (draw_rgn);
662 DeleteObject (outside_rgn);
664 /* Strangely enough, this function is called also to bitblt
667 if (src_private->window_type == GDK_DRAWABLE_PIXMAP)
669 if ((srcdc = CreateCompatibleDC (hdc)) == NULL)
670 g_warning ("gdk_draw_pixmap: CreateCompatibleDC failed");
672 if ((hgdiobj = SelectObject (srcdc, src_private->xwindow)) == NULL)
673 g_warning ("gdk_draw_pixmap: SelectObject #1 failed");
675 if (!BitBlt (hdc, xdest, ydest, width, height,
676 srcdc, xsrc, ysrc, SRCCOPY))
677 g_warning ("gdk_draw_pixmap: BitBlt failed");
679 if ((SelectObject (srcdc, hgdiobj) == NULL))
680 g_warning ("gdk_draw_pixmap: SelectObject #2 failed");
682 if (!DeleteDC (srcdc))
683 g_warning ("gdk_draw_pixmap: DeleteDC failed");
687 if (drawable_private->xwindow == src_private->xwindow)
689 /* Blitting inside a window, use ScrollDC */
690 RECT scrollRect, clipRect, emptyRect;
693 scrollRect.left = MIN (xsrc, xdest);
694 scrollRect.top = MIN (ysrc, ydest);
695 scrollRect.right = MAX (xsrc + width + 1, xdest + width + 1);
696 scrollRect.bottom = MAX (ysrc + height + 1, ydest + height + 1);
698 clipRect.left = xdest;
699 clipRect.top = ydest;
700 clipRect.right = xdest + width + 1;
701 clipRect.bottom = ydest + height + 1;
703 SetRectEmpty (&emptyRect);
704 updateRgn = CreateRectRgnIndirect (&emptyRect);
705 if (!ScrollDC (hdc, xdest - xsrc, ydest - ysrc,
706 &scrollRect, &clipRect,
708 g_warning ("gdk_draw_pixmap: ScrollDC failed");
709 if (!InvalidateRgn (drawable_private->xwindow, updateRgn, FALSE))
710 g_warning ("gdk_draw_pixmap: InvalidateRgn failed");
711 if (!UpdateWindow (drawable_private->xwindow))
712 g_warning ("gdk_draw_pixmap: UpdateWindow failed");
716 if ((srcdc = GetDC (src_private->xwindow)) == NULL)
717 g_warning ("gdk_draw_pixmap: GetDC failed");
719 if (!BitBlt (hdc, xdest, ydest, width, height,
720 srcdc, xsrc, ysrc, SRCCOPY))
721 g_warning ("gdk_draw_pixmap: BitBlt failed");
722 ReleaseDC (src_private->xwindow, srcdc);
725 gdk_gc_postdraw (drawable_private, gc_private);
729 gdk_draw_image (GdkDrawable *drawable,
739 GdkImagePrivate *image_private;
741 g_return_if_fail (drawable != NULL);
742 g_return_if_fail (image != NULL);
743 g_return_if_fail (gc != NULL);
745 image_private = (GdkImagePrivate*) image;
747 g_return_if_fail (image_private->image_put != NULL);
750 width = image->width;
752 height = image->height;
754 (* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
755 xdest, ydest, width, height);
759 gdk_draw_points (GdkDrawable *drawable,
764 GdkDrawablePrivate *drawable_private;
765 GdkGCPrivate *gc_private;
769 g_return_if_fail (drawable != NULL);
770 g_return_if_fail ((points != NULL) && (npoints > 0));
771 g_return_if_fail (gc != NULL);
773 if (GDK_DRAWABLE_DESTROYED (drawable))
775 drawable_private = (GdkDrawablePrivate*) drawable;
776 gc_private = (GdkGCPrivate*) gc;
778 hdc = gdk_gc_predraw (drawable_private, gc_private);
780 GDK_NOTE (MISC, g_print ("gdk_draw_points: %#x destdc: (%d) %#x "
782 drawable_private->xwindow, gc_private, hdc,
785 for (i = 0; i < npoints; i++)
787 if (!MoveToEx (hdc, points[i].x, points[i].y, NULL))
788 g_warning ("gdk_draw_points: MoveToEx failed");
789 if (!LineTo (hdc, points[i].x + 1, points[i].y))
790 g_warning ("gdk_draw_points: LineTo failed");
792 gdk_gc_postdraw (drawable_private, gc_private);
796 gdk_draw_segments (GdkDrawable *drawable,
801 GdkDrawablePrivate *drawable_private;
802 GdkGCPrivate *gc_private;
809 g_return_if_fail (drawable != NULL);
810 g_return_if_fail (segs != NULL);
811 g_return_if_fail (gc != NULL);
813 if (GDK_DRAWABLE_DESTROYED (drawable))
815 drawable_private = (GdkDrawablePrivate*) drawable;
816 gc_private = (GdkGCPrivate*) gc;
818 hdc = gdk_gc_predraw (drawable_private, gc_private);
820 for (i = 0; i < nsegs; i++)
822 if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
823 g_warning ("gdk_draw_segments: MoveToEx failed");
824 if (!LineTo (hdc, segs[i].x2, segs[i].y2))
825 g_warning ("gdk_draw_segments: LineTo #1 failed");
828 if (gc_private->pen_width == 1)
829 if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
830 g_warning ("gdk_draw_segments: LineTo #2 failed");
832 gdk_gc_postdraw (drawable_private, gc_private);
836 gdk_draw_lines (GdkDrawable *drawable,
841 GdkDrawablePrivate *drawable_private;
842 GdkGCPrivate *gc_private;
850 g_return_if_fail (drawable != NULL);
851 g_return_if_fail (points != NULL);
852 g_return_if_fail (gc != NULL);
854 if (GDK_DRAWABLE_DESTROYED (drawable))
856 drawable_private = (GdkDrawablePrivate*) drawable;
857 gc_private = (GdkGCPrivate*) gc;
859 hdc = gdk_gc_predraw (drawable_private, gc_private);
861 pts = g_malloc (npoints * sizeof (POINT));
863 for (i = 0; i < npoints; i++)
865 pts[i].x = points[i].x;
866 pts[i].y = points[i].y;
869 if (!Polyline (hdc, pts, npoints))
870 g_warning ("gdk_draw_lines: Polyline(,,%d) failed", npoints);
875 if (gc_private->pen_width == 1)
877 MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
878 if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
879 g_warning ("gdk_draw_lines: LineTo failed");
882 MoveToEx (hdc, points[0].x, points[0].y, NULL);
883 for (i = 1; i < npoints; i++)
884 if (!LineTo (hdc, points[i].x, points[i].y))
885 g_warning ("gdk_draw_lines: LineTo #1 failed");
888 if (gc_private->pen_width == 1)
889 if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
890 g_warning ("gdk_draw_lines: LineTo #2 failed");
892 gdk_gc_postdraw (drawable_private, gc_private);