texplay 0.3.1-i386-mingw32 → 0.3.3-i386-mingw32
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/.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-mingw32
|
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
|