src/reportlab/pdfbase/pdfmetrics.py
author rptlab
Tue, 30 Apr 2013 14:28:14 +0100
branchpy33
changeset 3723 99aa837b6703
parent 3721 0c93dd8ff567
child 3725 ca840494f9dd
permissions -rwxr-xr-x
second stage of port to Python 3.3; working hello world
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3617
ae5744e97c42 reportlab: copyright date changes
robin
parents: 3421
diff changeset
     1
#Copyright ReportLab Europe Ltd. 2000-2012
687
b84a53895dcb Initial split of pdfmetrics into code + database; some minor name adjustments
rgbecker
parents: 681
diff changeset
     2
#see license.txt for license details
2332
2a7ab4405e18 Remove $Header:, fix CopyRight & history
rgbecker
parents: 2328
diff changeset
     3
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/pdfbase/pdfmetrics.py
687
b84a53895dcb Initial split of pdfmetrics into code + database; some minor name adjustments
rgbecker
parents: 681
diff changeset
     4
#$Header $
2321
3454f5b41760 Unicode and UTF8 support changes
andy
parents: 2257
diff changeset
     5
__version__=''' $Id$ '''
3032
22224b1b4d24 New docstrings mainly for module titles
damian
parents: 3031
diff changeset
     6
__doc__="""This provides a database of font metric information and
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
     7
efines Font, Encoding and TypeFace classes aimed at end users.
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
     8
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
     9
There are counterparts to some of these in pdfbase/pdfdoc.py, but
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    10
the latter focus on constructing the right PDF objects.  These
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    11
classes are declarative and focus on letting the user construct
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    12
and query font objects.
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    13
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    14
The module maintains a registry of font objects at run time.
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 678
diff changeset
    15
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    16
It is independent of the canvas or any particular context.  It keeps
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    17
a registry of Font, TypeFace and Encoding objects.  Ideally these
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    18
would be pre-loaded, but due to a nasty circularity problem we
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    19
trap attempts to access them and do it on first access.
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 678
diff changeset
    20
"""
3246
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
    21
import string, os, sys
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    22
from reportlab.pdfbase import _fontdata
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    23
from reportlab.lib.logger import warnOnce
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    24
from reportlab.lib.utils import rl_isfile, rl_glob, rl_isdir, open_and_read, open_and_readlines, findInPaths, isSeqType, isStrType, isUnicodeType, isPython3
3214
f7e2da62a5a0 pdfmetrics.py: use findInPaths to improve font file finding
rgbecker
parents: 3032
diff changeset
    25
from reportlab.rl_config import defaultEncoding, T1SearchPath
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
    26
from . import rl_codecs
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    27
_notdefChar = b'n'
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    28
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    29
rl_codecs.RL_Codecs.register()
891
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
    30
standardFonts = _fontdata.standardFonts
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
    31
standardEncodings = _fontdata.standardEncodings
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
    32
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    33
_typefaces = {}
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    34
_encodings = {}
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
    35
_fonts = {}
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
    36
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
    37
def _py_unicode2T1(utext,fonts):
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    38
    '''return a list of (font,string) pairs representing the unicode text'''
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    39
    R = []
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    40
    font, fonts = fonts[0], fonts[1:]
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    41
    enc = font.encName
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    42
    if 'UCS-2' in enc:
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    43
        enc = 'UTF16'
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    44
    while utext:
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    45
        try:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    46
            if isUnicodeType(utext):
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    47
                s = utext.encode(enc)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    48
            else:
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    49
                s = utext
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    50
            R.append((font,s))
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    51
            break
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
    52
        except UnicodeEncodeError as e:
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    53
            i0, il = e.args[2:4]
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    54
            if i0:
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    55
                R.append((font,utext[:i0].encode(enc)))
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    56
            if fonts:
2614
c643e35aa4ac pdfmetrics.py: fix rl_accel --> _rl_accel typo
rgbecker
parents: 2602
diff changeset
    57
                R.extend(_py_unicode2T1(utext[i0:il],fonts))
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    58
            else:
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    59
                R.append((_notdefFont,_notdefChar*(il-i0)))
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    60
            utext = utext[il:]
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    61
    return R
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
    62
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
    63
try:
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
    64
    from _rl_accel import unicode2T1
2602
9cb4ad32237c pdfmetrics.py: _rl_accel._instanceStringWidthU
rgbecker
parents: 2601
diff changeset
    65
except ImportError:
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
    66
    unicode2T1 = _py_unicode2T1
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
    67
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    68
class FontError(Exception):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    69
    pass
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    70
class FontNotFoundError(Exception):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    71
    pass
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    72
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    73
def parseAFMFile(afmFileName):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    74
    """Quick and dirty - gives back a top-level dictionary
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    75
    with top-level items, and a 'widths' key containing
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    76
    a dictionary of glyph names and widths.  Just enough
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    77
    needed for embedding.  A better parser would accept
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    78
    options for what data you wwanted, and preserve the
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    79
    order."""
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    80
2257
da4f75df4161 Compact distro friendly
rgbecker
parents: 2217
diff changeset
    81
    lines = open_and_readlines(afmFileName, 'r')
1512
1a150013d0f8 MAC AFM files fix from Niki Spahiev
rgbecker
parents: 1482
diff changeset
    82
    if len(lines)<=1:
1a150013d0f8 MAC AFM files fix from Niki Spahiev
rgbecker
parents: 1482
diff changeset
    83
        #likely to be a MAC file
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    84
        if lines: lines = lines[0].split('\r')
