~openerp-commiter/openobject-addons/trunk-extra-addons

« back to all changes in this revision

Viewing changes to auction/barcode/code39.py

  • Committer: Fabien Pinckaers
  • Date: 2008-11-12 06:43:12 UTC
  • Revision ID: fp@tinyerp.com-20081112064312-fp85io97i1e95tuz
moved

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#
2
 
# Copyright (c) 1996-2000 Tyler C. Sarna <tsarna@sarna.org>
3
 
# All rights reserved.
4
 
#
5
 
# Redistribution and use in source and binary forms, with or without
6
 
# modification, are permitted provided that the following conditions
7
 
# are met:
8
 
# 1. Redistributions of source code must retain the above copyright
9
 
#    notice, this list of conditions and the following disclaimer.
10
 
# 2. Redistributions in binary form must reproduce the above copyright
11
 
#    notice, this list of conditions and the following disclaimer in the
12
 
#    documentation and/or other materials provided with the distribution.
13
 
# 3. All advertising materials mentioning features or use of this software
14
 
#    must display the following acknowledgement:
15
 
#      This product includes software developed by Tyler C. Sarna.
16
 
# 4. Neither the name of the author nor the names of contributors
17
 
#    may be used to endorse or promote products derived from this software
18
 
#    without specific prior written permission.
19
 
#
20
 
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21
 
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
 
# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
24
 
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
 
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
 
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
 
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
 
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
 
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
 
# POSSIBILITY OF SUCH DAMAGE.
31
 
#
32
 
 
33
 
from reportlab.lib.units import inch
34
 
from common import Barcode
35
 
import string
36
 
 
37
 
_patterns = {
38
 
    '0':    ("bsbSBsBsb", 0),       '1': ("BsbSbsbsB", 1),
39
 
    '2':    ("bsBSbsbsB", 2),       '3': ("BsBSbsbsb", 3),
40
 
    '4':    ("bsbSBsbsB", 4),       '5': ("BsbSBsbsb", 5),
41
 
    '6':    ("bsBSBsbsb", 6),       '7': ("bsbSbsBsB", 7),
42
 
    '8':    ("BsbSbsBsb", 8),       '9': ("bsBSbsBsb", 9),
43
 
    'A':    ("BsbsbSbsB", 10),      'B': ("bsBsbSbsB", 11),
44
 
    'C':    ("BsBsbSbsb", 12),      'D': ("bsbsBSbsB", 13),
45
 
    'E':    ("BsbsBSbsb", 14),      'F': ("bsBsBSbsb", 15),
46
 
    'G':    ("bsbsbSBsB", 16),      'H': ("BsbsbSBsb", 17),
47
 
    'I':    ("bsBsbSBsb", 18),      'J': ("bsbsBSBsb", 19),
48
 
    'K':    ("BsbsbsbSB", 20),      'L': ("bsBsbsbSB", 21),
49
 
    'M':    ("BsBsbsbSb", 22),      'N': ("bsbsBsbSB", 23),
50
 
    'O':    ("BsbsBsbSb", 24),      'P': ("bsBsBsbSb", 25),
51
 
    'Q':    ("bsbsbsBSB", 26),      'R': ("BsbsbsBSb", 27),
52
 
    'S':    ("bsBsbsBSb", 28),      'T': ("bsbsBsBSb", 29),
53
 
    'U':    ("BSbsbsbsB", 30),      'V': ("bSBsbsbsB", 31),
54
 
    'W':    ("BSBsbsbsb", 32),      'X': ("bSbsBsbsB", 33),
55
 
    'Y':    ("BSbsBsbsb", 34),      'Z': ("bSBsBsbsb", 35),
56
 
    '-':    ("bSbsbsBsB", 36),      '.': ("BSbsbsBsb", 37),
57
 
    ' ':    ("bSBsbsBsb", 38),      '*': ("bSbsBsBsb", 39),
58
 
    '$':    ("bSbSbSbsb", 40),      '/': ("bSbSbsbSb", 41),
59
 
    '+':    ("bSbsbSbSb", 42),      '%': ("bsbSbSbSb", 43)
60
 
}
61
 
 
62
 
_valchars = [
63
 
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
64
 
    'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
65
 
    'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
66
 
    'X', 'Y', 'Z', '-', '.', ' ', '*', '$', '/', '+', '%'
67
 
]
68
 
 
69
 
