mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix crash when generating covers with Qt 5.8 on linux
This commit is contained in:
parent
73e9043976
commit
4e5287e923
@ -1,31 +1,37 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
@ -70,12 +76,6 @@ static inline int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper,
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool requiresOpenType(int writingSystem)
|
||||
{
|
||||
return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
|
||||
|| writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
|
||||
}
|
||||
|
||||
static inline int weightFromFcWeight(int fcweight)
|
||||
{
|
||||
// Font Config uses weights from 0 to 215 (the highest enum value) while QFont ranges from
|
||||
@ -146,7 +146,7 @@ static inline int stretchFromFcWidth(int fcwidth)
|
||||
return qtstretch;
|
||||
}
|
||||
|
||||
static const char *specialLanguages[] = {
|
||||
static const char specialLanguages[][6] = {
|
||||
"", // Unknown
|
||||
"", // Inherited
|
||||
"", // Common
|
||||
@ -289,12 +289,12 @@ static const char *specialLanguages[] = {
|
||||
#endif // Qt >= 5.5.0
|
||||
|
||||
};
|
||||
Q_STATIC_ASSERT(sizeof(specialLanguages) / sizeof(const char *) == QChar::ScriptCount);
|
||||
Q_STATIC_ASSERT(sizeof specialLanguages / sizeof *specialLanguages == QChar::ScriptCount);
|
||||
|
||||
// this could become a list of all languages used for each writing
|
||||
// system, instead of using the single most common language.
|
||||
static const char *languageForWritingSystem[] = {
|
||||
0, // Any
|
||||
static const char languageForWritingSystem[][6] = {
|
||||
"", // Any
|
||||
"en", // Latin
|
||||
"el", // Greek
|
||||
"ru", // Cyrillic
|
||||
@ -324,25 +324,25 @@ static const char *languageForWritingSystem[] = {
|
||||
"ja", // Japanese
|
||||
"ko", // Korean
|
||||
"vi", // Vietnamese
|
||||
0, // Symbol
|
||||
"", // Symbol
|
||||
"sga", // Ogham
|
||||
"non", // Runic
|
||||
"man" // N'Ko
|
||||
};
|
||||
Q_STATIC_ASSERT(sizeof(languageForWritingSystem) / sizeof(const char *) == QFontDatabase::WritingSystemsCount);
|
||||
Q_STATIC_ASSERT(sizeof languageForWritingSystem / sizeof *languageForWritingSystem == QFontDatabase::WritingSystemsCount);
|
||||
|
||||
#if FC_VERSION >= 20297
|
||||
// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
|
||||
// open type tables for is directly. Do this so we don't pick some strange
|
||||
// pseudo unicode font
|
||||
static const char *openType[] = {
|
||||
0, // Any
|
||||
0, // Latin
|
||||
0, // Greek
|
||||
0, // Cyrillic
|
||||
0, // Armenian
|
||||
0, // Hebrew
|
||||
0, // Arabic
|
||||
// Newer FontConfig let's us sort out fonts that report certain scripts support,
|
||||
// but no open type tables for handling them correctly.
|
||||
// Check the reported script presence in the FC_CAPABILITY's "otlayout:" section.
|
||||
static const char capabilityForWritingSystem[][5] = {
|
||||
"", // Any
|
||||
"", // Latin
|
||||
"", // Greek
|
||||
"", // Cyrillic
|
||||
"", // Armenian
|
||||
"", // Hebrew
|
||||
"", // Arabic
|
||||
"syrc", // Syriac
|
||||
"thaa", // Thaana
|
||||
"deva", // Devanagari
|
||||
@ -359,23 +359,23 @@ static const char *openType[] = {
|
||||
"knda", // Kannada
|
||||
"mlym", // Malayalam
|
||||
"sinh", // Sinhala
|
||||
0, // Thai
|
||||
0, // Lao
|
||||
"", // Thai
|
||||
"", // Lao
|
||||
"tibt", // Tibetan
|
||||
"mymr", // Myanmar
|
||||
0, // Georgian
|
||||
"", // Georgian
|
||||
"khmr", // Khmer
|
||||
0, // SimplifiedChinese
|
||||
0, // TraditionalChinese
|
||||
0, // Japanese
|
||||
0, // Korean
|
||||
0, // Vietnamese
|
||||
0, // Symbol
|
||||
0, // Ogham
|
||||
0, // Runic
|
||||
"", // SimplifiedChinese
|
||||
"", // TraditionalChinese
|
||||
"", // Japanese
|
||||
"", // Korean
|
||||
"", // Vietnamese
|
||||
"", // Symbol
|
||||
"", // Ogham
|
||||
"", // Runic
|
||||
"nko " // N'Ko
|
||||
};
|
||||
Q_STATIC_ASSERT(sizeof(openType) / sizeof(const char *) == QFontDatabase::WritingSystemsCount);
|
||||
Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount);
|
||||
#endif
|
||||
|
||||
static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
|
||||
@ -404,9 +404,18 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
|
||||
return stylehint;
|
||||
}
|
||||
|
||||
static inline bool requiresOpenType(int writingSystem)
|
||||
{
|
||||
return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
|
||||
|| writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
|
||||
}
|
||||
|
||||
static void populateFromPattern(FcPattern *pattern)
|
||||
{
|
||||
QString familyName;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
||||
QString familyNameLang;
|
||||
#endif
|
||||
FcChar8 *value = 0;
|
||||
int weight_value;
|
||||
int slant_value;
|
||||
@ -423,7 +432,10 @@ static void populateFromPattern(FcPattern *pattern)
|
||||
return;
|
||||
|
||||
familyName = QString::fromUtf8((const char *)value);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
||||
if (FcPatternGetString(pattern, FC_FAMILYLANG, 0, &value) == FcResultMatch)
|
||||
familyNameLang = QString::fromUtf8((const char *)value);
|
||||
#endif
|
||||
slant_value = FC_SLANT_ROMAN;
|
||||
weight_value = FC_WEIGHT_REGULAR;
|
||||
spacing_value = FC_PROPORTIONAL;
|
||||
@ -458,11 +470,23 @@ static void populateFromPattern(FcPattern *pattern)
|
||||
FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
|
||||
if (res == FcResultMatch) {
|
||||
bool hasLang = false;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) && FC_VERSION >= 20297
|
||||
FcChar8 *cap = Q_NULLPTR;
|
||||
FcResult capRes = FcResultNoMatch;
|
||||
#endif
|
||||
for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
|
||||
const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
|
||||
if (lang) {
|
||||
FcLangResult langRes = FcLangSetHasLang(langset, lang);
|
||||
if (langRes != FcLangDifferentLang) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) && FC_VERSION >= 20297
|
||||
if (*capabilityForWritingSystem[j] && requiresOpenType(j)) {
|
||||
if (cap == Q_NULLPTR)
|
||||
capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap);
|
||||
if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == 0)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
writingSystems.setSupported(QFontDatabase::WritingSystem(j));
|
||||
hasLang = true;
|
||||
}
|
||||
@ -478,13 +502,13 @@ static void populateFromPattern(FcPattern *pattern)
|
||||
writingSystems.setSupported(QFontDatabase::Other);
|
||||
}
|
||||
|
||||
#if FC_VERSION >= 20297
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 8, 0)) && FC_VERSION >= 20297
|
||||
for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
|
||||
if (writingSystems.supported(QFontDatabase::WritingSystem(j))
|
||||
&& requiresOpenType(j) && openType[j]) {
|
||||
&& requiresOpenType(j) && capabilityForWritingSystem[j]) {
|
||||
FcChar8 *cap;
|
||||
res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap);
|
||||
if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
|
||||
if (res != FcResultMatch || !strstr((const char *)cap, capabilityForWritingSystem[j]))
|
||||
writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
|
||||
}
|
||||
}
|
||||
@ -513,14 +537,45 @@ static void populateFromPattern(FcPattern *pattern)
|
||||
QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
|
||||
// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
||||
for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k) {
|
||||
const QString altFamilyName = QString::fromUtf8((const char *)value);
|
||||
// Extra family names can be aliases or subfamilies.
|
||||
// If it is a subfamily, register it as a separate font, so only members of the subfamily are
|
||||
// matched when the subfamily is requested.
|
||||
QString altStyleName;
|
||||
if (FcPatternGetString(pattern, FC_STYLE, k, &value) == FcResultMatch)
|
||||
altStyleName = QString::fromUtf8((const char *)value);
|
||||
else
|
||||
altStyleName = styleName;
|
||||
|
||||
QString altFamilyNameLang;
|
||||
if (FcPatternGetString(pattern, FC_FAMILYLANG, k, &value) == FcResultMatch)
|
||||
altFamilyNameLang = QString::fromUtf8((const char *)value);
|
||||
else
|
||||
altFamilyNameLang = familyNameLang;
|
||||
|
||||
if (familyNameLang == altFamilyNameLang && altStyleName != styleName) {
|
||||
FontFile *altFontFile = new FontFile(*fontFile);
|
||||
QPlatformFontDatabase::registerFont(altFamilyName, altStyleName, QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile);
|
||||
} else {
|
||||
QPlatformFontDatabase::registerAliasToFontFamily(familyName, altFamilyName);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k)
|
||||
QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void QFontconfigDatabase::populateFontDatabase()
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
||||
FcInit();
|
||||
#else
|
||||
FcInitReinitialize();
|
||||
#endif
|
||||
FcFontSet *fonts;
|
||||
|
||||
{
|
||||
@ -531,6 +586,9 @@ void QFontconfigDatabase::populateFontDatabase()
|
||||
FC_SPACING, FC_FILE, FC_INDEX,
|
||||
FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
|
||||
FC_WIDTH,
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
||||
FC_FAMILYLANG,
|
||||
#endif
|
||||
#if FC_VERSION >= 20297
|
||||
FC_CAPABILITY,
|
||||
#endif
|
||||
@ -584,6 +642,14 @@ void QFontconfigDatabase::populateFontDatabase()
|
||||
// QApplication::setFont(font);
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
||||
void QFontconfigDatabase::invalidate()
|
||||
{
|
||||
// Clear app fonts.
|
||||
FcConfigAppFontClear(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
|
||||
{
|
||||
return new QFontEngineMultiFontConfig(fontEngine, script);
|
||||
|
@ -22,6 +22,9 @@ class QFontconfigDatabase : public QBasicFontDatabase
|
||||
public:
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0))
|
||||
void populateFontDatabase() Q_DECL_OVERRIDE;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
||||
void invalidate() Q_DECL_OVERRIDE;
|
||||
#endif
|
||||
QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) Q_DECL_OVERRIDE;
|
||||
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
|
||||
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) Q_DECL_OVERRIDE;
|
||||
|
@ -138,6 +138,9 @@ class BuildTest(unittest.TestCase):
|
||||
os.environ.pop('DISPLAY', None)
|
||||
app = Application([], headless=islinux)
|
||||
self.assertGreaterEqual(len(QFontDatabase().families()), 5, 'The QPA headless plugin is not able to locate enough system fonts via fontconfig')
|
||||
if islinux:
|
||||
from calibre.ebooks.covers import create_cover
|
||||
create_cover('xxx', ['yyy'])
|
||||
na = QNetworkAccessManager()
|
||||
self.assertTrue(hasattr(na, 'sslErrors'), 'Qt not compiled with openssl')
|
||||
from PyQt5.QtWebKitWidgets import QWebView
|
||||
|
Loading…
x
Reference in New Issue
Block a user