1512
1a150013d0f8 MAC AFM files fix from Niki Spahiev
rgbecker
parents: 1482
diff changeset
    85
        if len(lines)<=1:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
    86
            raise ValueError('AFM file %s hasn\'t enough data' % afmFileName)
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    87
    topLevel = {}
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    88
    glyphLevel = []
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    89
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    90
    lines = [l.strip() for l in lines]
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
    91
    lines = [l for l in lines if not l.lower().startswith('comment')]
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    92
    #pass 1 - get the widths
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    93
    inMetrics = 0  # os 'TOP', or 'CHARMETRICS'
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    94
    for line in lines:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    95
        if line[0:16] == 'StartCharMetrics':
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    96
            inMetrics = 1
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    97
        elif line[0:14] == 'EndCharMetrics':
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    98
            inMetrics = 0
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
    99
        elif inMetrics:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   100
            chunks = line.split(';')
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   101
            chunks = [chunk.strip() for chunk in chunks]
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   102
            cidChunk, widthChunk, nameChunk = chunks[0:3]
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   103
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   104
            # character ID
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   105
            l, r = cidChunk.split()
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   106
            assert l == 'C', 'bad line in font file %s' % line
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   107
            cid = int(r)
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   108
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   109
            # width
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   110
            l, r = widthChunk.split()
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   111
            assert l == 'WX', 'bad line in font file %s' % line
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   112
            width = int(r)
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   113
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   114
            # name
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   115
            l, r = nameChunk.split()
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   116
            assert l == 'N', 'bad line in font file %s' % line
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   117
            name = r
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   118
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   119
            glyphLevel.append((cid, width, name))
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   120
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   121
    # pass 2 font info
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   122
    inHeader = 0
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   123
    for line in lines:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   124
        if line[0:16] == 'StartFontMetrics':
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   125
            inHeader = 1
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   126
        if line[0:16] == 'StartCharMetrics':
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   127
            inHeader = 0
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   128
        elif inHeader:
1482
efa5fe3b2938 Improved AFM error handling
rgbecker
parents: 1446
diff changeset
   129
            if line[0:7] == 'Comment': pass
efa5fe3b2938 Improved AFM error handling
rgbecker
parents: 1446
diff changeset
   130
            try:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   131
                left, right = line.split(' ',1)
1482
efa5fe3b2938 Improved AFM error handling
rgbecker
parents: 1446
diff changeset
   132
            except:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   133
                raise ValueError("Header information error in afm %s: line='%s'" % (afmFileName, line))
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   134
            try:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   135
                right = int(right)
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   136
            except:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   137
                pass
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   138
            topLevel[left] = right
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   139
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   140
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   141
    return (topLevel, glyphLevel)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   142
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   143
class TypeFace:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   144
    def __init__(self, name):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   145
        self.name = name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   146
        self.glyphNames = []
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   147
        self.glyphWidths = {}
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   148
        self.ascent = 0
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   149
        self.descent = 0
2216
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   150
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   151
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   152
        # all typefaces of whatever class should have these 3 attributes.
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   153
        # these are the basis for family detection.
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   154
        self.familyName = None  # should set on load/construction if possible
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   155
        self.bold = 0    # bold faces should set this
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   156
        self.italic = 0  #italic faces should set this
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   157
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   158
        if name == 'ZapfDingbats':
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   159
            self.requiredEncoding = 'ZapfDingbatsEncoding'
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   160
        elif name == 'Symbol':
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   161
            self.requiredEncoding = 'SymbolEncoding'
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   162
        else:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   163
            self.requiredEncoding = None
891
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
   164
        if name in standardFonts:
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   165
            self.builtIn = 1
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   166
            self._loadBuiltInData(name)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   167
        else:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   168
            self.builtIn = 0
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   169
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   170
    def _loadBuiltInData(self, name):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   171
        """Called for the built in 14 fonts.  Gets their glyph data.
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   172
        We presume they never change so this can be a shared reference."""
2200
be0cfccc662a Fixed up tabs and whitespace in all source files
andy_robinson
parents: 2125
diff changeset
   173
        name = str(name)    #needed for pycanvas&jython/2.1 compatibility
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   174
        self.glyphWidths = _fontdata.widthsByFontGlyph[name]
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   175
        self.glyphNames = list(self.glyphWidths.keys())
1570
8c1459d1f12a Hacked to use ascent and descent properly.
johnprecedo
parents: 1512
diff changeset
   176
        self.ascent,self.descent = _fontdata.ascent_descent[name]
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   177
2216
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   178
    def getFontFiles(self):
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   179
        "Info function, return list of the font files this depends on."
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   180
        return []
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   181
1630
e398cb68fd71 Fixed font filename extension case buglets on OS X.
dinu_gherman
parents: 1570
diff changeset
   182
    def findT1File(self, ext='.pfb'):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   183
        possible_exts = (ext.lower(), ext.upper())
881
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   184
        if hasattr(self,'pfbFileName'):
1446
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   185
            r_basename = os.path.splitext(self.pfbFileName)[0]
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   186
            for e in possible_exts:
2257
da4f75df4161 Compact distro friendly
rgbecker
parents: 2217
diff changeset
   187
                if rl_isfile(r_basename + e):
1446
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   188
                    return r_basename + e
881
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   189
        try:
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   190
            r = _fontdata.findT1File(self.name)
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   191
        except:
1291
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   192
            afm = bruteForceSearchForAFM(self.name)
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   193
            if afm:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   194
                if ext.lower() == '.pfb':
1446
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   195
                    for e in possible_exts:
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   196
                        pfb = os.path.splitext(afm)[0] + e
2257
da4f75df4161 Compact distro friendly
rgbecker
parents: 2217
diff changeset
   197
                        if rl_isfile(pfb):
1446
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   198
                            r = pfb
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   199
                        else:
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   200
                            r = None
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   201
                elif ext.lower() == '.afm':
1291
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   202
                    r = afm
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   203
            else:
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   204
                r = None
881
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   205
        if r is None:
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   206
            warnOnce("Can't find %s for face '%s'" % (ext, self.name))
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   207
        return r
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   208
2473
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   209
def bruteForceSearchForFile(fn,searchPath=None):
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   210
    if searchPath is None: from reportlab.rl_config import T1SearchPath as searchPath
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   211
    if rl_isfile(fn): return fn
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   212
    bfn = os.path.basename(fn)
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   213
    for dirname in searchPath:
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   214
        if not rl_isdir(dirname): continue
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   215
        tfn = os.path.join(dirname,bfn)
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   216
        if rl_isfile(tfn): return tfn
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   217
    return fn
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   218
1291
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   219
def bruteForceSearchForAFM(faceName):
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   220
    """Looks in all AFM files on path for face with given name.
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   221
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   222
    Returns AFM file name or None.  Ouch!"""
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   223
    from reportlab.rl_config import T1SearchPath
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   224
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   225
    for dirname in T1SearchPath:
