]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/dc.cpp
(run-time) fix for !wxUSE_IPC build
[wxWidgets.git] / src / msw / dc.cpp
index 7031bf7bd9621bc17978e87d2b5c19af5ead129e..d6be602027d299e1eb4bba0baa6ae21f9c578172 100644 (file)
@@ -23,6 +23,7 @@
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
+#include "wx/msw/private.h" // needs to be before #include <commdlg.h>
 
 #ifdef __BORLANDC__
     #pragma hdrstop
     #include <print.h>
 #endif
 
-#include "wx/msw/private.h"
-
-#if !USE_SHARED_LIBRARY
     IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
-#endif
 
 // ---------------------------------------------------------------------------
 // constants
@@ -601,27 +598,85 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
 {
     if (!bmp.Ok())
         return;
-
+    
+    bool needsPixelCopy = FALSE ;
+    bool isPrinter = FALSE ;
+    if (IsKindOf(CLASSINFO(wxPrinterDC)) )
+    {
+        isPrinter = TRUE ;
+        if ( ::GetDeviceCaps((HDC) m_hDC, RASTERCAPS) & RC_STRETCHDIB )
+               {
+        }
+               else
+               {
+            needsPixelCopy = TRUE ;
+               }
+    }
     // If we're not drawing transparently, and not drawing to a printer,
     // optimize this function to use Windows functions.
-    if (!useMask && !IsKindOf(CLASSINFO(wxPrinterDC)))
+    if (!useMask && !needsPixelCopy)
     {
-        HDC cdc = GetHdc();
-        HDC memdc = ::CreateCompatibleDC( cdc );
-        HBITMAP hbitmap = (HBITMAP) bmp.GetHBITMAP( );
+        if ( isPrinter )
+        {
+            BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) ) ;
+            int iBitsSize = ((bmp.GetWidth() + 3 ) & ~3 ) * bmp.GetHeight() ;
+            
+            void* bits = malloc( iBitsSize ) ;
+            
+            memset( info , 0 , sizeof( BITMAPINFOHEADER ) ) ;
+            
+            info->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ) ;
+            info->bmiHeader.biWidth = bmp.GetWidth() ;
+            info->bmiHeader.biHeight = bmp.GetHeight() ;
+            info->bmiHeader.biPlanes = 1 ;
+            info->bmiHeader.biBitCount = 8 ;
+            info->bmiHeader.biCompression = BI_RGB ;
+            
+            HDC display = GetDC( NULL ) ;
+            if ( GetDIBits( display , (HBITMAP) bmp.GetHBITMAP( ) , 0 , bmp.GetHeight() , bits , info , DIB_RGB_COLORS ) )
+            {
+                StretchDIBits( (HDC) m_hDC, 
+                    x, y, bmp.GetWidth(), bmp.GetHeight() , 
+                    0 , 0 ,bmp.GetWidth(), bmp.GetHeight() , 
+                    bits , info , DIB_RGB_COLORS , SRCCOPY ) ;
+            }
+            ReleaseDC( NULL , display ) ;
+            free ( bits ) ;
+            free( info ) ;
+        }
+        else
+        {
+            HDC cdc = GetHdc();
+            HDC memdc = ::CreateCompatibleDC( cdc );
+            HBITMAP hbitmap = (HBITMAP) bmp.GetHBITMAP( );
+            
+            wxASSERT_MSG( hbitmap, wxT("bitmap is ok but HBITMAP is NULL?") );
+            
+            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() );
+            }
 
-        wxASSERT_MSG( hbitmap, wxT("bitmap is ok but HBITMAP is NULL?") );
+            ::SelectObject( memdc, hbitmap );
+            ::BitBlt( cdc, x, y, bmp.GetWidth(), bmp.GetHeight(), memdc, 0, 0, SRCCOPY);
+            ::DeleteDC( memdc );
 
-        ::SelectObject( memdc, hbitmap );
-        ::BitBlt( cdc, x, y, bmp.GetWidth(), bmp.GetHeight(), memdc, 0, 0, SRCCOPY);
-        ::DeleteDC( memdc );
+            ::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);
-
+        
         /* Not sure if we need this. The mask should leave the
         * masked areas as per the original background of this DC.
         */
@@ -631,9 +686,9 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
         memDC.SetBackground(* GetBackground());
         memDC.Clear();
         */
-
+        
         Blit(x, y, bmp.GetWidth(), bmp.GetHeight(), & memDC, 0, 0, wxCOPY, useMask);
-
+        
         memDC.SelectObject(wxNullBitmap);
     }
 }
