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.
- data/COPYING +674 -0
- data/README +28 -0
- data/examples/class_diagram.rb +151 -0
- data/examples/data/03311056.xlsx +0 -0
- data/examples/data/currency.xlsx +0 -0
- data/examples/data/money.csv +12 -0
- data/examples/line_and_bar.rb +26 -0
- data/examples/line_chart.rb +30 -0
- data/examples/logo.rb +68 -0
- data/examples/pie_chart.rb +19 -0
- data/examples/simple_shapes.rb +15 -0
- data/lib/dyi.rb +49 -0
- data/lib/dyi/chart.rb +34 -0
- data/lib/dyi/chart/array_reader.rb +136 -0
- data/lib/dyi/chart/base.rb +580 -0
- data/lib/dyi/chart/csv_reader.rb +93 -0
- data/lib/dyi/chart/excel_reader.rb +100 -0
- data/lib/dyi/chart/line_chart.rb +468 -0
- data/lib/dyi/chart/pie_chart.rb +141 -0
- data/lib/dyi/chart/table.rb +201 -0
- data/lib/dyi/color.rb +218 -0
- data/lib/dyi/coordinate.rb +224 -0
- data/lib/dyi/drawing.rb +32 -0
- data/lib/dyi/drawing/canvas.rb +100 -0
- data/lib/dyi/drawing/clipping.rb +61 -0
- data/lib/dyi/drawing/color_effect.rb +118 -0
- data/lib/dyi/drawing/filter.rb +74 -0
- data/lib/dyi/drawing/pen.rb +231 -0
- data/lib/dyi/drawing/pen_3d.rb +270 -0
- data/lib/dyi/font.rb +132 -0
- data/lib/dyi/formatter.rb +36 -0
- data/lib/dyi/formatter/base.rb +245 -0
- data/lib/dyi/formatter/emf_formatter.rb +253 -0
- data/lib/dyi/formatter/eps_formatter.rb +397 -0
- data/lib/dyi/formatter/svg_formatter.rb +260 -0
- data/lib/dyi/formatter/svg_reader.rb +113 -0
- data/lib/dyi/formatter/xaml_formatter.rb +317 -0
- data/lib/dyi/length.rb +399 -0
- data/lib/dyi/matrix.rb +122 -0
- data/lib/dyi/painting.rb +177 -0
- data/lib/dyi/shape.rb +1332 -0
- data/lib/dyi/svg_element.rb +149 -0
- data/lib/dyi/type.rb +104 -0
- data/lib/ironruby.rb +326 -0
- data/lib/util.rb +231 -0
- data/test/path_command_test.rb +217 -0
- data/test/test_length.rb +91 -0
- metadata +114 -0
@@ -0,0 +1,224 @@
|
|
1
|
+
# -*- encoding: UTF-8 -*-
|
2
|
+
|
3
|
+
# Copyright (c) 2009-2011 Sound-F Co., Ltd. All rights reserved.
|
4
|
+
#
|
5
|
+
# Author:: Mamoru Yuo
|
6
|
+
# Documentation:: Mamoru Yuo
|
7
|
+
#
|
8
|
+
# This file is part of DYI.
|
9
|
+
#
|
10
|
+
# DYI is free software: you can redistribute it and/or modify it
|
11
|
+
# under the terms of the GNU General Public License as published by
|
12
|
+
# the Free Software Foundation, either version 3 of the License, or
|
13
|
+
# (at your option) any later version.
|
14
|
+
#
|
15
|
+
# DYI is distributed in the hope that it will be useful,
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
+
# GNU General Public License for more details.
|
19
|
+
#
|
20
|
+
# You should have received a copy of the GNU General Public License
|
21
|
+
# along with DYI. If not, see <http://www.gnu.org/licenses/>.
|
22
|
+
#
|
23
|
+
# == Overview
|
24
|
+
#
|
25
|
+
# This file provides the DYI::Coordinate class, which provides
|
26
|
+
# coordinate supports for DYI scripts. The coordinate represents a
|
27
|
+
# length in the user coordinate system that is the given distance from the
|
28
|
+
# origin of the user coordinate system along the relevant axis (the x-axis for
|
29
|
+
# X coordinates, the y-axis for Y coordinates).
|
30
|
+
#
|
31
|
+
# See the documentation to the DYI::Coordinate class for more details
|
32
|
+
# and examples of usage.
|
33
|
+
#
|
34
|
+
|
35
|
+
module DYI #:nodoc:
|
36
|
+
|
37
|
+
# Class representing a coordinate. See documentation for the file
|
38
|
+
# dyi/coordinate.rb for an overview.
|
39
|
+
#
|
40
|
+
# == Introduction
|
41
|
+
#
|
42
|
+
# This class works with two length that mean orthogonal coordinates. The
|
43
|
+
# initial coordinate system has the origin at the top/left with the x-axis
|
44
|
+
# pointing to the right and the y-axis pointing down.
|
45
|
+
#
|
46
|
+
# The equality operator '<tt>==</tt>' does not test equality instance but test
|
47
|
+
# equality value of x-coordinate and y-coordinate.
|
48
|
+
#
|
49
|
+
# == Ways of calculating
|
50
|
+
#
|
51
|
+
# This class suports following arithmetic operators and methods: <tt>+</tt>,
|
52
|
+
# <tt>-</tt>, <tt>*</tt>, <tt>/</tt>, <tt>**</tt>, +#quo+. The operators
|
53
|
+
# '<tt>+</tt>', '<tt>-</tt>' coerced right hand operand into Coordinate, and
|
54
|
+
# then calculate.
|
55
|
+
#
|
56
|
+
# See the documentation to each operators and methods class for details.
|
57
|
+
class Coordinate
|
58
|
+
@@default_format = '(x,y)'
|
59
|
+
|
60
|
+
attr_reader :x, :y
|
61
|
+
|
62
|
+
# :call-seq:
|
63
|
+
# new (x_length, y_length)
|
64
|
+
# new (x_number, y_number)
|
65
|
+
# new (array)
|
66
|
+
# new (coordinate)
|
67
|
+
#
|
68
|
+
def initialize(*args)
|
69
|
+
case args.size
|
70
|
+
when 1
|
71
|
+
case arg = args.first
|
72
|
+
when Coordinate
|
73
|
+
@x = arg.x
|
74
|
+
@y = arg.y
|
75
|
+
when Array
|
76
|
+
raise ArgumentError, "wrong number of arguments' size (#{arg.size} for 2)" if arg.size != 2
|
77
|
+
@x = Length.new(arg[0])
|
78
|
+
@y = Length.new(arg[1])
|
79
|
+
else
|
80
|
+
raise TypeError, "#{arg.class} can't be coerced into #{self.class}"
|
81
|
+
end
|
82
|
+
when 2
|
83
|
+
@x = Length.new(args[0])
|
84
|
+
@y = Length.new(args[1])
|
85
|
+
else
|
86
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for #{args.size == 0 ? 1 : 2})"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
ZERO = new(0,0)
|
91
|
+
|
92
|
+
def +@
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
def -@
|
97
|
+
self.class.new(-@x, -@y)
|
98
|
+
end
|
99
|
+
|
100
|
+
def +(other)
|
101
|
+
other = self.class.new(other)
|
102
|
+
self.class.new(@x + other.x, @y + other.y)
|
103
|
+
end
|
104
|
+
|
105
|
+
def -(other)
|
106
|
+
other = self.class.new(other)
|
107
|
+
self.class.new(@x - other.x, @y - other.y)
|
108
|
+
end
|
109
|
+
|
110
|
+
def *(number)
|
111
|
+
self.class.new(@x * number, @y * number)
|
112
|
+
end
|
113
|
+
|
114
|
+
def **(number)
|
115
|
+
self.class.new(@x ** number, @y ** number)
|
116
|
+
end
|
117
|
+
|
118
|
+
def quo(number)
|
119
|
+
raise TypeError, "#{number.class} can't be coerced into Numeric" unless number.kind_of?(Numeric)
|
120
|
+
self.class.new(@x.quo(number.to_f), @y.quo(number.to_f))
|
121
|
+
end
|
122
|
+
|
123
|
+
alias / quo
|
124
|
+
|
125
|
+
def zero?
|
126
|
+
@x.zero? && @y.zero?
|
127
|
+
end
|
128
|
+
|
129
|
+
def nonzero?
|
130
|
+
zero? ? nil : self
|
131
|
+
end
|
132
|
+
|
133
|
+
def ==(other)
|
134
|
+
return false unless other.kind_of?(self.class)
|
135
|
+
@x == other.x && @y == other.y
|
136
|
+
end
|
137
|
+
|
138
|
+
def abs
|
139
|
+
(@x ** 2 + @y ** 2) ** 0.5
|
140
|
+
end
|
141
|
+
|
142
|
+
def distance(other)
|
143
|
+
(self - other).abs
|
144
|
+
end
|
145
|
+
|
146
|
+
def to_user_unit
|
147
|
+
self.class.new(@x.to_user_unit, @y.to_user_unit)
|
148
|
+
end
|
149
|
+
|
150
|
+
# :call-seq:
|
151
|
+
# to_s ()
|
152
|
+
# to_s (format)
|
153
|
+
#
|
154
|
+
def to_s(format=nil)
|
155
|
+
fmts = (format || @@default_format).split('\\\\')
|
156
|
+
fmts = fmts.map do |fmt|
|
157
|
+
fmt.gsub(/(?!\\x)(.|\G)x/, '\\1' + @x.to_s).gsub(/(?!\\y)(.|\G)y/, '\\1' + @y.to_s).delete('\\')
|
158
|
+
end
|
159
|
+
fmts.join('\\')
|
160
|
+
end
|
161
|
+
|
162
|
+
def inspect #:nodoc:
|
163
|
+
"(#{@x.inspect}, #{@y.inspect})"
|
164
|
+
end
|
165
|
+
|
166
|
+
class << self
|
167
|
+
|
168
|
+
public
|
169
|
+
|
170
|
+
def new(*args) #:nodoc:
|
171
|
+
return args.first if args.size == 1 && args.first.instance_of?(self)
|
172
|
+
super
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
# Creats and Returns new instance as +new+ method when an argument is not
|
177
|
+
# +nil+. If an argument is +nil+, returns +nil+.
|
178
|
+
def new_or_nil(*args)
|
179
|
+
(args.size == 1 && args.first.nil?) ? nil : new(*args)
|
180
|
+
end
|
181
|
+
|
182
|
+
def orthogonal_coordinates(x, y)
|
183
|
+
new(x, y)
|
184
|
+
end
|
185
|
+
|
186
|
+
def polar_coordinates(radius, theta)
|
187
|
+
new(radius * Math.cos(theta * Math::PI / 180), radius * Math.sin(theta * Math::PI / 180))
|
188
|
+
end
|
189
|
+
|
190
|
+
def set_default_format(format)
|
191
|
+
if block_given?
|
192
|
+
org_format = default_format
|
193
|
+
self.default_format = format
|
194
|
+
yield
|
195
|
+
self.default_format = org_format
|
196
|
+
self
|
197
|
+
else
|
198
|
+
self.default_format = format
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def default_format
|
203
|
+
@@default_format
|
204
|
+
end
|
205
|
+
|
206
|
+
# Sets format that is used when called to_s.
|
207
|
+
#
|
208
|
+
# The following format indicators can be used for the format specification
|
209
|
+
# character string.
|
210
|
+
#
|
211
|
+
# +x+:: (x-coordinate placeholder) Placeholder '+x+' is replaced as
|
212
|
+
# x-coordinate.
|
213
|
+
# +y+:: (y-coordinate placeholder) Placeholder '+y+' is replaced as
|
214
|
+
# y-coordinate.
|
215
|
+
# <tt>\\\\<tt>:: (escape character) Causes the next character to be interpreted
|
216
|
+
# as a literal rather than as a custom format specifier.
|
217
|
+
# all other characters:: The character is copied to the result string
|
218
|
+
# unchanged.
|
219
|
+
def default_format=(fromat)
|
220
|
+
@@default_format = fromat.dup
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
data/lib/dyi/drawing.rb
ADDED
@@ -0,0 +1,32 @@
|
|
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
|
+
%w(
|
23
|
+
|
24
|
+
canvas
|
25
|
+
pen
|
26
|
+
pen_3d
|
27
|
+
clipping
|
28
|
+
color_effect
|
29
|
+
|
30
|
+
).each do |file_name|
|
31
|
+
require File.join(File.dirname(__FILE__), 'drawing', file_name)
|
32
|
+
end
|
@@ -0,0 +1,100 @@
|
|
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 Canvas
|
26
|
+
extend AttributeCreator
|
27
|
+
IMPLEMENT_ATTRIBUTES = [:view_box, :preserve_aspect_ratio]
|
28
|
+
attr_length :width, :height
|
29
|
+
attr_reader *IMPLEMENT_ATTRIBUTES
|
30
|
+
attr_reader :child_elements
|
31
|
+
|
32
|
+
def initialize(width, height, real_width = nil, real_height = nil, preserve_aspect_ratio='none')
|
33
|
+
self.width = width
|
34
|
+
self.height = height
|
35
|
+
@view_box = "0 0 #{width} #{height}"
|
36
|
+
@preserve_aspect_ratio = preserve_aspect_ratio
|
37
|
+
@child_elements = []
|
38
|
+
self.real_width = real_width
|
39
|
+
self.real_height = real_height
|
40
|
+
end
|
41
|
+
|
42
|
+
def real_width
|
43
|
+
@real_width || width
|
44
|
+
end
|
45
|
+
|
46
|
+
def real_width=(width)
|
47
|
+
@real_width = Length.new_or_nil(width)
|
48
|
+
end
|
49
|
+
|
50
|
+
def real_height
|
51
|
+
@real_height || height
|
52
|
+
end
|
53
|
+
|
54
|
+
def real_height=(height)
|
55
|
+
@real_height = Length.new_or_nil(height)
|
56
|
+
end
|
57
|
+
|
58
|
+
def root_node?
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def write_as(formatter, io=$>)
|
63
|
+
formatter.write_canvas(self, io)
|
64
|
+
end
|
65
|
+
|
66
|
+
def save(file_name, format=nil, options={})
|
67
|
+
get_formatter(format).save(file_name, options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def puts_in_io(format=nil, io=$>)
|
71
|
+
get_formatter(format).puts(io)
|
72
|
+
end
|
73
|
+
|
74
|
+
def string(format=nil)
|
75
|
+
get_formatter(format).string
|
76
|
+
end
|
77
|
+
|
78
|
+
def attributes #:nodoc:
|
79
|
+
attrs = {:width => real_width, :height => real_height}
|
80
|
+
IMPLEMENT_ATTRIBUTES.inject(attrs) do |hash, attribute|
|
81
|
+
variable_name = '@' + attribute.to_s.split(/(?=[A-Z])/).map{|str| str.downcase}.join('_')
|
82
|
+
value = instance_variable_get(variable_name)
|
83
|
+
hash[attribute] = value.to_s if value
|
84
|
+
hash
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def get_formatter(format=nil) #:nodoc:
|
91
|
+
case format
|
92
|
+
when :svg, nil then Formatter::SvgFormatter.new(self, 2)
|
93
|
+
when :xaml then Formatter::XamlFormatter.new(self, 2)
|
94
|
+
when :eps then Formatter::EpsFormatter.new(self)
|
95
|
+
else raise ArgumentError, "`#{format}' is unknown format"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,61 @@
|
|
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 Clipping
|
26
|
+
RULES = ['nonzero', 'evenodd']
|
27
|
+
attr_reader :rule, :shapes
|
28
|
+
|
29
|
+
def initialize(*shapes)
|
30
|
+
@shapes = shapes
|
31
|
+
@rules = Array.new(shapes.size)
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_shape(shape, rule=nil)
|
35
|
+
raise ArgumentError, "\"#{rule}\" is invalid rule" if rule && !RULES.include?(rule)
|
36
|
+
unless @shapes.include?(shape)
|
37
|
+
@shapes.push(shape)
|
38
|
+
@rules.push(rule)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def remove_shape(shape)
|
43
|
+
index = @shapes.each_with_index {|s, i| break i if s == shape}
|
44
|
+
if index
|
45
|
+
@shapes.delete_at(index)
|
46
|
+
@rules.delete_at(index)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def each_shapes #:yields: shape, rule
|
51
|
+
@shapes.size.times do |i|
|
52
|
+
yield @shapes[i], @rules[i]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def write_as(formatter, io=$>)
|
57
|
+
formatter.write_clipping(self, io)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,118 @@
|
|
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 ColorEffect #:nodoc:
|
25
|
+
|
26
|
+
class LinearGradient
|
27
|
+
SPREAD_METHODS = ['pad', 'reflect', 'repeat']
|
28
|
+
attr_reader :start_point, :stop_point, :spread_method
|
29
|
+
|
30
|
+
def initialize(start_point=[0,0], stop_point=[1,0], spread_method=nil)
|
31
|
+
@start_point = start_point
|
32
|
+
@stop_point = stop_point
|
33
|
+
self.spread_method = spread_method
|
34
|
+
@child_elements = []
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_color(offset, color)
|
38
|
+
@child_elements.push(GradientStop.new(offset, :color => color))
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_opacity(offset, opacity)
|
42
|
+
@child_elements.push(GradientStop.new(offset, :opacity => opacity))
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_color_opacity(offset, color, opacity)
|
46
|
+
@child_elements.push(GradientStop.new(offset, :color => color, :opacity => opacity))
|
47
|
+
end
|
48
|
+
|
49
|
+
def spread_method=(value)
|
50
|
+
raise ArgumentError, "\"#{value}\" is invalid spreadMethod" if value && !SPREAD_METHODS.include?(value)
|
51
|
+
@spread_method = value
|
52
|
+
end
|
53
|
+
|
54
|
+
def child_elements
|
55
|
+
@child_elements.clone
|
56
|
+
end
|
57
|
+
|
58
|
+
def color?
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def write_as(formatter, io=$>)
|
63
|
+
formatter.write_linear_gradient(self, io)
|
64
|
+
end
|
65
|
+
|
66
|
+
class << self
|
67
|
+
|
68
|
+
public
|
69
|
+
|
70
|
+
def simple_gradation(derection, *colors)
|
71
|
+
case count = colors.size
|
72
|
+
when 0
|
73
|
+
nil
|
74
|
+
when 1
|
75
|
+
Color.new(colors.first)
|
76
|
+
else
|
77
|
+
case deraction
|
78
|
+
when :vertical then obj = new([0,0], [0,1])
|
79
|
+
when :horizontal then obj = new([0,0], [1,0])
|
80
|
+
when :lowerright then obj = new([0,0], [1,1])
|
81
|
+
when :upperright then obj = new([0,1], [1,0])
|
82
|
+
else raise ArgumentError, "unknown derection: `#{derection}'"
|
83
|
+
end
|
84
|
+
colors.each_with_index do |color, i|
|
85
|
+
obj.add_color(i.quo(count - 1), color)
|
86
|
+
end
|
87
|
+
obj
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class GradientStop
|
94
|
+
attr_reader :offset, :color, :opacity
|
95
|
+
|
96
|
+
def initialize(offset, options={})
|
97
|
+
@offset = offset.to_f
|
98
|
+
self.color = options[:color]
|
99
|
+
self.opacity = options[:opacity]
|
100
|
+
end
|
101
|
+
|
102
|
+
def color=(value)
|
103
|
+
@color = Color.new_or_nil(value)
|
104
|
+
value
|
105
|
+
end
|
106
|
+
|
107
|
+
def opacity=(value)
|
108
|
+
@opacity = value ? value.to_f : nil
|
109
|
+
value
|
110
|
+
end
|
111
|
+
|
112
|
+
def write_as(formatter, io=$>)
|
113
|
+
formatter.write_gradient_stop(self, io)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|