_extended = {
70
 
    '\0':   "%U",    '\01':  "$A",    '\02':  "$B",    '\03':  "$C",
71
 
    '\04':  "$D",    '\05':  "$E",    '\06':  "$F",    '\07':  "$G",
72
 
    '\010': "$H",    '\011': "$I",    '\012': "$J",    '\013': "$K",
73
 
    '\014': "$L",    '\015': "$M",    '\016': "$N",    '\017': "$O",
74
 
    '\020': "$P",    '\021': "$Q",    '\022': "$R",    '\023': "$S",
75
 
    '\024': "$T",    '\025': "$U",    '\026': "$V",    '\027': "$W",
76
 
    '\030': "$X",    '\031': "$Y",    '\032': "$Z",    '\033': "%A",
77
 
    '\034': "%B",    '\035': "%C",    '\036': "%D",    '\037': "%E",
78
 
    '!':    "/A",    '"':    "/B",    '#':    "/C",    '$':    "/D",
79
 
    '%':    "/E",    '&':    "/F",    '\'':   "/G",    '(':    "/H",
80
 
    ')':    "/I",    '*':    "/J",    '+':    "/K",    ',':    "/L",
81
 
    '/':    "/O",    ':':    "/Z",    ';':    "%F",    '<':    "%G",
82
 
    '=':    "%H",    '>':    "%I",    '?':    "%J",    '@':    "%V",
83
 
    '[':    "%K",    '\\':   "%L",    ']':    "%M",    '^':    "%N",
84
 
    '_':    "%O",    '`':    "%W",    'a':    "+A",    'b':    "+B",
85
 
    'c':    "+C",    'd':    "+D",    'e':    "+E",    'f':    "+F",
86
 
    'g':    "+G",    'h':    "+H",    'i':    "+I",    'j':    "+J",
87
 
    'k':    "+K",    'l':    "+L",    'm':    "+M",    'n':    "+N",
88
 
    'o':    "+O",    'p':    "+P",    'q':    "+Q",    'r':    "+R",
89
 
    's':    "+S",    't':    "+T",    'u':    "+U",    'v':    "+V",
90
 
    'w':    "+W",    'x':    "+X",    'y':    "+Y",    'z':    "+Z",
91
 
    '{':    "%P",    '|':    "%Q",    '}':    "%R",    '~':    "%S",
92
 
    '\177': "%T"
93
 
}
94
 
 
95
 
 
96
 
_stdchrs = string.digits + string.uppercase + "-. *$/+%"
97
 
_extchrs = _stdchrs + string.lowercase + \
98
 
    "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017" + \
99
 
    "\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" + \
100
 
    "!'#&\"(),:;<=>?@[\\]^_`{|}~\177"
101
 
 
102
 
 
103
 
def _encode39(str, cksum):
104
 
    newval = "*"
105
 
    v = 0
106
 
    for c in str:
107
 
        v = v + _patterns[c][1]
108
 
        newval = newval + c
109
 
    v = v % 43
110
 
    if cksum:
111
 
        newval = newval + _valchars[v]
112
 
    return newval + '*'
113
 
 
114
 
        
115
 
class _Code39Base(Barcode):
116
 
    def __init__(self, value = "", **args):
117
 
        self.xdim = inch * 0.0075
118
 
        self.lquiet = None
119
 
        self.rquiet = None
120
 
        self.quiet = 1
121
 
        self.gap = None
122
 
        self.height = None
123
 
        self.ratio = 2.2
124
 
        self.checksum = 0
125
 
        self.bearers = 0.0
126
 
 
127
 
        for (k, v) in args.items():
128
 
            setattr(self, k, v)
129
 
            
130
 
        if self.quiet:
131
 
            if self.lquiet is None:
132
 
                self.lquiet = max(inch * 0.25, self.xdim * 10.0)
133
 
                self.rquiet = max(inch * 0.25, self.xdim * 10.0)
134
 
        else:
135
 
            self.lquiet = self.rquiet = 0.0
136
 
                                                         
137
 
        Barcode.__init__(self, value)
138
 
 
139
 
    def decompose(self):
140
 
        dval = ""
141
 
        for c in self.encoded:
142
 
            dval = dval + _patterns[c][0] + 'i'
143
 
        self.decomposed = dval[:-1]
144
 
        return self.decomposed
145
 
 
146
 
 
147
 
