arena_barby 0.3.2

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.
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