diff --git a/src/calibre/ebooks/conversion/plugins/pdf_output.py b/src/calibre/ebooks/conversion/plugins/pdf_output.py index c2b0050dd7..44d0a6bce7 100644 --- a/src/calibre/ebooks/conversion/plugins/pdf_output.py +++ b/src/calibre/ebooks/conversion/plugins/pdf_output.py @@ -8,11 +8,13 @@ __docformat__ = 'restructuredtext en' Convert OEB ebook format to PDF. ''' -import glob -import os +import glob, os -from calibre.customize.conversion import OutputFormatPlugin, \ - OptionRecommendation +from PyQt4.Qt import QRawFont, QFont + +from calibre.constants import iswindows +from calibre.customize.conversion import (OutputFormatPlugin, + OptionRecommendation) from calibre.ptempfile import TemporaryDirectory UNITS = ['millimeter', 'centimeter', 'point', 'inch' , 'pica' , 'didot', @@ -136,7 +138,7 @@ class PDFOutput(OutputFormatPlugin): ''' from calibre.ebooks.oeb.base import urlnormalize from calibre.gui2 import must_use_qt - from calibre.utils.fonts.utils import get_font_names, remove_embed_restriction + from calibre.utils.fonts.utils import remove_embed_restriction from PyQt4.Qt import QFontDatabase, QByteArray # First find all @font-face rules and remove them, adding the embedded @@ -166,11 +168,13 @@ class PDFOutput(OutputFormatPlugin): except: continue must_use_qt() - QFontDatabase.addApplicationFontFromData(QByteArray(raw)) - try: - family_name = get_font_names(raw)[0] - except: - family_name = None + fid = QFontDatabase.addApplicationFontFromData(QByteArray(raw)) + family_name = None + if fid > -1: + try: + family_name = unicode(QFontDatabase.applicationFontFamilies(fid)[0]) + except (IndexError, KeyError): + pass if family_name: family_map[icu_lower(font_family)] = family_name @@ -190,6 +194,19 @@ class PDFOutput(OutputFormatPlugin): k = icu_lower(val[i].value) if k in family_map: val[i].value = family_map[k] + if iswindows: + # On windows, Qt uses GDI which does not support OpenType + # (CFF) fonts, so we need to nuke references to OpenType + # fonts. Note that you could compile QT with configure + # -directwrite, but that requires atleast Vista SP2 + for i in xrange(val.length): + if val[i].value: + f = QRawFont.fromFont(QFont(val[i].value)) + if len(f.fontTable('head')) == 0: + self.log.warn('Ignoring unsupported font: %s' + %val[i].value) + # Either a bitmap or (more likely) a CFF font + val[i].value = 'serif' def convert_text(self, oeb_book): from calibre.ebooks.metadata.opf2 import OPF diff --git a/src/calibre/ebooks/pdf/render/qt_hack.cpp b/src/calibre/ebooks/pdf/render/qt_hack.cpp index e5f74c0a0f..1a9a33c35f 100644 --- a/src/calibre/ebooks/pdf/render/qt_hack.cpp +++ b/src/calibre/ebooks/pdf/render/qt_hack.cpp @@ -21,6 +21,8 @@ GlyphInfo* get_glyphs(QPointF &p, const QTextItem &text_item) { // This is used in the Qt sourcecode, but it gives incorrect results, // so I have disabled it. I dont understand how it works in qpdf.cpp QFontEngineWin *fe = static_cast(ti.fontEngine); + // I think this should be tmHeight - tmInternalLeading, but pixelSize + // seems to work on windows as well, so leave it as pixelSize size = fe->tm.tmHeight; } #endif diff --git a/src/calibre/utils/fonts/sfnt/container.py b/src/calibre/utils/fonts/sfnt/container.py index 932cd6a3d2..0987869610 100644 --- a/src/calibre/utils/fonts/sfnt/container.py +++ b/src/calibre/utils/fonts/sfnt/container.py @@ -66,8 +66,10 @@ class Sfnt(object): if table: self.tables[table_tag] = self.TABLE_MAP.get( table_tag, UnknownTable)(table) - self.sfnt_version = (b'\0\x01\0\0' if b'glyf' in self.tables - else b'OTTO') + if not self.tables: + raise UnsupportedFont('This font has no tables') + self.sfnt_version = (b'\0\x01\0\0' if b'glyf' in self.tables + else b'OTTO') def __getitem__(self, key): return self.tables[key]