--- a/src/reportlab/pdfbase/pdfmetrics.py Sun Feb 17 12:13:56 2013 +0000
+++ b/src/reportlab/pdfbase/pdfmetrics.py Tue Apr 30 14:28:14 2013 +0100
@@ -19,13 +19,12 @@
trap attempts to access them and do it on first access.
"""
import string, os, sys
-from types import StringType, ListType, TupleType
from reportlab.pdfbase import _fontdata
from reportlab.lib.logger import warnOnce
-from reportlab.lib.utils import rl_isfile, rl_glob, rl_isdir, open_and_read, open_and_readlines, findInPaths
+from reportlab.lib.utils import rl_isfile, rl_glob, rl_isdir, open_and_read, open_and_readlines, findInPaths, isSeqType, isStrType, isUnicodeType, isPython3
from reportlab.rl_config import defaultEncoding, T1SearchPath
from . import rl_codecs
-_notdefChar = chr(110)
+_notdefChar = b'n'
rl_codecs.RL_Codecs.register()
standardFonts = _fontdata.standardFonts
@@ -37,8 +36,6 @@
def _py_unicode2T1(utext,fonts):
'''return a list of (font,string) pairs representing the unicode text'''
- #print 'unicode2t1(%s, %s): %s' % (utext, fonts, type(utext))
- #if type(utext)
R = []
font, fonts = fonts[0], fonts[1:]
enc = font.encName
@@ -46,7 +43,11 @@
enc = 'UTF16'
while utext:
try:
- R.append((font,utext.encode(enc)))
+ if isUnicodeType(utext):
+ s = utext.encode(enc)
+ else:
+ s = utext
+ R.append((font,s))
break
except UnicodeEncodeError as e:
i0, il = e.args[2:4]
@@ -80,13 +81,14 @@
lines = open_and_readlines(afmFileName, 'r')
if len(lines)<=1:
#likely to be a MAC file
- if lines: lines = string.split(lines[0],'\r')
+ if lines: lines = lines[0].split('\r')
if len(lines)<=1:
raise ValueError('AFM file %s hasn\'t enough data' % afmFileName)
topLevel = {}
glyphLevel = []
- lines = [l for l in map(string.strip, lines) if not l.lower().startswith('comment')]
+ lines = [l.strip() for l in lines]
+ lines = [l for l in lines if not l.lower().startswith('comment')]
#pass 1 - get the widths
inMetrics = 0 # os 'TOP', or 'CHARMETRICS'
for line in lines:
@@ -95,22 +97,22 @@
elif line[0:14] == 'EndCharMetrics':
inMetrics = 0
elif inMetrics:
- chunks = string.split(line, ';')
- chunks = list(map(string.strip, chunks))
+ chunks = line.split(';')
+ chunks = [chunk.strip() for chunk in chunks]
cidChunk, widthChunk, nameChunk = chunks[0:3]
# character ID
- l, r = string.split(cidChunk)
+ l, r = cidChunk.split()
assert l == 'C', 'bad line in font file %s' % line
- cid = string.atoi(r)
+ cid = int(r)
# width
- l, r = string.split(widthChunk)
+ l, r = widthChunk.split()
assert l == 'WX', 'bad line in font file %s' % line
- width = string.atoi(r)
+ width = int(r)
# name
- l, r = string.split(nameChunk)
+ l, r = nameChunk.split()
assert l == 'N', 'bad line in font file %s' % line
name = r
@@ -126,11 +128,11 @@
elif inHeader:
if line[0:7] == 'Comment': pass
try:
- left, right = string.split(line,' ',1)
+ left, right = line.split(' ',1)
except:
raise ValueError("Header information error in afm %s: line='%s'" % (afmFileName, line))
try:
- right = string.atoi(right)
+ right = int(right)
except:
pass
topLevel[left] = right
@@ -178,7 +180,7 @@
return []
def findT1File(self, ext='.pfb'):
- possible_exts = (string.lower(ext), string.upper(ext))
+ possible_exts = (ext.lower(), ext.upper())
if hasattr(self,'pfbFileName'):
r_basename = os.path.splitext(self.pfbFileName)[0]
for e in possible_exts:
@@ -189,14 +191,14 @@
except:
afm = bruteForceSearchForAFM(self.name)
if afm:
- if string.lower(ext) == '.pfb':
+ if ext.lower() == '.pfb':
for e in possible_exts:
pfb = os.path.splitext(afm)[0] + e
if rl_isfile(pfb):
r = pfb
else:
r = None
- elif string.lower(ext) == '.afm':
+ elif ext.lower() == '.afm':
r = afm
else:
r = None
@@ -251,11 +253,11 @@
# assume based on the usual one
self.baseEncodingName = defaultEncoding
self.vector = _fontdata.encodings[defaultEncoding]
- elif type(base) is StringType:
+ elif isStrType(base):
baseEnc = getEncoding(base)
self.baseEncodingName = baseEnc.name
self.vector = baseEnc.vector[:]
- elif type(base) in (ListType, TupleType):
+ elif isSeqType(base):
self.baseEncodingName = defaultEncoding
self.vector = base[:]
elif isinstance(base, Encoding):
@@ -407,19 +409,19 @@
"""This is the "purist" approach to width. The practical approach
is to use the stringWidth function, which may be swapped in for one
written in C."""
- if not isinstance(text,str): text = text.decode(encoding)
+ if not isUnicodeType(text): text = text.decode(encoding)
return sum([sum(map(f.widths.__getitem__,list(map(ord,t)))) for f, t in unicode2T1(text,[self]+self.substitutionFonts)])*0.001*size
stringWidth = _py_stringWidth
def _formatWidths(self):
"returns a pretty block in PDF Array format to aid inspection"
- text = '['
+ text = b'['
for i in range(256):
- text = text + ' ' + str(self.widths[i])
+ text = text + b' ' + bytes(str(self.widths[i]),'utf8')
if i == 255:
- text = text + ' ]'
+ text = text + b' ]'
if i % 16 == 15:
- text = text + '\n'
+ text = text + b'\n'
return text
def addObjects(self, doc):
@@ -457,20 +459,33 @@
PFB_ASCII=chr(1)
PFB_BINARY=chr(2)
PFB_EOF=chr(3)
-def _pfbSegLen(p,d):
- '''compute a pfb style length from the first 4 bytes of string d'''
- return ((((ord(d[p+3])<<8)|ord(d[p+2])<<8)|ord(d[p+1]))<<8)|ord(d[p])
-def _pfbCheck(p,d,m,fn):
- if d[p]!=PFB_MARKER or d[p+1]!=m:
- raise ValueError('Bad pfb file\'%s\' expected chr(%d)chr(%d) at char %d, got chr(%d)chr(%d)' % (fn,ord(PFB_MARKER),ord(m),p,ord(d[p]),ord(d[p+1])))
- if m==PFB_EOF: return
- p = p + 2
- l = _pfbSegLen(p,d)
- p = p + 4
- if p+l>len(d):
- raise ValueError('Bad pfb file\'%s\' needed %d+%d bytes have only %d!' % (fn,p,l,len(d)))
- return p, p+l
+if isPython3:
+ def _pfbCheck(p,d,m,fn):
+ if chr(d[p])!=PFB_MARKER or chr(d[p+1])!=m:
+ raise ValueError('Bad pfb file\'%s\' expected chr(%d)chr(%d) at char %d, got chr(%d)chr(%d)' % (fn,ord(PFB_MARKER),ord(m),p,d[p],d[p+1]))
+ if m==PFB_EOF: return
+ p = p + 2
+ l = (((((d[p+3])<<8)|(d[p+2])<<8)|(d[p+1]))<<8)|(d[p])
+ p = p + 4
+ if p+l>len(d):
+ raise ValueError('Bad pfb file\'%s\' needed %d+%d bytes have only %d!' % (fn,p,l,len(d)))
+ return p, p+l
+else:
+ def _pfbSegLen(p,d):
+ '''compute a pfb style length from the first 4 bytes of string d'''
+ return ((((ord(d[p+3])<<8)|ord(d[p+2])<<8)|ord(d[p+1]))<<8)|ord(d[p])
+
+ def _pfbCheck(p,d,m,fn):
+ if d[p]!=PFB_MARKER or d[p+1]!=m:
+ raise ValueError('Bad pfb file\'%s\' expected chr(%d)chr(%d) at char %d, got chr(%d)chr(%d)' % (fn,ord(PFB_MARKER),ord(m),p,ord(d[p]),ord(d[p+1])))
+ if m==PFB_EOF: return
+ p = p + 2
+ l = _pfbSegLen(p,d)
+ p = p + 4
+ if p+l>len(d):
+ raise ValueError('Bad pfb file\'%s\' needed %d+%d bytes have only %d!' % (fn,p,l,len(d)))
+ return p, p+l
class EmbeddedType1Face(TypeFace):
"""A Type 1 font other than one of the basic 14.
@@ -526,10 +541,10 @@
self.xHeight = topLevel.get('XHeight', 1000)
strBbox = topLevel.get('FontBBox', [0,0,1000,1000])
- tokens = string.split(strBbox)
+ tokens = strBbox.split()
self.bbox = []
for tok in tokens:
- self.bbox.append(string.atoi(tok))
+ self.bbox.append(int(tok))
glyphWidths = {}
for (cid, width, name) in glyphData:
@@ -666,6 +681,7 @@
def findFontAndRegister(fontName):
'''search for and register a font given its name'''
+ assert type(fontName) is str
#it might have a font-specific encoding e.g. Symbol
# or Dingbats. If not, take the default.
face = getTypeFace(fontName)
@@ -784,7 +800,7 @@
print('test one huge string...')
test3widths([rawdata])
print()
- words = string.split(rawdata)
+ words = rawdata.split()
print('test %d shorter strings (average length %0.2f chars)...' % (len(words), 1.0*len(rawdata)/len(words)))
test3widths(words)