arena_barby 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/README +29 -0
  2. data/bin/barby +41 -0
  3. data/lib/barby.rb +17 -0
  4. data/lib/barby/barcode.rb +116 -0
  5. data/lib/barby/barcode/bookland.rb +37 -0
  6. data/lib/barby/barcode/code_128.rb +410 -0
  7. data/lib/barby/barcode/code_25.rb +193 -0
  8. data/lib/barby/barcode/code_25_iata.rb +23 -0
  9. data/lib/barby/barcode/code_25_interleaved.rb +73 -0
  10. data/lib/barby/barcode/code_39.rb +233 -0
  11. data/lib/barby/barcode/code_93.rb +230 -0
  12. data/lib/barby/barcode/ean_13.rb +178 -0
  13. data/lib/barby/barcode/ean_8.rb +32 -0
  14. data/lib/barby/barcode/gs1_128.rb +42 -0
  15. data/lib/barby/barcode/pdf_417.rb +76 -0
  16. data/lib/barby/barcode/qr_code.rb +101 -0
  17. data/lib/barby/outputter.rb +127 -0
  18. data/lib/barby/outputter/ascii_outputter.rb +41 -0
  19. data/lib/barby/outputter/cairo_outputter.rb +185 -0
  20. data/lib/barby/outputter/pdfwriter_outputter.rb +83 -0
  21. data/lib/barby/outputter/png_outputter.rb +97 -0
  22. data/lib/barby/outputter/prawn_outputter.rb +99 -0
  23. data/lib/barby/outputter/rmagick_outputter.rb +126 -0
  24. data/lib/barby/outputter/svg_outputter.rb +225 -0
  25. data/lib/barby/vendor.rb +3 -0
  26. data/lib/barby/version.rb +9 -0
  27. data/vendor/Pdf417lib-java-0.91/lib/Pdf417lib.jar +0 -0
  28. data/vendor/Pdf417lib-java-0.91/lib/Pdf417lib.java +1471 -0
  29. data/vendor/rqrcode/CHANGELOG +29 -0
  30. data/vendor/rqrcode/COPYING +19 -0
  31. data/vendor/rqrcode/README +98 -0
  32. data/vendor/rqrcode/Rakefile +65 -0
  33. data/vendor/rqrcode/lib/rqrcode.rb +13 -0
  34. data/vendor/rqrcode/lib/rqrcode/core_ext.rb +5 -0
  35. data/vendor/rqrcode/lib/rqrcode/core_ext/array.rb +5 -0
  36. data/vendor/rqrcode/lib/rqrcode/core_ext/array/behavior.rb +9 -0
  37. data/vendor/rqrcode/lib/rqrcode/core_ext/integer.rb +5 -0
  38. data/vendor/rqrcode/lib/rqrcode/core_ext/integer/bitwise.rb +11 -0
  39. data/vendor/rqrcode/lib/rqrcode/qrcode.rb +4 -0
  40. data/vendor/rqrcode/lib/rqrcode/qrcode/qr_8bit_byte.rb +37 -0
  41. data/vendor/rqrcode/lib/rqrcode/qrcode/qr_bit_buffer.rb +56 -0
  42. data/vendor/rqrcode/lib/rqrcode/qrcode/qr_code.rb +421 -0
  43. data/vendor/rqrcode/lib/rqrcode/qrcode/qr_math.rb +63 -0
  44. data/vendor/rqrcode/lib/rqrcode/qrcode/qr_polynomial.rb +78 -0
  45. data/vendor/rqrcode/lib/rqrcode/qrcode/qr_rs_block.rb +313 -0
  46. data/vendor/rqrcode/lib/rqrcode/qrcode/qr_util.rb +254 -0
  47. data/vendor/rqrcode/test/runtest.rb +78 -0
  48. data/vendor/rqrcode/test/test_data.rb +21 -0
  49. metadata +114 -0
