diff options
Diffstat (limited to 'src/gui/text/qfontengine_ft.cpp')
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 221 |
1 files changed, 84 insertions, 137 deletions
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 25156bf1e1..8176ede994 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -76,34 +76,6 @@ QT_BEGIN_NAMESPACE -/* - * Freetype 2.1.7 and earlier used width/height - * for matching sizes in the BDF and PCF loaders. - * This has been fixed for 2.1.8. - */ -#if (FREETYPE_MAJOR*10000+FREETYPE_MINOR*100+FREETYPE_PATCH) >= 20105 -#define X_SIZE(face,i) ((face)->available_sizes[i].x_ppem) -#define Y_SIZE(face,i) ((face)->available_sizes[i].y_ppem) -#else -#define X_SIZE(face,i) ((face)->available_sizes[i].width << 6) -#define Y_SIZE(face,i) ((face)->available_sizes[i].height << 6) -#endif - -/* FreeType 2.1.10 starts to provide FT_GlyphSlot_Embolden */ -#if (FREETYPE_MAJOR*10000+FREETYPE_MINOR*100+FREETYPE_PATCH) >= 20110 -#define Q_FT_GLYPHSLOT_EMBOLDEN(slot) FT_GlyphSlot_Embolden(slot) -#else -#define Q_FT_GLYPHSLOT_EMBOLDEN(slot) -#endif - -/* FreeType 2.1.10 starts to provide FT_GlyphSlot_Oblique */ -#if (FREETYPE_MAJOR*10000+FREETYPE_MINOR*100+FREETYPE_PATCH) >= 20110 -#define Q_HAS_FT_GLYPHSLOT_OBLIQUE -#define Q_FT_GLYPHSLOT_OBLIQUE(slot) FT_GlyphSlot_Oblique(slot) -#else -#define Q_FT_GLYPHSLOT_OBLIQUE(slot) -#endif - #define FLOOR(x) ((x) & -64) #define CEIL(x) (((x)+63) & -64) #define TRUNC(x) ((x) >> 6) @@ -297,7 +269,7 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id, } if (!FT_IS_SCALABLE(newFreetype->face) && newFreetype->face->num_fixed_sizes == 1) - FT_Set_Char_Size (face, X_SIZE(newFreetype->face, 0), Y_SIZE(newFreetype->face, 0), 0, 0); + FT_Set_Char_Size(face, newFreetype->face->available_sizes[0].x_ppem, newFreetype->face->available_sizes[0].y_ppem, 0, 0); FT_Set_Charmap(newFreetype->face, newFreetype->unicode_map); QT_TRY { @@ -357,18 +329,18 @@ void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) { int best = 0; for (int i = 1; i < face->num_fixed_sizes; i++) { - if (qAbs(*ysize - Y_SIZE(face,i)) < - qAbs (*ysize - Y_SIZE(face, best)) || - (qAbs (*ysize - Y_SIZE(face, i)) == - qAbs (*ysize - Y_SIZE(face, best)) && - qAbs (*xsize - X_SIZE(face, i)) < - qAbs (*xsize - X_SIZE(face, best)))) { + if (qAbs(*ysize - face->available_sizes[i].y_ppem) < + qAbs(*ysize - face->available_sizes[best].y_ppem) || + (qAbs(*ysize - face->available_sizes[i].y_ppem) == + qAbs(*ysize - face->available_sizes[best].y_ppem) && + qAbs(*xsize - face->available_sizes[i].x_ppem) < + qAbs(*xsize - face->available_sizes[best].x_ppem))) { best = i; } } - if (FT_Set_Char_Size (face, X_SIZE(face, best), Y_SIZE(face, best), 0, 0) == 0) { - *xsize = X_SIZE(face, best); - *ysize = Y_SIZE(face, best); + if (FT_Set_Char_Size(face, face->available_sizes[best].x_ppem, face->available_sizes[best].y_ppem, 0, 0) == 0) { + *xsize = face->available_sizes[best].x_ppem; + *ysize = face->available_sizes[best].y_ppem; } else { int err = 1; if (!(face->face_flags & FT_FACE_FLAG_SCALABLE) && ysize == 0 && face->num_fixed_sizes >= 1) { @@ -538,7 +510,7 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data, int bpl, int w, int h, QPainterPath *path); -void QFreetypeFace::addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool) +void QFreetypeFace::addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path) { if (slot->format != FT_GLYPH_FORMAT_BITMAP || slot->bitmap.pixel_mode != FT_PIXEL_MODE_MONO) @@ -719,14 +691,8 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, if (FT_IS_SCALABLE(face)) { bool fake_oblique = (fontDef.style != QFont::StyleNormal) && !(face->style_flags & FT_STYLE_FLAG_ITALIC); - if (fake_oblique) { -#if !defined(Q_HAS_FT_GLYPHSLOT_OBLIQUE) - matrix.xy = 0x10000*3/10; - transform = true; -#else + if (fake_oblique) obliquen = true; -#endif - } FT_Set_Transform(face, &matrix, 0); freetype->matrix = matrix; // fake bold @@ -758,7 +724,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, */ if (FT_IS_SCALABLE(face)) { for (int i = 0; i < face->num_fixed_sizes; ++i) { - if (xsize == X_SIZE(face, i) && ysize == Y_SIZE(face, i)) { + if (xsize == face->available_sizes[i].x_ppem && ysize == face->available_sizes[i].y_ppem) { face->face_flags &= ~FT_FACE_FLAG_SCALABLE; FT_Select_Size(face, i); @@ -908,9 +874,10 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, FT_GlyphSlot slot = face->glyph; - if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(slot); + if (embolden) + FT_GlyphSlot_Embolden(slot); if (obliquen) { - Q_FT_GLYPHSLOT_OBLIQUE(slot); + FT_GlyphSlot_Oblique(slot); // While Embolden alters the metrics of the slot, oblique does not, so we need // to fix this ourselves. @@ -924,8 +891,6 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, FT_Matrix_Multiply(&m, &matrix); } - FT_Library library = qt_getFreetype(); - info.xOff = TRUNC(ROUND(slot->advance.x)); info.yOff = 0; @@ -963,12 +928,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, return g; } - uchar *glyph_buffer = 0; int glyph_buffer_size = 0; + QScopedArrayPointer<uchar> glyph_buffer; #if defined(QT_USE_FREETYPE_LCDFILTER) bool useFreetypeRenderGlyph = false; if (slot->format == FT_GLYPH_FORMAT_OUTLINE && (hsubpixel || vfactor != 1)) { - err = FT_Library_SetLcdFilter(library, (FT_LcdFilter)lcdFilterType); + err = FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType); if (err == FT_Err_Ok) useFreetypeRenderGlyph = true; } @@ -979,7 +944,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, if (err != FT_Err_Ok) qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph); - FT_Library_SetLcdFilter(library, FT_LCD_FILTER_NONE); + FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE); info.height = slot->bitmap.rows / vfactor; info.width = hsubpixel ? slot->bitmap.width / 3 : slot->bitmap.width; @@ -987,12 +952,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, info.y = slot->bitmap_top; glyph_buffer_size = info.width * info.height * 4; - glyph_buffer = new uchar[glyph_buffer_size]; + glyph_buffer.reset(new uchar[glyph_buffer_size]); if (hsubpixel) - convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false); + convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false); else if (vfactor != 1) - convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false); + convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false); } else #endif { @@ -1063,26 +1028,30 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, || ((signed char)(info.xOff) != info.xOff)); if (large_glyph) { - delete [] glyph_buffer; return 0; } int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 : (format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4)); - glyph_buffer_size = pitch * info.height; - glyph_buffer = new uchar[glyph_buffer_size]; - memset(glyph_buffer, 0, glyph_buffer_size); + if (glyph_buffer_size < pitch * info.height) { + glyph_buffer_size = pitch * info.height; + glyph_buffer.reset(new uchar[glyph_buffer_size]); + } + memset(glyph_buffer.data(), 0, glyph_buffer_size); if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { FT_Bitmap bitmap; bitmap.rows = info.height*vfactor; bitmap.width = hpixels; bitmap.pitch = format == Format_Mono ? (((info.width + 31) & ~31) >> 3) : ((bitmap.width + 3) & ~3); - if (!hsubpixel && vfactor == 1 && format != Format_A32) - bitmap.buffer = glyph_buffer; - else - bitmap.buffer = new uchar[bitmap.rows*bitmap.pitch]; - memset(bitmap.buffer, 0, bitmap.rows*bitmap.pitch); + int bitmap_buffer_size = bitmap.rows * bitmap.pitch; + if (!hsubpixel && vfactor == 1 && format != Format_A32) { + Q_ASSERT(glyph_buffer_size <= bitmap_buffer_size); + bitmap.buffer = glyph_buffer.data(); + } else { + bitmap.buffer = new uchar[bitmap_buffer_size]; + memset(bitmap.buffer, 0, bitmap_buffer_size); + } bitmap.pixel_mode = format == Format_Mono ? FT_PIXEL_MODE_MONO : FT_PIXEL_MODE_GRAY; FT_Matrix matrix; matrix.xx = (hsubpixel ? 3 : 1) << 16; @@ -1091,11 +1060,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, FT_Outline_Transform(&slot->outline, &matrix); FT_Outline_Translate (&slot->outline, (hsubpixel ? -3*left +(4<<6) : -left), -bottom*vfactor); - FT_Outline_Get_Bitmap(library, &slot->outline, &bitmap); + FT_Outline_Get_Bitmap(slot->library, &slot->outline, &bitmap); if (hsubpixel) { Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); Q_ASSERT(antialias); - uchar *convoluted = new uchar[bitmap.rows*bitmap.pitch]; + uchar *convoluted = new uchar[bitmap_buffer_size]; bool useLegacyLcdFilter = false; #if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H) useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY); @@ -1105,20 +1074,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch); buffer = convoluted; } - convertRGBToARGB(buffer + 1, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter); + convertRGBToARGB(buffer + 1, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter); delete [] convoluted; } else if (vfactor != 1) { - convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true); + convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true); } else if (format == Format_A32 && bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) { - convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer, info.width, info.height, bitmap.pitch); + convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch); } - if (bitmap.buffer != glyph_buffer) + if (bitmap.buffer != glyph_buffer.data()) delete [] bitmap.buffer; } else if (slot->format == FT_GLYPH_FORMAT_BITMAP) { Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO); uchar *src = slot->bitmap.buffer; - uchar *dst = glyph_buffer; + uchar *dst = glyph_buffer.data(); int h = slot->bitmap.rows; if (format == Format_Mono) { int bytes = ((info.width + 7) & ~7) >> 3; @@ -1163,7 +1132,6 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, } } else { qWarning("QFontEngine: Glyph neither outline nor bitmap format=%d", slot->format); - delete [] glyph_buffer; return 0; } } @@ -1182,7 +1150,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, g->advance = info.xOff; g->format = format; delete [] g->data; - g->data = glyph_buffer; + g->data = glyph_buffer.take(); if (set) set->setGlyph(glyph, subPixelPosition, g); @@ -1366,14 +1334,14 @@ static inline FT_Matrix QTransformToFTMatrix(const QTransform &matrix) return m; } -QFontEngineFT::QGlyphSet *QFontEngineFT::loadTransformedGlyphSet(const QTransform &matrix) +QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix) { if (matrix.type() > QTransform::TxShear || !cacheEnabled) return 0; // FT_Set_Transform only supports scalable fonts if (!FT_IS_SCALABLE(freetype->face)) - return 0; + return matrix.type() <= QTransform::TxTranslate ? &defaultGlyphSet : Q_NULLPTR; FT_Matrix m = QTransformToFTMatrix(matrix); @@ -1463,7 +1431,7 @@ void QFontEngineFT::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyph for (int gl = 0; gl < glyphs.numGlyphs; gl++) { FT_UInt glyph = positioned_glyphs[gl]; FT_Load_Glyph(face, glyph, FT_LOAD_TARGET_MONO); - freetype->addBitmapToPath(face->glyph, positions[gl], path); + QFreetypeFace::addBitmapToPath(face->glyph, positions[gl], path); } unlockFace(); } @@ -1482,8 +1450,10 @@ void QFontEngineFT::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int FT_GlyphSlot g = face->glyph; if (g->format != FT_GLYPH_FORMAT_OUTLINE) continue; - if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(g); - if (obliquen) Q_FT_GLYPHSLOT_OBLIQUE(g); + if (embolden) + FT_GlyphSlot_Embolden(g); + if (obliquen) + FT_GlyphSlot_Oblique(g); QFreetypeFace::addGlyphToPath(face, g, positions[gl], path, xsize, ysize); } unlockFace(); @@ -1775,7 +1745,7 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe format = QImage::Format_Mono; break; case Format_A8: - format = QImage::Format_Indexed8; + format = QImage::Format_Alpha8; break; case Format_A32: format = QImage::Format_ARGB32; @@ -1786,17 +1756,12 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe }; QFontEngineFT::Glyph *glyph; - QScopedPointer<QFontEngineFT::Glyph> glyphGuard; if (cacheEnabled) { - QFontEngineFT::QGlyphSet *gset = &defaultGlyphSet; + QGlyphSet *gset = loadGlyphSet(t); QFontEngine::HintStyle hintStyle = default_hint_style; if (t.type() >= QTransform::TxScale) { // disable hinting if the glyphs are transformed default_hint_style = HintNone; - if (t.isAffine()) - gset = loadTransformedGlyphSet(t); - else - gset = 0; } if (gset) { @@ -1806,15 +1771,13 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe freetype->matrix = m; } - if (!gset || gset->outline_drawing || !loadGlyph(gset, glyphIndex, subPixelPosition, - neededFormat)) { + if (!gset || gset->outline_drawing || !(glyph = loadGlyph(gset, glyphIndex, subPixelPosition, + neededFormat))) { default_hint_style = hintStyle; return QFontEngine::lockedAlphaMapForGlyph(glyphIndex, subPixelPosition, neededFormat, t, offset); } default_hint_style = hintStyle; - - glyph = gset->getGlyph(glyphIndex, subPixelPosition); } else { FT_Matrix m = matrix; FT_Matrix extra = QTransformToFTMatrix(t); @@ -1822,10 +1785,11 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe FT_Set_Transform(freetype->face, &m, 0); freetype->matrix = m; glyph = loadGlyph(0, glyphIndex, subPixelPosition, neededFormat); - glyphGuard.reset(glyph); } if (glyph == 0 || glyph->data == 0 || glyph->width == 0 || glyph->height == 0) { + if (!cacheEnabled && glyph != &emptyGlyph) + delete glyph; unlockFace(); return 0; } @@ -1850,8 +1814,10 @@ QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixe *offset = QPoint(glyph->x, -glyph->y); currentlyLockedAlphaMap = QImage(glyph->data, glyph->width, glyph->height, pitch, format); - if (!glyphGuard.isNull()) + if (!cacheEnabled && glyph != &emptyGlyph) { currentlyLockedAlphaMap = currentlyLockedAlphaMap.copy(); + delete glyph; + } Q_ASSERT(!currentlyLockedAlphaMap.isNull()); QImageData *data = currentlyLockedAlphaMap.data_ptr(); @@ -1873,31 +1839,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, const QTransform &t, bool fetchBoundingBox) { - FT_Face face = 0; - QGlyphSet *glyphSet = 0; - FT_Matrix ftMatrix = QTransformToFTMatrix(t); - if (cacheEnabled) { - if (t.type() > QTransform::TxTranslate && FT_IS_SCALABLE(freetype->face)) - glyphSet = loadTransformedGlyphSet(t); - else - glyphSet = &defaultGlyphSet; - Q_ASSERT(glyphSet != 0); - } - + QGlyphSet *glyphSet = loadGlyphSet(t); if (glyphSet != 0 && glyphSet->outline_drawing && !fetchBoundingBox) return 0; Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0; - if (!glyph || glyph->format != format) { - face = lockFace(); + if (!glyph || glyph->format != format || (!fetchBoundingBox && !glyph->data)) { + lockFace(); FT_Matrix m = this->matrix; + FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t); FT_Matrix_Multiply(&ftMatrix, &m); freetype->matrix = m; glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false); - } - - if (face) unlockFace(); + } return glyph; } @@ -1909,23 +1864,17 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition) QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t) { - lockFace(); - - QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono, t)); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono, t); if (!glyph || !glyph->data) { - unlockFace(); + if (!cacheEnabled && glyph != &emptyGlyph) + delete glyph; return QFontEngine::alphaMapForGlyph(g); } const int pitch = antialias ? (glyph->width + 3) & ~3 : ((glyph->width + 31)/32) * 4; - QImage img(glyph->width, glyph->height, antialias ? QImage::Format_Indexed8 : QImage::Format_Mono); - if (antialias) { - QVector<QRgb> colors(256); - for (int i=0; i<256; ++i) - colors[i] = qRgba(0, 0, 0, i); - img.setColorTable(colors); - } else { + QImage img(glyph->width, glyph->height, antialias ? QImage::Format_Alpha8 : QImage::Format_Mono); + if (!antialias) { QVector<QRgb> colors(2); colors[0] = qRgba(0, 0, 0, 0); colors[1] = qRgba(0, 0, 0, 255); @@ -1936,9 +1885,9 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const for (int y = 0; y < glyph->height; ++y) memcpy(img.scanLine(y), &glyph->data[y * pitch], pitch); } - if (cacheEnabled) - glyph.take(); - unlockFace(); + + if (!cacheEnabled && glyph != &emptyGlyph) + delete glyph; return img; } @@ -1948,20 +1897,18 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co if (t.type() > QTransform::TxRotate) return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); - lockFace(); - - QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, Format_A32, t)); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, Format_A32, t); if (!glyph || !glyph->data) { - unlockFace(); + if (!cacheEnabled && glyph != &emptyGlyph) + delete glyph; return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); } QImage img(glyph->width, glyph->height, QImage::Format_RGB32); memcpy(img.bits(), glyph->data, 4 * glyph->width * glyph->height); - if (cacheEnabled) - glyph.take(); - unlockFace(); + if (!cacheEnabled && glyph != &emptyGlyph) + delete glyph; return img; } |