From 8d07d6bf5509e15c25bb0bbf051741f53430abb2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 22 Nov 2019 09:56:23 +0530 Subject: [PATCH] PDF Output: Add an option to shift text horizontally on odd/even pages. Fixes #1853155 [PDF Output with even/odd page margins](https://bugs.launchpad.net/calibre/+bug/1853155) --- src/calibre/ebooks/conversion/config.py | 2 +- .../ebooks/conversion/plugins/pdf_output.py | 12 +++++++ src/calibre/ebooks/pdf/html_writer.py | 10 ++++++ src/calibre/gui2/convert/pdf_output.ui | 32 +++++++++++++++++-- src/pyj/book_list/conversion_widgets.pyj | 1 + 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/calibre/ebooks/conversion/config.py b/src/calibre/ebooks/conversion/config.py index 8ec90b9481..530dc04177 100644 --- a/src/calibre/ebooks/conversion/config.py +++ b/src/calibre/ebooks/conversion/config.py @@ -304,7 +304,7 @@ OPTIONS = { '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', - 'pdf_use_document_margins', 'pdf_page_number_map',), + 'pdf_use_document_margins', 'pdf_page_number_map', 'pdf_odd_even_offset'), 'pml': ('inline_toc', 'full_image_depth', 'pml_output_encoding'), diff --git a/src/calibre/ebooks/conversion/plugins/pdf_output.py b/src/calibre/ebooks/conversion/plugins/pdf_output.py index 72a4e0994f..81971289dc 100644 --- a/src/calibre/ebooks/conversion/plugins/pdf_output.py +++ b/src/calibre/ebooks/conversion/plugins/pdf_output.py @@ -130,6 +130,18 @@ class PDFOutput(OutputFormatPlugin): recommended_value=False, help=_( 'Generate an uncompressed PDF, useful for debugging.') ), + OptionRecommendation(name='pdf_odd_even_offset', recommended_value=0.0, + level=OptionRecommendation.LOW, + help=_( + 'Shift the text horizontally by the specified offset (in pts).' + ' On odd numbered pages, it is shifted to the right and on even' + ' numbered pages to the left. Use negative numbers for the opposite' + ' effect. Note that this setting is ignored on pages where the margins' + ' are smaller than the specified offset. Shifting is done by setting' + ' the PDF CropBox, not all software respects the CropBox.' + ) + ), + } def specialize_options(self, log, opts, input_fmt): diff --git a/src/calibre/ebooks/pdf/html_writer.py b/src/calibre/ebooks/pdf/html_writer.py index b386b48f7c..dc4d0a40c3 100644 --- a/src/calibre/ebooks/pdf/html_writer.py +++ b/src/calibre/ebooks/pdf/html_writer.py @@ -1213,6 +1213,16 @@ def convert(opf_path, opts, metadata=None, output_path=None, log=default_log, co if num_removed: log('Removed', num_removed, 'duplicate images') + if opts.pdf_odd_even_offset: + for i in range(1, pdf_doc.page_count()): + margins = page_margins_map[i] + mult = -1 if i % 2 else 1 + val = opts.pdf_odd_even_offset + if abs(val) < min(margins.left, margins.right): + box = list(pdf_doc.get_page_box("CropBox", i)) + box[0] += val * mult + pdf_doc.set_page_box("CropBox", i, *box) + if cover_data: add_cover(pdf_doc, cover_data, page_layout, opts) diff --git a/src/calibre/gui2/convert/pdf_output.ui b/src/calibre/gui2/convert/pdf_output.ui index 95a92a2344..0af14e0d15 100644 --- a/src/calibre/gui2/convert/pdf_output.ui +++ b/src/calibre/gui2/convert/pdf_output.ui @@ -7,7 +7,7 @@ 0 0 638 - 634 + 665 @@ -210,14 +210,14 @@ - + Page margins - + Page headers and footers @@ -272,6 +272,32 @@ + + + + Odd/even &offset: + + + opt_pdf_odd_even_offset + + + + + + + pt + + + 1 + + + -100000.000000000000000 + + + 100000.000000000000000 + + + diff --git a/src/pyj/book_list/conversion_widgets.pyj b/src/pyj/book_list/conversion_widgets.pyj index ef6068ef21..d4a482435c 100644 --- a/src/pyj/book_list/conversion_widgets.pyj +++ b/src/pyj/book_list/conversion_widgets.pyj @@ -664,6 +664,7 @@ def pdf_output(container): g.appendChild(float_spin('pdf_page_margin_top', indent + _('Top page margin'), unit='pt', min=-100, max=500)) g.appendChild(float_spin('pdf_page_margin_right', indent + _('Right page margin'), unit='pt', min=-100, max=500)) g.appendChild(float_spin('pdf_page_margin_bottom', indent + _('Bottom page margin'), unit='pt', min=-100, max=500)) + g.appendChild(float_spin('pdf_odd_even_offset', indent + _('Odd/event offset'), unit='pt', min=-500, max=500)) g.appendChild(lineedit('pdf_header_template', _('&Header template:'))) g.appendChild(lineedit('pdf_footer_template', _('&Footer template:'))) # }}}