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