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. Convert OEB ebook format to PDF.
''' '''
import glob import glob, os
import os
from calibre.customize.conversion import OutputFormatPlugin, \ from PyQt4.Qt import QRawFont, QFont
OptionRecommendation
from calibre.constants import iswindows
from calibre.customize.conversion import (OutputFormatPlugin,
OptionRecommendation)
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
UNITS = ['millimeter', 'centimeter', 'point', 'inch' , 'pica' , 'didot', UNITS = ['millimeter', 'centimeter', 'point', 'inch' , 'pica' , 'didot',
@ -136,7 +138,7 @@ class PDFOutput(OutputFormatPlugin):
''' '''
from calibre.ebooks.oeb.base import urlnormalize from calibre.ebooks.oeb.base import urlnormalize
from calibre.gui2 import must_use_qt 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 from PyQt4.Qt import QFontDatabase, QByteArray
# First find all @font-face rules and remove them, adding the embedded # First find all @font-face rules and remove them, adding the embedded
@ -166,11 +168,13 @@ class PDFOutput(OutputFormatPlugin):
except: except:
continue continue
must_use_qt() must_use_qt()
QFontDatabase.addApplicationFontFromData(QByteArray(raw)) fid = QFontDatabase.addApplicationFontFromData(QByteArray(raw))
try:
family_name = get_font_names(raw)[0]
except:
family_name = None family_name = None
if fid > -1:
try:
family_name = unicode(QFontDatabase.applicationFontFamilies(fid)[0])
except (IndexError, KeyError):
pass
if family_name: if family_name:
family_map[icu_lower(font_family)] = family_name family_map[icu_lower(font_family)] = family_name
@ -190,6 +194,19 @@ class PDFOutput(OutputFormatPlugin):
k = icu_lower(val[i].value) k = icu_lower(val[i].value)
if k in family_map: if k in family_map:
val[i].value = family_map[k] 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): def convert_text(self, oeb_book):
from calibre.ebooks.metadata.opf2 import OPF 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, // 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 // so I have disabled it. I dont understand how it works in qpdf.cpp
QFontEngineWin *fe = static_cast<QFontEngineWin *>(ti.fontEngine); 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; size = fe->tm.tmHeight;
} }
#endif #endif

View File

@ -66,6 +66,8 @@ class Sfnt(object):
if table: if table:
self.tables[table_tag] = self.TABLE_MAP.get( self.tables[table_tag] = self.TABLE_MAP.get(
table_tag, UnknownTable)(table) table_tag, UnknownTable)(table)
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 self.sfnt_version = (b'\0\x01\0\0' if b'glyf' in self.tables
else b'OTTO') else b'OTTO')