Support antialias and rgba Xft settings as used by GNOME and UNITY
We only parsed the hintstyle from the Xft settings. This patch adds parsing for also subpixel style and disabling antialiasing. Task-number: QTBUG-27106 Change-Id: Icdb88ccc10e50d76eb30a5b126bee7590e257022 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>bb10
parent
20c14d87f2
commit
6efa8cd70a
|
|
@ -516,7 +516,7 @@ QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine,
|
|||
}
|
||||
|
||||
namespace {
|
||||
QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintingPreference, FcPattern *match)
|
||||
QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintingPreference, FcPattern *match, bool useXftConf)
|
||||
{
|
||||
switch (hintingPreference) {
|
||||
case QFont::PreferNoHinting:
|
||||
|
|
@ -529,8 +529,7 @@ QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintin
|
|||
break;
|
||||
}
|
||||
|
||||
const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
|
||||
if (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")) {
|
||||
if (useXftConf) {
|
||||
void *hintStyleResource =
|
||||
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
|
||||
QGuiApplication::primaryScreen());
|
||||
|
|
@ -558,8 +557,17 @@ QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintin
|
|||
return QFontEngine::HintFull;
|
||||
}
|
||||
|
||||
QFontEngine::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match)
|
||||
QFontEngine::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match, bool useXftConf)
|
||||
{
|
||||
if (useXftConf) {
|
||||
void *subpixelTypeResource =
|
||||
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("subpixeltype",
|
||||
QGuiApplication::primaryScreen());
|
||||
int subpixelType = int(reinterpret_cast<qintptr>(subpixelTypeResource));
|
||||
if (subpixelType > 0)
|
||||
return QFontEngine::SubpixelAntialiasingType(subpixelType - 1);
|
||||
}
|
||||
|
||||
int subpixel = FC_RGBA_UNKNOWN;
|
||||
FcPatternGetInteger(match, FC_RGBA, 0, &subpixel);
|
||||
|
||||
|
|
@ -596,8 +604,22 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
|
|||
fid.index = fontfile->indexValue;
|
||||
|
||||
bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
|
||||
bool forcedAntialiasSetting = !antialias;
|
||||
engine = new QFontEngineFT(fontDef);
|
||||
|
||||
const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
|
||||
bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY"));
|
||||
if (useXftConf) {
|
||||
void *antialiasResource =
|
||||
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled",
|
||||
QGuiApplication::primaryScreen());
|
||||
int antialiasingEnabled = int(reinterpret_cast<qintptr>(antialiasResource));
|
||||
if (antialiasingEnabled > 0) {
|
||||
antialias = antialiasingEnabled - 1;
|
||||
forcedAntialiasSetting = true;
|
||||
}
|
||||
}
|
||||
|
||||
QFontEngine::GlyphFormat format;
|
||||
// try and get the pattern
|
||||
FcPattern *pattern = FcPatternCreate();
|
||||
|
|
@ -622,7 +644,7 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
|
|||
|
||||
FcPattern *match = FcFontMatch(0, pattern, &result);
|
||||
if (match) {
|
||||
engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)f.hintingPreference, match));
|
||||
engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)f.hintingPreference, match, useXftConf));
|
||||
|
||||
FcBool fc_autohint;
|
||||
if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch)
|
||||
|
|
@ -634,18 +656,16 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
|
|||
engine->lcdFilterType = lcdFilter;
|
||||
#endif
|
||||
|
||||
if (antialias) {
|
||||
// If antialiasing is not fully disabled, fontconfig may still disable it on a font match basis.
|
||||
if (!forcedAntialiasSetting) {
|
||||
FcBool fc_antialias;
|
||||
if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) != FcResultMatch)
|
||||
fc_antialias = true;
|
||||
antialias = fc_antialias;
|
||||
if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch)
|
||||
antialias = fc_antialias;
|
||||
}
|
||||
|
||||
if (antialias) {
|
||||
QFontEngine::SubpixelAntialiasingType subpixelType = QFontEngine::Subpixel_None;
|
||||
if (!(f.styleStrategy & QFont::NoSubpixelAntialias))
|
||||
subpixelType = subpixelTypeFromMatch(match);
|
||||
subpixelType = subpixelTypeFromMatch(match, useXftConf);
|
||||
engine->subpixelType = subpixelType;
|
||||
|
||||
format = (subpixelType == QFontEngine::Subpixel_None)
|
||||
|
|
@ -676,6 +696,20 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal p
|
|||
|
||||
QFontDef fontDef = engine->fontDef;
|
||||
|
||||
bool forcedAntialiasSetting = false;
|
||||
const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
|
||||
bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY"));
|
||||
if (useXftConf) {
|
||||
void *antialiasResource =
|
||||
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled",
|
||||
QGuiApplication::primaryScreen());
|
||||
int antialiasingEnabled = int(reinterpret_cast<qintptr>(antialiasResource));
|
||||
if (antialiasingEnabled > 0) {
|
||||
engine->antialias = antialiasingEnabled - 1;
|
||||
forcedAntialiasSetting = true;
|
||||
}
|
||||
}
|
||||
|
||||
QFontEngine::GlyphFormat format;
|
||||
// try and get the pattern
|
||||
FcPattern *pattern = FcPatternCreate();
|
||||
|
|
@ -693,7 +727,7 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal p
|
|||
|
||||
FcPattern *match = FcFontMatch(0, pattern, &result);
|
||||
if (match) {
|
||||
engine->setDefaultHintStyle(defaultHintStyleFromMatch(hintingPreference, match));
|
||||
engine->setDefaultHintStyle(defaultHintStyleFromMatch(hintingPreference, match, useXftConf));
|
||||
|
||||
FcBool fc_autohint;
|
||||
if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch)
|
||||
|
|
@ -705,13 +739,14 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal p
|
|||
engine->lcdFilterType = lcdFilter;
|
||||
#endif
|
||||
|
||||
FcBool fc_antialias;
|
||||
if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) != FcResultMatch)
|
||||
fc_antialias = true;
|
||||
engine->antialias = fc_antialias;
|
||||
if (!forcedAntialiasSetting) {
|
||||
FcBool fc_antialias;
|
||||
if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch)
|
||||
engine->antialias = fc_antialias;
|
||||
}
|
||||
|
||||
if (engine->antialias) {
|
||||
QFontEngine::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match);
|
||||
QFontEngine::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match, useXftConf);
|
||||
engine->subpixelType = subpixelType;
|
||||
|
||||
format = subpixelType == QFontEngine::Subpixel_None
|
||||
|
|
|
|||
|
|
@ -85,7 +85,8 @@ static int resourceType(const QByteArray &key)
|
|||
QByteArrayLiteral("appusertime"), QByteArrayLiteral("hintstyle"),
|
||||
QByteArrayLiteral("startupid"), QByteArrayLiteral("traywindow"),
|
||||
QByteArrayLiteral("gettimestamp"), QByteArrayLiteral("x11screen"),
|
||||
QByteArrayLiteral("rootwindow")
|
||||
QByteArrayLiteral("rootwindow"),
|
||||
QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingEnabled")
|
||||
};
|
||||
const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
|
||||
const QByteArray *result = std::find(names, end, key);
|
||||
|
|
@ -277,6 +278,12 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q
|
|||
case ScreenHintStyle:
|
||||
result = reinterpret_cast<void *>(xcbScreen->hintStyle() + 1);
|
||||
break;
|
||||
case ScreenSubpixelType:
|
||||
result = reinterpret_cast<void *>(xcbScreen->subpixelType() + 1);
|
||||
break;
|
||||
case ScreenAntialiasingEnabled:
|
||||
result = reinterpret_cast<void *>(xcbScreen->antialiasingEnabled() + 1);
|
||||
break;
|
||||
case TrayWindow:
|
||||
if (QXcbSystemTrayTracker *s = systemTrayTracker(screen))
|
||||
result = (void *)quintptr(s->trayWindow());
|
||||
|
|
|
|||
|
|
@ -73,7 +73,9 @@ public:
|
|||
TrayWindow,
|
||||
GetTimestamp,
|
||||
X11Screen,
|
||||
RootWindow
|
||||
RootWindow,
|
||||
ScreenSubpixelType,
|
||||
ScreenAntialiasingEnabled
|
||||
};
|
||||
|
||||
QXcbNativeInterface();
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
|
|||
, m_refreshRate(60)
|
||||
, m_forcedDpi(-1)
|
||||
, m_hintStyle(QFontEngine::HintStyle(-1))
|
||||
, m_subpixelType(QFontEngine::SubpixelAntialiasingType(-1))
|
||||
, m_antialiasingEnabled(-1)
|
||||
, m_xSettings(0)
|
||||
{
|
||||
if (connection->hasXRandr())
|
||||
|
|
@ -547,32 +549,52 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool QXcbScreen::xResource(const QByteArray &identifier,
|
||||
const QByteArray &expectedIdentifier,
|
||||
int *value)
|
||||
static bool parseXftInt(const QByteArray& stringValue, int *value)
|
||||
{
|
||||
Q_ASSERT(value != 0);
|
||||
bool ok;
|
||||
*value = stringValue.toInt(&ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static QFontEngine::HintStyle parseXftHintStyle(const QByteArray& stringValue)
|
||||
{
|
||||
if (stringValue == "hintfull")
|
||||
return QFontEngine::HintFull;
|
||||
else if (stringValue == "hintnone")
|
||||
return QFontEngine::HintNone;
|
||||
else if (stringValue == "hintmedium")
|
||||
return QFontEngine::HintMedium;
|
||||
else if (stringValue == "hintslight")
|
||||
return QFontEngine::HintLight;
|
||||
|
||||
return QFontEngine::HintStyle(-1);
|
||||
}
|
||||
|
||||
static QFontEngine::SubpixelAntialiasingType parseXftRgba(const QByteArray& stringValue)
|
||||
{
|
||||
if (stringValue == "none")
|
||||
return QFontEngine::Subpixel_None;
|
||||
else if (stringValue == "rgb")
|
||||
return QFontEngine::Subpixel_RGB;
|
||||
else if (stringValue == "bgr")
|
||||
return QFontEngine::Subpixel_BGR;
|
||||
else if (stringValue == "vrgb")
|
||||
return QFontEngine::Subpixel_VRGB;
|
||||
else if (stringValue == "vbgr")
|
||||
return QFontEngine::Subpixel_VBGR;
|
||||
|
||||
return QFontEngine::SubpixelAntialiasingType(-1);
|
||||
}
|
||||
|
||||
bool QXcbScreen::xResource(const QByteArray &identifier,
|
||||
const QByteArray &expectedIdentifier,
|
||||
QByteArray& stringValue)
|
||||
{
|
||||
if (identifier.startsWith(expectedIdentifier)) {
|
||||
QByteArray stringValue = identifier.mid(expectedIdentifier.size());
|
||||
|
||||
bool ok;
|
||||
*value = stringValue.toInt(&ok);
|
||||
if (!ok) {
|
||||
if (stringValue == "hintfull")
|
||||
*value = QFontEngine::HintFull;
|
||||
else if (stringValue == "hintnone")
|
||||
*value = QFontEngine::HintNone;
|
||||
else if (stringValue == "hintmedium")
|
||||
*value = QFontEngine::HintMedium;
|
||||
else if (stringValue == "hintslight")
|
||||
*value = QFontEngine::HintLight;
|
||||
|
||||
return *value != 0;
|
||||
}
|
||||
|
||||
stringValue = identifier.mid(expectedIdentifier.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -604,10 +626,18 @@ void QXcbScreen::readXResources()
|
|||
for (int i = 0; i < split.size(); ++i) {
|
||||
const QByteArray &r = split.at(i);
|
||||
int value;
|
||||
if (xResource(r, "Xft.dpi:\t", &value))
|
||||
m_forcedDpi = value;
|
||||
else if (xResource(r, "Xft.hintstyle:\t", &value))
|
||||
m_hintStyle = QFontEngine::HintStyle(value);
|
||||
QByteArray stringValue;
|
||||
if (xResource(r, "Xft.dpi:\t", stringValue)) {
|
||||
if (parseXftInt(stringValue, &value))
|
||||
m_forcedDpi = value;
|
||||
} else if (xResource(r, "Xft.hintstyle:\t", stringValue)) {
|
||||
m_hintStyle = parseXftHintStyle(stringValue);
|
||||
} else if (xResource(r, "Xft.antialias:\t", stringValue)) {
|
||||
if (parseXftInt(stringValue, &value))
|
||||
m_antialiasingEnabled = value;
|
||||
} else if (xResource(r, "Xft.rgba:\t", stringValue)) {
|
||||
m_subpixelType = parseXftRgba(stringValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,13 +104,15 @@ public:
|
|||
void readXResources();
|
||||
|
||||
QFontEngine::HintStyle hintStyle() const { return m_hintStyle; }
|
||||
QFontEngine::SubpixelAntialiasingType subpixelType() const { return m_subpixelType; }
|
||||
int antialiasingEnabled() const { return m_antialiasingEnabled; }
|
||||
|
||||
QXcbXSettings *xSettings() const;
|
||||
|
||||
private:
|
||||
static bool xResource(const QByteArray &identifier,
|
||||
const QByteArray &expectedIdentifier,
|
||||
int *value);
|
||||
const QByteArray &expectedIdentifier,
|
||||
QByteArray &stringValue);
|
||||
void sendStartupMessage(const QByteArray &message) const;
|
||||
|
||||
xcb_screen_t *m_screen;
|
||||
|
|
@ -133,6 +135,8 @@ private:
|
|||
int m_refreshRate;
|
||||
int m_forcedDpi;
|
||||
QFontEngine::HintStyle m_hintStyle;
|
||||
QFontEngine::SubpixelAntialiasingType m_subpixelType;
|
||||
int m_antialiasingEnabled;
|
||||
QXcbXSettings *m_xSettings;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue