dyi 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/COPYING +674 -0
  2. data/README +28 -0
  3. data/examples/class_diagram.rb +151 -0
  4. data/examples/data/03311056.xlsx +0 -0
  5. data/examples/data/currency.xlsx +0 -0
  6. data/examples/data/money.csv +12 -0
  7. data/examples/line_and_bar.rb +26 -0
  8. data/examples/line_chart.rb +30 -0
  9. data/examples/logo.rb +68 -0
  10. data/examples/pie_chart.rb +19 -0
  11. data/examples/simple_shapes.rb +15 -0
  12. data/lib/dyi.rb +49 -0
  13. data/lib/dyi/chart.rb +34 -0
  14. data/lib/dyi/chart/array_reader.rb +136 -0
  15. data/lib/dyi/chart/base.rb +580 -0
  16. data/lib/dyi/chart/csv_reader.rb +93 -0
  17. data/lib/dyi/chart/excel_reader.rb +100 -0
  18. data/lib/dyi/chart/line_chart.rb +468 -0
  19. data/lib/dyi/chart/pie_chart.rb +141 -0
  20. data/lib/dyi/chart/table.rb +201 -0
  21. data/lib/dyi/color.rb +218 -0
  22. data/lib/dyi/coordinate.rb +224 -0
  23. data/lib/dyi/drawing.rb +32 -0
  24. data/lib/dyi/drawing/canvas.rb +100 -0
  25. data/lib/dyi/drawing/clipping.rb +61 -0
  26. data/lib/dyi/drawing/color_effect.rb +118 -0
  27. data/lib/dyi/drawing/filter.rb +74 -0
  28. data/lib/dyi/drawing/pen.rb +231 -0
  29. data/lib/dyi/drawing/pen_3d.rb +270 -0
  30. data/lib/dyi/font.rb +132 -0
  31. data/lib/dyi/formatter.rb +36 -0
  32. data/lib/dyi/formatter/base.rb +245 -0
  33. data/lib/dyi/formatter/emf_formatter.rb +253 -0
  34. data/lib/dyi/formatter/eps_formatter.rb +397 -0
  35. data/lib/dyi/formatter/svg_formatter.rb +260 -0
  36. data/lib/dyi/formatter/svg_reader.rb +113 -0
  37. data/lib/dyi/formatter/xaml_formatter.rb +317 -0
  38. data/lib/dyi/length.rb +399 -0
  39. data/lib/dyi/matrix.rb +122 -0
  40. data/lib/dyi/painting.rb +177 -0
  41. data/lib/dyi/shape.rb +1332 -0
  42. data/lib/dyi/svg_element.rb +149 -0
  43. data/lib/dyi/type.rb +104 -0
  44. data/lib/ironruby.rb +326 -0
  45. data/lib/util.rb +231 -0
  46. data/test/path_command_test.rb +217 -0
  47. data/test/test_length.rb +91 -0
  48. metadata +114 -0
