support bdf version 2.2

This commit is contained in:
copyliu 2014-10-13 15:55:12 +08:00
parent 838afa1528
commit 6598ab4003

View File

@ -17,6 +17,7 @@
# See the README file for information on usage and redistribution. # See the README file for information on usage and redistribution.
# #
from PIL import Image from PIL import Image
from PIL import FontFile from PIL import FontFile
@ -41,75 +42,33 @@ bdf_spacing = {
} }
def bdf_char(f):
# skip to STARTCHAR
while True:
s = f.readline()
if not s:
return None
if s[:9] == b"STARTCHAR":
break
id = s[9:].strip().decode('ascii')
# load symbol properties
props = {}
while True:
s = f.readline()
if not s or s[:6] == b"BITMAP":
break
i = s.find(b" ")
props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii')
# load bitmap
bitmap = []
while True:
s = f.readline()
if not s or s[:7] == b"ENDCHAR":
break
bitmap.append(s[:-1])
bitmap = b"".join(bitmap)
[x, y, l, d] = [int(s) for s in props["BBX"].split()]
[dx, dy] = [int(s) for s in props["DWIDTH"].split()]
bbox = (dx, dy), (l, -d-y, x+l, -d), (0, 0, x, y)
try:
im = Image.frombytes("1", (x, y), bitmap, "hex", "1")
except ValueError:
# deal with zero-width characters
im = Image.new("1", (x, y))
return id, int(props["ENCODING"]), bbox, im
## ##
# Font file plugin for the X11 BDF format. # Font file plugin for the X11 BDF format.
class BdfFontFile(FontFile.FontFile): class BdfFontFile(FontFile.FontFile):
props = {}
comments = []
def __init__(self, fp): def __init__(self, fp):
FontFile.FontFile.__init__(self) FontFile.FontFile.__init__(self)
self.glyph = [None] * 65536
s = fp.readline() s = fp.readline()
if s[:13] != b"STARTFONT 2.1": if s[:13] != b"STARTFONT 2.1" and s[:13] != b"STARTFONT 2.2":
raise SyntaxError("not a valid BDF file") raise SyntaxError("not a valid BDF file")
props = {}
comments = []
while True: while True:
s = fp.readline() s = fp.readline()
if not s or s[:13] == b"ENDPROPERTIES": if not s or s[:13] == b"ENDPROPERTIES":
break break
i = s.find(b" ") i = s.find(b" ")
props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii') self.props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii')
if s[:i] in [b"COMMENT", b"COPYRIGHT"]: if s[:i] in [b"COMMENT", b"COPYRIGHT"]:
if s.find(b"LogicalFontDescription") < 0: if s.find(b"LogicalFontDescription") < 0:
comments.append(s[i+1:-1].decode('ascii')) self.comments.append(s[i+1:-1].decode('ascii'))
font = props["FONT"].split("-") font = self.props["FONT"].split("-")
font[4] = bdf_slant[font[4].upper()] font[4] = bdf_slant[font[4].upper()]
font[11] = bdf_spacing[font[11].upper()] font[11] = bdf_spacing[font[11].upper()]
@ -125,9 +84,57 @@ class BdfFontFile(FontFile.FontFile):
font = [] font = []
while True: while True:
c = bdf_char(fp) c = self.bdf_char(fp)
if not c: if not c:
break break
id, ch, (xy, dst, src), im = c id, ch, (xy, dst, src), im = c
if 0 <= ch < len(self.glyph): if 0 <= ch < len(self.glyph):
self.glyph[ch] = xy, dst, src, im self.glyph[ch] = xy, dst, src, im
def bdf_char(self,f):
# skip to STARTCHAR
while True:
s = f.readline()
if not s:
return None
if s[:9] == b"STARTCHAR":
break
id = s[9:].strip().decode('ascii')
# load symbol properties
props = {}
while True:
s = f.readline()
if not s or s[:6] == b"BITMAP":
break
i = s.find(b" ")
props[s[:i].decode('ascii')] = s[i+1:-1].decode('ascii')
# load bitmap
bitmap = []
while True:
s = f.readline()
if not s or s[:7] == b"ENDCHAR":
break
bitmap.append(s[:-1])
bitmap = b"".join(bitmap)
[x, y, l, d] = [int(s) for s in props["BBX"].split()]
if props.has_key("DWIDTH"):
[dx, dy] = [int(s) for s in props["DWIDTH"].split()]
else:
[dx, dy] = [int(s) for s in self.props["DWIDTH"].split()]
bbox = (dx, dy), (l, -d-y, x+l, -d), (0, 0, x, y)
try:
im = Image.frombytes("1", (x, y), bitmap, "hex", "1")
except ValueError:
# deal with zero-width characters
im = Image.new("1", (x, y))
return id, int(props["ENCODING"]), bbox, im