mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement imposing headers/footers onto their target pages
This commit is contained in:
parent
848d91c6d8
commit
227679985f
@ -116,7 +116,7 @@
|
||||
},
|
||||
{
|
||||
"name": "podofo",
|
||||
"sources": "calibre/utils/podofo/utils.cpp calibre/utils/podofo/output.cpp calibre/utils/podofo/doc.cpp calibre/utils/podofo/outline.cpp calibre/utils/podofo/fonts.cpp calibre/utils/podofo/podofo.cpp",
|
||||
"sources": "calibre/utils/podofo/utils.cpp calibre/utils/podofo/output.cpp calibre/utils/podofo/doc.cpp calibre/utils/podofo/outline.cpp calibre/utils/podofo/fonts.cpp calibre/utils/podofo/impose.cpp calibre/utils/podofo/podofo.cpp",
|
||||
"headers": "calibre/utils/podofo/global.h",
|
||||
"libraries": "podofo",
|
||||
"lib_dirs": "!podofo_lib",
|
||||
|
@ -860,7 +860,7 @@ def add_header_footer(manager, opts, pdf_doc, container, page_number_display_map
|
||||
root = container.parsed(name)
|
||||
body = root[-1]
|
||||
body.attrib.pop('id', None)
|
||||
body.set('style', 'margin: 0; padding: 0; border-width: 0')
|
||||
body.set('style', 'margin: 0; padding: 0; border-width: 0; background-color: unset')
|
||||
job = job_for_name(container, name, Margins(0, 0, 0, 0), page_layout)
|
||||
|
||||
def m(tag_name, text=None, style=None, **attrs):
|
||||
@ -928,6 +928,7 @@ def add_header_footer(manager, opts, pdf_doc, container, page_number_display_map
|
||||
'padding': '0',
|
||||
'border-width': '0',
|
||||
'overflow': 'hidden',
|
||||
'background-color': 'unset',
|
||||
}
|
||||
|
||||
ans = m('div', style=style, id='p{}'.format(page_num))
|
||||
@ -944,7 +945,7 @@ def add_header_footer(manager, opts, pdf_doc, container, page_number_display_map
|
||||
style = ans.get('style') or ''
|
||||
style = (
|
||||
'margin: 0; padding: 0; height: {height}pt; border-width: 0;'
|
||||
'display: flex; align-items: center; overflow: hidden').format(height=height) + style
|
||||
'display: flex; align-items: center; overflow: hidden; background-color: unset').format(height=height) + style
|
||||
ans.set('style', style)
|
||||
for child in ans.xpath('descendant-or-self::*[@class]'):
|
||||
cls = frozenset(child.get('class').split())
|
||||
@ -970,7 +971,13 @@ def add_header_footer(manager, opts, pdf_doc, container, page_number_display_map
|
||||
if not isinstance(data, bytes):
|
||||
raise SystemExit(data)
|
||||
doc = data_as_pdf_doc(data)
|
||||
first_page_num = pdf_doc.page_count()
|
||||
num_pages = doc.page_count()
|
||||
if first_page_num != num_pages:
|
||||
raise ValueError('The number of header/footers pages ({}) != number of document pages ({})'.format(
|
||||
num_pages, first_page_num))
|
||||
pdf_doc.append(doc)
|
||||
pdf_doc.impose(1, first_page_num + 1, num_pages)
|
||||
report_progress(0.9, _('Headers and footers added'))
|
||||
|
||||
# }}}
|
||||
|
@ -756,6 +756,9 @@ static PyMethodDef PDFDoc_methods[] = {
|
||||
{"dedup_type3_fonts", (PyCFunction)py_dedup_type3_fonts, METH_VARARGS,
|
||||
"dedup_type3_fonts() -> De-duplicate repeated glyphs in Type3 fonts"
|
||||
},
|
||||
{"impose", (PyCFunction)py_impose, METH_VARARGS,
|
||||
"impose() -> impose pages onto each other"
|
||||
},
|
||||
{"delete_pages", (PyCFunction)PDFDoc_delete_pages, METH_VARARGS,
|
||||
"delete_page(page_num, count=1) -> Delete the specified pages from the pdf."
|
||||
},
|
||||
|
@ -11,14 +11,6 @@
|
||||
|
||||
using namespace pdf;
|
||||
|
||||
#define PYWRAP(name) extern "C" PyObject* py_##name(PDFDoc *self, PyObject *args) { \
|
||||
try { \
|
||||
return name(self, args); \
|
||||
} catch (const PdfError &err) { podofo_set_exception(err); return NULL; \
|
||||
} catch (const std::exception &err) { PyErr_Format(Error, "Error in %s(): %s", #name, err.what()); return NULL; \
|
||||
} catch (...) { PyErr_SetString(Error, "An unknown error occurred in " #name); return NULL; } \
|
||||
}
|
||||
|
||||
static inline PyObject*
|
||||
ref_as_tuple(const PdfReference &ref) {
|
||||
unsigned long num = ref.ObjectNumber(), generation = ref.GenerationNumber();
|
||||
|
@ -100,5 +100,14 @@ PyObject* py_list_fonts(PDFDoc*, PyObject*);
|
||||
PyObject* py_remove_unused_fonts(PDFDoc *self, PyObject *args);
|
||||
PyObject* py_merge_fonts(PDFDoc *self, PyObject *args);
|
||||
PyObject* py_dedup_type3_fonts(PDFDoc *self, PyObject *args);
|
||||
PyObject* py_impose(PDFDoc *self, PyObject *args);
|
||||
}
|
||||
}
|
||||
|
||||
#define PYWRAP(name) extern "C" PyObject* py_##name(PDFDoc *self, PyObject *args) { \
|
||||
try { \
|
||||
return name(self, args); \
|
||||
} catch (const PdfError &err) { podofo_set_exception(err); return NULL; \
|
||||
} catch (const std::exception &err) { PyErr_Format(Error, "Error in %s(): %s", #name, err.what()); return NULL; \
|
||||
} catch (...) { PyErr_SetString(Error, "An unknown error occurred in " #name); return NULL; } \
|
||||
}
|
||||
|
40
src/calibre/utils/podofo/impose.cpp
Normal file
40
src/calibre/utils/podofo/impose.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* impose.cpp
|
||||
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
using namespace pdf;
|
||||
|
||||
static void
|
||||
impose_page(PdfMemDocument *doc, unsigned long dest_page_num, unsigned long src_page_num) {
|
||||
PdfXObject *xobj = new PdfXObject(doc, src_page_num, "HeaderFooter");
|
||||
PdfPage *dest = doc->GetPage(dest_page_num);
|
||||
dest->AddResource(xobj->GetIdentifier(), xobj->GetObject()->Reference(), "XObject");
|
||||
PdfStream *stream = dest->GetContents()->GetStream();
|
||||
char *buffer = NULL; pdf_long sz;
|
||||
stream->GetFilteredCopy(&buffer, &sz);
|
||||
stream->BeginAppend();
|
||||
stream->Append("q\n1 0 0 1 0 0 cm\n/");
|
||||
stream->Append(xobj->GetIdentifier().GetName());
|
||||
stream->Append(" Do\nQ\n");
|
||||
stream->Append(buffer, sz);
|
||||
stream->EndAppend();
|
||||
podofo_free(buffer);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
impose(PDFDoc *self, PyObject *args) {
|
||||
unsigned long dest_page_num, src_page_num, count;
|
||||
if (!PyArg_ParseTuple(args, "kkk", &dest_page_num, &src_page_num, &count)) return NULL;
|
||||
for (unsigned long i = 0; i < count; i++) {
|
||||
impose_page(self->doc, dest_page_num - 1 + i, src_page_num - 1 + i);
|
||||
}
|
||||
self->doc->DeletePages(src_page_num - 1, count);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PYWRAP(impose)
|
Loading…
x
Reference in New Issue
Block a user