@@ -0,0 +1,74 @@
1
+ # -*- encoding: UTF-8 -*-
2
+
3
+ # Copyright (c) 2009-2011 Sound-F Co., Ltd. All rights reserved.
4
+ #
5
+ # Author:: Mamoru Yuo
6
+ #
7
+ # This file is part of DYI.
8
+ #
9
+ # DYI is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # DYI is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with DYI. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+ module DYI #:nodoc:
23
+ module Drawing #:nodoc:
24
+ module Filter #:nodoc:
25
+
26
+ class DropShadow
27
+ include DYI::SvgElement
28
+ attr_reader :id
29
+
30
+ def initialize(canvas, blur_std, dx, dy)
31
+ @canvas = canvas
32
+ @blur_std = blur_std.to_i
33
+ @dx = Length.new(dx)
34
+ @dy = Length.new(dy)
35
+ @id = @canvas.add_define(self)
36
+ end
37
+
38
+ def child_elements
39
+ []
40
+ end
41
+
42
+ def draw_children?
43
+ true
44
+ end
45
+
46
+ private
47
+
48
+ def attributes #:nodoc:
49
+ {
50
+ :id => @id,
51
+ :filterUnits => 'userSpaceOnUse',
52
+ :x => 0,
53
+ :y => 0,
54
+ :width => @canvas.width,
55
+ :height => @canvas.height,
56
+ }
57
+ end
58
+
59
+ def svg_tag #:nodoc:
60
+ 'filter'
61
+ end
62
+
63
+ def child_elements_to_svg(xml) #:nodoc:
64
+ xml.feGaussianBlur(:in => 'SourceAlpha', :stdDeviation => @blur_std, :result => 'blur')
65
+ xml.feOffset(:in => 'blur', :dx => @dx, :dy => @dy, :result => 'offsetBlur')
66
+ xml.feMerge {
67
+ xml.feMergeNode(:in => 'offsetBlur')
68
+ xml.feMergeNode(:in => 'SourceGraphic')
69
+ }
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,231 @@
1
+ # -*- encoding: UTF-8 -*-
2
+
3
+ # Copyright (c) 2009-2011 Sound-F Co., Ltd. All rights reserved.
4
+ #
5
+ # Author:: Mamoru Yuo
6
+ #
7
+ # This file is part of DYI.
8
+ #
9
+ # DYI is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # DYI is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with DYI. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+ module DYI #:nodoc:
23
+ module Drawing #:nodoc:
24
+
25
+ class PenBase
26
+ extend AttributeCreator
27
+ DROP_SHADOW_OPTIONS = [:blur_std, :dx, :dy]
28
+ attr_font :font
29
+ attr_reader :drop_shadow
30
+
31
+ def initialize(options={})
32
+ @attributes = {}
33
+ @painting = Painting.new
34
+ options.each do |key, value|
35
+ if key.to_sym == :font
36
+ self.font = value
37
+ elsif Painting::IMPLEMENT_ATTRIBUTES.include?(key)
38
+ @painting.__send__("#{key}=", value)
39
+ else
40
+ @attributes[key] = value
41
+ end
42
+ end
43
+ end
44
+
45
+ Painting::IMPLEMENT_ATTRIBUTES.each do |painting_attr|
46
+ define_method(painting_attr) {| | @painting.__send__(painting_attr)}
47
+ define_method("#{painting_attr}=".to_sym) {|value|
48
+ @painting = @painting.dup
49
+ @painting.__send__("#{painting_attr}=".to_sym, value)
50
+ }
51
+ end
52
+
53
+ def drop_shadow=(options)
54
+ DROP_SHADOW_OPTIONS.each do |key|
55
+ @drop_shadow[key] = options[key.to_sym] if options[key.to_sym]
56
+ end
57
+ end
58
+
59
+ def draw_line(canvas, start_point, end_point, options={})
60
+ Shape::Line.create_on_start_end(start_point, end_point, merge_option(options)).draw_on(canvas)
61
+ end
62
+
63
+ alias draw_line_on_start_end draw_line
64
+
65
+ def draw_line_on_direction(canvas, start_point, direction_x, direction_y, options={})
66
+ Shape::Line.create_on_direction(start_point, direction_x, direction_y, merge_option(options)).draw_on(canvas)
67
+ end
68
+
69
+ def draw_polyline(canvas, point, options={}, &block)
70
+ polyline = Shape::Polyline.new(point, merge_option(options))
71
+ yield polyline
72
+ polyline.draw_on(canvas)
73
+ end
74
+
75
+ def draw_polygon(canvas, point, options={}, &block)
76
+ polygon = Shape::Polygon.new(point, merge_option(options))
77
+ yield polygon
78
+ polygon.draw_on(canvas)
79
+ end
80
+
81
+ def draw_rectangle(canvas, left_top_point, width, height, options={})
82
+ Shape::Rectangle.create_on_width_height(left_top_point, width, height, merge_option(options)).draw_on(canvas)
83
+ end
84
+
85
+ alias draw_rectangle_on_width_height draw_rectangle
86
+
87
+ def draw_rectangle_on_corner(canvas, top, right, bottom, left, options={})
88
+ Shape::Rectangle.create_on_corner(top, right, bottom, left, merge_option(options)).draw_on(canvas)
89
+ end
90
+
91
+ def draw_path(canvas, point, options={}, &block)
92
+ Shape::Path.draw(point, merge_option(options), &block).draw_on(canvas)
93
+ end
94
+
95
+ def draw_closed_path(canvas, point, options={}, &block)
96
+ Shape::Path.draw_and_close(point, merge_option(options), &block).draw_on(canvas)
97
+ end
98
+
99
+ def draw_circle(canvas, center_point, radius, options={})
100
+ Shape::Circle.create_on_center_radius(center_point, radius, merge_option(options)).draw_on(canvas)
101
+ end
102
+
103
+ def draw_ellipse(canvas, center_point, radius_x, radius_y, options={})
104
+ Shape::Ellipse.create_on_center_radius(center_point, radius_x, radius_y, merge_option(options)).draw_on(canvas)
105
+ end
106
+
107
+ def draw_sector(canvas, center_point, radius_x, radius_y, start_angle, center_angle, options={})
108
+ raise ArgumentError, "center_angle is out of range: #{center_angle}" if center_angle.abs > 360
109
+ center_point = Coordinate.new(center_point)
110
+ radius_x = Length.new(radius_x)
111
+ radius_y = Length.new(radius_y)
112
+ large_arc = (center_angle.abs > 180)
113
+
114
+ arc_start_pt = Coordinate.new(radius_x * Math.cos(Math::PI * start_angle / 180), radius_y * Math.sin(Math::PI * start_angle / 180)) + center_point
115
+ arc_end_pt = Coordinate.new(radius_x * Math.cos(Math::PI * (start_angle + center_angle) / 180), radius_y * Math.sin(Math::PI * (start_angle + center_angle) / 180)) + center_point
116
+
117
+ draw_path(canvas, center_point, merge_option(options)) {|path|
118
+ path.line_to(arc_start_pt)
119
+ if center_angle.abs > 270
120
+ transit_pt = center_point * 2 - arc_start_pt
121
+ path.arc_to(transit_pt, radius_x, radius_y, 0, true)
122
+ path.arc_to(arc_end_pt, radius_x, radius_y, 0, false)
123
+ else
124
+ path.arc_to(arc_end_pt, radius_x, radius_y, 0, large_arc)
125
+ end
126
+ path.line_to(center_point)
127
+ }
128
+ end
129
+
130
+ def draw_text(canvas, point, text, options={})
131
+ Shape::Text.new(point, text, merge_option(options)).draw_on(canvas)
132
+ end
133
+
134
+ private
135
+
136
+ def merge_option(options)
137
+ {:painting=>@painting, :font=>@font}.merge(options)
138
+ end
139
+ end
140
+
141
+ class Pen < PenBase
142
+ #:stopdoc:
143
+ ALIAS_ATTRIBUTES =
144
+ Painting::IMPLEMENT_ATTRIBUTES.inject({}) do |hash, key|
145
+ hash[$'.empty? ? :color : $'.to_sym] = key if key.to_s =~ /^(stroke_|stroke$)/
146
+ hash
147
+ end
148
+ #:startdoc:
149
+
150
+ def initialize(options={})
151
+ options = options.dup
152
+ ALIAS_ATTRIBUTES.each do |key, value|
153
+ options[value] = options.delete(key) if options.key?(key) && !options.key?(value)
154
+ end
155
+ options[:stroke] = 'black' unless options.key?(:stroke)
156
+ super
157
+ end
158
+
159
+ ALIAS_ATTRIBUTES.each do |key, value|
160
+ alias_method key, value
161
+ alias_method "#{key}=", "#{value}="
162
+ end
163
+
164
+ def draw_text(canvas, point, text, options={})
165
+ painting = @painting
166
+ text_painting = Painting.new(painting)
167
+ text_painting.fill = painting.stroke
168
+ text_painting.fill_opacity = painting.stroke_opacity
169
+ text_painting.stroke = nil
170
+ text_painting.stroke_width = nil
171
+ @painting = text_painting
172
+ shape = super
173
+ @painting = painting
174
+ shape
175
+ end
176
+
177
+ class << self
178
+ def method_missing(method_name, *args, &block) #:nodoc:
179
+ if method_name.to_s =~ /^([a-z]+)_pen$/
180
+ if options = args.first
181
+ self.new(options.merge(:stroke => $1))
182
+ else
183
+ self.new(:stroke => $1)
184
+ end
185
+ else
186
+ super
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ class Brush < PenBase
193
+ #:stopdoc:
194
+ ALIAS_ATTRIBUTES =
195
+ Painting::IMPLEMENT_ATTRIBUTES.inject({}) do |hash, key|
196
+ hash[$'.empty? ? :color : $'.to_sym] = key if key.to_s =~ /^(fill_|fill$)/
197
+ hash
198
+ end
199
+ #:startdoc:
200
+
201
+ def initialize(options={})
202
+ options = options.dup
203
+ ALIAS_ATTRIBUTES.each do |key, value|
204
+ options[value] = options.delete(key) if options.key?(key) && !options.key?(value)
205
+ end
206
+ options[:stroke_width] = 0 unless options.key?(:stroke_width)
207
+ options[:fill] = 'black' unless options.key?(:fill)
208
+ super
209
+ end
210
+
211
+ ALIAS_ATTRIBUTES.each do |key, value|
212
+ alias_method key, value
213
+ alias_method "#{key}=", "#{value}="
214
+ end
215
+
216
+ class << self
217
+ def method_missing(method_name, *args, &block) #:nodoc:
218
+ if method_name.to_s =~ /([a-z]+)_brush/
219
+ if options = args.first
220
+ self.new(options.merge(:fill => $1))
221
+ else
222
+ self.new(:fill => $1)
223
+ end
224
+ else
225
+ super
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,270 @@
1
+ # -*- encoding: UTF-8 -*-
2
+
3
+ # Copyright (c) 2009-2011 Sound-F Co., Ltd. All rights reserved.
4
+ #
5
+ # Author:: Mamoru Yuo
6
+ #
7
+ # This file is part of DYI.
8
+ #
9
+ # DYI is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # DYI is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with DYI. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+ module DYI #:nodoc:
23
+ module Drawing #:nodoc:
24
+
25
+ class CubicPen < Pen
26
+ POSITION_TYPE_VALUES = [:baseline, :center, :backline]
27
+ attr_reader :position_type, :background_color, :background_opacity, :dx, :dy
28
+
29
+ def initialize(options={})
30
+ self.position_type = options.delete(:position_type)
31
+ self.background_color = options.delete(:background_color)
32
+ self.background_opacity = options.delete(:background_opacity)
33
+ self.dx = options.delete(:dx)
34
+ self.dy = options.delete(:dy)
35
+ super
36
+ end
37
+
38
+ def position_type=(value)
39
+ if value.to_s.size != 0
40
+ raise ArgumentError, "\"#{value}\" is invalid position-type" unless POSITION_TYPE_VALUES.include?(value)
41
+ @position_type = value
42
+ else
43
+ @position_type = nil
44
+ end
45
+ end
46
+
47
+ def background_color=(color)
48
+ @background_color = Color.new_or_nil(color)
49
+ end
50
+
51
+ def background_opacity=(opacity)
52
+ @background_opacity = opacity ? opacity.to_f : nil
53
+ end
54
+
55
+ def dx
56
+ @dx || Length.new(24)
57
+ end
58
+
59
+ def dx=(value)
60
+ @dx = Length.new_or_nil(value)
61
+ end
62
+
63
+ def dy
64
+ @dy || Length.new(-8)
65
+ end
66
+
67
+ def dy=(value)
68
+ @dy = Length.new_or_nil(value)
69
+ end
70
+
71
+ def brush
72
+ @brush ||= Brush.new(:color => background_color || color, :opacity => background_opacity || nil)
73
+ end
74
+
75
+ def draw_line(canvas, start_point, end_point, options={})
76
+ group = Shape::ShapeGroup.new
77
+ draw_background_shape(group, start_point, end_point, options)
78
+ super(group, start_point, end_point, options)
79
+ adjust_z_coordinate(group)
80
+ group.draw_on(canvas)
81
+ end
82
+
83
+ def draw_polyline(canvas, point, options={}, &block)
84
+ group = Shape::ShapeGroup.new(options)
85
+ polyline = super(group, point, {}, &block)
86
+ (1...polyline.points.size).each do |i|
87
+ draw_background_shape(group, polyline.points[i-1], polyline.points[i], {})
88
+ end
89
+ polyline = super(group, point, {}, &block)
90
+ adjust_z_coordinate(group)
91
+ group.draw_on(canvas)
92
+ end
93
+
94
+ private
95
+
96
+ def adjust_z_coordinate(shape) #:nodoc:
97
+ case position_type
98
+ when :center then shape.translate(-dx / 2, -dy / 2)
99
+ when :backline then shape.translate(-dx, -dy)
100
+ end
101
+ end
102
+
103
+ def draw_background_shape(canvas, start_point, end_point, options={}) #:nodoc:
104
+ brush.draw_polygon(canvas, start_point, options) {|polygon|
105
+ polygon.line_to(end_point)
106
+ polygon.line_to(Coordinate.new(end_point) + Coordinate.new(dx, dy))
107
+ polygon.line_to(Coordinate.new(start_point) + Coordinate.new(dx, dy))
108
+ }
109
+ end
110
+ end
111
+
112
+ class CylinderBrush < Brush
113
+
114
+ def initialize(options={})
115
+ self.ry = options.delete(:ry)
116
+ super
117
+ end
118
+
119
+ def ry
120
+ @ry || Length.new(8)
121
+ end
122
+
123
+ def ry=(value)
124
+ @ry = Length.new_or_nil(value)
125
+ end
126
+
127
+ def fill
128
+ @painting.fill
129
+ end
130
+
131
+ def fill=(value)
132
+ if @painting.fill != Color.new_or_nil(value)
133
+ @painting.fill = Color.new_or_nil(value)
134
+ end
135
+ value
136
+ end
137
+
138
+ alias color fill
139
+ alias color= fill=
140
+
141
+ def draw_rectangle(canvas, left_top_point, width, height, options={})
142
+ radius_x = width.quo(2)
143
+ radius_y = ry
144
+
145
+ shape = Shape::ShapeGroup.draw_on(canvas)
146
+ top_painting = @painting.dup
147
+ top_painting.fill = top_color
148
+ Shape::Ellipse.create_on_center_radius(Coordinate.new(left_top_point) + [width.quo(2), 0], radius_x, radius_y, merge_option(:painting => top_painting)).draw_on(shape)
149
+ body_painting = @painting.dup
150
+ body_painting.fill = body_gradient(canvas)
151
+ Shape::Path.draw(left_top_point, merge_option(:painting => body_painting)) {|path|
152
+ path.rarc_to([width, 0], radius_x, radius_y, 0, false, false)
153
+ path.rline_to([0, height])
154
+ path.rarc_to([-width, 0], radius_x, radius_y, 0, false, true)
155
+ path.rline_to([0, -height])
156
+ }.draw_on(shape)
157
+ shape
158
+ end
159
+
160
+ private
161
+
162
+ def body_gradient(canvas) #:nodoc:
163
+ gradient = ColorEffect::LinearGradient.new([0,0],[1,0])
164
+ gradient.add_color(0, color.merge(Color.white, 0.4))
165
+ gradient.add_color(0.3, color.merge(Color.white, 0.65))
166
+ gradient.add_color(0.4, color.merge(Color.white, 0.7))
167
+ gradient.add_color(0.5, color.merge(Color.white, 0.65))
168
+ gradient.add_color(0.7, color.merge(Color.white, 0.4))
169
+ gradient.add_color(1, color)
170
+ gradient
171
+ end
172
+
173
+ def top_color #:nodoc:
174
+ color.merge(Color.white, 0.3)
175
+ end
176
+ end
177
+
178
+ class ColumnBrush < Brush
179
+
180
+ def dy
181
+ @dy || Length.new(16)
182
+ end
183
+
184
+ def dy=(value)
185
+ @dy = Length.new_or_nil(value)
186
+ end
187
+
188
+ def draw_sector(canvas, center_point, radius_x, radius_y, start_angle, center_angle, options={})
189
+ @fill = color
190
+
191
+ start_angle = (center_angle > 0 ? start_angle : (start_angle + center_angle)) % 360
192
+ center_angle = center_angle.abs % 360
193
+ center_point = Coordinate.new(center_point)
194
+ radius_x = Length.new(radius_x)
195
+ radius_y = Length.new(radius_y)
196
+ large_arc = (center_angle > 180)
197
+
198
+ arc_start_pt = Coordinate.new(radius_x * Math.cos(Math::PI * start_angle / 180), radius_y * Math.sin(Math::PI * start_angle / 180)) + center_point
199
+ arc_end_pt = Coordinate.new(radius_x * Math.cos(Math::PI * (start_angle + center_angle) / 180), radius_y * Math.sin(Math::PI * (start_angle + center_angle) / 180)) + center_point
200
+
201
+ org_opacity = opacity
202
+ if org_color = color
203
+ self.color = color.merge('black', 0.2)
204
+ else
205
+ self.color = 'black'
206
+ self.opacity = 0.2
207
+ end
208
+
209
+ if (90..270).include?(start_angle) && center_angle < 180
210
+ draw_polygon(canvas, center_point, options) {|polygon|
211
+ polygon.line_to(center_point + [0, dy])
212
+ polygon.line_to(arc_end_pt + [0, dy])
213
+ polygon.line_to(arc_end_pt)
214
+ }
215
+ draw_polygon(canvas, center_point, options) {|polygon|
216
+ polygon.line_to(center_point + [0, dy])
217
+ polygon.line_to(arc_start_pt + [0, dy])
218
+ polygon.line_to(arc_start_pt)
219
+ }
220
+ else
221
+ draw_polygon(canvas, center_point, options) {|polygon|
222
+ polygon.line_to(center_point + [0, dy])
223
+ polygon.line_to(arc_start_pt + [0, dy])
224
+ polygon.line_to(arc_start_pt)
225
+ }
226
+ draw_polygon(canvas, center_point, options) {|polygon|
227
+ polygon.line_to(center_point + [0, dy])
228
+ polygon.line_to(arc_end_pt + [0, dy])
229
+ polygon.line_to(arc_end_pt)
230
+ }
231
+ end
232
+ if (0..180).include?(start_angle)
233
+ draw_path(canvas, arc_start_pt, options) {|path|
234
+ path.line_to(arc_start_pt + [0, dy])
235
+ if arc_end_pt.y >= center_point.y
236
+ path.arc_to(arc_end_pt + [0, dy], radius_x, radius_y, 0, false)
237
+ path.line_to(arc_end_pt)
238
+ path.arc_to(arc_start_pt, radius_x, radius_y, 0, false, false)
239
+ else
240
+ path.arc_to(center_point + [-(radius_x.abs), dy], radius_x, radius_y, 0, false)
241
+ path.line_to(center_point + [-(radius_x.abs), 0])
242
+ path.arc_to(arc_start_pt, radius_x, radius_y, 0, false, false)
243
+ end
244
+ }
245
+ elsif (270..360).include?(start_angle) && start_angle + center_angle > 360
246
+ draw_path(canvas, center_point + [radius_x.abs, 0], options) {|path|
247
+ path.line_to(center_point + [radius_x.abs, dy])
248
+ if arc_end_pt.y >= center_point.y
249
+ path.arc_to(arc_end_pt + [0, dy], radius_x, radius_y, 0, false)
250
+ path.line_to(arc_end_pt)
251
+ path.arc_to(center_point + [radius_x.abs, 0], radius_x, radius_y, 0, false, false)
252
+ else
253
+ path.arc_to(center_point + [-(radius_x.abs), dy], radius_x, radius_y, 0, false)
254
+ path.line_to(center_point + [-(radius_x.abs), 0])
255
+ path.arc_to(center_point + [radius_x.abs, 0], radius_x, radius_y, 0, false, false)
256
+ end
257
+ }
258
+ end
259
+ self.color = org_color
260
+ self.opacity = org_opacity
261
+
262
+ draw_path(canvas, center_point, options) {|path|
263
+ path.line_to(arc_start_pt)
264
+ path.arc_to(arc_end_pt, radius_x, radius_y, 0, large_arc)
265
+ path.line_to(center_point)
266
+ }
267
+ end
268
+ end
269
+ end
270
+ end