Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
245 lines (225 sloc) 5.19 KB
import struct, sys
from cStringIO import StringIO
class vfile:
def __init__(self, f):
self.f = f
self.off = f.tell()
def seek(self, x, y=0):
if y == 1:
self.off += x
else:
self.off = x
def read(self, x):
old = self.f.tell()
self.f.seek(self.off)
ret = self.f.read(x)
self.off += x
self.f.seek(old)
return ret
def tell(self):
return self.off
def rb(f):
try:
return ord(f.read(1))
except TypeError:
return None
def rh(f):
return struct.unpack('>H', f.read(2))[0]
def rw(f):
return struct.unpack('>I', f.read(4))[0]
def read_off(offsize, f):
s = '\0' * (4 - offsize) + f.read(offsize)
return struct.unpack('>I', s)[0]
def read_realop(f):
def i():
while True:
byte = rb(f)
yield (byte >> 4)
yield (byte & 0xf)
s = ''
for nib in i():
if 0 <= nib <= 9:
s += str(nib)
elif nib == 0xa:
s += '.'
elif nib == 0xb:
s += 'E'
elif nib == 0xc:
s += 'E-'
elif nib == 0xd:
raise ValueError(nib)
elif nib == 0xe:
s += '-'
elif nib == 0xf:
return s
def read_intop(f):
b0 = rb(f)
if 32 <= b0 <= 246:
return b0-139
elif 247 <= b0 <= 250:
b1 = rb(f)
return (b0-247)*256 + b1 + 108
elif 251 <= b0 <= 254:
b1 = rb(f)
return -(b0-251)*256 - b1 - 108
elif b0 == 28:
return rh(f)
elif b0 == 29:
return rw(f)
elif b0 == 30:
return read_realop(f)
elif b0 == 255:
return float(struct.unpack('>i', f.read(4))[0]) / 65536
else:
raise ValueError(b0)
def read_index(f):
count = rh(f)
if count == 0:
return []
offsize = rb(f)
offbase = f.tell() + offsize*(count+1) - 1
offs = vfile(f)
offs = [read_off(offsize, offs) for i in xrange(count+1)]
data = []
for i in xrange(count):
f.seek(offs[i] + offbase)
data.append(f.read(offs[i+1] - offs[i]))
f.seek(offs[count] + offbase)
return data
def read_dict(f):
opnds = []
ret = []
while True:
b0 = rb(f)
if b0 is None: break
if b0 <= 21:
if b0 == 12:
op = (b0, rb(f))
else:
op = b0
ret.append((op, opnds[0] if len(opnds) == 1 else tuple(opnds)))
opnds = []
else:
f.seek(-1, 1)
op = read_intop(f)
opnds.append(op)
return ret
def read_csop(f):
b0 = rb(f)
if b0 is None:
return None
elif b0 == 12:
b1 = rb(f)
return tbops[b1]
elif 0 <= b0 <= 11 or 13 <= b0 <= 18 or 19 <= b0 <= 20 or 21 <= b0 <= 27 or 29 <= b0 <= 31:
return ops[b0]
else:
f.seek(-1, 1)
return read_intop(f)
ops = {
0: '0??',
1: 'hstem',
2: '2??',
3: 'vstem',
4: 'vmoveto',
5: 'rlineto',
6: 'hlineto',
7: 'vlineto',
8: 'rrcurveto',
9: '9??',
10:'callsubr',
11:'return',
13:'13??',
14:'endchar',
15:'15??',
16:'16??',
17:'17??',
18:'hstemhm',
19:'hintmask',
20:'cntrmask',
21:'rmoveto',
22:'hmoveto',
23:'vstemhm',
24:'rcurveline',
25:'rlinecurve',
26:'vvcurveto',
27:'hhcurveto',
29:'callgsubr',
30:'vhcurveto',
31:'hvcurveto',
}
tbops = {
0: 'dotsection',
3: 'and',
4: 'or',
5: 'not',
9: 'abs',
10:'add',
11:'sub',
12:'div',
14:'neg',
15:'eq',
18:'drop',
20:'put',
21:'get',
22:'ifelse',
23:'random',
24:'mul',
26:'sqrt',
27:'dup',
28:'exch',
29:'index',
30:'roll',
34:'hflex',
35:'flex',
36:'hflex1',
37:'flex1',
}
def read_cs(f):
while True:
dec = read_csop(f)
print dec,
if dec == 'endchar' or dec is None:
print
break
elif type(dec) == str:
print
def read_cff(f):
# Header
major = rb(f)
minor = rb(f)
hdrsize = rb(f)
absoffsize = rb(f)
names = read_index(f)
print 'Fonts:', names
topdicts = [read_dict(StringIO(x)) for x in read_index(f)]
strings = read_index(f)
print 'Strings:', strings
for font in topdicts:
print '--font--'
font = dict(font)
print font
for i in (0, 1, 2, 3, 4):
print 'font[%d]:' % i,
x = font.get(i)
if x is None:
print 'notdef'
elif x > 390:
print strings[x - 391]
else:
print '<standard: %d>' % x
#encoding_off = font[16]
#charset_off = font[15]
charstring_off = font[17]
private_off = font[18]
charstringtype = font.get((12, 6), 2)
if charstringtype == 2:
f.seek(charstring_off)
for charstring in read_index(f):
g = vfile(f)
g.seek(0)
print g.read(10485760).find(charstring)
print '-'*80
read_cs(StringIO(charstring))
#print read_cs(g)
read_cff(open(sys.argv[1]))