]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/dc.cpp
Initial revision
[wxWidgets.git] / src / msw / dc.cpp
index 9b43f56bb7f7181c54b9a4f5074367bba73f149f..3cffc336ee304d28f0f62fe309e970d53cc4d60f 100644 (file)
@@ -58,9 +58,7 @@
 
 #include "wx/msw/private.h"
 
-#if !USE_SHARED_LIBRARY
     IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
-#endif
 
 // ---------------------------------------------------------------------------
 // constants
@@ -602,19 +600,63 @@ 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( );
-
-        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 );
+       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?") );
+
+               ::SelectObject( memdc, hbitmap );
+               ::BitBlt( cdc, x, y, bmp.GetWidth(), bmp.GetHeight(), memdc, 0, 0, SRCCOPY);
+               ::DeleteDC( memdc );
+        }
     }
     else
     {
@@ -734,7 +776,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));
@@ -1233,17 +1274,6 @@ 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
 
@@ -1321,11 +1351,37 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
     }
     else
     {
+        // If we are printing, source colours are screen colours
+        // not printer colours and so we need copy the bitmap
+        // pixel by pixel.
         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.
+            HDC dc_src = (HDC) source->m_hDC;
+               RECT rect;
+               for (int y = 0; y < height; y++)
+               {
+                // This is Stefan Csomor's optimisation, where
+                // identical adjacent pixels are drawn together.
+                // We still need a faster way of drawing bitmaps,
+                // perhaps converting to a DIB first and using SetDIBitsToDevice.
+                   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);
+                }
+               }
+/*
             HDC dc_src = (HDC) source->m_hDC;
             RECT rect;
             for (int x = 0; x < width; x++)
@@ -1339,7 +1395,8 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
                     ::DeleteObject(brush);
                 }
             }
-        }
+*/
+           }
         else
         {
             success = (BitBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height, (HDC) source->m_hDC,