src/reportlab/pdfbase/pdfmetrics.py
branchpy33
changeset 3723 99aa837b6703
parent 3721 0c93dd8ff567
child 3725 ca840494f9dd
--- 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)