Code to add cover to textual PDF output

This commit is contained in:
Kovid Goyal 2019-07-08 18:20:35 +05:30
parent 6c78ae2105
commit 8029b3cc83
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 56 additions and 4 deletions

View File

@ -238,4 +238,7 @@ class PDFOutput(OutputFormatPlugin):
oeb_output = plugin_for_output_format('oeb')
oeb_output.convert(oeb_book, oeb_dir, self.input_plugin, self.opts, self.log)
opfpath = glob.glob(os.path.join(oeb_dir, '*.opf'))[0]
convert(opfpath, self.opts, metadata=self.metadata, output_path=self.output_path, log=self.log)
convert(
opfpath, self.opts, metadata=self.metadata, output_path=self.output_path,
log=self.log, cover_data=self.cover_data
)

View File

@ -6,17 +6,21 @@ from __future__ import absolute_import, division, print_function, unicode_litera
import os
from PyQt5.Qt import QApplication, QTimer, QUrl
from PyQt5.Qt import (
QApplication, QBuffer, QMarginsF, QPageLayout, QPainter, QPdfWriter, QTimer,
QUrl
)
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from calibre.constants import iswindows
from calibre.ebooks.oeb.polish.container import Container as ContainerBase
from calibre.ebooks.oeb.polish.split import merge_html
from calibre.ebooks.pdf.image_writer import (
PDFMetadata, get_page_layout, update_metadata
PDFMetadata, draw_image_page, get_page_layout, update_metadata
)
from calibre.gui2 import setup_unix_signals
from calibre.gui2.webengine import secure_webengine
from calibre.utils.img import image_from_data
from calibre.utils.logging import default_log
from calibre.utils.podofo import get_podofo
from polyglot.builtins import range
@ -98,7 +102,28 @@ class Renderer(QWebEnginePage):
return self.pdf_data
def convert(opf_path, opts, metadata=None, output_path=None, log=default_log):
def add_cover(pdf_doc, cover_data, page_layout, opts):
buf = QBuffer()
buf.open(QBuffer.ReadWrite)
cover_layout = QPageLayout(page_layout)
cover_layout.setMargins(QMarginsF(0, 0, 0, 0))
img = image_from_data(cover_data)
writer = QPdfWriter(buf)
writer.setPageLayout(cover_layout)
painter = QPainter()
painter.begin(writer)
try:
draw_image_page(painter, img, preserve_aspect_ratio=opts.preserve_cover_aspect_ratio)
finally:
painter.end()
cover_pdf = buf.data().data()
podofo = get_podofo()
cover_pdf_doc = podofo.PDFDoc()
cover_pdf_doc.load(cover_pdf)
pdf_doc.insert_existing_page(cover_pdf_doc)
def convert(opf_path, opts, metadata=None, output_path=None, log=default_log, cover_data=None):
container = Container(opf_path, log)
spine_names = [name for name, is_linear in container.spine_names]
master = spine_names[0]
@ -115,6 +140,9 @@ def convert(opf_path, opts, metadata=None, output_path=None, log=default_log):
pdf_doc = podofo.PDFDoc()
pdf_doc.load(pdf_data)
if cover_data:
add_cover(pdf_doc, cover_data, page_layout, opts)
if metadata is not None:
update_metadata(pdf_doc, PDFMetadata(metadata))

View File

@ -219,6 +219,24 @@ PDFDoc_append(PDFDoc *self, PyObject *args) {
Py_RETURN_NONE;
} // }}}
// insert_existing_page() {{{
static PyObject *
PDFDoc_insert_existing_page(PDFDoc *self, PyObject *args) {
PDFDoc *src_doc;
int src_page = 0, at = 0;
if (!PyArg_ParseTuple(args, "O!|ii", &PDFDocType, &src_doc, &src_page, &at)) return NULL;
try {
self->doc->InsertExistingPageAt(*src_doc->doc, src_page, at);
} catch (const PdfError & err) {
podofo_set_exception(err);
return NULL;
}
Py_RETURN_NONE;
} // }}}
// set_box() {{{
static PyObject *
PDFDoc_set_box(PDFDoc *self, PyObject *args) {
@ -629,6 +647,9 @@ static PyMethodDef PDFDoc_methods[] = {
{"append", (PyCFunction)PDFDoc_append, METH_VARARGS,
"append(doc) -> Append doc (which must be a PDFDoc) to this document."
},
{"insert_existing_page", (PyCFunction)PDFDoc_insert_existing_page, METH_VARARGS,
"insert_existing_page(src_doc, src_page, at) -> Insert the page src_page from src_doc at index: at."
},
{"set_box", (PyCFunction)PDFDoc_set_box, METH_VARARGS,
"set_box(page_num, box, left, bottom, width, height) -> Set the PDF bounding box for the page numbered nu, box must be one of: MediaBox, CropBox, TrimBox, BleedBox, ArtBox. The numbers are interpreted as pts."
},