PDF Output: Allow choosing the default font family and size when generating PDF files (under PDF Options) in the conversion dialog

This commit is contained in:
Kovid Goyal 2012-08-29 16:36:33 +05:30
parent a90367296c
commit 05de8b4b21
7 changed files with 173 additions and 44 deletions

View File

@ -703,6 +703,15 @@ if isosx:
import traceback import traceback
traceback.print_exc() traceback.print_exc()
def load_builtin_fonts():
import glob
from PyQt4.Qt import QFontDatabase
base = P('fonts/liberation/*.ttf')
for f in glob.glob(base):
QFontDatabase.addApplicationFont(f)
return 'Liberation Serif', 'Liberation Sans', 'Liberation Mono'
def ipython(user_ns=None): def ipython(user_ns=None):
from calibre.utils.ipython import ipython from calibre.utils.ipython import ipython
ipython(user_ns=user_ns) ipython(user_ns=user_ns)

View File

@ -88,6 +88,25 @@ class PDFOutput(OutputFormatPlugin):
help=_('Preserve the aspect ratio of the cover, instead' help=_('Preserve the aspect ratio of the cover, instead'
' of stretching it to fill the full first page of the' ' of stretching it to fill the full first page of the'
' generated pdf.')), ' generated pdf.')),
OptionRecommendation(name='pdf_serif_family',
recommended_value='Times New Roman', help=_(
'The font family used to render serif fonts')),
OptionRecommendation(name='pdf_sans_family',
recommended_value='Helvetica', help=_(
'The font family used to render sans-serif fonts')),
OptionRecommendation(name='pdf_mono_family',
recommended_value='Courier New', help=_(
'The font family used to render monospaced fonts')),
OptionRecommendation(name='pdf_standard_font', choices=['serif',
'sans', 'mono'],
recommended_value='serif', help=_(
'The font family used to render monospaced fonts')),
OptionRecommendation(name='pdf_default_font_size',
recommended_value=20, help=_(
'The default font size')),
OptionRecommendation(name='pdf_mono_font_size',
recommended_value=16, help=_(
'The default font size for monospaced text')),
]) ])
def convert(self, oeb_book, output_path, input_plugin, opts, log): def convert(self, oeb_book, output_path, input_plugin, opts, log):

View File

