reimplement last resort font check

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-01-10 10:04:17 +02:00
parent 61e8665fb6
commit 1fe9e3fc3d
9 changed files with 87 additions and 244 deletions

View file

@ -1254,7 +1254,7 @@ QFont QApplication::font()
{
QMutexLocker locker(applicationFontMutex());
if (!QApplicationPrivate::app_font) {
QApplicationPrivate::app_font = new QFont(QLatin1String("Helvetica"));
QApplicationPrivate::app_font = new QFont(QFont::lastResortFamily());
}
return *QApplicationPrivate::app_font;
}

View file

@ -1267,8 +1267,7 @@ void qt_init(QApplicationPrivate *priv, Display *display,
if (!QApplicationPrivate::sys_font) {
// no font from settings, provide a fallback
QFont f(qt_x11Data->has_fontconfig ? QLatin1String("Sans Serif") : QLatin1String("Helvetica"),
ptsz);
QFont f(QFont::lastResortFamily(), ptsz);
QApplicationPrivate::setSystemFont(f);
}

View file

@ -233,11 +233,10 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
If the requested font family is unavailable you can influence the
\link #fontmatching font matching algorithm\endlink by choosing a
particular \l{QFont::StyleStrategy} with setStyleStrategy(). The
default family is returned by defaultFamily().
particular \l{QFont::StyleStrategy} with setStyleStrategy().
The font-matching algorithm has a lastResortFamily() and
lastResortFont() in cases where a suitable match cannot be found.
The font-matching algorithm has a lastResortFamily() and in cases
where a suitable match cannot be found.
Every QFont has a key() which you can use, for example, as the key
in a cache or dictionary. If you want to store a user's font
@ -261,21 +260,18 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
\list 1
\o The specified font family is searched for.
\o Each replacement font family is searched for.
\o If none of these are found "helvetica" will be searched for.
\o If "helvetica" isn't found Katie will try the lastResortFamily().
\o If the lastResortFamily() isn't found Katie will try the
lastResortFont() which will always return a name of some kind.
\o If none of these are found application font will be searched for.
\o If none of these are found lastResortFamily() will be searched for.
\o If the lastResortFamily() isn't found Katie will not abort but no
text will be visible unless a valid font filepath has been set in
the global settings file or via QApplication::setFont().
\endlist
Note that the actual font matching algorithm varies from platform to platform.
Note that the actual font matching algorithm varies from platform to
platform.
In Windows a request for the "Courier" font is automatically changed to
"Courier New", an improved version of Courier that allows for smooth scaling.
The older "Courier" bitmap font can be selected by setting the PreferBitmap
style strategy (see setStyleStrategy()).
Once a font is found, the remaining attributes are matched in order of
priority:
Once a font is found, the remaining attributes are matched in order
of priority:
\list 1
\o fixedPitch()
\o pointSize() (see below)
@ -384,46 +380,6 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
i.e., X11 and some Embedded Linux platforms.
*/
/*!
\fn QString QFont::lastResortFamily() const
Returns the "last resort" font family name.
The current implementation tries a wide variety of common fonts,
returning the first one it finds. Is is possible that no family is
found in which case an empty string is returned.
\sa lastResortFont()
*/
/*!
\fn QString QFont::defaultFamily() const
Returns the family name that corresponds to the current style.
*/
/*!
\fn QString QFont::lastResortFont() const
Returns a "last resort" font name for the font matching algorithm.
This is used if the last resort family is not available. It will
always return a name, if necessary returning something like
"fixed" or "system".
The current implementation tries a wide variety of common fonts,
returning the first one it finds. The implementation may change
at any time, but this function will always return a string
containing something.
It is theoretically possible that there really isn't a
lastResortFont() in which case Qt will abort with an error
message. We have not been able to identify a case where this
happens. Please \link bughowto.html report it as a bug\endlink if
it does, preferably with a list of the fonts you have installed.
\sa lastResortFamily()
*/
/*!
Constructs a font from \a font for use on the paint device \a pd.
*/

View file

@ -182,9 +182,7 @@ public:
QString toString() const;
bool fromString(const QString &);
QString defaultFamily() const;
QString lastResortFamily() const;
QString lastResortFont() const;
static QString lastResortFamily();
QFont resolve(const QFont &) const;
inline uint resolve() const { return resolve_mask; }

View file

@ -19,27 +19,13 @@
**
****************************************************************************/
#define QT_FATAL_ASSERT
#include "qplatformdefs.h"
#include "qfont.h"
#include "qapplication.h"
#include "qfontinfo.h"
#include "qfontdatabase.h"
#include "qfontmetrics.h"
#include "qpaintdevice.h"
#include "qtextcodec.h"
#include "qunicodetables_p.h"
#include "qfontengine_p.h"
#include "qfontengine_ft_p.h"
#include "qt_x11_p.h"
#include "qx11info_x11.h"
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
QT_BEGIN_NAMESPACE
double qt_pixelSize(double pointSize, int dpi)
@ -48,7 +34,7 @@ double qt_pixelSize(double pointSize, int dpi)
return -1.;
if (dpi == 75) // the stupid 75 dpi setting on X11
dpi = 72;
return (pointSize * dpi) /72.;
return ((pointSize * dpi) / 72.0);
}
double qt_pointSize(double pixelSize, int dpi)
@ -57,7 +43,7 @@ double qt_pointSize(double pixelSize, int dpi)
return -1.;
if (dpi == 75) // the stupid 75 dpi setting on X11
dpi = 72;
return pixelSize * 72. / ((double) dpi);
return (pixelSize * 72. / double(dpi));
}
/*!
@ -100,72 +86,11 @@ FT_Face QFont::freetypeFace() const
return 0;
}
QString QFont::lastResortFamily() const
QString QFont::lastResortFamily()
{
return QString::fromLatin1("Helvetica");
}
QString QFont::defaultFamily() const
{
return QString::fromLatin1("Helvetica");
}
static const char* LastResortFontsTbl[] = {
"-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
"-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
"-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
"-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
"-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
"-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
"-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
"-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
"-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
"-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
"-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
"-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
"-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
"6x13",
"7x13",
"8x13",
"9x15",
"fixed",
};
static const qint16 LastResortFontsTblSize = 18;
/*
Returns a last resort raw font name for the font matching algorithm.
This is used if even the last resort family is not available. It
returns \e something, almost no matter what. The current
implementation tries a wide variety of common fonts, returning the
first one it finds. The implementation may change at any time.
*/
QString QFont::lastResortFont() const
{
static QString last;
// already found
if (!last.isNull())
return last;
for (qint16 i = 0; i < LastResortFontsTblSize; i++) {
int count;
char **fontNames = XListFonts(QX11Info::display(), LastResortFontsTbl[i], SHRT_MAX, &count);
if (fontNames) {
XFreeFontNames(fontNames);
}
if (count != 0) {
last = QString::fromLatin1(LastResortFontsTbl[i]);
return last;
}
}
#if defined(CHECK_NULL)
qFatal("QFontPrivate::lastResortFont: Cannot find any reasonable font");
#endif
return last;
}
QT_END_NAMESPACE

View file

@ -609,9 +609,9 @@ static FcPattern *getFcPattern(const QFontPrivate *fp, QUnicodeTables::Script sc
value.u.s = (const FcChar8 *)cs.data();
FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
// add QFont::defaultFamily() to the list, for compatibility with
// add QFont::lastResortFamily() to the list, for compatibility with
// previous versions
defaultFamily = QApplication::font().defaultFamily();
defaultFamily = QFont::lastResortFamily();
cs = defaultFamily.toUtf8();
value.u.s = (const FcChar8 *)cs.data();
FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);

View file

@ -1527,23 +1527,10 @@ static const char *helvetica_styles[4] = {
"Helvetica-Oblique",
"Helvetica-BoldOblique"
};
static const char *times_styles[4] = {
"Times-Regular",
"Times-Bold",
"Times-Italic",
"Times-BoldItalic"
};
static const char *courier_styles[4] = {
"Courier",
"Courier-Bold",
"Courier-Oblique",
"Courier-BoldOblique"
};
QByteArray QFontSubset::toType1() const
{
QFontEngine::Properties properties = fontEngine->properties();
QVector<int> reverseMap = getReverseMap();
QByteArray font;
QPdf::ByteStream s(&font);
@ -1564,12 +1551,6 @@ QByteArray QFontSubset::toType1() const
if (fontEngine->fontDef.family.contains(QLatin1String("Helvetica"))) {
psname = helvetica_styles[style];
standard_font = true;
} else if (fontEngine->fontDef.family.contains(QLatin1String("Times"))) {
psname = times_styles[style];
standard_font = true;
} else if (fontEngine->fontDef.family.contains(QLatin1String("Courier"))) {
psname = courier_styles[style];
standard_font = true;
}
}
s << "/F" << id << "-Base\n";

