texplay 0.2.722 → 0.2.800
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/Rakefile +20 -20
- data/examples/example_color_transform.rb +4 -5
- data/examples/example_trace.rb +23 -0
- data/examples/example_weird.rb +2 -11
- data/ext/texplay/actions.c +72 -4
- data/ext/texplay/actions.h +9 -1
- data/ext/texplay/bindings.c +21 -2
- data/ext/texplay/graphics_utils.c +433 -5
- data/ext/texplay/texplay.h +25 -2
- data/ext/texplay/utils.c +0 -3
- data/lib/texplay/version.rb +3 -3
- metadata +4 -3
data/Rakefile
CHANGED
|
@@ -39,29 +39,29 @@ Rake::ExtensionTask.new('texplay', specification) do |ext|
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
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-mswin32'
|
|
56
|
+
# s.homepage = "http://banisterfiend.wordpress.com/2008/08/23/texplay-an-image-manipulation-tool-for-ruby-and-gosu/"
|
|
57
|
+
# s.has_rdoc = false
|
|
58
58
|
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
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
62
|
# FileList["examples/*.rb", "examples/media/*"].to_a
|
|
63
63
|
# end
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
Rake::GemPackageTask.new(specification) do |package|
|
|
66
66
|
package.need_zip = false
|
|
67
67
|
package.need_tar = false
|
|
@@ -30,13 +30,12 @@ class W < Gosu::Window
|
|
|
30
30
|
@y2 += 1
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
@copy2.splice @img, 0, 0, :crop => [@x2 - @rad, @y2 - @rad, @x2 + @rad, @y2 + @rad]
|
|
34
|
-
@copy.splice @img, 0, 0, :crop => [@x - @rad, @y - @rad, @x + @rad, @y + @rad]
|
|
33
|
+
@copy2.splice @img, 0, 0, :crop => [@x2 - @rad, @y2 - @rad, @x2 + @rad, @y2 + @rad], :sync_mode => :no_sync
|
|
34
|
+
@copy.splice @img, 0, 0, :crop => [@x - @rad, @y - @rad, @x + @rad, @y + @rad], :sync_mode => :no_sync
|
|
35
35
|
@img.
|
|
36
|
-
circle @x, @y, @rad, :fill => true,
|
|
37
|
-
:color_control => { :mult => [1.0, 0.5, 0.5, 1] }
|
|
36
|
+
circle @x, @y, @rad, :fill => true, :lerp => 0.3, :color => :red
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
@img.circle @x2, @y2, @rad, :fill => true, :lerp => 0.3, :color => :blue
|
|
40
39
|
# :color_control => { :mult => [0.3, 0.9, 0.3, 1] }
|
|
41
40
|
|
|
42
41
|
|
|
@@ -0,0 +1,23 @@
|
|
|
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 = TexPlay.create_image(self, 500, 500).fill(3,3, :color => :alpha)
|
|
10
|
+
@img.rect 100, 100, 300 , 300, :color => :blue, :fill => true
|
|
11
|
+
puts (@img.line 0,0, 100, 100, :trace => { :until_color => :blue }).inspect
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def draw
|
|
15
|
+
@img.draw 100, 50,1
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
w = W.new
|
|
22
|
+
w.show
|
|
23
|
+
|
data/examples/example_weird.rb
CHANGED
|
@@ -6,24 +6,15 @@ require 'texplay'
|
|
|
6
6
|
class W < Gosu::Window
|
|
7
7
|
def initialize
|
|
8
8
|
super(1024, 768, false, 20)
|
|
9
|
-
@img = Gosu::Image.new(self, "#{Common::MEDIA}/
|
|
10
|
-
@
|
|
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
|
-
|
|
9
|
+
@img = Gosu::Image.new(self, "#{Common::MEDIA}/gob.png")
|
|
10
|
+
@img.rect 0, 10, 300, 300, :color => :blue, :fill => true, :mode => :softlight
|
|
18
11
|
end
|
|
19
12
|
|
|
20
13
|
def draw
|
|
21
14
|
@img.draw 100, 50,1
|
|
22
15
|
end
|
|
23
|
-
|
|
24
16
|
end
|
|
25
17
|
|
|
26
|
-
|
|
27
18
|
w = W.new
|
|
28
19
|
w.show
|
|
29
20
|
|
data/ext/texplay/actions.c
CHANGED
|
@@ -12,7 +12,24 @@
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
/** line_do_action, bresenham's algorithm **/
|
|
15
|
-
|
|
15
|
+
typedef enum { no_mode, until_color, while_color} trace_mode_type;
|
|
16
|
+
|
|
17
|
+
static inline bool
|
|
18
|
+
is_trace_match(rgba c, rgba trace_color, trace_mode_type trace_mode)
|
|
19
|
+
{
|
|
20
|
+
if(trace_mode == while_color) {
|
|
21
|
+
if(!cmp_color(c, trace_color))
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
else if(trace_mode == until_color) {
|
|
25
|
+
if(cmp_color(c, trace_color))
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
trace_match
|
|
16
33
|
line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_arg,
|
|
17
34
|
sync sync_mode, bool primary, action_struct * payload)
|
|
18
35
|
{
|
|
@@ -21,11 +38,39 @@ line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_ar
|
|
|
21
38
|
action_struct cur;
|
|
22
39
|
int thickness = 1;
|
|
23
40
|
|
|
24
|
-
|
|
25
|
-
|
|
41
|
+
bool has_trace = false;
|
|
42
|
+
rgba trace_color;
|
|
43
|
+
trace_mode_type trace_mode = no_mode;
|
|
44
|
+
|
|
45
|
+
|
|
26
46
|
|
|
27
47
|
if(has_optional_hash_arg(hash_arg, "thickness"))
|
|
28
48
|
thickness = NUM2INT(get_from_hash(hash_arg, "thickness"));
|
|
49
|
+
|
|
50
|
+
if(has_optional_hash_arg(hash_arg, "trace") && primary) {
|
|
51
|
+
VALUE trace_hash = get_from_hash(hash_arg, "trace");
|
|
52
|
+
|
|
53
|
+
/* we're tracing (not drawing) */
|
|
54
|
+
has_trace = true;
|
|
55
|
+
|
|
56
|
+
/* since we're not drawing, no need to sync */
|
|
57
|
+
sync_mode = no_sync;
|
|
58
|
+
|
|
59
|
+
if(has_optional_hash_arg(trace_hash, "until_color")) {
|
|
60
|
+
VALUE c = get_from_hash(trace_hash, "until_color");
|
|
61
|
+
trace_color = convert_rb_color_to_rgba(c);
|
|
62
|
+
trace_mode = until_color;
|
|
63
|
+
}
|
|
64
|
+
else if(has_optional_hash_arg(trace_hash, "while_color")) {
|
|
65
|
+
VALUE c = get_from_hash(trace_hash, "while_color");
|
|
66
|
+
trace_color = convert_rb_color_to_rgba(c);
|
|
67
|
+
trace_mode = while_color;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
draw_prologue(&cur, tex, x1, y1,
|
|
72
|
+
x2, y2, &hash_arg, sync_mode, primary, &payload);
|
|
73
|
+
|
|
29
74
|
|
|
30
75
|
/* clip the line */
|
|
31
76
|
cohen_sutherland_clip(&x1, &y1, &x2, &y2, 0, 0, tex->width - 1, tex->height - 1);
|
|
@@ -50,7 +95,14 @@ line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_ar
|
|
|
50
95
|
F = 2 * H - W;
|
|
51
96
|
while(x != x2) {
|
|
52
97
|
if(thickness <= 1) {
|
|
98
|
+
if(!has_trace)
|
|
53
99
|
set_pixel_color_with_style(payload, tex, x, y);
|
|
100
|
+
else {
|
|
101
|
+
rgba c = get_pixel_color(tex, x, y);
|
|
102
|
+
|
|
103
|
+
if (is_trace_match(c, trace_color, trace_mode))
|
|
104
|
+
return (trace_match) { x, y, c };
|
|
105
|
+
}
|
|
54
106
|
}
|
|
55
107
|
else {
|
|
56
108
|
set_hash_value(hash_arg, "fill", Qtrue);
|
|
@@ -71,7 +123,14 @@ line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_ar
|
|
|
71
123
|
while(y != y2 ) {
|
|
72
124
|
|
|
73
125
|
if(thickness <= 1) {
|
|
126
|
+
if(!has_trace)
|
|
74
127
|
set_pixel_color_with_style(payload, tex, x, y);
|
|
128
|
+
else {
|
|
129
|
+
rgba c = get_pixel_color(tex, x, y);
|
|
130
|
+
|
|
131
|
+
if (is_trace_match(c, trace_color, trace_mode))
|
|
132
|
+
return (trace_match) { x, y, c };
|
|
133
|
+
}
|
|
75
134
|
}
|
|
76
135
|
else {
|
|
77
136
|
set_hash_value(hash_arg, "fill", Qtrue);
|
|
@@ -89,7 +148,14 @@ line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_ar
|
|
|
89
148
|
}
|
|
90
149
|
|
|
91
150
|
if(thickness <= 1) {
|
|
92
|
-
|
|
151
|
+
if(!has_trace)
|
|
152
|
+
set_pixel_color_with_style(payload, tex, x2, y2);
|
|
153
|
+
else {
|
|
154
|
+
rgba c = get_pixel_color(tex, x, y);
|
|
155
|
+
|
|
156
|
+
if (is_trace_match(c, trace_color, trace_mode))
|
|
157
|
+
return (trace_match) { x, y, c };
|
|
158
|
+
}
|
|
93
159
|
}
|
|
94
160
|
else {
|
|
95
161
|
set_hash_value(hash_arg, "fill", Qtrue);
|
|
@@ -97,6 +163,8 @@ line_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_ar
|
|
|
97
163
|
|
|
98
164
|
}
|
|
99
165
|
draw_epilogue(&cur, tex, primary);
|
|
166
|
+
|
|
167
|
+
return (trace_match) { .x = -1, .y = -1 };
|
|
100
168
|
}
|
|
101
169
|
/** end line **/
|
|
102
170
|
|
data/ext/texplay/actions.h
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
#ifndef GUARD_ACTIONS_H
|
|
2
2
|
#define GUARD_ACTIONS_H
|
|
3
3
|
|
|
4
|
+
#include "texplay.h"
|
|
5
|
+
|
|
6
|
+
/* used by line_do_action */
|
|
7
|
+
typedef struct {
|
|
8
|
+
int x, y;
|
|
9
|
+
rgba color;
|
|
10
|
+
} trace_match;
|
|
11
|
+
|
|
4
12
|
|
|
5
13
|
/* lines */
|
|
6
|
-
|
|
14
|
+
trace_match line_do_action(int, int, int, int, texture_info *, VALUE, sync, bool primary, action_struct * payload);
|
|
7
15
|
|
|
8
16
|
/* circles */
|
|
9
17
|
void circle_do_action(int, int, int, texture_info *, VALUE, sync, bool primary, action_struct * payload);
|
data/ext/texplay/bindings.c
CHANGED
|
@@ -505,7 +505,18 @@ m_flood_fill(int argc, VALUE * argv, VALUE self)
|
|
|
505
505
|
|
|
506
506
|
return self;
|
|
507
507
|
}
|
|
508
|
-
|
|
508
|
+
|
|
509
|
+
static inline VALUE
|
|
510
|
+
convert_trace_match_to_ruby_array(trace_match match)
|
|
511
|
+
{
|
|
512
|
+
VALUE ary = rb_ary_new();
|
|
513
|
+
|
|
514
|
+
rb_ary_store(ary, 0, INT2FIX(match.x));
|
|
515
|
+
rb_ary_store(ary, 1, INT2FIX(match.y));
|
|
516
|
+
rb_ary_store(ary, 2, convert_rgba_to_rb_color(&match.color));
|
|
517
|
+
|
|
518
|
+
return ary;
|
|
519
|
+
}
|
|
509
520
|
|
|
510
521
|
/* line action */
|
|
511
522
|
VALUE
|
|
@@ -515,6 +526,7 @@ m_line(int argc, VALUE * argv, VALUE self)
|
|
|
515
526
|
int last = argc - 1;
|
|
516
527
|
VALUE options;
|
|
517
528
|
texture_info tex;
|
|
529
|
+
trace_match match;
|
|
518
530
|
|
|
519
531
|
ADJUST_SELF(self);
|
|
520
532
|
|
|
@@ -526,7 +538,14 @@ m_line(int argc, VALUE * argv, VALUE self)
|
|
|
526
538
|
|
|
527
539
|
get_texture_info(self, &tex);
|
|
528
540
|
|
|
529
|
-
line_do_action(x1, y1, x2, y2, &tex, options, sync_mode, true, NULL);
|
|
541
|
+
match = line_do_action(x1, y1, x2, y2, &tex, options, sync_mode, true, NULL);
|
|
542
|
+
|
|
543
|
+
if (has_optional_hash_arg(options, "trace")) {
|
|
544
|
+
if (match.x == -1)
|
|
545
|
+
return Qnil;
|
|
546
|
+
else
|
|
547
|
+
return convert_trace_match_to_ruby_array(match);
|
|
548
|
+
}
|
|
530
549
|
|
|
531
550
|
return self;
|
|
532
551
|
}
|
|
@@ -13,9 +13,13 @@
|
|
|
13
13
|
/* small helper functions */
|
|
14
14
|
static void initialize_action_struct(action_struct * cur, VALUE hash_arg, sync sync_mode);
|
|
15
15
|
static void process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode, bool primary);
|
|
16
|
+
static void prepare_drawing_mode(action_struct * cur);
|
|
16
17
|
static void prepare_fill_texture(action_struct * cur);
|
|
17
18
|
static void prepare_color_control(action_struct * cur);
|
|
19
|
+
static rgba apply_lerp(action_struct * payload, texture_info * tex, int x, int y);
|
|
18
20
|
static rgba apply_alpha_blend(action_struct * payload, texture_info * tex, int x, int y, rgba blended_pixel);
|
|
21
|
+
static rgba apply_drawing_mode(action_struct * payload, texture_info * tex, int x, int y);
|
|
22
|
+
|
|
19
23
|
static rgba apply_color_control_transform(action_struct * payload, texture_info * tex, int x, int y);
|
|
20
24
|
static rgba exec_color_control_proc(action_struct * cur, texture_info * tex, int x, int y, rgba blended_pixel);
|
|
21
25
|
/* end helpers */
|
|
@@ -149,11 +153,16 @@ set_pixel_color_with_style(action_struct * payload, texture_info * tex, int x, i
|
|
|
149
153
|
|
|
150
154
|
blended_pixel = payload->color;
|
|
151
155
|
|
|
156
|
+
/* for linear interpolation */
|
|
157
|
+
if(payload->pen.has_lerp) {
|
|
158
|
+
blended_pixel = apply_lerp(payload, tex, x, y);
|
|
159
|
+
}
|
|
160
|
+
|
|
152
161
|
/* for color_control transform */
|
|
153
162
|
if(payload->pen.has_color_control_transform)
|
|
154
163
|
blended_pixel = apply_color_control_transform(payload, tex, x, y);
|
|
155
164
|
|
|
156
|
-
/*
|
|
165
|
+
/* for texture fill */
|
|
157
166
|
if(payload->pen.has_source_texture)
|
|
158
167
|
blended_pixel = get_pixel_color(&payload->pen.source_tex,
|
|
159
168
|
x % payload->pen.source_tex.width,
|
|
@@ -165,7 +174,10 @@ set_pixel_color_with_style(action_struct * payload, texture_info * tex, int x, i
|
|
|
165
174
|
|
|
166
175
|
|
|
167
176
|
/* TO DO: do bitwise pixel combinations here */
|
|
168
|
-
|
|
177
|
+
if(payload->pen.has_drawing_mode) {
|
|
178
|
+
blended_pixel = apply_drawing_mode(payload, tex, x, y);
|
|
179
|
+
}
|
|
180
|
+
|
|
169
181
|
/* TO DO: refactor into its own helper function
|
|
170
182
|
& rewrite using sse2 */
|
|
171
183
|
if(payload->pen.alpha_blend)
|
|
@@ -236,13 +248,13 @@ create_image(VALUE window, int width, int height)
|
|
|
236
248
|
VALUE gosu = rb_const_get(rb_cObject, rb_intern("Gosu"));
|
|
237
249
|
VALUE image = rb_const_get(gosu, rb_intern("Image"));
|
|
238
250
|
|
|
239
|
-
VALUE
|
|
240
|
-
VALUE
|
|
251
|
+
VALUE tp = rb_const_get(rb_cObject, rb_intern("TexPlay"));
|
|
252
|
+
VALUE empty_image_stub = rb_const_get(tp, rb_intern("EmptyImageStub"));
|
|
241
253
|
|
|
242
254
|
VALUE rmagick_img;
|
|
243
255
|
VALUE new_image;
|
|
244
256
|
|
|
245
|
-
rmagick_img = rb_funcall(
|
|
257
|
+
rmagick_img = rb_funcall(empty_image_stub, rb_intern("new"), 2, INT2FIX(width), INT2FIX(height));
|
|
246
258
|
|
|
247
259
|
new_image = rb_funcall(image, rb_intern("new"), 2, window, rmagick_img);
|
|
248
260
|
|
|
@@ -275,6 +287,12 @@ initialize_action_struct(action_struct * cur, VALUE hash_arg, sync sync_mode)
|
|
|
275
287
|
cur->pen.color_add.green = 0.0;
|
|
276
288
|
cur->pen.color_add.blue = 0.0;
|
|
277
289
|
cur->pen.color_add.alpha = 0.0;
|
|
290
|
+
|
|
291
|
+
/* lerp is off by default */
|
|
292
|
+
cur->pen.has_lerp = false;
|
|
293
|
+
|
|
294
|
+
/* drawing mode is off by deafult */
|
|
295
|
+
cur->pen.has_drawing_mode = false;
|
|
278
296
|
}
|
|
279
297
|
|
|
280
298
|
/* TODO: fix this function below, it's too ugly and bulky and weird **/
|
|
@@ -315,6 +333,16 @@ process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode,
|
|
|
315
333
|
|
|
316
334
|
cur->pen.has_color_control_transform = true;
|
|
317
335
|
}
|
|
336
|
+
|
|
337
|
+
/* lerp */
|
|
338
|
+
if(RTEST(get_from_hash(*hash_arg, "lerp"))) {
|
|
339
|
+
cur->pen.lerp = NUM2DBL(get_from_hash(*hash_arg, "lerp"));
|
|
340
|
+
|
|
341
|
+
/* bounds */
|
|
342
|
+
if(cur->pen.lerp > 1.0) cur->pen.lerp = 1.0;
|
|
343
|
+
if(cur->pen.lerp < 0.0) cur->pen.lerp = 0.0;
|
|
344
|
+
cur->pen.has_lerp = true;
|
|
345
|
+
}
|
|
318
346
|
|
|
319
347
|
/* sync mode */
|
|
320
348
|
if(has_optional_hash_arg(*hash_arg, "sync_mode")) {
|
|
@@ -337,6 +365,9 @@ process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode,
|
|
|
337
365
|
|
|
338
366
|
}
|
|
339
367
|
|
|
368
|
+
/* process drawing mode */
|
|
369
|
+
prepare_drawing_mode(cur);
|
|
370
|
+
|
|
340
371
|
/* process the color_control block or transform (if there is one) */
|
|
341
372
|
prepare_color_control(cur);
|
|
342
373
|
|
|
@@ -349,8 +380,96 @@ process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode,
|
|
|
349
380
|
|
|
350
381
|
}
|
|
351
382
|
|
|
383
|
+
static void
|
|
384
|
+
prepare_drawing_mode(action_struct * cur)
|
|
385
|
+
{
|
|
386
|
+
if(is_a_hash(cur->hash_arg)) {
|
|
387
|
+
/* drawing mode */
|
|
388
|
+
if(has_optional_hash_arg(cur->hash_arg, "mode")) {
|
|
389
|
+
cur->pen.has_drawing_mode = true;
|
|
390
|
+
|
|
391
|
+
VALUE draw_mode = get_from_hash(cur->hash_arg, "mode");
|
|
352
392
|
|
|
353
393
|
|
|
394
|
+
Check_Type(draw_mode, T_SYMBOL);
|
|
395
|
+
|
|
396
|
+
if(draw_mode == string2sym("clear"))
|
|
397
|
+
cur->pen.drawing_mode = clear;
|
|
398
|
+
|
|
399
|
+
else if(draw_mode == string2sym("copy"))
|
|
400
|
+
cur->pen.drawing_mode = copy;
|
|
401
|
+
|
|
402
|
+
else if(draw_mode == string2sym("noop"))
|
|
403
|
+
cur->pen.drawing_mode = noop;
|
|
404
|
+
|
|
405
|
+
else if(draw_mode == string2sym("set"))
|
|
406
|
+
cur->pen.drawing_mode = set;
|
|
407
|
+
|
|
408
|
+
else if(draw_mode == string2sym("copy_inverted"))
|
|
409
|
+
cur->pen.drawing_mode = copy_inverted;
|
|
410
|
+
|
|
411
|
+
else if(draw_mode == string2sym("invert"))
|
|
412
|
+
cur->pen.drawing_mode = invert;
|
|
413
|
+
|
|
414
|
+
else if(draw_mode == string2sym("and_reverse"))
|
|
415
|
+
cur->pen.drawing_mode = and_reverse;
|
|
416
|
+
|
|
417
|
+
else if(draw_mode == string2sym("and"))
|
|
418
|
+
cur->pen.drawing_mode = and;
|
|
419
|
+
|
|
420
|
+
else if(draw_mode == string2sym("or"))
|
|
421
|
+
cur->pen.drawing_mode = or;
|
|
422
|
+
|
|
423
|
+
else if(draw_mode == string2sym("nand"))
|
|
424
|
+
cur->pen.drawing_mode = nand;
|
|
425
|
+
|
|
426
|
+
else if(draw_mode == string2sym("nor"))
|
|
427
|
+
cur->pen.drawing_mode = nor;
|
|
428
|
+
|
|
429
|
+
else if(draw_mode == string2sym("xor"))
|
|
430
|
+
cur->pen.drawing_mode = xor;
|
|
431
|
+
|
|
432
|
+
else if(draw_mode == string2sym("equiv"))
|
|
433
|
+
cur->pen.drawing_mode = equiv;
|
|
434
|
+
|
|
435
|
+
else if(draw_mode == string2sym("and_inverted"))
|
|
436
|
+
cur->pen.drawing_mode = and_inverted;
|
|
437
|
+
|
|
438
|
+
else if(draw_mode == string2sym("or_inverted"))
|
|
439
|
+
cur->pen.drawing_mode = or_inverted;
|
|
440
|
+
|
|
441
|
+
else if(draw_mode == string2sym("additive"))
|
|
442
|
+
cur->pen.drawing_mode = additive;
|
|
443
|
+
else if(draw_mode == string2sym("multiply"))
|
|
444
|
+
cur->pen.drawing_mode = multiply;
|
|
445
|
+
else if(draw_mode == string2sym("screen"))
|
|
446
|
+
cur->pen.drawing_mode = screen;
|
|
447
|
+
else if(draw_mode == string2sym("overlay"))
|
|
448
|
+
cur->pen.drawing_mode = overlay;
|
|
449
|
+
else if(draw_mode == string2sym("darken"))
|
|
450
|
+
cur->pen.drawing_mode = darken;
|
|
451
|
+
else if(draw_mode == string2sym("lighten"))
|
|
452
|
+
cur->pen.drawing_mode = lighten;
|
|
453
|
+
else if(draw_mode == string2sym("colordodge"))
|
|
454
|
+
cur->pen.drawing_mode = colordodge;
|
|
455
|
+
else if(draw_mode == string2sym("colorburn"))
|
|
456
|
+
cur->pen.drawing_mode = colorburn;
|
|
457
|
+
else if(draw_mode == string2sym("hardlight"))
|
|
458
|
+
cur->pen.drawing_mode = hardlight;
|
|
459
|
+
else if(draw_mode == string2sym("softlight"))
|
|
460
|
+
cur->pen.drawing_mode = softlight;
|
|
461
|
+
else if(draw_mode == string2sym("difference"))
|
|
462
|
+
cur->pen.drawing_mode = difference;
|
|
463
|
+
else if(draw_mode == string2sym("exclusion"))
|
|
464
|
+
cur->pen.drawing_mode = exclusion;
|
|
465
|
+
else
|
|
466
|
+
rb_raise(rb_eArgError, "unrecognized drawing mode: %s\n.",
|
|
467
|
+
sym2string(draw_mode));
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
|
|
354
473
|
/* set action color to return value of color_control proc */
|
|
355
474
|
static void
|
|
356
475
|
prepare_color_control(action_struct * cur)
|
|
@@ -457,7 +576,316 @@ prepare_fill_texture(action_struct * payload)
|
|
|
457
576
|
}
|
|
458
577
|
}
|
|
459
578
|
|
|
579
|
+
/***********************************/
|
|
580
|
+
/**** drawing mode related code ****/
|
|
581
|
+
/***********************************/
|
|
582
|
+
|
|
583
|
+
typedef struct {
|
|
584
|
+
unsigned char red, green, blue, alpha;
|
|
585
|
+
} rgba_char;
|
|
586
|
+
|
|
587
|
+
static inline rgba_char
|
|
588
|
+
color_float_to_int_format(rgba c)
|
|
589
|
+
{
|
|
590
|
+
return (rgba_char) { c.red * 255,
|
|
591
|
+
c.green * 255,
|
|
592
|
+
c.blue * 255,
|
|
593
|
+
c.alpha * 255
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
static inline rgba
|
|
598
|
+
color_int_vals_to_float_format(unsigned char r, unsigned char g, unsigned char b,
|
|
599
|
+
unsigned char a)
|
|
600
|
+
{
|
|
601
|
+
return (rgba) { r / 255.0,
|
|
602
|
+
g / 255.0,
|
|
603
|
+
b / 255.0,
|
|
604
|
+
a / 255.0
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/* using terminology from photoshop PDF. b=background, s=source */
|
|
609
|
+
static inline rgba
|
|
610
|
+
mode_multiply(rgba b, rgba s)
|
|
611
|
+
{
|
|
612
|
+
return (rgba) { b.red * s.red,
|
|
613
|
+
b.green * s.green,
|
|
614
|
+
b.blue * s.blue,
|
|
615
|
+
b.alpha * s.alpha };
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
static inline rgba
|
|
619
|
+
mode_screen(rgba b, rgba s)
|
|
620
|
+
{
|
|
621
|
+
return (rgba) { b.red + s.red - (b.red * s.red),
|
|
622
|
+
b.green + s.green - (b.green * s.green),
|
|
623
|
+
b.blue + s.blue - (b.blue * s.blue),
|
|
624
|
+
b.alpha + s.alpha - (b.alpha * s.alpha) };
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
static inline float
|
|
628
|
+
mode_hardlight_channel(float b, float s)
|
|
629
|
+
{
|
|
630
|
+
if (s <= 0.5)
|
|
631
|
+
return 2 * b * s;
|
|
632
|
+
|
|
633
|
+
else
|
|
634
|
+
return b + s - (b * s);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
static inline rgba
|
|
638
|
+
mode_hardlight(rgba b, rgba s)
|
|
639
|
+
{
|
|
640
|
+
return (rgba) { mode_hardlight_channel(b.red, s.red),
|
|
641
|
+
mode_hardlight_channel(b.green, s.green),
|
|
642
|
+
mode_hardlight_channel(b.blue, s.blue),
|
|
643
|
+
mode_hardlight_channel(b.alpha, s.alpha) };
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/* function from the photoshop PDF to implement soft lighting */
|
|
647
|
+
static inline float
|
|
648
|
+
D(float x)
|
|
649
|
+
{
|
|
650
|
+
if (x <= 0.25)
|
|
651
|
+
return ((16 * x - 12) * x + 4) * x;
|
|
652
|
+
else
|
|
653
|
+
return sqrt(x);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
static inline float
|
|
657
|
+
mode_softlight_channel(float b, float s)
|
|
658
|
+
{
|
|
659
|
+
if (s <= 0.5)
|
|
660
|
+
return b - (1 - 2 * s) * b * (1 - b);
|
|
661
|
+
else
|
|
662
|
+
return b + (2 * s - 1) * (D(b) - b);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
static inline rgba
|
|
666
|
+
mode_softlight(rgba b, rgba s)
|
|
667
|
+
{
|
|
668
|
+
return (rgba) { mode_softlight_channel(b.red, s.red),
|
|
669
|
+
mode_softlight_channel(b.green, s.green),
|
|
670
|
+
mode_softlight_channel(b.blue, s.blue),
|
|
671
|
+
mode_softlight_channel(b.alpha, s.alpha) };
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
static inline float
|
|
675
|
+
mode_colordodge_channel(float b, float s)
|
|
676
|
+
{
|
|
677
|
+
if (s < 1)
|
|
678
|
+
return MIN(1, b / (1 - s));
|
|
679
|
+
else
|
|
680
|
+
return 1;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
static inline float
|
|
684
|
+
mode_colorburn_channel(float b, float s)
|
|
685
|
+
{
|
|
686
|
+
if (s > 0)
|
|
687
|
+
return 1 - MIN(1, (1 - b) / s);
|
|
688
|
+
else
|
|
689
|
+
return 0;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
static rgba
|
|
693
|
+
apply_drawing_mode(action_struct * payload, texture_info * tex, int x, int y)
|
|
694
|
+
{
|
|
695
|
+
rgba finished_pixel;
|
|
696
|
+
|
|
697
|
+
rgba source_pixel = payload->color;
|
|
698
|
+
rgba dest_pixel = get_pixel_color(tex, x, y);
|
|
699
|
+
|
|
700
|
+
rgba_char dest_pixel_char = color_float_to_int_format(dest_pixel);
|
|
701
|
+
rgba_char source_pixel_char = color_float_to_int_format(source_pixel);
|
|
702
|
+
|
|
703
|
+
switch(payload->pen.drawing_mode)
|
|
704
|
+
{
|
|
705
|
+
|
|
706
|
+
/* bitwise blending functions */
|
|
707
|
+
case clear:
|
|
708
|
+
finished_pixel = (rgba) { 0, 0, 0, 0 };
|
|
709
|
+
break;
|
|
710
|
+
case copy:
|
|
711
|
+
finished_pixel = source_pixel;
|
|
712
|
+
break;
|
|
713
|
+
case noop:
|
|
714
|
+
finished_pixel = dest_pixel;
|
|
715
|
+
break;
|
|
716
|
+
case set:
|
|
717
|
+
finished_pixel = (rgba) { 1, 1, 1, 1 };
|
|
718
|
+
break;
|
|
719
|
+
case copy_inverted:
|
|
720
|
+
finished_pixel = color_int_vals_to_float_format(~source_pixel_char.red,
|
|
721
|
+
~source_pixel_char.green,
|
|
722
|
+
~source_pixel_char.blue,
|
|
723
|
+
~source_pixel_char.alpha);
|
|
724
|
+
break;
|
|
725
|
+
case invert:
|
|
726
|
+
finished_pixel = color_int_vals_to_float_format(~dest_pixel_char.red,
|
|
727
|
+
~dest_pixel_char.green,
|
|
728
|
+
~dest_pixel_char.blue,
|
|
729
|
+
~dest_pixel_char.alpha);
|
|
730
|
+
|
|
731
|
+
break;
|
|
732
|
+
case and_reverse:
|
|
733
|
+
finished_pixel = color_int_vals_to_float_format(source_pixel_char.red | ~dest_pixel_char.red,
|
|
734
|
+
source_pixel_char.green | ~dest_pixel_char.green,
|
|
735
|
+
source_pixel_char.blue | ~dest_pixel_char.blue,
|
|
736
|
+
source_pixel_char.alpha | ~dest_pixel_char.alpha);
|
|
737
|
+
break;
|
|
738
|
+
case and:
|
|
739
|
+
finished_pixel = color_int_vals_to_float_format(source_pixel_char.red & dest_pixel_char.red,
|
|
740
|
+
source_pixel_char.green & dest_pixel_char.green,
|
|
741
|
+
source_pixel_char.blue & dest_pixel_char.blue,
|
|
742
|
+
source_pixel_char.alpha & dest_pixel_char.alpha);
|
|
743
|
+
break;
|
|
744
|
+
case or:
|
|
745
|
+
finished_pixel = color_int_vals_to_float_format(source_pixel_char.red | dest_pixel_char.red,
|
|
746
|
+
source_pixel_char.green | dest_pixel_char.green,
|
|
747
|
+
source_pixel_char.blue | dest_pixel_char.blue,
|
|
748
|
+
source_pixel_char.alpha | dest_pixel_char.alpha);
|
|
749
|
+
|
|
750
|
+
break;
|
|
751
|
+
case nand:
|
|
752
|
+
finished_pixel = color_int_vals_to_float_format(~(source_pixel_char.red & dest_pixel_char.red),
|
|
753
|
+
~(source_pixel_char.green & dest_pixel_char.green),
|
|
754
|
+
~(source_pixel_char.blue & dest_pixel_char.blue),
|
|
755
|
+
~(source_pixel_char.alpha & dest_pixel_char.alpha));
|
|
756
|
+
|
|
757
|
+
break;
|
|
758
|
+
case nor:
|
|
759
|
+
finished_pixel = color_int_vals_to_float_format(~(source_pixel_char.red | dest_pixel_char.red),
|
|
760
|
+
~(source_pixel_char.green | dest_pixel_char.green),
|
|
761
|
+
~(source_pixel_char.blue | dest_pixel_char.blue),
|
|
762
|
+
~(source_pixel_char.alpha | dest_pixel_char.alpha));
|
|
763
|
+
|
|
764
|
+
break;
|
|
765
|
+
case xor:
|
|
766
|
+
finished_pixel = color_int_vals_to_float_format(source_pixel_char.red ^ dest_pixel_char.red,
|
|
767
|
+
source_pixel_char.green ^ dest_pixel_char.green,
|
|
768
|
+
source_pixel_char.blue ^ dest_pixel_char.blue,
|
|
769
|
+
source_pixel_char.alpha ^ dest_pixel_char.alpha);
|
|
770
|
+
|
|
771
|
+
break;
|
|
772
|
+
case equiv:
|
|
773
|
+
finished_pixel = color_int_vals_to_float_format(~(source_pixel_char.red ^ dest_pixel_char.red),
|
|
774
|
+
~(source_pixel_char.green ^ dest_pixel_char.green),
|
|
775
|
+
~(source_pixel_char.blue ^ dest_pixel_char.blue),
|
|
776
|
+
~(source_pixel_char.alpha ^ dest_pixel_char.alpha));
|
|
777
|
+
|
|
778
|
+
break;
|
|
779
|
+
case and_inverted:
|
|
780
|
+
finished_pixel = color_int_vals_to_float_format(~source_pixel_char.red & dest_pixel_char.red,
|
|
781
|
+
~source_pixel_char.green & dest_pixel_char.green,
|
|
782
|
+
~source_pixel_char.blue & dest_pixel_char.blue,
|
|
783
|
+
~source_pixel_char.alpha & dest_pixel_char.alpha);
|
|
784
|
+
break;
|
|
785
|
+
case or_inverted:
|
|
786
|
+
finished_pixel = color_int_vals_to_float_format(~source_pixel_char.red | dest_pixel_char.red,
|
|
787
|
+
~source_pixel_char.green | dest_pixel_char.green,
|
|
788
|
+
~source_pixel_char.blue | dest_pixel_char.blue,
|
|
789
|
+
~source_pixel_char.alpha | dest_pixel_char.alpha);
|
|
790
|
+
|
|
791
|
+
break;
|
|
792
|
+
|
|
793
|
+
/* photoshop style blending functions */
|
|
794
|
+
case additive:
|
|
795
|
+
finished_pixel = (rgba) { MIN(source_pixel.red + dest_pixel.red, 1),
|
|
796
|
+
MIN(source_pixel.green + dest_pixel.green, 1),
|
|
797
|
+
MIN(source_pixel.blue + dest_pixel.blue, 1),
|
|
798
|
+
MIN(source_pixel.alpha + dest_pixel.alpha, 1) };
|
|
799
|
+
break;
|
|
800
|
+
case multiply:
|
|
801
|
+
finished_pixel = mode_multiply(dest_pixel, source_pixel);
|
|
802
|
+
|
|
803
|
+
break;
|
|
804
|
+
case screen:
|
|
805
|
+
finished_pixel = mode_screen(dest_pixel, source_pixel);
|
|
806
|
+
|
|
807
|
+
break;
|
|
808
|
+
case overlay:
|
|
809
|
+
finished_pixel = mode_hardlight(source_pixel, dest_pixel);
|
|
810
|
+
|
|
811
|
+
break;
|
|
812
|
+
|
|
813
|
+
case darken:
|
|
814
|
+
finished_pixel = (rgba) { MIN(source_pixel.red, dest_pixel.red),
|
|
815
|
+
MIN(source_pixel.green, dest_pixel.green),
|
|
816
|
+
MIN(source_pixel.blue, dest_pixel.blue),
|
|
817
|
+
MIN(source_pixel.alpha, dest_pixel.alpha) };
|
|
818
|
+
break;
|
|
819
|
+
case lighten:
|
|
820
|
+
finished_pixel = (rgba) { MAX(source_pixel.red, dest_pixel.red),
|
|
821
|
+
MAX(source_pixel.green, dest_pixel.green),
|
|
822
|
+
MAX(source_pixel.blue, dest_pixel.blue),
|
|
823
|
+
MAX(source_pixel.alpha, dest_pixel.alpha) };
|
|
824
|
+
break;
|
|
825
|
+
case colordodge:
|
|
826
|
+
finished_pixel = (rgba) { mode_colordodge_channel(dest_pixel.red, source_pixel.red),
|
|
827
|
+
mode_colordodge_channel(dest_pixel.green, source_pixel.green),
|
|
828
|
+
mode_colordodge_channel(dest_pixel.blue, source_pixel.blue),
|
|
829
|
+
mode_colordodge_channel(dest_pixel.alpha, source_pixel.alpha) };
|
|
830
|
+
|
|
831
|
+
break;
|
|
832
|
+
case colorburn:
|
|
833
|
+
finished_pixel = (rgba) { mode_colorburn_channel(dest_pixel.red, source_pixel.red),
|
|
834
|
+
mode_colorburn_channel(dest_pixel.green, source_pixel.green),
|
|
835
|
+
mode_colorburn_channel(dest_pixel.blue, source_pixel.blue),
|
|
836
|
+
mode_colorburn_channel(dest_pixel.alpha, source_pixel.alpha) };
|
|
837
|
+
break;
|
|
838
|
+
case hardlight:
|
|
839
|
+
finished_pixel = mode_hardlight(dest_pixel, source_pixel);
|
|
840
|
+
|
|
841
|
+
break;
|
|
842
|
+
case softlight:
|
|
843
|
+
finished_pixel = mode_softlight(dest_pixel, source_pixel);
|
|
844
|
+
|
|
845
|
+
break;
|
|
846
|
+
case difference:
|
|
847
|
+
finished_pixel = (rgba) { ABS(dest_pixel.red - source_pixel.red),
|
|
848
|
+
ABS(dest_pixel.green - source_pixel.green),
|
|
849
|
+
ABS(dest_pixel.blue - source_pixel.blue),
|
|
850
|
+
ABS(dest_pixel.alpha - source_pixel.alpha) };
|
|
851
|
+
break;
|
|
852
|
+
case exclusion:
|
|
853
|
+
finished_pixel = (rgba) { dest_pixel.red + source_pixel.red - (2 * dest_pixel.red * source_pixel.red),
|
|
854
|
+
dest_pixel.green + source_pixel.green - (2 * dest_pixel.green * source_pixel.green),
|
|
855
|
+
dest_pixel.blue + source_pixel.blue - (2 * dest_pixel.blue * source_pixel.blue),
|
|
856
|
+
dest_pixel.alpha + source_pixel.alpha - (2 * dest_pixel.alpha * source_pixel.alpha) };
|
|
857
|
+
break;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
return finished_pixel;
|
|
861
|
+
}
|
|
862
|
+
/***************************************/
|
|
863
|
+
/**** end drawing mode related code ****/
|
|
864
|
+
/***************************************/
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
static rgba
|
|
868
|
+
apply_lerp(action_struct * payload, texture_info * tex, int x, int y)
|
|
869
|
+
{
|
|
870
|
+
rgba finished_pixel;
|
|
871
|
+
rgba dest_pixel = get_pixel_color(tex, x, y);
|
|
872
|
+
|
|
873
|
+
finished_pixel.red = payload->pen.lerp * payload->color.red +
|
|
874
|
+
(1 - payload->pen.lerp) * dest_pixel.red;
|
|
875
|
+
|
|
876
|
+
finished_pixel.green = payload->pen.lerp * payload->color.green +
|
|
877
|
+
(1 - payload->pen.lerp) * dest_pixel.green;
|
|
878
|
+
|
|
879
|
+
finished_pixel.blue = payload->pen.lerp * payload->color.blue +
|
|
880
|
+
(1 - payload->pen.lerp) * dest_pixel.blue;
|
|
881
|
+
|
|
882
|
+
finished_pixel.alpha = payload->pen.lerp * payload->color.alpha +
|
|
883
|
+
(1 - payload->pen.lerp) * dest_pixel.alpha;
|
|
884
|
+
|
|
885
|
+
return finished_pixel;
|
|
886
|
+
}
|
|
460
887
|
|
|
888
|
+
|
|
461
889
|
/* TODO: reimplement using SSE2 */
|
|
462
890
|
static rgba
|
|
463
891
|
apply_color_control_transform(action_struct * payload, texture_info * tex, int x, int y)
|
data/ext/texplay/texplay.h
CHANGED
|
@@ -40,6 +40,19 @@ typedef enum e_sync_mode {
|
|
|
40
40
|
lazy_sync, eager_sync, no_sync
|
|
41
41
|
} sync;
|
|
42
42
|
|
|
43
|
+
typedef enum {
|
|
44
|
+
clear, copy, noop,
|
|
45
|
+
set, copy_inverted,
|
|
46
|
+
invert, and_reverse, and,
|
|
47
|
+
or, nand, nor, xor,
|
|
48
|
+
equiv, and_inverted,
|
|
49
|
+
or_inverted, additive,
|
|
50
|
+
multiply, screen, overlay,
|
|
51
|
+
darken, lighten, colordodge,
|
|
52
|
+
colorburn, hardlight, softlight,
|
|
53
|
+
difference, exclusion
|
|
54
|
+
} draw_mode;
|
|
55
|
+
|
|
43
56
|
/* structs */
|
|
44
57
|
typedef struct s_rgba {
|
|
45
58
|
float red, green, blue, alpha;
|
|
@@ -66,6 +79,7 @@ typedef struct {
|
|
|
66
79
|
int ymax;
|
|
67
80
|
} image_bounds;
|
|
68
81
|
|
|
82
|
+
|
|
69
83
|
typedef struct action_struct {
|
|
70
84
|
int xmin, ymin, xmax, ymax;
|
|
71
85
|
sync sync_mode;
|
|
@@ -84,8 +98,8 @@ typedef struct action_struct {
|
|
|
84
98
|
struct {
|
|
85
99
|
|
|
86
100
|
/* color control, dynamic */
|
|
87
|
-
VALUE color_control_proc;
|
|
88
101
|
bool has_color_control_proc;
|
|
102
|
+
VALUE color_control_proc;
|
|
89
103
|
int color_control_arity;
|
|
90
104
|
|
|
91
105
|
/* color control, static */
|
|
@@ -94,11 +108,20 @@ typedef struct action_struct {
|
|
|
94
108
|
rgba color_add;
|
|
95
109
|
|
|
96
110
|
/* texture fill */
|
|
97
|
-
texture_info source_tex;
|
|
98
111
|
bool has_source_texture;
|
|
112
|
+
texture_info source_tex;
|
|
113
|
+
|
|
114
|
+
/* lerp */
|
|
115
|
+
bool has_lerp;
|
|
116
|
+
float lerp;
|
|
99
117
|
|
|
100
118
|
/* alpha blend */
|
|
101
119
|
bool alpha_blend;
|
|
120
|
+
|
|
121
|
+
/* drawing mode */
|
|
122
|
+
bool has_drawing_mode;
|
|
123
|
+
draw_mode drawing_mode;
|
|
124
|
+
|
|
102
125
|
} pen;
|
|
103
126
|
|
|
104
127
|
} action_struct;
|
data/ext/texplay/utils.c
CHANGED
data/lib/texplay/version.rb
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module TexPlay
|
|
2
|
-
VERSION = "0.2.
|
|
3
|
-
end
|
|
1
|
+
module TexPlay
|
|
2
|
+
VERSION = "0.2.800"
|
|
3
|
+
end
|
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
|
+
- 800
|
|
9
|
+
version: 0.2.800
|
|
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-03-
|
|
17
|
+
date: 2010-03-22 00:00:00 +13:00
|
|
18
18
|
default_executable:
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
@@ -84,6 +84,7 @@ files:
|
|
|
84
84
|
- examples/example_simple.rb
|
|
85
85
|
- examples/example_splice.rb
|
|
86
86
|
- examples/example_sync.rb
|
|
87
|
+
- examples/example_trace.rb
|
|
87
88
|
- examples/example_turtle.rb
|
|
88
89
|
- examples/example_weird.rb
|
|
89
90
|
- examples/media/bird.png
|