diff options
author | Jiang Jiang <jiang.jiang@nokia.com> | 2011-04-01 15:07:18 (GMT) |
---|---|---|
committer | Jiang Jiang <jiang.jiang@nokia.com> | 2011-04-04 10:49:07 (GMT) |
commit | 3cdbe0c7bc42f5f3bcb8c2f6d93cbb4d20c720e2 (patch) | |
tree | a9a2940e00c9bccbf01d62e0e728336fe6e2faba /src/gui | |
parent | cb705c2e3c35fa7c6d70a9348477450cddf50633 (diff) | |
download | Qt-3cdbe0c7bc42f5f3bcb8c2f6d93cbb4d20c720e2.zip Qt-3cdbe0c7bc42f5f3bcb8c2f6d93cbb4d20c720e2.tar.gz Qt-3cdbe0c7bc42f5f3bcb8c2f6d93cbb4d20c720e2.tar.bz2 |
Fix positioning in GL2 paint engine with subpixel antialiasing
In this case we will use QTextureGlyphCache with FreeType renderer,
which requires the subpixel positition to get correct left bearings,
thus alphaMapBoundingBox is extended to support subPixelPosition.
In QFontEngineFT we also simplify the code a bit by reusing
loadGlyphs for metrics calculation instead of duplicate code. Since
we need to use the glyphs after all, cache them here in
alphaMapBoundingBox shouldn't be a problem.
Reviewed-by: Eskil
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/painting/qtextureglyphcache.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 109 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft_p.h | 5 | ||||
-rw-r--r-- | src/gui/text/qfontengine_p.h | 2 |
4 files changed, 11 insertions, 107 deletions
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 727852d..53f025f 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -168,7 +168,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const continue; if (listItemCoordinates.contains(GlyphAndSubPixelPosition(glyph, subPixelPosition))) continue; - glyph_metrics_t metrics = fontEngine->alphaMapBoundingBox(glyph, m_transform, format); + glyph_metrics_t metrics = fontEngine->alphaMapBoundingBox(glyph, subPixelPosition, m_transform, format); #ifdef CACHE_DEBUG printf("(%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n", diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 08eb6bb..ffdaaa7 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -791,106 +791,6 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags, return load_flags; } -QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const -{ - Glyph *g = set->getGlyph(glyph); - if (g && g->format == format) - return g; - - bool hsubpixel = false; - int vfactor = 1; - int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor); - - // apply our matrix to this, but note that the metrics will not be affected by this. - FT_Face face = lockFace(); - FT_Matrix matrix = this->matrix; - FT_Matrix_Multiply(&set->transformationMatrix, &matrix); - FT_Set_Transform(face, &matrix, 0); - freetype->matrix = matrix; - - bool transform = matrix.xx != 0x10000 || matrix.yy != 0x10000 || matrix.xy != 0 || matrix.yx != 0; - if (transform) - load_flags |= FT_LOAD_NO_BITMAP; - - FT_Error err = FT_Load_Glyph(face, glyph, load_flags); - if (err && (load_flags & FT_LOAD_NO_BITMAP)) { - load_flags &= ~FT_LOAD_NO_BITMAP; - err = FT_Load_Glyph(face, glyph, load_flags); - } - if (err == FT_Err_Too_Few_Arguments) { - // this is an error in the bytecode interpreter, just try to run without it - load_flags |= FT_LOAD_FORCE_AUTOHINT; - err = FT_Load_Glyph(face, glyph, load_flags); - } - if (err != FT_Err_Ok) - qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph); - - unlockFace(); - if (set->outline_drawing) - return 0; - - if (!g) { - g = new Glyph; - g->uploadedToServer = false; - g->data = 0; - } - - FT_GlyphSlot slot = face->glyph; - if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(slot); - int left = slot->metrics.horiBearingX; - int right = slot->metrics.horiBearingX + slot->metrics.width; - int top = slot->metrics.horiBearingY; - int bottom = slot->metrics.horiBearingY - slot->metrics.height; - if(transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { // freetype doesn't apply the transformation on the metrics - int l, r, t, b; - FT_Vector vector; - vector.x = left; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - l = r = vector.x; - t = b = vector.y; - vector.x = right; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = right; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = left; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - left = l; - right = r; - top = t; - bottom = b; - } - left = FLOOR(left); - right = CEIL(right); - bottom = FLOOR(bottom); - top = CEIL(top); - - g->linearAdvance = face->glyph->linearHoriAdvance >> 10; - g->width = TRUNC(right-left); - g->height = TRUNC(top-bottom); - g->x = TRUNC(left); - g->y = TRUNC(top); - g->advance = TRUNC(ROUND(face->glyph->advance.x)); - g->format = Format_None; - - return g; -} - QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat format, @@ -1792,10 +1692,10 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph) glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph, const QTransform &matrix) { - return alphaMapBoundingBox(glyph, matrix, QFontEngine::Format_None); + return alphaMapBoundingBox(glyph, 0, matrix, QFontEngine::Format_None); } -glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, const QTransform &matrix, QFontEngine::GlyphFormat format) +glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, QFontEngine::GlyphFormat format) { FT_Face face = 0; glyph_metrics_t overall; @@ -1842,7 +1742,10 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, const QTransfo Glyph * g = glyphSet->getGlyph(glyph); if (!g || g->format != format) { face = lockFace(); - g = loadGlyphMetrics(glyphSet, glyph, format); + FT_Matrix m = this->matrix; + FT_Matrix_Multiply(&glyphSet->transformationMatrix, &m); + freetype->matrix = m; + g = loadGlyph(glyphSet, glyph, subPixelPosition, format); } if (g) { diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index fc3ac82..451d26e 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -257,7 +257,9 @@ private: virtual QImage alphaMapForGlyph(glyph_t g) { return alphaMapForGlyph(g, 0); } virtual QImage alphaMapForGlyph(glyph_t, QFixed); virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); - virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, const QTransform &matrix, + virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, + QFixed subPixelPosition, + const QTransform &matrix, QFontEngine::GlyphFormat format); virtual void removeGlyphFromCache(glyph_t glyph); @@ -333,7 +335,6 @@ protected: bool embeddedbitmap; private: - QFontEngineFT::Glyph *loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const; int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const; GlyphFormat defaultFormat; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index f501141..7b29993 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -203,7 +203,7 @@ public: virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); - virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, const QTransform &matrix, GlyphFormat /*format*/) + virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/) { return boundingBox(glyph, matrix); } |