1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
81
82
83
84
85
86
87
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
118
119
120
121
122
123
124
125
126
127
|
'''
Copyright (C) 2007 Martin Owens
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
import itertools
import sys
class Barcode:
def __init__(self, param={}):
self.document = None
self.x = 0
self.y = 0
if param.has_key('document'):
self.document = param['document']
if param.has_key('x'):
self.x = param['x']
if param.has_key('y'):
self.y = param['y']
if param.has_key('height'):
self.height = param['height']
else:
self.height = 30
self.text = param['text']
self.label = self.text
self.string = self.encode( self.text )
if not self.string:
return
self.width = len(self.string)
self.data = self.graphicalArray(self.string)
def generate(self):
if not self.string or not self.data:
return
data = self.data;
# create an SVG document if required
# if not self.document:
# self.document = UNKNOWN
if not self.document:
sys.stderr.write("No document defined to add barcode to\n")
return
# We don't have svg documents so lets do something raw:
name = 'barcode'
# Make sure that the id/name is inique
index = 0
while (self.document.getElementById(name)):
name = 'barcode' + str(index)
index = index + 1
# use an svg group element to contain the barcode
barcode = self.document.createElement('svg:g')
barcode.setAttribute('id', name)
barcode.setAttribute('style', 'fill: black;')
draw = 1
wOffset = int(self.x)
id = 1
for datum in data:
# Datum 0 tells us what style of bar is to come next
style = self.getStyle(int(datum[0]))
# Datum 1 tells us what width in units,
# style tells us how wide a unit is
width = int(datum[1]) * int(style['width'])
if style['write']:
# Add height for styles such as EA8 where
# the barcode goes into the text
rect = self.document.createElement('svg:rect')
rect.setAttribute('x', str(wOffset))
rect.setAttribute('y', str(style['top']))
rect.setAttribute('width', str(width))
rect.setAttribute('height', str(style['height']))
rect.setAttribute('id', name + '_bar' + str(id))
barcode.appendChild(rect)
wOffset = int(wOffset) + int(width)
id = id + 1
barwidth = wOffset - int(self.x)
# Add text at the bottom of the barcode
text = self.document.createElement('svg:text')
text.setAttribute( 'x', str(int(self.x) + int(barwidth / 2)) )
text.setAttribute( 'y', str(int(self.height) + 10 + int(self.y)) )
text.setAttribute( 'style', 'font-size:' + self.fontSize() + 'px;text-align:center;text-anchor:middle;' )
text.setAttribute( 'xml:space', 'preserve' )
text.setAttribute( 'id', name + '_bottomtext' )
text.appendChild(self.document.createTextNode(str(self.label)))
barcode.appendChild(text)
return barcode
# Converts black and white markers into a space array
def graphicalArray(self, code):
return [(x,len(list(y))) for x, y in itertools.groupby(code)]
def getStyle(self, index):
result = { 'width' : 1, 'top' : int(self.y), 'write' : False }
if index==1: # Black Bar
result['height'] = int(self.height)
result['write'] = True
return result
def fontSize(self):
return '9'
|