Rely solely on alphaMapBoundingBox in QTextureGlyphCache

We're currently adding a lot of transparent pixels to the cache,
wasting both memory and cpu cycles while drawing. AlphaMapBoundingBox
was introduced to return the exact same bounds as the alphaMapForGlyph
function so we should only rely on this instead of adding arbitrary
padding and margins all over the place.

Windows still has an arbitrary +4 in the its drawGDIGlyph() which
means batching will not work on windows, but at least now
other platforms do not need to suffer.

Change-Id: I714903fa195004400c09c3bf6570e46179775f09
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
This commit is contained in:
Gunnar Sletta 2013-09-04 15:17:05 +02:00 committed by The Qt Project
parent 0b481f28d1
commit 35bc3dc45a
5 changed files with 44 additions and 12 deletions

View File

@ -108,7 +108,6 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
#endif
m_current_fontengine = fontEngine;
const int margin = m_current_fontengine->glyphMargin(m_type);
const int padding = glyphPadding();
const int paddingDoubled = padding * 2;
@ -174,8 +173,6 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
coords.insert(key, c);
continue;
}
glyph_width += margin * 2 + 4;
glyph_height += margin * 2 + 4;
// align to 8-bit boundary
if (m_type == QFontEngineGlyphCache::Raster_Mono)
glyph_width = (glyph_width+7)&~7;
@ -192,7 +189,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
if (listItemCoordinates.isEmpty())
return true;
rowHeight += margin * 2 + paddingDoubled;
rowHeight += paddingDoubled;
if (m_w == 0) {
if (fontEngine->maxCharWidth() <= QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH)
@ -207,7 +204,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
while (iter != listItemCoordinates.end()) {
Coord c = iter.value();
m_currentRowHeight = qMax(m_currentRowHeight, c.h + margin * 2);
m_currentRowHeight = qMax(m_currentRowHeight, c.h);
if (m_cx + c.w + padding > requiredWidth) {
int new_width = requiredWidth*2;
@ -219,7 +216,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
// no room on the current line, start new glyph strip
m_cx = padding;
m_cy += m_currentRowHeight + paddingDoubled;
m_currentRowHeight = c.h + margin * 2; // New row
m_currentRowHeight = c.h; // New row
}
}

View File

@ -444,18 +444,38 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position
}
}
QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool aa, const QTransform &m)
static void qcoretextfontengine_scaleMetrics(glyph_metrics_t &br, const QTransform &matrix)
{
glyph_metrics_t br = boundingBox(glyph);
if (m.isScaling()) {
qreal hscale = m.m11();
qreal vscale = m.m22();
if (matrix.isScaling()) {
qreal hscale = matrix.m11();
qreal vscale = matrix.m22();
br.width = QFixed::fromReal(br.width.toReal() * hscale);
br.height = QFixed::fromReal(br.height.toReal() * vscale);
br.x = QFixed::fromReal(br.x.toReal() * hscale);
br.y = QFixed::fromReal(br.y.toReal() * vscale);
}
}
glyph_metrics_t QCoreTextFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed pos, const QTransform &matrix, GlyphFormat format)
{
if (matrix.type() > QTransform::TxScale)
return QFontEngine::alphaMapBoundingBox(glyph, pos, matrix, format);
glyph_metrics_t br = boundingBox(glyph);
qcoretextfontengine_scaleMetrics(br, matrix);
br.width = qAbs(qRound(br.width)) + 2;
br.height = qAbs(qRound(br.height)) + 2;
return br;
}
QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool aa, const QTransform &m)
{
glyph_metrics_t br = boundingBox(glyph);
qcoretextfontengine_scaleMetrics(br, m);
bool isColorGlyph = glyphFormat == QFontEngineGlyphCache::Raster_ARGB;
QImage::Format format = isColorGlyph ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;

View File

@ -96,6 +96,7 @@ public:
virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition);
virtual QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t);
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat);
virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t);
virtual qreal minRightBearing() const;
virtual qreal minLeftBearing() const;

View File

@ -1133,6 +1133,8 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph,
<< "If you need them anyway, start your application with -platform windows:fontengine=freetype.";
}
#endif // wince
// The padding here needs to be kept in sync with the values in alphaMapBoundingBox.
QWindowsNativeImage *ni = new QWindowsNativeImage(iw + 2 * margin + 4,
ih + 2 * margin + 4,
QWindowsNativeImage::systemFormat());
@ -1167,6 +1169,17 @@ QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph,
return ni;
}
glyph_metrics_t QWindowsFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed pos, const QTransform &matrix, GlyphFormat format)
{
int margin = 0;
if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB)
margin = glyphMargin(QFontEngineGlyphCache::Raster_RGBMask);
glyph_metrics_t gm = boundingBox(glyph, matrix);
gm.width += margin * 2 + 4;
gm.height += margin * 2 + 4;
return gm;
}
QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
{
HFONT font = hfont;

View File

@ -121,6 +121,7 @@ public:
virtual QImage alphaMapForGlyph(glyph_t t) { return alphaMapForGlyph(t, QTransform()); }
virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform);
virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform);
virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat);
virtual QFontEngine *cloneWithSize(qreal pixelSize) const;
virtual bool supportsTransformation(const QTransform &transform) const;