Class: Rasem::SVGImage

Inherits:
Object
  • Object
show all
Defined in:
lib/rasem/svg_image.rb

Constant Summary collapse

DefaultStyles =
{
  :text => {:fill=>"black"},
  :line => {:stroke=>"black"},
  :rect => {:stroke=>"black"},
  :circle => {:stroke=>"black"},
  :ellipse => {:stroke=>"black"},
  :polygon => {:stroke=>"black"},
  :polyline => {:stroke=>"black"}
}

Instance Method Summary collapse

Constructor Details

#initialize(width, height, output = nil, &block) ⇒ SVGImage

Returns a new instance of SVGImage.



13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/rasem/svg_image.rb', line 13

def initialize(width, height, output=nil, &block)
  @output = create_output(output)
  
  # Initialize a stack of default styles
  @default_styles = []

  write_header(width, height)
  if block
    self.instance_exec(&block)
    self.close
  end
end

Instance Method Details

#circle(cx, cy, r, style = ) ⇒ Object

Draw a circle given a center and a radius



50
51
52
53
54
# File 'lib/rasem/svg_image.rb', line 50

def circle(cx, cy, r, style=DefaultStyles[:circle])
  @output << %Q{<circle cx="#{cx}" cy="#{cy}" r="#{r}"}
  write_style(style)
  @output << %Q{/>}
end

#closeObject

Closes the file. No more drawing is possible after this



91
92
93
94
# File 'lib/rasem/svg_image.rb', line 91

def close
  write_close
  @closed = true
end

#closed?Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/rasem/svg_image.rb', line 100

def closed?
  @closed
end

#ellipse(cx, cy, rx, ry, style = ) ⇒ Object

Draw an circle given a center and two radii



76
77
78
79
80
# File 'lib/rasem/svg_image.rb', line 76

def ellipse(cx, cy, rx, ry, style=DefaultStyles[:ellipse])
  @output << %Q{<ellipse cx="#{cx}" cy="#{cy}" rx="#{rx}" ry="#{ry}"}
  write_style(style)
  @output << %Q{/>}
end

#group(style = {}, &proc) ⇒ Object



115
116
117
118
119
120
121
122
123
124
# File 'lib/rasem/svg_image.rb', line 115

def group(style={}, &proc)
  # Open the group
  @output << "<g"
  write_style(style)
  @output << ">"
  # Call the block
  self.instance_exec(&proc)
  # Close the group
  @output << "</g>"
end

#line(x1, y1, x2, y2, style = ) ⇒ Object

Draw a straight line between the two end points



43
44
45
46
47
# File 'lib/rasem/svg_image.rb', line 43

def line(x1, y1, x2, y2, style=DefaultStyles[:line])
  @output << %Q{<line x1="#{x1}" y1="#{y1}" x2="#{x2}" y2="#{y2}"}
  write_style(style)
  @output << %Q{/>}
end

#outputObject



96
97
98
# File 'lib/rasem/svg_image.rb', line 96

def output
  @output.to_s
end

#polygon(*args) ⇒ Object



82
83
84
# File 'lib/rasem/svg_image.rb', line 82

def polygon(*args)
  polything("polygon", *args)
end

#polyline(*args) ⇒ Object



86
87
88
# File 'lib/rasem/svg_image.rb', line 86

def polyline(*args)
  polything("polyline", *args)
end

#rectangle(x, y, width, height, *args) ⇒ Object

Draw a rectangle or rounded rectangle



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rasem/svg_image.rb', line 57

def rectangle(x, y, width, height, *args)
  style = (!args.empty? && args.last.is_a?(Hash)) ? args.pop : DefaultStyles[:rect]
  if args.length == 0
    rx = ry = 0
  elsif args.length == 1
    rx = ry = args.pop
  elsif args.length == 2
    rx, ry = args
  else
    raise "Illegal number of arguments to rectangle"
  end
    
  @output << %Q{<rect x="#{x}" y="#{y}" width="#{width}" height="#{height}"}
  @output << %Q{ rx="#{rx}" ry="#{ry}"} if rx && ry
  write_style(style)
  @output << %Q{/>}
end

#set_height(new_height) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/rasem/svg_image.rb', line 34

def set_height(new_height)
  if @output.respond_to?(:sub!)
    @output.sub!(/<svg width="([^"]+)" height="[^"]+"/, %Q{<svg width="\\1" height="#{new_height}"})
  else
    raise "Cannot change width after initialization for this output"
  end
end

#set_width(new_width) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/rasem/svg_image.rb', line 26

def set_width(new_width)
  if @output.respond_to?(:sub!)
    @output.sub!(/<svg width="[^"]+"/, %Q{<svg width="#{new_width}"})
  else
    raise "Cannot change width after initialization for this output"
  end
end

#text(x, y, text, style = ) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/rasem/svg_image.rb', line 126

def text(x, y, text, style=DefaultStyles[:text])
  @output << %Q{<text x="#{x}" y="#{y}"}
  style = fix_style(default_style.merge(style))
  @output << %Q{ font-family="#{style.delete "font-family"}"} if style["font-family"]
  @output << %Q{ font-size="#{style.delete "font-size"}"} if style["font-size"]
  write_style style
  @output << ">"
  dy = 0      # First line should not be shifted
  text.each_line do |line|
    @output << %Q{<tspan x="#{x}" dy="#{dy}em">}
    dy = 1    # Next lines should be shifted
    @output << line.rstrip
    @output << "</tspan>"
  end
  @output << "</text>"
end

#with_style(style = {}, &proc) ⇒ Object



104
105
106
107
108
109
110
111
112
113
# File 'lib/rasem/svg_image.rb', line 104

def with_style(style={}, &proc)
  # Merge passed style with current default style
  updated_style = default_style.merge(style)
  # Push updated style to the stack
  @default_styles.push(updated_style)
  # Call the block
  self.instance_exec(&proc)
  # Pop style again to revert changes
  @default_styles.pop
end