From 134c6db8587a8ce156d4fa31ffa62605821851b2 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 7 Mar 2015 07:20:50 +0400 Subject: [QFontEngineFT] Consolidate .*lpha.*MapForGlyph() behavior ...and decrease code duplication. Change-Id: I5eb3c0694dde9030405a3bd3d410ff9784ed7717 Reviewed-by: Lars Knoll --- src/gui/text/qfontengine_ft.cpp | 123 +++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 71 deletions(-) (limited to 'src/gui/text/qfontengine_ft.cpp') diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 8176ede994..03b9e6ef99 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1725,6 +1725,33 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe return overall; } +static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEngine::GlyphFormat glyphFormat) +{ + if (glyph == Q_NULLPTR) + return QImage(); + + QImage::Format format; + int bytesPerLine; + switch (glyphFormat) { + case QFontEngine::Format_Mono: + format = QImage::Format_Mono; + bytesPerLine = ((glyph->width + 31) & ~31) >> 3; + break; + case QFontEngine::Format_A8: + format = QImage::Format_Alpha8; + bytesPerLine = (glyph->width + 3) & ~3; + break; + case QFontEngine::Format_A32: + format = QImage::Format_ARGB32; + bytesPerLine = glyph->width * 4; + break; + default: + Q_UNREACHABLE(); + }; + + return QImage(static_cast(glyph->data), glyph->width, glyph->height, bytesPerLine, format); +} + QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixelPosition, QFontEngine::GlyphFormat neededFormat, const QTransform &t, QPoint *offset) @@ -1739,22 +1766,6 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe else if (neededFormat == Format_None) neededFormat = Format_A8; - QImage::Format format; - switch (neededFormat) { - case Format_Mono: - format = QImage::Format_Mono; - break; - case Format_A8: - format = QImage::Format_Alpha8; - break; - case Format_A32: - format = QImage::Format_ARGB32; - break; - default: - Q_ASSERT(false); - format = QImage::Format_Invalid; - }; - QFontEngineFT::Glyph *glyph; if (cacheEnabled) { QGlyphSet *gset = loadGlyphSet(t); @@ -1787,38 +1798,20 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe glyph = loadGlyph(0, glyphIndex, subPixelPosition, neededFormat); } - if (glyph == 0 || glyph->data == 0 || glyph->width == 0 || glyph->height == 0) { - if (!cacheEnabled && glyph != &emptyGlyph) - delete glyph; - unlockFace(); - return 0; - } - - int pitch; - switch (neededFormat) { - case Format_Mono: - pitch = ((glyph->width + 31) & ~31) >> 3; - break; - case Format_A8: - pitch = (glyph->width + 3) & ~3; - break; - case Format_A32: - pitch = glyph->width * 4; - break; - default: - Q_ASSERT(false); - pitch = 0; - }; - - if (offset != 0) + if (offset != 0 && glyph != 0) *offset = QPoint(glyph->x, -glyph->y); - currentlyLockedAlphaMap = QImage(glyph->data, glyph->width, glyph->height, pitch, format); + currentlyLockedAlphaMap = alphaMapFromGlyphData(glyph, neededFormat); + if (!cacheEnabled && glyph != &emptyGlyph) { currentlyLockedAlphaMap = currentlyLockedAlphaMap.copy(); delete glyph; } - Q_ASSERT(!currentlyLockedAlphaMap.isNull()); + + if (currentlyLockedAlphaMap.isNull()) { + unlockFace(); + return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset); + } QImageData *data = currentlyLockedAlphaMap.data_ptr(); data->is_locked = true; @@ -1864,32 +1857,20 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition) QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t) { - Glyph *glyph = loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono, t); - if (!glyph || !glyph->data) { - if (!cacheEnabled && glyph != &emptyGlyph) - delete glyph; - return QFontEngine::alphaMapForGlyph(g); - } + const GlyphFormat neededFormat = antialias ? Format_A8 : Format_Mono; - const int pitch = antialias ? (glyph->width + 3) & ~3 : ((glyph->width + 31)/32) * 4; + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); - QImage img(glyph->width, glyph->height, antialias ? QImage::Format_Alpha8 : QImage::Format_Mono); - if (!antialias) { - QVector colors(2); - colors[0] = qRgba(0, 0, 0, 0); - colors[1] = qRgba(0, 0, 0, 255); - img.setColorTable(colors); - } - Q_ASSERT(img.bytesPerLine() == pitch); - if (glyph->width) { - for (int y = 0; y < glyph->height; ++y) - memcpy(img.scanLine(y), &glyph->data[y * pitch], pitch); - } + QImage img = alphaMapFromGlyphData(glyph, neededFormat); + img = img.copy(); if (!cacheEnabled && glyph != &emptyGlyph) delete glyph; - return img; + if (!img.isNull()) + return img; + + return QFontEngine::alphaMapForGlyph(g); } QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t) @@ -1897,20 +1878,20 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co if (t.type() > QTransform::TxRotate) return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); - Glyph *glyph = loadGlyphFor(g, subPixelPosition, Format_A32, t); - if (!glyph || !glyph->data) { - if (!cacheEnabled && glyph != &emptyGlyph) - delete glyph; - return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); - } + const GlyphFormat neededFormat = Format_A32; - QImage img(glyph->width, glyph->height, QImage::Format_RGB32); - memcpy(img.bits(), glyph->data, 4 * glyph->width * glyph->height); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); + + QImage img = alphaMapFromGlyphData(glyph, neededFormat); + img = img.copy(); if (!cacheEnabled && glyph != &emptyGlyph) delete glyph; - return img; + if (!img.isNull()) + return img; + + return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); } void QFontEngineFT::removeGlyphFromCache(glyph_t glyph) -- cgit v1.2.3