Stay in GETCOORDS if there are more coord prompts.
[geda-gaf/berndj.git] / libgeda / src / gdk-pixbuf-hacks.c
blob4462f08dffeb8b1a8114022290120e765940d54f
1 /* Functions gdk_pixbuf_rotate and gdk_pixbuf_add are taken from gtkam,
2 and is covered by this copyright. */
3 /*
4 * Copyright © 2001 Lutz Müller <lutz@users.sf.net>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 /* Taken from gtkam's sources */
23 #include "config.h"
25 #include <gdk-pixbuf/gdk-pixbuf.h>
27 /*! \def COPY90 */
28 #define COPY90 \
29 if ((r2 < h1) && (c2 < w1)) { \
30 if ((w1 <= h1) && (r1 < h2)) \
31 for (i = 0; i < c; i++) \
32 new_pixels[r1 * rs2 + c1 * c + i] = \
33 pixels[r2 * rs1 + c2 * c + i]; \
34 if ((w1 > h1) && (c1 > (w1 - h2))) \
35 for (i = 0; i < c; i++) \
36 new_pixels[r1 * rs2 + (c1 - (w1 - h1)) * c + i] = \
37 pixels[r2 * rs1 + c2 * c + i]; \
40 /*! \def COPY270 */
41 #define COPY270 \
42 if ((r2 < h1) && (c2 < w1)) { \
43 if ((h1 > w1) && (r1 > (h1 - w1))) \
44 for (i = 0; i < c; i++) \
45 new_pixels[(r1 - (h1 - w1)) * rs2 + c1 * c + i] = \
46 pixels[r2 * rs1 + c2 * c + i]; \
47 if ((h1 <= w1) && (c1 < w2)) \
48 for (i = 0; i < c; i++) \
49 new_pixels[r1 * rs2 + c1 * c + i] = \
50 pixels[r2 * rs1 + c2 * c + i]; \
54 /*! \brief Rotate a GdkPixbuf by a given angle
55 * \par Function Description
56 * This function will take a GdkPixbuf and rotate it by the specified angle.
58 * \param [in] pixbuf The pixel buffer to rotate.
59 * \param [in] angle The rotation angle.
60 * \return The rotated pixbuf.
62 GdkPixbuf *gdk_pixbuf_rotate (GdkPixbuf *pixbuf, guint angle)
64 GdkPixbuf *new = NULL;
65 guint row, col, w1, h1, w2, h2;
66 guint r1, r2, c1, c2;
67 guint rs1, rs2;
68 guint c;
69 guint i;
70 guchar *pixels, *new_pixels;
72 if (pixbuf == NULL) {
73 return NULL;
75 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
77 /* Swapped original definitions, so the picture turns counter-clockwise */
78 if (angle == 90)
79 angle = 270;
80 else if (angle == 270)
81 angle = 90;
83 switch (angle) {
84 case 0:
85 return (gdk_pixbuf_copy (pixbuf));
86 case 180:
87 new = gdk_pixbuf_new (
88 gdk_pixbuf_get_colorspace (pixbuf),
89 gdk_pixbuf_get_has_alpha (pixbuf),
90 gdk_pixbuf_get_bits_per_sample (pixbuf),
91 gdk_pixbuf_get_width (pixbuf),
92 gdk_pixbuf_get_height (pixbuf));
93 break;
94 case 90:
95 case 270:
96 new = gdk_pixbuf_new (
97 gdk_pixbuf_get_colorspace (pixbuf),
98 gdk_pixbuf_get_has_alpha (pixbuf),
99 gdk_pixbuf_get_bits_per_sample (pixbuf),
100 gdk_pixbuf_get_height (pixbuf),
101 gdk_pixbuf_get_width (pixbuf));
102 break;
103 default:
104 g_warning ("Rotation by %i not implemented.", angle);
105 break;
108 rs1 = gdk_pixbuf_get_rowstride (pixbuf);
109 rs2 = gdk_pixbuf_get_rowstride (new);
111 c = gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3;
113 w1 = gdk_pixbuf_get_width (pixbuf);
114 h1 = gdk_pixbuf_get_height (pixbuf);
115 w2 = gdk_pixbuf_get_width (new);
116 h2 = gdk_pixbuf_get_height (new);
118 pixels = gdk_pixbuf_get_pixels (pixbuf);
119 new_pixels = gdk_pixbuf_get_pixels (new);
122 * For rotation by 90 or 270, we assume the pixbuf to be a
123 * square and move (r2,c2) to (r1,c1):
125 switch (angle) {
126 case 90:
127 for (row = 0; row < MAX (w1, h1) / 2; row++) {
128 for (col = row; col < MAX (w1, h1) - row - 1; col++) {
129 r1 = row;
130 c1 = col;
131 r2 = MAX (w1, h1) - col - 1;
132 c2 = row;
133 COPY90;
134 r1 = r2;
135 c1 = c2;
136 r2 = MAX (w1, h1) - row - 1;
137 c2 = MAX (w1, h1) - col - 1;
138 COPY90;
139 r1 = r2;
140 c1 = c2;
141 r2 = col;
142 c2 = MAX (w1, h1) - row - 1;
143 COPY90;
144 r1 = r2;
145 c1 = c2;
146 r2 = row;
147 c2 = col;
148 COPY90;
151 break;
152 case 270:
153 for (row = 0; row < MAX (w1, h1) / 2; row++) {
154 for (col = row; col < MAX (w1, h1) - row - 1; col++) {
155 r1 = row;
156 c1 = col;
157 r2 = col;
158 c2 = MAX (w1, h1) - row - 1;
159 COPY270;
160 r1 = r2;
161 c1 = c2;
162 r2 = MAX (w1, h1) - row - 1;
163 c2 = MAX (w1, h1) - col - 1;
164 COPY270;
165 r1 = r2;
166 c1 = c2;
167 r2 = MAX (w1, h1) - col - 1;
168 c2 = row;
169 COPY270;
170 r1 = r2;
171 c1 = c2;
172 r2 = row;
173 c2 = col;
174 COPY270;
177 break;
178 case 180:
179 for (row = 0; row < h1; row++) {
180 for (col = 0; col < w1; col++) {
181 r1 = row;
182 c1 = col;
183 r2 = h1 - row - 1;
184 c2 = w1 - col - 1;
185 for (i = 0; i < c; i++) {
186 new_pixels[r2 * rs2 + c2 * c + i] =
187 pixels[r1 * rs1 + c1 * c + i];
191 break;
192 default:
193 g_warning ("Rotation by %i not implemented.", angle);
194 break;
197 return (new);
200 /*! \note
201 * The following function was taken from GQview, and is covered by this copyright.
202 * The name of the function was changed from pixbuf_copy_mirror to
203 * gdk_pixbuf_mirror_rotate.
205 * GQview
206 * (C) 2002 John Ellis
208 * Author: John Ellis
210 * This software is released under the GNU General Public License (GNU GPL).
211 * Please read the included file COPYING for more information.
212 * This software comes with no warranty of any kind, use at your own risk!
215 /*! \brief Mirror and flip a GdkPixbuf.
216 * \par Function Description
217 * This function will mirror and/or flip the source GdkPixbuf.
218 * To do a 180 degree rotation, set both mirror and flip to TRUE.
219 * If mirror and flip are FALSE, the source image is copied.
221 * \param [in] src Source image to operate on.
222 * \param [in] mirror Mirror image if set to TRUE.
223 * \param [in] flip Flipped image if set to TRUE.
224 * \return Updated copy of source image with operations performed.
226 GdkPixbuf *gdk_pixbuf_mirror_flip(GdkPixbuf *src, gint mirror, gint flip)
228 GdkPixbuf *dest;
229 gint has_alpha;
230 gint w, h, srs;
231 gint drs;
232 guchar *s_pix;
233 guchar *d_pix;
234 guchar *sp;
235 guchar *dp;
236 gint i, j;
237 gint a;
239 if (!src) return NULL;
241 w = gdk_pixbuf_get_width(src);
242 h = gdk_pixbuf_get_height(src);
243 has_alpha = gdk_pixbuf_get_has_alpha(src);
244 srs = gdk_pixbuf_get_rowstride(src);
245 s_pix = gdk_pixbuf_get_pixels(src);
247 dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, has_alpha, 8, w, h);
248 drs = gdk_pixbuf_get_rowstride(dest);
249 d_pix = gdk_pixbuf_get_pixels(dest);
251 a = has_alpha ? 4 : 3;
253 for (i = 0; i < h; i++)
255 sp = s_pix + (i * srs);
256 if (flip)
258 dp = d_pix + ((h - i - 1) * drs);
260 else
262 dp = d_pix + (i * drs);
264 if (mirror)
266 dp += (w - 1) * a;
267 for (j = 0; j < w; j++)
269 *(dp++) = *(sp++); /* r */
270 *(dp++) = *(sp++); /* g */
271 *(dp++) = *(sp++); /* b */
272 if (has_alpha) *(dp) = *(sp++); /* a */
273 dp -= (a + 3);
276 else
278 for (j = 0; j < w; j++)
280 *(dp++) = *(sp++); /* r */
281 *(dp++) = *(sp++); /* g */
282 *(dp++) = *(sp++); /* b */
283 if (has_alpha) *(dp++) = *(sp++); /* a */
288 return dest;