texplay 0.2.983pre2-i386-mingw32 → 0.3.0-i386-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/Rakefile +41 -49
  2. data/examples/common.rb +13 -2
  3. data/examples/example_alpha_blend.rb +1 -3
  4. data/examples/example_bezier.rb +1 -2
  5. data/examples/example_blank.rb +1 -3
  6. data/examples/example_cache.rb +1 -3
  7. data/examples/example_color_transform.rb +1 -3
  8. data/examples/example_color_transform_circle.rb +1 -3
  9. data/examples/example_darken.rb +1 -4
  10. data/examples/example_dup.rb +1 -4
  11. data/examples/example_each.rb +1 -4
  12. data/examples/example_effect.rb +1 -2
  13. data/examples/example_fill.rb +1 -2
  14. data/examples/example_fill_old.rb +1 -2
  15. data/examples/example_fluent.rb +1 -3
  16. data/examples/example_font.rb +1 -3
  17. data/examples/example_gen_eval.rb +1 -2
  18. data/examples/example_hash_arguments.rb +1 -2
  19. data/examples/example_ippa.rb +1 -3
  20. data/examples/example_light.rb +1 -3
  21. data/examples/example_light_multiply.rb +1 -3
  22. data/examples/example_lsystem.rb +1 -1
  23. data/examples/example_melt.rb +1 -3
  24. data/examples/example_meyet.rb +1 -3
  25. data/examples/example_polyline.rb +1 -2
  26. data/examples/example_scale.rb +1 -3
  27. data/examples/example_select.rb +1 -3
  28. data/examples/example_select2.rb +1 -4
  29. data/examples/example_simple.rb +1 -3
  30. data/examples/example_splice.rb +2 -4
  31. data/examples/example_sync.rb +1 -2
  32. data/examples/example_tiles.rb +1 -3
  33. data/examples/example_trace.rb +1 -2
  34. data/examples/example_transparent.rb +1 -3
  35. data/examples/example_transparent2.rb +1 -3
  36. data/examples/example_transparent3.rb +1 -3
  37. data/examples/example_turtle.rb +1 -2
  38. data/examples/example_weird.rb +1 -2
  39. data/examples/example_window_render_to_image.rb +41 -0
  40. data/examples/example_window_to_blob.rb +2 -5
  41. data/ext/texplay/actions.c +1006 -0
  42. data/ext/texplay/actions.h +60 -0
  43. data/ext/texplay/bindings.c +1186 -0
  44. data/ext/texplay/bindings.h +46 -0
  45. data/ext/texplay/cache.c +118 -0
  46. data/ext/texplay/cache.h +24 -0
  47. data/ext/texplay/compat.h +27 -0
  48. data/ext/texplay/extconf.rb +28 -0
  49. data/ext/texplay/gen_eval.c +211 -0
  50. data/ext/texplay/gen_eval.h +20 -0
  51. data/ext/texplay/graphics_utils.c +1244 -0
  52. data/ext/texplay/graphics_utils.h +22 -0
  53. data/ext/texplay/object2module.c +171 -0
  54. data/ext/texplay/object2module.h +11 -0
  55. data/ext/texplay/texplay.c +216 -0
  56. data/ext/texplay/texplay.h +148 -0
  57. data/ext/texplay/utils.c +887 -0
  58. data/ext/texplay/utils.h +153 -0
  59. data/lib/1.8/texplay.so +0 -0
  60. data/lib/1.9/texplay.so +0 -0
  61. data/lib/texplay.rb +271 -165
  62. data/lib/texplay/c_function_docs.rb +189 -0
  63. data/lib/texplay/version.rb +1 -1
  64. metadata +33 -21
  65. data/examples/example_window_to_texture.rb +0 -55
  66. data/lib/texplay/patches.rb +0 -4
