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;
49 g_return_if_fail (drawable != NULL);
50 g_return_if_fail (gc != NULL);
52 drawable_private = (GdkWindowPrivate*) drawable;
53 if (drawable_private->destroyed)
55 gc_private = (GdkGCPrivate*) gc;
57 hdc = gdk_gc_predraw (drawable_private, gc_private);
58 hbr = GetCurrentObject (hdc, OBJ_BRUSH);
59 /* We use FillRect because SetPixel wants the COLORREF directly,
60 * and doesn't use the current brush, which is what we want.
64 rect.right = rect.left + 1;
65 rect.bottom = rect.top + 1;
66 FillRect (hdc, &rect, hbr);
68 gdk_gc_postdraw (drawable_private, gc_private);
72 gdk_draw_line (GdkDrawable *drawable,
79 GdkWindowPrivate *drawable_private;
80 GdkGCPrivate *gc_private;
83 g_return_if_fail (drawable != NULL);
84 g_return_if_fail (gc != NULL);
86 drawable_private = (GdkWindowPrivate*) drawable;
87 if (drawable_private->destroyed)
89 gc_private = (GdkGCPrivate*) gc;
91 hdc = gdk_gc_predraw (drawable_private, gc_private);
93 GDK_NOTE (MISC, g_print ("gdk_draw_line: %#x (%d) +%d+%d..+%d+%d\n",
94 drawable_private->xwindow, gc_private,
97 MoveToEx (hdc, x1, y1, NULL);
98 if (!LineTo (hdc, x2, y2))
99 g_warning ("gdk_draw_line: LineTo #1 failed");
100 /* LineTo doesn't draw the last point, so if we have a pen width of 1,
101 * we draw the end pixel separately... With wider pens it hopefully
104 if (gc_private->pen_width == 1)
105 if (!LineTo (hdc, x2 + 1, y2))
106 g_warning ("gdk_draw_line: LineTo #2 failed");
107 gdk_gc_postdraw (drawable_private, gc_private);
111 gdk_draw_rectangle (GdkDrawable *drawable,
119 GdkWindowPrivate *drawable_private;
120 GdkGCPrivate *gc_private;
125 HGDIOBJ oldpen, oldbrush;
127 g_return_if_fail (drawable != NULL);
128 g_return_if_fail (gc != NULL);
130 drawable_private = (GdkWindowPrivate*) drawable;
131 if (drawable_private->destroyed)
133 gc_private = (GdkGCPrivate*) gc;
136 width = drawable_private->width;
138 height = drawable_private->height;
140 hdc = gdk_gc_predraw (drawable_private, gc_private);
142 GDK_NOTE (MISC, g_print ("gdk_draw_rectangle: %#x (%d) %s%dx%d@+%d+%d\n",
143 drawable_private->xwindow,
145 (filled ? "fill " : ""),
146 width, height, x, y));
150 HBRUSH hbr = GetCurrentObject (hdc, OBJ_BRUSH);
151 HPEN hpen = GetCurrentObject (hdc, OBJ_PEN);
154 GetObject (hbr, sizeof (lbr), &lbr);
155 GetObject (hpen, sizeof (lpen), &lpen);
157 g_print ("current brush: style = %s, color = 0x%.08x\n",
158 (lbr.lbStyle == BS_SOLID ? "SOLID" : "???"),
160 g_print ("current pen: style = %s, width = %d, color = 0x%.08x\n",
161 (lpen.lopnStyle == PS_SOLID ? "SOLID" : "???"),
168 oldpen = SelectObject (hdc, GetStockObject (NULL_PEN));
170 oldbrush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
172 if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
173 g_warning ("gdk_draw_rectangle: Rectangle failed");
176 SelectObject (hdc, oldpen);
178 SelectObject (hdc, oldbrush);
180 gdk_gc_postdraw (drawable_private, gc_private);
184 gdk_draw_arc (GdkDrawable *drawable,
194 GdkWindowPrivate *drawable_private;
195 GdkGCPrivate *gc_private;
197 int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
199 g_return_if_fail (drawable != NULL);
200 g_return_if_fail (gc != NULL);
202 drawable_private = (GdkWindowPrivate*) drawable;
203 if (drawable_private->destroyed)
205 gc_private = (GdkGCPrivate*) gc;
208 width = drawable_private->width;
210 height = drawable_private->height;
212 hdc = gdk_gc_predraw (drawable_private, gc_private);
214 nXStartArc = x + width/2 + (int) (sin(angle1/64.*M_TWOPI)*width);
215 nYStartArc = y + height/2 + (int) (cos(angle1/64.*M_TWOPI)*height);
216 nXEndArc = x + width/2 + (int) (sin(angle2/64.*M_TWOPI)*width);
217 nYEndArc = y + height/2 + (int) (cos(angle2/64.*M_TWOPI)*height);
221 if (!Pie (hdc, x, y, x+width, y+height,
222 nXStartArc, nYStartArc, nXEndArc, nYEndArc))
223 g_warning ("gdk_draw_arc: Pie failed");
227 if (!Arc (hdc, x, y, x+width, y+height,
228 nXStartArc, nYStartArc, nXEndArc, nYEndArc))
229 g_warning ("gdk_draw_arc: Arc failed");
231 gdk_gc_postdraw (drawable_private, gc_private);
235 gdk_draw_polygon (GdkDrawable *drawable,
241 GdkWindowPrivate *drawable_private;
242 GdkGCPrivate *gc_private;
247 g_return_if_fail (drawable != NULL);
248 g_return_if_fail (gc != NULL);
250 drawable_private = (GdkWindowPrivate*) drawable;
251 if (drawable_private->destroyed)
253 gc_private = (GdkGCPrivate*) gc;
255 hdc = gdk_gc_predraw (drawable_private, gc_private);
256 pts = g_malloc ((npoints+1) * sizeof (POINT));
258 GDK_NOTE (MISC, g_print ("gdk_draw_polygon: %#x (%d) %d\n",
259 drawable_private->xwindow, gc_private,
262 for (i = 0; i < npoints; i++)
264 pts[i].x = points[i].x;
265 pts[i].y = points[i].y;
268 if ((points[0].x != points[npoints-1].x) ||
269 (points[0].y != points[npoints-1].y))
271 pts[npoints].x = points[0].x;
272 pts[npoints].y = points[0].y;
277 if (!Polygon (hdc, pts, npoints))
278 g_warning ("gdk_draw_polygon: Polygon failed");
282 if (!Polyline (hdc, pts, npoints))
283 g_warning ("gdk_draw_polygon: Polyline failed");
286 gdk_gc_postdraw (drawable_private, gc_private);
292 gdk_draw_string (GdkDrawable *drawable,
299 gdk_draw_text (drawable, font, gc, x, y, string, strlen (string));
304 * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
306 * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
309 gdk_draw_text (GdkDrawable *drawable,
317 GdkWindowPrivate *drawable_private;
318 GdkFontPrivate *font_private;
319 GdkGCPrivate *gc_private;
324 g_return_if_fail (drawable != NULL);
325 g_return_if_fail (font != NULL);
326 g_return_if_fail (gc != NULL);
327 g_return_if_fail (text != NULL);
329 drawable_private = (GdkWindowPrivate*) drawable;
330 if (drawable_private->destroyed)
332 gc_private = (GdkGCPrivate*) gc;
333 font_private = (GdkFontPrivate*) font;
335 if (font->type == GDK_FONT_FONT)
337 hdc = gdk_gc_predraw (drawable_private, gc_private);
338 xfont = (HFONT) font_private->xfont;
340 GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
341 "+%d+%d font: %#x \"%.*s\" length: %d\n",
342 drawable_private->xwindow,
343 gc_private, gc_private->xgc,
345 (text_length > 10 ? 10 : text_length),
348 if ((oldfont = SelectObject (hdc, xfont)) == NULL)
349 g_warning ("gdk_draw_text: SelectObject failed");
350 if (!TextOutA (hdc, x, y, text, text_length))
351 g_warning ("gdk_draw_text: TextOutA failed");
352 SelectObject (hdc, oldfont);
353 gdk_gc_postdraw (drawable_private, gc_private);
356 g_error ("undefined font type");
360 gdk_draw_text_wc (GdkDrawable *drawable,
365 const GdkWChar *text,
368 GdkWindowPrivate *drawable_private;
369 GdkFontPrivate *font_private;
370 GdkGCPrivate *gc_private;
374 g_return_if_fail (drawable != NULL);
375 g_return_if_fail (font != NULL);
376 g_return_if_fail (gc != NULL);
377 g_return_if_fail (text != NULL);
379 drawable_private = (GdkWindowPrivate*) drawable;
380 if (drawable_private->destroyed)
382 gc_private = (GdkGCPrivate*) gc;
383 font_private = (GdkFontPrivate*) font;
385 if (font->type == GDK_FONT_FONT)
391 hdc = gdk_gc_predraw (drawable_private, gc_private);
392 xfont = (HFONT) font_private->xfont;
394 GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
395 "+%d+%d font: %#x length: %d\n",
396 drawable_private->xwindow,
397 gc_private, gc_private->xgc,
401 if ((oldfont = SelectObject (hdc, xfont)) == NULL)
402 g_warning ("gdk_draw_text: SelectObject failed");
403 wcstr = g_new (wchar_t, text_length);
404 for (i = 0; i < text_length; i++)
406 if (!TextOutW (hdc, x, y, wcstr, text_length))
407 g_warning ("gdk_draw_text: TextOutW failed");
409 SelectObject (hdc, oldfont);
410 gdk_gc_postdraw (drawable_private, gc_private);
413 g_error ("undefined font type");
417 gdk_draw_pixmap (GdkDrawable *drawable,
427 GdkWindowPrivate *drawable_private;
428 GdkWindowPrivate *src_private;
429 GdkGCPrivate *gc_private;
434 g_return_if_fail (drawable != NULL);
435 g_return_if_fail (src != NULL);
436 g_return_if_fail (gc != NULL);
438 drawable_private = (GdkWindowPrivate*) drawable;
439 src_private = (GdkWindowPrivate*) src;
440 if (drawable_private->destroyed || src_private->destroyed)
442 gc_private = (GdkGCPrivate*) gc;
445 width = src_private->width;
447 height = src_private->height;
449 hdc = gdk_gc_predraw (drawable_private, gc_private);
451 GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x destdc: (%d) %#x "
452 "src: %#x %dx%d@+%d+%d\n",
453 drawable_private->xwindow, gc_private, hdc,
454 src_private->xwindow,
455 width, height, xdest, ydest));
457 /* Strangely enough, this function is called also to bitblt
460 if (src_private->window_type == GDK_WINDOW_PIXMAP)
462 if ((srcdc = CreateCompatibleDC (hdc)) == NULL)
463 g_warning ("gdk_draw_pixmap: CreateCompatibleDC failed");
465 if ((hgdiobj = SelectObject (srcdc, src_private->xwindow)) == NULL)
466 g_warning ("gdk_draw_pixmap: SelectObject #1 failed");
468 if (!BitBlt (hdc, xdest, ydest, width, height,
469 srcdc, xsrc, ysrc, SRCCOPY))
470 g_warning ("gdk_draw_pixmap: BitBlt failed");
472 if ((SelectObject (srcdc, hgdiobj) == NULL))
473 g_warning ("gdk_draw_pixmap: SelectObject #2 failed");
475 if (!DeleteDC (srcdc))
476 g_warning ("gdk_draw_pixmap: DeleteDC failed");
480 if ((srcdc = GetDC (src_private->xwindow)) == NULL)
481 g_warning ("gdk_draw_pixmap: GetDC failed");
483 if (!BitBlt (hdc, xdest, ydest, width, height,
484 srcdc, xsrc, ysrc, SRCCOPY))
485 g_warning ("gdk_draw_pixmap: BitBlt failed");
487 ReleaseDC (src_private->xwindow, srcdc);
489 gdk_gc_postdraw (drawable_private, gc_private);
493 gdk_draw_image (GdkDrawable *drawable,
503 GdkImagePrivate *image_private;
505 g_return_if_fail (drawable != NULL);
506 g_return_if_fail (image != NULL);
507 g_return_if_fail (gc != NULL);
509 image_private = (GdkImagePrivate*) image;
511 g_return_if_fail (image_private->image_put != NULL);
514 width = image->width;
516 height = image->height;
518 (* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
519 xdest, ydest, width, height);
523 gdk_draw_points (GdkDrawable *drawable,
528 GdkWindowPrivate *drawable_private;
529 GdkGCPrivate *gc_private;
534 g_return_if_fail (drawable != NULL);
535 g_return_if_fail ((points != NULL) && (npoints > 0));
536 g_return_if_fail (gc != NULL);
538 drawable_private = (GdkWindowPrivate*) drawable;
539 if (drawable_private->destroyed)
541 gc_private = (GdkGCPrivate*) gc;
543 hdc = gdk_gc_predraw (drawable_private, gc_private);
544 hbr = GetCurrentObject (hdc, OBJ_BRUSH);
546 for (i = 0; i < npoints; i++)
550 rect.left = points[i].x;
551 rect.top = points[i].y;
552 rect.right = rect.left + 1;
553 rect.bottom = rect.top + 1;
554 if (!FillRect (hdc, &rect, hbr))
555 g_warning ("gdk_draw_points: FillRect failed");
557 gdk_gc_postdraw (drawable_private, gc_private);
561 gdk_draw_segments (GdkDrawable *drawable,
566 GdkWindowPrivate *drawable_private;
567 GdkGCPrivate *gc_private;
574 g_return_if_fail (drawable != NULL);
575 g_return_if_fail (segs != NULL);
576 g_return_if_fail (gc != NULL);
578 drawable_private = (GdkWindowPrivate*) drawable;
579 if (drawable_private->destroyed)
581 gc_private = (GdkGCPrivate*) gc;
583 hdc = gdk_gc_predraw (drawable_private, gc_private);
585 for (i = 0; i < nsegs; i++)
587 MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL);
588 if (!LineTo (hdc, segs[i].x2, segs[i].y2))
589 g_warning ("gdk_draw_segments: LineTo #1 failed");
592 if (gc_private->pen_width == 1)
593 if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
594 g_warning ("gdk_draw_segments: LineTo #2 failed");
596 gdk_gc_postdraw (drawable_private, gc_private);
600 gdk_draw_lines (GdkDrawable *drawable,
605 GdkWindowPrivate *drawable_private;
606 GdkGCPrivate *gc_private;
614 g_return_if_fail (drawable != NULL);
615 g_return_if_fail (points != NULL);
616 g_return_if_fail (gc != NULL);
618 drawable_private = (GdkWindowPrivate*) drawable;
619 gc_private = (GdkGCPrivate*) gc;
621 hdc = gdk_gc_predraw (drawable_private, gc_private);
623 pts = g_malloc (npoints * sizeof (POINT));
625 for (i = 0; i < npoints; i++)
627 pts[i].x = points[i].x;
628 pts[i].y = points[i].y;
631 if (!Polyline (hdc, pts, npoints))
632 g_warning ("gdk_draw_lines: Polyline failed");
637 if (gc_private->pen_width == 1)
639 MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
640 if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
641 g_warning ("gdk_draw_lines: LineTo failed");
644 MoveToEx (hdc, points[0].x, points[0].y, NULL);
645 for (i = 1; i < npoints; i++)
646 if (!LineTo (hdc, points[i].x, points[i].y))
647 g_warning ("gdk_draw_lines: LineTo #1 failed");
650 if (gc_private->pen_width == 1)
651 if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
652 g_warning ("gdk_draw_lines: LineTo #2 failed");
654 gdk_gc_postdraw (drawable_private, gc_private);