Commit c78dabc55943b76479f7a84bae146f52cbc7bbbf
- Diff rendering mode:
- inline
- side by side
src/corelib/global/qglobal.h
(1 / 0)
|   | |||
| 2389 | 2389 | #ifdef SYMBIAN_GRAPHICS_USE_GCE | |
| 2390 | 2390 | //RWsPointerCursor is fixed, so don't use low performance sprites | |
| 2391 | 2391 | #define Q_SYMBIAN_FIXED_POINTER_CURSORS | |
| 2392 | #define Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE | ||
| 2392 | 2393 | #endif | |
| 2393 | 2394 | ||
| 2394 | 2395 | //Symbian does not support data imports from a DLL |
src/gui/image/image.pri
(1 / 0)
|   | |||
| 70 | 70 | SOURCES += image/qpixmap_mac.cpp | |
| 71 | 71 | } | |
| 72 | 72 | symbian { | |
| 73 | HEADERS += image/qpixmap_s60_p.h | ||
| 73 | 74 | SOURCES += image/qpixmap_s60.cpp | |
| 74 | 75 | } | |
| 75 | 76 |
src/gui/image/qpixmap.cpp
(10 / 3)
|   | |||
| 1557 | 1557 | premultiplied alpha format. If the image has an alpha channel, and | |
| 1558 | 1558 | if the system allows, the preferred format is premultiplied alpha. | |
| 1559 | 1559 | Note also that QPixmap, unlike QImage, may be hardware dependent. | |
| 1560 | On X11 and Mac, a QPixmap is stored on the server side while a | ||
| 1561 | QImage is stored on the client side (on Windows, these two classes | ||
| 1560 | On X11, Mac and Symbian, a QPixmap is stored on the server side while | ||
| 1561 | a QImage is stored on the client side (on Windows, these two classes | ||
| 1562 | 1562 | have an equivalent internal representation, i.e. both QImage and | |
| 1563 | 1563 | QPixmap are stored on the client side and don't use any GDI | |
| 1564 | 1564 | resources). | |
| … | … | ||
| 1577 | 1577 | screen. Alternatively, if no manipulation is desired, the image | |
| 1578 | 1578 | file can be loaded directly into a QPixmap. On Windows, the | |
| 1579 | 1579 | QPixmap class also supports conversion between \c HBITMAP and | |
| 1580 | QPixmap. | ||
| 1580 | QPixmap. On Symbian, the QPixmap class also supports conversion | ||
| 1581 | between CFbsBitmap and QPixmap. | ||
| 1581 | 1582 | ||
| 1582 | 1583 | QPixmap provides a collection of functions that can be used to | |
| 1583 | 1584 | obtain a variety of information about the pixmap. In addition, | |
| … | … | ||
| 1683 | 1683 | returns the HBITMAP handle. The fromWinHBITMAP() function returns | |
| 1684 | 1684 | a QPixmap that is equivalent to the given bitmap which has the | |
| 1685 | 1685 | specified format. | |
| 1686 | |||
| 1687 | In addition, on Symbian, the QPixmap class supports conversion to | ||
| 1688 | and from CFbsBitmap: the toSymbianCFbsBitmap() function creates | ||
| 1689 | CFbsBitmap equivalent to the QPixmap, based on given mode and returns | ||
| 1690 | a CFbsBitmap object. The fromSymbianCFbsBitmap() function returns a | ||
| 1691 | QPixmap that is equivalent to the given bitmap and given mode. | ||
| 1686 | 1692 | ||
| 1687 | 1693 | \section1 Pixmap Transformations | |
| 1688 | 1694 |
src/gui/image/qpixmap.h
(5 / 2)
|   | |||
| 157 | 157 | #endif | |
| 158 | 158 | ||
| 159 | 159 | #if defined(Q_OS_SYMBIAN) | |
| 160 | CFbsBitmap *toSymbianCFbsBitmap() const; | ||
| 161 | static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap); | ||
| 160 | enum ConversionMode { CopyData, DuplicateHandle }; | ||
| 161 | |||
| 162 | CFbsBitmap *toSymbianCFbsBitmap(ConversionMode mode = DuplicateHandle) const; | ||
| 163 | static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode = DuplicateHandle); | ||
| 162 | 164 | #endif | |
| 163 | 165 | ||
| 164 | 166 | inline QPixmap copy(int x, int y, int width, int height) const; | |
| … | … | ||
| 256 | 256 | friend class QPixmapData; | |
| 257 | 257 | friend class QX11PixmapData; | |
| 258 | 258 | friend class QMacPixmapData; | |
| 259 | friend class QS60PixmapData; | ||
| 259 | 260 | friend class QBitmap; | |
| 260 | 261 | friend class QPaintDevice; | |
| 261 | 262 | friend class QPainter; |
|   | |||
| 83 | 83 | ||
| 84 | 84 | protected: | |
| 85 | 85 | int metric(QPaintDevice::PaintDeviceMetric metric) const; | |
| 86 | QImage image; | ||
| 86 | 87 | ||
| 87 | 88 | private: | |
| 88 | 89 | friend class QPixmap; | |
| 89 | 90 | friend class QBitmap; | |
| 90 | 91 | friend class QDetachedPixmap; | |
| 91 | 92 | friend class QRasterPaintEngine; | |
| 92 | QImage image; | ||
| 93 | 93 | }; | |
| 94 | 94 | ||
| 95 | 95 | QT_END_NAMESPACE |
src/gui/image/qpixmap_s60.cpp
(773 / 118)
|   | |||
| 43 | 43 | #include <fbs.h> | |
| 44 | 44 | ||
| 45 | 45 | #include <private/qt_s60_p.h> | |
| 46 | #include <private/qpaintengine_s60_p.h> | ||
| 47 | |||
| 46 | 48 | #include "qpixmap.h" | |
| 47 | 49 | #include "qpixmap_raster_p.h" | |
| 48 | 50 | #include <qwidget.h> | |
| 51 | #include "qpixmap_s60_p.h" | ||
| 52 | #include "qnativeimage_p.h" | ||
| 53 | #include "qbitmap.h" | ||
| 54 | #include "qimage.h" | ||
| 55 | #include "qimage_p.h" | ||
| 49 | 56 | ||
| 57 | #include <fbs.h> | ||
| 58 | |||
| 50 | 59 | QT_BEGIN_NAMESPACE | |
| 51 | 60 | ||
| 52 | QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h ) | ||
| 61 | const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08, | ||
| 62 | 0x10, 0x20, 0x40, 0x80 }; | ||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | /*! | ||
| 67 | \since 4.6 | ||
| 68 | |||
| 69 | Symbian Font And Bitmap server client that is | ||
| 70 | used to lock the global bitmap heap. Only used in | ||
| 71 | S60 v3.1 and S60 v3.2. | ||
| 72 | */ | ||
| 73 | class QSymbianFbsClient | ||
| 53 | 74 | { | |
| 75 | public: | ||
| 76 | |||
| 77 | QSymbianFbsClient() : heapLock(0), heapLocked(false) | ||
| 78 | { | ||
| 79 | QT_TRAP_THROWING(heapLock = new(ELeave) CFbsBitmap); | ||
| 80 | heapLock->Create(TSize(0,0), S60->screenDevice()->DisplayMode()); | ||
| 81 | } | ||
| 82 | |||
| 83 | ~QSymbianFbsClient() | ||
| 84 | { | ||
| 85 | delete heapLock; | ||
| 86 | } | ||
| 87 | |||
| 88 | bool lockHeap() | ||
| 89 | { | ||
| 90 | bool wasLocked = heapLocked; | ||
| 91 | |||
| 92 | if (heapLock && !heapLocked) { | ||
| 93 | heapLock->LockHeap(ETrue); | ||
| 94 | heapLocked = true; | ||
| 95 | } | ||
| 96 | |||
| 97 | return wasLocked; | ||
| 98 | } | ||
| 99 | |||
| 100 | bool unlockHeap() | ||
| 101 | { | ||
| 102 | bool wasLocked = heapLocked; | ||
| 103 | |||
| 104 | if (heapLock && heapLocked) { | ||
| 105 | heapLock->UnlockHeap(ETrue); | ||
| 106 | heapLocked = false; | ||
| 107 | } | ||
| 108 | |||
| 109 | return wasLocked; | ||
| 110 | } | ||
| 111 | |||
| 112 | |||
| 113 | private: | ||
| 114 | |||
| 115 | CFbsBitmap *heapLock; | ||
| 116 | bool heapLocked; | ||
| 117 | }; | ||
| 118 | |||
| 119 | Q_GLOBAL_STATIC(QSymbianFbsClient, qt_symbianFbsClient); | ||
| 120 | |||
| 121 | |||
| 122 | |||
| 123 | // QSymbianFbsHeapLock | ||
| 124 | |||
| 125 | QSymbianFbsHeapLock::QSymbianFbsHeapLock(LockAction a) | ||
| 126 | : action(a), wasLocked(false) | ||
| 127 | { | ||
| 128 | QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); | ||
| 129 | if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) | ||
| 130 | wasLocked = qt_symbianFbsClient()->unlockHeap(); | ||
| 131 | } | ||
| 132 | |||
| 133 | QSymbianFbsHeapLock::~QSymbianFbsHeapLock() | ||
| 134 | { | ||
| 135 | // Do nothing | ||
| 136 | } | ||
| 137 | |||
| 138 | void QSymbianFbsHeapLock::relock() | ||
| 139 | { | ||
| 140 | QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); | ||
| 141 | if (wasLocked && (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3)) | ||
| 142 | qt_symbianFbsClient()->lockHeap(); | ||
| 143 | } | ||
| 144 | |||
| 145 | /*! | ||
| 146 | \since 4.6 | ||
| 147 | |||
| 148 | Data access class that is used to locks/unlocks pixel data | ||
| 149 | when drawing or modifying CFbsBitmap pixel data. | ||
| 150 | */ | ||
| 151 | class QSymbianBitmapDataAccess | ||
| 152 | { | ||
| 153 | public: | ||
| 154 | |||
| 155 | bool heapWasLocked; | ||
| 156 | QSysInfo::SymbianVersion symbianVersion; | ||
| 157 | |||
| 158 | explicit QSymbianBitmapDataAccess() : heapWasLocked(false) | ||
| 159 | { | ||
| 160 | symbianVersion = QSysInfo::symbianVersion(); | ||
| 161 | }; | ||
| 162 | |||
| 163 | ~QSymbianBitmapDataAccess() {}; | ||
| 164 | |||
| 165 | inline void beginDataAccess(CFbsBitmap *bitmap) | ||
| 166 | { | ||
| 167 | if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) | ||
| 168 | heapWasLocked = qt_symbianFbsClient()->lockHeap(); | ||
| 169 | else | ||
| 170 | bitmap->LockHeap(ETrue); | ||
| 171 | } | ||
| 172 | |||
| 173 | inline void endDataAccess(CFbsBitmap *bitmap) | ||
| 174 | { | ||
| 175 | if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) { | ||
| 176 | if (!heapWasLocked) | ||
| 177 | qt_symbianFbsClient()->unlockHeap(); | ||
| 178 | } else { | ||
| 179 | bitmap->UnlockHeap(ETrue); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | }; | ||
| 183 | |||
| 184 | |||
| 185 | #define UPDATE_BUFFER() \ | ||
| 186 | { \ | ||
| 187 | beginDataAccess(); \ | ||
| 188 | endDataAccess(); \ | ||
| 189 | } | ||
| 190 | |||
| 191 | |||
| 192 | static CFbsBitmap* createSymbianCFbsBitmap(const TSize& size, TDisplayMode mode) | ||
| 193 | { | ||
| 194 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | ||
| 195 | |||
| 196 | CFbsBitmap* bitmap = 0; | ||
| 197 | QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap); | ||
| 198 | |||
| 199 | if (bitmap->Create(size, mode) != KErrNone) { | ||
| 200 | delete bitmap; | ||
| 201 | bitmap = 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | lock.relock(); | ||
| 205 | |||
| 206 | return bitmap; | ||
| 207 | } | ||
| 208 | |||
| 209 | static CFbsBitmap* uncompress(CFbsBitmap* bitmap) | ||
| 210 | { | ||
| 211 | if(bitmap->IsCompressedInRAM()) { | ||
| 212 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | ||
| 213 | |||
| 214 | CFbsBitmap *uncompressed = 0; | ||
| 215 | QT_TRAP_THROWING(uncompressed = new (ELeave) CFbsBitmap); | ||
| 216 | |||
| 217 | if (uncompressed->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) { | ||
| 218 | delete bitmap; | ||
| 219 | bitmap = 0; | ||
| 220 | lock.relock(); | ||
| 221 | |||
| 222 | return bitmap; | ||
| 223 | } | ||
| 224 | |||
| 225 | lock.relock(); | ||
| 226 | |||
| 227 | CBitmapContext *bitmapContext = 0; | ||
| 228 | CFbsBitmapDevice* bitmapDevice = 0; | ||
| 229 | QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(uncompressed)); | ||
| 230 | TInt err = bitmapDevice->CreateBitmapContext(bitmapContext); | ||
| 231 | if (err != KErrNone) { | ||
| 232 | delete bitmap; | ||
| 233 | delete bitmapDevice; | ||
| 234 | bitmap = 0; | ||
| 235 | bitmapDevice = 0; | ||
| 236 | |||
| 237 | lock.relock(); | ||
| 238 | |||
| 239 | return bitmap; | ||
| 240 | } | ||
| 241 | |||
| 242 | bitmapContext->DrawBitmap(TPoint(), bitmap); | ||
| 243 | |||
| 244 | delete bitmapContext; | ||
| 245 | delete bitmapDevice; | ||
| 246 | |||
| 247 | return uncompressed; | ||
| 248 | } else { | ||
| 249 | return bitmap; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 253 | QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h) | ||
| 254 | { | ||
| 54 | 255 | CWsScreenDevice* screenDevice = S60->screenDevice(); | |
| 55 | 256 | TSize screenSize = screenDevice->SizeInPixels(); | |
| 56 | |||
| 257 | |||
| 57 | 258 | TSize srcSize; | |
| 58 | 259 | // Find out if this is one of our windows. | |
| 59 | 260 | QSymbianControl *sControl; | |
| … | … | ||
| 268 | 268 | y += relativePos.iY; | |
| 269 | 269 | srcSize = winId->Size(); | |
| 270 | 270 | } | |
| 271 | |||
| 271 | |||
| 272 | 272 | TRect srcRect(TPoint(x, y), srcSize); | |
| 273 | 273 | // Clip to the screen | |
| 274 | 274 | srcRect.Intersection(TRect(screenSize)); | |
| 275 | |||
| 275 | |||
| 276 | 276 | if (w > 0 && h > 0) { | |
| 277 | 277 | TRect subRect(TPoint(x, y), TSize(w, h)); | |
| 278 | 278 | // Clip to the subRect | |
| 279 | 279 | srcRect.Intersection(subRect); | |
| 280 | 280 | } | |
| 281 | |||
| 281 | |||
| 282 | 282 | if (srcRect.IsEmpty()) | |
| 283 | 283 | return QPixmap(); | |
| 284 | |||
| 285 | TDisplayMode displayMode = screenDevice->DisplayMode(); | ||
| 286 | CFbsBitmap* temporary = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new | ||
| 287 | TInt error = temporary->Create(srcRect.Size(), displayMode); | ||
| 288 | if (error == KErrNone) | ||
| 289 | error = screenDevice->CopyScreenToBitmap(temporary, srcRect); | ||
| 290 | |||
| 291 | if (error != KErrNone) { | ||
| 292 | CBase::Delete(temporary); | ||
| 293 | return QPixmap(); | ||
| 284 | |||
| 285 | CFbsBitmap* temporary = createSymbianCFbsBitmap(srcRect.Size(), screenDevice->DisplayMode()); | ||
| 286 | |||
| 287 | QPixmap pix; | ||
| 288 | |||
| 289 | if (temporary && screenDevice->CopyScreenToBitmap(temporary, srcRect) == KErrNone) { | ||
| 290 | pix = QPixmap::fromSymbianCFbsBitmap(temporary); | ||
| 294 | 291 | } | |
| 295 | |||
| 296 | QPixmap pixmap = QPixmap::fromSymbianCFbsBitmap(temporary); | ||
| 297 | CBase::Delete(temporary); | ||
| 298 | return pixmap; | ||
| 292 | |||
| 293 | delete temporary; | ||
| 294 | return pix; | ||
| 299 | 295 | } | |
| 300 | 296 | ||
| 301 | 297 | /*! | |
| 302 | \since 4.6 | ||
| 298 | \enum QPixmap::ConversionMode | ||
| 303 | 299 | ||
| 304 | Returns a \c CFbsBitmap that is equivalent to the QPixmap by copying the data. | ||
| 300 | \bold{Symbian only:} This enum defines how the conversion between \c | ||
| 301 | CFbsBitmap and QPixmap is performed. | ||
| 305 | 302 | ||
| 306 | It is the caller's responsibility to delete the \c CFbsBitmap after use. | ||
| 303 | \warning This enum is only available on Symbian. | ||
| 307 | 304 | ||
| 308 | \warning This function is only available on Symbian OS. | ||
| 305 | \value CopyData Copied CFbsBitmap data. | ||
| 309 | 306 | ||
| 310 | \sa fromSymbianCFbsBitmap() | ||
| 307 | \value DuplicateHandle Duplicates CFbsBitmap handle. This also means | ||
| 308 | that pixmap data will be explicitly shared. | ||
| 309 | |||
| 310 | \sa fromSymbianCFbsBitmap(), toSymbianCFbsBitmap() | ||
| 311 | 311 | */ | |
| 312 | 312 | ||
| 313 | CFbsBitmap *QPixmap::toSymbianCFbsBitmap() const | ||
| 313 | |||
| 314 | /*! | ||
| 315 | \fn CFbsBitmap *QPixmap::toSymbianCFbsBitmap(ConversionMode mode) | ||
| 316 | \since 4.6 | ||
| 317 | |||
| 318 | Creates \c CFbsBitmap that is equivalent to the QPixmap, based on | ||
| 319 | the given \a mode. If the creation then this function returns 0. | ||
| 320 | |||
| 321 | It is the caller's responsibility to release the \c CFbsBitmap data | ||
| 322 | after use either by deleting the bitmap or calling \c Reset(). | ||
| 323 | |||
| 324 | \warning On S60 3.1 and S60 3.2 conversion mode will always be CopyData | ||
| 325 | if QPixmap pixels have alpha values. | ||
| 326 | \warning This function is only available on Symbian OS. | ||
| 327 | |||
| 328 | \sa fromSymbianCFbsBitmap() | ||
| 329 | */ | ||
| 330 | CFbsBitmap *QPixmap::toSymbianCFbsBitmap(ConversionMode mode) const | ||
| 314 | 331 | { | |
| 315 | if (isNull()) | ||
| 332 | QS60PixmapData *s60data = static_cast<QS60PixmapData *>(data.data()); | ||
| 333 | |||
| 334 | if (isNull() || !s60data->cfbsBitmap) | ||
| 316 | 335 | return 0; | |
| 336 | |||
| 337 | bool convertToArgb32 = false; | ||
| 338 | |||
| 339 | QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); | ||
| 340 | if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) { | ||
| 341 | // Convert argb32_premultiplied to argb32 since Symbian 9.2 and Symbian 9.3 do | ||
| 342 | // not support premultipied format. | ||
| 343 | |||
| 344 | if (s60data->image.format() == QImage::Format_ARGB32_Premultiplied) { | ||
| 345 | mode = CopyData; | ||
| 346 | convertToArgb32 = true; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | |||
| 350 | CFbsBitmap *bitmap = 0; | ||
| 351 | |||
| 352 | TDisplayMode displayMode = s60data->cfbsBitmap->DisplayMode(); | ||
| 353 | |||
| 354 | if(displayMode == EGray2) { | ||
| 355 | //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid | ||
| 356 | //So invert mono bitmaps so that masks work correctly. | ||
| 357 | s60data->image.invertPixels(); | ||
| 358 | mode = CopyData; | ||
| 359 | } | ||
| 360 | |||
| 361 | if (mode == CopyData) { | ||
| 362 | QImage source; | ||
| 363 | |||
| 364 | if (convertToArgb32) { | ||
| 365 | source = s60data->image.convertToFormat(QImage::Format_ARGB32); | ||
| 366 | displayMode = EColor16MA; | ||
| 367 | } else { | ||
| 368 | source = s60data->image; | ||
| 369 | } | ||
| 370 | |||
| 371 | CFbsBitmap *newBitmap = createSymbianCFbsBitmap(TSize(source.width(), source.height()), displayMode); | ||
| 372 | const uchar *sptr = source.bits(); | ||
| 373 | s60data->symbianBitmapDataAccess->beginDataAccess(newBitmap); | ||
| 374 | |||
| 375 | uchar *dptr = (uchar*)newBitmap->DataAddress(); | ||
| 376 | Mem::Copy(dptr, sptr, source.numBytes()); | ||
| 377 | |||
| 378 | s60data->symbianBitmapDataAccess->endDataAccess(newBitmap); | ||
| 379 | |||
| 380 | bitmap = newBitmap; | ||
| 381 | } else { | ||
| 382 | |||
| 383 | QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap); | ||
| 384 | |||
| 385 | TInt err = bitmap->Duplicate(s60data->cfbsBitmap->Handle()); | ||
| 386 | if (err != KErrNone) { | ||
| 387 | qWarning("Could not duplicate CFbsBitmap"); | ||
| 388 | delete bitmap; | ||
| 389 | bitmap = 0; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | if(displayMode == EGray2) { | ||
| 394 | // restore pixels | ||
| 395 | s60data->image.invertPixels(); | ||
| 396 | } | ||
| 397 | |||
| 398 | return bitmap; | ||
| 399 | } | ||
| 317 | 400 | ||
| 401 | /*! | ||
| 402 | \fn QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode) | ||
| 403 | \since 4.6 | ||
| 404 | |||
| 405 | Creates a QPixmap from native \c CFbsBitmap \a bitmap. The conversion | ||
| 406 | is based on the specified \a mode. Conversion mode is always QPixmap::CopyData | ||
| 407 | if given \a bitmap does not have display mode of TDisplayMode::EGray2, | ||
| 408 | \c TDisplayMode::EColor16MU or \c TDisplayMode::EColor16MAP. | ||
| 409 | |||
| 410 | If the CFbsBitmap is not valid this function will return a null QPixmap. | ||
| 411 | |||
| 412 | \warning This function is only available on Symbian OS. | ||
| 413 | |||
| 414 | \sa toSymbianCFbsBitmap(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} | ||
| 415 | */ | ||
| 416 | QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode) | ||
| 417 | { | ||
| 418 | if (bitmap) { | ||
| 419 | |||
| 420 | bool deleteSourceBitmap = false; | ||
| 421 | |||
| 422 | #if Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE | ||
| 423 | |||
| 424 | // Rasterize extended bitmaps | ||
| 425 | |||
| 426 | TUid extendedBitmapType = = bitmap->ExtendedBitmapType(); | ||
| 427 | if (extendedBitmapType != KNullUid) { | ||
| 428 | CFbsBitmap *rasterBitmap = createSymbianCFbsBitmap(bitmap->SizeInPixels(), EColor16MA); | ||
| 429 | |||
| 430 | CFbsBitmapDevice *rasterBitmapDev = 0; | ||
| 431 | QT_TRAP_THROWING(rasterBitmapDev = CFbsBitmapDevice::NewL(rasterBitmap)); | ||
| 432 | |||
| 433 | CFbsBitGc *rasterBitmapGc = 0; | ||
| 434 | TInt err = rasterBitmapDev->CreateContext(rasterBitmapGc); | ||
| 435 | if (err != KErrNone) { | ||
| 436 | delete rasterBitmap; | ||
| 437 | delete rasterBitmapDev; | ||
| 438 | rasterBitmapDev = 0; | ||
| 439 | return QPixmap(); | ||
| 440 | } | ||
| 441 | |||
| 442 | rasterBitmapGc->BitBlt(TPoint( 0, 0), bitmap); | ||
| 443 | |||
| 444 | bitmap = rasterBitmap; | ||
| 445 | |||
| 446 | delete rasterBitmapDev; | ||
| 447 | delete rasterBitmapGc; | ||
| 448 | |||
| 449 | rasterBitmapDev = 0; | ||
| 450 | rasterBitmapGc = 0; | ||
| 451 | |||
| 452 | deleteSourceBitmap = true; | ||
| 453 | } | ||
| 454 | #endif | ||
| 455 | |||
| 456 | |||
| 457 | deleteSourceBitmap = bitmap->IsCompressedInRAM(); | ||
| 458 | CFbsBitmap *sourceBitmap = uncompress(bitmap); | ||
| 459 | |||
| 460 | TDisplayMode displayMode = sourceBitmap->DisplayMode(); | ||
| 461 | QImage::Format format = qt_TDisplayMode2Format(displayMode); | ||
| 462 | |||
| 463 | QImage::Format opaqueFormat = QNativeImage::systemFormat(); | ||
| 464 | QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; | ||
| 465 | |||
| 466 | if (format != opaqueFormat && format != alphaFormat && format != QImage::Format_MonoLSB) | ||
| 467 | mode = CopyData; | ||
| 468 | |||
| 469 | |||
| 470 | QPixmapData::PixelType type = (format!=QImage::Format_MonoLSB) | ||
| 471 | ? QPixmapData::PixmapType | ||
| 472 | : QPixmapData::BitmapType; | ||
| 473 | |||
| 474 | QS60PixmapData *pixmapData = 0; | ||
| 475 | |||
| 476 | if (mode == CopyData) { | ||
| 477 | |||
| 478 | TSize size = sourceBitmap->SizeInPixels(); | ||
| 479 | |||
| 480 | QSymbianBitmapDataAccess da; | ||
| 481 | da.beginDataAccess(sourceBitmap); | ||
| 482 | uchar *bytes = (uchar*)sourceBitmap->DataAddress(); | ||
| 483 | QImage img = QImage(bytes, size.iWidth, size.iHeight, format); | ||
| 484 | da.endDataAccess(sourceBitmap); | ||
| 485 | |||
| 486 | pixmapData = new QS60PixmapData(type); | ||
| 487 | pixmapData->fromImage(img, Qt::AutoColor); | ||
| 488 | |||
| 489 | if(deleteSourceBitmap) | ||
| 490 | delete sourceBitmap; | ||
| 491 | |||
| 492 | if(displayMode == EGray2) { | ||
| 493 | //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid | ||
| 494 | //So invert mono bitmaps so that masks work correctly. | ||
| 495 | pixmapData->image.invertPixels(); | ||
| 496 | } | ||
| 497 | } else { | ||
| 498 | CFbsBitmap* duplicate = 0; | ||
| 499 | QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap); | ||
| 500 | |||
| 501 | TInt err = duplicate->Duplicate(sourceBitmap->Handle()); | ||
| 502 | if (err != KErrNone) { | ||
| 503 | qWarning("Could not duplicate CFbsBitmap"); | ||
| 504 | |||
| 505 | if(deleteSourceBitmap) | ||
| 506 | delete sourceBitmap; | ||
| 507 | |||
| 508 | delete duplicate; | ||
| 509 | return QPixmap(); | ||
| 510 | } | ||
| 511 | |||
| 512 | pixmapData = new QS60PixmapData(type); | ||
| 513 | pixmapData->fromSymbianBitmap(duplicate); | ||
| 514 | |||
| 515 | if(deleteSourceBitmap) | ||
| 516 | delete sourceBitmap; | ||
| 517 | } | ||
| 518 | |||
| 519 | return QPixmap(pixmapData); | ||
| 520 | } | ||
| 521 | |||
| 522 | return QPixmap(); | ||
| 523 | } | ||
| 524 | |||
| 525 | QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type), | ||
| 526 | symbianBitmapDataAccess(new QSymbianBitmapDataAccess), | ||
| 527 | cfbsBitmap(0), | ||
| 528 | bitmapDevice(0), | ||
| 529 | bitmapContext(0), | ||
| 530 | pengine(0), | ||
| 531 | bytes(0) | ||
| 532 | { | ||
| 533 | |||
| 534 | } | ||
| 535 | |||
| 536 | QS60PixmapData::~QS60PixmapData() | ||
| 537 | { | ||
| 538 | release(); | ||
| 539 | } | ||
| 540 | |||
| 541 | void QS60PixmapData::resize(int width, int height) | ||
| 542 | { | ||
| 543 | if (width <= 0 || height <= 0) { | ||
| 544 | w = width; | ||
| 545 | h = height; | ||
| 546 | is_null = true; | ||
| 547 | |||
| 548 | release(); | ||
| 549 | return; | ||
| 550 | } else if (!cfbsBitmap) { | ||
| 551 | TDisplayMode mode; | ||
| 552 | if (pixelType() == BitmapType) | ||
| 553 | mode = EGray2; | ||
| 554 | else | ||
| 555 | mode = EColor16MU; | ||
| 556 | |||
| 557 | CFbsBitmap* bitmap = createSymbianCFbsBitmap(TSize(width, height), mode); | ||
| 558 | fromSymbianBitmap(bitmap); | ||
| 559 | } else { | ||
| 560 | |||
| 561 | TSize newSize(width, height); | ||
| 562 | |||
| 563 | if(cfbsBitmap->SizeInPixels() != newSize) { | ||
| 564 | cfbsBitmap->Resize(TSize(width, height)); | ||
| 565 | if(pengine) { | ||
| 566 | delete pengine; | ||
| 567 | pengine = 0; | ||
| 568 | } | ||
| 569 | } | ||
| 570 | |||
| 571 | UPDATE_BUFFER(); | ||
| 572 | } | ||
| 573 | } | ||
| 574 | |||
| 575 | bool QS60PixmapData::initSymbianBitmapContext() | ||
| 576 | { | ||
| 577 | QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(cfbsBitmap)); | ||
| 578 | TInt err = bitmapDevice->CreateBitmapContext(bitmapContext); | ||
| 579 | if (err != KErrNone) { | ||
| 580 | delete bitmapDevice; | ||
| 581 | bitmapDevice = 0; | ||
| 582 | return false; | ||
| 583 | } | ||
| 584 | return true; | ||
| 585 | } | ||
| 586 | |||
| 587 | void QS60PixmapData::release() | ||
| 588 | { | ||
| 589 | if (cfbsBitmap) { | ||
| 590 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | ||
| 591 | delete bitmapContext; | ||
| 592 | delete bitmapDevice; | ||
| 593 | delete cfbsBitmap; | ||
| 594 | lock.relock(); | ||
| 595 | } | ||
| 596 | |||
| 597 | delete pengine; | ||
| 598 | image = QImage(); | ||
| 599 | cfbsBitmap = 0; | ||
| 600 | bitmapContext = 0; | ||
| 601 | bitmapDevice = 0; | ||
| 602 | pengine = 0; | ||
| 603 | bytes = 0; | ||
| 604 | } | ||
| 605 | |||
| 606 | /*! | ||
| 607 | * Takes ownership of bitmap | ||
| 608 | */ | ||
| 609 | void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap) | ||
| 610 | { | ||
| 611 | cfbsBitmap = bitmap; | ||
| 612 | |||
| 613 | if(!initSymbianBitmapContext()) { | ||
| 614 | qWarning("Could not create CBitmapContext"); | ||
| 615 | release(); | ||
| 616 | return; | ||
| 617 | } | ||
| 618 | |||
| 619 | setSerialNumber(cfbsBitmap->Handle()); | ||
| 620 | |||
| 621 | UPDATE_BUFFER(); | ||
| 622 | |||
| 623 | // Create default palette if needed | ||
| 624 | if (cfbsBitmap->DisplayMode() == EGray2) { | ||
| 625 | image.setNumColors(2); | ||
| 626 | image.setColor(0, QColor(Qt::color0).rgba()); | ||
| 627 | image.setColor(1, QColor(Qt::color1).rgba()); | ||
| 628 | |||
| 629 | //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid | ||
| 630 | //So invert mono bitmaps so that masks work correctly. | ||
| 631 | image.invertPixels(); | ||
| 632 | } else if (cfbsBitmap->DisplayMode() == EGray256) { | ||
| 633 | for (int i=0; i < 256; ++i) | ||
| 634 | image.setColor(i, qRgb(i, i, i)); | ||
| 635 | }else if (cfbsBitmap->DisplayMode() == EColor256) { | ||
| 636 | const TColor256Util *palette = TColor256Util::Default(); | ||
| 637 | for (int i=0; i < 256; ++i) | ||
| 638 | image.setColor(i, (QRgb)(palette->Color256(i).Value())); | ||
| 639 | } | ||
| 640 | } | ||
| 641 | |||
| 642 | void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags) | ||
| 643 | { | ||
| 644 | QImage sourceImage; | ||
| 645 | |||
| 646 | if (pixelType() == BitmapType) { | ||
| 647 | sourceImage = img.convertToFormat(QImage::Format_MonoLSB); | ||
| 648 | } else { | ||
| 649 | if (img.depth() == 1) { | ||
| 650 | image = img.hasAlphaChannel() | ||
| 651 | ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) | ||
| 652 | : img.convertToFormat(QImage::Format_RGB32); | ||
| 653 | } else { | ||
| 654 | |||
| 655 | QImage::Format opaqueFormat = QNativeImage::systemFormat(); | ||
| 656 | QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; | ||
| 657 | |||
| 658 | if (!img.hasAlphaChannel() | ||
| 659 | || ((flags & Qt::NoOpaqueDetection) == 0 | ||
| 660 | && !const_cast<QImage &>(img).data_ptr()->checkForAlphaPixels())) { | ||
| 661 | sourceImage = img.convertToFormat(opaqueFormat); | ||
| 662 | } else { | ||
| 663 | sourceImage = img.convertToFormat(alphaFormat); | ||
| 664 | } | ||
| 665 | } | ||
| 666 | } | ||
| 667 | |||
| 668 | |||
| 669 | QImage::Format destFormat = sourceImage.format(); | ||
| 318 | 670 | TDisplayMode mode; | |
| 319 | const QImage img = toImage(); | ||
| 320 | QImage::Format destFormat = img.format(); | ||
| 321 | switch (img.format()) { | ||
| 322 | case QImage::Format_Mono: | ||
| 323 | destFormat = QImage::Format_MonoLSB; | ||
| 324 | // Fall through intended | ||
| 671 | switch (destFormat) { | ||
| 325 | 672 | case QImage::Format_MonoLSB: | |
| 326 | 673 | mode = EGray2; | |
| 327 | 674 | break; | |
| 328 | case QImage::Format_Indexed8: | ||
| 329 | if (img.isGrayscale()) | ||
| 330 | mode = EGray256; | ||
| 331 | else | ||
| 332 | mode = EColor256; | ||
| 333 | break; | ||
| 334 | 675 | case QImage::Format_RGB32: | |
| 335 | 676 | mode = EColor16MU; | |
| 336 | 677 | break; | |
| 337 | case QImage::Format_ARGB6666_Premultiplied: | ||
| 338 | case QImage::Format_ARGB8565_Premultiplied: | ||
| 339 | case QImage::Format_ARGB8555_Premultiplied: | ||
| 340 | destFormat = QImage::Format_ARGB32_Premultiplied; | ||
| 341 | // Fall through intended | ||
| 342 | 678 | case QImage::Format_ARGB32_Premultiplied: | |
| 343 | 679 | #if !defined(__SERIES60_31__) && !defined(__S60_32__) | |
| 344 | // ### TODO: Add runtime detection as well? | ||
| 345 | 680 | mode = EColor16MAP; | |
| 346 | break; | ||
| 681 | break; | ||
| 347 | 682 | #endif | |
| 348 | 683 | destFormat = QImage::Format_ARGB32; | |
| 349 | 684 | // Fall through intended | |
| 350 | 685 | case QImage::Format_ARGB32: | |
| 351 | 686 | mode = EColor16MA; | |
| 352 | 687 | break; | |
| 353 | case QImage::Format_RGB555: | ||
| 354 | destFormat = QImage::Format_RGB16; | ||
| 355 | // Fall through intended | ||
| 356 | case QImage::Format_RGB16: | ||
| 357 | mode = EColor64K; | ||
| 358 | break; | ||
| 359 | case QImage::Format_RGB666: | ||
| 360 | destFormat = QImage::Format_RGB888; | ||
| 361 | // Fall through intended | ||
| 362 | case QImage::Format_RGB888: | ||
| 363 | mode = EColor16M; | ||
| 364 | break; | ||
| 365 | case QImage::Format_RGB444: | ||
| 366 | mode = EColor4K; | ||
| 367 | break; | ||
| 368 | 688 | case QImage::Format_Invalid: | |
| 369 | return 0; | ||
| 689 | return; | ||
| 370 | 690 | default: | |
| 371 | qWarning("Image format not supported: %d", img.format()); | ||
| 372 | return 0; | ||
| 691 | qWarning("Image format not supported: %d", image.format()); | ||
| 692 | return; | ||
| 373 | 693 | } | |
| 694 | |||
| 695 | cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode); | ||
| 696 | if (!(cfbsBitmap && initSymbianBitmapContext())) { | ||
| 697 | qWarning("Could not create CFbsBitmap and/or CBitmapContext"); | ||
| 698 | release(); | ||
| 699 | return; | ||
| 700 | } | ||
| 701 | |||
| 702 | setSerialNumber(cfbsBitmap->Handle()); | ||
| 703 | |||
| 704 | const uchar *sptr = const_cast<const QImage &>(sourceImage).bits(); | ||
| 705 | symbianBitmapDataAccess->beginDataAccess(cfbsBitmap); | ||
| 706 | uchar *dptr = (uchar*)cfbsBitmap->DataAddress(); | ||
| 707 | Mem::Copy(dptr, sptr, sourceImage.numBytes()); | ||
| 708 | symbianBitmapDataAccess->endDataAccess(cfbsBitmap); | ||
| 709 | |||
| 710 | UPDATE_BUFFER(); | ||
| 711 | |||
| 712 | if (destFormat == QImage::Format_MonoLSB) { | ||
| 713 | image.setNumColors(2); | ||
| 714 | image.setColor(0, QColor(Qt::color0).rgba()); | ||
| 715 | image.setColor(1, QColor(Qt::color1).rgba()); | ||
| 716 | } else { | ||
| 717 | image.setColorTable(sourceImage.colorTable()); | ||
| 718 | } | ||
| 719 | } | ||
| 374 | 720 | ||
| 375 | CFbsBitmap* bitmap = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new | ||
| 376 | TSize size(width(), height()); | ||
| 377 | if (bitmap->Create(size, mode) != KErrNone) { | ||
| 378 | CBase::Delete(bitmap); | ||
| 379 | return 0; | ||
| 721 | void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect) | ||
| 722 | { | ||
| 723 | if (data->pixelType() == BitmapType) { | ||
| 724 | QBitmap::fromImage(data->toImage().copy(rect)); | ||
| 725 | return; | ||
| 380 | 726 | } | |
| 727 | |||
| 728 | const QS60PixmapData *s60Data = static_cast<const QS60PixmapData*>(data); | ||
| 729 | |||
| 730 | resize(rect.width(), rect.height()); | ||
| 731 | cfbsBitmap->SetDisplayMode(s60Data->cfbsBitmap->DisplayMode()); | ||
| 732 | |||
| 733 | bitmapContext->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect)); | ||
| 734 | } | ||
| 381 | 735 | ||
| 382 | QImage converted = img.convertToFormat(destFormat); | ||
| 383 | |||
| 384 | //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid | ||
| 385 | //So invert mono bitmaps so that masks work correctly. | ||
| 386 | if (mode == EGray2) | ||
| 387 | converted.invertPixels(); | ||
| 388 | |||
| 389 | bitmap->LockHeap(); | ||
| 390 | const uchar *sptr = converted.bits(); | ||
| 391 | uchar *dptr = (uchar*)bitmap->DataAddress(); | ||
| 392 | Mem::Copy(dptr, sptr, converted.numBytes()); | ||
| 393 | bitmap->UnlockHeap(); | ||
| 394 | return bitmap; | ||
| 736 | bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect) | ||
| 737 | { | ||
| 738 | bitmapContext->CopyRect(TPoint(dx, dy), qt_QRect2TRect(rect)); | ||
| 739 | return true; | ||
| 395 | 740 | } | |
| 396 | 741 | ||
| 397 | /*! | ||
| 398 | \since 4.6 | ||
| 742 | int QS60PixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const | ||
| 743 | { | ||
| 744 | if (!cfbsBitmap) | ||
| 745 | return 0; | ||
| 399 | 746 | ||
| 400 | Returns a QPixmap that is equivalent to the \c CFbsBitmap \a bitmap | ||
| 401 | by copying the data. If the CFbsBitmap is not valid or is compressed | ||
| 402 | in memory, this function will return a null QPixmap. | ||
| 747 | switch (metric) { | ||
| 748 | case QPaintDevice::PdmWidth: | ||
| 749 | return cfbsBitmap->SizeInPixels().iWidth; | ||
| 750 | case QPaintDevice::PdmHeight: | ||
| 751 | return cfbsBitmap->SizeInPixels().iHeight; | ||
| 752 | case QPaintDevice::PdmWidthMM: { | ||
| 753 | TInt twips = cfbsBitmap->SizeInTwips().iWidth; | ||
| 754 | return (int)(twips * (25.4/KTwipsPerInch)); | ||
| 755 | } | ||
| 756 | case QPaintDevice::PdmHeightMM: { | ||
| 757 | TInt twips = cfbsBitmap->SizeInTwips().iHeight; | ||
| 758 | return (int)(twips * (25.4/KTwipsPerInch)); | ||
| 759 | } | ||
| 760 | case QPaintDevice::PdmNumColors: | ||
| 761 | return TDisplayModeUtils::NumDisplayModeColors(cfbsBitmap->DisplayMode()); | ||
| 762 | case QPaintDevice::PdmDpiX: | ||
| 763 | case QPaintDevice::PdmPhysicalDpiX: { | ||
| 764 | TReal inches = cfbsBitmap->SizeInTwips().iWidth / (TReal)KTwipsPerInch; | ||
| 765 | TInt pixels = cfbsBitmap->SizeInPixels().iWidth; | ||
| 766 | return pixels / inches; | ||
| 767 | } | ||
| 768 | case QPaintDevice::PdmDpiY: | ||
| 769 | case QPaintDevice::PdmPhysicalDpiY: { | ||
| 770 | TReal inches = cfbsBitmap->SizeInTwips().iHeight / (TReal)KTwipsPerInch; | ||
| 771 | TInt pixels = cfbsBitmap->SizeInPixels().iHeight; | ||
| 772 | return pixels / inches; | ||
| 773 | } | ||
| 774 | case QPaintDevice::PdmDepth: | ||
| 775 | return TDisplayModeUtils::NumDisplayModeBitsPerPixel(cfbsBitmap->DisplayMode()); | ||
| 776 | default: | ||
| 777 | qWarning("QPixmap::metric: Invalid metric command"); | ||
| 778 | } | ||
| 779 | return 0; | ||
| 403 | 780 | ||
| 404 | \warning This function is only available on Symbian OS. | ||
| 781 | } | ||
| 405 | 782 | ||
| 406 | \sa toSymbianCFbsBitmap(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} | ||
| 407 | */ | ||
| 783 | void QS60PixmapData::fill(const QColor &color) | ||
| 784 | { | ||
| 785 | if (color.alpha() != 255) { | ||
| 786 | QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied); | ||
| 787 | im.fill(PREMUL(color.rgba())); | ||
| 788 | release(); | ||
| 789 | fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither); | ||
| 790 | } else { | ||
| 791 | beginDataAccess(); | ||
| 792 | QRasterPixmapData::fill(color); | ||
| 793 | endDataAccess(); | ||
| 794 | } | ||
| 795 | } | ||
| 408 | 796 | ||
| 409 | QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap) | ||
| 797 | void QS60PixmapData::setMask(const QBitmap &mask) | ||
| 410 | 798 | { | |
| 411 | if (!bitmap) | ||
| 412 | return QPixmap(); | ||
| 799 | if (mask.size().isEmpty()) { | ||
| 800 | if (image.depth() != 1) { | ||
| 801 | QImage newImage = image.convertToFormat(QImage::Format_RGB32); | ||
| 802 | release(); | ||
| 803 | fromImage(newImage, Qt::AutoColor | Qt::OrderedAlphaDither); | ||
| 804 | } | ||
| 805 | } else if (image.depth() == 1) { | ||
| 806 | beginDataAccess(); | ||
| 807 | QRasterPixmapData::setMask(mask); | ||
| 808 | endDataAccess(); | ||
| 809 | } else { | ||
| 810 | const int w = image.width(); | ||
| 811 | const int h = image.height(); | ||
| 812 | |||
| 813 | const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); | ||
| 814 | QImage newImage = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); | ||
| 815 | for (int y = 0; y < h; ++y) { | ||
| 816 | const uchar *mscan = imageMask.scanLine(y); | ||
| 817 | QRgb *tscan = (QRgb *)newImage.scanLine(y); | ||
| 818 | for (int x = 0; x < w; ++x) { | ||
| 819 | if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7])) | ||
| 820 | tscan[x] = 0; | ||
| 821 | } | ||
| 822 | } | ||
| 823 | release(); | ||
| 824 | fromImage(newImage, Qt::AutoColor | Qt::OrderedAlphaDither); | ||
| 825 | } | ||
| 826 | } | ||
| 413 | 827 | ||
| 414 | int width = bitmap->SizeInPixels().iWidth; | ||
| 415 | int height = bitmap->SizeInPixels().iHeight; | ||
| 828 | void QS60PixmapData::setAlphaChannel(const QPixmap &alphaChannel) | ||
| 829 | { | ||
| 830 | QImage img(toImage()); | ||
| 831 | img.setAlphaChannel(alphaChannel.toImage()); | ||
| 832 | release(); | ||
| 833 | fromImage(img, Qt::OrderedDither | Qt::OrderedAlphaDither); | ||
| 834 | } | ||
| 416 | 835 | ||
| 417 | if (width <= 0 || height <= 0 || bitmap->IsCompressedInRAM()) | ||
| 418 | return QPixmap(); | ||
| 836 | QImage QS60PixmapData::toImage() const | ||
| 837 | { | ||
| 838 | return image; | ||
| 839 | } | ||
| 419 | 840 | ||
| 420 | TDisplayMode displayMode = bitmap->DisplayMode(); | ||
| 421 | QImage::Format format = qt_TDisplayMode2Format(displayMode); | ||
| 422 | int bytesPerLine = CFbsBitmap::ScanLineLength(width, displayMode); | ||
| 423 | bitmap->LockHeap(); | ||
| 424 | QImage image = QImage((const uchar*)bitmap->DataAddress(), width, height, bytesPerLine, format); | ||
| 425 | if (displayMode == EGray2) { | ||
| 426 | image.setNumColors(2); | ||
| 427 | image.setColor(0, QColor(Qt::color0).rgba()); | ||
| 428 | image.setColor(1, QColor(Qt::color1).rgba()); | ||
| 429 | //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid | ||
| 430 | //So invert mono bitmaps so that masks work correctly. | ||
| 431 | image.invertPixels(); | ||
| 432 | } else if (displayMode == EGray256) { | ||
| 433 | for (int i=0; i < 256; ++i) | ||
| 434 | image.setColor(i, qRgb(i, i, i)); | ||
| 435 | }else if (displayMode == EColor256) { | ||
| 436 | const TColor256Util *palette = TColor256Util::Default(); | ||
| 437 | for (int i=0; i < 256; ++i) | ||
| 438 | image.setColor(i, (QRgb)(palette->Color256(i).Value())); | ||
| 841 | QPaintEngine* QS60PixmapData::paintEngine() const | ||
| 842 | { | ||
| 843 | if (!pengine) { | ||
| 844 | QS60PixmapData *that = const_cast<QS60PixmapData*>(this); | ||
| 845 | that->pengine = new QS60PaintEngine(&that->image, that); | ||
| 439 | 846 | } | |
| 440 | QPixmap pixmap = QPixmap::fromImage(image.copy()); | ||
| 441 | bitmap->UnlockHeap(); | ||
| 442 | return pixmap; | ||
| 847 | return pengine; | ||
| 443 | 848 | } | |
| 849 | |||
| 850 | void QS60PixmapData::beginDataAccess() | ||
| 851 | { | ||
| 852 | if(!cfbsBitmap) | ||
| 853 | return; | ||
| 854 | |||
| 855 | symbianBitmapDataAccess->beginDataAccess(cfbsBitmap); | ||
| 856 | |||
| 857 | uchar* newBytes = (uchar*)cfbsBitmap->DataAddress(); | ||
| 858 | |||
| 859 | if (newBytes == bytes) | ||
| 860 | return; | ||
| 861 | |||
| 862 | |||
| 863 | bytes = newBytes; | ||
| 864 | TDisplayMode mode = cfbsBitmap->DisplayMode(); | ||
| 865 | QImage::Format format = qt_TDisplayMode2Format(mode); | ||
| 866 | TSize size = cfbsBitmap->SizeInPixels(); | ||
| 867 | |||
| 868 | QVector<QRgb> savedColorTable; | ||
| 869 | if (!image.isNull()) | ||
| 870 | savedColorTable = image.colorTable(); | ||
| 871 | |||
| 872 | image = QImage(bytes, size.iWidth, size.iHeight, format); | ||
| 873 | |||
| 874 | // Restore the palette or create a default | ||
| 875 | if (!savedColorTable.isEmpty()) { | ||
| 876 | image.setColorTable(savedColorTable); | ||
| 877 | } | ||
| 878 | |||
| 879 | w = size.iWidth; | ||
| 880 | h = size.iHeight; | ||
| 881 | d = image.depth(); | ||
| 882 | is_null = (w <= 0 || h <= 0); | ||
| 883 | |||
| 884 | if (pengine) { | ||
| 885 | QS60PaintEngine *engine = static_cast<QS60PaintEngine *>(pengine); | ||
| 886 | engine->prepare(&image); | ||
| 887 | } | ||
| 888 | } | ||
| 889 | |||
| 890 | void QS60PixmapData::endDataAccess(bool readOnly) const | ||
| 891 | { | ||
| 892 | if(!cfbsBitmap) | ||
| 893 | return; | ||
| 894 | |||
| 895 | symbianBitmapDataAccess->endDataAccess(cfbsBitmap); | ||
| 896 | } | ||
| 897 | |||
| 444 | 898 | ||
| 445 | 899 | QT_END_NAMESPACE |
src/gui/image/qpixmap_s60_p.h
(96 / 0)
|   | |||
| 1 | /**************************************************************************** | ||
| 2 | ** | ||
| 3 | ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). | ||
| 4 | ** Contact: Qt Software Information (qt-info@nokia.com) | ||
| 5 | ** | ||
| 6 | ** This file is part of the $MODULE$ of the Qt Toolkit. | ||
| 7 | ** | ||
| 8 | ** $TROLLTECH_DUAL_LICENSE$ | ||
| 9 | ** | ||
| 10 | ****************************************************************************/ | ||
| 11 | |||
| 12 | #ifndef QPIXMAPDATA_S60_P_H | ||
| 13 | #define QPIXMAPDATA_S60_P_H | ||
| 14 | |||
| 15 | // | ||
| 16 | // W A R N I N G | ||
| 17 | // ------------- | ||
| 18 | // | ||
| 19 | // This file is not part of the Qt API. It exists purely as an | ||
| 20 | // implementation detail. This header file may change from version to | ||
| 21 | // version without notice, or even be removed. | ||
| 22 | // | ||
| 23 | // We mean it. | ||
| 24 | // | ||
| 25 | |||
| 26 | #include <QtGui/private/qpixmap_raster_p.h> | ||
| 27 | |||
| 28 | QT_BEGIN_NAMESPACE | ||
| 29 | |||
| 30 | class CFbsBitmap; | ||
| 31 | class CFbsBitmapDevice; | ||
| 32 | class CBitmapContext; | ||
| 33 | |||
| 34 | class QSymbianBitmapDataAccess; | ||
| 35 | |||
| 36 | class QSymbianFbsHeapLock | ||
| 37 | { | ||
| 38 | public: | ||
| 39 | |||
| 40 | enum LockAction { | ||
| 41 | Unlock | ||
| 42 | }; | ||
| 43 | |||
| 44 | explicit QSymbianFbsHeapLock(LockAction a); | ||
| 45 | ~QSymbianFbsHeapLock(); | ||
| 46 | void relock(); | ||
| 47 | |||
| 48 | private: | ||
| 49 | |||
| 50 | LockAction action; | ||
| 51 | bool wasLocked; | ||
| 52 | }; | ||
| 53 | |||
| 54 | class QS60PixmapData : public QRasterPixmapData | ||
| 55 | { | ||
| 56 | public: | ||
| 57 | QS60PixmapData(PixelType type); | ||
| 58 | ~QS60PixmapData(); | ||
| 59 | |||
| 60 | void resize(int width, int height); | ||
| 61 | void fromImage(const QImage &image, Qt::ImageConversionFlags flags); | ||
| 62 | void copy(const QPixmapData *data, const QRect &rect); | ||
| 63 | bool scroll(int dx, int dy, const QRect &rect); | ||
| 64 | |||
| 65 | int metric(QPaintDevice::PaintDeviceMetric metric) const; | ||
| 66 | void fill(const QColor &color); | ||
| 67 | void setMask(const QBitmap &mask); | ||
| 68 | void setAlphaChannel(const QPixmap &alphaChannel); | ||
| 69 | QImage toImage() const; | ||
| 70 | QPaintEngine* paintEngine() const; | ||
| 71 | |||
| 72 | void beginDataAccess(); | ||
| 73 | void endDataAccess(bool readOnly=false) const; | ||
| 74 | |||
| 75 | private: | ||
| 76 | void release(); | ||
| 77 | void fromSymbianBitmap(CFbsBitmap* bitmap); | ||
| 78 | bool initSymbianBitmapContext(); | ||
| 79 | |||
| 80 | QSymbianBitmapDataAccess *symbianBitmapDataAccess; | ||
| 81 | |||
| 82 | CFbsBitmap *cfbsBitmap; | ||
| 83 | CFbsBitmapDevice *bitmapDevice; | ||
| 84 | CBitmapContext *bitmapContext; | ||
| 85 | QPaintEngine *pengine; | ||
| 86 | uchar* bytes; | ||
| 87 | |||
| 88 | friend class QPixmap; | ||
| 89 | friend class QS60WindowSurface; | ||
| 90 | friend class QS60PaintEngine; | ||
| 91 | friend class QS60Data; | ||
| 92 | }; | ||
| 93 | |||
| 94 | QT_END_NAMESPACE | ||
| 95 | |||
| 96 | #endif // QPIXMAPDATA_S60_P_H |
|   | |||
| 47 | 47 | #ifdef Q_WS_X11 | |
| 48 | 48 | # include <private/qpixmap_x11_p.h> | |
| 49 | 49 | #endif | |
| 50 | #if defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) | ||
| 50 | #if defined(Q_WS_WIN) | ||
| 51 | 51 | # include <private/qpixmap_raster_p.h> | |
| 52 | 52 | #endif | |
| 53 | 53 | #ifdef Q_WS_MAC | |
| 54 | 54 | # include <private/qpixmap_mac_p.h> | |
| 55 | 55 | #endif | |
| 56 | #ifdef Q_WS_S60 | ||
| 57 | # include <private/qpixmap_s60_p.h> | ||
| 58 | #endif | ||
| 56 | 59 | ||
| 57 | 60 | #include "private/qapplication_p.h" | |
| 58 | 61 | #include "private/qgraphicssystem_p.h" | |
| … | … | ||
| 78 | 78 | ||
| 79 | 79 | #if defined(Q_WS_X11) | |
| 80 | 80 | return new QX11PixmapData(type); | |
| 81 | #elif defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) | ||
| 81 | #elif defined(Q_WS_WIN) | ||
| 82 | 82 | return new QRasterPixmapData(type); | |
| 83 | 83 | #elif defined(Q_WS_MAC) | |
| 84 | 84 | return new QMacPixmapData(type); | |
| 85 | #elif defined(Q_WS_S60) | ||
| 86 | return new QS60PixmapData(type); | ||
| 85 | 87 | #else | |
| 86 | 88 | #error QSimplePixmapDataFactory::create() not implemented | |
| 87 | 89 | #endif |
src/gui/kernel/qt_s60_p.h
(2 / 2)
|   | |||
| 108 | 108 | bool virtualMouseRequired; | |
| 109 | 109 | int qtOwnsS60Environment : 1; | |
| 110 | 110 | static inline void updateScreenSize(); | |
| 111 | static inline RWsSession& wsSession(); | ||
| 111 | static inline RWsSession& wsSession(); | ||
| 112 | 112 | static inline RWindowGroup& windowGroup(); | |
| 113 | 113 | static inline CWsScreenDevice* screenDevice(); | |
| 114 | 114 | static inline CCoeAppUi* appUi(); | |
| … | … | ||
| 284 | 284 | format = QImage::Format_RGB16; | |
| 285 | 285 | break; | |
| 286 | 286 | case EColor16M: | |
| 287 | format = QImage::Format_RGB666; | ||
| 287 | format = QImage::Format_RGB888; | ||
| 288 | 288 | break; | |
| 289 | 289 | case EColor16MU: | |
| 290 | 290 | format = QImage::Format_RGB32; |
|   | |||
| 14 | 14 | painting/qoutlinemapper_p.h \ | |
| 15 | 15 | painting/qpaintdevice.h \ | |
| 16 | 16 | painting/qpaintengine.h \ | |
| 17 | painting/qpaintengine_p.h \ | ||
| 17 | painting/qpaintengine_p.h \ | ||
| 18 | 18 | painting/qpaintengine_alpha_p.h \ | |
| 19 | 19 | painting/qpaintengine_preview_p.h \ | |
| 20 | 20 | painting/qpaintengineex_p.h \ | |
| … | … | ||
| 179 | 179 | ||
| 180 | 180 | symbian { | |
| 181 | 181 | SOURCES += \ | |
| 182 | painting/qpaintengine_s60.cpp \ | ||
| 182 | 183 | painting/qregion_s60.cpp \ | |
| 183 | 184 | painting/qcolormap_s60.cpp | |
| 185 | |||
| 186 | HEADERS += \ | ||
| 187 | painting/qpaintengine_s60_p.h | ||
| 184 | 188 | } | |
| 185 | 189 | ||
| 186 | 190 | x11|embedded { |
|   | |||
| 44 | 44 | #ifdef Q_WS_X11 | |
| 45 | 45 | # include <private/qpixmap_x11_p.h> | |
| 46 | 46 | #endif | |
| 47 | #if defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) | ||
| 47 | #if defined(Q_WS_WIN) | ||
| 48 | 48 | # include <private/qpixmap_raster_p.h> | |
| 49 | 49 | #endif | |
| 50 | 50 | #ifdef Q_WS_MAC | |
| 51 | 51 | # include <private/qpixmap_mac_p.h> | |
| 52 | 52 | #endif | |
| 53 | #ifdef Q_WS_S60 | ||
| 54 | # include <private/qpixmap_s60_p.h> | ||
| 55 | #endif | ||
| 53 | 56 | ||
| 54 | 57 | QT_BEGIN_NAMESPACE | |
| 55 | 58 | ||
| … | … | ||
| 67 | 67 | #endif | |
| 68 | 68 | #if defined(Q_WS_X11) | |
| 69 | 69 | return new QX11PixmapData(type); | |
| 70 | #elif defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) | ||
| 70 | #elif defined(Q_WS_WIN) | ||
| 71 | 71 | return new QRasterPixmapData(type); | |
| 72 | 72 | #elif defined(Q_WS_MAC) | |
| 73 | 73 | return new QMacPixmapData(type); | |
| 74 | #elif defined(Q_WS_S60) | ||
| 75 | return new QS60PixmapData(type); | ||
| 74 | 76 | #elif !defined(Q_WS_QWS) | |
| 75 | 77 | #error QGraphicsSystem::createDefaultPixmapData() not implemented | |
| 76 | 78 | #endif |
|   | |||
| 1 | /**************************************************************************** | ||
| 2 | ** | ||
| 3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). | ||
| 4 | ** Contact: Qt Software Information (qt-info@nokia.com) | ||
| 5 | ** | ||
| 6 | ** This file is part of the $MODULE$ of the Qt Toolkit. | ||
| 7 | ** | ||
| 8 | ** $TROLLTECH_DUAL_LICENSE$ | ||
| 9 | ** | ||
| 10 | ****************************************************************************/ | ||
| 11 | |||
| 12 | #include <private/qpaintengine_s60_p.h> | ||
| 13 | #include <private/qpixmap_s60_p.h> | ||
| 14 | #include <private/qt_s60_p.h> | ||
| 15 | |||
| 16 | QT_BEGIN_NAMESPACE | ||
| 17 | |||
| 18 | class QS60PaintEnginePrivate : public QRasterPaintEnginePrivate | ||
| 19 | { | ||
| 20 | public: | ||
| 21 | QS60PaintEnginePrivate(QS60PaintEngine *engine) { } | ||
| 22 | }; | ||
| 23 | |||
| 24 | QS60PaintEngine::QS60PaintEngine(QPaintDevice *device, QS60PixmapData *data) | ||
| 25 | : QRasterPaintEngine(*(new QS60PaintEnginePrivate(this)), device), pixmapData(data) | ||
| 26 | { | ||
| 27 | } | ||
| 28 | |||
| 29 | bool QS60PaintEngine::begin(QPaintDevice *device) | ||
| 30 | { | ||
| 31 | pixmapData->beginDataAccess(); | ||
| 32 | return QRasterPaintEngine::begin(device); | ||
| 33 | } | ||
| 34 | |||
| 35 | bool QS60PaintEngine::end() | ||
| 36 | { | ||
| 37 | bool ret = QRasterPaintEngine::end(); | ||
| 38 | pixmapData->endDataAccess(); | ||
| 39 | return ret; | ||
| 40 | } | ||
| 41 | |||
| 42 | void QS60PaintEngine::drawPixmap(const QPointF &p, const QPixmap &pm) | ||
| 43 | { | ||
| 44 | QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); | ||
| 45 | srcData->beginDataAccess(); | ||
| 46 | QRasterPaintEngine::drawPixmap(p, pm); | ||
| 47 | srcData->endDataAccess(); | ||
| 48 | } | ||
| 49 | |||
| 50 | void QS60PaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) | ||
| 51 | { | ||
| 52 | QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); | ||
| 53 | srcData->beginDataAccess(); | ||
| 54 | QRasterPaintEngine::drawPixmap(r, pm, sr); | ||
| 55 | srcData->endDataAccess(); | ||
| 56 | } | ||
| 57 | |||
| 58 | void QS60PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr) | ||
| 59 | { | ||
| 60 | QS60PixmapData *srcData = static_cast<QS60PixmapData *>(pm.pixmapData()); | ||
| 61 | srcData->beginDataAccess(); | ||
| 62 | QRasterPaintEngine::drawTiledPixmap(r, pm, sr); | ||
| 63 | srcData->endDataAccess(); | ||
| 64 | } | ||
| 65 | |||
| 66 | void QS60PaintEngine::prepare(QImage *image) | ||
| 67 | { | ||
| 68 | QRasterBuffer *buffer = d_func()->rasterBuffer.data(); | ||
| 69 | if (buffer) | ||
| 70 | buffer->prepare(image); | ||
| 71 | } | ||
| 72 | |||
| 73 | QT_END_NAMESPACE |
|   | |||
| 1 | /**************************************************************************** | ||
| 2 | ** | ||
| 3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). | ||
| 4 | ** Contact: Qt Software Information (qt-info@nokia.com) | ||
| 5 | ** | ||
| 6 | ** This file is part of the $MODULE$ of the Qt Toolkit. | ||
| 7 | ** | ||
| 8 | ** $TROLLTECH_DUAL_LICENSE$ | ||
| 9 | ** | ||
| 10 | ****************************************************************************/ | ||
| 11 | |||
| 12 | #ifndef QPAINTENGINE_S60_P_H | ||
| 13 | #define QPAINTENGINE_S60_P_H | ||
| 14 | |||
| 15 | // | ||
| 16 | // W A R N I N G | ||
| 17 | // ------------- | ||
| 18 | // | ||
| 19 | // This file is not part of the Qt API. It exists for the convenience | ||
| 20 | // of other Qt classes. This header file may change from version to | ||
| 21 | // version without notice, or even be removed. | ||
| 22 | // | ||
| 23 | // We mean it. | ||
| 24 | // | ||
| 25 | |||
| 26 | #include "private/qpaintengine_raster_p.h" | ||
| 27 | |||
| 28 | QT_BEGIN_NAMESPACE | ||
| 29 | |||
| 30 | class QS60PaintEnginePrivate; | ||
| 31 | class QS60PixmapData; | ||
| 32 | |||
| 33 | class QS60PaintEngine : public QRasterPaintEngine | ||
| 34 | { | ||
| 35 | Q_DECLARE_PRIVATE(QS60PaintEngine) | ||
| 36 | |||
| 37 | public: | ||
| 38 | QS60PaintEngine(QPaintDevice *device, QS60PixmapData* data); | ||
| 39 | bool begin(QPaintDevice *device); | ||
| 40 | bool end(); | ||
| 41 | |||
| 42 | void drawPixmap(const QPointF &p, const QPixmap &pm); | ||
| 43 | void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); | ||
| 44 | void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr); | ||
| 45 | |||
| 46 | void prepare(QImage* image); | ||
| 47 | |||
| 48 | private: | ||
| 49 | QS60PixmapData *pixmapData; | ||
| 50 | }; | ||
| 51 | |||
| 52 | QT_END_NAMESPACE | ||
| 53 | |||
| 54 | #endif // QPAINTENGINE_S60_P_H |
src/gui/painting/qwindowsurface_s60.cpp
(54 / 103)
|   | |||
| 44 | 44 | #include <QtGui/qpaintdevice.h> | |
| 45 | 45 | #include <private/qwidget_p.h> | |
| 46 | 46 | #include "qwindowsurface_s60_p.h" | |
| 47 | #include "qpixmap_s60_p.h" | ||
| 47 | 48 | #include "qt_s60_p.h" | |
| 48 | 49 | #include "private/qdrawhelper_p.h" | |
| 49 | 50 | ||
| … | … | ||
| 52 | 52 | ||
| 53 | 53 | struct QS60WindowSurfacePrivate | |
| 54 | 54 | { | |
| 55 | QImage device; | ||
| 56 | CFbsBitmap *bitmap; | ||
| 57 | uchar* bytes; | ||
| 58 | |||
| 59 | // Since only one CFbsBitmap is allowed to be locked at a time, this is static. | ||
| 60 | static QS60WindowSurface* lockedSurface; | ||
| 55 | QPixmap device; | ||
| 56 | QList<QImage*> bufferImages; | ||
| 61 | 57 | }; | |
| 62 | QS60WindowSurface* QS60WindowSurfacePrivate::lockedSurface = NULL; | ||
| 63 | 58 | ||
| 64 | 59 | QS60WindowSurface::QS60WindowSurface(QWidget* widget) | |
| 65 | 60 | : QWindowSurface(widget), d_ptr(new QS60WindowSurfacePrivate) | |
| 66 | 61 | { | |
| 67 | d_ptr->bytes = 0; | ||
| 68 | d_ptr->bitmap = 0; | ||
| 69 | 62 | ||
| 70 | 63 | TDisplayMode mode = S60->screenDevice()->DisplayMode(); | |
| 71 | 64 | bool isOpaque = qt_widget_private(widget)->isOpaque; | |
| … | … | ||
| 67 | 67 | else if (mode == EColor16MU && !isOpaque) | |
| 68 | 68 | mode = EColor16MA; // Try for transparency anyway | |
| 69 | 69 | ||
| 70 | |||
| 71 | 70 | // We create empty CFbsBitmap here -> it will be resized in setGeometry | |
| 72 | d_ptr->bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new | ||
| 73 | qt_symbian_throwIfError( d_ptr->bitmap->Create(TSize(0, 0), mode ) ); | ||
| 74 | |||
| 75 | updatePaintDeviceOnBitmap(); | ||
| 76 | |||
| 71 | CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new | ||
| 72 | qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) ); | ||
| 73 | |||
| 74 | QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType); | ||
| 75 | data->fromSymbianBitmap(bitmap); | ||
| 76 | d_ptr->device = QPixmap(data); | ||
| 77 | |||
| 77 | 78 | setStaticContentsSupport(true); | |
| 78 | 79 | } | |
| 79 | |||
| 80 | 80 | QS60WindowSurface::~QS60WindowSurface() | |
| 81 | 81 | { | |
| 82 | if (QS60WindowSurfacePrivate::lockedSurface == this) | ||
| 83 | unlockBitmapHeap(); | ||
| 84 | |||
| 85 | delete d_ptr->bitmap; | ||
| 86 | 82 | delete d_ptr; | |
| 87 | 83 | } | |
| 88 | 84 | ||
| 89 | 85 | void QS60WindowSurface::beginPaint(const QRegion &rgn) | |
| 90 | 86 | { | |
| 91 | if(!d_ptr->bitmap) | ||
| 92 | return; | ||
| 93 | |||
| 94 | if (QS60WindowSurfacePrivate::lockedSurface) | ||
| 95 | unlockBitmapHeap(); | ||
| 96 | |||
| 97 | QS60WindowSurfacePrivate::lockedSurface = this; | ||
| 98 | lockBitmapHeap(); | ||
| 99 | |||
| 100 | 87 | if (!qt_widget_private(window())->isOpaque) { | |
| 101 | QRgb *data = reinterpret_cast<QRgb *>(d_ptr->device.bits()); | ||
| 102 | const int row_stride = d_ptr->device.bytesPerLine() / 4; | ||
| 88 | QImage image = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image; | ||
| 89 | QRgb *data = reinterpret_cast<QRgb *>(image.bits()); | ||
| 90 | const int row_stride = image.bytesPerLine() / 4; | ||
| 103 | 91 | ||
| 104 | 92 | const QVector<QRect> rects = rgn.rects(); | |
| 105 | 93 | for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { | |
| … | … | ||
| 106 | 106 | } | |
| 107 | 107 | } | |
| 108 | 108 | ||
| 109 | void QS60WindowSurface::endPaint(const QRegion &) | ||
| 110 | { | ||
| 111 | qDeleteAll(d_ptr->bufferImages); | ||
| 112 | d_ptr->bufferImages.clear(); | ||
| 113 | } | ||
| 114 | |||
| 115 | QImage* QS60WindowSurface::buffer(const QWidget *widget) | ||
| 116 | { | ||
| 117 | if (widget->window() != window()) | ||
| 118 | return 0; | ||
| 119 | |||
| 120 | QPaintDevice *pdev = paintDevice(); | ||
| 121 | if (!pdev) | ||
| 122 | return 0; | ||
| 123 | |||
| 124 | const QPoint off = offset(widget); | ||
| 125 | QImage *img = &(static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image); | ||
| 126 | |||
| 127 | QRect rect(off, widget->size()); | ||
| 128 | rect &= QRect(QPoint(), img->size()); | ||
| 129 | |||
| 130 | if (rect.isEmpty()) | ||
| 131 | return 0; | ||
| 132 | |||
| 133 | img = new QImage(img->scanLine(rect.y()) + rect.x() * img->depth() / 8, | ||
| 134 | rect.width(), rect.height(), | ||
| 135 | img->bytesPerLine(), img->format()); | ||
| 136 | d_ptr->bufferImages.append(img); | ||
| 137 | |||
| 138 | return img; | ||
| 139 | } | ||
| 140 | |||
| 109 | 141 | void QS60WindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &) | |
| 110 | 142 | { | |
| 111 | 143 | const QVector<QRect> subRects = region.rects(); | |
| … | … | ||
| 157 | 157 | if (d_ptr->device.isNull()) | |
| 158 | 158 | return false; | |
| 159 | 159 | ||
| 160 | CFbsBitmapDevice *bitmapDevice = 0; | ||
| 161 | QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(d_ptr->bitmap)); | ||
| 162 | CBitmapContext *bitmapContext; | ||
| 163 | TInt err = bitmapDevice->CreateBitmapContext(bitmapContext); | ||
| 164 | if (err != KErrNone) { | ||
| 165 | CBase::Delete(bitmapDevice); | ||
| 166 | return false; | ||
| 167 | } | ||
| 168 | bitmapContext->CopyRect(TPoint(dx, dy), qt_QRect2TRect(rect)); | ||
| 169 | CBase::Delete(bitmapContext); | ||
| 170 | CBase::Delete(bitmapDevice); | ||
| 160 | QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); | ||
| 161 | data->scroll(dx, dy, rect); | ||
| 162 | |||
| 171 | 163 | return true; | |
| 172 | 164 | } | |
| 173 | 165 | ||
| 174 | void QS60WindowSurface::endPaint(const QRegion & /* rgn */) | ||
| 175 | { | ||
| 176 | if(!d_ptr->bitmap) | ||
| 177 | return; | ||
| 178 | |||
| 179 | Q_ASSERT(QS60WindowSurfacePrivate::lockedSurface); | ||
| 180 | unlockBitmapHeap(); | ||
| 181 | QS60WindowSurfacePrivate::lockedSurface = NULL; | ||
| 182 | } | ||
| 183 | |||
| 184 | 166 | QPaintDevice* QS60WindowSurface::paintDevice() | |
| 185 | 167 | { | |
| 186 | 168 | return &d_ptr->device; | |
| … | … | ||
| 173 | 173 | if (rect == geometry()) | |
| 174 | 174 | return; | |
| 175 | 175 | ||
| 176 | QWindowSurface::setGeometry(rect); | ||
| 176 | QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); | ||
| 177 | data->resize(rect.width(), rect.height()); | ||
| 177 | 178 | ||
| 178 | TRect nativeRect(qt_QRect2TRect(rect)); | ||
| 179 | qt_symbian_throwIfError(d_ptr->bitmap->Resize(nativeRect.Size())); | ||
| 180 | |||
| 181 | if (!rect.isNull()) | ||
| 182 | updatePaintDeviceOnBitmap(); | ||
| 179 | QWindowSurface::setGeometry(rect); | ||
| 183 | 180 | } | |
| 184 | 181 | ||
| 185 | void QS60WindowSurface::lockBitmapHeap() | ||
| 182 | CFbsBitmap* QS60WindowSurface::symbianBitmap() const | ||
| 186 | 183 | { | |
| 187 | if (!QS60WindowSurfacePrivate::lockedSurface) | ||
| 188 | return; | ||
| 189 | |||
| 190 | // Get some local variables to make later code lines more clear to read | ||
| 191 | CFbsBitmap*& bitmap = QS60WindowSurfacePrivate::lockedSurface->d_ptr->bitmap; | ||
| 192 | QImage& device = QS60WindowSurfacePrivate::lockedSurface->d_ptr->device; | ||
| 193 | uchar*& bytes = QS60WindowSurfacePrivate::lockedSurface->d_ptr->bytes; | ||
| 194 | |||
| 195 | bitmap->LockHeap(); | ||
| 196 | uchar *newBytes = (uchar*)bitmap->DataAddress(); | ||
| 197 | if (newBytes != bytes) { | ||
| 198 | bytes = newBytes; | ||
| 199 | |||
| 200 | // Get some values for QImage creation | ||
| 201 | TDisplayMode mode = bitmap->DisplayMode(); | ||
| 202 | if (mode == EColor16MA | ||
| 203 | && qt_widget_private(QS60WindowSurfacePrivate::lockedSurface->window())->isOpaque) | ||
| 204 | mode = EColor16MU; | ||
| 205 | QImage::Format format = qt_TDisplayMode2Format( mode ); | ||
| 206 | TSize bitmapSize = bitmap->SizeInPixels(); | ||
| 207 | int bytesPerLine = CFbsBitmap::ScanLineLength( bitmapSize.iWidth, mode); | ||
| 208 | |||
| 209 | device = QImage( bytes, bitmapSize.iWidth, bitmapSize.iHeight, bytesPerLine, format ); | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | void QS60WindowSurface::unlockBitmapHeap() | ||
| 214 | { | ||
| 215 | if (!QS60WindowSurfacePrivate::lockedSurface) | ||
| 216 | return; | ||
| 217 | |||
| 218 | QS60WindowSurfacePrivate::lockedSurface->d_ptr->bitmap->UnlockHeap(); | ||
| 219 | } | ||
| 220 | |||
| 221 | void QS60WindowSurface::updatePaintDeviceOnBitmap() | ||
| 222 | { | ||
| 223 | // This forces the actual device to be updated based on CFbsBitmap | ||
| 224 | beginPaint(QRegion()); | ||
| 225 | endPaint(QRegion()); | ||
| 226 | } | ||
| 227 | |||
| 228 | CFbsBitmap *QS60WindowSurface::symbianBitmap() const | ||
| 229 | { | ||
| 230 | return d_ptr->bitmap; | ||
| 184 | QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data()); | ||
| 185 | return data->cfbsBitmap; | ||
| 231 | 186 | } | |
| 232 | 187 | ||
| 233 | 188 | QT_END_NAMESPACE |
|   | |||
| 75 | 75 | void beginPaint(const QRegion &); | |
| 76 | 76 | void endPaint(const QRegion &); | |
| 77 | 77 | ||
| 78 | QImage* buffer(const QWidget *widget); | ||
| 79 | |||
| 78 | 80 | void setGeometry(const QRect &rect); | |
| 79 | 81 | ||
| 80 | static void lockBitmapHeap(); | ||
| 81 | static void unlockBitmapHeap(); | ||
| 82 | |||
| 83 | 82 | CFbsBitmap *symbianBitmap() const; | |
| 84 | |||
| 85 | private: | ||
| 86 | void updatePaintDeviceOnBitmap(); | ||
| 87 | 83 | ||
| 88 | 84 | private: | |
| 89 | 85 | QS60WindowSurfacePrivate* d_ptr; |
|   | |||
| 44 | 44 | #include "qpainter.h" | |
| 45 | 45 | #include "qstyleoption.h" | |
| 46 | 46 | #include "qstyle.h" | |
| 47 | #include "private/qwindowsurface_s60_p.h" | ||
| 48 | 47 | #include "private/qt_s60_p.h" | |
| 48 | #include "private/qpixmap_s60_p.h" | ||
| 49 | 49 | #include "private/qcore_symbian_p.h" | |
| 50 | 50 | #include "qapplication.h" | |
| 51 | 51 | ||
| … | … | ||
| 1136 | 1136 | QPixmap QS60StylePrivate::part(QS60StyleEnums::SkinParts part, | |
| 1137 | 1137 | const QSize &size, SkinElementFlags flags) | |
| 1138 | 1138 | { | |
| 1139 | QS60WindowSurface::unlockBitmapHeap(); | ||
| 1139 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | ||
| 1140 | |||
| 1140 | 1141 | QPixmap result = (flags & SF_ColorSkinned)? | |
| 1141 | 1142 | QS60StyleModeSpecifics::colorSkinnedGraphics(part, size, flags) | |
| 1142 | 1143 | : QS60StyleModeSpecifics::skinnedGraphics(part, size, flags); | |
| 1143 | QS60WindowSurface::lockBitmapHeap(); | ||
| 1144 | |||
| 1145 | lock.relock(); | ||
| 1144 | 1146 | ||
| 1145 | 1147 | if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledPartGraphic(part)) { | |
| 1146 | 1148 | QStyleOption opt; | |
| … | … | ||
| 1160 | 1160 | ||
| 1161 | 1161 | QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, SkinElementFlags flags) | |
| 1162 | 1162 | { | |
| 1163 | QS60WindowSurface::unlockBitmapHeap(); | ||
| 1163 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | ||
| 1164 | 1164 | QPixmap result = QS60StyleModeSpecifics::skinnedGraphics(frame, size, flags); | |
| 1165 | QS60WindowSurface::lockBitmapHeap(); | ||
| 1165 | lock.relock(); | ||
| 1166 | 1166 | ||
| 1167 | 1167 | if (flags & SF_StateDisabled && !QS60StyleModeSpecifics::disabledFrameGraphic(frame)) { | |
| 1168 | 1168 | QStyleOption opt; |
src/gui/text/qfont_s60.cpp
(6 / 3)
|   | |||
| 41 | 41 | ||
| 42 | 42 | #include "qfont.h" | |
| 43 | 43 | #include "qt_s60_p.h" | |
| 44 | #include <private/qwindowsurface_s60_p.h> | ||
| 44 | #include "qpixmap_s60_p.h" | ||
| 45 | 45 | #include "qmutex.h" | |
| 46 | 46 | ||
| 47 | 47 | QT_BEGIN_NAMESPACE | |
| … | … | ||
| 57 | 57 | QMutexLocker locker(lastResortFamilyMutex()); | |
| 58 | 58 | static QString family; | |
| 59 | 59 | if (family.isEmpty()) { | |
| 60 | QS60WindowSurface::unlockBitmapHeap(); | ||
| 60 | |||
| 61 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | ||
| 62 | |||
| 61 | 63 | CFont *font; | |
| 62 | 64 | const TInt err = S60->screenDevice()->GetNearestFontInTwips(font, TFontSpec()); | |
| 63 | 65 | Q_ASSERT(err == KErrNone); | |
| 64 | 66 | const TFontSpec spec = font->FontSpecInTwips(); | |
| 65 | 67 | family = QString((const QChar *)spec.iTypeface.iName.Ptr(), spec.iTypeface.iName.Length()); | |
| 66 | 68 | S60->screenDevice()->ReleaseFont(font); | |
| 67 | QS60WindowSurface::lockBitmapHeap(); | ||
| 69 | |||
| 70 | lock.relock(); | ||
| 68 | 71 | } | |
| 69 | 72 | return family; | |
| 70 | 73 | #else |
|   | |||
| 45 | 45 | #include "qfontengine_s60_p.h" | |
| 46 | 46 | #include "qabstractfileengine.h" | |
| 47 | 47 | #include "qdesktopservices.h" | |
| 48 | #include "qpixmap_s60_p.h" | ||
| 48 | 49 | #include "qt_s60_p.h" | |
| 49 | 50 | #include "qendian.h" | |
| 50 | #include <private/qwindowsurface_s60_p.h> | ||
| 51 | 51 | #include <private/qcore_symbian_p.h> | |
| 52 | 52 | #if defined(QT_NO_FREETYPE) | |
| 53 | 53 | #include <OPENFONT.H> | |
| … | … | ||
| 217 | 217 | if (!db->s60Store) | |
| 218 | 218 | db->s60Store = new QFontDatabaseS60StoreImplementation; | |
| 219 | 219 | ||
| 220 | QS60WindowSurface::unlockBitmapHeap(); | ||
| 220 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | ||
| 221 | |||
| 221 | 222 | const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces(); | |
| 222 | 223 | const QFontDatabaseS60StoreImplementation *store = dynamic_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store); | |
| 223 | 224 | Q_ASSERT(store); | |
| … | … | ||
| 272 | 272 | } | |
| 273 | 273 | QS60Data::screenDevice()->ReleaseFont(font); | |
| 274 | 274 | } | |
| 275 | |||
| 275 | 276 | Q_ASSERT(fontAdded); | |
| 276 | QS60WindowSurface::lockBitmapHeap(); | ||
| 277 | |||
| 278 | lock.relock(); | ||
| 279 | |||
| 277 | 280 | #else // defined(QT_NO_FREETYPE) | |
| 278 | 281 | QDir dir(QDesktopServices::storageLocation(QDesktopServices::FontsLocation)); | |
| 279 | 282 | dir.setNameFilters(QStringList() << QLatin1String("*.ttf") |
src/gui/text/qfontengine_s60.cpp
(10 / 5)
|   | |||
| 43 | 43 | #include "qtextengine_p.h" | |
| 44 | 44 | #include "qglobal.h" | |
| 45 | 45 | #include <private/qapplication_p.h> | |
| 46 | #include <private/qwindowsurface_s60_p.h> | ||
| 47 | 46 | #include "qimage.h" | |
| 48 | 47 | #include "qt_s60_p.h" | |
| 48 | #include "qpixmap_s60_p.h" | ||
| 49 | 49 | ||
| 50 | 50 | #include <e32base.h> | |
| 51 | 51 | #include <e32std.h> | |
| … | … | ||
| 136 | 136 | QFontEngine::fontDef = request; | |
| 137 | 137 | m_fontSizeInPixels = (request.pixelSize >= 0)? | |
| 138 | 138 | request.pixelSize:pointsToPixels(request.pointSize); | |
| 139 | QS60WindowSurface::unlockBitmapHeap(); | ||
| 139 | |||
| 140 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | ||
| 141 | |||
| 140 | 142 | m_textRenderBitmap = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new | |
| 141 | 143 | const TSize bitmapSize(1, 1); // It is just a dummy bitmap that I need to keep the font alive (or maybe not) | |
| 142 | 144 | qt_symbian_throwIfError(m_textRenderBitmap->Create(bitmapSize, EGray256)); | |
| … | … | ||
| 153 | 153 | const TInt errorCode = m_textRenderBitmapDevice->GetNearestFontInPixels(m_font, fontSpec); | |
| 154 | 154 | Q_ASSERT(errorCode == 0); | |
| 155 | 155 | m_textRenderBitmapGc->UseFont(m_font); | |
| 156 | QS60WindowSurface::lockBitmapHeap(); | ||
| 156 | |||
| 157 | lock.relock(); | ||
| 157 | 158 | } | |
| 158 | 159 | ||
| 159 | 160 | QFontEngineS60::~QFontEngineS60() | |
| 160 | 161 | { | |
| 161 | QS60WindowSurface::unlockBitmapHeap(); | ||
| 162 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | ||
| 163 | |||
| 162 | 164 | m_textRenderBitmapGc->DiscardFont(); | |
| 163 | 165 | delete m_textRenderBitmapGc; | |
| 164 | 166 | m_textRenderBitmapGc = NULL; | |
| … | … | ||
| 169 | 169 | m_textRenderBitmapDevice = NULL; | |
| 170 | 170 | delete m_textRenderBitmap; | |
| 171 | 171 | m_textRenderBitmap = NULL; | |
| 172 | QS60WindowSurface::lockBitmapHeap(); | ||
| 172 | |||
| 173 | lock.relock(); | ||
| 173 | 174 | } | |
| 174 | 175 | ||
| 175 | 176 | bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const |

