mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
PDF Output: Do not create duplicate embedded fonts in the PDF for every individual HTML file in the input document
This commit is contained in:
parent
05de8b4b21
commit
e20450d956
@ -12,7 +12,7 @@ import os, shutil, json
|
|||||||
from future_builtins import map
|
from future_builtins import map
|
||||||
|
|
||||||
from PyQt4.Qt import (QEventLoop, QObject, QPrinter, QSizeF, Qt, QPainter,
|
from PyQt4.Qt import (QEventLoop, QObject, QPrinter, QSizeF, Qt, QPainter,
|
||||||
QPixmap, QTimer, pyqtProperty, QString)
|
QPixmap, QTimer, pyqtProperty, QString, QSize)
|
||||||
from PyQt4.QtWebKit import QWebView, QWebPage, QWebSettings
|
from PyQt4.QtWebKit import QWebView, QWebPage, QWebSettings
|
||||||
|
|
||||||
from calibre.ptempfile import PersistentTemporaryDirectory
|
from calibre.ptempfile import PersistentTemporaryDirectory
|
||||||
@ -192,8 +192,17 @@ class PDFWriter(QObject): # {{{
|
|||||||
self.insert_cover()
|
self.insert_cover()
|
||||||
|
|
||||||
self.render_succeeded = False
|
self.render_succeeded = False
|
||||||
|
self.combine_queue.append(os.path.join(self.tmp_path,
|
||||||
|
'qprinter_out.pdf'))
|
||||||
|
self.first_page = True
|
||||||
|
self.setup_printer(self.combine_queue[-1])
|
||||||
QTimer.singleShot(0, self._render_book)
|
QTimer.singleShot(0, self._render_book)
|
||||||
self.loop.exec_()
|
self.loop.exec_()
|
||||||
|
if self.painter is not None:
|
||||||
|
self.painter.end()
|
||||||
|
if self.printer is not None:
|
||||||
|
self.printer.abort()
|
||||||
|
|
||||||
if not self.render_succeeded:
|
if not self.render_succeeded:
|
||||||
raise Exception('Rendering HTML to PDF failed')
|
raise Exception('Rendering HTML to PDF failed')
|
||||||
|
|
||||||
@ -209,7 +218,6 @@ class PDFWriter(QObject): # {{{
|
|||||||
|
|
||||||
def _render_next(self):
|
def _render_next(self):
|
||||||
item = unicode(self.render_queue.pop(0))
|
item = unicode(self.render_queue.pop(0))
|
||||||
self.combine_queue.append(os.path.join(self.tmp_path, '%i.pdf' % (len(self.combine_queue) + 1)))
|
|
||||||
|
|
||||||
self.logger.debug('Processing %s...' % item)
|
self.logger.debug('Processing %s...' % item)
|
||||||
self.current_item = item
|
self.current_item = item
|
||||||
@ -217,9 +225,7 @@ class PDFWriter(QObject): # {{{
|
|||||||
|
|
||||||
def _render_html(self, ok):
|
def _render_html(self, ok):
|
||||||
if ok:
|
if ok:
|
||||||
item_path = os.path.join(self.tmp_path, '%i.pdf' % len(self.combine_queue))
|
self.do_paged_render()
|
||||||
self.logger.debug('\tRendering item %s as %i.pdf' % (os.path.basename(str(self.view.url().toLocalFile())), len(self.combine_queue)))
|
|
||||||
self.do_paged_render(item_path)
|
|
||||||
else:
|
else:
|
||||||
# The document is so corrupt that we can't render the page.
|
# The document is so corrupt that we can't render the page.
|
||||||
self.logger.error('Document cannot be rendered.')
|
self.logger.error('Document cannot be rendered.')
|
||||||
@ -237,25 +243,28 @@ class PDFWriter(QObject): # {{{
|
|||||||
_pass_json_value = pyqtProperty(QString, fget=_pass_json_value_getter,
|
_pass_json_value = pyqtProperty(QString, fget=_pass_json_value_getter,
|
||||||
fset=_pass_json_value_setter)
|
fset=_pass_json_value_setter)
|
||||||
|
|
||||||
def do_paged_render(self, outpath):
|
def setup_printer(self, outpath):
|
||||||
from PyQt4.Qt import QSize, QPainter
|
self.printer = self.painter = None
|
||||||
if self.paged_js is None:
|
|
||||||
from calibre.utils.resources import compiled_coffeescript
|
|
||||||
self.paged_js = compiled_coffeescript('ebooks.oeb.display.utils')
|
|
||||||
self.paged_js += compiled_coffeescript('ebooks.oeb.display.indexing')
|
|
||||||
self.paged_js += compiled_coffeescript('ebooks.oeb.display.paged')
|
|
||||||
printer = get_pdf_printer(self.opts, output_file_name=outpath)
|
printer = get_pdf_printer(self.opts, output_file_name=outpath)
|
||||||
painter = QPainter(printer)
|
painter = QPainter(printer)
|
||||||
zoomx = printer.logicalDpiX()/self.view.logicalDpiX()
|
zoomx = printer.logicalDpiX()/self.view.logicalDpiX()
|
||||||
zoomy = printer.logicalDpiY()/self.view.logicalDpiY()
|
zoomy = printer.logicalDpiY()/self.view.logicalDpiY()
|
||||||
painter.scale(zoomx, zoomy)
|
painter.scale(zoomx, zoomy)
|
||||||
|
pr = printer.pageRect()
|
||||||
|
self.printer, self.painter = printer, painter
|
||||||
|
self.viewport_size = QSize(pr.width()/zoomx, pr.height()/zoomy)
|
||||||
|
self.page.setViewportSize(self.viewport_size)
|
||||||
|
|
||||||
|
def do_paged_render(self):
|
||||||
|
if self.paged_js is None:
|
||||||
|
from calibre.utils.resources import compiled_coffeescript
|
||||||
|
self.paged_js = compiled_coffeescript('ebooks.oeb.display.utils')
|
||||||
|
self.paged_js += compiled_coffeescript('ebooks.oeb.display.indexing')
|
||||||
|
self.paged_js += compiled_coffeescript('ebooks.oeb.display.paged')
|
||||||
|
|
||||||
self.view.page().mainFrame().addToJavaScriptWindowObject("py_bridge", self)
|
self.view.page().mainFrame().addToJavaScriptWindowObject("py_bridge", self)
|
||||||
pr = printer.pageRect()
|
|
||||||
evaljs = self.view.page().mainFrame().evaluateJavaScript
|
evaljs = self.view.page().mainFrame().evaluateJavaScript
|
||||||
evaljs(self.paged_js)
|
evaljs(self.paged_js)
|
||||||
self.view.page().setViewportSize(QSize(pr.width()/zoomx,
|
|
||||||
pr.height()/zoomy))
|
|
||||||
evaljs('''
|
evaljs('''
|
||||||
py_bridge.__defineGetter__('value', function() {
|
py_bridge.__defineGetter__('value', function() {
|
||||||
return JSON.parse(this._pass_json_value);
|
return JSON.parse(this._pass_json_value);
|
||||||
@ -271,11 +280,13 @@ class PDFWriter(QObject): # {{{
|
|||||||
''')
|
''')
|
||||||
mf = self.view.page().mainFrame()
|
mf = self.view.page().mainFrame()
|
||||||
while True:
|
while True:
|
||||||
mf.render(painter)
|
if not self.first_page:
|
||||||
|
self.printer.newPage()
|
||||||
|
self.first_page = False
|
||||||
|
mf.render(self.painter)
|
||||||
nsl = evaljs('paged_display.next_screen_location()').toInt()
|
nsl = evaljs('paged_display.next_screen_location()').toInt()
|
||||||
if not nsl[1] or nsl[0] <= 0: break
|
if not nsl[1] or nsl[0] <= 0: break
|
||||||
evaljs('window.scrollTo(%d, 0)'%nsl[0])
|
evaljs('window.scrollTo(%d, 0)'%nsl[0])
|
||||||
printer.newPage()
|
|
||||||
|
|
||||||
self.bridge_value = tuple(self.outline.anchor_map[self.current_item])
|
self.bridge_value = tuple(self.outline.anchor_map[self.current_item])
|
||||||
evaljs('py_bridge.value = book_indexing.anchor_positions(py_bridge.value)')
|
evaljs('py_bridge.value = book_indexing.anchor_positions(py_bridge.value)')
|
||||||
@ -288,10 +299,6 @@ class PDFWriter(QObject): # {{{
|
|||||||
pagenum, ypos = x
|
pagenum, ypos = x
|
||||||
self.outline.set_pos(self.current_item, anchor, pages + pagenum, ypos)
|
self.outline.set_pos(self.current_item, anchor, pages + pagenum, ypos)
|
||||||
|
|
||||||
painter.end()
|
|
||||||
printer.abort()
|
|
||||||
self.append_doc(outpath)
|
|
||||||
|
|
||||||
def append_doc(self, outpath):
|
def append_doc(self, outpath):
|
||||||
doc = self.podofo.PDFDoc()
|
doc = self.podofo.PDFDoc()
|
||||||
with open(outpath, 'rb') as f:
|
with open(outpath, 'rb') as f:
|
||||||
@ -322,7 +329,10 @@ class PDFWriter(QObject): # {{{
|
|||||||
printer.abort()
|
printer.abort()
|
||||||
|
|
||||||
def _write(self):
|
def _write(self):
|
||||||
self.logger.debug('Combining individual PDF parts...')
|
self.painter.end()
|
||||||
|
self.printer.abort()
|
||||||
|
self.painter = self.printer = None
|
||||||
|
self.append_doc(self.combine_queue[-1])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.doc.creator = u'%s %s [http://calibre-ebook.com]'%(
|
self.doc.creator = u'%s %s [http://calibre-ebook.com]'%(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user