texplay 0.2.710 → 0.2.722

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ 12/03/10
2
+ version 0.2.721
3
+ * fixed bug in alpha_blend (now blends alpha channels too)
4
+
1
5
  6/12/09
2
6
  version 0.2.710
3
7
  * fixed bug in line drawing code (wasn't drawing final pixel)
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
- ext.config_script = 'extconf.rb'
41
- ext.cross_compile = true
42
- ext.cross_platform = 'i386-mswin32'
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
- # file "#{SELENE}/lib/texplay-contrib.rb" => "texplay-contrib.rb" do |t|
57
- # cp t.prerequisites.first, t.name, :verbose => true
58
- # end
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
- # file "#{SELENE}/lib/ctexplay.#{$dlext}" => "ctexplay.#{$dlext}" do |t|
61
- # cp t.prerequisites.first, t.name, :verbose => true
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, 1, 1, 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
 
@@ -1,5 +1,5 @@
1
1
  require 'common'
2
- require 'devil/gosu'
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, 350, Dragon, :order => 13, :line_length => 4)
52
- @img.save("dragon.jpg")
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
@@ -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
- :color_control => proc { |c1, c2, x, y|
14
- factor = 1 - (y - 25) / @gosu.height.to_f
15
- c2[0] *= factor
16
- c2[1] *= factor
17
- c2[2] *= factor
18
- c2
19
- }
20
-
21
- @img.splice @gosu, 50,20, :chroma_key => :alpha
22
- end
23
-
24
- def draw
25
- @img.draw 100, 50,1
26
- end
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
File without changes
File without changes
@@ -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
- action_struct cur;
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 x, y, arity;
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(&current_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(&current_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