Class: Barby::SvgOutputter

Inherits:
Outputter show all
Defined in:
lib/barby/outputter/svg_outputter.rb

Overview

Renders the barcode to a simple SVG image using pure ruby

Registers the to_svg, bars_to_path, and bars_to_rects method

Bars can be rendered as a stroked path or as filled rectangles. Path generally yields smaller files, but this doesn’t render cleanly in Firefox 3 for odd xdims. My guess is that the renderer tries to put half a pixel on one side of the path and half on the other, leading to fuzzy dithering instead of sharp, clean b&w.

Therefore, default behavior is to use a path for even xdims, and rectangles for odd. This can be overridden by calling with explicit :use => ‘rects’ or :use => ‘path’ options.

Instance Attribute Summary collapse

Attributes inherited from Outputter

#barcode

Instance Method Summary collapse

Methods inherited from Outputter

#boolean_groups, #booleans, #encoding, #initialize, register, #two_dimensional?

Constructor Details

This class inherits a constructor from Barby::Outputter

Instance Attribute Details

#backgroundObject



186
187
188
# File 'lib/barby/outputter/svg_outputter.rb', line 186

def background
  @background || '#fff'
end

#bmarginObject



159
160
161
# File 'lib/barby/outputter/svg_outputter.rb', line 159

def bmargin
  @bmargin || _ymargin
end

#foregroundObject



182
183
184
# File 'lib/barby/outputter/svg_outputter.rb', line 182

def foreground
  @foreground || '#000'
end

#heightObject



127
128
129
# File 'lib/barby/outputter/svg_outputter.rb', line 127

def height
  barcode.two_dimensional? ? (ydim * encoding.length) : (@height || 100)
end

#lmarginObject



147
148
149
# File 'lib/barby/outputter/svg_outputter.rb', line 147

def lmargin
  @lmargin || _xmargin
end

#marginObject



173
174
175
176
# File 'lib/barby/outputter/svg_outputter.rb', line 173

def margin
  return nil if @ymargin || @xmargin || @tmargin || @bmargin || @lmargin || @rmargin
  _margin
end

#rmarginObject



151
152
153
# File 'lib/barby/outputter/svg_outputter.rb', line 151

def rmargin
  @rmargin || _xmargin
end

#titleObject



119
120
121
# File 'lib/barby/outputter/svg_outputter.rb', line 119

def title
  @title || barcode.to_s
end

#tmarginObject



155
156
157
# File 'lib/barby/outputter/svg_outputter.rb', line 155

def tmargin
  @tmargin || _ymargin
end

#xdimObject



139
140
141
# File 'lib/barby/outputter/svg_outputter.rb', line 139

def xdim
  @xdim || 1
end

#xmarginObject



163
164
165
166
# File 'lib/barby/outputter/svg_outputter.rb', line 163

def xmargin
  return nil if @lmargin || @rmargin
  _margin
end

#ydimObject



143
144
145
# File 'lib/barby/outputter/svg_outputter.rb', line 143

def ydim
  @ydim || xdim
end

#ymarginObject



168
169
170
171
# File 'lib/barby/outputter/svg_outputter.rb', line 168

def ymargin
  return nil if @tmargin || @bmargin
  _margin
end

Instance Method Details

#bars_to_path(opts = {}) ⇒ Object



82
83
84
85
86
# File 'lib/barby/outputter/svg_outputter.rb', line 82

def bars_to_path(opts={})
  with_options opts do
    %Q|<path stroke="black" stroke-width="#{xdim}" d="#{bars_to_path_data(opts)}" />|
  end
end

#bars_to_path_data(opts = {}) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/barby/outputter/svg_outputter.rb', line 88

def bars_to_path_data(opts={})
  path_data = ''
  with_options opts do
    x, y = lmargin+(xdim/2), tmargin

    if barcode.two_dimensional?
      booleans.each do |line|
        line.each do |bar|
          if bar
            path_data << "M#{x} #{y}V #{y+ydim}"
          end
          x += xdim
        end
        y += ydim
        x = lmargin+(xdim/2)
      end

    else
      booleans.each do |bar|
        if bar
          path_data << "M#{x} #{y}V#{y+height}"
        end
        x += xdim
      end

    end
  end # with_options

  path_data
end

#bars_to_rects(opts = {}) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/barby/outputter/svg_outputter.rb', line 49

def bars_to_rects(opts={})
  rects = ''
  with_options opts do
    x, y = lmargin, tmargin

    if barcode.two_dimensional?
      boolean_groups.each do |line|
        line.each do |bar, amount|
          bar_width = xdim * amount
          if bar
            rects << %Q|<rect x="#{x}" y="#{y}" width="#{bar_width}px" height="#{ydim}px" />\n|
          end
          x += bar_width
        end
        y += ydim
        x = lmargin
      end

    else
      boolean_groups.each do |bar, amount|
        bar_width = xdim * amount
        if bar
          rects << %Q|<rect x="#{x}" y="#{y}" width="#{bar_width}px" height="#{height}px" />\n|
        end
        x += bar_width
      end

    end
  end # with_options

  rects
end

#full_heightObject



135
136
137
# File 'lib/barby/outputter/svg_outputter.rb', line 135

def full_height
  height + tmargin + bmargin
end

#full_widthObject



131
132
133
# File 'lib/barby/outputter/svg_outputter.rb', line 131

def full_width
  width + lmargin + rmargin
end

#lengthObject



178
179
180
# File 'lib/barby/outputter/svg_outputter.rb', line 178

def length
  barcode.two_dimensional? ? encoding.first.length : encoding.length
end

#svg_height(opts = {}) ⇒ Object



194
195
196
# File 'lib/barby/outputter/svg_outputter.rb', line 194

def svg_height(opts={})
  opts[:rot] ? full_width : full_height
end

#svg_width(opts = {}) ⇒ Object



190
191
192
# File 'lib/barby/outputter/svg_outputter.rb', line 190

def svg_width(opts={})
  opts[:rot] ? full_height : full_width
end

#to_svg(opts = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/barby/outputter/svg_outputter.rb', line 25

def to_svg(opts={})
  with_options opts do
    case opts[:use]
      when 'rects' then bars = bars_to_rects
      when 'path'  then bars = bars_to_path
    else
      xdim_odd = (xdim % 2 == 1)
      bars = xdim_odd ? bars_to_rects : bars_to_path
    end

    <<-"EOT"
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="#{svg_width(opts)}px" height="#{svg_height(opts)}px" viewBox="0 0 #{svg_width(opts)} #{svg_height(opts)}" version="1.1" preserveAspectRatio="none" >
<title>#{escape title}</title>
<g id="canvas" #{transform(opts)}>
<rect x="0" y="0" width="#{full_width}px" height="#{full_height}px" fill="#{background}" />
<g id="barcode" fill="#{foreground}">
#{bars}
</g></g>
</svg>
EOT
  end
end

#transform(opts = {}) ⇒ Object



198
199
200
# File 'lib/barby/outputter/svg_outputter.rb', line 198

def transform(opts={})
  opts[:rot] ? %Q|transform="rotate(-90) translate(-#{full_width}, 0)"| : nil
end

#widthObject



123
124
125
# File 'lib/barby/outputter/svg_outputter.rb', line 123

def width
  length * xdim
end