Enable transformations for Qt Quick in FT engine
In Qt Quick (or in Qt Widgets when setting QT_NO_FT_CACHE to 1 or when using OpenGL engine), the alphaRGBMapForGlyph() will be used to get glyphs, because we need to keep our own cache. Transforms was not supported in this code path, instead it was turned off in supportsTransformations(). This patch enables transformations in the alphaRGBMapForGlyph() and alphaMapForGlyph() code paths as well, since this is needed for proper rendering with QT_DEVICE_PIXEL_RATIO. Change-Id: I7d6b79918f7c0bcc051a8343b16b315bfbba59cf Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
bec1854cc0
commit
41db4b8cdc
@ -1459,10 +1459,7 @@ void QFontEngineFT::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_me
|
||||
|
||||
bool QFontEngineFT::supportsTransformation(const QTransform &transform) const
|
||||
{
|
||||
// The freetype engine falls back to QFontEngine for tranformed glyphs,
|
||||
// which uses fast-tranform and produces very ugly results, so we claim
|
||||
// to support just translations.
|
||||
return transform.type() <= QTransform::TxTranslate;
|
||||
return transform.type() <= QTransform::TxRotate;
|
||||
}
|
||||
|
||||
void QFontEngineFT::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
|
||||
@ -1943,17 +1940,75 @@ void QFontEngineFT::unlockAlphaMapForGlyph()
|
||||
currentlyLockedAlphaMap = QImage();
|
||||
}
|
||||
|
||||
QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format)
|
||||
QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
|
||||
QFixed subPixelPosition,
|
||||
GlyphFormat format,
|
||||
const QTransform &t)
|
||||
{
|
||||
return defaultGlyphSet.outline_drawing ? 0 :
|
||||
loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, g, subPixelPosition, format);
|
||||
FT_Face face = 0;
|
||||
QGlyphSet *glyphSet = 0;
|
||||
FT_Matrix ftMatrix = QTransformToFTMatrix(t);
|
||||
if (cacheEnabled) {
|
||||
if (t.type() > QTransform::TxTranslate && FT_IS_SCALABLE(freetype->face)) {
|
||||
for (int i = 0; i < transformedGlyphSets.count(); ++i) {
|
||||
const QGlyphSet &g = transformedGlyphSets.at(i);
|
||||
if (g.transformationMatrix.xx == ftMatrix.xx
|
||||
&& g.transformationMatrix.xy == ftMatrix.xy
|
||||
&& g.transformationMatrix.yx == ftMatrix.yx
|
||||
&& g.transformationMatrix.yy == ftMatrix.yy) {
|
||||
|
||||
// found a match, move it to the front
|
||||
transformedGlyphSets.move(i, 0);
|
||||
glyphSet = &transformedGlyphSets[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!glyphSet) {
|
||||
// don't cache more than 10 transformations
|
||||
if (transformedGlyphSets.count() >= 10) {
|
||||
transformedGlyphSets.move(transformedGlyphSets.size() - 1, 0);
|
||||
} else {
|
||||
transformedGlyphSets.prepend(QGlyphSet());
|
||||
}
|
||||
glyphSet = &transformedGlyphSets[0];
|
||||
glyphSet->clear();
|
||||
glyphSet->transformationMatrix = ftMatrix;
|
||||
}
|
||||
} else {
|
||||
glyphSet = &defaultGlyphSet;
|
||||
}
|
||||
Q_ASSERT(glyphSet != 0);
|
||||
}
|
||||
|
||||
if (glyphSet != 0 && glyphSet->outline_drawing)
|
||||
return 0;
|
||||
|
||||
Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0;
|
||||
if (!glyph || glyph->format != format) {
|
||||
face = lockFace();
|
||||
FT_Matrix m = this->matrix;
|
||||
FT_Matrix_Multiply(&ftMatrix, &m);
|
||||
freetype->matrix = m;
|
||||
glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false);
|
||||
}
|
||||
|
||||
if (face)
|
||||
unlockFace();
|
||||
|
||||
return glyph;
|
||||
}
|
||||
|
||||
QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
|
||||
{
|
||||
return alphaMapForGlyph(g, subPixelPosition, QTransform());
|
||||
}
|
||||
|
||||
QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
|
||||
{
|
||||
lockFace();
|
||||
|
||||
QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono));
|
||||
QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono, t));
|
||||
if (!glyph || !glyph->data) {
|
||||
unlockFace();
|
||||
return QFontEngine::alphaMapForGlyph(g);
|
||||
@ -1987,12 +2042,12 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
|
||||
|
||||
QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
|
||||
{
|
||||
if (t.type() > QTransform::TxTranslate)
|
||||
if (t.type() > QTransform::TxRotate)
|
||||
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
|
||||
|
||||
lockFace();
|
||||
|
||||
QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, Format_A32));
|
||||
QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, Format_A32, t));
|
||||
if (!glyph || !glyph->data) {
|
||||
unlockFace();
|
||||
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
|
||||
|
@ -233,6 +233,7 @@ private:
|
||||
virtual void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags flags) const;
|
||||
virtual QImage alphaMapForGlyph(glyph_t g) { return alphaMapForGlyph(g, 0); }
|
||||
virtual QImage alphaMapForGlyph(glyph_t, QFixed);
|
||||
QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t);
|
||||
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
|
||||
virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
|
||||
QFixed subPixelPosition,
|
||||
@ -265,7 +266,7 @@ private:
|
||||
inline Glyph *loadGlyph(uint glyph, QFixed subPixelPosition, GlyphFormat format = Format_None, bool fetchMetricsOnly = false) const
|
||||
{ return loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyph, subPixelPosition, format, fetchMetricsOnly); }
|
||||
Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false) const;
|
||||
Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format);
|
||||
Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t);
|
||||
|
||||
QGlyphSet *loadTransformedGlyphSet(const QTransform &matrix);
|
||||
bool loadGlyphs(QGlyphSet *gs, const glyph_t *glyphs, int num_glyphs,
|
||||
|
Loading…
Reference in New Issue
Block a user