texplay 0.2.950 → 0.2.960
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 +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
|