PDF Output: Allow using images in the header/footer templates

Images can be loaded using <img> tags with data URIs
This commit is contained in:
Kovid Goyal 2018-05-23 15:23:47 +05:30
parent 5012d9066c
commit 4fba18f974
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 29 additions and 3 deletions

Binary file not shown.

View File

@ -312,6 +312,8 @@ class PagedDisplay
this.footer.style.setProperty('left', left+'px') this.footer.style.setProperty('left', left+'px')
update_header_footer: (pagenum) -> update_header_footer: (pagenum) ->
has_images = false
this.header_footer_images = []
if this.hf_style != null if this.hf_style != null
if pagenum%2 == 1 then cls = "even_page" else cls = "odd_page" if pagenum%2 == 1 then cls = "even_page" else cls = "odd_page"
this.hf_style.innerHTML = "#pdf_page_header_#{ this.hf_uuid } .#{ cls }, #pdf_page_footer_#{ this.hf_uuid } .#{ cls } { display: none }" this.hf_style.innerHTML = "#pdf_page_header_#{ this.hf_uuid } .#{ cls }, #pdf_page_footer_#{ this.hf_uuid } .#{ cls } { display: none }"
@ -322,9 +324,22 @@ class PagedDisplay
if this.header != null if this.header != null
this.header.innerHTML = this.header_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_TOP_LEVEL_SECTION_/g, tl_section+"").replace(/_SECTION_/g, section+"") this.header.innerHTML = this.header_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_TOP_LEVEL_SECTION_/g, tl_section+"").replace(/_SECTION_/g, section+"")
runscripts(this.header) runscripts(this.header)
for img in this.header.getElementsByTagName('img')
this.header_footer_images.push(img)
has_images = true
if this.footer != null if this.footer != null
this.footer.innerHTML = this.footer_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_TOP_LEVEL_SECTION_/g, tl_section+"").replace(/_SECTION_/g, section+"") this.footer.innerHTML = this.footer_template.replace(/_PAGENUM_/g, pagenum+"").replace(/_TITLE_/g, title+"").replace(/_AUTHOR_/g, author+"").replace(/_TOP_LEVEL_SECTION_/g, tl_section+"").replace(/_SECTION_/g, section+"")
runscripts(this.footer) runscripts(this.footer)
for img in this.header.getElementsByTagName('img')
this.header_footer_images.push(img)
has_images = true
has_images
header_footer_images_loaded: () ->
for img in this.header_footer_images
if not img.complete
return false
return true
fit_images: () -> fit_images: () ->
# Ensure no images are wider than the available width in a column. Note # Ensure no images are wider than the available width in a column. Note

View File

@ -159,8 +159,7 @@ class PDFWriter(QObject):
self.view = QWebView() self.view = QWebView()
self.page = Page(opts, self.log) self.page = Page(opts, self.log)
self.view.setPage(self.page) self.view.setPage(self.page)
self.view.setRenderHints(QPainter.Antialiasing| self.view.setRenderHints(QPainter.Antialiasing|QPainter.TextAntialiasing|QPainter.SmoothPixmapTransform)
QPainter.TextAntialiasing|QPainter.SmoothPixmapTransform)
self.view.loadFinished.connect(self.render_html, self.view.loadFinished.connect(self.render_html,
type=Qt.QueuedConnection) type=Qt.QueuedConnection)
for x in (Qt.Horizontal, Qt.Vertical): for x in (Qt.Horizontal, Qt.Vertical):
@ -316,6 +315,16 @@ class PDFWriter(QObject):
self.loop.processEvents(self.loop.ExcludeUserInputEvents) self.loop.processEvents(self.loop.ExcludeUserInputEvents)
evaljs('document.getElementById("MathJax_Message").style.display="none";') evaljs('document.getElementById("MathJax_Message").style.display="none";')
def load_header_footer_images(self):
from calibre.utils.monotonic import monotonic
evaljs = self.view.page().mainFrame().evaluateJavaScript
st = monotonic()
while not evaljs('paged_display.header_footer_images_loaded()'):
self.loop.processEvents(self.loop.ExcludeUserInputEvents)
if monotonic() - st > 5:
self.log.warn('Header and footer images have not loaded in 5 seconds, ignoring')
break
def get_sections(self, anchor_map, only_top_level=False): def get_sections(self, anchor_map, only_top_level=False):
sections = defaultdict(list) sections = defaultdict(list)
ci = os.path.abspath(os.path.normcase(self.current_item)) ci = os.path.abspath(os.path.normcase(self.current_item))
@ -395,7 +404,9 @@ class PDFWriter(QObject):
set_section(col, tl_sections, 'current_tl_section') set_section(col, tl_sections, 'current_tl_section')
self.doc.init_page() self.doc.init_page()
if self.header or self.footer: if self.header or self.footer:
evaljs('paged_display.update_header_footer(%d)'%self.current_page_num) if evaljs('paged_display.update_header_footer(%d)'%self.current_page_num) is True:
self.load_header_footer_images()
self.painter.save() self.painter.save()
mf.render(self.painter) mf.render(self.painter)
self.painter.restore() self.painter.restore()