From 9aea1e6fc8a2a2caa86219c55e532b4cd097c52b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 13 Apr 2017 08:50:23 +0530 Subject: [PATCH] PDF Output: Add separate, pdf specific, page margin settings that override the common settings --- .../ebooks/conversion/plugins/docx_output.py | 8 +++--- .../ebooks/conversion/plugins/pdf_output.py | 26 ++++++++++++++++++- src/calibre/ebooks/pdf/render/from_html.py | 18 ++++++++----- src/calibre/gui2/convert/pdf_output.py | 21 +++++++++++++++ src/calibre/gui2/convert/pdf_output.ui | 13 +++++++--- 5 files changed, 72 insertions(+), 14 deletions(-) diff --git a/src/calibre/ebooks/conversion/plugins/docx_output.py b/src/calibre/ebooks/conversion/plugins/docx_output.py index d596496183..781fce589f 100644 --- a/src/calibre/ebooks/conversion/plugins/docx_output.py +++ b/src/calibre/ebooks/conversion/plugins/docx_output.py @@ -44,25 +44,25 @@ class DOCXOutput(OutputFormatPlugin): OptionRecommendation(name='docx_page_margin_left', recommended_value=72.0, level=OptionRecommendation.LOW, help=_('The size of the left page margin, in pts. Default is 72pt.' - ' Overrides the main left page margin setting.') + ' Overrides the common left page margin setting.') ), OptionRecommendation(name='docx_page_margin_top', recommended_value=72.0, level=OptionRecommendation.LOW, help=_('The size of the top page margin, in pts. Default is 72pt.' - ' Overrides the main top page margin setting, unless set to zero.') + ' Overrides the common top page margin setting, unless set to zero.') ), OptionRecommendation(name='docx_page_margin_right', recommended_value=72.0, level=OptionRecommendation.LOW, help=_('The size of the right page margin, in pts. Default is 72pt.' - ' Overrides the main right page margin setting, unless set to zero.') + ' Overrides the common right page margin setting, unless set to zero.') ), OptionRecommendation(name='docx_page_margin_bottom', recommended_value=72.0, level=OptionRecommendation.LOW, help=_('The size of the bottom page margin, in pts. Default is 72pt.' - ' Overrides the main bottom page margin setting, unless set to zero.') + ' Overrides the common bottom page margin setting, unless set to zero.') ), } diff --git a/src/calibre/ebooks/conversion/plugins/pdf_output.py b/src/calibre/ebooks/conversion/plugins/pdf_output.py index 9b70c5e317..32bf2d6f5a 100644 --- a/src/calibre/ebooks/conversion/plugins/pdf_output.py +++ b/src/calibre/ebooks/conversion/plugins/pdf_output.py @@ -117,7 +117,31 @@ class PDFOutput(OutputFormatPlugin): OptionRecommendation(name='toc_title', recommended_value=None, help=_('Title for generated table of contents.') ), - ]) + + OptionRecommendation(name='pdf_page_margin_left', recommended_value=72.0, + level=OptionRecommendation.LOW, + help=_('The size of the left page margin, in pts. Default is 72pt.' + ' Overrides the common left page margin setting.') + ), + + OptionRecommendation(name='pdf_page_margin_top', recommended_value=72.0, + level=OptionRecommendation.LOW, + help=_('The size of the top page margin, in pts. Default is 72pt.' + ' Overrides the common top page margin setting, unless set to zero.') + ), + + OptionRecommendation(name='pdf_page_margin_right', recommended_value=72.0, + level=OptionRecommendation.LOW, + help=_('The size of the right page margin, in pts. Default is 72pt.' + ' Overrides the common right page margin setting, unless set to zero.') + ), + + OptionRecommendation(name='pdf_page_margin_bottom', recommended_value=72.0, + level=OptionRecommendation.LOW, + help=_('The size of the bottom page margin, in pts. Default is 72pt.' + ' Overrides the common bottom page margin setting, unless set to zero.') + ), + ]) def convert(self, oeb_book, output_path, input_plugin, opts, log): from calibre.gui2 import must_use_qt, load_builtin_fonts diff --git a/src/calibre/ebooks/pdf/render/from_html.py b/src/calibre/ebooks/pdf/render/from_html.py index 1ad09252a4..31d484f817 100644 --- a/src/calibre/ebooks/pdf/render/from_html.py +++ b/src/calibre/ebooks/pdf/render/from_html.py @@ -185,10 +185,16 @@ class PDFWriter(QObject): opts = self.opts page_size = get_page_size(self.opts) xdpi, ydpi = self.view.logicalDpiX(), self.view.logicalDpiY() + + def margin(which): + val = getattr(opts, 'pdf_page_margin_' + which) + if val == 0.0: + val = getattr(opts, 'margin_' + which) + return val + ml, mr, mt, mb = map(margin, 'left right top bottom'.split()) # We cannot set the side margins in the webview as there is no right # margin for the last page (the margins are implemented with # -webkit-column-gap) - ml, mr = opts.margin_left, opts.margin_right self.doc = PdfDevice(out_stream, page_size=page_size, left_margin=ml, top_margin=0, right_margin=mr, bottom_margin=0, xdpi=xdpi, ydpi=ydpi, errors=self.log.error, @@ -204,18 +210,18 @@ class PDFWriter(QObject): if self.header: self.header = self.header.strip() min_margin = 1.5 * opts._final_base_font_size - if self.footer and opts.margin_bottom < min_margin: + if self.footer and mb < min_margin: self.log.warn('Bottom margin is too small for footer, increasing it to %.1fpts' % min_margin) - opts.margin_bottom = min_margin - if self.header and opts.margin_top < min_margin: + mb = min_margin + if self.header and mt < min_margin: self.log.warn('Top margin is too small for header, increasing it to %.1fpts' % min_margin) - opts.margin_top = min_margin + mt = min_margin self.page.setViewportSize(QSize(self.doc.width(), self.doc.height())) self.render_queue = items self.total_items = len(items) - mt, mb = map(self.doc.to_px, (opts.margin_top, opts.margin_bottom)) + mt, mb = map(self.doc.to_px, (mt, mb)) self.margin_top, self.margin_bottom = map(lambda x:int(floor(x)), (mt, mb)) self.painter = QPainter(self.doc) diff --git a/src/calibre/gui2/convert/pdf_output.py b/src/calibre/gui2/convert/pdf_output.py index 87c82ba500..dd9f1839e6 100644 --- a/src/calibre/gui2/convert/pdf_output.py +++ b/src/calibre/gui2/convert/pdf_output.py @@ -4,6 +4,9 @@ __license__ = 'GPL 3' __copyright__ = '2009, John Schember ' __docformat__ = 'restructuredtext en' + +from PyQt5.Qt import QHBoxLayout, QFormLayout, QDoubleSpinBox + from calibre.gui2.convert.pdf_output_ui import Ui_Form from calibre.gui2.convert import Widget from calibre.utils.localization import localize_user_manual_link @@ -26,6 +29,7 @@ class PluginWidget(Widget, Ui_Form): 'pdf_sans_family', 'pdf_mono_family', 'pdf_standard_font', 'pdf_default_font_size', 'pdf_mono_font_size', 'pdf_page_numbers', 'pdf_footer_template', 'pdf_header_template', 'pdf_add_toc', 'toc_title', + 'pdf_page_margin_left', 'pdf_page_margin_top', 'pdf_page_margin_right', 'pdf_page_margin_bottom', ]) self.db, self.book_id = db, book_id try: @@ -45,3 +49,20 @@ class PluginWidget(Widget, Ui_Form): self.layout().setFieldGrowthPolicy(self.layout().ExpandingFieldsGrow) self.template_box.layout().setFieldGrowthPolicy(self.layout().AllNonFixedFieldsGrow) + def setupUi(self, *a): + Ui_Form.setupUi(self, *a) + h = self.page_margins_box.h = QHBoxLayout(self.page_margins_box) + l = self.page_margins_box.l = QFormLayout() + r = self.page_margins_box.r = QFormLayout() + h.addLayout(l), h.addLayout(r) + + def margin(which): + w = QDoubleSpinBox(self) + w.setRange(-100, 500), w.setSuffix(' pt'), w.setDecimals(1) + setattr(self, 'opt_pdf_page_margin_' + which, w) + return w + + l.addRow(_('&Left:'), margin('left')) + l.addRow(_('&Right:'), margin('right')) + r.addRow(_('&Top:'), margin('top')) + r.addRow(_('&Bottom:'), margin('bottom')) diff --git a/src/calibre/gui2/convert/pdf_output.ui b/src/calibre/gui2/convert/pdf_output.ui index 205d9f91e6..53f72fa1f5 100644 --- a/src/calibre/gui2/convert/pdf_output.ui +++ b/src/calibre/gui2/convert/pdf_output.ui @@ -104,7 +104,7 @@ - Se&rif family: + Serif famil&y: opt_pdf_serif_family @@ -117,7 +117,7 @@ - &Sans family: + Sans fami&ly: opt_pdf_sans_family @@ -187,7 +187,7 @@ - + Page headers and footers @@ -255,6 +255,13 @@ + + + + Page margins + + +