Revert "Fix application font removal when using FontConfig"

This reverts commit a4ff400e25.
The patch caused a regression for bold fonts which is currently
blocking the alpha of Qt 5.3, so lets revert it and try
resubmitting a fixed version later to avoid delaying any release.

Task-number: QTBUG-36929
Change-Id: I8d474b09b2270eb2f861853e60605429be08e2d9
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2014-02-21 11:31:18 +01:00 committed by The Qt Project
parent a0ebaca9cb
commit e1fd82981c
5 changed files with 113 additions and 163 deletions

View File

@ -331,8 +331,10 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
return stylehint;
}
static void populateFromPattern(FcPattern *pattern)
void QFontconfigDatabase::populateFontDatabase()
{
FcFontSet *fonts;
QString familyName;
FcChar8 *value = 0;
int weight_value;
@ -346,110 +348,6 @@ static void populateFromPattern(FcPattern *pattern)
FcBool scalable;
FcBool antialias;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) != FcResultMatch)
return;
familyName = QString::fromUtf8((const char *)value);
slant_value = FC_SLANT_ROMAN;
weight_value = FC_WEIGHT_REGULAR;
spacing_value = FC_PROPORTIONAL;
file_value = 0;
indexValue = 0;
scalable = FcTrue;
if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant_value) != FcResultMatch)
slant_value = FC_SLANT_ROMAN;
if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight_value) != FcResultMatch)
weight_value = FC_WEIGHT_REGULAR;
if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width_value) != FcResultMatch)
width_value = FC_WIDTH_NORMAL;
if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
spacing_value = FC_PROPORTIONAL;
if (FcPatternGetString(pattern, FC_FILE, 0, &file_value) != FcResultMatch)
file_value = 0;
if (FcPatternGetInteger(pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
indexValue = 0;
if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
scalable = FcTrue;
if (FcPatternGetString(pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
foundry_value = 0;
if (FcPatternGetString(pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
style_value = 0;
if (FcPatternGetBool(pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
antialias = true;
QSupportedWritingSystems writingSystems;
FcLangSet *langset = 0;
FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
if (res == FcResultMatch) {
bool hasLang = false;
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) {
writingSystems.setSupported(QFontDatabase::WritingSystem(j));
hasLang = true;
}
}
}
if (!hasLang)
// none of our known languages, add it to the other set
writingSystems.setSupported(QFontDatabase::Other);
} else {
// we set Other to supported for symbol fonts. It makes no
// sense to merge these with other ones, as they are
// special in a way.
writingSystems.setSupported(QFontDatabase::Other);
}
#if FC_VERSION >= 20297
for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
if (writingSystems.supported(QFontDatabase::WritingSystem(j))
&& requiresOpenType(j) && openType[j]) {
FcChar8 *cap;
res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap);
if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
}
}
#endif
FontFile *fontFile = new FontFile;
fontFile->fileName = QLatin1String((const char *)file_value);
fontFile->indexValue = indexValue;
QFont::Style style = (slant_value == FC_SLANT_ITALIC)
? QFont::StyleItalic
: ((slant_value == FC_SLANT_OBLIQUE)
? QFont::StyleOblique
: QFont::StyleNormal);
// Note: weight should really be an int but registerFont incorrectly uses an enum
QFont::Weight weight = QFont::Weight(weightFromFcWeight(weight_value));
double pixel_size = 0;
if (!scalable)
FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixel_size);
bool fixedPitch = spacing_value >= FC_MONO;
// Note: stretch should really be an int but registerFont incorrectly uses an enum
QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
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;
for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k)
QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
}
void QFontconfigDatabase::populateFontDatabase()
{
FcInitReinitialize();
FcFontSet *fonts;
{
FcObjectSet *os = FcObjectSetCreate();
FcPattern *pattern = FcPatternCreate();
@ -473,8 +371,103 @@ void QFontconfigDatabase::populateFontDatabase()
FcPatternDestroy(pattern);
}
for (int i = 0; i < fonts->nfont; i++)
populateFromPattern(fonts->fonts[i]);
for (int i = 0; i < fonts->nfont; i++) {
if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
continue;
// capitalize(value);
familyName = QString::fromUtf8((const char *)value);
slant_value = FC_SLANT_ROMAN;
weight_value = FC_WEIGHT_REGULAR;
spacing_value = FC_PROPORTIONAL;
file_value = 0;
indexValue = 0;
scalable = FcTrue;
if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
slant_value = FC_SLANT_ROMAN;
if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
weight_value = FC_WEIGHT_REGULAR;
if (FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width_value) != FcResultMatch)
width_value = FC_WIDTH_NORMAL;
if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
spacing_value = FC_PROPORTIONAL;
if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
file_value = 0;
if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch)
indexValue = 0;
if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
scalable = FcTrue;
if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
foundry_value = 0;
if (FcPatternGetString(fonts->fonts[i], FC_STYLE, 0, &style_value) != FcResultMatch)
style_value = 0;
if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch)
antialias = true;
QSupportedWritingSystems writingSystems;
FcLangSet *langset = 0;
FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
if (res == FcResultMatch) {
bool hasLang = false;
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) {
writingSystems.setSupported(QFontDatabase::WritingSystem(j));
hasLang = true;
}
}
}
if (!hasLang)
// none of our known languages, add it to the other set
writingSystems.setSupported(QFontDatabase::Other);
} else {
// we set Other to supported for symbol fonts. It makes no
// sense to merge these with other ones, as they are
// special in a way.
writingSystems.setSupported(QFontDatabase::Other);
}
#if FC_VERSION >= 20297
for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
if (writingSystems.supported(QFontDatabase::WritingSystem(j))
&& requiresOpenType(j) && openType[j]) {
FcChar8 *cap;
res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
}
}
#endif
FontFile *fontFile = new FontFile;
fontFile->fileName = QLatin1String((const char *)file_value);
fontFile->indexValue = indexValue;
QFont::Style style = (slant_value == FC_SLANT_ITALIC)
? QFont::StyleItalic
: ((slant_value == FC_SLANT_OBLIQUE)
? QFont::StyleOblique
: QFont::StyleNormal);
// Note: weight should really be an int but registerFont incorrectly uses an enum
QFont::Weight weight = QFont::Weight(weightFromFcWeight(weight_value));
double pixel_size = 0;
if (!scalable)
FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
bool fixedPitch = spacing_value >= FC_MONO;
// Note: stretch should really be an int but registerFont incorrectly uses an enum
QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
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;
for (int k = 1; FcPatternGetString(fonts->fonts[i], FC_FAMILY, k, &value) == FcResultMatch; ++k)
QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
}
FcFontSetDestroy (fonts);
@ -522,12 +515,14 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
return 0;
QFontDef fontDef = f;
QFontEngineFT *engine;
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
QFontEngine::FaceId fid;
fid.filename = QFile::encodeName(fontfile->fileName);
fid.index = fontfile->indexValue;
bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
engine = new QFontEngineFT(fontDef);
QFontEngineFT::GlyphFormat format;
// try and get the pattern
@ -552,19 +547,7 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
FcDefaultSubstitute(pattern);
FcPattern *match = FcFontMatch(0, pattern, &result);
QFontEngineFT *engine = new QFontEngineFT(fontDef);
if (match) {
//Respect the file and index of the font config match
FcChar8 *file_value;
int indexValue;
if (FcPatternGetString(match, FC_FILE, 0, &file_value) == FcResultMatch)
fid.filename = (const char *)file_value;
if (FcPatternGetInteger(match, FC_INDEX, 0, &indexValue) == FcResultMatch)
fid.index = indexValue;
QFontEngineFT::HintStyle default_hint_style;
if (f.hintingPreference != QFont::PreferDefaultHinting) {
switch (f.hintingPreference) {
@ -641,14 +624,12 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
format = subpixelType == QFontEngineFT::Subpixel_None
? QFontEngineFT::Format_A8 : QFontEngineFT::Format_A32;
engine->subpixelType = subpixelType;
} else {
} else
format = QFontEngineFT::Format_Mono;
}
FcPatternDestroy(match);
} else {
} else
format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
}
FcPatternDestroy(pattern);
@ -762,7 +743,6 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
QStringList families;
FcFontSet *set = FcConfigGetFonts(0, FcSetApplication);
if (!set) {
FcConfigAppFontAddFile(0, (const FcChar8 *)":/non-existent");
@ -775,24 +755,28 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
FcBlanks *blanks = FcConfigGetBlanks(0);
int count = 0;
FcPattern *pattern;
FcPattern *pattern = 0;
do {
pattern = queryFont((const FcChar8 *)QFile::encodeName(fileName).constData(),
fontData, id, blanks, &count);
if (!pattern)
return families;
FcPatternDel(pattern, FC_FILE);
QByteArray cs = fileName.toUtf8();
FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData());
FcChar8 *fam = 0;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
families << family;
}
populateFromPattern(pattern);
FcFontSetAdd(set, pattern);
if (!FcFontSetAdd(set, pattern))
return families;
++id;
} while (id < count);
} while (pattern && id < count);
return families;
}

