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,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 => '&amp;', # ampersand
122
+ 60 => '&lt;', # left angle bracket
123
+ 62 => '&gt;' # 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 => '&quot;', # double quote
129
+ 39 => '&apos;' # 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