diff options
author | Jiang Jiang <jiang.jiang@nokia.com> | 2011-02-22 13:15:43 (GMT) |
---|---|---|
committer | Jiang Jiang <jiang.jiang@nokia.com> | 2011-03-22 11:03:51 (GMT) |
commit | 037e632d4b3884d06bf9e92de77d726c75fe7898 (patch) | |
tree | 6834662159359112e2b2b8acf43f574990dda0e3 /src/gui/painting | |
parent | 23098630c94e6655a33042bee0caa6c933c0c7d9 (diff) | |
download | Qt-037e632d4b3884d06bf9e92de77d726c75fe7898.zip Qt-037e632d4b3884d06bf9e92de77d726c75fe7898.tar.gz Qt-037e632d4b3884d06bf9e92de77d726c75fe7898.tar.bz2 |
Implement subpixel positioning with FreeType
QFontEngineFT are used in raster/OpenGL paint engine and QGLWidget,
also in Symbian, etc. We want to make sure it works well in raster
and QGLWidget first. Regardless subpixel antialiasing (LCD filtering)
is enabled or not (though it does look better when subpixel
antialiasing is on). We also need to support transformations.
The tricky part here is that, under X11, we have a different code
path for QFontEngineFT and other font engines in raster engine,
which uses QFontEngineFT's own glyph cache system. While in other
platforms (Windows and Mac) and QGLWidget, we will use the generic
QTextureGlyphCache.
The generic QTextureGlyphCache already has support for subpixel
positions, this solution is ported to QFontEngineFT for its
QGlyphSet: the key for QGlyphSet hash table has been extended from
glyph_t to <glyph_t, QFixed subPixelPosition> pair.
The real work to enable subpixel positioning with FreeType is in
fact really simple, we just set the horizontal translation to the
subpixel position * 64 (FreeType uses a coordinate system of 1/64
of a pixel resolution internally) immediately before loading the
glyph. A slight tweek to bitmap width is applied when we are
getting the bitmap ourselves instead of using FT_Render_Glyph to
accommodate the subpixel translation, which will only be used in
non-LCD filtering cases (grayscale antialiasing).
From what we have observed, FreeType can generate different bitmaps
for at least 12 different subpixel positions (each with a slight
difference). To limit the memory consumption, we restrict the
number of subpixel positions to be 4 (hardcoded), which should be
good enough for most low resolution displays.
Subpixel positioning (and fractional glyph advances) will only be
enabled when the hintingPreference for the font being used is
PreferNoHinting or PreferVerticalHinting. We will use fontconfig
hintstyle setting by default when no hintingPreference is set for
the font.
Task-number: QTBUG-12279
Reviewed-by: Eskil
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 7 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_x11.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qtextureglyphcache.cpp | 10 |
3 files changed, 13 insertions, 6 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 9242fb6..3af98d6 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3469,7 +3469,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte } if (!gset || gset->outline_drawing - || !fe->loadGlyphs(gset, glyphs.data(), glyphs.size(), neededFormat)) + || !fe->loadGlyphs(gset, glyphs.data(), glyphs.size(), positions, neededFormat)) { QPaintEngine::drawTextItem(p, ti); return; @@ -3494,12 +3494,13 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte }; for(int i = 0; i < glyphs.size(); i++) { - QFontEngineFT::Glyph *glyph = gset->getGlyph(glyphs[i]); + QFixed spp = fe->subPixelPositionForX(positions[i].x); + QFontEngineFT::Glyph *glyph = gset->getGlyph(glyphs[i], spp); if (!glyph || glyph->format != neededFormat) { if (!lockedFace) lockedFace = fe->lockFace(); - glyph = fe->loadGlyph(gset, glyphs[i], neededFormat); + glyph = fe->loadGlyph(gset, glyphs[i], spp, neededFormat); } if (!glyph || !glyph->data) diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 8b71b83..16ef09b 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -2385,7 +2385,7 @@ void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti) set = ft->loadTransformedGlyphSet(d->matrix); if (!set || set->outline_drawing - || !ft->loadGlyphs(set, glyphs.data(), glyphs.size(), QFontEngineFT::Format_Render)) + || !ft->loadGlyphs(set, glyphs.data(), glyphs.size(), positions, QFontEngineFT::Format_Render)) { QPaintEngine::drawTextItem(p, ti); return; diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index e75c0f5..b83dbc0 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -134,9 +134,13 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const if (!supportsSubPixelPositions) { m_subPixelPositionCount = 1; } else { +#if !defined(Q_WS_X11) int i = 0; while (m_subPixelPositionCount == 0 && i < numGlyphs) m_subPixelPositionCount = calculateSubPixelPositionCount(glyphs[i++]); +#else + m_subPixelPositionCount = 4; +#endif } } @@ -307,9 +311,11 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_fontengine); QFontEngineFT::QGlyphSet *gset = ft->loadTransformedGlyphSet(m_transform); + QFontEngineFT::Glyph *glyph = NULL; + if (gset) + glyph = ft->loadGlyph(gset, g, subPixelPosition, format); - if (gset && ft->loadGlyphs(gset, &g, 1, format)) { - QFontEngineFT::Glyph *glyph = gset->getGlyph(g); + if (glyph) { const int bytesPerLine = (format == QFontEngineFT::Format_Mono ? ((glyph->width + 31) & ~31) >> 3 : (glyph->width + 3) & ~3); return QImage(glyph->data, glyph->width, glyph->height, bytesPerLine, imageFormat); |