ruby_svg_light 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+
2
+ test = false #require 'ruby_svg_light'
3
+ if not test
4
+ require '../lib/ruby_svg_light'
5
+ end
6
+
7
+ canvas = RubySVGLight::Document.new
8
+ canvas.circle(40,40,20)
9
+ canvas.rectangle(80,20,40,40)
10
+ canvas.line(20,80,100,0)
11
+ canvas.line(20,105,100,0)
12
+
13
+ options = {:font_size=>'12px'}
14
+ canvas.options(options)
15
+ canvas.text(20,100, 'HelloWorld!')
16
+
17
+ canvas.text(20,130, 'HelloWorld!', {:font_size=>'18px'})
18
+
19
+ canvas.to_file('shapes.svg')
@@ -0,0 +1,53 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+
4
+ <svg
5
+ width="100%"
6
+ height="100%"
7
+ version="1.1"
8
+ xmlns="http://www.w3.org/2000/svg">
9
+
10
+ <circle
11
+ cx="40" cy="40"
12
+ r="20"
13
+ stroke="#000000"
14
+ stroke-width="1"
15
+ fill="white"/>
16
+
17
+ <rect
18
+ x="80" y="20"
19
+ width="40" height="40"
20
+ fill="white"
21
+ stroke="#000000"
22
+ stroke-width="1"
23
+ />
24
+
25
+ <line
26
+ x1="20" y1="80"
27
+ x2="120" y2="80"
28
+ stroke="#000000"
29
+ stroke-width="1"
30
+ />
31
+
32
+ <line
33
+ x1="20" y1="105"
34
+ x2="120" y2="105"
35
+ stroke="#000000"
36
+ stroke-width="1"
37
+ />
38
+
39
+ <text
40
+ x="20" y="100"
41
+ font-size="12px"
42
+ fill="#000000"
43
+ font-family="Sans"
44
+ >HelloWorld!
45
+ </text>
46
+ <text
47
+ x="20" y="130"
48
+ font-size="18px"
49
+ fill="#000000"
50
+ font-family="Sans"
51
+ >HelloWorld!
52
+ </text>
53
+ </svg>
data/lib/ruby_svg.rb ADDED
@@ -0,0 +1,145 @@
1
+
2
+ module RubySVGLight
3
+
4
+ class Document
5
+ attr_accessor :stroke, :fill, :height, :width, :name, :font_size
6
+ attr_reader :body
7
+
8
+ def initialize( options={} )
9
+ @options = options
10
+ @options[:name] ||= ''
11
+ #@options[:width] ||= 0
12
+ #@options[:height] ||= 0
13
+ @options[:stroke] ||= '#000000'
14
+ @options[:stroke_width] ||= 1
15
+ @options[:fill] ||= 'white'
16
+ @options[:font_size] ||= '24px'
17
+
18
+ @width = 0
19
+ @height = 0
20
+ @body = []
21
+ end
22
+
23
+ def update_size(x,y)
24
+ @width = x if x > @width
25
+ @height = y if y > @height
26
+ end
27
+
28
+ def header
29
+ text = %{<?xml version="1.0" encoding="UTF-8" standalone="no"?>
30
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
31
+
32
+ <svg
33
+ width="100%"
34
+ height="100%"
35
+ version="1.1"
36
+ xmlns="http://www.w3.org/2000/svg">
37
+ }
38
+ end
39
+
40
+ def footer
41
+ text = %{</svg>}
42
+ end
43
+
44
+
45
+
46
+
47
+ def circle(x=0, y=0, radius=10)
48
+ text = %{<circle
49
+ cx="#{x}"
50
+ cy="#{y}"
51
+ r="#{radius}"
52
+ stroke="#{@options[:stroke]}"
53
+ stroke-width="#{@options[:stroke_width]}"
54
+ fill="#{@options[:fill]}"/>
55
+ }
56
+
57
+ update_size(x+radius, y+radius)
58
+ #The call below should be in method missing
59
+ @body << text
60
+ end
61
+
62
+ def line(x,y,w,h)
63
+ text = %{<path
64
+ style="fill:none;stroke:#{@options[:stroke]};stroke-width:#{@options[:stroke_width]};stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
65
+ d="m #{x},#{y} l #{w},#{h}"
66
+ />
67
+ }
68
+
69
+ update_size(x+w, y+h)
70
+ @body << text
71
+ end
72
+
73
+ def rectangle(x,y,width,height)
74
+ text = %{<rect
75
+ style="fill:#{@options[:fill]};stroke:#{@options[:stroke]};stroke-width:#{@options[:stroke_width]};stroke-linecap:butt;stroke-linejoin:miter;"
76
+ width="#{width}"
77
+ height="#{height}"
78
+ x="#{x}"
79
+ y="#{y}" />
80
+ }
81
+ update_size(x+width, y+height)
82
+ @body << text
83
+ end
84
+
85
+ def text(x,y, input_text, size=@options[:font_size])
86
+ centre_text = "text-anchor:middle; dominant-baseline:central;"
87
+
88
+
89
+ #Stroke is outline
90
+ #fill is normal font. ie for text fill gets stroke colour
91
+ text = %{<text
92
+ xml:space="preserve"
93
+ style="font-size:#{size};font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#{@options[:stroke]};fill-opacity:1;stroke:none;font-family:Sans;#{centre_text}"
94
+ <tspan
95
+ x="#{x}"
96
+ y="#{y}">#{input_text}</tspan></text>
97
+ }
98
+ #Do not know height or width of text only the anchor
99
+ update_size(x, y)
100
+ @body << text
101
+ end
102
+
103
+ def to_s
104
+ text = ""
105
+ @body.each do |section|
106
+ text << section
107
+ end
108
+ return text
109
+ end
110
+
111
+ def components_only_to_s
112
+ text = ""
113
+ @body.each do |section|
114
+ text << section
115
+ end
116
+ return text
117
+ end
118
+
119
+ def finalise
120
+ #Maybe add the initial and closing things here so we are just noramlly dealing drawn components
121
+ @body.insert(0, header)
122
+ @body.insert(-1, footer)
123
+
124
+ end
125
+
126
+
127
+ def to_file( filename )
128
+ File.open(filename, 'w') do |f|
129
+ f.puts self.header
130
+ @body.each do |section|
131
+ f.puts section
132
+ end
133
+ f.puts self.footer
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+
140
+
141
+ if $0 == __FILE__
142
+ a = RubySVGLight::Document.new()
143
+ a.circle(20,10,10)
144
+ a.to_file('test.svg')
145
+ end
@@ -0,0 +1,193 @@
1
+
2
+ class RubySVG
3
+ attr_accessor :stroke, :fill, :height, :width, :name, :font_size
4
+ attr_reader :body
5
+
6
+ def initialize( name='', stroke='#000000', fill='white')
7
+ @name = name
8
+ @width = 0
9
+ @height = 0
10
+ @stroke = stroke
11
+ @fill = fill
12
+ @body = []
13
+ @font_size = '24px'
14
+ end
15
+
16
+ def update_size(x,y)
17
+ @width = x if x > @width
18
+ @height = y if y > @height
19
+ end
20
+
21
+ def header
22
+ text = %{<?xml version="1.0" encoding="UTF-8" standalone="no"?>
23
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
24
+
25
+ <svg
26
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
27
+ xmlns:cc="http://creativecommons.org/ns#"
28
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
29
+ xmlns:svg="http://www.w3.org/2000/svg"
30
+ xmlns="http://www.w3.org/2000/svg"
31
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
32
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
33
+ width="#{@width}"
34
+ height="#{@height}"
35
+ id="svg2"
36
+ version="1.1"
37
+ inkscape:version="0.48.1 r9760"
38
+ sodipodi:docname="CIC">
39
+ <defs
40
+ id="defs4" />
41
+ <sodipodi:namedview
42
+ id="base"
43
+ pagecolor="#ffffff"
44
+ bordercolor="#666666"
45
+ borderopacity="1.0"
46
+ inkscape:pageopacity="0.0"
47
+ inkscape:pageshadow="2"
48
+ inkscape:zoom="0.7"
49
+ inkscape:cx="-62.402701"
50
+ inkscape:cy="706.05086"
51
+ inkscape:document-units="px"
52
+ inkscape:current-layer="layer1"
53
+ showgrid="false"
54
+ inkscape:snap-nodes="false"
55
+ inkscape:window-width="1280"
56
+ inkscape:window-height="756"
57
+ inkscape:window-x="0"
58
+ inkscape:window-y="272"
59
+ inkscape:window-maximized="0" />
60
+ <metadata
61
+ id="metadata7">
62
+ <rdf:RDF>
63
+ <cc:Work
64
+ rdf:about="">
65
+ <dc:format>image/svg+xml</dc:format>
66
+ <dc:type
67
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
68
+ <dc:title>#{@name}</dc:title>
69
+ </cc:Work>
70
+ </rdf:RDF>
71
+ </metadata>
72
+ <g
73
+ inkscape:label="Layer 1"
74
+ inkscape:groupmode="layer"
75
+ id="layer1">
76
+ }
77
+ end
78
+
79
+ def footer
80
+ text = %{</g></svg>}
81
+ end
82
+
83
+
84
+
85
+
86
+ def circle(x=0, y=0, radius=10)
87
+ text = %{<circle
88
+ cx="#{x}"
89
+ cy="#{y}"
90
+ r="#{radius}"
91
+ stroke="#{stroke}"
92
+ stroke-width="1"
93
+ fill="#{@fill}"/>
94
+ }
95
+
96
+ update_size(x+radius, y+radius)
97
+ #The call below should be in method missing
98
+ @body << text
99
+ #@body.insert(-2, text)
100
+ end
101
+
102
+ def line(x,y,w,h)
103
+ text = %{<path
104
+ style="fill:none;stroke:#{@stroke};stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
105
+ d="m #{x},#{y} l #{w},#{h}"
106
+ id="path2999"
107
+ inkscape:connector-curvature="0"
108
+ sodipodi:nodetypes="cccccc" />
109
+ }
110
+
111
+ update_size(x+w, y+h)
112
+ @body << text
113
+ #@body.insert(-2, text)
114
+ end
115
+
116
+ def rectangle(x,y,width,height)
117
+ text = %{<rect
118
+ style="fill:#ffffff;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;"
119
+ id="rect2985"
120
+ width="#{width}"
121
+ height="#{height}"
122
+ x="#{x}"
123
+ y="#{y}" />
124
+ }
125
+ update_size(x+width, y+height)
126
+ @body << text
127
+
128
+ #@body.insert(-2, text)
129
+ end
130
+
131
+ def text(x,y, input_text='???', size=@font_size)
132
+ centre_text = "text-anchor:middle; dominant-baseline:central;"
133
+
134
+
135
+ #Stroke is outline
136
+ #fill is normal font. ie for text fill gets stroke colour
137
+ text = %{<text
138
+ xml:space="preserve"
139
+ style="font-size:#{size};font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#{@stroke};fill-opacity:1;stroke:none;font-family:Sans;#{centre_text}"
140
+ id="text2995"
141
+ sodipodi:linespacing="125%"><tspan
142
+ sodipodi:role="line"
143
+ id="tspan2997"
144
+ x="#{x}"
145
+ y="#{y}">#{input_text}</tspan></text>
146
+ }
147
+ #Do not know height or width of text only the anchor
148
+ update_size(x, y)
149
+ @body << text
150
+ end
151
+
152
+ def to_s
153
+ text = ""
154
+ @body.each do |section|
155
+ text << section
156
+ end
157
+ return text
158
+ end
159
+
160
+ def components_only_to_s
161
+ text = ""
162
+ @body.each do |section|
163
+ text << section
164
+ end
165
+ return text
166
+ end
167
+
168
+ def finalise
169
+ #Maybe add the initial and closing things here so we are just noramlly dealing drawn components
170
+ @body.insert(0, header)
171
+ @body.insert(-1, footer)
172
+
173
+ end
174
+
175
+
176
+ def to_file( filename )
177
+ File.open(filename, 'w') do |f|
178
+ f.puts RubySVG.header
179
+ @body.each do |section|
180
+ f.puts section
181
+ end
182
+ f.puts RubySVG.footer
183
+ end
184
+ end
185
+ end
186
+
187
+
188
+ if $0 == __FILE__
189
+ a = RubySVG.new('Test', 100, 100)
190
+
191
+ a.circle(20,10,10)
192
+ a.to_file('test.svg')
193
+ end
@@ -0,0 +1,205 @@
1
+
2
+ module RubySVGLight
3
+ VERSION = '0.0.1'
4
+
5
+ class Document
6
+ attr_reader :body
7
+
8
+ def initialize( options={} )
9
+ @options = options
10
+ @options[:name] ||= ''
11
+ @options[:width] ||= :auto
12
+ @options[:height] ||= :auto
13
+ @options[:stroke] ||= '#000000'
14
+ @options[:stroke_width] ||= 1
15
+ @options[:fill] ||= 'white'
16
+ @options[:font_size] ||= '24px'
17
+
18
+ @width = 0
19
+ @height = 0
20
+ @body = []
21
+ end
22
+
23
+
24
+
25
+ def header
26
+ text = %{<?xml version="1.0" encoding="UTF-8" standalone="no"?>
27
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
28
+
29
+ <svg
30
+ width="100%"
31
+ height="100%"
32
+ version="1.1"
33
+ xmlns="http://www.w3.org/2000/svg">
34
+ }
35
+ end
36
+
37
+ def footer
38
+ text = %{</svg>}
39
+ end
40
+
41
+
42
+
43
+ ## Drawing methodds
44
+ def circle(x=0, y=0, radius=10, opts={})
45
+ local_options = calc_local_options(opts)
46
+ text = %{<circle
47
+ cx="#{x}" cy="#{y}"
48
+ r="#{radius}"
49
+ stroke="#{local_options[:stroke]}"
50
+ stroke-width="#{local_options[:stroke_width]}"
51
+ fill="#{local_options[:fill]}"/>
52
+ }
53
+
54
+ #The call below should be in method missing add_[circle|line|rectangle]
55
+ update_size(x+radius, y+radius)
56
+ @body << text
57
+ end
58
+
59
+ def line(x,y,w,h, opts={})
60
+ local_options = calc_local_options(opts)
61
+ text = %{<line
62
+ x1="#{x}" y1="#{y}"
63
+ x2="#{x+w}" y2="#{y+h}"
64
+ stroke="#{local_options[:stroke]}"
65
+ stroke-width="#{local_options[:stroke_width]}"
66
+ />
67
+ }
68
+ #path d="m #{x},#{y} l #{x+w},#{y+h}"
69
+
70
+ update_size(x+w, y+h)
71
+ @body << text
72
+ end
73
+
74
+ def rectangle(x,y,width,height, opts={})
75
+ local_options = calc_local_options(opts)
76
+ text = %{<rect
77
+ x="#{x}" y="#{y}"
78
+ width="#{width}" height="#{height}"
79
+ fill="#{local_options[:fill]}"
80
+ stroke="#{local_options[:stroke]}"
81
+ stroke-width="#{local_options[:stroke_width]}"
82
+ />
83
+ }
84
+ update_size(x+width, y+height)
85
+ @body << text
86
+ end
87
+
88
+ def text(x,y, input_text, opts={})
89
+ centre_text = "text-anchor:middle; dominant-baseline:central;"
90
+ local_options = calc_local_options(opts)
91
+
92
+
93
+ #Stroke is outline
94
+ #fill is normal font. ie for text fill gets stroke colour
95
+ text = %{<text
96
+ x="#{x}" y="#{y}"
97
+ font-size="#{local_options[:font_size]}"
98
+ fill="#{local_options[:stroke]}"
99
+ font-family="Sans"
100
+ >#{input_text}
101
+ </text>
102
+ }
103
+ #{centre_text}"
104
+ # xml:space="preserve"
105
+ #Do not know height or width of text only the anchor
106
+ update_size(x, y)
107
+ @body << text
108
+ end
109
+
110
+ def options(opts={})
111
+ opts.each_pair do |key,value|
112
+ @options[key] = value
113
+ end
114
+
115
+ #return
116
+ @options
117
+ end
118
+
119
+
120
+ def height
121
+ if @options[:height] == :auto
122
+ @height
123
+ else
124
+ @options[:height]
125
+ end
126
+ end
127
+
128
+ def width
129
+ if @options[:width] == :auto
130
+ @width
131
+ else
132
+ @options[:width]
133
+ end
134
+ end
135
+
136
+
137
+ def components_only_to_s
138
+ text = ""
139
+ @body.each do |section|
140
+ text << section
141
+ end
142
+
143
+ #return
144
+ text
145
+ end
146
+
147
+ # To string includes header and footers
148
+ def to_s
149
+ text = ""
150
+ text << self.header
151
+ @body.each do |section|
152
+ text << section
153
+ end
154
+ text << self.footer
155
+
156
+ #return
157
+ text
158
+ end
159
+
160
+
161
+ #def finalise
162
+ # #Maybe add the initial and closing things here so we are just noramlly dealing drawn components
163
+ # @body.insert(0, header)
164
+ # @body.insert(-1, footer)
165
+ #end
166
+
167
+ # to_file includes header and footers for a complete svg file
168
+ def to_file( filename )
169
+ File.open(filename, 'w') do |f|
170
+ f.puts self.header
171
+ @body.each do |section|
172
+ f.puts section
173
+ end
174
+ f.puts self.footer
175
+ end
176
+ end
177
+
178
+
179
+ # Private method, for allowing overide options
180
+ def calc_local_options(opts={})
181
+ local_opts = @options.dup
182
+ opts.each_pair do |key,value|
183
+ local_opts[key] = value
184
+ end
185
+
186
+ #return
187
+ local_opts
188
+ end
189
+
190
+ #Internal helper function for updating dimensions
191
+ def update_size(x,y)
192
+ @width = x if x > @width
193
+ @height = y if y > @height
194
+ end
195
+
196
+ end
197
+ end
198
+
199
+
200
+
201
+ if $0 == __FILE__
202
+ a = RubySVGLight::Document.new()
203
+ a.circle(20,10,10)
204
+ a.to_file('test.svg')
205
+ end
@@ -0,0 +1,54 @@
1
+
2
+ require File.join( '..', 'lib', 'ruby_svg_light')
3
+
4
+ def check_width_height(svg, width, height)
5
+ svg.width.should == width
6
+ svg.height.should == height
7
+ end
8
+
9
+ describe RubySVGLight, "RubySVGLight" do
10
+ it "Check width calculations, objects from origin" do
11
+ canvas = RubySVGLight::Document.new()
12
+ check_width_height(canvas, 0, 0)
13
+
14
+ canvas.rectangle(0,0,10,20)
15
+ check_width_height(canvas, 10, 20)
16
+
17
+ canvas.line(0,0, 30, 40)
18
+ check_width_height(canvas, 30, 40)
19
+
20
+ canvas.circle(0,0,100)
21
+ check_width_height(canvas, 100, 100)
22
+ end
23
+
24
+ it "Smaller new component should not shrink size" do
25
+ canvas = RubySVGLight::Document.new()
26
+ canvas.circle(0,0,100)
27
+ check_width_height(canvas, 100, 100)
28
+
29
+ canvas.circle(0,0,50)
30
+ check_width_height(canvas, 100, 100)
31
+
32
+ canvas.line(0,0, 60, 40)
33
+ check_width_height(canvas, 100, 100)
34
+
35
+ canvas.rectangle(0,0,10,20)
36
+ check_width_height(canvas, 100, 100)
37
+ end
38
+
39
+ it "Check width calculations, objects not on origin" do
40
+ canvas = RubySVGLight::Document.new()
41
+ check_width_height(canvas, 0, 0)
42
+
43
+ canvas.rectangle(15,25,10,20)
44
+ check_width_height(canvas, 25, 45)
45
+
46
+ canvas.line(35,45, 30, 40)
47
+ check_width_height(canvas, 65, 85)
48
+
49
+ canvas.circle(10,15,100)
50
+ check_width_height(canvas, 110, 115)
51
+ end
52
+ end
53
+
54
+