|
1 from reportlab.lib.utils import isUnicodeType, isSeqType |
|
2 from math import log |
|
3 _log_10 = lambda x,log=log,_log_e_10=log(10.0): log(x)/_log_e_10 |
|
4 _fp_fmts = "%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", "%.6f" |
|
5 def fp_str(*a): |
|
6 '''convert separate arguments (or single sequence arg) into space separated numeric strings''' |
|
7 if len(a)==1 and isSeqType(a[0]): a = a[0] |
|
8 s = [] |
|
9 A = s.append |
|
10 for i in a: |
|
11 sa =abs(i) |
|
12 if sa<=1e-7: A('0') |
|
13 else: |
|
14 l = sa<=1 and 6 or min(max(0,(6-int(_log_10(sa)))),6) |
|
15 n = _fp_fmts[l]%i |
|
16 if l: |
|
17 j = len(n) |
|
18 while j: |
|
19 j -= 1 |
|
20 if n[j]!='0': |
|
21 if n[j]!='.': j += 1 |
|
22 break |
|
23 n = n[:j] |
|
24 A((n[0]!='0' or len(n)==1) and n or n[1:]) |
|
25 return ' '.join(s) |
|
26 |
|
27 #hack test for comma users |
|
28 if ',' in fp_str(0.25): |
|
29 _FP_STR = fp_str |
|
30 def fp_str(*a): |
|
31 return _FP_STR(*a).replace(',','.') |
|
32 |
|
33 def unicode2T1(utext,fonts,font0=None): |
|
34 '''return a list of (font,string) pairs representing the unicode text''' |
|
35 R = [] |
|
36 font, fonts = fonts[0], fonts[1:] |
|
37 if font0 is None: font0 = font |
|
38 enc = font.encName |
|
39 if 'UCS-2' in enc: |
|
40 enc = 'UTF16' |
|
41 while utext: |
|
42 try: |
|
43 if isUnicodeType(utext): |
|
44 s = utext.encode(enc) |
|
45 else: |
|
46 s = utext |
|
47 R.append((font,s)) |
|
48 break |
|
49 except UnicodeEncodeError as e: |
|
50 i0, il = e.args[2:4] |
|
51 if i0: |
|
52 R.append((font,utext[:i0].encode(enc))) |
|
53 if fonts: |
|
54 R.extend(unicode2T1(utext[i0:il],fonts,font0)) |
|
55 else: |
|
56 R.append((font0._notdefFont,font0._notdefChar*(il-i0))) |
|
57 utext = utext[il:] |
|
58 return R |
|
59 |
|
60 def _instanceStringWidthU(self, text, size, encoding='utf8'): |
|
61 """This is the "purist" approach to width""" |
|
62 if not isUnicodeType(text): text = text.decode(encoding) |
|
63 return sum([sum(map(f.widths.__getitem__,list(map(ord,t)))) for f, t in unicode2T1(text,[self]+self.substitutionFonts)])*0.001*size |
|
64 |
|
65 if __name__=='__main__': |
|
66 import sys, os |
|
67 for modname in 'reportlab.lib.rl_accel','reportlab.lib._rl_accel': |
|
68 for cmd in ( |
|
69 #"unicode2T1('abcde fghi . jkl ; mno',fonts)", |
|
70 #"unicode2T1(u'abcde fghi . jkl ; mno',fonts)", |
|
71 "_instanceStringWidthU(font,'abcde fghi . jkl ; mno',10)", |
|
72 "_instanceStringWidthU(font,u'abcde fghi . jkl ; mno',10)", |
|
73 ): |
|
74 print '%s %s' % (modname,cmd) |
|
75 s=';'.join(( |
|
76 "from reportlab.pdfbase.pdfmetrics import getFont", |
|
77 "from %s import unicode2T1,_instanceStringWidthU" % modname, |
|
78 "fonts=[getFont('Helvetica')]+getFont('Helvetica').substitutionFonts""", |
|
79 "font=fonts[0]", |
|
80 )) |
|
81 os.system('%s -m timeit -s"%s" "%s"' % (sys.executable,s,cmd)) |