rmagick4j 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +84 -0
- data/LICENSE.txt +9 -0
- data/Manifest.txt +142 -0
- data/README.txt +25 -0
- data/Rakefile +109 -0
- data/lib/RMagick.rb +1861 -0
- data/lib/jhlabs-filters.jar +0 -0
- data/lib/magick4j.jar +0 -0
- data/lib/rmagick4j/constants.rb +21 -0
- data/lib/rmagick4j/draw.rb +86 -0
- data/lib/rmagick4j/enum.rb +120 -0
- data/lib/rmagick4j/gradient_fill.rb +14 -0
- data/lib/rmagick4j/image.rb +289 -0
- data/lib/rmagick4j/image_list.rb +21 -0
- data/lib/rmagick4j/pixel.rb +170 -0
- data/lib/rmagick4j/rmagick4j.rb +19 -0
- data/lib/rmagick4j/texture_fill.rb +14 -0
- data/lib/rmagick4j/type_metric.rb +8 -0
- data/lib/rmagick4j/version.rb +5 -0
- data/lib/rvg/clippath.rb +48 -0
- data/lib/rvg/container.rb +131 -0
- data/lib/rvg/deep_equal.rb +56 -0
- data/lib/rvg/describable.rb +53 -0
- data/lib/rvg/embellishable.rb +417 -0
- data/lib/rvg/misc.rb +739 -0
- data/lib/rvg/paint.rb +55 -0
- data/lib/rvg/pathdata.rb +131 -0
- data/lib/rvg/rvg.rb +283 -0
- data/lib/rvg/stretchable.rb +168 -0
- data/lib/rvg/stylable.rb +118 -0
- data/lib/rvg/text.rb +187 -0
- data/lib/rvg/transformable.rb +133 -0
- data/lib/rvg/units.rb +66 -0
- data/lib/svgsalamander.jar +0 -0
- data/test/RMagickTestSuite.rb +129 -0
- data/test/eyetests/bullseye.rb +150 -0
- data/test/eyetests/tests/draw_arc_basic.rb +16 -0
- data/test/eyetests/tests/draw_circle_affine.rb +19 -0
- data/test/eyetests/tests/draw_circle_basic.rb +16 -0
- data/test/eyetests/tests/draw_ellipse_affine.rb +19 -0
- data/test/eyetests/tests/draw_ellipse_basic.rb +16 -0
- data/test/eyetests/tests/draw_line_affine.rb +24 -0
- data/test/eyetests/tests/draw_line_basic.rb +20 -0
- data/test/eyetests/tests/draw_pattern_1.rb +35 -0
- data/test/eyetests/tests/draw_polygon_affine.rb +21 -0
- data/test/eyetests/tests/draw_polygon_basic.rb +19 -0
- data/test/eyetests/tests/draw_polyline_affine.rb +19 -0
- data/test/eyetests/tests/draw_polyline_basic.rb +18 -0
- data/test/eyetests/tests/draw_rectangle_affine.rb +16 -0
- data/test/eyetests/tests/draw_rectangle_basic.rb +16 -0
- data/test/eyetests/tests/draw_rmagick_test_01.rb +35 -0
- data/test/eyetests/tests/draw_rmagick_test_02.rb +40 -0
- data/test/eyetests/tests/draw_rmagick_test_03.rb +17 -0
- data/test/eyetests/tests/draw_rmagick_test_04.rb +21 -0
- data/test/eyetests/tests/draw_roundrectangle_affine.rb +19 -0
- data/test/eyetests/tests/draw_roundrectangle_basic.rb +16 -0
- data/test/eyetests/tests/gradient_fill_horizontal_diagonal_fill.rb +9 -0
- data/test/eyetests/tests/gradient_fill_horizontal_fill.rb +9 -0
- data/test/eyetests/tests/gradient_fill_point_fill.rb +9 -0
- data/test/eyetests/tests/gradient_fill_vertical_diagonal_fill.rb +9 -0
- data/test/eyetests/tests/gradient_fill_vertical_fill.rb +9 -0
- data/test/eyetests/tests/gruff_accumulator_bar.rb +29 -0
- data/test/eyetests/tests/gruff_area_1.rb +16 -0
- data/test/eyetests/tests/gruff_area_2.rb +27 -0
- data/test/eyetests/tests/gruff_bar_1.rb +29 -0
- data/test/eyetests/tests/gruff_bar_2.rb +19 -0
- data/test/eyetests/tests/gruff_line_1.rb +13 -0
- data/test/eyetests/tests/gruff_line_2.rb +20 -0
- data/test/eyetests/tests/gruff_net_1.rb +16 -0
- data/test/eyetests/tests/gruff_net_2.rb +16 -0
- data/test/eyetests/tests/gruff_pie_1.rb +21 -0
- data/test/eyetests/tests/gruff_pie_2.rb +22 -0
- data/test/eyetests/tests/gruff_scene_1.rb +14 -0
- data/test/eyetests/tests/gruff_scene_2.rb +14 -0
- data/test/eyetests/tests/gruff_sidebar.rb +32 -0
- data/test/eyetests/tests/gruff_sidestacked_bar_1.rb +26 -0
- data/test/eyetests/tests/gruff_sidestacked_bar_2.rb +26 -0
- data/test/eyetests/tests/gruff_spider_1.rb +22 -0
- data/test/eyetests/tests/gruff_spider_2.rb +15 -0
- data/test/eyetests/tests/gruff_stacked_bar_1.rb +23 -0
- data/test/eyetests/tests/gruff_stacked_bar_2.rb +26 -0
- data/test/eyetests/tests/hatch_fill.rb +9 -0
- data/test/eyetests/tests/image_list_flatten_images.rb +15 -0
- data/test/eyetests/tests/new_image.rb +24 -0
- data/test/eyetests/tests/path_a_command_01.rb +16 -0
- data/test/eyetests/tests/path_a_command_02.rb +19 -0
- data/test/eyetests/tests/path_c_command_01.rb +16 -0
- data/test/eyetests/tests/path_c_command_02.rb +16 -0
- data/test/eyetests/tests/path_complex_01.rb +16 -0
- data/test/eyetests/tests/path_espiral_01.rb +28 -0
- data/test/eyetests/tests/path_h_command_01.rb +16 -0
- data/test/eyetests/tests/path_h_command_02.rb +16 -0
- data/test/eyetests/tests/path_l_command_01.rb +16 -0
- data/test/eyetests/tests/path_l_command_02.rb +16 -0
- data/test/eyetests/tests/path_m_command_01.rb +16 -0
- data/test/eyetests/tests/path_m_command_02.rb +16 -0
- data/test/eyetests/tests/path_m_command_03.rb +16 -0
- data/test/eyetests/tests/path_q_command_01.rb +16 -0
- data/test/eyetests/tests/path_q_command_02.rb +16 -0
- data/test/eyetests/tests/path_q_command_03.rb +25 -0
- data/test/eyetests/tests/path_s_command_01.rb +16 -0
- data/test/eyetests/tests/path_s_command_02.rb +16 -0
- data/test/eyetests/tests/path_star_01.rb +16 -0
- data/test/eyetests/tests/path_t_command_01.rb +16 -0
- data/test/eyetests/tests/path_t_command_02.rb +16 -0
- data/test/eyetests/tests/path_v_command_01.rb +16 -0
- data/test/eyetests/tests/path_v_command_02.rb +16 -0
- data/test/eyetests/tests/store_pixel_smiley.rb +123 -0
- data/test/eyetests/tests/texture_fill.rb +11 -0
- data/test/gruff_tests/test/gruff_test_case.rb +120 -0
- data/test/gruff_tests/test/monkey_gruff.rb +7 -0
- data/test/gruff_tests/test/test_accumulator_bar.rb +50 -0
- data/test/gruff_tests/test/test_area.rb +134 -0
- data/test/gruff_tests/test/test_bar.rb +283 -0
- data/test/gruff_tests/test/test_base.rb +8 -0
- data/test/gruff_tests/test/test_bullet.rb +26 -0
- data/test/gruff_tests/test/test_legend.rb +71 -0
- data/test/gruff_tests/test/test_line.rb +493 -0
- data/test/gruff_tests/test/test_mini_bar.rb +32 -0
- data/test/gruff_tests/test/test_mini_pie.rb +20 -0
- data/test/gruff_tests/test/test_mini_side_bar.rb +37 -0
- data/test/gruff_tests/test/test_net.rb +230 -0
- data/test/gruff_tests/test/test_photo.rb +41 -0
- data/test/gruff_tests/test/test_pie.rb +154 -0
- data/test/gruff_tests/test/test_scene.rb +100 -0
- data/test/gruff_tests/test/test_side_bar.rb +12 -0
- data/test/gruff_tests/test/test_sidestacked_bar.rb +89 -0
- data/test/gruff_tests/test/test_spider.rb +216 -0
- data/test/gruff_tests/test/test_stacked_bar.rb +52 -0
- data/test/images/clown.jpg +0 -0
- data/test/images/texture.jpg +0 -0
- data/test/implemented_methods.rb +18 -0
- data/test/spec/draw_spec.rb +24 -0
- data/test/spec/image_constants.rb +76 -0
- data/test/spec/image_spec.rb +23 -0
- data/test/spec/pixel_spec.rb +84 -0
- data/test/spec/stories/geometry_runner.rb +13 -0
- data/test/spec/stories/geometry_steps.rb +24 -0
- data/test/spec/stories/geometry_story.rb +116 -0
- data/test/spec/stories/image_filling_runner.rb +13 -0
- data/test/spec/stories/image_filling_steps.rb +64 -0
- data/test/spec/stories/image_filling_story.rb +41 -0
- metadata +215 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
#--
|
2
|
+
# $Id: transformable.rb,v 1.4 2008/02/24 18:26:37 rmagick Exp $
|
3
|
+
# Copyright (C) 2008 Timothy P. Hunter
|
4
|
+
#++
|
5
|
+
|
6
|
+
module Magick
|
7
|
+
class RVG
|
8
|
+
|
9
|
+
# Transforms is an Array with a deep_copy method.
|
10
|
+
# During unit-testing it also has a deep_equal method.
|
11
|
+
class Transforms < Array #:nodoc:
|
12
|
+
|
13
|
+
def deep_copy(h=nil)
|
14
|
+
copy = self.class.new
|
15
|
+
each { |transform| copy << [transform[0], transform[1].dup] }
|
16
|
+
return copy
|
17
|
+
end
|
18
|
+
|
19
|
+
end # class Transform
|
20
|
+
|
21
|
+
# Transformations are operations on the coordinate system.
|
22
|
+
# All the transformations defined within a container (an RVG object
|
23
|
+
# or a group) are applied before drawing any shapes or text.
|
24
|
+
# All transformations are applied in the order they were
|
25
|
+
# defined. <em>Note:</em> This means that
|
26
|
+
# g.translate(10,20).scale(2)
|
27
|
+
# is not the same as
|
28
|
+
# g.scale(2).translate(10,20)
|
29
|
+
module Transformable
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Apply transforms in the same order they were specified!
|
34
|
+
def add_transform_primitives(gc)
|
35
|
+
@transforms.each { |transform| gc.__send__(transform[0], *transform[1]) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(*args, &block)
|
39
|
+
super()
|
40
|
+
@transforms = Transforms.new
|
41
|
+
end
|
42
|
+
|
43
|
+
public
|
44
|
+
|
45
|
+
# Applies the transformation matrix [sx, rx, ry, sy, tx, ty]
|
46
|
+
def matrix(sx, rx, ry, sy, tx, ty)
|
47
|
+
begin
|
48
|
+
@transforms << [:affine, [Float(sx), Float(rx), Float(ry), Float(sy), Float(tx), Float(ty)]]
|
49
|
+
rescue ArgumentError
|
50
|
+
raise ArgumentError, "arguments must be convertable to float (got #{sx.class}, #{rx.class}, #{ry.class}, #{sy.class}, #{sx.class}, #{sx.class}, #{tx.class}, #{ty.class})"
|
51
|
+
end
|
52
|
+
yield(self) if block_given?
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
# Add <tt>tx</tt> to all x-coordinates and <tt>ty</tt>
|
57
|
+
# to all y-coordinates. If <tt>ty</tt> is omitted it defaults
|
58
|
+
# to <tt>tx</tt>.
|
59
|
+
def translate(tx, ty=nil)
|
60
|
+
ty ||= tx
|
61
|
+
begin
|
62
|
+
@transforms << [:translate, [Float(tx), Float(ty)]]
|
63
|
+
rescue ArgumentError
|
64
|
+
raise ArgumentError, "arguments must be convertable to float (got #{tx.class}, #{ty.class})"
|
65
|
+
end
|
66
|
+
yield(self) if block_given?
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
# Multiply the x-coordinates by <tt>sx</tt> and the y-coordinates
|
71
|
+
# by <tt>sy</tt>. If <tt>sy</tt> is omitted it defaults to <tt>sx</tt>.
|
72
|
+
def scale(sx, sy=nil)
|
73
|
+
sy ||= sx
|
74
|
+
begin
|
75
|
+
@transforms << [:scale, [Float(sx), Float(sy)]]
|
76
|
+
rescue ArgumentError
|
77
|
+
raise ArgumentError, "arguments must be convertable to float (got #{sx.class}, #{sy.class})"
|
78
|
+
end
|
79
|
+
yield(self) if block_given?
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
# This method can take either of two argument lists:
|
84
|
+
# [rotate(angle)] rotate by <tt>angle</tt> degrees
|
85
|
+
# [rotate(angle, cx, cy)] rotate by <tt>angle</tt> degrees about
|
86
|
+
# the point [<tt>cx</tt>, <tt>cy</tt>].
|
87
|
+
def rotate(angle, *args)
|
88
|
+
begin
|
89
|
+
case args.length
|
90
|
+
when 0
|
91
|
+
@transforms << [:rotate, [Float(angle)]]
|
92
|
+
when 2
|
93
|
+
cx, cy = Float(args[0]), Float(args[1])
|
94
|
+
@transforms << [:translate, [cx, cy]]
|
95
|
+
@transforms << [:rotate, [angle]]
|
96
|
+
@transforms << [:translate, [-cx, -cy]]
|
97
|
+
else
|
98
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for 1 or 3)"
|
99
|
+
end
|
100
|
+
rescue ArgumentError
|
101
|
+
raise ArgumentError, "arguments must be convertable to float (got #{[angle, *args].collect {|a| a.class}.join(', ')})"
|
102
|
+
end
|
103
|
+
yield(self) if block_given?
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
# Skew the X-axis by <tt>angle</tt> degrees.
|
108
|
+
def skewX(angle)
|
109
|
+
begin
|
110
|
+
@transforms << [:skewx, [Float(angle)]]
|
111
|
+
rescue ArgumentError
|
112
|
+
raise ArgumentError, "argument must be convertable to float (got #{angle.class})"
|
113
|
+
end
|
114
|
+
yield(self) if block_given?
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
# Skew the Y-axis by <tt>angle</tt> degrees.
|
119
|
+
def skewY(angle)
|
120
|
+
begin
|
121
|
+
@transforms << [:skewy, [Float(angle)]]
|
122
|
+
rescue ArgumentError
|
123
|
+
raise ArgumentError, "argument must be convertable to float (got #{angle.class})"
|
124
|
+
end
|
125
|
+
yield(self) if block_given?
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
129
|
+
end # module Transformable
|
130
|
+
|
131
|
+
end # class RVG
|
132
|
+
end # module Magick
|
133
|
+
|
data/lib/rvg/units.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# $Id: units.rb,v 1.4 2008/02/24 18:26:37 rmagick Exp $
|
2
|
+
# Copyright (C) 2008 Timothy P. Hunter
|
3
|
+
module Magick
|
4
|
+
class RVG
|
5
|
+
|
6
|
+
# Define RVG.dpi and RVG.dpi=. Add conversions to Fixnum and Float classes
|
7
|
+
class << self
|
8
|
+
attr_reader :dpi
|
9
|
+
def dpi=(n)
|
10
|
+
if !defined?(@dpi)
|
11
|
+
[Float, Fixnum].each do |c|
|
12
|
+
c.class_eval <<-END_DEFS
|
13
|
+
# the default measurement - 1px is 1 pixel
|
14
|
+
def px
|
15
|
+
self
|
16
|
+
end
|
17
|
+
# inches
|
18
|
+
def in
|
19
|
+
self * ::Magick::RVG.dpi
|
20
|
+
end
|
21
|
+
# millimeters
|
22
|
+
def mm
|
23
|
+
self * ::Magick::RVG.dpi / 25.4
|
24
|
+
end
|
25
|
+
# centimeters
|
26
|
+
def cm
|
27
|
+
self * ::Magick::RVG.dpi / 2.54
|
28
|
+
end
|
29
|
+
# points
|
30
|
+
def pt
|
31
|
+
self * ::Magick::RVG.dpi / 72.0
|
32
|
+
end
|
33
|
+
# picas
|
34
|
+
def pc
|
35
|
+
self * ::Magick::RVG.dpi / 6.0
|
36
|
+
end
|
37
|
+
# percentage of the argument
|
38
|
+
def pct(of)
|
39
|
+
self * Float(of) / 100.0
|
40
|
+
end
|
41
|
+
# the default is deg
|
42
|
+
def deg
|
43
|
+
self
|
44
|
+
end
|
45
|
+
# radians -> degrees
|
46
|
+
def rad
|
47
|
+
self * 180.0 / Math::PI
|
48
|
+
end
|
49
|
+
# grads -> degrees
|
50
|
+
def grad
|
51
|
+
self * 9.0 / 10.0
|
52
|
+
end
|
53
|
+
END_DEFS
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
@dpi = Float(n)
|
58
|
+
return @dpi
|
59
|
+
rescue ArgumentError
|
60
|
+
raise TypeError, "Can't convert `#{n}' to Float"
|
61
|
+
end
|
62
|
+
end # class << self
|
63
|
+
|
64
|
+
end # class RVG
|
65
|
+
end # module Magick
|
66
|
+
|
Binary file
|
@@ -0,0 +1,129 @@
|
|
1
|
+
puts Time.new
|
2
|
+
begin
|
3
|
+
require 'rubygems'
|
4
|
+
gem PLATFORM == 'java' ? 'rmagick4j' : 'rmagick'
|
5
|
+
rescue Exception
|
6
|
+
puts "No gems! #{$!}"
|
7
|
+
end
|
8
|
+
puts Time.new
|
9
|
+
require 'RMagick'
|
10
|
+
puts Time.new
|
11
|
+
|
12
|
+
# TODO I know this isn't a real test, but it's what I've got for now.
|
13
|
+
# TODO Probably eventually want to hook into RMagick's existing tests.
|
14
|
+
|
15
|
+
def main
|
16
|
+
if ARGV.length > 0
|
17
|
+
ARGV.each {|arg| send(arg).display}
|
18
|
+
else
|
19
|
+
image = addTransparencyWithAMask.raise
|
20
|
+
# image = open_clown.blur_image(0, 5)
|
21
|
+
open(File.dirname(__FILE__) +'/test.jpg', 'w') do |file|
|
22
|
+
file.write(image.to_blob {self.format = 'JPEG'})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
puts Time.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def addRaisedEdges
|
29
|
+
open_clown.raise
|
30
|
+
end
|
31
|
+
|
32
|
+
def addText
|
33
|
+
clown = open_clown
|
34
|
+
text = Magick::Draw.new
|
35
|
+
text.annotate(clown, 0, 0, 0, 60, "My friend!") {
|
36
|
+
self.gravity = Magick::SouthGravity
|
37
|
+
self.pointsize = 48
|
38
|
+
self.stroke = 'transparent'
|
39
|
+
self.fill = '#0000A9'
|
40
|
+
self.font_weight = Magick::BoldWeight
|
41
|
+
}
|
42
|
+
clown.first
|
43
|
+
end
|
44
|
+
|
45
|
+
def addTransparencyWithAMask
|
46
|
+
clown = open_clown.first
|
47
|
+
mask = Magick::Image.new(clown.columns, clown.rows) {
|
48
|
+
self.background_color = 'black'
|
49
|
+
}
|
50
|
+
bg = Magick::Image.read("pattern:checkerboard") {
|
51
|
+
self.size = "#{clown.columns}x#{clown.rows}"
|
52
|
+
}
|
53
|
+
bg = bg.first
|
54
|
+
|
55
|
+
height = clown.rows * 0.8
|
56
|
+
width = clown.columns * 0.7
|
57
|
+
x = (clown.columns - width) / 2
|
58
|
+
y = (clown.rows - height) / 2
|
59
|
+
|
60
|
+
gc = Magick::Draw.new
|
61
|
+
gc.stroke('white').fill('white')
|
62
|
+
gc.roundrectangle(x, y, x+width, y+height, 24, 24)
|
63
|
+
gc.draw(mask)
|
64
|
+
|
65
|
+
mask = mask.blur_image(0, 20)
|
66
|
+
|
67
|
+
mask.matte = false
|
68
|
+
clown.matte = true
|
69
|
+
|
70
|
+
clown = clown.composite(mask, Magick::CenterGravity, Magick::CopyOpacityCompositeOp)
|
71
|
+
bg.composite(clown, Magick::CenterGravity, Magick::OverCompositeOp)
|
72
|
+
end
|
73
|
+
|
74
|
+
def addWatermark
|
75
|
+
mark = Magick::Image.new(300, 50) do
|
76
|
+
self.background_color = 'none'
|
77
|
+
end
|
78
|
+
gc = Magick::Draw.new
|
79
|
+
gc.annotate(mark, 0, 0, 0, 0, "Image by RMagick") do
|
80
|
+
self.gravity = Magick::CenterGravity
|
81
|
+
self.pointsize = 32
|
82
|
+
self.font_family = "Times"
|
83
|
+
self.fill = "white"
|
84
|
+
self.stroke = "none"
|
85
|
+
end
|
86
|
+
mark.rotate!(-90)
|
87
|
+
clown = open_clown.first
|
88
|
+
clown = clown.watermark(mark, 0.15, 0, Magick::EastGravity)
|
89
|
+
clown
|
90
|
+
end
|
91
|
+
|
92
|
+
def crop_resized
|
93
|
+
open_clown.crop_resized(50, 50)
|
94
|
+
end
|
95
|
+
|
96
|
+
def cropToANewSize
|
97
|
+
clown = open_clown
|
98
|
+
face = clown.crop(50, 15, 150, 165)
|
99
|
+
white_bg = Magick::Image.new(clown.columns, clown.rows)
|
100
|
+
white_bg.composite(face, 50, 15, Magick::OverCompositeOp)
|
101
|
+
end
|
102
|
+
|
103
|
+
def flipIt
|
104
|
+
open_clown.flip!
|
105
|
+
end
|
106
|
+
|
107
|
+
def makeAThumbnail
|
108
|
+
clown = open_clown
|
109
|
+
tiny = clown.resize(0.25)
|
110
|
+
white_bg = Magick::Image.new(clown.columns, clown.rows)
|
111
|
+
white_bg.composite(tiny, Magick::CenterGravity, Magick::OverCompositeOp)
|
112
|
+
end
|
113
|
+
|
114
|
+
def open_clown
|
115
|
+
#Magick::ImageList.new("clown.jpg")
|
116
|
+
open(File.dirname(__FILE__) + "/clown.jpg") {|file| Magick::ImageList.new.from_blob(file.read)}
|
117
|
+
end
|
118
|
+
|
119
|
+
def rotateToAnyAngle
|
120
|
+
clown = open_clown
|
121
|
+
clown.rotate(130)
|
122
|
+
end
|
123
|
+
|
124
|
+
def turnItIntoBlackAndWhite
|
125
|
+
clown = Magick::ImageList.new("clown.jpg")
|
126
|
+
clown.quantize(256, Magick::GRAYColorspace)
|
127
|
+
end
|
128
|
+
|
129
|
+
main
|
@@ -0,0 +1,150 @@
|
|
1
|
+
TEST_ROOT = File.expand_path(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'java'
|
4
|
+
require 'rubygems'
|
5
|
+
|
6
|
+
#require 'RMagick'
|
7
|
+
require 'profligacy/swing'
|
8
|
+
require 'profligacy/lel'
|
9
|
+
require TEST_ROOT + '/tests/new_image.rb'
|
10
|
+
require 'tmpdir'
|
11
|
+
Kernel.srand(Time.now.to_i)
|
12
|
+
OUTPUT_DIR = File.join(Dir.tmpdir,Kernel.rand(100).to_s)
|
13
|
+
Dir.mkdir(OUTPUT_DIR)
|
14
|
+
|
15
|
+
module Bullseye
|
16
|
+
include Profligacy
|
17
|
+
|
18
|
+
DefaultListModel = javax.swing.DefaultListModel
|
19
|
+
ImageIO = javax.imageio.ImageIO
|
20
|
+
JButton = javax.swing.JButton
|
21
|
+
JFile = java.io.File
|
22
|
+
JFrame = javax.swing.JFrame
|
23
|
+
JLabel = javax.swing.JLabel
|
24
|
+
JList = javax.swing.JList
|
25
|
+
JPanel = javax.swing.JPanel
|
26
|
+
JScrollPane = javax.swing.JScrollPane
|
27
|
+
JTextField = javax.swing.JTextField
|
28
|
+
|
29
|
+
class ImagePanel < JPanel
|
30
|
+
attr_accessor :image_1, :image_2
|
31
|
+
|
32
|
+
def paint(graphics)
|
33
|
+
|
34
|
+
unless image_1.nil?
|
35
|
+
begin
|
36
|
+
pic = load_image(image_1)
|
37
|
+
graphics.drawImage(pic, 0, 0, nil)
|
38
|
+
rescue
|
39
|
+
pic = Magick::Image.new(300, 300)
|
40
|
+
pic.background_color = 'red'
|
41
|
+
pic.erase!
|
42
|
+
graphics.drawImage(pic._image.getImage, 0, 0, nil)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
unless image_2.nil?
|
47
|
+
begin
|
48
|
+
pic = load_image(image_2)
|
49
|
+
graphics.drawImage(pic, 310, 0, nil)
|
50
|
+
rescue
|
51
|
+
pic = Magick::Image.new(300, 300)
|
52
|
+
pic.background_color = 'red'
|
53
|
+
pic.erase!
|
54
|
+
graphics.drawImage(pic._image.getImage, 310, 0, nil)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def load_image(filename)
|
60
|
+
file = JFile.new(filename)
|
61
|
+
raise ArgumentError.new("File #{filename} does not exist") unless file.exists
|
62
|
+
ImageIO.read(file)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class ScriptRunner < Struct.new(:picture_panel, :source)
|
67
|
+
def initialize(picture_panel, source)
|
68
|
+
super(picture_panel, source)
|
69
|
+
@running = false
|
70
|
+
end
|
71
|
+
|
72
|
+
def run_script
|
73
|
+
@running = true
|
74
|
+
script_name = source.selected_value.downcase.gsub(' ','_')
|
75
|
+
selected_script = File.join(TEST_ROOT, 'tests', script_name + '.rb')
|
76
|
+
NOTIFIER.notify 'Running script in MRI.'
|
77
|
+
output_commands = `sh -c 'ruby #{selected_script} #{OUTPUT_DIR}'`
|
78
|
+
NOTIFIER.notify 'Running in JRuby.'
|
79
|
+
output_commands += `jruby #{selected_script} #{OUTPUT_DIR}`
|
80
|
+
if output_commands == ''
|
81
|
+
NOTIFIER.notify 'Done'
|
82
|
+
picture_panel.image_1 = File.join(OUTPUT_DIR, script_name + '.jruby.jpg')
|
83
|
+
picture_panel.image_2 = File.join(OUTPUT_DIR, script_name + '.mri.jpg')
|
84
|
+
picture_panel.repaint
|
85
|
+
else
|
86
|
+
puts output_commands
|
87
|
+
NOTIFIER.notify 'Error'
|
88
|
+
end
|
89
|
+
@running = false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class Notifier < Struct.new(:output)
|
94
|
+
def notify(string)
|
95
|
+
output.text = string.to_s
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class ScriptList < JList
|
100
|
+
def initialize
|
101
|
+
@default_model = DefaultListModel.new
|
102
|
+
super(@default_model)
|
103
|
+
load_test_scripts
|
104
|
+
self.setSelectedIndex(0)
|
105
|
+
end
|
106
|
+
|
107
|
+
def load_test_scripts
|
108
|
+
Dir[File.dirname(__FILE__) + '/tests/*.rb'].each do |script|
|
109
|
+
script = script.gsub(/(^.*tests\/|.rb$)/,'').split('_').map{|x| x.capitalize}.join(' ')
|
110
|
+
@default_model.addElement(script) unless script == 'New Image'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.scrollable(component)
|
116
|
+
JScrollPane.new component,
|
117
|
+
JScrollPane::VERTICAL_SCROLLBAR_AS_NEEDED,
|
118
|
+
JScrollPane::HORIZONTAL_SCROLLBAR_NEVER
|
119
|
+
end
|
120
|
+
|
121
|
+
lel = '[ <label_results | <label_scripts ]
|
122
|
+
[ (610,300)image_panel | <scripts_list ]
|
123
|
+
[ >status | >run_button ]'
|
124
|
+
|
125
|
+
ui = Swing::LEL.new(JFrame, lel) do |c, i|
|
126
|
+
c.label_scripts = JLabel.new('Scripts')
|
127
|
+
c.scripts_list = scrollable(scripts = ScriptList.new)
|
128
|
+
c.run_button = JButton.new('Run')
|
129
|
+
c.label_results = JLabel.new('Results')
|
130
|
+
c.image_panel = ImagePanel.new
|
131
|
+
c.status = JLabel.new ""
|
132
|
+
|
133
|
+
Bullseye::NOTIFIER = Notifier.new(c.status)
|
134
|
+
script_runner = ScriptRunner.new(c.image_panel, scripts)
|
135
|
+
run_script = proc {
|
136
|
+
scripts.enabled = c.run_button.enabled = false
|
137
|
+
Thread.new do
|
138
|
+
NOTIFIER.notify 'Running scripts...'
|
139
|
+
script_runner.run_script
|
140
|
+
scripts.enabled = c.run_button.enabled = true
|
141
|
+
end
|
142
|
+
}
|
143
|
+
|
144
|
+
scripts.addMouseListener { |event| run_script.call if event.click_count == 2 }
|
145
|
+
i.run_button = {:action => proc { |t,e| run_script.call } }
|
146
|
+
end.build :args => 'Bullseye'
|
147
|
+
|
148
|
+
ui.default_close_operation = JFrame::EXIT_ON_CLOSE
|
149
|
+
|
150
|
+
end
|