int width = bmp.GetWidth(),
height = bmp.GetHeight();
- if ( !useMask )
+ HBITMAP hbmpMask = 0;
+
+ if ( useMask )
+ {
+ wxMask *mask = bmp.GetMask();
+ if ( mask )
+ hbmpMask = (HBITMAP)mask->GetMaskBitmap();
+
+ if ( !hbmpMask )
+ {
+ // don't give assert here because this would break existing
+ // programs - just silently ignore useMask parameter
+ useMask = FALSE;
+ }
+ }
+
+ if ( useMask )
+ {
+#ifdef __WIN32__
+ HDC hdcMem = ::CreateCompatibleDC(GetHdc());
+ ::SelectObject(hdcMem, GetHbitmapOf(bmp));
+
+ // this will only work if the transparent part of our bitmap is black
+ // because it is combined with the destination rectangle using OR, so
+ // it won't be really transparent otherwise - I don't know what to do
+ // about it, may be use MAKEROP4(SRCCOPY, DSTINVERT) twice? Or create a
+ // copy of the bitmap with the transparent part replaced with black
+ // pixels?
+ bool ok = ::MaskBlt(GetHdc(), x, y, width, height,
+ hdcMem, 0, 0,
+ hbmpMask, 0, 0,
+ MAKEROP4(SRCCOPY, SRCPAINT)) != 0;
+ ::DeleteDC(hdcMem);
+
+ if ( !ok )
+#endif // Win32
+ {
+ // VZ: this is incorrect, Blit() doesn't (and can't) draw
+ // transparently, but it's still better than nothing at all
+
+ // Rather than reproduce wxDC::Blit, let's do it at the wxWin API level
+ wxMemoryDC memDC;
+ memDC.SelectObject(bmp);
+
+ Blit(x, y, width, height, &memDC, 0, 0, wxCOPY, useMask);
+
+ memDC.SelectObject(wxNullBitmap);
+ }
+ }
+ else // no mask, just use BitBlt()
{
HDC cdc = GetHdc();
HDC memdc = ::CreateCompatibleDC( cdc );
::SetTextColor(GetHdc(), old_textground);
::SetBkColor(GetHdc(), old_background);
}
- else
- {
- // Rather than reproduce wxDC::Blit, let's do it at the wxWin API level
- wxMemoryDC memDC;
- memDC.SelectObject(bmp);
-
- Blit(x, y, width, height, &memDC, 0, 0, wxCOPY, useMask);
-
- memDC.SelectObject(wxNullBitmap);
- }
}
void wxDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y)
{
m_logicalFunction = function;
- SetRop((WXHDC) m_hDC);
+ SetRop(m_hDC);
}
void wxDC::SetRop(WXHDC dc)
{
- if (!dc || m_logicalFunction < 0)
+ if ( !dc || m_logicalFunction < 0 )
return;
- int c_rop;
-
+ int rop;
+
switch (m_logicalFunction)
{
- case wxXOR: c_rop = R2_XORPEN; break;
- case wxINVERT: c_rop = R2_NOT; break;
- case wxOR_REVERSE: c_rop = R2_MERGEPENNOT; break;
- case wxAND_REVERSE: c_rop = R2_MASKPENNOT; break;
- case wxCLEAR: c_rop = R2_WHITE; break;
- case wxSET: c_rop = R2_BLACK; break;
- case wxOR_INVERT: c_rop = R2_MERGENOTPEN; break;
- case wxAND: c_rop = R2_MASKPEN; break;
- case wxOR: c_rop = R2_MERGEPEN; break;
- case wxEQUIV: c_rop = R2_NOTXORPEN; break;
- case wxNAND: c_rop = R2_NOTMASKPEN; break;
- case wxAND_INVERT: c_rop = R2_MASKNOTPEN; break;
- case wxCOPY: c_rop = R2_COPYPEN; break;
- case wxNO_OP: c_rop = R2_NOP; break;
- case wxSRC_INVERT: c_rop = R2_NOTCOPYPEN; break;
- case wxNOR: c_rop = R2_NOTMERGEPEN; break;
+ case wxXOR: rop = R2_XORPEN; break;
+ case wxINVERT: rop = R2_NOT; break;
+ case wxOR_REVERSE: rop = R2_MERGEPENNOT; break;
+ case wxAND_REVERSE: rop = R2_MASKPENNOT; break;
+ case wxCLEAR: rop = R2_WHITE; break;
+ case wxSET: rop = R2_BLACK; break;
+ case wxOR_INVERT: rop = R2_MERGENOTPEN; break;
+ case wxAND: rop = R2_MASKPEN; break;
+ case wxOR: rop = R2_MERGEPEN; break;
+ case wxEQUIV: rop = R2_NOTXORPEN; break;
+ case wxNAND: rop = R2_NOTMASKPEN; break;
+ case wxAND_INVERT: rop = R2_MASKNOTPEN; break;
+ case wxCOPY: rop = R2_COPYPEN; break;
+ case wxNO_OP: rop = R2_NOP; break;
+ case wxSRC_INVERT: rop = R2_NOTCOPYPEN; break;
+ case wxNOR: rop = R2_NOTMERGEPEN; break;
default:
- {
wxFAIL_MSG( wxT("unsupported logical function") );
- break;
- }
+ return;
}
- SetROP2((HDC) dc, c_rop);
+
+ SetROP2(GetHdc(), rop);
}
bool wxDC::StartDoc(const wxString& message)
DWORD dwRop = SRCCOPY;
switch (rop)
{
- case wxXOR: dwRop = SRCINVERT; break;
- case wxINVERT: dwRop = DSTINVERT; break;
- case wxOR_REVERSE: dwRop = 0x00DD0228; break;
- case wxAND_REVERSE: dwRop = SRCERASE; break;
- case wxCLEAR: dwRop = BLACKNESS; break;
- case wxSET: dwRop = WHITENESS; break;
- case wxOR_INVERT: dwRop = MERGEPAINT; break;
- case wxAND: dwRop = SRCAND; break;
- case wxOR: dwRop = SRCPAINT; break;
- case wxEQUIV: dwRop = 0x00990066; break;
- case wxNAND: dwRop = 0x007700E6; break;
- case wxAND_INVERT: dwRop = 0x00220326; break;
- case wxCOPY: dwRop = SRCCOPY; break;
- case wxNO_OP: dwRop = 0x00AA0029; break;
- case wxSRC_INVERT: dwRop = NOTSRCCOPY; break;
+ case wxXOR: dwRop = SRCINVERT; break;
+ case wxINVERT: dwRop = DSTINVERT; break;
+ case wxOR_REVERSE: dwRop = 0x00DD0228; break;
+ case wxAND_REVERSE: dwRop = SRCERASE; break;
+ case wxCLEAR: dwRop = BLACKNESS; break;
+ case wxSET: dwRop = WHITENESS; break;
+ case wxOR_INVERT: dwRop = MERGEPAINT; break;
+ case wxAND: dwRop = SRCAND; break;
+ case wxOR: dwRop = SRCPAINT; break;
+ case wxEQUIV: dwRop = 0x00990066; break;
+ case wxNAND: dwRop = 0x007700E6; break;
+ case wxAND_INVERT: dwRop = 0x00220326; break;
+ case wxCOPY: dwRop = SRCCOPY; break;
+ case wxNO_OP: dwRop = 0x00AA0029; break;
+ case wxSRC_INVERT: dwRop = NOTSRCCOPY; break;
case wxNOR: dwRop = NOTSRCCOPY; break;
default:
- {
wxFAIL_MSG( wxT("unsupported logical function") );
- break;
- }
+ return FALSE;
}
if (useMask)
{
#ifdef __WIN32__
+ // prepare the mask bitmap
HBITMAP hbmpMask = wxInvertMask((HBITMAP)mask->GetMaskBitmap());
+ // select the correct brush: the current one by default, background one
+ // if none
+ HBRUSH hbrNew;
+ if ( m_brush.Ok() )
+ {
+ hbrNew = (HBRUSH)m_brush.GetResourceHandle();
+ }
+ else if ( m_backgroundBrush.Ok() )
+ {
+ hbrNew = (HBRUSH)m_backgroundBrush.GetResourceHandle();
+ }
+ else
+ {
+ hbrNew = 0;
+ }
+
+ HGDIOBJ hbrOld = hbrNew ? ::SelectObject(GetHdc(), hbrNew) : 0;
+
// 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);
+ if ( hbrNew )
+ {
+ (void)::SelectObject(GetHdc(), hbrOld);
+ }
+
::DeleteObject(hbmpMask);
if ( !success )