Commit 402ac576ec951f68eb02787515bd1f87354c35eb
- Diff rendering mode:
- inline
- side by side
src/gui/image/qpixmap_s60.cpp
(140 / 140)
|   | |||
| 68 | 68 | /*! | |
| 69 | 69 | \since 4.6 | |
| 70 | 70 | ||
| 71 | Symbian Font And Bitmap server client that is | ||
| 71 | Symbian Font And Bitmap server client that is | ||
| 72 | 72 | used to lock the global bitmap heap. Only used in | |
| 73 | 73 | S60 v3.1 and S60 v3.2. | |
| 74 | 74 | */ | |
| 75 | 75 | class QSymbianFbsClient | |
| 76 | 76 | { | |
| 77 | 77 | public: | |
| 78 | |||
| 79 | QSymbianFbsClient() : heapLock(0), heapLocked(false) | ||
| 78 | |||
| 79 | QSymbianFbsClient() : heapLock(0), heapLocked(false) | ||
| 80 | 80 | { | |
| 81 | 81 | QT_TRAP_THROWING(heapLock = new(ELeave) CFbsBitmap); | |
| 82 | heapLock->Create(TSize(0,0), S60->screenDevice()->DisplayMode()); | ||
| 82 | heapLock->Create(TSize(0,0), S60->screenDevice()->DisplayMode()); | ||
| 83 | 83 | } | |
| 84 | |||
| 84 | |||
| 85 | 85 | ~QSymbianFbsClient() | |
| 86 | 86 | { | |
| 87 | 87 | delete heapLock; | |
| 88 | 88 | } | |
| 89 | |||
| 89 | |||
| 90 | 90 | bool lockHeap() | |
| 91 | 91 | { | |
| 92 | 92 | bool wasLocked = heapLocked; | |
| 93 | |||
| 93 | |||
| 94 | 94 | if (heapLock && !heapLocked) { | |
| 95 | 95 | heapLock->LockHeap(ETrue); | |
| 96 | 96 | heapLocked = true; | |
| 97 | 97 | } | |
| 98 | |||
| 98 | |||
| 99 | 99 | return wasLocked; | |
| 100 | 100 | } | |
| 101 | |||
| 101 | |||
| 102 | 102 | bool unlockHeap() | |
| 103 | 103 | { | |
| 104 | 104 | bool wasLocked = heapLocked; | |
| 105 | |||
| 105 | |||
| 106 | 106 | if (heapLock && heapLocked) { | |
| 107 | 107 | heapLock->UnlockHeap(ETrue); | |
| 108 | 108 | heapLocked = false; | |
| 109 | 109 | } | |
| 110 | |||
| 110 | |||
| 111 | 111 | return wasLocked; | |
| 112 | 112 | } | |
| 113 | |||
| 114 | |||
| 113 | |||
| 114 | |||
| 115 | 115 | private: | |
| 116 | |||
| 116 | |||
| 117 | 117 | CFbsBitmap *heapLock; | |
| 118 | 118 | bool heapLocked; | |
| 119 | 119 | }; | |
| … | … | ||
| 156 | 156 | ||
| 157 | 157 | bool heapWasLocked; | |
| 158 | 158 | QSysInfo::SymbianVersion symbianVersion; | |
| 159 | |||
| 160 | explicit QSymbianBitmapDataAccess() : heapWasLocked(false) | ||
| 159 | |||
| 160 | explicit QSymbianBitmapDataAccess() : heapWasLocked(false) | ||
| 161 | 161 | { | |
| 162 | 162 | symbianVersion = QSysInfo::symbianVersion(); | |
| 163 | 163 | }; | |
| 164 | |||
| 164 | |||
| 165 | 165 | ~QSymbianBitmapDataAccess() {}; | |
| 166 | |||
| 166 | |||
| 167 | 167 | inline void beginDataAccess(CFbsBitmap *bitmap) | |
| 168 | 168 | { | |
| 169 | 169 | if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) | |
| … | … | ||
| 171 | 171 | else | |
| 172 | 172 | bitmap->LockHeap(ETrue); | |
| 173 | 173 | } | |
| 174 | |||
| 174 | |||
| 175 | 175 | inline void endDataAccess(CFbsBitmap *bitmap) | |
| 176 | 176 | { | |
| 177 | 177 | if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) { | |
| … | … | ||
| 182 | 182 | } | |
| 183 | 183 | } | |
| 184 | 184 | }; | |
| 185 | |||
| 186 | |||
| 185 | |||
| 186 | |||
| 187 | 187 | #define UPDATE_BUFFER() \ | |
| 188 | 188 | { \ | |
| 189 | 189 | beginDataAccess(); \ | |
| … | … | ||
| 194 | 194 | static CFbsBitmap* createSymbianCFbsBitmap(const TSize& size, TDisplayMode mode) | |
| 195 | 195 | { | |
| 196 | 196 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | |
| 197 | |||
| 197 | |||
| 198 | 198 | CFbsBitmap* bitmap = 0; | |
| 199 | 199 | QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap); | |
| 200 | |||
| 200 | |||
| 201 | 201 | if (bitmap->Create(size, mode) != KErrNone) { | |
| 202 | 202 | delete bitmap; | |
| 203 | 203 | bitmap = 0; | |
| 204 | 204 | } | |
| 205 | |||
| 205 | |||
| 206 | 206 | lock.relock(); | |
| 207 | |||
| 207 | |||
| 208 | 208 | return bitmap; | |
| 209 | 209 | } | |
| 210 | 210 | ||
| … | … | ||
| 212 | 212 | { | |
| 213 | 213 | if(bitmap->IsCompressedInRAM()) { | |
| 214 | 214 | QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); | |
| 215 | |||
| 215 | |||
| 216 | 216 | CFbsBitmap *uncompressed = 0; | |
| 217 | 217 | QT_TRAP_THROWING(uncompressed = new (ELeave) CFbsBitmap); | |
| 218 | |||
| 218 | |||
| 219 | 219 | if (uncompressed->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) { | |
| 220 | 220 | delete bitmap; | |
| 221 | 221 | bitmap = 0; | |
| 222 | 222 | lock.relock(); | |
| 223 | |||
| 223 | |||
| 224 | 224 | return bitmap; | |
| 225 | 225 | } | |
| 226 | |||
| 226 | |||
| 227 | 227 | lock.relock(); | |
| 228 | |||
| 228 | |||
| 229 | 229 | CBitmapContext *bitmapContext = 0; | |
| 230 | 230 | CFbsBitmapDevice* bitmapDevice = 0; | |
| 231 | 231 | QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(uncompressed)); | |
| … | … | ||
| 235 | 235 | delete bitmapDevice; | |
| 236 | 236 | bitmap = 0; | |
| 237 | 237 | bitmapDevice = 0; | |
| 238 | |||
| 238 | |||
| 239 | 239 | lock.relock(); | |
| 240 | |||
| 240 | |||
| 241 | 241 | return bitmap; | |
| 242 | 242 | } | |
| 243 | |||
| 243 | |||
| 244 | 244 | bitmapContext->DrawBitmap(TPoint(), bitmap); | |
| 245 | |||
| 245 | |||
| 246 | 246 | delete bitmapContext; | |
| 247 | 247 | delete bitmapDevice; | |
| 248 | |||
| 248 | |||
| 249 | 249 | return uncompressed; | |
| 250 | 250 | } else { | |
| 251 | 251 | return bitmap; | |
| … | … | ||
| 256 | 256 | { | |
| 257 | 257 | CWsScreenDevice* screenDevice = S60->screenDevice(); | |
| 258 | 258 | TSize screenSize = screenDevice->SizeInPixels(); | |
| 259 | |||
| 259 | |||
| 260 | 260 | TSize srcSize; | |
| 261 | 261 | // Find out if this is one of our windows. | |
| 262 | 262 | QSymbianControl *sControl; | |
| … | … | ||
| 270 | 270 | y += relativePos.iY; | |
| 271 | 271 | srcSize = winId->Size(); | |
| 272 | 272 | } | |
| 273 | |||
| 273 | |||
| 274 | 274 | TRect srcRect(TPoint(x, y), srcSize); | |
| 275 | 275 | // Clip to the screen | |
| 276 | 276 | srcRect.Intersection(TRect(screenSize)); | |
| 277 | |||
| 277 | |||
| 278 | 278 | if (w > 0 && h > 0) { | |
| 279 | 279 | TRect subRect(TPoint(x, y), TSize(w, h)); | |
| 280 | 280 | // Clip to the subRect | |
| 281 | 281 | srcRect.Intersection(subRect); | |
| 282 | 282 | } | |
| 283 | |||
| 283 | |||
| 284 | 284 | if (srcRect.IsEmpty()) | |
| 285 | 285 | return QPixmap(); | |
| 286 | |||
| 286 | |||
| 287 | 287 | CFbsBitmap* temporary = createSymbianCFbsBitmap(srcRect.Size(), screenDevice->DisplayMode()); | |
| 288 | |||
| 288 | |||
| 289 | 289 | QPixmap pix; | |
| 290 | |||
| 290 | |||
| 291 | 291 | if (temporary && screenDevice->CopyScreenToBitmap(temporary, srcRect) == KErrNone) { | |
| 292 | pix = QPixmap::fromSymbianCFbsBitmap(temporary); | ||
| 292 | pix = QPixmap::fromSymbianCFbsBitmap(temporary); | ||
| 293 | 293 | } | |
| 294 | |||
| 294 | |||
| 295 | 295 | delete temporary; | |
| 296 | 296 | return pix; | |
| 297 | 297 | } | |
| … | … | ||
| 320 | 320 | Creates \c CFbsBitmap that is equivalent to the QPixmap, based on | |
| 321 | 321 | the given \a mode. If the creation then this function returns 0. | |
| 322 | 322 | ||
| 323 | It is the caller's responsibility to release the \c CFbsBitmap data | ||
| 323 | It is the caller's responsibility to release the \c CFbsBitmap data | ||
| 324 | 324 | after use either by deleting the bitmap or calling \c Reset(). | |
| 325 | 325 | ||
| 326 | 326 | \warning On S60 3.1 and S60 3.2 conversion mode will always be CopyData | |
| … | … | ||
| 332 | 332 | CFbsBitmap *QPixmap::toSymbianCFbsBitmap(ConversionMode mode) const | |
| 333 | 333 | { | |
| 334 | 334 | QS60PixmapData *s60data = static_cast<QS60PixmapData *>(data.data()); | |
| 335 | |||
| 335 | |||
| 336 | 336 | if (isNull() || !s60data->cfbsBitmap) | |
| 337 | 337 | return 0; | |
| 338 | |||
| 338 | |||
| 339 | 339 | bool convertToArgb32 = false; | |
| 340 | |||
| 340 | |||
| 341 | 341 | QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); | |
| 342 | 342 | if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) { | |
| 343 | // Convert argb32_premultiplied to argb32 since Symbian 9.2 and Symbian 9.3 do | ||
| 343 | // Convert argb32_premultiplied to argb32 since Symbian 9.2 and Symbian 9.3 do | ||
| 344 | 344 | // not support premultipied format. | |
| 345 | |||
| 345 | |||
| 346 | 346 | if (s60data->image.format() == QImage::Format_ARGB32_Premultiplied) { | |
| 347 | 347 | mode = CopyData; | |
| 348 | 348 | convertToArgb32 = true; | |
| 349 | 349 | } | |
| 350 | 350 | } | |
| 351 | |||
| 351 | |||
| 352 | 352 | CFbsBitmap *bitmap = 0; | |
| 353 | |||
| 353 | |||
| 354 | 354 | TDisplayMode displayMode = s60data->cfbsBitmap->DisplayMode(); | |
| 355 | |||
| 355 | |||
| 356 | 356 | if(displayMode == EGray2) { | |
| 357 | 357 | //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid | |
| 358 | 358 | //So invert mono bitmaps so that masks work correctly. | |
| 359 | 359 | s60data->image.invertPixels(); | |
| 360 | 360 | mode = CopyData; | |
| 361 | 361 | } | |
| 362 | |||
| 362 | |||
| 363 | 363 | if (mode == CopyData) { | |
| 364 | 364 | QImage source; | |
| 365 | |||
| 365 | |||
| 366 | 366 | if (convertToArgb32) { | |
| 367 | 367 | source = s60data->image.convertToFormat(QImage::Format_ARGB32); | |
| 368 | 368 | displayMode = EColor16MA; | |
| 369 | 369 | } else { | |
| 370 | 370 | source = s60data->image; | |
| 371 | 371 | } | |
| 372 | |||
| 372 | |||
| 373 | 373 | CFbsBitmap *newBitmap = createSymbianCFbsBitmap(TSize(source.width(), source.height()), displayMode); | |
| 374 | 374 | const uchar *sptr = source.bits(); | |
| 375 | 375 | s60data->symbianBitmapDataAccess->beginDataAccess(newBitmap); | |
| 376 | |||
| 376 | |||
| 377 | 377 | uchar *dptr = (uchar*)newBitmap->DataAddress(); | |
| 378 | 378 | Mem::Copy(dptr, sptr, source.numBytes()); | |
| 379 | |||
| 379 | |||
| 380 | 380 | s60data->symbianBitmapDataAccess->endDataAccess(newBitmap); | |
| 381 | |||
| 381 | |||
| 382 | 382 | bitmap = newBitmap; | |
| 383 | 383 | } else { | |
| 384 | |||
| 384 | |||
| 385 | 385 | QT_TRAP_THROWING(bitmap = new (ELeave) CFbsBitmap); | |
| 386 | |||
| 386 | |||
| 387 | 387 | TInt err = bitmap->Duplicate(s60data->cfbsBitmap->Handle()); | |
| 388 | 388 | if (err != KErrNone) { | |
| 389 | 389 | qWarning("Could not duplicate CFbsBitmap"); | |
| … | … | ||
| 391 | 391 | bitmap = 0; | |
| 392 | 392 | } | |
| 393 | 393 | } | |
| 394 | |||
| 394 | |||
| 395 | 395 | if(displayMode == EGray2) { | |
| 396 | 396 | // restore pixels | |
| 397 | 397 | s60data->image.invertPixels(); | |
| 398 | 398 | } | |
| 399 | |||
| 399 | |||
| 400 | 400 | return bitmap; | |
| 401 | 401 | } | |
| 402 | 402 | ||
| … | … | ||
| 404 | 404 | \fn QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode) | |
| 405 | 405 | \since 4.6 | |
| 406 | 406 | ||
| 407 | Creates a QPixmap from native \c CFbsBitmap \a bitmap. The conversion | ||
| 407 | Creates a QPixmap from native \c CFbsBitmap \a bitmap. The conversion | ||
| 408 | 408 | is based on the specified \a mode. Conversion mode is always QPixmap::CopyData | |
| 409 | if given \a bitmap does not have display mode of TDisplayMode::EGray2, | ||
| 410 | \c TDisplayMode::EColor16MU or \c TDisplayMode::EColor16MAP. | ||
| 411 | |||
| 409 | if given \a bitmap does not have display mode of TDisplayMode::EGray2, | ||
| 410 | \c TDisplayMode::EColor16MU or \c TDisplayMode::EColor16MAP. | ||
| 411 | |||
| 412 | 412 | If the CFbsBitmap is not valid this function will return a null QPixmap. | |
| 413 | 413 | ||
| 414 | 414 | \warning This function is only available on Symbian OS. | |
| … | … | ||
| 418 | 418 | QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode) | |
| 419 | 419 | { | |
| 420 | 420 | if (bitmap) { | |
| 421 | |||
| 421 | |||
| 422 | 422 | bool deleteSourceBitmap = false; | |
| 423 | |||
| 424 | #if Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE | ||
| 425 | |||
| 423 | |||
| 424 | #ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE | ||
| 425 | |||
| 426 | 426 | // Rasterize extended bitmaps | |
| 427 | |||
| 428 | TUid extendedBitmapType = = bitmap->ExtendedBitmapType(); | ||
| 427 | |||
| 428 | TUid extendedBitmapType = bitmap->ExtendedBitmapType(); | ||
| 429 | 429 | if (extendedBitmapType != KNullUid) { | |
| 430 | 430 | CFbsBitmap *rasterBitmap = createSymbianCFbsBitmap(bitmap->SizeInPixels(), EColor16MA); | |
| 431 | |||
| 431 | |||
| 432 | 432 | CFbsBitmapDevice *rasterBitmapDev = 0; | |
| 433 | 433 | QT_TRAP_THROWING(rasterBitmapDev = CFbsBitmapDevice::NewL(rasterBitmap)); | |
| 434 | |||
| 434 | |||
| 435 | 435 | CFbsBitGc *rasterBitmapGc = 0; | |
| 436 | 436 | TInt err = rasterBitmapDev->CreateContext(rasterBitmapGc); | |
| 437 | 437 | if (err != KErrNone) { | |
| … | … | ||
| 440 | 440 | rasterBitmapDev = 0; | |
| 441 | 441 | return QPixmap(); | |
| 442 | 442 | } | |
| 443 | |||
| 443 | |||
| 444 | 444 | rasterBitmapGc->BitBlt(TPoint( 0, 0), bitmap); | |
| 445 | |||
| 445 | |||
| 446 | 446 | bitmap = rasterBitmap; | |
| 447 | |||
| 447 | |||
| 448 | 448 | delete rasterBitmapDev; | |
| 449 | 449 | delete rasterBitmapGc; | |
| 450 | |||
| 450 | |||
| 451 | 451 | rasterBitmapDev = 0; | |
| 452 | 452 | rasterBitmapGc = 0; | |
| 453 | |||
| 453 | |||
| 454 | 454 | deleteSourceBitmap = true; | |
| 455 | 455 | } | |
| 456 | #endif | ||
| 457 | |||
| 458 | |||
| 456 | #endif | ||
| 457 | |||
| 458 | |||
| 459 | 459 | deleteSourceBitmap = bitmap->IsCompressedInRAM(); | |
| 460 | 460 | CFbsBitmap *sourceBitmap = uncompress(bitmap); | |
| 461 | |||
| 461 | |||
| 462 | 462 | TDisplayMode displayMode = sourceBitmap->DisplayMode(); | |
| 463 | 463 | QImage::Format format = qt_TDisplayMode2Format(displayMode); | |
| 464 | |||
| 464 | |||
| 465 | 465 | QImage::Format opaqueFormat = QNativeImage::systemFormat(); | |
| 466 | 466 | QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; | |
| 467 | |||
| 467 | |||
| 468 | 468 | if (format != opaqueFormat && format != alphaFormat && format != QImage::Format_MonoLSB) | |
| 469 | 469 | mode = CopyData; | |
| 470 | 470 | ||
| 471 | |||
| 471 | |||
| 472 | 472 | QPixmapData::PixelType type = (format!=QImage::Format_MonoLSB) | |
| 473 | 473 | ? QPixmapData::PixmapType | |
| 474 | 474 | : QPixmapData::BitmapType; | |
| 475 | |||
| 475 | |||
| 476 | 476 | QS60PixmapData *pixmapData = 0; | |
| 477 | |||
| 477 | |||
| 478 | 478 | if (mode == CopyData) { | |
| 479 | |||
| 479 | |||
| 480 | 480 | TSize size = sourceBitmap->SizeInPixels(); | |
| 481 | |||
| 481 | |||
| 482 | 482 | QSymbianBitmapDataAccess da; | |
| 483 | 483 | da.beginDataAccess(sourceBitmap); | |
| 484 | 484 | uchar *bytes = (uchar*)sourceBitmap->DataAddress(); | |
| 485 | 485 | QImage img = QImage(bytes, size.iWidth, size.iHeight, format); | |
| 486 | 486 | da.endDataAccess(sourceBitmap); | |
| 487 | |||
| 487 | |||
| 488 | 488 | pixmapData = new QS60PixmapData(type); | |
| 489 | 489 | pixmapData->fromImage(img, Qt::AutoColor); | |
| 490 | |||
| 490 | |||
| 491 | 491 | if(deleteSourceBitmap) | |
| 492 | 492 | delete sourceBitmap; | |
| 493 | |||
| 493 | |||
| 494 | 494 | if(displayMode == EGray2) { | |
| 495 | 495 | //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid | |
| 496 | 496 | //So invert mono bitmaps so that masks work correctly. | |
| … | … | ||
| 499 | 499 | } else { | |
| 500 | 500 | CFbsBitmap* duplicate = 0; | |
| 501 | 501 | QT_TRAP_THROWING(duplicate = new (ELeave) CFbsBitmap); | |
| 502 | |||
| 502 | |||
| 503 | 503 | TInt err = duplicate->Duplicate(sourceBitmap->Handle()); | |
| 504 | 504 | if (err != KErrNone) { | |
| 505 | 505 | qWarning("Could not duplicate CFbsBitmap"); | |
| 506 | |||
| 506 | |||
| 507 | 507 | if(deleteSourceBitmap) | |
| 508 | 508 | delete sourceBitmap; | |
| 509 | |||
| 509 | |||
| 510 | 510 | delete duplicate; | |
| 511 | 511 | return QPixmap(); | |
| 512 | 512 | } | |
| 513 | |||
| 513 | |||
| 514 | 514 | pixmapData = new QS60PixmapData(type); | |
| 515 | 515 | pixmapData->fromSymbianBitmap(duplicate); | |
| 516 | |||
| 516 | |||
| 517 | 517 | if(deleteSourceBitmap) | |
| 518 | 518 | delete sourceBitmap; | |
| 519 | 519 | } | |
| 520 | |||
| 520 | |||
| 521 | 521 | return QPixmap(pixmapData); | |
| 522 | 522 | } | |
| 523 | |||
| 523 | |||
| 524 | 524 | return QPixmap(); | |
| 525 | 525 | } | |
| 526 | 526 | ||
| … | … | ||
| 546 | 546 | w = width; | |
| 547 | 547 | h = height; | |
| 548 | 548 | is_null = true; | |
| 549 | |||
| 549 | |||
| 550 | 550 | release(); | |
| 551 | 551 | return; | |
| 552 | 552 | } else if (!cfbsBitmap) { | |
| … | … | ||
| 554 | 554 | if (pixelType() == BitmapType) | |
| 555 | 555 | mode = EGray2; | |
| 556 | 556 | else | |
| 557 | mode = EColor16MU; | ||
| 558 | |||
| 557 | mode = EColor16MU; | ||
| 558 | |||
| 559 | 559 | CFbsBitmap* bitmap = createSymbianCFbsBitmap(TSize(width, height), mode); | |
| 560 | 560 | fromSymbianBitmap(bitmap); | |
| 561 | 561 | } else { | |
| 562 | |||
| 562 | |||
| 563 | 563 | TSize newSize(width, height); | |
| 564 | |||
| 564 | |||
| 565 | 565 | if(cfbsBitmap->SizeInPixels() != newSize) { | |
| 566 | 566 | cfbsBitmap->Resize(TSize(width, height)); | |
| 567 | 567 | if(pengine) { | |
| … | … | ||
| 569 | 569 | pengine = 0; | |
| 570 | 570 | } | |
| 571 | 571 | } | |
| 572 | |||
| 572 | |||
| 573 | 573 | UPDATE_BUFFER(); | |
| 574 | 574 | } | |
| 575 | 575 | } | |
| … | … | ||
| 595 | 595 | delete cfbsBitmap; | |
| 596 | 596 | lock.relock(); | |
| 597 | 597 | } | |
| 598 | |||
| 598 | |||
| 599 | 599 | delete pengine; | |
| 600 | 600 | image = QImage(); | |
| 601 | 601 | cfbsBitmap = 0; | |
| … | … | ||
| 611 | 611 | void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap) | |
| 612 | 612 | { | |
| 613 | 613 | cfbsBitmap = bitmap; | |
| 614 | |||
| 614 | |||
| 615 | 615 | if(!initSymbianBitmapContext()) { | |
| 616 | 616 | qWarning("Could not create CBitmapContext"); | |
| 617 | 617 | release(); | |
| 618 | 618 | return; | |
| 619 | 619 | } | |
| 620 | |||
| 620 | |||
| 621 | 621 | setSerialNumber(cfbsBitmap->Handle()); | |
| 622 | |||
| 622 | |||
| 623 | 623 | UPDATE_BUFFER(); | |
| 624 | |||
| 624 | |||
| 625 | 625 | // Create default palette if needed | |
| 626 | 626 | if (cfbsBitmap->DisplayMode() == EGray2) { | |
| 627 | 627 | image.setNumColors(2); | |
| 628 | 628 | image.setColor(0, QColor(Qt::color0).rgba()); | |
| 629 | 629 | image.setColor(1, QColor(Qt::color1).rgba()); | |
| 630 | |||
| 630 | |||
| 631 | 631 | //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid | |
| 632 | 632 | //So invert mono bitmaps so that masks work correctly. | |
| 633 | 633 | image.invertPixels(); | |
| … | … | ||
| 644 | 644 | void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags) | |
| 645 | 645 | { | |
| 646 | 646 | QImage sourceImage; | |
| 647 | |||
| 647 | |||
| 648 | 648 | if (pixelType() == BitmapType) { | |
| 649 | 649 | sourceImage = img.convertToFormat(QImage::Format_MonoLSB); | |
| 650 | 650 | } else { | |
| … | … | ||
| 653 | 653 | ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) | |
| 654 | 654 | : img.convertToFormat(QImage::Format_RGB32); | |
| 655 | 655 | } else { | |
| 656 | |||
| 656 | |||
| 657 | 657 | QImage::Format opaqueFormat = QNativeImage::systemFormat(); | |
| 658 | 658 | QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied; | |
| 659 | |||
| 659 | |||
| 660 | 660 | if (!img.hasAlphaChannel() | |
| 661 | 661 | || ((flags & Qt::NoOpaqueDetection) == 0 | |
| 662 | 662 | && !const_cast<QImage &>(img).data_ptr()->checkForAlphaPixels())) { | |
| … | … | ||
| 666 | 666 | } | |
| 667 | 667 | } | |
| 668 | 668 | } | |
| 669 | |||
| 670 | |||
| 669 | |||
| 670 | |||
| 671 | 671 | QImage::Format destFormat = sourceImage.format(); | |
| 672 | 672 | TDisplayMode mode; | |
| 673 | 673 | switch (destFormat) { | |
| … | … | ||
| 693 | 693 | qWarning("Image format not supported: %d", image.format()); | |
| 694 | 694 | return; | |
| 695 | 695 | } | |
| 696 | |||
| 696 | |||
| 697 | 697 | cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode); | |
| 698 | 698 | if (!(cfbsBitmap && initSymbianBitmapContext())) { | |
| 699 | 699 | qWarning("Could not create CFbsBitmap and/or CBitmapContext"); | |
| 700 | 700 | release(); | |
| 701 | 701 | return; | |
| 702 | 702 | } | |
| 703 | |||
| 703 | |||
| 704 | 704 | setSerialNumber(cfbsBitmap->Handle()); | |
| 705 | |||
| 705 | |||
| 706 | 706 | const uchar *sptr = const_cast<const QImage &>(sourceImage).bits(); | |
| 707 | 707 | symbianBitmapDataAccess->beginDataAccess(cfbsBitmap); | |
| 708 | 708 | uchar *dptr = (uchar*)cfbsBitmap->DataAddress(); | |
| 709 | 709 | Mem::Copy(dptr, sptr, sourceImage.numBytes()); | |
| 710 | symbianBitmapDataAccess->endDataAccess(cfbsBitmap); | ||
| 711 | |||
| 710 | symbianBitmapDataAccess->endDataAccess(cfbsBitmap); | ||
| 711 | |||
| 712 | 712 | UPDATE_BUFFER(); | |
| 713 | |||
| 713 | |||
| 714 | 714 | if (destFormat == QImage::Format_MonoLSB) { | |
| 715 | 715 | image.setNumColors(2); | |
| 716 | 716 | image.setColor(0, QColor(Qt::color0).rgba()); | |
| 717 | image.setColor(1, QColor(Qt::color1).rgba()); | ||
| 717 | image.setColor(1, QColor(Qt::color1).rgba()); | ||
| 718 | 718 | } else { | |
| 719 | 719 | image.setColorTable(sourceImage.colorTable()); | |
| 720 | 720 | } | |
| … | … | ||
| 726 | 726 | QBitmap::fromImage(data->toImage().copy(rect)); | |
| 727 | 727 | return; | |
| 728 | 728 | } | |
| 729 | |||
| 729 | |||
| 730 | 730 | const QS60PixmapData *s60Data = static_cast<const QS60PixmapData*>(data); | |
| 731 | |||
| 731 | |||
| 732 | 732 | resize(rect.width(), rect.height()); | |
| 733 | 733 | cfbsBitmap->SetDisplayMode(s60Data->cfbsBitmap->DisplayMode()); | |
| 734 | |||
| 734 | |||
| 735 | 735 | bitmapContext->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect)); | |
| 736 | 736 | } | |
| 737 | 737 | ||
| … | … | ||
| 811 | 811 | } else { | |
| 812 | 812 | const int w = image.width(); | |
| 813 | 813 | const int h = image.height(); | |
| 814 | |||
| 814 | |||
| 815 | 815 | const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); | |
| 816 | 816 | QImage newImage = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); | |
| 817 | 817 | for (int y = 0; y < h; ++y) { | |
| … | … | ||
| 853 | 853 | { | |
| 854 | 854 | if(!cfbsBitmap) | |
| 855 | 855 | return; | |
| 856 | |||
| 856 | |||
| 857 | 857 | symbianBitmapDataAccess->beginDataAccess(cfbsBitmap); | |
| 858 | |||
| 858 | |||
| 859 | 859 | uchar* newBytes = (uchar*)cfbsBitmap->DataAddress(); | |
| 860 | |||
| 860 | |||
| 861 | 861 | if (newBytes == bytes) | |
| 862 | 862 | return; | |
| 863 | |||
| 864 | |||
| 863 | |||
| 864 | |||
| 865 | 865 | bytes = newBytes; | |
| 866 | 866 | TDisplayMode mode = cfbsBitmap->DisplayMode(); | |
| 867 | 867 | QImage::Format format = qt_TDisplayMode2Format(mode); | |
| 868 | 868 | TSize size = cfbsBitmap->SizeInPixels(); | |
| 869 | |||
| 869 | |||
| 870 | 870 | QVector<QRgb> savedColorTable; | |
| 871 | 871 | if (!image.isNull()) | |
| 872 | 872 | savedColorTable = image.colorTable(); | |
| 873 | |||
| 873 | |||
| 874 | 874 | image = QImage(bytes, size.iWidth, size.iHeight, format); | |
| 875 | |||
| 875 | |||
| 876 | 876 | // Restore the palette or create a default | |
| 877 | 877 | if (!savedColorTable.isEmpty()) { | |
| 878 | 878 | image.setColorTable(savedColorTable); | |
| 879 | 879 | } | |
| 880 | |||
| 880 | |||
| 881 | 881 | w = size.iWidth; | |
| 882 | 882 | h = size.iHeight; | |
| 883 | 883 | d = image.depth(); | |
| 884 | 884 | is_null = (w <= 0 || h <= 0); | |
| 885 | |||
| 885 | |||
| 886 | 886 | if (pengine) { | |
| 887 | 887 | QS60PaintEngine *engine = static_cast<QS60PaintEngine *>(pengine); | |
| 888 | 888 | engine->prepare(&image); | |
| … | … | ||
| 893 | 893 | { | |
| 894 | 894 | if(!cfbsBitmap) | |
| 895 | 895 | return; | |
| 896 | |||
| 896 | |||
| 897 | 897 | symbianBitmapDataAccess->endDataAccess(cfbsBitmap); | |
| 898 | 898 | } | |
| 899 | 899 |

