9
|
1 /*
|
|
2 * GQview
|
|
3 * (C) 2004 John Ellis
|
|
4 *
|
|
5 * Author: John Ellis
|
|
6 *
|
|
7 * This software is released under the GNU General Public License (GNU GPL).
|
|
8 * Please read the included file COPYING for more information.
|
|
9 * This software comes with no warranty of any kind, use at your own risk!
|
|
10 */
|
|
11
|
|
12
|
|
13 #include "gqview.h"
|
|
14 #include "pixbuf_util.h"
|
|
15
|
|
16 #include "icons/icons_inline.h"
|
|
17
|
|
18
|
|
19 /*
|
|
20 *-----------------------------------------------------------------------------
|
|
21 * png save
|
|
22 *-----------------------------------------------------------------------------
|
|
23 */
|
|
24
|
|
25 gboolean pixbuf_to_file_as_png (GdkPixbuf *pixbuf, const char *filename)
|
|
26 {
|
|
27 GError *error = NULL;
|
|
28 gint ret;
|
|
29
|
|
30 if (!pixbuf || !filename) return FALSE;
|
|
31
|
|
32 ret = gdk_pixbuf_save(pixbuf, filename, "png", &error,
|
|
33 "tEXt::Software", "GQview "VERSION, NULL);
|
|
34
|
|
35 if (error)
|
|
36 {
|
|
37 printf("Error saving png file: %s\n", error->message);
|
|
38 g_error_free(error);
|
|
39 }
|
|
40
|
|
41 return ret;
|
|
42 }
|
|
43
|
|
44 /*
|
|
45 *-----------------------------------------------------------------------------
|
|
46 * jpeg save
|
|
47 *-----------------------------------------------------------------------------
|
|
48 */
|
|
49
|
|
50 gboolean pixbuf_to_file_as_jpg(GdkPixbuf *pixbuf, const gchar *filename, gint quality)
|
|
51 {
|
|
52 GError *error = NULL;
|
|
53 gchar *qbuf;
|
|
54 gboolean ret;
|
|
55
|
|
56 if (!pixbuf || !filename) return FALSE;
|
|
57
|
|
58 if (quality == -1) quality = 75;
|
|
59 if (quality < 1 || quality > 100)
|
|
60 {
|
|
61 printf("Jpeg not saved, invalid quality %d\n", quality);
|
|
62 return FALSE;
|
|
63 }
|
|
64
|
|
65 qbuf = g_strdup_printf("%d", quality);
|
|
66 ret = gdk_pixbuf_save(pixbuf, filename, "jpeg", &error, "quality", qbuf, NULL);
|
|
67 g_free(qbuf);
|
|
68
|
|
69 if (error)
|
|
70 {
|
|
71 printf("Error saving jpeg to %s\n%s\n", filename, error->message);
|
|
72 g_error_free(error);
|
|
73 }
|
|
74
|
|
75 return ret;
|
|
76 }
|
|
77
|
|
78 /*
|
|
79 *-----------------------------------------------------------------------------
|
|
80 * pixbuf from inline
|
|
81 *-----------------------------------------------------------------------------
|
|
82 */
|
|
83
|
|
84 typedef struct _PixbufInline PixbufInline;
|
|
85 struct _PixbufInline
|
|
86 {
|
|
87 const gchar *key;
|
|
88 const guint8 *data;
|
|
89 };
|
|
90
|
|
91 static PixbufInline inline_pixbuf_data[] = {
|
|
92 { PIXBUF_INLINE_FOLDER_CLOSED, folder_closed },
|
|
93 { PIXBUF_INLINE_FOLDER_LOCKED, folder_locked },
|
|
94 { PIXBUF_INLINE_FOLDER_OPEN, folder_open },
|
|
95 { PIXBUF_INLINE_FOLDER_UP, folder_up },
|
|
96 { PIXBUF_INLINE_SCROLLER, icon_scroller },
|
|
97 { PIXBUF_INLINE_BROKEN, icon_broken },
|
|
98 { PIXBUF_INLINE_LOGO, gqview_logo },
|
|
99 { NULL, NULL }
|
|
100 };
|
|
101
|
|
102 GdkPixbuf *pixbuf_inline(const gchar *key)
|
|
103 {
|
|
104 gint i;
|
|
105
|
|
106 if (!key) return NULL;
|
|
107
|
|
108 i = 0;
|
|
109 while (inline_pixbuf_data[i].key)
|
|
110 {
|
|
111 if (strcmp(inline_pixbuf_data[i].key, key) == 0)
|
|
112 {
|
|
113 return gdk_pixbuf_new_from_inline(-1, inline_pixbuf_data[i].data, FALSE, NULL);
|
|
114 }
|
|
115 i++;
|
|
116 }
|
|
117
|
|
118 printf("warning: inline pixbuf key \"%s\" not found.\n", key);
|
|
119
|
|
120 return NULL;
|
|
121 }
|
|
122
|
|
123 /*
|
|
124 *-----------------------------------------------------------------------------
|
|
125 * pixbuf rotation
|
|
126 *-----------------------------------------------------------------------------
|
|
127 */
|
|
128
|
|
129 static void pixbuf_copy_block_rotate(guchar *src, gint src_row_stride, gint x, gint y,
|
|
130 guchar *dest, gint dest_row_stride, gint w, gint h,
|
|
131 gint bytes_per_pixel, gint counter_clockwise)
|
|
132 {
|
|
133 gint i, j;
|
|
134 guchar *sp;
|
|
135 guchar *dp;
|
|
136
|
|
137 for (i = 0; i < h; i++)
|
|
138 {
|
|
139 sp = src + ((i + y) * src_row_stride) + (x * bytes_per_pixel);
|
|
140 for (j = 0; j < w; j++)
|
|
141 {
|
|
142 if (counter_clockwise)
|
|
143 {
|
|
144 dp = dest + ((w - j - 1) * dest_row_stride) + (i * bytes_per_pixel);
|
|
145 }
|
|
146 else
|
|
147 {
|
|
148 dp = dest + (j * dest_row_stride) + ((h - i - 1) * bytes_per_pixel);
|
|
149 }
|
|
150 *(dp++) = *(sp++); /* r */
|
|
151 *(dp++) = *(sp++); /* g */
|
|
152 *(dp++) = *(sp++); /* b */
|
|
153 if (bytes_per_pixel == 4) *(dp) = *(sp++); /* a */
|
|
154 }
|
|
155 }
|
|
156
|
|
157 }
|
|
158
|
|
159 static void pixbuf_copy_block(guchar *src, gint src_row_stride, gint w, gint h,
|
|
160 guchar *dest, gint dest_row_stride, gint x, gint y, gint bytes_per_pixel)
|
|
161 {
|
|
162 gint i;
|
|
163 guchar *sp;
|
|
164 guchar *dp;
|
|
165
|
|
166 for (i = 0; i < h; i++)
|
|
167 {
|
|
168 sp = src + (i * src_row_stride);
|
|
169 dp = dest + ((y + i) * dest_row_stride) + (x * bytes_per_pixel);
|
|
170 memcpy(dp, sp, w * bytes_per_pixel);
|
|
171 }
|
|
172 }
|
|
173
|
|
174 #define ROTATE_BUFFER_WIDTH 48
|
|
175 #define ROTATE_BUFFER_HEIGHT 48
|
|
176
|
|
177 /*
|
|
178 * Returns a copy of pixbuf src rotated 90 degrees clockwise or 90 counterclockwise
|
|
179 *
|
|
180 */
|
|
181 GdkPixbuf *pixbuf_copy_rotate_90(GdkPixbuf *src, gint counter_clockwise)
|
|
182 {
|
|
183 GdkPixbuf *dest;
|
|
184 gint has_alpha;
|
|
185 gint sw, sh, srs;
|
|
186 gint dw, dh, drs;
|
|
187 guchar *s_pix;
|
|
188 guchar *d_pix;
|
|
189 #if 0
|
|
190 guchar *sp;
|
|
191 guchar *dp;
|
|
192 #endif
|
|
193 gint i, j;
|
|
194 gint a;
|
|
195 GdkPixbuf *buffer;
|
|
196 guchar *b_pix;
|
|
197 gint brs;
|
|
198 gint w, h;
|
|
199
|
|
200 if (!src) return NULL;
|
|
201
|
|
202 sw = gdk_pixbuf_get_width(src);
|
|
203 sh = gdk_pixbuf_get_height(src);
|
|
204 has_alpha = gdk_pixbuf_get_has_alpha(src);
|
|
205 srs = gdk_pixbuf_get_rowstride(src);
|
|
206 s_pix = gdk_pixbuf_get_pixels(src);
|
|
207
|
|
208 dw = sh;
|
|
209 dh = sw;
|
|
210 dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, has_alpha, 8, dw, dh);
|
|
211 drs = gdk_pixbuf_get_rowstride(dest);
|
|
212 d_pix = gdk_pixbuf_get_pixels(dest);
|
|
213
|
|
214 a = (has_alpha ? 4 : 3);
|
|
215
|
|
216 buffer = gdk_pixbuf_new(GDK_COLORSPACE_RGB, has_alpha, 8,
|
|
217 ROTATE_BUFFER_WIDTH, ROTATE_BUFFER_HEIGHT);
|
|
218 b_pix = gdk_pixbuf_get_pixels(buffer);
|
|
219 brs = gdk_pixbuf_get_rowstride(buffer);
|
|
220
|
|
221 for (i = 0; i < sh; i+= ROTATE_BUFFER_WIDTH)
|
|
222 {
|
|
223 w = MIN(ROTATE_BUFFER_WIDTH, (sh - i));
|
|
224 for (j = 0; j < sw; j += ROTATE_BUFFER_HEIGHT)
|
|
225 {
|
|
226 gint x, y;
|
|
227
|
|
228 h = MIN(ROTATE_BUFFER_HEIGHT, (sw - j));
|
|
229 pixbuf_copy_block_rotate(s_pix, srs, j, i,
|
|
230 b_pix, brs, h, w,
|
|
231 a, counter_clockwise);
|
|
232
|
|
233 if (counter_clockwise)
|
|
234 {
|
|
235 x = i;
|
|
236 y = sw - h - j;
|
|
237 }
|
|
238 else
|
|
239 {
|
|
240 x = sh - w - i;
|
|
241 y = j;
|
|
242 }
|
|
243 pixbuf_copy_block(b_pix, brs, w, h,
|
|
244 d_pix, drs, x, y, a);
|
|
245 }
|
|
246 }
|
|
247
|
|
248 gdk_pixbuf_unref(buffer);
|
|
249
|
|
250 #if 0
|
|
251 /* this is the simple version of rotation (roughly 2-4x slower) */
|
|
252
|
|
253 for (i = 0; i < sh; i++)
|
|
254 {
|
|
255 sp = s_pix + (i * srs);
|
|
256 for (j = 0; j < sw; j++)
|
|
257 {
|
|
258 if (counter_clockwise)
|
|
259 {
|
|
260 dp = d_pix + ((dh - j - 1) * drs) + (i * a);
|
|
261 }
|
|
262 else
|
|
263 {
|
|
264 dp = d_pix + (j * drs) + ((dw - i - 1) * a);
|
|
265 }
|
|
266
|
|
267 *(dp++) = *(sp++); /* r */
|
|
268 *(dp++) = *(sp++); /* g */
|
|
269 *(dp++) = *(sp++); /* b */
|
|
270 if (has_alpha) *(dp) = *(sp++); /* a */
|
|
271 }
|
|
272 }
|
|
273 #endif
|
|
274
|
|
275 return dest;
|
|
276 }
|
|
277
|
|
278 /*
|
|
279 * Returns a copy of pixbuf mirrored and or flipped.
|
|
280 * TO do a 180 degree rotations set both mirror and flipped TRUE
|
|
281 * if mirror and flip are FALSE, result is a simple copy.
|
|
282 */
|
|
283 GdkPixbuf *pixbuf_copy_mirror(GdkPixbuf *src, gint mirror, gint flip)
|
|
284 {
|
|
285 GdkPixbuf *dest;
|
|
286 gint has_alpha;
|
|
287 gint w, h, srs;
|
|
288 gint drs;
|
|
289 guchar *s_pix;
|
|
290 guchar *d_pix;
|
|
291 guchar *sp;
|
|
292 guchar *dp;
|
|
293 gint i, j;
|
|
294 gint a;
|
|
295
|
|
296 if (!src) return NULL;
|
|
297
|
|
298 w = gdk_pixbuf_get_width(src);
|
|
299 h = gdk_pixbuf_get_height(src);
|
|
300 has_alpha = gdk_pixbuf_get_has_alpha(src);
|
|
301 srs = gdk_pixbuf_get_rowstride(src);
|
|
302 s_pix = gdk_pixbuf_get_pixels(src);
|
|
303
|
|
304 dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, has_alpha, 8, w, h);
|
|
305 drs = gdk_pixbuf_get_rowstride(dest);
|
|
306 d_pix = gdk_pixbuf_get_pixels(dest);
|
|
307
|
|
308 a = has_alpha ? 4 : 3;
|
|
309
|
|
310 for (i = 0; i < h; i++)
|
|
311 {
|
|
312 sp = s_pix + (i * srs);
|
|
313 if (flip)
|
|
314 {
|
|
315 dp = d_pix + ((h - i - 1) * drs);
|
|
316 }
|
|
317 else
|
|
318 {
|
|
319 dp = d_pix + (i * drs);
|
|
320 }
|
|
321 if (mirror)
|
|
322 {
|
|
323 dp += (w - 1) * a;
|
|
324 for (j = 0; j < w; j++)
|
|
325 {
|
|
326 *(dp++) = *(sp++); /* r */
|
|
327 *(dp++) = *(sp++); /* g */
|
|
328 *(dp++) = *(sp++); /* b */
|
|
329 if (has_alpha) *(dp) = *(sp++); /* a */
|
|
330 dp -= (a + 3);
|
|
331 }
|
|
332 }
|
|
333 else
|
|
334 {
|
|
335 for (j = 0; j < w; j++)
|
|
336 {
|
|
337 *(dp++) = *(sp++); /* r */
|
|
338 *(dp++) = *(sp++); /* g */
|
|
339 *(dp++) = *(sp++); /* b */
|
|
340 if (has_alpha) *(dp++) = *(sp++); /* a */
|
|
341 }
|
|
342 }
|
|
343 }
|
|
344
|
|
345 return dest;
|
|
346 }
|
|
347
|
|
348
|
|
349 /*
|
|
350 *-----------------------------------------------------------------------------
|
|
351 * pixbuf drawing
|
|
352 *-----------------------------------------------------------------------------
|
|
353 */
|
|
354
|
|
355 /*
|
|
356 * Fills region of pixbuf at x,y over w,h
|
|
357 * with colors red (r), green (g), blue (b)
|
|
358 * applying alpha (a), use a=255 for solid.
|
|
359 */
|
|
360 void pixbuf_draw_rect_fill(GdkPixbuf *pb,
|
|
361 gint x, gint y, gint w, gint h,
|
|
362 gint r, gint g, gint b, gint a)
|
|
363 {
|
|
364 gint p_alpha;
|
|
365 gint pw, ph, prs;
|
|
366 guchar *p_pix;
|
|
367 guchar *pp;
|
|
368 gint i, j;
|
|
369
|
|
370 if (!pb) return;
|
|
371
|
|
372 pw = gdk_pixbuf_get_width(pb);
|
|
373 ph = gdk_pixbuf_get_height(pb);
|
|
374
|
|
375 if (x < 0 || x + w > pw) return;
|
|
376 if (y < 0 || y + h > ph) return;
|
|
377
|
|
378 p_alpha = gdk_pixbuf_get_has_alpha(pb);
|
|
379 prs = gdk_pixbuf_get_rowstride(pb);
|
|
380 p_pix = gdk_pixbuf_get_pixels(pb);
|
|
381
|
|
382 for (i = 0; i < h; i++)
|
|
383 {
|
|
384 pp = p_pix + (y + i) * prs + (x * (p_alpha ? 4 : 3));
|
|
385 for (j = 0; j < w; j++)
|
|
386 {
|
|
387 *pp = (r * a + *pp * (256-a)) >> 8;
|
|
388 pp++;
|
|
389 *pp = (g * a + *pp * (256-a)) >> 8;
|
|
390 pp++;
|
|
391 *pp = (b * a + *pp * (256-a)) >> 8;
|
|
392 pp++;
|
|
393 if (p_alpha) pp++;
|
|
394 }
|
|
395 }
|
|
396 }
|
|
397
|
|
398 void pixbuf_draw_rect(GdkPixbuf *pb,
|
|
399 gint x, gint y, gint w, gint h,
|
|
400 gint r, gint g, gint b, gint a,
|
|
401 gint left, gint right, gint top, gint bottom)
|
|
402 {
|
|
403 pixbuf_draw_rect_fill(pb, x + left, y, w - left - right, top,
|
|
404 r, g, b ,a);
|
|
405 pixbuf_draw_rect_fill(pb, x + w - right, y, right, h,
|
|
406 r, g, b ,a);
|
|
407 pixbuf_draw_rect_fill(pb, x + left, y + h - bottom, w - left - right, bottom,
|
|
408 r, g, b ,a);
|
|
409 pixbuf_draw_rect_fill(pb, x, y, left, h,
|
|
410 r, g, b ,a);
|
|
411 }
|
|
412
|
|
413 void pixbuf_set_rect_fill(GdkPixbuf *pb,
|
|
414 gint x, gint y, gint w, gint h,
|
|
415 gint r, gint g, gint b, gint a)
|
|
416 {
|
|
417 gint p_alpha;
|
|
418 gint pw, ph, prs;
|
|
419 guchar *p_pix;
|
|
420 guchar *pp;
|
|
421 gint i, j;
|
|
422
|
|
423 if (!pb) return;
|
|
424
|
|
425 pw = gdk_pixbuf_get_width(pb);
|
|
426 ph = gdk_pixbuf_get_height(pb);
|
|
427
|
|
428 if (x < 0 || x + w > pw) return;
|
|
429 if (y < 0 || y + h > ph) return;
|
|
430
|
|
431 p_alpha = gdk_pixbuf_get_has_alpha(pb);
|
|
432 prs = gdk_pixbuf_get_rowstride(pb);
|
|
433 p_pix = gdk_pixbuf_get_pixels(pb);
|
|
434
|
|
435 for (i = 0; i < h; i++)
|
|
436 {
|
|
437 pp = p_pix + (y + i) * prs + (x * (p_alpha ? 4 : 3));
|
|
438 for (j = 0; j < w; j++)
|
|
439 {
|
|
440 *pp = r; pp++;
|
|
441 *pp = g; pp++;
|
|
442 *pp = b; pp++;
|
|
443 if (p_alpha) { *pp = a; pp++; }
|
|
444 }
|
|
445 }
|
|
446 }
|
|
447
|
|
448 void pixbuf_set_rect(GdkPixbuf *pb,
|
|
449 gint x, gint y, gint w, gint h,
|
|
450 gint r, gint g, gint b, gint a,
|
|
451 gint left, gint right, gint top, gint bottom)
|
|
452 {
|
|
453 pixbuf_set_rect_fill(pb, x + left, y, w - left - right, top,
|
|
454 r, g, b ,a);
|
|
455 pixbuf_set_rect_fill(pb, x + w - right, y, right, h,
|
|
456 r, g, b ,a);
|
|
457 pixbuf_set_rect_fill(pb, x + left, y + h - bottom, w - left - right, bottom,
|
|
458 r, g, b ,a);
|
|
459 pixbuf_set_rect_fill(pb, x, y, left, h,
|
|
460 r, g, b ,a);
|
|
461 }
|
|
462
|
|
463 void pixbuf_pixel_set(GdkPixbuf *pb, gint x, gint y, gint r, gint g, gint b, gint a)
|
|
464 {
|
|
465 guchar *buf;
|
|
466 gint has_alpha;
|
|
467 gint rowstride;
|
|
468 guchar *p;
|
|
469
|
|
470 if (x < 0 || x >= gdk_pixbuf_get_width(pb) ||
|
|
471 y < 0 || y >= gdk_pixbuf_get_height(pb)) return;
|
|
472
|
|
473 buf = gdk_pixbuf_get_pixels(pb);
|
|
474 has_alpha = gdk_pixbuf_get_has_alpha(pb);
|
|
475 rowstride = gdk_pixbuf_get_rowstride(pb);
|
|
476
|
|
477 p = buf + (y * rowstride) + (x * (has_alpha ? 4 : 3));
|
|
478 *p = r; p++;
|
|
479 *p = g; p++;
|
|
480 *p = b; p++;
|
|
481 if (has_alpha) *p = a;
|
|
482 }
|
|
483
|
|
484
|
|
485 /*
|
|
486 *-----------------------------------------------------------------------------
|
|
487 * pixbuf text rendering
|
|
488 *-----------------------------------------------------------------------------
|
|
489 */
|
|
490
|
|
491 static void pixbuf_copy_font(GdkPixbuf *src, gint sx, gint sy,
|
|
492 GdkPixbuf *dest, gint dx, gint dy,
|
|
493 gint w, gint h,
|
|
494 guint8 r, guint8 g, guint8 b, guint8 a)
|
|
495 {
|
|
496 gint sw, sh, srs;
|
|
497 gint s_alpha;
|
|
498 gint s_step;
|
|
499 guchar *s_pix;
|
|
500 gint dw, dh, drs;
|
|
501 gint d_alpha;
|
|
502 gint d_step;
|
|
503 guchar *d_pix;
|
|
504
|
|
505 guchar *sp;
|
|
506 guchar *dp;
|
|
507 gint i, j;
|
|
508
|
|
509 if (!src || !dest) return;
|
|
510
|
|
511 sw = gdk_pixbuf_get_width(src);
|
|
512 sh = gdk_pixbuf_get_height(src);
|
|
513
|
|
514 if (sx < 0 || sx + w > sw) return;
|
|
515 if (sy < 0 || sy + h > sh) return;
|
|
516
|
|
517 dw = gdk_pixbuf_get_width(dest);
|
|
518 dh = gdk_pixbuf_get_height(dest);
|
|
519
|
|
520 if (dx < 0 || dx + w > dw) return;
|
|
521 if (dy < 0 || dy + h > dh) return;
|
|
522
|
|
523 s_alpha = gdk_pixbuf_get_has_alpha(src);
|
|
524 d_alpha = gdk_pixbuf_get_has_alpha(dest);
|
|
525 srs = gdk_pixbuf_get_rowstride(src);
|
|
526 drs = gdk_pixbuf_get_rowstride(dest);
|
|
527 s_pix = gdk_pixbuf_get_pixels(src);
|
|
528 d_pix = gdk_pixbuf_get_pixels(dest);
|
|
529
|
|
530 s_step = (s_alpha) ? 4 : 3;
|
|
531 d_step = (d_alpha) ? 4 : 3;
|
|
532
|
|
533 for (i = 0; i < h; i++)
|
|
534 {
|
|
535 sp = s_pix + (sy + i) * srs + sx * s_step;
|
|
536 dp = d_pix + (dy + i) * drs + dx * d_step;
|
|
537 for (j = 0; j < w; j++)
|
|
538 {
|
|
539 if (*sp)
|
|
540 {
|
|
541 guint8 asub;
|
|
542
|
|
543 asub = a * sp[0] / 255;
|
|
544 *dp = (r * asub + *dp * (256-asub)) >> 8;
|
|
545 dp++;
|
|
546 asub = a * sp[1] / 255;
|
|
547 *dp = (g * asub + *dp * (256-asub)) >> 8;
|
|
548 dp++;
|
|
549 asub = a * sp[2] / 255;
|
|
550 *dp = (b * asub + *dp * (256-asub)) >> 8;
|
|
551 dp++;
|
|
552
|
|
553 if (d_alpha)
|
|
554 {
|
|
555 *dp = MAX(*dp, a * ((sp[0] + sp[1] + sp[2]) / 3) / 255);
|
|
556 dp++;
|
|
557 }
|
|
558 }
|
|
559 else
|
|
560 {
|
|
561 dp += d_step;
|
|
562 }
|
|
563
|
|
564 sp += s_step;
|
|
565 }
|
|
566 }
|
|
567 }
|
|
568
|
|
569 void pixbuf_draw_layout(GdkPixbuf *pixbuf, PangoLayout *layout, GtkWidget *widget,
|
|
570 gint x, gint y,
|
|
571 guint8 r, guint8 g, guint8 b, guint8 a)
|
|
572 {
|
|
573 GdkPixmap *pixmap;
|
|
574 GdkPixbuf *buffer;
|
|
575 gint w, h;
|
|
576 GdkGC *gc;
|
|
577 gint sx, sy;
|
|
578 gint dw, dh;
|
|
579
|
|
580 if (!widget || !widget->window) return;
|
|
581
|
|
582 pango_layout_get_pixel_size(layout, &w, &h);
|
|
583 pixmap = gdk_pixmap_new(widget->window, w, h, -1);
|
|
584
|
|
585 gc = gdk_gc_new(widget->window);
|
|
586 gdk_gc_copy(gc, widget->style->black_gc);
|
|
587 gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, w, h);
|
|
588 gdk_gc_copy(gc, widget->style->white_gc);
|
|
589 gdk_draw_layout(pixmap, gc, 0, 0, layout);
|
|
590 g_object_unref(gc);
|
|
591
|
|
592 buffer = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, w, h);
|
|
593 gdk_pixbuf_get_from_drawable(buffer, pixmap,
|
|
594 gdk_drawable_get_colormap(widget->window),
|
|
595 0, 0, 0, 0, w, h);
|
|
596 g_object_unref(pixmap);
|
|
597
|
|
598 sx = 0;
|
|
599 sy = 0;
|
|
600 dw = gdk_pixbuf_get_width(pixbuf);
|
|
601 dh = gdk_pixbuf_get_height(pixbuf);
|
|
602
|
|
603 if (x < 0)
|
|
604 {
|
|
605 w += x;
|
|
606 sx = -x;
|
|
607 x = 0;
|
|
608 }
|
|
609
|
|
610 if (y < 0)
|
|
611 {
|
|
612 h += y;
|
|
613 sy = -y;
|
|
614 y = 0;
|
|
615 }
|
|
616
|
|
617 if (x + w > dw) w = dw - x;
|
|
618 if (y + h > dh) h = dh - y;
|
|
619
|
|
620 pixbuf_copy_font(buffer, 0, 0,
|
|
621 pixbuf, x, y, w, h,
|
|
622 r, g, b, a);
|
|
623
|
|
624 g_object_unref(buffer);
|
|
625 }
|
|
626
|