gdk_pixbuf2 0.90.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }