1 /* GdkPixbuf library - Rendering functions
3 * Copyright (C) 1999 The Free Software Foundation
5 * Author: Federico Mena-Quintero <federico@gimp.org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
25 #include "gdkinternals.h" /* _gdk_draw_pixbuf() */
26 #include "gdk-pixbuf-private.h"
27 #include "gdkpixbuf.h"
28 #include "gdkscreen.h"
33 * gdk_pixbuf_render_threshold_alpha:
35 * @bitmap: Bitmap where the bilevel mask will be painted to.
36 * @src_x: Source X coordinate.
37 * @src_y: source Y coordinate.
38 * @dest_x: Destination X coordinate.
39 * @dest_y: Destination Y coordinate.
40 * @width: Width of region to threshold, or -1 to use pixbuf width
41 * @height: Height of region to threshold, or -1 to use pixbuf height
42 * @alpha_threshold: Opacity values below this will be painted as zero; all
43 * other values will be painted as one.
45 * Takes the opacity values in a rectangular portion of a pixbuf and thresholds
46 * them to produce a bi-level alpha mask that can be used as a clipping mask for
51 gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf,
54 int dest_x, int dest_y,
55 int width, int height,
62 int start, start_status;
65 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
66 g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB);
67 g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4);
68 g_return_if_fail (pixbuf->bits_per_sample == 8);
71 width = pixbuf->width;
73 height = pixbuf->height;
75 g_return_if_fail (bitmap != NULL);
76 g_return_if_fail (width >= 0 && height >= 0);
77 g_return_if_fail (src_x >= 0 && src_x + width <= pixbuf->width);
78 g_return_if_fail (src_y >= 0 && src_y + height <= pixbuf->height);
80 g_return_if_fail (alpha_threshold >= 0 && alpha_threshold <= 255);
82 if (width == 0 || height == 0)
85 gc = gdk_gc_new (bitmap);
87 if (!pixbuf->has_alpha)
89 color.pixel = (alpha_threshold == 255) ? 0 : 1;
90 gdk_gc_set_foreground (gc, &color);
91 gdk_draw_rectangle (bitmap, gc, TRUE, dest_x, dest_y, width, height);
97 gdk_gc_set_foreground (gc, &color);
98 gdk_draw_rectangle (bitmap, gc, TRUE, dest_x, dest_y, width, height);
101 gdk_gc_set_foreground (gc, &color);
103 for (y = 0; y < height; y++)
105 p = (pixbuf->pixels + (y + src_y) * pixbuf->rowstride + src_x * pixbuf->n_channels
106 + pixbuf->n_channels - 1);
109 start_status = *p < alpha_threshold;
111 for (x = 0; x < width; x++)
113 status = *p < alpha_threshold;
115 if (status != start_status)
118 gdk_draw_line (bitmap, gc,
119 start + dest_x, y + dest_y,
120 x - 1 + dest_x, y + dest_y);
123 start_status = status;
126 p += pixbuf->n_channels;
130 gdk_draw_line (bitmap, gc,
131 start + dest_x, y + dest_y,
132 x - 1 + dest_x, y + dest_y);
141 * gdk_pixbuf_render_to_drawable:
143 * @drawable: Destination drawable.
144 * @gc: GC used for rendering.
145 * @src_x: Source X coordinate within pixbuf.
146 * @src_y: Source Y coordinate within pixbuf.
147 * @dest_x: Destination X coordinate within drawable.
148 * @dest_y: Destination Y coordinate within drawable.
149 * @width: Width of region to render, in pixels, or -1 to use pixbuf width
150 * @height: Height of region to render, in pixels, or -1 to use pixbuf height
151 * @dither: Dithering mode for GdkRGB.
152 * @x_dither: X offset for dither.
153 * @y_dither: Y offset for dither.
155 * Renders a rectangular portion of a pixbuf to a drawable while using the
156 * specified GC. This is done using GdkRGB, so the specified drawable must have
157 * the GdkRGB visual and colormap. Note that this function will ignore the
158 * opacity information for images with an alpha channel; the GC must already
159 * have the clipping mask set if you want transparent regions to show through.
161 * For an explanation of dither offsets, see the GdkRGB documentation. In
162 * brief, the dither offset is important when re-rendering partial regions of an
163 * image to a rendered version of the full image, or for when the offsets to a
164 * base position change, as in scrolling. The dither matrix has to be shifted
165 * for consistent visual results. If you do not have any of these cases, the
166 * dither offsets can be both zero.
169 gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf,
170 GdkDrawable *drawable,
172 int src_x, int src_y,
173 int dest_x, int dest_y,
174 int width, int height,
176 int x_dither, int y_dither)
178 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
179 g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB);
180 g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4);
181 g_return_if_fail (pixbuf->bits_per_sample == 8);
183 g_return_if_fail (drawable != NULL);
186 width = pixbuf->width;
188 height = pixbuf->height;
190 g_return_if_fail (width >= 0 && height >= 0);
191 g_return_if_fail (src_x >= 0 && src_x + width <= pixbuf->width);
192 g_return_if_fail (src_y >= 0 && src_y + height <= pixbuf->height);
194 if (width == 0 || height == 0)
197 _gdk_draw_pixbuf (drawable, gc, pixbuf,
198 src_x, src_y, dest_x, dest_y, width, height,
199 dither, x_dither, y_dither);
205 * gdk_pixbuf_render_to_drawable_alpha:
207 * @drawable: Destination drawable.
208 * @src_x: Source X coordinate within pixbuf.
209 * @src_y: Source Y coordinates within pixbuf.
210 * @dest_x: Destination X coordinate within drawable.
211 * @dest_y: Destination Y coordinate within drawable.
212 * @width: Width of region to render, in pixels, or -1 to use pixbuf width.
213 * @height: Height of region to render, in pixels, or -1 to use pixbuf height.
214 * @alpha_mode: Ignored. Present for backwards compatibility.
215 * @alpha_threshold: Ignored. Present for backwards compatibility
216 * @dither: Dithering mode for GdkRGB.
217 * @x_dither: X offset for dither.
218 * @y_dither: Y offset for dither.
220 * Renders a rectangular portion of a pixbuf to a drawable. The destination
221 * drawable must have a colormap. All windows have a colormap, however, pixmaps
222 * only have colormap by default if they were created with a non-NULL window argument.
223 * Otherwise a colormap must be set on them with gdk_drawable_set_colormap.
225 * On older X servers, rendering pixbufs with an alpha channel involves round trips
226 * to the X server, and may be somewhat slow.
229 gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf,
230 GdkDrawable *drawable,
231 int src_x, int src_y,
232 int dest_x, int dest_y,
233 int width, int height,
234 GdkPixbufAlphaMode alpha_mode,
237 int x_dither, int y_dither)
239 _gdk_draw_pixbuf (drawable, NULL, pixbuf,
240 src_x, src_y, dest_x, dest_y, width, height,
241 dither, x_dither, y_dither);
245 * gdk_pixbuf_render_pixmap_and_mask:
247 * @pixmap_return: Location to store a pointer to the created pixmap,
248 * or %NULL if the pixmap is not needed.
249 * @mask_return: Location to store a pointer to the created mask,
250 * or %NULL if the mask is not needed.
251 * @alpha_threshold: Threshold value for opacity values.
253 * Creates a pixmap and a mask bitmap which are returned in the @pixmap_return
254 * and @mask_return arguments, respectively, and renders a pixbuf and its
255 * corresponding thresholded alpha mask to them. This is merely a convenience
256 * function; applications that need to render pixbufs with dither offsets or to
257 * given drawables should use gdk_pixbuf_render_to_drawable_alpha() or
258 * gdk_pixbuf_render_to_drawable(), and gdk_pixbuf_render_threshold_alpha().
260 * The pixmap that is created is created for the colormap returned
261 * by gdk_rgb_get_colormap(). You normally will want to instead use
262 * the actual colormap for a widget, and use
263 * gdk_pixbuf_render_pixmap_and_mask_for_colormap.
265 * If the pixbuf does not have an alpha channel, then *@mask_return will be set
269 gdk_pixbuf_render_pixmap_and_mask (GdkPixbuf *pixbuf,
270 GdkPixmap **pixmap_return,
271 GdkBitmap **mask_return,
274 gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf,
275 gdk_rgb_get_colormap (),
276 pixmap_return, mask_return,
281 * gdk_pixbuf_render_pixmap_and_mask_for_colormap:
283 * @colormap: A #GdkColormap
284 * @pixmap_return: Location to store a pointer to the created pixmap,
285 * or %NULL if the pixmap is not needed.
286 * @mask_return: Location to store a pointer to the created mask,
287 * or %NULL if the mask is not needed.
288 * @alpha_threshold: Threshold value for opacity values.
290 * Creates a pixmap and a mask bitmap which are returned in the @pixmap_return
291 * and @mask_return arguments, respectively, and renders a pixbuf and its
292 * corresponding tresholded alpha mask to them. This is merely a convenience
293 * function; applications that need to render pixbufs with dither offsets or to
294 * given drawables should use gdk_pixbuf_render_to_drawable_alpha() or
295 * gdk_pixbuf_render_to_drawable(), and gdk_pixbuf_render_threshold_alpha().
297 * The pixmap that is created uses the #GdkColormap specified by @colormap.
298 * This colormap must match the colormap of the window where the pixmap
299 * will eventually be used or an error will result.
301 * If the pixbuf does not have an alpha channel, then *@mask_return will be set
305 gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf,
306 GdkColormap *colormap,
307 GdkPixmap **pixmap_return,
308 GdkBitmap **mask_return,
313 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
314 g_return_if_fail (GDK_IS_COLORMAP (colormap));
316 screen = gdk_colormap_get_screen (colormap);
321 *pixmap_return = gdk_pixmap_new (gdk_screen_get_root_window (screen),
322 gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),
323 gdk_colormap_get_visual (colormap)->depth);
325 gdk_drawable_set_colormap (GDK_DRAWABLE (*pixmap_return), colormap);
326 gc = gdk_gc_new (*pixmap_return);
327 gdk_pixbuf_render_to_drawable (pixbuf, *pixmap_return, gc,
329 gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),
330 GDK_RGB_DITHER_NORMAL,
337 if (gdk_pixbuf_get_has_alpha (pixbuf))
339 *mask_return = gdk_pixmap_new (gdk_screen_get_root_window (screen),
340 gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), 1);
342 gdk_pixbuf_render_threshold_alpha (pixbuf, *mask_return,
344 gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf),