Disable font antialiasing in QtQuick Text element
-
Hello everybody,
I would like to turn-off font antialiasing for a Text element in QtQuick 2.I tried to set both
@
antialiasing: false
@
and
@
renderType: Text.NativeRendering
@but nothing changes... how can I do that? Is it possible?
-
No it is not currently possible to do this with QtQuick 2.
There are two related properties in QQuickItem ("antialiasing" and "smooth") but none will affect the rendering of the text itself as the glyphs are pixmaps that have already been either rasterised by the operating system or they are drawn using shaders. There is not really any significant performance gain by disabling this so I am a bit puzzled that you want it.
In theory there are some undocumented internal defines you could play with if you custom-compile Qt that modify how distance field text rendering is drawn and in theory could force the aliasing effects if you really want them, but at no performance gain:
#define QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE 54
#define QT_DISTANCEFIELD_DEFAULT_TILESIZE 64
#define QT_DISTANCEFIELD_DEFAULT_SCALE 16
#define QT_DISTANCEFIELD_DEFAULT_RADIUS 80
#define QT_DISTANCEFIELD_HIGHGLYPHCOUNT 2000 -
Thank you Jens, for your reply.
Actually I am willing to disable antialiasing because I am developing an application for an embedded device having a display with very low dpi (and low color depth) and in such a scenario antialiasing is not as good as expected...
Your insights about QT_DISTANCEFIELD_* seems interesting... can you tell me something more about that? Or even can you point me out where I can find some other info about that?
-
Yes disabling antialiasing is probably not what you want. I suspect it could be that the default settings we use for distance field rendering is just not optimal for your DPI and needs to be sharpened up.
Since you most likely build your own version of Qt you can simply look up the source code for qdistancefield_p.h in the qtdeclarative module as it contains the defines I am talking about. I don't have a good explanation for them though. They are a bit of "fudge" factors tweaked to look good so I would suggest you perhaps just make them into environment variables and play with some different settings on your device. I think "scale" and "radius" would be the most important to tweak.
-
Keep in mind that they have no effect when using Qt.NativeTextRendering.
-
Thank you Jens for your time. I am going to play with what you've described and I'll let you know if it is enough for workarounding my problem.
Anyway are you aware if there are plannings to introduce the possibility to disable text antialiasing in future versions of Qt ? I think it would be nice to turn-off antialiasing by request... It could help to easily handle "special" application scenario, like mine...
-
I don't think there are any plans in the pipeline to support this. You could of course raise it as a suggestion task.
https://bugreports.qt-project.org/browse/QTBUG-28993 seems related. Perhaps you could see if QML_DISABLE_DISTANCEFIELD has an effect as well.
-
Jens,
I still had no time to experiment with DISTANCEFIELDS (I'll do it ASAP and let you know)... but anyway I would like to submit here a different approach I am experimenting for having text without antialias...I thought: if I cannot do that directly, maybe I can do it rendering a image off-screen (with the desired antialiasing attributes) and the presenting it on the screen)...
Here is my code, and... it works! (I post it since it could be useful for someone else):
imageprovider.h:
@
#ifndef IMAGEPROVIDER_H
#define IMAGEPROVIDER_H#include <QQuickImageProvider>
#include <QQmlImageProviderBase>
#include <QPixmap>
#include <QPainter>
#include <QDebug>class ImageProvider : public QQuickImageProvider
{
public:
ImageProvider();QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize);
};
#endif // IMAGEPROVIDER_H
@imageprovider.cpp:
@
#include "imageprovider.h"ImageProvider::ImageProvider() : QQuickImageProvider(QQmlImageProviderBase::Pixmap, 0)
{
}QPixmap ImageProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize)
{
bool aa = false;QString text = "my text here"; QFont font("Arial", size); if(aa) { font.setHintingPreference(QFont::PreferFullHinting); font.setStyleStrategy(QFont::PreferAntialias); } else { font.setHintingPreference(QFont::PreferNoHinting); font.setStyleStrategy(QFont::NoAntialias); } QFontMetrics fm(font); QPixmap pix(fm.width(text), fm.height()); QPainter painter(&pix); pix.fill(Qt::black); painter.setFont(font); painter.setBrush(QBrush(Qt::white)); painter.setPen(Qt::white); if(aa) { painter.setRenderHint(QPainter::Antialiasing, true); painter.setRenderHint(QPainter::TextAntialiasing, true); } else { painter.setRenderHint(QPainter::Antialiasing, false); painter.setRenderHint(QPainter::TextAntialiasing, false); } painter.drawText(pix.rect(), text, QTextOption(Qt::AlignCenter)); return(pix);
}
@main.cpp:
@
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <QtQml>#include "imageprovider.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);QtQuick2ApplicationViewer viewer; viewer.engine()->addImageProvider("testimage", new ImageProvider()); viewer.setMainQmlFile(QStringLiteral("qml/TestQtQuick5/test.qml")); viewer.showExpanded(); return app.exec();
}
@and then in my QML file:
@
/* [...] /
Image {
source: "image://testimage/myimage"
}
/ [...] */
@ -
You could probably do a similar approach even simpler by using QQuickPaintedItem or even just a Canvas item in QML. While it would technically work, I don't think I would recommend it as you lose all benefits of hardware acceleration and the performance memory cost would be significant for all but the most simple use cases. However you might even want to consider using Qt Quick 1 on your device as it still works and supports the antialiasing property directly.