summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2021-01-15 09:11:07 +0100
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2021-01-25 15:56:50 +0100
commitd79a9b1a4f694a227ce62ccab9b44685a9755916 (patch)
treee943780120ee3abcf987ecd0c05440f9ed5a9b7b /src/opengl
parent80e87ca05c2b421dbca9fc8f9a8f290a3eabc206 (diff)
Implement vertical subpixel positioning where available
For some use cases, vertical subpixel positioning may be useful, as it allows you to vertically align text with other painting primitives. This does impose an overhead, so we make it opt-int with a render hint on the painter. Note that this is only supported on Freetype currently. It might be possible to support on older macOS versions, prior to Mojave (which has disabled subpixel positioning entirely), but since it would have limited usefulness and Freetype is cross-platform anyway, I skipped that. Note: This drive-by-fixes an issue with subpixel positioning where glyphs would always be offset by 1/64, because we added the aliasing offset *after* we had determined the closest subpixel position. The idea of this, as far as I can understand, is rather to snap to nearest subpixel position upwards, not to add an offset to all glyphs, so it should be added before finding the correct position. It had a subtle visual effect when animating the position. It might be that we could get rid of it entirely, as I haven't been able to reproduce any issues with that, but I have moved it instead, to match what I believe the intention was. [ChangeLog][QtGui][Text] Added render hint flag QPainter::VerticalSubpixelPositioning which will position text at subpixel positions vertically whenever supported. In absence of this, text position will be rounded vertically as before. Fixes: QTBUG-35682 Change-Id: I8ce7a72a64e5a0924dac7c244e3e07c2938bfd09 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/qopenglpaintengine.cpp22
-rw-r--r--src/opengl/qopengltextureglyphcache.cpp4
-rw-r--r--src/opengl/qopengltextureglyphcache_p.h4
3 files changed, 22 insertions, 8 deletions
diff --git a/src/opengl/qopenglpaintengine.cpp b/src/opengl/qopenglpaintengine.cpp
index 3bb3496de5..9c8325ca11 100644
--- a/src/opengl/qopenglpaintengine.cpp
+++ b/src/opengl/qopenglpaintengine.cpp
@@ -1797,11 +1797,13 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
if (recreateVertexArrays) {
cache->setPaintEnginePrivate(this);
if (!cache->populate(fe, staticTextItem->numGlyphs,
- staticTextItem->glyphs, staticTextItem->glyphPositions)) {
+ staticTextItem->glyphs, staticTextItem->glyphPositions,
+ s->renderHints)) {
// No space for glyphs in cache. We need to reset it and try again.
cache->clear();
cache->populate(fe, staticTextItem->numGlyphs,
- staticTextItem->glyphs, staticTextItem->glyphPositions);
+ staticTextItem->glyphs, staticTextItem->glyphPositions,
+ s->renderHints);
}
if (cache->hasPendingGlyphs()) {
@@ -1874,10 +1876,15 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
textureCoordinates->clear();
bool supportsSubPixelPositions = fe->supportsSubPixelPositions();
+ bool verticalSubPixelPositions = fe->supportsVerticalSubPixelPositions()
+ && (s->renderHints & QPainter::VerticalSubpixelPositioning) != 0;
for (int i=0; i<staticTextItem->numGlyphs; ++i) {
- QFixed subPixelPosition;
- if (supportsSubPixelPositions)
- subPixelPosition = fe->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
+ QFixedPoint subPixelPosition;
+ if (supportsSubPixelPositions) {
+ subPixelPosition = fe->subPixelPositionFor(staticTextItem->glyphPositions[i]);
+ if (!verticalSubPixelPositions)
+ subPixelPosition.y = 0;
+ }
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);
@@ -1886,7 +1893,10 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
continue;
int x = qFloor(staticTextItem->glyphPositions[i].x.toReal() * cache->transform().m11()) + c.baseLineX - margin;
- int y = qRound(staticTextItem->glyphPositions[i].y.toReal() * cache->transform().m22()) - c.baseLineY - margin;
+ int y = verticalSubPixelPositions
+ ? qRound(staticTextItem->glyphPositions[i].y.toReal() * cache->transform().m22())
+ : qFloor(staticTextItem->glyphPositions[i].y.toReal() * cache->transform().m22());
+ y -= c.baseLineY + margin;
vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h));
textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy));
diff --git a/src/opengl/qopengltextureglyphcache.cpp b/src/opengl/qopengltextureglyphcache.cpp
index a38d4328cc..6c8971fddb 100644
--- a/src/opengl/qopengltextureglyphcache.cpp
+++ b/src/opengl/qopengltextureglyphcache.cpp
@@ -421,7 +421,9 @@ void QOpenGLTextureGlyphCache::resizeTextureData(int width, int height)
}
}
-void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
+void QOpenGLTextureGlyphCache::fillTexture(const Coord &c,
+ glyph_t glyph,
+ const QFixedPoint &subPixelPosition)
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (ctx == nullptr) {
diff --git a/src/opengl/qopengltextureglyphcache_p.h b/src/opengl/qopengltextureglyphcache_p.h
index 15ecd6209b..5b30881e55 100644
--- a/src/opengl/qopengltextureglyphcache_p.h
+++ b/src/opengl/qopengltextureglyphcache_p.h
@@ -115,7 +115,9 @@ public:
virtual void createTextureData(int width, int height) override;
virtual void resizeTextureData(int width, int height) override;
- virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) override;
+ virtual void fillTexture(const Coord &c,
+ glyph_t glyph,
+ const QFixedPoint &subPixelPosition) override;
virtual int glyphPadding() const override;
virtual int maxTextureWidth() const override;
virtual int maxTextureHeight() const override;