// 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"
-
IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
// ---------------------------------------------------------------------------
{
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.
*/
memDC.SetBackground(* GetBackground());
memDC.Clear();
*/
-
+
Blit(x, y, bmp.GetWidth(), bmp.GetHeight(), & memDC, 0, 0, wxCOPY, useMask);
-
+
memDC.SelectObject(wxNullBitmap);
}
}
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())
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__
// 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
}
}
}
- else
+ else if (needsPixelCopy) // not masked, but we need pixel copy. Only true if it's a printer
{
// 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 (isPrinter)
{
HDC dc_src = (HDC) source->m_hDC;
RECT rect;
{
// 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) ;
::DeleteObject(brush);
}
}
-/*
- 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);
- }
- }
-*/
}
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);