2473
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   226
        if not rl_isdir(dirname): continue
2506
aa058aaf324c pdfbase.pdfmetrics: fix glob to be zip friendly
rgbecker
parents: 2473
diff changeset
   227
        possibles = rl_glob(dirname + os.sep + '*.[aA][fF][mM]')
1291
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   228
        for possible in possibles:
3246
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
   229
            try:
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
   230
                topDict, glyphDict = parseAFMFile(possible)
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
   231
                if topDict['FontName'] == faceName:
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
   232
                    return possible
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
   233
            except:
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
   234
                t,v,b=sys.exc_info()
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
   235
                v.args = (' '.join(map(str,v.args))+', while looking for faceName=%r' % faceName,)
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
   236
                raise 
7087d203eb88 pdfmetrics.py: attempt to make bruteForceSearchForAFM more revealing
rgbecker
parents: 3214
diff changeset
   237
1683
7fa753e4420a Removed all trailing whitespace
andy_robinson
parents: 1677
diff changeset
   238
891
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
   239
#for faceName in standardFonts:
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   240
#    registerTypeFace(TypeFace(faceName))
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   241
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   242
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   243
class Encoding:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   244
    """Object to help you create and refer to encodings."""
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   245
    def __init__(self, name, base=None):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   246
        self.name = name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   247
        self.frozen = 0
891
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
   248
        if name in standardEncodings:
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   249
            assert base is None, "Can't have a base encoding for a standard encoding"
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   250
            self.baseEncodingName = name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   251
            self.vector = _fontdata.encodings[name]
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   252
        elif base == None:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   253
            # assume based on the usual one
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   254
            self.baseEncodingName = defaultEncoding
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   255
            self.vector = _fontdata.encodings[defaultEncoding]
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   256
        elif isStrType(base):
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   257
            baseEnc = getEncoding(base)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   258
            self.baseEncodingName = baseEnc.name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   259
            self.vector = baseEnc.vector[:]
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   260
        elif isSeqType(base):
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   261
            self.baseEncodingName = defaultEncoding
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   262
            self.vector = base[:]
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   263
        elif isinstance(base, Encoding):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   264
            # accept a vector
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   265
            self.baseEncodingName = base.name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   266
            self.vector = base.vector[:]
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   267
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   268
    def __getitem__(self, index):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   269
        "Return glyph name for that code point, or None"
1660
c93476060b9d simple support for acrobat forms in reportlab documents. Minor optimizations to metrics
aaron_watters
parents: 1630
diff changeset
   270
        # THIS SHOULD BE INLINED FOR SPEED
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   271
        return self.vector[index]
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   272
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   273
    def __setitem__(self, index, value):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   274
        # should fail if they are frozen
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   275
        assert self.frozen == 0, 'Cannot modify a frozen encoding'
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   276
        if self.vector[index]!=value:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   277
            L = list(self.vector)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   278
            L[index] = value
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   279
            self.vector = tuple(L)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   280
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   281
    def freeze(self):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   282
        self.vector = tuple(self.vector)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   283
        self.frozen = 1
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   284
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   285
    def isEqual(self, other):
2943
50dc4e6d2ce7 double encoding bug fix from Max Folwell mjf@pearson.co.uk
rgbecker
parents: 2888
diff changeset
   286
        return self.name==other.name and tuple(self.vector)==tuple(other.vector)
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   287
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   288
    def modifyRange(self, base, newNames):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   289
        """Set a group of character names starting at the code point 'base'."""
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   290
        assert self.frozen == 0, 'Cannot modify a frozen encoding'
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   291
        idx = base
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   292
        for name in newNames:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   293
            self.vector[idx] = name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   294
            idx = idx + 1
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   295
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   296
    def getDifferences(self, otherEnc):
3031
6f90e7668adb docstrings cleaned up for epydoc
tim
parents: 2977
diff changeset
   297
        """
6f90e7668adb docstrings cleaned up for epydoc
tim
parents: 2977
diff changeset
   298
        Return a compact list of the code points differing between two encodings
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   299
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   300
        This is in the Adobe format: list of
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   301
           [[b1, name1, name2, name3],
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   302
           [b2, name4]]
3031
6f90e7668adb docstrings cleaned up for epydoc
tim
parents: 2977
diff changeset
   303
           
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   304
        where b1...bn is the starting code point, and the glyph names following
3031
6f90e7668adb docstrings cleaned up for epydoc
tim
parents: 2977
diff changeset
   305
        are assigned consecutive code points.
6f90e7668adb docstrings cleaned up for epydoc
tim
parents: 2977
diff changeset
   306
        
6f90e7668adb docstrings cleaned up for epydoc
tim
parents: 2977
diff changeset
   307
        """
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   308
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   309
        ranges = []
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   310
        curRange = None
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   311
        for i in range(len(self.vector)):
1660
c93476060b9d simple support for acrobat forms in reportlab documents. Minor optimizations to metrics
aaron_watters
parents: 1630
diff changeset
   312
            glyph = self.vector[i]
c93476060b9d simple support for acrobat forms in reportlab documents. Minor optimizations to metrics
aaron_watters
parents: 1630
diff changeset
   313
            if glyph==otherEnc.vector[i]:
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   314
                if curRange:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   315
                    ranges.append(curRange)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   316
                    curRange = []
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   317
            else:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   318
                if curRange:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   319
                    curRange.append(glyph)
1512
1a150013d0f8 MAC AFM files fix from Niki Spahiev
rgbecker
parents: 1482
diff changeset
   320
                elif glyph:
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   321
                    curRange = [i, glyph]
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   322
        if curRange:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   323
            ranges.append(curRange)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   324
        return ranges
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   325
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   326
    def makePDFObject(self):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   327
        "Returns a PDF Object representing self"
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   328
        # avoid circular imports - this cannot go at module level
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   329
        from reportlab.pdfbase import pdfdoc
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   330
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   331
        D = {}
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   332
        baseEnc = getEncoding(self.baseEncodingName)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   333
        differences = self.getDifferences(baseEnc) #[None] * 256)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   334
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   335
        # if no differences, we just need the base name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   336
        if differences == []:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   337
            return pdfdoc.PDFName(self.baseEncodingName)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   338
        else:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   339
            #make up a dictionary describing the new encoding
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   340
            diffArray = []
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   341
            for range in differences:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   342
                diffArray.append(range[0])        # numbers go 'as is'
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   343
                for glyphName in range[1:]:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   344
                    if glyphName is not None:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   345
                        # there is no way to 'unset' a character in the base font.
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   346
                        diffArray.append('/' + glyphName)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   347
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   348
            #print 'diffArray = %s' % diffArray
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   349
            D["Differences"] = pdfdoc.PDFArray(diffArray)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   350
            D["BaseEncoding"] = pdfdoc.PDFName(self.baseEncodingName)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   351
            D["Type"] = pdfdoc.PDFName("Encoding")
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   352
            PD = pdfdoc.PDFDictionary(D)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   353
            return PD
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   354
891
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
   355
