rasem 0.5.3 → 0.5.6

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.
@@ -1,6 +1,6 @@
1
1
  = Rasem
2
2
 
3
- rasem is a ruby gem that allows you to describe your images in ruby code.
3
+ rasem is a pure ruby gem that allows you to describe your SVG images in ruby code.
4
4
 
5
5
  == Why Rasem
6
6
 
@@ -8,6 +8,8 @@ rasem is a ruby gem that allows you to describe your images in ruby code.
8
8
  * Do you want to draw a complex image that is easier to describe using a code?
9
9
  * Would you like to power your HTML 5 site with nicely drawn SVG images?
10
10
  * Do you need to generate nice images from your ruby code?
11
+ * Did you feed up with using DIVs and Javascript to draw simple graphs?
12
+ * Is your server overwhelmed with sending PNG images that can be described in a few bytes using SVG?
11
13
 
12
14
  Rasem allows you to generate SVG images that can be easily exported to other
13
15
  formats and embed in an HTML 5 page.
@@ -17,6 +19,15 @@ formats and embed in an HTML 5 page.
17
19
  * Draw basic elements: line, rectangle, rouned rectangle, circle, ellipse, polygon and polyline.
18
20
  * Use SVG styles such as stroke-width, opacity and fill.
19
21
  * Create SVG groups for better editing in SVG editors.
22
+ Coming features:
23
+ * Include all SVG standard elements such as gradients, filters and paths
24
+ * Create default rake and thor tasks to convert your .rasem files to .svg.
25
+ * Embed other images in your SVG image
26
+ * Output to more formats such as PNG.
27
+
28
+ Rasem is still in alpha release. Please report your bugs so that we can work on it.
29
+ You are welcome to contribute to the project by adding more features and fixing bugs.
30
+ The end goal of the project is to fully support SVG standard and make it easy to use.
20
31
 
21
32
  == Installation
22
33
  gem install rasem
@@ -75,7 +86,9 @@ Here is a more sophisticated example.
75
86
  tictactoe.rasem
76
87
  set_width 150
77
88
  set_height 150
78
- board = [['x','o','x'], ['o', '-', 'o'], ['x', 'o', 'x']]
89
+ board = [['x', 'o', 'x'],
90
+ ['o', '-', 'o'],
91
+ ['x', 'o', 'x']]
79
92
  def draw_x(x,y)
80
93
  group :stroke=>"red" do
81
94
  line x-20, y-20, x+20, y+20
@@ -87,7 +100,6 @@ tictactoe.rasem
87
100
  circle x, y, 20, :stroke=>"blue", :fill=>"white"
88
101
  end
89
102
 
90
- # Draw the board
91
103
  group :stroke=>"black" do
92
104
  rectangle 0, 0, 150, 150, :stroke_width=>2, :fill=>"white"
93
105
  line 50, 0, 50, 150
@@ -132,12 +144,12 @@ to SVGImage.new
132
144
  end
133
145
  end
134
146
 
135
- The previous example has another advantage of not buffering the whole image to
136
- memory before writing to file. Rasem is smart enough to detect that the output
137
- can be passed directly to the file, hence, saving unnecessary memory buffers.
147
+ The previous example has another advantage.
148
+ It does not need to buffer the whole image to memory before writing to file.
149
+ Rasem is smart enough to detect that the output can be passed directly to the
150
+ file, hence, saving unnecessary memory buffers.
138
151
 
139
152
  == Contributing to rasem
140
-
141
153
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
142
154
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
143
155
  * Fork the project
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.3
1
+ 0.5.6
@@ -17,7 +17,7 @@ class Rasem::Application
17
17
  else
18
18
  svg_file = source_file + ".svg"
19
19
  end
20
- img = Rasem::SVGImage.new(nil, "100%", "100%") do
20
+ img = Rasem::SVGImage.new("100%", "100%") do
21
21
  eval(File.read(source_file), binding)
22
22
  end
23
23
  File.open(svg_file, "w") do |f|
@@ -1,11 +1,20 @@
1
1
  class Rasem::SVGImage
2
- DefaultStyle = {:stroke=>"black", :fill=>"black"}
2
+ DefaultStyles = {
3
+ :text => {:fill=>"black"},
4
+ :line => {:stroke=>"black"},
5
+ :rect => {:stroke=>"black"},
6
+ :circle => {:stroke=>"black"},
7
+ :ellipse => {:stroke=>"black"},
8
+ :polygon => {:stroke=>"black"},
9
+ :polyline => {:stroke=>"black"}
10
+ }
11
+
3
12
 
4
13
  def initialize(width, height, output=nil, &block)
5
14
  @output = create_output(output)
6
15
 
7
16
  # Initialize a stack of default styles
8
- @default_styles = [DefaultStyle]
17
+ @default_styles = []
9
18
 
10
19
  write_header(width, height)
11
20
  if block
@@ -31,14 +40,14 @@ class Rasem::SVGImage
31
40
  end
32
41
 
33
42
  # Draw a straight line between the two end points
34
- def line(x1, y1, x2, y2, style={})
43
+ def line(x1, y1, x2, y2, style=DefaultStyles[:line])
35
44
  @output << %Q{<line x1="#{x1}" y1="#{y1}" x2="#{x2}" y2="#{y2}"}
36
45
  write_style(style)
37
46
  @output << %Q{/>}
38
47
  end
39
48
 
40
49
  # Draw a circle given a center and a radius
41
- def circle(cx, cy, r, style={})
50
+ def circle(cx, cy, r, style=DefaultStyles[:circle])
42
51
  @output << %Q{<circle cx="#{cx}" cy="#{cy}" r="#{r}"}
43
52
  write_style(style)
