texplay 0.2.710 → 0.2.722
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 +4 -0
- data/README.markdown +0 -0
- data/Rakefile +31 -25
- data/examples/example_color_transform.rb +3 -3
- data/examples/example_lsystem.rb +3 -3
- data/examples/example_splice.rb +27 -33
- data/examples/example_weird.rb +29 -0
- data/examples/media/bird.png +0 -0
- data/examples/media/gob.png +0 -0
- data/examples/media/green.png +0 -0
- data/examples/media/maria.png +0 -0
- data/examples/media/rose.bmp +0 -0
- data/ext/texplay/actions.c +13 -419
- data/ext/texplay/bindings.c +1 -0
- data/ext/texplay/extconf.rb +3 -5
- data/ext/texplay/gen_eval.c +0 -0
- data/ext/texplay/gen_eval.h +0 -0
- data/ext/texplay/graphics_utils.c +660 -0
- data/ext/texplay/graphics_utils.h +23 -0
- data/ext/texplay/utils.c +35 -258
- data/ext/texplay/utils.h +2 -2
- data/lib/texplay-contrib.rb +0 -0
- data/lib/texplay.rb +0 -0
- data/lib/texplay/version.rb +1 -1
- metadata +58 -44
- data/examples/example_blur.rb +0 -59
- data/examples/example_fill_test.rb +0 -106
- data/examples/example_modify.rb +0 -40
- data/examples/example_sine.rb +0 -55
- data/examples/media/platform.png +0 -0
data/CHANGELOG
CHANGED
data/README.markdown
CHANGED
File without changes
|
data/Rakefile
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
require 'rake/clean'
|
2
3
|
require 'rake/gempackagetask'
|
3
4
|
require 'rake/extensiontask'
|
@@ -27,36 +28,41 @@ specification = Gem::Specification.new do |s|
|
|
27
28
|
s.extensions = ["ext/texplay/extconf.rb"]
|
28
29
|
s.files = ["Rakefile", "README.markdown", "CHANGELOG",
|
29
30
|
"lib/texplay.rb", "lib/texplay-contrib.rb", "lib/texplay/version.rb"] +
|
30
|
-
FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "examples/*.rb",
|
31
|
-
"examples/media/*"].to_a
|
32
|
-
end
|
33
|
-
|
34
|
-
Rake::GemPackageTask.new(specification) do |package|
|
35
|
-
package.need_zip = false
|
36
|
-
package.need_tar = false
|
31
|
+
FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "examples/*.rb", "examples/media/*"].to_a
|
37
32
|
end
|
38
33
|
|
39
34
|
Rake::ExtensionTask.new('texplay', specification) do |ext|
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
# ext.config_script = 'extconf.rb'
|
36
|
+
# ext.cross_compile = true
|
37
|
+
#ext.cross_platform = 'i386-mswin32'
|
38
|
+
# ext.platform = 'i386-mswin32'
|
43
39
|
end
|
44
40
|
|
45
|
-
# SELENE = '/home/john/ruby/projects/selene'
|
46
|
-
# desc "update selene's version of texplay"
|
47
|
-
# task :selene => ["#{SELENE}/lib/texplay.rb", "#{SELENE}/lib/texplay-contrib.rb",
|
48
|
-
# "#{SELENE}/lib/ctexplay.so"] do
|
49
|
-
# puts "...done!"
|
50
|
-
# end
|
51
|
-
|
52
|
-
# file "#{SELENE}/lib/texplay.rb" => "texplay.rb" do |t|
|
53
|
-
# cp t.prerequisites.first, t.name, :verbose => true
|
54
|
-
# end
|
55
41
|
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
42
|
+
# comment this when want to build normal gems.
|
43
|
+
# only have this code uncommented when building mswin32 and mingw32
|
44
|
+
# binary gems
|
45
|
+
# specification = Gem::Specification.new do |s|
|
46
|
+
# s.name = "texplay"
|
47
|
+
# s.summary = "TexPlay is a light-weight image manipulation framework for Ruby and Gosu"
|
48
|
+
# s.version = TexPlay::VERSION
|
49
|
+
# s.date = Time.now.strftime '%Y-%m-%d'
|
50
|
+
# s.author = "John Mair (banisterfiend)"
|
51
|
+
# s.email = 'jrmair@gmail.com'
|
52
|
+
# s.description = s.summary
|
53
|
+
# s.require_path = 'lib'
|
54
|
+
# s.add_dependency("gosu",">=0.7.14")
|
55
|
+
# s.platform = 'i386-mingw32'
|
56
|
+
# s.homepage = "http://banisterfiend.wordpress.com/2008/08/23/texplay-an-image-manipulation-tool-for-ruby-and-gosu/"
|
57
|
+
# s.has_rdoc = false
|
59
58
|
|
60
|
-
#
|
61
|
-
#
|
59
|
+
# s.files = ["Rakefile", "README.markdown", "CHANGELOG",
|
60
|
+
# "lib/texplay.rb", "lib/texplay-contrib.rb", "lib/texplay/version.rb", "lib/1.8/texplay.so",
|
61
|
+
# "lib/1.9/texplay.so"] +
|
62
|
+
# FileList["examples/*.rb", "examples/media/*"].to_a
|
62
63
|
# end
|
64
|
+
|
65
|
+
Rake::GemPackageTask.new(specification) do |package|
|
66
|
+
package.need_zip = false
|
67
|
+
package.need_tar = false
|
68
|
+
end
|
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'common'
|
3
3
|
require 'gosu'
|
4
4
|
require 'texplay'
|
5
|
-
require 'devil/gosu'
|
5
|
+
#require 'devil/gosu'
|
6
6
|
|
7
7
|
class W < Gosu::Window
|
8
8
|
def initialize
|
@@ -34,7 +34,7 @@ class W < Gosu::Window
|
|
34
34
|
@copy.splice @img, 0, 0, :crop => [@x - @rad, @y - @rad, @x + @rad, @y + @rad]
|
35
35
|
@img.
|
36
36
|
circle @x, @y, @rad, :fill => true,
|
37
|
-
:color_control => { :mult => [1,
|
37
|
+
:color_control => { :mult => [1.0, 0.5, 0.5, 1] }
|
38
38
|
|
39
39
|
# circle @x2, @y2, @rad, :fill => true,
|
40
40
|
# :color_control => { :mult => [0.3, 0.9, 0.3, 1] }
|
@@ -47,7 +47,7 @@ class W < Gosu::Window
|
|
47
47
|
if button_down?(Gosu::KbEscape)
|
48
48
|
IL.Enable(IL::ORIGIN_SET)
|
49
49
|
IL.OriginFunc(IL::ORIGIN_UPPER_LEFT)
|
50
|
-
screenshot.crop(0,0, 500, 500).save("screenshot.jpg").free
|
50
|
+
# screenshot.crop(0,0, 500, 500).save("screenshot.jpg").free
|
51
51
|
exit
|
52
52
|
end
|
53
53
|
|
data/examples/example_lsystem.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'common'
|
2
|
-
require '
|
2
|
+
require 'gosu'
|
3
3
|
|
4
4
|
Dragon = TexPlay::LSystem.new do
|
5
5
|
rule "F" => "F"
|
@@ -48,8 +48,8 @@ class W < Gosu::Window
|
|
48
48
|
super(1024, 768, false, 20)
|
49
49
|
@img = TexPlay::create_blank_image(self, 500, 500)
|
50
50
|
@img.set_options :color => :rand
|
51
|
-
@img.lsystem(400,
|
52
|
-
|
51
|
+
@img.lsystem(400, 150, Koch, :order => 8, :line_length => 6)
|
52
|
+
#@img.save("dragon.jpg")
|
53
53
|
end
|
54
54
|
|
55
55
|
def draw
|
data/examples/example_splice.rb
CHANGED
@@ -1,33 +1,27 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'common'
|
3
|
-
require 'texplay'
|
4
|
-
|
5
|
-
|
6
|
-
class W < Gosu::Window
|
7
|
-
def initialize
|
8
|
-
super(1024, 768, false, 20)
|
9
|
-
@img = Gosu::Image.new(self, "#{Common::MEDIA}/texplay.png")
|
10
|
-
@gosu = Gosu::Image.new(self, "#{Common::MEDIA}/gosu.png")
|
11
|
-
|
12
|
-
@img.splice @gosu, 140,20,
|
13
|
-
:
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
w = W.new
|
32
|
-
w.show
|
33
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'common'
|
3
|
+
require 'texplay'
|
4
|
+
|
5
|
+
|
6
|
+
class W < Gosu::Window
|
7
|
+
def initialize
|
8
|
+
super(1024, 768, false, 20)
|
9
|
+
@img = Gosu::Image.new(self, "#{Common::MEDIA}/texplay.png")
|
10
|
+
@gosu = Gosu::Image.new(self, "#{Common::MEDIA}/gosu.png")
|
11
|
+
|
12
|
+
@img.splice @gosu, 140,20, :alpha_blend => true
|
13
|
+
@img.rect 140,20, 160, 180, :color => [1,1,1,0.5], :alpha_blend => true, :fill => true
|
14
|
+
|
15
|
+
@img.splice @gosu, 50,20, :chroma_key => :alpha
|
16
|
+
end
|
17
|
+
|
18
|
+
def draw
|
19
|
+
@img.draw 100, 50,1
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
w = W.new
|
26
|
+
w.show
|
27
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'common'
|
3
|
+
require 'texplay'
|
4
|
+
|
5
|
+
|
6
|
+
class W < Gosu::Window
|
7
|
+
def initialize
|
8
|
+
super(1024, 768, false, 20)
|
9
|
+
@img = Gosu::Image.new(self, "#{Common::MEDIA}/bird.png")
|
10
|
+
@green = Gosu::Image.new(self, "#{Common::MEDIA}/gob.png")
|
11
|
+
### @img = Gosu::Image.new(self, "gob.png")
|
12
|
+
#@img = TexPlay.create_image(self, 500, 500).fill(0,0, :color => :red)
|
13
|
+
|
14
|
+
@img.splice @green, 0, 0, :alpha_blend => true
|
15
|
+
puts @img.get_pixel 15, 15
|
16
|
+
# @img.rect 0, 0, @img.width, @img.height, :texture => @gob, :fill => true, :alpha_blend => true
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def draw
|
21
|
+
@img.draw 100, 50,1
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
w = W.new
|
28
|
+
w.show
|
29
|
+
|
Binary file
|
Binary file
|
Binary file
|
data/examples/media/maria.png
CHANGED
File without changes
|
data/examples/media/rose.bmp
CHANGED
File without changes
|
data/ext/texplay/actions.c
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#include "texplay.h"
|
2
2
|
#include "utils.h"
|
3
|
+
#include "graphics_utils.h"
|
3
4
|
#include "actions.h"
|
4
5
|
#include <assert.h>
|
5
6
|
#include <math.h>
|
@@ -10,24 +11,6 @@
|
|
10
11
|
#endif
|
11
12
|
|
12
13
|
|
13
|
-
/* small helper functions */
|
14
|
-
static void process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode, bool primary);
|
15
|
-
static void update_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax);
|
16
|
-
static void update_lazy_bounds(action_struct * cur, texture_info * tex);
|
17
|
-
static void set_local_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax, texture_info * tex);
|
18
|
-
|
19
|
-
static void draw_prologue(action_struct * cur, texture_info * tex,
|
20
|
-
int xmin, int ymin, int xmax, int ymax, VALUE * hash_arg, sync sync_mode,
|
21
|
-
bool primary, action_struct ** payload_ptr);
|
22
|
-
static void draw_epilogue(action_struct * cur, texture_info * tex, bool primary);
|
23
|
-
|
24
|
-
static void prepare_fill_texture(action_struct * cur);
|
25
|
-
static void prepare_color_control(action_struct * cur);
|
26
|
-
static void set_pixel_color_with_style(action_struct * payload, texture_info * tex,
|
27
|
-
int x, int y);
|
28
|
-
/* end helpers */
|
29
|
-
|
30
|
-
|
31
14
|
/** line_do_action, bresenham's algorithm **/
|
32
15
|
void
|
33
16
|
line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_arg,
|
@@ -151,14 +134,14 @@ void
|
|
151
134
|
polyline_do_action(VALUE points, texture_info * tex, VALUE hash_arg,
|
152
135
|
sync sync_mode, bool primary, action_struct * payload)
|
153
136
|
{
|
154
|
-
|
137
|
+
|
155
138
|
int x1, y1, x2, y2;
|
156
139
|
int format;
|
157
140
|
int num_point_pairs;
|
158
141
|
int k;
|
142
|
+
int draw_offset_y, draw_offset_x;
|
143
|
+
action_struct cur;
|
159
144
|
VALUE offset_val;
|
160
|
-
int draw_offset_x;
|
161
|
-
int draw_offset_y;
|
162
145
|
bool closed = false;
|
163
146
|
|
164
147
|
draw_prologue(&cur, tex, XMAX_OOB, YMAX_OOB, XMIN_OOB, YMIN_OOB, &hash_arg, sync_mode, primary, &payload);
|
@@ -230,7 +213,6 @@ ngon_do_action(int x, int y, int r, int num_sides, texture_info * tex, VALUE has
|
|
230
213
|
{
|
231
214
|
action_struct cur;
|
232
215
|
int x1, y1, x2, y2, x0, y0;
|
233
|
-
int n;
|
234
216
|
int thickness;
|
235
217
|
float angle = 0;
|
236
218
|
|
@@ -258,7 +240,7 @@ ngon_do_action(int x, int y, int r, int num_sides, texture_info * tex, VALUE has
|
|
258
240
|
x0 = x1 = x + r * cos(angle);
|
259
241
|
y0 = y1 = y + r * sin(angle);
|
260
242
|
|
261
|
-
for(n = 0; n < num_sides; n++) {
|
243
|
+
for(int n = 0; n < num_sides; n++) {
|
262
244
|
x2 = x + r * cos((2 * PI / num_sides) * n + angle);
|
263
245
|
y2 = y + r * sin((2 * PI / num_sides) * n + angle);
|
264
246
|
|
@@ -316,10 +298,9 @@ rect_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_ar
|
|
316
298
|
line_do_action(x2, y1, x2, y2, tex, hash_arg, no_sync, false, payload);
|
317
299
|
}
|
318
300
|
else {
|
319
|
-
int y;
|
320
301
|
if(y1 > y2) SWAP(y1, y2);
|
321
302
|
|
322
|
-
for(y = y1; y <= y2; y++)
|
303
|
+
for(int y = y1; y <= y2; y++)
|
323
304
|
line_do_action(x1, y, x2, y, tex, hash_arg, no_sync, false, payload);
|
324
305
|
}
|
325
306
|
|
@@ -702,12 +683,11 @@ static void
|
|
702
683
|
bezier_point(VALUE points, float u, float * x, float * y, int n, int format,
|
703
684
|
int draw_offset_x, int draw_offset_y)
|
704
685
|
{
|
705
|
-
int k;
|
706
686
|
int xy_index;
|
707
687
|
double sumx = 0, sumy = 0;
|
708
688
|
|
709
689
|
|
710
|
-
for(k = 0; k < n; k++) {
|
690
|
+
for(int k = 0; k < n; k++) {
|
711
691
|
switch(format) {
|
712
692
|
case POINT_FORMAT:
|
713
693
|
|
@@ -843,15 +823,15 @@ each_pixel_do_action(int x1, int y1, int x2, int y2, VALUE proc, texture_info *
|
|
843
823
|
sync sync_mode, bool primary, action_struct * payload)
|
844
824
|
{
|
845
825
|
action_struct cur;
|
846
|
-
int
|
826
|
+
int arity;
|
847
827
|
VALUE rb_pix = rb_ary_new2(4);
|
848
828
|
|
849
829
|
draw_prologue(&cur, tex, x1, y1, x2, y2, &hash_arg, sync_mode, primary, &payload);
|
850
830
|
|
851
831
|
arity = FIX2INT(rb_funcall(proc, rb_intern("arity"), 0));
|
852
832
|
|
853
|
-
for(y = y1; y < y2 + 1; y++)
|
854
|
-
for(x = x1; x < x2 + 1; x++) {
|
833
|
+
for(int y = y1; y < y2 + 1; y++)
|
834
|
+
for(int x = x1; x < x2 + 1; x++) {
|
855
835
|
rgba pix = get_pixel_color(tex, x, y);
|
856
836
|
|
857
837
|
set_color_array(rb_pix, &pix);
|
@@ -889,11 +869,10 @@ splice_do_action(int x0, int y0, int cx1, int cy1, int cx2, int cy2, texture_inf
|
|
889
869
|
int xbound;
|
890
870
|
int ybound;
|
891
871
|
rgba chromakey;
|
892
|
-
int x, y;
|
893
872
|
float * image_buf = NULL;
|
894
873
|
bool inverse_chroma = false;
|
895
|
-
bool has_chroma = false;
|
896
874
|
bool same_image = false;
|
875
|
+
bool has_chroma = false;
|
897
876
|
|
898
877
|
constrain_boundaries(&cx1, &cy1, &cx2, &cy2, splice_tex->width, splice_tex->height);
|
899
878
|
xbound = cx2 - cx1 + 1;
|
@@ -923,8 +902,8 @@ splice_do_action(int x0, int y0, int cx1, int cy1, int cx2, int cy2, texture_inf
|
|
923
902
|
if(same_image)
|
924
903
|
image_buf = get_image_chunk(splice_tex, cx1, cy1, cx2, cy2);
|
925
904
|
|
926
|
-
for(y = 0; y < ybound; y++)
|
927
|
-
for(x = 0; x < xbound; x++) {
|
905
|
+
for(int y = 0; y < ybound; y++)
|
906
|
+
for(int x = 0; x < xbound; x++) {
|
928
907
|
|
929
908
|
if(!same_image)
|
930
909
|
payload->color = get_pixel_color(splice_tex, cx1 + x, cy1 + y);
|
@@ -950,390 +929,5 @@ splice_do_action(int x0, int y0, int cx1, int cy1, int cx2, int cy2, texture_inf
|
|
950
929
|
}
|
951
930
|
/** end splice **/
|
952
931
|
|
953
|
-
static void
|
954
|
-
initialize_action_struct(action_struct * cur, VALUE hash_arg, sync sync_mode)
|
955
|
-
{
|
956
|
-
/* initialize action-struct to default values */
|
957
|
-
cur->sync_mode = sync_mode;
|
958
|
-
cur->hash_arg = hash_arg;
|
959
|
-
|
960
|
-
cur->color = convert_image_local_color_to_rgba(cur->tex->image);
|
961
|
-
cur->pen.has_color_control_proc = false;
|
962
|
-
cur->pen.has_color_control_transform = false;
|
963
|
-
cur->pen.has_source_texture = false;
|
964
|
-
cur->pen.alpha_blend = false;
|
965
|
-
|
966
|
-
/* set static color control transformations to defaults */
|
967
|
-
cur->pen.color_mult.red = 1.0;
|
968
|
-
cur->pen.color_mult.green = 1.0;
|
969
|
-
cur->pen.color_mult.blue = 1.0;
|
970
|
-
cur->pen.color_mult.alpha = 1.0;
|
971
|
-
|
972
|
-
cur->pen.color_add.red = 0.0;
|
973
|
-
cur->pen.color_add.green = 0.0;
|
974
|
-
cur->pen.color_add.blue = 0.0;
|
975
|
-
cur->pen.color_add.alpha = 0.0;
|
976
|
-
}
|
977
|
-
|
978
|
-
/* TODO: fix this function below, it's too ugly and bulky and weird **/
|
979
|
-
static void
|
980
|
-
process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode, bool primary)
|
981
|
-
{
|
982
|
-
|
983
|
-
VALUE user_defaults;
|
984
|
-
VALUE hash_blend;
|
985
|
-
|
986
|
-
|
987
|
-
/* if a hash doesn't exist then create one */
|
988
|
-
if(!is_a_hash(*hash_arg))
|
989
|
-
*hash_arg = rb_hash_new();
|
990
|
-
|
991
|
-
/* init the action to default values */
|
992
|
-
initialize_action_struct(cur, *hash_arg, sync_mode);
|
993
|
-
|
994
|
-
/* get the user default options & merge with given options */
|
995
|
-
user_defaults = get_image_local(cur->tex->image, USER_DEFAULTS);
|
996
|
-
hash_blend = rb_funcall(user_defaults, rb_intern("merge"), 1, *hash_arg);
|
997
|
-
rb_funcall(*hash_arg, rb_intern("merge!"), 1, hash_blend);
|
998
|
-
|
999
|
-
if(has_optional_hash_arg(*hash_arg, "color")) {
|
1000
|
-
VALUE c = get_from_hash(*hash_arg, "color");
|
1001
|
-
cur->color = convert_rb_color_to_rgba(c);
|
1002
|
-
if(c == string2sym("random")) {
|
1003
|
-
set_hash_value(*hash_arg, "color", convert_rgba_to_rb_color(&cur->color));
|
1004
|
-
}
|
1005
|
-
}
|
1006
|
-
|
1007
|
-
/* shadows */
|
1008
|
-
if(RTEST(get_from_hash(*hash_arg, "shadow"))) {
|
1009
|
-
cur->pen.color_mult.red = 0.66;
|
1010
|
-
cur->pen.color_mult.green = 0.66;
|
1011
|
-
cur->pen.color_mult.blue = 0.66;
|
1012
|
-
cur->pen.color_mult.alpha = 1;
|
1013
|
-
|
1014
|
-
cur->pen.has_color_control_transform = true;
|
1015
|
-
}
|
1016
|
-
|
1017
|
-
/* sync mode */
|
1018
|
-
if(has_optional_hash_arg(*hash_arg, "sync_mode")) {
|
1019
|
-
VALUE user_sync_mode = get_from_hash(*hash_arg, "sync_mode");
|
1020
|
-
|
1021
|
-
Check_Type(user_sync_mode, T_SYMBOL);
|
1022
|
-
|
1023
|
-
if(user_sync_mode == string2sym("lazy_sync"))
|
1024
|
-
cur->sync_mode = lazy_sync;
|
1025
|
-
else if(user_sync_mode == string2sym("eager_sync"))
|
1026
|
-
cur->sync_mode = eager_sync;
|
1027
|
-
else if(user_sync_mode == string2sym("no_sync"))
|
1028
|
-
cur->sync_mode = no_sync;
|
1029
|
-
else
|
1030
|
-
rb_raise(rb_eArgError, "unrecognized sync mode: %s\n. Allowable modes are "
|
1031
|
-
":lazy_sync, :eager_sync, :no_sync.",
|
1032
|
-
sym2string(user_sync_mode));
|
1033
|
-
|
1034
|
-
delete_from_hash(*hash_arg, "sync_mode");
|
1035
|
-
|
1036
|
-
}
|
1037
|
-
|
1038
|
-
/* process the color_control block or transform (if there is one) */
|
1039
|
-
prepare_color_control(cur);
|
1040
|
-
|
1041
|
-
/* process the filling texture (if there is one) */
|
1042
|
-
prepare_fill_texture(cur);
|
1043
|
-
|
1044
|
-
/* does the user want to blend alpha values ? */
|
1045
|
-
if(get_from_hash(*hash_arg, "alpha_blend") == Qtrue)
|
1046
|
-
cur->pen.alpha_blend = true;
|
1047
|
-
|
1048
|
-
}
|
1049
|
-
|
1050
|
-
static void
|
1051
|
-
update_lazy_bounds(action_struct * cur, texture_info * tex)
|
1052
|
-
{
|
1053
|
-
|
1054
|
-
/* only update global bounds if we're doing a lazy_sync */
|
1055
|
-
if(cur->sync_mode == lazy_sync) {
|
1056
|
-
int xmin, ymin, xmax, ymax;
|
1057
|
-
VALUE lazy_bounds;
|
1058
|
-
|
1059
|
-
lazy_bounds = get_image_local(tex->image, LAZY_BOUNDS);
|
1060
|
-
|
1061
|
-
xmin = INT2FIX(MIN(cur->xmin, FIX2INT(get_from_array(lazy_bounds, 0))));
|
1062
|
-
ymin = INT2FIX(MIN(cur->ymin, FIX2INT(get_from_array(lazy_bounds, 1))));
|
1063
|
-
xmax = INT2FIX(MAX(cur->xmax, FIX2INT(get_from_array(lazy_bounds, 2))));
|
1064
|
-
ymax = INT2FIX(MAX(cur->ymax, FIX2INT(get_from_array(lazy_bounds, 3))));
|
1065
|
-
|
1066
|
-
set_array_value(lazy_bounds, 0, xmin);
|
1067
|
-
set_array_value(lazy_bounds, 1, ymin);
|
1068
|
-
set_array_value(lazy_bounds, 2, xmax);
|
1069
|
-
set_array_value(lazy_bounds, 3, ymax);
|
1070
|
-
}
|
1071
|
-
}
|
1072
|
-
|
1073
|
-
static void
|
1074
|
-
update_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax)
|
1075
|
-
{
|
1076
|
-
if(xmin > xmax) SWAP(xmin, xmax);
|
1077
|
-
if(ymin > ymax) SWAP(ymin, ymax);
|
1078
|
-
|
1079
|
-
cur->xmin = MIN(cur->xmin, xmin);
|
1080
|
-
cur->ymin = MIN(cur->ymin, ymin);
|
1081
|
-
cur->xmax = MAX(cur->xmax, xmax);
|
1082
|
-
cur->ymax = MAX(cur->ymax, ymax);
|
1083
|
-
}
|
1084
|
-
|
1085
|
-
static void
|
1086
|
-
set_local_bounds(action_struct * cur, int xmin, int ymin, int xmax, int ymax, texture_info * tex)
|
1087
|
-
{
|
1088
|
-
if(cur->sync_mode == no_sync)
|
1089
|
-
return;
|
1090
|
-
|
1091
|
-
/* local bounds used by both eager_sync and lazy_sync: */
|
1092
|
-
|
1093
|
-
/* eager sync: to demarcate precise area to sync to opengl */
|
1094
|
-
/* lazy sync: to update global bounds */
|
1095
|
-
cur->xmin = xmin;
|
1096
|
-
cur->ymin = ymin;
|
1097
|
-
cur->xmax = xmax;
|
1098
|
-
cur->ymax = ymax;
|
1099
|
-
}
|
1100
|
-
|
1101
|
-
static void
|
1102
|
-
draw_prologue(action_struct * cur, texture_info * tex, int xmin, int ymin, int xmax, int ymax,
|
1103
|
-
VALUE * hash_arg, sync sync_mode, bool primary, action_struct ** payload_ptr)
|
1104
|
-
{
|
1105
|
-
if(!primary) return;
|
1106
|
-
|
1107
|
-
/* set the payload pointer */
|
1108
|
-
*payload_ptr = cur;
|
1109
|
-
|
1110
|
-
/* not too happy about having this here, look at texplay.h for why */
|
1111
|
-
cur->tex = tex;
|
1112
|
-
|
1113
|
-
process_common_hash_args(cur, hash_arg, sync_mode, primary);
|
1114
|
-
|
1115
|
-
set_local_bounds(cur, xmin, ymin, xmax, ymax, tex);
|
1116
|
-
}
|
1117
|
-
|
1118
|
-
void
|
1119
|
-
draw_epilogue(action_struct * cur, texture_info * tex, bool primary)
|
1120
|
-
{
|
1121
|
-
/* only primary actions get sync'd */
|
1122
|
-
if(!primary) return;
|
1123
|
-
|
1124
|
-
switch(cur->sync_mode) {
|
1125
|
-
|
1126
|
-
/* do not sync */
|
1127
|
-
case no_sync:
|
1128
|
-
return;
|
1129
|
-
break;
|
1130
|
-
|
1131
|
-
/* sync immediately */
|
1132
|
-
case eager_sync:
|
1133
|
-
create_subtexture_and_sync_to_gl(IMAGE_BOUNDS(cur), tex);
|
1134
|
-
break;
|
1135
|
-
|
1136
|
-
/* sync later (at end of paint block?) */
|
1137
|
-
case lazy_sync:
|
1138
|
-
update_lazy_bounds(cur, tex);
|
1139
|
-
break;
|
1140
|
-
|
1141
|
-
default:
|
1142
|
-
rb_raise(rb_eRuntimeError,
|
1143
|
-
"sync_mode may only be: lazy_sync, eager_sync, no_sync. got %d\n", cur->sync_mode);
|
1144
|
-
}
|
1145
|
-
}
|
1146
|
-
|
1147
|
-
/* set action color to return value of color_control proc */
|
1148
|
-
static void
|
1149
|
-
prepare_color_control(action_struct * cur)
|
1150
|
-
{
|
1151
|
-
|
1152
|
-
if(is_a_hash(cur->hash_arg)) {
|
1153
|
-
VALUE try_val = get_from_hash(cur->hash_arg, "color_control");
|
1154
|
-
|
1155
|
-
if(rb_respond_to(try_val, rb_intern("call"))) {
|
1156
|
-
cur->pen.color_control_proc = try_val;
|
1157
|
-
cur->pen.color_control_arity = FIX2INT(rb_funcall(try_val, rb_intern("arity"), 0));
|
1158
|
-
cur->pen.has_color_control_proc = true;
|
1159
|
-
}
|
1160
|
-
else if(is_a_hash(try_val)) {
|
1161
|
-
VALUE try_add = get_from_hash(try_val, "add");
|
1162
|
-
VALUE try_mult = get_from_hash(try_val, "mult");
|
1163
|
-
|
1164
|
-
if(is_an_array(try_add)) {
|
1165
|
-
if(RARRAY_LEN(try_add) < 4)
|
1166
|
-
rb_raise(rb_eArgError, ":color_control transform :add needs 4 parameters");
|
1167
|
-
|
1168
|
-
cur->pen.color_add.red = NUM2DBL(get_from_array(try_add, 0));
|
1169
|
-
cur->pen.color_add.green = NUM2DBL(get_from_array(try_add, 1));
|
1170
|
-
cur->pen.color_add.blue = NUM2DBL(get_from_array(try_add, 2));
|
1171
|
-
cur->pen.color_add.alpha = NUM2DBL(get_from_array(try_add, 3));
|
1172
|
-
|
1173
|
-
cur->pen.has_color_control_transform = true;
|
1174
|
-
}
|
1175
|
-
if(is_an_array(try_mult)) {
|
1176
|
-
if(RARRAY_LEN(try_mult) < 4)
|
1177
|
-
rb_raise(rb_eArgError, ":color_control transform :mult needs 4 parameters");
|
1178
|
-
|
1179
|
-
cur->pen.color_mult.red = NUM2DBL(get_from_array(try_mult, 0));
|
1180
|
-
cur->pen.color_mult.green = NUM2DBL(get_from_array(try_mult, 1));
|
1181
|
-
cur->pen.color_mult.blue = NUM2DBL(get_from_array(try_mult, 2));
|
1182
|
-
cur->pen.color_mult.alpha = NUM2DBL(get_from_array(try_mult, 3));
|
1183
|
-
|
1184
|
-
cur->pen.has_color_control_transform = true;
|
1185
|
-
}
|
1186
|
-
|
1187
|
-
}
|
1188
|
-
}
|
1189
|
-
}
|
1190
|
-
|
1191
|
-
static rgba
|
1192
|
-
exec_color_control_proc(action_struct * cur, texture_info * tex, int x, int y, rgba blended_pixel)
|
1193
|
-
{
|
1194
|
-
int arity = cur->pen.color_control_arity;
|
1195
|
-
VALUE proc = cur->pen.color_control_proc;
|
1196
|
-
rgba old_color = get_pixel_color(tex, x, y);
|
1197
|
-
rgba current_color = blended_pixel;
|
1198
|
-
rgba new_color;
|
1199
|
-
|
1200
|
-
if(!cur->pen.has_color_control_proc)
|
1201
|
-
rb_raise(rb_eRuntimeError, "needs a proc");
|
1202
|
-
|
1203
|
-
switch(arity) {
|
1204
|
-
case -1:
|
1205
|
-
case 0:
|
1206
|
-
new_color = convert_rb_color_to_rgba(rb_funcall(proc, rb_intern("call"), 0));
|
1207
|
-
break;
|
1208
|
-
|
1209
|
-
case 1:
|
1210
|
-
new_color = convert_rb_color_to_rgba(rb_funcall(proc, rb_intern("call"), arity,
|
1211
|
-
convert_rgba_to_rb_color(&old_color)));
|
1212
|
-
break;
|
1213
|
-
|
1214
|
-
case 2:
|
1215
|
-
new_color = convert_rb_color_to_rgba(rb_funcall(proc, rb_intern("call"), arity,
|
1216
|
-
convert_rgba_to_rb_color(&old_color),
|
1217
|
-
convert_rgba_to_rb_color(¤t_color)));
|
1218
|
-
break;
|
1219
|
-
|
1220
|
-
case 3:
|
1221
|
-
new_color = convert_rb_color_to_rgba(rb_funcall(proc, rb_intern("call"), arity,
|
1222
|
-
convert_rgba_to_rb_color(&old_color),
|
1223
|
-
INT2FIX(x), INT2FIX(y)));
|
1224
|
-
break;
|
1225
|
-
case 4:
|
1226
|
-
new_color = convert_rb_color_to_rgba(rb_funcall(proc, rb_intern("call"), arity,
|
1227
|
-
convert_rgba_to_rb_color(&old_color),
|
1228
|
-
convert_rgba_to_rb_color(¤t_color),
|
1229
|
-
INT2FIX(x), INT2FIX(y)));
|
1230
|
-
break;
|
1231
|
-
default:
|
1232
|
-
rb_raise(rb_eArgError, "permissible arities for color_control proc are 1, 2, 3 and 4. Got %d\n",
|
1233
|
-
arity);
|
1234
|
-
}
|
1235
|
-
|
1236
|
-
/* update the action color */
|
1237
|
-
return new_color;
|
1238
|
-
}
|
1239
932
|
|
1240
|
-
static void
|
1241
|
-
prepare_fill_texture(action_struct * payload)
|
1242
|
-
{
|
1243
|
-
if(is_a_hash(payload->hash_arg)) {
|
1244
|
-
VALUE try_image = get_from_hash(payload->hash_arg, "texture");
|
1245
|
-
if(is_gosu_image(try_image)) {
|
1246
|
-
|
1247
|
-
get_texture_info(try_image, &payload->pen.source_tex);
|
1248
|
-
payload->pen.has_source_texture = true;
|
1249
|
-
}
|
1250
|
-
}
|
1251
|
-
}
|
1252
|
-
|
1253
|
-
|
1254
|
-
/* TODO: reimplement using SSE2 */
|
1255
|
-
static rgba
|
1256
|
-
apply_color_control_transform(action_struct * payload, texture_info * tex, int x, int y)
|
1257
|
-
|
1258
|
-
{
|
1259
|
-
rgba transformed_color;
|
1260
|
-
|
1261
|
-
transformed_color = get_pixel_color(tex, x, y);
|
1262
|
-
|
1263
|
-
transformed_color.red += payload->pen.color_add.red;
|
1264
|
-
transformed_color.green += payload->pen.color_add.green;
|
1265
|
-
transformed_color.blue += payload->pen.color_add.blue;
|
1266
|
-
transformed_color.alpha += payload->pen.color_add.alpha;
|
1267
|
-
|
1268
|
-
transformed_color.red *= payload->pen.color_mult.red;
|
1269
|
-
transformed_color.green *= payload->pen.color_mult.green;
|
1270
|
-
transformed_color.blue *= payload->pen.color_mult.blue;
|
1271
|
-
transformed_color.alpha *= payload->pen.color_mult.alpha;
|
1272
|
-
|
1273
|
-
return transformed_color;
|
1274
|
-
}
|
1275
|
-
|
1276
|
-
static rgba
|
1277
|
-
apply_alpha_blend(action_struct * payload, texture_info * tex, int x, int y, rgba blended_pixel)
|
1278
|
-
{
|
1279
|
-
rgba dest_pixel = get_pixel_color(tex, x, y);
|
1280
|
-
rgba finished_pixel;
|
1281
|
-
|
1282
|
-
|
1283
|
-
if(not_a_color(blended_pixel))
|
1284
|
-
return blended_pixel;
|
1285
|
-
|
1286
|
-
/* alpha blending is nothing more than a weighted average of src and dest pixels
|
1287
|
-
based on source alpha value */
|
1288
|
-
/* NB: destination alpha value is ignored */
|
1289
|
-
|
1290
|
-
/** TO DO: rewrite this using sse2 instructions **/
|
1291
|
-
finished_pixel.red = blended_pixel.alpha * blended_pixel.red + (1 - blended_pixel.alpha)
|
1292
|
-
* dest_pixel.red;
|
1293
|
-
|
1294
|
-
finished_pixel.green = blended_pixel.alpha * blended_pixel.green + (1 - blended_pixel.alpha)
|
1295
|
-
* dest_pixel.green;
|
1296
|
-
|
1297
|
-
finished_pixel.blue = blended_pixel.alpha * blended_pixel.blue + (1 - blended_pixel.alpha)
|
1298
|
-
* dest_pixel.blue;
|
1299
|
-
|
1300
|
-
finished_pixel.alpha = blended_pixel.alpha;
|
1301
|
-
|
1302
|
-
|
1303
|
-
return finished_pixel;
|
1304
|
-
}
|
1305
|
-
|
1306
|
-
static void
|
1307
|
-
set_pixel_color_with_style(action_struct * payload, texture_info * tex, int x, int y)
|
1308
|
-
{
|
1309
|
-
|
1310
|
-
rgba blended_pixel;
|
1311
|
-
|
1312
|
-
blended_pixel = payload->color;
|
1313
|
-
|
1314
|
-
/* for color_control transform */
|
1315
|
-
if(payload->pen.has_color_control_transform)
|
1316
|
-
blended_pixel = apply_color_control_transform(payload, tex, x, y);
|
1317
|
-
|
1318
|
-
/* for texture fill */
|
1319
|
-
if(payload->pen.has_source_texture)
|
1320
|
-
blended_pixel = get_pixel_color(&payload->pen.source_tex,
|
1321
|
-
x % payload->pen.source_tex.width,
|
1322
|
-
y % payload->pen.source_tex.height);
|
1323
|
-
|
1324
|
-
/* for color_control block */
|
1325
|
-
if(payload->pen.has_color_control_proc)
|
1326
|
-
blended_pixel = exec_color_control_proc(payload, tex, x, y, blended_pixel);
|
1327
|
-
|
1328
|
-
|
1329
|
-
/* TO DO: do bitwise pixel combinations here */
|
1330
|
-
|
1331
|
-
/* TO DO: refactor into its own helper function
|
1332
|
-
& rewrite using sse2 */
|
1333
|
-
if(payload->pen.alpha_blend)
|
1334
|
-
blended_pixel = apply_alpha_blend(payload, tex, x, y, blended_pixel);
|
1335
|
-
|
1336
|
-
|
1337
|
-
set_pixel_color(&blended_pixel, tex, x, y);
|
1338
|
-
}
|
1339
933
|
|