#for encName in standardEncodings:
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   356
#    registerEncoding(Encoding(encName))
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   357
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   358
standardT1SubstitutionFonts = []
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   359
class Font:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   360
    """Represents a font (i.e combination of face and encoding).
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   361
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   362
    Defines suitable machinery for single byte fonts.  This is
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   363
    a concrete class which can handle the basic built-in fonts;
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   364
    not clear yet if embedded ones need a new font class or
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   365
    just a new typeface class (which would do the job through
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   366
    composition)"""
2678
38d18a697cd0 reportlab: Python2.5 changes + minor cosmetics and improvements
rgbecker
parents: 2636
diff changeset
   367
38d18a697cd0 reportlab: Python2.5 changes + minor cosmetics and improvements
rgbecker
parents: 2636
diff changeset
   368
    _multiByte = 0      # do not want our own stringwidth
38d18a697cd0 reportlab: Python2.5 changes + minor cosmetics and improvements
rgbecker
parents: 2636
diff changeset
   369
    _dynamicFont = 0    # do not want dynamic subsetting
38d18a697cd0 reportlab: Python2.5 changes + minor cosmetics and improvements
rgbecker
parents: 2636
diff changeset
   370
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   371
    def __init__(self, name, faceName, encName):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   372
        self.fontName = name
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   373
        face = self.face = getTypeFace(faceName)
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   374
        self.encoding= getEncoding(encName)
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   375
        self.encName = encName
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   376
        if face.builtIn and face.requiredEncoding is None:
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   377
            _ = standardT1SubstitutionFonts
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   378
        else:
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   379
            _ = []
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   380
        self.substitutionFonts = _
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   381
        self._calcWidths()
3421
d6f26fcd26d2 _rl_accel.c: remove pdfmetrics.py variable caching (except for _notdefChar/Font when used with older pdfmetrics.py)
rgbecker
parents: 3326
diff changeset
   382
        self._notdefChar = _notdefChar
d6f26fcd26d2 _rl_accel.c: remove pdfmetrics.py variable caching (except for _notdefChar/Font when used with older pdfmetrics.py)
rgbecker
parents: 3326
diff changeset
   383
        self._notdefFont = name=='ZapfDingbats' and self or _notdefFont
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   384
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   385
    def __repr__(self):
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   386
        return "<%s %s>" % (self.__class__.__name__, self.face.name)
1179
dfa435dc15d2 Changes to facilitate CID (Asian) fonts.
andy_robinson
parents: 1158
diff changeset
   387
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   388
    def _calcWidths(self):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   389
        """Vector of widths for stringWidth function"""
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   390
        #synthesize on first request
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   391
        w = [0] * 256
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   392
        gw = self.face.glyphWidths
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   393
        vec = self.encoding.vector
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   394
        for i in range(256):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   395
            glyphName = vec[i]
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   396
            if glyphName is not None:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   397
                try:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   398
                    width = gw[glyphName]
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   399
                    w[i] = width
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   400
                except KeyError:
1070
340bb905c1d0 Official sample font checked in
andy_robinson
parents: 1069
diff changeset
   401
                    import reportlab.rl_config
340bb905c1d0 Official sample font checked in
andy_robinson
parents: 1069
diff changeset
   402
                    if reportlab.rl_config.warnOnMissingFontGlyphs:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   403
                        print('typeface "%s" does not have a glyph "%s", bad font!' % (self.face.name, glyphName))
1070
340bb905c1d0 Official sample font checked in
andy_robinson
parents: 1069
diff changeset
   404
                    else:
340bb905c1d0 Official sample font checked in
andy_robinson
parents: 1069
diff changeset
   405
                        pass
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   406
        self.widths = w
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   407
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   408
    def _py_stringWidth(self, text, size, encoding='utf8'):
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   409
        """This is the "purist" approach to width.  The practical approach
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   410
        is to use the stringWidth function, which may be swapped in for one
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   411
        written in C."""
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   412
        if not isUnicodeType(text): text = text.decode(encoding)
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   413
        return sum([sum(map(f.widths.__getitem__,list(map(ord,t)))) for f, t in unicode2T1(text,[self]+self.substitutionFonts)])*0.001*size
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   414
    stringWidth = _py_stringWidth
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   415
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   416
    def _formatWidths(self):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   417
        "returns a pretty block in PDF Array format to aid inspection"
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   418
        text = b'['
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   419
        for i in range(256):
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   420
            text = text + b' ' + bytes(str(self.widths[i]),'utf8')
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   421
            if i == 255:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   422
                text = text + b' ]'
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   423
            if i % 16 == 15:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   424
                text = text + b'\n'
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   425
        return text
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   426
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   427
    def addObjects(self, doc):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   428
        """Makes and returns one or more PDF objects to be added
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   429
        to the document.  The caller supplies the internal name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   430
        to be used (typically F1, F2... in sequence) """
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   431
        # avoid circular imports - this cannot go at module level
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   432
        from reportlab.pdfbase import pdfdoc
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   433
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   434
        # construct a Type 1 Font internal object
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   435
        internalName = 'F' + repr(len(doc.fontMapping)+1)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   436
        pdfFont = pdfdoc.PDFType1Font()
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   437
        pdfFont.Name = internalName
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   438
        pdfFont.BaseFont = self.face.name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   439
        pdfFont.__Comment__ = 'Font %s' % self.fontName
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   440
        pdfFont.Encoding = self.encoding.makePDFObject()
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   441
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   442
        # is it a built-in one?  if not, need more stuff.
