1 /*
2 * pixbuf-util.c
3 * Copyright (C) 2010 Jim Evins <evins@snaught.com>.
4 *
5 * This file is part of gLabels.
6 *
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * gLabels 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
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <config.h>
22
23 #include "pixbuf-util.h"
24
25 #include "color.h"
26
27 #include "debug.h"
28
29
30 /*========================================================*/
31 /* Private macros and constants. */
32 /*========================================================*/
33
34
35 /*========================================================*/
36 /* Private types. */
37 /*========================================================*/
38
39
40 /*========================================================*/
41 /* Private globals. */
42 /*========================================================*/
43
44
45 /*========================================================*/
46 /* Private function prototypes. */
47 /*========================================================*/
48
49
50 /****************************************************************************/
51 /* Create shadow version of given pixbuf. */
52 /****************************************************************************/
53 GdkPixbuf *
gl_pixbuf_util_create_shadow_pixbuf(const GdkPixbuf * pixbuf,guint shadow_color,gdouble shadow_opacity)54 gl_pixbuf_util_create_shadow_pixbuf (const GdkPixbuf *pixbuf,
55 guint shadow_color,
56 gdouble shadow_opacity)
57 {
58 gint bits_per_sample, channels;
59 gboolean src_has_alpha;
60 gint width, height, src_rowstride, dest_rowstride;
61 GdkPixbuf *dest_pixbuf;
62 guchar *buf_src, *buf_dest;
63 guchar *p_src, *p_dest;
64 gint ix, iy;
65 guchar shadow_r, shadow_g, shadow_b;
66
67 g_return_val_if_fail (pixbuf && GDK_IS_PIXBUF (pixbuf), NULL);
68
69 shadow_r = GL_COLOR_F_RED (shadow_color) * 255.0;
70 shadow_g = GL_COLOR_F_GREEN (shadow_color) * 255.0;
71 shadow_b = GL_COLOR_F_BLUE (shadow_color) * 255.0;
72
73 /* extract pixels and parameters from source pixbuf. */
74 buf_src = gdk_pixbuf_get_pixels (pixbuf);
75 bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf);
76 channels = gdk_pixbuf_get_n_channels (pixbuf);
77 src_has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
78 width = gdk_pixbuf_get_width (pixbuf);
79 height = gdk_pixbuf_get_height (pixbuf);
80 src_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
81
82 /* validate assumptions about source pixbuf. */
83 g_return_val_if_fail (buf_src, NULL);
84 g_return_val_if_fail (bits_per_sample == 8, NULL);
85 g_return_val_if_fail ((channels >= 3) && (channels <= 4), NULL);
86 g_return_val_if_fail (width > 0, NULL);
87 g_return_val_if_fail (height > 0, NULL);
88 g_return_val_if_fail (src_rowstride > 0, NULL);
89
90 /* Allocate a destination pixbuf */
91 dest_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, bits_per_sample, width, height);
92 dest_rowstride = gdk_pixbuf_get_rowstride (dest_pixbuf);
93 buf_dest = gdk_pixbuf_get_pixels (dest_pixbuf);
94 if (!buf_dest) {
95 return NULL;
96 }
97
98 /* Process pixels: set rgb components and composite alpha with shadow_opacity. */
99 p_src = buf_src;
100 p_dest = buf_dest;
101 for ( iy=0; iy < height; iy++ )
102 {
103
104 p_src = buf_src + iy*src_rowstride;
105 p_dest = buf_dest + iy*dest_rowstride;
106
107 for ( ix=0; ix < width; ix++ )
108 {
109
110 p_src += 3; /* skip RGB */
111
112 *p_dest++ = shadow_r;
113 *p_dest++ = shadow_g;
114 *p_dest++ = shadow_b;
115
116 if ( src_has_alpha )
117 {
118 *p_dest++ = *p_src++ * shadow_opacity;
119 }
120 else
121 {
122 *p_dest++ = shadow_opacity * 255.0;
123 }
124
125
126 }
127
128 }
129
130 return dest_pixbuf;
131 }
132
133
134
135
136 /*
137 * Local Variables: -- emacs
138 * mode: C -- emacs
139 * c-basic-offset: 8 -- emacs
140 * tab-width: 8 -- emacs
141 * indent-tabs-mode: nil -- emacs
142 * End: -- emacs
143 */
144