author  rgbecker 
Fri, 12 Apr 2002 22:57:23 +0000  
changeset 1577  ad1dd1f8e061 
parent 1576  e22268b709bd 
child 1578  75fccc4ed46b 
permissions  rwxrxrx 
500  1 

494  2 
#copyright ReportLab Inc. 2000 
3 
#see license.txt for license details 

4 
#history http://cvs.sourceforge.net/cgibin/cvsweb.cgi/reportlab/pdfbase/pdfdoc.py?cvsroot=reportlab 

1577  5 
#$Header: /tmp/reportlab/reportlab/pdfbase/pdfdoc.py,v 1.60 2002/04/12 22:57:23 rgbecker Exp $ 
6 
__version__=''' $Id: pdfdoc.py,v 1.60 2002/04/12 22:57:23 rgbecker Exp $ ''' 

7 
__doc__=""" 

0  8 
The module pdfdoc.py handles the 'outer structure' of PDF documents, ensuring that 
1577  9 
all objects are properly crossreferenced and indexed to the nearest byte. The 
10 
'inner structure'  the page descriptions  are presumed to be generated before 

0  11 
each page is saved. 
12 
pdfgen.py calls this and provides a 'canvas' object to handle page marking operators. 

13 
piddlePDF calls pdfgen and offers a highlevel interface. 

14 

873  15 
The classes within this generally mirror structures in the PDF file 
16 
and are not part of any public interface. Instead, canvas and font 

17 
classes are made available elsewhere for users to manipulate. 

0  18 
""" 
19 

873  20 
import string, types 
21 
from reportlab.pdfbase import pdfutils 

22 
from reportlab.pdfbase.pdfutils import LINEEND # this constant needed in both 

23 
from reportlab import rl_config 

1576  24 
from reportlab.lib.utils import import_zlib, PIL_Image, open_for_read 
873  25 

26 
class PDFError(Exception): 

27 
pass 

28 

0  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) 
1363
92e3fb40a784
Asian fonts now all working in major encodings, and partly documented
andy_robinson
parents:
1317
diff
changeset

31 
LongFormat = 1 
1062  32 
##if LongFormat: (doesn't work) 
33 
## pass 

34 
##else: 

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  46 

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  49 
if not LongFormat: 
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  63 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

64 
def markfilename(filename): 
681  65 
# with the Mac, we need to tag the file in a special 
66 
#way so the system knows it is a PDF file. 

67 
#This supplied by Joe Strout 

68 
import os 

69 
if os.name == 'mac': 

70 
import macfs 

1577  71 
try: 
681  72 
macfs.FSSpec(filename).SetCreatorType('CARO','PDF ') 
73 
except: 

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 

1552  103 
def xObjectName(externalname): 
1560
382bbd1f20ae
revert to older internal name for backward compatibility
rgbecker
parents:
1554
diff
changeset

104 
return "FormXob.%s" % externalname 
1552  105 

591  106 

1062  107 
# no encryption 
108 
class NoEncryption: 

109 
def encode(self, t): 

110 
"encode a string, stream, text" 

111 
return t 

112 
def prepare(self, document): 

113 
# get ready to do encryption 

114 
pass 

115 
def register(self, objnum, version): 

116 
# enter a new direct object 

117 
pass 

118 
def info(self): 

119 
# the representation of self in file if any (should be None or PDFDict) 

120 
return None 

121 

122 
class DummyDoc: 

123 
"used to bypass encryption when required" 

124 
encrypt = NoEncryption() 

1577  125 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

126 
### the global document structure manager 
0  127 

128 
class PDFDocument: 

1062  129 
_ID = None 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

130 
objectcounter = 0 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

131 
inObject = None 
1577  132 
# set this to define filters 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

133 
defaultStreamFilters = None 
1062  134 
encrypt = NoEncryption() # default no encryption 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

135 
pageCounter = 1 
873  136 
def __init__(self, encoding=rl_config.defaultEncoding, dummyoutline=0): 
484  137 
#self.defaultStreamFilters = [PDFBase85Encode, PDFZCompress] # for testing! 
138 
#self.defaultStreamFilters = [PDFZCompress] # for testing! 

502
3a9547186146
Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents:
500
diff
changeset

139 
assert encoding in ['MacRomanEncoding', 
3a9547186146
Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents:
500
diff
changeset

140 
'WinAnsiEncoding', 
3a9547186146
Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents:
500
diff
changeset

141 
'MacRoman', 
3a9547186146
Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents:
500
diff
changeset

142 
'WinAnsi'], 'Unsupported encoding %s' % encoding 
3a9547186146
Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents:
500
diff
changeset

143 
if encoding[8:] <> 'Encoding': 
3a9547186146
Fixed font encoding lookup, metrics for JPython, created test directory
andy_robinson
parents:
500
diff
changeset

144 
encoding = encoding + 'Encoding' 
1577  145 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

146 
self.encoding = encoding 
1062  147 
# signature for creating PDF ID 
148 
import md5, time 

149 
sig = self.signature = md5.new() 

150 
sig.update("a reportlab document") 

151 
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

152 
# 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

153 
self.idToObjectNumberAndVersion = {} 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

154 
# 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

155 
self.idToObject = {} 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

156 
# internal id to file location 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

157 
self.idToOffset = {} 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

158 
# number to id 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

159 
self.numberToId = {} 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

160 
cat = self.Catalog = self._catalog = PDFCatalog() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

161 
pages = self.Pages = PDFPages() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

162 
cat.Pages = pages 
483
c4c3969d1e30
undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents:
482
diff
changeset

163 
if dummyoutline: 
c4c3969d1e30
undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents:
482
diff
changeset

164 
outlines = PDFOutlines0() 
c4c3969d1e30
undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents:
482
diff
changeset

165 
else: 
c4c3969d1e30
undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents:
482
diff
changeset

166 
outlines = PDFOutlines() 
c4c3969d1e30
undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents:
482
diff
changeset

167 
self.Outlines = self.outline = outlines 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

