From b5922c89ba942f59d52ebbbf4986565ef410a14d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 15 Jan 2013 15:32:41 +0100 Subject: Add support for retina glyph-based text drawing in the GL paint-engine Instead of always using a non-transformed glyph-cache we now allow a scaled glyph-cache so that retina-screens can take advantage of this. We take the cache's scale into account when positioning and drawing the glyphs so that the scale is not applied twice. Change-Id: Ia927656f0070df61e78da76e97d2c49de4d856d9 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 34 ++++++++++++++++------ .../gl2paintengineex/qpaintengineex_opengl2_p.h | 1 + 2 files changed, 26 insertions(+), 9 deletions(-) (limited to 'src/opengl/gl2paintengineex') diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index ebff94da77..22be2e08a0 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1086,6 +1086,18 @@ void QGL2PaintEngineExPrivate::resetClipIfNeeded() glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } +bool QGL2PaintEngineExPrivate::prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache) +{ + Q_Q(QGL2PaintEngineEx); + + QTransform &transform = q->state()->matrix; + transform.scale(1.0 / cache.transform().m11(), 1.0 / cache.transform().m22()); + bool ret = prepareForDraw(false); + transform.scale(cache.transform().m11(), cache.transform().m22()); + + return ret; +} + bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) { if (brushTextureDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) @@ -1580,11 +1592,15 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp void *cacheKey = const_cast(QGLContextPrivate::contextGroup(ctx)->context()); bool recreateVertexArrays = false; + // We allow scaling, so that the glyph-cache will contain glyphs with the + // appropriate resolution in the case of displays with a device-pixel-ratio != 1. + QTransform transform = QTransform::fromScale(s->matrix.m11(), s->matrix.m22()); + QFontEngine *fe = staticTextItem->fontEngine(); QGLTextureGlyphCache *cache = - (QGLTextureGlyphCache *) fe->glyphCache(cacheKey, glyphType, QTransform()); + (QGLTextureGlyphCache *) fe->glyphCache(cacheKey, glyphType, transform); if (!cache || cache->cacheType() != glyphType || cache->contextGroup() == 0) { - cache = new QGLTextureGlyphCache(glyphType, QTransform()); + cache = new QGLTextureGlyphCache(glyphType, transform); fe->setGlyphCache(cacheKey, cache); recreateVertexArrays = true; } @@ -1676,8 +1692,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp if (c.isNull()) continue; - int x = qFloor(staticTextItem->glyphPositions[i].x) + c.baseLineX - margin; - int y = qRound(staticTextItem->glyphPositions[i].y) - c.baseLineY - margin; + 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; vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h)); textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy)); @@ -1750,9 +1766,9 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp } compositionModeDirty = false; // I can handle this myself, thank you very much - prepareForDraw(false); // Text always causes src pixels to be transparent + prepareForCachedGlyphDraw(*cache); - // prepareForDraw() have set the opacity on the current shader, so the opacity state can now be reset. + // prepareForCachedGlyphDraw() have set the opacity on the current shader, so the opacity state can now be reset. if (compMode == QPainter::CompositionMode_Source) { q->state()->opacity = oldOpacity; opacityUniformDirty = true; @@ -1773,7 +1789,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp } compositionModeDirty = false; // I can handle this myself, thank you very much - prepareForDraw(false); // Text always causes src pixels to be transparent + prepareForCachedGlyphDraw(*cache); glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); @@ -1797,7 +1813,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp } compositionModeDirty = false; - prepareForDraw(false); // Text always causes src pixels to be transparent + prepareForCachedGlyphDraw(*cache); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); } @@ -1806,7 +1822,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp // Greyscale/mono glyphs shaderManager->setMaskType(QGLEngineShaderManager::PixelMask); - prepareForDraw(false); // Text always causes src pixels to be transparent + prepareForCachedGlyphDraw(*cache); } QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index dd09046bc9..3004b5c9d0 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -227,6 +227,7 @@ public: void setBrush(const QBrush& brush); void transferMode(EngineMode newMode); bool prepareForDraw(bool srcPixelsAreOpaque); // returns true if the program has changed + bool prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache); inline void useSimpleShader(); inline GLuint location(const QGLEngineShaderManager::Uniform uniform) { return shaderManager->getUniformLocation(uniform); -- cgit v1.2.3