dyi 0.0.0

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.
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