barcodes 0.0.1
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.
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +107 -0
- data/Rakefile +11 -0
- data/barcodes.gemspec +24 -0
- data/bin/barcodes +6 -0
- data/lib/barcodes.rb +63 -0
- data/lib/barcodes/exec.rb +74 -0
- data/lib/barcodes/renderer.rb +9 -0
- data/lib/barcodes/renderer/ascii.rb +199 -0
- data/lib/barcodes/renderer/pdf.rb +257 -0
- data/lib/barcodes/symbology.rb +47 -0
- data/lib/barcodes/symbology/base.rb +103 -0
- data/lib/barcodes/symbology/codabar.rb +36 -0
- data/lib/barcodes/symbology/code11.rb +74 -0
- data/lib/barcodes/symbology/code128.rb +317 -0
- data/lib/barcodes/symbology/code39.rb +48 -0
- data/lib/barcodes/symbology/code39extended.rb +93 -0
- data/lib/barcodes/symbology/code39extendedmod43.rb +73 -0
- data/lib/barcodes/symbology/code39mod43.rb +73 -0
- data/lib/barcodes/symbology/code93.rb +142 -0
- data/lib/barcodes/symbology/code93extended.rb +116 -0
- data/lib/barcodes/symbology/ean.rb +149 -0
- data/lib/barcodes/symbology/ean13.rb +27 -0
- data/lib/barcodes/symbology/ean8.rb +50 -0
- data/lib/barcodes/symbology/interleaved2of5.rb +30 -0
- data/lib/barcodes/symbology/interleaved2of5mod10.rb +40 -0
- data/lib/barcodes/symbology/msi.rb +30 -0
- data/lib/barcodes/symbology/msimod10.rb +50 -0
- data/lib/barcodes/symbology/msimod11.rb +37 -0
- data/lib/barcodes/symbology/planet.rb +83 -0
- data/lib/barcodes/symbology/postnet.rb +83 -0
- data/lib/barcodes/symbology/standard2of5.rb +30 -0
- data/lib/barcodes/symbology/standard2of5mod10.rb +40 -0
- data/lib/barcodes/symbology/upca.rb +27 -0
- data/lib/barcodes/version.rb +3 -0
- data/spec/barcodes/exec_spec.rb +14 -0
- data/spec/barcodes/renderer/ascii_spec.rb +12 -0
- data/spec/barcodes/renderer/pdf_spec.rb +12 -0
- data/spec/barcodes/symbology/base_spec.rb +8 -0
- data/spec/barcodes/symbology/codabar_spec.rb +8 -0
- data/spec/barcodes/symbology/code11_spec.rb +8 -0
- data/spec/barcodes/symbology/code128_spec.rb +8 -0
- data/spec/barcodes/symbology/code39_spec.rb +8 -0
- data/spec/barcodes/symbology/code39extended_spec.rb +8 -0
- data/spec/barcodes/symbology/code39extendedmod43_spec.rb +8 -0
- data/spec/barcodes/symbology/code39mod43_spec.rb +8 -0
- data/spec/barcodes/symbology/code93_spec.rb +8 -0
- data/spec/barcodes/symbology/code93extended_spec.rb +8 -0
- data/spec/barcodes/symbology/ean13_spec.rb +8 -0
- data/spec/barcodes/symbology/ean8_spec.rb +8 -0
- data/spec/barcodes/symbology/ean_spec.rb +8 -0
- data/spec/barcodes/symbology/interleaved2of5_spec.rb +8 -0
- data/spec/barcodes/symbology/interleaved2of5mod10_spec.rb +8 -0
- data/spec/barcodes/symbology/msi_spec.rb +8 -0
- data/spec/barcodes/symbology/msimod10_spec.rb +8 -0
- data/spec/barcodes/symbology/msimod11_spec.rb +8 -0
- data/spec/barcodes/symbology/planet_spec.rb +8 -0
- data/spec/barcodes/symbology/postnet_spec.rb +8 -0
- data/spec/barcodes/symbology/standard2of5_spec.rb +8 -0
- data/spec/barcodes/symbology/standard2of5mod10_spec.rb +8 -0
- data/spec/barcodes/symbology/upca_spec.rb +8 -0
- data/spec/barcodes_spec.rb +27 -0
- data/spec/spec_helper.rb +17 -0
- metadata +174 -0
@@ -0,0 +1,257 @@
|
|
1
|
+
require 'prawn'
|
2
|
+
|
3
|
+
module Barcodes
|
4
|
+
module Renderer
|
5
|
+
class Pdf
|
6
|
+
attr_accessor :barcode
|
7
|
+
|
8
|
+
def initialize(barcode=nil)
|
9
|
+
@barcode = barcode
|
10
|
+
end
|
11
|
+
|
12
|
+
def render(filename=nil)
|
13
|
+
unless filename.nil?
|
14
|
+
self.pdf.render_file filename
|
15
|
+
else
|
16
|
+
self.pdf.render
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def pdf
|
21
|
+
width = (@barcode.width * 0.001) * 72.0
|
22
|
+
height = (@barcode.height * 0.001) * 72.0
|
23
|
+
|
24
|
+
document_options = {
|
25
|
+
:page_size => [width, height],
|
26
|
+
:left_margin => 0,
|
27
|
+
:right_margin => 0,
|
28
|
+
:top_margin => 0,
|
29
|
+
:bottom_margin => 0
|
30
|
+
}
|
31
|
+
|
32
|
+
Prawn::Document.new document_options do |pdf|
|
33
|
+
if @barcode.class == Barcodes::Symbology::Ean8 || @barcode.class == Barcodes::Symbology::Ean13 || @barcode.class == Barcodes::Symbology::UpcA
|
34
|
+
self._draw_ean_upc(@barcode, pdf)
|
35
|
+
elsif @barcode.class == Barcodes::Symbology::Planet || @barcode.class == Barcodes::Symbology::Postnet
|
36
|
+
self._draw_planet_postnet(@barcode, pdf)
|
37
|
+
else
|
38
|
+
self._draw_standard(@barcode, pdf)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
def _draw_standard(barcode, pdf)
|
46
|
+
if barcode.valid?
|
47
|
+
pdf.save_graphics_state
|
48
|
+
|
49
|
+
pdf.fill_color barcode.color
|
50
|
+
|
51
|
+
pdf.transparent barcode.alpha do
|
52
|
+
quiet_zone_width_pixels = (barcode.quiet_zone_width * 0.001) * 72.0
|
53
|
+
barcode_box_width_pixels = ((barcode.encoded_data.length * barcode.bar_width) * 0.001) * 72.0
|
54
|
+
bar_height_pixels = (barcode.bar_height * 0.001) * 72.0
|
55
|
+
bar_width_pixels = (barcode.bar_width * 0.001) * 72.0
|
56
|
+
caption_size_pixels = ((barcode.caption_size * 0.001) * 72.0)
|
57
|
+
caption_height_pixels = ((barcode.caption_height * 0.001) * 72.0)
|
58
|
+
barcode_height_pixels = ((barcode.height * 0.001) * 72.0)
|
59
|
+
|
60
|
+
pdf.bounding_box([quiet_zone_width_pixels, barcode_height_pixels], :width => barcode_box_width_pixels, :height => bar_height_pixels) do
|
61
|
+
index = 0
|
62
|
+
bar_count = 0
|
63
|
+
origin = []
|
64
|
+
barcode.encoded_data.each_char do |char|
|
65
|
+
if char == '1'
|
66
|
+
if bar_count == 0
|
67
|
+
origin = [index * bar_width_pixels, bar_height_pixels]
|
68
|
+
end
|
69
|
+
bar_count += 1
|
70
|
+
else
|
71
|
+
pdf.fill_rectangle origin, bar_width_pixels * bar_count, bar_height_pixels
|
72
|
+
bar_count = 0
|
73
|
+
end
|
74
|
+
index += 1
|
75
|
+
end
|
76
|
+
|
77
|
+
if bar_count > 0
|
78
|
+
pdf.fill_rectangle origin, bar_width_pixels * bar_count, bar_height_pixels
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
if barcode.captioned
|
83
|
+
options = {
|
84
|
+
:at => [quiet_zone_width_pixels, caption_height_pixels],
|
85
|
+
:width => barcode_box_width_pixels,
|
86
|
+
:height => caption_height_pixels,
|
87
|
+
:overflow => :truncate,
|
88
|
+
:size => caption_size_pixels,
|
89
|
+
:fallback_fonts => ['Courier'],
|
90
|
+
:valign => :center,
|
91
|
+
:align => :center,
|
92
|
+
:style => :normal
|
93
|
+
}
|
94
|
+
pdf.text_box barcode.caption_data, options
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
pdf.restore_graphics_state
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def _draw_ean_upc(barcode, pdf)
|
103
|
+
if barcode.valid?
|
104
|
+
pdf.save_graphics_state
|
105
|
+
|
106
|
+
pdf.fill_color barcode.color
|
107
|
+
|
108
|
+
pdf.transparent barcode.alpha do
|
109
|
+
quiet_zone_width_pixels = (barcode.quiet_zone_width * 0.001) * 72.0
|
110
|
+
barcode_box_width_pixels = ((barcode.encoded_data.length * barcode.bar_width) * 0.001) * 72.0
|
111
|
+
bar_height_pixels = (barcode.bar_height * 0.001) * 72.0
|
112
|
+
bar_width_pixels = (barcode.bar_width * 0.001) * 72.0
|
113
|
+
caption_size_pixels = ((barcode.caption_size * 0.001) * 72.0)
|
114
|
+
caption_height_pixels = ((barcode.caption_height * 0.001) * 72.0)
|
115
|
+
barcode_height_pixels = ((barcode.height * 0.001) * 72.0)
|
116
|
+
encoded_data = barcode.encoded_data
|
117
|
+
|
118
|
+
if barcode.data.length == 7 # EAN8
|
119
|
+
start_range = (0..3)
|
120
|
+
middle_range = (32..35)
|
121
|
+
end_range = (65..encoded_data.length)
|
122
|
+
elsif barcode.data.length == 11 # UPCA
|
123
|
+
start_range = (0..10)
|
124
|
+
middle_range = (46..49)
|
125
|
+
end_range = (85..encoded_data.length)
|
126
|
+
elsif barcode.data.length == 12 # EAN13
|
127
|
+
start_range = (0..3)
|
128
|
+
middle_range = (46..49)
|
129
|
+
end_range = (93..encoded_data.length)
|
130
|
+
end
|
131
|
+
|
132
|
+
pdf.bounding_box([quiet_zone_width_pixels, barcode_height_pixels], :width => barcode_box_width_pixels, :height => bar_height_pixels) do
|
133
|
+
index = 0
|
134
|
+
bar_count = 0
|
135
|
+
origin = []
|
136
|
+
encoded_data.each_char do |char|
|
137
|
+
if char == '1'
|
138
|
+
if bar_count == 0
|
139
|
+
origin = [index * bar_width_pixels, bar_height_pixels]
|
140
|
+
end
|
141
|
+
bar_count += 1
|
142
|
+
else
|
143
|
+
if start_range.include?(index) || middle_range.include?(index) || end_range.include?(index)
|
144
|
+
pdf.fill_rectangle origin, bar_width_pixels * bar_count, bar_height_pixels + (caption_height_pixels * 0.5)
|
145
|
+
else
|
146
|
+
pdf.fill_rectangle origin, bar_width_pixels * bar_count, bar_height_pixels
|
147
|
+
end
|
148
|
+
bar_count = 0
|
149
|
+
end
|
150
|
+
index += 1
|
151
|
+
end
|
152
|
+
|
153
|
+
if bar_count > 0
|
154
|
+
pdf.fill_rectangle origin, bar_width_pixels * bar_count, bar_height_pixels + (caption_height_pixels * 0.5)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
if barcode.captioned
|
159
|
+
number_system_options = {
|
160
|
+
:at => [0, caption_height_pixels * 1.5],
|
161
|
+
:width => quiet_zone_width_pixels,
|
162
|
+
:height => caption_height_pixels,
|
163
|
+
:overflow => :truncate,
|
164
|
+
:size => caption_size_pixels,
|
165
|
+
:valign => :center,
|
166
|
+
:align => :center,
|
167
|
+
:style => :normal
|
168
|
+
}
|
169
|
+
check_digit_options = {
|
170
|
+
:at => [pdf.bounds.width - quiet_zone_width_pixels, caption_height_pixels * 1.5],
|
171
|
+
:width => quiet_zone_width_pixels,
|
172
|
+
:height => caption_height_pixels,
|
173
|
+
:overflow => :truncate,
|
174
|
+
:size => caption_size_pixels,
|
175
|
+
:valign => :center,
|
176
|
+
:align => :center,
|
177
|
+
:style => :normal
|
178
|
+
}
|
179
|
+
left_hand_options = {
|
180
|
+
:at => [quiet_zone_width_pixels, caption_height_pixels],
|
181
|
+
:width => barcode_box_width_pixels * 0.5,
|
182
|
+
:height => caption_height_pixels,
|
183
|
+
:overflow => :truncate,
|
184
|
+
:size => caption_size_pixels,
|
185
|
+
:valign => :center,
|
186
|
+
:align => :center,
|
187
|
+
:style => :normal
|
188
|
+
}
|
189
|
+
right_hand_options = {
|
190
|
+
:at => [quiet_zone_width_pixels + (barcode_box_width_pixels * 0.5), caption_height_pixels],
|
191
|
+
:width => barcode_box_width_pixels * 0.5,
|
192
|
+
:height => caption_height_pixels,
|
193
|
+
:overflow => :truncate,
|
194
|
+
:size => caption_size_pixels,
|
195
|
+
:valign => :center,
|
196
|
+
:align => :center,
|
197
|
+
:style => :normal
|
198
|
+
}
|
199
|
+
|
200
|
+
if barcode.data.length == 7 # EAN8
|
201
|
+
pdf.text_box barcode.caption_data[0..3], left_hand_options
|
202
|
+
pdf.text_box barcode.caption_data[4..7], right_hand_options
|
203
|
+
elsif barcode.data.length == 11 # UPCA
|
204
|
+
left_hand_options[:at] = [quiet_zone_width_pixels + (10 * bar_width_pixels), caption_height_pixels]
|
205
|
+
left_hand_options[:width] = (barcode_box_width_pixels * 0.5) - (10 * bar_width_pixels)
|
206
|
+
right_hand_options[:at] = [quiet_zone_width_pixels + (barcode_box_width_pixels * 0.5), caption_height_pixels]
|
207
|
+
right_hand_options[:width] = barcode_box_width_pixels * 0.5 - (10 * bar_width_pixels)
|
208
|
+
|
209
|
+
pdf.text_box barcode.caption_data[0], number_system_options
|
210
|
+
pdf.text_box barcode.caption_data[11], check_digit_options
|
211
|
+
pdf.text_box barcode.caption_data[1..5], left_hand_options
|
212
|
+
pdf.text_box barcode.caption_data[6..10], right_hand_options
|
213
|
+
elsif barcode.data.length == 12 # EAN13
|
214
|
+
pdf.text_box barcode.caption_data[0], number_system_options
|
215
|
+
pdf.text_box barcode.caption_data[1..6], left_hand_options
|
216
|
+
pdf.text_box barcode.caption_data[7..12], right_hand_options
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
pdf.restore_graphics_state
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def _draw_planet_postnet(barcode, pdf)
|
226
|
+
if barcode.valid?
|
227
|
+
pdf.save_graphics_state
|
228
|
+
|
229
|
+
pdf.fill_color barcode.color
|
230
|
+
|
231
|
+
pdf.transparent barcode.alpha do
|
232
|
+
barcode_box_width = (barcode.width * 0.001) * 72.0
|
233
|
+
full_bar_height_pixels = (125 * 0.001) * 72.0
|
234
|
+
half_bar_height_pixels = (50 * 0.001) * 72.0
|
235
|
+
bar_width_pixels = (20 * 0.001) * 72.0
|
236
|
+
|
237
|
+
pdf.bounding_box([0, full_bar_height_pixels], :width => barcode_box_width, :height => full_bar_height_pixels) do
|
238
|
+
index = 0
|
239
|
+
barcode.encoded_data.each_char do |char|
|
240
|
+
if char == '1'
|
241
|
+
origin = [index * (bar_width_pixels * 2.0), full_bar_height_pixels]
|
242
|
+
pdf.fill_rectangle origin, bar_width_pixels, full_bar_height_pixels
|
243
|
+
else
|
244
|
+
origin = [index * (bar_width_pixels * 2.0), half_bar_height_pixels]
|
245
|
+
pdf.fill_rectangle origin, bar_width_pixels, half_bar_height_pixels
|
246
|
+
end
|
247
|
+
index += 1
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
pdf.restore_graphics_state
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'barcodes/symbology/codabar'
|
2
|
+
require 'barcodes/symbology/code11'
|
3
|
+
require 'barcodes/symbology/code39'
|
4
|
+
require 'barcodes/symbology/code39mod43'
|
5
|
+
require 'barcodes/symbology/code39extended'
|
6
|
+
require 'barcodes/symbology/code39extendedmod43'
|
7
|
+
require 'barcodes/symbology/code93'
|
8
|
+
require 'barcodes/symbology/code93extended'
|
9
|
+
require 'barcodes/symbology/code128'
|
10
|
+
require 'barcodes/symbology/ean8'
|
11
|
+
require 'barcodes/symbology/ean13'
|
12
|
+
require 'barcodes/symbology/msi'
|
13
|
+
require 'barcodes/symbology/msimod10'
|
14
|
+
require 'barcodes/symbology/msimod11'
|
15
|
+
require 'barcodes/symbology/standard2of5'
|
16
|
+
require 'barcodes/symbology/standard2of5mod10'
|
17
|
+
require 'barcodes/symbology/interleaved2of5'
|
18
|
+
require 'barcodes/symbology/interleaved2of5mod10'
|
19
|
+
require 'barcodes/symbology/planet'
|
20
|
+
require 'barcodes/symbology/postnet'
|
21
|
+
require 'barcodes/symbology/upca'
|
22
|
+
|
23
|
+
module Barcodes
|
24
|
+
module Symbology
|
25
|
+
CODABAR = ['Codabar', 'codabar']
|
26
|
+
CODE_11 = ['Code11', 'Code 11', 'code11']
|
27
|
+
CODE_39 = ['Code39', 'Code 39', 'code39']
|
28
|
+
CODE_39_MOD_43 = ['Code39Mod43', 'Code 39 Mod 43', 'code39mod43']
|
29
|
+
CODE_39_EXTENDED = ['Code39Extended', 'Code 39 Extended', 'code39extended']
|
30
|
+
CODE_39_EXTENDED_MOD_43 = ['Code39ExtendedMod43', 'Code 39 Extended Mod 43', 'code39extendedmod43']
|
31
|
+
CODE_93 = ['Code93', 'Code 93', 'code93']
|
32
|
+
CODE_93_EXTENDED = ['Code93Extended', 'Code 93 Extended', 'code93extended']
|
33
|
+
CODE_128 = ['Code128', 'Code 128', 'code128']
|
34
|
+
EAN_8 = ['EAN8', 'EAN 8', 'EAN-8', 'ean8']
|
35
|
+
EAN_13 = ['EAN13', 'EAN 13', 'EAN-13', 'ean13']
|
36
|
+
MSI = ['MSI', 'Modified Plessey', 'msi']
|
37
|
+
MSI_MOD_10 = ['MSI Mod 10', 'Modified Plessey Mod 10', 'msimod10']
|
38
|
+
MSI_MOD_11 = ['MSI Mod 11', 'Modified Plessey Mod 11', 'msimod11']
|
39
|
+
STANDARD_2_OF_5 = ['Standard2of5', 'Standard 2 of 5', 'standard_2_of_5']
|
40
|
+
STANDARD_2_OF_5_MOD_10 = ['Standard2of5Mod10', 'Standard 2 of 5 Mod 10', 'standard_2_of_5_mod_10']
|
41
|
+
INTERLEAVED_2_OF_5 = ['Interleaved2of5', 'Interleaved 2 of 5', 'interleaved_2_of_5']
|
42
|
+
INTERLEAVED_2_OF_5_MOD_10 = ['Interleaved2of5Mod10', 'Interleaved 2 of 5 Mod 10', 'interleaved_2_of_5_mod_10']
|
43
|
+
PLANET = ['Planet', 'PLANET', 'planet']
|
44
|
+
POSTNET = ['Postnet', 'POSTNET', 'postnet']
|
45
|
+
UPC_A = ['UPCA', 'UPC-A', 'upc_a']
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Barcodes
|
2
|
+
module Symbology
|
3
|
+
class Base
|
4
|
+
attr_accessor :data
|
5
|
+
attr_accessor :start_character
|
6
|
+
attr_accessor :stop_character
|
7
|
+
attr_accessor :bar_width
|
8
|
+
attr_accessor :bar_height
|
9
|
+
attr_accessor :alpha
|
10
|
+
attr_accessor :color
|
11
|
+
attr_accessor :caption_height
|
12
|
+
attr_accessor :caption_size
|
13
|
+
attr_accessor :captioned
|
14
|
+
|
15
|
+
def self.charset
|
16
|
+
# Should be overridden by subclass to provide charset
|
17
|
+
[].collect {|c| c.bytes.to_a[0] }
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.valueset
|
21
|
+
# Should be overridden by subclass to provide valueset
|
22
|
+
[]
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(args={})
|
26
|
+
@data = '0123456789'
|
27
|
+
@start_character = ''
|
28
|
+
@stop_character = ''
|
29
|
+
@bar_width = 20
|
30
|
+
@bar_height = 1000
|
31
|
+
@alpha = 1.0
|
32
|
+
@color = '000000'
|
33
|
+
@caption_height = 180
|
34
|
+
@caption_size = 167
|
35
|
+
@captioned = true
|
36
|
+
|
37
|
+
args.each do |k,v|
|
38
|
+
instance_variable_set("@#{k}", v) unless v.nil?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def caption_data
|
43
|
+
# Can be overridden by subclass to format data string for display
|
44
|
+
self.data
|
45
|
+
end
|
46
|
+
|
47
|
+
def formatted_data
|
48
|
+
# Can be overridden by subclass to add additional formatting to data string
|
49
|
+
self.data
|
50
|
+
end
|
51
|
+
|
52
|
+
def encoded_data
|
53
|
+
if self.valid?
|
54
|
+
encoded_data = ""
|
55
|
+
self.formatted_data.each_byte do |char|
|
56
|
+
encoded_data += self._encode_character char
|
57
|
+
end
|
58
|
+
encoded_data
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def quiet_zone_width
|
63
|
+
# Can be overriden in subclass to adjust quiet zone width
|
64
|
+
0
|
65
|
+
end
|
66
|
+
|
67
|
+
def width
|
68
|
+
if valid?
|
69
|
+
(self.encoded_data.length * self.bar_width) + (self.quiet_zone_width * 2)
|
70
|
+
else
|
71
|
+
0
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def height
|
76
|
+
self.captioned ? self.caption_height + self.bar_height : self.bar_height
|
77
|
+
end
|
78
|
+
|
79
|
+
def valid?
|
80
|
+
# Can be overridden in subclass to validate barcode
|
81
|
+
valid = self.data.length > 0 ? true : false
|
82
|
+
|
83
|
+
self.data.each_byte do |char|
|
84
|
+
if self._encode_character(char).nil?
|
85
|
+
return false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
return valid
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
|
94
|
+
def _encode_character(character)
|
95
|
+
if self.class.charset.include? character
|
96
|
+
return self.class.valueset.at(self.class.charset.index(character))
|
97
|
+
else
|
98
|
+
return nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'barcodes/symbology/base'
|
2
|
+
|
3
|
+
module Barcodes
|
4
|
+
module Symbology
|
5
|
+
class Codabar < Base
|
6
|
+
def self.charset
|
7
|
+
['0','1','2','3','4','5','6','7','8','9','-','$',':','/','.','+','A','B','C','D'].collect {|c| c.bytes.to_a[0] }
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.valueset
|
11
|
+
[
|
12
|
+
'1010100110','1010110010','1010010110','110010101',
|
13
|
+
'101101001','110101001','100101011','100101101',
|
14
|
+
'100110101','110100101','101001101','101100101',
|
15
|
+
'1101011011','1101101011','1101101101','101100110011',
|
16
|
+
'1011001001','1010010011','1001001011','1010011001'
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(args={})
|
21
|
+
unless args.has_key? :start_character
|
22
|
+
args[:start_character] = 'A'
|
23
|
+
end
|
24
|
+
unless args.has_key? :stop_character
|
25
|
+
args[:stop_character] = 'B'
|
26
|
+
end
|
27
|
+
|
28
|
+
super(args)
|
29
|
+
end
|
30
|
+
|
31
|
+
def formatted_data
|
32
|
+
@start_character + @data + @stop_character
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'barcodes/symbology/base'
|
2
|
+
|
3
|
+
module Barcodes
|
4
|
+
module Symbology
|
5
|
+
class Code11 < Base
|
6
|
+
def self.charset
|
7
|
+
['0','1','2','3','4','5','6','7','8','9','-','S'].collect {|c| c.bytes.to_a[0] }
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.valueset
|
11
|
+
[
|
12
|
+
'1010110','11010110','10010110',
|
13
|
+
'11001010','10110110','11011010',
|
14
|
+
'10011010','10100110','11010010',
|
15
|
+
'1101010','1011010','10110010'
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(args={})
|
20
|
+
super(args)
|
21
|
+
|
22
|
+
@start_character = 'S'
|
23
|
+
@stop_character = 'S'
|
24
|
+
end
|
25
|
+
|
26
|
+
def formatted_data
|
27
|
+
checksum = self.checksum
|
28
|
+
unless checksum.nil?
|
29
|
+
@start_character + @data + checksum + @stop_character
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def checksum
|
34
|
+
if valid?
|
35
|
+
unless @data.length >= 10
|
36
|
+
c_value = self._checksum(@data, 10)
|
37
|
+
return c_value
|
38
|
+
else
|
39
|
+
c_value = self._checksum(@data, 10)
|
40
|
+
k_value = self._checksum(@data + c_value, 9)
|
41
|
+
return c_value + k_value
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def _checksum(data, weight_max)
|
49
|
+
sum = 0
|
50
|
+
weight = 0
|
51
|
+
data.reverse.each_char do |char|
|
52
|
+
if ('0'..'9').include? char
|
53
|
+
sum += weight * char.to_i
|
54
|
+
elsif char == '-'
|
55
|
+
sum += weight * 10
|
56
|
+
end
|
57
|
+
if weight < weight_max
|
58
|
+
weight += 1
|
59
|
+
else
|
60
|
+
weight = 0
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
value = sum % 11
|
65
|
+
|
66
|
+
if (0..9).include? value
|
67
|
+
return value.to_s
|
68
|
+
elsif value == 10
|
69
|
+
return '-'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|