From 9884dde0bc4e9003c79f6de2ffacc05867e51594 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 20 Jun 2012 16:37:14 +0530 Subject: [PATCH] PDF Output: Fix the long standing bug that caused the last line on each page to be partially cut off --- resources/compiled_coffeescript.zip | Bin 37150 -> 39482 bytes .../ebooks/conversion/plugins/pdf_output.py | 2 +- src/calibre/ebooks/pdf/writer.py | 59 ++++++++++++++---- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/resources/compiled_coffeescript.zip b/resources/compiled_coffeescript.zip index 6a24d85b2a30867b4e02dc07eac1c4e38b5a8917..180e44166d0286232a869435d48469b670fb8acf 100644 GIT binary patch delta 2471 zcmZ`*U2Icj7~Z-nWo~284Jh4~Zz}ebwTJGfGdN2YGYn{e@i&BKIrQhWJ?m*tJw095 zKxi0rIOoFHn?Uq}pz*?l#7OFeG4aB9=Y^33jl?UWCU`;O6?cm7`EE7~7P_3keA^+lX1l)c{kuPgEoI5N z{yf|`^hU>YC@x2*lx#)~72wxH#%hV$=l6%>sb{ zbA?qcl60{P7r0B*BB2oqtFp_@&Q}sM( zQWC*7fnZE3V)!xK<2oX-r52SjGp<^XONmm#WA(UdCGIH3RU6|n&c3QiP*OJpHan{4 ztg0*;aO9+e1K~&IpeuvNz#G=(P|_QgF$dY@VH<^^m?7&;G9{f=qOz+YLbZTYy#Oke z3h>tpNSOr`(_>gcs<{FJicV71E-0m%VlX;OxJ}rZtP$^Mp#cm;%EC42MS~hNC5t(--(1CsI^ajSxQZ6`xf(hC@kL;t5<9;Njv9D5h*fp>!4t zN#|6x%2PsWP{=FksFoMeEgLlV-7xI8x1m0qo9lsB1_##r_V|(1*kJS!j9_5qWky2D zio~hf2t^Q^gz#8DR9rwKvNh*XtruKI=RJtIFFb2IYgSS*9uE3Yz>BI$h8rkD)llik zJ0Hy}Q+GcDi_>8xHoylb7_8nTX+h|mQPD!U_ z{h&;MKWm4bDxekjp9<-5C2f@qEd!UP?Z*ZMzPmrbs$JOVssgcTB!xA@&{A&q#`#BB z5);rruY3rmdmXN7drhSC_p0nZS5S*Wz}=J;M$+OWQi7jHaXwQ_TzSI_%6O z7`D1nCpG)b(O3+bZO--7%I;l^sajlc%_wp{qv;0G^EDhIxX^)siPi1UceV$Mq8UN+U;3KJ}`rC)dR^c3x0j}Bl%dX2;TFZYfYpq=p=OV(&Ybi@B53F5{ pf2QEgwKJA+FMPb_VGS4{4i5h3t9o%}9`fGH*&NPHsEfInZ`wJ9!ElSY3$e z-1HGcgNUFmx`{g86qG`A6I2&LVNkc-g;zlrVdqR%N%X?^@$$Ss&-c9F`)t*8=bou{ z@VL38!k`;_?R}{JLt|#6!C=r&Elvg9^KA?EuoS(*3A`8=9nmIL}Zlu0c|Yp(I1;1Vf4zQ4~xbc3Vhus26?Snlp+( zy`+fAsHCuBGRda~bSk;WP6hkJF6(&$1*usU#59{2O~u6|7nWpMN@$_KL0KB}tB>}4 zHY4lmz*?6Rtyi1z!&SQbEGM4VTch6PRvRkHjFn+sfmR=tB9{_;Qf75VytPo17^CJw zl-2stp??@?V!P2kte0Dk?Rb@55TxJ5ehQFp?6S{aRFx^J`yV-`?Um~3y-OwPmS@F= zwOdy8E`u`1>!%MxFFH>=+2jm{O*M3|atN9HkRvLlwO@$yG8c)7c#|Jjhv)Abu{twh zErKI69vjj4Xo~cd8#DWD?F?}#KGxBLT%a1>B@2WW2L@-$abea6E8{6(-n<)Ftispp zjrcZOhtg~dIKi*AwF>t^IPr?S8bE9*PwbFKT)J-47tEC$B=c@2& zt{wJV7lI=dIGGEf|7N%5JMraQ89wIv;MTZ)1{|0SSh2NegELTS%&6ZN6k}0_I l;@r8b2rmzt${X=~nV}u?(PmU#*zMxAs};7DfQ8BHz%ME@2oC@N diff --git a/src/calibre/ebooks/conversion/plugins/pdf_output.py b/src/calibre/ebooks/conversion/plugins/pdf_output.py index 808d7edff3..c6ebabe41f 100644 --- a/src/calibre/ebooks/conversion/plugins/pdf_output.py +++ b/src/calibre/ebooks/conversion/plugins/pdf_output.py @@ -61,7 +61,7 @@ ORIENTATIONS = ['portrait', 'landscape'] class PDFOutput(OutputFormatPlugin): name = 'PDF Output' - author = 'John Schember and Kovid Goyal' + author = 'Kovid Goyal' file_type = 'pdf' options = set([ diff --git a/src/calibre/ebooks/pdf/writer.py b/src/calibre/ebooks/pdf/writer.py index a680d61188..910eaa82f2 100644 --- a/src/calibre/ebooks/pdf/writer.py +++ b/src/calibre/ebooks/pdf/writer.py @@ -87,11 +87,6 @@ def get_pdf_printer(opts, for_comic=False, output_file_name=None): return printer -def get_printer_page_size(opts, for_comic=False): - printer = get_pdf_printer(opts, for_comic=for_comic) - size = printer.paperSize(QPrinter.Millimeter) - return size.width() / 10., size.height() / 10. - def draw_image_page(printer, painter, p, preserve_aspect_ratio=True): page_rect = printer.pageRect() if preserve_aspect_ratio: @@ -138,13 +133,16 @@ class PDFWriter(QObject): # {{{ self.view.setRenderHints(QPainter.Antialiasing|QPainter.TextAntialiasing|QPainter.SmoothPixmapTransform) self.view.loadFinished.connect(self._render_html, type=Qt.QueuedConnection) + for x in (Qt.Horizontal, Qt.Vertical): + self.view.page().mainFrame().setScrollBarPolicy(x, + Qt.ScrollBarAlwaysOff) self.render_queue = [] self.combine_queue = [] self.tmp_path = PersistentTemporaryDirectory(u'_pdf_output_parts') self.opts = opts - self.size = get_printer_page_size(opts) self.cover_data = cover_data + self.paged_js = None def dump(self, items, out_stream, pdf_metadata): self.metadata = pdf_metadata @@ -176,19 +174,55 @@ class PDFWriter(QObject): # {{{ if ok: item_path = os.path.join(self.tmp_path, '%i.pdf' % len(self.combine_queue)) self.logger.debug('\tRendering item %s as %i.pdf' % (os.path.basename(str(self.view.url().toLocalFile())), len(self.combine_queue))) - printer = get_pdf_printer(self.opts, output_file_name=item_path) - self.view.page().mainFrame().evaluateJavaScript(''' - document.body.style.backgroundColor = "white"; + if True: + self.do_paged_render(item_path) + else: + printer = get_pdf_printer(self.opts, output_file_name=item_path) + self.view.page().mainFrame().evaluateJavaScript(''' + document.body.style.backgroundColor = "white"; - ''') - self.view.print_(printer) - printer.abort() + ''') + self.view.print_(printer) + printer.abort() else: # The document is so corrupt that we can't render the page. self.loop.exit(0) raise Exception('Document cannot be rendered.') self._render_book() + def do_paged_render(self, outpath): + from PyQt4.Qt import QSize, QPainter + if self.paged_js is None: + from calibre.utils.resources import compiled_coffeescript + self.paged_js = compiled_coffeescript('ebooks.oeb.display.paged', + dynamic=False) + printer = get_pdf_printer(self.opts, output_file_name=outpath) + painter = QPainter(printer) + zoomx = printer.logicalDpiX()/self.view.logicalDpiX() + zoomy = printer.logicalDpiY()/self.view.logicalDpiY() + painter.scale(zoomx, zoomy) + + pr = printer.pageRect() + evaljs = self.view.page().mainFrame().evaluateJavaScript + evaljs(self.paged_js) + self.view.page().setViewportSize(QSize(pr.width()/zoomx, + pr.height()/zoomy)) + evaljs(''' + document.body.style.backgroundColor = "white"; + paged_display.set_geometry(1, 0, 0, 0); + paged_display.layout(); + ''') + mf = self.view.page().mainFrame() + while True: + mf.render(painter) + nsl = evaljs('paged_display.next_screen_location()').toInt() + if not nsl[1] or nsl[0] <= 0: break + evaljs('window.scrollTo(%d, 0)'%nsl[0]) + printer.newPage() + + painter.end() + printer.abort() + def _delete_tmpdir(self): if os.path.exists(self.tmp_path): shutil.rmtree(self.tmp_path, True) @@ -237,7 +271,6 @@ class ImagePDFWriter(object): def __init__(self, opts, log, cover_data=None): self.opts = opts self.log = log - self.size = get_printer_page_size(opts, for_comic=True) def dump(self, items, out_stream, pdf_metadata): f = PersistentTemporaryFile('_comic2pdf.pdf')