src/gui/image/qpixmap_s60.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtGui of the Qt Toolkit.
     7 ** This file is part of the QtGui module of the Qt Toolkit.
     8 **
     8 **
     9 ** $QT_BEGIN_LICENSE:LGPL$
     9 ** $QT_BEGIN_LICENSE:LGPL$
    10 ** No Commercial Usage
    10 ** No Commercial Usage
    11 ** This file contains pre-release code and may not be distributed.
    11 ** This file contains pre-release code and may not be distributed.
    12 ** You may use this file in accordance with the terms and conditions
    12 ** You may use this file in accordance with the terms and conditions
    71 
    71 
    72     Symbian Font And Bitmap server client that is
    72     Symbian Font And Bitmap server client that is
    73     used to lock the global bitmap heap. Only used in
    73     used to lock the global bitmap heap. Only used in
    74     S60 v3.1 and S60 v3.2.
    74     S60 v3.1 and S60 v3.2.
    75 */
    75 */
       
    76 _LIT(KFBSERVLargeBitmapAccessName,"FbsLargeBitmapAccess");
    76 class QSymbianFbsClient
    77 class QSymbianFbsClient
    77 {
    78 {
    78 public:
    79 public:
    79 
    80 
    80     QSymbianFbsClient() : heapLock(0), heapLocked(false)
    81     QSymbianFbsClient() : heapLocked(false)
    81     {
    82     {
    82         QT_TRAP_THROWING(heapLock = new(ELeave) CFbsBitmap);
    83         heapLock.OpenGlobal(KFBSERVLargeBitmapAccessName);
    83         heapLock->Create(TSize(0,0), S60->screenDevice()->DisplayMode());
       
    84     }
    84     }
    85 
    85 
    86     ~QSymbianFbsClient()
    86     ~QSymbianFbsClient()
    87     {
    87     {
    88         delete heapLock;
    88         heapLock.Close();
    89     }
    89     }
    90 
    90 
    91     bool lockHeap()
    91     bool lockHeap()
    92     {
    92     {
    93         bool wasLocked = heapLocked;
    93         bool wasLocked = heapLocked;
    94 
    94 
    95         if (heapLock && !heapLocked) {
    95         if (heapLock.Handle() && !heapLocked) {
    96             heapLock->LockHeap(ETrue);
    96             heapLock.Wait();
    97             heapLocked = true;
    97             heapLocked = true;
    98         }
    98         }
    99 
    99 
   100         return wasLocked;
   100         return wasLocked;
   101     }
   101     }
   102 
   102 
   103     bool unlockHeap()
   103     bool unlockHeap()
   104     {
   104     {
   105         bool wasLocked = heapLocked;
   105         bool wasLocked = heapLocked;
   106 
   106 
   107         if (heapLock && heapLocked) {
   107         if (heapLock.Handle() && heapLocked) {
   108             heapLock->UnlockHeap(ETrue);
   108             heapLock.Signal();
   109             heapLocked = false;
   109             heapLocked = false;
   110         }
   110         }
   111 
   111 
   112         return wasLocked;
   112         return wasLocked;
   113     }
   113     }
   114 
   114 
   115 
   115 
   116 private:
   116 private:
   117 
   117 
   118     CFbsBitmap *heapLock;
   118     RMutex heapLock;
   119     bool heapLocked;
   119     bool heapLocked;
   120 };
   120 };
   121 
   121 
   122 Q_GLOBAL_STATIC(QSymbianFbsClient, qt_symbianFbsClient);
   122 Q_GLOBAL_STATIC(QSymbianFbsClient, qt_symbianFbsClient);
   123 
   123 
   167 
   167 
   168     ~QSymbianBitmapDataAccess() {};
   168     ~QSymbianBitmapDataAccess() {};
   169 
   169 
   170     inline void beginDataAccess(CFbsBitmap *bitmap)
   170     inline void beginDataAccess(CFbsBitmap *bitmap)
   171     {
   171     {
   172         if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3)
   172         if (symbianVersion == QSysInfo::SV_9_2)
   173             heapWasLocked = qt_symbianFbsClient()->lockHeap();
   173             heapWasLocked = qt_symbianFbsClient()->lockHeap();
   174         else
   174         else
   175             bitmap->LockHeap(ETrue);
   175             bitmap->LockHeap(ETrue);
   176     }
   176     }
   177 
   177 
   178     inline void endDataAccess(CFbsBitmap *bitmap)
   178     inline void endDataAccess(CFbsBitmap *bitmap)
   179     {
   179     {
   180         if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) {
   180         if (symbianVersion == QSysInfo::SV_9_2) {
   181             if (!heapWasLocked)
   181             if (!heapWasLocked)
   182                 qt_symbianFbsClient()->unlockHeap();
   182                 qt_symbianFbsClient()->unlockHeap();
   183         } else {
   183         } else {
   184             bitmap->UnlockHeap(ETrue);
   184             bitmap->UnlockHeap(ETrue);
   185         }
   185         }
   233         CFbsBitGc *bitmapGc = 0;
   233         CFbsBitGc *bitmapGc = 0;
   234         QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(uncompressed));
   234         QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(uncompressed));
   235         QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
   235         QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
   236         bitmapGc->Activate(bitmapDevice);
   236         bitmapGc->Activate(bitmapDevice);
   237 
   237 
   238         bitmapGc->DrawBitmap(TPoint(), bitmap);
   238         bitmapGc->BitBlt(TPoint(), bitmap);
   239 
   239 
   240         delete bitmapGc;
   240         delete bitmapGc;
   241         delete bitmapDevice;
   241         delete bitmapDevice;
   242 
   242 
   243         return uncompressed;
   243         return uncompressed;
   309     \sa fromSymbianCFbsBitmap()
   309     \sa fromSymbianCFbsBitmap()
   310 */
   310 */
   311 CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
   311 CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const
   312 {
   312 {
   313     QPixmapData *data = pixmapData();
   313     QPixmapData *data = pixmapData();
   314     if (data->isNull())
   314     if (!data || data->isNull())
   315         return 0;
   315         return 0;
   316 
   316 
   317     return reinterpret_cast<CFbsBitmap*>(data->toNativeType(QPixmapData::FbsBitmap));
   317     return reinterpret_cast<CFbsBitmap*>(data->toNativeType(QPixmapData::FbsBitmap));
   318 }
   318 }
   319 
   319 
   335 QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
   335 QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
   336 {
   336 {
   337     if (!bitmap)
   337     if (!bitmap)
   338         return QPixmap();
   338         return QPixmap();
   339 
   339 
   340     QPixmap pixmap;
   340     QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType));
   341     pixmap.pixmapData()->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap);
   341     data->fromNativeType(reinterpret_cast<void*>(bitmap), QPixmapData::FbsBitmap);
       
   342     QPixmap pixmap(data.take());
   342     return pixmap;
   343     return pixmap;
   343 }
   344 }
   344 
   345 
   345 QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type),
   346 QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type),
   346     symbianBitmapDataAccess(new QSymbianBitmapDataAccess),
   347     symbianBitmapDataAccess(new QSymbianBitmapDataAccess),
   347     cfbsBitmap(0),
   348     cfbsBitmap(0),
   348     bitmapDevice(0),
       
   349     bitmapGc(0),
       
   350     pengine(0),
   349     pengine(0),
   351     bytes(0)
   350     bytes(0),
       
   351     formatLocked(false)
   352 {
   352 {
   353 
   353 
   354 }
   354 }
   355 
   355 
   356 QS60PixmapData::~QS60PixmapData()
   356 QS60PixmapData::~QS60PixmapData()
   381 
   381 
   382         TSize newSize(width, height);
   382         TSize newSize(width, height);
   383 
   383 
   384         if(cfbsBitmap->SizeInPixels() != newSize) {
   384         if(cfbsBitmap->SizeInPixels() != newSize) {
   385             cfbsBitmap->Resize(TSize(width, height));
   385             cfbsBitmap->Resize(TSize(width, height));
   386             bitmapDevice->Resize(TSize(width, height));
       
   387             bitmapGc->Resized();
       
   388             if(pengine) {
   386             if(pengine) {
   389                 delete pengine;
   387                 delete pengine;
   390                 pengine = 0;
   388                 pengine = 0;
   391             }
   389             }
   392         }
   390         }
   393 
   391 
   394         UPDATE_BUFFER();
   392         UPDATE_BUFFER();
   395     }
   393     }
   396 }
   394 }
   397 
   395 
   398 bool QS60PixmapData::initSymbianBitmapContext()
       
   399 {
       
   400     QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(cfbsBitmap));
       
   401     QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
       
   402     bitmapGc->Activate(bitmapDevice);
       
   403 
       
   404     return true;
       
   405 }
       
   406 
       
   407 void QS60PixmapData::release()
   396 void QS60PixmapData::release()
   408 {
   397 {
   409     if (cfbsBitmap) {
   398     if (cfbsBitmap) {
   410         QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
   399         QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
   411         delete bitmapGc;
       
   412         delete bitmapDevice;
       
   413         delete cfbsBitmap;
   400         delete cfbsBitmap;
   414         lock.relock();
   401         lock.relock();
   415     }
   402     }
   416 
   403 
   417     delete pengine;
   404     delete pengine;
   418     image = QImage();
   405     image = QImage();
   419     cfbsBitmap = 0;
   406     cfbsBitmap = 0;
   420     bitmapGc = 0;
       
   421     bitmapDevice = 0;
       
   422     pengine = 0;
   407     pengine = 0;
   423     bytes = 0;
   408     bytes = 0;
   424 }
   409 }
   425 
   410 
   426 /*!
   411 /*!
   427  * Takes ownership of bitmap
   412  * Takes ownership of bitmap. Used by window surface
   428  */
   413  */
   429 void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap)
   414 void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat)
   430 {
   415 {
   431 	cfbsBitmap = bitmap;
   416     Q_ASSERT(bitmap);
   432 
   417 
   433 	 if(!initSymbianBitmapContext()) {
   418     release();
   434 		qWarning("Could not create CBitmapContext");
   419 
   435 		release();
   420     cfbsBitmap = bitmap;
   436 		return;
   421     formatLocked = lockFormat;
   437 	}
   422 
   438 
   423     setSerialNumber(cfbsBitmap->Handle());
   439 	setSerialNumber(cfbsBitmap->Handle());
   424 
   440 
   425     UPDATE_BUFFER();
   441 	UPDATE_BUFFER();
   426 
   442 
   427     // Create default palette if needed
   443 	// Create default palette if needed
   428     if (cfbsBitmap->DisplayMode() == EGray2) {
   444 	if (cfbsBitmap->DisplayMode() == EGray2) {
   429         image.setColorCount(2);
   445 		image.setNumColors(2);
   430         image.setColor(0, QColor(Qt::color0).rgba());
   446 		image.setColor(0, QColor(Qt::color0).rgba());
   431         image.setColor(1, QColor(Qt::color1).rgba());
   447 		image.setColor(1, QColor(Qt::color1).rgba());
       
   448 
   432 
   449         //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
   433         //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
   450         //So invert mono bitmaps so that masks work correctly.
   434         //So invert mono bitmaps so that masks work correctly.
   451         image.invertPixels();
   435         image.invertPixels();
   452 	} else if (cfbsBitmap->DisplayMode() == EGray256) {
   436     } else if (cfbsBitmap->DisplayMode() == EGray256) {
   453 		for (int i=0; i < 256; ++i)
   437         for (int i=0; i < 256; ++i)
   454 			image.setColor(i, qRgb(i, i, i));
   438             image.setColor(i, qRgb(i, i, i));
   455 	}else if (cfbsBitmap->DisplayMode() == EColor256) {
   439     } else if (cfbsBitmap->DisplayMode() == EColor256) {
   456 		const TColor256Util *palette = TColor256Util::Default();
   440         const TColor256Util *palette = TColor256Util::Default();
   457 		for (int i=0; i < 256; ++i)
   441         for (int i=0; i < 256; ++i)
   458 			image.setColor(i, (QRgb)(palette->Color256(i).Value()));
   442             image.setColor(i, (QRgb)(palette->Color256(i).Value()));
   459 	}
   443     }
       
   444 }
       
   445 
       
   446 QImage QS60PixmapData::toImage(const QRect &r) const
       
   447 {
       
   448     QS60PixmapData *that = const_cast<QS60PixmapData*>(this);
       
   449     that->beginDataAccess();
       
   450     QImage copy = that->image.copy(r);
       
   451     that->endDataAccess();
       
   452 
       
   453     return copy;
   460 }
   454 }
   461 
   455 
   462 void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
   456 void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
   463 {
   457 {
       
   458     release();
       
   459 
   464     QImage sourceImage;
   460     QImage sourceImage;
   465 
   461 
   466     if (pixelType() == BitmapType) {
   462     if (pixelType() == BitmapType) {
   467         sourceImage = img.convertToFormat(QImage::Format_MonoLSB);
   463         sourceImage = img.convertToFormat(QImage::Format_MonoLSB);
   468     } else {
   464     } else {
   512         qWarning("Image format not supported: %d", image.format());
   508         qWarning("Image format not supported: %d", image.format());
   513         return;
   509         return;
   514     }
   510     }
   515 
   511 
   516     cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode);
   512     cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode);
   517     if (!(cfbsBitmap && initSymbianBitmapContext())) {
   513     if (!cfbsBitmap) {
   518         qWarning("Could not create CFbsBitmap and/or CBitmapContext");
   514         qWarning("Could not create CFbsBitmap");
   519         release();
   515         release();
   520         return;
   516         return;
   521     }
   517     }
   522 
   518 
   523     setSerialNumber(cfbsBitmap->Handle());
   519     setSerialNumber(cfbsBitmap->Handle());
   524 
   520 
   525     const uchar *sptr = const_cast<const QImage &>(sourceImage).bits();
   521     const uchar *sptr = const_cast<const QImage &>(sourceImage).bits();
   526     symbianBitmapDataAccess->beginDataAccess(cfbsBitmap);
   522     symbianBitmapDataAccess->beginDataAccess(cfbsBitmap);
   527     uchar *dptr = (uchar*)cfbsBitmap->DataAddress();
   523     uchar *dptr = (uchar*)cfbsBitmap->DataAddress();
   528     Mem::Copy(dptr, sptr, sourceImage.numBytes());
   524     Mem::Copy(dptr, sptr, sourceImage.byteCount());
   529     symbianBitmapDataAccess->endDataAccess(cfbsBitmap);
   525     symbianBitmapDataAccess->endDataAccess(cfbsBitmap);
   530 
   526 
   531     UPDATE_BUFFER();
   527     UPDATE_BUFFER();
   532 
   528 
   533     if (destFormat == QImage::Format_MonoLSB) {
   529     if (destFormat == QImage::Format_MonoLSB) {
   534 		image.setNumColors(2);
   530 		image.setColorCount(2);
   535 		image.setColor(0, QColor(Qt::color0).rgba());
   531 		image.setColor(0, QColor(Qt::color0).rgba());
   536 		image.setColor(1, QColor(Qt::color1).rgba());
   532 		image.setColor(1, QColor(Qt::color1).rgba());
   537 	} else {
   533 	} else {
   538 		image.setColorTable(sourceImage.colorTable());
   534 		image.setColorTable(sourceImage.colorTable());
   539 	}
   535 	}
   540 }
   536 }
   541 
   537 
   542 void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect)
   538 void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect)
   543 {
   539 {
   544     if (data->pixelType() == BitmapType) {
       
   545         QBitmap::fromImage(data->toImage().copy(rect));
       
   546         return;
       
   547     }
       
   548 
       
   549     const QS60PixmapData *s60Data = static_cast<const QS60PixmapData*>(data);
   540     const QS60PixmapData *s60Data = static_cast<const QS60PixmapData*>(data);
   550 
   541     fromImage(s60Data->toImage(rect), Qt::AutoColor | Qt::OrderedAlphaDither);
   551     resize(rect.width(), rect.height());
       
   552     cfbsBitmap->SetDisplayMode(s60Data->cfbsBitmap->DisplayMode());
       
   553 
       
   554     bitmapGc->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect));
       
   555 }
   542 }
   556 
   543 
   557 bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect)
   544 bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect)
   558 {
   545 {
   559     beginDataAccess();
   546     beginDataAccess();
   656     fromImage(img, Qt::OrderedDither | Qt::OrderedAlphaDither);
   643     fromImage(img, Qt::OrderedDither | Qt::OrderedAlphaDither);
   657 }
   644 }
   658 
   645 
   659 QImage QS60PixmapData::toImage() const
   646 QImage QS60PixmapData::toImage() const
   660 {
   647 {
   661     QS60PixmapData *that = const_cast<QS60PixmapData*>(this);
   648     return toImage(QRect());
   662     that->beginDataAccess();
       
   663     QImage copy = that->image.copy();
       
   664     that->endDataAccess();
       
   665 
       
   666     return copy;
       
   667 }
   649 }
   668 
   650 
   669 QPaintEngine* QS60PixmapData::paintEngine() const
   651 QPaintEngine* QS60PixmapData::paintEngine() const
   670 {
   652 {
   671     if (!pengine) {
   653     if (!pengine) {
   682 
   664 
   683     symbianBitmapDataAccess->beginDataAccess(cfbsBitmap);
   665     symbianBitmapDataAccess->beginDataAccess(cfbsBitmap);
   684 
   666 
   685     uchar* newBytes = (uchar*)cfbsBitmap->DataAddress();
   667     uchar* newBytes = (uchar*)cfbsBitmap->DataAddress();
   686 
   668 
   687     if (newBytes == bytes)
   669     TSize size = cfbsBitmap->SizeInPixels();
       
   670 
       
   671     if (newBytes == bytes && image.width() == size.iWidth && image.height() == size.iHeight)
   688         return;
   672         return;
   689 
       
   690 
   673 
   691     bytes = newBytes;
   674     bytes = newBytes;
   692     TDisplayMode mode = cfbsBitmap->DisplayMode();
   675     TDisplayMode mode = cfbsBitmap->DisplayMode();
   693     QImage::Format format = qt_TDisplayMode2Format(mode);
   676     QImage::Format format = qt_TDisplayMode2Format(mode);
   694     //on S60 3.1, premultiplied alpha pixels are stored in a bitmap with 16MA type
   677     // On S60 3.1, premultiplied alpha pixels are stored in a bitmap with 16MA type.
   695     if (format == QImage::Format_ARGB32)
   678     // S60 window surface needs backing store pixmap for transparent window in ARGB32 format.
       
   679     // In that case formatLocked is true.
       
   680     if (!formatLocked && format == QImage::Format_ARGB32)
   696         format = QImage::Format_ARGB32_Premultiplied; // pixel data is actually in premultiplied format
   681         format = QImage::Format_ARGB32_Premultiplied; // pixel data is actually in premultiplied format
   697 
       
   698     TSize size = cfbsBitmap->SizeInPixels();
       
   699 
   682 
   700     QVector<QRgb> savedColorTable;
   683     QVector<QRgb> savedColorTable;
   701     if (!image.isNull())
   684     if (!image.isNull())
   702         savedColorTable = image.colorTable();
   685         savedColorTable = image.colorTable();
   703 
   686 
   750     // Surely things might change in future
   733     // Surely things might change in future
   751 
   734 
   752     if (!sgImage)
   735     if (!sgImage)
   753         return QPixmap();
   736         return QPixmap();
   754 
   737 
   755     QPixmap pixmap;
   738     QScopedPointer<QS60PixmapData> data(new QS60PixmapData(QPixmapData::PixmapType));
   756     pixmap.pixmapData()->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage);
   739     data->fromNativeType(reinterpret_cast<void*>(sgImage), QPixmapData::SgImage);
   757 
   740     QPixmap pixmap(data.take());
   758     return pixmap;
   741     return pixmap;
   759 }
   742 }
   760 
   743 
   761 /*!
   744 /*!
   762 \since 4.6
   745 \since 4.6
   814         TDisplayMode displayMode = cfbsBitmap->DisplayMode();
   797         TDisplayMode displayMode = cfbsBitmap->DisplayMode();
   815 
   798 
   816         if(displayMode == EGray2) {
   799         if(displayMode == EGray2) {
   817             //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
   800             //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
   818             //So invert mono bitmaps so that masks work correctly.
   801             //So invert mono bitmaps so that masks work correctly.
       
   802             beginDataAccess();
   819             image.invertPixels();
   803             image.invertPixels();
       
   804             endDataAccess();
   820             needsCopy = true;
   805             needsCopy = true;
   821         }
   806         }
   822 
   807 
   823         if (needsCopy) {
   808         if (needsCopy) {
   824             QImage source;
   809             QImage source;
   825 
   810 
   826             if (convertToArgb32) {
   811             if (convertToArgb32) {
       
   812                 beginDataAccess();
   827                 source = image.convertToFormat(QImage::Format_ARGB32);
   813                 source = image.convertToFormat(QImage::Format_ARGB32);
       
   814                 endDataAccess();
   828                 displayMode = EColor16MA;
   815                 displayMode = EColor16MA;
   829             } else {
   816             } else {
   830                 source = image;
   817                 source = image;
   831             }
   818             }
   832 
   819 
   833             CFbsBitmap *newBitmap = createSymbianCFbsBitmap(TSize(source.width(), source.height()), displayMode);
   820             CFbsBitmap *newBitmap = createSymbianCFbsBitmap(TSize(source.width(), source.height()), displayMode);
   834             const uchar *sptr = source.bits();
   821             const uchar *sptr = source.bits();
   835             symbianBitmapDataAccess->beginDataAccess(newBitmap);
   822             symbianBitmapDataAccess->beginDataAccess(newBitmap);
   836 
   823 
   837             uchar *dptr = (uchar*)newBitmap->DataAddress();
   824             uchar *dptr = (uchar*)newBitmap->DataAddress();
   838             Mem::Copy(dptr, sptr, source.numBytes());
   825             Mem::Copy(dptr, sptr, source.byteCount());
   839 
   826 
   840             symbianBitmapDataAccess->endDataAccess(newBitmap);
   827             symbianBitmapDataAccess->endDataAccess(newBitmap);
   841 
   828 
   842             bitmap = newBitmap;
   829             bitmap = newBitmap;
   843         } else {
   830         } else {
   852             }
   839             }
   853         }
   840         }
   854 
   841 
   855         if(displayMode == EGray2) {
   842         if(displayMode == EGray2) {
   856             // restore pixels
   843             // restore pixels
       
   844             beginDataAccess();
   857             image.invertPixels();
   845             image.invertPixels();
       
   846             endDataAccess();
   858         }
   847         }
   859 
   848 
   860         return reinterpret_cast<void*>(bitmap);
   849         return reinterpret_cast<void*>(bitmap);
   861 
   850 
   862     }
   851     }
   933 
   922 
   934             QSymbianBitmapDataAccess da;
   923             QSymbianBitmapDataAccess da;
   935             da.beginDataAccess(sourceBitmap);
   924             da.beginDataAccess(sourceBitmap);
   936             uchar *bytes = (uchar*)sourceBitmap->DataAddress();
   925             uchar *bytes = (uchar*)sourceBitmap->DataAddress();
   937             QImage img = QImage(bytes, size.iWidth, size.iHeight, format);
   926             QImage img = QImage(bytes, size.iWidth, size.iHeight, format);
       
   927             img = img.copy();
   938             da.endDataAccess(sourceBitmap);
   928             da.endDataAccess(sourceBitmap);
   939 
       
   940             fromImage(img, Qt::AutoColor);
       
   941 
       
   942             if(deleteSourceBitmap)
       
   943                 delete sourceBitmap;
       
   944 
   929 
   945             if(displayMode == EGray2) {
   930             if(displayMode == EGray2) {
   946                 //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
   931                 //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
   947                 //So invert mono bitmaps so that masks work correctly.
   932                 //So invert mono bitmaps so that masks work correctly.
   948                 image.invertPixels();
   933                 img.invertPixels();
       
   934             } else if(displayMode == EColor16M) {
       
   935                 img = img.rgbSwapped(); // EColor16M is BGR
   949             }
   936             }
       
   937 
       
   938             fromImage(img, Qt::AutoColor);
       
   939 
       
   940             if(deleteSourceBitmap)
       
   941                 delete sourceBitmap;
   950         } else {
   942         } else {
   951             CFbsBitmap* duplicate = 0;
   943             CFbsBitmap* duplicate = 0;
   952             QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap);
   944             QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap);
   953 
   945 
   954             TInt err = duplicate->Duplicate(sourceBitmap->Handle());
   946             TInt err = duplicate->Duplicate(sourceBitmap->Handle());
   968                 delete sourceBitmap;
   960                 delete sourceBitmap;
   969         }
   961         }
   970     }
   962     }
   971 }
   963 }
   972 
   964 
       
   965 QPixmapData *QS60PixmapData::createCompatiblePixmapData() const
       
   966 {
       
   967     return new QS60PixmapData(pixelType());
       
   968 }
       
   969 
   973 QT_END_NAMESPACE
   970 QT_END_NAMESPACE