168 
cat.Outlines = outlines 
603  169 
self.info = PDFInfo() 
591  170 
#self.Reference(self.Catalog) 
171 
#self.Reference(self.Info) 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

172 
self.fontMapping = {} 
873  173 
#make an empty font dictionary 
174 
DD = PDFDictionary({}) 

175 
DD.__Comment__ = "The standard fonts dictionary" 

176 
DDR = self.Reference(DD, BasicFonts) 

177 

1062  178 
def updateSignature(self, thing): 
179 
"add information to the signature" 

180 
if self._ID: return # but not if its used already! 

181 
self.signature.update(str(thing)) 

1577  182 

1062  183 
def ID(self): 
184 
if self._ID: 

185 
return self._ID 

186 
digest = self.signature.digest() 

187 
doc = DummyDoc() 

188 
ID = PDFString(digest) 

189 
IDs = ID.format(doc) 

190 
self._ID = "%s %% ReportLab generated PDF document  digest (http://www.reportlab.com) %s [%s %s] %s" % ( 

191 
LINEEND, LINEEND, IDs, IDs, LINEEND) 

192 
return self._ID 

0  193 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

194 
def SaveToFile(self, filename, canvas): 
1062  195 
# add info stuff to signature 
196 
self.info.digest(self.signature) 

197 
### 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

198 
# prepare outline 
591  199 
self.Reference(self.Catalog) 
603  200 
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

201 
outline = self.outline 
c4c3969d1e30
undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents:
482
diff
changeset

202 
outline.prepare(self, canvas) 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

203 
from types import StringType 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

204 
if type(filename) is StringType: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

205 
myfile = 1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

206 
f = open(filename, "wb") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

207 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

208 
myfile = 0 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

209 
f = filename # IT BETTER BE A FILELIKE OBJECT! 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

210 
txt = self.format() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

211 
f.write(txt) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

212 
if myfile: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

213 
f.close() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

214 
markfilename(filename) # do platform specific file junk 
1577  215 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

