reportlab/pdfbase/pdfdoc.py
author aaron_watters
Tue, 10 Jul 2001 00:14:04 +0000
changeset 1062 c6dec1c5a962
parent 1014 ba7f9c1294ea
child 1063 378a0f553608
permissions -rwxr-xr-x
extensions to support encryption plugins
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
500
58d712fef651 Fixed page transitions; extended Pythonpoint
andy_robinson
parents: 494
diff changeset
     1
494
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 484
diff changeset
     2
#copyright ReportLab Inc. 2000
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 484
diff changeset
     3
#see license.txt for license details
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 484
diff changeset
     4
#history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/pdfbase/pdfdoc.py?cvsroot=reportlab
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
     5
#$Header: /tmp/reportlab/reportlab/pdfbase/pdfdoc.py,v 1.46 2001/07/10 00:14:04 aaron_watters Exp $
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
     6
__version__=''' $Id: pdfdoc.py,v 1.46 2001/07/10 00:14:04 aaron_watters Exp $ '''
16
f9c7525619fb Docstring & other fixes
rgbecker
parents: 10
diff changeset
     7
__doc__=""" 
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
     8
The module pdfdoc.py handles the 'outer structure' of PDF documents, ensuring that
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
     9
all objects are properly cross-referenced and indexed to the nearest byte.  The 
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    10
'inner structure' - the page descriptions - are presumed to be generated before 
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    11
each page is saved.
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    12
pdfgen.py calls this and provides a 'canvas' object to handle page marking operators.
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    13
piddlePDF calls pdfgen and offers a high-level interface.
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    14
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    15
The classes within this generally mirror structures in the PDF file
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    16
and are not part of any public interface.  Instead, canvas and font
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    17
classes are made available elsewhere for users to manipulate.
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    18
"""
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    19
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    20
import string, types
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    21
from reportlab.pdfbase import pdfutils
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    22
from reportlab.pdfbase.pdfutils import LINEEND   # this constant needed in both
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    23
from reportlab import rl_config
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    24
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    25
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    26
class PDFError(Exception):
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    27
    pass
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
    28
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    29
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    30
# set this flag to get more vertical whitespace (and larger files)
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
    31
LongFormat = 0
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
    32
##if LongFormat: (doesn't work)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
    33
##    pass
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
    34
##else:
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
    35
##    LINEEND = "\n" # no wasteful carriage returns!
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    36
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    37
# __InternalName__ is a special attribute that can only be set by the Document arbitrator
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    38
__InternalName__ = "__InternalName__"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    39
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    40
# __RefOnly__ marks reference only elements that must be formatted on top level
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    41
__RefOnly__ = "__RefOnly__"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    42
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    43
# __Comment__ provides a (one line) comment to inline with an object ref, if present
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    44
#   if it is more than one line then percentize it...
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    45
__Comment__ = "__Comment__"
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
    46
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
    47
# If DoComments is set then add helpful (space wasting) comment lines to PDF files
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    48
DoComments = 1
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
    49
