]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/dc.cpp
Added ShowFullScreen
[wxWidgets.git] / src / msw / dc.cpp
index 91443fae020f077014e65e5ef067f25d45de3ba1..c720b36fa35d304be3ed4af3cd9bafa4e24680db 100644 (file)
@@ -657,7 +657,56 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
     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 );
@@ -683,16 +732,6 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
         ::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)
@@ -992,41 +1031,40 @@ void wxDC::SetLogicalFunction(int function)
 {
     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)
@@ -1278,27 +1316,25 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
     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;
     }
 
 
@@ -1307,21 +1343,40 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
     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 )