Make distance field text more easily configurable.
authorYoann Lopes <yoann.lopes@nokia.com>
Tue, 9 Aug 2011 09:39:40 +0000 (11:39 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 9 Aug 2011 13:59:10 +0000 (15:59 +0200)
Custom functions can be provided to compute the distance field threshold
value and antialiasing range.

Change-Id: Ie2ec8160d81671dedf72f0c72c3a5cbdf04d993a
Reviewed-on: http://codereview.qt.nokia.com/2772
Reviewed-by: Yoann Lopes <yoann.lopes@nokia.com>
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>

src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp
src/declarative/scenegraph/qsgdistancefieldglyphcache_p.h
src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp

index a1df05c..90bd8c3 100644 (file)
@@ -86,6 +86,21 @@ static inline int qt_next_power_of_two(int v)
     return v;
 }
 
+static float defaultThresholdFunc(float glyphScale)
+{
+    static float base = qgetenv("QT_DF_BASE").isEmpty() ? 0.5f : qgetenv("QT_DF_BASE").toFloat();
+    static float baseDev = qgetenv("QT_DF_BASEDEVIATION").isEmpty() ? 0.065f : qgetenv("QT_DF_BASEDEVIATION").toFloat();
+    static float devScaleMin = qgetenv("QT_DF_SCALEFORMAXDEV").isEmpty() ? 0.15f : qgetenv("QT_DF_SCALEFORMAXDEV").toFloat();
+    static float devScaleMax = qgetenv("QT_DF_SCALEFORNODEV").isEmpty() ? 0.3f : qgetenv("QT_DF_SCALEFORNODEV").toFloat();
+    return base - ((qBound(devScaleMin, glyphScale, devScaleMax) - devScaleMin) / (devScaleMax - devScaleMin) * -baseDev + baseDev);
+}
+
+static float defaultAntialiasingSpreadFunc(float glyphScale)
+{
+    static float range = qgetenv("QT_DF_RANGE").isEmpty() ? 0.06f : qgetenv("QT_DF_RANGE").toFloat();
+    return range / glyphScale;
+}
+
 namespace
 {
     enum FillHDir
@@ -808,6 +823,8 @@ QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(const QGLContext *c, cons
     , m_maxTextureSize(0)
     , ctx(c)
     , m_blitProgram(0)
+    , m_threshold_func(defaultThresholdFunc)
+    , m_antialiasingSpread_func(defaultAntialiasingSpreadFunc)
 {
     Q_ASSERT(font.isValid());
     m_font = font;
index bcfb44a..0284d5a 100644 (file)
@@ -53,6 +53,9 @@ QT_BEGIN_NAMESPACE
 
 class QGLShaderProgram;
 
+typedef float (*ThresholdFunc)(float glyphScale);
+typedef float (*AntialiasingSpreadFunc)(float glyphScale);
+
 class Q_DECLARATIVE_EXPORT QSGDistanceFieldGlyphCache : public QObject
 {
     Q_OBJECT
@@ -104,6 +107,12 @@ public:
 
     static bool distanceFieldEnabled();
 
+    ThresholdFunc thresholdFunc() const { return m_threshold_func; }
+    void setThresholdFunc(ThresholdFunc func) { m_threshold_func = func; }
+
+    AntialiasingSpreadFunc antialiasingSpreadFunc() const { return m_antialiasingSpread_func; }
+    void setAntialiasingSpreadFunc(AntialiasingSpreadFunc func) { m_antialiasingSpread_func = func; }
+
 private Q_SLOTS:
     void onContextDestroyed(const QGLContext *context);
 
@@ -153,6 +162,8 @@ private:
     GLfloat m_vertexCoordinateArray[8];
     GLfloat m_textureCoordinateArray[8];
 
+    ThresholdFunc m_threshold_func;
+    AntialiasingSpreadFunc m_antialiasingSpread_func;
 };
 
 QT_END_NAMESPACE
index 18de955..e58febc 100644 (file)
@@ -60,10 +60,10 @@ protected:
     virtual const char *vertexShader() const;
     virtual const char *fragmentShader() const;
 
-    virtual void updateAlphaRange();
+    void updateAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc);
 
-    qreal m_fontScale;
-    qreal m_matrixScale;
+    float m_fontScale;
+    float m_matrixScale;
 
     int m_matrix_id;
     int m_textureScale_id;
@@ -110,11 +110,14 @@ QSGDistanceFieldTextMaterialShader::QSGDistanceFieldTextMaterialShader()
 {
 }
 
-void QSGDistanceFieldTextMaterialShader::updateAlphaRange()
+void QSGDistanceFieldTextMaterialShader::updateAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc)
 {
-    qreal combinedScale = m_fontScale * m_matrixScale;
-    qreal alphaMin = qMax(0.0, 0.5 - 0.07 / combinedScale);
-    qreal alphaMax = qMin(0.5 + 0.07 / combinedScale, 1.0);
+    float combinedScale = m_fontScale * m_matrixScale;
+    float base = thresholdFunc(combinedScale);
+    float range = spreadFunc(combinedScale);
+
+    float alphaMin = qMax(0.0f, base - range);
+    float alphaMax = qMin(base + range, 1.0f);
     program()->setUniformValue(m_alphaMin_id, GLfloat(alphaMin));
     program()->setUniformValue(m_alphaMax_id, GLfloat(alphaMax));
 }
@@ -160,7 +163,7 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
         updateRange = true;
     }
     if (updateRange)
-        updateAlphaRange();
+        updateAlphaRange(material->glyphCache()->thresholdFunc(), material->glyphCache()->antialiasingSpreadFunc());
 
     Q_ASSERT(material->glyphCache());
 
@@ -506,8 +509,6 @@ protected:
     virtual const char *vertexShader() const;
     virtual const char *fragmentShader() const;
 
-    void updateAlphaRange();
-
 private:
     int m_fontScale_id;
     int m_vecDelta_id;
@@ -620,15 +621,6 @@ void QSGSubPixelDistanceFieldTextMaterialShader::deactivate()
     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 }
 
-void QSGSubPixelDistanceFieldTextMaterialShader::updateAlphaRange()
-{
-    qreal combinedScale = m_fontScale * m_matrixScale;
-    qreal alphaMin = qMax(0.0, 0.5 - 0.05 / combinedScale);
-    qreal alphaMax = qMin(0.5 + 0.05 / combinedScale, 1.0);
-    program()->setUniformValue(m_alphaMin_id, GLfloat(alphaMin));
-    program()->setUniformValue(m_alphaMax_id, GLfloat(alphaMax));
-}
-
 void QSGSubPixelDistanceFieldTextMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
 {
     Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type());