diff -r 000000000000 -r 89c329efa980 ganeswidgets/src/hgvgimage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ganeswidgets/src/hgvgimage.cpp Mon Apr 19 14:40:06 2010 +0300 @@ -0,0 +1,179 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "HgVgImage.h" +#include "HgImageFader.h" +#include "hgvgquadrenderer.h" + +const int KMaxMirrorWidth(128); +const int KMaxMirrorHeight(64); + +static QSize getMirrorSize(const QImage& image) +{ + return QSize( + qMin(image.width() / 2, KMaxMirrorWidth), + qMin(image.height() / 4, KMaxMirrorHeight) + ); +} + +HgVgImage::HgVgImage(HgVgQuadRenderer* renderer) : + mVgImage(VG_INVALID_HANDLE), + mMirrorImage(VG_INVALID_HANDLE), + mMirrorSize(0,0), + mRenderer(renderer) +{ + setAlpha(1.0); +} + +HgVgImage::~HgVgImage() +{ + releaseImage(); +} + +int HgVgImage::width() const +{ + return mQImage.width(); +} + +int HgVgImage::height() const +{ + return mQImage.height(); +} + +VGImage HgVgImage::image() const +{ + return mVgImage; +} + +int HgVgImage::mirrorImageWidth() const +{ + return mMirrorSize.width(); +} + +int HgVgImage::mirrorImageHeight() const +{ + return mMirrorSize.height(); +} + +VGImage HgVgImage::mirrorImage() const +{ + return mMirrorImage; +} + + +void HgVgImage::setImage(QImage& image) +{ + if (image.isNull()) + return; + + // release previous images vg data + releaseImage(); + + mQImage = image; + + mMirrorSize = getMirrorSize(mQImage); + +} + +void HgVgImage::releaseImage() +{ + if (mVgImage != VG_INVALID_HANDLE) + { + vgDestroyImage(mVgImage); + mVgImage = VG_INVALID_HANDLE; + } + if (mMirrorImage != VG_INVALID_HANDLE) + { + vgDestroyImage(mMirrorImage); + mMirrorImage = VG_INVALID_HANDLE; + } + + // TODO, check that this will free all the previously reserved image resources. + mQImage = QImage(); +} + +void HgVgImage::upload(bool mirror) +{ + + if (mVgImage == VG_INVALID_HANDLE) + { + + VGImageFormat format; + + switch (mQImage.format()) + { + case QImage::Format_ARGB32_Premultiplied: + format = VG_sARGB_8888_PRE; + break; + case QImage::Format_ARGB32: + format = VG_sARGB_8888; + break; + case QImage::Format_RGB16: + format = VG_sRGB_565; + break; + default: + mQImage = mQImage.convertToFormat(QImage::Format_RGB16); + format = VG_sRGB_565; + break; + } + + + mVgImage = vgCreateImage(format, + mQImage.width(), mQImage.height(),VG_IMAGE_QUALITY_NONANTIALIASED); + if (mVgImage == VG_INVALID_HANDLE) + { + qWarning("HgMediaWall run out of video memory for images!"); + return; + } + + vgImageSubData(mVgImage, mQImage.bits(), mQImage.bytesPerLine(), + format, 0, 0, mQImage.width(), mQImage.height() ); + } + + if (mirror && mMirrorImage == VG_INVALID_HANDLE) + { + mMirrorImage = vgCreateImage(VG_sARGB_8888_PRE, mMirrorSize.width(), mMirrorSize.height(), VG_IMAGE_QUALITY_NONANTIALIASED); + if (mMirrorImage == VG_INVALID_HANDLE) + { + qWarning("HgMediaWall run out of video memory for images!"); + return; + } + + // cut half of the image, then scale to desired width/height if needed + QImage mirrorImage = mQImage.copy(0, mQImage.height()/2, mQImage.width(), mQImage.height()/2).scaled(mMirrorSize).convertToFormat(QImage::Format_ARGB32); + + // apply gradient to alpha channel so that mirror image looks like + // it fades under the floor + for (int i = 0; i < mirrorImage.height(); i++) + { + qreal t = qreal(i) / qreal(mirrorImage.height()); + int a = (int)(t * 255.0); + for (int j = 0; j < mirrorImage.width(); j++) + { + QRgb rgb = mirrorImage.pixel(j, i); + mirrorImage.setPixel(j, i, qRgba(qRed(rgb), qGreen(rgb), qBlue(rgb), a)); + } + } + + // copy data to vg image + vgImageSubData(mMirrorImage, mirrorImage.bits(), mirrorImage.bytesPerLine(), + VG_sARGB_8888, 0, 0, mirrorImage.width(), mirrorImage.height() ); + + } + +} +