]> Pileus Git - ~andy/gtk/blob - gdk/gdkdraw.c
Added notice to look in AUTHORS and ChangeLog files for a list of changes.
[~andy/gtk] / gdk / 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 <X11/Xlib.h>
28 #include <X11/Xos.h>
29 #include "gdk.h"
30 #include "gdkprivate.h"
31
32
33 void
34 gdk_draw_point (GdkDrawable *drawable,
35                 GdkGC       *gc,
36                 gint         x,
37                 gint         y)
38 {
39   GdkWindowPrivate *drawable_private;
40   GdkGCPrivate *gc_private;
41
42   g_return_if_fail (drawable != NULL);
43   g_return_if_fail (gc != NULL);
44
45   drawable_private = (GdkWindowPrivate*) drawable;
46   if (drawable_private->destroyed)
47     return;
48   gc_private = (GdkGCPrivate*) gc;
49
50   XDrawPoint (drawable_private->xdisplay, drawable_private->xwindow,
51               gc_private->xgc, x, y);
52 }
53
54 void
55 gdk_draw_line (GdkDrawable *drawable,
56                GdkGC       *gc,
57                gint         x1,
58                gint         y1,
59                gint         x2,
60                gint         y2)
61 {
62   GdkWindowPrivate *drawable_private;
63   GdkGCPrivate *gc_private;
64
65   g_return_if_fail (drawable != NULL);
66   g_return_if_fail (gc != NULL);
67
68   drawable_private = (GdkWindowPrivate*) drawable;
69   if (drawable_private->destroyed)
70     return;
71   gc_private = (GdkGCPrivate*) gc;
72
73   XDrawLine (drawable_private->xdisplay, drawable_private->xwindow,
74              gc_private->xgc, x1, y1, x2, y2);
75 }
76
77 void
78 gdk_draw_rectangle (GdkDrawable *drawable,
79                     GdkGC       *gc,
80                     gint         filled,
81                     gint         x,
82                     gint         y,
83                     gint         width,
84                     gint         height)
85 {
86   GdkWindowPrivate *drawable_private;
87   GdkGCPrivate *gc_private;
88
89   g_return_if_fail (drawable != NULL);
90   g_return_if_fail (gc != NULL);
91
92   drawable_private = (GdkWindowPrivate*) drawable;
93   if (drawable_private->destroyed)
94     return;
95   gc_private = (GdkGCPrivate*) gc;
96
97   if (width == -1)
98     width = drawable_private->width;
99   if (height == -1)
100     height = drawable_private->height;
101
102   if (filled)
103     XFillRectangle (drawable_private->xdisplay, drawable_private->xwindow,
104                     gc_private->xgc, x, y, width, height);
105   else
106     XDrawRectangle (drawable_private->xdisplay, drawable_private->xwindow,
107                     gc_private->xgc, x, y, width, height);
108 }
109
110 void
111 gdk_draw_arc (GdkDrawable *drawable,
112               GdkGC       *gc,
113               gint         filled,
114               gint         x,
115               gint         y,
116               gint         width,
117               gint         height,
118               gint         angle1,
119               gint         angle2)
120 {
121   GdkWindowPrivate *drawable_private;
122   GdkGCPrivate *gc_private;
123
124   g_return_if_fail (drawable != NULL);
125   g_return_if_fail (gc != NULL);
126
127   drawable_private = (GdkWindowPrivate*) drawable;
128   if (drawable_private->destroyed)
129     return;
130   gc_private = (GdkGCPrivate*) gc;
131
132   if (width == -1)
133     width = drawable_private->width;
134   if (height == -1)
135     height = drawable_private->height;
136
137   if (filled)
138     XFillArc (drawable_private->xdisplay, drawable_private->xwindow,
139               gc_private->xgc, x, y, width, height, angle1, angle2);
140   else
141     XDrawArc (drawable_private->xdisplay, drawable_private->xwindow,
142               gc_private->xgc, x, y, width, height, angle1, angle2);
143 }
144
145 void
146 gdk_draw_polygon (GdkDrawable *drawable,
147                   GdkGC       *gc,
148                   gint         filled,
149                   GdkPoint    *points,
150                   gint         npoints)
151 {
152   GdkWindowPrivate *drawable_private;
153   GdkGCPrivate *gc_private;
154   GdkPoint *local_points = points;
155   gint local_npoints = npoints;
156   gint local_alloc = 0;
157
158   g_return_if_fail (drawable != NULL);
159   g_return_if_fail (gc != NULL);
160
161   drawable_private = (GdkWindowPrivate*) drawable;
162   if (drawable_private->destroyed)
163     return;
164   gc_private = (GdkGCPrivate*) gc;
165
166   if (filled)
167     {
168       XFillPolygon (drawable_private->xdisplay, drawable_private->xwindow,
169                     gc_private->xgc, (XPoint*) points, npoints, Complex, CoordModeOrigin);
170     }
171   else
172     {
173       if ((points[0].x != points[npoints-1].x) ||
174         (points[0].y != points[npoints-1].y)) 
175         {
176           local_alloc = 1;
177           ++local_npoints;
178           local_points = (GdkPoint*) g_malloc (local_npoints * sizeof(GdkPoint));
179           memcpy (local_points, points, npoints * sizeof(GdkPoint));
180           local_points[npoints].x = points[0].x;
181           local_points[npoints].y = points[0].y;
182       }
183
184       XDrawLines (drawable_private->xdisplay, drawable_private->xwindow,
185                  gc_private->xgc,
186                  (XPoint*) local_points, local_npoints,
187                  CoordModeOrigin);
188   
189        if (local_alloc)
190        g_free (local_points);
191     }
192 }
193
194 /* gdk_draw_string
195  *
196  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
197  *
198  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
199  */
200 void
201 gdk_draw_string (GdkDrawable *drawable,
202                  GdkFont     *font,
203                  GdkGC       *gc,
204                  gint         x,
205                  gint         y,
206                  const gchar *string)
207 {
208   GdkWindowPrivate *drawable_private;
209   GdkFontPrivate *font_private;
210   GdkGCPrivate *gc_private;
211
212   g_return_if_fail (drawable != NULL);
213   g_return_if_fail (font != NULL);
214   g_return_if_fail (gc != NULL);
215   g_return_if_fail (string != NULL);
216
217   drawable_private = (GdkWindowPrivate*) drawable;
218   if (drawable_private->destroyed)
219     return;
220   gc_private = (GdkGCPrivate*) gc;
221   font_private = (GdkFontPrivate*) font;
222
223   if (font->type == GDK_FONT_FONT)
224     {
225       XFontStruct *xfont = (XFontStruct *) font_private->xfont;
226       XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);
227       if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
228         {
229           XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
230                        gc_private->xgc, x, y, string, strlen (string));
231         }
232       else
233         {
234           XDrawString16 (drawable_private->xdisplay, drawable_private->xwindow,
235                          gc_private->xgc, x, y, (XChar2b *) string,
236                          strlen (string) / 2);
237         }
238     }
239   else if (font->type == GDK_FONT_FONTSET)
240     {
241       XFontSet fontset = (XFontSet) font_private->xfont;
242       XmbDrawString (drawable_private->xdisplay, drawable_private->xwindow,
243                      fontset, gc_private->xgc, x, y, string, strlen (string));
244     }
245   else
246     g_error("undefined font type\n");
247 }
248
249 /* gdk_draw_text
250  *
251  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
252  *
253  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
254  */
255 void
256 gdk_draw_text (GdkDrawable *drawable,
257                GdkFont     *font,
258                GdkGC       *gc,
259                gint         x,
260                gint         y,
261                const gchar *text,
262                gint         text_length)
263 {
264   GdkWindowPrivate *drawable_private;
265   GdkFontPrivate *font_private;
266   GdkGCPrivate *gc_private;
267
268   g_return_if_fail (drawable != NULL);
269   g_return_if_fail (font != NULL);
270   g_return_if_fail (gc != NULL);
271   g_return_if_fail (text != NULL);
272
273   drawable_private = (GdkWindowPrivate*) drawable;
274   if (drawable_private->destroyed)
275     return;
276   gc_private = (GdkGCPrivate*) gc;
277   font_private = (GdkFontPrivate*) font;
278
279   if (font->type == GDK_FONT_FONT)
280     {
281       XFontStruct *xfont = (XFontStruct *) font_private->xfont;
282       XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);
283       if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
284         {
285           XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
286                        gc_private->xgc, x, y, text, text_length);
287         }
288       else
289         {
290           XDrawString16 (drawable_private->xdisplay, drawable_private->xwindow,
291                          gc_private->xgc, x, y, (XChar2b *) text, text_length / 2);
292         }
293     }
294   else if (font->type == GDK_FONT_FONTSET)
295     {
296       XFontSet fontset = (XFontSet) font_private->xfont;
297       XmbDrawString (drawable_private->xdisplay, drawable_private->xwindow,
298                      fontset, gc_private->xgc, x, y, text, text_length);
299     }
300   else
301     g_error("undefined font type\n");
302 }
303
304 void
305 gdk_draw_text_wc (GdkDrawable    *drawable,
306                   GdkFont        *font,
307                   GdkGC          *gc,
308                   gint            x,
309                   gint            y,
310                   const GdkWChar *text,
311                   gint            text_length)
312 {
313   GdkWindowPrivate *drawable_private;
314   GdkFontPrivate *font_private;
315   GdkGCPrivate *gc_private;
316
317   g_return_if_fail (drawable != NULL);
318   g_return_if_fail (font != NULL);
319   g_return_if_fail (gc != NULL);
320   g_return_if_fail (text != NULL);
321
322   drawable_private = (GdkWindowPrivate*) drawable;
323   if (drawable_private->destroyed)
324     return;
325   gc_private = (GdkGCPrivate*) gc;
326   font_private = (GdkFontPrivate*) font;
327
328   if (font->type == GDK_FONT_FONT)
329     {
330       XFontStruct *xfont = (XFontStruct *) font_private->xfont;
331       gchar *text_8bit;
332       gint i;
333       XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);
334       text_8bit = g_new (gchar, text_length);
335       for (i=0; i<text_length; i++) text_8bit[i] = text[i];
336       XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
337                    gc_private->xgc, x, y, text_8bit, text_length);
338       g_free (text_8bit);
339     }
340   else if (font->type == GDK_FONT_FONTSET)
341     {
342       if (sizeof(GdkWChar) == sizeof(wchar_t))
343         {
344           XwcDrawString (drawable_private->xdisplay, drawable_private->xwindow,
345                          (XFontSet) font_private->xfont,
346                          gc_private->xgc, x, y, (wchar_t *)text, text_length);
347         }
348       else
349         {
350           wchar_t *text_wchar;
351           gint i;
352           text_wchar = g_new (wchar_t, text_length);
353           for (i=0; i<text_length; i++) text_wchar[i] = text[i];
354           XwcDrawString (drawable_private->xdisplay, drawable_private->xwindow,
355                          (XFontSet) font_private->xfont,
356                          gc_private->xgc, x, y, text_wchar, text_length);
357           g_free (text_wchar);
358         }
359     }
360   else
361     g_error("undefined font type\n");
362 }
363
364 void
365 gdk_draw_pixmap (GdkDrawable *drawable,
366                  GdkGC       *gc,
367                  GdkPixmap   *src,
368                  gint         xsrc,
369                  gint         ysrc,
370                  gint         xdest,
371                  gint         ydest,
372                  gint         width,
373                  gint         height)
374 {
375   GdkWindowPrivate *drawable_private;
376   GdkWindowPrivate *src_private;
377   GdkGCPrivate *gc_private;
378
379   g_return_if_fail (drawable != NULL);
380   g_return_if_fail (src != NULL);
381   g_return_if_fail (gc != NULL);
382
383   drawable_private = (GdkWindowPrivate*) drawable;
384   src_private = (GdkWindowPrivate*) src;
385   if (drawable_private->destroyed || src_private->destroyed)
386     return;
387   gc_private = (GdkGCPrivate*) gc;
388
389   if (width == -1)
390     width = src_private->width;
391   if (height == -1)
392     height = src_private->height;
393
394   XCopyArea (drawable_private->xdisplay,
395              src_private->xwindow,
396              drawable_private->xwindow,
397              gc_private->xgc,
398              xsrc, ysrc,
399              width, height,
400              xdest, ydest);
401 }
402
403 void
404 gdk_draw_image (GdkDrawable *drawable,
405                 GdkGC       *gc,
406                 GdkImage    *image,
407                 gint         xsrc,
408                 gint         ysrc,
409                 gint         xdest,
410                 gint         ydest,
411                 gint         width,
412                 gint         height)
413 {
414   GdkImagePrivate *image_private;
415
416   g_return_if_fail (drawable != NULL);
417   g_return_if_fail (image != NULL);
418   g_return_if_fail (gc != NULL);
419
420   image_private = (GdkImagePrivate*) image;
421
422   g_return_if_fail (image_private->image_put != NULL);
423
424   if (width == -1)
425     width = image->width;
426   if (height == -1)
427     height = image->height;
428
429   (* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
430                                 xdest, ydest, width, height);
431 }
432
433 void
434 gdk_draw_points (GdkDrawable *drawable,
435                  GdkGC       *gc,
436                  GdkPoint    *points,
437                  gint         npoints)
438 {
439   GdkWindowPrivate *drawable_private;
440   GdkGCPrivate *gc_private;
441
442   g_return_if_fail (drawable != NULL);
443   g_return_if_fail ((points != NULL) && (npoints > 0));
444   g_return_if_fail (gc != NULL);
445
446   drawable_private = (GdkWindowPrivate*) drawable;
447   if (drawable_private->destroyed)
448     return;
449   gc_private = (GdkGCPrivate*) gc;
450
451   XDrawPoints (drawable_private->xdisplay,
452                drawable_private->xwindow,
453                gc_private->xgc,
454                (XPoint *) points,
455                npoints,
456                CoordModeOrigin);
457 }
458
459 void
460 gdk_draw_segments (GdkDrawable *drawable,
461                    GdkGC       *gc,
462                    GdkSegment  *segs,
463                    gint         nsegs)
464 {
465   GdkWindowPrivate *drawable_private;
466   GdkGCPrivate *gc_private;
467
468   if (nsegs <= 0)
469     return;
470
471   g_return_if_fail (drawable != NULL);
472   g_return_if_fail (segs != NULL);
473   g_return_if_fail (gc != NULL);
474
475   drawable_private = (GdkWindowPrivate*) drawable;
476   if (drawable_private->destroyed)
477     return;
478   gc_private = (GdkGCPrivate*) gc;
479
480   XDrawSegments (drawable_private->xdisplay,
481                  drawable_private->xwindow,
482                  gc_private->xgc,
483                  (XSegment *) segs,
484                  nsegs);
485 }
486
487 void
488 gdk_draw_lines (GdkDrawable *drawable,
489               GdkGC       *gc,
490               GdkPoint    *points,
491               gint         npoints)
492 {
493   GdkWindowPrivate *drawable_private;
494   GdkGCPrivate *gc_private;
495
496   if (npoints <= 0)
497     return;
498
499   g_return_if_fail (drawable != NULL);
500   g_return_if_fail (points != NULL);
501   g_return_if_fail (gc != NULL);
502
503   drawable_private = (GdkWindowPrivate*) drawable;
504   gc_private = (GdkGCPrivate*) gc;
505
506   XDrawLines (drawable_private->xdisplay,
507             drawable_private->xwindow,
508             gc_private->xgc,
509             (XPoint *) points,
510             npoints,
511             CoordModeOrigin);
512 }