216 
def inPage(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

217 
"""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

218 
if self.inObject is not None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

219 
if self.inObject=="page": return 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

220 
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

221 
self.inObject = "page" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

222 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

223 
def inForm(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

224 
"""specify that we are in a form xobject (disable page features, etc)""" 
742  225 
# don't need this check anymore since going in a form pushes old context at canvas level. 
226 
#if self.inObject not in ["form", None]: 

227 
# 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

228 
self.inObject = "form" 
1577  229 
# don't need to do anything else, I think... 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

230 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

231 
def getInternalFontName(self, psfontname): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

232 
fm = self.fontMapping 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

233 
if fm.has_key(psfontname): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

234 
return fm[psfontname] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

235 
else: 
873  236 
try: 
237 
# does pdfmetrics know about it? if so, add 

1577  238 
from reportlab.pdfbase import pdfmetrics 
873  239 
fontObj = pdfmetrics.getFont(psfontname) 
1577  240 
fontObj.addObjects(self) 
873  241 
#self.addFont(fontObj) 
242 
return fm[psfontname] 

243 
except KeyError: 

244 
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

245 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

246 
def thisPageName(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

247 
return "Page"+repr(self.pageCounter) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

248 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

249 
def thisPageRef(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

250 
return PDFObjectReference(self.thisPageName()) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

251 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

252 
def addPage(self, page): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

253 
name = self.thisPageName() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

254 
self.Reference(page, name) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

255 
self.Pages.addPage(page) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

256 
self.pageCounter = self.pageCounter+1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

257 
self.inObject = None 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

258 

1577  259 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

260 
def addForm(self, name, form): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

261 
"""add a Form XObject.""" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

262 
# 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

263 
if self.inObject != "form": 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

264 
self.inForm() 
1552  265 
self.Reference(form, xObjectName(name)) 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

266 
self.inObject = None 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

267 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

268 
def annotationName(self, externalname): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

269 
return "Annot.%s"%externalname 
1577  270 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

271 
def addAnnotation(self, name, annotation): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

272 
self.Reference(annotation, self.annotationName(name)) 
1577  273 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

274 
def refAnnotation(self, name): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

275 
internalname = self.annotationName(name) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

276 
return PDFObjectReference(internalname) 
1577  277 

0  278 
def setTitle(self, title): 
279 
"embeds in PDF file" 

280 
self.info.title = title 

1577  281 

0  282 
def setAuthor(self, author): 
283 
"embedded in PDF file" 

284 
self.info.author = author 

1577  285 

0  286 
def setSubject(self, subject): 
287 
"embeds in PDF file" 

288 
self.info.subject = subject 

289 

290 
def getAvailableFonts(self): 

291 
fontnames = self.fontMapping.keys() 

1151
431ef9e78aae
"the 14 std fonts" should always be "available"
aaron_watters
parents:
1063
diff
changeset

292 
# the standard 14 are also always available! (even if not initialized yet) 
431ef9e78aae
"the 14 std fonts" should always be "available"
aaron_watters
parents:
1063
diff
changeset

293 
import _fontdata 
431ef9e78aae
"the 14 std fonts" should always be "available"
aaron_watters
parents:
1063
diff
changeset

294 
for name in _fontdata.standardFonts: 
431ef9e78aae
"the 14 std fonts" should always be "available"
aaron_watters
parents:
1063
diff
changeset

295 
if name not in fontnames: 
431ef9e78aae
"the 14 std fonts" should always be "available"
aaron_watters
parents:
1063
diff
changeset

296 
fontnames.append(name) 
0  297 
fontnames.sort() 
298 
return fontnames 

681  299 

300 

301 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

302 
def format(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

303 
# 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

304 
# (possible infinite loop if there is a bug that continually makes new objects/refs...) 
1062  305 
# Prepare encryption 
306 
self.encrypt.prepare(self) 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

307 
cat = self.Catalog 
603  308 
info = self.info 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

309 
self.Reference(self.Catalog) 
603  310 
self.Reference(self.info) 
1062  311 
# register the encryption dictionary if present 
312 
encryptref = None 

313 
encryptinfo = self.encrypt.info() 

314 
if encryptinfo: 

315 
encryptref = self.Reference(encryptinfo) 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

316 
# 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

317 
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

318 
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

319 
numbertoid = self.numberToId 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

320 
idToNV = self.idToObjectNumberAndVersion 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

321 
idToOb = self.idToObject 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

322 
idToOf = self.idToOffset 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

323 
### 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

324 
done = None 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

325 
File = PDFFile() # output collector 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

326 
while done is None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

327 
counter = counter+1 # do next object... 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

328 
if numbertoid.has_key(counter): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

329 
id = numbertoid[counter] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

330 
#printidToOb 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

331 
obj = idToOb[id] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

332 
IO = PDFIndirectObject(id, obj) 
1062  333 
# register object number and version 
1577  334 
#encrypt.register(id, 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

335 
IOf = IO.format(self) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

336 
# add a comment to the PDF output 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

337 
if DoComments: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

338 
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

339 
offset = File.add(IOf) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

340 
idToOf[id] = offset 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

341 
ids.append(id) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

342 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

343 
done = 1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

344 
# sanity checks (must happen AFTER formatting) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

345 
lno = len(numbertoid) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

346 
if counter1!=lno: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

347 
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

348 
# now add the xref 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

349 
xref = PDFCrossReferenceTable() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

350 
xref.addsection(0, ids) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

351 
xreff = xref.format(self) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

352 
xrefoffset = File.add(xreff) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

353 
# now add the trailer 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

354 
trailer = PDFTrailer( 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

355 
startxref = xrefoffset, 
1309  356 
Size = lno+1, 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

357 
Root = self.Reference(cat), 
1062  358 
Info = self.Reference(info), 
359 
Encrypt = encryptref, 

360 
ID = self.ID(), 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

361 
) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

362 
trailerf = trailer.format(self) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

363 
File.add(trailerf) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

364 
# return string format for pdf file 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

365 
return File.format(self) 
1577  366 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

367 
def hasForm(self, name): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

368 
"""test for existence of named form""" 
1552  369 
internalname = xObjectName(name) 
1395  370 
return self.idToObject.has_key(internalname) 
0  371 

1430  372 
def getFormBBox(self, name): 
373 
"get the declared bounding box of the form as a list" 

1552  374 
internalname = xObjectName(name) 
1430  375 
if self.idToObject.has_key(internalname): 
376 
theform = self.idToObject[internalname] 

377 
if isinstance(theform, PDFFormXObject): 

378 
# internally defined form 

379 
return theform.BBoxList() 

380 
elif isinstance(theform, PDFStream): 

381 
# externally defined form 

382 
return list(theform.dictionary.dict["BBox"].sequence) 

383 
else: 

384 
raise ValueError, "I don't understand the form instance %s" % repr(name) 

385 

1552  386 
def getXObjectName(self, name): 
1395  387 
"""Lets canvas find out what form is called internally. 
388 
Never mind whether it is defined yet or not.""" 

1552  389 
return xObjectName(name) 
1577  390 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

391 
def xobjDict(self, formnames): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

392 
"""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

393 
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

394 
D = {} 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

395 
for name in formnames: 
1552  396 
internalname = xObjectName(name) 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

397 
reference = PDFObjectReference(internalname) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

398 
D[internalname] = reference 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

399 
#print "xobjDict D", D 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

400 
return PDFDictionary(D) 
1577  401 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

402 
def Reference(self, object, name=None): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

403 
### 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

404 
# 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

405 
from types import InstanceType 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

406 
#print"object type is ", type(object) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

407 
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

408 
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

409 
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

410 
(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

411 
return object 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

412 
if hasattr(object, __InternalName__): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

413 
# already registered 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

414 
intname = object.__InternalName__ 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

415 
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

416 
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

417 
repr(intname), repr(name)) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

418 
if not idToObject.has_key(intname): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

419 
raise ValueError, "object named but not registered" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

420 
return PDFObjectReference(intname) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

421 
# otherwise register the new object 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

422 
objectcounter = self.objectcounter = self.objectcounter+1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

423 
if name is None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

424 
name = "R"+repr(objectcounter) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

425 
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

426 
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

427 
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

428 
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

429 
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

430 
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

431 
object.__InternalName__ = name 
591  432 
#print "name", name, "counter", objectcounter 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

433 
self.idToObjectNumberAndVersion[name] = (objectcounter, 0) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

434 
self.numberToId[objectcounter] = name 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

435 
idToObject[name] = object 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

436 
return PDFObjectReference(name) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

437 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

438 
### chapter 4 Objects 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

439 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

440 
PDFtrue = "true" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

441 
PDFfalse = "false" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

442 
PDFnull = "null" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

443 

1062  444 
class PDFText: 
445 
def __init__(self, t): 

446 
self.t = t 

447 
def format(self, document): 

448 
t = self.t 

449 
t = document.encrypt.encode(t) 

450 
L = list(t) 

451 
for i in range(len(L)): 

452 
ch = L[i] 

453 
n = ord(ch) 

454 
h = hex(n) 

455 
h2 = h[2:] # nuke the 0x 

456 
if len(h2)<2: 

457 
h2 = "0"+h2 

458 
L[i] = h2 

459 
result = string.join(L, "") 

460 
return "<%s>" % result 

461 
def __str__(self): 

462 
dummydoc = DummyDoc() 

463 
return self.format(dummydoc) 

1014
ba7f9c1294ea
added missing PDFText() function for consistency (needed by pagecatcher)
aaron_watters
parents:
873
diff
changeset

464 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

465 
def PDFnumber(n): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

466 
return n 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

467 

1062  468 
class PDFString: 
469 
def __init__(self, str): 

470 
# might need to change this to class for encryption 

471 
self.s = str 

472 
def format(self, document): 

473 
s = document.encrypt.encode(self.s) 

474 
return "(%s)" % pdfutils._escape(s) 

475 
def __str__(self): 

476 
return "(%s)" % pdfutils._escape(self.s) 

1577  477 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

478 
def PDFName(data): 
484  479 
# might need to change this to class for encryption 
1062  480 
# 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

481 
# first convert the name 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

482 
ldata = list(data) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

483 
index = 0 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

484 
for thischar in data: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

485 
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

486 
pass # no problemo 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

487 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

488 
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

489 
ldata[index] = "#"+hexord 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

490 
index = index+1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

491 
data = string.join(ldata, "") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

492 
return "/%s" % data 
1577  493 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

494 
class PDFDictionary: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

495 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

496 
multiline = LongFormat 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

497 
def __init__(self, dict=None): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

498 
"""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

499 
if dict is None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

500 
self.dict = {} 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

501 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

502 
self.dict = dict.copy() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

503 
def __setitem__(self, name, value): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

504 
self.dict[name] = value 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

505 
def Reference(name, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

506 
ob = self.dict[name] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

507 
self.dict[name] = document.Reference(ob) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

508 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

509 
dict = self.dict 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

510 
keys = dict.keys() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

511 
keys.sort() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

512 
L = [] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

513 
a = L.append 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

514 
for k in keys: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

515 
v = dict[k] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

516 
fv = format(v, document) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

517 
fk = format(PDFName(k), document) 
681  518 
#a(fk) 
519 
#a(" "+fv) 

520 
a(fk + " " + fv) 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

521 
#L = map(str, L) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

522 
if self.multiline: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

523 
Lj = string.join(L, LINEEND) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

524 
Lj = indent(Lj) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

525 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

526 
Lj = L 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

527 
# break up every 6 elements anyway 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

528 
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

529 
Lj.insert(i,LINEEND) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

530 
Lj = string.join(L, " ") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

531 
return "<< %s >>" % Lj 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

532 

484  533 
# stream filters are objects to support round trip and 
534 
# possibly in the future also support parameters 

535 
class PDFStreamFilterZCompress: 

536 
pdfname = "FlateDecode" 

537 
def encode(self, text): 

674  538 
from reportlab.lib.utils import import_zlib 
539 
zlib = import_zlib() 

540 
if not zlib: raise ImportError, "cannot zcompress zlib unavailable" 

541 
return zlib.compress(text) 

484  542 
def decode(self, encoded): 
674  543 
from reportlab.lib.utils import import_zlib 
544 
zlib = import_zlib() 

545 
if not zlib: raise ImportError, "cannot zdecompress zlib unavailable" 

546 
return zlib.decompress(encoded) 

484  547 

548 
# need only one of these, unless we implement parameters later 

1577  549 
PDFZCompress = PDFStreamFilterZCompress() 
484  550 

551 
class PDFStreamFilterBase85Encode: 

552 
pdfname = "ASCII85Decode" 

553 
def encode(self, text): 

554 
from pdfutils import _AsciiBase85Encode, _wrap 

555 
return _wrap(_AsciiBase85Encode(text)) 

556 
def decode(self, text): 

557 
from pdfutils import _AsciiBase85Decode 

558 
return _AsciiBase85Decode(text) 

1577  559 

484  560 
# need only one of these too 
561 
PDFBase85Encode = PDFStreamFilterBase85Encode() 

562 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

563 
STREAMFMT = ("%(dictionary)s%(LINEEND)s" # dictionary 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

564 
"stream" # stream keyword 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

565 
"%(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

566 
"%(content)s" # the content, with no lineend 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

567 
"endstream%(LINEEND)s" # the endstream keyword 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

568 
) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

569 
class PDFStream: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

570 
'''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

571 
### compression stuff not implemented yet 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

572 
__RefOnly__ = 1 # must be at top level 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

573 
def __init__(self, dictionary=None, content=None): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

574 
if dictionary is None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

575 
dictionary = PDFDictionary() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

576 
self.dictionary = dictionary 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

577 
self.content = content 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

578 
self.filters = None 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

579 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

580 
dictionary = self.dictionary 
591  581 
# copy it for modification 
582 
dictionary = PDFDictionary(dictionary.dict.copy()) 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

583 
content = self.content 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

584 
filters = self.filters 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

585 
if self.content is None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

586 
raise ValueError, "stream content not set" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

587 
if filters is None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

588 
filters = document.defaultStreamFilters 
591  589 
# only apply filters if they haven't been applied elsewhere 
603  590 
if filters is not None and not dictionary.dict.has_key("Filter"): 
484  591 
# apply filters in reverse order listed 
592 
rf = list(filters) 

593 
rf.reverse() 

594 
fnames = [] 

595 
for f in rf: 

596 
#print "*****************content:"; print repr(content[:200]) 

597 
#print "*****************filter", f.pdfname 

598 
content = f.encode(content) 

599 
fnames.insert(0, PDFName(f.pdfname)) 

600 
#print "*****************finally:"; print content[:200] 

601 
#print "****** FILTERS", fnames 

602 
#stop 

603 
dictionary["Filter"] = PDFArray(fnames) 

1062  604 
# "stream encoding is done after all filters have been applied" 
605 
content = document.encrypt.encode(content) 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

606 
fc = format(content, document) 
591  607 
#print "type(content)", type(content), len(content), type(self.dictionary) 
608 
lc = len(content) 

484  609 
#if fc!=content: burp 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

610 
# set dictionary length parameter 
591  611 
dictionary["Length"] = lc 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

612 
fd = format(dictionary, document) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

613 
sdict = LINEENDDICT.copy() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

614 
sdict["dictionary"] = fd 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

615 
sdict["content"] = fc 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

616 
return STREAMFMT % sdict 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

617 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

618 
def teststream(content=None): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

619 
#content = "" # test 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

620 
if content is None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

621 
content = teststreamcontent 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

622 
content = string.strip(content) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

623 
content = string.replace(content, "\n", LINEEND) + LINEEND 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

624 
S = PDFStream() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

625 
S.content = content 
484  626 
S.filters = [PDFBase85Encode, PDFZCompress] 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

627 
# nothing else needed... 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

628 
S.__Comment__ = "test stream" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

629 
return S 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

630 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

631 
teststreamcontent = """ 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

632 
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

633 
1.00 0.00 1.00 rg 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

634 
n 72.00 72.00 432.00 648.00 re B* 
1577  635 
""" 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

636 
class PDFArray: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

637 
multiline = LongFormat 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

638 
def __init__(self, sequence): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

639 
self.sequence = list(sequence) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

640 
def References(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

641 
"""make all objects in sequence references""" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

642 
self.sequence = map(document.Reference, self.sequence) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

643 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

644 
#ssequence = map(str, self.sequence) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

645 
sequence = self.sequence 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

646 
fsequence = [] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

647 
for elt in sequence: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

648 
felt = format(elt, document) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

649 
fsequence.append(felt) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

650 
if self.multiline: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

651 
Lj = string.join(fsequence, LINEEND) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

652 
Lj = indent(Lj) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

653 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

654 
# break up every 10 elements anyway 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

655 
Lj = fsequence 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

656 
breakline = LINEEND+" " 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

657 
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

658 
Lj.insert(i,breakline) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

659 
Lj = string.join(Lj) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

660 
return "[ %s ]" % Lj 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

661 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

662 
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

663 
"%(content)s" "%(LINEEND)s" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

664 
"endobj" "%(LINEEND)s") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

665 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

666 
class PDFIndirectObject: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

667 
__RefOnly__ = 1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

668 
def __init__(self, name, content): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

669 
self.name = name 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

670 
self.content = content 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

671 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

672 
name = self.name 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

673 
(n, v) = document.idToObjectNumberAndVersion[name] 
1062  674 
# set encryption parameters 
675 
document.encrypt.register(n, v) 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

676 
content = self.content 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

677 
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

678 
sdict = LINEENDDICT.copy() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

679 
sdict["n"] = n 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

680 
sdict["v"] = v 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

681 
sdict["content"] = fcontent 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

682 
return INDIRECTOBFMT % sdict 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

683 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

684 
class PDFObjectReference: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

685 
def __init__(self, name): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

686 
self.name = name 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

687 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

688 
name = self.name 
1317
2c0575047463
allow forms to be forward references (to allow table of contents, eg).
aaron_watters
parents:
1309
diff
changeset

689 
try: 
2c0575047463
allow forms to be forward references (to allow table of contents, eg).
aaron_watters
parents:
1309
diff
changeset

690 
(n, v) = document.idToObjectNumberAndVersion[name] 
2c0575047463
allow forms to be forward references (to allow table of contents, eg).
aaron_watters
parents:
1309
diff
changeset

691 
except: 
2c0575047463
allow forms to be forward references (to allow table of contents, eg).
aaron_watters
parents:
1309
diff
changeset

692 
raise KeyError, "forward reference to %s not resolved upon final formatting" % repr(name) 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

693 
return "%s %s R" % (n,v) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

694 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

695 
### chapter 5 
681  696 
# Following Ken Lunde's advice and the PDF spec, this includes 
697 
# some highorder bytes. I chose the characters for Tokyo 

698 
# in ShiftJIS encoding, as these cannot be mistaken for 

699 
# any other encoding, and we'll be able to tell if something 

700 
# has run our PDF files through a dodgy Unicode conversion. 

1063  701 
PDFHeader = ( 
702 
"%PDF1.3"+LINEEND+ 

703 
"%\223\214\213\236 ReportLab Generated PDF document http://www.reportlab.com"+LINEEND) 

0  704 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

705 
class PDFFile: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

706 
### 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

707 
def __init__(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

708 
self.strings = [] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

709 
self.offset = 0 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

710 
self.add(PDFHeader) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

711 
def add(self, s): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

712 
"""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

713 
result = self.offset 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

714 
self.offset = result+len(s) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

715 
self.strings.append(s) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

716 
return result 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

717 
def format(self, document): 
1062  718 
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

719 
return string.join(self.strings, "") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

720 

1577  721 
XREFFMT = '%0.10d %0.5d n' 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

722 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

723 
class PDFCrossReferenceSubsection: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

724 
def __init__(self, firstentrynumber, idsequence): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

725 
self.firstentrynumber = firstentrynumber 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

726 
self.idsequence = idsequence 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

727 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

728 
"""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

729 
firstentrynumber = self.firstentrynumber 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

730 
idsequence = self.idsequence 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

731 
entries = list(idsequence) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

732 
nentries = len(idsequence) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

733 
# 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

734 
taken = {} 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

735 
if firstentrynumber==0: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

736 
taken[0] = "standard free entry" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

737 
nentries = nentries+1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

738 
entries.insert(0, "0000000000 65535 f") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

739 
idToNV = document.idToObjectNumberAndVersion 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

740 
idToOffset = document.idToOffset 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

741 
lastentrynumber = firstentrynumber+nentries1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

742 
for id in idsequence: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

743 
(num, version) = idToNV[id] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

744 
if taken.has_key(num): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

745 
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

746 
if num>lastentrynumber or num<firstentrynumber: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

747 
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

748 
# compute position in list 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

749 
rnum = numfirstentrynumber 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

750 
taken[num] = id 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

751 
offset = idToOffset[id] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

752 
entries[num] = XREFFMT % (offset, version) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

753 
# now add the initial line 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

754 
firstline = "%s %s" % (firstentrynumber, nentries) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

755 
entries.insert(0, firstline) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

756 
# make sure it ends with a LINEEND 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

757 
entries.append("") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

758 
if LINEEND=="\n" or LINEEND=="\r": 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

759 
reflineend = " "+LINEEND # as per spec 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

760 
elif LINEEND=="\r\n": 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

761 
reflineend = LINEEND 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

762 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

763 
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

764 
return string.join(entries, LINEEND) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

765 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

766 
class PDFCrossReferenceTable: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

767 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

768 
def __init__(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

769 
self.sections = [] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

770 
def addsection(self, firstentry, ids): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

771 
section = PDFCrossReferenceSubsection(firstentry, ids) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

772 
self.sections.append(section) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

773 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

774 
sections = self.sections 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

775 
if not sections: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

776 
raise ValueError, "no crossref sections" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

777 
L = ["xref"+LINEEND] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

778 
for s in self.sections: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

779 
fs = format(s, document) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

780 
L.append(fs) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

781 
return string.join(L, "") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

782 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

783 
TRAILERFMT = ("trailer%(LINEEND)s" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

784 
"%(dict)s%(LINEEND)s" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

785 
"startxref%(LINEEND)s" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

786 
"%(startxref)s%(LINEEND)s" 
873  787 
"%(PERCENT)s%(PERCENT)sEOF%(LINEEND)s") 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

788 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

789 
class PDFTrailer: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

790 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

791 
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

792 
self.startxref = startxref 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

793 
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

794 
raise ValueError, "Size and Root keys required" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

795 
dict = self.dict = PDFDictionary() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

796 
for (n,v) in [("Size", Size), ("Prev", Prev), ("Root", Root), 
1062  797 
("Info", Info), ("ID", ID), ("Encrypt", Encrypt)]: 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

798 
if v is not None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

799 
dict[n] = v 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

800 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

801 
fdict = format(self.dict, document) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

802 
D = LINEENDDICT.copy() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

803 
D["dict"] = fdict 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

804 
D["startxref"] = self.startxref 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

805 
return TRAILERFMT % D 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

806 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

807 
#### XXXX skipping incremental update, 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

808 
#### encryption 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

809 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

810 
#### chapter 6, doc structure 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

811 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

812 
class PDFCatalog: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

813 
__Comment__ = "Document Root" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

814 
__RefOnly__ = 1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

815 
# to override, set as attributes 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

816 
__Defaults__ = {"Type": PDFName("Catalog"), 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

817 
"PageMode": PDFName("UseNone"), 
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 
__NoDefault__ = string.split(""" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

820 
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

821 
ViewerPreferences PageLabels PageLayout JavaScript StructTreeRoot SpiderInfo""" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

822 
) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

823 
__Refs__ = __NoDefault__ # make these all into references, if present 
1577  824 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

825 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

826 
self.check_format(document) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

827 
defaults = self.__Defaults__ 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

828 
Refs = self.__Refs__ 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

829 
D = {} 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

830 
for k in defaults.keys(): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

831 
default = defaults[k] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

832 
v = None 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

833 
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

834 
v = getattr(self, k) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

835 
elif default is not None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

836 
v = default 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

837 
if v is not None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

838 
D[k] = v 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

839 
for k in self.__NoDefault__: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

840 
if hasattr(self, k): 
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 
if v is not None: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

843 
D[k] = v 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

844 
# force objects to be references where required 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

845 
for k in Refs: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

846 
if D.has_key(k): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

847 
#print"k is", k, "value", D[k] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

848 
D[k] = document.Reference(D[k]) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

849 
dict = PDFDictionary(D) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

850 
return format(dict, document) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

851 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

852 
def showOutline(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

853 
self.PageMode = PDFName("UseOutlines") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

854 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

855 
def showFullScreen(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

856 
self.PageMode = PDFName("FullScreen") 
1577  857 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

858 
def check_format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

859 
"""for use in subclasses""" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

860 
pass 
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 
# not yet implementing 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

863 
# ViewerPreferences, PageLabelDictionaries, 
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 
class PDFPages(PDFCatalog): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

866 
"""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

867 
__Comment__ = "page tree" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

868 
__RefOnly__ = 1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

869 
# note: could implement page attribute inheritance... 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

870 
__Defaults__ = {"Type": PDFName("Pages"), 
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 
__NoDefault__ = string.split("Kids Count Parent") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

873 
__Refs__ = ["Parent"] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

874 
def __init__(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

875 
self.pages = [] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

876 
def __getitem__(self, item): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

877 
return self.pages[item] 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

878 
def addPage(self, page): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

879 
self.pages.append(page) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

880 
def check_format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

881 
# convert all pages to page references 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

882 
pages = self.pages 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

883 
kids = PDFArray(self.pages) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

884 
# make sure all pages are references 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

885 
kids.References(document) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

886 
self.Kids = kids 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

887 
self.Count = len(pages) 
0  888 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

889 
class PDFPage(PDFCatalog): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

890 
__Comment__ = "Page dictionary" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

891 
# all PDF attributes can be set explicitly 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

892 
# 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

893 
Override_default_compilation = 0 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

894 
__RefOnly__ = 1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

895 
__Defaults__ = {"Type": PDFName("Page"), 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

896 
# "Parent": PDFObjectReference(Pages), # no! use document.Pages 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

897 
} 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

898 
__NoDefault__ = string.split(""" Parent 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

899 
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

900 
PieceInfo LastModified SeparationInfo ArtBox TrimBox BleedBox ID PZ 
500  901 
Trans 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

902 
""") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

903 
__Refs__ = string.split(""" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

904 
Contents Parent ID 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

905 
""") 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

906 
pagewidth = 595 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

907 
pageheight = 842 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

908 
stream = None 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

909 
hasImages = 0 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

910 
compression = 0 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

911 
XObjects = None 
500  912 
Trans = None 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

913 
# transitionstring? 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

914 
# xobjects? 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

915 
# annotations 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

916 
def __init__(self): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

917 
# set all nodefaults to None 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

918 
for name in self.__NoDefault__: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

919 
setattr(self, name, None) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

920 
def setCompression(self, onoff): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

921 
self.compression = onoff 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

922 
def setStream(self, code): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

923 
if self.Override_default_compilation: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

924 
raise ValueError, "overridden! must set stream explicitly" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

925 
from types import ListType 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

926 
if type(code) is ListType: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

927 
code = string.join(code, LINEEND)+LINEEND 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

928 
self.stream = code 
500  929 

930 
def setPageTransition(self, tranDict): 

931 
self.Trans = PDFDictionary(tranDict) 

1577  932 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

933 
def check_format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

934 
# 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

935 
if self.Override_default_compilation: 
1577  936 
return 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

937 
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

938 
if not self.Annots: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

939 
self.Annots = None 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

940 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

941 
#print self.Annots 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

942 
#raise ValueError, "annotations not reimplemented yet" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

943 
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

944 
self.Annots = PDFArray(self.Annots) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

945 
if not self.Contents: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

946 
stream = self.stream 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

947 
if not stream: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

948 
self.Contents = teststream() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

949 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

950 
S = PDFStream() 
484  951 
if self.compression: 
952 
S.filters = [PDFZCompress, PDFBase85Encode] 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

953 
S.content = stream 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

954 
S.__Comment__ = "page stream" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

955 
self.Contents = S 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

956 
if not self.Resources: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

957 
resources = PDFResourceDictionary() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

958 
# fonts! 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

959 
resources.basicFonts() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

960 
if self.hasImages: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

961 
resources.allProcs() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

962 
else: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

963 
resources.basicProcs() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

964 
if self.XObjects: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

965 
#print "XObjects", self.XObjects.dict 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

966 
resources.XObject = self.XObjects 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

967 
self.Resources = resources 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

968 
if not self.Parent: 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

969 
pages = document.Pages 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

970 
self.Parent = document.Reference(pages) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

971 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

972 
def testpage(document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

973 
P = PDFPage() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

974 
P.Contents = teststream() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

975 
pages = document.Pages 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

976 
P.Parent = document.Reference(pages) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

977 
P.MediaBox = PDFArray([0, 0, 595, 841]) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

978 
resources = PDFResourceDictionary() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

979 
resources.allProcs() # enable all procsets 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

980 
resources.basicFonts() 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

981 
P.Resources = resources 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

982 
pages.addPage(P) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

983 

483
c4c3969d1e30
undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents:
482
diff
changeset

984 
#### DUMMY OUTLINES IMPLEMENTATION FOR testing 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

985 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

986 
DUMMYOUTLINE = """ 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

987 
<< 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

988 
/Count 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

989 
0 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

990 
/Type 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

991 
/Outlines 
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 

483
c4c3969d1e30
undid last checkin and added an option for a default outline (different fix)
aaron_watters
parents:
482
diff
changeset

994 
class PDFOutlines0: 
481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

995 
__Comment__ = "TEST OUTLINE!" 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

996 
text = string.replace(DUMMYOUTLINE, "\n", LINEEND) 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

997 
__RefOnly__ = 1 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

998 
def format(self, document): 
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

999 
return self.text 
1577  1000 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

1001 

136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

1002 
class OutlineEntryObject: 
681  1003 
"an entry in an outline" 
1004 
Title = Dest = Parent = Prev = Next = First = Last = Count = None 

1005 
def format(self, document): 

1006 
D = {} 

1007 
D["Title"] = PDFString(self.Title) 

1008 
D["Parent"] = self.Parent 

1009 
D["Dest"] = self.Dest 

1010 
for n in ("Prev", "Next", "First", "Last", "Count"): 

1011 
v = getattr(self, n) 

1012 
if v is not None: 

1013 
D[n] = v 

1014 
PD = PDFDictionary(D) 

1015 
return PD.format(document) 

0  1016 

1017 

481
136669babedf
complete revision of pdfdoc. Not finished (compression missing, testing needed)
aaron_watters
parents:
479
diff
changeset

1018 
class PDFOutlines: 
681  1019 
"""takes a recursive list of outline destinations 
1020 
like 

1021 
out = PDFOutline1() 

1022 
out.setNames(canvas, # requires canvas for name resolution 

1023 
"chapter1dest", 

1024 
("chapter2dest", 

1025 
["chapter2section1dest", 

1026 
"chapter2section2dest", 

1027 
"chapter2conclusiondest"] 

1028 
), # end of chapter2 description 

1029 
"chapter3dest", 

1030 
("chapter4dest", ["c4s1", "c4s2"]) 

1031 
) 

1032 
Higher layers may build this structure incrementally. KISS at base level. 

1033 
""" 

1034 
# first attempt, many possible features missing. 

1035 
#no init for now 

1036 
mydestinations = ready = None 

1037 
counter = 0 

1038 
currentlevel = 1 # ie, no levels yet 

1577  1039 

681  1040 
def __init__(self): 
1041 
self.destinationnamestotitles = {} 

1042 
self.destinationstotitles = {} 

1043 
self.levelstack = [] 

1044 
self.buildtree = [] 

1045 
self.closedict = {} # dictionary of "closed" destinations in the outline 

0  1046 

681  1047 
def addOutlineEntry(self, destinationname, level=0, title=None, closed=None): 
1048 
"""destinationname of None means "close the tree" """ 

1049 
from types import IntType, TupleType 

1050 
if destinationname is None and level!=0: 

1051 
raise ValueError, "close tree must have level of 0" 

1052 
if type(level) is not IntType: raise ValueError, "level must be integer, got %s" % type(level) 

1053 
if level<0: raise ValueError, "negative levels not allowed" 

1054 
if title is None: title = destinationname 

1055 
currentlevel = self.currentlevel 

1056 
stack = self.levelstack 

1057 
tree = self.buildtree 

1058 
# adjust currentlevel and stack to match level 

1059 
if level>currentlevel: 

1060 
if level>currentlevel+1: 

1061 
raise ValueError, "can't jump from outline level %s to level %s, need intermediates" %(currentlevel, level) 

1062 
level = currentlevel = currentlevel+1 

1063 
stack.append([]) 

1064 
while level<currentlevel: 

1065 
# pop off levels to match 

1066 
current = stack[1] 

1067 
del stack[1] 

1068 
previous = stack[1] 

1069 
lastinprevious = previous[1] 

1070 
if type(lastinprevious) is TupleType: 

1071 
(name, sectionlist) = lastinprevious 

1072 
raise ValueError, "cannot reset existing sections: " + repr(lastinprevious) 

1073 
else: 

1074 
name = lastinprevious 

1075 
sectionlist = current 

1076 
previous[1] = (name, sectionlist) 

1077 
#sectionlist.append(current) 

1078 
currentlevel = currentlevel1 

1079 
if destinationname is None: return 

1080 
stack[1].append(destinationname) 

1081 
self.destinationnamestotitles[destinationname] = title 

1082 
if closed: self.closedict[destinationname] = 1 

1083 
self.currentlevel = level 

1577  1084 

681  1085 
def setDestinations(self, destinationtree): 
1086 
self.mydestinations = destinationtree 

1577  1087 

681  1088 
def format(self, document): 
1089 
D = {} 

1090 
D["Type"] = PDFName("Outlines") 

1091 
c = self.count 

1092 
D["Count"] = c 

1093 
if c!=0: 

1094 
D["First"] = self.first 

1095 
D["Last"] = self.last 

1096 
PD = PDFDictionary(D) 

1097 
return PD.format(document) 

1577  1098 

681  1099 
def setNames(self, canvas, *nametree): 
1100 
desttree = self.translateNames(canvas, nametree) 

1101 
self.setDestinations(desttree) 

1577  1102 

681  1103 
def setNameList(self, canvas, nametree): 
1104 
"Explicit list so I don't need to do apply(...) in the caller" 

1105 
desttree = self.translateNames(canvas, nametree) 

1106 
self.setDestinations(desttree) 

1577  1107 

681  1108 
def translateNames(self, canvas, object): 
1109 
"recursively translate tree of names into tree of destinations" 

1110 
from types import StringType, ListType, TupleType 

1111 
Ot = type(object) 

1112 
destinationnamestotitles = self.destinationnamestotitles 

1113 
destinationstotitles = self.destinationstotitles 

1114 
closedict = self.closedict 

1115 
if Ot is StringType: 

1116 
destination = canvas._bookmarkReference(object) 

1117 
title = object 

1118 
if destinationnamestotitles.has_key(object): 

1119 
title = destinationnamestotitles[object] 

1120 
else: 

1121 
destinationnamestotitles[title] = title 

1122 
destinationstotitles[destination] = title 

1123 
if closedict.has_key(object): 

1124 
closedict[destination] = 1 # mark destination closed 

1125 
return {object: canvas._bookmarkReference(object)} # name>ref 

1126 
if Ot is ListType or Ot is TupleType: 

1127 
L = [] 

1128 
for o in object: 

1129 
L.append(self.translateNames(canvas, o)) 

1130 
if Ot is TupleType: 

1131 
return tuple(L) 

1132 
return L 

1133 
raise "in outline, destination name must be string: got a %s" % Ot 

0  1134 

681  1135 
def prepare(self, document, canvas): 
1136 
"""prepare all data structures required for save operation (create related objects)""" 

1137 
if self.mydestinations is None: 

1138 
if self.levelstack: 

1139 
self.addOutlineEntry(None) # close the tree 

1140 
destnames = self.levelstack[0] 

1141 
#from pprint import pprint; pprint(destnames); stop 

1142 
self.mydestinations = self.translateNames(canvas, destnames) 

1143 
else: 

1144 
self.first = self.last = None 

1145 
self.count = 0 

1146 
self.ready = 1 

1147 
return 

1148 
#self.first = document.objectReference("Outline.First") 

1149 
#self.last = document.objectReference("Outline.Last") 

1150 
# XXXX this needs to be generalized for closed entries! 

1151 
self.count = count(self.mydestinations, self.closedict) 

1152 
(self.first, self.last) = self.maketree(document, self.mydestinations, toplevel=1) 

1153 
self.ready = 1 

0  1154 

681  1155 
def maketree(self, document, destinationtree, Parent=None, toplevel=0): 
1156 
from types import ListType, TupleType, DictType 

1157 
tdestinationtree = type(destinationtree) 

1158 
if toplevel: 

1159 
levelname = "Outline" 

1160 
Parent = document.Reference(document.Outlines) 

1161 
else: 

1162 
self.count = self.count+1 

1163 
levelname = "Outline.%s" % self.count 

1164 
if Parent is None: 

1165 
raise ValueError, "nontop level outline elt parent must be specified" 

1166 
if tdestinationtree is not ListType and tdestinationtree is not TupleType: 

1167 
raise ValueError, "destinationtree must be list or tuple, got %s" 

1168 
nelts = len(destinationtree) 

1169 
lastindex = nelts1 

1170 
lastelt = firstref = lastref = None 

1171 
destinationnamestotitles = self.destinationnamestotitles 

1172 
closedict = self.closedict 

1173 
for index in range(nelts): 

1174 
eltobj = OutlineEntryObject() 

1175 
eltobj.Parent = Parent 

1176 
eltname = "%s.%s" % (levelname, index) 

1177 
eltref = document.Reference(eltobj, eltname) 

1178 
#document.add(eltname, eltobj) 

1179 
if lastelt is not None: 

1180 
lastelt.Next = eltref 

1181 
eltobj.Prev = lastref 

1182 
if firstref is None: 

1183 
firstref = eltref 

1184 
lastref = eltref 

1185 
lastelt = eltobj # advance eltobj 

1186 
lastref = eltref 

1187 
elt = destinationtree[index] 

1188 
te = type(elt) 

1189 
if te is DictType: 

1190 
# simple leaf {name: dest} 

1191 
leafdict = elt 

1192 
elif te is TupleType: 

1193 
# leaf with subsections: ({name: ref}, subsections) XXXX should clean up (see count(...)) 

1194 
try: 

1195 
(leafdict, subsections) = elt 

1196 
except: 

1197 
raise ValueError, "destination tree elt tuple should have two elts, got %s" % len(elt) 

1198 
eltobj.Count = count(subsections, closedict) 

1199 
(eltobj.First, eltobj.Last) = self.maketree(document, subsections, eltref) 

