texplay 0.2.800 → 0.2.900
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.
- data/CHANGELOG +138 -119
- data/README.markdown +43 -41
- data/Rakefile +68 -68
- data/examples/common.rb +8 -8
- data/examples/example_alpha_blend.rb +31 -31
- data/examples/example_bezier.rb +42 -42
- data/examples/example_color_control.rb +69 -69
- data/examples/example_color_transform.rb +64 -67
- data/examples/example_color_transform_circle.rb +65 -0
- data/examples/example_dup.rb +75 -75
- data/examples/example_each.rb +42 -42
- data/examples/example_effect.rb +35 -35
- data/examples/example_fill.rb +44 -44
- data/examples/example_fill_old.rb +49 -49
- data/examples/example_fluent.rb +31 -31
- data/examples/example_gen_eval.rb +34 -34
- data/examples/example_hash_arguments.rb +47 -47
- data/examples/example_light.rb +77 -0
- data/examples/example_lsystem.rb +61 -61
- data/examples/example_melt.rb +27 -27
- data/examples/example_meyet.rb +64 -0
- data/examples/example_polyline.rb +43 -43
- data/examples/example_scale.rb +29 -29
- data/examples/example_simple.rb +48 -38
- data/examples/example_sync.rb +60 -60
- data/examples/example_trace.rb +1 -1
- data/examples/example_turtle.rb +40 -40
- data/examples/example_weird.rb +3 -1
- data/examples/media/Thumbs.db +0 -0
- data/ext/texplay/actions.c +999 -1001
- data/ext/texplay/actions.h +60 -60
- data/ext/texplay/bindings.c +1162 -1149
- data/ext/texplay/bindings.h +46 -46
- data/ext/texplay/cache.c +118 -118
- data/ext/texplay/cache.h +24 -24
- data/ext/texplay/compat.h +27 -27
- data/ext/texplay/extconf.rb +28 -28
- data/ext/texplay/gen_eval.c +211 -211
- data/ext/texplay/gen_eval.h +20 -20
- data/ext/texplay/graphics_utils.c +188 -63
- data/ext/texplay/graphics_utils.h +0 -1
- data/ext/texplay/object2module.c +171 -171
- data/ext/texplay/object2module.h +11 -11
- data/ext/texplay/texplay.c +169 -169
- data/ext/texplay/texplay.h +147 -130
- data/ext/texplay/utils.c +816 -752
- data/ext/texplay/utils.h +151 -145
- data/lib/texplay-contrib.rb +171 -171
- data/lib/texplay.rb +162 -137
- data/lib/texplay/version.rb +1 -1
- metadata +9 -5
|
@@ -16,6 +16,7 @@ static void process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync
|
|
|
16
16
|
static void prepare_drawing_mode(action_struct * cur);
|
|
17
17
|
static void prepare_fill_texture(action_struct * cur);
|
|
18
18
|
static void prepare_color_control(action_struct * cur);
|
|
19
|
+
static void prepare_color_select(action_struct * cur);
|
|
19
20
|
static rgba apply_lerp(action_struct * payload, texture_info * tex, int x, int y);
|
|
20
21
|
static rgba apply_alpha_blend(action_struct * payload, texture_info * tex, int x, int y, rgba blended_pixel);
|
|
21
22
|
static rgba apply_drawing_mode(action_struct * payload, texture_info * tex, int x, int y);
|
|
@@ -30,22 +31,23 @@ update_lazy_bounds(action_struct * cur, texture_info * tex)
|
|
|
30
31
|
{
|
|
31
32
|
|
|
32
33
|
/* only update global bounds if we're doing a lazy_sync */
|
|
33
|
-
if(cur->sync_mode
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
xmin = INT2FIX(MIN(cur->xmin, FIX2INT(get_from_array(lazy_bounds, 0))));
|
|
40
|
-
ymin = INT2FIX(MIN(cur->ymin, FIX2INT(get_from_array(lazy_bounds, 1))));
|
|
41
|
-
xmax = INT2FIX(MAX(cur->xmax, FIX2INT(get_from_array(lazy_bounds, 2))));
|
|
42
|
-
ymax = INT2FIX(MAX(cur->ymax, FIX2INT(get_from_array(lazy_bounds, 3))));
|
|
34
|
+
if (cur->sync_mode != lazy_sync)
|
|
35
|
+
return;
|
|
36
|
+
|
|
37
|
+
VALUE lazy_bounds;
|
|
38
|
+
int xmin, ymin, xmax, ymax;
|
|
43
39
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
lazy_bounds = get_image_local(tex->image, LAZY_BOUNDS);
|
|
41
|
+
|
|
42
|
+
xmin = INT2FIX(MIN(cur->xmin, FIX2INT(get_from_array(lazy_bounds, 0))));
|
|
43
|
+
ymin = INT2FIX(MIN(cur->ymin, FIX2INT(get_from_array(lazy_bounds, 1))));
|
|
44
|
+
xmax = INT2FIX(MAX(cur->xmax, FIX2INT(get_from_array(lazy_bounds, 2))));
|
|
45
|
+
ymax = INT2FIX(MAX(cur->ymax, FIX2INT(get_from_array(lazy_bounds, 3))));
|
|
46
|
+
|
|
47
|
+
set_array_value(lazy_bounds, 0, xmin);
|
|
48
|
+
set_array_value(lazy_bounds, 1, ymin);
|
|
49
|
+
set_array_value(lazy_bounds, 2, xmax);
|
|
50
|
+
set_array_value(lazy_bounds, 3, ymax);
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
void
|
|
@@ -63,11 +65,11 @@ update_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax)
|
|
|
63
65
|
void
|
|
64
66
|
set_local_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax, texture_info * tex)
|
|
65
67
|
{
|
|
66
|
-
if(cur->sync_mode == no_sync)
|
|
67
|
-
return;
|
|
68
68
|
|
|
69
69
|
/* local bounds used by both eager_sync and lazy_sync: */
|
|
70
|
-
|
|
70
|
+
if(cur->sync_mode == no_sync)
|
|
71
|
+
return;
|
|
72
|
+
|
|
71
73
|
/* eager sync: to demarcate precise area to sync to opengl */
|
|
72
74
|
/* lazy sync: to update global bounds */
|
|
73
75
|
cur->xmin = xmin;
|
|
@@ -145,6 +147,55 @@ set_pixel_color(rgba * pixel_color, texture_info * tex, int x, int y)
|
|
|
145
147
|
tex_data[alpha] = pixel_color->alpha;
|
|
146
148
|
}
|
|
147
149
|
|
|
150
|
+
static bool
|
|
151
|
+
skip_pixel(rgba source_color, action_struct * payload, texture_info * tex, int x, int y)
|
|
152
|
+
{
|
|
153
|
+
|
|
154
|
+
if (!payload->pen.has_color_select) return false;
|
|
155
|
+
|
|
156
|
+
rgba dest_color = get_pixel_color(tex, x, y);
|
|
157
|
+
bool color_match = false;
|
|
158
|
+
|
|
159
|
+
if (payload->pen.source_select.size > 0) {
|
|
160
|
+
for (int i = 0; i < payload->pen.source_select.size; i++) {
|
|
161
|
+
if (cmp_color(source_color, payload->pen.source_select.colors[i])) {
|
|
162
|
+
color_match = true;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (!color_match) return true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
if (payload->pen.source_ignore.size > 0) {
|
|
171
|
+
for (int i = 0; i < payload->pen.source_ignore.size; i++) {
|
|
172
|
+
if (cmp_color(source_color, payload->pen.source_ignore.colors[i]))
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
color_match = false;
|
|
178
|
+
if (payload->pen.dest_select.size > 0) {
|
|
179
|
+
for (int i = 0; i < payload->pen.dest_select.size; i++) {
|
|
180
|
+
if (cmp_color(dest_color, payload->pen.dest_select.colors[i])) {
|
|
181
|
+
color_match = true;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (!color_match) return true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (payload->pen.dest_ignore.size > 0) {
|
|
189
|
+
for (int i = 0; i < payload->pen.dest_ignore.size; i++) {
|
|
190
|
+
if (cmp_color(dest_color, payload->pen.dest_ignore.colors[i]))
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
|
|
148
199
|
void
|
|
149
200
|
set_pixel_color_with_style(action_struct * payload, texture_info * tex, int x, int y)
|
|
150
201
|
{
|
|
@@ -153,6 +204,7 @@ set_pixel_color_with_style(action_struct * payload, texture_info * tex, int x, i
|
|
|
153
204
|
|
|
154
205
|
blended_pixel = payload->color;
|
|
155
206
|
|
|
207
|
+
|
|
156
208
|
/* for linear interpolation */
|
|
157
209
|
if(payload->pen.has_lerp) {
|
|
158
210
|
blended_pixel = apply_lerp(payload, tex, x, y);
|
|
@@ -168,12 +220,15 @@ set_pixel_color_with_style(action_struct * payload, texture_info * tex, int x, i
|
|
|
168
220
|
x % payload->pen.source_tex.width,
|
|
169
221
|
y % payload->pen.source_tex.height);
|
|
170
222
|
|
|
171
|
-
/* for color_control
|
|
223
|
+
/* for color_control proc */
|
|
172
224
|
if(payload->pen.has_color_control_proc)
|
|
173
225
|
blended_pixel = exec_color_control_proc(payload, tex, x, y, blended_pixel);
|
|
174
|
-
|
|
175
226
|
|
|
176
|
-
/*
|
|
227
|
+
/* should skip this pixel? */
|
|
228
|
+
if (skip_pixel(blended_pixel, payload, tex, x, y))
|
|
229
|
+
return;
|
|
230
|
+
|
|
231
|
+
/* drawing modes */
|
|
177
232
|
if(payload->pen.has_drawing_mode) {
|
|
178
233
|
blended_pixel = apply_drawing_mode(payload, tex, x, y);
|
|
179
234
|
}
|
|
@@ -245,12 +300,16 @@ get_pixel_data(texture_info * tex, int x, int y)
|
|
|
245
300
|
VALUE
|
|
246
301
|
create_image(VALUE window, int width, int height)
|
|
247
302
|
{
|
|
248
|
-
VALUE
|
|
249
|
-
VALUE image =
|
|
303
|
+
static VALUE empty_image_stub = 0;
|
|
304
|
+
static VALUE image = 0;
|
|
305
|
+
|
|
306
|
+
if (empty_image_stub == 0) {
|
|
307
|
+
VALUE gosu = rb_const_get(rb_cObject, rb_intern("Gosu"));
|
|
308
|
+
VALUE tp = rb_const_get(rb_cObject, rb_intern("TexPlay"));
|
|
309
|
+
empty_image_stub = rb_const_get(tp, rb_intern("EmptyImageStub"));
|
|
310
|
+
image = rb_const_get(gosu, rb_intern("Image"));
|
|
311
|
+
}
|
|
250
312
|
|
|
251
|
-
VALUE tp = rb_const_get(rb_cObject, rb_intern("TexPlay"));
|
|
252
|
-
VALUE empty_image_stub = rb_const_get(tp, rb_intern("EmptyImageStub"));
|
|
253
|
-
|
|
254
313
|
VALUE rmagick_img;
|
|
255
314
|
VALUE new_image;
|
|
256
315
|
|
|
@@ -293,6 +352,13 @@ initialize_action_struct(action_struct * cur, VALUE hash_arg, sync sync_mode)
|
|
|
293
352
|
|
|
294
353
|
/* drawing mode is off by deafult */
|
|
295
354
|
cur->pen.has_drawing_mode = false;
|
|
355
|
+
|
|
356
|
+
/* color selection */
|
|
357
|
+
cur->pen.has_color_select = false;
|
|
358
|
+
cur->pen.source_select.size = 0;
|
|
359
|
+
cur->pen.source_ignore.size = 0;
|
|
360
|
+
cur->pen.dest_select.size = 0;
|
|
361
|
+
cur->pen.dest_ignore.size = 0;
|
|
296
362
|
}
|
|
297
363
|
|
|
298
364
|
/* TODO: fix this function below, it's too ugly and bulky and weird **/
|
|
@@ -365,6 +431,9 @@ process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode,
|
|
|
365
431
|
|
|
366
432
|
}
|
|
367
433
|
|
|
434
|
+
/* prepare color selection */
|
|
435
|
+
prepare_color_select(cur);
|
|
436
|
+
|
|
368
437
|
/* process drawing mode */
|
|
369
438
|
prepare_drawing_mode(cur);
|
|
370
439
|
|
|
@@ -450,14 +519,14 @@ prepare_drawing_mode(action_struct * cur)
|
|
|
450
519
|
cur->pen.drawing_mode = darken;
|
|
451
520
|
else if(draw_mode == string2sym("lighten"))
|
|
452
521
|
cur->pen.drawing_mode = lighten;
|
|
453
|
-
else if(draw_mode == string2sym("
|
|
454
|
-
cur->pen.drawing_mode =
|
|
455
|
-
else if(draw_mode == string2sym("
|
|
456
|
-
cur->pen.drawing_mode =
|
|
457
|
-
else if(draw_mode == string2sym("
|
|
458
|
-
cur->pen.drawing_mode =
|
|
459
|
-
else if(draw_mode == string2sym("
|
|
460
|
-
cur->pen.drawing_mode =
|
|
522
|
+
else if(draw_mode == string2sym("color_dodge"))
|
|
523
|
+
cur->pen.drawing_mode = color_dodge;
|
|
524
|
+
else if(draw_mode == string2sym("color_burn"))
|
|
525
|
+
cur->pen.drawing_mode = color_burn;
|
|
526
|
+
else if(draw_mode == string2sym("hard_light"))
|
|
527
|
+
cur->pen.drawing_mode = hard_light;
|
|
528
|
+
else if(draw_mode == string2sym("soft_light"))
|
|
529
|
+
cur->pen.drawing_mode = soft_light;
|
|
461
530
|
else if(draw_mode == string2sym("difference"))
|
|
462
531
|
cur->pen.drawing_mode = difference;
|
|
463
532
|
else if(draw_mode == string2sym("exclusion"))
|
|
@@ -488,24 +557,23 @@ prepare_color_control(action_struct * cur)
|
|
|
488
557
|
VALUE try_mult = get_from_hash(try_val, "mult");
|
|
489
558
|
|
|
490
559
|
if(is_an_array(try_add)) {
|
|
491
|
-
if(RARRAY_LEN(try_add) < 4)
|
|
492
|
-
rb_raise(rb_eArgError, ":color_control transform :add needs 4 parameters");
|
|
493
560
|
|
|
494
|
-
cur->pen.color_add
|
|
495
|
-
cur->pen.color_add.
|
|
496
|
-
cur->pen.color_add.
|
|
497
|
-
cur->pen.color_add.
|
|
561
|
+
cur->pen.color_add = convert_rb_color_to_rgba(try_add);
|
|
562
|
+
/* cur->pen.color_add.red = NUM2DBL(get_from_array(try_add, 0)); */
|
|
563
|
+
/* cur->pen.color_add.green = NUM2DBL(get_from_array(try_add, 1)); */
|
|
564
|
+
/* cur->pen.color_add.blue = NUM2DBL(get_from_array(try_add, 2)); */
|
|
565
|
+
/* cur->pen.color_add.alpha = NUM2DBL(get_from_array(try_add, 3)); */
|
|
498
566
|
|
|
499
567
|
cur->pen.has_color_control_transform = true;
|
|
500
568
|
}
|
|
501
569
|
if(is_an_array(try_mult)) {
|
|
502
|
-
if(RARRAY_LEN(try_mult) < 4)
|
|
503
|
-
rb_raise(rb_eArgError, ":color_control transform :mult needs 4 parameters");
|
|
504
570
|
|
|
505
|
-
cur->pen.color_mult
|
|
506
|
-
|
|
507
|
-
cur->pen.color_mult.
|
|
508
|
-
cur->pen.color_mult.
|
|
571
|
+
cur->pen.color_mult = convert_rb_color_to_rgba(try_mult);
|
|
572
|
+
|
|
573
|
+
/* cur->pen.color_mult.red = NUM2DBL(get_from_array(try_mult, 0)); */
|
|
574
|
+
/* cur->pen.color_mult.green = NUM2DBL(get_from_array(try_mult, 1)); */
|
|
575
|
+
/* cur->pen.color_mult.blue = NUM2DBL(get_from_array(try_mult, 2)); */
|
|
576
|
+
/* cur->pen.color_mult.alpha = NUM2DBL(get_from_array(try_mult, 3)); */
|
|
509
577
|
|
|
510
578
|
cur->pen.has_color_control_transform = true;
|
|
511
579
|
}
|
|
@@ -576,6 +644,65 @@ prepare_fill_texture(action_struct * payload)
|
|
|
576
644
|
}
|
|
577
645
|
}
|
|
578
646
|
|
|
647
|
+
static void
|
|
648
|
+
process_select_color_list(rgba_list * clist, VALUE try_color)
|
|
649
|
+
{
|
|
650
|
+
/* is a general array of colors? i.e [:red, Gosu::Color::RED, [1,1,1,1] ] */
|
|
651
|
+
if (TYPE(try_color) == T_ARRAY && not_rb_raw_color(try_color)) {
|
|
652
|
+
int num_colors = RARRAY_LEN(try_color);
|
|
653
|
+
|
|
654
|
+
if (num_colors > RGBA_LIST_SIZE)
|
|
655
|
+
rb_raise(rb_eArgError, "Too many colors given in array. Maximum is %d\n. Got %d\n",
|
|
656
|
+
RGBA_LIST_SIZE, num_colors);
|
|
657
|
+
|
|
658
|
+
for (int i = 0; i < RARRAY_LEN(try_color); ++i) {
|
|
659
|
+
clist->colors[i] = convert_rb_color_to_rgba(get_from_array(try_color, i));
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
clist->size = num_colors;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/* is a single color value? i.e :red, [1,1,1,1], Gosu::Color::GREEN */
|
|
666
|
+
else {
|
|
667
|
+
clist->colors[0] = convert_rb_color_to_rgba(try_color);
|
|
668
|
+
clist->size = 1;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
static void
|
|
674
|
+
prepare_color_select(action_struct * payload)
|
|
675
|
+
{
|
|
676
|
+
VALUE try_color = get_from_hash(payload->hash_arg,
|
|
677
|
+
"source_select");
|
|
678
|
+
if (!NIL_P(try_color)) {
|
|
679
|
+
process_select_color_list(&payload->pen.source_select, try_color);
|
|
680
|
+
payload->pen.has_color_select = true;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
try_color = get_from_hash(payload->hash_arg,
|
|
684
|
+
"source_ignore");
|
|
685
|
+
if (!NIL_P(try_color)) {
|
|
686
|
+
process_select_color_list(&payload->pen.source_ignore, try_color);
|
|
687
|
+
payload->pen.has_color_select = true;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
try_color = get_from_hash(payload->hash_arg,
|
|
691
|
+
"dest_select");
|
|
692
|
+
if (!NIL_P(try_color)) {
|
|
693
|
+
process_select_color_list(&payload->pen.dest_select, try_color);
|
|
694
|
+
payload->pen.has_color_select = true;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
try_color = get_from_hash(payload->hash_arg,
|
|
698
|
+
"dest_ignore");
|
|
699
|
+
if (!NIL_P(try_color)) {
|
|
700
|
+
process_select_color_list(&payload->pen.dest_ignore, try_color);
|
|
701
|
+
payload->pen.has_color_select = true;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
}
|
|
705
|
+
|
|
579
706
|
/***********************************/
|
|
580
707
|
/**** drawing mode related code ****/
|
|
581
708
|
/***********************************/
|
|
@@ -720,32 +847,32 @@ apply_drawing_mode(action_struct * payload, texture_info * tex, int x, int y)
|
|
|
720
847
|
finished_pixel = color_int_vals_to_float_format(~source_pixel_char.red,
|
|
721
848
|
~source_pixel_char.green,
|
|
722
849
|
~source_pixel_char.blue,
|
|
723
|
-
|
|
850
|
+
source_pixel_char.alpha);
|
|
724
851
|
break;
|
|
725
852
|
case invert:
|
|
726
853
|
finished_pixel = color_int_vals_to_float_format(~dest_pixel_char.red,
|
|
727
854
|
~dest_pixel_char.green,
|
|
728
855
|
~dest_pixel_char.blue,
|
|
729
|
-
|
|
856
|
+
dest_pixel_char.alpha);
|
|
730
857
|
|
|
731
858
|
break;
|
|
732
859
|
case and_reverse:
|
|
733
860
|
finished_pixel = color_int_vals_to_float_format(source_pixel_char.red | ~dest_pixel_char.red,
|
|
734
861
|
source_pixel_char.green | ~dest_pixel_char.green,
|
|
735
862
|
source_pixel_char.blue | ~dest_pixel_char.blue,
|
|
736
|
-
source_pixel_char.alpha
|
|
863
|
+
source_pixel_char.alpha);
|
|
737
864
|
break;
|
|
738
865
|
case and:
|
|
739
866
|
finished_pixel = color_int_vals_to_float_format(source_pixel_char.red & dest_pixel_char.red,
|
|
740
867
|
source_pixel_char.green & dest_pixel_char.green,
|
|
741
868
|
source_pixel_char.blue & dest_pixel_char.blue,
|
|
742
|
-
source_pixel_char.alpha
|
|
869
|
+
source_pixel_char.alpha);
|
|
743
870
|
break;
|
|
744
871
|
case or:
|
|
745
872
|
finished_pixel = color_int_vals_to_float_format(source_pixel_char.red | dest_pixel_char.red,
|
|
746
873
|
source_pixel_char.green | dest_pixel_char.green,
|
|
747
874
|
source_pixel_char.blue | dest_pixel_char.blue,
|
|
748
|
-
source_pixel_char.alpha
|
|
875
|
+
source_pixel_char.alpha);
|
|
749
876
|
|
|
750
877
|
break;
|
|
751
878
|
case nand:
|
|
@@ -759,34 +886,34 @@ apply_drawing_mode(action_struct * payload, texture_info * tex, int x, int y)
|
|
|
759
886
|
finished_pixel = color_int_vals_to_float_format(~(source_pixel_char.red | dest_pixel_char.red),
|
|
760
887
|
~(source_pixel_char.green | dest_pixel_char.green),
|
|
761
888
|
~(source_pixel_char.blue | dest_pixel_char.blue),
|
|
762
|
-
|
|
889
|
+
source_pixel_char.alpha);
|
|
763
890
|
|
|
764
891
|
break;
|
|
765
892
|
case xor:
|
|
766
893
|
finished_pixel = color_int_vals_to_float_format(source_pixel_char.red ^ dest_pixel_char.red,
|
|
767
894
|
source_pixel_char.green ^ dest_pixel_char.green,
|
|
768
895
|
source_pixel_char.blue ^ dest_pixel_char.blue,
|
|
769
|
-
source_pixel_char.alpha
|
|
896
|
+
source_pixel_char.alpha);
|
|
770
897
|
|
|
771
898
|
break;
|
|
772
899
|
case equiv:
|
|
773
900
|
finished_pixel = color_int_vals_to_float_format(~(source_pixel_char.red ^ dest_pixel_char.red),
|
|
774
901
|
~(source_pixel_char.green ^ dest_pixel_char.green),
|
|
775
902
|
~(source_pixel_char.blue ^ dest_pixel_char.blue),
|
|
776
|
-
|
|
903
|
+
source_pixel_char.alpha);
|
|
777
904
|
|
|
778
905
|
break;
|
|
779
906
|
case and_inverted:
|
|
780
907
|
finished_pixel = color_int_vals_to_float_format(~source_pixel_char.red & dest_pixel_char.red,
|
|
781
908
|
~source_pixel_char.green & dest_pixel_char.green,
|
|
782
909
|
~source_pixel_char.blue & dest_pixel_char.blue,
|
|
783
|
-
|
|
910
|
+
source_pixel_char.alpha);
|
|
784
911
|
break;
|
|
785
912
|
case or_inverted:
|
|
786
913
|
finished_pixel = color_int_vals_to_float_format(~source_pixel_char.red | dest_pixel_char.red,
|
|
787
914
|
~source_pixel_char.green | dest_pixel_char.green,
|
|
788
915
|
~source_pixel_char.blue | dest_pixel_char.blue,
|
|
789
|
-
|
|
916
|
+
source_pixel_char.alpha);
|
|
790
917
|
|
|
791
918
|
break;
|
|
792
919
|
|
|
@@ -809,7 +936,6 @@ apply_drawing_mode(action_struct * payload, texture_info * tex, int x, int y)
|
|
|
809
936
|
finished_pixel = mode_hardlight(source_pixel, dest_pixel);
|
|
810
937
|
|
|
811
938
|
break;
|
|
812
|
-
|
|
813
939
|
case darken:
|
|
814
940
|
finished_pixel = (rgba) { MIN(source_pixel.red, dest_pixel.red),
|
|
815
941
|
MIN(source_pixel.green, dest_pixel.green),
|
|
@@ -822,24 +948,24 @@ apply_drawing_mode(action_struct * payload, texture_info * tex, int x, int y)
|
|
|
822
948
|
MAX(source_pixel.blue, dest_pixel.blue),
|
|
823
949
|
MAX(source_pixel.alpha, dest_pixel.alpha) };
|
|
824
950
|
break;
|
|
825
|
-
case
|
|
951
|
+
case color_dodge:
|
|
826
952
|
finished_pixel = (rgba) { mode_colordodge_channel(dest_pixel.red, source_pixel.red),
|
|
827
953
|
mode_colordodge_channel(dest_pixel.green, source_pixel.green),
|
|
828
954
|
mode_colordodge_channel(dest_pixel.blue, source_pixel.blue),
|
|
829
955
|
mode_colordodge_channel(dest_pixel.alpha, source_pixel.alpha) };
|
|
830
956
|
|
|
831
957
|
break;
|
|
832
|
-
case
|
|
958
|
+
case color_burn:
|
|
833
959
|
finished_pixel = (rgba) { mode_colorburn_channel(dest_pixel.red, source_pixel.red),
|
|
834
960
|
mode_colorburn_channel(dest_pixel.green, source_pixel.green),
|
|
835
961
|
mode_colorburn_channel(dest_pixel.blue, source_pixel.blue),
|
|
836
962
|
mode_colorburn_channel(dest_pixel.alpha, source_pixel.alpha) };
|
|
837
963
|
break;
|
|
838
|
-
case
|
|
964
|
+
case hard_light:
|
|
839
965
|
finished_pixel = mode_hardlight(dest_pixel, source_pixel);
|
|
840
966
|
|
|
841
967
|
break;
|
|
842
|
-
case
|
|
968
|
+
case soft_light:
|
|
843
969
|
finished_pixel = mode_softlight(dest_pixel, source_pixel);
|
|
844
970
|
|
|
845
971
|
break;
|
|
@@ -915,7 +1041,7 @@ apply_alpha_blend(action_struct * payload, texture_info * tex, int x, int y, rgb
|
|
|
915
1041
|
rgba finished_pixel;
|
|
916
1042
|
|
|
917
1043
|
|
|
918
|
-
if(not_a_color(blended_pixel))
|
|
1044
|
+
if (not_a_color(blended_pixel))
|
|
919
1045
|
return blended_pixel;
|
|
920
1046
|
|
|
921
1047
|
/* alpha blending is nothing more than a weighted average of src and dest pixels
|
|
@@ -948,7 +1074,6 @@ allocate_texture(int width, int height)
|
|
|
948
1074
|
int mval;
|
|
949
1075
|
|
|
950
1076
|
mval = 4 * width * height * sizeof(float);
|
|
951
|
-
// assert(mval > 0);
|
|
952
1077
|
|
|
953
1078
|
new_texture = malloc(mval);
|
|
954
1079
|
|
data/ext/texplay/object2module.c
CHANGED
|
@@ -1,171 +1,171 @@
|
|
|
1
|
-
/* object2module.c */
|
|
2
|
-
/* (C) John Mair 2009
|
|
3
|
-
* This program is distributed under the terms of the MIT License
|
|
4
|
-
* */
|
|
5
|
-
|
|
6
|
-
#include <ruby.h>
|
|
7
|
-
#include "compat.h"
|
|
8
|
-
|
|
9
|
-
#ifdef RUBY_19
|
|
10
|
-
# include <ruby/st.h>
|
|
11
|
-
#else
|
|
12
|
-
# include <st.h>
|
|
13
|
-
#endif
|
|
14
|
-
|
|
15
|
-
/* class creation. from class.c in 1.9.1 */
|
|
16
|
-
#ifdef RUBY_19
|
|
17
|
-
static VALUE
|
|
18
|
-
class_alloc(VALUE flags, VALUE klass)
|
|
19
|
-
{
|
|
20
|
-
rb_classext_t *ext = ALLOC(rb_classext_t);
|
|
21
|
-
NEWOBJ(obj, struct RClass);
|
|
22
|
-
OBJSETUP(obj, klass, flags);
|
|
23
|
-
obj->ptr = ext;
|
|
24
|
-
RCLASS_IV_TBL(obj) = 0;
|
|
25
|
-
RCLASS_M_TBL(obj) = 0;
|
|
26
|
-
RCLASS_SUPER(obj) = 0;
|
|
27
|
-
RCLASS_IV_INDEX_TBL(obj) = 0;
|
|
28
|
-
return (VALUE)obj;
|
|
29
|
-
}
|
|
30
|
-
#endif
|
|
31
|
-
|
|
32
|
-
/* a modified version of include_class_new from class.c */
|
|
33
|
-
static VALUE
|
|
34
|
-
j_class_new(VALUE module, VALUE sup)
|
|
35
|
-
{
|
|
36
|
-
|
|
37
|
-
#ifdef RUBY_19
|
|
38
|
-
VALUE klass = class_alloc(T_ICLASS, rb_cClass);
|
|
39
|
-
#else
|
|
40
|
-
NEWOBJ(klass, struct RClass);
|
|
41
|
-
OBJSETUP(klass, rb_cClass, T_ICLASS);
|
|
42
|
-
#endif
|
|
43
|
-
|
|
44
|
-
if (BUILTIN_TYPE(module) == T_ICLASS) {
|
|
45
|
-
module = KLASS_OF(module);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!RCLASS_IV_TBL(module)) {
|
|
49
|
-
|
|
50
|
-
RCLASS_IV_TBL(module) = (struct st_table *)st_init_numtable();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/* assign iv_tbl, m_tbl and super */
|
|
54
|
-
RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
|
|
55
|
-
RCLASS_SUPER(klass) = sup;
|
|
56
|
-
if(TYPE(module) != T_OBJECT) {
|
|
57
|
-
|
|
58
|
-
RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
RCLASS_M_TBL(klass) = RCLASS_M_TBL(CLASS_OF(module));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/* */
|
|
65
|
-
|
|
66
|
-
if (TYPE(module) == T_ICLASS) {
|
|
67
|
-
KLASS_OF(klass) = KLASS_OF(module);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
KLASS_OF(klass) = module;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if(TYPE(module) != T_OBJECT) {
|
|
74
|
-
OBJ_INFECT(klass, module);
|
|
75
|
-
OBJ_INFECT(klass, sup);
|
|
76
|
-
}
|
|
77
|
-
return (VALUE)klass;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
VALUE
|
|
81
|
-
rb_to_module(VALUE self)
|
|
82
|
-
{
|
|
83
|
-
VALUE rclass, chain_start, jcur, klass;
|
|
84
|
-
|
|
85
|
-
switch(BUILTIN_TYPE(self)) {
|
|
86
|
-
case T_MODULE:
|
|
87
|
-
return self;
|
|
88
|
-
case T_CLASS:
|
|
89
|
-
klass = self;
|
|
90
|
-
break;
|
|
91
|
-
case T_OBJECT:
|
|
92
|
-
default:
|
|
93
|
-
klass = rb_singleton_class(self);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
chain_start = j_class_new(klass, rb_cObject);
|
|
97
|
-
|
|
98
|
-
KLASS_OF(chain_start) = rb_cModule;
|
|
99
|
-
RBASIC(chain_start)->flags = T_MODULE;
|
|
100
|
-
|
|
101
|
-
jcur = chain_start;
|
|
102
|
-
for(rclass = RCLASS_SUPER(klass); rclass != rb_cObject;
|
|
103
|
-
rclass = RCLASS_SUPER(rclass)) {
|
|
104
|
-
|
|
105
|
-
RCLASS_SUPER(jcur) = j_class_new(rclass, rb_cObject);
|
|
106
|
-
jcur = RCLASS_SUPER(jcur);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
RCLASS_SUPER(jcur) = (VALUE)NULL;
|
|
110
|
-
|
|
111
|
-
return chain_start;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
VALUE
|
|
115
|
-
rb_reset_tbls(VALUE self)
|
|
116
|
-
{
|
|
117
|
-
RCLASS_IV_TBL(self) = (struct st_table *) 0;
|
|
118
|
-
RCLASS_M_TBL(self) = (struct st_table *) st_init_numtable();
|
|
119
|
-
return Qnil;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/* cannot simply forward to gen_include as need to invoke 'extended' hook */
|
|
123
|
-
VALUE
|
|
124
|
-
rb_gen_extend(int argc, VALUE * argv, VALUE self)
|
|
125
|
-
{
|
|
126
|
-
int i;
|
|
127
|
-
|
|
128
|
-
if (argc == 0) rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
|
|
129
|
-
|
|
130
|
-
rb_singleton_class(self);
|
|
131
|
-
|
|
132
|
-
for(i = 0; i < argc; i++) {
|
|
133
|
-
VALUE mod = rb_to_module(argv[i]);
|
|
134
|
-
rb_funcall(mod, rb_intern("extend_object"), 1, self);
|
|
135
|
-
rb_funcall(mod, rb_intern("extended"), 1, self);
|
|
136
|
-
|
|
137
|
-
/* only redirect if argv[i] is not a module */
|
|
138
|
-
if(argv[i] != mod) rb_reset_tbls(mod);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return self;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
VALUE
|
|
145
|
-
rb_gen_include(int argc, VALUE * argv, VALUE self)
|
|
146
|
-
{
|
|
147
|
-
int i;
|
|
148
|
-
|
|
149
|
-
if (argc == 0) rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
|
|
150
|
-
|
|
151
|
-
for(i = 0; i < argc; i++) {
|
|
152
|
-
VALUE mod = rb_to_module(argv[i]);
|
|
153
|
-
rb_funcall(mod, rb_intern("append_features"), 1, self);
|
|
154
|
-
rb_funcall(mod, rb_intern("included"), 1, self);
|
|
155
|
-
|
|
156
|
-
if(argv[i] != mod) rb_reset_tbls(mod);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return self;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
void Init_object2module()
|
|
164
|
-
{
|
|
165
|
-
|
|
166
|
-
rb_define_method(rb_cObject, "to_module", rb_to_module , 0);
|
|
167
|
-
rb_define_method(rb_cObject, "gen_extend", rb_gen_extend, -1);
|
|
168
|
-
rb_define_method(rb_cModule, "gen_include", rb_gen_include, -1);
|
|
169
|
-
rb_define_method(rb_cModule, "reset_tbls", rb_reset_tbls, 0);
|
|
170
|
-
}
|
|
171
|
-
|
|
1
|
+
/* object2module.c */
|
|
2
|
+
/* (C) John Mair 2009
|
|
3
|
+
* This program is distributed under the terms of the MIT License
|
|
4
|
+
* */
|
|
5
|
+
|
|
6
|
+
#include <ruby.h>
|
|
7
|
+
#include "compat.h"
|
|
8
|
+
|
|
9
|
+
#ifdef RUBY_19
|
|
10
|
+
# include <ruby/st.h>
|
|
11
|
+
#else
|
|
12
|
+
# include <st.h>
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
/* class creation. from class.c in 1.9.1 */
|
|
16
|
+
#ifdef RUBY_19
|
|
17
|
+
static VALUE
|
|
18
|
+
class_alloc(VALUE flags, VALUE klass)
|
|
19
|
+
{
|
|
20
|
+
rb_classext_t *ext = ALLOC(rb_classext_t);
|
|
21
|
+
NEWOBJ(obj, struct RClass);
|
|
22
|
+
OBJSETUP(obj, klass, flags);
|
|
23
|
+
obj->ptr = ext;
|
|
24
|
+
RCLASS_IV_TBL(obj) = 0;
|
|
25
|
+
RCLASS_M_TBL(obj) = 0;
|
|
26
|
+
RCLASS_SUPER(obj) = 0;
|
|
27
|
+
RCLASS_IV_INDEX_TBL(obj) = 0;
|
|
28
|
+
return (VALUE)obj;
|
|
29
|
+
}
|
|
30
|
+
#endif
|
|
31
|
+
|
|
32
|
+
/* a modified version of include_class_new from class.c */
|
|
33
|
+
static VALUE
|
|
34
|
+
j_class_new(VALUE module, VALUE sup)
|
|
35
|
+
{
|
|
36
|
+
|
|
37
|
+
#ifdef RUBY_19
|
|
38
|
+
VALUE klass = class_alloc(T_ICLASS, rb_cClass);
|
|
39
|
+
#else
|
|
40
|
+
NEWOBJ(klass, struct RClass);
|
|
41
|
+
OBJSETUP(klass, rb_cClass, T_ICLASS);
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
if (BUILTIN_TYPE(module) == T_ICLASS) {
|
|
45
|
+
module = KLASS_OF(module);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!RCLASS_IV_TBL(module)) {
|
|
49
|
+
|
|
50
|
+
RCLASS_IV_TBL(module) = (struct st_table *)st_init_numtable();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* assign iv_tbl, m_tbl and super */
|
|
54
|
+
RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
|
|
55
|
+
RCLASS_SUPER(klass) = sup;
|
|
56
|
+
if(TYPE(module) != T_OBJECT) {
|
|
57
|
+
|
|
58
|
+
RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
RCLASS_M_TBL(klass) = RCLASS_M_TBL(CLASS_OF(module));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* */
|
|
65
|
+
|
|
66
|
+
if (TYPE(module) == T_ICLASS) {
|
|
67
|
+
KLASS_OF(klass) = KLASS_OF(module);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
KLASS_OF(klass) = module;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if(TYPE(module) != T_OBJECT) {
|
|
74
|
+
OBJ_INFECT(klass, module);
|
|
75
|
+
OBJ_INFECT(klass, sup);
|
|
76
|
+
}
|
|
77
|
+
return (VALUE)klass;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
VALUE
|
|
81
|
+
rb_to_module(VALUE self)
|
|
82
|
+
{
|
|
83
|
+
VALUE rclass, chain_start, jcur, klass;
|
|
84
|
+
|
|
85
|
+
switch(BUILTIN_TYPE(self)) {
|
|
86
|
+
case T_MODULE:
|
|
87
|
+
return self;
|
|
88
|
+
case T_CLASS:
|
|
89
|
+
klass = self;
|
|
90
|
+
break;
|
|
91
|
+
case T_OBJECT:
|
|
92
|
+
default:
|
|
93
|
+
klass = rb_singleton_class(self);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
chain_start = j_class_new(klass, rb_cObject);
|
|
97
|
+
|
|
98
|
+
KLASS_OF(chain_start) = rb_cModule;
|
|
99
|
+
RBASIC(chain_start)->flags = T_MODULE;
|
|
100
|
+
|
|
101
|
+
jcur = chain_start;
|
|
102
|
+
for(rclass = RCLASS_SUPER(klass); rclass != rb_cObject;
|
|
103
|
+
rclass = RCLASS_SUPER(rclass)) {
|
|
104
|
+
|
|
105
|
+
RCLASS_SUPER(jcur) = j_class_new(rclass, rb_cObject);
|
|
106
|
+
jcur = RCLASS_SUPER(jcur);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
RCLASS_SUPER(jcur) = (VALUE)NULL;
|
|
110
|
+
|
|
111
|
+
return chain_start;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
VALUE
|
|
115
|
+
rb_reset_tbls(VALUE self)
|
|
116
|
+
{
|
|
117
|
+
RCLASS_IV_TBL(self) = (struct st_table *) 0;
|
|
118
|
+
RCLASS_M_TBL(self) = (struct st_table *) st_init_numtable();
|
|
119
|
+
return Qnil;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* cannot simply forward to gen_include as need to invoke 'extended' hook */
|
|
123
|
+
VALUE
|
|
124
|
+
rb_gen_extend(int argc, VALUE * argv, VALUE self)
|
|
125
|
+
{
|
|
126
|
+
int i;
|
|
127
|
+
|
|
128
|
+
if (argc == 0) rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
|
|
129
|
+
|
|
130
|
+
rb_singleton_class(self);
|
|
131
|
+
|
|
132
|
+
for(i = 0; i < argc; i++) {
|
|
133
|
+
VALUE mod = rb_to_module(argv[i]);
|
|
134
|
+
rb_funcall(mod, rb_intern("extend_object"), 1, self);
|
|
135
|
+
rb_funcall(mod, rb_intern("extended"), 1, self);
|
|
136
|
+
|
|
137
|
+
/* only redirect if argv[i] is not a module */
|
|
138
|
+
if(argv[i] != mod) rb_reset_tbls(mod);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return self;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
VALUE
|
|
145
|
+
rb_gen_include(int argc, VALUE * argv, VALUE self)
|
|
146
|
+
{
|
|
147
|
+
int i;
|
|
148
|
+
|
|
149
|
+
if (argc == 0) rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
|
|
150
|
+
|
|
151
|
+
for(i = 0; i < argc; i++) {
|
|
152
|
+
VALUE mod = rb_to_module(argv[i]);
|
|
153
|
+
rb_funcall(mod, rb_intern("append_features"), 1, self);
|
|
154
|
+
rb_funcall(mod, rb_intern("included"), 1, self);
|
|
155
|
+
|
|
156
|
+
if(argv[i] != mod) rb_reset_tbls(mod);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return self;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
void Init_object2module()
|
|
164
|
+
{
|
|
165
|
+
|
|
166
|
+
rb_define_method(rb_cObject, "to_module", rb_to_module , 0);
|
|
167
|
+
rb_define_method(rb_cObject, "gen_extend", rb_gen_extend, -1);
|
|
168
|
+
rb_define_method(rb_cModule, "gen_include", rb_gen_include, -1);
|
|
169
|
+
rb_define_method(rb_cModule, "reset_tbls", rb_reset_tbls, 0);
|
|
170
|
+
}
|
|
171
|
+
|