]> Pileus Git - ~andy/gtk/blob - gdk/gdkdraw.c
03517f48a06353670eced1b955ec3c8c685169cd
[~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 "gdkdrawable.h"
28 #include "gdkinternals.h"
29 #include "gdkwindow.h"
30
31 /* Manipulation of drawables
32  */
33 GdkDrawable *
34 gdk_drawable_alloc (void)
35 {
36   GdkDrawablePrivate *private = g_new (GdkDrawablePrivate, 1);
37   GdkDrawable *drawable = (GdkDrawable*) private;
38   
39   drawable->user_data = NULL;
40
41   private->ref_count = 1;
42   private->destroyed = FALSE;
43   private->klass = NULL;
44   private->klass_data = NULL;
45   private->window_type = GDK_WINDOW_CHILD;
46
47   private->width = 1;
48   private->height = 1;
49
50   private->depth = 0;
51
52   private->colormap = NULL;
53
54   return drawable;
55 }
56
57 void          
58 gdk_drawable_set_data (GdkDrawable   *drawable,
59                        const gchar   *key,
60                        gpointer       data,
61                        GDestroyNotify destroy_func)
62 {
63   g_dataset_set_data_full (drawable, key, data, destroy_func);
64 }
65
66 gpointer
67 gdk_drawable_get_data (GdkDrawable   *drawable,
68                        const gchar   *key)
69 {
70   return g_dataset_get_data (drawable, key);
71 }
72
73 GdkDrawableType
74 gdk_drawable_get_type (GdkDrawable *drawable)
75 {
76   g_return_val_if_fail (drawable != NULL, (GdkDrawableType) -1);
77   
78   return GDK_DRAWABLE_TYPE (drawable);
79 }
80
81 void
82 gdk_drawable_get_size (GdkDrawable *drawable,
83                        gint        *width,
84                        gint        *height)
85 {
86   GdkDrawablePrivate *drawable_private;
87   
88   g_return_if_fail (drawable != NULL);
89   
90   drawable_private = (GdkDrawablePrivate*) drawable;
91   
92   if (width)
93     *width = drawable_private->width;
94   if (height)
95     *height = drawable_private->height;
96 }
97
98 GdkVisual*
99 gdk_drawable_get_visual (GdkDrawable *drawable)
100 {
101   GdkColormap *colormap;
102
103   g_return_val_if_fail (drawable != NULL, NULL);
104
105   colormap = gdk_drawable_get_colormap (drawable);
106   return colormap ? gdk_colormap_get_visual (colormap) : NULL;
107 }
108
109 gint
110 gdk_drawable_get_depth (GdkDrawable *drawable)
111 {
112   GdkDrawablePrivate *private = (GdkDrawablePrivate *)drawable;
113   g_return_val_if_fail (drawable != NULL, 0);
114
115   return private->depth;
116 }
117
118 GdkDrawable*
119 gdk_drawable_ref (GdkDrawable *drawable)
120 {
121   GdkDrawablePrivate *private = (GdkDrawablePrivate *)drawable;
122   g_return_val_if_fail (drawable != NULL, NULL);
123   
124   private->ref_count += 1;
125   return drawable;
126 }
127
128 void
129 gdk_drawable_unref (GdkDrawable *drawable)
130 {
131   GdkDrawablePrivate *private = (GdkDrawablePrivate *)drawable;
132   
133   g_return_if_fail (drawable != NULL);
134   g_return_if_fail (private->ref_count > 0);
135   
136   private->ref_count -= 1;
137   if (private->ref_count == 0)
138     {
139       private->klass->destroy (drawable);
140       g_dataset_destroy (drawable);
141       g_free (drawable);
142     }
143 }
144
145 /* Drawing
146  */
147 void
148 gdk_draw_point (GdkDrawable *drawable,
149                 GdkGC       *gc,
150                 gint         x,
151                 gint         y)
152 {
153   GdkGCPrivate *gc_private;
154   GdkPoint point;
155
156   g_return_if_fail (drawable != NULL);
157   g_return_if_fail (gc != NULL);
158
159   if (GDK_DRAWABLE_DESTROYED (drawable))
160     return;
161   gc_private = (GdkGCPrivate*) gc;
162
163   point.x = x;
164   point.y = y;
165   
166   ((GdkDrawablePrivate *)drawable)->klass->draw_points (drawable, gc, &point, 1);
167 }
168
169 void
170 gdk_draw_line (GdkDrawable *drawable,
171                GdkGC       *gc,
172                gint         x1,
173                gint         y1,
174                gint         x2,
175                gint         y2)
176 {
177   GdkGCPrivate *gc_private;
178   GdkSegment segment;
179
180   g_return_if_fail (drawable != NULL);
181   g_return_if_fail (gc != NULL);
182
183   if (GDK_DRAWABLE_DESTROYED (drawable))
184     return;
185   gc_private = (GdkGCPrivate*) gc;
186
187   segment.x1 = x1;
188   segment.y1 = y1;
189   segment.x2 = x2;
190   segment.y2 = y2;
191   ((GdkDrawablePrivate *)drawable)->klass->draw_segments (drawable, gc, &segment, 1);
192 }
193
194 void
195 gdk_draw_rectangle (GdkDrawable *drawable,
196                     GdkGC       *gc,
197                     gint         filled,
198                     gint         x,
199                     gint         y,
200                     gint         width,
201                     gint         height)
202 {
203   GdkDrawablePrivate *drawable_private;
204
205   g_return_if_fail (drawable != NULL);
206   g_return_if_fail (gc != NULL);
207
208   drawable_private = (GdkDrawablePrivate*) drawable;
209   if (GDK_DRAWABLE_DESTROYED (drawable))
210     return;
211
212   if (width < 0)
213     width = drawable_private->width;
214   if (height < 0)
215     height = drawable_private->height;
216
217   ((GdkDrawablePrivate *)drawable)->klass->draw_rectangle (drawable, gc, filled, x, y,
218                                                            width, height);
219 }
220
221 void
222 gdk_draw_arc (GdkDrawable *drawable,
223               GdkGC       *gc,
224               gint         filled,
225               gint         x,
226               gint         y,
227               gint         width,
228               gint         height,
229               gint         angle1,
230               gint         angle2)
231 {
232   GdkDrawablePrivate *drawable_private;
233   GdkGCPrivate *gc_private;
234
235   g_return_if_fail (drawable != NULL);
236   g_return_if_fail (gc != NULL);
237
238   drawable_private = (GdkDrawablePrivate*) drawable;
239   if (GDK_DRAWABLE_DESTROYED (drawable))
240     return;
241   gc_private = (GdkGCPrivate*) gc;
242
243   if (width < 0)
244     width = drawable_private->width;
245   if (height < 0)
246     height = drawable_private->height;
247
248   ((GdkDrawablePrivate *)drawable)->klass->draw_arc (drawable, gc, filled,
249                                                      x, y, width, height, angle1, angle2);
250 }
251
252 void
253 gdk_draw_polygon (GdkDrawable *drawable,
254                   GdkGC       *gc,
255                   gint         filled,
256                   GdkPoint    *points,
257                   gint         npoints)
258 {
259   g_return_if_fail (drawable != NULL);
260   g_return_if_fail (gc != NULL);
261
262   if (GDK_DRAWABLE_DESTROYED (drawable))
263     return;
264
265   ((GdkDrawablePrivate *)drawable)->klass->draw_polygon (drawable, gc, filled,
266                                                          points, npoints);
267 }
268
269 /* gdk_draw_string
270  *
271  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
272  *
273  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
274  */
275 void
276 gdk_draw_string (GdkDrawable *drawable,
277                  GdkFont     *font,
278                  GdkGC       *gc,
279                  gint         x,
280                  gint         y,
281                  const gchar *string)
282 {
283   gdk_draw_text (drawable, font, gc, x, y, string, _gdk_font_strlen (font, string));
284 }
285
286 /* gdk_draw_text
287  *
288  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
289  *
290  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
291  */
292 void
293 gdk_draw_text (GdkDrawable *drawable,
294                GdkFont     *font,
295                GdkGC       *gc,
296                gint         x,
297                gint         y,
298                const gchar *text,
299                gint         text_length)
300 {
301   g_return_if_fail (drawable != NULL);
302   g_return_if_fail (font != NULL);
303   g_return_if_fail (gc != NULL);
304   g_return_if_fail (text != NULL);
305
306   ((GdkDrawablePrivate *)drawable)->klass->draw_text (drawable, font, gc, x, y, text, text_length);
307 }
308
309 void
310 gdk_draw_text_wc (GdkDrawable    *drawable,
311                   GdkFont        *font,
312                   GdkGC          *gc,
313                   gint            x,
314                   gint            y,
315                   const GdkWChar *text,
316                   gint            text_length)
317 {
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);
322
323   ((GdkDrawablePrivate *)drawable)->klass->draw_text_wc (drawable, font, gc, x, y, text, text_length);
324 }
325
326 void
327 gdk_draw_drawable (GdkDrawable *drawable,
328                    GdkGC       *gc,
329                    GdkDrawable *src,
330                    gint         xsrc,
331                    gint         ysrc,
332                    gint         xdest,
333                    gint         ydest,
334                    gint         width,
335                    gint         height)
336 {
337   g_return_if_fail (drawable != NULL);
338   g_return_if_fail (src != NULL);
339   g_return_if_fail (gc != NULL);
340
341   if (GDK_DRAWABLE_DESTROYED (drawable) || GDK_DRAWABLE_DESTROYED (src))
342     return;
343
344   if (width == -1)
345     width = ((GdkDrawablePrivate *)src)->width;
346   if (height == -1)
347     height = ((GdkDrawablePrivate *)src)->height;
348
349   ((GdkDrawablePrivate *)drawable)->klass->draw_drawable (drawable, gc, src,
350                                                           xsrc, ysrc, xdest, ydest,
351                                                           width, height);
352 }
353
354 void
355 gdk_draw_image (GdkDrawable *drawable,
356                 GdkGC       *gc,
357                 GdkImage    *image,
358                 gint         xsrc,
359                 gint         ysrc,
360                 gint         xdest,
361                 gint         ydest,
362                 gint         width,
363                 gint         height)
364 {
365   GdkImagePrivate *image_private;
366
367   g_return_if_fail (drawable != NULL);
368   g_return_if_fail (image != NULL);
369   g_return_if_fail (gc != NULL);
370
371   image_private = (GdkImagePrivate*) image;
372
373   if (width == -1)
374     width = image->width;
375   if (height == -1)
376     height = image->height;
377
378
379   if (GDK_IS_WINDOW (drawable))
380     _gdk_window_draw_image (drawable, gc, image, xsrc, ysrc,
381                             xdest, ydest, width, height);
382   else
383     image_private->klass->image_put (image, drawable, gc, xsrc, ysrc,
384                                      xdest, ydest, width, height);
385 }
386
387 void
388 gdk_draw_points (GdkDrawable *drawable,
389                  GdkGC       *gc,
390                  GdkPoint    *points,
391                  gint         npoints)
392 {
393   g_return_if_fail (drawable != NULL);
394   g_return_if_fail ((points != NULL) && (npoints > 0));
395   g_return_if_fail (gc != NULL);
396   g_return_if_fail (npoints >= 0);
397
398   if (npoints == 0)
399     return;
400
401   if (GDK_DRAWABLE_DESTROYED (drawable))
402     return;
403
404   ((GdkDrawablePrivate *)drawable)->klass->draw_points (drawable, gc, points, npoints);
405 }
406
407 void
408 gdk_draw_segments (GdkDrawable *drawable,
409                    GdkGC       *gc,
410                    GdkSegment  *segs,
411                    gint         nsegs)
412 {
413   g_return_if_fail (drawable != NULL);
414
415   if (nsegs == 0)
416     return;
417
418   g_return_if_fail (segs != NULL);
419   g_return_if_fail (gc != NULL);
420   g_return_if_fail (nsegs >= 0);
421
422   if (GDK_DRAWABLE_DESTROYED (drawable))
423     return;
424
425   ((GdkDrawablePrivate *)drawable)->klass->draw_segments (drawable, gc, segs, nsegs);
426 }
427
428 void
429 gdk_draw_lines (GdkDrawable *drawable,
430                 GdkGC       *gc,
431                 GdkPoint    *points,
432                 gint         npoints)
433 {
434
435   g_return_if_fail (drawable != NULL);
436   g_return_if_fail (points != NULL);
437   g_return_if_fail (gc != NULL);
438   g_return_if_fail (npoints >= 0);
439
440   if (npoints == 0)
441     return;
442
443   if (GDK_DRAWABLE_DESTROYED (drawable))
444     return;
445
446   ((GdkDrawablePrivate *)drawable)->klass->draw_lines (drawable, gc, points, npoints);
447 }