44
53
  @output << %Q{/>}
@@ -46,7 +55,7 @@ class Rasem::SVGImage
46
55
 
47
56
  # Draw a rectangle or rounded rectangle
48
57
  def rectangle(x, y, width, height, *args)
49
- style = (!args.empty? && args.last.is_a?(Hash)) ? args.pop : {}
58
+ style = (!args.empty? && args.last.is_a?(Hash)) ? args.pop : DefaultStyles[:rect]
50
59
  if args.length == 0
51
60
  rx = ry = 0
52
61
  elsif args.length == 1
@@ -64,7 +73,7 @@ class Rasem::SVGImage
64
73
  end
65
74
 
66
75
  # Draw an circle given a center and two radii
67
- def ellipse(cx, cy, rx, ry, style={})
76
+ def ellipse(cx, cy, rx, ry, style=DefaultStyles[:ellipse])
68
77
  @output << %Q{<ellipse cx="#{cx}" cy="#{cy}" rx="#{rx}" ry="#{ry}"}
69
78
  write_style(style)
70
79
  @output << %Q{/>}
@@ -114,6 +123,23 @@ class Rasem::SVGImage
114
123
  @output << "</g>"
115
124
  end
116
125
 
126
+ def text(x, y, text, style=DefaultStyles[:text])
127
+ @output << %Q{<text x="#{x}" y="#{y}"}
128
+ style = fix_style(default_style.merge(style))
129
+ @output << %Q{ font-family="#{style.delete "font-family"}"} if style["font-family"]
130
+ @output << %Q{ font-size="#{style.delete "font-size"}"} if style["font-size"]
131
+ write_style style
132
+ @output << ">"
133
+ dy = 0 # First line should not be shifted
134
+ text.each_line do |line|
135
+ @output << %Q{<tspan x="#{x}" dy="#{dy}em">}
136
+ dy = 1 # Next lines should be shifted
137
+ @output << line.rstrip
138
+ @output << "</tspan>"
139
+ end
140
+ @output << "</text>"
141
+ end
142
+
117
143
  private
118
144
  # Creates an object for ouput out of an argument
119
145
  def create_output(arg)
@@ -145,7 +171,7 @@ private
145
171
  # Draws either a polygon or polyline according to the first parameter
146
172
  def polything(name, *args)
147
173
  return if args.empty?
148
- style = (args.last.is_a?(Hash)) ? args.pop : {}
174
+ style = (args.last.is_a?(Hash)) ? args.pop : DefaultStyles[name.to_sym]
149
175
  coords = args.flatten
150
176
  raise "Illegal number of coordinates (should be even)" if coords.length.odd?
151
177
  @output << %Q{<#{name} points="}
@@ -164,6 +190,16 @@ private
164
190
  @default_styles.last || {}
165
191
  end
166
192
 
193
+ # Returns a new hash for styles after fixing names to match SVG standard
194
+ def fix_style(style)
195
+ new_style = {}
196
+ style.each_pair do |k, v|
197
+ new_k = k.to_s.gsub('_', '-')
198
+ new_style[new_k] = v
199
+ end
200
+ new_style
201
+ end
202
+
167
203
  # Writes styles to current output
168
204
  # Avaialable styles are:
169
205
  # fill: Fill color
@@ -173,11 +209,11 @@ private
173
209
  # stroke-opacity: stroke opacity. ranges from 0 to 1
174
210
  # opacity: Opacity for the whole element
175
211
  def write_style(style)
176
- style_ = default_style.merge(style)
212
+ style_ = fix_style(default_style.merge(style))
177
213
  return if style_.empty?
178
214
  @output << ' style="'
179
- style_.each_pair do |style, value|
180
- @output << "#{style.to_s.gsub('_','-')}:#{value};"
215
+ style_.each_pair do |attribute, value|
216
+ @output << "#{attribute}:#{value};"
181
217
  end
182
218
  @output << '"'
183
219
  end
@@ -270,4 +270,32 @@ describe Rasem::SVGImage do
270
270
  str.should =~ %r{height="300"}
271
271
  end
272
272
 
273
+ it "should draw text" do
274
+ img = Rasem::SVGImage.new(100, 100) do
275
+ text 10, 20, "Hello world!"
276
+ end
277
+ str = img.output
278
+ str.should =~ %r{<text}
279
+ str.should =~ %r{x="10"}
280
+ str.should =~ %r{y="20"}
281
+ str.should =~ %r{Hello world!}
282
+ end
283
+
284
+ it "should draw multiline text" do
285
+ img = Rasem::SVGImage.new(100, 100) do
286
+ text 10, 20, "Hello\nworld!"
287
+ end
288
+ str = img.output
289
+ str.should =~ %r{<text.*tspan.*tspan.*</text}
290
+ end
291
+
292
+ it "should draw text with font" do
293
+ img = Rasem::SVGImage.new(100, 100) do
294
+ text 10, 20, "Hello\nworld!", :font_family=>"Times", "font-size"=>24
295
+ end
296
+ str = img.output
297
+ str.should =~ %r{font-family="Times"}
298
+ str.should =~ %r{font-size="24"}
299
+ end
300
+
273
301
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 5
8
- - 3
9
- version: 0.5.3
8
+ - 6
9
+ version: 0.5.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ahmed Eldawy
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-04-10 00:00:00 -05:00
17
+ date: 2011-04-14 00:00:00 -05:00
18
18
  default_executable: rasem
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -112,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
112
  requirements:
113
113
  - - ">="
114
114
  - !ruby/object:Gem::Version
115
- hash: 1518989641663935495
115
+ hash: 367852017
116
116
  segments:
117
117
  - 0
118
118
  version: "0"