summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mkspecs/common/symbian/symbian.conf2
-rw-r--r--src/openvg/qpixmapdata_vg.cpp94
-rw-r--r--tests/auto/qpixmap/tst_qpixmap.cpp45
3 files changed, 136 insertions, 5 deletions
diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf
index b1ef354..7162bad 100644
--- a/mkspecs/common/symbian/symbian.conf
+++ b/mkspecs/common/symbian/symbian.conf
@@ -70,7 +70,7 @@ QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lhal -lgdi -lws32
QMAKE_LIBS_NETWORK =
QMAKE_LIBS_EGL = -llibEGL
QMAKE_LIBS_OPENGL =
-QMAKE_LIBS_OPENVG = -llibOpenVG -lgraphicsresource
+QMAKE_LIBS_OPENVG = -llibOpenVG -lgraphicsresource -lfbscli -lbitgdi -lgdi
QMAKE_LIBS_COMPAT =
QMAKE_LIBS_QT_ENTRY = -llibcrt0.lib
QMAKE_LIBS_S60 = -lavkon
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp
index cc0e5a1..3087b77 100644
--- a/src/openvg/qpixmapdata_vg.cpp
+++ b/src/openvg/qpixmapdata_vg.cpp
@@ -46,11 +46,13 @@
#include "qvgimagepool_p.h"
#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
+#include <private/qt_s60_p.h>
+#include <fbs.h>
#include <graphics/sgimage.h>
typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*);
typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR);
typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR);
-#endif
+#endif // QT_SYMBIAN_SUPPORTS_SGIMAGE
QT_BEGIN_NAMESPACE
@@ -425,6 +427,34 @@ Q_OPENVG_EXPORT VGImage qPixmapToVGImage(const QPixmap& pixmap)
}
#if defined(Q_OS_SYMBIAN)
+
+static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap)
+{
+ CFbsBitmap *copy = q_check_ptr(new CFbsBitmap);
+ if(!copy)
+ return 0;
+
+ if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {
+ delete copy;
+ copy = 0;
+
+ return 0;
+ }
+
+ CFbsBitmapDevice* bitmapDevice = 0;
+ CFbsBitGc *bitmapGc = 0;
+ QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy));
+ QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
+ bitmapGc->Activate(bitmapDevice);
+
+ bitmapGc->BitBlt(TPoint(), bitmap);
+
+ delete bitmapGc;
+ delete bitmapDevice;
+
+ return copy;
+}
+
void QVGPixmapData::cleanup()
{
is_null = w = h = 0;
@@ -510,7 +540,49 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
eglDestroyImageKHR(context->display(), eglImage);
SgDriver::Close();
} else if (type == QPixmapData::FbsBitmap) {
+ CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
+
+ bool deleteSourceBitmap = false;
+
+#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
+
+ // Rasterize extended bitmaps
+
+ TUid extendedBitmapType = bitmap->ExtendedBitmapType();
+ if (extendedBitmapType != KNullUid) {
+ bitmap = createBlitCopy(bitmap);
+ deleteSourceBitmap = true;
+ }
+#endif
+
+ if (bitmap->IsCompressedInRAM()) {
+ bitmap = createBlitCopy(bitmap);
+ deleteSourceBitmap = true;
+ }
+
+ TDisplayMode displayMode = bitmap->DisplayMode();
+ QImage::Format format = qt_TDisplayMode2Format(displayMode);
+
+ TSize size = bitmap->SizeInPixels();
+
+ bitmap->BeginDataAccess();
+ uchar *bytes = (uchar*)bitmap->DataAddress();
+ QImage img = QImage(bytes, size.iWidth, size.iHeight, format);
+ img = img.copy();
+ bitmap->EndDataAccess();
+
+ if(displayMode == EGray2) {
+ //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
+ //So invert mono bitmaps so that masks work correctly.
+ img.invertPixels();
+ } else if(displayMode == EColor16M) {
+ img = img.rgbSwapped(); // EColor16M is BGR
+ }
+
+ fromImage(img, Qt::AutoColor);
+ if(deleteSourceBitmap)
+ delete bitmap;
}
#else
Q_UNUSED(pixmap);
@@ -593,7 +665,25 @@ void* QVGPixmapData::toNativeType(NativeType type)
SgDriver::Close();
return reinterpret_cast<void*>(sgImage);
} else if (type == QPixmapData::FbsBitmap) {
- return 0;
+ CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
+
+ if (bitmap) {
+ if (bitmap->Create(TSize(source.width(), source.height()),
+ EColor16MAP) == KErrNone) {
+ const uchar *sptr = qt_vg_imageBits(source);
+ bitmap->BeginDataAccess();
+
+ uchar *dptr = (uchar*)bitmap->DataAddress();
+ Mem::Copy(dptr, sptr, source.byteCount());
+
+ bitmap->EndDataAccess();
+ } else {
+ delete bitmap;
+ bitmap = 0;
+ }
+ }
+
+ return reinterpret_cast<void*>(bitmap);
}
#else
Q_UNUSED(type);
diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp
index 8bcd5e8..d7c6ad3 100644
--- a/tests/auto/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/qpixmap/tst_qpixmap.cpp
@@ -145,9 +145,11 @@ private slots:
void fromWinHICON();
#endif
-#if defined(Q_WS_S60)
+#if defined(Q_OS_SYMBIAN)
void fromSymbianCFbsBitmap_data();
void fromSymbianCFbsBitmap();
+ void toSymbianCFbsBitmap_data();
+ void toSymbianCFbsBitmap();
#endif
void onlyNullPixmapsOutsideGuiThread();
@@ -1110,7 +1112,7 @@ void tst_QPixmap::fromWinHICON()
#endif // Q_WS_WIN
-#if defined(Q_WS_S60)
+#if defined(Q_OS_SYMBIAN)
Q_DECLARE_METATYPE(TDisplayMode)
void tst_QPixmap::fromSymbianCFbsBitmap_data()
@@ -1206,6 +1208,45 @@ void tst_QPixmap::fromSymbianCFbsBitmap()
CleanupStack::PopAndDestroy(3);
}
+
+void tst_QPixmap::toSymbianCFbsBitmap_data()
+{
+ QTest::addColumn<int>("red");
+ QTest::addColumn<int>("green");
+ QTest::addColumn<int>("blue");
+
+ QTest::newRow("red") << 255 << 0 << 0;
+ QTest::newRow("green") << 0 << 255 << 0;
+ QTest::newRow("blue") << 0 << 0 << 255;
+}
+
+void tst_QPixmap::toSymbianCFbsBitmap()
+{
+ QFETCH(int, red);
+ QFETCH(int, green);
+ QFETCH(int, blue);
+
+ QPixmap pm(100, 100);
+ pm.fill(QColor(red, green, blue));
+
+ CFbsBitmap *bitmap = pm.toSymbianCFbsBitmap();
+
+ QVERIFY(bitmap != 0);
+
+ // Verify size
+ QCOMPARE(100, (int) bitmap->SizeInPixels().iWidth);
+ QCOMPARE(100, (int) bitmap->SizeInPixels().iHeight);
+
+ // Verify pixel color
+ TRgb pixel;
+ bitmap->GetPixel(pixel, TPoint(0,0));
+ QCOMPARE((int)pixel.Red(), red);
+ QCOMPARE((int)pixel.Green(), green);
+ QCOMPARE((int)pixel.Blue(), blue);
+
+ // Clean up
+ delete bitmap;
+}
#endif
void tst_QPixmap::onlyNullPixmapsOutsideGuiThread()