Ignore:
Timestamp:
Jan 29, 2006, 8:56:21 PM (20 years ago)
Author:
dmik
Message:

Implemented alpha blending for pixmaps.
Improved blitting of masked pixmaps.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel/qpaintdevice_pm.cpp

    r8 r59  
    125125
    126126// 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     };
     127static 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{
    138131    IMAGEBUNDLE oldIb;
    139132
    140133    if ( !mask_ps ) {
    141134        // self-masked pixmap
     135        POINTL ptls[] = { { dx, dy }, { dx + w, dy + h },
     136                          { sx, sy } };
    142137        IMAGEBUNDLE newIb;
    143138        GpiQueryAttrs( dst_ps, PRIM_IMAGE, IBB_BACK_MIX_MODE, (PBUNDLE) &oldIb );
     
    148143    } else {
    149144        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       
    163188        // query the destination color for 1-bpp bitmaps
    164189        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
    171221        // draw the mask: make non-transparent pixels (corresponding to
    172222        // ones in the mask) black. skip this step when rop = XorROP
    173223        // 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       
    178230        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 );
    194235        } else {
    195236            // draw masked pixmap; transparent pixels are zeroed there
    196237            // 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 );
    199242        }
    200243
    201244        // 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       
    203251        // 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
     265static 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
    204307        GpiSetBitmap( hpsBuf, 0 );
    205308        GpiDeleteBitmap( hbmBuf );
    206309        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}
    268395
    269396void bitBlt( QPaintDevice *dst, int dx, int dy,
     
    271398             Qt::RasterOp rop, bool ignoreMask  )
    272399{
    273     if ( !src || !dst ) {
     400    if ( !src || !dst || sw == 0 || sh == 0 ) {
    274401#if defined(QT_CHECK_NULL)
    275402        Q_ASSERT( src != 0 );
     
    288415    int td = dst->devType();                    // to device type
    289416
    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   
    303447    if ( dst->paintingActive() && dst->isExtDev() ) {
    304448        QPixmap *pm;                            // output to picture/printer
     
    423567    };
    424568
    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() );
    432589    } 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): later
    436 //          src_pm->convertToAlphaPixmap();
    437 //          QPixmap::bitBltAlphaPixmap( (QPixmap *)dst, dx, dy, src_pm, sx, sy, sw, sh, TRUE );
    438         } else {
    439590#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 //  will not apways work on many video drivers (including SDD/SNAP) since
    443 //  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             const ULONG AllAreaAttrs =
    447                 ABB_COLOR | ABB_BACK_COLOR |
    448                 ABB_MIX_MODE | ABB_BACK_MIX_MODE |
    449                 ABB_SET | ABB_SYMBOL | ABB_REF_POINT;
    450             AREABUNDLE oldAb;
    451             GpiQueryAttrs( dst_ps, PRIM_AREA, AllAreaAttrs, (PBUNDLE) &oldAb );
    452             AREABUNDLE newAb = {
    453                 CLR_TRUE, CLR_FALSE, FM_OVERPAINT, BM_OVERPAINT,
    454                 LCID_QTMaskBitmap, 0, ptls [0]
    455             };
    456             GpiSetBitmap( mask->hps, 0 );
    457             GpiSetBitmapId( dst_ps, mask->hbm(), LCID_QTMaskBitmap );
    458             GpiSetAttrs( dst_ps, PRIM_AREA, AllAreaAttrs, 0, (PBUNDLE) &newAb );
    459             // we use the same rop codes for masked bitblt after setting the
    460             // low half of the rop byte to 0xA, which means destination bits
    461             // should be preserved where the corresponding bits in the mask
    462             // are zeroes.
    463             GpiBitBlt( dst_ps, src_ps, 3, ptls, (qt_ropCodes_2ROP[rop] & 0xF0) | 0x0A, BBO_IGNORE );
    464             GpiSetAttrs( dst_ps, PRIM_AREA, AllAreaAttrs, 0, (PBUNDLE) &oldAb );
    465             GpiDeleteSetId( dst_ps, LCID_QTMaskBitmap );
    466             GpiSetBitmap( mask->hps, mask->hbm() );
     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() );
    467618#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
    478627    } 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
    503631    if ( src_tmp )
    504632        WinReleasePS( src_ps );
Note: See TracChangeset for help on using the changeset viewer.