src/reportlab/lib/rl_accel.py
branchpy33
changeset 3725 ca840494f9dd
child 3727 67e69a84138b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/reportlab/lib/rl_accel.py	Fri Feb 22 17:55:24 2013 +0000
@@ -0,0 +1,81 @@
+from reportlab.lib.utils import isUnicodeType, isSeqType
+from math import log
+_log_10 = lambda x,log=log,_log_e_10=log(10.0): log(x)/_log_e_10
+_fp_fmts = "%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", "%.6f"
+def fp_str(*a):
+    '''convert separate arguments (or single sequence arg) into space separated numeric strings'''
+    if len(a)==1 and isSeqType(a[0]): a = a[0]
+    s = []
+    A = s.append
+    for i in a:
+        sa =abs(i)
+        if sa<=1e-7: A('0')
+        else:
+            l = sa<=1 and 6 or min(max(0,(6-int(_log_10(sa)))),6)
+            n = _fp_fmts[l]%i
+            if l:
+                j = len(n)
+                while j:
+                    j -= 1
+                    if n[j]!='0':
+                        if n[j]!='.': j += 1
+                        break
+                n = n[:j]
+            A((n[0]!='0' or len(n)==1) and n or n[1:])
+    return ' '.join(s)
+
+#hack test for comma users
+if ',' in fp_str(0.25):
+    _FP_STR = fp_str
+    def fp_str(*a):
+        return _FP_STR(*a).replace(',','.')
+
+def unicode2T1(utext,fonts,font0=None):
+    '''return a list of (font,string) pairs representing the unicode text'''
+    R = []
+    font, fonts = fonts[0], fonts[1:]
+    if font0 is None: font0 = font
+    enc = font.encName
+    if 'UCS-2' in enc:
+        enc = 'UTF16'
+    while utext:
+        try:
+            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]
+            if i0:
+                R.append((font,utext[:i0].encode(enc)))
+            if fonts:
+                R.extend(unicode2T1(utext[i0:il],fonts,font0))
+            else:
+                R.append((font0._notdefFont,font0._notdefChar*(il-i0)))
+            utext = utext[il:]
+    return R
+
+def _instanceStringWidthU(self, text, size, encoding='utf8'):
+    """This is the "purist" approach to width"""
+    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
+
+if __name__=='__main__':
+    import sys, os
+    for modname in 'reportlab.lib.rl_accel','reportlab.lib._rl_accel':
+        for cmd  in (
+            #"unicode2T1('abcde fghi . jkl ; mno',fonts)",
+            #"unicode2T1(u'abcde fghi . jkl ; mno',fonts)",
+            "_instanceStringWidthU(font,'abcde fghi . jkl ; mno',10)",
+            "_instanceStringWidthU(font,u'abcde fghi . jkl ; mno',10)",
+            ):
+            print '%s %s' % (modname,cmd)
+            s=';'.join((
+                "from reportlab.pdfbase.pdfmetrics import getFont",
+                "from %s import unicode2T1,_instanceStringWidthU" % modname,
+                "fonts=[getFont('Helvetica')]+getFont('Helvetica').substitutionFonts""",
+                "font=fonts[0]",
+                ))
+            os.system('%s -m timeit -s"%s" "%s"' % (sys.executable,s,cmd))