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 +7 -0
- data/README.markdown +1 -1
- data/examples/example_color_transform.rb +2 -2
- data/examples/example_select.rb +14 -14
- data/examples/example_weird.rb +5 -3
- data/ext/texplay/actions.c +15 -8
- data/ext/texplay/bindings.c +4 -8
- data/ext/texplay/graphics_utils.c +33 -9
- data/ext/texplay/texplay.h +5 -3
- data/ext/texplay/utils.c +57 -2
- data/ext/texplay/utils.h +1 -0
- data/lib/texplay/version.rb +1 -1
- metadata +3 -3
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
@@ -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 => :
|
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 => :
|
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
|
|
data/examples/example_select.rb
CHANGED
@@ -5,26 +5,26 @@ require 'texplay'
|
|
5
5
|
|
6
6
|
|
7
7
|
class W < Gosu::Window
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
15
|
+
@img.line 0, 0, 500, 500, :dest_ignore => :red, :dest_select => :blue, :tolerance => 1
|
16
16
|
|
17
|
-
|
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
|
+
|
data/examples/example_weird.rb
CHANGED
@@ -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
|
-
@
|
11
|
-
@img.
|
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
|
17
|
+
@img.draw 50, 50,1
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
data/ext/texplay/actions.c
CHANGED
@@ -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
|
-
|
22
|
-
|
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
|
-
|
26
|
-
|
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
|
}
|
data/ext/texplay/bindings.c
CHANGED
@@ -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
|
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
|
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
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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"));
|
data/ext/texplay/texplay.h
CHANGED
@@ -56,7 +56,8 @@ typedef enum {
|
|
56
56
|
|
57
57
|
/* structs */
|
58
58
|
typedef struct s_rgba {
|
59
|
-
|
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
|
-
|
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);
|
data/lib/texplay/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
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-
|
17
|
+
date: 2010-07-04 00:00:00 +12:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|