891
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
   443
        if not self.face.name in standardFonts:
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   444
            pdfFont.FirstChar = 0
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   445
            pdfFont.LastChar = 255
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   446
            pdfFont.Widths = pdfdoc.PDFArray(self.widths)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   447
            pdfFont.FontDescriptor = self.face.addObjects(doc)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   448
        # now link it in
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   449
        ref = doc.Reference(pdfFont, internalName)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   450
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   451
        # also refer to it in the BasicFonts dictionary
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   452
        fontDict = doc.idToObject['BasicFonts'].dict
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   453
        fontDict[internalName] = pdfFont
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   454
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   455
        # and in the font mappings
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   456
        doc.fontMapping[self.fontName] = '/' + internalName
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   457
1393
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   458
PFB_MARKER=chr(0x80)
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   459
PFB_ASCII=chr(1)
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   460
PFB_BINARY=chr(2)
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   461
PFB_EOF=chr(3)
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   462
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   463
if isPython3:
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   464
    def _pfbCheck(p,d,m,fn):
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   465
        if chr(d[p])!=PFB_MARKER or chr(d[p+1])!=m:
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   466
            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]))
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   467
        if m==PFB_EOF: return
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   468
        p = p + 2
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   469
        l = (((((d[p+3])<<8)|(d[p+2])<<8)|(d[p+1]))<<8)|(d[p])
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   470
        p = p + 4
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   471
        if p+l>len(d):
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   472
            raise ValueError('Bad pfb file\'%s\' needed %d+%d bytes have only %d!' % (fn,p,l,len(d)))
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   473
        return p, p+l
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   474
else:
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   475
    def _pfbSegLen(p,d):
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   476
        '''compute a pfb style length from the first 4 bytes of string d'''
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   477
        return ((((ord(d[p+3])<<8)|ord(d[p+2])<<8)|ord(d[p+1]))<<8)|ord(d[p])
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   478
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   479
    def _pfbCheck(p,d,m,fn):
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   480
        if d[p]!=PFB_MARKER or d[p+1]!=m:
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   481
            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])))
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   482
        if m==PFB_EOF: return
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   483
        p = p + 2
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   484
        l = _pfbSegLen(p,d)
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   485
        p = p + 4
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   486
        if p+l>len(d):
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   487
            raise ValueError('Bad pfb file\'%s\' needed %d+%d bytes have only %d!' % (fn,p,l,len(d)))
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   488
        return p, p+l
1393
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   489
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   490
class EmbeddedType1Face(TypeFace):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   491
    """A Type 1 font other than one of the basic 14.
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   492
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   493
    Its glyph data will be embedded in the PDF file."""
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   494
    def __init__(self, afmFileName, pfbFileName):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   495
        # ignore afm file for now
2216
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   496
        TypeFace.__init__(self, None)
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   497
        #None is a hack, name will be supplied by AFM parse lower done
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   498
        #in this __init__ method.
3214
f7e2da62a5a0 pdfmetrics.py: use findInPaths to improve font file finding
rgbecker
parents: 3032
diff changeset
   499
        afmFileName = findInPaths(afmFileName,T1SearchPath)
f7e2da62a5a0 pdfmetrics.py: use findInPaths to improve font file finding
rgbecker
parents: 3032
diff changeset
   500
        pfbFileName = findInPaths(pfbFileName,T1SearchPath)
881
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   501
        self.afmFileName = os.path.abspath(afmFileName)
865c3099aec4 Added findT1File to base Face, and _fontdata
rgbecker
parents: 879
diff changeset
   502
        self.pfbFileName = os.path.abspath(pfbFileName)
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   503
        self.requiredEncoding = None
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   504
        self._loadGlyphs(pfbFileName)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   505
        self._loadMetrics(afmFileName)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   506
2216
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   507
    def getFontFiles(self):
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   508
        return [self.afmFileName, self.pfbFileName]
2678
38d18a697cd0 reportlab: Python2.5 changes + minor cosmetics and improvements
rgbecker
parents: 2636
diff changeset
   509
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   510
    def _loadGlyphs(self, pfbFileName):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   511
        """Loads in binary glyph data, and finds the four length
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   512
        measurements needed for the font descriptor"""
2473
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   513
        pfbFileName = bruteForceSearchForFile(pfbFileName)
2257
da4f75df4161 Compact distro friendly
rgbecker
parents: 2217
diff changeset
   514
        assert rl_isfile(pfbFileName), 'file %s not found' % pfbFileName
da4f75df4161 Compact distro friendly
rgbecker
parents: 2217
diff changeset
   515
        d = open_and_read(pfbFileName, 'b')
1393
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   516
        s1, l1 = _pfbCheck(0,d,PFB_ASCII,pfbFileName)
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   517
        s2, l2 = _pfbCheck(l1,d,PFB_BINARY,pfbFileName)
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   518
        s3, l3 = _pfbCheck(l2,d,PFB_ASCII,pfbFileName)
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   519
        _pfbCheck(l3,d,PFB_EOF,pfbFileName)
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   520
        self._binaryData = d[s1:l1]+d[s2:l2]+d[s3:l3]
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   521
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   522
        self._length = len(self._binaryData)
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   523
        self._length1 = l1-s1
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   524
        self._length2 = l2-s2
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   525
        self._length3 = l3-s3
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   526
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   527
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   528
    def _loadMetrics(self, afmFileName):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   529
        """Loads in and parses font metrics"""
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   530
        #assert os.path.isfile(afmFileName), "AFM file %s not found" % afmFileName
2473
10d3b640b4f7 pdfmetrics.py: fix minor buglet discovered by Ron Peleg
rgbecker
parents: 2341
diff changeset
   531
        afmFileName = bruteForceSearchForFile(afmFileName)
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   532
        (topLevel, glyphData) = parseAFMFile(afmFileName)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   533
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   534
        self.name = topLevel['FontName']
