#include "wx/msw/private.h"
-#if !USE_SHARED_LIBRARY
IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
-#endif
// ---------------------------------------------------------------------------
// constants
{
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
{
// 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);
}
}
: OPAQUE);
if ( ::TextOut(GetHdc(), XLOG2DEV(x), YLOG2DEV(y),
- text.c_str(), text.length()) != 0 )
+ text.c_str(), text.length()) == 0 )
{
wxLogLastError("TextOut");
}
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);
// "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));
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
}
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++)
::DeleteObject(brush);
}
}
- }
+*/
+ }
else
{
success = (BitBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height, (HDC) source->m_hDC,