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