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 "gdkprivate.h"
34 #define M_TWOPI (2.0 * 3.14159265358979323846)
38 gdk_draw_point (GdkDrawable *drawable,
43 GdkWindowPrivate *drawable_private;
44 GdkGCPrivate *gc_private;
47 g_return_if_fail (drawable != NULL);
48 g_return_if_fail (gc != NULL);
50 drawable_private = (GdkWindowPrivate*) drawable;
51 if (drawable_private->destroyed)
53 gc_private = (GdkGCPrivate*) gc;
55 hdc = gdk_gc_predraw (drawable_private, gc_private);
57 /* We use LineTo because SetPixel wants the COLORREF directly,
58 * and doesn't use the current pen, which is what we want.
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");
65 gdk_gc_postdraw (drawable_private, gc_private);
69 gdk_draw_line (GdkDrawable *drawable,
76 GdkWindowPrivate *drawable_private;
77 GdkGCPrivate *gc_private;
80 g_return_if_fail (drawable != NULL);
81 g_return_if_fail (gc != NULL);
83 drawable_private = (GdkWindowPrivate*) drawable;
84 if (drawable_private->destroyed)
86 gc_private = (GdkGCPrivate*) gc;
88 hdc = gdk_gc_predraw (drawable_private, gc_private);
90 GDK_NOTE (MISC, g_print ("gdk_draw_line: %#x (%d) +%d+%d..+%d+%d\n",
91 drawable_private->xwindow, gc_private,
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
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);
108 gdk_draw_rectangle (GdkDrawable *drawable,
116 GdkWindowPrivate *drawable_private;
117 GdkGCPrivate *gc_private;
119 HGDIOBJ oldpen, oldbrush;
121 g_return_if_fail (drawable != NULL);
122 g_return_if_fail (gc != NULL);
124 drawable_private = (GdkWindowPrivate*) drawable;
125 if (drawable_private->destroyed)
127 gc_private = (GdkGCPrivate*) gc;
130 width = drawable_private->width;
132 height = drawable_private->height;
134 hdc = gdk_gc_predraw (drawable_private, gc_private);
136 GDK_NOTE (MISC, g_print ("gdk_draw_rectangle: %#x (%d) %s%dx%d@+%d+%d\n",
137 drawable_private->xwindow,
139 (filled ? "fill " : ""),
140 width, height, x, y));
144 HBRUSH hbr = GetCurrentObject (hdc, OBJ_BRUSH);
145 HPEN hpen = GetCurrentObject (hdc, OBJ_PEN);
148 GetObject (hbr, sizeof (lbr), &lbr);
149 GetObject (hpen, sizeof (lpen), &lpen);
151 g_print ("current brush: style = %s, color = 0x%.08x\n",
152 (lbr.lbStyle == BS_SOLID ? "SOLID" : "???"),
154 g_print ("current pen: style = %s, width = %d, color = 0x%.08x\n",
155 (lpen.lopnStyle == PS_SOLID ? "SOLID" : "???"),
162 oldpen = SelectObject (hdc, GetStockObject (NULL_PEN));
164 oldbrush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
166 if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
167 g_warning ("gdk_draw_rectangle: Rectangle failed");
170 SelectObject (hdc, oldpen);
172 SelectObject (hdc, oldbrush);
174 gdk_gc_postdraw (drawable_private, gc_private);
178 gdk_draw_arc (GdkDrawable *drawable,
188 GdkWindowPrivate *drawable_private;
189 GdkGCPrivate *gc_private;
191 int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
193 g_return_if_fail (drawable != NULL);
194 g_return_if_fail (gc != NULL);
196 drawable_private = (GdkWindowPrivate*) drawable;
197 if (drawable_private->destroyed)
199 gc_private = (GdkGCPrivate*) gc;
202 width = drawable_private->width;
204 height = drawable_private->height;
206 hdc = gdk_gc_predraw (drawable_private, gc_private);
208 nXStartArc = x + width/2 + (int) (sin(angle1/64.*M_TWOPI)*width);
209 nYStartArc = y + height/2 + (int) (cos(angle1/64.*M_TWOPI)*height);
210 nXEndArc = x + width/2 + (int) (sin(angle2/64.*M_TWOPI)*width);
211 nYEndArc = y + height/2 + (int) (cos(angle2/64.*M_TWOPI)*height);
215 if (!Pie (hdc, x, y, x+width, y+height,
216 nXStartArc, nYStartArc, nXEndArc, nYEndArc))
217 g_warning ("gdk_draw_arc: Pie failed");
221 if (!Arc (hdc, x, y, x+width, y+height,
222 nXStartArc, nYStartArc, nXEndArc, nYEndArc))
223 g_warning ("gdk_draw_arc: Arc failed");
225 gdk_gc_postdraw (drawable_private, gc_private);
229 gdk_draw_polygon (GdkDrawable *drawable,
235 GdkWindowPrivate *drawable_private;
236 GdkGCPrivate *gc_private;
241 g_return_if_fail (drawable != NULL);
242 g_return_if_fail (gc != NULL);
244 drawable_private = (GdkWindowPrivate*) drawable;
245 if (drawable_private->destroyed)
247 gc_private = (GdkGCPrivate*) gc;
249 hdc = gdk_gc_predraw (drawable_private, gc_private);
250 pts = g_malloc ((npoints+1) * sizeof (POINT));
252 GDK_NOTE (MISC, g_print ("gdk_draw_polygon: %#x (%d) %d\n",
253 drawable_private->xwindow, gc_private,
256 for (i = 0; i < npoints; i++)
258 pts[i].x = points[i].x;
259 pts[i].y = points[i].y;
262 if ((points[0].x != points[npoints-1].x) ||
263 (points[0].y != points[npoints-1].y))
265 pts[npoints].x = points[0].x;
266 pts[npoints].y = points[0].y;
271 if (!Polygon (hdc, pts, npoints))
272 g_warning ("gdk_draw_polygon: Polygon failed");
276 if (!Polyline (hdc, pts, npoints))
277 g_warning ("gdk_draw_polygon: Polyline failed");
280 gdk_gc_postdraw (drawable_private, gc_private);
286 gdk_draw_string (GdkDrawable *drawable,
293 gdk_draw_text (drawable, font, gc, x, y, string, strlen (string));
298 * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
300 * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
303 gdk_draw_text (GdkDrawable *drawable,
311 GdkWindowPrivate *drawable_private;
312 GdkFontPrivate *font_private;
313 GdkGCPrivate *gc_private;
318 g_return_if_fail (drawable != NULL);
319 g_return_if_fail (font != NULL);
320 g_return_if_fail (gc != NULL);
321 g_return_if_fail (text != NULL);
323 drawable_private = (GdkWindowPrivate*) drawable;
324 if (drawable_private->destroyed)
326 gc_private = (GdkGCPrivate*) gc;
327 font_private = (GdkFontPrivate*) font;
329 if (font->type == GDK_FONT_FONT)
331 hdc = gdk_gc_predraw (drawable_private, gc_private);
332 xfont = (HFONT) font_private->xfont;
334 GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
335 "+%d+%d font: %#x \"%.*s\" length: %d\n",
336 drawable_private->xwindow,
337 gc_private, gc_private->xgc,
339 (text_length > 10 ? 10 : text_length),
342 if ((oldfont = SelectObject (hdc, xfont)) == NULL)
343 g_warning ("gdk_draw_text: SelectObject failed");
344 if (!TextOutA (hdc, x, y, text, text_length))
345 g_warning ("gdk_draw_text: TextOutA failed");
346 SelectObject (hdc, oldfont);
347 gdk_gc_postdraw (drawable_private, gc_private);
350 g_error ("undefined font type");
354 gdk_draw_text_wc (GdkDrawable *drawable,
359 const GdkWChar *text,
362 GdkWindowPrivate *drawable_private;
363 GdkFontPrivate *font_private;
364 GdkGCPrivate *gc_private;
368 g_return_if_fail (drawable != NULL);
369 g_return_if_fail (font != NULL);
370 g_return_if_fail (gc != NULL);
371 g_return_if_fail (text != NULL);
373 drawable_private = (GdkWindowPrivate*) drawable;
374 if (drawable_private->destroyed)
376 gc_private = (GdkGCPrivate*) gc;
377 font_private = (GdkFontPrivate*) font;
379 if (font->type == GDK_FONT_FONT)
385 hdc = gdk_gc_predraw (drawable_private, gc_private);
386 xfont = (HFONT) font_private->xfont;
388 GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
389 "+%d+%d font: %#x length: %d\n",
390 drawable_private->xwindow,
391 gc_private, gc_private->xgc,
395 if ((oldfont = SelectObject (hdc, xfont)) == NULL)
396 g_warning ("gdk_draw_text: SelectObject failed");
397 wcstr = g_new (wchar_t, text_length);
398 for (i = 0; i < text_length; i++)
400 if (!TextOutW (hdc, x, y, wcstr, text_length))
401 g_warning ("gdk_draw_text: TextOutW failed");
403 SelectObject (hdc, oldfont);
404 gdk_gc_postdraw (drawable_private, gc_private);
407 g_error ("undefined font type");
411 gdk_draw_pixmap (GdkDrawable *drawable,
421 GdkWindowPrivate *drawable_private;
422 GdkWindowPrivate *src_private;
423 GdkGCPrivate *gc_private;
428 g_return_if_fail (drawable != NULL);
429 g_return_if_fail (src != NULL);
430 g_return_if_fail (gc != NULL);
432 drawable_private = (GdkWindowPrivate*) drawable;
433 src_private = (GdkWindowPrivate*) src;
434 if (drawable_private->destroyed || src_private->destroyed)
436 gc_private = (GdkGCPrivate*) gc;
439 width = src_private->width;
441 height = src_private->height;
443 hdc = gdk_gc_predraw (drawable_private, gc_private);
445 GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x destdc: (%d) %#x "
446 "src: %#x %dx%d@+%d+%d\n",
447 drawable_private->xwindow, gc_private, hdc,
448 src_private->xwindow,
449 width, height, xdest, ydest));
451 /* Strangely enough, this function is called also to bitblt
454 if (src_private->window_type == GDK_WINDOW_PIXMAP)
456 if ((srcdc = CreateCompatibleDC (hdc)) == NULL)
457 g_warning ("gdk_draw_pixmap: CreateCompatibleDC failed");
459 if ((hgdiobj = SelectObject (srcdc, src_private->xwindow)) == NULL)
460 g_warning ("gdk_draw_pixmap: SelectObject #1 failed");
462 if (!BitBlt (hdc, xdest, ydest, width, height,
463 srcdc, xsrc, ysrc, SRCCOPY))
464 g_warning ("gdk_draw_pixmap: BitBlt failed");
466 if ((SelectObject (srcdc, hgdiobj) == NULL))
467 g_warning ("gdk_draw_pixmap: SelectObject #2 failed");
469 if (!DeleteDC (srcdc))
470 g_warning ("gdk_draw_pixmap: DeleteDC failed");
474 if ((srcdc = GetDC (src_private->xwindow)) == NULL)
475 g_warning ("gdk_draw_pixmap: GetDC failed");
477 if (!BitBlt (hdc, xdest, ydest, width, height,
478 srcdc, xsrc, ysrc, SRCCOPY))
479 g_warning ("gdk_draw_pixmap: BitBlt failed");
481 ReleaseDC (src_private->xwindow, srcdc);
483 gdk_gc_postdraw (drawable_private, gc_private);
487 gdk_draw_image (GdkDrawable *drawable,
497 GdkImagePrivate *image_private;
499 g_return_if_fail (drawable != NULL);
500 g_return_if_fail (image != NULL);
501 g_return_if_fail (gc != NULL);
503 image_private = (GdkImagePrivate*) image;
505 g_return_if_fail (image_private->image_put != NULL);
508 width = image->width;
510 height = image->height;
512 (* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
513 xdest, ydest, width, height);
517 gdk_draw_points (GdkDrawable *drawable,
522 GdkWindowPrivate *drawable_private;
523 GdkGCPrivate *gc_private;
527 g_return_if_fail (drawable != NULL);
528 g_return_if_fail ((points != NULL) && (npoints > 0));
529 g_return_if_fail (gc != NULL);
531 drawable_private = (GdkWindowPrivate*) drawable;
532 if (drawable_private->destroyed)
534 gc_private = (GdkGCPrivate*) gc;
536 hdc = gdk_gc_predraw (drawable_private, gc_private);
538 GDK_NOTE (MISC, g_print ("gdk_draw_points: %#x destdc: (%d) %#x "
540 drawable_private->xwindow, gc_private, hdc,
543 for (i = 0; i < npoints; i++)
545 if (!MoveToEx (hdc, points[i].x, points[i].y, NULL))
546 g_warning ("gdk_draw_points: MoveToEx failed");
547 if (!LineTo (hdc, points[i].x + 1, points[i].y))
548 g_warning ("gdk_draw_points: LineTo failed");
550 gdk_gc_postdraw (drawable_private, gc_private);
554 gdk_draw_segments (GdkDrawable *drawable,
559 GdkWindowPrivate *drawable_private;
560 GdkGCPrivate *gc_private;
567 g_return_if_fail (drawable != NULL);
568 g_return_if_fail (segs != NULL);
569 g_return_if_fail (gc != NULL);
571 drawable_private = (GdkWindowPrivate*) drawable;
572 if (drawable_private->destroyed)
574 gc_private = (GdkGCPrivate*) gc;
576 hdc = gdk_gc_predraw (drawable_private, gc_private);
578 for (i = 0; i < nsegs; i++)
580 if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
581 g_warning ("gdk_draw_segments: MoveToEx failed");
582 if (!LineTo (hdc, segs[i].x2, segs[i].y2))
583 g_warning ("gdk_draw_segments: LineTo #1 failed");
586 if (gc_private->pen_width == 1)
587 if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
588 g_warning ("gdk_draw_segments: LineTo #2 failed");
590 gdk_gc_postdraw (drawable_private, gc_private);
594 gdk_draw_lines (GdkDrawable *drawable,
599 GdkWindowPrivate *drawable_private;
600 GdkGCPrivate *gc_private;
608 g_return_if_fail (drawable != NULL);
609 g_return_if_fail (points != NULL);
610 g_return_if_fail (gc != NULL);
612 drawable_private = (GdkWindowPrivate*) drawable;
613 gc_private = (GdkGCPrivate*) gc;
615 hdc = gdk_gc_predraw (drawable_private, gc_private);
617 pts = g_malloc (npoints * sizeof (POINT));
619 for (i = 0; i < npoints; i++)
621 pts[i].x = points[i].x;
622 pts[i].y = points[i].y;
625 if (!Polyline (hdc, pts, npoints))
626 g_warning ("gdk_draw_lines: Polyline failed");
631 if (gc_private->pen_width == 1)
633 MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
634 if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
635 g_warning ("gdk_draw_lines: LineTo failed");
638 MoveToEx (hdc, points[0].x, points[0].y, NULL);
639 for (i = 1; i < npoints; i++)
640 if (!LineTo (hdc, points[i].x, points[i].y))
641 g_warning ("gdk_draw_lines: LineTo #1 failed");
644 if (gc_private->pen_width == 1)
645 if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
646 g_warning ("gdk_draw_lines: LineTo #2 failed");
648 gdk_gc_postdraw (drawable_private, gc_private);