aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-06-16 09:03:43 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-06-19 11:41:26 +0200
commit1a7457e03381e217f1242bce49b86cd0e06bd65f (patch)
treee4ae2019537091c77f9bf8f3104ff599812d326b
parentd1b1fa52a2fded9691f6be5ee864b30adab0db2b (diff)
Fix outline for connected text
For any font where glyphs are connected (any font could have this, but specifically Arabic and Indic fonts will typically always connect glyphs, as it is required to express the language correctly), we would draw the outline on a per-glyph basis, thus getting outlines that disconnect the glyphs. In order to fix this, we have to draw the fill of the glyphs in a separate pass after the outline has been drawn. Note that in order for this to look correct, we have to disable subpixel antialiasing on the fill, which required some plumbing in the native rendering glyph node. The outline shaders have also been changed to only draw the outline and not the fill. Also contains back-port of d46c406cc67f12e6a0798ef509abbb973b34d39d in addition to e8d9bc1bcada7d94af5a33d64a9afc860ede5b84. [ChangeLog][QtQuick][Text] Fixed Outline style on connected glyphs, especially visible in e.g. Arabic and Indic writing systems. Fixes: QTBUG-69301 Fixes: QTBUG-83358 Change-Id: If52a940bfb0267384ea002120655aed1310458a1 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> (cherry picked from commit e8d9bc1bcada7d94af5a33d64a9afc860ede5b84)
-rw-r--r--src/quick/items/qquicktextnode.cpp16
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h1
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode.cpp30
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.h3
-rw-r--r--src/quick/scenegraph/shaders/distancefieldoutlinetext.frag6
-rw-r--r--src/quick/scenegraph/shaders/distancefieldoutlinetext_core.frag6
-rw-r--r--src/quick/scenegraph/shaders/outlinedtext.frag4
-rw-r--r--src/quick/scenegraph/shaders/outlinedtext_core.frag4
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag4
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsbbin1783 -> 1780 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag4
-rw-r--r--src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsbbin1780 -> 1771 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.frag2
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsbbin2107 -> 2067 bytes
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext_a.frag2
-rw-r--r--src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsbbin1402 -> 1357 bytes
16 files changed, 65 insertions, 17 deletions
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index 9110a0664f..1bdc80c9a5 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -129,6 +129,22 @@ QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun
parentNode = this;
parentNode->appendChildNode(node);
+ if (style == QQuickText::Outline && color.alpha() > 0 && styleColor != color) {
+ QSGGlyphNode *fillNode = sg->sceneGraphContext()->createGlyphNode(sg, preferNativeGlyphNode);
+ fillNode->setOwnerElement(m_ownerElement);
+ fillNode->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
+ fillNode->setStyle(QQuickText::Normal);
+ fillNode->setPreferredAntialiasingMode(QSGGlyphNode::GrayAntialiasing);
+ fillNode->setColor(color);
+ fillNode->update();
+
+ fillNode->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern);
+ fillNode->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern);
+
+ parentNode->appendChildNode(fillNode);
+ fillNode->setRenderOrder(node->renderOrder() + 1);
+ }
+
return node;
}
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 1db49feb5d..742a4d03b2 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -374,6 +374,7 @@ class Q_QUICK_PRIVATE_EXPORT QSGGlyphNode : public QSGVisitableNode
public:
enum AntialiasingMode
{
+ DefaultAntialiasing = -1,
GrayAntialiasing,
LowQualitySubPixelAntialiasing,
HighQualitySubPixelAntialiasing
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode.cpp b/src/quick/scenegraph/qsgdefaultglyphnode.cpp
index 5bd5cc4891..d3e0d5a7c5 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode.cpp
@@ -40,12 +40,15 @@
#include "qsgdefaultglyphnode_p.h"
#include "qsgdefaultglyphnode_p_p.h"
+#include <private/qrawfont_p.h>
+
QT_BEGIN_NAMESPACE
QSGDefaultGlyphNode::QSGDefaultGlyphNode(QSGRenderContext *context)
: m_context(context)
, m_glyphNodeType(RootGlyphNode)
, m_dirtyGeometry(false)
+ , m_preferredAntialiasingMode(DefaultAntialiasing)
{
setFlag(UsePreprocess);
}
@@ -59,6 +62,11 @@ QSGDefaultGlyphNode::~QSGDefaultGlyphNode()
m_nodesToDelete.clear();
}
+void QSGDefaultGlyphNode::setPreferredAntialiasingMode(AntialiasingMode mode)
+{
+ m_preferredAntialiasingMode = mode;
+}
+
void QSGDefaultGlyphNode::setMaterialColor(const QColor &color)
{
static_cast<QSGTextMaskMaterial *>(m_material)->setColor(color);
@@ -76,7 +84,27 @@ void QSGDefaultGlyphNode::update()
QMargins margins(0, 0, 0, 0);
if (m_style == QQuickText::Normal) {
- m_material = new QSGTextMaskMaterial(m_context, QVector4D(m_color.redF(), m_color.greenF(), m_color.blueF(), m_color.alphaF()), font);
+ QFontEngine::GlyphFormat glyphFormat;
+
+ // Don't try to override glyph format of color fonts
+ if (QRawFontPrivate::get(font)->fontEngine->glyphFormat == QFontEngine::Format_ARGB) {
+ glyphFormat = QFontEngine::Format_None;
+ } else {
+ switch (m_preferredAntialiasingMode) {
+ case GrayAntialiasing:
+ glyphFormat = QFontEngine::Format_A8;
+ break;
+ case HighQualitySubPixelAntialiasing:
+ case LowQualitySubPixelAntialiasing:
+ glyphFormat = QFontEngine::Format_A32;
+ break;
+ default:
+ glyphFormat = QFontEngine::Format_None;
+ break;
+ }
+ }
+
+ m_material = new QSGTextMaskMaterial(m_context, QVector4D(m_color.redF(), m_color.greenF(), m_color.blueF(), m_color.alphaF()), font, glyphFormat);
} else if (m_style == QQuickText::Outline) {
QSGOutlinedTextMaterial *material = new QSGOutlinedTextMaterial(m_context, font);
material->setStyleColor(m_styleColor);
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.h b/src/quick/scenegraph/qsgdefaultglyphnode_p.h
index 4cff2d3d24..4122806002 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.h
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.h
@@ -66,6 +66,7 @@ public:
void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) override;
void update() override;
void preprocess() override;
+ void setPreferredAntialiasingMode(AntialiasingMode) override;
void updateGeometry();
private:
@@ -86,6 +87,8 @@ private:
};
uint m_dirtyGeometry: 1;
+
+ AntialiasingMode m_preferredAntialiasingMode;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/shaders/distancefieldoutlinetext.frag b/src/quick/scenegraph/shaders/distancefieldoutlinetext.frag
index 250ed322a1..f7cdeb9064 100644
--- a/src/quick/scenegraph/shaders/distancefieldoutlinetext.frag
+++ b/src/quick/scenegraph/shaders/distancefieldoutlinetext.frag
@@ -11,6 +11,6 @@ uniform mediump float outlineAlphaMax1;
void main()
{
mediump float d = texture2D(_qt_texture, sampleCoord).a;
- gl_FragColor = mix(styleColor, color, smoothstep(alphaMin, alphaMax, d))
- * smoothstep(outlineAlphaMax0, outlineAlphaMax1, d);
-} \ No newline at end of file
+ mediump float a = smoothstep(alphaMin, alphaMax, d);
+ gl_FragColor = (1.0 - a) * styleColor * smoothstep(outlineAlphaMax0, outlineAlphaMax1, d);
+}
diff --git a/src/quick/scenegraph/shaders/distancefieldoutlinetext_core.frag b/src/quick/scenegraph/shaders/distancefieldoutlinetext_core.frag
index 80fa05ca3c..622e353019 100644
--- a/src/quick/scenegraph/shaders/distancefieldoutlinetext_core.frag
+++ b/src/quick/scenegraph/shaders/distancefieldoutlinetext_core.frag
@@ -15,6 +15,6 @@ uniform float outlineAlphaMax1;
void main()
{
float d = texture(_qt_texture, sampleCoord).r;
- fragColor = mix(styleColor, color, smoothstep(alphaMin, alphaMax, d))
- * smoothstep(outlineAlphaMax0, outlineAlphaMax1, d);
-} \ No newline at end of file
+ float a = smoothstep(alphaMin, alphaMax, d);
+ fragColor = (1.0 - a) * styleColor * smoothstep(outlineAlphaMax0, outlineAlphaMax1, d);
+}
diff --git a/src/quick/scenegraph/shaders/outlinedtext.frag b/src/quick/scenegraph/shaders/outlinedtext.frag
index b3e5475d5d..5fe2b14e24 100644
--- a/src/quick/scenegraph/shaders/outlinedtext.frag
+++ b/src/quick/scenegraph/shaders/outlinedtext.frag
@@ -17,5 +17,5 @@ void main()
texture2D(_qt_texture, sCoordRight).a,
0.0, 1.0) - glyph,
0.0, 1.0);
- gl_FragColor = outline * styleColor + glyph * color;
-} \ No newline at end of file
+ gl_FragColor = outline * styleColor;
+}
diff --git a/src/quick/scenegraph/shaders/outlinedtext_core.frag b/src/quick/scenegraph/shaders/outlinedtext_core.frag
index e19c8937f9..4d7c614185 100644
--- a/src/quick/scenegraph/shaders/outlinedtext_core.frag
+++ b/src/quick/scenegraph/shaders/outlinedtext_core.frag
@@ -21,5 +21,5 @@ void main()
texture(_qt_texture, sCoordRight).r,
0.0, 1.0) - glyph,
0.0, 1.0);
- fragColor = outline * styleColor + glyph * color;
-} \ No newline at end of file
+ fragColor = outline * styleColor;
+}
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag
index c8c1ac89dc..945ef56fee 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag
@@ -20,6 +20,6 @@ layout(std140, binding = 0) uniform buf {
void main()
{
float d = texture(_qt_texture, sampleCoord).r;
- fragColor = mix(ubuf.styleColor, ubuf.color, smoothstep(ubuf.alphaMin, ubuf.alphaMax, d))
- * smoothstep(ubuf.outlineAlphaMax0, ubuf.outlineAlphaMax1, d);
+ float a = smoothstep(ubuf.alphaMin, ubuf.alphaMax, d);
+ fragColor = (1.0 - a) * ubuf.styleColor * smoothstep(ubuf.outlineAlphaMax0, ubuf.outlineAlphaMax1, d);
}
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
index 33de256615..942db41a5a 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag
index 70fb80852d..7ccd06610a 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag
@@ -20,6 +20,6 @@ layout(std140, binding = 0) uniform buf {
void main()
{
float d = texture(_qt_texture, sampleCoord).a;
- fragColor = mix(ubuf.styleColor, ubuf.color, smoothstep(ubuf.alphaMin, ubuf.alphaMax, d))
- * smoothstep(ubuf.outlineAlphaMax0, ubuf.outlineAlphaMax1, d);
+ float a = smoothstep(ubuf.alphaMin, ubuf.alphaMax, d);
+ fragColor = (1.0 - a) * ubuf.styleColor * smoothstep(ubuf.outlineAlphaMax0, ubuf.outlineAlphaMax1, d);
}
diff --git a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
index f64d7ac315..00e0497248 100644
--- a/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/distancefieldoutlinetext_a.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag b/src/quick/scenegraph/shaders_ng/outlinedtext.frag
index 0023ed5467..aac9e4bff8 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag
@@ -29,5 +29,5 @@ void main()
texture(_qt_texture, sCoordRight).r,
0.0, 1.0) - glyph,
0.0, 1.0);
- fragColor = outline * ubuf.styleColor + glyph * ubuf.color;
+ fragColor = outline * ubuf.styleColor;
}
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
index c1e81f4163..95924de0c8 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag.qsb
Binary files differ
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
index 9a3d8cf5ed..481d8c94d0 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
@@ -29,5 +29,5 @@ void main()
texture(_qt_texture, sCoordRight).a,
0.0, 1.0) - glyph,
0.0, 1.0);
- fragColor = outline * ubuf.styleColor + glyph * ubuf.color;
+ fragColor = outline * ubuf.styleColor;
}
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
index 7e26f3775e..ddceb17a94 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag.qsb
Binary files differ