Binary file not shown.

View File

@ -1,34 +0,0 @@
Font: LED Real (led_real.ttf)
Created By: Matthew Welch
E-Mail: daffy-duck@worldnet.att.net
Web Address: http://home.att.net/~daffy-duck
(PGP public key available here)
LED Real, like all of my fonts, is free. You can use it for most
personal or business uses you'd like, and I ask for no money. I
would, however, like to hear from you. If you use my fonts for
something please send me a postcard or e-mail letting me know how
you used it. Send me a copy if you can or let me know where I can
find your work.
You may use this font for graphical or printed work, but you may not
sell it or include it in a collection of fonts (on CD or otherwise)
being sold. You can redistribute this font as long as you charge
nothing to receive it. If you redistribute it include this text file
with it as is (without modifications).
If you use this font for commercial purposes please credit me in
at least some little way.
About the font:
Unlike most LED/LCD style fonts mine could be recreated with an
actual LED. I created this font working from memories of the good
old Speak and Spell display. Since I don't have an actual Speak
and Spell to work from I had to just do as well as I could in its
spirit. Be warned that some characters look just like others. The
( and the <, for instance. Also C and [. Most of these will be
pretty clear in context. To see all the sections of the LED "lit
up" at once use character 127 (hold down alt and type 0127 on the
numeric keypad). This font is, of course, monospaced.

View File

@ -83,7 +83,7 @@ private:
};
tst_QFontDatabase::tst_QFontDatabase()
: m_testFont(QFINDTESTDATA("LED_REAL.TTF"))
: m_testFont(QFINDTESTDATA("FreeMono.ttf"))
{
}