Changeset 59 for trunk/src/kernel/qpaintdevice_pm.cpp
- Timestamp:
- Jan 29, 2006, 8:56:21 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel/qpaintdevice_pm.cpp
r8 r59 125 125 126 126 // draws the pixmap with a mask using the black source method 127 void drawMaskedPixmap( 128 HPS dst_ps, int dst_depth, HPS src_ps, int src_w, int src_h, HPS mask_ps, 129 int dx, int dy, int sx, int sy, int w, int h, Qt::RasterOp rop 130 ) { 131 // all rectangles for different operations combined together 132 POINTL ptls[] = { 133 { dx, dy }, { dx + w, dy + h }, // 0: src/buf => dst 134 { sx, sy }, { sx + w, sy + h }, // 2: src <=> buf 135 { sx, sy }, { sx + w, sy + h }, // 4: dst => buf 136 { dx, dy } 137 }; 127 static void drawMaskedPixmap( 128 HPS dst_ps, int dst_depth, bool grab_dest, HPS src_ps, HPS mask_ps, 129 int dx, int dy, int sx, int sy, int w, int h, Qt::RasterOp rop ) 130 { 138 131 IMAGEBUNDLE oldIb; 139 132 140 133 if ( !mask_ps ) { 141 134 // self-masked pixmap 135 POINTL ptls[] = { { dx, dy }, { dx + w, dy + h }, 136 { sx, sy } }; 142 137 IMAGEBUNDLE newIb; 143 138 GpiQueryAttrs( dst_ps, PRIM_IMAGE, IBB_BACK_MIX_MODE, (PBUNDLE) &oldIb ); … … 148 143 } else { 149 144 bool simple = (rop == Qt::CopyROP) || (rop == Qt::XorROP); 150 // helper hps for dblbuf 151 HPS hpsBuf = qt_alloc_mem_ps( src_w, simple ? src_h : src_h * 2, dst_ps ); 152 // helper bitmap for dblbuf 153 BITMAPINFOHEADER2 bmh; 154 memset( &bmh, 0, sizeof(BITMAPINFOHEADER2) ); 155 bmh.cbFix = sizeof(BITMAPINFOHEADER2); 156 bmh.cx = src_w; 157 bmh.cy = simple ? src_h : src_h * 2; 158 bmh.cPlanes = 1; 159 bmh.cBitCount = dst_depth; 160 HBITMAP hbmBuf = GpiCreateBitmap( hpsBuf, &bmh, 0, NULL, NULL ); 161 GpiSetBitmap( hpsBuf, hbmBuf ); 162 145 // origial helper buffer handles 146 HPS hpsBuf = 0; 147 HBITMAP hbmBuf = 0; 148 // two pointers to the helper buffer 149 HPS hpsBuf1 = dst_ps; 150 HPS hpsBuf2 = 0; 151 // first helper buffer's coordinates 152 int buf1_x = dx, buf1_y = dy; 153 // second helper buffer's coordinates 154 int buf2_x = -1, buf2_y = -1; 155 156 if ( grab_dest || !simple ) { 157 // create the helper buffer (we need two buffers if grab_dest and 158 // not simple -- double the height in this case) 159 BITMAPINFOHEADER2 bmh; 160 memset( &bmh, 0, sizeof(BITMAPINFOHEADER2) ); 161 bmh.cbFix = sizeof(BITMAPINFOHEADER2); 162 bmh.cx = w; 163 bmh.cy = grab_dest && !simple ? h * 2 : h; 164 bmh.cPlanes = 1; 165 bmh.cBitCount = dst_depth; 166 hpsBuf = qt_alloc_mem_ps( bmh.cx, bmh.cy, dst_ps ); 167 hbmBuf = GpiCreateBitmap( hpsBuf, &bmh, 0, NULL, NULL ); 168 GpiSetBitmap( hpsBuf, hbmBuf ); 169 // setup buffer handles and coordinates 170 if ( grab_dest && !simple ) { 171 hpsBuf1 = hpsBuf2 = hpsBuf; 172 buf1_x = buf1_y = 0; 173 buf2_x = 0; 174 buf2_y = h; 175 } else if ( grab_dest ) { 176 hpsBuf1 = hpsBuf; 177 buf1_x = buf1_y = 0; 178 } else { // i.e. !grab_dest && !simple 179 hpsBuf2 = hpsBuf; 180 buf2_x = buf2_y = 0; 181 } 182 } 183 184 // save current destination colors 185 ULONG oldColor = GpiQueryColor( dst_ps ); 186 ULONG oldBackColor = GpiQueryBackColor( dst_ps ); 187 163 188 // query the destination color for 1-bpp bitmaps 164 189 GpiQueryAttrs( dst_ps, PRIM_IMAGE, IBB_COLOR, (PBUNDLE) &oldIb ); 165 // setup colors for the masking 166 GpiSetColor( hpsBuf, CLR_TRUE ); 167 GpiSetBackColor( hpsBuf, CLR_FALSE ); 168 169 // grab the destination 170 GpiBitBlt( hpsBuf, dst_ps, 3, &ptls[4], ROP_SRCCOPY, BBO_IGNORE ); 190 // setup colors for masking 191 GpiSetColor( hpsBuf1, CLR_TRUE ); 192 GpiSetBackColor( hpsBuf1, CLR_FALSE ); 193 if ( hpsBuf2 != hpsBuf1 ) { 194 GpiSetColor( hpsBuf2, CLR_TRUE ); 195 GpiSetBackColor( hpsBuf2, CLR_FALSE ); 196 } 197 198 if ( grab_dest ) { 199 // grab the destination 200 POINTL ptls[] = { { buf1_x, buf1_y }, { buf1_x + w, buf1_y + h }, 201 { dx, dy } }; 202 GpiBitBlt( hpsBuf1, dst_ps, 3, ptls, ROP_SRCCOPY, BBO_IGNORE ); 203 } 204 205 // compose a masked pixmap with a given rop into the second buffer 206 if ( !simple ) { 207 // grab the destination to the 2nd buffer 208 POINTL ptDB2[] = { { buf2_x, buf2_y }, { buf2_x + w, buf2_y + h }, 209 { dx, dy } }; 210 GpiBitBlt( hpsBuf2, dst_ps, 3, ptDB2, ROP_SRCCOPY, BBO_IGNORE ); 211 // bitblt pixmap using rop 212 POINTL ptSB2[] = { { buf2_x, buf2_y }, { buf2_x + w, buf2_y + h }, 213 { sx, sy } }; 214 GpiSetColor( hpsBuf2, oldIb.lColor ); 215 GpiBitBlt( hpsBuf2, src_ps, 3, ptSB2, qt_ropCodes_2ROP[rop], BBO_IGNORE ); 216 // make transparent pixels black 217 GpiSetColor( hpsBuf2, CLR_TRUE ); 218 GpiBitBlt( hpsBuf2, mask_ps, 3, ptSB2, ROP_SRCAND, BBO_IGNORE ); 219 } 220 171 221 // draw the mask: make non-transparent pixels (corresponding to 172 222 // ones in the mask) black. skip this step when rop = XorROP 173 223 // to get the XOR effect. 174 if ( rop != Qt::XorROP ) 175 GpiBitBlt( hpsBuf, mask_ps, 3, &ptls[2], 0x22, BBO_IGNORE ); 176 177 // compose a masked pixmap with a given rop into the second buffer 224 if ( rop != Qt::XorROP ) { 225 POINTL ptls[] = { { buf1_x, buf1_y }, { buf1_x + w, buf1_y + h }, 226 { sx, sy } }; 227 GpiBitBlt( hpsBuf1, mask_ps, 3, ptls, 0x22, BBO_IGNORE ); 228 } 229 178 230 if ( !simple ) { 179 // grab the destination to the 2nd buffer 180 ptls[4].y += h; ptls[5].y += h; 181 GpiBitBlt( hpsBuf, dst_ps, 3, &ptls[4], ROP_SRCCOPY, BBO_IGNORE ); 182 ptls[4].y -= h; ptls[5].y -= h; 183 // bitblt pixmap using rop 184 ptls[2].y += h; ptls[3].y += h; 185 GpiSetColor( hpsBuf, oldIb.lColor ); 186 GpiBitBlt( hpsBuf, src_ps, 3, &ptls[2], qt_ropCodes_2ROP[rop], BBO_IGNORE ); 187 // make transparent pixels black 188 GpiSetColor( hpsBuf, CLR_TRUE ); 189 GpiBitBlt( hpsBuf, mask_ps, 3, &ptls[2], ROP_SRCAND, BBO_IGNORE ); 190 // draw masked pixmap from the 2nd buffer to the 1rd 191 ptls[2].y -= h; ptls[3].y -= h; 192 ptls[4].y += h; ptls[5].y += h; 193 GpiBitBlt( hpsBuf, hpsBuf, 3, &ptls[2], ROP_SRCPAINT, BBO_IGNORE ); 231 // draw masked pixmap from the 2nd buffer to the 1st 232 POINTL ptB2B1[] = { { buf1_x, buf1_y }, { buf1_x + w, buf1_y + h }, 233 { buf2_x, buf2_y } }; 234 GpiBitBlt( hpsBuf1, hpsBuf2, 3, ptB2B1, ROP_SRCPAINT, BBO_IGNORE ); 194 235 } else { 195 236 // draw masked pixmap; transparent pixels are zeroed there 196 237 // by prepareForMasking( TRUE ) 197 GpiSetColor( hpsBuf, oldIb.lColor ); 198 GpiBitBlt( hpsBuf, src_ps, 3, &ptls[2], ROP_SRCINVERT, BBO_IGNORE ); 238 POINTL ptls[] = { { buf1_x, buf1_y }, { buf1_x + w, buf1_y + h }, 239 { sx, sy } }; 240 GpiSetColor( hpsBuf1, oldIb.lColor ); 241 GpiBitBlt( hpsBuf1, src_ps, 3, ptls, ROP_SRCINVERT, BBO_IGNORE ); 199 242 } 200 243 201 244 // flush the buffer 202 GpiBitBlt( dst_ps, hpsBuf, 3, &ptls[0], ROP_SRCCOPY, BBO_IGNORE ); 245 if ( hpsBuf1 != dst_ps ) { 246 POINTL ptls[] = { { dx, dy }, { dx + w, dy + h }, 247 { buf1_x, buf1_y } }; 248 GpiBitBlt( dst_ps, hpsBuf1, 3, ptls, ROP_SRCCOPY, BBO_IGNORE ); 249 } 250 203 251 // free resources 252 if ( hpsBuf ) { 253 GpiSetBitmap( hpsBuf, 0 ); 254 GpiDeleteBitmap( hbmBuf ); 255 qt_free_mem_ps( hpsBuf ); 256 } 257 258 // restore current destination colors 259 GpiSetColor( dst_ps, oldColor ); 260 GpiSetBackColor( dst_ps, oldBackColor ); 261 } 262 } 263 264 // draws the pixmap with a mask using the black source method 265 static void drawAlphaPixmap ( 266 HPS dst_ps, int dst_w, HPS src_ps, int src_w, uchar *alpha, 267 int dx, int dy, int sx, int sy, int w, int h, int depth ) 268 { 269 Q_ASSERT( depth == 32 || depth == 24 ); 270 271 bool grab_dest = false; 272 int dst_x = dx; 273 274 if ( dst_w == 0 ) { 275 grab_dest = true; 276 dst_w = w; 277 dst_x = 0; 278 } 279 280 int dst_bpl = ((depth * dst_w + 31) / 32) * 4; 281 int src_bpl = ((depth * src_w + 31) / 32) * 4; 282 283 uchar *dst = new uchar [dst_bpl * h]; 284 uchar *src = new uchar [src_bpl * h]; 285 286 BITMAPINFOHEADER2 bmh; 287 memset( &bmh, 0, sizeof(BITMAPINFOHEADER2) ); 288 bmh.cbFix = sizeof(BITMAPINFOHEADER2); 289 bmh.cPlanes = 1; 290 bmh.cBitCount = depth; 291 if ( grab_dest ) { 292 bmh.cx = w; 293 bmh.cy = h; 294 295 // helper hps for dblbuf 296 HPS hpsBuf = qt_alloc_mem_ps( w, h, dst_ps ); 297 // helper bitmap for dblbuf 298 HBITMAP hbmBuf = GpiCreateBitmap( hpsBuf, &bmh, 0, NULL, NULL ); 299 GpiSetBitmap( hpsBuf, hbmBuf ); 300 301 // grab the destination and get bits 302 POINTL ptls[] = { { 0, 0 }, { w, h }, { dx, dy } }; 303 GpiBitBlt ( hpsBuf, dst_ps, 3, ptls, ROP_SRCCOPY, BBO_IGNORE ); 304 GpiQueryBitmapBits( hpsBuf, 0, h, (PBYTE) dst, (PBITMAPINFO2) &bmh ); 305 306 // free dblbuf 204 307 GpiSetBitmap( hpsBuf, 0 ); 205 308 GpiDeleteBitmap( hbmBuf ); 206 309 qt_free_mem_ps( hpsBuf ); 207 } 208 } 209 210 //@@TODO (dmik): later 211 // 212 //#ifndef Q_OS_TEMP 213 //// For alpha blending, we must load the AlphaBlend() function at run time. 214 //#if !defined(AC_SRC_ALPHA) 215 //#define AC_SRC_ALPHA 0x01 216 //#endif 217 //typedef BOOL (WINAPI *ALPHABLEND)( HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION ); 218 //static HINSTANCE msimg32Lib = 0; 219 //static ALPHABLEND alphaBlend = 0; 220 //static bool loadAlphaBlendFailed = FALSE; 221 //static void cleanup_msimg32Lib() 222 //{ 223 // if ( msimg32Lib != 0 ) { 224 // FreeLibrary( msimg32Lib ); 225 // msimg32Lib = 0; 226 // alphaBlend = 0; 227 // loadAlphaBlendFailed = FALSE; 228 // } 229 //} 230 //#endif 231 // 232 ///* 233 // Try to do an AlphaBlend(). If it fails for some reasons, use BitBlt() 234 // instead. The arguments are like in the BitBlt() call. 235 //*/ 236 //void qt_AlphaBlend( HDC dst_dc, int dx, int dy, int sw, int sh, HDC src_dc, int sx, int sy, DWORD rop ) 237 //{ 238 //#ifndef Q_OS_TEMP 239 // BLENDFUNCTION blend = { 240 // AC_SRC_OVER, 241 // 0, 242 // 255, 243 // AC_SRC_ALPHA 244 // }; 245 // if ( alphaBlend ) { 246 // alphaBlend( dst_dc, dx, dy, sw, sh, src_dc, sx, sy, sw, sh, blend ); 247 // } else { 248 // if ( !loadAlphaBlendFailed ) { 249 // // try to load msimg32.dll and get the function 250 // // AlphaBlend() 251 // loadAlphaBlendFailed = TRUE; 252 // msimg32Lib = LoadLibraryA( "msimg32" ); 253 // if ( msimg32Lib != 0 ) { 254 // qAddPostRoutine( cleanup_msimg32Lib ); 255 // alphaBlend = (ALPHABLEND) GetProcAddress( msimg32Lib, "AlphaBlend" ); 256 // loadAlphaBlendFailed = ( alphaBlend == 0 ); 257 // } 258 // } 259 // if ( loadAlphaBlendFailed ) 260 // BitBlt( dst_dc, dx, dy, sw, sh, src_dc, sx, sy, rop ); 261 // else 262 // alphaBlend( dst_dc, dx, dy, sw, sh, src_dc, sx, sy, sw, sh, blend ); 263 // } 264 //#else 265 // BitBlt( dst_dc, dx, dy, sw, sh, src_dc, sx, sy, rop ); 266 //#endif 267 //} 310 } else { 311 // get bits of the destination 312 GpiQueryBitmapBits( dst_ps, dy, h, (PBYTE) dst, (PBITMAPINFO2) &bmh ); 313 } 314 315 // get bits of the source pixmap 316 GpiQueryBitmapBits( src_ps, sy, h, (PBYTE) src, (PBITMAPINFO2) &bmh ); 317 318 uchar px_sz = depth / 8; 319 uchar *dst_ptr = dst + px_sz * dst_x; 320 uchar *src_ptr = src + px_sz * sx; 321 uchar *a_ptr = alpha ? alpha + sx : 0; 322 int dst_inc = dst_bpl - px_sz * w; 323 int src_inc = src_bpl - px_sz * w; 324 int px_skip = px_sz - 3; 325 326 // use two separate code paths to increase the speed slightly by 327 // eliminating one comparison op (a_ptr != 0) inside the most nested loop 328 if ( a_ptr ) { 329 for ( int y = 0; y < h; y++ ) { 330 for ( int x = 0; x < w; x++ ) { 331 uchar a = *(a_ptr++); 332 if ( a == 0 ) { 333 dst_ptr += px_sz; 334 src_ptr += px_sz; 335 continue; 336 } else if ( a == 255 ) { 337 *(dst_ptr++) = *(src_ptr++); 338 *(dst_ptr++) = *(src_ptr++); 339 *(dst_ptr++) = *(src_ptr++); 340 } else { 341 *dst_ptr += (*(src_ptr++) - *dst_ptr) * a / 255; 342 dst_ptr ++; 343 *dst_ptr += (*(src_ptr++) - *dst_ptr) * a / 255; 344 dst_ptr ++; 345 *dst_ptr += (*(src_ptr++) - *dst_ptr) * a / 255; 346 dst_ptr ++; 347 } 348 dst_ptr += px_skip; 349 src_ptr += px_skip; 350 } 351 dst_ptr += dst_inc; 352 src_ptr += src_inc; 353 } 354 } else { 355 for ( int y = 0; y < h; y++ ) { 356 for ( int x = 0; x < w; x++ ) { 357 uchar a = src_ptr [3]; 358 if ( a == 0 ) { 359 dst_ptr += px_sz; 360 src_ptr += px_sz; 361 continue; 362 } else if ( a == 255 ) { 363 *(dst_ptr++) = *(src_ptr++); 364 *(dst_ptr++) = *(src_ptr++); 365 *(dst_ptr++) = *(src_ptr++); 366 } else { 367 *dst_ptr += (*(src_ptr++) - *dst_ptr) * a / 255; 368 dst_ptr ++; 369 *dst_ptr += (*(src_ptr++) - *dst_ptr) * a / 255; 370 dst_ptr ++; 371 *dst_ptr += (*(src_ptr++) - *dst_ptr) * a / 255; 372 dst_ptr ++; 373 } 374 dst_ptr += px_skip; 375 src_ptr += px_skip; 376 } 377 dst_ptr += dst_inc; 378 src_ptr += src_inc; 379 } 380 } 381 382 // flush the dst buffer 383 { 384 bmh.cx = dst_w; 385 bmh.cy = h; 386 POINTL ptls[] = { { dx, dy }, { dx + w - 1, dy + h - 1 }, 387 { dst_x, 0 }, { dst_x + w, h } }; 388 GpiDrawBits( dst_ps, (PVOID) dst, (PBITMAPINFO2) &bmh, 4, ptls, 389 ROP_SRCCOPY, BBO_IGNORE ); 390 } 391 392 delete[] src; 393 delete[] dst; 394 } 268 395 269 396 void bitBlt( QPaintDevice *dst, int dx, int dy, … … 271 398 Qt::RasterOp rop, bool ignoreMask ) 272 399 { 273 if ( !src || !dst ) {400 if ( !src || !dst || sw == 0 || sh == 0 ) { 274 401 #if defined(QT_CHECK_NULL) 275 402 Q_ASSERT( src != 0 ); … … 288 415 int td = dst->devType(); // to device type 289 416 290 if ( sw <= 0 ) { // special width 291 if ( sw < 0 ) 292 sw = src->metric(QPaintDeviceMetrics::PdmWidth) - sx; 293 else 294 return; 295 } 296 if ( sh <= 0 ) { // special height 297 if ( sh < 0 ) 298 sh = src->metric(QPaintDeviceMetrics::PdmHeight) - sy; 299 else 300 return; 301 } 302 417 int src_w = src->metric(QPaintDeviceMetrics::PdmWidth); 418 int src_h = src->metric(QPaintDeviceMetrics::PdmHeight); 419 int dst_w = dst->metric(QPaintDeviceMetrics::PdmWidth); 420 int dst_h = dst->metric(QPaintDeviceMetrics::PdmHeight); 421 422 if ( sw < 0 ) // special width 423 sw = src_w - sx; 424 if ( sh < 0 ) // special height 425 sh = src_h - sy; 426 427 // ensure coordinates are within borders, clip if necessary 428 if ( sx < 0 || sy < 0 || sx + sw > src_w || sy + sh > src_h || 429 dx < 0 || dy < 0 || dx + sw > dst_w || dy + sh > dst_h ) 430 { 431 int tx = dx - sx; 432 int ty = dy - sy; 433 QRect dr( 0, 0, dst_w, dst_h ); // dst rect 434 QRect sr( tx, ty, src_w, src_h ); // src rect in dst coords 435 QRect bltr( dx, dy, sw, sh ); // blit rect in dst coords 436 bltr &= (dr & sr); 437 if (bltr.isEmpty()) 438 return; 439 dx = bltr.x(); 440 dy = bltr.y(); 441 sx = dx - tx; 442 sy = dy - ty; 443 sw = bltr.width(); 444 sh = bltr.height(); 445 } 446 303 447 if ( dst->paintingActive() && dst->isExtDev() ) { 304 448 QPixmap *pm; // output to picture/printer … … 423 567 }; 424 568 425 if ( src_pm && src_pm->data->realAlphaBits ) { 426 qWarning( "::bitBlt() for pixmaps with alpha is not yet implemented on OS/2" ); 427 //@@TODO (dmik): later 428 // if ( td == QInternal::Pixmap && ((QPixmap *)dst)->data->realAlphaBits ) 429 // QPixmap::bitBltAlphaPixmap( ((QPixmap *)dst), dx, dy, src_pm, sx, sy, sw, sh, TRUE ); 430 // else 431 // qt_AlphaBlend( dst_dc, dx, dy, sw, sh, src_dc, sx, sy, ropCodes[rop] ); 569 if ( td == QInternal::Pixmap ) { 570 // Ensure the auxiliary masked bitmap created for masking is destroyed 571 // (to cause it to be recreated when the destination is blitted next 572 // time). Also ensure the alpha channel of the destination pixmap is 573 // unfolded -- any GPI call will clear the high byte that may be storing 574 // the alpha bits, so the pixmap will appear as fully transparent. 575 QPixmap *dst_pm = (QPixmap *) dst; 576 if ( dst_pm->data->mask ) 577 dst_pm->prepareForMasking( FALSE, TRUE ); 578 if ( dst_pm->data->hasRealAlpha ) 579 dst_pm->unfoldAlphaChannel(); 580 } 581 582 if ( src_pm && src_pm->data->hasRealAlpha && !ignoreMask ) { 583 int dst_w = 0; // implies grab_dest = true 584 if ( td == QInternal::Pixmap ) 585 dst_w = ((QPixmap *) dst)->data->w; // implies grab_dest = false 586 drawAlphaPixmap( dst_ps, dst_w, src_ps, src_pm->data->w, 587 src_pm->data->realAlphaBits, 588 dx, fdy, sx, fsy, sw, sh, QPixmap::trueColorDepth() ); 432 589 } else if ( mask ) { 433 if ( /*src_pm &&*/ td==QInternal::Pixmap && ((QPixmap *)dst)->data->realAlphaBits ) {434 qWarning( "::bitBlt() for pixmaps with alpha is not yet implemented on OS/2" );435 //@@TODO (dmik): later436 // src_pm->convertToAlphaPixmap();437 // QPixmap::bitBltAlphaPixmap( (QPixmap *)dst, dx, dy, src_pm, sx, sy, sw, sh, TRUE );438 } else {439 590 #if 0 440 //@@TODO (dmik): unfortunately, this nice method of setting the mask as a 441 // pattern and using the corresponding ROPs to do masking in one step 442 // willnot apways work on many video drivers (including SDD/SNAP) since443 // they can spontaneously simplify the bitmap set as a pattern (for example, 444 // take only first 8 pixels of the mask width), which will produce wrong 445 //results.446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 591 // Unfortunately, this nice method of setting the mask as a pattern 592 // and using the corresponding ROPs to do masking in one step will 593 // not apways work on many video drivers (including SDD/SNAP) since 594 // they can spontaneously simplify the bitmap set as a pattern (for 595 // example, take only first 8 pixels of the mask width), which will 596 // produce wrong results. 597 const ULONG AllAreaAttrs = 598 ABB_COLOR | ABB_BACK_COLOR | 599 ABB_MIX_MODE | ABB_BACK_MIX_MODE | 600 ABB_SET | ABB_SYMBOL | ABB_REF_POINT; 601 AREABUNDLE oldAb; 602 GpiQueryAttrs( dst_ps, PRIM_AREA, AllAreaAttrs, (PBUNDLE) &oldAb ); 603 AREABUNDLE newAb = { 604 CLR_TRUE, CLR_FALSE, FM_OVERPAINT, BM_OVERPAINT, 605 LCID_QTMaskBitmap, 0, ptls [0] 606 }; 607 GpiSetBitmap( mask->hps, 0 ); 608 GpiSetBitmapId( dst_ps, mask->hbm(), LCID_QTMaskBitmap ); 609 GpiSetAttrs( dst_ps, PRIM_AREA, AllAreaAttrs, 0, (PBUNDLE) &newAb ); 610 // we use the same rop codes for masked bitblt after setting the 611 // low half of the rop byte to 0xA, which means destination bits 612 // should be preserved where the corresponding bits in the mask 613 // are zeroes. 614 GpiBitBlt( dst_ps, src_ps, 3, ptls, (qt_ropCodes_2ROP[rop] & 0xF0) | 0x0A, BBO_IGNORE ); 615 GpiSetAttrs( dst_ps, PRIM_AREA, AllAreaAttrs, 0, (PBUNDLE) &oldAb ); 616 GpiDeleteSetId( dst_ps, LCID_QTMaskBitmap ); 617 GpiSetBitmap( mask->hps, mask->hbm() ); 467 618 #else 468 src_pm->prepareForMasking( TRUE ); 469 drawMaskedPixmap( 470 dst_ps, dst->metric( QPaintDeviceMetrics::PdmDepth ), 471 src_ps, src_pm->data->w, src_pm->data->h, 472 src_pm->data->selfmask ? 0 : mask->hps, 473 dx, fdy, sx, fsy, sw, sh, rop 474 ); 475 src_pm->prepareForMasking( FALSE ); 476 #endif 477 } 619 bool grab_dest = td != QInternal::Pixmap; 620 src_pm->prepareForMasking( TRUE ); 621 drawMaskedPixmap( 622 dst_ps, dst->metric( QPaintDeviceMetrics::PdmDepth ), grab_dest, 623 src_ps, src_pm->data->selfmask ? 0 : mask->hps, 624 dx, fdy, sx, fsy, sw, sh, rop ); 625 src_pm->prepareForMasking( FALSE ); 626 #endif 478 627 } else { 479 if ( td==QInternal::Pixmap && ((QPixmap *)dst)->isQBitmap() ) { 480 GpiBitBlt( dst_ps, src_ps, 3, ptls, qt_ropCodes_2ROP[rop], BBO_IGNORE ); 481 } else if ( src_pm && td==QInternal::Pixmap && ((QPixmap *)dst)->data->realAlphaBits ) { 482 qWarning( "::bitBlt() for pixmaps with alpha is not yet implemented on OS/2" ); 483 //@@TODO (dmik): later 484 // QPixmap *dst_pm = (QPixmap *)dst; 485 // if ( rop == Qt::CopyROP ) { 486 // src_pm->convertToAlphaPixmap(); 487 // QPixmap::bitBltAlphaPixmap( dst_pm, dx, dy, src_pm, sx, sy, sw, sh, TRUE ); 488 // } else { 489 // src_pm->convertToAlphaPixmap(); 490 // if ( dst_pm->mask() ) { 491 // int width = QMIN( dst_pm->mask()->width()-dx, sw ); 492 // int height = QMIN( dst_pm->mask()->height()-dy, sh ); 493 // MaskBlt( dst_dc, dx, dy, width, height, src_pm->hdc, sx, sy, dst_pm->mask()->hbm(), 494 // dx, dy, MAKEROP4(0x00aa0000,ropCodes[rop]) ); 495 // } else { 496 // BitBlt( dst_dc, dx, dy, sw, sh, src_pm->hdc, sx, sy, ropCodes[rop] ); 497 // } 498 // } 499 } else { 500 GpiBitBlt( dst_ps, src_ps, 3, ptls, qt_ropCodes_2ROP[rop], BBO_IGNORE ); 501 } 502 } 628 GpiBitBlt( dst_ps, src_ps, 3, ptls, qt_ropCodes_2ROP[rop], BBO_IGNORE ); 629 } 630 503 631 if ( src_tmp ) 504 632 WinReleasePS( src_ps );
Note:
See TracChangeset
for help on using the changeset viewer.