mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-24 17:02:18 +00:00
Added printing requirements
This commit is contained in:
209
reportlab/graphics/barcode/qr.py
Normal file
209
reportlab/graphics/barcode/qr.py
Normal file
@@ -0,0 +1,209 @@
|
||||
#
|
||||
# ReportLab QRCode widget
|
||||
#
|
||||
# Ported from the Javascript library QRCode for Javascript by Sam Curren
|
||||
#
|
||||
# URL: http://www.d-project.com/
|
||||
# http://d-project.googlecode.com/svn/trunk/misc/qrcode/js/qrcode.js
|
||||
# qrcode.js is copyright (c) 2009 Kazuhiko Arase
|
||||
#
|
||||
# Original ReportLab module by German M. Bravo
|
||||
#
|
||||
# modified and improved by Anders Hammarquist <iko@openend.se>
|
||||
# and used with permission under the ReportLab License
|
||||
#
|
||||
# The word "QR Code" is registered trademark of
|
||||
# DENSO WAVE INCORPORATED
|
||||
# http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
|
||||
__all__ = ('QrCodeWidget')
|
||||
|
||||
import itertools
|
||||
|
||||
from reportlab.platypus.flowables import Flowable
|
||||
from reportlab.graphics.shapes import Group, Rect
|
||||
from reportlab.lib import colors
|
||||
from reportlab.lib.validators import isNumber, isNumberOrNone, isColor, isString, Validator
|
||||
from reportlab.lib.attrmap import AttrMap, AttrMapValue
|
||||
from reportlab.graphics.widgetbase import Widget
|
||||
from reportlab.lib.units import mm
|
||||
try:
|
||||
from reportlab.lib.utils import asUnicodeEx, isUnicode
|
||||
except ImportError:
|
||||
# ReportLab 2.x compatibility
|
||||
def asUnicodeEx(v, enc='utf8'):
|
||||
if isinstance(v, unicode):
|
||||
return v
|
||||
if isinstance(v, str):
|
||||
return v.decode(enc)
|
||||
return str(v).decode(enc)
|
||||
|
||||
def isUnicode(v):
|
||||
return isinstance(v, unicode)
|
||||
|
||||
from reportlab.graphics.barcode import qrencoder
|
||||
|
||||
class isLevel(Validator):
|
||||
def test(self, x):
|
||||
return x in ['L', 'M', 'Q', 'H']
|
||||
isLevel = isLevel()
|
||||
|
||||
class isUnicodeOrQRList(Validator):
|
||||
def _test(self, x):
|
||||
if isUnicode(x):
|
||||
return True
|
||||
if all(isinstance(v, qrencoder.QR) for v in x):
|
||||
return True
|
||||
return False
|
||||
|
||||
def test(self, x):
|
||||
return self._test(x) or self.normalizeTest(x)
|
||||
|
||||
def normalize(self, x):
|
||||
if self._test(x):
|
||||
return x
|
||||
try:
|
||||
return asUnicodeEx(x)
|
||||
except UnicodeError:
|
||||
raise ValueError("Can't convert to unicode: %r" % x)
|
||||
isUnicodeOrQRList = isUnicodeOrQRList()
|
||||
|
||||
class SRect(Rect):
|
||||
def __init__(self, x, y, width, height, fillColor=colors.black):
|
||||
Rect.__init__(self, x, y, width, height, fillColor=fillColor,
|
||||
strokeColor=None, strokeWidth=0)
|
||||
|
||||
class QrCodeWidget(Widget):
|
||||
codeName = "QR"
|
||||
_attrMap = AttrMap(
|
||||
BASE = Widget,
|
||||
value = AttrMapValue(isUnicodeOrQRList, desc='QRCode data'),
|
||||
x = AttrMapValue(isNumber, desc='x-coord'),
|
||||
y = AttrMapValue(isNumber, desc='y-coord'),
|
||||
barFillColor = AttrMapValue(isColor, desc='bar color'),
|
||||
barWidth = AttrMapValue(isNumber, desc='Width of bars.'), # maybe should be named just width?
|
||||
barHeight = AttrMapValue(isNumber, desc='Height of bars.'), # maybe should be named just height?
|
||||
barBorder = AttrMapValue(isNumber, desc='Width of QR border.'), # maybe should be named qrBorder?
|
||||
barLevel = AttrMapValue(isLevel, desc='QR Code level.'), # maybe should be named qrLevel
|
||||
qrVersion = AttrMapValue(isNumberOrNone, desc='QR Code version. None for auto'),
|
||||
# Below are ignored, they make no sense
|
||||
barStrokeWidth = AttrMapValue(isNumber, desc='Width of bar borders.'),
|
||||
barStrokeColor = AttrMapValue(isColor, desc='Color of bar borders.'),
|
||||
)
|
||||
x = 0
|
||||
y = 0
|
||||
barFillColor = colors.black
|
||||
barStrokeColor = None
|
||||
barStrokeWidth = 0
|
||||
barHeight = 32*mm
|
||||
barWidth = 32*mm
|
||||
barBorder = 4
|
||||
barLevel = 'L'
|
||||
qrVersion = None
|
||||
value = None
|
||||
|
||||
def __init__(self, value='Hello World', **kw):
|
||||
self.value = isUnicodeOrQRList.normalize(value)
|
||||
for k, v in kw.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
ec_level = getattr(qrencoder.QRErrorCorrectLevel, self.barLevel)
|
||||
|
||||
self.__dict__['qr'] = qrencoder.QRCode(self.qrVersion, ec_level)
|
||||
|
||||
if isUnicode(self.value):
|
||||
self.addData(self.value)
|
||||
elif self.value:
|
||||
for v in self.value:
|
||||
self.addData(v)
|
||||
|
||||
def addData(self, value):
|
||||
self.qr.addData(value)
|
||||
|
||||
def draw(self):
|
||||
self.qr.make()
|
||||
|
||||
g = Group()
|
||||
|
||||
color = self.barFillColor
|
||||
border = self.barBorder
|
||||
width = self.barWidth
|
||||
height = self.barHeight
|
||||
x = self.x
|
||||
y = self.y
|
||||
|
||||
g.add(SRect(x, y, width, height, fillColor=None))
|
||||
|
||||
moduleCount = self.qr.getModuleCount()
|
||||
minwh = float(min(width, height))
|
||||
boxsize = minwh / (moduleCount + border * 2.0)
|
||||
offsetX = (width - minwh) / 2.0
|
||||
offsetY = (minwh - height) / 2.0
|
||||
|
||||
for r, row in enumerate(self.qr.modules):
|
||||
row = map(bool, row)
|
||||
c = 0
|
||||
for t, tt in itertools.groupby(row):
|
||||
isDark = t
|
||||
count = len(list(tt))
|
||||
if isDark:
|
||||
x = (c + border) * boxsize
|
||||
y = (r + border + 1) * boxsize
|
||||
s = SRect(offsetX + x, offsetY + height - y, count * boxsize, boxsize)
|
||||
g.add(s)
|
||||
c += count
|
||||
|
||||
return g
|
||||
|
||||
|
||||
# Flowable version
|
||||
|
||||
class QrCode(Flowable):
|
||||
height = 32*mm
|
||||
width = 32*mm
|
||||
qrBorder = 4
|
||||
qrLevel = 'L'
|
||||
qrVersion = None
|
||||
value = None
|
||||
|
||||
def __init__(self, value=None, **kw):
|
||||
self.value = isUnicodeOrQRList.normalize(value)
|
||||
|
||||
for k, v in kw.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
ec_level = getattr(qrencoder.QRErrorCorrectLevel, self.qrLevel)
|
||||
|
||||
self.qr = qrencoder.QRCode(self.qrVersion, ec_level)
|
||||
|
||||
if isUnicode(self.value):
|
||||
self.addData(self.value)
|
||||
elif self.value:
|
||||
for v in self.value:
|
||||
self.addData(v)
|
||||
|
||||
def addData(self, value):
|
||||
self.qr.addData(value)
|
||||
|
||||
def draw(self):
|
||||
self.qr.make()
|
||||
|
||||
moduleCount = self.qr.getModuleCount()
|
||||
border = self.qrBorder
|
||||
xsize = self.width / (moduleCount + border * 2.0)
|
||||
ysize = self.height / (moduleCount + border * 2.0)
|
||||
|
||||
for r, row in enumerate(self.qr.modules):
|
||||
row = map(bool, row)
|
||||
c = 0
|
||||
for t, tt in itertools.groupby(row):
|
||||
isDark = t
|
||||
count = len(list(tt))
|
||||
if isDark:
|
||||
x = (c + border) * xsize
|
||||
y = self.height - (r + border + 1) * ysize
|
||||
self.rect(x, y, count * xsize, ysize * 1.05)
|
||||
c += count
|
||||
|
||||
def rect(self, x, y, w, h):
|
||||
self.canv.rect(x, y, w, h, stroke=0, fill=1)
|
||||
Reference in New Issue
Block a user