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