View file

@ -1282,87 +1282,72 @@ void tst_QDataStream::readQDateTime(QDataStream *s)
static QFont qFontData(int index)
{
switch (index)
{
case 0: return QFont("Courier", 20, QFont::Bold, true);
case 1: return QFont("Courier", 18, QFont::Bold, false);
case 2: return QFont("Courier", 16, QFont::Light, true);
case 3: return QFont("Courier", 14, QFont::Normal, false);
case 4: return QFont("Courier", 12, QFont::DemiBold, true);
case 5: return QFont("Courier", 10, QFont::Black, false);
case 6:
{
QFont f("Helvetica", 10, QFont::Normal, false);
switch (index) {
case 0: {
QFont f(QFont::lastResortFamily(), 10, QFont::Normal, false);
f.setPixelSize(2);
f.setUnderline(false);
f.setStrikeOut(false);
f.setFixedPitch(false);
return f;
}
case 7:
{
QFont f("Helvetica", 10, QFont::Bold, false);
case 1: {
QFont f(QFont::lastResortFamily(), 10, QFont::Bold, false);
f.setPixelSize(4);
f.setUnderline(true);
f.setStrikeOut(false);
f.setFixedPitch(false);
return f;
}
case 8:
{
QFont f("Helvetica", 10, QFont::Light, false);
case 2: {
QFont f(QFont::lastResortFamily(), 10, QFont::Light, false);
f.setPixelSize(6);
f.setUnderline(false);
f.setStrikeOut(true);
f.setFixedPitch(false);
return f;
}
case 9:
{
QFont f("Helvetica", 10, QFont::DemiBold, false);
case 3: {
QFont f(QFont::lastResortFamily(), 10, QFont::DemiBold, false);
f.setPixelSize(8);
f.setUnderline(false);
f.setStrikeOut(false);
f.setFixedPitch(true);
return f;
}
case 10:
{
QFont f("Helvetica", 10, QFont::Black, false);
case 4: {
QFont f(QFont::lastResortFamily(), 10, QFont::Black, false);
f.setPixelSize(10);
f.setUnderline(true);
f.setStrikeOut(true);
f.setFixedPitch(false);
return f;
}
case 11:
{
QFont f("Helvetica", 10, QFont::Normal, true);
case 5: {
QFont f(QFont::lastResortFamily(), 10, QFont::Normal, true);
f.setPixelSize(12);
f.setUnderline(false);
f.setStrikeOut(true);
f.setFixedPitch(true);
return f;
}
case 12:
{
QFont f("Helvetica", 10, QFont::Bold, true);
case 6: {
QFont f(QFont::lastResortFamily(), 10, QFont::Bold, true);
f.setPixelSize(14);
f.setUnderline(true);
f.setStrikeOut(true);
f.setFixedPitch(true);
return f;
}
case 13:
{
QFont f("Helvetica", 10, QFont::Bold, true);
case 7: {
QFont f(QFont::lastResortFamily(), 10, QFont::Bold, true);
f.setStretch(200);
return f;
}
}
return QFont("Courier", 18, QFont::Bold, true);
Q_UNREACHABLE();
}
#define MAX_QFONT_DATA 14
#define MAX_QFONT_DATA 8
void tst_QDataStream::stream_QFont_data()
{

View file

@ -55,7 +55,7 @@ private slots:
void resetFont();
void isCopyOf();
void italicOblique();
void lastResortFont();
void lastResortFamily();
};
// Testing get/set functions
@ -317,10 +317,9 @@ void tst_QFont::isCopyOf()
QVERIFY(!font3.isCopyOf(font));
}
void tst_QFont::lastResortFont()
void tst_QFont::lastResortFamily()
{
QFont font;
QVERIFY(!font.lastResortFont().isEmpty());
QVERIFY(!QFont::lastResortFamily().isEmpty());
}
QTEST_MAIN(tst_QFont)