@ -13,14 +13,14 @@ 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)
from PyQt4.QtWebKit import QWebView, QWebPage from PyQt4.QtWebKit import QWebView, QWebPage, QWebSettings
from calibre.ptempfile import PersistentTemporaryDirectory from calibre.ptempfile import PersistentTemporaryDirectory
from calibre.ebooks.pdf.pageoptions import (unit, paper_size, orientation) from calibre.ebooks.pdf.pageoptions import (unit, paper_size, orientation)
from calibre.ebooks.pdf.outline_writer import Outline from calibre.ebooks.pdf.outline_writer import Outline
from calibre.ebooks.metadata import authors_to_string from calibre.ebooks.metadata import authors_to_string
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre import __appname__, __version__, fit_image, isosx, force_unicode from calibre import (__appname__, __version__, fit_image, isosx, force_unicode)
from calibre.ebooks.oeb.display.webview import load_html from calibre.ebooks.oeb.display.webview import load_html
def get_custom_size(opts): def get_custom_size(opts):
@ -123,10 +123,25 @@ class PDFMetadata(object): # {{{
class Page(QWebPage): class Page(QWebPage):
def __init__(self, log): def __init__(self, opts, log):
self.log = log self.log = log
QWebPage.__init__(self) QWebPage.__init__(self)
settings = self.settings()
settings.setFontSize(QWebSettings.DefaultFontSize,
opts.pdf_default_font_size)
settings.setFontSize(QWebSettings.DefaultFixedFontSize,
opts.pdf_mono_font_size)
settings.setFontSize(QWebSettings.MinimumLogicalFontSize, 8)
settings.setFontSize(QWebSettings.MinimumFontSize, 8)
std = {'serif':opts.pdf_serif_family, 'sans':opts.pdf_sans_family,
'mono':opts.pdf_mono_family}.get(opts.pdf_standard_font,
opts.pdf_serif_family)
settings.setFontFamily(QWebSettings.StandardFont, std)
settings.setFontFamily(QWebSettings.SerifFont, opts.pdf_serif_family)
settings.setFontFamily(QWebSettings.SansSerifFont,
opts.pdf_sans_family)
settings.setFontFamily(QWebSettings.FixedFont, opts.pdf_mono_family)
def javaScriptConsoleMessage(self, msg, lineno, msgid): def javaScriptConsoleMessage(self, msg, lineno, msgid):
self.log.debug(u'JS:', unicode(msg)) self.log.debug(u'JS:', unicode(msg))
@ -149,7 +164,7 @@ class PDFWriter(QObject): # {{{
self.loop = QEventLoop() self.loop = QEventLoop()
self.view = QWebView() self.view = QWebView()
self.page = Page(self.log) self.page = Page(opts, self.log)
self.view.setPage(self.page) 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, self.view.loadFinished.connect(self._render_html,

View File

@ -9,8 +9,9 @@ __docformat__ = 'restructuredtext en'
import textwrap, codecs, importlib import textwrap, codecs, importlib
from functools import partial from functools import partial
from PyQt4.Qt import QWidget, QSpinBox, QDoubleSpinBox, QLineEdit, QTextEdit, \ from PyQt4.Qt import (QWidget, QSpinBox, QDoubleSpinBox, QLineEdit, QTextEdit,
QCheckBox, QComboBox, Qt, QIcon, pyqtSignal, QLabel QCheckBox, QComboBox, Qt, QIcon, pyqtSignal, QLabel, QFontComboBox, QFont,
QFontInfo)
from calibre.customize.conversion import OptionRecommendation from calibre.customize.conversion import OptionRecommendation
from calibre.ebooks.conversion.config import load_defaults, \ from calibre.ebooks.conversion.config import load_defaults, \
@ -35,8 +36,6 @@ def bulk_defaults_for_input_format(fmt):
return load_defaults(w.COMMIT_NAME) return load_defaults(w.COMMIT_NAME)
return {} return {}
class Widget(QWidget): class Widget(QWidget):
TITLE = _('Unknown') TITLE = _('Unknown')
@ -143,6 +142,8 @@ class Widget(QWidget):
if not ans: if not ans:
ans = None ans = None
return ans return ans
elif isinstance(g, QFontComboBox):
ans = unicode(QFontInfo(g.currentFont().family()))
elif isinstance(g, EncodingComboBox): elif isinstance(g, EncodingComboBox):
ans = unicode(g.currentText()).strip() ans = unicode(g.currentText()).strip()
try: try:
@ -205,6 +206,8 @@ class Widget(QWidget):
if not val: val = '' if not val: val = ''
getattr(g, 'setPlainText', g.setText)(val) getattr(g, 'setPlainText', g.setText)(val)
getattr(g, 'setCursorPosition', lambda x: x)(0) getattr(g, 'setCursorPosition', lambda x: x)(0)
elif isinstance(g, QFontComboBox):
g.setCurrentFont(QFont(val or ''))
elif isinstance(g, EncodingComboBox): elif isinstance(g, EncodingComboBox):
if val: if val:
g.setEditText(val) g.setEditText(val)

View File

@ -19,13 +19,17 @@ class PluginWidget(Widget, Ui_Form):
def __init__(self, parent, get_option, get_help, db=None, book_id=None): def __init__(self, parent, get_option, get_help, db=None, book_id=None):
Widget.__init__(self, parent, ['paper_size', 'custom_size', Widget.__init__(self, parent, ['paper_size', 'custom_size',
'orientation', 'preserve_cover_aspect_ratio']) 'orientation', 'preserve_cover_aspect_ratio', 'pdf_serif_family',
'pdf_sans_family', 'pdf_mono_family', 'pdf_standard_font',
'pdf_default_font_size', 'pdf_mono_font_size'])
self.db, self.book_id = db, book_id self.db, self.book_id = db, book_id
for x in get_option('paper_size').option.choices: for x in get_option('paper_size').option.choices:
self.opt_paper_size.addItem(x) self.opt_paper_size.addItem(x)
for x in get_option('orientation').option.choices: for x in get_option('orientation').option.choices:
self.opt_orientation.addItem(x) self.opt_orientation.addItem(x)
for x in get_option('pdf_standard_font').option.choices:
self.opt_pdf_standard_font.addItem(x)
self.initialize_options(get_option, get_help, db, book_id) self.initialize_options(get_option, get_help, db, book_id)

View File

@ -6,14 +6,14 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>590</width>
<height>300</height> <height>395</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QFormLayout" name="formLayout">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
@ -40,26 +40,6 @@
<item row="1" column="1"> <item row="1" column="1">
<widget class="QComboBox" name="opt_orientation"/> <widget class="QComboBox" name="opt_orientation"/>
</item> </item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>213</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="opt_preserve_cover_aspect_ratio">
<property name="text">
<string>Preserve &amp;aspect ratio of cover</string>
</property>
</widget>
</item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
@ -73,6 +53,112 @@
<item row="2" column="1"> <item row="2" column="1">
<widget class="QLineEdit" name="opt_custom_size"/> <widget class="QLineEdit" name="opt_custom_size"/>
</item> </item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="opt_preserve_cover_aspect_ratio">
<property name="text">
<string>Preserve &amp;aspect ratio of cover</string>
</property>
</widget>
</item>
<item row="10" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>213</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Se&amp;rif family:</string>
</property>
<property name="buddy">
<cstring>opt_pdf_serif_family</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QFontComboBox" name="opt_pdf_serif_family"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>&amp;Sans family:</string>
</property>
<property name="buddy">
<cstring>opt_pdf_sans_family</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QFontComboBox" name="opt_pdf_sans_family"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>&amp;Monospace family:</string>
</property>
<property name="buddy">
<cstring>opt_pdf_mono_family</cstring>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QFontComboBox" name="opt_pdf_mono_family"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>S&amp;tandard font:</string>
</property>
<property name="buddy">
<cstring>opt_pdf_standard_font</cstring>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="opt_pdf_standard_font"/>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Default font si&amp;ze:</string>
</property>
<property name="buddy">
<cstring>opt_pdf_default_font_size</cstring>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="opt_pdf_default_font_size">
<property name="suffix">
<string> px</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Monospace &amp;font size:</string>
</property>
<property name="buddy">
<cstring>opt_pdf_mono_font_size</cstring>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QSpinBox" name="opt_pdf_mono_font_size">
<property name="suffix">
<string> px</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>

View File

@ -4,19 +4,19 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
# Imports {{{ # Imports {{{
import os, math, glob, json import os, math, json
from base64 import b64encode from base64 import b64encode
from functools import partial from functools import partial
from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt, pyqtProperty, from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt, pyqtProperty,
QPainter, QPalette, QBrush, QFontDatabase, QDialog, QColor, QPoint, QPainter, QPalette, QBrush, QDialog, QColor, QPoint, QImage, QRegion,
QImage, QRegion, QIcon, pyqtSignature, QAction, QMenu, QString, QIcon, pyqtSignature, QAction, QMenu, QString, pyqtSignal,
pyqtSignal, QSwipeGesture, QApplication, pyqtSlot) QSwipeGesture, QApplication, pyqtSlot)
from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings
from calibre.gui2.viewer.flip import SlideFlip from calibre.gui2.viewer.flip import SlideFlip
from calibre.gui2.shortcuts import Shortcuts from calibre.gui2.shortcuts import Shortcuts
from calibre import prints from calibre import prints, load_builtin_fonts
from calibre.customize.ui import all_viewer_plugins from calibre.customize.ui import all_viewer_plugins
from calibre.gui2.viewer.keys import SHORTCUTS from calibre.gui2.viewer.keys import SHORTCUTS
from calibre.gui2.viewer.javascript import JavaScriptLoader from calibre.gui2.viewer.javascript import JavaScriptLoader
@ -27,13 +27,6 @@ from calibre.ebooks.oeb.display.webview import load_html
from calibre.constants import isxp, iswindows from calibre.constants import isxp, iswindows
# }}} # }}}
def load_builtin_fonts():
base = P('fonts/liberation/*.ttf')
for f in glob.glob(base):
QFontDatabase.addApplicationFont(f)
return 'Liberation Serif', 'Liberation Sans', 'Liberation Mono'
class Document(QWebPage): # {{{ class Document(QWebPage): # {{{
page_turn = pyqtSignal(object) page_turn = pyqtSignal(object)