diff --git src/gui/painting/qpaintengine_raster.cpp src/gui/painting/qpaintengine_raster.cpp index 78f899c..e6ce1c4 100644 --- src/gui/painting/qpaintengine_raster.cpp +++ src/gui/painting/qpaintengine_raster.cpp @@ -2909,7 +2909,20 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, // x, y, // positions[i].x.toInt(), positions[i].y.toInt()); - alphaPenBlt(bits + ((c.x << leftShift) >> rightShift) + c.y * bpl, bpl, depth, x, y, c.w, c.h); +// alphaPenBlt(bits + ((c.x << leftShift) >> rightShift) + c.y * bpl, bpl, depth, x, y, c.w, c.h); + const uchar *glyphBits = bits + ((c.x << leftShift) >> rightShift) + c.y * bpl; + + if (glyphType == QFontEngineGlyphCache::Raster_ARGB) { + // The current state transform has already been applied to the positions, + // so we prevent drawImage() from re-applying the transform by clearing + // the state for the duration of the call. + QTransform originalTransform = s->matrix; + s->matrix = QTransform(); + drawImage(QPoint(x, y), QImage(glyphBits, c.w, c.h, bpl, image.format())); + s->matrix = originalTransform; + } else { + alphaPenBlt(glyphBits, bpl, depth, x, y, c.w, c.h); + } } } return true; diff --git src/gui/painting/qtextureglyphcache.cpp src/gui/painting/qtextureglyphcache.cpp index 883433a..234cab3 100644 --- src/gui/painting/qtextureglyphcache.cpp +++ src/gui/painting/qtextureglyphcache.cpp @@ -151,6 +151,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const switch (m_type) { case Raster_A8: format = QFontEngine::Format_A8; break; case Raster_RGBMask: format = QFontEngine::Format_A32; break; + case Raster_ARGB: format = QFontEngine::Format_ARGB; break; default: format = QFontEngine::Format_Mono; break; } @@ -327,7 +328,7 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition } } else #endif - if (m_type == QFontEngineGlyphCache::Raster_RGBMask) + if (m_type == QFontEngineGlyphCache::Raster_RGBMask || m_type == QFontEngineGlyphCache::Raster_ARGB) return m_current_fontengine->alphaRGBMapForGlyph(g, subPixelPosition, glyphMargin(), m_transform); else return m_current_fontengine->alphaMapForGlyph(g, subPixelPosition, m_transform); @@ -362,6 +363,9 @@ void QImageTextureGlyphCache::createTextureData(int width, int height) case QFontEngineGlyphCache::Raster_RGBMask: m_image = QImage(width, height, QImage::Format_RGB32); break; + case QFontEngineGlyphCache::Raster_ARGB: + m_image = QImage(width, height, QImage::Format_ARGB32_Premultiplied); + break; } } @@ -386,7 +390,8 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP } #endif - if (m_type == QFontEngineGlyphCache::Raster_RGBMask) { + if (m_type == QFontEngineGlyphCache::Raster_RGBMask + || m_type == QFontEngineGlyphCache::Raster_ARGB) { QImage ref(m_image.bits() + (c.x * 4 + c.y * m_image.bytesPerLine()), qMax(mask.width(), c.w), qMax(mask.height(), c.h), m_image.bytesPerLine(), m_image.format()); diff --git src/gui/text/qfontengine.cpp src/gui/text/qfontengine.cpp index 67b8798..381166d 100644 --- src/gui/text/qfontengine.cpp +++ src/gui/text/qfontengine.cpp @@ -682,6 +682,13 @@ QImage QFontEngine::alphaMapForGlyph(glyph_t glyph) return indexed; } +QImage QFontEngine::bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform&) +{ + Q_UNUSED(subPixelPosition); + + return QImage(); +} + void QFontEngine::removeGlyphFromCache(glyph_t) { } diff --git src/gui/text/qfontengine_coretext.mm src/gui/text/qfontengine_coretext.mm index 204d685..ae07871 100644 --- src/gui/text/qfontengine_coretext.mm +++ src/gui/text/qfontengine_coretext.mm @@ -370,24 +370,76 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay QVarLengthArray cgGlyphs(len); CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len); + CGGlyph placeHolder = 0; for (int i = 0; i < len; ++i) { if (cgGlyphs[i]) { glyphs->glyphs[i] = cgGlyphs[i]; } else { + bool isUTF32 = false; if (!cfstring) cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast(str), len, kCFAllocatorNull); QCFType substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1)); +// QCFString family = CTFontCopyFamilyName(substituteFont); +// QCFString styleName = (CFStringRef) CTFontCopyAttribute(substituteFont, kCTFontStyleNameAttribute); + CGGlyph substituteGlyph = 0; CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1); + if (!substituteGlyph && i < len-1) { + // try UTF32 + substituteFont = QCFType(CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 2))); +// family = CTFontCopyFamilyName(substituteFont); +// styleName = (CFStringRef) CTFontCopyAttribute(substituteFont, kCTFontStyleNameAttribute); + CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 2); + isUTF32 = true; + } if (substituteGlyph) { const uint fontIndex = (fontIndexForFont(substituteFont) << 24); glyphs->glyphs[i] = substituteGlyph | fontIndex; +#if 1 + if (isUTF32) { + if (!placeHolder) { + CGFontRef fontRef = CTFontCopyGraphicsFont(ctfont, NULL); + if (fontRef) { + // look up the non-breaking-space glyph for the official font + placeHolder = CGFontGetGlyphWithGlyphName(fontRef, CFSTR("uni00A0")); +// // or rather use ".null" which might take less horizontal space. +// placeHolder = CGFontGetGlyphWithGlyphName(fontRef, CFSTR(".null")); + CFRelease(fontRef); + } + } + if (placeHolder) { + glyphs->glyphs[i+1] = placeHolder; + // also set this one! + cgGlyphs[i+1] = placeHolder; + } + } +#endif if (!(flags & QTextEngine::GlyphIndicesOnly)) { CGSize advance; CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1); glyphs->advances_x[i] = QFixed::fromReal(advance.width); glyphs->advances_y[i] = QFixed::fromReal(advance.height); +#if 1 + if (isUTF32 && placeHolder) { + CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &placeHolder, &advance, 1); + glyphs->advances_x[i+1] = QFixed::fromReal(advance.width); + glyphs->advances_y[i+1] = QFixed::fromReal(advance.height); + } +#endif + } + if (isUTF32) { +// QCFType sFont = CTFontCopyGraphicsFont(substituteFont, NULL); +// QCFString glyphName = CGFontCopyGlyphNameForGlyph(sFont, substituteGlyph); +// qWarning() << Q_FUNC_INFO << "Font" << QString(family) << QString(styleName) +// << "instead of" << fontDef.family << fontDef.styleName +// << "for" << str[i].unicode() << str[i] +// << substituteGlyph << QString(glyphName); + // skip the next glyph! + i += 1; +// glyphName = CGFontCopyGlyphNameForGlyph(CTFontCopyGraphicsFont(ctfont, NULL), glyphs->glyphs[i]); +// qWarning() << "\t: next glyph:" << glyphs->glyphs[i] << QString(glyphName) << "advances:" +// << glyphs->advances_x[i] << glyphs->advances_y[i]; } } } @@ -472,6 +524,16 @@ void QCoreTextFontEngine::init() synthesisFlags = 0; CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont); + // RJVB: backported, but only set glyphFormat for colour glyphs +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + isColourFont = (traits & kCTFontColorGlyphsTrait); + if (isColourFont) { + glyphFormat = QFontEngineGlyphCache::Raster_ARGB; + } +#else + isColourFont = false; +#endif + if (traits & kCTFontItalicTrait) fontDef.style = QFont::StyleItalic; @@ -708,6 +770,9 @@ static void convertCGPathToQPainterPath(void *info, const CGPathElement *element void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs, QPainterPath *path, QTextItem::RenderFlags) { + if (isColourFont) + return; // We can't convert color-glyphs to path + CGAffineTransform cgMatrix = CGAffineTransformIdentity; cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1); @@ -725,16 +790,21 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition { Q_UNUSED(margin); const glyph_metrics_t br = boundingBox(glyph); - QImage im(qRound(br.width) + 2, qRound(br.height) + 2, QImage::Format_RGB32); + QImage::Format imageFormat = isColourFont ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + QImage im(qRound(br.width) + 2, qRound(br.height) + 2, imageFormat); im.fill(0); + if (!im.width() || !im.height()) { + return im; + } + CGColorSpaceRef colorspace = #ifdef Q_WS_MAC CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); #else CGColorSpaceCreateDeviceRGB(); #endif - uint cgflags = kCGImageAlphaNoneSkipFirst; + uint cgflags = isColourFont ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; #ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version cgflags |= kCGBitmapByteOrder32Host; #endif @@ -745,38 +815,51 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CGContextSetShouldAntialias(ctx, (aa || fontDef.pointSize > qt_antialiasing_threshold) && !(fontDef.styleStrategy & QFont::NoAntialias)); CGContextSetShouldSmoothFonts(ctx, aa); - CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); - CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); - - CGAffineTransformConcat(cgMatrix, oldTextMatrix); + CGAffineTransform cgMatrix = CGAffineTransformIdentity; if (synthesisFlags & QFontEngine::SynthesizedItalic) cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, SYNTHETIC_ITALIC_SKEW, 1, 0, 0)); - cgMatrix = CGAffineTransformConcat(cgMatrix, transform); - - CGContextSetTextMatrix(ctx, cgMatrix); - CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); - CGContextSetTextDrawingMode(ctx, kCGTextFill); - - CGContextSetFont(ctx, cgFont); + if (!isColourFont) { + cgMatrix = CGAffineTransformConcat(cgMatrix, transform); + } + CGGlyph cgGlyph = glyph; qreal pos_x = -br.x.truncate() + subPixelPosition.toReal(); qreal pos_y = im.height() + br.y.toReal(); - CGContextSetTextPosition(ctx, pos_x, pos_y); - CGSize advance; - advance.width = 0; - advance.height = 0; - CGGlyph cgGlyph = glyph; - CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); + if (!isColourFont) { + CGContextSetTextMatrix(ctx, cgMatrix); + CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); + CGContextSetTextDrawingMode(ctx, kCGTextFill); - if (synthesisFlags & QFontEngine::SynthesizedBold) { - CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y); + CGContextSetFont(ctx, cgFont); + + CGContextSetTextPosition(ctx, pos_x, pos_y); + + CGSize advance; + advance.width = 0; + advance.height = 0; CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); + + if (synthesisFlags & QFontEngine::SynthesizedBold) { + CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y); + CGContextShowGlyphsWithAdvances(ctx, &cgGlyph, &advance, 1); + } + } else { + // CGContextSetTextMatrix does not work with color glyphs, so we use + // the CTM instead. This means we must translate the CTM as well, to + // set the glyph position, instead of using CGContextSetTextPosition. + CGContextTranslateCTM(ctx, pos_x, pos_y); + CGContextConcatCTM(ctx, cgMatrix); + + // CGContextShowGlyphsWithAdvances does not support the 'sbix' color-bitmap + // glyphs in the Apple Color Emoji font, so we use CTFontDrawGlyphs instead. + CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx); } CGContextRelease(ctx); + CGColorSpaceRelease(colorspace); return im; } diff --git src/gui/text/qfontengine_coretext_p.h src/gui/text/qfontengine_coretext_p.h index 5a46c98..a8b01b8 100644 --- src/gui/text/qfontengine_coretext_p.h +++ src/gui/text/qfontengine_coretext_p.h @@ -116,6 +116,7 @@ private: CGAffineTransform transform; QFixed avgCharWidth; friend class QCoreTextFontEngineMulti; + bool isColourFont; }; class QCoreTextFontEngineMulti : public QFontEngineMulti diff --git src/gui/text/qfontengine_p.h src/gui/text/qfontengine_p.h index f29ac47..d644e67 100644 --- src/gui/text/qfontengine_p.h +++ src/gui/text/qfontengine_p.h @@ -127,7 +127,8 @@ public: Format_Render = Format_None, Format_Mono, Format_A8, - Format_A32 + Format_A32, + Format_ARGB }; QFontEngine(); @@ -200,6 +201,7 @@ public: virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t); virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t); + virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed /*subPixelPosition*/, const QTransform &matrix, GlyphFormat /*format*/) { diff --git src/gui/text/qfontengineglyphcache_p.h src/gui/text/qfontengineglyphcache_p.h index 602927c..c8dc64b 100644 --- src/gui/text/qfontengineglyphcache_p.h +++ src/gui/text/qfontengineglyphcache_p.h @@ -79,6 +79,8 @@ public: Raster_RGBMask, Raster_A8, Raster_Mono + // RJVB backported + , Raster_ARGB }; QFontEngineGlyphCache(const QTransform &matrix, Type type) : m_transform(matrix), m_type(type) { } diff --git src/gui/text/qtextengine.cpp src/gui/text/qtextengine.cpp index f50e711..765ccb8 100644 --- src/gui/text/qtextengine.cpp +++ src/gui/text/qtextengine.cpp @@ -1195,6 +1195,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading); bool kerningEnabled = this->font(si).d->kerning; + const int itemLength = length(item); HB_ShaperItem entire_shaper_item; qMemSet(&entire_shaper_item, 0, sizeof(entire_shaper_item)); @@ -1202,7 +1203,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const entire_shaper_item.stringLength = layoutData->string.length(); entire_shaper_item.item.script = (HB_Script)si.analysis.script; entire_shaper_item.item.pos = si.position; - entire_shaper_item.item.length = length(item); + entire_shaper_item.item.length = itemLength; entire_shaper_item.item.bidiLevel = si.analysis.bidiLevel; HB_UChar16 upperCased[256]; // XXX what about making this 4096, so we don't have to extend it ever. @@ -1227,7 +1228,19 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const if (option.useDesignMetrics()) entire_shaper_item.shaperFlags |= HB_ShaperFlag_UseDesignMetrics; - entire_shaper_item.num_glyphs = qMax(layoutData->glyphLayout.numGlyphs - layoutData->used, int(entire_shaper_item.item.length)); +// entire_shaper_item.num_glyphs = qMax(layoutData->glyphLayout.numGlyphs - layoutData->used, int(entire_shaper_item.item.length)); + // RJVB backported from Qt 5.9, scoped for `string` + { + // ensure we are not asserting in HB_HeuristicSetGlyphAttributes() + entire_shaper_item.num_glyphs = 0; + const ushort *string = reinterpret_cast(layoutData->string.constData()); + for (int i = 0; i < itemLength; ++i, ++entire_shaper_item.num_glyphs) { + if (QChar::isHighSurrogate(string[i]) && i + 1 < itemLength && QChar::isLowSurrogate(string[i + 1])) { + ++i; + } + } + } + if (! ensureSpace(entire_shaper_item.num_glyphs)) { if (hasCaseChange(si)) delete [] const_cast(entire_shaper_item.string); @@ -1292,6 +1305,10 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const shaper_item.item.length -= shaper_item.item.pos - entire_shaper_item.item.pos; shaper_item.num_glyphs -= itemBoundaries[k + 1]; } + if (static_cast(shaper_item.item.length) < 0) { + remaining_glyphs -= shaper_item.initialGlyphCount; + continue; + } shaper_item.initialGlyphCount = shaper_item.num_glyphs; if (shaper_item.num_glyphs < shaper_item.item.length) shaper_item.num_glyphs = shaper_item.item.length; diff --git src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 6bf9399..41c1f4f 100644 --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1104,7 +1104,8 @@ void QGL2PaintEngineExPrivate::resetClipIfNeeded() bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) { - if (brushTextureDirty && !imageDrawingMode) + if (brushTextureDirty + && (!imageDrawingMode || imageDrawingMode == TextDrawingMode || imageDrawingMode == BrushDrawingMode)) updateBrushTexture(); if (compositionModeDirty) @@ -1129,7 +1130,8 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) } else { opacityMode = stateHasOpacity ? QGLEngineShaderManager::UniformOpacity : QGLEngineShaderManager::NoOpacity; - if (stateHasOpacity && !imageDrawingMode) { + if (stateHasOpacity && !imageDrawingMode + && imageDrawingMode != ImageDrawingMode && imageDrawingMode != ImageArrayDrawingMode) { // Using a brush bool brushIsPattern = (currentBrush.style() >= Qt::Dense1Pattern) && (currentBrush.style() <= Qt::DiagCrossPattern); @@ -1149,7 +1151,8 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) matrixUniformDirty = true; } - if (brushUniformsDirty && !imageDrawingMode) + if (brushUniformsDirty + && (!imageDrawingMode || imageDrawingMode == TextDrawingMode || imageDrawingMode == BrushDrawingMode)) updateBrushUniforms(); if (opacityMode == QGLEngineShaderManager::UniformOpacity && opacityUniformDirty) { @@ -1641,7 +1644,10 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp if (cache->width() == 0 || cache->height() == 0) return; - transferMode(TextDrawingMode); + if (glyphType == QFontEngineGlyphCache::Raster_ARGB) + transferMode(ImageArrayDrawingMode); + else + transferMode(TextDrawingMode); int margin = cache->glyphMargin(); @@ -1737,8 +1743,10 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp #endif } - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinates->data()); - setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinates->data()); + if (glyphType != QFontEngineGlyphCache::Raster_ARGB || recreateVertexArrays) { + setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinates->data()); + setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinates->data()); + } if (!snapToPixelGrid) { snapToPixelGrid = true; @@ -1852,6 +1860,11 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp glBlendFunc(GL_ONE, GL_ONE); } compositionModeDirty = true; + } else if (glyphType == QFontEngineGlyphCache::Raster_ARGB) { + currentBrush = noBrush; + shaderManager->setSrcPixelType(QGLEngineShaderManager::ImageSrc); + if (prepareForDraw(true)) + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); } else { // Greyscale/mono glyphs @@ -1862,7 +1875,11 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest; if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) { - glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); + if (glyphType == QFontEngineGlyphCache::Raster_ARGB) + glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + else + glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); + if (lastMaskTextureUsed != cache->texture()) { glBindTexture(GL_TEXTURE_2D, cache->texture()); lastMaskTextureUsed = cache->texture(); @@ -2073,7 +2090,8 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QRectF *targetRects, co data[i].y = 1 - data[i].y; } - transferMode(ImageArrayDrawingMode); +// transferMode(ImageArrayDrawingMode); + transferMode(ImageArrayWithOpacityDrawingMode); bool isBitmap = pixmap.isQBitmap(); bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)); diff --git src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 75a67e8..8897448 100644 --- src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -127,7 +127,7 @@ void QGLTextureGlyphCache::createTextureData(int width, int height) glyphTexture->m_width = width; glyphTexture->m_height = height; - if (m_type == QFontEngineGlyphCache::Raster_RGBMask) { + if (m_type == QFontEngineGlyphCache::Raster_RGBMask || m_type == QFontEngineGlyphCache::Raster_ARGB) { QVarLengthArray data(width * height * 4); for (int i = 0; i < data.size(); ++i) data[i] = 0; @@ -311,23 +311,29 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub for (int x = 0; x < maskWidth; ++x) src[x] = -src[x]; // convert 0 and 1 into 0 and 255 } - } else if (mask.format() == QImage::Format_RGB32) { - // Make the alpha component equal to the average of the RGB values. - // This is needed when drawing sub-pixel antialiased text on translucent targets. - for (int y = 0; y < maskHeight; ++y) { - quint32 *src = (quint32 *) mask.scanLine(y); - for (int x = 0; x < maskWidth; ++x) { - uchar r = src[x] >> 16; - uchar g = src[x] >> 8; - uchar b = src[x]; - quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. - src[x] = (src[x] & 0x00ffffff) | (avg << 24); + } else if (mask.depth() == 32) { + if (mask.format() == QImage::Format_RGB32) { + // We need to make the alpha component equal to the average of the RGB values. + // This is needed when drawing sub-pixel antialiased text on translucent targets. + for (int y = 0; y < maskHeight; ++y) { + quint32 *src = (quint32 *) mask.scanLine(y); + for (int x = 0; x < maskWidth; ++x) { + uchar r = src[x] >> 16; + uchar g = src[x] >> 8; + uchar b = src[x]; + quint32 avg; + if (mask.format() == QImage::Format_RGB32) + avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. + else // Format_ARGB_Premultiplied + avg = src[x] >> 24; + src[x] = (src[x] & 0x00ffffff) | (avg << 24); + } } } } glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture); - if (mask.format() == QImage::Format_RGB32) { + if (mask.depth() == 32) { glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits()); } else { // glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is