cf3 0.0.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG +6 -0
- data/Gemfile +1 -1
- data/README.md +21 -21
- data/Rakefile +6 -2
- data/cf3ruby.gemspec +13 -13
- data/lib/cf3.rb +75 -90
- data/lib/cf3/version.rb +1 -1
- data/samples/Rakefile +30 -0
- data/samples/accident.rb +34 -30
- data/samples/alhambra.rb +32 -29
- data/samples/bar_code.rb +26 -22
- data/samples/city.rb +14 -11
- data/samples/creature.rb +10 -6
- data/samples/dark_star.rb +5 -3
- data/samples/data/java_args.txt +1 -2
- data/samples/dragon.rb +8 -4
- data/samples/escher.rb +115 -116
- data/samples/fern.rb +10 -6
- data/samples/hex_tube.rb +16 -13
- data/samples/isosceles.rb +16 -11
- data/samples/levy.rb +4 -1
- data/samples/pcr.rb +28 -24
- data/samples/rubystar.rb +23 -17
- data/samples/sierpinski.rb +15 -11
- data/samples/spiral.rb +14 -10
- data/samples/star.rb +10 -6
- data/samples/tree.rb +19 -16
- data/samples/tree4.rb +12 -8
- data/samples/vine.rb +11 -7
- data/samples/xcross.rb +10 -7
- data/samples/y.rb +12 -8
- data/test/test_cf3.rb +11 -7
- metadata +23 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b71a0ec8b28c1fd599073b44c0d22ae1522d505b7969a535edf3dfed706491ad
|
4
|
+
data.tar.gz: 36e50b4f45a4e77c6937e2e268f654c8563647045c44824c798cfb18879f3494
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7d53015eeaff4ffe3b5a641c29e1774ce02ed669f2b4447b2da66d6babbc03c58c48b9c69292bc10ba71895069bc03a22f078aaff1337a434f8a5384234d581
|
7
|
+
data.tar.gz: 4aca28d84f49c8f11bda4f028c20c8b9334eed0cab8259f3011129ff1f3c8e72d4dd4dcb67f7afc310e9525e1b36041d96dacb1a8b25d418d7fb81eda282c1ad
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
v1.0.0 About time for a regular release number, fixed and update some examples NB: see also https://github.com/funatsufumiya/cf3ruby_sketches
|
2
|
+
|
3
|
+
v0.0.7 Update for processing3 and JRubyArt by Funatsufumiya san (aka funniti)
|
4
|
+
|
5
|
+
v0.0.6 Some tidy up remove @finished
|
6
|
+
|
1
7
|
v0.0.4 Introduce :w and :h as options to supplement size
|
2
8
|
* start support for width and height options (:w, :h)
|
3
9
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,38 +1,42 @@
|
|
1
1
|
# cf3ruby
|
2
2
|
|
3
|
-
|
3
|
+
Now updated to be compatible with ruby 2.4, JRubyArt 1.4.4 (newer version of ruby-processing), and Processing 3+.*
|
4
|
+
|
5
|
+
**context-free DSL for ruby-2.4 and CF3 syntax**
|
6
|
+
|
7
|
+
Very much derived from [context-free.rb](https://github.com/jashkenas/context_free) by Jeremy Ashkenas this version is updated to be more in line with CF3 and ruby 2.3 syntax. NB this version will not work with original ruby-processing.
|
4
8
|
|
5
|
-
Very much derived from [context-free.rb][] by Jeremy Ashkenas this version is updated to be more in line with CF3 and ruby 1.9 syntax. Tested as working with last rubygems release of ruby-processing (v 1.0.11) as well as the current [version][] (v 2.4.0).
|
6
|
-
[context-free.rb]:https://github.com/jashkenas/context_free/
|
7
|
-
[version]:https://github.com/monkstone/ruby-processing/releases/
|
8
9
|
## Installation
|
9
10
|
|
10
|
-
To use this library you need install jruby (preferably jruby-1
|
11
|
+
To use this library you need install jruby (preferably jruby-9.1+), you will also need [ruby-processing/JRubyArt](https://github.com/ruby-processing/JRubyArt) to be installed (preferred version 1.4.4). There are three ways you can install this library:-
|
11
12
|
|
12
13
|
***rake test and gem install***
|
13
14
|
|
14
|
-
|
15
|
+
Clone this repository,
|
15
16
|
|
16
17
|
```bash
|
17
|
-
cd cf3ruby
|
18
|
+
cd cf3ruby
|
18
19
|
jruby -S rake test # builds and tests gem (mouse click on frame for test image to show)
|
19
|
-
jruby -S gem install cf3-0.0.
|
20
|
+
jruby -S gem install cf3-1.0.0.gem # may need sudo access
|
20
21
|
```
|
21
22
|
|
22
23
|
***local bundle install***
|
23
24
|
|
24
|
-
|
25
|
+
Clone this repository,
|
25
26
|
|
26
27
|
```bash
|
27
|
-
cd
|
28
|
-
bundle install # using regular installed bundler may need to set GEM_PATH
|
28
|
+
cd cf3ruby
|
29
|
+
# bundle install # using regular installed bundler may need to set GEM_PATH
|
29
30
|
jruby -S bundle install # if you installed bundler with jruby
|
30
31
|
```
|
31
32
|
|
32
33
|
***gem install from rubygems***
|
34
|
+
|
33
35
|
```bash
|
34
|
-
|
35
|
-
|
36
|
+
# When rubygems is updatd for this release.
|
37
|
+
|
38
|
+
# gem install cf3 # regular install may need to set GEM_PATH env variable
|
39
|
+
# jruby -S gem install cf3 # jruby install
|
36
40
|
```
|
37
41
|
it couldn't be easier could it?
|
38
42
|
|
@@ -44,19 +48,15 @@ cf3samples # should work
|
|
44
48
|
jruby -S cf3samples # else if installed with jruby this should also work
|
45
49
|
```
|
46
50
|
|
47
|
-
As for running ruby-processing,
|
51
|
+
As for running ruby-processing,
|
48
52
|
```bash
|
49
|
-
|
53
|
+
k9 --run city.rb # providing you installed both ruby-processing (JRubyArt) and cf3ruby using jruby
|
50
54
|
|
51
55
|
```
|
52
|
-
You should read the [ruby-
|
56
|
+
You should read the [JRubyArt documentation](https://github.com/ruby-processing/JRubyArt/blob/master/README.md) on using rubygems.
|
53
57
|
|
54
58
|
## Contributing
|
55
59
|
|
56
|
-
[
|
57
|
-
[contributing]:CONTRIBUTING.md
|
58
|
-
[ruby-processing_documentation]:https://github.com/jashkenas/ruby-processing/wiki/Using-Rubygems/
|
59
|
-
[snapshot]:https://github.com/monkstone/cf3ruby/releases
|
60
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
60
61
|
|
61
62
|
![Y](http://3.bp.blogspot.com/-KNBKD7lArMA/UNBayboXQFI/AAAAAAAAD7A/YAgZCewTOxQ/s400/y.png)
|
62
|
-
|
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
1
|
+
#require "bundler/gem_tasks"
|
2
2
|
|
3
3
|
task :install => :build do
|
4
4
|
sh "jruby -S gem install #{Dir.glob('*.gem').join(' ')} --no-ri --no-rdoc"
|
@@ -9,7 +9,11 @@ task :build do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
task :test do
|
12
|
-
sh "jruby -S
|
12
|
+
sh "jruby -S k9 --run test/test_cf3.rb"
|
13
13
|
end
|
14
14
|
|
15
|
+
task :clean do
|
16
|
+
sh "rm *.gem"
|
17
|
+
end
|
18
|
+
|
15
19
|
task :default => [:install]
|
data/cf3ruby.gemspec
CHANGED
@@ -4,26 +4,26 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'cf3/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'cf3'
|
8
8
|
spec.version = Cf3::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Jeremy Ashkenas', 'Martin Prout, Funatsufumiya']
|
10
|
+
spec.email = ['mamba2928@yahoo.co.uk']
|
11
11
|
spec.description = <<-EOF
|
12
|
-
A library for
|
12
|
+
A library for JRubyArt, that allows the writing of context free
|
13
13
|
sketches (like context free art) in a ruby DSL. It is a bit of a toy
|
14
|
-
compared to the c++ version. However you can get quite a bit of
|
14
|
+
compared to the c++ version. However you can get quite a bit of
|
15
15
|
satisfaction creating an interesting graphic, and you can't always
|
16
16
|
predict what you are going to get.
|
17
17
|
EOF
|
18
18
|
spec.summary = %q{A ruby-DSL library for CF3 sketches}
|
19
|
-
spec.homepage =
|
20
|
-
spec.default_executable =
|
21
|
-
spec.
|
19
|
+
spec.homepage = 'http://learning-ruby-processing.blogspot.co.uk/'
|
20
|
+
spec.default_executable = 'cf3samples'
|
21
|
+
spec.licenses = %w(GPL-3.0 LGPL-2.0)
|
22
22
|
spec.files = `git ls-files`.split($/)
|
23
23
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
-
spec.executables = [
|
25
|
-
spec.require_paths = [
|
26
|
-
spec.add_runtime_dependency '
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
24
|
+
spec.executables = ['cf3samples']
|
25
|
+
spec.require_paths = ['lib']
|
26
|
+
spec.add_runtime_dependency 'jruby_art', '~> 1.4'
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
28
|
+
spec.add_development_dependency 'rake', '~> 12.0'
|
29
29
|
end
|
data/lib/cf3.rb
CHANGED
@@ -1,42 +1,37 @@
|
|
1
|
-
# A Context-Free library for Ruby-Processing, inspired by
|
2
|
-
# based on context_free.rb by Jeremy Ashkenas. Which in turn
|
3
|
-
# was inspired by contextfreeart.org
|
4
|
-
|
5
1
|
module Processing
|
6
|
-
|
2
|
+
# A Context-Free library for JRubyArt, inspired by and
|
3
|
+
# based on context_free.rb by Jeremy Ashkenas. That in turn
|
4
|
+
# was inspired by contextfreeart.org
|
7
5
|
class ContextFree
|
8
|
-
|
9
6
|
include Processing::Proxy
|
10
|
-
|
11
7
|
attr_accessor :rule, :app, :width, :height
|
12
8
|
|
13
|
-
AVAILABLE_OPTIONS = [
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
AVAILABLE_OPTIONS = %i[
|
10
|
+
x y w h rotation size flip color hue saturation brightness alpha
|
11
|
+
].freeze
|
12
|
+
HSB_ORDER = { hue: 0, saturation: 1, brightness: 2, alpha: 3 }.freeze
|
13
|
+
TRIANGLE_TOP = -1 / Math.sqrt(3)
|
14
|
+
TRIANGLE_BOTTOM = Math.sqrt(3) / 6
|
17
15
|
RADIANS = (Math::PI / 180.0)
|
18
16
|
# Define a context-free system. Use this method to create a ContextFree
|
19
17
|
# object. Call render() on it to make it draw.
|
20
18
|
def self.define(&block)
|
21
19
|
cf = ContextFree.new
|
22
|
-
cf.instance_eval
|
20
|
+
cf.instance_eval(&block)
|
23
21
|
cf
|
24
22
|
end
|
25
23
|
|
26
|
-
|
27
24
|
# Initialize a bare ContextFree object with empty recursion stacks.
|
28
25
|
def initialize
|
29
|
-
@app
|
30
|
-
@graphics =
|
31
|
-
@width =
|
32
|
-
@height =
|
33
|
-
@finished = false
|
26
|
+
@app = Processing.app
|
27
|
+
@graphics = @app.g
|
28
|
+
@width = @app.width
|
29
|
+
@height = @app.height
|
34
30
|
@rules = {}
|
35
31
|
@rewind_stack = []
|
36
32
|
@matrix_stack = []
|
37
33
|
end
|
38
34
|
|
39
|
-
|
40
35
|
# Create an accessor for the current value of every option. We use a values
|
41
36
|
# object so that all the state can be saved and restored as a unit.
|
42
37
|
AVAILABLE_OPTIONS.each do |option_name|
|
@@ -45,17 +40,16 @@ module Processing
|
|
45
40
|
end
|
46
41
|
end
|
47
42
|
|
48
|
-
|
49
43
|
# Here's the first serious method: A Rule has an
|
50
44
|
# identifying name, a probability, and is associated with
|
51
45
|
# a block of code. These code blocks are saved, and indexed
|
52
46
|
# by name in a hash, to be run later, when needed.
|
53
47
|
# The method then dynamically defines a method of the same
|
54
48
|
# name here, in order to determine which rule to run.
|
55
|
-
def shape(rule_name, prob=1, &proc)
|
56
|
-
@rules[rule_name] ||= {procs: [], total: 0}
|
49
|
+
def shape(rule_name, prob = 1, &proc)
|
50
|
+
@rules[rule_name] ||= { procs: [], total: 0 }
|
57
51
|
total = @rules[rule_name][:total]
|
58
|
-
@rules[rule_name][:procs] << [(total...(prob+total)), proc]
|
52
|
+
@rules[rule_name][:procs] << [(total...(prob + total)), proc]
|
59
53
|
@rules[rule_name][:total] += prob
|
60
54
|
unless ContextFree.method_defined? rule_name
|
61
55
|
self.class.class_eval do
|
@@ -63,9 +57,8 @@ module Processing
|
|
63
57
|
def #{rule_name}(options)
|
64
58
|
merge_options(@values, options)
|
65
59
|
pick = determine_rule(#{rule_name.inspect})
|
66
|
-
|
67
|
-
|
68
|
-
get_ready_to_draw
|
60
|
+
unless (@values[:size] - @values[:stop_size]) < 0
|
61
|
+
prepare_to_draw
|
69
62
|
pick[1].call(options)
|
70
63
|
end
|
71
64
|
end
|
@@ -74,37 +67,37 @@ module Processing
|
|
74
67
|
end
|
75
68
|
end
|
76
69
|
|
77
|
-
|
78
70
|
# Rule choice is random, based on the assigned probabilities.
|
79
71
|
def determine_rule(rule_name)
|
80
72
|
rule = @rules[rule_name]
|
81
|
-
chance = rand
|
82
|
-
|
83
|
-
|
73
|
+
chance = rand(0.0..rule[:total])
|
74
|
+
@rules[rule_name][:procs].select do |the_proc|
|
75
|
+
the_proc[0].include?(chance)
|
76
|
+
end.flatten
|
84
77
|
end
|
85
78
|
|
86
|
-
|
87
79
|
# At each step of the way, any of the options may change, slightly.
|
88
80
|
# Many of them have different strategies for being merged.
|
89
81
|
def merge_options(old_ops, new_ops)
|
90
82
|
return unless new_ops
|
91
83
|
# Do size first
|
92
|
-
old_ops[:size] *= new_ops
|
84
|
+
old_ops[:size] *= new_ops.fetch(:size, 1.0)
|
93
85
|
new_ops.each do |key, value|
|
94
86
|
case key
|
95
|
-
when :size
|
87
|
+
# when :size
|
96
88
|
when :x, :y
|
97
|
-
old_ops[key] = value * old_ops
|
89
|
+
old_ops[key] = value * old_ops.fetch(:size, 1.0)
|
98
90
|
when :rotation
|
99
91
|
old_ops[key] = value * RADIANS
|
100
92
|
when :hue, :saturation, :brightness, :alpha
|
101
93
|
adjusted = old_ops[:color].dup
|
102
|
-
adjusted[HSB_ORDER[key]] *= value
|
94
|
+
adjusted[HSB_ORDER[key]] *= value unless key == :hue
|
95
|
+
adjusted[HSB_ORDER[key]] += value if key == :hue
|
103
96
|
old_ops[:color] = adjusted
|
104
97
|
when :flip
|
105
98
|
old_ops[key] = !old_ops[key]
|
106
99
|
when :w, :h
|
107
|
-
old_ops[key] = value * old_ops
|
100
|
+
old_ops[key] = value * old_ops.fetch(:size, 1.0)
|
108
101
|
when :color
|
109
102
|
old_ops[key] = value
|
110
103
|
else # Used a key that we don't know about or trying to set
|
@@ -113,133 +106,125 @@ module Processing
|
|
113
106
|
end
|
114
107
|
end
|
115
108
|
|
116
|
-
|
117
109
|
# Using an unknown key let's you set arbitrary values,
|
118
110
|
# to keep track of for your own ends.
|
119
111
|
def merge_unknown_key(key, value, old_ops)
|
120
112
|
key_s = key.to_s
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
end
|
113
|
+
return unless key_s =~ /^set/
|
114
|
+
key_sym = key_s.sub('set_', '').to_sym
|
115
|
+
if key_s =~ /(brightness|hue|saturation)/
|
116
|
+
adjusted = old_ops[:color].dup
|
117
|
+
adjusted[HSB_ORDER[key_sym]] = value
|
118
|
+
old_ops[:color] = adjusted
|
119
|
+
else
|
120
|
+
old_ops[key_sym] = value
|
130
121
|
end
|
131
122
|
end
|
132
123
|
|
133
|
-
|
134
124
|
# Doing a 'split' saves the context, and proceeds from there,
|
135
125
|
# allowing you to rewind to where you split from at any moment.
|
136
|
-
def split(options=nil
|
126
|
+
def split(options = nil)
|
137
127
|
save_context
|
138
128
|
merge_options(@values, options) if options
|
139
129
|
yield
|
140
130
|
restore_context
|
141
131
|
end
|
142
132
|
|
143
|
-
|
144
133
|
# Saving the context means the values plus the coordinate matrix.
|
145
134
|
def save_context
|
146
135
|
@rewind_stack.push @values.dup
|
147
136
|
@matrix_stack << @graphics.get_matrix
|
148
137
|
end
|
149
138
|
|
150
|
-
|
151
139
|
# Restore the values and the coordinate matrix as the recursion unwinds.
|
152
140
|
def restore_context
|
153
141
|
@values = @rewind_stack.pop
|
154
142
|
@graphics.set_matrix @matrix_stack.pop
|
155
143
|
end
|
156
144
|
|
157
|
-
|
158
145
|
# Rewinding goes back one step.
|
159
146
|
def rewind
|
160
|
-
@finished = false
|
161
147
|
restore_context
|
162
148
|
save_context
|
163
149
|
end
|
164
150
|
|
165
|
-
|
166
151
|
# Render the is method that kicks it all off, initializing the options
|
167
152
|
# and calling the first rule.
|
168
|
-
def render(rule_name, starting_values={})
|
169
|
-
@values =
|
170
|
-
rotation: 0, flip: false,
|
171
|
-
size: 20, w: nil, h: nil,
|
172
|
-
start_x: width/2, start_y: height/2,
|
173
|
-
color: [180, 0.5, 0.5, 1],
|
174
|
-
stop_size: 1.5}
|
153
|
+
def render(rule_name, starting_values = {})
|
154
|
+
@values = defaults
|
175
155
|
@values.merge!(starting_values)
|
176
|
-
@finished = false
|
177
156
|
@app.reset_matrix
|
178
157
|
@app.rect_mode CENTER
|
179
158
|
@app.ellipse_mode CENTER
|
180
159
|
@app.no_stroke
|
181
|
-
@app.color_mode HSB, 360, 1.0, 1.0, 1.0
|
182
|
-
@app.translate @values
|
183
|
-
|
160
|
+
@app.color_mode HSB, 360, 1.0, 1.0, 1.0 # match cfdg
|
161
|
+
@app.translate @values.fetch(:start_x, 0), @values.fetch(:start_y, 0)
|
162
|
+
send(rule_name, {})
|
184
163
|
end
|
185
164
|
|
165
|
+
def defaults
|
166
|
+
{
|
167
|
+
x: 0,
|
168
|
+
y: 0,
|
169
|
+
rotation: 0,
|
170
|
+
flip: false,
|
171
|
+
size: 20,
|
172
|
+
start_x: width / 2,
|
173
|
+
start_y: height / 2,
|
174
|
+
color: [180, 0.5, 0.5, 1],
|
175
|
+
stop_size: 1.5
|
176
|
+
}
|
177
|
+
end
|
186
178
|
|
187
179
|
# Before actually drawing the next step, we need to move to the appropriate
|
188
180
|
# location.
|
189
|
-
def
|
190
|
-
@app.translate(@values
|
181
|
+
def prepare_to_draw
|
182
|
+
@app.translate(@values.fetch(:x, 0), @values.fetch(:y, 0))
|
191
183
|
sign = (@values[:flip] ? -1 : 1)
|
192
184
|
@app.rotate(sign * @values[:rotation])
|
193
185
|
end
|
194
186
|
|
195
|
-
|
196
187
|
# Compute the rendering parameters for drawing a shape.
|
197
188
|
def get_shape_values(some_options)
|
198
189
|
old_ops = @values.dup
|
199
|
-
merge_options(old_ops, some_options)
|
200
|
-
@app.fill
|
201
|
-
|
190
|
+
merge_options(old_ops, some_options) unless some_options.empty?
|
191
|
+
@app.fill(*old_ops[:color])
|
192
|
+
old_ops
|
202
193
|
end
|
203
194
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
def square(some_options={})
|
208
|
-
size, options = *get_shape_values(some_options)
|
195
|
+
# Square, circle, ellipse and triangles are the primitive shapes
|
196
|
+
def square(some_options = {})
|
197
|
+
options = get_shape_values(some_options)
|
209
198
|
width = options[:w] || options[:size]
|
210
199
|
height = options[:h] || options[:size]
|
211
|
-
rot = options[:rotation]
|
200
|
+
rot = options[:rotation]
|
212
201
|
@app.rotate(rot) if rot
|
213
202
|
@app.rect(0, 0, width, height)
|
214
|
-
@app.rotate(-rot) if rot
|
203
|
+
@app.rotate(-rot) if rot
|
215
204
|
end
|
216
205
|
|
217
|
-
|
218
|
-
|
219
|
-
size, options = *get_shape_values(some_options)
|
206
|
+
def circle(some_options = {})
|
207
|
+
get_shape_values(some_options)
|
220
208
|
@app.ellipse(0, 0, size, size)
|
221
209
|
end
|
222
210
|
|
223
|
-
def triangle(some_options={})
|
224
|
-
|
225
|
-
rot = options[:rotation]
|
211
|
+
def triangle(some_options = {})
|
212
|
+
options = get_shape_values(some_options)
|
213
|
+
rot = options[:rotation]
|
226
214
|
@app.rotate(rot) if rot
|
227
215
|
@app.triangle(0, TRIANGLE_TOP * size, 0.5 * size, TRIANGLE_BOTTOM * size, -0.5 * size, TRIANGLE_BOTTOM * size)
|
228
216
|
@app.rotate(-rot) if rot
|
229
217
|
end
|
230
218
|
|
231
|
-
|
232
|
-
|
233
|
-
size, options = *get_shape_values(some_options)
|
219
|
+
def ellipse(some_options = {})
|
220
|
+
options = get_shape_values(some_options)
|
234
221
|
width = options[:w] || options[:size]
|
235
222
|
height = options[:h] || options[:size]
|
236
|
-
rot = some_options[:rotation]
|
223
|
+
rot = some_options[:rotation]
|
237
224
|
@app.rotate(rot) if rot
|
238
225
|
@app.oval(options[:x] || 0, options[:y] || 0, width, height)
|
239
226
|
@app.rotate(-rot) if rot
|
240
227
|
end
|
241
|
-
|
242
|
-
|
228
|
+
alias oval ellipse
|
243
229
|
end
|
244
|
-
|
245
230
|
end
|