texplay 0.2.983pre2-i386-mswin32 → 0.3.0-i386-mswin32

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.
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
+