diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2012-07-04 14:56:38 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-07-10 14:22:34 +0200 |
commit | b0b4869440fc6e5af42797cbcaa64ec30238be73 (patch) | |
tree | 208f5f90c9ee6c3a71cc9e751a9374addede67d0 /src/quick/scenegraph | |
parent | c66d00a7f53d6a6a847bc7171529273f4d089923 (diff) |
Add option to use native rasterizer for SceneGraph text
For old-style (desktop components) apps using QML 2 on regular density
displays, distance field text will look out of place. We introduce
an option to use the native rasterizer instead if you would rather
have native look and feel than scalable text items.
Change-Id: Idb38e3c89f2deab9ae1963357c6c5fb235ddeab8
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 11 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext_p.h | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultglyphnode_p.cpp | 51 |
3 files changed, 56 insertions, 7 deletions
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 20b383a2b6..dec9ea9f7d 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -335,6 +335,15 @@ QSGDistanceFieldGlyphCache *QSGContext::distanceFieldGlyphCache(const QRawFont & } /*! + Factory function for scene graph backends of the Text elements which supports native + text rendering. Used in special cases where native look and feel is a main objective. +*/ +QSGGlyphNode *QSGContext::createNativeGlyphNode() +{ + return new QSGDefaultGlyphNode; +} + +/*! Factory function for scene graph backends of the Text elements; */ QSGGlyphNode *QSGContext::createGlyphNode() @@ -342,7 +351,7 @@ QSGGlyphNode *QSGContext::createGlyphNode() Q_D(QSGContext); if (d->distanceFieldDisabled) { - return new QSGDefaultGlyphNode; + return createNativeGlyphNode(); } else { QSGDistanceFieldGlyphNode *node = new QSGDistanceFieldGlyphNode(this); node->setPreferredAntialiasingMode(d->distanceFieldAntialiasing); diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 30372c371a..a2495a8029 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -101,6 +101,7 @@ public: virtual QSGRectangleNode *createRectangleNode(); virtual QSGImageNode *createImageNode(); virtual QSGGlyphNode *createGlyphNode(); + virtual QSGGlyphNode *createNativeGlyphNode(); virtual QSGRenderer *createRenderer(); virtual QSGTexture *createTexture(const QImage &image = QImage()) const; diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 4c4f97ad34..2f1a4ae457 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -44,6 +44,8 @@ #include <qopenglshaderprogram.h> #include <QtGui/private/qopengltextureglyphcache_p.h> +#include <QtGui/private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> #include <private/qfontengine_p.h> #include <private/qopenglextensions_p.h> @@ -61,6 +63,10 @@ public: virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); virtual char const *const *attributeNames() const; + + virtual void activate(); + virtual void deactivate(); + private: virtual void initialize(); virtual const char *vertexShader() const; @@ -90,7 +96,7 @@ const char *QSGTextMaskMaterialData::fragmentShader() const { "uniform sampler2D texture; \n" "uniform lowp vec4 color; \n" "void main() { \n" - " gl_FragColor = color * texture2D(texture, sampleCoord).a; \n" + " gl_FragColor = vec4(texture2D(texture, sampleCoord).rgb, 1.0); \n" "}"; } @@ -111,6 +117,32 @@ void QSGTextMaskMaterialData::initialize() m_textureScale_id = program()->uniformLocation("textureScale"); } +static inline qreal fontSmoothingGamma() +{ + static qreal fontSmoothingGamma = QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::FontSmoothingGamma).toReal(); + return fontSmoothingGamma; +} + +void QSGTextMaskMaterialData::activate() +{ + QSGMaterialShader::activate(); + glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); + + // 0.25 was found to be acceptable error margin by experimentation. On Mac, the gamma is 2.0, + // but using sRGB looks okay. + if (qAbs(fontSmoothingGamma() - 2.2) < 0.25) + glEnable(GL_FRAMEBUFFER_SRGB); +} + +void QSGTextMaskMaterialData::deactivate() +{ + QSGMaterialShader::deactivate(); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + if (qAbs(fontSmoothingGamma() - 2.2) < 0.25) + glDisable(GL_FRAMEBUFFER_SRGB); +} + void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) { Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); @@ -118,10 +150,17 @@ void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect); if (oldMaterial == 0 || material->color() != oldMaterial->color() || state.isOpacityDirty()) { - QVector4D color(material->color().redF(), material->color().greenF(), - material->color().blueF(), material->color().alphaF()); + QColor c = material->color(); + QVector4D color(c.redF(), c.greenF(), c.blueF(), c.alphaF()); color *= state.opacity(); program()->setUniformValue(m_color_id, color); + + if (oldMaterial == 0 || material->color() != oldMaterial->color()) { + state.context()->functions()->glBlendColor(c.redF(), + c.greenF(), + c.blueF(), + 1.0f); + } } bool updated = material->ensureUpToDate(); @@ -138,8 +177,8 @@ void QSGTextMaskMaterialData::updateState(const RenderState &state, QSGMaterial // Set the mag/min filters to be linear. We only need to do this when the texture // has been recreated. if (updated) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } } @@ -161,7 +200,7 @@ void QSGTextMaskMaterial::init() { Q_ASSERT(m_font.isValid()); - QFontEngineGlyphCache::Type type = QFontEngineGlyphCache::Raster_A8; + QFontEngineGlyphCache::Type type = QFontEngineGlyphCache::Raster_RGBMask; setFlag(Blending, true); QOpenGLContext *ctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext()); |