2216
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   535
        self.familyName = topLevel['FamilyName']
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   536
        self.ascent = topLevel.get('Ascender', 1000)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   537
        self.descent = topLevel.get('Descender', 0)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   538
        self.capHeight = topLevel.get('CapHeight', 1000)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   539
        self.italicAngle = topLevel.get('ItalicAngle', 0)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   540
        self.stemV = topLevel.get('stemV', 0)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   541
        self.xHeight = topLevel.get('XHeight', 1000)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   542
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   543
        strBbox = topLevel.get('FontBBox', [0,0,1000,1000])
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   544
        tokens = strBbox.split()
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   545
        self.bbox = []
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   546
        for tok in tokens:
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   547
            self.bbox.append(int(tok))
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   548
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   549
        glyphWidths = {}
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   550
        for (cid, width, name) in glyphData:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   551
            glyphWidths[name] = width
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   552
        self.glyphWidths = glyphWidths
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   553
        self.glyphNames = list(glyphWidths.keys())
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   554
        self.glyphNames.sort()
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   555
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   556
        # for font-specific encodings like Symbol, Dingbats, Carta we
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   557
        # need to make a new encoding as well....
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   558
        if topLevel.get('EncodingScheme', None) == 'FontSpecific':
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   559
            names = [None] * 256
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   560
            for (code, width, name) in glyphData:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   561
                if code >=0 and code <=255:
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   562
                    names[code] = name
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   563
            encName = self.name + 'Encoding'
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   564
            self.requiredEncoding = encName
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   565
            enc = Encoding(encName, names)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   566
            registerEncoding(enc)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   567
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   568
    def addObjects(self, doc):
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   569
        """Add whatever needed to PDF file, and return a FontDescriptor reference"""
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   570
        from reportlab.pdfbase import pdfdoc
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   571
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   572
        fontFile = pdfdoc.PDFStream()
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   573
        fontFile.content = self._binaryData
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   574
        #fontFile.dictionary['Length'] = self._length
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   575
        fontFile.dictionary['Length1'] = self._length1
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   576
        fontFile.dictionary['Length2'] = self._length2
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   577
        fontFile.dictionary['Length3'] = self._length3
1393
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   578
        #fontFile.filters = [pdfdoc.PDFZCompress]
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   579
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   580
        fontFileRef = doc.Reference(fontFile, 'fontFile:' + self.pfbFileName)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   581
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   582
        fontDescriptor = pdfdoc.PDFDictionary({
1393
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   583
            'Type': '/FontDescriptor',
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   584
            'Ascent':self.ascent,
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   585
            'CapHeight':self.capHeight,
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   586
            'Descent':self.descent,
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   587
            'Flags': 34,
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   588
            'FontBBox':pdfdoc.PDFArray(self.bbox),
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   589
            'FontName':pdfdoc.PDFName(self.name),
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   590
            'ItalicAngle':self.italicAngle,
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   591
            'StemV':self.stemV,
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   592
            'XHeight':self.xHeight,
1393
1ed4b862dcf7 Fixed up font embedding
rgbecker
parents: 1291
diff changeset
   593
            'FontFile': fontFileRef,
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   594
            })
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   595
        fontDescriptorRef = doc.Reference(fontDescriptor, 'fontDescriptor:' + self.name)
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   596
        return fontDescriptorRef
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   597
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   598
def registerTypeFace(face):
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   599
    assert isinstance(face, TypeFace), 'Not a TypeFace: %s' % face
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   600
    _typefaces[face.name] = face
1077
f377552772b2 Fixed bug introduced yesterday where bold and italic fonts fail
andy_robinson
parents: 1073
diff changeset
   601
    if not face.name in standardFonts:
2815
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   602
        # HACK - bold/italic do not apply for type 1, so egister
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   603
        # all combinations of mappings.
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   604
        registerFontFamily(face.name)
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   605
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   606
def registerEncoding(enc):
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   607
    assert isinstance(enc, Encoding), 'Not an Encoding: %s' % enc
3326
ce725978d11c Initial Python3 compatibility fixes
damian
parents: 3246
diff changeset
   608
    if enc.name in _encodings:
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   609
        # already got one, complain if they are not the same
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   610
        if enc.isEqual(_encodings[enc.name]):
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   611
            enc.freeze()
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   612
        else:
2943
50dc4e6d2ce7 double encoding bug fix from Max Folwell mjf@pearson.co.uk
rgbecker
parents: 2888
diff changeset
   613
            raise FontError('Encoding "%s" already registered with a different name vector!' % enc.name)
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   614
    else:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   615
        _encodings[enc.name] = enc
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   616
        enc.freeze()
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   617
    # have not yet dealt with immutability!
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   618
2815
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   619
def registerFontFamily(family,normal=None,bold=None,italic=None,boldItalic=None):
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   620
    from reportlab.lib import fonts
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   621
    if not normal: normal = family
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   622
    family = family.lower()
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   623
    if not boldItalic: boldItalic = italic or bold or normal
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   624
    if not bold: bold = normal
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   625
    if not italic: italic = normal
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   626
    fonts.addMapping(family, 0, 0, normal)
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   627
    fonts.addMapping(family, 1, 0, bold)
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   628
    fonts.addMapping(family, 0, 1, italic)
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   629
    fonts.addMapping(family, 1, 1, boldItalic)
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   630
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   631
def registerFont(font):
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   632
    "Registers a font, including setting up info for accelerated stringWidth"
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   633
    #assert isinstance(font, Font), 'Not a Font: %s' % font
1777
48870c5f865a Jerome's New improved hasher
rgbecker
parents: 1775
diff changeset
   634
    fontName = font.fontName
1775
acd97501cb9f Fix for Jerome's magic breakages in 1.5.2
rgbecker
parents: 1748
diff changeset
   635
    _fonts[fontName] = font
1822
c8d9861fcc45 Allows Asian fonts to have correct TT mapping and thus work in paragraphs
andy_robinson
parents: 1777
diff changeset
   636
    if font._multiByte:
c8d9861fcc45 Allows Asian fonts to have correct TT mapping and thus work in paragraphs
andy_robinson
parents: 1777
diff changeset
   637
        # CID fonts don't need to have typeface registered.
c8d9861fcc45 Allows Asian fonts to have correct TT mapping and thus work in paragraphs
andy_robinson
parents: 1777
diff changeset
   638
        #need to set mappings so it can go in a paragraph even if within