if not LongFormat:
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
    50
    DoComments = 0
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    51
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    52
# name for standard font dictionary
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    53
BasicFonts = "BasicFonts"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    54
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    55
# name for the pages object
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    56
Pages = "Pages"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    57
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    58
### generic utilities
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    59
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    60
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    61
# for % substitutions
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    62
LINEENDDICT = {"LINEEND": LINEEND, "PERCENT": "%"}
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
    63
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    64
def markfilename(filename):
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    65
    # with the Mac, we need to tag the file in a special
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    66
    #way so the system knows it is a PDF file.
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    67
    #This supplied by Joe Strout
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    68
    import os
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    69
    if os.name == 'mac':
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    70
        import macfs
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    71
        try: 
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    72
            macfs.FSSpec(filename).SetCreatorType('CARO','PDF ')
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    73
        except:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
    74
            pass
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    75
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    76
def format(element, document, toplevel=0):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    77
    """Indirection step for formatting.
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    78
       Ensures that document parameters alter behaviour
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    79
       of formatting for all elements.
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    80
    """
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    81
    from types import InstanceType
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    82
    if type(element) is InstanceType:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    83
        if not toplevel and hasattr(element, __RefOnly__):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    84
            # the object cannot be a component at non top level.
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    85
            # make a reference to it and return it's format
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    86
            R = document.Reference(element)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    87
            return R.format(document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    88
        else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    89
            try:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    90
                fmt = element.format
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    91
            except:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    92
                raise AttributeError, "%s has no format operation" % element
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    93
            f = fmt(document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    94
            if DoComments and hasattr(element, __Comment__):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    95
                f = "%s%s%s%s" % ("% ", element.__Comment__, LINEEND, f)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    96
            return f
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    97
    else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    98
        return str(element)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
    99
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   100
def indent(s, IND=LINEEND+" "):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   101
    return string.replace(s, LINEEND, IND)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   102
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   103
def formName(externalname):
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   104
    return "FormXob.%s" % externalname
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   105
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   106
# no encryption
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   107
class NoEncryption:
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   108
    def encode(self, t):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   109
        "encode a string, stream, text"
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   110
        return t
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   111
    def prepare(self, document):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   112
        # get ready to do encryption
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   113
        pass
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   114
    def register(self, objnum, version):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   115
        # enter a new direct object
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   116
        pass
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   117
    def info(self):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   118
        # the representation of self in file if any (should be None or PDFDict)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   119
        return None
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   120
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   121
class DummyDoc:
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   122
    "used to bypass encryption when required"
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   123
    encrypt = NoEncryption()
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   124
    
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   125
### the global document structure manager
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   126
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   127
class PDFDocument:
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   128
    _ID = None
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   129
    objectcounter = 0
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   130
    inObject = None
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   131
    # set this to define filters 
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   132
    defaultStreamFilters = None
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   133
    encrypt = NoEncryption() # default no encryption
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   134
    pageCounter = 1
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   135
    def __init__(self, encoding=rl_config.defaultEncoding, dummyoutline=0):
484
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   136
        #self.defaultStreamFilters = [PDFBase85Encode, PDFZCompress] # for testing!
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   137
        #self.defaultStreamFilters = [PDFZCompress] # for testing!
502
3a9547186146 Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents: 500
diff changeset
   138
        assert encoding in ['MacRomanEncoding',
3a9547186146 Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents: 500
diff changeset
   139
                            'WinAnsiEncoding',
3a9547186146 Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents: 500
diff changeset
   140
                            'MacRoman',
3a9547186146 Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents: 500
diff changeset
   141
                            'WinAnsi'], 'Unsupported encoding %s' % encoding
3a9547186146 Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents: 500
diff changeset
   142
        if encoding[-8:] <> 'Encoding':
3a9547186146 Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents: 500
diff changeset
   143
            encoding = encoding + 'Encoding'
3a9547186146 Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents: 500
diff changeset
   144
            
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   145
        self.encoding = encoding
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   146
        # signature for creating PDF ID
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   147
        import md5, time
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   148
        sig = self.signature = md5.new()
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   149
        sig.update("a reportlab document")
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   150
        sig.update(repr(time.time())) # initialize with timestamp digest
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   151
        # mapping of internal identifier ("Page001") to PDF objectnumber and generation number (34, 0)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   152
        self.idToObjectNumberAndVersion = {}
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   153
        # mapping of internal identifier ("Page001") to PDF object (PDFPage instance)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   154
        self.idToObject = {}
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   155
        # internal id to file location
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   156
        self.idToOffset = {}
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   157
        # number to id
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   158
        self.numberToId = {}
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   159
        cat = self.Catalog = self._catalog = PDFCatalog()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   160
        pages = self.Pages = PDFPages()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   161
        cat.Pages = pages
483
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
   162
        if dummyoutline:
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
   163
            outlines = PDFOutlines0()
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
   164
        else:
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
   165
            outlines = PDFOutlines()
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
   166
        self.Outlines = self.outline = outlines
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   167
        cat.Outlines = outlines
603
a6f460e53b00 forms in forms now work
aaron_watters
parents: 595
diff changeset
   168
        self.info = PDFInfo()
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   169
        #self.Reference(self.Catalog)
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   170
        #self.Reference(self.Info)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   171
        self.fontMapping = {}
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   172
        #make an empty font dictionary
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   173
        DD = PDFDictionary({})
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   174
        DD.__Comment__ = "The standard fonts dictionary"
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   175
        DDR = self.Reference(DD, BasicFonts)
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   176
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   177
    def updateSignature(self, thing):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   178
        "add information to the signature"
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   179
        if self._ID: return # but not if its used already!
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   180
        self.signature.update(str(thing))
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   181
        
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   182
    def ID(self):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   183
        if self._ID:
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   184
            return self._ID
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   185
        digest = self.signature.digest()
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   186
        doc = DummyDoc()
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   187
        ID = PDFString(digest)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   188
        IDs = ID.format(doc)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   189
        self._ID = "%s %% ReportLab generated PDF document -- digest (http://www.reportlab.com) %s [%s %s] %s" % (
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   190
            LINEEND, LINEEND, IDs, IDs, LINEEND)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   191
        return self._ID
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   192
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   193
    def SaveToFile(self, filename, canvas):
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   194
        # add info stuff to signature
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   195
        self.info.digest(self.signature)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   196
        ### later: maybe add more info to sig?
483
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
   197
        # prepare outline
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   198
        self.Reference(self.Catalog)
603
a6f460e53b00 forms in forms now work
aaron_watters
parents: 595
diff changeset
   199
        self.Reference(self.info)
483
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
   200
        outline = self.outline
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
   201
        outline.prepare(self, canvas)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   202
        from types import StringType
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   203
        if type(filename) is StringType:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   204
            myfile = 1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   205
            f = open(filename, "wb")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   206
        else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   207
            myfile = 0
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   208
            f = filename # IT BETTER BE A FILE-LIKE OBJECT!
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   209
        txt = self.format()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   210
        f.write(txt)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   211
        if myfile:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   212
            f.close()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   213
            markfilename(filename) # do platform specific file junk
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   214
        
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   215
    def inPage(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   216
        """specify the current object as a page (enables reference binding and other page features)"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   217
        if self.inObject is not None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   218
            if self.inObject=="page": return
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   219
            raise ValueError, "can't go in page already in object %s" % self.inObject
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   220
        self.inObject = "page"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   221
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   222
    def inForm(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   223
        """specify that we are in a form xobject (disable page features, etc)"""
742
df72775fc33d fixed minor bug in forms handling
aaron_watters
parents: 724
diff changeset
   224
        # don't need this check anymore since going in a form pushes old context at canvas level.
df72775fc33d fixed minor bug in forms handling
aaron_watters
parents: 724
diff changeset
   225
        #if self.inObject not in ["form", None]:
df72775fc33d fixed minor bug in forms handling
aaron_watters
parents: 724
diff changeset
   226
        #    raise ValueError, "can't go in form already in object %s" % self.inObject
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   227
        self.inObject = "form"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   228
        # don't need to do anything else, I think...        
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   229
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   230
    def getInternalFontName(self, psfontname):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   231
        fm = self.fontMapping
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   232
        if fm.has_key(psfontname):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   233
            return fm[psfontname]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   234
        else:
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   235
            try:
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   236
                # does pdfmetrics know about it? if so, add
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   237
                from reportlab.pdfbase import pdfmetrics                
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   238
                fontObj = pdfmetrics.getFont(psfontname)
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   239
                fontObj.addObjects(self) 
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   240
                #self.addFont(fontObj)
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   241
                return fm[psfontname]
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   242
            except KeyError:
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   243
                raise PDFError, "Font %s not known!" % repr(psfontname)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   244
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   245
    def thisPageName(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   246
        return "Page"+repr(self.pageCounter)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   247
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   248
    def thisPageRef(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   249
        return PDFObjectReference(self.thisPageName())
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   250
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   251
    def addPage(self, page):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   252
        name = self.thisPageName()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   253
        self.Reference(page, name)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   254
        self.Pages.addPage(page)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   255
        self.pageCounter = self.pageCounter+1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   256
        self.inObject = None
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   257
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   258
    #def formName(self, externalname):  # made externally available
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   259
    #    return "FormXob.%s" % externalname
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   260
    
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   261
    def addForm(self, name, form):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   262
        """add a Form XObject."""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   263
        # XXX should check that name is a legal PDF name
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   264
        if self.inObject != "form":
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   265
            self.inForm()
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   266
        self.Reference(form, formName(name))
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   267
        self.inObject = None
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   268
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   269
    def annotationName(self, externalname):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   270
        return "Annot.%s"%externalname
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   271
    
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   272
    def addAnnotation(self, name, annotation):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   273
        self.Reference(annotation, self.annotationName(name))
53
e624c027a5d6 Added forms, destinations, linkages and other features
aaron_watters
parents: 47
diff changeset
   274
        
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   275
    def refAnnotation(self, name):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   276
        internalname = self.annotationName(name)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   277
        return PDFObjectReference(internalname)
53
e624c027a5d6 Added forms, destinations, linkages and other features
aaron_watters
parents: 47
diff changeset
   278
        
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   279
    def setTitle(self, title):
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   280
        "embeds in PDF file"
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   281
        self.info.title = title
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   282
        
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   283
    def setAuthor(self, author):
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   284
        "embedded in PDF file"
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   285
        self.info.author = author
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   286
            
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   287
    def setSubject(self, subject):
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   288
        "embeds in PDF file"
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   289
        self.info.subject = subject
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   290
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   291
    def getAvailableFonts(self):
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   292
        fontnames = self.fontMapping.keys()
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   293
        fontnames.sort()
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   294
        return fontnames
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   295
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   296
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   297
    def addFont(self, userFont):
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   298
        """Add a new font object to the document."""
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   299
        #UGLY ALERT - not O-O, should find a cleaner way to locate
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   300
        #the right font class.
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   301
        from reportlab.pdfbase import pdfmetrics        
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   302
        internalName = 'F' + repr(len(self.fontMapping)+1)
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   303
        if isinstance(userFont, pdfmetrics.Font):
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   304
            # construct a Type 1 Font internal object
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   305
            pdfFont = PDFType1Font()
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   306
            pdfFont.Name = internalName
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   307
            pdfFont.BaseFont = userFont.face.name
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   308
            pdfFont.__Comment__ = 'Font %s' % userFont.name
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   309
            if type(userFont.encoding) is types.StringType:
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   310
                pdfFont.Encoding = PDFName(userFont.encoding)
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   311
            else:
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   312
                enc = makePDFEncoding(userFont.encoding)
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   313
                pdfFont.Encoding = enc
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   314
        elif isinstance(userFont, pdfmetrics.EmbeddedType1Font):
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   315
            
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   316
            pass
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   317
        # now link it in
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   318
        ref = self.Reference(pdfFont, internalName)
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   319
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   320
        # also refer to it in the BasicFonts dictionary
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   321
        fontDict = self.idToObject['BasicFonts'].dict
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   322
        fontDict[internalName] = pdfFont
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   323
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   324
        # and in the font mappings
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   325
        self.fontMapping[userFont.name] = '/' + internalName
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   326
        #print 'Font.addObjects called for %s -> %s' % (self.name, internalName)
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   327
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   328
    def format(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   329
        # register the Catalog/INfo and then format the objects one by one until exhausted
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   330
        # (possible infinite loop if there is a bug that continually makes new objects/refs...)
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   331
        # Prepare encryption
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   332
        self.encrypt.prepare(self)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   333
        cat = self.Catalog
603
a6f460e53b00 forms in forms now work
aaron_watters
parents: 595
diff changeset
   334
        info = self.info
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   335
        self.Reference(self.Catalog)
603
a6f460e53b00 forms in forms now work
aaron_watters
parents: 595
diff changeset
   336
        self.Reference(self.info)
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   337
        # register the encryption dictionary if present
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   338
        encryptref = None
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   339
        encryptinfo = self.encrypt.info()
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   340
        if encryptinfo:
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   341
            encryptref = self.Reference(encryptinfo)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   342
        # make std fonts (this could be made optional
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   343
        counter = 0 # start at first object (object 1 after preincrement)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   344
        ids = [] # the collection of object ids in object number order
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   345
        numbertoid = self.numberToId
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   346
        idToNV = self.idToObjectNumberAndVersion
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   347
        idToOb = self.idToObject
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   348
        idToOf = self.idToOffset
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   349
        ### note that new entries may be "appended" DURING FORMATTING
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   350
        done = None
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   351
        File = PDFFile() # output collector
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   352
        while done is None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   353
            counter = counter+1 # do next object...
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   354
            if numbertoid.has_key(counter):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   355
                id = numbertoid[counter]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   356
                #printidToOb
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   357
                obj = idToOb[id]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   358
                IO = PDFIndirectObject(id, obj)
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   359
                # register object number and version
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   360
                #encrypt.register(id, 
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   361
                IOf = IO.format(self)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   362
                # add a comment to the PDF output
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   363
                if DoComments:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   364
                    File.add("%% %s %s %s" % (repr(id), repr(repr(obj)[:50]), LINEEND))
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   365
                offset = File.add(IOf)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   366
                idToOf[id] = offset
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   367
                ids.append(id)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   368
            else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   369
                done = 1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   370
        # sanity checks (must happen AFTER formatting)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   371
        lno = len(numbertoid)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   372
        if counter-1!=lno:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   373
            raise ValueError, "counter %s doesn't match number to id dictionary %s" %(counter, lno)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   374
        # now add the xref
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   375
        xref = PDFCrossReferenceTable()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   376
        xref.addsection(0, ids)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   377
        xreff = xref.format(self)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   378
        xrefoffset = File.add(xreff)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   379
        # now add the trailer
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   380
        trailer = PDFTrailer(
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   381
            startxref = xrefoffset,
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   382
            Size = lno,
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   383
            Root = self.Reference(cat),
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   384
            Info = self.Reference(info),
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   385
            Encrypt = encryptref,
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   386
            ID = self.ID(),
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   387
            )
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   388
        trailerf = trailer.format(self)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   389
        File.add(trailerf)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   390
        # return string format for pdf file
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   391
        return File.format(self)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   392
    
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   393
    def hasForm(self, name):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   394
        """test for existence of named form"""
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   395
        internalname = formName(name)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   396
        try:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   397
            test = self.idToObject[internalname]          
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   398
        except:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   399
            return 0
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   400
        else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   401
            return internalname
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   402
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   403
    def xobjDict(self, formnames):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   404
        """construct an xobject dict (for inclusion in a resource dict, usually)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   405
           from a list of form names (images not yet supported)"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   406
        D = {}
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   407
        for name in formnames:
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   408
            internalname = formName(name)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   409
            reference = PDFObjectReference(internalname)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   410
            D[internalname] = reference
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   411
        #print "xobjDict D", D
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   412
        return PDFDictionary(D)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   413
        
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   414
    def Reference(self, object, name=None):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   415
        ### note references may "grow" during the final formatting pass: don't use d.keys()!
628
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   416
        # don't make references to other references, or non instances, unless they are named!
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   417
        from types import InstanceType
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   418
        #print"object type is ", type(object)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   419
        tob = type(object)
628
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   420
        idToObject = self.idToObject
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   421
        if name is None and (
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   422
            (tob is not InstanceType) or (tob is InstanceType and object.__class__ is PDFObjectReference)):
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   423
            return object
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   424
        if hasattr(object, __InternalName__):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   425
            # already registered
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   426
            intname = object.__InternalName__
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   427
            if name is not None and name!=intname:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   428
                raise ValueError, "attempt to reregister object %s with new name %s" % (
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   429
                    repr(intname), repr(name))
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   430
            if not idToObject.has_key(intname):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   431
                raise ValueError, "object named but not registered"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   432
            return PDFObjectReference(intname)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   433
        # otherwise register the new object
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   434
        objectcounter = self.objectcounter = self.objectcounter+1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   435
        if name is None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   436
            name = "R"+repr(objectcounter)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   437
        if idToObject.has_key(name):
628
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   438
            other = idToObject[name]
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   439
            if other!=object:
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   440
                raise ValueError, "redefining named object: "+repr(name)
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   441
            return PDFObjectReference(name)
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   442
        if tob is InstanceType:
7f5cd20a02f1 very subtle bug that is only hit by pagecatcher: indirect references to integers now work.
aaron_watters
parents: 603
diff changeset
   443
            object.__InternalName__ = name
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   444
        #print "name", name, "counter", objectcounter
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   445
        self.idToObjectNumberAndVersion[name] = (objectcounter, 0)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   446
        self.numberToId[objectcounter] = name
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   447
        idToObject[name] = object
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   448
        return PDFObjectReference(name)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   449
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   450
### chapter 4 Objects
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   451
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   452
PDFtrue = "true"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   453
PDFfalse = "false"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   454
PDFnull = "null"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   455
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   456
class PDFText:
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   457
    def __init__(self, t):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   458
        self.t = t
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   459
    def format(self, document):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   460
        t = self.t
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   461
        t = document.encrypt.encode(t)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   462
        L = list(t)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   463
        for i in range(len(L)):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   464
            ch = L[i]
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   465
            n = ord(ch)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   466
            h = hex(n)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   467
            h2 = h[2:] # nuke the 0x
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   468
            if len(h2)<2:
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   469
                h2 = "0"+h2
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   470
            L[i] = h2
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   471
        result = string.join(L, "")
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   472
        return "<%s>" % result
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   473
    def __str__(self):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   474
        dummydoc = DummyDoc()
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   475
        return self.format(dummydoc)
1014
ba7f9c1294ea added missing PDFText() function for consistency (needed by pagecatcher)
aaron_watters
parents: 873
diff changeset
   476
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   477
def PDFnumber(n):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   478
    return n
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   479
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   480
class PDFString:
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   481
    def __init__(self, str):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   482
        # might need to change this to class for encryption
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   483
        self.s = str
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   484
    def format(self, document):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   485
        s = document.encrypt.encode(self.s)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   486
        return "(%s)" % pdfutils._escape(s)
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   487
    def __str__(self):
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   488
        return "(%s)" % pdfutils._escape(self.s)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   489
    
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   490
def PDFName(data):
484
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   491
    # might need to change this to class for encryption
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   492
    #  NOTE: RESULT MUST ALWAYS SUPPORT MEANINGFUL COMPARISONS (EQUALITY) AND HASH
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   493
    # first convert the name
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   494
    ldata = list(data)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   495
    index = 0
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   496
    for thischar in data:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   497
        if 0x21<=ord(thischar)<=0x7e and thischar not in "%()<>{}[]#":
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   498
            pass # no problemo
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   499
        else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   500
            hexord = hex(ord(thischar))[2:] # forget the 0x thing...
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   501
            ldata[index] = "#"+hexord
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   502
        index = index+1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   503
    data = string.join(ldata, "")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   504
    return "/%s" % data
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   505
    
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   506
class PDFDictionary:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   507
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   508
    multiline = LongFormat
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   509
    def __init__(self, dict=None):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   510
        """dict should be namestring to value eg "a": 122 NOT pdfname to value NOT "/a":122"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   511
        if dict is None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   512
            self.dict = {}
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   513
        else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   514
            self.dict = dict.copy()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   515
    def __setitem__(self, name, value):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   516
        self.dict[name] = value
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   517
    def Reference(name, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   518
        ob = self.dict[name]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   519
        self.dict[name] = document.Reference(ob)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   520
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   521
        dict = self.dict
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   522
        keys = dict.keys()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   523
        keys.sort()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   524
        L = []
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   525
        a = L.append
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   526
        for k in keys:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   527
            v = dict[k]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   528
            fv = format(v, document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   529
            fk = format(PDFName(k), document)
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   530
            #a(fk)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   531
            #a(" "+fv)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   532
            a(fk + " " + fv)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   533
        #L = map(str, L)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   534
        if self.multiline:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   535
            Lj = string.join(L, LINEEND)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   536
            Lj = indent(Lj)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   537
        else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   538
            Lj = L
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   539
            # break up every 6 elements anyway
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   540
            for i in range(6, len(Lj), 6):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   541
                Lj.insert(i,LINEEND)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   542
            Lj = string.join(L, " ")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   543
        return "<< %s >>" % Lj
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   544
484
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   545
# stream filters are objects to support round trip and
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   546
# possibly in the future also support parameters
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   547
class PDFStreamFilterZCompress:
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   548
    pdfname = "FlateDecode"
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   549
    def encode(self, text):
674
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 628
diff changeset
   550
        from reportlab.lib.utils import import_zlib
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 628
diff changeset
   551
        zlib = import_zlib()
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 628
diff changeset
   552
        if not zlib: raise ImportError, "cannot z-compress zlib unavailable"
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 628
diff changeset
   553
        return zlib.compress(text)
484
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   554
    def decode(self, encoded):
674
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 628
diff changeset
   555
        from reportlab.lib.utils import import_zlib
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 628
diff changeset
   556
        zlib = import_zlib()
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 628
diff changeset
   557
        if not zlib: raise ImportError, "cannot z-decompress zlib unavailable"
c25a9dbfc27a Improved ImportError handling
rgbecker
parents: 628
diff changeset
   558
        return zlib.decompress(encoded)
484
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   559
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   560
# need only one of these, unless we implement parameters later
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   561
PDFZCompress = PDFStreamFilterZCompress()    
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   562
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   563
class PDFStreamFilterBase85Encode:
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   564
    pdfname = "ASCII85Decode"
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   565
    def encode(self, text):
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   566
        from pdfutils import _AsciiBase85Encode, _wrap
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   567
        return _wrap(_AsciiBase85Encode(text))
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   568
    def decode(self, text):
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   569
        from pdfutils import _AsciiBase85Decode
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   570
        return _AsciiBase85Decode(text)
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   571
    
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   572
# need only one of these too
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   573
PDFBase85Encode = PDFStreamFilterBase85Encode()
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   574
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   575
STREAMFMT = ("%(dictionary)s%(LINEEND)s" # dictionary
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   576
             "stream" # stream keyword
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   577
             "%(LINEEND)s" # a line end (could be just a \n)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   578
             "%(content)s" # the content, with no lineend
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   579
             "endstream%(LINEEND)s" # the endstream keyword
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   580
             )
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   581
class PDFStream:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   582
    '''set dictionary elements explicitly stream.dictionary[name]=value'''
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   583
    ### compression stuff not implemented yet
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   584
    __RefOnly__ = 1 # must be at top level
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   585
    def __init__(self, dictionary=None, content=None):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   586
        if dictionary is None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   587
            dictionary = PDFDictionary()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   588
        self.dictionary = dictionary
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   589
        self.content = content
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   590
        self.filters = None
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   591
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   592
        dictionary = self.dictionary
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   593
        # copy it for modification
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   594
        dictionary = PDFDictionary(dictionary.dict.copy())
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   595
        content = self.content
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   596
        filters = self.filters
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   597
        if self.content is None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   598
            raise ValueError, "stream content not set"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   599
        if filters is None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   600
            filters = document.defaultStreamFilters
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   601
        # only apply filters if they haven't been applied elsewhere
603
a6f460e53b00 forms in forms now work
aaron_watters
parents: 595
diff changeset
   602
        if filters is not None and not dictionary.dict.has_key("Filter"):
484
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   603
            # apply filters in reverse order listed
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   604
            rf = list(filters)
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   605
            rf.reverse()
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   606
            fnames = []
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   607
            for f in rf:
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   608
                #print "*****************content:"; print repr(content[:200])
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   609
                #print "*****************filter", f.pdfname
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   610
                content = f.encode(content)
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   611
                fnames.insert(0, PDFName(f.pdfname))
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   612
            #print "*****************finally:"; print content[:200]
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   613
            #print "****** FILTERS", fnames
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   614
            #stop
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   615
            dictionary["Filter"] = PDFArray(fnames)
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   616
        # "stream encoding is done after all filters have been applied"
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   617
        content = document.encrypt.encode(content)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   618
        fc = format(content, document)
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   619
        #print "type(content)", type(content), len(content), type(self.dictionary)
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   620
        lc = len(content)
484
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   621
        #if fc!=content: burp
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   622
        # set dictionary length parameter
591
8ab476fd7d96 minor changes to support pdfparse
aaron_watters
parents: 504
diff changeset
   623
        dictionary["Length"] = lc
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   624
        fd = format(dictionary, document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   625
        sdict = LINEENDDICT.copy()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   626
        sdict["dictionary"] = fd
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   627
        sdict["content"] = fc
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   628
        return STREAMFMT % sdict
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   629
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   630
def teststream(content=None):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   631
    #content = "" # test
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   632
    if content is None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   633
        content = teststreamcontent
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   634
    content = string.strip(content)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   635
    content = string.replace(content, "\n", LINEEND) + LINEEND
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   636
    S = PDFStream()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   637
    S.content = content
484
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   638
    S.filters = [PDFBase85Encode, PDFZCompress]
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   639
    # nothing else needed...
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   640
    S.__Comment__ = "test stream"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   641
    return S
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   642
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   643
teststreamcontent = """
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   644
1 0 0 1 0 0 cm BT /F9 12 Tf 14.4 TL ET
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   645
1.00 0.00 1.00 rg
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   646
n 72.00 72.00 432.00 648.00 re B*
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   647
"""       
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   648
class PDFArray:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   649
    multiline = LongFormat
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   650
    def __init__(self, sequence):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   651
        self.sequence = list(sequence)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   652
    def References(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   653
        """make all objects in sequence references"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   654
        self.sequence = map(document.Reference, self.sequence)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   655
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   656
        #ssequence = map(str, self.sequence)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   657
        sequence = self.sequence
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   658
        fsequence = []
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   659
        for elt in sequence:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   660
            felt = format(elt, document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   661
            fsequence.append(felt)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   662
        if self.multiline:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   663
            Lj = string.join(fsequence, LINEEND)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   664
            Lj = indent(Lj)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   665
        else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   666
            # break up every 10 elements anyway
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   667
            Lj = fsequence
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   668
            breakline = LINEEND+" "
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   669
            for i in range(10, len(Lj), 10):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   670
                Lj.insert(i,breakline)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   671
            Lj = string.join(Lj)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   672
        return "[ %s ]" % Lj
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   673
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   674
INDIRECTOBFMT = ("%(n)s %(v)s obj%(LINEEND)s"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   675
                 "%(content)s" "%(LINEEND)s"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   676
                 "endobj" "%(LINEEND)s")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   677
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   678
class PDFIndirectObject:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   679
    __RefOnly__ = 1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   680
    def __init__(self, name, content):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   681
        self.name = name
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   682
        self.content = content
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   683
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   684
        name = self.name
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   685
        (n, v) = document.idToObjectNumberAndVersion[name]
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   686
        # set encryption parameters
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   687
        document.encrypt.register(n, v)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   688
        content = self.content
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   689
        fcontent = format(content, document, toplevel=1) # yes this is at top level
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   690
        sdict = LINEENDDICT.copy()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   691
        sdict["n"] = n
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   692
        sdict["v"] = v
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   693
        sdict["content"] = fcontent
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   694
        return INDIRECTOBFMT % sdict
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   695
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   696
class PDFObjectReference:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   697
    def __init__(self, name):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   698
        self.name = name
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   699
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   700
        name = self.name
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   701
        (n, v) = document.idToObjectNumberAndVersion[name]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   702
        return "%s %s R" % (n,v)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   703
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   704
### chapter 5
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   705
# Following Ken Lunde's advice and the PDF spec, this includes
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   706
# some high-order bytes.  I chose the characters for Tokyo
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   707
# in Shift-JIS encoding, as these cannot be mistaken for
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   708
# any other encoding, and we'll be able to tell if something
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   709
# has run our PDF files through a dodgy Unicode conversion.
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
   710
PDFHeader = ("%PDF-1.3"+LINEEND+"%\223\214\213\236"+LINEEND)
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   711
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   712
class PDFFile:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   713
    ### just accumulates strings: keeps track of current offset
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   714
    def __init__(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   715
        self.strings = []
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   716
        self.offset = 0
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   717
        self.add(PDFHeader)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   718
    def add(self, s):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   719
        """should be constructed as late as possible, return position where placed"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   720
        result = self.offset
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   721
        self.offset = result+len(s)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   722
        self.strings.append(s)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   723
        return result
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   724
    def format(self, document):
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   725
        strings = map(str, self.strings) # final conversion, in case of lazy objects
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   726
        return string.join(self.strings, "")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   727
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   728
XREFFMT = '%0.10d %0.5d n'    
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   729
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   730
class PDFCrossReferenceSubsection:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   731
    def __init__(self, firstentrynumber, idsequence):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   732
        self.firstentrynumber = firstentrynumber
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   733
        self.idsequence = idsequence
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   734
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   735
        """id sequence should represent contiguous object nums else error. free numbers not supported (yet)"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   736
        firstentrynumber = self.firstentrynumber
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   737
        idsequence = self.idsequence
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   738
        entries = list(idsequence)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   739
        nentries = len(idsequence)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   740
        # special case: object number 0 is always free
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   741
        taken = {}
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   742
        if firstentrynumber==0:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   743
            taken[0] = "standard free entry"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   744
            nentries = nentries+1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   745
            entries.insert(0, "0000000000 65535 f")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   746
        idToNV = document.idToObjectNumberAndVersion
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   747
        idToOffset = document.idToOffset
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   748
        lastentrynumber = firstentrynumber+nentries-1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   749
        for id in idsequence:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   750
            (num, version) = idToNV[id]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   751
            if taken.has_key(num):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   752
                raise ValueError, "object number collision %s %s %s" % (num, repr(id), repr(taken[id]))
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   753
            if num>lastentrynumber or num<firstentrynumber:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   754
                raise ValueError, "object number %s not in range %s..%s" % (num, firstentrynumber, lastentrynumber)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   755
            # compute position in list
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   756
            rnum = num-firstentrynumber
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   757
            taken[num] = id
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   758
            offset = idToOffset[id]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   759
            entries[num] = XREFFMT % (offset, version)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   760
        # now add the initial line
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   761
        firstline = "%s %s" % (firstentrynumber, nentries)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   762
        entries.insert(0, firstline)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   763
        # make sure it ends with a LINEEND
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   764
        entries.append("")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   765
        if LINEEND=="\n" or LINEEND=="\r":
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   766
            reflineend = " "+LINEEND # as per spec
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   767
        elif LINEEND=="\r\n":
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   768
            reflineend = LINEEND
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   769
        else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   770
            raise ValueError, "bad end of line! %s" % repr(LINEEND)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   771
        return string.join(entries, LINEEND)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   772
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   773
class PDFCrossReferenceTable:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   774
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   775
    def __init__(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   776
        self.sections = []
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   777
    def addsection(self, firstentry, ids):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   778
        section = PDFCrossReferenceSubsection(firstentry, ids)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   779
        self.sections.append(section)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   780
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   781
        sections = self.sections
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   782
        if not sections:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   783
            raise ValueError, "no crossref sections"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   784
        L = ["xref"+LINEEND]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   785
        for s in self.sections:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   786
            fs = format(s, document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   787
            L.append(fs)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   788
        return string.join(L, "")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   789
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   790
TRAILERFMT = ("trailer%(LINEEND)s"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   791
              "%(dict)s%(LINEEND)s"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   792
              "startxref%(LINEEND)s"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   793
              "%(startxref)s%(LINEEND)s"
873
62ba1388703d New font embedding stuff.
rgbecker
parents: 742
diff changeset
   794
              "%(PERCENT)s%(PERCENT)sEOF%(LINEEND)s")
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   795
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   796
class PDFTrailer:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   797
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   798
    def __init__(self, startxref, Size=None, Prev=None, Root=None, Info=None, ID=None, Encrypt=None):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   799
        self.startxref = startxref
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   800
        if Size is None or Root is None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   801
            raise ValueError, "Size and Root keys required"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   802
        dict = self.dict = PDFDictionary()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   803
        for (n,v) in [("Size", Size), ("Prev", Prev), ("Root", Root),
1062
c6dec1c5a962 extensions to support encryption plugins
aaron_watters
parents: 1014
diff changeset
   804
                      ("Info", Info), ("ID", ID), ("Encrypt", Encrypt)]:
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   805
            if v is not None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   806
                dict[n] = v
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   807
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   808
        fdict = format(self.dict, document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   809
        D = LINEENDDICT.copy()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   810
        D["dict"] = fdict
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   811
        D["startxref"] = self.startxref
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   812
        return TRAILERFMT % D
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   813
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   814
#### XXXX skipping incremental update,
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   815
#### encryption
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   816
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   817
#### chapter 6, doc structure
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   818
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   819
class PDFCatalog:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   820
    __Comment__ = "Document Root"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   821
    __RefOnly__ = 1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   822
    # to override, set as attributes
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   823
    __Defaults__ = {"Type": PDFName("Catalog"),
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   824
                "PageMode": PDFName("UseNone"),
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   825
                }
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   826
    __NoDefault__ = string.split("""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   827
        Dests Outlines Pages Threads AcroForm Names OpenActions PageMode URI
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   828
        ViewerPreferences PageLabels PageLayout JavaScript StructTreeRoot SpiderInfo"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   829
                                 )
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   830
    __Refs__ = __NoDefault__ # make these all into references, if present
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   831
    
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   832
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   833
        self.check_format(document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   834
        defaults = self.__Defaults__
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   835
        Refs = self.__Refs__
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   836
        D = {}
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   837
        for k in defaults.keys():
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   838
            default = defaults[k]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   839
            v = None
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   840
            if hasattr(self, k) and getattr(self,k) is not None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   841
                v = getattr(self, k)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   842
            elif default is not None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   843
                v = default
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   844
            if v is not None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   845
                D[k] = v
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   846
        for k in self.__NoDefault__:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   847
            if hasattr(self, k):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   848
                v = getattr(self,k)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   849
                if v is not None:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   850
                    D[k] = v
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   851
        # force objects to be references where required
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   852
        for k in Refs:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   853
            if D.has_key(k):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   854
                #print"k is", k, "value", D[k]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   855
                D[k] = document.Reference(D[k])
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   856
        dict = PDFDictionary(D)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   857
        return format(dict, document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   858
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   859
    def showOutline(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   860
        self.PageMode = PDFName("UseOutlines")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   861
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   862
    def showFullScreen(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   863
        self.PageMode = PDFName("FullScreen")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   864
        
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   865
    def check_format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   866
        """for use in subclasses"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   867
        pass
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   868
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   869
# not yet implementing
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   870
#  ViewerPreferences, PageLabelDictionaries,
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   871
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   872
class PDFPages(PDFCatalog):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   873
    """PAGES TREE WITH ONE INTERNAL NODE, FOR "BALANCING" CHANGE IMPLEMENATION"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   874
    __Comment__ = "page tree"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   875
    __RefOnly__ = 1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   876
    # note: could implement page attribute inheritance...
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   877
    __Defaults__ = {"Type": PDFName("Pages"),
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   878
                    }
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   879
    __NoDefault__ = string.split("Kids Count Parent")
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   880
    __Refs__ = ["Parent"]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   881
    def __init__(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   882
        self.pages = []
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   883
    def __getitem__(self, item):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   884
        return self.pages[item]
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   885
    def addPage(self, page):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   886
        self.pages.append(page)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   887
    def check_format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   888
        # convert all pages to page references
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   889
        pages = self.pages
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   890
        kids = PDFArray(self.pages)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   891
        # make sure all pages are references
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   892
        kids.References(document)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   893
        self.Kids = kids
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   894
        self.Count = len(pages)
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
   895
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   896
class PDFPage(PDFCatalog):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   897
    __Comment__ = "Page dictionary"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   898
    # all PDF attributes can be set explicitly
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   899
    # if this flag is set, the "usual" behavior will be suppressed
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   900
    Override_default_compilation = 0
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   901
    __RefOnly__ = 1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   902
    __Defaults__ = {"Type": PDFName("Page"),
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   903
                   # "Parent": PDFObjectReference(Pages),  # no! use document.Pages
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   904
                    }
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   905
    __NoDefault__ = string.split(""" Parent
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   906
        MediaBox Resources Contents CropBox Rotate Thumb Annots B Dur Hid Trans AA
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   907
        PieceInfo LastModified SeparationInfo ArtBox TrimBox BleedBox ID PZ
500
58d712fef651 Fixed page transitions; extended Pythonpoint
andy_robinson
parents: 494
diff changeset
   908
        Trans
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   909
    """)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   910
    __Refs__ = string.split("""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   911
        Contents Parent ID
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   912
    """)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   913
    pagewidth = 595
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   914
    pageheight = 842
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   915
    stream = None
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   916
    hasImages = 0
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   917
    compression = 0
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   918
    XObjects = None
500
58d712fef651 Fixed page transitions; extended Pythonpoint
andy_robinson
parents: 494
diff changeset
   919
    Trans = None
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   920
    # transitionstring?
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   921
    # xobjects?
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   922
    # annotations
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   923
    def __init__(self):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   924
        # set all nodefaults to None
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   925
        for name in self.__NoDefault__:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   926
            setattr(self, name, None)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   927
    def setCompression(self, onoff):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   928
        self.compression = onoff
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   929
    def setStream(self, code):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   930
        if self.Override_default_compilation:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   931
            raise ValueError, "overridden! must set stream explicitly"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   932
        from types import ListType
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   933
        if type(code) is ListType:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   934
            code = string.join(code, LINEEND)+LINEEND
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   935
        self.stream = code
500
58d712fef651 Fixed page transitions; extended Pythonpoint
andy_robinson
parents: 494
diff changeset
   936
58d712fef651 Fixed page transitions; extended Pythonpoint
andy_robinson
parents: 494
diff changeset
   937
    def setPageTransition(self, tranDict):
58d712fef651 Fixed page transitions; extended Pythonpoint
andy_robinson
parents: 494
diff changeset
   938
        self.Trans = PDFDictionary(tranDict)
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   939
        
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   940
    def check_format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   941
        # set up parameters unless usual behaviour is suppressed
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   942
        if self.Override_default_compilation:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   943
            return   
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   944
        self.MediaBox = self.MediaBox or PDFArray([0, 0, self.pagewidth, self.pageheight])
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   945
        if not self.Annots:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   946
            self.Annots = None
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   947
        else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   948
            #print self.Annots
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   949
            #raise ValueError, "annotations not reimplemented yet"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   950
            if type(self.Annots) is not types.InstanceType:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   951
                self.Annots = PDFArray(self.Annots)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   952
        if not self.Contents:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   953
            stream = self.stream
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   954
            if not stream:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   955
                self.Contents = teststream()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   956
            else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   957
                S = PDFStream()
484
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   958
                if self.compression:
cc20a344973c Aaron's latest update from the newslist
rgbecker
parents: 483
diff changeset
   959
                    S.filters = [PDFZCompress, PDFBase85Encode]
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   960
                S.content = stream
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   961
                S.__Comment__ = "page stream"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   962
                self.Contents = S
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   963
        if not self.Resources:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   964
            resources = PDFResourceDictionary()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   965
            # fonts!
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   966
            resources.basicFonts()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   967
            if self.hasImages:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   968
                resources.allProcs()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   969
            else:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   970
                resources.basicProcs()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   971
            if self.XObjects:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   972
                #print "XObjects", self.XObjects.dict
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   973
                resources.XObject = self.XObjects
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   974
            self.Resources = resources
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   975
        if not self.Parent:
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   976
            pages = document.Pages
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   977
            self.Parent = document.Reference(pages)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   978
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   979
def testpage(document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   980
    P = PDFPage()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   981
    P.Contents = teststream()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   982
    pages = document.Pages
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   983
    P.Parent = document.Reference(pages)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   984
    P.MediaBox = PDFArray([0, 0, 595, 841])
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   985
    resources = PDFResourceDictionary()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   986
    resources.allProcs() # enable all procsets
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   987
    resources.basicFonts()
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   988
    P.Resources = resources
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   989
    pages.addPage(P)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   990
483
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
   991
#### DUMMY OUTLINES IMPLEMENTATION FOR testing
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   992
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   993
DUMMYOUTLINE = """
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   994
<<
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   995
  /Count
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   996
      0
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   997
  /Type
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   998
      /Outlines
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
   999
>>"""
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
  1000
483
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
  1001
class PDFOutlines0:
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
  1002
    __Comment__ = "TEST OUTLINE!"
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
  1003
    text = string.replace(DUMMYOUTLINE, "\n", LINEEND)
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
  1004
    __RefOnly__ = 1
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
  1005
    def format(self, document):
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
  1006
        return self.text
483
c4c3969d1e30 undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents: 482
diff changeset
  1007
        
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
  1008
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
  1009
class OutlineEntryObject:
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1010
    "an entry in an outline"
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1011
    Title = Dest = Parent = Prev = Next = First = Last = Count = None
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1012
    def format(self, document):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1013
        D = {}
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1014
        D["Title"] = PDFString(self.Title)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1015
        D["Parent"] = self.Parent
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1016
        D["Dest"] = self.Dest
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1017
        for n in ("Prev", "Next", "First", "Last", "Count"):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1018
            v = getattr(self, n)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1019
            if v is not None:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1020
                D[n] = v
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1021
        PD = PDFDictionary(D)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1022
        return PD.format(document)
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
  1023
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
  1024
481
136669babedf complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents: 479
diff changeset
  1025
class PDFOutlines:
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1026
    """takes a recursive list of outline destinations
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1027
       like
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1028
           out = PDFOutline1()
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1029
           out.setNames(canvas, # requires canvas for name resolution
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1030
             "chapter1dest",
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1031
             ("chapter2dest",
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1032
              ["chapter2section1dest",
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1033
               "chapter2section2dest",
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1034
               "chapter2conclusiondest"]
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1035
             ), # end of chapter2 description
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1036
             "chapter3dest",
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1037
             ("chapter4dest", ["c4s1", "c4s2"])
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1038
             )
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1039
       Higher layers may build this structure incrementally. KISS at base level.
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1040
    """
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1041
    # first attempt, many possible features missing.
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1042
    #no init for now
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1043
    mydestinations = ready = None
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1044
    counter = 0
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1045
    currentlevel = -1 # ie, no levels yet
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1046
    
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1047
    def __init__(self):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1048
        self.destinationnamestotitles = {}
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1049
        self.destinationstotitles = {}
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1050
        self.levelstack = []
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1051
        self.buildtree = []
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1052
        self.closedict = {} # dictionary of "closed" destinations in the outline
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
  1053
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1054
    def addOutlineEntry(self, destinationname, level=0, title=None, closed=None):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1055
        """destinationname of None means "close the tree" """
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1056
        from types import IntType, TupleType
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1057
        if destinationname is None and level!=0:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1058
            raise ValueError, "close tree must have level of 0"
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1059
        if type(level) is not IntType: raise ValueError, "level must be integer, got %s" % type(level)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1060
        if level<0: raise ValueError, "negative levels not allowed"
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1061
        if title is None: title = destinationname
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1062
        currentlevel = self.currentlevel
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1063
        stack = self.levelstack
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1064
        tree = self.buildtree
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1065
        # adjust currentlevel and stack to match level
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1066
        if level>currentlevel:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1067
            if level>currentlevel+1:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1068
                raise ValueError, "can't jump from outline level %s to level %s, need intermediates" %(currentlevel, level)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1069
            level = currentlevel = currentlevel+1
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1070
            stack.append([])
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1071
        while level<currentlevel:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1072
            # pop off levels to match
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1073
            current = stack[-1]
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1074
            del stack[-1]
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1075
            previous = stack[-1]
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1076
            lastinprevious = previous[-1]
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1077
            if type(lastinprevious) is TupleType:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1078
                (name, sectionlist) = lastinprevious
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1079
                raise ValueError, "cannot reset existing sections: " + repr(lastinprevious)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1080
            else:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1081
                name = lastinprevious
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1082
                sectionlist = current
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1083
                previous[-1] = (name, sectionlist)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1084
            #sectionlist.append(current)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1085
            currentlevel = currentlevel-1
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1086
        if destinationname is None: return
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1087
        stack[-1].append(destinationname)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1088
        self.destinationnamestotitles[destinationname] = title
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1089
        if closed: self.closedict[destinationname] = 1
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1090
        self.currentlevel = level
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1091
        
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1092
    def setDestinations(self, destinationtree):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1093
        self.mydestinations = destinationtree
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1094
        
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1095
    def format(self, document):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1096
        D = {}
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1097
        D["Type"] = PDFName("Outlines")
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1098
        c = self.count
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1099
        D["Count"] = c
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1100
        if c!=0:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1101
            D["First"] = self.first
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1102
            D["Last"] = self.last
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1103
        PD = PDFDictionary(D)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1104
        return PD.format(document)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1105
        
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1106
    def setNames(self, canvas, *nametree):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1107
        desttree = self.translateNames(canvas, nametree)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1108
        self.setDestinations(desttree)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1109
        
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1110
    def setNameList(self, canvas, nametree):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1111
        "Explicit list so I don't need to do apply(...) in the caller"
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1112
        desttree = self.translateNames(canvas, nametree)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1113
        self.setDestinations(desttree)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1114
        
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1115
    def translateNames(self, canvas, object):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1116
        "recursively translate tree of names into tree of destinations"
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1117
        from types import StringType, ListType, TupleType
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1118
        Ot = type(object)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1119
        destinationnamestotitles = self.destinationnamestotitles
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1120
        destinationstotitles = self.destinationstotitles
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1121
        closedict = self.closedict
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1122
        if Ot is StringType:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1123
            destination = canvas._bookmarkReference(object)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1124
            title = object
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1125
            if destinationnamestotitles.has_key(object):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1126
                title = destinationnamestotitles[object]
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1127
            else:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1128
                destinationnamestotitles[title] = title
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1129
            destinationstotitles[destination] = title
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1130
            if closedict.has_key(object):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1131
                closedict[destination] = 1 # mark destination closed
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1132
            return {object: canvas._bookmarkReference(object)} # name-->ref
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1133
        if Ot is ListType or Ot is TupleType:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1134
            L = []
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1135
            for o in object:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1136
                L.append(self.translateNames(canvas, o))
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1137
            if Ot is TupleType:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1138
                return tuple(L)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1139
            return L
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1140
        raise "in outline, destination name must be string: got a %s" % Ot
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
  1141
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1142
    def prepare(self, document, canvas):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1143
        """prepare all data structures required for save operation (create related objects)"""
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1144
        if self.mydestinations is None:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1145
            if self.levelstack:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1146
                self.addOutlineEntry(None) # close the tree
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1147
                destnames = self.levelstack[0]
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1148
                #from pprint import pprint; pprint(destnames); stop
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1149
                self.mydestinations = self.translateNames(canvas, destnames)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1150
            else:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1151
                self.first = self.last = None
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1152
                self.count = 0
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1153
                self.ready = 1
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1154
                return
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1155
        #self.first = document.objectReference("Outline.First")
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1156
        #self.last = document.objectReference("Outline.Last")
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1157
        # XXXX this needs to be generalized for closed entries!
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1158
        self.count = count(self.mydestinations, self.closedict)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1159
        (self.first, self.last) = self.maketree(document, self.mydestinations, toplevel=1)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1160
        self.ready = 1
0
f19e0a2433ab Initial revision
gmcm
parents:
diff changeset
  1161
681
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1162
    def maketree(self, document, destinationtree, Parent=None, toplevel=0):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1163
        from types import ListType, TupleType, DictType
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1164
        tdestinationtree = type(destinationtree)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1165
        if toplevel:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1166
            levelname = "Outline"
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1167
            Parent = document.Reference(document.Outlines)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1168
        else:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1169
            self.count = self.count+1
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1170
            levelname = "Outline.%s" % self.count
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1171
            if Parent is None:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1172
                raise ValueError, "non-top level outline elt parent must be specified"
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1173
        if tdestinationtree is not ListType and tdestinationtree is not TupleType:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1174
            raise ValueError, "destinationtree must be list or tuple, got %s"
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1175
        nelts = len(destinationtree)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1176
        lastindex = nelts-1
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1177
        lastelt = firstref = lastref = None
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1178
        destinationnamestotitles = self.destinationnamestotitles
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1179
        closedict = self.closedict
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1180
        for index in range(nelts):
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1181
            eltobj = OutlineEntryObject()
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1182
            eltobj.Parent = Parent
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1183
            eltname = "%s.%s" % (levelname, index)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1184
            eltref = document.Reference(eltobj, eltname)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1185
            #document.add(eltname, eltobj)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1186
            if lastelt is not None:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1187
                lastelt.Next = eltref
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1188
                eltobj.Prev = lastref
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1189
            if firstref is None:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1190
                firstref = eltref
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1191
            lastref = eltref
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1192
            lastelt = eltobj # advance eltobj
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1193
            lastref = eltref
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1194
            elt = destinationtree[index]
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1195
            te = type(elt)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1196
            if te is DictType:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1197
                # simple leaf {name: dest}
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1198
                leafdict = elt
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1199
            elif te is TupleType:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1200
                # leaf with subsections: ({name: ref}, subsections) XXXX should clean up (see count(...))
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1201
                try:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1202
                    (leafdict, subsections) = elt
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1203
                except:
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1204
                    raise ValueError, "destination tree elt tuple should have two elts, got %s" % len(elt)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1205
                eltobj.Count = count(subsections, closedict)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1206
                (eltobj.First, eltobj.Last) = self.maketree(document, subsections, eltref)
934a4f24ea5d Added explicit font and encoding support
andy_robinson
parents: 674
diff changeset
  1207
            else: