Fix subpixel positioning support
Move subpixelPositionForX from QTextureGlyphCache to QFontEngine, since some font engines like QFontEngineFT may need a custom implementation or tweak it a little bit. In QRasterPaintEngine::drawCachedGlyphs, do not add aliasedCoodinate to x offset as that will break subpixel positioning. Change-Id: Idbcec617509459b80965220ceb07b17737649bbf Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>bb10
parent
04f6983979
commit
63eae1bd15
|
|
@ -1536,12 +1536,13 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type
|
|||
|
||||
void *cacheKey = ctx->shareGroup();
|
||||
bool recreateVertexArrays = false;
|
||||
QFontEngine *fe = staticTextItem->fontEngine();
|
||||
|
||||
QOpenGLTextureGlyphCache *cache =
|
||||
(QOpenGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(cacheKey, glyphType, QTransform());
|
||||
(QOpenGLTextureGlyphCache *) fe->glyphCache(cacheKey, glyphType, QTransform());
|
||||
if (!cache || cache->cacheType() != glyphType || cache->contextGroup() == 0) {
|
||||
cache = new QOpenGLTextureGlyphCache(glyphType, QTransform());
|
||||
staticTextItem->fontEngine()->setGlyphCache(cacheKey, cache);
|
||||
fe->setGlyphCache(cacheKey, cache);
|
||||
recreateVertexArrays = true;
|
||||
}
|
||||
|
||||
|
|
@ -1565,11 +1566,11 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type
|
|||
// cache so this text is performed before we test if the cache size has changed.
|
||||
if (recreateVertexArrays) {
|
||||
cache->setPaintEnginePrivate(this);
|
||||
if (!cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs,
|
||||
if (!cache->populate(fe, staticTextItem->numGlyphs,
|
||||
staticTextItem->glyphs, staticTextItem->glyphPositions)) {
|
||||
// No space for glyphs in cache. We need to reset it and try again.
|
||||
cache->clear();
|
||||
cache->populate(staticTextItem->fontEngine(), staticTextItem->numGlyphs,
|
||||
cache->populate(fe, staticTextItem->numGlyphs,
|
||||
staticTextItem->glyphs, staticTextItem->glyphPositions);
|
||||
}
|
||||
cache->fillInPendingGlyphs();
|
||||
|
|
@ -1620,11 +1621,11 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type
|
|||
vertexCoordinates->clear();
|
||||
textureCoordinates->clear();
|
||||
|
||||
bool supportsSubPixelPositions = staticTextItem->fontEngine()->supportsSubPixelPositions();
|
||||
bool supportsSubPixelPositions = fe->supportsSubPixelPositions();
|
||||
for (int i=0; i<staticTextItem->numGlyphs; ++i) {
|
||||
QFixed subPixelPosition;
|
||||
if (supportsSubPixelPositions)
|
||||
subPixelPosition = cache->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
|
||||
subPixelPosition = fe->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
|
||||
|
||||
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);
|
||||
|
||||
|
|
|
|||
|
|
@ -2752,13 +2752,13 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
|
|||
const uchar *bits = image.bits();
|
||||
for (int i=0; i<numGlyphs; ++i) {
|
||||
|
||||
QFixed subPixelPosition = cache->subPixelPositionForX(positions[i].x);
|
||||
QFixed subPixelPosition = fontEngine->subPixelPositionForX(positions[i].x);
|
||||
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphs[i], subPixelPosition);
|
||||
const QTextureGlyphCache::Coord &c = cache->coords[glyph];
|
||||
if (c.isNull())
|
||||
continue;
|
||||
|
||||
int x = qFloor(positions[i].x + offs) + c.baseLineX - margin;
|
||||
int x = qFloor(positions[i].x) + c.baseLineX - margin;
|
||||
int y = qFloor(positions[i].y + offs) - c.baseLineY - margin;
|
||||
|
||||
// printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n",
|
||||
|
|
|
|||
|
|
@ -99,23 +99,6 @@ int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const
|
|||
return images.size();
|
||||
}
|
||||
|
||||
QFixed QTextureGlyphCache::subPixelPositionForX(QFixed x) const
|
||||
{
|
||||
if (m_subPixelPositionCount <= 1)
|
||||
return QFixed();
|
||||
|
||||
QFixed subPixelPosition;
|
||||
if (x != 0) {
|
||||
subPixelPosition = x - x.floor();
|
||||
QFixed fraction = (subPixelPosition / QFixed::fromReal(1.0 / m_subPixelPositionCount)).floor();
|
||||
|
||||
// Compensate for precision loss in fixed point to make sure we are always drawing at a subpixel position over
|
||||
// the lower boundary for the selected rasterization by adding 1/64.
|
||||
subPixelPosition = fraction / QFixed(m_subPixelPositionCount) + QFixed::fromReal(0.015625);
|
||||
}
|
||||
return subPixelPosition;
|
||||
}
|
||||
|
||||
bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
|
||||
const QFixedPoint *positions)
|
||||
{
|
||||
|
|
@ -129,13 +112,13 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
|
|||
const int paddingDoubled = glyphPadding() * 2;
|
||||
|
||||
bool supportsSubPixelPositions = fontEngine->supportsSubPixelPositions();
|
||||
if (m_subPixelPositionCount == 0) {
|
||||
if (fontEngine->m_subPixelPositionCount == 0) {
|
||||
if (!supportsSubPixelPositions) {
|
||||
m_subPixelPositionCount = 1;
|
||||
fontEngine->m_subPixelPositionCount = 1;
|
||||
} else {
|
||||
int i = 0;
|
||||
while (m_subPixelPositionCount == 0 && i < numGlyphs)
|
||||
m_subPixelPositionCount = calculateSubPixelPositionCount(glyphs[i++]);
|
||||
while (fontEngine->m_subPixelPositionCount == 0 && i < numGlyphs)
|
||||
fontEngine->m_subPixelPositionCount = calculateSubPixelPositionCount(glyphs[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -156,7 +139,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
|
|||
QFixed subPixelPosition;
|
||||
if (supportsSubPixelPositions) {
|
||||
QFixed x = positions != 0 ? positions[i].x : QFixed();
|
||||
subPixelPosition = subPixelPositionForX(x);
|
||||
subPixelPosition = fontEngine->subPixelPositionForX(x);
|
||||
}
|
||||
|
||||
if (coords.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition)))
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ class Q_GUI_EXPORT QTextureGlyphCache : public QFontEngineGlyphCache
|
|||
public:
|
||||
QTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix)
|
||||
: QFontEngineGlyphCache(matrix, type), m_current_fontengine(0),
|
||||
m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0), m_subPixelPositionCount(0)
|
||||
m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0)
|
||||
{ }
|
||||
|
||||
virtual ~QTextureGlyphCache() { }
|
||||
|
|
@ -146,8 +146,6 @@ public:
|
|||
|
||||
QImage textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const;
|
||||
|
||||
QFixed subPixelPositionForX(QFixed x) const;
|
||||
|
||||
protected:
|
||||
int calculateSubPixelPositionCount(glyph_t) const;
|
||||
|
||||
|
|
@ -159,7 +157,6 @@ protected:
|
|||
int m_cx; // current x
|
||||
int m_cy; // current y
|
||||
int m_currentRowHeight; // Height of last row
|
||||
int m_subPixelPositionCount; // Number of positions within a single pixel for this cache
|
||||
};
|
||||
|
||||
inline uint qHash(const QTextureGlyphCache::GlyphAndSubPixelPosition &g)
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ QFontEngine::QFontEngine()
|
|||
|
||||
hbFace = 0;
|
||||
glyphFormat = -1;
|
||||
m_subPixelPositionCount = 0;
|
||||
}
|
||||
|
||||
QFontEngine::~QFontEngine()
|
||||
|
|
@ -635,17 +636,19 @@ QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition
|
|||
return rgbMask;
|
||||
}
|
||||
|
||||
QFixed QFontEngine::subPixelPositionForX(QFixed x)
|
||||
QFixed QFontEngine::subPixelPositionForX(QFixed x) const
|
||||
{
|
||||
int m_subPixelPositionCount = 4;
|
||||
if (!supportsSubPixelPositions())
|
||||
return 0;
|
||||
if (m_subPixelPositionCount <= 1 || !supportsSubPixelPositions())
|
||||
return QFixed();
|
||||
|
||||
QFixed subPixelPosition;
|
||||
if (x != 0) {
|
||||
subPixelPosition = x - x.floor();
|
||||
QFixed fraction = (subPixelPosition / QFixed::fromReal(1.0 / m_subPixelPositionCount)).floor();
|
||||
subPixelPosition = fraction / QFixed(m_subPixelPositionCount);
|
||||
|
||||
// Compensate for precision loss in fixed point to make sure we are always drawing at a subpixel position over
|
||||
// the lower boundary for the selected rasterization by adding 1/64.
|
||||
subPixelPosition = fraction / QFixed(m_subPixelPositionCount) + QFixed::fromReal(0.015625);
|
||||
}
|
||||
return subPixelPosition;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -657,6 +657,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd)
|
|||
defaultFormat = Format_None;
|
||||
embeddedbitmap = false;
|
||||
cacheEnabled = qgetenv("QT_NO_FT_CACHE").isEmpty() || qgetenv("QT_NO_FT_CACHE").toInt() == 0;
|
||||
m_subPixelPositionCount = 4;
|
||||
}
|
||||
|
||||
QFontEngineFT::~QFontEngineFT()
|
||||
|
|
|
|||
|
|
@ -315,7 +315,6 @@ private:
|
|||
bool initFromFontEngine(const QFontEngineFT *fontEngine);
|
||||
|
||||
HintStyle defaultHintStyle() const { return default_hint_style; }
|
||||
|
||||
protected:
|
||||
|
||||
QFreetypeFace *freetype;
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public:
|
|||
};
|
||||
virtual int synthesized() const { return 0; }
|
||||
virtual bool supportsSubPixelPositions() const { return false; }
|
||||
QFixed subPixelPositionForX(QFixed x);
|
||||
virtual QFixed subPixelPositionForX(QFixed x) const;
|
||||
|
||||
virtual QFixed emSquareSize() const { return ascent(); }
|
||||
|
||||
|
|
@ -277,6 +277,7 @@ public:
|
|||
|
||||
int glyphFormat;
|
||||
QImage currentlyLockedAlphaMap;
|
||||
int m_subPixelPositionCount; // Number of positions within a single pixel for this cache
|
||||
|
||||
protected:
|
||||
static const QVector<QRgb> &grayPalette();
|
||||
|
|
|
|||
|
|
@ -1654,7 +1654,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
|
|||
for (int i=0; i<staticTextItem->numGlyphs; ++i) {
|
||||
QFixed subPixelPosition;
|
||||
if (supportsSubPixelPositions)
|
||||
subPixelPosition = cache->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
|
||||
subPixelPosition = staticTextItem->fontEngine()->subPixelPositionForX(staticTextItem->glyphPositions[i].x);
|
||||
|
||||
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue