Introduce FontSmoothingGamma as a platform style hint.
- Allocate gamma tables on the heap in a thread-safe way, use font smoothing returned by the style hints of the platform to calculate them. - Improve font rendering on Windows. Change-Id: I8cd39b51cf03cbd642474c02b9076814baecd597 Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
This commit is contained in:
parent
8d28f263aa
commit
4f92f9b725
@ -51,6 +51,7 @@
|
||||
#include "qvariant.h"
|
||||
#include "qimagepixmapcleanuphooks_p.h"
|
||||
#include "qplatformintegration_qpa.h"
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
@ -3303,10 +3304,10 @@ extern const uchar *qt_pow_rgb_gamma();
|
||||
|
||||
void qGamma_correct_back_to_linear_cs(QImage *image)
|
||||
{
|
||||
const uchar *gamma = qt_pow_rgb_gamma();
|
||||
if (!gamma)
|
||||
const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
|
||||
if (!tables)
|
||||
return;
|
||||
|
||||
const uchar *gamma = tables->qt_pow_rgb_gamma;
|
||||
// gamma correct the pixels back to linear color space...
|
||||
int h = image->height();
|
||||
int w = image->width();
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include <qpalette.h>
|
||||
#include <qscreen.h>
|
||||
#include <private/qscreen_p.h>
|
||||
#include <private/qdrawhelper_p.h>
|
||||
|
||||
#include <QtGui/QPlatformIntegration>
|
||||
#include <QtGui/QGenericPluginFactory>
|
||||
@ -764,6 +765,7 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
|
||||
delete platform_theme;
|
||||
delete platform_integration;
|
||||
platform_integration = 0;
|
||||
delete m_gammaTables.load();
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -2170,4 +2172,17 @@ void QGuiApplicationPrivate::notifyThemeChanged()
|
||||
}
|
||||
}
|
||||
|
||||
const QDrawHelperGammaTables *QGuiApplicationPrivate::gammaTables()
|
||||
{
|
||||
QDrawHelperGammaTables *result = m_gammaTables.load();
|
||||
if (!result){
|
||||
const qreal smoothing = qApp->styleHints()->fontSmoothingGamma();
|
||||
QDrawHelperGammaTables *tables = new QDrawHelperGammaTables(smoothing);
|
||||
if (!m_gammaTables.testAndSetRelease(0, tables))
|
||||
delete tables;
|
||||
result = m_gammaTables.load();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPlatformIntegration;
|
||||
class QPlatformTheme;
|
||||
struct QDrawHelperGammaTables;
|
||||
|
||||
class Q_GUI_EXPORT QGuiApplicationPrivate : public QCoreApplicationPrivate
|
||||
{
|
||||
@ -203,6 +204,8 @@ public:
|
||||
};
|
||||
QHash<QWindow *, SynthesizedMouseData> synthesizedMousePoints;
|
||||
|
||||
const QDrawHelperGammaTables *gammaTables();
|
||||
|
||||
protected:
|
||||
virtual void notifyThemeChanged();
|
||||
|
||||
@ -212,6 +215,7 @@ private:
|
||||
static QGuiApplicationPrivate *self;
|
||||
static QTouchDevice *m_fakeTouchDevice;
|
||||
static int m_fakeMouseSourcePointId;
|
||||
QAtomicPointer<QDrawHelperGammaTables> m_gammaTables;
|
||||
};
|
||||
|
||||
Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k);
|
||||
|
@ -293,6 +293,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
|
||||
return false;
|
||||
case PasswordMaskDelay:
|
||||
return 0;
|
||||
case FontSmoothingGamma:
|
||||
return qreal(1.7);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -122,7 +122,8 @@ public:
|
||||
StartDragTime,
|
||||
KeyboardAutoRepeatRate,
|
||||
ShowIsFullScreen,
|
||||
PasswordMaskDelay
|
||||
PasswordMaskDelay,
|
||||
FontSmoothingGamma
|
||||
};
|
||||
|
||||
virtual QVariant styleHint(StyleHint hint) const;
|
||||
|
@ -101,4 +101,9 @@ int QStyleHints::passwordMaskDelay() const
|
||||
return hint(QPlatformIntegration::PasswordMaskDelay).toInt();
|
||||
}
|
||||
|
||||
qreal QStyleHints::fontSmoothingGamma() const
|
||||
{
|
||||
return hint(QPlatformIntegration::FontSmoothingGamma).toReal();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -63,6 +63,7 @@ public:
|
||||
int cursorFlashTime() const;
|
||||
bool showIsFullScreen() const;
|
||||
int passwordMaskDelay() const;
|
||||
qreal fontSmoothingGamma() const;
|
||||
|
||||
private:
|
||||
friend class QGuiApplication;
|
||||
|
@ -75,6 +75,7 @@ SOURCES += \
|
||||
SOURCES += \
|
||||
painting/qpaintengine_raster.cpp \
|
||||
painting/qdrawhelper.cpp \
|
||||
painting/qgammatables.cpp \
|
||||
painting/qimagescale.cpp \
|
||||
painting/qgrayraster.c \
|
||||
painting/qpaintengine_blitter.cpp \
|
||||
|
@ -39,6 +39,9 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <qstylehints.h>
|
||||
#include <qguiapplication.h>
|
||||
#include <qatomic.h>
|
||||
#include <private/qdrawhelper_p.h>
|
||||
#include <private/qpaintengine_raster_p.h>
|
||||
#include <private/qpainter_p.h>
|
||||
@ -51,6 +54,7 @@
|
||||
#include <private/qdrawhelper_mips_dsp_p.h>
|
||||
#endif
|
||||
#include <private/qmath_p.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qmath.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -5313,54 +5317,6 @@ inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer,
|
||||
map, mapWidth, mapHeight, mapStride);
|
||||
}
|
||||
|
||||
|
||||
struct QDrawHelperGammaTables
|
||||
{
|
||||
QDrawHelperGammaTables();
|
||||
|
||||
uchar qt_pow_rgb_gamma[256];
|
||||
uchar qt_pow_rgb_invgamma[256];
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
uint qt_pow_gamma[256];
|
||||
uchar qt_pow_invgamma[2048];
|
||||
#endif
|
||||
};
|
||||
|
||||
QDrawHelperGammaTables::QDrawHelperGammaTables()
|
||||
{
|
||||
qreal smoothing = qreal(1.7);
|
||||
|
||||
for (int i=0; i<256; ++i) {
|
||||
qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255));
|
||||
qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255));
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
const qreal gray_gamma = 2.31;
|
||||
for (int i=0; i<256; ++i)
|
||||
qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
|
||||
for (int i=0; i<2048; ++i)
|
||||
qt_pow_invgamma[i] = uchar(qRound(qPow(i / qreal(2047.0), 1 / gray_gamma) * 255));
|
||||
#endif
|
||||
}
|
||||
|
||||
Q_GLOBAL_STATIC(QDrawHelperGammaTables, qt_gamma_tables);
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
const uint *qt_pow_gamma()
|
||||
{
|
||||
QDrawHelperGammaTables *tables = qt_gamma_tables();
|
||||
return tables ? tables->qt_pow_gamma : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
const uchar *qt_pow_rgb_gamma()
|
||||
{
|
||||
QDrawHelperGammaTables *tables = qt_gamma_tables();
|
||||
return tables ? tables->qt_pow_rgb_gamma : 0;
|
||||
}
|
||||
|
||||
static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
|
||||
int x, int y, quint32 color,
|
||||
const uchar *map,
|
||||
@ -5473,7 +5429,7 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer,
|
||||
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint32);
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
|
||||
QDrawHelperGammaTables *tables = qt_gamma_tables();
|
||||
const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
|
||||
if (!tables)
|
||||
return;
|
||||
|
||||
@ -5570,7 +5526,7 @@ static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer,
|
||||
int sb = qBlue(color);
|
||||
int sa = qAlpha(color);
|
||||
|
||||
QDrawHelperGammaTables *tables = qt_gamma_tables();
|
||||
const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
|
||||
if (!tables)
|
||||
return;
|
||||
|
||||
|
@ -328,6 +328,18 @@ struct QSpanData
|
||||
void adjustSpanMethods();
|
||||
};
|
||||
|
||||
struct QDrawHelperGammaTables
|
||||
{
|
||||
explicit QDrawHelperGammaTables(qreal smoothing);
|
||||
|
||||
void refresh(qreal smoothing);
|
||||
|
||||
uchar qt_pow_rgb_gamma[256];
|
||||
uchar qt_pow_rgb_invgamma[256];
|
||||
uint qt_pow_gamma[256];
|
||||
uchar qt_pow_invgamma[2048];
|
||||
};
|
||||
|
||||
static inline uint qt_gradient_clamp(const QGradientData *data, int ipos)
|
||||
{
|
||||
if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) {
|
||||
|
66
src/gui/painting/qgammatables.cpp
Normal file
66
src/gui/painting/qgammatables.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <private/qdrawhelper_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
QDrawHelperGammaTables::QDrawHelperGammaTables(qreal smoothing)
|
||||
{
|
||||
const qreal gray_gamma = 2.31;
|
||||
for (int i=0; i<256; ++i)
|
||||
qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
|
||||
for (int i=0; i<2048; ++i)
|
||||
qt_pow_invgamma[i] = uchar(qRound(qPow(i / qreal(2047.0), 1 / gray_gamma) * 255));
|
||||
|
||||
refresh(smoothing);
|
||||
}
|
||||
|
||||
void QDrawHelperGammaTables::refresh(qreal smoothing)
|
||||
{
|
||||
for (int i=0; i<256; ++i) {
|
||||
qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255));
|
||||
qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255));
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -68,8 +68,10 @@ QT_BEGIN_NAMESPACE
|
||||
*/
|
||||
|
||||
QWindowsFontEngineData::QWindowsFontEngineData()
|
||||
: clearTypeEnabled(false)
|
||||
, fontSmoothingGamma(QWindowsFontDatabase::fontSmoothingGamma())
|
||||
#if !defined(QT_NO_DIRECTWRITE)
|
||||
: directWriteFactory(0)
|
||||
, directWriteFactory(0)
|
||||
, directWriteGdiInterop(0)
|
||||
#endif
|
||||
{
|
||||
@ -78,17 +80,6 @@ QWindowsFontEngineData::QWindowsFontEngineData()
|
||||
if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
|
||||
clearTypeEnabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
|
||||
|
||||
int winSmooth;
|
||||
if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) {
|
||||
fontSmoothingGamma = winSmooth / qreal(1000.0);
|
||||
} else {
|
||||
fontSmoothingGamma = 1.0;
|
||||
}
|
||||
|
||||
// Safeguard ourselves against corrupt registry values...
|
||||
if (fontSmoothingGamma > 5 || fontSmoothingGamma < 1)
|
||||
fontSmoothingGamma = qreal(1.4);
|
||||
|
||||
const qreal gray_gamma = 2.31;
|
||||
for (int i=0; i<256; ++i)
|
||||
pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
|
||||
@ -110,6 +101,19 @@ QWindowsFontEngineData::~QWindowsFontEngineData()
|
||||
#endif
|
||||
}
|
||||
|
||||
qreal QWindowsFontDatabase::fontSmoothingGamma()
|
||||
{
|
||||
int winSmooth;
|
||||
qreal result = 1;
|
||||
if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0))
|
||||
result = qreal(winSmooth) / qreal(1000.0);
|
||||
|
||||
// Safeguard ourselves against corrupt registry values...
|
||||
if (result > 5 || result < 1)
|
||||
result = qreal(1.4);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_DIRECTWRITE)
|
||||
static inline bool initDirectWrite(QWindowsFontEngineData *d)
|
||||
{
|
||||
|
@ -96,6 +96,8 @@ public:
|
||||
static HFONT systemFont();
|
||||
static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
|
||||
|
||||
static qreal fontSmoothingGamma();
|
||||
|
||||
private:
|
||||
void populate(const QString &family = QString());
|
||||
QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
|
||||
|
@ -317,6 +317,8 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co
|
||||
case QPlatformIntegration::KeyboardInputInterval:
|
||||
case QPlatformIntegration::ShowIsFullScreen:
|
||||
break; // Not implemented
|
||||
case QPlatformIntegration::FontSmoothingGamma:
|
||||
return QVariant(QWindowsFontDatabase::fontSmoothingGamma());
|
||||
}
|
||||
return QPlatformIntegration::styleHint(hint);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user