mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
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:
parent
a90367296c
commit
05de8b4b21
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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 &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 &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&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>&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>&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&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&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 &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/>
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user