PDF Output: Fix OpenType fonts causing conversion to fail on windows

This commit is contained in:
Kovid Goyal 2013-01-03 15:35:05 +05:30
parent b33929bbae
commit 2d37f94143
3 changed files with 33 additions and 12 deletions

View File

@ -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

View File

@ -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<QFontEngineWin *>(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

View File

@ -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]