VGImage QVGPixmapData::toVGImage(qreal opacity) { #if !defined(QT_SHIVAVG) // Force the primary VG image to be recreated if necessary. if (toVGImage() == VG_INVALID_HANDLE) return VG_INVALID_HANDLE; if (opacity == 1.0f) return vgImage; // Create an alternative image for the selected opacity. if (vgImageOpacity == VG_INVALID_HANDLE || cachedOpacity != opacity) { if (vgImageOpacity == VG_INVALID_HANDLE) { if (inImagePool) { vgImageOpacity = QVGImagePool::instance()->createImageForPixmap (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this); } else { vgImageOpacity = vgCreateImage (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER); } // Bail out if we run out of GPU memory - try again next time. if (vgImageOpacity == VG_INVALID_HANDLE) return VG_INVALID_HANDLE; } VGfloat matrix[20] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, opacity, 0.0f, 0.0f, 0.0f, 0.0f }; vgColorMatrix(vgImageOpacity, vgImage, matrix); cachedOpacity = opacity; } return vgImageOpacity; #else // vgColorMatrix() doesn't work with ShivaVG, so ignore the opacity. Q_UNUSED(opacity); return toVGImage(); #endif }
/** Overridden function, which creates OpenVG images for monochrome and anti-aliased fonts. @param aGlyphImage Data source bitmap in 256 or 2 Grey format. @param aGlyphImageSize Glyph image data size. @param aDisplayMode Image display mode. @param aForeground Foreground component of the glyph. @param aPreAllocForeground Pre-allocated buffer which will be used for setting foreground VG image @post Requested OpenVG image is ready for rendering. @panic Panic if bitmap display mode is not 256 grey or 2 grey. */ void CFontGlyphTree::CreateVGImageL(const TUint8* aGlyphImage, const TSize& aGlyphImageSize, TDisplayMode aDisplayMode, VGImage& aForeground, TUint8* aPreAllocForeground) { GRAPHICS_ASSERT_DEBUG((aDisplayMode == EGray256) || (aDisplayMode == EGray2), EDirectGdiPanicInvalidDisplayMode); GRAPHICS_ASSERT_DEBUG(aGlyphImage, EDirectGdiPanicInvalidParameter); VGImageFormat imageFormat = VG_IMAGE_FORMAT_INVALID; TInt vgCompatibleSourceStride = 0x00; TUint32 binaryDataArray[32]; TUint8* binaryData = NULL; TUint8* tempBuffer = NULL; if(aDisplayMode == EGray256) { imageFormat = VG_sL_8; vgCompatibleSourceStride = aGlyphImageSize.iWidth; binaryData = const_cast <TUint8*> (aGlyphImage); } else //EGray2 { imageFormat = VG_BW_1; vgCompatibleSourceStride = ((aGlyphImageSize.iWidth + 31) / 32) << 2; if (aGlyphImageSize.iWidth > 30 || aGlyphImageSize.iHeight > 32) { binaryData = aPreAllocForeground; if(!binaryData) { tempBuffer = (TUint8*) User::AllocL(vgCompatibleSourceStride * aGlyphImageSize.iHeight); CleanupStack::PushL(tempBuffer); binaryData = tempBuffer; } DecodeBinaryDataExLarge(aGlyphImageSize, aGlyphImage, vgCompatibleSourceStride, reinterpret_cast <TUint32*> (binaryData)); } else { DecodeBinaryData(aGlyphImageSize, aGlyphImage, binaryDataArray); binaryData = reinterpret_cast <TUint8*> (binaryDataArray); } } if(aForeground == VG_INVALID_HANDLE) { aForeground = vgCreateImage(imageFormat, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED); } if (aForeground != VG_INVALID_HANDLE) { // Copy from the source image to our new VGImage vgImageSubData(aForeground, binaryData, vgCompatibleSourceStride, imageFormat, 0, 0, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight); #ifdef DRAWGLYPH_MULTIPLY_MODE VGImage image = vgCreateImage(VG_sARGB_8888_PRE, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED); vgColorMatrix(image, aForeground, KColorMatrix); vgDestroyImage(aForeground); aForeground = image; #endif } else { if(tempBuffer) { CleanupStack::PopAndDestroy(tempBuffer); } User::Leave(KErrNoMemory); } if(tempBuffer) { CleanupStack::PopAndDestroy(tempBuffer); } }
void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const { if (src.isNull()) return; if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) { // The pixmap data is not an instance of QVGPixmapData, so fall // back to the default colorize filter implementation. QPixmapColorizeFilter::draw(painter, dest, src, srcRect); return; } QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData()); VGImage srcImage = pd->toVGImage(); if (srcImage == VG_INVALID_HANDLE) return; QSize size = pd->size(); VGImage dstImage = QVGImagePool::instance()->createTemporaryImage (VG_sARGB_8888_PRE, size.width(), size.height(), VG_IMAGE_QUALITY_FASTER, pd); if (dstImage == VG_INVALID_HANDLE) return; // Determine the weights for the matrix from the color and strength. QColor c = color(); VGfloat strength = this->strength(); VGfloat weights[3]; VGfloat invweights[3]; VGfloat alpha = c.alphaF(); weights[0] = c.redF() * alpha; weights[1] = c.greenF() * alpha; weights[2] = c.blueF() * alpha; invweights[0] = (1.0f - weights[0]) * strength; invweights[1] = (1.0f - weights[1]) * strength; invweights[2] = (1.0f - weights[2]) * strength; // Grayscale weights. static const VGfloat redGray = 11.0f / 32.0f; static const VGfloat greenGray = 16.0f / 32.0f; static const VGfloat blueGray = 1.0f - (redGray + greenGray); VGfloat matrix[5][4]; matrix[0][0] = redGray * invweights[0] + (1.0f - strength); matrix[0][1] = redGray * invweights[1]; matrix[0][2] = redGray * invweights[2]; matrix[0][3] = 0.0f; matrix[1][0] = greenGray * invweights[0]; matrix[1][1] = greenGray * invweights[1] + (1.0f - strength); matrix[1][2] = greenGray * invweights[2]; matrix[1][3] = 0.0f; matrix[2][0] = blueGray * invweights[0]; matrix[2][1] = blueGray * invweights[1]; matrix[2][2] = blueGray * invweights[2] + (1.0f - strength); matrix[2][3] = 0.0f; matrix[3][0] = 0.0f; matrix[3][1] = 0.0f; matrix[3][2] = 0.0f; matrix[3][3] = 1.0f; matrix[4][0] = weights[0] * strength; matrix[4][1] = weights[1] * strength; matrix[4][2] = weights[2] * strength; matrix[4][3] = 0.0f; vgColorMatrix(dstImage, srcImage, matrix[0]); VGImage child = VG_INVALID_HANDLE; if (srcRect.isNull() || (srcRect.topLeft().isNull() && srcRect.size() == size)) { child = dstImage; } else { QRect src = srcRect.toRect(); child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height()); } qt_vg_drawVGImage(painter, dest, child); if(child != dstImage) vgDestroyImage(child); QVGImagePool::instance()->releaseImage(0, dstImage); }
/** Overridden function, which creates Open VG images for foreground, background, shadow and outline components of the font. @param aGlyphImage Source bitmap data in 256 grey format. Each pixel value is an index to a constant lookup table. Four entries of this table represent % of Outline, Shadow, Fill and Background colour to be used to get the final colour to be displayed on screen. @param aGlyphImageSize Size of the glyph bitmap image. @param aForeground Foreground component of the glyph. @param aOutline Outline component of the glyph. @param aShadow Shadow component of the glyph. @param aPreAllocForeground Pre-allocated buffer which will be used for setting text foreground VG image @param aPreAllocOutline Pre-allocated buffer which will be used for setting text outline VG image @param aPreAllocShadow Pre-allocated buffer which will be used for setting text shadow VG image @post Requested OpenVG images are ready for rendering. */ void CFontGlyphTree::CreateVGImageL(const TUint8* aGlyphImage, const TSize& aGlyphImageSize, VGImage& aForeground, VGImage& aOutline, VGImage& aShadow, TUint8* aPreAllocForeground, TUint8* aPreAllocOutline, TUint8* aPreAllocShadow) { TInt dataStride = aGlyphImageSize.iWidth; TInt targetByteCount = dataStride * aGlyphImageSize.iHeight; // Allocate memory and transform source into target format. // TAny* foregroundBuffer = NULL; TAny* outlineBuffer = NULL; TAny* shadowBuffer = NULL; TBool destroyTempBuffer = EFalse; if(aPreAllocForeground && aPreAllocOutline && aPreAllocShadow && (aGlyphImageSize.iWidth <= KMaxSizeImageOOM.iWidth) && (aGlyphImageSize.iHeight <= KMaxSizeImageOOM.iHeight)) { foregroundBuffer = aPreAllocForeground; outlineBuffer = aPreAllocOutline; shadowBuffer = aPreAllocShadow; } else { foregroundBuffer = User::AllocL(targetByteCount); CleanupStack::PushL(foregroundBuffer); outlineBuffer = User::AllocL(targetByteCount); CleanupStack::PushL(outlineBuffer); shadowBuffer = User::AllocL(targetByteCount); CleanupStack::PushL(shadowBuffer); destroyTempBuffer = ETrue; } TUint8* foregroundByte = static_cast <TUint8*> (foregroundBuffer); TUint8* outlineByte = static_cast <TUint8*> (outlineBuffer); TUint8* shadowByte = static_cast <TUint8*> (shadowBuffer); const TUint8* endByte = (TUint8*)aGlyphImage + targetByteCount; TUint8* curSrcGlyphImage = const_cast <TUint8*> (aGlyphImage); while (curSrcGlyphImage < endByte) { *outlineByte++ = FourColorBlendLookup[*curSrcGlyphImage] [KOutlineColorIndex]; *shadowByte++ = FourColorBlendLookup[*curSrcGlyphImage] [KShadowColorIndex]; *foregroundByte++ = FourColorBlendLookup[*curSrcGlyphImage] [KFillColorIndex]; curSrcGlyphImage++; } const VGImageFormat imageFormat = VG_sL_8; if(aForeground == VG_INVALID_HANDLE) { aForeground = vgCreateImage(imageFormat, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED); if(aForeground == VG_INVALID_HANDLE) { User::Leave(KErrNoMemory); } aOutline = vgCreateImage(imageFormat, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED); if(aOutline == VG_INVALID_HANDLE) { DestroyVGImage(&aForeground); User::Leave(KErrNoMemory); } aShadow = vgCreateImage(imageFormat, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED); if(aShadow == VG_INVALID_HANDLE) { DestroyVGImage(&aForeground, &aOutline); User::Leave(KErrNoMemory); } } vgImageSubData( aForeground, foregroundBuffer, dataStride, imageFormat, 0, 0,aGlyphImageSize.iWidth, aGlyphImageSize.iHeight); #ifdef DRAWGLYPH_MULTIPLY_MODE VGImage image = vgCreateImage(VG_sARGB_8888_PRE, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED); vgColorMatrix(image, aForeground, KColorMatrix); vgDestroyImage(aForeground); aForeground = image; #endif // DRAWGLYPH_MULTIPLY_MODE vgImageSubData( aOutline, outlineBuffer, dataStride, imageFormat, 0, 0, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight); #ifdef DRAWGLYPH_MULTIPLY_MODE image = vgCreateImage(VG_sARGB_8888_PRE, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED); vgColorMatrix(image, aOutline, KColorMatrix); vgDestroyImage(aOutline); aOutline = image; #endif // DRAWGLYPH_MULTIPLY_MODE vgImageSubData( aShadow, shadowBuffer, dataStride, imageFormat, 0, 0, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight); #ifdef DRAWGLYPH_MULTIPLY_MODE image = vgCreateImage(VG_sARGB_8888_PRE, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED); vgColorMatrix(image, aShadow, KColorMatrix); vgDestroyImage(aShadow); aShadow = image; #endif // DRAWGLYPH_MULTIPLY_MODE if(destroyTempBuffer) { CleanupStack::PopAndDestroy(3, foregroundBuffer); } }
void HbVgBcEffect::performEffect(QPainter *painter, const QPointF &offset, const QVariant &vgImage, const QSize &vgImageSize) { #ifdef HB_EFFECTS_OPENVG QPixmap cachedPm = cached(vgImageSize); if (!cachedPm.isNull()) { painter->drawPixmap(offset, cachedPm); return; } Q_D(HbVgBcEffect); VGImage srcImage = vgImage.value<VGImage>(); VGImage dstImage = d->ensurePixmap(&d->dstPixmap, vgImageSize); qreal opacity = clamp(d->opacity, 0.0f, 1.0f); if (opacity > HBVG_EPSILON) { if (d->paramsChanged) { // brightness [-1, 1] const VGfloat offset_br = clamp(d->brightness, -1.0f, 1.0f); const VGfloat scale_br = 1.0f - 0.5f * ((offset_br < 0.0f) ? -offset_br : offset_br); // contrast [0, N] const VGfloat scale_con = clamp(d->contrast, 0.0f, 100.0f); const VGfloat offset_con = -0.5f * scale_con + 0.5f ; // combine the effects of brightness and contrast const VGfloat off = offset_br + offset_con; const VGfloat sc = scale_br * scale_con; // take opacity into account const VGfloat o = (VGfloat) opacity; const VGfloat oOff = off * o; const VGfloat oSc = (sc * o) + (1.0f - o); d->colorMatrix[0] = oSc; d->colorMatrix[1] = 0.0f; d->colorMatrix[2] = 0.0f; d->colorMatrix[3] = 0.0f; d->colorMatrix[4] = 0.0f; d->colorMatrix[5] = oSc; d->colorMatrix[6] = 0.0f; d->colorMatrix[7] = 0.0f; d->colorMatrix[8] = 0.0f; d->colorMatrix[9] = 0.0f; d->colorMatrix[10] = oSc; d->colorMatrix[11] = 0.0f; d->colorMatrix[12] = 0.0f; d->colorMatrix[13] = 0.0f; d->colorMatrix[14] = 0.0f; d->colorMatrix[15] = 1.0f; d->colorMatrix[16] = oOff; d->colorMatrix[17] = oOff; d->colorMatrix[18] = oOff; d->colorMatrix[19] = 0.0f; } vgColorMatrix(dstImage, srcImage, d->colorMatrix); painter->drawPixmap(offset, d->dstPixmap); tryCache(d->dstPixmap); } else { painter->drawPixmap(offset, d->srcPixmap); } #else Q_UNUSED(painter); Q_UNUSED(offset); Q_UNUSED(vgImage); Q_UNUSED(vgImageSize); #endif }