texplay 0.2.950 → 0.2.960

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ 4/7/10
2
+ version 0.2.960
3
+ * added :transparent pseudo-color
4
+ * added :tolerance option (applies to :trace and :source_select etc
5
+ family)
6
+ * fixed memleak in to_blob
7
+
1
8
  10/6/10
2
9
  version 0.2.950
3
10
  * fixed bug in apply_drawing_mode, wasn't using blended_pixel as source_pixel
data/README.markdown CHANGED
@@ -5,7 +5,7 @@
5
5
  INSTRUCTIONS
6
6
  ============
7
7
 
8
- **TexPlay version 0.2.950**
8
+ **TexPlay version 0.2.960**
9
9
 
10
10
  [Read The Documentation](http://banisterfiend.wordpress.com/2008/08/23/texplay-an-image-manipulation-tool-for-ruby-and-gosu/)
11
11
 
@@ -32,9 +32,9 @@ class W < Gosu::Window
32
32
 
33
33
  @copy2.splice @img, 0, 0, :crop => [@x2 - @rad, @y2 - @rad, @x2 + @rad, @y2 + @rad], :sync_mode => :no_sync
34
34
  @copy.splice @img, 0, 0, :crop => [@x - @rad, @y - @rad, @x + @rad, @y + @rad], :sync_mode => :no_sync
35
- @img.rect @x - @rad, @y - @rad, @x + @rad, @y + @rad, :fill => true, :mode => :overlay, :color => :tyrian
35
+ @img.rect @x - @rad, @y - @rad, @x + @rad, @y + @rad, :fill => true, :mode => :color_dodge, :color => 0xff888888, :alpha_blend => true
36
36
 
37
- @img.rect @x2 - @rad, @y2 - @rad, @x2 + @rad, @y2 + @rad, :fill => true, :mode => :invert, :color => :blue
37
+ @img.rect @x2 - @rad, @y2 - @rad, @x2 + @rad, @y2 + @rad, :fill => true, :mode => :color_dodge, :color => 0xff888888
38
38
 
39
39
  # @img.force_sync [0,0, @img.width, @img.height]
40
40
 
@@ -5,26 +5,26 @@ require 'texplay'
5
5
 
6
6
 
7
7
  class W < Gosu::Window
8
- def initialize
9
- super(500, 500, false, 20)
10
- @img = TexPlay.create_image(self, 500, 500)
11
- @img.rect 100, 100, 200, 300, :color => :red, :fill => true
12
- @img.rect 200, 100, 300, 300, :color => :blue, :fill => true
8
+ def initialize
9
+ super(500, 500, false, 20)
10
+ @img = TexPlay.create_image(self, 500, 500)
11
+ @img.rect 100, 100, 200, 300, :color => :red, :fill => true
12
+ @img.rect 200, 100, 300, 300, :color_control => proc { [0, 0, 1 - (0.5 * rand), 1.0] }, :fill => true
13
13
 
14
14
 
15
- @img.line 0, 0, 500, 500, :dest_ignore => :red
15
+ @img.line 0, 0, 500, 500, :dest_ignore => :red, :dest_select => :blue, :tolerance => 1
16
16
 
17
- @img.circle 200, 100, 50, :fill => true, :dest_select => [:red, :blue], :color => :orange
18
-
19
- end
20
-
21
- def draw
22
- @img.draw 100, 50,1
23
- end
17
+ @img.circle 200, 100, 50, :fill => true, :dest_select => [:red, :blue], :color => :transparent
24
18
 
19
+ end
20
+
21
+ def draw
22
+ @img.draw 100, 50,1
23
+ end
24
+
25
25
  end
26
26
 
27
27
 
28
28
  w = W.new
29
29
  w.show
30
-
30
+
@@ -7,12 +7,14 @@ class W < Gosu::Window
7
7
  def initialize
8
8
  super(500, 500, false, 20)
9
9
  @img = Gosu::Image.new(self, "#{Common::MEDIA}/gob.png")
10
- @sun = Gosu::Image.new(self, "#{Common::MEDIA}/sunset.png")
11
- @img.splice @sun, 0, 0, :mode => :exclusion
10
+ @img.rect 0, 0, @img.width - 1, @img.height - 1
11
+ puts @img.line 1,1, 1, @img.height - 1, :trace => { :while_color => :alpha }
12
+
13
+
12
14
  end
13
15
 
14
16
  def draw
15
- @img.draw 100, 50,1
17
+ @img.draw 50, 50,1
16
18
  end
17
19
  end
18
20
 
@@ -14,16 +14,23 @@
14
14
  /** line_do_action, bresenham's algorithm **/
15
15
  typedef enum { no_mode, until_color, while_color} trace_mode_type;
16
16
 
17
+ /* utility func to manage both kinds of color comparions */
18
+ static bool
19
+ cmp_color_with_or_without_tolerance(rgba c1, rgba c2, action_struct * payload)
20
+ {
21
+ return payload->pen.has_tolerance ? cmp_color_with_tolerance(c1, c2, payload->pen.tolerance) : cmp_color(c1, c2);
22
+ }
23
+
17
24
  static inline bool
18
- is_trace_match(rgba c, rgba trace_color, trace_mode_type trace_mode)
25
+ is_trace_match(action_struct * cur, rgba c, rgba trace_color, trace_mode_type trace_mode)
19
26
  {
20
27
  if(trace_mode == while_color) {
21
- if(!cmp_color(c, trace_color))
22
- return true;
28
+ if(!cmp_color_with_or_without_tolerance(c, trace_color, cur))
29
+ return true;
23
30
  }
24
31
  else if(trace_mode == until_color) {
25
- if(cmp_color(c, trace_color))
26
- return true;
32
+ if(cmp_color_with_or_without_tolerance(c, trace_color, cur))
33
+ return true;
27
34
  }
28
35
 
29
36
  return false;
@@ -98,7 +105,7 @@ line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_ar
98
105
  else {
99
106
  rgba c = get_pixel_color(tex, x, y);
100
107
 
101
- if (is_trace_match(c, trace_color, trace_mode))
108
+ if (is_trace_match(payload, c, trace_color, trace_mode))
102
109
  return (trace_match) { x, y, c };
103
110
  }
104
111
  }
@@ -126,7 +133,7 @@ line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_ar
126
133
  else {
127
134
  rgba c = get_pixel_color(tex, x, y);
128
135
 
129
- if (is_trace_match(c, trace_color, trace_mode))
136
+ if (is_trace_match(payload, c, trace_color, trace_mode))
130
137
  return (trace_match) { x, y, c };
131
138
  }
132
139
  }
