|
|
|
"""
|
|
|
|
This module is part of the 'blup' package and defines a font class as well as
|
|
|
|
some methods to load fonts from files and draw text on frames.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
import re
|
|
|
|
|
|
|
|
class FontFileError(Exception):
|
|
|
|
def __init__(self, value):
|
|
|
|
self.__value = value
|
|
|
|
def __str__(self):
|
|
|
|
return repr(self.__value)
|
|
|
|
|
|
|
|
class Font(object):
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self.__chars = {}
|
|
|
|
self.__spacing = 1
|
|
|
|
self.__height = -1
|
|
|
|
|
|
|
|
@property
|
|
|
|
def spacing(self):
|
|
|
|
return self.__spacing
|
|
|
|
|
|
|
|
@spacing.setter
|
|
|
|
def spacing(self, value):
|
|
|
|
if type(self.value) == int and self.value > 0:
|
|
|
|
self.__spacing = value
|
|
|
|
else:
|
|
|
|
raise ValueError('illegal spacing given')
|
|
|
|
|
|
|
|
@property
|
|
|
|
def height(self):
|
|
|
|
if self.__height == -1:
|
|
|
|
raise ValueError('this font does not contain any characters')
|
|
|
|
else:
|
|
|
|
return self.__height
|
|
|
|
|
|
|
|
def __setitem__(self, item, value):
|
|
|
|
height = len(value)
|
|
|
|
if self.__height == -1:
|
|
|
|
self.__height = height
|
|
|
|
elif height != self.__height:
|
|
|
|
raise ValueError('character height does not match font height')
|
|
|
|
|
|
|
|
if len(set(map(len, value))) != 1:
|
|
|
|
raise ValueError('character lines differ in width')
|
|
|
|
|
|
|
|
allowedValues = set([0,1])
|
|
|
|
for line in value:
|
|
|
|
if set(line) != allowedValues:
|
|
|
|
raise ValueError('character contains invalid pixel value')
|
|
|
|
|
|
|
|
self.__chars[item] = value
|
|
|
|
|
|
|
|
def __getitem__(self, item):
|
|
|
|
return self.__chars[item]
|
|
|
|
|
|
|
|
|
|
|
|
charPixels = None
|
|
|
|
def load(filename):
|
|
|
|
f = open(filename, 'r')
|
|
|
|
data = f.read()
|
|
|
|
|
|
|
|
f = Font()
|
|
|
|
for line in f:
|
|
|
|
m = re.match('^\s*§(\d+)\s*$', line)
|
|
|
|
if m:
|
|
|
|
f.spacing = int(m.group(1))
|
|
|
|
continue
|
|
|
|
|
|
|
|
m = re.match('^\s*@(\d+)\|(\d+)\s*$', line)
|
|
|
|
if m:
|
|
|
|
charCode = int(m.group(1))
|
|
|
|
charWidth = int(m.group(2))
|
|
|
|
charPixels = []
|
|
|
|
continue
|
|
|
|
|
|
|
|
m = re.match('^\s*([01]+)\s*$', line)
|
|
|
|
if m and charPixels != None:
|
|
|
|
charRow = m.group(1)
|
|
|
|
if len(charRow) < charWidth:
|
|
|
|
raise FontFileError('char row does not contain enough pixels')
|
|
|
|
row = []
|
|
|
|
for i in xrange(charWidth):
|
|
|
|
row.append(int(charRow[i]))
|
|
|
|
charPixels.append(row)
|
|
|
|
|
|
|
|
continue
|