@@ -0,0 +1,60 @@
1
+ #ifndef GUARD_ACTIONS_H
2
+ #define GUARD_ACTIONS_H
3
+
4
+ #include "texplay.h"
5
+
6
+ /* used by line_do_action */
7
+ typedef struct {
8
+ int x, y;
9
+ rgba color;
10
+ } trace_match;
11
+
12
+
13
+ /* lines */
14
+ trace_match line_do_action(int, int, int, int, texture_info *, VALUE, sync, bool primary, action_struct * payload);
15
+
16
+ /* circles */
17
+ void circle_do_action(int, int, int, texture_info *, VALUE, sync, bool primary, action_struct * payload);
18
+
19
+ /* pixels */
20
+ void pixel_do_action(int, int, texture_info *, VALUE, sync, bool primary, action_struct * payload);
21
+
22
+ /* rectangles */
23
+ void rect_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_arg,
24
+ sync sync_mode, bool primary, action_struct * payload);
25
+
26
+ /* flood fill */
27
+ void flood_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg, sync sync_mode, bool primary,
28
+ action_struct * payload);
29
+
30
+ /* glow fill */
31
+ void glow_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg, sync sync_mode, bool primary,
32
+ action_struct * payload);
33
+
34
+ /* scan fill */
35
+ void scan_fill_do_action(int x, int y, texture_info * tex, VALUE hash_arg,
36
+ sync sync_mode, bool primary, action_struct * payload);
37
+
38
+ /* polyline */
39
+ void polyline_do_action(VALUE points, texture_info * tex, VALUE hash_arg, sync sync_mode, bool primary,
40
+ action_struct * payload);
41
+
42
+ /* bezier */
43
+ void bezier_do_action(VALUE points, texture_info * tex, VALUE hash_arg, sync sync_mode, bool primary,
44
+ action_struct * payload);
45
+
46
+ /* ngon */
47
+ void ngon_do_action(int x, int y, int r, int num_sides, texture_info * tex, VALUE hash_arg,
48
+ sync sync_mode, bool primary, action_struct * payload);
49
+
50
+
51
+ /* splice */
52
+ void splice_do_action(int x0,int y0, int cx1, int cy1, int cx2, int cy2, texture_info * splice_tex,
53
+ texture_info * tex, VALUE hash_arg, sync sync_mode,
54
+ bool primary, action_struct * payload);
55
+
56
+ /* each iterator */
57
+ void each_pixel_do_action(int x1, int y1, int x2, int y2, VALUE proc, texture_info * tex, VALUE hash_arg,
58
+ sync sync_mode, bool primary, action_struct * payload);
59
+
60
+ #endif
@@ -0,0 +1,1186 @@
1
+ #include <ruby.h>
2
+ #include <stdio.h>
3
+ #include <string.h>
4
+ #include <ctype.h>
5
+ #include <math.h>
6
+ #include <stdlib.h>
7
+ #include <assert.h>
8
+ #include <stdarg.h>
9
+
10
+ #ifdef __APPLE__
11
+ # include <glut.h>
12
+ #else
13
+ # include <GL/glut.h>
14
+ #endif
15
+
16
+ #include "texplay.h"
17
+ #include "utils.h"
18
+ #include "graphics_utils.h"
19
+ #include "bindings.h"
20
+ #include "actions.h"
21
+ #include "cache.h"
22
+ #include "compat.h"
23
+
24
+ /* associated with gen_eval */
25
+ #include "object2module.h"
26
+ #include "gen_eval.h"
27
+
28
+ /* syncing mode */
29
+ /* lazy_sync = sync at end of paint block */
30
+ /* eager_sync = sync immediately (after action) */
31
+ /* no_sync = do not sync at all */
32
+ sync sync_mode = eager_sync;
33
+
34
+ static void
35
+ process_x_y_pairs(VALUE image, int num_pairs, VALUE * argv, ...)
36
+ {
37
+ va_list ap;
38
+ int i;
39
+ int draw_offset_x;
40
+ int draw_offset_y;
41
+ VALUE offset_val;
42
+
43
+ offset_val = get_image_local(image, DRAW_OFFSET);
44
+
45
+ draw_offset_x = NUM2INT(get_from_array(offset_val, 0));
46
+ draw_offset_y = NUM2INT(get_from_array(offset_val, 1));
47
+
48
+ va_start(ap, argv);
49
+ if(is_a_point(argv[0])) {
50
+ for(i = 0; i < num_pairs; i++) {
51
+ int *x_ptr, *y_ptr;
52
+
53
+ x_ptr = va_arg(ap, int*);
54
+ y_ptr = va_arg(ap, int*);
55
+
56
+ *x_ptr = NUM2INT(rb_funcall(argv[i], rb_intern("x"), 0)) + draw_offset_x;
57
+ *y_ptr = NUM2INT(rb_funcall(argv[i], rb_intern("y"), 0)) + draw_offset_y;
58
+ }
59
+ }
60
+ else {
61
+ for(i = 0; i < (num_pairs * 2); i+=2) {
62
+ int *x_ptr, *y_ptr;
63
+
64
+ x_ptr = va_arg(ap, int*);
65
+ y_ptr = va_arg(ap, int*);
66
+
67
+ *x_ptr = NUM2INT(argv[i]) + draw_offset_x;
68
+ *y_ptr = NUM2INT(argv[i + 1]) + draw_offset_y;
69
+ }
70
+ }
71
+ va_end(ap);
72
+ }
73
+
74
+
75
+ /* singleton methods */
76
+
77
+ /* responsible for creating macros */
78
+ VALUE
79
+ M_create_macro(VALUE self, VALUE method_name)
80
+ {
81
+ VALUE proc;
82
+
83
+ rb_need_block();
84
+
85
+ /* convert the block to a proc */
86
+ proc = rb_block_proc();
87
+
88
+ /* define the method in the TexPlay class so that it is accessible to 'instances' */
89
+ rb_funcall(self, rb_intern("define_method"), 2, method_name, proc);
90
+
91
+ return Qnil;
92
+ }
93
+
94
+
95
+ /* responsible for removing macros */
96
+ VALUE
97
+ M_remove_macro(VALUE self, VALUE method_name)
98
+ {
99
+
100
+ /* remove the method in the TexPlay class */
101
+ rb_funcall(self, rb_intern("remove_method"), 1, method_name);
102
+
103
+ return Qnil;
104
+ }
105
+
106
+ /* responsible for refreshing all entries in cache */
107
+ VALUE
108
+ M_refresh_cache_all(VALUE self)
109
+ {
110
+ cache_refresh_all();
111
+
112
+ return Qnil;
113
+ }
114
+
115
+ /* VALUE */
116
+ /* M_screenshot(VALUE self, VALUE x, VALUE y, VALUE width, VALUE width) */
117
+ /* { */
118
+ /* texture_info tex; */
119
+ /* int sidelength; */
120
+ /* int rb_x = FIX2INT(x); */
121
+ /* int rb_y = FIX2INT(y); */
122
+ /* int rb_width = FIX2INT(width); */
123
+ /* int rb_height = FIX2INT(height); */
124
+
125
+ /* VALUE blob = rb_str_new(NULL, 4 * rb_width * rb_height); */
126
+
127
+ /* glReadPixels(rb_x, rb_y, rb_width, rb_height, GL_RGBA, GL_UNSIGNED_BYTE, RSTRING_PTR(blob)); */
128
+
129
+ /* return blob; */
130
+ /* } */
131
+
132
+
133
+ /* creates a blank image */
134
+ /* VALUE */
135
+ /* M_create_blank(VALUE self, VALUE window, VALUE width, VALUE height) */
136
+ /* { */
137
+ /* VALUE fresh_image; */
138
+
139
+ /* fresh_image = create_image(window, NUM2INT(width), NUM2INT(height)); */
140
+
141
+ /* return fresh_image; */
142
+ /* } */
143
+ /** end singleton methods **/
144
+
145
+ /* some helper methods */
146
+ static void
147
+ rb_lazy_bounds_to_image_bounds(VALUE image, image_bounds * bounds)
148
+ {
149
+ VALUE lazy_bounds;
150
+
151
+ lazy_bounds = get_image_local(image, LAZY_BOUNDS);
152
+
153
+ Check_Type(lazy_bounds, T_ARRAY);
154
+
155
+ bounds->xmin = FIX2INT(get_from_array(lazy_bounds, 0));
156
+ bounds->ymin = FIX2INT(get_from_array(lazy_bounds, 1));
157
+ bounds->xmax = FIX2INT(get_from_array(lazy_bounds, 2));
158
+ bounds->ymax = FIX2INT(get_from_array(lazy_bounds, 3));
159
+ }
160
+
161
+ static VALUE
162
+ parse_sync_mode(VALUE user_sync_mode)
163
+ {
164
+ sync mode;
165
+
166
+ Check_Type(user_sync_mode, T_SYMBOL);
167
+
168
+ if(user_sync_mode == string2sym("lazy_sync"))
169
+ mode = lazy_sync;
170
+ else if(user_sync_mode == string2sym("eager_sync"))
171
+ mode = eager_sync;
172
+ else if(user_sync_mode == string2sym("no_sync"))
173
+ mode = no_sync;
174
+ else
175
+ rb_raise(rb_eArgError, "unrecognized sync mode: %s\n. Allowable modes are "
176
+ ":lazy_sync, :eager_sync, :no_sync.",
177
+ sym2string(user_sync_mode));
178
+
179
+ return mode;
180
+ }
181
+ /* end helpers */
182
+
183
+ /* entry point for TexPlay paint actions */
184
+ VALUE
185
+ m_paint(int argc, VALUE * argv, VALUE self)
186
+ {
187
+ texture_info tex;
188
+ VALUE options;
189
+ image_bounds bounds;
190
+ int arity;
191
+
192
+ ADJUST_SELF(self);
193
+
194
+ rb_scan_args(argc, argv, "01", &options);
195
+
196
+ /* get texture info from image */
197
+ get_texture_info(self, &tex);
198
+
199
+ /* set default sync_mode to lazy */
200
+ sync_mode = lazy_sync;
201
+
202
+ /* parse sync_mode, overriding lazy sync mode? */
203
+ if(has_optional_hash_arg(options, "sync_mode")) {
204
+ VALUE user_sync_mode = get_from_hash(options, "sync_mode");
205
+ sync_mode = parse_sync_mode(user_sync_mode);
206
+ }
207
+
208
+ /* if no block then just sync */
209
+ if(!rb_block_given_p()) {
210
+
211
+ rb_lazy_bounds_to_image_bounds(self, &bounds);
212
+
213
+ create_subtexture_and_sync_to_gl(&bounds, &tex);
214
+
215
+ /* reset the LAZY_BOUNDS now we've sync'd */
216
+ set_image_local(self, LAZY_BOUNDS, Qnil);
217
+
218
+ sync_mode = eager_sync;
219
+
220
+ return self;
221
+ }
222
+
223
+ /* find arity of block */
224
+ arity = FIX2INT(rb_funcall(rb_block_proc(), rb_intern("arity"), 0));
225
+
226
+ /* yield self if the arity is 1, else gen_eval the block */
227
+ switch(arity) {
228
+ case -1:
229
+ case 0:
230
+ rb_gen_eval(0, 0, self);
231
+ break;
232
+ case 1:
233
+ rb_yield(self);
234
+ break;
235
+ default:
236
+ rb_raise(rb_eArgError, "block arity must be either 1 or -1 or 0, received arity of: %d", arity);
237
+ }
238
+
239
+ /* if lazy sync is selected then sync now..as the paint block has finished executing the draw actions*/
240
+ if(sync_mode == lazy_sync) {
241
+
242
+ rb_lazy_bounds_to_image_bounds(self, &bounds);
243
+
244
+ create_subtexture_and_sync_to_gl(&bounds, &tex);
245
+
246
+ /* reset the LAZY_BOUNDS now we've sync'd */
247
+ set_image_local(self, LAZY_BOUNDS, Qnil);
248
+
249
+ }
250
+
251
+ /* now we've finished the paint block we reset the default sync_mode back to eager */
252
+ sync_mode = eager_sync;
253
+
254
+ return self;
255
+ }
256
+
257
+ VALUE
258
+ m_force_sync(VALUE self, VALUE ary)
259
+ {
260
+ image_bounds bounds;
261
+ texture_info tex;
262
+
263
+ ADJUST_SELF(self);
264
+
265
+ Check_Type(ary, T_ARRAY);
266
+
267
+ get_texture_info(self, &tex);
268
+
269
+ bounds.xmin = NUM2INT(get_from_array(ary, 0));
270
+ bounds.ymin = NUM2INT(get_from_array(ary, 1));
271
+ bounds.xmax = NUM2INT(get_from_array(ary, 2));
272
+ bounds.ymax = NUM2INT(get_from_array(ary, 3));
273
+
274
+ create_subtexture_and_sync_to_gl(&bounds, &tex);
275
+
276
+ return Qnil;
277
+ }
278
+
279
+ VALUE
280
+ m_dup_image(VALUE self)
281
+ {
282
+ texture_info tex, dup_tex;
283
+ VALUE dupped_image;
284
+ VALUE window;
285
+
286
+ ADJUST_SELF(self);
287
+
288
+ get_texture_info(self, &tex);
289
+
290
+ window = rb_funcall(self, rb_intern("__window__"), 0);
291
+
292
+ /* create a new blank image with the height/width of the current image */
293
+ dupped_image = create_image(window, tex.width, tex.height);
294
+
295
+ /* get the new image's data */
296
+ get_texture_info(dupped_image, &dup_tex);
297
+
298
+ /* splice into the new image content from the current image, and sync it to gl */
299
+ splice_do_action(0, 0, 0, 0, XMAX_OOB, YMAX_OOB, &tex, &dup_tex, Qnil, eager_sync, true, NULL);
300
+
301
+ /* copy across the ivars too! */
302
+ rb_copy_generic_ivar(dupped_image, self);
303
+
304
+ /* we now have a full dup of the current image, return it */
305
+ return dupped_image;
306
+ }
307
+
308
+ VALUE
309
+ m_clone_image(VALUE self)
310
+ {
311
+ VALUE cloned_image;
312
+
313
+ ADJUST_SELF(self);
314
+
315
+ cloned_image = m_dup_image(self);
316
+
317
+ /* the main diff b/w clone and dup is that clone also dups the singleton */
318
+ KLASS_OF(cloned_image) = rb_singleton_class_clone(self);
319
+
320
+ return cloned_image;
321
+ }
322
+
323
+ VALUE
324
+ m_user_set_options(VALUE self, VALUE options)
325
+ {
326
+ ADJUST_SELF(self);
327
+
328
+ if(!is_a_hash(options))
329
+ rb_raise(rb_eArgError, "only a single hash argument is accepted");
330
+
331
+ set_image_local(self, USER_DEFAULTS, options);
332
+
333
+ return Qnil;
334
+ }
335
+
336
+ VALUE
337
+ m_user_delete_options(VALUE self)
338
+ {
339
+
340
+ ADJUST_SELF(self);
341
+
342
+ set_image_local(self, USER_DEFAULTS, Qnil);
343
+
344
+ return Qnil;
345
+ }
346
+
347
+ VALUE
348
+ m_get_options(VALUE self)
349
+ {
350
+ ADJUST_SELF(self);
351
+
352
+ return get_image_local(self, USER_DEFAULTS);
353
+ }
354
+
355
+ static void
356
+ get_image_chunk_with_size(char * data, texture_info * tex, char * blob)
357
+ {
358
+ for(int y = 0; y < tex->height; y++)
359
+ for(int x = 0; x < tex->width; x++) {
360
+ int buf_index = 4 * (x + y * tex->width);
361
+
362
+ int offset = calc_pixel_offset(tex, x, y);
363
+
364
+ memcpy(blob + buf_index, data + offset, 4);
365
+ }
366
+ }
367
+
368
+
369
+
370
+ VALUE
371
+ m_to_blob(VALUE self)
372
+ {
373
+ texture_info tex;
374
+ int sidelength;
375
+
376
+ ADJUST_SELF(self);
377
+
378
+ get_texture_info(self, &tex);
379
+
380
+ glEnable(GL_TEXTURE_2D);
381
+ glBindTexture(GL_TEXTURE_2D, tex.tname);
382
+
383
+ /* get length of a side, since square texture */
384
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &sidelength);
385
+
386
+ /* initialize texture data array, mult. by 4 because {rgba} */
387
+ char new_array[sidelength * sidelength * 4];
388
+
389
+ /* get texture data from video memory */
390
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,(void*)(new_array));
391
+
392
+ VALUE blob = rb_str_new(NULL, 4 * tex.width * tex.height);
393
+
394
+ get_image_chunk_with_size(new_array, &tex, RSTRING_PTR(blob));
395
+
396
+ glDisable(GL_TEXTURE_2D);
397
+
398
+ return blob;
399
+ }
400
+
401
+ /* return the pixel colour for the given x, y */
402
+ VALUE
403
+ m_getpixel(int argc, VALUE * argv, VALUE self)
404
+ {
405
+ int x1, y1;
406
+ int last = argc - 1;
407
+ texture_info tex;
408
+ rgba pix;
409
+ bool gosu_color_mode = false;
410
+ VALUE options;
411
+
412
+
413
+ /* change self to hidden self if using gen_eval */
414
+ ADJUST_SELF(self);
415
+
416
+ process_x_y_pairs(self, 1, argv, &x1, &y1);
417
+
418
+ /* get texture info */
419
+ get_texture_info(self, &tex);
420
+
421
+ options = argv[last];
422
+
423
+ if (hash_value_is(options, "color_mode", string2sym("gosu")))
424
+ gosu_color_mode = true;
425
+
426
+ /* locate the desired pixel; */
427
+ pix = get_pixel_color(&tex, x1, y1);
428
+
429
+ if(not_a_color(pix))
430
+ return Qnil;
431
+ else {
432
+ if (gosu_color_mode)
433
+ return convert_rgba_to_gosu_color(&pix);
434
+ else
435
+ return convert_rgba_to_rb_color(&pix);
436
+ }
437
+ }
438
+
439
+ /* circle action */
440
+ VALUE
441
+ m_circle(int argc, VALUE * argv, VALUE self)
442
+ {
443
+ int x1, y1, r;
444
+ int last = argc - 1;
445
+ VALUE options;
446
+ texture_info tex;
447
+
448
+ ADJUST_SELF(self);
449
+
450
+ if(argc < 2) rb_raise(rb_eArgError, "circle action needs at least 2 parameter");
451
+
452
+ process_x_y_pairs(self, 1, argv, &x1, &y1);
453
+
454
+ if(is_a_point(argv[0]))
455
+ r = NUM2INT(argv[1]);
456
+ else
457
+ r = NUM2INT(argv[2]);
458
+
459
+ options = argv[last];
460
+
461
+ get_texture_info(self, &tex);
462
+
463
+ circle_do_action(x1, y1, r, &tex, options, sync_mode, true, NULL);
464
+
465
+ return self;
466
+ }
467
+
468
+ /* ngon */
469
+ VALUE
470
+ m_ngon(int argc, VALUE * argv, VALUE self)
471
+ {
472
+ int x1, y1, r, n;
473
+ int last = argc - 1;
474
+ VALUE options;
475
+ texture_info tex;
476
+
477
+ ADJUST_SELF(self);
478
+
479
+ if(argc < 3) rb_raise(rb_eArgError, "ngon requires at least 3 parameters (x, y, radius, num_sides)");
480
+
481
+ process_x_y_pairs(self, 1, argv, &x1, &y1);
482
+
483
+ options = argv[last];
484
+
485
+ get_texture_info(self, &tex);
486
+
487
+ r = NUM2INT(argv[2]);
488
+ n = NUM2INT(argv[3]);
489
+
490
+ ngon_do_action(x1, y1, r, n, &tex, options, sync_mode, true, NULL);
491
+
492
+ return self;
493
+ }
494
+
495
+
496
+ /* flood fill action */
497
+ VALUE
498
+ m_flood_fill(int argc, VALUE * argv, VALUE self)
499
+ {
500
+ int x1, y1;
501
+ int last = argc - 1;
502
+ VALUE options;
503
+ texture_info tex;
504
+ bool iter = false, glow = false;
505
+
506
+ ADJUST_SELF(self);
507
+
508
+ if (argc < 1) rb_raise(rb_eArgError, "flood fill action needs at least 1 parameter");
509
+
510
+ process_x_y_pairs(self, 1, argv, &x1, &y1);
511
+
512
+ options = argv[last];
513
+
514
+ get_texture_info(self, &tex);
515
+
516
+ if(is_a_hash(options)) {
517
+ if(RTEST(get_from_hash(options, "iter")))
518
+ iter = true;
519
+ if(RTEST(get_from_hash(options, "glow")))
520
+ glow = true;
521
+ }
522
+
523
+ if(iter) {
524
+ flood_fill_do_action(x1, y1, &tex, options, sync_mode, true, NULL);
525
+ }
526
+ else if(glow) {
527
+ glow_fill_do_action(x1, y1, &tex, options, sync_mode, true, NULL);
528
+
529
+ }
530
+ /* this is the default fill */
531
+ else {
532
+ scan_fill_do_action(x1, y1, &tex, options, sync_mode, true, NULL);
533
+ }
534
+
535
+ return self;
536
+ }
537
+
538
+ static inline VALUE
539
+ convert_trace_match_to_ruby_array(trace_match match, bool gosu_color_mode)
540
+ {
541
+ VALUE ary = rb_ary_new();
542
+
543
+ rb_ary_store(ary, 0, INT2FIX(match.x));
544
+ rb_ary_store(ary, 1, INT2FIX(match.y));
545
+
546
+ if (gosu_color_mode)
547
+ rb_ary_store(ary, 2, convert_rgba_to_gosu_color(&match.color));
548
+ else
549
+ rb_ary_store(ary, 2, convert_rgba_to_rb_color(&match.color));
550
+
551
+ return ary;
552
+ }
553
+
554
+ /* line action */
555
+ VALUE
556
+ m_line(int argc, VALUE * argv, VALUE self)
557
+ {
558
+ int x1, y1, x2, y2;
559
+ int last = argc - 1;
560
+ bool gosu_color_mode = false;
561
+ VALUE options;
562
+ texture_info tex;
563
+ trace_match match;
564
+
565
+ ADJUST_SELF(self);
566
+
567
+ if(argc < 2) rb_raise(rb_eArgError, "line action needs at least 2 parameters");
568
+
569
+ process_x_y_pairs(self, 2, argv, &x1, &y1, &x2, &y2);
570
+
571
+ options = argv[last];
572
+
573
+ if (hash_value_is(options, "color_mode", string2sym("gosu")))
574
+ gosu_color_mode = true;
575
+
576
+ get_texture_info(self, &tex);
577
+
578
+ match = line_do_action(x1, y1, x2, y2, &tex, options, sync_mode, true, NULL);
579
+
580
+ if (has_optional_hash_arg(options, "trace")) {
581
+ if (match.x == -9999)
582
+ return Qnil;
583
+ else
584
+ return convert_trace_match_to_ruby_array(match, gosu_color_mode);
585
+ }
586
+
587
+ return self;
588
+ }
589
+
590
+ /* box action */
591
+ VALUE
592
+ m_rect(int argc, VALUE * argv, VALUE self)
593
+ {
594
+
595
+ int x1, y1, x2, y2;
596
+ int last = argc - 1;
597
+ VALUE options;
598
+ texture_info tex;
599
+
600
+ ADJUST_SELF(self);
601
+
602
+ if(argc < 2) rb_raise(rb_eArgError, "rect action needs at least 2 parameters");
603
+
604
+ process_x_y_pairs(self, 2, argv, &x1, &y1, &x2, &y2);
605
+
606
+ options = argv[last];
607
+
608
+ get_texture_info(self, &tex);
609
+
610
+ rect_do_action(x1, y1, x2, y2, &tex, options, sync_mode, true, NULL);
611
+
612
+ return self;
613
+ }
614
+
615
+
616
+ /* pixel action */
617
+ VALUE
618
+ m_pixel(int argc, VALUE * argv, VALUE self)
619
+ {
620
+ int x1, y1;
621
+ int last = argc - 1;
622
+ VALUE options;
623
+ texture_info tex;
624
+
625
+ ADJUST_SELF(self);
626
+
627
+ if(argc < 1) rb_raise(rb_eArgError, "pixel action needs 1 parameter");
628
+
629
+ process_x_y_pairs(self, 1, argv, &x1, &y1);
630
+
631
+ options = argv[last];
632
+
633
+ get_texture_info(self, &tex);
634
+
635
+ pixel_do_action(x1, y1, &tex, options, sync_mode, true, NULL);
636
+
637
+ return self;
638
+ }
639
+
640
+ /* bezier curve */
641
+ VALUE
642
+ m_bezier(int argc, VALUE * argv, VALUE self)
643
+ {
644
+ VALUE points = Qnil;
645
+ VALUE options = Qnil;
646
+ int last = argc - 1;
647
+ texture_info tex;
648
+
649
+ ADJUST_SELF(self);
650
+
651
+ if(argc < 1) rb_raise(rb_eArgError, "bezier action needs at least 1 parameter");
652
+
653
+ /* get array of points */
654
+ points = argv[0];
655
+ Check_Type(points, T_ARRAY);
656
+
657
+ options = argv[last];
658
+
659
+ get_texture_info(self, &tex);
660
+
661
+ bezier_do_action(points, &tex, options, sync_mode, true, NULL);
662
+
663
+ return self;
664
+ }
665
+
666
+ /* bezier curve */
667
+ VALUE
668
+ m_polyline(int argc, VALUE * argv, VALUE self)
669
+ {
670
+ VALUE points = Qnil;
671
+ VALUE options = Qnil;
672
+ int last = argc - 1;
673
+ texture_info tex;
674
+
675
+ ADJUST_SELF(self);
676
+
677
+ if(argc < 1) rb_raise(rb_eArgError, "polyline action needs at least 1 parameter");
678
+
679
+ /* get array of points */
680
+ points = argv[0];
681
+ Check_Type(points, T_ARRAY);
682
+
683
+ options = argv[last];
684
+
685
+ get_texture_info(self, &tex);
686
+
687
+ polyline_do_action(points, &tex, options, sync_mode, true, NULL);
688
+
689
+ return self;
690
+ }
691
+
692
+
693
+
694
+ /* splice action */
695
+ VALUE
696
+ m_splice(int argc, VALUE * argv, VALUE self)
697
+ {
698
+ int x0, y0;
699
+ int cx1 = 0, cy1 = 0, cx2 = XMAX_OOB, cy2 = YMAX_OOB;
700
+ texture_info splice_tex;
701
+ int last = argc - 1;
702
+ texture_info tex;
703
+ VALUE options;
704
+
705
+ ADJUST_SELF(self);
706
+
707
+ if(argc < 3) rb_raise(rb_eArgError, "splice action needs at least 3 parameters");
708
+
709
+ if(!is_gosu_image(argv[0]))
710
+ rb_raise(rb_eArgError, "first parameter must be a valid Gosu::Image");
711
+
712
+ /* get the splice image */
713
+ get_texture_info(argv[0], &splice_tex);
714
+
715
+ /* add 1 to argv to skip the Image parameter */
716
+ process_x_y_pairs(self, 1, argv + 1, &x0, &y0);
717
+
718
+ /* get the hash args */
719
+ options = argv[last];
720
+
721
+ get_texture_info(self, &tex);
722
+
723
+ /* get the crop boundaries */
724
+ if(is_a_hash(options))
725
+ if(RTEST(get_from_hash(options, "crop"))) {
726
+ VALUE c = get_from_hash(options, "crop");
727
+ Check_Type(c, T_ARRAY);
728
+ cx1 = NUM2INT(get_from_array(c, 0));
729
+ cy1 = NUM2INT(get_from_array(c, 1));
730
+ cx2 = NUM2INT(get_from_array(c, 2));
731
+ cy2 = NUM2INT(get_from_array(c, 3));
732
+ }
733
+
734
+ splice_do_action(x0, y0, cx1, cy1, cx2, cy2, &splice_tex,
735
+ &tex, options, sync_mode, true, NULL);
736
+
737
+ return self;
738
+ }
739
+
740
+
741
+ /* clear action - really just an alias for box */
742
+ VALUE
743
+ m_clear(int argc, VALUE * argv, VALUE self)
744
+ {
745
+ VALUE parms[4];
746
+
747
+ parms[0] = INT2NUM(0);
748
+ parms[1] = INT2NUM(0);
749
+ parms[2] = INT2NUM(XMAX_OOB);
750
+ parms[3] = INT2NUM(YMAX_OOB);
751
+
752
+ // m_box(ARY_SIZE(parms), parms, self);
753
+
754
+ return self;
755
+ }
756
+
757
+ /* offset function */
758
+ VALUE
759
+ m_offset(int argc, VALUE * argv, VALUE self)
760
+ {
761
+ char * try_offset;
762
+
763
+ ADJUST_SELF(self);
764
+
765
+ if(argc == 0)
766
+ return get_image_local(self, DRAW_OFFSET);
767
+
768
+ switch(TYPE(argv[0])) {
769
+
770
+ case T_ARRAY:
771
+
772
+ set_image_local(self, DRAW_OFFSET, argv[0]);
773
+ break;
774
+ case T_SYMBOL:
775
+ try_offset = sym2string(argv[0]);
776
+
777
+ if(!strcmp("default", try_offset)) {
778
+ set_image_local(self, DRAW_OFFSET, Qnil);
779
+ }
780
+ else {
781
+ rb_raise(rb_eArgError, "no such offset defined: %s\n", try_offset);
782
+ }
783
+
784
+ break;
785
+ default:
786
+ rb_raise(rb_eArgError, "invalid offset. please use an array or :default.");
787
+ }
788
+ return Qnil;
789
+ }
790
+
791
+ /* color change */
792
+ VALUE
793
+ m_color(int argc, VALUE * argv, VALUE self)
794
+ {
795
+ VALUE first;
796
+ rgba new_color;
797
+
798
+ ADJUST_SELF(self);
799
+
800
+ /* if no params then return action current color */
801
+ if(argc == 0)
802
+ return get_image_local(self, IMAGE_COLOR);
803
+
804
+ /* otherwise set the action color */
805
+ /* NB: we cannot just set image_local_color to 'first' because first may not be an array,
806
+ it could also be a symbol */
807
+
808
+ first = argv[0];
809
+
810
+ new_color = convert_rb_color_to_rgba(first);
811
+
812
+ /* im quite sure i DO want to set the color even if it is not_a_color.
813
+ why ? consistency only
814
+ (NB: not_a_color_v is skipped by the set_pixel_color routine */
815
+
816
+ /* if(is_a_color(new_color)) */
817
+
818
+ save_rgba_to_image_local_color(self, new_color);
819
+
820
+ return Qnil;
821
+ }
822
+
823
+ /* this function manages all other method calls */
824
+ VALUE
825
+ m_missing(int argc, VALUE * argv, VALUE self)
826
+ {
827
+ char * action_name = lowercase(sym2string(argv[0]));
828
+
829
+ /* try case insensitive version of action name */
830
+ if(rb_respond_to(self, rb_intern(action_name))) {
831
+ rb_funcall2(self, rb_intern(action_name), --argc, ++argv);
832
+ }
833
+ /* still no match? then method does not exist */
834
+ else {
835
+ rb_raise (rb_eRuntimeError, "unrecognized action: %s\n", action_name);
836
+ }
837
+
838
+ return self;
839
+ }
840
+
841
+ /* refreshes the cache */
842
+ VALUE
843
+ m_cache_refresh(VALUE self)
844
+ {
845
+ texture_info tex;
846
+
847
+ ADJUST_SELF(self);
848
+
849
+ get_texture_info(self, &tex);
850
+
851
+ cache_refresh_entry(tex.tname);
852
+
853
+ return self;
854
+ }
855
+
856
+ /* check whether img quad is already cached */
857
+ VALUE
858
+ m_quad_cached(VALUE self)
859
+ {
860
+ VALUE info, gc_state_off;
861
+ int tex_name;
862
+ cache_entry * entry;
863
+
864
+ ADJUST_SELF(self);
865
+
866
+ /* prevent weird segfault bug */
867
+ gc_state_off = rb_gc_disable();
868
+
869
+ /* ensure gl_tex_info returns non nil */
870
+ info = check_for_texture_info(self);
871
+
872
+ tex_name = FIX2INT(rb_funcall(info, rb_intern("tex_name"), 0));
873
+
874
+ entry = find_in_cache(tex_name);
875
+
876
+ /* only enable gc if was enabled on function entry */
877
+ if(!gc_state_off) rb_gc_enable();
878
+
879
+ return entry ? Qtrue : Qfalse;
880
+ }
881
+
882
+ /** m_each **/
883
+ VALUE
884
+ m_each(int argc, VALUE * argv, VALUE self)
885
+ {
886
+ int x1 = 0, y1 = 0, x2 = XMAX_OOB, y2 = YMAX_OOB;
887
+ texture_info tex;
888
+ VALUE proc;
889
+ VALUE options = Qnil;
890
+
891
+ rb_need_block();
892
+
893
+ ADJUST_SELF(self);
894
+
895
+ get_texture_info(self, &tex);
896
+
897
+ if(argc >= 1) {
898
+ options = argv[0];
899
+ Check_Type(options, T_HASH);
900
+ if(RTEST(get_from_hash(options, "region"))) {
901
+ VALUE region = get_from_hash(options, "region");
902
+ Check_Type(region, T_ARRAY);
903
+
904
+ if(RARRAY_LEN(region) < 4)
905
+ rb_raise(rb_eArgError, "region requires 4 elements");
906
+
907
+ x1 = NUM2INT(get_from_array(region, 0));
908
+ y1 = NUM2INT(get_from_array(region, 1));
909
+ x2 = NUM2INT(get_from_array(region, 2));
910
+ y2 = NUM2INT(get_from_array(region, 3));
911
+
912
+ }
913
+
914
+ }
915
+
916
+ constrain_boundaries(&x1, &y1,
917
+ &x2, &y2, tex.width, tex.height);
918
+
919
+ proc = rb_block_proc();
920
+
921
+ each_pixel_do_action(x1, y1, x2, y2, proc, &tex, options, sync_mode, true, NULL);
922
+
923
+ return self;
924
+ }
925
+ /** end of each **/
926
+
927
+ /** turtle drawing functions **/
928
+ /* static VALUE */
929
+ /* m_turtle_move_to */
930
+
931
+ /* VALUE */
932
+ /* m_bezier(int argc, VALUE * argv, VALUE self) */
933
+ /* { */
934
+ /* VALUE points = Qnil; */
935
+ /* VALUE options = Qnil; */
936
+ /* int last = argc - 1; */
937
+ /* texture_info tex; */
938
+
939
+ /* ADJUST_SELF(self); */
940
+
941
+ /* if(argc < 1) rb_raise(rb_eArgError, "bezier action needs at least 1 parameter"); */
942
+
943
+ /* /\* get array of points *\/ */
944
+ /* points = argv[0]; */
945
+ /* Check_Type(points, T_ARRAY); */
946
+
947
+ /* options = argv[last]; */
948
+
949
+ /* get_texture_info(self, &tex); */
950
+
951
+ /* bezier_do_action(points, &tex, options, sync_mode, true, NULL); */
952
+
953
+ /* return self; */
954
+ /* } */
955
+
956
+ /** end turtle drawing **/
957
+
958
+
959
+ /* below is yucky old code that needs to be updated */
960
+ /* each_pixel iterator */
961
+
962
+
963
+ /* VALUE */
964
+ /* m_each(int argc, VALUE * argv, VALUE self) */
965
+ /* { */
966
+ /* int x0, y0, x1, y1, xbound, ybound, arity; */
967
+ /* VALUE options, region, pixel_data[2], yield_vals; */
968
+ /* register int x, y; */
969
+ /* texture_info tex; */
970
+ /* image_bounds bounds; */
971
+
972
+ /* rb_need_block(); */
973
+
974
+ /* arity = FIX2INT(rb_funcall(rb_block_proc(), rb_intern("arity"), 0)); */
975
+ /* if(arity != 1 && arity != 3) */
976
+ /* rb_raise(rb_eRuntimeError, "block arity must be either 1 or 3"); */
977
+
978
+ /* /\* ADJUST_SELF(self); *\/ */
979
+
980
+ /* /\* rb_scan_args(argc, argv, "01", &options); *\/ */
981
+
982
+ /* /\* /\\* get texture info *\\/ *\/ */
983
+ /* /\* get_texture_info(self, &tex); *\/ */
984
+
985
+ /* /\* /\\* default values for region *\\/ *\/ */
986
+ /* /\* x0 = 0; y0 = 0; x1 = tex.width; y1 = tex.height; *\/ */
987
+
988
+ /* /\* if(has_optional_hash_arg(options, "region")) { *\/ */
989
+ /* /\* region = get_from_hash(options, "region"); *\/ */
990
+
991
+ /* /\* x0 = NUM2INT(get_from_array(region, 0)); *\/ */
992
+ /* /\* y0 = NUM2INT(get_from_array(region, 1)); *\/ */
993
+ /* /\* x1 = NUM2INT(get_from_array(region, 2)); *\/ */
994
+ /* /\* y1 = NUM2INT(get_from_array(region, 3)); *\/ */
995
+
996
+ /* /\* constrain_boundaries(&x0, &y0, &x1, &y1, tex.width, tex.height); *\/ */
997
+ /* /\* } *\/ */
998
+
999
+ /* /\* /\\* width and height of action *\\/ *\/ */
1000
+ /* /\* xbound = x1 - x0; *\/ */
1001
+ /* /\* ybound = y1 - y0; *\/ */
1002
+
1003
+ /* /\* yield_vals = rb_ary_new(); *\/ */
1004
+
1005
+ /* /\* for(y = 0; y < ybound; y++) *\/ */
1006
+ /* /\* for(x = 0; x < xbound; x++) { *\/ */
1007
+ /* /\* VALUE pixel_color; *\/ */
1008
+ /* /\* rgba old_color; *\/ */
1009
+
1010
+ /* /\* /\\* adjusted x and y *\\/ *\/ */
1011
+ /* /\* register int ax = x + x0, ay = y + y0; *\/ */
1012
+
1013
+ /* /\* pixel_data[0] = INT2FIX(ax); *\/ */
1014
+ /* /\* pixel_data[1] = INT2FIX(ay); *\/ */
1015
+
1016
+ /* /\* pixel_color = m_getpixel(self, INT2FIX(ax), INT2FIX(ay)); *\/ */
1017
+
1018
+ /* /\* if(arity == 1) { *\/ */
1019
+ /* /\* rb_yield(pixel_color); *\/ */
1020
+ /* /\* } *\/ */
1021
+ /* /\* else if(arity == 3) { *\/ */
1022
+ /* /\* rb_ary_store(yield_vals, 0, pixel_color); *\/ */
1023
+ /* /\* rb_ary_store(yield_vals, 1, INT2FIX(x)); *\/ */
1024
+ /* /\* rb_ary_store(yield_vals, 2, INT2FIX(y)); *\/ */
1025
+
1026
+ /* /\* rb_yield(yield_vals); *\/ */
1027
+ /* /\* } *\/ */
1028
+
1029
+ /* /\* m_color(1, &pixel_color, self); *\/ */
1030
+ /* /\* // process_action(pixel, self, 2, pixel_data, false); *\/ */
1031
+ /* /\* // color_struct = old_color; *\/ */
1032
+ /* /\* } *\/ */
1033
+
1034
+ /* /\* bounds.xmin = x0; *\/ */
1035
+ /* /\* bounds.ymin = y0; *\/ */
1036
+ /* /\* bounds.xmax = x1; *\/ */
1037
+ /* /\* bounds.ymax = y1; *\/ */
1038
+
1039
+ /* /\* create_subtexture_and_sync_to_gl(&bounds, &tex); *\/ */
1040
+
1041
+ /* /\* return self; *\/ */
1042
+ /* /\* } *\/ */
1043
+
1044
+ /* /\** end each_pixel algorithm **\/} */
1045
+ /* /\** end each_pixel algorithm **\/ */
1046
+
1047
+
1048
+ /* /\* VALUE *\/ */
1049
+ /* /\* m_lshift(int argc, VALUE * argv, VALUE self) *\/ */
1050
+ /* /\* { *\/ */
1051
+ /* /\* int y,x, step, yoffset; *\/ */
1052
+ /* /\* VALUE options, loop; *\/ */
1053
+ /* /\* register int offset; *\/ */
1054
+ /* /\* texture_info tex; *\/ */
1055
+ /* /\* image_bounds bounds; *\/ */
1056
+
1057
+ /* /\* ADJUST_SELF(self); *\/ */
1058
+
1059
+ /* /\* rb_scan_args(argc, argv, "01", &options); *\/ */
1060
+
1061
+ /* /\* /\\* default values for other params *\\/ *\/ */
1062
+ /* /\* step = 1; loop = Qfalse; *\/ */
1063
+
1064
+ /* /\* if(TYPE(options) == T_HASH) { *\/ */
1065
+ /* /\* step = NUM2INT(get_from_hash(options, "step")); *\/ */
1066
+ /* /\* loop = get_from_hash(options, "loop"); *\/ */
1067
+ /* /\* } *\/ */
1068
+ /* /\* else if(options != Qnil) { *\/ */
1069
+ /* /\* rb_raise(rb_eArgError, "argument must be a hash"); *\/ */
1070
+ /* /\* } *\/ */
1071
+
1072
+ /* /\* /\\* get texture info *\\/ *\/ */
1073
+ /* /\* get_texture_info(self, &tex); *\/ */
1074
+
1075
+ /* /\* for(y = 0; y < tex.height; y++) { *\/ */
1076
+ /* /\* for(x = 0; x < tex.width; x++) { *\/ */
1077
+ /* /\* offset = calc_pixel_offset(&tex, x, y); *\/ */
1078
+
1079
+ /* /\* if((x + step) < tex.width) { *\/ */
1080
+ /* /\* color_copy(tex.td_array + offset + step * 4, tex.td_array + offset); *\/ */
1081
+ /* /\* } *\/ */
1082
+ /* /\* else { *\/ */
1083
+ /* /\* if(loop == Qtrue) { *\/ */
1084
+ /* /\* yoffset = calc_pixel_offset(&tex, x + step - tex.width, y); *\/ */
1085
+
1086
+ /* /\* color_copy(tex.td_array + yoffset, tex.td_array + offset); *\/ */
1087
+ /* /\* } *\/ */
1088
+ /* /\* else { *\/ */
1089
+
1090
+ /* /\* zero_color(tex.td_array + offset); *\/ */
1091
+ /* /\* } *\/ */
1092
+ /* /\* } *\/ */
1093
+
1094
+ /* /\* } *\/ */
1095
+ /* /\* } *\/ */
1096
+
1097
+ /* /\* bounds.xmin = 0; *\/ */
1098
+ /* /\* bounds.xmax = tex.width; *\/ */
1099
+ /* /\* bounds.ymin = 0; *\/ */
1100
+ /* /\* bounds.ymax = tex.height; *\/ */
1101
+
1102
+ /* /\* create_subtexture_and_sync_to_gl(&bounds, &tex); *\/ */
1103
+
1104
+ /* /\* return Qnil; *\/ */
1105
+ /* /\* } *\/ */
1106
+
1107
+ /* /\* VALUE *\/ */
1108
+ /* /\* m_rshift(int argc, VALUE * argv, VALUE self) *\/ */
1109
+ /* /\* { *\/ */
1110
+ /* /\* int y,x, step, yoffset; *\/ */
1111
+ /* /\* VALUE options, loop; *\/ */
1112
+ /* /\* register int offset; *\/ */
1113
+ /* /\* texture_info tex; *\/ */
1114
+ /* /\* image_bounds bounds; *\/ */
1115
+
1116
+ /* /\* ADJUST_SELF(self); *\/ */
1117
+
1118
+ /* /\* rb_scan_args(argc, argv, "01", &options); *\/ */
1119
+
1120
+ /* /\* /\\* default values for other params *\\/ *\/ */
1121
+ /* /\* step = 1; loop = Qfalse; *\/ */
1122
+
1123
+ /* /\* if(TYPE(options) == T_HASH) { *\/ */
1124
+ /* /\* step = NUM2INT(get_from_hash(options, "step")); *\/ */
1125
+ /* /\* loop = get_from_hash(options, "loop"); *\/ */
1126
+ /* /\* } *\/ */
1127
+ /* /\* else if(options != Qnil) { *\/ */
1128
+ /* /\* rb_raise(rb_eArgError, "argument must be a hash"); *\/ */
1129
+ /* /\* } *\/ */
1130
+
1131
+ /* /\* /\\* get texture info *\\/ *\/ */
1132
+ /* /\* get_texture_info(self, &tex); *\/ */
1133
+
1134
+ /* /\* for(y = 0; y < tex.height; y++) { *\/ */
1135
+ /* /\* for(x = tex.width - 1; x > -1; x--) { *\/ */
1136
+ /* /\* offset = calc_pixel_offset(&tex, x, y); *\/ */
1137
+
1138
+ /* /\* if((x - step) > -1) { *\/ */
1139
+ /* /\* color_copy(tex.td_array + offset - step * 4, tex.td_array + offset); *\/ */
1140
+ /* /\* } *\/ */
1141
+ /* /\* else { *\/ */
1142
+ /* /\* if(loop == Qtrue) { *\/ */
1143
+ /* /\* yoffset = calc_pixel_offset(&tex, x + tex.width - step, y); *\/ */
1144
+ /* /\* color_copy(tex.td_array + yoffset, tex.td_array + offset); *\/ */
1145
+ /* /\* } *\/ */
1146
+ /* /\* else { *\/ */
1147
+ /* /\* zero_color(tex.td_array + offset); *\/ */
1148
+ /* /\* } *\/ */
1149
+ /* /\* } *\/ */
1150
+
1151
+ /* /\* } *\/ */
1152
+ /* /\* } *\/ */
1153
+
1154
+ /* /\* bounds.xmin = 0; *\/ */
1155
+ /* /\* bounds.xmax = tex.width; *\/ */
1156
+ /* /\* bounds.ymin = 0; *\/ */
1157
+ /* /\* bounds.ymax = tex.height; *\/ */
1158
+
1159
+ /* /\* create_subtexture_and_sync_to_gl(&bounds, &tex); *\/ */
1160
+
1161
+ /* /\* return Qnil; *\/ */
1162
+ /* /\* } *\/ */
1163
+
1164
+ /* /\* /\\* special pixel action for image[]= *\\/ *\/ */
1165
+ /* /\* VALUE *\/ */
1166
+ /* /\* m_special_pixel(int argc, VALUE * argv, VALUE self) *\/ */
1167
+ /* /\* { *\/ */
1168
+
1169
+ /* /\* rgba old_color; *\/ */
1170
+
1171
+ /* /\* ADJUST_SELF(self); *\/ */
1172
+
1173
+ /* /\* if(argc < 3) rb_raise(rb_eArgError, "[]= action needs 3 parameters"); *\/ */
1174
+
1175
+ /* /\* m_color(1, &argv[2], self); *\/ */
1176
+
1177
+ /* /\* m_pixel(2, argv, self); *\/ */
1178
+
1179
+ /* /\* // color_struct = old_color; *\/ */
1180
+
1181
+
1182
+ /* /\* return Qnil; *\/ */
1183
+ /* /\* } *\/ */
1184
+
1185
+ /* /\* /\\* instance methods *\\/ *\/ */
1186
+