@@ -666,7 +721,7 @@ void wxDC::DrawAnyText(const wxString& text, wxCoord x, wxCoord y)
                                                           : OPAQUE);
 
     if ( ::TextOut(GetHdc(), XLOG2DEV(x), YLOG2DEV(y),
-                   text.c_str(), text.length()) != 0 )
+                   text.c_str(), text.length()) == 0 )
     {
         wxLogLastError("TextOut");
     }
@@ -684,28 +739,39 @@ void wxDC::DoDrawRotatedText(const wxString& text,
                              wxCoord x, wxCoord y,
                              double angle)
 {
-    if ( angle == 0.0 )
+    // we test that we have some font because otherwise we should still use the
+    // "else" part below to avoid that DrawRotatedText(angle = 180) and
+    // DrawRotatedText(angle = 0) use different fonts (we can't use the default
+    // font for drawing rotated fonts unfortunately)
+    if ( (angle == 0.0) && m_font.Ok() )
     {
         DoDrawText(text, x, y);
     }
     else
     {
+        // NB: don't take DEFAULT_GUI_FONT because it's not TrueType and so
+        //     can't have non zero orientation/escapement
+        wxFont font = m_font.Ok() ? m_font : *wxNORMAL_FONT;
+        HFONT hfont = (HFONT)font.GetResourceHandle();
         LOGFONT lf;
-        wxFillLogFont(&lf, &m_font);
+        if ( ::GetObject(hfont, sizeof(lf), &lf) == 0 )
+        {
+            wxLogLastError("GetObject(hfont)");
+        }
 
         // GDI wants the angle in tenth of degree
         long angle10 = (long)(angle * 10);
         lf.lfEscapement = angle10;
         lf. lfOrientation = angle10;
 
-        HFONT hfont = ::CreateFontIndirect(&lf);
+        hfont = ::CreateFontIndirect(&lf);
         if ( !hfont )
         {
             wxLogLastError("CreateFont");
         }
         else
         {
-            HFONT hfontOld = ::SelectObject(GetHdc(), hfont);
+            HFONT hfontOld = (HFONT)::SelectObject(GetHdc(), hfont);
 
             DrawAnyText(text, x, y);
 
@@ -723,7 +789,6 @@ void wxDC::DoDrawRotatedText(const wxString& text,
         // "upper left" and "upper right"
         CalcBoundingBox(x, y);
         CalcBoundingBox(x + w*cos(rad), y - h*sin(rad));
-        CalcBoundingBox(x + h*sin(rad), y + h*cos(rad));
 
         // "bottom left" and "bottom right"
         x += (wxCoord)(h*sin(rad));
@@ -1180,8 +1245,6 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
     wxCoord xsrc1 = xsrc;
     wxCoord ysrc1 = ysrc;
 
-    // Chris Breeze 18/5/98: use text foreground/background colours
-    // when blitting from 1-bit bitmaps
     COLORREF old_textground = ::GetTextColor(GetHdc());
     COLORREF old_background = ::GetBkColor(GetHdc());
     if (m_textForegroundColour.Ok())
@@ -1208,7 +1271,27 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
     SRCCOPY;
 
     bool success = TRUE;
-    if (useMask && source->m_selectedBitmap.Ok() && source->m_selectedBitmap.GetMask())
+    bool needsPixelCopy = FALSE ;
+    bool isPrinter = FALSE ;
+
+    if (IsKindOf(CLASSINFO(wxPrinterDC)) )
+    {
+        isPrinter = TRUE ;
+        if ( ::GetDeviceCaps((HDC) m_hDC, RASTERCAPS) & RC_STRETCHDIB )
+               {
+        }
+               else
+               {
+            needsPixelCopy = TRUE ;
+               }
+    }
+    if (useMask && !source->m_selectedBitmap.Ok())
+        return FALSE;
+
+    if (useMask && !source->m_selectedBitmap.GetMask())
+        useMask = FALSE;
+
+    if (useMask)
     {
 
 #if 0 // __WIN32__
@@ -1222,21 +1305,10 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
         else
 #endif
         {
-            // Old code
-#if 0
-            HDC dc_mask = CreateCompatibleDC((HDC) source->m_hDC);
-            ::SelectObject(dc_mask, (HBITMAP) source->m_selectedBitmap.GetMask()->GetMaskBitmap());
-            success = (BitBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height,
-                dc_mask, xsrc1, ysrc1, 0x00220326 /* NOTSRCAND */) != 0);
-            success = (BitBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height,
-                (HDC) source->m_hDC, xsrc1, ysrc1, SRCPAINT) != 0);
-            ::SelectObject(dc_mask, 0);
-            ::DeleteDC(dc_mask);
-#endif
             // New code from Chris Breeze, 15/7/98
             // Blit bitmap with mask
 
-            if (IsKindOf(CLASSINFO(wxPrinterDC)))
+            if (isPrinter)
             {
                 // If we are printing source colours are screen colours
                 // not printer colours and so we need copy the bitmap
@@ -1308,32 +1380,77 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
             }
         }
     }
-    else
+    else if (needsPixelCopy) // not masked, but we need pixel copy. Only true if it's a printer
     {
-        if (IsKindOf(CLASSINFO(wxPrinterDC)))
+        // If we are printing, source colours are screen colours
+        // not printer colours and so we need copy the bitmap
+        // pixel by pixel.
+        if (isPrinter)
         {
-            // If we are printing, source colours are screen colours
-            // not printer colours and so we need copy the bitmap
-            // pixel by pixel.
             HDC dc_src = (HDC) source->m_hDC;
-            RECT rect;
-            for (int x = 0; x < width; x++)
-            {
-                for (int y = 0; y < height; y++)
-                {
-                    HBRUSH brush = ::CreateSolidBrush(::GetPixel(dc_src, x, y));
-                    rect.left = xdest1 + x;   rect.right = rect.left + 1;
-                    rect.top = ydest1 + y;    rect.bottom = rect.top + 1;
-                    ::FillRect(GetHdc(), &rect, brush);
-                    ::DeleteObject(brush);
+               RECT rect;
+               for (int y = 0; y < height; y++)
+               {
+                // This is Stefan Csomor's optimisation, where
+                // identical adjacent pixels are drawn together.
+                   for (int x = 0; x < width; x++)
+                   {
+                       COLORREF col = ::GetPixel(dc_src, x, y) ;
+                       HBRUSH brush = ::CreateSolidBrush( col );
+
+                       rect.left = xdest1 + x;
+                       rect.top = ydest1 + y;
+                       while( (x + 1 < width) && (::GetPixel(dc_src, x + 1, y) == col ) )
+                       {
+                               ++x ;
+                       }
+                       rect.right = xdest1 + x + 1;
+                       rect.bottom = rect.top + 1;
+                       ::FillRect((HDC) m_hDC, &rect, brush);
+                       ::DeleteObject(brush);
                 }
-            }
-        }
+               }
+           }
         else
         {
-            success = (BitBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height, (HDC) source->m_hDC,
-                xsrc1, ysrc1, dwRop) != 0);
+            wxFAIL_MSG( "If needsPixelCopy is true, isPrinter should be true also." );
+        }
+    }
+    else if (isPrinter) // not masked, not pixel copy
+    {
+        wxBitmap& bmp = source->m_selectedBitmap ;
+        BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) ) ;
+        int iBitsSize = ((bmp.GetWidth() + 3 ) & ~3 ) * bmp.GetHeight() ;
+            
+        void* bits = malloc( iBitsSize ) ;
+            
+        memset( info , 0 , sizeof( BITMAPINFOHEADER ) ) ;
+            
+        info->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ) ;
+        info->bmiHeader.biWidth = bmp.GetWidth() ;
+        info->bmiHeader.biHeight = bmp.GetHeight() ;
+        info->bmiHeader.biPlanes = 1 ;
+        info->bmiHeader.biBitCount = 8 ;
+        info->bmiHeader.biCompression = BI_RGB ;
+            
+        HDC display = GetDC( NULL ) ;
+        if ( GetDIBits( display , (HBITMAP) bmp.GetHBITMAP( ) , 0 , bmp.GetHeight() , bits , info , DIB_RGB_COLORS ) )
+        {
+            success = (GDI_ERROR != StretchDIBits( (HDC) m_hDC,
+                    xdest1, ydest1, bmp.GetWidth(), bmp.GetHeight() ,
+                    xsrc1 , ysrc1 ,bmp.GetWidth(), bmp.GetHeight() ,
+                    bits , info , DIB_RGB_COLORS , SRCCOPY )) ;
         }
+        else
+            success = FALSE;
+        ReleaseDC( NULL , display ) ;
+        free ( bits ) ;
+        free( info ) ;
+    }
+    else // Not masked, not printer, not pixel copy
+    {
+        success = (BitBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height, (HDC) source->m_hDC,
+             xsrc1, ysrc1, dwRop) != 0);
     }
     ::SetTextColor(GetHdc(), old_textground);
     ::SetBkColor(GetHdc(), old_background);