home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
pypil112.zip
/
Scripts
/
bdf2pil.py
next >
Wrap
Text File
|
2001-05-03
|
6KB
|
237 lines
#! /usr/local/bin/python
#
# $Id: bdf2pil.py,v 1.1 1996/12/16 18:51:31 fl Exp $
#
# File:
# bdf2pil.py -- font compiler for X bitmap distribution files
#
# Description:
# This utility converts a BDF font to an image file with an
# associated font metrics file.
#
# History:
# 96-05-16 fl: Created (after an idea from David Ascher)
# 96-08-07 fl: Font metrics file uses network byte order
#
# Copyright (c) Fredrik Lundh 1996. All rights reserved.
#
VERSION = "1.0"
# HACK
try:
import Image
except:
import sys
sys.path.insert(0, ".")
import Image
# --------------------------------------------------------------------
# Parse X Bitmap Distribution Format (BDF)
# --------------------------------------------------------------------
import string
bdf_slant = {
"R": "Roman",
"I": "Italic",
"O": "Oblique",
"RI": "Reverse Italic",
"RO": "Reverse Oblique",
"OT": "Other"
}
bdf_spacing = {
"P": "Proportional",
"M": "Monospaced",
"C": "Cell"
}
def bdf_char(f):
# skip to STARTCHAR
while 1:
s = f.readline()
if not s:
return None
if s[:9] == "STARTCHAR":
break
id = string.strip(s[9:])
# load symbol properties
props = {}
while 1:
s = f.readline()
if not s or s[:6] == "BITMAP":
break
i = string.find(s, " ")
props[s[:i]] = s[i+1:-1]
# load bitmap
bitmap = []
while 1:
s = f.readline()
if not s or s[:7] == "ENDCHAR":
break
bitmap.append(s[:-1])
bitmap = string.join(bitmap, "")
[w, h, x, y] = map(string.atoi, string.split(props["BBX"]))
[dx, dy] = map(string.atoi, string.split(props["DWIDTH"]))
bbox = (dx, dy, x, y, x+w, y+h)
return id, string.atoi(props["ENCODING"]), bbox, bitmap
def bdf2font(filename):
f = open(filename)
s = f.readline()
if s[:13] != "STARTFONT 2.1":
print filename, "is not a valid BDF file (ignoring)"
return None
print filename
props = {}
comments = []
while 1:
s = f.readline()
if not s or s[:13] == "ENDPROPERTIES":
break
i = string.find(s, " ")
props[s[:i]] = s[i+1:-1]
if s[:i] in ["COMMENT", "COPYRIGHT"]:
if string.find(s, "LogicalFontDescription") < 0:
comments.append(s[i+1:-1])
font = string.split(props["FONT"], "-")
font[4] = bdf_slant[font[4]]
font[11] = bdf_spacing[font[11]]
ascent = string.atoi(props["FONT_ASCENT"])
descent = string.atoi(props["FONT_DESCENT"])
fontname = string.join(font[1:], ";")
print "#", fontname
#for i in comments:
# print "#", i
font = []
while 1:
c = bdf_char(f)
if not c:
break
id, code, bbox, bits = c
if code >= 0:
font.append((code, bbox, bits))
return font, fontname, ascent, descent
# --------------------------------------------------------------------
# Translate font to image
# --------------------------------------------------------------------
def font2image(font, ascent, descent):
metrics = [None] * 256
# create glyph images for all characters in this font
width = height = 0
glyph = [None]*256
for id, (dx, dy, b0, b1, b2, b3), bits in font:
w, h = b2-b0, b3-b1
if w > 0 and h > 0:
i = Image.core.new("L", (w, h))
height = max(height, h)
d = Image.core.hex_decoder("1")
d.setimage(i)
d.decode(bits)
glyph[id] = i
width = width + w
# pack the glyphs into a large image
x = 0
bboxes = {}
i = Image.core.fill("L", (width, height), 0)
for id, (dx, dy, b0, b1, b2, b3), bits in font:
w, h = b2-b0, b3-b1
if w > 0 and h > 0:
bbox = (x, 0, x+w, h)
metrics[id] = (dx, dy), (b0, b1, b2, b3), bbox
i.paste(glyph[id], bbox)
x = x + w
bboxes[id] = bbox
return i, bboxes
def puti16(fp, values):
# write network order (big-endian) 16-bit sequence
for v in values:
fp.write(chr(v>>8&255) + chr(v&255))
# --------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------
import glob, os, sys
print "BDF2PIL", VERSION, "-- Font compiler for X BDF fonts."
print "Copyright (c) Fredrik Lundh 1996. All rights reserved."
if len(sys.argv) <= 1:
print
print "Usage: bdf2pil files..."
print
print "BDF files are converted to a bitmap file (currently"
print "using PBM format) and a font metrics file (PIL)."
sys.exit(1)
files = []
for f in sys.argv[1:]:
files = files + glob.glob(f)
for file in files:
font, fontname, ascent, descent = bdf2font(file)
if font:
image, srcbbox = font2image(font, ascent, descent)
# to be changed to PCX or something...
image.save_ppm(os.path.splitext(file)[0] + ".pbm")
# create font metrics file
metrics = {}
for id, xy_bbox, bits in font:
x, y, x0, y0, x1, y1 = xy_bbox
metrics[id] = (x, y, x0, ascent-y1, x1, ascent-y0) + srcbbox[id]
fp = open(os.path.splitext(file)[0] + ".pil", "wb")
fp.write("PILfont\n")
fp.write("%s\n" % fontname)
fp.write("DATA\n")
for id in range(256):
try:
puti16(fp, metrics[id])
except KeyError:
puti16(fp, (0,) * 10)
fp.close()
# --------------------------------------------------------------------
# Font metrics format:
# "PILfont" LF
# fontdescriptor LF
# (optional) key=value... LF
# "DATA" LF
# binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox)
#
# To place a character, cut out srcbox and paste at dstbox,
# relative to the character position. Then move the character
# position according to dx, dy.
# --------------------------------------------------------------------