c8d9861fcc45 Allows Asian fonts to have correct TT mapping and thus work in paragraphs
andy_robinson
parents: 1777
diff changeset
   639
        # bold tags
2815
0a9baa55d61f reportlab: added registerFontFamily
rgbecker
parents: 2767
diff changeset
   640
        registerFontFamily(font.fontName)
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   641
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   642
def getTypeFace(faceName):
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   643
    """Lazily construct known typefaces if not found"""
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   644
    try:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   645
        return _typefaces[faceName]
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   646
    except KeyError:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   647
        # not found, construct it if known
891
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
   648
        if faceName in standardFonts:
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   649
            face = TypeFace(faceName)
2216
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   650
            (face.familyName, face.bold, face.italic) = _fontdata.standardFontAttributes[faceName]
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   651
            registerTypeFace(face)
2216
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   652
##            print 'auto-constructing type face %s with family=%s, bold=%d, italic=%d' % (
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   653
##                face.name, face.familyName, face.bold, face.italic)
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   654
            return face
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   655
        else:
1291
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   656
            #try a brute force search
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   657
            afm = bruteForceSearchForAFM(faceName)
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   658
            if afm:
1446
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   659
                for e in ('.pfb', '.PFB'):
3db8518e7f18 Added Paul Winkler's extension case patch
rgbecker
parents: 1432
diff changeset
   660
                    pfb = os.path.splitext(afm)[0] + e
2257
da4f75df4161 Compact distro friendly
rgbecker
parents: 2217
diff changeset
   661
                    if rl_isfile(pfb): break
da4f75df4161 Compact distro friendly
rgbecker
parents: 2217
diff changeset
   662
                assert rl_isfile(pfb), 'file %s not found!' % pfb
1291
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   663
                face = EmbeddedType1Face(afm, pfb)
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   664
                registerTypeFace(face)
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   665
                return face
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   666
            else:
64ed97db21dd Auto-load fonts from AFM files where possible
andy_robinson
parents: 1179
diff changeset
   667
                raise
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   668
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   669
def getEncoding(encName):
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   670
    """Lazily construct known encodings if not found"""
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   671
    try:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   672
        return _encodings[encName]
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   673
    except KeyError:
891
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
   674
        if encName in standardEncodings:
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   675
            enc = Encoding(encName)
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   676
            registerEncoding(enc)
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   677
            #print 'auto-constructing encoding %s' % encName
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   678
            return enc
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   679
        else:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   680
            raise
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   681
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   682
def findFontAndRegister(fontName):
2636
65ee4afe1b8b Fix typo in docstring
jjlee
parents: 2614
diff changeset
   683
    '''search for and register a font given its name'''
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   684
    assert type(fontName) is str
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   685
    #it might have a font-specific encoding e.g. Symbol
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   686
    # or Dingbats.  If not, take the default.
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   687
    face = getTypeFace(fontName)
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   688
    if face.requiredEncoding:
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   689
        font = Font(fontName, fontName, face.requiredEncoding)
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   690
    else:
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   691
        font = Font(fontName, fontName, defaultEncoding)
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   692
    registerFont(font)
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   693
    return font
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   694
3421
d6f26fcd26d2 _rl_accel.c: remove pdfmetrics.py variable caching (except for _notdefChar/Font when used with older pdfmetrics.py)
rgbecker
parents: 3326
diff changeset
   695
def getFont(fontName):
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   696
    """Lazily constructs known fonts if not found.
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   697
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   698
    Names of form 'face-encoding' will be built if
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   699
    face and encoding are known.  Also if the name is
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   700
    just one of the standard 14, it will make up a font
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   701
    in the default encoding."""
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   702
    try:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   703
        return _fonts[fontName]
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   704
    except KeyError:
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   705
        return findFontAndRegister(fontName)
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   706
3421
d6f26fcd26d2 _rl_accel.c: remove pdfmetrics.py variable caching (except for _notdefChar/Font when used with older pdfmetrics.py)
rgbecker
parents: 3326
diff changeset
   707
_notdefFont = getFont('ZapfDingbats')
d6f26fcd26d2 _rl_accel.c: remove pdfmetrics.py variable caching (except for _notdefChar/Font when used with older pdfmetrics.py)
rgbecker
parents: 3326
diff changeset
   708
standardT1SubstitutionFonts.extend([getFont('Symbol'),_notdefFont])
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 678
diff changeset
   709
2888
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   710
def getAscentDescent(fontName,fontSize=None):
2574
d81949596070 reportlab: changes to accomodate barcodes
rgbecker
parents: 2506
diff changeset
   711
    font = getFont(fontName)
d81949596070 reportlab: changes to accomodate barcodes
rgbecker
parents: 2506
diff changeset
   712
    try:
2888
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   713
        ascent = font.ascent
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   714
        descent = font.descent
2574
d81949596070 reportlab: changes to accomodate barcodes
rgbecker
parents: 2506
diff changeset
   715
    except:
2888
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   716
        ascent = font.face.ascent
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   717
        descent = font.face.descent
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   718
    if fontSize:
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   719
        norm = fontSize/1000.
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   720
        return ascent*norm, descent*norm
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   721
    else:
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   722
        return ascent, descent
2574
d81949596070 reportlab: changes to accomodate barcodes
rgbecker
parents: 2506
diff changeset
   723
2888
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   724
def getAscent(fontName,fontSize=None):
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   725
    return getAscentDescent(fontName,fontSize)[0]
2574
d81949596070 reportlab: changes to accomodate barcodes
rgbecker
parents: 2506
diff changeset
   726
2888
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   727
def getDescent(fontName,fontSize=None):
edf4cc50dbc1 paragraph.py: better initialization for maxSize/maxAscent etc
rgbecker
parents: 2815
diff changeset
   728
    return getAscentDescent(fontName,fontSize)[1]
2574
d81949596070 reportlab: changes to accomodate barcodes
rgbecker
parents: 2506
diff changeset
   729
2216
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   730
def getRegisteredFontNames():
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   731
    "Returns what's in there"
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   732
    reg = list(_fonts.keys())
2216
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   733
    reg.sort()
