+ wxMask *mask = NULL;
+ if ( useMask )
+ {
+ const wxBitmap& bmp = source->m_selectedBitmap;
+ mask = bmp.GetMask();
+
+ if ( !(bmp.Ok() && mask && mask->GetMaskBitmap()) )
+ {
+ // don't give assert here because this would break existing
+ // programs - just silently ignore useMask parameter
+ useMask = FALSE;
+ }
+ }
+
+ COLORREF old_textground = ::GetTextColor(GetHdc());
+ COLORREF old_background = ::GetBkColor(GetHdc());
+ if (m_textForegroundColour.Ok())
+ {
+ ::SetTextColor(GetHdc(), m_textForegroundColour.GetPixel() );
+ }
+ if (m_textBackgroundColour.Ok())
+ {
+ ::SetBkColor(GetHdc(), m_textBackgroundColour.GetPixel() );
+ }
+
+ DWORD dwRop = rop == wxCOPY ? SRCCOPY :
+ rop == wxCLEAR ? WHITENESS :
+ rop == wxSET ? BLACKNESS :
+ rop == wxINVERT ? DSTINVERT :
+ rop == wxAND ? MERGECOPY :
+ rop == wxOR ? MERGEPAINT :
+ rop == wxSRC_INVERT ? NOTSRCCOPY :
+ rop == wxXOR ? SRCINVERT :
+ rop == wxOR_REVERSE ? MERGEPAINT :
+ rop == wxAND_REVERSE ? SRCERASE :
+ rop == wxSRC_OR ? SRCPAINT :
+ rop == wxSRC_AND ? SRCAND :
+ SRCCOPY;
+
+ bool success;
+
+ if (useMask)
+ {
+#ifdef __WIN32__
+ HBITMAP hbmpMask = wxInvertMask((HBITMAP)mask->GetMaskBitmap());
+
+ // we want the part of the image corresponding to the mask to be
+ // transparent, i.e. do PATCOPY there and apply dwRop elsewhere
+ const wxColour& colBg = m_backgroundBrush.GetColour();
+ HBRUSH hbrBg = (HBRUSH)::CreateSolidBrush(wxColourToRGB(colBg));
+ HBRUSH hbrOld = (HBRUSH)::SelectObject(GetHdc(), hbrBg);
+
+ success = ::MaskBlt(GetHdc(), xdest, ydest, width, height,
+ GetHdcOf(*source), xsrc, ysrc,
+ hbmpMask, 0, 0,
+ MAKEROP4(PATCOPY, dwRop)) != 0;
+
+ (void)::SelectObject(GetHdc(), hbrOld);
+ ::DeleteObject(hbrOld);
+ ::DeleteObject(hbmpMask);
+
+ if ( !success )
+#endif // Win32
+ {
+ // Blit bitmap with mask
+
+ // create a temp buffer bitmap and DCs to access it and the mask
+ HDC dc_mask = ::CreateCompatibleDC(GetHdcOf(*source));
+ HDC dc_buffer = ::CreateCompatibleDC(GetHdc());
+ HBITMAP buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height);
+ ::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap());
+ ::SelectObject(dc_buffer, buffer_bmap);
+
+ // copy dest to buffer
+ if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+ GetHdc(), xdest, ydest, SRCCOPY) )
+ {
+ wxLogLastError("BitBlt");
+ }
+
+ // copy src to buffer using selected raster op
+ if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+ GetHdcOf(*source), xsrc, ysrc, dwRop) )
+ {
+ wxLogLastError("BitBlt");
+ }
+
+ // set masked area in buffer to BLACK (pixel value 0)
+ COLORREF prevBkCol = ::SetBkColor(GetHdc(), RGB(255, 255, 255));
+ COLORREF prevCol = ::SetTextColor(GetHdc(), RGB(0, 0, 0));
+ if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+ dc_mask, xsrc, ysrc, SRCAND) )
+ {
+ wxLogLastError("BitBlt");
+ }
+
+ // set unmasked area in dest to BLACK
+ ::SetBkColor(GetHdc(), RGB(0, 0, 0));
+ ::SetTextColor(GetHdc(), RGB(255, 255, 255));
+ if ( !::BitBlt(GetHdc(), xdest, ydest, (int)width, (int)height,
+ dc_mask, xsrc, ysrc, SRCAND) )
+ {
+ wxLogLastError("BitBlt");
+ }
+ ::SetBkColor(GetHdc(), prevBkCol); // restore colours to original values
+ ::SetTextColor(GetHdc(), prevCol);
+
+ // OR buffer to dest
+ success = ::BitBlt(GetHdc(), xdest, ydest,
+ (int)width, (int)height,
+ dc_buffer, 0, 0, SRCPAINT) != 0;
+ if ( !success )
+ {
+ wxLogLastError("BitBlt");
+ }
+
+ // tidy up temporary DCs and bitmap
+ ::SelectObject(dc_mask, 0);
+ ::DeleteDC(dc_mask);
+ ::SelectObject(dc_buffer, 0);
+ ::DeleteDC(dc_buffer);
+ ::DeleteObject(buffer_bmap);
+ }
+ }
+ else // no mask, just BitBlt() it
+ {
+ success = ::BitBlt(GetHdc(), xdest, ydest,
+ (int)width, (int)height,
+ GetHdcOf(*source), xsrc, ysrc, dwRop) != 0;
+ if ( !success )
+ {
+ wxLogLastError("BitBlt");
+ }
+ }
+
+ ::SetTextColor(GetHdc(), old_textground);
+ ::SetBkColor(GetHdc(), old_background);
+
+ return success;