@@ -0,0 +1,76 @@
1
+ require 'barby/barcode'
2
+ require 'java'
3
+ require 'Pdf417lib'
4
+ import 'Pdf417lib'
5
+
6
+ module Barby
7
+ class Pdf417 < Barcode2D
8
+ DEFAULT_OPTIONS = {
9
+ :options => 0,
10
+ :y_height => 3,
11
+ :aspect_ratio => 0.5,
12
+ :error_level => 0,
13
+ :len_codewords => 0,
14
+ :code_rows => 0,
15
+ :code_columns => 0
16
+ }
17
+
18
+ # Creates a new Pdf417 barcode. The +options+ argument
19
+ # can use the same keys as DEFAULT_OPTIONS. Please consult
20
+ # the source code of Pdf417lib.java for details about values
21
+ # that can be used.
22
+ def initialize(data, options={})
23
+ @pdf417 = Java::Pdf417lib.new
24
+ self.data = data
25
+ DEFAULT_OPTIONS.merge(options).each{|k,v| send("#{k}=", v) }
26
+ end
27
+
28
+ def options=(options)
29
+ @options = options
30
+ end
31
+
32
+ def y_height=(y_height)
33
+ @pdf417.setYHeight(y_height)
34
+ end
35
+
36
+ def aspect_ratio=(aspect_ratio)
37
+ @pdf417.setAspectRatio(aspect_ratio)
38
+ end
39
+
40
+ def error_level=(error_level)
41
+ @pdf417.setErrorLevel(error_level)
42
+ end
43
+
44
+ def len_codewords=(len_codewords)
45
+ @pdf417.setLenCodewords(len_codewords)
46
+ end
47
+
48
+ def code_rows=(code_rows)
49
+ @pdf417.setCodeRows(code_rows)
50
+ end
51
+
52
+ def code_columns=(code_columns)
53
+ @pdf417.setCodeColumns(code_columns)
54
+ end
55
+
56
+ def data=(data)
57
+ @pdf417.setText(data)
58
+ end
59
+
60
+ def encoding
61
+ @pdf417.paintCode()
62
+
63
+ cols = (@pdf417.getBitColumns() - 1) / 8 + 1
64
+ enc = []
65
+ row = nil
66
+ @pdf417.getOutBits.each_with_index do |byte, n|
67
+ if n%cols == 0
68
+ row = ""
69
+ enc << row
70
+ end
71
+ row << sprintf("%08b", (byte & 0xff) | 0x100)
72
+ end
73
+ enc
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,101 @@
1
+ require 'rqrcode'
2
+ require 'barby/barcode'
3
+
4
+ module Barby
5
+
6
+
7
+ #QrCode is a thin wrapper around the RQRCode library
8
+ class QrCode < Barcode2D
9
+
10
+ #Maximum sizes for each correction level for binary data
11
+ #It's an array
12
+ SIZES = {
13
+ #L M Q H
14
+ 1 => [17, 14, 11, 7], 2 => [32, 26, 20, 14],
15
+ 3 => [53, 42, 32, 24], 4 => [78, 62, 46, 34],
16
+ 5 => [106, 84, 60, 44], 6 => [134, 106, 74, 58],
17
+ 7 => [154, 122, 86, 64], 8 => [192, 152, 108, 84],
18
+ 9 => [230, 180, 130, 98], 10 => [271, 213, 151, 119],
19
+ 11 => [321, 251, 177, 137], 12 => [367, 287, 203, 155],
20
+ 13 => [425, 331, 241, 177], 14 => [458, 362, 258, 194],
21
+ 15 => [520, 412, 292, 220], 16 => [586, 450, 322, 250],
22
+ 17 => [644, 504, 364, 280], 18 => [718, 560, 394, 310],
23
+ 19 => [792, 624, 442, 338], 20 => [858, 666, 482, 382],
24
+ 21 => [929, 711, 509, 403], 22 => [1003, 779, 565, 439],
25
+ 23 => [1091, 857, 611, 461], 24 => [1171, 911, 661, 511],
26
+ 25 => [1273, 997, 715, 535], 26 => [1367, 1059, 751, 593],
27
+ 27 => [1465, 1125, 805, 625], 28 => [1528, 1190, 868, 658],
28
+ 29 => [1628, 1264, 908, 698], 30 => [1732, 1370, 982, 742],
29
+ 31 => [1840, 1452, 1030, 790], 32 => [1952, 1538, 1112, 842],
30
+ 33 => [2068, 1628, 1168, 898], 34 => [2188, 1722, 1228, 958],
31
+ 35 => [2303, 1809, 1283, 983], 36 => [2431, 1911, 1351, 1051],
32
+ 37 => [2563, 1989, 1423, 1093], 38 => [2699, 2099, 1499, 1139],
33
+ 39 => [2809, 2213, 1579, 1219], 40 => [2953, 2331, 1663, 1273]
34
+ }.sort
35
+
36
+ LEVELS = { :l => 0, :m => 1, :q => 2, :h => 3 }
37
+
38
+ attr_reader :data
39
+ attr_writer :level, :size
40
+
41
+
42
+ def initialize(data, options={})
43
+ self.data = data
44
+ options.each{|k,v| send("#{k}=", v) }
45
+ raise(ArgumentError, "data too large") unless size
46
+ end
47
+
48
+
49
+ def data=(data)
50
+ @data = data
51
+ end
52
+
53
+
54
+ def encoding
55
+ rqrcode.modules.map{|r| r.inject(''){|s,m| s << (m ? '1' : '0') } }
56
+ end
57
+
58
+
59
+ #Error correction level
60
+ #Can be one of [:l, :m, :q, :h] (7%, 15%, 25%, 30%)
61
+ def level
62
+ @level || :l
63
+ end
64
+
65
+
66
+ def size
67
+ #@size is only used for manual override, if it's not set
68
+ #manually the size is always dynamic, calculated from the
69
+ #length of the data
70
+ return @size if @size
71
+
72
+ level_index = LEVELS[level]
73
+ length = data.length
74
+ found_size = nil
75
+ SIZES.each do |size,max_values|
76
+ if max_values[level_index] >= length
77
+ found_size = size
78
+ break
79
+ end
80
+ end
81
+ found_size
82
+ end
83
+
84
+
85
+ def to_s
86
+ data[0,20]
87
+ end
88
+
89
+
90
+ private
91
+
92
+ #Generate an RQRCode object with the available values
93
+ def rqrcode
94
+ RQRCode::QRCode.new(data, :level => level, :size => size)
95
+ end
96
+
97
+
98
+ end
99
+
100
+
101
+ end
@@ -0,0 +1,127 @@
1
+ require 'barby/barcode'
2
+
3
+ module Barby
4
+
5
+
6
+ #An Outputter creates something from a barcode. That something can be
7
+ #anything, but is most likely a graphical representation of the barcode.
8
+ #Outputters can register methods on barcodes that will be associated with
9
+ #them.
10
+ #
11
+ #The basic structure of an outputter class:
12
+ #
13
+ # class FooOutputter < Barby::Outputter
14
+ # register :to_foo
15
+ # def to_too
16
+ # do_something_with(barcode.encoding)
17
+ # end
18
+ # end
19
+ #
20
+ #Barcode#to_foo will now be available to all barcodes
21
+ class Outputter
22
+
23
+ attr_accessor :barcode
24
+
25
+
26
+ #An outputter instance will have access to a Barcode
27
+ def initialize(barcode)
28
+ self.barcode = barcode
29
+ end
30
+
31
+
32
+ #Register one or more handler methods with this outputter
33
+ #Barcodes will then be able to use these methods to get the output
34
+ #from the outputter. For example, if you have an ImageOutputter,
35
+ #you could do:
36
+ #
37
+ #register :to_png, :to_gif
38
+ #
39
+ #You could then do aBarcode.to_png and get the result of that method.
40
+ #The class which registers the method will receive the barcode as the only
41
+ #argument, and the default implementation of initialize puts that into
42
+ #the +barcode+ accessor.
43
+ #
44
+ #You can also have different method names on the barcode and the outputter
45
+ #by providing a hash:
46
+ #
47
+ #register :to_png => :create_png, :to_gif => :create_gif
48
+ def self.register(*method_names)
49
+ if method_names.first.is_a? Hash
50
+ method_names.first.each do |name, method_name|
51
+ Barcode.register_outputter(name, self, method_name)
52
+ end
53
+ else
54
+ method_names.each do |name|
55
+ Barcode.register_outputter(name, self, name)
56
+ end
57
+ end
58
+ end
59
+
60
+
61
+ private
62
+
63
+ #Converts the barcode's encoding (a string containing 1s and 0s)
64
+ #to true and false values (1 == true == "black bar")
65
+ #
66
+ #If the barcode is 2D, each line will be converted to an array
67
+ #in the same way
68
+ def booleans(reload=false)#:doc:
69
+ if barcode.two_dimensional?
70
+ encoding(reload).map{|l| l.split(//).map{|c| c == '1' } }
71
+ else
72
+ encoding(reload).split(//).map{|c| c == '1' }
73
+ end
74
+ end
75
+
76
+
77
+ #Returns the barcode's encoding. The encoding
78
+ #is cached and can be reloaded by passing true
79
+ def encoding(reload=false)#:doc:
80
+ @encoding = barcode.encoding if reload
81
+ @encoding ||= barcode.encoding
82
+ end
83
+
84
+
85
+ #Collects continuous groups of bars and spaces (1 and 0)
86
+ #into arrays where the first item is true or false (1 or 0)
87
+ #and the second is the size of the group
88
+ #
89
+ #For example, "1100111000" becomes [[true,2],[false,2],[true,3],[false,3]]
90
+ def boolean_groups(reload=false)
91
+ if barcode.two_dimensional?
92
+ encoding(reload).map do |line|
93
+ line.scan(/1+|0+/).map do |group|
94
+ [group[0,1] == '1', group.size]
95
+ end
96
+ end
97
+ else
98
+ encoding(reload).scan(/1+|0+/).map do |group|
99
+ [group[0,1] == '1', group.size]
100
+ end
101
+ end
102
+ end
103
+
104
+
105
+ def with_options(options={})
106
+ original_options = options.inject({}) do |origs,pair|
107
+ if respond_to?(pair.first) && respond_to?("#{pair.first}=")
108
+ origs[pair.first] = send(pair.first)
109
+ send("#{pair.first}=", pair.last)
110
+ end
111
+ origs
112
+ end
113
+
114
+ rv = yield
115
+
116
+ original_options.each do |attribute,value|
117
+ send("#{attribute}=", value)
118
+ end
119
+
120
+ rv
121
+ end
122
+
123
+
124
+ end
125
+
126
+
127
+ end
@@ -0,0 +1,41 @@
1
+ require 'barby/outputter'
2
+
3
+ module Barby
4
+
5
+ #Outputs an ASCII representation of the barcode. This is mostly useful for printing
6
+ #the barcode directly to the terminal for testing.
7
+ #
8
+ #Registers to_ascii
9
+ class ASCIIOutputter < Outputter
10
+
11
+ register :to_ascii
12
+
13
+
14
+ def to_ascii(opts={})
15
+ default_opts = {:height => 10, :xdim => 1, :bar => '#', :space => ' '}
16
+ default_opts.update(:height => 1, :bar => ' X ', :space => ' ') if barcode.two_dimensional?
17
+ opts = default_opts.merge(opts)
18
+
19
+ if barcode.two_dimensional?
20
+ booleans.map do |bools|
21
+ line_to_ascii(bools, opts)
22
+ end.join("\n")
23
+ else
24
+ line_to_ascii(booleans, opts)
25
+ end
26
+ end
27
+
28
+
29
+ private
30
+
31
+ def line_to_ascii(booleans, opts)
32
+ Array.new(
33
+ opts[:height],
34
+ booleans.map{|b| (b ? opts[:bar] : opts[:space]) * opts[:xdim] }.join
35
+ ).join("\n")
36
+ end
37
+
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,185 @@
1
+ require 'barby/outputter'
2
+ require 'cairo'
3
+ require 'stringio'
4
+
5
+ module Barby
6
+
7
+ #Uses Cairo to render a barcode to a number of formats: PNG, PS, EPS, PDF and SVG
8
+ #
9
+ #Registers methods render_to_cairo_context, to_png, to_ps, to_eps, to_pdf and to_svg
10
+ class CairoOutputter < Outputter
11
+
12
+ register :render_to_cairo_context
13
+ register :to_png
14
+
15
+ if Cairo.const_defined?(:PSSurface)
16
+ register :to_ps
17
+ register :to_eps if Cairo::PSSurface.method_defined?(:eps=)
18
+ end
19
+
20
+ register :to_pdf if Cairo.const_defined?(:PDFSurface)
21
+ register :to_svg if Cairo.const_defined?(:SVGSurface)
22
+
23
+ attr_writer :x, :y, :xdim, :height, :margin
24
+
25
+
26
+ #Render the barcode onto a Cairo context
27
+ def render_to_cairo_context(context, options={})
28
+ if context.respond_to?(:have_current_point?) and
29
+ context.have_current_point?
30
+ current_x, current_y = context.current_point
31
+ else
32
+ current_x = x(options) || margin(options)
33
+ current_y = y(options) || margin(options)
34
+ end
35
+
36
+ _xdim = xdim(options)
37
+ _height = height(options)
38
+ original_current_x = current_x
39
+ context.save do
40
+ context.set_source_color(:black)
41
+ context.fill do
42
+ if barcode.two_dimensional?
43
+ boolean_groups.each do |groups|
44
+ groups.each do |bar,amount|
45
+ current_width = _xdim * amount
46
+ if bar
47
+ context.rectangle(current_x, current_y, current_width, _xdim)
48
+ end
49
+ current_x += current_width
50
+ end
51
+ current_x = original_current_x
52
+ current_y += _xdim
53
+ end
54
+ else
55
+ boolean_groups.each do |bar,amount|
56
+ current_width = _xdim * amount
57
+ if bar
58
+ context.rectangle(current_x, current_y, current_width, _height)
59
+ end
60
+ current_x += current_width
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ context
67
+ end
68
+
69
+
70
+ #Render the barcode to a PNG image
71
+ def to_png(options={})
72
+ output_to_string_io do |io|
73
+ Cairo::ImageSurface.new(options[:format],
74
+ full_width(options),
75
+ full_height(options)) do |surface|
76
+ render(surface, options)
77
+ surface.write_to_png(io)
78
+ end
79
+ end
80
+ end
81
+
82
+
83
+ #Render the barcode to a PS document
84
+ def to_ps(options={})
85
+ output_to_string_io do |io|
86
+ Cairo::PSSurface.new(io,
87
+ full_width(options),
88
+ full_height(options)) do |surface|
89
+ surface.eps = options[:eps] if surface.respond_to?(:eps=)
90
+ render(surface, options)
91
+ end
92
+ end
93
+ end
94
+
95
+
96
+ #Render the barcode to an EPS document
97
+ def to_eps(options={})
98
+ to_ps(options.merge(:eps => true))
99
+ end
100
+
101
+
102
+ #Render the barcode to a PDF document
103
+ def to_pdf(options={})
104
+ output_to_string_io do |io|
105
+ Cairo::PDFSurface.new(io,
106
+ full_width(options),
107
+ full_height(options)) do |surface|
108
+ render(surface, options)
109
+ end
110
+ end
111
+ end
112
+
113
+
114
+ #Render the barcode to an SVG document
115
+ def to_svg(options={})
116
+ output_to_string_io do |io|
117
+ Cairo::SVGSurface.new(io,
118
+ full_width(options),
119
+ full_height(options)) do |surface|
120
+ render(surface, options)
121
+ end
122
+ end
123
+ end
124
+
125
+
126
+ def x(options={})
127
+ @x || options[:x]
128
+ end
129
+
130
+ def y(options={})
131
+ @y || options[:y]
132
+ end
133
+
134
+ def width(options={})
135
+ (barcode.two_dimensional? ? encoding.first.length : encoding.length) * xdim(options)
136
+ end
137
+
138
+ def height(options={})
139
+ if barcode.two_dimensional?
140
+ encoding.size * xdim(options)
141
+ else
142
+ @height || options[:height] || 50
143
+ end
144
+ end
145
+
146
+ def full_width(options={})
147
+ width(options) + (margin(options) * 2)
148
+ end
149
+
150
+ def full_height(options={})
151
+ height(options) + (margin(options) * 2)
152
+ end
153
+
154
+ def xdim(options={})
155
+ @xdim || options[:xdim] || 1
156
+ end
157
+
158
+ def margin(options={})
159
+ @margin || options[:margin] || 10
160
+ end
161
+
162
+
163
+ private
164
+
165
+ def output_to_string_io
166
+ io = StringIO.new
167
+ yield(io)
168
+ io.rewind
169
+ io.read
170
+ end
171
+
172
+
173
+ def render(surface, options)
174
+ context = Cairo::Context.new(surface)
175
+ yield(context) if block_given?
176
+ context.set_source_color(options[:background] || :white)
177
+ context.paint
178
+ render_to_cairo_context(context, options)
179
+ context
180
+ end
181
+
182
+
183
+ end
184
+
185
+ end