Code

398e877e931efe5513c556aed8111426a7f34cf5
[inkscape.git] / share / extensions / Barcode / Base.py
1 #!/usr/bin/env python
2 '''
3 Copyright (C) 2007 Martin Owens
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 '''
20 import itertools
21 import sys
22 from lxml import etree
24 class Barcode:
25     def __init__(self, param={}):
26         self.document = None
27         self.x = 0
28         self.y = 0
30         if param.has_key('document'):
31             self.document = param['document']
32         if param.has_key('x'):
33             self.x = param['x']
34         if param.has_key('y'):
35             self.y = param['y']
37         if param.has_key('height'):
38             self.height = param['height']
39         else:
40             self.height = 30
42         self.text   = param['text']
43         self.label  = self.text
44         self.string = self.encode( self.text )
45         if not self.string:
46             return
47         self.width  = len(self.string)
48         self.data   = self.graphicalArray(self.string)
50     def generate(self):
51         svg_uri = u'http://www.w3.org/2000/svg'
52         if not self.string or not self.data:
53             return
55         data = self.data;
56     
57         # create an SVG document if required
58         # if not self.document:
59         #     self.document = UNKNOWN
60     
61         if not self.document:
62             sys.stderr.write("No document defined to add barcode to\n")
63             return
64         
65         # Collect document ids
66         doc_ids = {}
67         docIdNodes = self.document.xpath('//@id')
68         for m in docIdNodes:
69             doc_ids[m] = 1
71         # We don't have svg documents so lets do something raw:
72         name  = 'barcode'
74         # Make sure that the id/name is inique
75         index = 0
76         while (doc_ids.has_key(name)):
77             name = 'barcode' + str(index)
78             index = index + 1
80         # use an svg group element to contain the barcode
81         barcode = etree.Element('{%s}%s' % (svg_uri,'g'))
82         barcode.set('id', name)
83         barcode.set('style', 'fill: black;')
85         draw    = 1
86         wOffset = int(self.x)
87         id      = 1
89         for datum in data:
90             # Datum 0 tells us what style of bar is to come next
91             style = self.getStyle(int(datum[0]))
92             # Datum 1 tells us what width in units,
93             # style tells us how wide a unit is
94             width = int(datum[1]) * int(style['width'])
96             if style['write']:
97                 # Add height for styles such as EA8 where
98                 # the barcode goes into the text
99                 
100                 rect = etree.SubElement(barcode,'{%s}%s' % (svg_uri,'rect'))
101                 rect.set('x',      str(wOffset))
102                 rect.set('y',      str(style['top']))
103                 rect.set('width',  str(width))
104                 rect.set('height', str(style['height']))
105                 rect.set('id', name + '_bar' + str(id))
106             wOffset = int(wOffset) + int(width)
107             id      = id + 1
109         barwidth = wOffset - int(self.x)
110         # Add text at the bottom of the barcode
111         text = etree.SubElement(barcode,'{%s}%s' % (svg_uri,'text'))
112         text.set( 'x', str(int(self.x) + int(barwidth / 2)) )
113         text.set( 'y', str(int(self.height) + 10 + int(self.y)) )
114         text.set( 'style', 'font-size:' + self.fontSize() + 'px;text-align:center;text-anchor:middle;' )
115         text.set( '{http://www.w3.org/XML/1998/namespace}space', 'preserve' )
116         text.set( 'id', name + '_bottomtext' )
118         text.text = str(self.label)
120         return barcode
122     # Converts black and white markers into a space array
123     def graphicalArray(self, code):
124         return [(x,len(list(y))) for x, y in itertools.groupby(code)]
126     def getStyle(self, index):
127         result = { 'width' : 1, 'top' : int(self.y), 'write' : False }
128         if index==1: # Black Bar
129             result['height'] = int(self.height)
130             result['write']  = True
131         return result
133     def fontSize(self):
134         return '9'