class Standard39(_Code39Base):
148
 
    """
149
 
    Interleaved 2 of 5 is a numeric-only barcode.  It encodes an even
150
 
    number of digits; if an odd number is given, a 0 is prepended.
151
 
 
152
 
    Options that may be passed to constructor:
153
 
 
154
 
        value (int, or numeric string. required.):
155
 
            The value to encode.
156
 
   
157
 
        xdim (float, default .0075):
158
 
            X-Dimension, or width of the smallest element
159
 
            Minumum is .0075 inch (7.5 mils).
160
 
            
161
 
        ratio (float, default 2.2):
162
 
            The ratio of wide elements to narrow elements.
163
 
            Must be between 2.0 and 3.0 (or 2.2 and 3.0 if the
164
 
            xdim is greater than 20 mils (.02 inch))
165
 
            
166
 
        gap (float or None, default None):
167
 
            width of intercharacter gap. None means "use xdim".
168
 
        
169
 
        height (float, see default below):
170
 
            Height of the symbol.  Default is the height of the two
171
 
            bearer bars (if they exist) plus the greater of .25 inch
172
 
            or .15 times the symbol's length.
173
 
 
174
 
        checksum (bool, default 0):
175
 
            Wether to compute and include the check digit
176
 
            
177
 
        bearers (float, in units of xdim. default 0):
178
 
            Height of bearer bars (horizontal bars along the top and
179
 
            bottom of the barcode). Default is 0 (no bearers).
180
 
            
181
 
        quiet (bool, default 1):
182
 
            Wether to include quiet zones in the symbol.
183
 
            
184
 
        lquiet (float, see default below):
185
 
            Quiet zone size to left of code, if quiet is true.
186
 
            Default is the greater of .25 inch, or .15 times the symbol's
187
 
            length.
188
 
            
189
 
        rquiet (float, defaults as above):
190
 
            Quiet zone size to right left of code, if quiet is true.
191
 
 
192
 
    Sources of Information on Code 39:
193
 
    
194
 
    http://www.semiconductor.agilent.com/barcode/sg/Misc/code_39.html
195
 
    http://www.adams1.com/pub/russadam/39code.html
196
 
    http://www.barcodeman.com/c39_1.html
197
 
 
198
 
    Official Spec, "ANSI/AIM BC1-1995, USS" is available for US$45 from
199
 
    http://www.aimglobal.org/aimstore/
200
 
    """
201
 
 
202
 
    def validate(self):
203
 
        vval = ""
204
 
        self.valid = 1
205
 
        for c in self.value:
206
 
            if c in string.lowercase:
207
 
                c = string.upper(c)
208
 
            if c not in _stdchrs:
209
 
                self.valid = 0
210
 
                continue
211
 
            vval = vval + c
212
 
        self.validated = vval
213
 
        return vval
214
 
 
215
 
    def encode(self):
216
 
        self.encoded = _encode39(self.validated, self.checksum)
217
 
        return self.encoded
218
 
 
219
 
 
220
 
class Extended39(_Code39Base):
221
 
    """
222
 
    Extended Code 39 is a convention for encoding additional characters
223
 
    not present in stanmdard Code 39 by using pairs of characters to
224
 
    represent the characters missing in Standard Code 39.
225
 
    
226
 
    See Standard39 for arguments.
227
 
 
228
 
    Sources of Information on Extended Code 39:
229
 
    
230
 
    http://www.semiconductor.agilent.com/barcode/sg/Misc/xcode_39.html
231
 
    http://www.barcodeman.com/c39_ext.html
232
 
    """
233
 
 
234
 
    def validate(self):
235
 
        vval = ""
236
 
        self.valid = 1
237
 
        for c in self.value:
238
 
            if c not in _extchrs:
239
 
                self.valid = 0
240
 
                continue
241
 
            vval = vval + c
242
 
        self.validated = vval
243
 
        return vval
244
 
 
245
 
    def encode(self):
246
 
        self.encoded = ""
247
 
        for c in self.validated:
248
 
            if _extended.has_key(c):
249
 
                self.encoded = self.encoded + _extended[c]
250
 
            elif c in _stdchrs:
251
 
                self.encoded = self.encoded + c
252
 
            else:
253
 
                raise ValueError
254
 
        self.encoded = _encode39(self.encoded, self.checksum)
255
 
        return self.encoded