]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkdraw.c
6acf1e488fcc32f22da8ade00683adb549230572
[~andy/gtk] / gdk / win32 / gdkdraw.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /*
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/. 
25  */
26
27 #include "config.h"
28
29 #include <math.h>
30 #include <gdk/gdk.h>
31 #include "gdkprivate.h"
32
33 #ifndef M_TWOPI
34 #define M_TWOPI         (2.0 * 3.14159265358979323846)
35 #endif
36
37 void
38 gdk_draw_point (GdkDrawable *drawable,
39                 GdkGC       *gc,
40                 gint         x,
41                 gint         y)
42 {
43   GdkWindowPrivate *drawable_private;
44   GdkGCPrivate *gc_private;
45   HDC hdc;
46
47   g_return_if_fail (drawable != NULL);
48   g_return_if_fail (gc != NULL);
49
50   drawable_private = (GdkWindowPrivate*) drawable;
51   if (drawable_private->destroyed)
52     return;
53   gc_private = (GdkGCPrivate*) gc;
54
55   hdc = gdk_gc_predraw (drawable_private, gc_private);
56
57   /* We use LineTo because SetPixel wants the COLORREF directly,
58    * and doesn't use the current pen, which is what we want.
59    */
60   if (!MoveToEx (hdc, x, y, NULL))
61     g_warning ("gdk_draw_point: MoveToEx failed");
62   if (!LineTo (hdc, x + 1, y))
63     g_warning ("gdk_draw_point: LineTo failed");
64   
65   gdk_gc_postdraw (drawable_private, gc_private);
66 }
67
68 void
69 gdk_draw_line (GdkDrawable *drawable,
70                GdkGC       *gc,
71                gint         x1,
72                gint         y1,
73                gint         x2,
74                gint         y2)
75 {
76   GdkWindowPrivate *drawable_private;
77   GdkGCPrivate *gc_private;
78   HDC hdc;
79
80   g_return_if_fail (drawable != NULL);
81   g_return_if_fail (gc != NULL);
82
83   drawable_private = (GdkWindowPrivate*) drawable;
84   if (drawable_private->destroyed)
85     return;
86   gc_private = (GdkGCPrivate*) gc;
87
88   hdc = gdk_gc_predraw (drawable_private, gc_private);
89     
90   GDK_NOTE (MISC, g_print ("gdk_draw_line: %#x (%d) +%d+%d..+%d+%d\n",
91                            drawable_private->xwindow, gc_private,
92                            x1, y1, x2, y2));
93   
94   MoveToEx (hdc, x1, y1, NULL);
95   if (!LineTo (hdc, x2, y2))
96     g_warning ("gdk_draw_line: LineTo #1 failed");
97   /* LineTo doesn't draw the last point, so if we have a pen width of 1,
98    * we draw the end pixel separately... With wider pens it hopefully
99    * doesn't matter?
100    */
101   if (gc_private->pen_width == 1)
102     if (!LineTo (hdc, x2 + 1, y2))
103       g_warning ("gdk_draw_line: LineTo #2 failed");
104   gdk_gc_postdraw (drawable_private, gc_private);
105 }
106
107 void
108 gdk_draw_rectangle (GdkDrawable *drawable,
109                     GdkGC       *gc,
110                     gint         filled,
111                     gint         x,
112                     gint         y,
113                     gint         width,
114                     gint         height)
115 {
116   GdkWindowPrivate *drawable_private;
117   GdkGCPrivate *gc_private;
118   HDC hdc;
119   HGDIOBJ oldpen, oldbrush;
120
121   g_return_if_fail (drawable != NULL);
122   g_return_if_fail (gc != NULL);
123
124   drawable_private = (GdkWindowPrivate*) drawable;
125   if (drawable_private->destroyed)
126     return;
127   gc_private = (GdkGCPrivate*) gc;
128
129   if (width == -1)
130     width = drawable_private->width;
131   if (height == -1)
132     height = drawable_private->height;
133
134   hdc = gdk_gc_predraw (drawable_private, gc_private);
135
136   GDK_NOTE (MISC, g_print ("gdk_draw_rectangle: %#x (%d) %s%dx%d@+%d+%d\n",
137                            drawable_private->xwindow,
138                            gc_private,
139                            (filled ? "fill " : ""),
140                            width, height, x, y));
141     
142 #if 0
143   {
144     HBRUSH hbr = GetCurrentObject (hdc, OBJ_BRUSH);
145     HPEN hpen = GetCurrentObject (hdc, OBJ_PEN);
146     LOGBRUSH lbr;
147     LOGPEN lpen;
148     GetObject (hbr, sizeof (lbr), &lbr);
149     GetObject (hpen, sizeof (lpen), &lpen);
150     
151     g_print ("current brush: style = %s, color = 0x%.08x\n",
152              (lbr.lbStyle == BS_SOLID ? "SOLID" : "???"),
153              lbr.lbColor);
154     g_print ("current pen: style = %s, width = %d, color = 0x%.08x\n",
155              (lpen.lopnStyle == PS_SOLID ? "SOLID" : "???"),
156              lpen.lopnWidth,
157              lpen.lopnColor);
158   }
159 #endif
160
161   if (filled)
162     oldpen = SelectObject (hdc, GetStockObject (NULL_PEN));
163   else
164     oldbrush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
165   
166   if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
167     g_warning ("gdk_draw_rectangle: Rectangle failed");
168   
169   if (filled)
170     SelectObject (hdc, oldpen);
171   else
172     SelectObject (hdc, oldbrush);
173
174   gdk_gc_postdraw (drawable_private, gc_private);
175 }
176
177 void
178 gdk_draw_arc (GdkDrawable *drawable,
179               GdkGC       *gc,
180               gint         filled,
181               gint         x,
182               gint         y,
183               gint         width,
184               gint         height,
185               gint         angle1,
186               gint         angle2)
187 {
188   GdkWindowPrivate *drawable_private;
189   GdkGCPrivate *gc_private;
190   HDC hdc;
191   int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
192
193   g_return_if_fail (drawable != NULL);
194   g_return_if_fail (gc != NULL);
195
196   drawable_private = (GdkWindowPrivate*) drawable;
197   if (drawable_private->destroyed)
198     return;
199   gc_private = (GdkGCPrivate*) gc;
200
201   if (width == -1)
202     width = drawable_private->width;
203   if (height == -1)
204     height = drawable_private->height;
205
206   if (width != 0 && height != 0)
207     {
208       hdc = gdk_gc_predraw (drawable_private, gc_private);
209
210       nXStartArc = x + width/2 + (int) (sin(angle1/64.*M_TWOPI)*width);
211       nYStartArc = y + height/2 + (int) (cos(angle1/64.*M_TWOPI)*height);
212       nXEndArc = x + width/2 + (int) (sin(angle2/64.*M_TWOPI)*width);
213       nYEndArc = y + height/2 + (int) (cos(angle2/64.*M_TWOPI)*height);
214
215       if (filled)
216         {
217           Pie (hdc, x, y, x+width, y+height,
218                nXStartArc, nYStartArc, nXEndArc, nYEndArc);
219         }
220       else
221         {
222           Arc (hdc, x, y, x+width, y+height,
223                nXStartArc, nYStartArc, nXEndArc, nYEndArc);
224         }
225       gdk_gc_postdraw (drawable_private, gc_private);
226     }
227 }
228
229 void
230 gdk_draw_polygon (GdkDrawable *drawable,
231                   GdkGC       *gc,
232                   gint         filled,
233                   GdkPoint    *points,
234                   gint         npoints)
235 {
236   GdkWindowPrivate *drawable_private;
237   GdkGCPrivate *gc_private;
238   HDC hdc;
239   POINT *pts;
240   int i;
241
242   g_return_if_fail (drawable != NULL);
243   g_return_if_fail (gc != NULL);
244
245   drawable_private = (GdkWindowPrivate*) drawable;
246   if (drawable_private->destroyed)
247     return;
248   gc_private = (GdkGCPrivate*) gc;
249
250   GDK_NOTE (MISC, g_print ("gdk_draw_polygon: %#x (%d) %d\n",
251                            drawable_private->xwindow, gc_private,
252                            npoints));
253
254   if (npoints < 2)
255     return;
256
257   hdc = gdk_gc_predraw (drawable_private, gc_private);
258   pts = g_malloc ((npoints+1) * sizeof (POINT));
259
260   for (i = 0; i < npoints; i++)
261     {
262       pts[i].x = points[i].x;
263       pts[i].y = points[i].y;
264     }
265   
266   if ((points[0].x != points[npoints-1].x) ||
267       (points[0].y != points[npoints-1].y)) 
268     {
269       pts[npoints].x = points[0].x;
270       pts[npoints].y = points[0].y;
271       npoints++;
272     }
273   if (filled)
274     {
275       if (!Polygon (hdc, pts, npoints))
276         g_warning ("gdk_draw_polygon: Polygon failed");
277     }
278   else
279     {
280       if (!Polyline (hdc, pts, npoints))
281         g_warning ("gdk_draw_polygon: Polyline failed");
282     }
283   g_free (pts);
284   gdk_gc_postdraw (drawable_private, gc_private);
285 }
286
287 /* gdk_draw_string
288  */
289 void
290 gdk_draw_string (GdkDrawable *drawable,
291                  GdkFont     *font,
292                  GdkGC       *gc,
293                  gint         x,
294                  gint         y,
295                  const gchar *string)
296 {
297   gdk_draw_text (drawable, font, gc, x, y, string, strlen (string));
298 }
299
300 /* gdk_draw_text
301  *
302  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
303  *
304  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
305  */
306 void
307 gdk_draw_text (GdkDrawable *drawable,
308                GdkFont     *font,
309                GdkGC       *gc,
310                gint         x,
311                gint         y,
312                const gchar *text,
313                gint         text_length)
314 {
315   GdkWindowPrivate *drawable_private;
316   GdkFontPrivate *font_private;
317   GdkGCPrivate *gc_private;
318   HDC hdc;
319   HFONT xfont;
320   HGDIOBJ oldfont;
321
322   g_return_if_fail (drawable != NULL);
323   g_return_if_fail (font != NULL);
324   g_return_if_fail (gc != NULL);
325   g_return_if_fail (text != NULL);
326
327   drawable_private = (GdkWindowPrivate*) drawable;
328   if (drawable_private->destroyed)
329     return;
330   gc_private = (GdkGCPrivate*) gc;
331   font_private = (GdkFontPrivate*) font;
332
333   if (font->type == GDK_FONT_FONT)
334     {
335       hdc = gdk_gc_predraw (drawable_private, gc_private);
336       xfont = (HFONT) font_private->xfont;
337
338       GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
339                                "+%d+%d font: %#x \"%.*s\" length: %d\n",
340                                drawable_private->xwindow,
341                                gc_private, gc_private->xgc,
342                                x, y, xfont,
343                                (text_length > 10 ? 10 : text_length),
344                                text, text_length));
345       
346       if ((oldfont = SelectObject (hdc, xfont)) == NULL)
347         g_warning ("gdk_draw_text: SelectObject failed");
348       if (!TextOutA (hdc, x, y, text, text_length))
349         g_warning ("gdk_draw_text: TextOutA failed");
350       SelectObject (hdc, oldfont);
351       gdk_gc_postdraw (drawable_private, gc_private);
352     }
353   else
354     g_error ("undefined font type");
355 }
356
357 void
358 gdk_draw_text_wc (GdkDrawable    *drawable,
359                   GdkFont        *font,
360                   GdkGC          *gc,
361                   gint            x,
362                   gint            y,
363                   const GdkWChar *text,
364                   gint            text_length)
365 {
366   GdkWindowPrivate *drawable_private;
367   GdkFontPrivate *font_private;
368   GdkGCPrivate *gc_private;
369   gint i;
370   wchar_t *wcstr;
371
372   g_return_if_fail (drawable != NULL);
373   g_return_if_fail (font != NULL);
374   g_return_if_fail (gc != NULL);
375   g_return_if_fail (text != NULL);
376
377   drawable_private = (GdkWindowPrivate*) drawable;
378   if (drawable_private->destroyed)
379     return;
380   gc_private = (GdkGCPrivate*) gc;
381   font_private = (GdkFontPrivate*) font;
382
383   if (font->type == GDK_FONT_FONT)
384     {
385       HDC hdc;
386       HFONT xfont;
387       HGDIOBJ oldfont;
388
389       hdc = gdk_gc_predraw (drawable_private, gc_private);
390       xfont = (HFONT) font_private->xfont;
391
392       GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
393                                "+%d+%d font: %#x length: %d\n",
394                                drawable_private->xwindow,
395                                gc_private, gc_private->xgc,
396                                x, y, xfont,
397                                text_length));
398       
399       if ((oldfont = SelectObject (hdc, xfont)) == NULL)
400         g_warning ("gdk_draw_text: SelectObject failed");
401       wcstr = g_new (wchar_t, text_length);
402       for (i = 0; i < text_length; i++)
403         wcstr[i] = text[i];
404       if (!TextOutW (hdc, x, y, wcstr, text_length))
405         g_warning ("gdk_draw_text: TextOutW failed");
406       g_free (wcstr);
407       SelectObject (hdc, oldfont);
408       gdk_gc_postdraw (drawable_private, gc_private);
409     }
410   else
411     g_error ("undefined font type");
412 }
413
414 void
415 gdk_draw_pixmap (GdkDrawable *drawable,
416                  GdkGC       *gc,
417                  GdkPixmap   *src,
418                  gint         xsrc,
419                  gint         ysrc,
420                  gint         xdest,
421                  gint         ydest,
422                  gint         width,
423                  gint         height)
424 {
425   GdkWindowPrivate *drawable_private;
426   GdkWindowPrivate *src_private;
427   GdkGCPrivate *gc_private;
428   HDC hdc;
429   HDC srcdc;
430   HGDIOBJ hgdiobj;
431   HRGN src_rgn, draw_rgn, outside_rgn;
432   RECT r;
433
434   g_return_if_fail (drawable != NULL);
435   g_return_if_fail (src != NULL);
436   g_return_if_fail (gc != NULL);
437
438   drawable_private = (GdkWindowPrivate*) drawable;
439   src_private = (GdkWindowPrivate*) src;
440   if (drawable_private->destroyed || src_private->destroyed)
441     return;
442   gc_private = (GdkGCPrivate*) gc;
443
444   if (width == -1)
445     width = src_private->width; /* Or should we subtract xsrc? */
446   if (height == -1)
447     height = src_private->height; /* Ditto? */
448
449   GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x "
450                            "src: %#x %dx%d@+%d+%d"
451                            " dest: %#x @+%d+%d\n",
452                            drawable_private->xwindow,
453                            src_private->xwindow,
454                            width, height, xsrc, ysrc,
455                            drawable_private->xwindow, xdest, ydest));
456
457   hdc = gdk_gc_predraw (drawable_private, gc_private);
458
459   src_rgn = CreateRectRgn (0, 0, src_private->width + 1, src_private->height + 1);
460   draw_rgn = CreateRectRgn (xsrc, ysrc, xsrc + width + 1, ysrc + height + 1);
461   SetRectEmpty (&r);
462   outside_rgn = CreateRectRgnIndirect (&r);
463   
464   if (drawable_private->window_type != GDK_WINDOW_PIXMAP)
465     {
466       /* If we are drawing on a window, calculate the region that is
467        * outside the source pixmap, and invalidate that, causing it to
468        * be cleared. XXX
469        */
470       if (CombineRgn (outside_rgn, draw_rgn, src_rgn, RGN_DIFF) != NULLREGION)
471         {
472           OffsetRgn (outside_rgn, xdest, ydest);
473           GDK_NOTE (MISC, (GetRgnBox (outside_rgn, &r),
474                            g_print ("...calling InvalidateRgn, "
475                                     "bbox: %dx%d@+%d+%d\n",
476                                     r.right - r.left - 1, r.bottom - r.top - 1,
477                                     r.left, r.top)));
478           InvalidateRgn (drawable_private->xwindow, outside_rgn, TRUE);
479         }
480     }
481
482 #if 1 /* Don't know if this is necessary  */
483   if (CombineRgn (draw_rgn, draw_rgn, src_rgn, RGN_AND) == COMPLEXREGION)
484     g_warning ("gdk_draw_pixmap: CombineRgn returned a COMPLEXREGION");
485
486   GetRgnBox (draw_rgn, &r);
487   if (r.left != xsrc
488       || r.top != ysrc
489       || r.right != xsrc + width + 1
490       || r.bottom != ysrc + height + 1)
491     {
492       xdest += r.left - xsrc;
493       xsrc = r.left;
494       ydest += r.top - ysrc;
495       ysrc = r.top;
496       width = r.right - xsrc - 1;
497       height = r.bottom - ysrc - 1;
498       
499       GDK_NOTE (MISC, g_print ("... restricted to src: %dx%d@+%d+%d, "
500                                "dest: @+%d+%d\n",
501                                width, height, xsrc, ysrc,
502                                xdest, ydest));
503     }
504 #endif
505
506   DeleteObject (src_rgn);
507   DeleteObject (draw_rgn);
508   DeleteObject (outside_rgn);
509
510   /* Strangely enough, this function is called also to bitblt
511    * from a window.
512    */
513   if (src_private->window_type == GDK_WINDOW_PIXMAP)
514     {
515       if ((srcdc = CreateCompatibleDC (hdc)) == NULL)
516         g_warning ("gdk_draw_pixmap: CreateCompatibleDC failed");
517       
518       if ((hgdiobj = SelectObject (srcdc, src_private->xwindow)) == NULL)
519         g_warning ("gdk_draw_pixmap: SelectObject #1 failed");
520       
521       if (!BitBlt (hdc, xdest, ydest, width, height,
522                    srcdc, xsrc, ysrc, SRCCOPY))
523         g_warning ("gdk_draw_pixmap: BitBlt failed");
524       
525       if ((SelectObject (srcdc, hgdiobj) == NULL))
526         g_warning ("gdk_draw_pixmap: SelectObject #2 failed");
527       
528       if (!DeleteDC (srcdc))
529         g_warning ("gdk_draw_pixmap: DeleteDC failed");
530     }
531   else
532     {
533       if ((srcdc = GetDC (src_private->xwindow)) == NULL)
534         g_warning ("gdk_draw_pixmap: GetDC failed");
535       
536       if (!BitBlt (hdc, xdest, ydest, width, height,
537                    srcdc, xsrc, ysrc, SRCCOPY))
538         g_warning ("gdk_draw_pixmap: BitBlt failed");
539       
540       ReleaseDC (src_private->xwindow, srcdc);
541     }
542   gdk_gc_postdraw (drawable_private, gc_private);
543 }
544
545 void
546 gdk_draw_image (GdkDrawable *drawable,
547                 GdkGC       *gc,
548                 GdkImage    *image,
549                 gint         xsrc,
550                 gint         ysrc,
551                 gint         xdest,
552                 gint         ydest,
553                 gint         width,
554                 gint         height)
555 {
556   GdkImagePrivate *image_private;
557
558   g_return_if_fail (drawable != NULL);
559   g_return_if_fail (image != NULL);
560   g_return_if_fail (gc != NULL);
561
562   image_private = (GdkImagePrivate*) image;
563
564   g_return_if_fail (image_private->image_put != NULL);
565
566   if (width == -1)
567     width = image->width;
568   if (height == -1)
569     height = image->height;
570
571   (* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
572                                 xdest, ydest, width, height);
573 }
574
575 void
576 gdk_draw_points (GdkDrawable *drawable,
577                  GdkGC       *gc,
578                  GdkPoint    *points,
579                  gint         npoints)
580 {
581   GdkWindowPrivate *drawable_private;
582   GdkGCPrivate *gc_private;
583   HDC hdc;
584   int i;
585
586   g_return_if_fail (drawable != NULL);
587   g_return_if_fail ((points != NULL) && (npoints > 0));
588   g_return_if_fail (gc != NULL);
589
590   drawable_private = (GdkWindowPrivate*) drawable;
591   if (drawable_private->destroyed)
592     return;
593   gc_private = (GdkGCPrivate*) gc;
594
595   hdc = gdk_gc_predraw (drawable_private, gc_private);
596   
597   GDK_NOTE (MISC, g_print ("gdk_draw_points: %#x destdc: (%d) %#x "
598                            "npoints: %d\n",
599                            drawable_private->xwindow, gc_private, hdc,
600                            npoints));
601
602   for (i = 0; i < npoints; i++)
603     {
604       if (!MoveToEx (hdc, points[i].x, points[i].y, NULL))
605         g_warning ("gdk_draw_points: MoveToEx failed");
606       if (!LineTo (hdc, points[i].x + 1, points[i].y))
607         g_warning ("gdk_draw_points: LineTo failed");
608     }
609   gdk_gc_postdraw (drawable_private, gc_private);
610 }
611
612 void
613 gdk_draw_segments (GdkDrawable *drawable,
614                    GdkGC       *gc,
615                    GdkSegment  *segs,
616                    gint         nsegs)
617 {
618   GdkWindowPrivate *drawable_private;
619   GdkGCPrivate *gc_private;
620   HDC hdc;
621   int i;
622
623   if (nsegs <= 0)
624     return;
625
626   g_return_if_fail (drawable != NULL);
627   g_return_if_fail (segs != NULL);
628   g_return_if_fail (gc != NULL);
629
630   drawable_private = (GdkWindowPrivate*) drawable;
631   if (drawable_private->destroyed)
632     return;
633   gc_private = (GdkGCPrivate*) gc;
634
635   hdc = gdk_gc_predraw (drawable_private, gc_private);
636
637   for (i = 0; i < nsegs; i++)
638     {
639       if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
640         g_warning ("gdk_draw_segments: MoveToEx failed");
641       if (!LineTo (hdc, segs[i].x2, segs[i].y2))
642         g_warning ("gdk_draw_segments: LineTo #1 failed");
643       
644       /* Draw end pixel */
645       if (gc_private->pen_width == 1)
646         if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
647           g_warning ("gdk_draw_segments: LineTo #2 failed");
648     }
649   gdk_gc_postdraw (drawable_private, gc_private);
650 }
651
652 void
653 gdk_draw_lines (GdkDrawable *drawable,
654                 GdkGC       *gc,
655                 GdkPoint    *points,
656                 gint         npoints)
657 {
658   GdkWindowPrivate *drawable_private;
659   GdkGCPrivate *gc_private;
660   HDC hdc;
661   POINT *pts;
662   int i;
663
664   if (npoints < 2)
665     return;
666
667   g_return_if_fail (drawable != NULL);
668   g_return_if_fail (points != NULL);
669   g_return_if_fail (gc != NULL);
670
671   drawable_private = (GdkWindowPrivate*) drawable;
672   gc_private = (GdkGCPrivate*) gc;
673
674   hdc = gdk_gc_predraw (drawable_private, gc_private);
675 #if 1
676   pts = g_malloc (npoints * sizeof (POINT));
677
678   for (i = 0; i < npoints; i++)
679     {
680       pts[i].x = points[i].x;
681       pts[i].y = points[i].y;
682     }
683   
684   if (!Polyline (hdc, pts, npoints))
685     g_warning ("gdk_draw_lines: Polyline(,,%d) failed", npoints);
686   
687   g_free (pts);
688   
689   /* Draw end pixel */
690   if (gc_private->pen_width == 1)
691     {
692       MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
693       if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
694         g_warning ("gdk_draw_lines: LineTo failed");
695     }
696 #else
697   MoveToEx (hdc, points[0].x, points[0].y, NULL);
698   for (i = 1; i < npoints; i++)
699     if (!LineTo (hdc, points[i].x, points[i].y))
700       g_warning ("gdk_draw_lines: LineTo #1 failed");
701   
702   /* Draw end pixel */
703   if (gc_private->pen_width == 1)
704     if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
705       g_warning ("gdk_draw_lines: LineTo #2 failed");
706 #endif  
707   gdk_gc_postdraw (drawable_private, gc_private);
708 }