From 4fba18f974148feb13366f7e3720046f8abbf198 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 23 May 2018 15:23:47 +0530 Subject: [PATCH] PDF Output: Allow using images in the header/footer templates Images can be loaded using tags with data URIs --- resources/compiled_coffeescript.zip | Bin 102048 -> 102927 bytes src/calibre/ebooks/oeb/display/paged.coffee | 15 +++++++++++++++ src/calibre/ebooks/pdf/render/from_html.py | 17 ++++++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/resources/compiled_coffeescript.zip b/resources/compiled_coffeescript.zip index 13fed66f1142106476401c7f112d3f66cec92402..fe76db495743721aa0b33f753e7f0fa9cbc6118d 100644 GIT binary patch delta 748 zcmZ25m#u#Z+lFoXgvzS6`$#7xEfykTwNdg_4ZSVm*kW$%+TWCqMYZJNf8y@yWRd; z92WNAfCst><{pe-M0L^R{m*5=fvNacLNGH;K|>MfE4}3W+=86clGMoy=9x^cpD#Jx zpOsO3^Zeh+{d}m2VfuwG#z^Mh28@#*Ocj~#(9LMXY~#*2{gpGL%=C%fj9SbK0~n|K z`!dQ-zunC!z_hk!`rB?sNsvO0>0f&oohRoea!v2;Wwf3i?aL@QeHBRP?mmv`4!w-5 z>PE?CNk)k#NhwAq1_p_VDTc|3iH500rpaaoDFy~+sVNrbMnqwaL2UPiI$7l3v%)&c-<76jn{ delta 291 zcmeBQ!nR;8+lFoXg!WY3_DU-XH(s8{zyQM14ATSq7-cs<-KS_V+4#HC=BeNLnJ1t5 zEVy~XZ(c^$)RNMoyveiwC`>=W!>GEM@4s?CAF2`4?fV!bnR|2@rz`d{icDYM$7sZS z)|qj7q&uU`w0=e{W+Pw5>H7j0Wv6@fGYT--bxx1zXOx_7J(1CMdTu`>$Mo~PjNH?I zOklL0-Y}7oeY!(GBiD4X35?Dlqd2D5_A@$9zPpb@U&%^ADap*z!r08r!o(oS)G*1^ zBGoV@)yzD}ILXK&IVm|c&D7M?+|0ltMM+0tdSXA&H3#~kwoESQ=9~U-BBL%7OzK?^ NBir; + has_images = false + this.header_footer_images = [] if this.hf_style != null 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 }" @@ -322,9 +324,22 @@ class PagedDisplay 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+"") runscripts(this.header) + for img in this.header.getElementsByTagName('img') + this.header_footer_images.push(img) + has_images = true 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+"") 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: () -> # Ensure no images are wider than the available width in a column. Note diff --git a/src/calibre/ebooks/pdf/render/from_html.py b/src/calibre/ebooks/pdf/render/from_html.py index c8255ac5eb..070ed083aa 100644 --- a/src/calibre/ebooks/pdf/render/from_html.py +++ b/src/calibre/ebooks/pdf/render/from_html.py @@ -159,8 +159,7 @@ class PDFWriter(QObject): self.view = QWebView() self.page = Page(opts, self.log) self.view.setPage(self.page) - self.view.setRenderHints(QPainter.Antialiasing| - QPainter.TextAntialiasing|QPainter.SmoothPixmapTransform) + self.view.setRenderHints(QPainter.Antialiasing|QPainter.TextAntialiasing|QPainter.SmoothPixmapTransform) self.view.loadFinished.connect(self.render_html, type=Qt.QueuedConnection) for x in (Qt.Horizontal, Qt.Vertical): @@ -316,6 +315,16 @@ class PDFWriter(QObject): self.loop.processEvents(self.loop.ExcludeUserInputEvents) 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): sections = defaultdict(list) 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') self.doc.init_page() 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() mf.render(self.painter) self.painter.restore()