aadcd9dc9480 Font reregistration cleanup
andy_robinson
parents: 2200
diff changeset
   734
    return reg
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   735
3421
d6f26fcd26d2 _rl_accel.c: remove pdfmetrics.py variable caching (except for _notdefChar/Font when used with older pdfmetrics.py)
rgbecker
parents: 3326
diff changeset
   736
def stringWidth(text, fontName, fontSize, encoding='utf8'):
d6f26fcd26d2 _rl_accel.c: remove pdfmetrics.py variable caching (except for _notdefChar/Font when used with older pdfmetrics.py)
rgbecker
parents: 3326
diff changeset
   737
    """Compute width of string in points;
d6f26fcd26d2 _rl_accel.c: remove pdfmetrics.py variable caching (except for _notdefChar/Font when used with older pdfmetrics.py)
rgbecker
parents: 3326
diff changeset
   738
    not accelerated as fast enough because of _instanceStringWidthU"""
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   739
    return getFont(fontName).stringWidth(text, fontSize, encoding=encoding)
725
05c05cc41686 Fix bad name error(s)
rgbecker
parents: 719
diff changeset
   740
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   741
try:
2602
9cb4ad32237c pdfmetrics.py: _rl_accel._instanceStringWidthU
rgbecker
parents: 2601
diff changeset
   742
    from _rl_accel import _instanceStringWidthU
2601
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   743
    import new
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   744
    Font.stringWidth = new.instancemethod(_instanceStringWidthU,None,Font)
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   745
except ImportError:
c68cae152da5 pdfmetrics.py: more version2 accelerator stuff
rgbecker
parents: 2575
diff changeset
   746
    pass
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   747
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   748
def dumpFontData():
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   749
    print('Registered Encodings:')
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   750
    keys = list(_encodings.keys())
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   751
    keys.sort()
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   752
    for encName in keys:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   753
        print('   ',encName)
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   754
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   755
    print()
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   756
    print('Registered Typefaces:')
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   757
    faces = list(_typefaces.keys())
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   758
    faces.sort()
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   759
    for faceName in faces:
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   760
        print('   ',faceName)
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   761
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   762
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   763
    print()
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   764
    print('Registered Fonts:')
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   765
    k = list(_fonts.keys())
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   766
    k.sort()
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   767
    for key in k:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   768
        font = _fonts[key]
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   769
        print('    %s (%s/%s)' % (font.fontName, font.face.name, font.encoding.name))
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   770
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   771
def test3widths(texts):
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   772
    # checks all 3 algorithms give same answer, note speed
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   773
    import time
891
5ddf7c34f68f Added some imports for compatibility/efficiency
rgbecker
parents: 881
diff changeset
   774
    for fontName in standardFonts[0:1]:
2575
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   775
##        t0 = time.time()
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   776
##        for text in texts:
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   777
##            l1 = stringWidth(text, fontName, 10)
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   778
##        t1 = time.time()
0cba68b93555 reportlab-utf8 moved to trunk
rgbecker
parents: 2574
diff changeset
   779
##        print 'fast stringWidth took %0.4f' % (t1 - t0)
714
115ed1fd2132 Stuff for adding standardFonts
rgbecker
parents: 689
diff changeset
   780
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   781
        t0 = time.time()
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   782
        w = getFont(fontName).widths
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   783
        for text in texts:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   784
            l2 = 0
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   785
            for ch in text:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   786
                l2 = l2 + w[ord(ch)]
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   787
        t1 = time.time()
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   788
        print('slow stringWidth took %0.4f' % (t1 - t0))
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   789
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   790
        t0 = time.time()
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   791
        for text in texts:
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   792
            l3 = getFont(fontName).stringWidth(text, 10)
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   793
        t1 = time.time()
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   794
        print('class lookup and stringWidth took %0.4f' % (t1 - t0))
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   795
        print()
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   796
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   797
def testStringWidthAlgorithms():
1512
1a150013d0f8 MAC AFM files fix from Niki Spahiev
rgbecker
parents: 1482
diff changeset
   798
    rawdata = open('../../rlextra/rml2pdf/doc/rml_user_guide.prep').read()
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   799
    print('rawdata length %d' % len(rawdata))
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   800
    print('test one huge string...')
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   801
    test3widths([rawdata])
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   802
    print()
3723
99aa837b6703 second stage of port to Python 3.3; working hello world
rptlab
parents: 3721
diff changeset
   803
    words = rawdata.split()
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   804
    print('test %d shorter strings (average length %0.2f chars)...' % (len(words), 1.0*len(rawdata)/len(words)))
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   805
    test3widths(words)
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   806
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   807
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   808
def test():
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   809
    helv = TypeFace('Helvetica')
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   810
    registerTypeFace(helv)
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   811
    print(helv.glyphNames[0:30])
878
ba8781b6a8f9 Merged pdfgen.fonts into pdfmetrics again
rgbecker
parents: 875
diff changeset
   812
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   813
    wombat = TypeFace('Wombat')
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   814
    print(wombat.glyphNames)
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   815
    registerTypeFace(wombat)
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   816
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   817
    dumpFontData()
689
18104568afde Changes to basic Font stuff, moved it to pdfmetrics
rgbecker
parents: 687
diff changeset
   818
2767
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   819
#preserve the initial values here
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   820
def _reset(
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   821
        initial_dicts = dict(
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   822
            _typefaces = _typefaces.copy(),
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   823
            _encodings = _encodings.copy(),
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   824
            _fonts = _fonts.copy(),
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   825
            )
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   826
        ):
3721
0c93dd8ff567 initial changes from 2to3-3.3
rptlab
parents: 3617
diff changeset
   827
    for k,v in initial_dicts.items():
2767
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   828
        d=globals()[k]
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   829
        d.clear()
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   830
        d.update(v)
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   831
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   832
from reportlab.rl_config import register_reset
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   833
register_reset(_reset)
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   834
del register_reset
2ba5a1d26ad0 reportlab: make a85 wrap optional, add _reset to rl_config
rgbecker
parents: 2678
diff changeset
   835
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 678
diff changeset
   836
if __name__=='__main__':
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 817
diff changeset
   837
    test()
1775
acd97501cb9f Fix for Jerome's magic breakages in 1.5.2
rgbecker
parents: 1748
diff changeset
   838
    testStringWidthAlgorithms()