gdk_pixbuf2 0.90.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,794 @@
1
+ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
2
+ /************************************************
3
+
4
+ rbgdk-pixbuf.c -
5
+
6
+ $Author: ggc $
7
+ $Date: 2007/07/13 16:07:28 $
8
+
9
+ Copyright (C) 2002-2004 Masao Mutoh
10
+ Copyright (C) 2000 Yasushi Shoji
11
+ ************************************************/
12
+
13
+ #include "rbgdk-pixbuf.h"
14
+ #include <string.h>
15
+
16
+ #ifdef HAVE_GDK_PIXBUF_GDK_PIXBUF_IO_H
17
+ #define GDK_PIXBUF_ENABLE_BACKEND
18
+ #include <gdk-pixbuf/gdk-pixbuf-io.h>
19
+ #endif
20
+
21
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,8,0) && defined(HAVE_RB_CAIRO_H)
22
+ # include <gdk/gdkcairo.h>
23
+ # include <rb_cairo.h>
24
+ # define CAIRO_AVAILABLE 1
25
+ #else
26
+ # define CAIRO_AVAILABLE 0
27
+ #endif
28
+
29
+ #define _SELF(s) GDK_PIXBUF(RVAL2GOBJ(s))
30
+
31
+ #define NOMEM_ERROR(error) g_set_error(error,\
32
+ GDK_PIXBUF_ERROR,\
33
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,\
34
+ "Insufficient memory to load image file");
35
+
36
+ static ID id_pixdata;
37
+
38
+ /****************************************************/
39
+ /* The GdkPixbuf Structure */
40
+ static VALUE
41
+ get_colorspace(self)
42
+ VALUE self;
43
+ {
44
+ return GENUM2RVAL(gdk_pixbuf_get_colorspace(_SELF(self)), GDK_TYPE_COLORSPACE);
45
+ }
46
+
47
+ static VALUE
48
+ get_n_channels(self)
49
+ VALUE self;
50
+ {
51
+ return INT2FIX(gdk_pixbuf_get_n_channels(_SELF(self)));
52
+ }
53
+
54
+ static VALUE
55
+ get_has_alpha(self)
56
+ VALUE self;
57
+ {
58
+ return CBOOL2RVAL(gdk_pixbuf_get_has_alpha(_SELF(self)));
59
+ }
60
+
61
+ static VALUE
62
+ get_bits_per_sample(self)
63
+ VALUE self;
64
+ {
65
+ return INT2FIX(gdk_pixbuf_get_bits_per_sample(_SELF(self)));
66
+ }
67
+
68
+ static int
69
+ pixels_size(GdkPixbuf *pixbuf)
70
+ {
71
+ int height, width, rowstride, n_channels, bits_per_sample;
72
+
73
+ height = gdk_pixbuf_get_height(pixbuf);
74
+ width = gdk_pixbuf_get_width(pixbuf);
75
+ rowstride = gdk_pixbuf_get_rowstride(pixbuf);
76
+ n_channels = gdk_pixbuf_get_n_channels(pixbuf);
77
+ bits_per_sample = gdk_pixbuf_get_bits_per_sample(pixbuf);
78
+
79
+ return ((height - 1) * rowstride +
80
+ width * ((n_channels * bits_per_sample + 7) / 8));
81
+ }
82
+
83
+ static VALUE
84
+ get_pixels(VALUE self)
85
+ {
86
+ GdkPixbuf *pixbuf = _SELF(self);
87
+ int size;
88
+
89
+ size = pixels_size(pixbuf);
90
+ return rb_str_new((const char*)gdk_pixbuf_get_pixels(pixbuf), size);
91
+ }
92
+
93
+ static VALUE
94
+ set_pixels(VALUE self, VALUE pixels)
95
+ {
96
+ GdkPixbuf *pixbuf = _SELF(self);
97
+ int size;
98
+ int arg_size;
99
+
100
+ size = pixels_size(pixbuf);
101
+
102
+ Check_Type(pixels, T_STRING);
103
+ arg_size = RSTRING_LEN(pixels);
104
+ if (arg_size != size)
105
+ rb_raise(rb_eRangeError,
106
+ "Pixels are %i bytes, %i bytes supplied.",
107
+ size, arg_size);
108
+
109
+ /* The user currently cannot get a pointer to the actual
110
+ * pixels, the data is copied to a String. */
111
+ memcpy(gdk_pixbuf_get_pixels(pixbuf),
112
+ RSTRING_PTR(pixels), MIN(RSTRING_LEN(pixels), size));
113
+
114
+ return pixels;
115
+ }
116
+
117
+ static VALUE
118
+ get_width(self)
119
+ VALUE self;
120
+ {
121
+ return INT2FIX(gdk_pixbuf_get_width(_SELF(self)));
122
+ }
123
+
124
+ static VALUE
125
+ get_height(self)
126
+ VALUE self;
127
+ {
128
+ return INT2FIX(gdk_pixbuf_get_height(_SELF(self)));
129
+ }
130
+
131
+ static VALUE
132
+ get_rowstride(self)
133
+ VALUE self;
134
+ {
135
+ return INT2FIX(gdk_pixbuf_get_rowstride(_SELF(self)));
136
+ }
137
+
138
+ static VALUE
139
+ get_option(self, key)
140
+ VALUE self, key;
141
+ {
142
+ const gchar* ret = gdk_pixbuf_get_option(_SELF(self), RVAL2CSTR(key));
143
+ return ret ? CSTR2RVAL(ret) : Qnil;
144
+ }
145
+
146
+ /****************************************************/
147
+ /* File opening */
148
+ /* Image Data in Memory */
149
+ static VALUE
150
+ initialize(argc, argv, self)
151
+ int argc;
152
+ VALUE *argv;
153
+ VALUE self;
154
+ {
155
+ GdkPixbuf* buf;
156
+ GError* error = NULL;
157
+ VALUE arg1, arg2, arg3, arg4, arg5, arg6, arg7;
158
+
159
+ rb_scan_args(argc, argv, "16", &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7);
160
+
161
+ if (argc == 7){
162
+ buf = gdk_pixbuf_new_from_data((const guchar*)RVAL2CSTR(arg1),
163
+ RVAL2GENUM(arg2, GDK_TYPE_COLORSPACE),
164
+ RVAL2CBOOL(arg3), NUM2INT(arg4),
165
+ NUM2INT(arg5), NUM2INT(arg6),
166
+ NUM2INT(arg7), NULL, NULL);
167
+ if (buf == NULL){
168
+ rb_gc();
169
+ buf = gdk_pixbuf_new_from_data((const guchar*)RVAL2CSTR(arg1),
170
+ RVAL2GENUM(arg2, GDK_TYPE_COLORSPACE),
171
+ RVAL2CBOOL(arg3), NUM2INT(arg4),
172
+ NUM2INT(arg5), NUM2INT(arg6),
173
+ NUM2INT(arg7), NULL, NULL);
174
+ if (buf == NULL) NOMEM_ERROR(&error);
175
+ }
176
+ // Save a reference to the string because the pixbuf doesn't copy it.
177
+ G_RELATIVE(self, arg1);
178
+ } else if (argc == 5){
179
+ if (rb_obj_is_kind_of(arg1, GTYPE2CLASS(GDK_TYPE_PIXBUF))){
180
+ buf = gdk_pixbuf_new_subpixbuf(_SELF(arg1),
181
+ NUM2INT(arg2), NUM2INT(arg3),
182
+ NUM2INT(arg4), NUM2INT(arg5));
183
+ if (buf == NULL){
184
+ rb_gc();
185
+ buf = gdk_pixbuf_new_subpixbuf(_SELF(arg1),
186
+ NUM2INT(arg2), NUM2INT(arg3),
187
+ NUM2INT(arg4), NUM2INT(arg5));
188
+ if (buf == NULL) NOMEM_ERROR(&error);
189
+ }
190
+ } else if (rb_obj_is_kind_of(arg1, GTYPE2CLASS(GDK_TYPE_COLORSPACE))){
191
+ buf = gdk_pixbuf_new(RVAL2GENUM(arg1, GDK_TYPE_COLORSPACE),
192
+ RVAL2CBOOL(arg2), NUM2INT(arg3),
193
+ NUM2INT(arg4), NUM2INT(arg5));
194
+ if (buf == NULL){
195
+ rb_gc();
196
+ buf = gdk_pixbuf_new(RVAL2GENUM(arg1, GDK_TYPE_COLORSPACE),
197
+ RVAL2CBOOL(arg2), NUM2INT(arg3),
198
+ NUM2INT(arg4), NUM2INT(arg5));
199
+ if (buf == NULL) NOMEM_ERROR(&error);
200
+ }
201
+ } else {
202
+ rb_raise(rb_eArgError, "Wrong type of 1st argument or wrong number of arguments");
203
+ }
204
+ } else if (argc == 4) {
205
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,6,0)
206
+ int width = NUM2INT(arg2);
207
+ int height = NUM2INT(arg3);
208
+ #if ! RBGDK_PIXBUF_CHECK_VERSION(2,8,0)
209
+ if (width < 0 || height < 0)
210
+ rb_warning("For scaling on load, a negative value for width or height are not supported in GTK+ < 2.8.0");
211
+ #endif
212
+ buf = gdk_pixbuf_new_from_file_at_scale(RVAL2CSTR(arg1),
213
+ width, height,
214
+ RVAL2CBOOL(arg4), &error);
215
+ if (buf == NULL){
216
+ rb_gc();
217
+ error = NULL;
218
+ buf = gdk_pixbuf_new_from_file_at_scale(RVAL2CSTR(arg1),
219
+ NUM2INT(arg2), NUM2INT(arg3),
220
+ RVAL2CBOOL(arg4), &error);
221
+ }
222
+ #else
223
+ rb_warning("Scaling on load not supported in GTK+ < 2.6.0");
224
+ buf = gdk_pixbuf_new_from_file(RVAL2CSTR(arg1), &error);
225
+ if (buf == NULL){
226
+ error = NULL;
227
+ rb_gc();
228
+ buf = gdk_pixbuf_new_from_file(RVAL2CSTR(arg1), &error);
229
+ }
230
+ #endif
231
+ } else if (argc == 3) {
232
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,4,0)
233
+ buf = gdk_pixbuf_new_from_file_at_size(RVAL2CSTR(arg1),
234
+ NUM2INT(arg2), NUM2INT(arg3), &error);
235
+ if (buf == NULL){
236
+ rb_gc();
237
+ error = NULL;
238
+ buf = gdk_pixbuf_new_from_file_at_size(RVAL2CSTR(arg1),
239
+ NUM2INT(arg2), NUM2INT(arg3), &error);
240
+ }
241
+ #else
242
+ rb_warning("Sizing on load not supported in GTK+ < 2.4.0");
243
+ buf = gdk_pixbuf_new_from_file(RVAL2CSTR(arg1), &error);
244
+ if (buf == NULL){
245
+ error = NULL;
246
+ rb_gc();
247
+ buf = gdk_pixbuf_new_from_file(RVAL2CSTR(arg1), &error);
248
+ }
249
+ #endif
250
+ } else if (argc == 2){
251
+ int i;
252
+ int len = RARRAY_LEN(arg1);
253
+ guint8 *gstream = g_new(guint8, len);
254
+ for (i = 0; i < len; i++){
255
+ gstream[i] = (guint8)NUM2UINT(RARRAY_PTR(arg1)[i]);
256
+ }
257
+ buf = gdk_pixbuf_new_from_inline(len, gstream, RVAL2CBOOL(arg2), &error);
258
+ if (buf == NULL){
259
+ rb_gc();
260
+ error = NULL;
261
+ buf = gdk_pixbuf_new_from_inline(len, gstream, RVAL2CBOOL(arg2), &error);
262
+ }
263
+ /* need to manage the returned value */
264
+ rb_ivar_set(self, id_pixdata, Data_Wrap_Struct(rb_cData, NULL, g_free, gstream));
265
+ } else if (argc == 1){
266
+ if (TYPE(arg1) == T_STRING) {
267
+ buf = gdk_pixbuf_new_from_file(RVAL2CSTR(arg1), &error);
268
+ if (buf == NULL){
269
+ rb_gc();
270
+ error = NULL;
271
+ buf = gdk_pixbuf_new_from_file(RVAL2CSTR(arg1), &error);
272
+ }
273
+ } else if (TYPE(arg1) == T_ARRAY) {
274
+ int i;
275
+ gchar** data = ALLOCA_N(gchar*, RARRAY_LEN(arg1));
276
+ for (i=0; i < RARRAY_LEN(arg1); i++) {
277
+ data[i] = RVAL2CSTR(RARRAY_PTR(arg1)[i]);
278
+ }
279
+ buf = gdk_pixbuf_new_from_xpm_data((const gchar**)data);
280
+ if (buf == NULL){
281
+ rb_gc();
282
+ buf = gdk_pixbuf_new_from_xpm_data((const gchar**)data);
283
+ if (buf == NULL) NOMEM_ERROR(&error);
284
+ }
285
+ } else {
286
+ rb_raise(rb_eArgError, "Wrong type of 1st argument or wrong number of arguments");
287
+ }
288
+ } else {
289
+ rb_raise(rb_eArgError, "Wrong number of arguments");
290
+ }
291
+
292
+ if (error || ! buf) RAISE_GERROR(error);
293
+
294
+ G_INITIALIZE(self, buf);
295
+ return Qnil;
296
+ }
297
+
298
+ static VALUE
299
+ copy(self)
300
+ VALUE self;
301
+ {
302
+ VALUE ret;
303
+ GdkPixbuf* dest = gdk_pixbuf_copy(_SELF(self));
304
+ if (dest == NULL)
305
+ return Qnil;
306
+ ret = GOBJ2RVAL(dest);
307
+ g_object_unref(dest);
308
+ return ret;
309
+ }
310
+
311
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,4,0)
312
+ static VALUE
313
+ get_file_info(self, filename)
314
+ VALUE self, filename;
315
+ {
316
+ gint width, height;
317
+
318
+ GdkPixbufFormat* format = gdk_pixbuf_get_file_info(RVAL2CSTR(filename),
319
+ &width, &height);
320
+ return format ? rb_ary_new3(3, BOXED2RVAL(format, GDK_TYPE_PIXBUF_FORMAT), INT2NUM(width), INT2NUM(height)) : Qnil;
321
+ }
322
+
323
+ #endif
324
+
325
+ static VALUE
326
+ save_to(VALUE self, gchar *filename, gchar *type, VALUE options)
327
+ {
328
+ VALUE result = self;
329
+ GError *error = NULL;
330
+ gchar **keys = NULL;
331
+ gchar **values = NULL;
332
+
333
+ if (!NIL_P(options)) {
334
+ VALUE ary, key, value;
335
+ ID to_s;
336
+ gint len, i;
337
+
338
+ Check_Type(options, T_HASH);
339
+ to_s = rb_intern("to_s");
340
+
341
+ ary = rb_funcall(options, rb_intern("to_a"), 0);
342
+ len = RARRAY_LEN(ary);
343
+ keys = ALLOCA_N(gchar *, len + 1);
344
+ values = ALLOCA_N(gchar *, len + 1);
345
+ for (i = 0; i < len; i++) {
346
+ key = RARRAY_PTR(RARRAY_PTR(ary)[i])[0];
347
+ if (SYMBOL_P(key)) {
348
+ const char *const_key;
349
+ const_key = rb_id2name(SYM2ID(key));
350
+ keys[i] = (gchar *)const_key;
351
+ } else {
352
+ keys[i] = RVAL2CSTR(key);
353
+ }
354
+ value = rb_funcall(RARRAY_PTR(RARRAY_PTR(ary)[i])[1], to_s, 0);
355
+ values[i] = RVAL2CSTR(value);
356
+ }
357
+ keys[len] = NULL;
358
+ values[len] = NULL;
359
+ }
360
+
361
+ if (filename) {
362
+ gdk_pixbuf_savev(_SELF(self), filename, type, keys, values, &error);
363
+ }
364
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,4,0)
365
+ else {
366
+ gchar *buffer;
367
+ gsize buffer_size;
368
+ if (gdk_pixbuf_save_to_bufferv(_SELF(self), &buffer, &buffer_size,
369
+ type, keys, values, &error))
370
+ result = rb_str_new(buffer, buffer_size);
371
+ }
372
+ #endif
373
+
374
+ if (error)
375
+ RAISE_GERROR(error);
376
+
377
+ return result;
378
+ }
379
+
380
+ /****************************************************/
381
+ /* File saving */
382
+ static VALUE
383
+ save(int argc, VALUE *argv, VALUE self)
384
+ {
385
+ VALUE filename, type, options;
386
+
387
+ rb_scan_args(argc, argv, "21", &filename, &type, &options);
388
+
389
+ return save_to(self, RVAL2CSTR(filename), RVAL2CSTR(type), options);
390
+ }
391
+
392
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,4,0)
393
+ /* XXX
394
+ gboolean gdk_pixbuf_save_to_callbackv (GdkPixbuf *pixbuf,
395
+ GdkPixbufSaveFunc save_func,
396
+ gpointer user_data,
397
+ const char *type,
398
+ char **option_keys,
399
+ char **option_values,
400
+ GError **error);
401
+ */
402
+
403
+ static VALUE
404
+ save_to_buffer(int argc, VALUE *argv, VALUE self)
405
+ {
406
+ VALUE type, options;
407
+
408
+ rb_scan_args(argc, argv, "11", &type, &options);
409
+
410
+ return save_to(self, NULL, RVAL2CSTR(type), options);
411
+ }
412
+ #endif
413
+
414
+ /****************************************************/
415
+ /* Scaling */
416
+ static VALUE
417
+ scale_simple(argc, argv, self)
418
+ int argc;
419
+ VALUE *argv;
420
+ VALUE self;
421
+ {
422
+ GdkPixbuf* dest;
423
+ VALUE dest_width, dest_height, interp_type, ret;
424
+ GdkInterpType type = GDK_INTERP_BILINEAR;
425
+
426
+ rb_scan_args(argc, argv, "21", &dest_width, &dest_height,
427
+ &interp_type);
428
+
429
+ if (!NIL_P(interp_type))
430
+ type = RVAL2GENUM(interp_type, GDK_TYPE_INTERP_TYPE);
431
+
432
+ dest = gdk_pixbuf_scale_simple(_SELF(self),
433
+ NUM2INT(dest_width),
434
+ NUM2INT(dest_height),
435
+ type);
436
+ if (dest == NULL)
437
+ return Qnil;
438
+
439
+ ret = GOBJ2RVAL(dest);
440
+ g_object_unref(dest);
441
+ return ret;
442
+ }
443
+
444
+ static VALUE
445
+ scale(argc, argv, self)
446
+ int argc;
447
+ VALUE *argv;
448
+ VALUE self;
449
+ {
450
+ GdkInterpType type = GDK_INTERP_BILINEAR;
451
+
452
+ VALUE src, src_x, src_y, src_width, src_height;
453
+ VALUE offset_x, offset_y, scale_x, scale_y, interp_type;
454
+
455
+ rb_scan_args(argc, argv, "91", &src, &src_x, &src_y,
456
+ &src_width, &src_height, &offset_x, &offset_y,
457
+ &scale_x, &scale_y, &interp_type);
458
+
459
+ if (!NIL_P(interp_type))
460
+ type = RVAL2GENUM(interp_type, GDK_TYPE_INTERP_TYPE);
461
+
462
+ gdk_pixbuf_scale(_SELF(src), _SELF(self),
463
+ NUM2INT(src_x), NUM2INT(src_y),
464
+ NUM2INT(src_width), NUM2INT(src_height),
465
+ NUM2DBL(offset_x), NUM2DBL(offset_y),
466
+ NUM2DBL(scale_x), NUM2DBL(scale_y), type);
467
+ return self;
468
+ }
469
+
470
+ static VALUE
471
+ composite_simple(self, dest_width, dest_height, interp_type, overall_alpha,
472
+ check_size, color1, color2)
473
+ VALUE self, dest_width, dest_height, interp_type, overall_alpha,
474
+ check_size, color1, color2;
475
+ {
476
+ GdkPixbuf* dest;
477
+ VALUE ret;
478
+ GdkInterpType type = GDK_INTERP_BILINEAR;
479
+
480
+ if (!NIL_P(interp_type))
481
+ type = RVAL2GENUM(interp_type, GDK_TYPE_INTERP_TYPE);
482
+
483
+ dest = gdk_pixbuf_composite_color_simple(
484
+ _SELF(self), NUM2INT(dest_width), NUM2INT(dest_height),
485
+ type, NUM2INT(overall_alpha), NUM2INT(check_size),
486
+ NUM2UINT(color1), NUM2UINT(color2));
487
+
488
+ if (dest == NULL)
489
+ return Qnil;
490
+
491
+ ret = GOBJ2RVAL(dest);
492
+ g_object_unref(dest);
493
+ return ret;
494
+ }
495
+
496
+ static VALUE
497
+ composite(argc, argv, self)
498
+ int argc;
499
+ VALUE *argv;
500
+ VALUE self;
501
+ {
502
+ VALUE ret;
503
+ VALUE args[16];
504
+ GdkInterpType interp_type = GDK_INTERP_BILINEAR;
505
+
506
+ rb_scan_args(argc, argv, "97",
507
+ &args[0], &args[1], &args[2], &args[3], &args[4],
508
+ &args[5], &args[6], &args[7], &args[8], &args[9],
509
+ &args[10], &args[11], &args[12], &args[13], &args[14],
510
+ &args[15]);
511
+
512
+ switch (argc) {
513
+ case 11:
514
+ if (!NIL_P(args[9]))
515
+ interp_type = RVAL2GENUM(args[9], GDK_TYPE_INTERP_TYPE);
516
+
517
+ gdk_pixbuf_composite(_SELF(args[0]), _SELF(self),
518
+ NUM2INT(args[1]), NUM2INT(args[2]),
519
+ NUM2INT(args[3]), NUM2INT(args[4]),
520
+ NUM2DBL(args[5]), NUM2DBL(args[6]),
521
+ NUM2DBL(args[7]), NUM2DBL(args[8]),
522
+ interp_type, NUM2INT(args[10]));
523
+ ret = self;
524
+ break;
525
+ case 16:
526
+ if (!NIL_P(args[9]))
527
+ interp_type = RVAL2GENUM(args[9], GDK_TYPE_INTERP_TYPE);
528
+
529
+ gdk_pixbuf_composite_color(_SELF(args[0]), _SELF(self),
530
+ NUM2INT(args[1]), NUM2INT(args[2]),
531
+ NUM2INT(args[3]), NUM2INT(args[4]),
532
+ NUM2DBL(args[5]), NUM2DBL(args[6]),
533
+ NUM2DBL(args[7]), NUM2DBL(args[8]),
534
+ interp_type, NUM2INT(args[10]),
535
+ NUM2INT(args[11]), NUM2INT(args[12]),
536
+ NUM2INT(args[13]), NUM2UINT(args[14]),
537
+ NUM2UINT(args[15]));
538
+ ret = self;
539
+ break;
540
+ default:
541
+ rb_raise(rb_eArgError, "Wrong number of arguments: %d", argc);
542
+ break;
543
+ }
544
+ return ret;
545
+ }
546
+
547
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,6,0)
548
+ static VALUE
549
+ rotate_simple(self, angle)
550
+ VALUE self, angle;
551
+ {
552
+ VALUE ret;
553
+ GdkPixbuf* dest = gdk_pixbuf_rotate_simple(_SELF(self), RVAL2GENUM(angle, GDK_TYPE_PIXBUF_ROTATION));
554
+ if (dest == NULL)
555
+ return Qnil;
556
+ ret = GOBJ2RVAL(dest);
557
+ g_object_unref(dest);
558
+ return ret;
559
+ }
560
+
561
+ static VALUE
562
+ flip(self, horizontal)
563
+ VALUE self, horizontal;
564
+ {
565
+ VALUE ret;
566
+ GdkPixbuf* dest = gdk_pixbuf_flip(_SELF(self), RVAL2CBOOL(horizontal));
567
+ if (dest == NULL)
568
+ return Qnil;
569
+ ret = GOBJ2RVAL(dest);
570
+ g_object_unref(dest);
571
+ return ret;
572
+ }
573
+ #endif
574
+
575
+ static VALUE
576
+ add_alpha(self, substitute_color, r, g, b)
577
+ VALUE self, substitute_color, r, g, b;
578
+ {
579
+ VALUE ret;
580
+ GdkPixbuf* dest = gdk_pixbuf_add_alpha(_SELF(self),
581
+ RVAL2CBOOL(substitute_color),
582
+ FIX2INT(r), FIX2INT(g), FIX2INT(b));
583
+ if (dest == NULL)
584
+ return Qnil;
585
+ ret = GOBJ2RVAL(dest);
586
+ g_object_unref(dest);
587
+ return ret;
588
+ }
589
+
590
+ static VALUE
591
+ copy_area(self, src_x, src_y, width, height, dest, dest_x, dest_y)
592
+ VALUE self, src_x, src_y, width, height, dest, dest_x, dest_y;
593
+ {
594
+ gdk_pixbuf_copy_area(_SELF(self), NUM2INT(src_x), NUM2INT(src_y),
595
+ NUM2INT(width), NUM2INT(height),
596
+ _SELF(dest), NUM2INT(dest_x), NUM2INT(dest_y));
597
+ return dest;
598
+ }
599
+
600
+ static VALUE
601
+ saturate_and_pixelate(self, staturation, pixelate)
602
+ VALUE self, staturation, pixelate;
603
+ {
604
+ GdkPixbuf* dest = gdk_pixbuf_copy(_SELF(self));
605
+ gdk_pixbuf_saturate_and_pixelate(_SELF(self), dest,
606
+ NUM2DBL(staturation), RVAL2CBOOL(pixelate));
607
+ return GOBJ2RVAL(dest);
608
+ }
609
+
610
+ static VALUE
611
+ fill(self, pixel)
612
+ VALUE self, pixel;
613
+ {
614
+ gdk_pixbuf_fill(_SELF(self), NUM2UINT(pixel));
615
+ return self;
616
+ }
617
+
618
+ /* From Module Interface */
619
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,2,0)
620
+ static VALUE
621
+ get_formats(self)
622
+ VALUE self;
623
+ {
624
+ return GSLIST2ARY2(gdk_pixbuf_get_formats(), GDK_TYPE_PIXBUF_FORMAT);
625
+ }
626
+
627
+ static VALUE
628
+ set_option(self, key, value)
629
+ VALUE self, key, value;
630
+ {
631
+ #if HAVE_GDK_PIXBUF_SET_OPTION
632
+ return CBOOL2RVAL(gdk_pixbuf_set_option(_SELF(self),
633
+ RVAL2CSTR(key), RVAL2CSTR(value)));
634
+ #else
635
+ rb_warning("not supported in this version of GTK+");
636
+ return Qfalse;
637
+ #endif
638
+ }
639
+ #endif
640
+
641
+ static VALUE
642
+ cairo_available_p(self)
643
+ VALUE self;
644
+ {
645
+ #if CAIRO_AVAILABLE
646
+ return Qtrue;
647
+ #else
648
+ return Qfalse;
649
+ #endif
650
+ }
651
+
652
+ #if CAIRO_AVAILABLE
653
+ /* Move from gtk/src/rbgdkcairo.c */
654
+ static VALUE
655
+ gdkdraw_cairo_set_source_pixbuf(argc, argv, self)
656
+ int argc;
657
+ VALUE *argv;
658
+ VALUE self;
659
+ {
660
+ VALUE pixbuf, pixbuf_x, pixbuf_y;
661
+
662
+ rb_scan_args(argc, argv, "12", &pixbuf, &pixbuf_x, &pixbuf_y);
663
+
664
+ gdk_cairo_set_source_pixbuf(RVAL2CRCONTEXT(self),
665
+ GDK_PIXBUF(RVAL2GOBJ(pixbuf)),
666
+ NIL_P(pixbuf_x) ? 0 : NUM2DBL(pixbuf_x),
667
+ NIL_P(pixbuf_y) ? 0 : NUM2DBL(pixbuf_y));
668
+ rb_cairo_check_status(cairo_status(RVAL2CRCONTEXT(self)));
669
+ return self;
670
+ }
671
+ #endif
672
+
673
+ void
674
+ Init_gdk_pixbuf2()
675
+ {
676
+ VALUE mGdk = rb_define_module("Gdk");
677
+ VALUE gdkPixbuf = G_DEF_CLASS(GDK_TYPE_PIXBUF, "Pixbuf", mGdk);
678
+
679
+ id_pixdata = rb_intern("pixdata");
680
+
681
+ /*
682
+ gdk_rgb_init();*/ /* initialize it anyway */
683
+
684
+
685
+ /*
686
+ * Initialization and Versions
687
+ */
688
+ /* Removed. This crashes Ruby/GTK on Windows + GTK+-2.4.x.
689
+ Pointed out by Laurent.
690
+ #ifdef HAVE_GDK_PIXBUF_VERSION
691
+ rb_define_const(gdkPixbuf, "VERSION", CSTR2RVAL(gdk_pixbuf_version));
692
+ #endif
693
+ */
694
+ rb_define_const(gdkPixbuf, "MAJOR", INT2FIX(GDK_PIXBUF_MAJOR));
695
+ rb_define_const(gdkPixbuf, "MINOR", INT2FIX(GDK_PIXBUF_MINOR));
696
+ rb_define_const(gdkPixbuf, "MICRO", INT2FIX(GDK_PIXBUF_MICRO));
697
+
698
+ /*
699
+ * The GdkPixbuf Structure
700
+ */
701
+ rb_define_method(gdkPixbuf, "colorspace", get_colorspace, 0);
702
+ rb_define_method(gdkPixbuf, "n_channels", get_n_channels, 0);
703
+ rb_define_method(gdkPixbuf, "has_alpha?", get_has_alpha, 0);
704
+ rb_define_method(gdkPixbuf, "bits_per_sample", get_bits_per_sample, 0);
705
+ rb_define_method(gdkPixbuf, "pixels", get_pixels, 0);
706
+ rb_define_method(gdkPixbuf, "pixels=", set_pixels, 1);
707
+ rb_define_method(gdkPixbuf, "width", get_width, 0);
708
+ rb_define_method(gdkPixbuf, "height", get_height, 0);
709
+ rb_define_method(gdkPixbuf, "rowstride", get_rowstride, 0);
710
+ rb_define_method(gdkPixbuf, "get_option", get_option, 1);
711
+
712
+ /* GdkPixbufError */
713
+ G_DEF_ERROR(GDK_PIXBUF_ERROR, "PixbufError", mGdk, rb_eRuntimeError, GDK_TYPE_PIXBUF_ERROR);
714
+
715
+ /* GdkColorspace */
716
+ G_DEF_CLASS(GDK_TYPE_COLORSPACE, "ColorSpace", gdkPixbuf);
717
+ G_DEF_CONSTANTS(gdkPixbuf, GDK_TYPE_COLORSPACE, "GDK_");
718
+
719
+ /* GdkPixbufAlphaMode */
720
+ G_DEF_CLASS(GDK_TYPE_PIXBUF_ALPHA_MODE, "AlphaMode", gdkPixbuf);
721
+ G_DEF_CONSTANTS(gdkPixbuf, GDK_TYPE_PIXBUF_ALPHA_MODE, "GDK_PIXBUF_");
722
+
723
+ /*
724
+ * File Loading, Image Data in Memory
725
+ */
726
+ rb_define_method(gdkPixbuf, "initialize", initialize, -1);
727
+ rb_define_method(gdkPixbuf, "dup", copy, 0);
728
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,4,0)
729
+ rb_define_singleton_method(gdkPixbuf, "get_file_info", get_file_info, 1);
730
+ #endif
731
+
732
+ /*
733
+ * File saving
734
+ */
735
+ rb_define_method(gdkPixbuf, "save", save, -1);
736
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,4,0)
737
+ rb_define_method(gdkPixbuf, "save_to_buffer", save_to_buffer, -1);
738
+ #endif
739
+
740
+ /*
741
+ * Scaling
742
+ */
743
+ rb_define_method(gdkPixbuf, "scale", scale_simple, -1);
744
+ rb_define_method(gdkPixbuf, "scale!", scale, -1);
745
+ rb_define_method(gdkPixbuf, "composite", composite_simple, 7);
746
+ rb_define_method(gdkPixbuf, "composite!", composite, -1);
747
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,6,0)
748
+ rb_define_method(gdkPixbuf, "rotate", rotate_simple, 1);
749
+ rb_define_method(gdkPixbuf, "flip", flip, 1);
750
+ #endif
751
+
752
+ /* GdkInterpType */
753
+ G_DEF_CLASS(GDK_TYPE_INTERP_TYPE, "InterpType", gdkPixbuf);
754
+ G_DEF_CONSTANTS(gdkPixbuf, GDK_TYPE_INTERP_TYPE, "GDK_");
755
+
756
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,6,0)
757
+ /* GdkPixbufRotation */
758
+ G_DEF_CLASS(GDK_TYPE_PIXBUF_ROTATION, "GdkPixbufRotation", gdkPixbuf);
759
+ G_DEF_CONSTANTS(gdkPixbuf, GDK_TYPE_PIXBUF_ROTATION, "GDK_PIXBUF_");
760
+ #endif
761
+ /*
762
+ * Utilities
763
+ */
764
+ rb_define_method(gdkPixbuf, "add_alpha", add_alpha, 4);
765
+ rb_define_method(gdkPixbuf, "copy_area", copy_area, 7);
766
+ rb_define_method(gdkPixbuf, "saturate_and_pixelate", saturate_and_pixelate, 2);
767
+ rb_define_method(gdkPixbuf, "fill!", fill, 1);
768
+
769
+ /*
770
+ * Module Interface
771
+ */
772
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,2,0)
773
+ rb_define_singleton_method(gdkPixbuf, "formats", get_formats, 0);
774
+ rb_define_method(gdkPixbuf, "set_option", set_option, 2);
775
+ #endif
776
+
777
+ /*
778
+ * cairo Interface
779
+ */
780
+ rb_define_module_function(gdkPixbuf, "cairo_available?",
781
+ cairo_available_p, 0);
782
+ #if CAIRO_AVAILABLE
783
+ rb_define_method(rb_cCairo_Context, "set_source_pixbuf",
784
+ gdkdraw_cairo_set_source_pixbuf, -1);
785
+ #endif
786
+
787
+ Init_gdk_pixbuf_animation(mGdk);
788
+ #if RBGDK_PIXBUF_CHECK_VERSION(2,8,0)
789
+ Init_gdk_pixbuf_simpleanim(mGdk);
790
+ #endif
791
+ Init_gdk_pixdata(mGdk);
792
+ Init_gdk_pixbuf_loader(mGdk);
793
+ Init_gdk_pixbuf_format(mGdk);
794
+ }