@@ -151,7 +158,7 @@ line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_ar
151
158
  else {
152
159
  rgba c = get_pixel_color(tex, x, y);
153
160
 
154
- if (is_trace_match(c, trace_color, trace_mode))
161
+ if (is_trace_match(payload, c, trace_color, trace_mode))
155
162
  return (trace_match) { x, y, c };
156
163
  }
157
164
  }
@@ -337,10 +337,8 @@ m_get_options(VALUE self)
337
337
  static void
338
338
  get_image_chunk_with_size(char * data, texture_info * tex, char * blob)
339
339
  {
340
- int x, y;
341
-
342
- for(y = 0; y < tex->height; y++)
343
- for(x = 0; x < tex->width; x++) {
340
+ for(int y = 0; y < tex->height; y++)
341
+ for(int x = 0; x < tex->width; x++) {
344
342
  int buf_index = 4 * (x + y * tex->width);
345
343
 
346
344
  int offset = calc_pixel_offset(tex, x, y);
@@ -354,8 +352,6 @@ m_to_blob(VALUE self)
354
352
  {
355
353
  texture_info tex;
356
354
  int sidelength;
357
- VALUE blob;
358
- void * new_array = NULL;
359
355
 
360
356
  ADJUST_SELF(self);
361
357
 
@@ -368,12 +364,12 @@ m_to_blob(VALUE self)
368
364
  glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &sidelength);
369
365
 
370
366
  /* initialize texture data array, mult. by 4 because {rgba} */
371
- new_array = malloc(sidelength * sidelength * 4);
367
+ char new_array[sidelength * sidelength * 4];
372
368
 
373
369
  /* get texture data from video memory */
374
370
  glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE,(void*)(new_array));
375
371
 
376
- blob = rb_str_new(NULL, 4 * tex.width * tex.height);
372
+ VALUE blob = rb_str_new(NULL, 4 * tex.width * tex.height);
377
373
 
378
374
  get_image_chunk_with_size(new_array, &tex, RSTRING_PTR(blob));
379
375
 
@@ -147,6 +147,13 @@ set_pixel_color(rgba * pixel_color, texture_info * tex, int x, int y)
147
147
  tex_data[alpha] = pixel_color->alpha;
148
148
  }
149
149
 
150
+ /* utility func to manage both kinds of color comparions */
151
+ static bool
152
+ cmp_color_with_or_without_tolerance(rgba c1, rgba c2, action_struct * payload)
153
+ {
154
+ return payload->pen.has_tolerance ? cmp_color_with_tolerance(c1, c2, payload->pen.tolerance) : cmp_color(c1, c2);
155
+ }
156
+
150
157
  static bool
151
158
  skip_pixel(rgba source_color, action_struct * payload, texture_info * tex, int x, int y)
152
159
  {
@@ -158,18 +165,17 @@ skip_pixel(rgba source_color, action_struct * payload, texture_info * tex, int x
158
165
 
159
166
  if (payload->pen.source_select.size > 0) {
160
167
  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
- }
168
+ if (cmp_color_with_or_without_tolerance(source_color, payload->pen.source_select.colors[i], payload)) {
169
+ color_match = true;
170
+ break;
171
+ }
166
172
  if (!color_match) return true;
173
+ }
167
174
  }
168
-
169
175
 
170
176
  if (payload->pen.source_ignore.size > 0) {
171
177
  for (int i = 0; i < payload->pen.source_ignore.size; i++) {
172
- if (cmp_color(source_color, payload->pen.source_ignore.colors[i]))
178
+ if (cmp_color_with_or_without_tolerance(source_color, payload->pen.source_ignore.colors[i], payload))
173
179
  return true;
174
180
  }
175
181
  }
@@ -177,7 +183,7 @@ skip_pixel(rgba source_color, action_struct * payload, texture_info * tex, int x
177
183
  color_match = false;
178
184
  if (payload->pen.dest_select.size > 0) {
179
185
  for (int i = 0; i < payload->pen.dest_select.size; i++) {
180
- if (cmp_color(dest_color, payload->pen.dest_select.colors[i])) {
186
+ if (cmp_color_with_or_without_tolerance(dest_color, payload->pen.dest_select.colors[i], payload)) {
181
187
  color_match = true;
182
188
  break;
183
189
  }
@@ -187,7 +193,7 @@ skip_pixel(rgba source_color, action_struct * payload, texture_info * tex, int x
187
193
 
188
194
  if (payload->pen.dest_ignore.size > 0) {
189
195
  for (int i = 0; i < payload->pen.dest_ignore.size; i++) {
190
- if (cmp_color(dest_color, payload->pen.dest_ignore.colors[i]))
196
+ if (cmp_color_with_or_without_tolerance(dest_color, payload->pen.dest_ignore.colors[i], payload))
191
197
  return true;
192
198
  }
193
199
  }
@@ -359,6 +365,10 @@ initialize_action_struct(action_struct * cur, VALUE hash_arg, sync sync_mode)
359
365
  cur->pen.source_ignore.size = 0;
360
366
  cur->pen.dest_select.size = 0;
361
367
  cur->pen.dest_ignore.size = 0;
368
+
369
+ /* tolerance */
370
+ cur->pen.has_tolerance = false;
371
+ cur->pen.tolerance = 0.0;
362
372
  }
363
373
 
364
374
  /* TODO: fix this function below, it's too ugly and bulky and weird **/
@@ -400,6 +410,20 @@ process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode,
400
410
  cur->pen.has_color_control_transform = true;
401
411
  }
402
412
 
413
+ /* tolerance */
414
+ if(RTEST(get_from_hash(*hash_arg, "tolerance"))) {
415
+ cur->pen.tolerance = NUM2DBL(get_from_hash(*hash_arg, "tolerance"));
416
+
417
+ /* maximum length of hypotonese extended in 4-space (color space) is sqrt(4) */
418
+ if (cur->pen.tolerance >= 2)
419
+ cur->pen.tolerance = 2;
420
+
421
+ if (cur->pen.tolerance < 0)
422
+ cur->pen.tolerance = 0;
423
+
424
+ cur->pen.has_tolerance = true;
425
+ }
426
+
403
427
  /* lerp */
404
428
  if(RTEST(get_from_hash(*hash_arg, "lerp"))) {
405
429
  cur->pen.lerp = NUM2DBL(get_from_hash(*hash_arg, "lerp"));
@@ -56,7 +56,8 @@ typedef enum {
56
56
 
57
57
  /* structs */
58
58
  typedef struct s_rgba {
59
- float red, green, blue, alpha;
59
+ float red, green, blue, alpha;
60
+ float tolerance;
60
61
  } rgba;
61
62
 
62
63
  typedef struct {
@@ -129,10 +130,11 @@ typedef struct action_struct {
129
130
  bool has_drawing_mode;
130
131
  draw_mode drawing_mode;
131
132
 
132
-
133
+ /* tolerance */
134
+ bool has_tolerance;
135
+ float tolerance;
133
136
 
134
137
  /* color selection */
135
-
136
138
  bool has_color_select;
137
139
  rgba_list source_select;
138
140
  rgba_list source_ignore;
data/ext/texplay/utils.c CHANGED
@@ -306,15 +306,64 @@ not_rb_raw_color(VALUE cval)
306
306
  !is_a_num(get_from_array(cval, 0));
307
307
  }
308
308
 
309
+ /** cmp_color related functions **/
310
+ static bool
311
+ is_transparent_color(rgba color1)
312
+ {
313
+ return color1.red == -666 && color1.green == -666 && color1.blue == -666 &&
314
+ color1.alpha == -666;
315
+ }
316
+
317
+ static bool
318
+ special_cmp_color(rgba color1, rgba color2)
319
+ {
320
+ if (is_transparent_color(color1))
321
+ return color2.alpha == 0;
322
+ else if (is_transparent_color(color2))
323
+ return color1.alpha == 0;
324
+ }
325
+
326
+ static bool
327
+ special_cmp_color_with_tolerance(rgba color1, rgba color2, float tolerance)
328
+ {
329
+ if (is_transparent_color(color1))
330
+ return (color1.alpha) <= tolerance;
331
+ else if (is_transparent_color(color2))
332
+ return color2.alpha <= tolerance;
333
+ }
334
+
335
+
336
+ static float
337
+ color_distance_squared(rgba c1, rgba c2)
338
+ {
339
+ return (c1.red - c2.red) * (c1.red - c2.red) +
340
+ (c1.green - c2.green) * (c1.green - c2.green) +
341
+ (c1.blue - c2.blue) * (c1.blue - c2.blue) +
342
+ (c1.alpha - c2.alpha) * (c1.alpha - c2.alpha);
343
+ }
344
+
309
345
 
310
346
  bool
311
- cmp_color(rgba color1, rgba color2)
347
+ cmp_color_with_tolerance(rgba color1, rgba color2, float tolerance)
312
348
  {
349
+ if (color1.red < 0 || color2.red < 0)
350
+ return special_cmp_color_with_tolerance(color1, color2, tolerance);
351
+
352
+ return color_distance_squared(color1, color2) <= (tolerance * tolerance);
353
+ }
313
354
 
355
+ bool
356
+ cmp_color(rgba color1, rgba color2)
357
+ {
358
+ if (color1.red < 0 || color2.red < 0)
359
+ return special_cmp_color(color1, color2);
360
+
314
361
  return (color1.red == color2.red) && (color1.green == color2.green) && (color1.blue == color2.blue)
315
362
  && (color1.alpha == color2.alpha);
316
363
  }
364
+
317
365
 
366
+ /*** these functions are UNSAFE ***/
318
367
  void
319
368
  color_copy(float * source, float * dest)
320
369
  {
@@ -327,6 +376,7 @@ zero_color(float * tex)
327
376
  {
328
377
  memset(tex, 0, 4 * sizeof(float));
329
378
  }
379
+ /*** ***/
330
380
 
331
381
  rgba
332
382
  find_color_from_string(char * try_color)
@@ -372,6 +422,9 @@ find_color_from_string(char * try_color)
372
422
  else if(!strcmp("alpha", try_color)) {
373
423
  cur_color.red = 0.0; cur_color.green = 0.0; cur_color.blue = 0.0; cur_color.alpha = 0.0;
374
424
  }
425
+ else if(!strcmp("transparent", try_color)) {
426
+ cur_color.red = -666; cur_color.green = -666; cur_color.blue = -666; cur_color.alpha = -666;
427
+ }
375
428
  else if(!strcmp("none", try_color)) {
376
429
  cur_color = not_a_color_v;
377
430
  }
@@ -438,7 +491,7 @@ convert_rgba_to_gosu_color(rgba * pix)
438
491
  VALUE
439
492
  gosu_color_class()
440
493
  {
441
- VALUE gcolor_class = 0;
494
+ static VALUE gcolor_class = 0;
442
495
 
443
496
  if (gcolor_class == 0) {
444
497
  VALUE gosu_class = rb_const_get(rb_cObject, rb_intern("Gosu"));
@@ -476,6 +529,8 @@ convert_rb_color_to_rgba(VALUE cval)
476
529
  my_color.alpha = 1;
477
530
 
478
531
  break;
532
+
533
+ /* hex literals */
479
534
  case T_FIXNUM:
480
535
  case T_BIGNUM:
481
536
  return convert_gosu_to_rgba_color(rb_funcall(gosu_color_class(),
data/ext/texplay/utils.h CHANGED
@@ -14,6 +14,7 @@ extern const rgba not_a_color_v;
14
14
  /* color and pixel related functions */
15
15
  rgba find_color_from_string(char * try_color);
16
16
  bool cmp_color(rgba color1, rgba color2);
17
+ bool cmp_color_with_tolerance(rgba color1, rgba color2, float tolerance);
17
18
  void color_copy(float * source, float * dest);
18
19
  rgba get_pixel_color(texture_info * tex, int x, int y) ;
19
20
  float* get_pixel_data(texture_info * tex, int x, int y);
@@ -1,3 +1,3 @@
1
1
  module TexPlay
2
- VERSION = "0.2.950"
2
+ VERSION = "0.2.960"
3
3
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 950
9
- version: 0.2.950
8
+ - 960
9
+ version: 0.2.960
10
10
  platform: ruby
11
11
  authors:
12
12
  - John Mair (banisterfiend)
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-10 00:00:00 +02:00
17
+ date: 2010-07-04 00:00:00 +12:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency