texplay 0.3.1-i386-mswin32 → 0.3.3-i386-mswin32
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/Rakefile +37 -13
- data/ext/texplay/graphics_utils.c +95 -26
- data/ext/texplay/texplay.h +62 -57
- data/lib/1.8/texplay.so +0 -0
- data/lib/1.9/texplay.so +0 -0
- data/lib/texplay/alone.rb +20 -0
- data/lib/texplay/c_function_docs.rb +3 -2
- data/lib/texplay/version.rb +1 -1
- data/lib/texplay-contrib.rb +111 -118
- data/lib/texplay.rb +36 -14
- data/live/live.rb +85 -0
- data/test/image_spec.rb +45 -0
- data/test/texplay_spec.rb +141 -0
- metadata +28 -9
- data/spec/image_spec.rb +0 -7
- data/spec/texplay_spec.rb +0 -80
data/.gemtest
ADDED
File without changes
|
data/Rakefile
CHANGED
@@ -1,17 +1,14 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
direc = File.dirname(__FILE__)
|
2
|
+
dlext = Config::CONFIG['DLEXT']
|
3
|
+
project_name = "texplay"
|
3
4
|
|
4
5
|
require 'rake/clean'
|
5
6
|
require 'rake/gempackagetask'
|
7
|
+
require "#{direc}/lib/#{project_name}/version"
|
6
8
|
|
7
|
-
# get the texplay version
|
8
|
-
require './lib/texplay/version'
|
9
|
-
|
10
|
-
direc = File.dirname(__FILE__)
|
11
|
-
dlext = Config::CONFIG['DLEXT']
|
12
|
-
|
13
|
-
CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o", "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "ext/**/*.def", "ext/**/*.pdb")
|
14
9
|
CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
|
10
|
+
CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o", "ext/**/*~",
|
11
|
+
"ext/**/*#*", "ext/**/*.obj", "ext/**/*.def", "ext/**/*.pdb")
|
15
12
|
|
16
13
|
def apply_spec_defaults(s)
|
17
14
|
s.name = "texplay"
|
@@ -23,13 +20,17 @@ def apply_spec_defaults(s)
|
|
23
20
|
s.description = s.summary
|
24
21
|
s.require_path = 'lib'
|
25
22
|
s.add_dependency("gosu",">=0.7.25")
|
23
|
+
s.add_development_dependency("bacon",">=1.1.0")
|
26
24
|
s.homepage = "http://banisterfiend.wordpress.com/2008/08/23/texplay-an-image-manipulation-tool-for-ruby-and-gosu/"
|
27
25
|
s.has_rdoc = 'yard'
|
28
|
-
s.files =
|
26
|
+
s.files = Dir["Rakefile", "README.markdown", "CHANGELOG",
|
29
27
|
"lib/**/*.rb", "ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c",
|
30
|
-
"examples/*.rb", "examples/media/*", "
|
28
|
+
"examples/*.rb", "examples/media/*", "test/*.rb", "live/*rb", ".gemtest"]
|
31
29
|
end
|
32
30
|
|
31
|
+
task :test do
|
32
|
+
sh "bacon -k #{direc}/test/texplay_spec.rb"
|
33
|
+
end
|
33
34
|
|
34
35
|
[:mingw32, :mswin32].each do |v|
|
35
36
|
namespace v do
|
@@ -50,7 +51,7 @@ namespace :ruby do
|
|
50
51
|
spec = Gem::Specification.new do |s|
|
51
52
|
apply_spec_defaults(s)
|
52
53
|
s.platform = Gem::Platform::RUBY
|
53
|
-
s.extensions = ["ext/
|
54
|
+
s.extensions = ["ext/#{project_name}/extconf.rb"]
|
54
55
|
end
|
55
56
|
|
56
57
|
Rake::GemPackageTask.new(spec) do |pkg|
|
@@ -58,9 +59,31 @@ namespace :ruby do
|
|
58
59
|
pkg.need_tar = false
|
59
60
|
end
|
60
61
|
end
|
62
|
+
|
63
|
+
directories = ["#{direc}/lib/1.8", "#{direc}/lib/1.9"]
|
64
|
+
directories.each { |d| directory d }
|
65
|
+
|
66
|
+
desc "build the 1.8 and 1.9 binaries from source and copy to lib/"
|
67
|
+
task :compile => directories do
|
68
|
+
build_for = proc do |pik_ver, ver|
|
69
|
+
sh %{ \
|
70
|
+
c:\\devkit\\devkitvars.bat && \
|
71
|
+
pik #{pik_ver} && \
|
72
|
+
ruby extconf.rb && \
|
73
|
+
make clean && \
|
74
|
+
make && \
|
75
|
+
cp *.so #{direc}/lib/#{ver} \
|
76
|
+
}
|
77
|
+
end
|
61
78
|
|
79
|
+
chdir("#{direc}/ext/#{project_name}") do
|
80
|
+
build_for.call("187", "1.8")
|
81
|
+
build_for.call("192", "1.9")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
62
85
|
desc "build all platform gems at once"
|
63
|
-
task :gems => ["mingw32:gem", "mswin32:gem", "ruby:gem"]
|
86
|
+
task :gems => [:clean, :rmgems, "mingw32:gem", "mswin32:gem", "ruby:gem"]
|
64
87
|
|
65
88
|
desc "remove all platform gems"
|
66
89
|
task :rmgems => ["ruby:clobber_package"]
|
@@ -73,3 +96,4 @@ task :pushgems => :gems do
|
|
73
96
|
end
|
74
97
|
end
|
75
98
|
end
|
99
|
+
|
@@ -14,6 +14,7 @@
|
|
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
16
|
static void prepare_drawing_mode(action_struct * cur);
|
17
|
+
static void prepare_alpha_blend(action_struct * cur);
|
17
18
|
static void prepare_fill_texture(action_struct * cur);
|
18
19
|
static void prepare_color_control(action_struct * cur);
|
19
20
|
static void prepare_color_select(action_struct * cur);
|
@@ -343,6 +344,8 @@ initialize_action_struct(action_struct * cur, VALUE hash_arg, sync sync_mode)
|
|
343
344
|
cur->pen.has_color_control_proc = false;
|
344
345
|
cur->pen.has_color_control_transform = false;
|
345
346
|
cur->pen.has_source_texture = false;
|
347
|
+
|
348
|
+
/* alpha blending */
|
346
349
|
cur->pen.alpha_blend = false;
|
347
350
|
|
348
351
|
/* set static color control transformations to defaults */
|
@@ -471,8 +474,48 @@ process_common_hash_args(action_struct * cur, VALUE * hash_arg, sync sync_mode,
|
|
471
474
|
prepare_fill_texture(cur);
|
472
475
|
|
473
476
|
/* does the user want to blend alpha values ? */
|
474
|
-
|
475
|
-
|
477
|
+
prepare_alpha_blend(cur);
|
478
|
+
}
|
479
|
+
|
480
|
+
static void
|
481
|
+
prepare_alpha_blend(action_struct * cur)
|
482
|
+
{
|
483
|
+
if(has_optional_hash_arg(cur->hash_arg, "alpha_blend")) {
|
484
|
+
|
485
|
+
VALUE blend_mode = get_from_hash(cur->hash_arg, "alpha_blend");
|
486
|
+
|
487
|
+
/* true is equivalent to default blend mode, 'source' */
|
488
|
+
if(blend_mode == Qtrue)
|
489
|
+
blend_mode = string2sym("source");
|
490
|
+
|
491
|
+
/* where false or nil is passed */
|
492
|
+
if(!RTEST(blend_mode)) {
|
493
|
+
cur->pen.alpha_blend = false;
|
494
|
+
return;
|
495
|
+
}
|
496
|
+
|
497
|
+
cur->pen.alpha_blend = true;
|
498
|
+
|
499
|
+
Check_Type(blend_mode, T_SYMBOL);
|
500
|
+
|
501
|
+
if(blend_mode == string2sym("source")) {
|
502
|
+
cur->pen.alpha_blend_mode = source;
|
503
|
+
}
|
504
|
+
else if(blend_mode == string2sym("dest")) {
|
505
|
+
cur->pen.alpha_blend_mode = dest;
|
506
|
+
}
|
507
|
+
else if(blend_mode == string2sym("source_with_fixed_alpha")) {
|
508
|
+
cur->pen.alpha_blend_mode = source_with_fixed_alpha;
|
509
|
+
}
|
510
|
+
else if(blend_mode == string2sym("dest_with_fixed_alpha")) {
|
511
|
+
cur->pen.alpha_blend_mode = dest_with_fixed_alpha;
|
512
|
+
}
|
513
|
+
else
|
514
|
+
rb_raise(rb_eArgError, "unrecognized blend mode: %s\n.",
|
515
|
+
sym2string(blend_mode));
|
516
|
+
|
517
|
+
}
|
518
|
+
|
476
519
|
|
477
520
|
}
|
478
521
|
|
@@ -591,10 +634,6 @@ prepare_color_control(action_struct * cur)
|
|
591
634
|
if(is_an_array(try_add)) {
|
592
635
|
|
593
636
|
cur->pen.color_add = convert_rb_color_to_rgba(try_add);
|
594
|
-
/* cur->pen.color_add.red = NUM2DBL(get_from_array(try_add, 0)); */
|
595
|
-
/* cur->pen.color_add.green = NUM2DBL(get_from_array(try_add, 1)); */
|
596
|
-
/* cur->pen.color_add.blue = NUM2DBL(get_from_array(try_add, 2)); */
|
597
|
-
/* cur->pen.color_add.alpha = NUM2DBL(get_from_array(try_add, 3)); */
|
598
637
|
|
599
638
|
cur->pen.has_color_control_transform = true;
|
600
639
|
}
|
@@ -602,11 +641,6 @@ prepare_color_control(action_struct * cur)
|
|
602
641
|
|
603
642
|
cur->pen.color_mult = convert_rb_color_to_rgba(try_mult);
|
604
643
|
|
605
|
-
/* cur->pen.color_mult.red = NUM2DBL(get_from_array(try_mult, 0)); */
|
606
|
-
/* cur->pen.color_mult.green = NUM2DBL(get_from_array(try_mult, 1)); */
|
607
|
-
/* cur->pen.color_mult.blue = NUM2DBL(get_from_array(try_mult, 2)); */
|
608
|
-
/* cur->pen.color_mult.alpha = NUM2DBL(get_from_array(try_mult, 3)); */
|
609
|
-
|
610
644
|
cur->pen.has_color_control_transform = true;
|
611
645
|
}
|
612
646
|
|
@@ -1068,33 +1102,68 @@ apply_color_control_transform(action_struct * payload, texture_info * tex, int x
|
|
1068
1102
|
static rgba
|
1069
1103
|
apply_alpha_blend(action_struct * payload, texture_info * tex, int x, int y, rgba blended_pixel)
|
1070
1104
|
{
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1105
|
+
rgba dest_pixel = get_pixel_color(tex, x, y);
|
1106
|
+
rgba finished_pixel;
|
1074
1107
|
|
1075
|
-
|
1076
|
-
|
1108
|
+
if (not_a_color(blended_pixel))
|
1109
|
+
return blended_pixel;
|
1110
|
+
|
1111
|
+
alpha_blend_mode_t blend_mode = payload->pen.alpha_blend_mode;
|
1077
1112
|
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1113
|
+
switch(blend_mode)
|
1114
|
+
{
|
1115
|
+
case source:
|
1116
|
+
case source_with_fixed_alpha:
|
1117
|
+
/** TO DO: rewrite this using sse2 instructions **/
|
1118
|
+
finished_pixel.red = blended_pixel.alpha * blended_pixel.red + (1 - blended_pixel.alpha)
|
1119
|
+
* dest_pixel.red;
|
1120
|
+
|
1121
|
+
finished_pixel.green = blended_pixel.alpha * blended_pixel.green + (1 - blended_pixel.alpha)
|
1122
|
+
* dest_pixel.green;
|
1123
|
+
|
1124
|
+
finished_pixel.blue = blended_pixel.alpha * blended_pixel.blue + (1 - blended_pixel.alpha)
|
1125
|
+
* dest_pixel.blue;
|
1126
|
+
|
1127
|
+
if(blend_mode == source) {
|
1128
|
+
finished_pixel.alpha = blended_pixel.alpha * blended_pixel.alpha + (1 - blended_pixel.alpha)
|
1129
|
+
* dest_pixel.alpha;
|
1130
|
+
}
|
1131
|
+
else {
|
1081
1132
|
|
1082
|
-
|
1083
|
-
|
1133
|
+
// fixed alpha
|
1134
|
+
finished_pixel.alpha = dest_pixel.alpha;
|
1135
|
+
}
|
1136
|
+
|
1137
|
+
break;
|
1138
|
+
case dest:
|
1139
|
+
case dest_with_fixed_alpha:
|
1140
|
+
finished_pixel.red = dest_pixel.alpha * blended_pixel.red + (1 - dest_pixel.alpha)
|
1084
1141
|
* dest_pixel.red;
|
1085
1142
|
|
1086
|
-
|
1143
|
+
finished_pixel.green = dest_pixel.alpha * blended_pixel.green + (1 - dest_pixel.alpha)
|
1087
1144
|
* dest_pixel.green;
|
1088
1145
|
|
1089
|
-
|
1146
|
+
finished_pixel.blue = dest_pixel.alpha * blended_pixel.blue + (1 - dest_pixel.alpha)
|
1090
1147
|
* dest_pixel.blue;
|
1091
1148
|
|
1149
|
+
if(blend_mode == dest) {
|
1150
|
+
finished_pixel.alpha = dest_pixel.alpha * blended_pixel.alpha + (1 - dest_pixel.alpha)
|
1151
|
+
* dest_pixel.alpha;
|
1152
|
+
}
|
1153
|
+
else {
|
1092
1154
|
|
1093
|
-
|
1094
|
-
|
1155
|
+
// fixed alpha
|
1156
|
+
finished_pixel.alpha = dest_pixel.alpha;
|
1157
|
+
}
|
1158
|
+
|
1159
|
+
break;
|
1160
|
+
default:
|
1161
|
+
rb_raise(rb_eRuntimeError,
|
1162
|
+
"apply_alpha_blend() impossible error. got %d\n", blend_mode);
|
1095
1163
|
|
1164
|
+
}
|
1096
1165
|
|
1097
|
-
|
1166
|
+
return finished_pixel;
|
1098
1167
|
}
|
1099
1168
|
|
1100
1169
|
/* NEW from utils.c */
|
data/ext/texplay/texplay.h
CHANGED
@@ -29,15 +29,15 @@
|
|
29
29
|
|
30
30
|
/* enums */
|
31
31
|
typedef enum e_bool {
|
32
|
-
|
32
|
+
false, true
|
33
33
|
} bool;
|
34
34
|
|
35
35
|
typedef enum e_color {
|
36
|
-
|
36
|
+
red, green, blue, alpha
|
37
37
|
} color_t;
|
38
38
|
|
39
39
|
typedef enum e_sync_mode {
|
40
|
-
|
40
|
+
lazy_sync, eager_sync, no_sync
|
41
41
|
} sync;
|
42
42
|
|
43
43
|
|
@@ -54,6 +54,10 @@ typedef enum {
|
|
54
54
|
difference, exclusion
|
55
55
|
} draw_mode;
|
56
56
|
|
57
|
+
typedef enum {
|
58
|
+
source, dest, source_with_fixed_alpha, dest_with_fixed_alpha
|
59
|
+
} alpha_blend_mode_t;
|
60
|
+
|
57
61
|
/* structs */
|
58
62
|
typedef struct s_rgba {
|
59
63
|
float red, green, blue, alpha;
|
@@ -67,80 +71,81 @@ typedef struct {
|
|
67
71
|
|
68
72
|
/* stores image data */
|
69
73
|
typedef struct {
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
int width, height;
|
75
|
+
float top, left;
|
76
|
+
int tname;
|
77
|
+
float * td_array;
|
78
|
+
int yincr, firstpixel;
|
79
|
+
int x_offset, y_offset;
|
80
|
+
VALUE image;
|
77
81
|
} texture_info;
|
78
82
|
|
79
83
|
|
80
84
|
/* convenience macro */
|
81
85
|
#define IMAGE_BOUNDS(X) ((image_bounds *) (X))
|
82
86
|
typedef struct {
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
+
int xmin;
|
88
|
+
int ymin;
|
89
|
+
int xmax;
|
90
|
+
int ymax;
|
87
91
|
} image_bounds;
|
88
92
|
|
89
93
|
|
90
94
|
typedef struct action_struct {
|
91
|
-
|
92
|
-
|
95
|
+
int xmin, ymin, xmax, ymax;
|
96
|
+
sync sync_mode;
|
93
97
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
+
/* pointer to associated texture */
|
99
|
+
/* a bit of a kludge having this here
|
100
|
+
since it's only being used by convert_image_local_color_to_rgba */
|
101
|
+
texture_info * tex;
|
98
102
|
|
99
|
-
|
100
|
-
|
101
|
-
/* action color */
|
102
|
-
rgba color;
|
103
|
+
VALUE hash_arg;
|
103
104
|
|
104
|
-
|
105
|
-
|
105
|
+
/* action color */
|
106
|
+
rgba color;
|
106
107
|
|
107
|
-
|
108
|
-
|
109
|
-
VALUE color_control_proc;
|
110
|
-
int color_control_arity;
|
108
|
+
/* pen data */
|
109
|
+
struct {
|
111
110
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
111
|
+
/* color control, dynamic */
|
112
|
+
bool has_color_control_proc;
|
113
|
+
VALUE color_control_proc;
|
114
|
+
int color_control_arity;
|
116
115
|
|
117
|
-
|
118
|
-
|
119
|
-
|
116
|
+
/* color control, static */
|
117
|
+
bool has_color_control_transform;
|
118
|
+
rgba color_mult;
|
119
|
+
rgba color_add;
|
120
120
|
|
121
|
-
|
122
|
-
|
123
|
-
|
121
|
+
/* texture fill */
|
122
|
+
bool has_source_texture;
|
123
|
+
texture_info source_tex;
|
124
124
|
|
125
|
-
|
126
|
-
|
125
|
+
/* lerp */
|
126
|
+
bool has_lerp;
|
127
|
+
float lerp;
|
127
128
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
129
|
+
/* alpha blend */
|
130
|
+
bool alpha_blend;
|
131
|
+
alpha_blend_mode_t alpha_blend_mode;
|
132
|
+
|
133
|
+
/* drawing mode */
|
134
|
+
bool has_drawing_mode;
|
135
|
+
draw_mode drawing_mode;
|
136
|
+
|
137
|
+
/* tolerance */
|
138
|
+
bool has_tolerance;
|
139
|
+
float tolerance;
|
140
|
+
|
141
|
+
/* color selection */
|
142
|
+
bool has_color_select;
|
143
|
+
rgba_list source_select;
|
144
|
+
rgba_list source_ignore;
|
145
|
+
rgba_list dest_select;
|
146
|
+
rgba_list dest_ignore;
|
142
147
|
|
143
|
-
|
148
|
+
} pen;
|
144
149
|
|
145
150
|
} action_struct;
|
146
151
|
|
data/lib/1.8/texplay.so
CHANGED
Binary file
|
data/lib/1.9/texplay.so
CHANGED
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
direc = File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require "#{direc}/../texplay"
|
4
|
+
|
5
|
+
module TexPlay
|
6
|
+
Win = Gosu::Window.new(0, 0, false)
|
7
|
+
|
8
|
+
set_options :sync_mode => :no_sync
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def load(name)
|
12
|
+
Gosu::Image.new(Win, name)
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :original_create_image, :create_image
|
16
|
+
def create_image(width, height, options={})
|
17
|
+
original_create_image(Win, width, height, options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: iso-8859-1 -*-
|
1
2
|
# This code is never run; it is just here so we can document the C functions.
|
2
3
|
|
3
4
|
|
@@ -44,7 +45,7 @@ module TexPlay
|
|
44
45
|
def each(&block)
|
45
46
|
end
|
46
47
|
|
47
|
-
# Fill at a given position.
|
48
|
+
# Perform a Flood Fill at a given position.
|
48
49
|
#
|
49
50
|
# @param [Number] x
|
50
51
|
# @param [Number] y
|
@@ -186,4 +187,4 @@ module TexPlay
|
|
186
187
|
# @return [String] Raw binary data (blob) in RGBA byte order.
|
187
188
|
def to_blob
|
188
189
|
end
|
189
|
-
end
|
190
|
+
end
|
data/lib/texplay/version.rb
CHANGED
data/lib/texplay-contrib.rb
CHANGED
@@ -1,171 +1,164 @@
|
|
1
|
-
begin
|
2
|
-
require 'rubygems'
|
3
|
-
rescue LoadError
|
4
|
-
end
|
5
|
-
|
6
|
-
require 'texplay'
|
7
|
-
|
8
1
|
# to bring in String#each_char for 1.8
|
9
2
|
if RUBY_VERSION =~ /1.8/
|
10
|
-
|
3
|
+
require 'jcode'
|
11
4
|
end
|
12
5
|
|
13
6
|
# setup will be executed straight after Gosu::Image instantiation
|
14
7
|
TexPlay::on_setup do
|
15
|
-
|
16
|
-
|
8
|
+
@turtle_pos = TexPlay::TPPoint.new(width / 2, height / 2 )
|
9
|
+
@turtle_angle = 0
|
17
10
|
end
|
18
11
|
|
19
12
|
|
20
13
|
TexPlay::create_macro(:move_to) do |x, y|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
14
|
+
capture {
|
15
|
+
@turtle_pos.x = x
|
16
|
+
@turtle_pos.y = y
|
17
|
+
}
|
25
18
|
end
|
26
19
|
|
27
20
|
TexPlay::create_macro(:move_rel) do |dx, dy|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
21
|
+
capture {
|
22
|
+
@turtle_pos.x += dx
|
23
|
+
@turtle_pos.y += dy
|
24
|
+
}
|
32
25
|
end
|
33
26
|
|
34
27
|
TexPlay::create_macro(:line_to) do |x, y, *other|
|
35
|
-
|
36
|
-
|
28
|
+
capture {
|
29
|
+
line(@turtle_pos.x, @turtle_pos.y, x, y, *other)
|
37
30
|
|
38
|
-
|
39
|
-
|
31
|
+
@turtle_pos.x, @turtle_pos.y = x, y
|
32
|
+
}
|
40
33
|
end
|
41
34
|
|
42
35
|
TexPlay::create_macro(:line_rel) do |dx, dy, *other|
|
43
|
-
|
44
|
-
|
45
|
-
|
36
|
+
capture {
|
37
|
+
x = @turtle_pos.x + dx
|
38
|
+
y = @turtle_pos.y + dy
|
46
39
|
|
47
|
-
|
40
|
+
line(@turtle_pos.x, @turtle_pos.y, x, y, *other)
|
48
41
|
|
49
|
-
|
50
|
-
|
42
|
+
@turtle_pos.x, @turtle_pos.y = x, y
|
43
|
+
}
|
51
44
|
end
|
52
45
|
|
53
46
|
TexPlay::create_macro(:turn_to) do |a|
|
54
|
-
|
55
|
-
|
56
|
-
|
47
|
+
capture {
|
48
|
+
@turtle_angle = a
|
49
|
+
}
|
57
50
|
end
|
58
51
|
|
59
52
|
TexPlay::create_macro(:turn) do |da|
|
60
|
-
|
61
|
-
|
62
|
-
|
53
|
+
capture {
|
54
|
+
@turtle_angle += da
|
55
|
+
}
|
63
56
|
end
|
64
57
|
|
65
58
|
TexPlay::create_macro(:forward) do |dist, *other|
|
66
|
-
|
67
|
-
|
59
|
+
capture {
|
60
|
+
visible = other.shift
|
68
61
|
|
69
|
-
|
62
|
+
radians_per_degree = 0.0174532925199433
|
70
63
|
|
71
|
-
|
72
|
-
|
64
|
+
x = @turtle_pos.x + dist * Math::cos(radians_per_degree * @turtle_angle)
|
65
|
+
y = @turtle_pos.y + dist * Math::sin(radians_per_degree * @turtle_angle)
|
73
66
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
67
|
+
if(visible) then
|
68
|
+
line_to(x, y, *other)
|
69
|
+
else
|
70
|
+
move_to(x, y)
|
71
|
+
end
|
72
|
+
}
|
80
73
|
end
|
81
74
|
|
82
75
|
# L-System code
|
83
76
|
# adding LSystem class to TexPlay module
|
84
77
|
class TexPlay::LSystem
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
instance_eval(&block) if block
|
89
|
-
end
|
78
|
+
def initialize(&block)
|
79
|
+
@rules = {}
|
90
80
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
81
|
+
instance_eval(&block) if block
|
82
|
+
end
|
83
|
+
|
84
|
+
def rule(new_rule)
|
85
|
+
@rules.merge!(new_rule)
|
86
|
+
end
|
87
|
+
|
88
|
+
def atom(new_atom)
|
89
|
+
@atom = new_atom
|
90
|
+
end
|
91
|
+
|
92
|
+
def angle(new_angle=nil)
|
93
|
+
return @angle if !new_angle
|
94
|
+
@angle = new_angle
|
95
|
+
end
|
96
|
+
|
97
|
+
def produce_string(order)
|
98
|
+
order = order[:order]
|
99
|
+
string = @atom.dup
|
100
|
+
|
101
|
+
order.times do
|
102
|
+
i = 0
|
103
|
+
while(i < string.length)
|
104
|
+
sub = @rules[string[i, 1]]
|
107
105
|
|
108
|
-
|
109
|
-
i = 0
|
110
|
-
while(i < string.length)
|
111
|
-
sub = @rules[string[i, 1]]
|
112
|
-
|
113
|
-
string[i] = sub if sub
|
114
|
-
|
115
|
-
i += sub ? sub.length : 1
|
116
|
-
end
|
117
|
-
end
|
106
|
+
string[i] = sub if sub
|
118
107
|
|
119
|
-
|
108
|
+
i += sub ? sub.length : 1
|
109
|
+
end
|
120
110
|
end
|
111
|
+
|
112
|
+
string
|
113
|
+
end
|
121
114
|
end
|
122
115
|
|
123
116
|
# L-System macro
|
124
117
|
TexPlay::create_macro(:lsystem) do |x, y, system, options|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
118
|
+
capture {
|
119
|
+
theta = system.angle
|
120
|
+
turtle_stack = []
|
121
|
+
move_to(x, y)
|
122
|
+
line_length = options[:line_length] || 1
|
123
|
+
|
124
|
+
system.produce_string(options).each_char do |v|
|
125
|
+
|
126
|
+
case v
|
127
|
+
when "F"
|
128
|
+
forward(line_length, true)
|
129
|
+
when "+"
|
130
|
+
turn(theta)
|
131
|
+
when "-"
|
132
|
+
turn(-theta)
|
133
|
+
when "["
|
134
|
+
turtle_stack.push([@turtle_pos.dup, @turtle_angle])
|
135
|
+
when "]"
|
136
|
+
@turtle_pos, @turtle_angle = turtle_stack.pop
|
137
|
+
end
|
138
|
+
end
|
139
|
+
}
|
147
140
|
end
|
148
141
|
|
149
142
|
# Scaling
|
150
143
|
# uses nearest-neighbour
|
151
144
|
TexPlay::create_macro(:splice_and_scale) do |img, cx, cy, *options|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
145
|
+
options = options.first ? options.first : {}
|
146
|
+
|
147
|
+
options = {
|
148
|
+
:color_control => proc do |c1, c2, x, y|
|
149
|
+
factor = options[:factor] || 1
|
150
|
+
factor_x = options[:factor_x] || factor
|
151
|
+
factor_y = options[:factor_y] || factor
|
152
|
+
|
153
|
+
x = factor_x * (x - cx) + cx
|
154
|
+
y = factor_y * (y - cy) + cy
|
155
|
+
|
156
|
+
rect x, y, x + factor_x, y + factor_y, :color => c2, :fill => true
|
157
|
+
:none
|
158
|
+
end
|
159
|
+
}.merge!(options)
|
160
|
+
|
161
|
+
splice img, cx, cy, options
|
162
|
+
|
163
|
+
self
|
171
164
|
end
|
data/lib/texplay.rb
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
direc = File.expand_path(File.dirname(__FILE__))
|
5
5
|
|
6
6
|
# include gosu first
|
7
|
-
require 'rbconfig'
|
8
7
|
require 'gosu'
|
9
8
|
require "#{direc}/texplay/version"
|
10
9
|
|
@@ -14,13 +13,12 @@ module TexPlay
|
|
14
13
|
class << self
|
15
14
|
def on_setup(&block)
|
16
15
|
raise "need a block" if !block
|
17
|
-
|
18
16
|
@__init_procs__ ||= []
|
19
17
|
@__init_procs__.push(block)
|
20
18
|
end
|
21
19
|
|
22
20
|
def setup(receiver)
|
23
|
-
if @__init_procs__
|
21
|
+
if @__init_procs__
|
24
22
|
@__init_procs__.each do |init_proc|
|
25
23
|
receiver.instance_eval(&init_proc)
|
26
24
|
end
|
@@ -36,7 +34,12 @@ module TexPlay
|
|
36
34
|
raise ArgumentError, "Height and width must be positive" if height <= 0 or width <= 0
|
37
35
|
|
38
36
|
img = Gosu::Image.new(window, EmptyImageStub.new(width, height), :caching => options[:caching])
|
39
|
-
|
37
|
+
|
38
|
+
# this should be a major speedup (avoids both a cache and a sync
|
39
|
+
# if color is alpha (default)
|
40
|
+
if options[:color] != :alpha
|
41
|
+
img.rect 0, 0, img.width - 1, img.height - 1, :color => options[:color], :fill => true
|
42
|
+
end
|
40
43
|
|
41
44
|
img
|
42
45
|
end
|
@@ -46,7 +49,7 @@ module TexPlay
|
|
46
49
|
# Image can be :tileable, but it will break if it is tileable AND gets modified after creation.
|
47
50
|
def from_blob(window, blob_data, width, height, options={})
|
48
51
|
options = {
|
49
|
-
:caching =>
|
52
|
+
:caching => false,
|
50
53
|
:tileable => false,
|
51
54
|
}.merge!(options)
|
52
55
|
|
@@ -71,7 +74,7 @@ module TexPlay
|
|
71
74
|
# default values defined here
|
72
75
|
def set_defaults
|
73
76
|
@options = {
|
74
|
-
:caching =>
|
77
|
+
:caching => :lazy
|
75
78
|
}
|
76
79
|
end
|
77
80
|
|
@@ -121,6 +124,7 @@ module TexPlay
|
|
121
124
|
#
|
122
125
|
# This object duck-types an RMagick image (#rows, #columns, #to_blob), so that Gosu will import it.
|
123
126
|
class ImageStub
|
127
|
+
|
124
128
|
# @return [Integer]
|
125
129
|
attr_reader :rows, :columns
|
126
130
|
|
@@ -153,14 +157,15 @@ module TexPlay
|
|
153
157
|
end
|
154
158
|
|
155
159
|
# bring in user-defined extensions to TexPlay
|
156
|
-
dlext = Config::CONFIG['DLEXT']
|
157
160
|
begin
|
158
161
|
if RUBY_VERSION && RUBY_VERSION =~ /1.9/
|
159
|
-
require "#{direc}/1.9/texplay
|
162
|
+
require "#{direc}/1.9/texplay"
|
160
163
|
else
|
161
|
-
require "#{direc}/1.8/texplay
|
164
|
+
require "#{direc}/1.8/texplay"
|
162
165
|
end
|
163
166
|
rescue LoadError => e
|
167
|
+
require 'rbconfig'
|
168
|
+
dlext = Config::CONFIG['DLEXT']
|
164
169
|
require "#{direc}/texplay.#{dlext}"
|
165
170
|
end
|
166
171
|
|
@@ -203,16 +208,33 @@ module Gosu
|
|
203
208
|
options = {
|
204
209
|
:caching => TexPlay.get_options[:caching]
|
205
210
|
}.merge!(options)
|
206
|
-
|
207
|
-
|
211
|
+
|
212
|
+
caching_mode = options[:caching]
|
213
|
+
|
214
|
+
# we can't manipulate large images, so skip them.
|
208
215
|
if obj.width <= (TexPlay::TP_MAX_QUAD_SIZE) &&
|
209
|
-
obj.height <= (TexPlay::TP_MAX_QUAD_SIZE)
|
210
|
-
|
216
|
+
obj.height <= (TexPlay::TP_MAX_QUAD_SIZE)
|
217
|
+
|
218
|
+
if caching_mode
|
219
|
+
if caching_mode == :lazy
|
220
|
+
|
221
|
+
# only cache if quad already cached (to refresh old data)
|
222
|
+
# otherwise cache lazily at point of first TexPlay call
|
223
|
+
obj.refresh_cache if obj.quad_cached?
|
224
|
+
|
225
|
+
else
|
226
|
+
|
227
|
+
# force a cache - this obviates the need for a
|
228
|
+
# potentialy expensive runtime cache of the image by
|
229
|
+
# moving the cache to load-time
|
230
|
+
obj.refresh_cache
|
231
|
+
end
|
232
|
+
end
|
211
233
|
end
|
212
234
|
|
213
235
|
# run custom setup
|
214
236
|
TexPlay.setup(obj)
|
215
|
-
|
237
|
+
|
216
238
|
obj.instance_variable_set(:@__window__, window)
|
217
239
|
|
218
240
|
obj
|
data/live/live.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
direc = File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require "#{direc}/../lib/texplay"
|
5
|
+
require 'pry'
|
6
|
+
|
7
|
+
WIDTH = 640
|
8
|
+
HEIGHT = 480
|
9
|
+
|
10
|
+
class Gosu::Image
|
11
|
+
attr_accessor :x, :y
|
12
|
+
|
13
|
+
alias_method :orig_init, :initialize
|
14
|
+
def initialize(*args)
|
15
|
+
@x = WIDTH / 2
|
16
|
+
@y = HEIGHT / 2
|
17
|
+
orig_init(*args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class WinClass < Gosu::Window
|
22
|
+
|
23
|
+
class View
|
24
|
+
attr_accessor :zoom, :rotate
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@zoom = 1
|
28
|
+
@rotate = 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def reset
|
32
|
+
@zoom = 1
|
33
|
+
@rotate = 0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :images, :view
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
super(WIDTH, HEIGHT, false)
|
41
|
+
Gosu.enable_undocumented_retrofication
|
42
|
+
|
43
|
+
@images = []
|
44
|
+
@view = View.new
|
45
|
+
@pry_instance = Pry.new :prompt => [Proc.new { "(live)> " }, Proc.new { "(live)* " }]
|
46
|
+
|
47
|
+
@img = TexPlay.create_image(self, 200, 200)
|
48
|
+
@img.rect 0, 0, @img.width - 1, @img.height - 1
|
49
|
+
|
50
|
+
images << @img
|
51
|
+
@binding = binding
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_image(width, height, options={})
|
55
|
+
TexPlay.create_image(self, width, height, options)
|
56
|
+
end
|
57
|
+
|
58
|
+
def load_image(file)
|
59
|
+
Gosu::Image.new(self, file)
|
60
|
+
end
|
61
|
+
|
62
|
+
def show_image(image)
|
63
|
+
images << image
|
64
|
+
end
|
65
|
+
|
66
|
+
def hide_image(image)
|
67
|
+
images.delete(image)
|
68
|
+
end
|
69
|
+
|
70
|
+
def draw
|
71
|
+
images.uniq!
|
72
|
+
images.each do |v|
|
73
|
+
v.draw_rot(v.x, v.y, 1, view.rotate, 0.5, 0.5, view.zoom, view.zoom)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def update
|
78
|
+
@pry_instance.rep(@binding)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
w = WinClass.new
|
83
|
+
|
84
|
+
w.show
|
85
|
+
|
data/test/image_spec.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
direc = File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require "#{direc}/../lib/texplay"
|
4
|
+
|
5
|
+
class Module
|
6
|
+
public :remove_const
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Gosu::Image do
|
10
|
+
before do
|
11
|
+
@window = Gosu::Window.new(640, 480, false)
|
12
|
+
NormalImageSize = [Gosu::MAX_TEXTURE_SIZE - 2, Gosu::MAX_TEXTURE_SIZE - 2]
|
13
|
+
TooLargeImageSize = [2000, 2000]
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
Object.remove_const(:NormalImageSize)
|
18
|
+
Object.remove_const(:TooLargeImageSize)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "Gosu::Image#new (patched by TexPlay)" do
|
22
|
+
describe "caching option" do
|
23
|
+
it "should not cache image if :caching => false" do
|
24
|
+
source_image = TexPlay.create_image(@window, *NormalImageSize)
|
25
|
+
source_image.quad_cached?.should == false
|
26
|
+
|
27
|
+
image = Gosu::Image.new(@window, source_image, :caching => false)
|
28
|
+
image.width.should == NormalImageSize[0]
|
29
|
+
image.height.should == NormalImageSize[1]
|
30
|
+
|
31
|
+
image.quad_cached?.should == false
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should cache the image if :caching => true" do
|
35
|
+
source_image = TexPlay.create_image(@window, *NormalImageSize)
|
36
|
+
|
37
|
+
image = Gosu::Image.new(@window, source_image, :caching => true)
|
38
|
+
image.width.should == NormalImageSize[0]
|
39
|
+
image.height.should == NormalImageSize[1]
|
40
|
+
|
41
|
+
image.quad_cached?.should == true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
$LOAD_PATH.unshift File.join(File.expand_path(__FILE__), '..', 'lib','texplay')
|
2
|
+
direc = File.dirname(__FILE__)
|
3
|
+
|
4
|
+
require "#{direc}/../lib/texplay"
|
5
|
+
|
6
|
+
describe TexPlay do
|
7
|
+
described_class = TexPlay
|
8
|
+
|
9
|
+
before do
|
10
|
+
@window = Gosu::Window.new(640, 480, false)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#create_image" do
|
14
|
+
it "should create a blank image of the correct size" do
|
15
|
+
width, height = 30, 10
|
16
|
+
image = described_class.create_image(@window, width, height)
|
17
|
+
|
18
|
+
image.width.should == width
|
19
|
+
image.height.should == height
|
20
|
+
|
21
|
+
width.times do |x|
|
22
|
+
height.times do |y|
|
23
|
+
image.get_pixel(x, y).should == [0.0, 0.0, 0.0, 0.0]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should create a coloured image of the correct size" do
|
29
|
+
width, height = 10, 30
|
30
|
+
color = [1.0, 1.0, 0.0, 1.0]
|
31
|
+
image = described_class.create_image(@window, width, height, :color => color)
|
32
|
+
|
33
|
+
image.width.should == width
|
34
|
+
image.height.should == height
|
35
|
+
|
36
|
+
width.times do |x|
|
37
|
+
height.times do |y|
|
38
|
+
image.get_pixel(x, y).should == color
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should raise an error if an image dimension is 0 or less" do
|
44
|
+
lambda { described_class.create_image(@window, 0, 0)}.should.raise ArgumentError
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO: Should probably be an ArgumentError.
|
48
|
+
it "should NOT raise an error if the image would be too large (as uses raw blobs, doesnt use TexPlay at all)" do
|
49
|
+
too_big = TexPlay::TP_MAX_QUAD_SIZE + 1
|
50
|
+
[[too_big, 5], [10, too_big], [too_big, too_big]].each do |width, height|
|
51
|
+
lambda { described_class.create_image(@window, width, height)}.should.not.raise Exception
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#clear" do
|
57
|
+
it "should clear an image to the correct color" do
|
58
|
+
img = described_class.create_image(@window, 10, 10)
|
59
|
+
img.clear :color => :red
|
60
|
+
(0...img.width).each do |x|
|
61
|
+
(0...img.height).each do |y|
|
62
|
+
img.get_pixel(x,y).should == [1,0,0,1]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#from_blob" do
|
69
|
+
# it "should create an image with the requested pixel data and size" do
|
70
|
+
# # 4 x 3, with columns of red, blue, green, transparent.
|
71
|
+
# gosu_colors = [[255, 0, 0, 255], [0, 255, 0, 255], [0, 0, 255, 255], [0, 0, 0, 0]]
|
72
|
+
# texplay_colors = gosu_colors.map {|a| a.map {|c| c / 255.0 } }
|
73
|
+
# width, height = gosu_colors.size, 3
|
74
|
+
|
75
|
+
# image = described_class.from_blob(@window, (gosu_colors * height).flatten.pack('C*'), width, height)
|
76
|
+
|
77
|
+
# image.width.should == width
|
78
|
+
# image.height.should == height
|
79
|
+
|
80
|
+
# texplay_colors.each_with_index do |color, x|
|
81
|
+
# 3.times do |y|
|
82
|
+
# image.get_pixel(x, y).should == color
|
83
|
+
# end
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
|
87
|
+
it "should raise an error if the image size is not correct for the blob data" do
|
88
|
+
lambda { described_class.from_blob(@window, [1, 1, 1, 1].pack("C*"), 2, 1) }.should.raise ArgumentError
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should raise an error if an image dimension is 0 or less" do
|
92
|
+
lambda { described_class.from_blob(@window, '', 0, 0) }.should.raise ArgumentError
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "alpha_blend" do
|
97
|
+
it "should alpha blend using source alpha and not fixing alpha" do
|
98
|
+
img1 = described_class.create_image(@window, 10, 10).clear :color => [1, 0, 0, 1]
|
99
|
+
img1.clear :color => [0, 0, 1, 0.5], :alpha_blend => :source
|
100
|
+
img1.get_pixel(5, 5).should == [0.5, 0, 0.5, 0.75]
|
101
|
+
end
|
102
|
+
|
103
|
+
it "hash params true and :source should be equivalent" do
|
104
|
+
img1 = described_class.create_image(@window, 10, 10).clear :color => [1, 0, 0, 1]
|
105
|
+
img2 = img1.dup
|
106
|
+
img1.clear :color => [0, 0, 1, 0.5], :alpha_blend => :source
|
107
|
+
img2.clear :color => [0, 0, 1, 0.5], :alpha_blend => true
|
108
|
+
|
109
|
+
img1.get_pixel(5, 5).should == [0.5, 0, 0.5, 0.75]
|
110
|
+
img2.get_pixel(5, 5).should == [0.5, 0, 0.5, 0.75]
|
111
|
+
end
|
112
|
+
|
113
|
+
it "false or nil should prevent alpha blending" do
|
114
|
+
img1 = described_class.create_image(@window, 10, 10).clear :color => [1, 0, 0, 1]
|
115
|
+
img2 = img1.dup
|
116
|
+
img1.clear :color => [0, 0, 1, 0.5], :alpha_blend => false
|
117
|
+
img2.clear :color => [0, 0, 1, 0.5], :alpha_blend => nil
|
118
|
+
|
119
|
+
img1.get_pixel(5, 5).should == [0, 0, 1, 0.5]
|
120
|
+
img2.get_pixel(5, 5).should == [0, 0, 1, 0.5]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should alpha blend using dest alpha and not fixing alpha" do
|
124
|
+
img1 = described_class.create_image(@window, 10, 10).clear :color => [1, 0, 0, 0.5]
|
125
|
+
img1.clear :color => [0, 0, 1, 1], :alpha_blend => :dest
|
126
|
+
img1.get_pixel(5, 5).should == [0.5, 0, 0.5, 0.75]
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should alpha blend using source alpha and fixing alpha" do
|
130
|
+
img1 = described_class.create_image(@window, 10, 10).clear :color => [1, 0, 0, 1]
|
131
|
+
img1.clear :color => [0, 0, 1, 0.5], :alpha_blend => :source_with_fixed_alpha
|
132
|
+
img1.get_pixel(5, 5).should == [0.5, 0, 0.5, 1]
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should alpha blend using dest alpha and fixing alpha" do
|
136
|
+
img1 = described_class.create_image(@window, 10, 10).clear :color => [1, 0, 0, 0.5]
|
137
|
+
img1.clear :color => [0, 0, 1, 1], :alpha_blend => :dest_with_fixed_alpha
|
138
|
+
img1.get_pixel(5, 5).should == [0.5, 0, 0.5, 0.5]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: texplay
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 21
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 3
|
10
|
+
version: 0.3.3
|
11
11
|
platform: i386-mswin32
|
12
12
|
authors:
|
13
13
|
- John Mair (banisterfiend)
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-02-22 00:00:00 +13:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -34,6 +34,22 @@ dependencies:
|
|
34
34
|
version: 0.7.25
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: bacon
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 19
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 1
|
49
|
+
- 0
|
50
|
+
version: 1.1.0
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
37
53
|
description: TexPlay is a light-weight image manipulation framework for Ruby and Gosu
|
38
54
|
email: jrmair@gmail.com
|
39
55
|
executables: []
|
@@ -46,6 +62,7 @@ files:
|
|
46
62
|
- Rakefile
|
47
63
|
- README.markdown
|
48
64
|
- CHANGELOG
|
65
|
+
- lib/texplay/alone.rb
|
49
66
|
- lib/texplay/c_function_docs.rb
|
50
67
|
- lib/texplay/version.rb
|
51
68
|
- lib/texplay-contrib.rb
|
@@ -122,11 +139,13 @@ files:
|
|
122
139
|
- examples/media/sand1.png
|
123
140
|
- examples/media/sunset.png
|
124
141
|
- examples/media/texplay.png
|
125
|
-
-
|
126
|
-
-
|
142
|
+
- test/image_spec.rb
|
143
|
+
- test/texplay_spec.rb
|
144
|
+
- live/live.rb
|
145
|
+
- .gemtest
|
127
146
|
- lib/1.8/texplay.so
|
128
147
|
- lib/1.9/texplay.so
|
129
|
-
has_rdoc:
|
148
|
+
has_rdoc: true
|
130
149
|
homepage: http://banisterfiend.wordpress.com/2008/08/23/texplay-an-image-manipulation-tool-for-ruby-and-gosu/
|
131
150
|
licenses: []
|
132
151
|
|
@@ -156,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
175
|
requirements: []
|
157
176
|
|
158
177
|
rubyforge_project:
|
159
|
-
rubygems_version: 1.
|
178
|
+
rubygems_version: 1.5.2
|
160
179
|
signing_key:
|
161
180
|
specification_version: 3
|
162
181
|
summary: TexPlay is a light-weight image manipulation framework for Ruby and Gosu
|
data/spec/image_spec.rb
DELETED
data/spec/texplay_spec.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.join(File.expand_path(__FILE__), '..', 'lib','texplay')
|
2
|
-
|
3
|
-
require 'texplay'
|
4
|
-
|
5
|
-
describe TexPlay do
|
6
|
-
before :each do
|
7
|
-
@window = Gosu::Window.new(640, 480, false)
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "#create_image" do
|
11
|
-
it "should create a blank image of the correct size" do
|
12
|
-
width, height = 30, 10
|
13
|
-
image = described_class.create_image(@window, width, height)
|
14
|
-
|
15
|
-
image.width.should == width
|
16
|
-
image.height.should == height
|
17
|
-
|
18
|
-
width.times do |x|
|
19
|
-
height.times do |y|
|
20
|
-
image.get_pixel(x, y).should == [0.0, 0.0, 0.0, 0.0]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should create a coloured image of the correct size" do
|
26
|
-
width, height = 10, 30
|
27
|
-
color = [1.0, 1.0, 0.0, 1.0]
|
28
|
-
image = described_class.create_image(@window, width, height, :color => color)
|
29
|
-
|
30
|
-
image.width.should == width
|
31
|
-
image.height.should == height
|
32
|
-
|
33
|
-
width.times do |x|
|
34
|
-
height.times do |y|
|
35
|
-
image.get_pixel(x, y).should == color
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should raise an error if an image dimension is 0 or less" do
|
41
|
-
lambda { described_class.create_image(@window, 0, 0)}.should raise_error ArgumentError
|
42
|
-
end
|
43
|
-
|
44
|
-
# TODO: Should probably be an ArgumentError.
|
45
|
-
it "should raise an error if the image would be too large" do
|
46
|
-
too_big = TexPlay::TP_MAX_QUAD_SIZE + 1
|
47
|
-
[[too_big, 5], [10, too_big], [too_big, too_big]].each do |width, height|
|
48
|
-
lambda { described_class.create_image(@window, width, height)}.should raise_error Exception
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "#from_blob" do
|
54
|
-
it "should create an image with the requested pixel data and size" do
|
55
|
-
# 4 x 3, with columns of red, blue, green, transparent.
|
56
|
-
gosu_colors = [[255, 0, 0, 255], [0, 255, 0, 255], [0, 0, 255, 255], [0, 0, 0, 0]]
|
57
|
-
texplay_colors = gosu_colors.map {|a| a.map {|c| c / 255.0 } }
|
58
|
-
width, height = gosu_colors.size, 3
|
59
|
-
|
60
|
-
image = described_class.from_blob(@window, (gosu_colors * height).flatten.pack('C*'), width, height)
|
61
|
-
|
62
|
-
image.width.should == width
|
63
|
-
image.height.should == height
|
64
|
-
|
65
|
-
texplay_colors.each_with_index do |color, x|
|
66
|
-
3.times do |y|
|
67
|
-
image.get_pixel(x, y).should == color
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should raise an error if the image size is not correct for the blob data" do
|
73
|
-
lambda { described_class.from_blob(@window, [1, 1, 1, 1].pack("C*"), 2, 1) }.should raise_error ArgumentError
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should raise an error if an image dimension is 0 or less" do
|
77
|
-
lambda { described_class.from_blob(@window, '', 0, 0) }.should raise_error ArgumentError
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|