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
data/lib/dyi/font.rb
ADDED
@@ -0,0 +1,132 @@
|
|
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
|
+
|
24
|
+
class Font
|
25
|
+
IMPLEMENT_ATTRIBUTES = [:font_family, :style, :variant, :weight, :size, :size_adjust, :stretch]
|
26
|
+
VALID_VALUES = {
|
27
|
+
:style => ['normal','italic','oblique'],
|
28
|
+
:variant => ['normal','small-caps'],
|
29
|
+
:weight => ['normal','bold','bolder','lighter','100','200','300','400','500','600','700','800','900'],
|
30
|
+
:stretch => ['normal','wider','narrower','ultra-condensed','extra-condensed','condensed','semi-condensed','semi-expanded','expanded','extra-expanded','ultra-expanded']
|
31
|
+
}
|
32
|
+
DEFAULT_SIZE = Length.new(16)
|
33
|
+
|
34
|
+
##
|
35
|
+
# :method: font_family
|
36
|
+
|
37
|
+
##
|
38
|
+
# :method: style
|
39
|
+
|
40
|
+
##
|
41
|
+
# :method: weight
|
42
|
+
|
43
|
+
##
|
44
|
+
# :method: size
|
45
|
+
|
46
|
+
##
|
47
|
+
attr_reader *IMPLEMENT_ATTRIBUTES
|
48
|
+
|
49
|
+
def initialize(options={})
|
50
|
+
case options
|
51
|
+
when Font
|
52
|
+
IMPLEMENT_ATTRIBUTES.each do |attr|
|
53
|
+
instance_variable_set("@#{attr}", options.__send__(attr))
|
54
|
+
end
|
55
|
+
when Hash
|
56
|
+
options.each do |attr, value|
|
57
|
+
__send__(attr.to_s + '=', value) if IMPLEMENT_ATTRIBUTES.include?(attr.to_sym)
|
58
|
+
end
|
59
|
+
else
|
60
|
+
raise TypeError, "#{options.class} can't be coerced into #{self.class}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# :method: style=
|
66
|
+
#
|
67
|
+
# :call-seq:
|
68
|
+
# style= (value)
|
69
|
+
#
|
70
|
+
|
71
|
+
##
|
72
|
+
# :method: weight=
|
73
|
+
#
|
74
|
+
# :call-seq:
|
75
|
+
# weight= (value)
|
76
|
+
#
|
77
|
+
|
78
|
+
##
|
79
|
+
VALID_VALUES.each do |attr, valid_values|
|
80
|
+
define_method("#{attr.to_s}=") {|value|
|
81
|
+
if (value = value.to_s).size == 0
|
82
|
+
instance_variable_set("@#{attr}", nil)
|
83
|
+
else
|
84
|
+
raise ArgumentError, "`#{value}' is invalid font-#{attr}" unless VALID_VALUES[attr].include?(value)
|
85
|
+
instance_variable_set("@#{attr}", value)
|
86
|
+
end
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def font_family=(value)
|
91
|
+
@font_family = value.to_s.size != 0 ? value.to_s : nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def size=(value)
|
95
|
+
@size = Length.new_or_nil(value)
|
96
|
+
end
|
97
|
+
|
98
|
+
def size_adjust=(value) #:nodoc:
|
99
|
+
@size_adjust = value.to_s.size != 0 ? value.to_s : nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def draw_size
|
103
|
+
@size || DEFAULT_SIZE
|
104
|
+
end
|
105
|
+
|
106
|
+
def attributes
|
107
|
+
IMPLEMENT_ATTRIBUTES.inject({}) do |hash, attr|
|
108
|
+
value = instance_variable_get("@#{attr}")
|
109
|
+
hash[/^font_/ =~ attr.to_s ? attr : "font_#{attr}".to_sym] = value.to_s unless value.nil?
|
110
|
+
hash
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def empty?
|
115
|
+
IMPLEMENT_ATTRIBUTES.all? do |attr|
|
116
|
+
not instance_variable_get("@#{attr}")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class << self
|
121
|
+
|
122
|
+
def new(*args) #:nodoc:
|
123
|
+
return args.first if args.size == 1 && args.first.instance_of?(self)
|
124
|
+
super
|
125
|
+
end
|
126
|
+
|
127
|
+
def new_or_nil(*args)
|
128
|
+
(args.size == 1 && args.first.nil?) ? nil : new(*args)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,36 @@
|
|
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
|
+
base
|
25
|
+
svg_formatter
|
26
|
+
xaml_formatter
|
27
|
+
eps_formatter
|
28
|
+
svg_reader
|
29
|
+
|
30
|
+
).each do |file_name|
|
31
|
+
require File.join(File.dirname(__FILE__), 'formatter', file_name)
|
32
|
+
end
|
33
|
+
|
34
|
+
if defined? IRONRUBY_VERSION
|
35
|
+
require File.join(File.dirname(__FILE__), 'formatter', 'emf_formatter')
|
36
|
+
end
|
@@ -0,0 +1,245 @@
|
|
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
|
+
require 'stringio'
|
23
|
+
|
24
|
+
module DYI #:nodoc:
|
25
|
+
module Formatter #:nodoc:
|
26
|
+
|
27
|
+
class Base
|
28
|
+
|
29
|
+
def initialize(canvas)
|
30
|
+
@canvas = canvas
|
31
|
+
end
|
32
|
+
|
33
|
+
def puts(io=$>)
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
|
+
|
37
|
+
def string
|
38
|
+
puts(sio = StringIO.new)
|
39
|
+
sio.string
|
40
|
+
end
|
41
|
+
|
42
|
+
def save(file_name, options={})
|
43
|
+
open(file_name, "w") {|io| puts(io)}
|
44
|
+
end
|
45
|
+
|
46
|
+
def write_canvas(canvas, io)
|
47
|
+
raise NotImplementedError
|
48
|
+
end
|
49
|
+
|
50
|
+
def write_rectangle(shape, io)
|
51
|
+
raise NotImplementedError
|
52
|
+
end
|
53
|
+
|
54
|
+
def write_circle(shape, io)
|
55
|
+
raise NotImplementedError
|
56
|
+
end
|
57
|
+
|
58
|
+
def write_ellipse(shape, io)
|
59
|
+
raise NotImplementedError
|
60
|
+
end
|
61
|
+
|
62
|
+
def write_line(shape, io)
|
63
|
+
raise NotImplementedError
|
64
|
+
end
|
65
|
+
|
66
|
+
def write_polyline(shape, io)
|
67
|
+
raise NotImplementedError
|
68
|
+
end
|
69
|
+
|
70
|
+
def write_polygon(shape, io)
|
71
|
+
raise NotImplementedError
|
72
|
+
end
|
73
|
+
|
74
|
+
def write_path(shape, io)
|
75
|
+
raise NotImplementedError
|
76
|
+
end
|
77
|
+
|
78
|
+
def write_text(shape, io)
|
79
|
+
raise NotImplementedError
|
80
|
+
end
|
81
|
+
|
82
|
+
def write_group(shape, io)
|
83
|
+
raise NotImplementedError
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
module XmlChar #:nodoc:
|
88
|
+
# See http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
|
89
|
+
CP1252 = { #:nodoc:
|
90
|
+
128 => 8364, # euro sign
|
91
|
+
130 => 8218, # single low-9 quotation mark
|
92
|
+
131 => 402, # latin small letter f with hook
|
93
|
+
132 => 8222, # double low-9 quotation mark
|
94
|
+
133 => 8230, # horizontal ellipsis
|
95
|
+
134 => 8224, # dagger
|
96
|
+
135 => 8225, # double dagger
|
97
|
+
136 => 710, # modifier letter circumflex accent
|
98
|
+
137 => 8240, # per mille sign
|
99
|
+
138 => 352, # latin capital letter s with caron
|
100
|
+
139 => 8249, # single left-pointing angle quotation mark
|
101
|
+
140 => 338, # latin capital ligature oe
|
102
|
+
142 => 381, # latin capital letter z with caron
|
103
|
+
145 => 8216, # left single quotation mark
|
104
|
+
146 => 8217, # right single quotation mark
|
105
|
+
147 => 8220, # left double quotation mark
|
106
|
+
148 => 8221, # right double quotation mark
|
107
|
+
149 => 8226, # bullet
|
108
|
+
150 => 8211, # en dash
|
109
|
+
151 => 8212, # em dash
|
110
|
+
152 => 732, # small tilde
|
111
|
+
153 => 8482, # trade mark sign
|
112
|
+
154 => 353, # latin small letter s with caron
|
113
|
+
155 => 8250, # single right-pointing angle quotation mark
|
114
|
+
156 => 339, # latin small ligature oe
|
115
|
+
158 => 382, # latin small letter z with caron
|
116
|
+
159 => 376 # latin capital letter y with diaeresis
|
117
|
+
}
|
118
|
+
|
119
|
+
# See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
|
120
|
+
PREDEFINED = { #:nodoc:
|
121
|
+
38 => '&', # ampersand
|
122
|
+
60 => '<', # left angle bracket
|
123
|
+
62 => '>' # right angle bracket
|
124
|
+
}
|
125
|
+
|
126
|
+
# See http://www.w3.org/TR/REC-xml/#dt-chardata for details.
|
127
|
+
ATTR_PREDEFINED = PREDEFINED.merge( #:nodoc:
|
128
|
+
34 => '"', # double quote
|
129
|
+
39 => ''' # single quote
|
130
|
+
)
|
131
|
+
|
132
|
+
# See http://www.w3.org/TR/REC-xml/#charsets for details.
|
133
|
+
VALID = [
|
134
|
+
0x9, 0xA, 0xD,
|
135
|
+
(0x20..0xD7FF),
|
136
|
+
(0xE000..0xFFFD),
|
137
|
+
(0x10000..0x10FFFF)
|
138
|
+
]
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def escape(s) #:nodoc:
|
143
|
+
s.to_s.unpack('U*').map {|n| code_to_char(n)}.join # ASCII, UTF-8
|
144
|
+
rescue
|
145
|
+
s.to_s.unpack('C*').map {|n| code_to_char(n)}.join # ISO-8859-1, WIN-1252
|
146
|
+
end
|
147
|
+
|
148
|
+
def attr_escape(s) #:nodoc:
|
149
|
+
s.to_s.unpack('U*').map {|n| code_to_char(n, true)}.join # ASCII, UTF-8
|
150
|
+
rescue
|
151
|
+
s.to_s.unpack('C*').map {|n| code_to_char(n, true)}.join # ISO-8859-1, WIN-1252
|
152
|
+
end
|
153
|
+
|
154
|
+
def code_to_char(code, is_attr=false) #:nodoc:
|
155
|
+
code = CP1252[code] || code
|
156
|
+
case code when *VALID
|
157
|
+
(is_attr ? ATTR_PREDEFINED : PREDEFINED)[code] || (code<128 ? code.chr : "&##{code};")
|
158
|
+
else
|
159
|
+
'*'
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
class XmlFormatter < Base
|
165
|
+
include XmlChar
|
166
|
+
|
167
|
+
def initialize(canvas, indent=0, level=0)
|
168
|
+
@canvas = canvas
|
169
|
+
@indent = indent
|
170
|
+
@level = level
|
171
|
+
end
|
172
|
+
|
173
|
+
def instruction
|
174
|
+
%Q{<?xml version="1.0" encoding="UTF-8"?>}
|
175
|
+
end
|
176
|
+
|
177
|
+
def generator_comment
|
178
|
+
%Q{<!-- Create with DYI #{VERSION} (http://xxxx/) -->}
|
179
|
+
end
|
180
|
+
|
181
|
+
def declaration
|
182
|
+
''
|
183
|
+
end
|
184
|
+
|
185
|
+
def puts(io=$>)
|
186
|
+
if @canvas.root_node?
|
187
|
+
puts_line(io) {io << instruction}
|
188
|
+
puts_line(io) {io << generator_comment}
|
189
|
+
declaration.each_line do |dec|
|
190
|
+
puts_line(io) {io << dec}
|
191
|
+
end
|
192
|
+
end
|
193
|
+
@canvas.write_as(self, io)
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
def puts_line(io, &block) #:nodoc:
|
199
|
+
io << (' ' * (@indent * @level)) if @indent != 0 && @level != 0
|
200
|
+
yield io
|
201
|
+
io << "\n" if @indent != 0
|
202
|
+
end
|
203
|
+
|
204
|
+
def create_node(io, tag_name, attributes={}, &block) #:nodoc:
|
205
|
+
puts_line(io) {
|
206
|
+
io << '<' << tag_name
|
207
|
+
attributes.each do |key, value|
|
208
|
+
io << ' ' << key << '="' << attr_escape(value) << '"'
|
209
|
+
end
|
210
|
+
io << '>'
|
211
|
+
}
|
212
|
+
create_nested_nodes(io, &block) if block
|
213
|
+
puts_line(io) {io << '</' << tag_name << '>'}
|
214
|
+
end
|
215
|
+
|
216
|
+
def create_leaf_node(io, tag_name, *attr) #:nodoc:
|
217
|
+
puts_line(io) {
|
218
|
+
io << '<' << tag_name
|
219
|
+
if attr.first.kind_of?(Hash)
|
220
|
+
attr.first.each do |key, value|
|
221
|
+
io << ' ' << key << '="' << attr_escape(value) << '"'
|
222
|
+
end
|
223
|
+
io << '/>'
|
224
|
+
elsif attr[1].kind_of?(Hash)
|
225
|
+
attr[1].each do |key, value|
|
226
|
+
io << ' ' << key << '="' << attr_escape(value) << '"'
|
227
|
+
end
|
228
|
+
io << '>' << escape(attr.first) << '</' << tag_name << '>'
|
229
|
+
elsif attr.first.nil?
|
230
|
+
io << '/>'
|
231
|
+
else
|
232
|
+
io << '>' << escape(attr.first) << '</' << tag_name << '>'
|
233
|
+
end
|
234
|
+
}
|
235
|
+
end
|
236
|
+
|
237
|
+
def create_nested_nodes(io, &block) #:nodoc:
|
238
|
+
@level += 1
|
239
|
+
yield io
|
240
|
+
ensure
|
241
|
+
@level -= 1
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
@@ -0,0 +1,253 @@
|
|
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
|
+
require 'System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
|
23
|
+
require 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
|
24
|
+
|
25
|
+
module DYI #:nodoc:
|
26
|
+
module Formatter #:nodoc:
|
27
|
+
|
28
|
+
class EmfFormatter < Base
|
29
|
+
|
30
|
+
def save(file_name, options={})
|
31
|
+
form = System::Windows::Forms::Form.new
|
32
|
+
tmp_g = form.create_graphics
|
33
|
+
dc = tmp_g.get_hdc
|
34
|
+
stream = System::IO::FileStream.new(file_name, System::IO::FileMode.create)
|
35
|
+
# stream = System::IO::MemoryStream.new()
|
36
|
+
metafile = System::Drawing::Imaging::Metafile.new(
|
37
|
+
stream,
|
38
|
+
dc,
|
39
|
+
System::Drawing::Rectangle.new(0, 0, @canvas.width.to_f, @canvas.height.to_f),
|
40
|
+
System::Drawing::Imaging::MetafileFrameUnit.pixel,
|
41
|
+
System::Drawing::Imaging::EmfType.emf_plus_dual)
|
42
|
+
tmp_g.release_hdc
|
43
|
+
tmp_g.dispose
|
44
|
+
|
45
|
+
graphics = System::Drawing::Graphics.from_image(metafile);
|
46
|
+
|
47
|
+
@canvas.write_as(self, graphics)
|
48
|
+
|
49
|
+
# fs = System::IO::FileStream.new('test.wmf', System::IO::FileMode.create)
|
50
|
+
# fs.write(stream.to_array, 0, stream.length)
|
51
|
+
|
52
|
+
graphics.dispose
|
53
|
+
metafile.dispose
|
54
|
+
end
|
55
|
+
|
56
|
+
def write_canvas(canvas, graphics)
|
57
|
+
canvas.child_elements.each do |element|
|
58
|
+
element.write_as(self, graphics)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def write_rectangle(shape, graphics)
|
63
|
+
set_transform(shape, graphics) {
|
64
|
+
painting = shape.painting
|
65
|
+
if painting.fill
|
66
|
+
graphics.fill_rectangle(painting.cls_brush(shape), shape.left.to_f, shape.top.to_f, shape.width.to_f, shape.height.to_f)
|
67
|
+
end
|
68
|
+
if painting.stroke && (painting.stroke_width != DYI::Length::ZERO)
|
69
|
+
graphics.draw_rectangle(painting.cls_pen, shape.left.to_f, shape.top.to_f, shape.width.to_f, shape.height.to_f)
|
70
|
+
end
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def write_circle(shape, graphics)
|
75
|
+
write_ellipse(shape, graphics)
|
76
|
+
end
|
77
|
+
|
78
|
+
def write_ellipse(shape, graphics)
|
79
|
+
set_transform(shape, graphics) {
|
80
|
+
painting = shape.painting
|
81
|
+
if painting.fill
|
82
|
+
graphics.fill_ellipse(painting.cls_brush(shape), shape.left.to_f, shape.top.to_f, shape.width.to_f, shape.height.to_f)
|
83
|
+
end
|
84
|
+
if painting.stroke && (painting.stroke_width != DYI::Length::ZERO)
|
85
|
+
graphics.draw_ellipse(painting.cls_pen, shape.left.to_f, shape.top.to_f, shape.width.to_f, shape.height.to_f)
|
86
|
+
end
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def write_line(shape, graphics)
|
91
|
+
set_transform(shape, graphics) {
|
92
|
+
painting = shape.painting
|
93
|
+
if painting.stroke && (painting.stroke_width != DYI::Length::ZERO)
|
94
|
+
graphics.draw_line(painting.cls_pen, shape.start_point.to_cls_point, shape.end_point.to_cls_point)
|
95
|
+
end
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
def write_polyline(shape, graphics)
|
100
|
+
set_transform(shape, graphics) {
|
101
|
+
points = System::Array[System::Drawing::PointF].new(shape.points.size)
|
102
|
+
shape.points.each_with_index do |point, i|
|
103
|
+
points[i] = point.to_cls_point
|
104
|
+
end
|
105
|
+
|
106
|
+
painting = shape.painting
|
107
|
+
if painting.stroke && (painting.stroke_width != DYI::Length::ZERO)
|
108
|
+
graphics.draw_lines(painting.cls_pen, points)
|
109
|
+
end
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
def write_polygon(shape, graphics)
|
114
|
+
set_transform(shape, graphics) {
|
115
|
+
points = System::Array[System::Drawing::PointF].new(shape.points.size)
|
116
|
+
shape.points.each_with_index do |point, i|
|
117
|
+
points[i] = point.to_cls_point
|
118
|
+
end
|
119
|
+
|
120
|
+
painting = shape.painting
|
121
|
+
if painting.fill
|
122
|
+
graphics.fill_polygon(painting.cls_brush(shape), points, painting.cls_fill_mode)
|
123
|
+
end
|
124
|
+
if painting.stroke && (painting.stroke_width != DYI::Length::ZERO)
|
125
|
+
graphics.draw_polygon(painting.cls_pen, points)
|
126
|
+
end
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
def write_path(shape, graphics)
|
131
|
+
set_transform(shape, graphics) {
|
132
|
+
painting = shape.painting
|
133
|
+
path = System::Drawing::Drawing2D::GraphicsPath.new(painting.cls_fill_mode)
|
134
|
+
path.start_figure
|
135
|
+
shape.compatible_path_data.each do |cmd|
|
136
|
+
case cmd
|
137
|
+
when Shape::Path::MoveCommand
|
138
|
+
# do nothing.
|
139
|
+
when Shape::Path::CloseCommand
|
140
|
+
path.close_figure
|
141
|
+
when Shape::Path::LineCommand
|
142
|
+
path.add_line(cmd.preceding_point.x.to_f, cmd.preceding_point.y.to_f,
|
143
|
+
cmd.last_point.x.to_f, cmd.last_point.y.to_f)
|
144
|
+
when Shape::Path::CurveCommand
|
145
|
+
pre_pt = cmd.preceding_point
|
146
|
+
ctrl_pt1 = cmd.relative? ? pre_pt + cmd.control_point1 : cmd.control_point1
|
147
|
+
ctrl_pt2 = cmd.relative? ? pre_pt + cmd.control_point2 : cmd.control_point2
|
148
|
+
path.add_bezier(pre_pt.x.to_f, pre_pt.y.to_f,
|
149
|
+
ctrl_pt1.x.to_f, ctrl_pt1.y.to_f,
|
150
|
+
ctrl_pt2.x.to_f, ctrl_pt2.y.to_f,
|
151
|
+
cmd.last_point.x.to_f, cmd.last_point.y.to_f)
|
152
|
+
else
|
153
|
+
raise TypeError, "unknown command: #{cmd.class}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
if painting.fill
|
157
|
+
graphics.fill_path(painting.cls_brush(shape), path)
|
158
|
+
end
|
159
|
+
if painting.stroke && (painting.stroke_width != DYI::Length::ZERO)
|
160
|
+
graphics.draw_path(painting.cls_pen, path)
|
161
|
+
end
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
def write_text(shape, graphics)
|
166
|
+
set_transform(shape, graphics) {
|
167
|
+
# font = Font.to_cls_font(shape.font)
|
168
|
+
# brush = System::Drawing::SolidBrush.new(Color.black.to_cls_color)
|
169
|
+
graphics.draw_string(shape.formated_text, shape.font.to_cls_font, shape.painting.cls_brush(shape), shape.point.to_cls_point, shape.string_format)
|
170
|
+
=begin
|
171
|
+
attrs = {:x => shape.point.x, :y => shape.point.y}
|
172
|
+
attrs.merge!(common_attributes(shape))
|
173
|
+
attrs[:"text-decoration"] = shape.attributes[:text_decoration] if shape.attributes[:text_decoration]
|
174
|
+
# attrs[:"alignment-baseline"] = shape.attributes[:alignment_baseline] if shape.attributes[:alignment_baseline]
|
175
|
+
case shape.attributes[:alignment_baseline]
|
176
|
+
when 'top' then attrs[:y] += shape.font_height * 0.85
|
177
|
+
when 'middle' then attrs[:y] += shape.font_height * 0.35
|
178
|
+
when 'bottom' then attrs[:y] -= shape.font_height * 0.15
|
179
|
+
end
|
180
|
+
attrs[:"text-anchor"] = shape.attributes[:text_anchor] if shape.attributes[:text_anchor]
|
181
|
+
attrs[:"writing-mode"] = shape.attributes[:writing_mode] if shape.attributes[:writing_mode]
|
182
|
+
attrs[:textLength] = shape.attributes[:textLength] if shape.attributes[:textLength]
|
183
|
+
attrs[:lengthAdjust] = shape.attributes[:lengthAdjust] if shape.attributes[:lengthAdjust]
|
184
|
+
text = shape.formated_text
|
185
|
+
if text =~ /(\r\n|\n|\r)/
|
186
|
+
create_node(io, 'text', attrs) {
|
187
|
+
create_leaf_node(io, 'tspan', $`.strip, :x => shape.point.x)
|
188
|
+
$'.each_line do |line|
|
189
|
+
create_leaf_node(io, 'tspan', line.strip, :x => shape.point.x, :dy => shape.dy)
|
190
|
+
end
|
191
|
+
}
|
192
|
+
else
|
193
|
+
create_leaf_node(io, 'text', text, attrs)
|
194
|
+
end
|
195
|
+
=end
|
196
|
+
}
|
197
|
+
end
|
198
|
+
|
199
|
+
def write_group(shape, graphics)
|
200
|
+
set_transform(shape, graphics) {
|
201
|
+
shape.child_elements.each do |element|
|
202
|
+
element.write_as(self, graphics)
|
203
|
+
end
|
204
|
+
}
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
=begin
|
209
|
+
def pre_render(shape) #:nodoc:
|
210
|
+
attributes = {}
|
211
|
+
style = create_style(shape)
|
212
|
+
transform = create_transform(shape)
|
213
|
+
clip_path = create_clip_path(shape)
|
214
|
+
attributes[:style] = style if style
|
215
|
+
attributes[:transform] = transform if transform
|
216
|
+
attributes[:'clip-path'] = clip_path if clip_path
|
217
|
+
attributes
|
218
|
+
end
|
219
|
+
=end
|
220
|
+
def set_transform(shape, graphics, &block) #:nodoc:
|
221
|
+
shape.transform.each do |tr|
|
222
|
+
case tr.first
|
223
|
+
when :translate
|
224
|
+
graphics.translate_transform(tr[1].to_f, tr[2].to_f)
|
225
|
+
when :scale
|
226
|
+
graphics.scale_transform(tr[1].to_f, tr[2].to_f)
|
227
|
+
when :rotate
|
228
|
+
graphics.rotate_transform(tr[1].to_f)
|
229
|
+
when :skewX
|
230
|
+
graphics.multiply_transform(DYI::Matrix.skew_x(tr[1]).to_cls_matrix)
|
231
|
+
when :skewY
|
232
|
+
graphics.multiply_transform(DYI::Matrix.skew_y(tr[1]).to_cls_matrix)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
yield
|
236
|
+
shape.transform.reverse_each do |tr|
|
237
|
+
case tr.first
|
238
|
+
when :translate
|
239
|
+
graphics.translate_transform(-tr[1].to_f, -tr[2].to_f)
|
240
|
+
when :scale
|
241
|
+
graphics.scale_transform(1.0 / tr[1].to_f, 1.0 / tr[2].to_f)
|
242
|
+
when :rotate
|
243
|
+
graphics.rotate_transform(-tr[1].to_f)
|
244
|
+
when :skewX
|
245
|
+
graphics.multiply_transform(DYI::Matrix.skew_x(-tr[1]).to_cls_matrix)
|
246
|
+
when :skewY
|
247
|
+
graphics.multiply_transform(DYI::Matrix.skew_y(-tr[1]).to_cls_matrix)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|