From d79a9b1a4f694a227ce62ccab9b44685a9755916 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 15 Jan 2021 09:11:07 +0100 Subject: 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 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qtextureglyphcache.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'src/gui/painting/qtextureglyphcache.cpp') diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 3728060caf..dfb937ed84 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -64,7 +64,7 @@ int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const QImage images[NumSubpixelPositions]; int numImages = 0; for (int i = 0; i < NumSubpixelPositions; ++i) { - QImage img = textureMapForGlyph(glyph, QFixed::fromReal(i / 12.0)); + QImage img = textureMapForGlyph(glyph, QFixedPoint(QFixed::fromReal(i / 12.0), 0)); if (numImages == 0) { QPainterPath path; @@ -92,8 +92,11 @@ int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const return numImages; } -bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs, - const QFixedPoint *positions) +bool QTextureGlyphCache::populate(QFontEngine *fontEngine, + int numGlyphs, + const glyph_t *glyphs, + const QFixedPoint *positions, + QPainter::RenderHints renderHints) { #ifdef CACHE_DEBUG printf("Populating with %d glyphs\n", numGlyphs); @@ -105,6 +108,8 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const const int paddingDoubled = padding * 2; bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions(); + bool verticalSubPixelPositions = fontEngine->supportsVerticalSubPixelPositions() + && (renderHints & QPainter::VerticalSubpixelPositioning) != 0; if (fontEngine->m_subPixelPositionCount == 0) { if (!supportsSubPixelPositions) { fontEngine->m_subPixelPositionCount = 1; @@ -127,10 +132,12 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const for (int i=0; i < numGlyphs; ++i) { const glyph_t glyph = glyphs[i]; - QFixed subPixelPosition; + QFixedPoint subPixelPosition; if (supportsSubPixelPositions) { - QFixed x = positions != nullptr ? positions[i].x : QFixed(); - subPixelPosition = fontEngine->subPixelPositionForX(x); + QFixedPoint pos = positions != nullptr ? positions[i] : QFixedPoint(); + subPixelPosition = fontEngine->subPixelPositionFor(pos); + if (!verticalSubPixelPositions) + subPixelPosition.y = 0; } if (coords.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition))) @@ -263,7 +270,7 @@ void QTextureGlyphCache::fillInPendingGlyphs() m_pendingGlyphs.clear(); } -QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const +QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, const QFixedPoint &subPixelPosition) const { switch (m_format) { case QFontEngine::Format_A32: @@ -317,7 +324,9 @@ void QImageTextureGlyphCache::createTextureData(int width, int height) m_image.fill(0); } -void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subPixelPosition) +void QImageTextureGlyphCache::fillTexture(const Coord &c, + glyph_t g, + const QFixedPoint &subPixelPosition) { QImage mask = textureMapForGlyph(g, subPixelPosition); -- cgit v1.2.3