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 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.
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.
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.
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/.
27 #include "gdkdrawable.h"
28 #include "gdkinternals.h"
29 #include "gdkwindow.h"
31 static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
36 gint *composite_x_offset,
37 gint *composite_y_offset);
38 static GdkRegion * gdk_drawable_real_get_visible_region (GdkDrawable *drawable);
40 static void gdk_drawable_class_init (GdkDrawableClass *klass);
43 gdk_drawable_get_type (void)
45 static GType object_type = 0;
49 static const GTypeInfo object_info =
51 sizeof (GdkDrawableClass),
53 (GBaseFinalizeFunc) NULL,
54 (GClassInitFunc) gdk_drawable_class_init,
55 NULL, /* class_finalize */
56 NULL, /* class_data */
59 (GInstanceInitFunc) NULL,
62 object_type = g_type_register_static (G_TYPE_OBJECT,
71 gdk_drawable_class_init (GdkDrawableClass *klass)
73 klass->get_composite_drawable = gdk_drawable_real_get_composite_drawable;
74 /* Default implementation for clip and visible region is the same */
75 klass->get_clip_region = gdk_drawable_real_get_visible_region;
76 klass->get_visible_region = gdk_drawable_real_get_visible_region;
79 /* Manipulation of drawables
83 * gdk_drawable_set_data:
84 * @drawable: a #GdkDrawable
85 * @key: name to store the data under
86 * @data: arbitrary data
87 * @destroy_func: function to free @data, or %NULL
89 * This function is equivalent to g_object_set_data(),
90 * the #GObject variant should be used instead.
94 gdk_drawable_set_data (GdkDrawable *drawable,
97 GDestroyNotify destroy_func)
99 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
101 g_object_set_qdata_full (G_OBJECT (drawable),
102 g_quark_from_string (key),
108 * gdk_drawable_get_data:
109 * @drawable: a #GdkDrawable
110 * @key: name the data was stored under
112 * Equivalent to g_object_get_data(); the #GObject variant should be
115 * Return value: the data stored at @key
118 gdk_drawable_get_data (GdkDrawable *drawable,
121 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
123 return g_object_get_qdata (G_OBJECT (drawable),
124 g_quark_try_string (key));
128 * gdk_drawable_get_size:
129 * @drawable: a #GdkDrawable
130 * @width: location to store drawable's width, or %NULL
131 * @height: location to store drawable's height, or %NULL
133 * Fills *@width and *@height with the size of @drawable.
134 * @width or @height can be %NULL if you only want the other one.
136 * On the X11 platform, if @drawable is a #GdkWindow, the returned
137 * size is the size reported in the most-recently-processed configure
138 * event, rather than the current size on the X server.
142 gdk_drawable_get_size (GdkDrawable *drawable,
146 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
148 GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height);
152 * gdk_drawable_get_visual:
153 * @drawable: a #GdkDrawable
155 * Gets the #GdkVisual describing the pixel format of @drawable.
157 * Return value: a #GdkVisual
160 gdk_drawable_get_visual (GdkDrawable *drawable)
162 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
164 return GDK_DRAWABLE_GET_CLASS (drawable)->get_visual (drawable);
168 * gdk_drawable_get_depth:
169 * @drawable: a #GdkDrawable
171 * Obtains the bit depth of the drawable, that is, the number of bits
172 * that make up a pixel in the drawable's visual. Examples are 8 bits
173 * per pixel, 24 bits per pixel, etc.
175 * Return value: number of bits per pixel
178 gdk_drawable_get_depth (GdkDrawable *drawable)
180 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), 0);
182 return GDK_DRAWABLE_GET_CLASS (drawable)->get_depth (drawable);
186 * gdk_drawable_set_colormap:
187 * @drawable: a #GdkDrawable
188 * @colormap: a #GdkColormap
190 * Sets the colormap associated with @drawable. Normally this will
191 * happen automatically when the drawable is created; you only need to
192 * use this function if the drawable-creating function did not have a
193 * way to determine the colormap, and you then use drawable operations
194 * that require a colormap. The colormap for all drawables and
195 * graphics contexts you intend to use together should match. i.e.
196 * when using a #GdkGC to draw to a drawable, or copying one drawable
197 * to another, the colormaps should match.
201 gdk_drawable_set_colormap (GdkDrawable *drawable,
204 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
205 g_return_if_fail (cmap == NULL || gdk_drawable_get_depth (drawable)
206 == cmap->visual->depth);
208 GDK_DRAWABLE_GET_CLASS (drawable)->set_colormap (drawable, cmap);
212 * gdk_drawable_get_colormap:
213 * @drawable: a #GdkDrawable
215 * Gets the colormap for @drawable, if one is set; returns
218 * Return value: the colormap, or %NULL
221 gdk_drawable_get_colormap (GdkDrawable *drawable)
223 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
225 return GDK_DRAWABLE_GET_CLASS (drawable)->get_colormap (drawable);
230 * @drawable: a #GdkDrawable
232 * Deprecated equivalent of calling g_object_ref() on @drawable.
233 * (Drawables were not objects in previous versions of GDK.)
235 * Return value: the same @drawable passed in
238 gdk_drawable_ref (GdkDrawable *drawable)
240 return (GdkDrawable *) g_object_ref (G_OBJECT (drawable));
244 * gdk_drawable_unref:
245 * @drawable: a #GdkDrawable
247 * Deprecated equivalent of calling g_object_unref() on @drawable.
251 gdk_drawable_unref (GdkDrawable *drawable)
253 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
255 g_object_unref (G_OBJECT (drawable));
261 gdk_draw_point (GdkDrawable *drawable,
268 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
269 g_return_if_fail (GDK_IS_GC (gc));
274 GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, &point, 1);
278 gdk_draw_line (GdkDrawable *drawable,
287 g_return_if_fail (drawable != NULL);
288 g_return_if_fail (gc != NULL);
289 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
290 g_return_if_fail (GDK_IS_GC (gc));
296 GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc, &segment, 1);
300 gdk_draw_rectangle (GdkDrawable *drawable,
308 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
309 g_return_if_fail (GDK_IS_GC (gc));
311 if (width < 0 || height < 0)
316 gdk_drawable_get_size (drawable, &real_width, &real_height);
321 height = real_height;
324 GDK_DRAWABLE_GET_CLASS (drawable)->draw_rectangle (drawable, gc, filled, x, y,
329 gdk_draw_arc (GdkDrawable *drawable,
339 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
340 g_return_if_fail (GDK_IS_GC (gc));
342 if (width < 0 || height < 0)
347 gdk_drawable_get_size (drawable, &real_width, &real_height);
352 height = real_height;
355 GDK_DRAWABLE_GET_CLASS (drawable)->draw_arc (drawable, gc, filled,
356 x, y, width, height, angle1, angle2);
360 gdk_draw_polygon (GdkDrawable *drawable,
366 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
367 g_return_if_fail (GDK_IS_GC (gc));
369 GDK_DRAWABLE_GET_CLASS (drawable)->draw_polygon (drawable, gc, filled,
375 * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
377 * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
380 gdk_draw_string (GdkDrawable *drawable,
387 gdk_draw_text (drawable, font, gc, x, y, string, _gdk_font_strlen (font, string));
392 * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
394 * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
397 gdk_draw_text (GdkDrawable *drawable,
405 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
406 g_return_if_fail (font != NULL);
407 g_return_if_fail (GDK_IS_GC (gc));
408 g_return_if_fail (text != NULL);
410 GDK_DRAWABLE_GET_CLASS (drawable)->draw_text (drawable, font, gc, x, y, text, text_length);
414 gdk_draw_text_wc (GdkDrawable *drawable,
419 const GdkWChar *text,
422 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
423 g_return_if_fail (font != NULL);
424 g_return_if_fail (GDK_IS_GC (gc));
425 g_return_if_fail (text != NULL);
427 GDK_DRAWABLE_GET_CLASS (drawable)->draw_text_wc (drawable, font, gc, x, y, text, text_length);
432 * @drawable: a #GdkDrawable
433 * @gc: a #GdkGC sharing the drawable's visual and colormap
434 * @src: another #GdkDrawable
435 * @xsrc: X position in @src of rectangle to draw
436 * @ysrc: Y position in @src of rectangle to draw
437 * @xdest: X position in @drawable where the rectangle should be drawn
438 * @ydest: Y position in @drawable where the rectangle should be drawn
439 * @width: width of rectangle to draw, or -1 for entire @src width
440 * @height: height of rectangle to draw, or -1 for entire @src height
442 * Copies the @width x @height region of @src at coordinates (@xsrc,
443 * @ysrc) to coordinates (@xdest, @ydest) in @drawable.
444 * @width and/or @height may be given as -1, in which case the entire
445 * @src drawable will be copied.
447 * Most fields in @gc are not used for this operation, but notably the
448 * clip mask or clip region will be honored.
450 * The source and destination drawables must have the same visual and
451 * colormap, or errors will result. (On X11, failure to match
452 * visual/colormap results in a BadMatch error from the X server.)
453 * A common cause of this problem is an attempt to draw a bitmap to
454 * a color drawable. The way to draw a bitmap is to set the
455 * bitmap as a clip mask on your #GdkGC, then use gdk_draw_rectangle()
456 * to draw a rectangle clipped to the bitmap.
459 gdk_draw_drawable (GdkDrawable *drawable,
469 GdkDrawable *composite;
470 gint composite_x_offset = 0;
471 gint composite_y_offset = 0;
473 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
474 g_return_if_fail (src != NULL);
475 g_return_if_fail (GDK_IS_GC (gc));
477 if (width < 0 || height < 0)
482 gdk_drawable_get_size (src, &real_width, &real_height);
487 height = real_height;
492 GDK_DRAWABLE_GET_CLASS (src)->get_composite_drawable (src,
496 &composite_y_offset);
499 GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc, composite,
500 xsrc - composite_x_offset,
501 ysrc - composite_y_offset,
505 g_object_unref (G_OBJECT (composite));
509 gdk_draw_image (GdkDrawable *drawable,
519 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
520 g_return_if_fail (image != NULL);
521 g_return_if_fail (GDK_IS_GC (gc));
524 width = image->width;
526 height = image->height;
528 GDK_DRAWABLE_GET_CLASS (drawable)->draw_image (drawable, gc, image, xsrc, ysrc,
529 xdest, ydest, width, height);
533 gdk_draw_points (GdkDrawable *drawable,
538 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
539 g_return_if_fail ((points != NULL) && (npoints > 0));
540 g_return_if_fail (GDK_IS_GC (gc));
541 g_return_if_fail (npoints >= 0);
546 GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, points, npoints);
550 gdk_draw_segments (GdkDrawable *drawable,
555 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
560 g_return_if_fail (segs != NULL);
561 g_return_if_fail (GDK_IS_GC (gc));
562 g_return_if_fail (nsegs >= 0);
564 GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc, segs, nsegs);
568 gdk_draw_lines (GdkDrawable *drawable,
574 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
575 g_return_if_fail (points != NULL);
576 g_return_if_fail (GDK_IS_GC (gc));
577 g_return_if_fail (npoints >= 0);
582 GDK_DRAWABLE_GET_CLASS (drawable)->draw_lines (drawable, gc, points, npoints);
587 * @drawable: a #GdkDrawable
589 * @font: font to be used
590 * @x: X coordinate of baseline origin
591 * @y: Y coordinate of baseline origin
592 * @glyphs: glyphs to render
594 * This is a low-level function; 99% of text rendering should be done
595 * using gdk_draw_layout() instead.
597 * A glyph is a character in a font. This function draws a sequence of
598 * glyphs. To obtain a sequence of glyphs you have to understand a
599 * lot about internationalized text handling, which you don't want to
600 * understand; thus, use gdk_draw_layout() instead of this function,
601 * gdk_draw_layout() handles the details.
605 gdk_draw_glyphs (GdkDrawable *drawable,
610 PangoGlyphString *glyphs)
612 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
613 g_return_if_fail (GDK_IS_GC (gc));
616 GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs (drawable, gc, font, x, y, glyphs);
621 * gdk_drawable_get_image:
622 * @drawable: a #GdkDrawable
623 * @x: x coordinate on @drawable
624 * @y: y coordinate on @drawable
625 * @width: width of region to get
626 * @height: height or region to get
628 * A #GdkImage stores client-side image data (pixels). In contrast,
629 * #GdkPixmap and #GdkWindow are server-side
630 * objects. gdk_drawable_get_image() obtains the pixels from a
631 * server-side drawable as a client-side #GdkImage. The format of a
632 * #GdkImage depends on the #GdkVisual of the current display, which
633 * makes manipulating #GdkImage extremely difficult; therefore, in
634 * most cases you should use gdk_pixbuf_get_from_drawable() instead of
635 * this lower-level function. A #GdkPixbuf contains image data in a
636 * canonicalized RGB format, rather than a display-dependent format.
637 * Of course, there's a convenience vs. speed tradeoff here, so you'll
638 * want to think about what makes sense for your application.
640 * @x, @y, @width, and @height define the region of @drawable to
641 * obtain as an image.
643 * You would usually copy image data to the client side if you intend
644 * to examine the values of individual pixels, for example to darken
645 * an image or add a red tint. It would be prohibitively slow to
646 * make a round-trip request to the windowing system for each pixel,
647 * so instead you get all of them at once, modify them, then copy
648 * them all back at once.
650 * If the X server or other windowing system backend is on the local
651 * machine, this function may use shared memory to avoid copying
654 * If the source drawable is a #GdkWindow and partially offscreen
655 * or obscured, then the obscured portions of the returned image
656 * will contain undefined data.
658 * Return value: a #GdkImage containing the contents of @drawable
661 gdk_drawable_get_image (GdkDrawable *drawable,
667 GdkDrawable *composite;
668 gint composite_x_offset = 0;
669 gint composite_y_offset = 0;
673 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
674 g_return_val_if_fail (x >= 0, NULL);
675 g_return_val_if_fail (y >= 0, NULL);
677 /* FIXME? Note race condition since we get the size then
678 * get the image, and the size may have changed.
681 if (width < 0 || height < 0)
682 gdk_drawable_get_size (drawable,
683 width < 0 ? &width : NULL,
684 height < 0 ? &height : NULL);
687 GDK_DRAWABLE_GET_CLASS (drawable)->get_composite_drawable (drawable,
691 &composite_y_offset);
693 retval = GDK_DRAWABLE_GET_CLASS (composite)->get_image (composite,
694 x - composite_x_offset,
695 y - composite_y_offset,
698 g_object_unref (G_OBJECT (composite));
700 cmap = gdk_drawable_get_colormap (drawable);
703 gdk_image_set_colormap (retval, cmap);
709 gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable,
714 gint *composite_x_offset,
715 gint *composite_y_offset)
717 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
719 *composite_x_offset = 0;
720 *composite_y_offset = 0;
722 return GDK_DRAWABLE (g_object_ref (G_OBJECT (drawable)));
726 * gdk_drawable_get_clip_region:
727 * @drawable: a #GdkDrawable
729 * Computes the region of a drawable that potentially can be written
730 * to by drawing primitives. This region will not take into account
731 * the clip region for the GC, and may also not take into account
732 * other factors such as if the window is obscured by other windows,
733 * but no area outside of this region will be affected by drawing
736 * Return value: a #GdkRegion. This must be freed with gdk_region_destroy()
740 gdk_drawable_get_clip_region (GdkDrawable *drawable)
742 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
744 return GDK_DRAWABLE_GET_CLASS (drawable)->get_clip_region (drawable);
748 * gdk_drawable_get_visible_region:
751 * Computes the region of a drawable that is potentially visible.
752 * This does not necessarily take into account if the window is
753 * obscured by other windows, but no area outside of this region
756 * Return value: a #GdkRegion. This must be freed with gdk_region_destroy()
760 gdk_drawable_get_visible_region (GdkDrawable *drawable)
762 g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
764 return GDK_DRAWABLE_GET_CLASS (drawable)->get_visible_region (drawable);
768 gdk_drawable_real_get_visible_region (GdkDrawable *drawable)
775 gdk_drawable_get_size (drawable, &rect.width, &rect.height);
777 return gdk_region_rectangle (&rect);