QScintilla/Exporters/ExporterPDF.py

changeset 429
dcc623c99907
parent 25
5163e6f94ba5
child 535
4b00d7336e19
equal deleted inserted replaced
428:58405c24aa09 429:dcc623c99907
72 Public method to write the data to the file. 72 Public method to write the data to the file.
73 73
74 @param objectData data to be written (integer or string) 74 @param objectData data to be written (integer or string)
75 """ 75 """
76 if isinstance(objectData, int): 76 if isinstance(objectData, int):
77 self.file.write("%d" % objectData) 77 self.file.write("{0:d}".format(objectData))
78 else: 78 else:
79 self.file.write(objectData) 79 self.file.write(objectData)
80 80
81 def add(self, objectData): 81 def add(self, objectData):
82 """ 82 """
106 # a xref entry *must* be 20 bytes long (PDF1.4Ref(p64)) 106 # a xref entry *must* be 20 bytes long (PDF1.4Ref(p64))
107 # so extra space added; also the first entry is special 107 # so extra space added; also the first entry is special
108 self.write("\n0000000000 65535 f \n") 108 self.write("\n0000000000 65535 f \n")
109 ind = 0 109 ind = 0
110 while ind < len(self.offsetList): 110 while ind < len(self.offsetList):
111 self.write("%010d 00000 n \n" % self.offsetList[ind]) 111 self.write("{0:010d} 00000 n \n".format(self.offsetList[ind]))
112 ind += 1 112 ind += 1
113 return xrefStart 113 return xrefStart
114 114
115 class PDFRender(object): 115 class PDFRender(object):
116 """ 116 """
168 168
169 buf = "" 169 buf = ""
170 if styleNext != self.styleCurrent or style_ == -1: 170 if styleNext != self.styleCurrent or style_ == -1:
171 if self.style[self.styleCurrent].font != self.style[styleNext].font or \ 171 if self.style[self.styleCurrent].font != self.style[styleNext].font or \
172 style_ == -1: 172 style_ == -1:
173 buf += "/F%d %d Tf " % (self.style[styleNext].font + 1, self.fontSize) 173 buf += "/F{0:d} {1:d} Tf ".format(self.style[styleNext].font + 1,
174 self.fontSize)
174 if self.style[self.styleCurrent].fore != self.style[styleNext].fore or \ 175 if self.style[self.styleCurrent].fore != self.style[styleNext].fore or \
175 style_ == -1: 176 style_ == -1:
176 buf += "%srg " % self.style[styleNext].fore 177 buf += "{0}rg ".format(self.style[styleNext].fore)
177 return buf 178 return buf
178 179
179 def startPDF(self): 180 def startPDF(self):
180 """ 181 """
181 Public method to start the PDF document. 182 Public method to start the PDF document.
204 # build objects for font resources; note that font objects are 205 # build objects for font resources; note that font objects are
205 # *expected* to start from index 1 since they are the first objects 206 # *expected* to start from index 1 since they are the first objects
206 # to be inserted (PDF1.4Ref(p317)) 207 # to be inserted (PDF1.4Ref(p317))
207 for i in range(4): 208 for i in range(4):
208 buffer = \ 209 buffer = \
209 "<</Type/Font/Subtype/Type1/Name/F%d/BaseFont/%s/Encoding/%s>>\n" % \ 210 "<</Type/Font/Subtype/Type1/Name/F{0:d}/BaseFont/{1}/Encoding/{2}>>\n"\
210 (i + 1, PDFfontNames[self.fontSet * 4 + i], PDF_ENCODING) 211 .format(i + 1, PDFfontNames[self.fontSet * 4 + i], PDF_ENCODING)
211 self.oT.add(buffer) 212 self.oT.add(buffer)
212 213
213 self.pageContentStart = self.oT.index 214 self.pageContentStart = self.oT.index
214 215
215 def endPDF(self): 216 def endPDF(self):
227 # create all the page objects (PDF1.4Ref(p88)) 228 # create all the page objects (PDF1.4Ref(p88))
228 # forward reference pages object; calculate its object number 229 # forward reference pages object; calculate its object number
229 pageObjectStart = self.oT.index 230 pageObjectStart = self.oT.index
230 pagesRef = pageObjectStart + self.pageCount 231 pagesRef = pageObjectStart + self.pageCount
231 for i in range(self.pageCount): 232 for i in range(self.pageCount):
232 buffer = "<</Type/Page/Parent %d 0 R\n" \ 233 buffer = "<</Type/Page/Parent {0:d} 0 R\n" \
233 "/MediaBox[ 0 0 %d %d]\n" \ 234 "/MediaBox[ 0 0 {1:d} {2:d}]\n" \
234 "/Contents %d 0 R\n" \ 235 "/Contents {3:d} 0 R\n" \
235 "/Resources %d 0 R\n>>\n" % \ 236 "/Resources {4:d} 0 R\n>>\n".format(
236 (pagesRef, self.pageWidth, self.pageHeight, 237 pagesRef, self.pageWidth, self.pageHeight,
237 self.pageContentStart + i, resourceRef) 238 self.pageContentStart + i, resourceRef)
238 self.oT.add(buffer) 239 self.oT.add(buffer)
239 240
240 # create page tree object (PDF1.4Ref(p86)) 241 # create page tree object (PDF1.4Ref(p86))
241 self.pageData = "<</Type/Pages/Kids[\n" 242 self.pageData = "<</Type/Pages/Kids[\n"
242 for i in range(self.pageCount): 243 for i in range(self.pageCount):
243 self.pageData += "%d 0 R\n" % (pageObjectStart + i) 244 self.pageData += "{0:d} 0 R\n".format(pageObjectStart + i)
244 self.pageData += "]/Count %d\n>>\n" % self.pageCount 245 self.pageData += "]/Count {0:d}\n>>\n".format(self.pageCount)
245 self.oT.add(self.pageData) 246 self.oT.add(self.pageData)
246 247
247 # create catalog object (PDF1.4Ref(p83)) 248 # create catalog object (PDF1.4Ref(p83))
248 buffer = "<</Type/Catalog/Pages %d 0 R >>\n" % pagesRef 249 buffer = "<</Type/Catalog/Pages {0:d} 0 R >>\n".format(pagesRef)
249 catalogRef = self.oT.add(buffer) 250 catalogRef = self.oT.add(buffer)
250 251
251 # append the cross reference table (PDF1.4Ref(p64)) 252 # append the cross reference table (PDF1.4Ref(p64))
252 xref = self.oT.xref() 253 xref = self.oT.xref()
253 254
254 # end the file with the trailer (PDF1.4Ref(p67)) 255 # end the file with the trailer (PDF1.4Ref(p67))
255 buffer = "trailer\n<< /Size %d /Root %d 0 R\n>>\nstartxref\n%d\n%%%%EOF\n" % \ 256 buffer = "trailer\n<< /Size {0:d} /Root {1:d} 0 R\n>>\nstartxref\n{2:d}\n%%EOF\n"\
256 (self.oT.index, catalogRef, xref) 257 .format(self.oT.index, catalogRef, xref)
257 self.oT.write(buffer) 258 self.oT.write(buffer)
258 259
259 def add(self, ch, style_): 260 def add(self, ch, style_):
260 """ 261 """
261 Public method to add a character to the page. 262 Public method to add a character to the page.
297 if len(self.segment) > 0: 298 if len(self.segment) > 0:
298 if self.justWhiteSpace: # optimise 299 if self.justWhiteSpace: # optimise
299 self.styleCurrent = self.stylePrev 300 self.styleCurrent = self.stylePrev
300 else: 301 else:
301 self.pageData += self.segStyle 302 self.pageData += self.segStyle
302 self.pageData += "(%s)Tj\n" % self.segment 303 self.pageData += "({0})Tj\n".format(self.segment)
303 self.segment = "" 304 self.segment = ""
304 self.segStyle = "" 305 self.segStyle = ""
305 self.justWhiteSpace = True 306 self.justWhiteSpace = True
306 307
307 def startPage(self): 308 def startPage(self):
313 self.pageCount += 1 314 self.pageCount += 1
314 fontAscender = self.fontToPoints(PDFfontAscenders[self.fontSet]) 315 fontAscender = self.fontToPoints(PDFfontAscenders[self.fontSet])
315 self.yPos = self.pageHeight - self.pageMargins["top"] - fontAscender 316 self.yPos = self.pageHeight - self.pageMargins["top"] - fontAscender
316 317
317 # start a new page 318 # start a new page
318 buffer = "BT 1 0 0 1 %d %d Tm\n" % (self.pageMargins["left"], int(self.yPos)) 319 buffer = "BT 1 0 0 1 {0:d} {1:d} Tm\n".format(
320 self.pageMargins["left"], int(self.yPos))
319 321
320 # force setting of initial font, colour 322 # force setting of initial font, colour
321 self.segStyle = self.setStyle(-1) 323 self.segStyle = self.setStyle(-1)
322 buffer += self.segStyle 324 buffer += self.segStyle
323 self.pageData = buffer 325 self.pageData = buffer
332 self.pageStarted = False 334 self.pageStarted = False
333 self.flushSegment() 335 self.flushSegment()
334 336
335 # build actual text object; +3 is for "ET\n" 337 # build actual text object; +3 is for "ET\n"
336 # PDF1.4Ref(p38) EOL marker preceding endstream not counted 338 # PDF1.4Ref(p38) EOL marker preceding endstream not counted
337 textObj = "<</Length %d>>\nstream\n%sET\nendstream\n" % \ 339 textObj = "<</Length {0:d}>>\nstream\n{1}ET\nendstream\n".format(
338 (len(self.pageData) - 1 + 3, self.pageData) 340 len(self.pageData) - 1 + 3, self.pageData)
339 self.oT.add(textObj) 341 self.oT.add(textObj)
340 342
341 def nextLine(self): 343 def nextLine(self):
342 """ 344 """
343 Public method to start a new line. 345 Public method to start a new line.
357 return 359 return
358 360
359 if self.firstLine: 361 if self.firstLine:
360 # avoid breakage due to locale setting 362 # avoid breakage due to locale setting
361 f = int(self.leading * 10 + 0.5) 363 f = int(self.leading * 10 + 0.5)
362 buffer = "0 -%d.%d TD\n" % (f // 10, f % 10) 364 buffer = "0 -{0:d}.{1:d} TD\n".format(f // 10, f % 10)
363 self.firstLine = False 365 self.firstLine = False
364 else: 366 else:
365 buffer = "T*\n" 367 buffer = "T*\n"
366 self.pageData += buffer 368 self.pageData += buffer
367 369
387 """ 389 """
388 pdfColor = "" 390 pdfColor = ""
389 for component in [color.red(), color.green(), color.blue()]: 391 for component in [color.red(), color.green(), color.blue()]:
390 c = (component * 1000 + 127) // 255 392 c = (component * 1000 + 127) // 255
391 if c == 0 or c == 1000: 393 if c == 0 or c == 1000:
392 pdfColor += "%d " % (c // 1000) 394 pdfColor += "{0:d} ".format(c // 1000)
393 else: 395 else:
394 pdfColor += "0.%03d " % c 396 pdfColor += "0.{0:03d} ".format(c)
395 return pdfColor 397 return pdfColor
396 398
397 def exportSource(self): 399 def exportSource(self):
398 """ 400 """
399 Public method performing the export. 401 Public method performing the export.

eric ide

mercurial