]> Pileus Git - ~andy/gtk/blob - gdk/gdkdraw.c
urg, removed implementation of gtk_marshal_VOID__INT_INT_INT_INT. if
[~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 Lesser 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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-2000.  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 static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
32                                                               gint         x,
33                                                               gint         y,
34                                                               gint         width,
35                                                               gint         height,
36                                                               gint        *composite_x_offset,
37                                                               gint        *composite_y_offset);
38
39 static void gdk_drawable_class_init (GdkDrawableClass *klass);
40
41 GType
42 gdk_drawable_get_type (void)
43 {
44   static GType object_type = 0;
45
46   if (!object_type)
47     {
48       static const GTypeInfo object_info =
49       {
50         sizeof (GdkDrawableClass),
51         (GBaseInitFunc) NULL,
52         (GBaseFinalizeFunc) NULL,
53         (GClassInitFunc) gdk_drawable_class_init,
54         NULL,           /* class_finalize */
55         NULL,           /* class_data */
56         sizeof (GdkDrawable),
57         0,              /* n_preallocs */
58         (GInstanceInitFunc) NULL,
59       };
60       
61       object_type = g_type_register_static (G_TYPE_OBJECT,
62                                             "GdkDrawable",
63                                             &object_info, 0);
64     }  
65
66   return object_type;
67 }
68
69 static void
70 gdk_drawable_class_init (GdkDrawableClass *klass)
71 {
72   klass->get_composite_drawable = gdk_drawable_real_get_composite_drawable;
73 }
74
75 /* Manipulation of drawables
76  */
77
78 void          
79 gdk_drawable_set_data (GdkDrawable   *drawable,
80                        const gchar   *key,
81                        gpointer       data,
82                        GDestroyNotify destroy_func)
83 {
84   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
85   
86   g_object_set_qdata_full (G_OBJECT (drawable),
87                            g_quark_from_string (key),
88                            data,
89                            destroy_func);
90 }
91
92 gpointer
93 gdk_drawable_get_data (GdkDrawable   *drawable,
94                        const gchar   *key)
95 {
96   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
97   
98   return g_object_get_qdata (G_OBJECT (drawable),
99                              g_quark_try_string (key));
100 }
101
102 void
103 gdk_drawable_get_size (GdkDrawable *drawable,
104                        gint        *width,
105                        gint        *height)
106 {
107   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
108
109   GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height);  
110 }
111
112 GdkVisual*
113 gdk_drawable_get_visual (GdkDrawable *drawable)
114 {
115   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
116   
117   return GDK_DRAWABLE_GET_CLASS (drawable)->get_visual (drawable);
118 }
119
120 gint
121 gdk_drawable_get_depth (GdkDrawable *drawable)
122 {
123   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), 0);
124
125   return GDK_DRAWABLE_GET_CLASS (drawable)->get_depth (drawable);
126 }
127
128 void
129 gdk_drawable_set_colormap (GdkDrawable *drawable,
130                            GdkColormap *cmap)
131 {
132   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
133
134   GDK_DRAWABLE_GET_CLASS (drawable)->set_colormap (drawable, cmap);
135 }
136
137 GdkColormap*
138 gdk_drawable_get_colormap (GdkDrawable *drawable)
139 {
140   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
141
142   return GDK_DRAWABLE_GET_CLASS (drawable)->get_colormap (drawable);
143 }
144
145 GdkDrawable*
146 gdk_drawable_ref (GdkDrawable *drawable)
147 {
148   return (GdkDrawable *) g_object_ref (G_OBJECT (drawable));
149 }
150
151 void
152 gdk_drawable_unref (GdkDrawable *drawable)
153 {
154   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
155
156   g_object_unref (G_OBJECT (drawable));
157 }
158
159 /* Drawing
160  */
161 void
162 gdk_draw_point (GdkDrawable *drawable,
163                 GdkGC       *gc,
164                 gint         x,
165                 gint         y)
166 {
167   GdkPoint point;
168
169   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
170   g_return_if_fail (GDK_IS_GC (gc));
171
172   point.x = x;
173   point.y = y;
174   
175   GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, &point, 1);
176 }
177
178 void
179 gdk_draw_line (GdkDrawable *drawable,
180                GdkGC       *gc,
181                gint         x1,
182                gint         y1,
183                gint         x2,
184                gint         y2)
185 {
186   GdkSegment segment;
187
188   g_return_if_fail (drawable != NULL);
189   g_return_if_fail (gc != NULL);
190   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
191   g_return_if_fail (GDK_IS_GC (gc));
192
193   segment.x1 = x1;
194   segment.y1 = y1;
195   segment.x2 = x2;
196   segment.y2 = y2;
197   GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc, &segment, 1);
198 }
199
200 void
201 gdk_draw_rectangle (GdkDrawable *drawable,
202                     GdkGC       *gc,
203                     gint         filled,
204                     gint         x,
205                     gint         y,
206                     gint         width,
207                     gint         height)
208 {  
209   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
210   g_return_if_fail (GDK_IS_GC (gc));
211
212   if (width < 0 || height < 0)
213     {
214       gint real_width;
215       gint real_height;
216       
217       gdk_drawable_get_size (drawable, &real_width, &real_height);
218
219       if (width < 0)
220         width = real_width;
221       if (height < 0)
222         height = real_height;
223     }
224
225   GDK_DRAWABLE_GET_CLASS (drawable)->draw_rectangle (drawable, gc, filled, x, y,
226                                                      width, height);
227 }
228
229 void
230 gdk_draw_arc (GdkDrawable *drawable,
231               GdkGC       *gc,
232               gint         filled,
233               gint         x,
234               gint         y,
235               gint         width,
236               gint         height,
237               gint         angle1,
238               gint         angle2)
239 {  
240   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
241   g_return_if_fail (GDK_IS_GC (gc));
242
243   if (width < 0 || height < 0)
244     {
245       gint real_width;
246       gint real_height;
247       
248       gdk_drawable_get_size (drawable, &real_width, &real_height);
249
250       if (width < 0)
251         width = real_width;
252       if (height < 0)
253         height = real_height;
254     }
255
256   GDK_DRAWABLE_GET_CLASS (drawable)->draw_arc (drawable, gc, filled,
257                                                x, y, width, height, angle1, angle2);
258 }
259
260 void
261 gdk_draw_polygon (GdkDrawable *drawable,
262                   GdkGC       *gc,
263                   gint         filled,
264                   GdkPoint    *points,
265                   gint         npoints)
266 {
267   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
268   g_return_if_fail (GDK_IS_GC (gc));
269
270   GDK_DRAWABLE_GET_CLASS (drawable)->draw_polygon (drawable, gc, filled,
271                                                    points, npoints);
272 }
273
274 /* gdk_draw_string
275  *
276  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
277  *
278  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
279  */
280 void
281 gdk_draw_string (GdkDrawable *drawable,
282                  GdkFont     *font,
283                  GdkGC       *gc,
284                  gint         x,
285                  gint         y,
286                  const gchar *string)
287 {
288   gdk_draw_text (drawable, font, gc, x, y, string, _gdk_font_strlen (font, string));
289 }
290
291 /* gdk_draw_text
292  *
293  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
294  *
295  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
296  */
297 void
298 gdk_draw_text (GdkDrawable *drawable,
299                GdkFont     *font,
300                GdkGC       *gc,
301                gint         x,
302                gint         y,
303                const gchar *text,
304                gint         text_length)
305 {
306   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
307   g_return_if_fail (font != NULL);
308   g_return_if_fail (GDK_IS_GC (gc));
309   g_return_if_fail (text != NULL);
310
311   GDK_DRAWABLE_GET_CLASS (drawable)->draw_text (drawable, font, gc, x, y, text, text_length);
312 }
313
314 void
315 gdk_draw_text_wc (GdkDrawable    *drawable,
316                   GdkFont        *font,
317                   GdkGC          *gc,
318                   gint            x,
319                   gint            y,
320                   const GdkWChar *text,
321                   gint            text_length)
322 {
323   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
324   g_return_if_fail (font != NULL);
325   g_return_if_fail (GDK_IS_GC (gc));
326   g_return_if_fail (text != NULL);
327
328   GDK_DRAWABLE_GET_CLASS (drawable)->draw_text_wc (drawable, font, gc, x, y, text, text_length);
329 }
330
331 void
332 gdk_draw_drawable (GdkDrawable *drawable,
333                    GdkGC       *gc,
334                    GdkDrawable *src,
335                    gint         xsrc,
336                    gint         ysrc,
337                    gint         xdest,
338                    gint         ydest,
339                    gint         width,
340                    gint         height)
341 {
342   GdkDrawable *composite;
343   gint composite_x_offset = 0;
344   gint composite_y_offset = 0;
345
346   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
347   g_return_if_fail (src != NULL);
348   g_return_if_fail (GDK_IS_GC (gc));
349
350   if (width < 0 || height < 0)
351     {
352       gint real_width;
353       gint real_height;
354       
355       gdk_drawable_get_size (src, &real_width, &real_height);
356
357       if (width < 0)
358         width = real_width;
359       if (height < 0)
360         height = real_height;
361     }
362
363
364   composite =
365     GDK_DRAWABLE_GET_CLASS (src)->get_composite_drawable (src,
366                                                           xsrc, ysrc,
367                                                           width, height,
368                                                           &composite_x_offset,
369                                                           &composite_y_offset);
370
371   
372   GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc, composite,
373                                                     xsrc - composite_x_offset,
374                                                     ysrc - composite_y_offset,
375                                                     xdest, ydest,
376                                                     width, height);
377   
378   g_object_unref (G_OBJECT (composite));
379 }
380
381 void
382 gdk_draw_image (GdkDrawable *drawable,
383                 GdkGC       *gc,
384                 GdkImage    *image,
385                 gint         xsrc,
386                 gint         ysrc,
387                 gint         xdest,
388                 gint         ydest,
389                 gint         width,
390                 gint         height)
391 {
392   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
393   g_return_if_fail (image != NULL);
394   g_return_if_fail (GDK_IS_GC (gc));
395
396   if (width == -1)
397     width = image->width;
398   if (height == -1)
399     height = image->height;
400
401   GDK_DRAWABLE_GET_CLASS (drawable)->draw_image (drawable, gc, image, xsrc, ysrc,
402                                                  xdest, ydest, width, height);
403 }
404
405 void
406 gdk_draw_points (GdkDrawable *drawable,
407                  GdkGC       *gc,
408                  GdkPoint    *points,
409                  gint         npoints)
410 {
411   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
412   g_return_if_fail ((points != NULL) && (npoints > 0));
413   g_return_if_fail (GDK_IS_GC (gc));
414   g_return_if_fail (npoints >= 0);
415
416   if (npoints == 0)
417     return;
418
419   GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, points, npoints);
420 }
421
422 void
423 gdk_draw_segments (GdkDrawable *drawable,
424                    GdkGC       *gc,
425                    GdkSegment  *segs,
426                    gint         nsegs)
427 {
428   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
429
430   if (nsegs == 0)
431     return;
432
433   g_return_if_fail (segs != NULL);
434   g_return_if_fail (GDK_IS_GC (gc));
435   g_return_if_fail (nsegs >= 0);
436
437   GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc, segs, nsegs);
438 }
439
440 void
441 gdk_draw_lines (GdkDrawable *drawable,
442                 GdkGC       *gc,
443                 GdkPoint    *points,
444                 gint         npoints)
445 {
446
447   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
448   g_return_if_fail (points != NULL);
449   g_return_if_fail (GDK_IS_GC (gc));
450   g_return_if_fail (npoints >= 0);
451
452   if (npoints == 0)
453     return;
454
455   GDK_DRAWABLE_GET_CLASS (drawable)->draw_lines (drawable, gc, points, npoints);
456 }
457
458 void
459 gdk_draw_glyphs (GdkDrawable      *drawable,
460                  GdkGC            *gc,
461                  PangoFont        *font,
462                  gint              x,
463                  gint              y,
464                  PangoGlyphString *glyphs)
465 {
466   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
467   g_return_if_fail (GDK_IS_GC (gc));
468
469
470   GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs (drawable, gc, font, x, y, glyphs);
471 }
472
473
474 GdkImage*
475 gdk_drawable_get_image (GdkDrawable *drawable,
476                         gint         x,
477                         gint         y,
478                         gint         width,
479                         gint         height)
480 {
481   GdkDrawable *composite;
482   gint composite_x_offset = 0;
483   gint composite_y_offset = 0;
484   GdkImage *retval;
485   
486   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
487   g_return_val_if_fail (x >= 0, NULL);
488   g_return_val_if_fail (y >= 0, NULL);
489   g_return_val_if_fail (width >= 0, NULL);
490   g_return_val_if_fail (height >= 0, NULL);
491
492   composite =
493     GDK_DRAWABLE_GET_CLASS (drawable)->get_composite_drawable (drawable,
494                                                                x, y,
495                                                                width, height,
496                                                                &composite_x_offset,
497                                                                &composite_y_offset); 
498   
499   retval = GDK_DRAWABLE_GET_CLASS (composite)->get_image (composite,
500                                                           x - composite_x_offset,
501                                                           y - composite_y_offset,
502                                                           width, height);
503
504   g_object_unref (G_OBJECT (composite));
505
506   return retval;
507 }
508
509 static GdkDrawable*
510 gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
511                                           gint         x,
512                                           gint         y,
513                                           gint         width,
514                                           gint         height,
515                                           gint        *composite_x_offset,
516                                           gint        *composite_y_offset)
517 {
518   g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
519
520   *composite_x_offset = 0;
521   *composite_y_offset = 0;
522   
523   return GDK_DRAWABLE (g_object_ref (G_OBJECT (drawable)));
524 }