use wxDIB class instead of duplicating DDB -> DIB conversion code once again (aaaargh, just how many copies of the same code with slightly different bugs in each case can we have??)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19788 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2003-03-24 23:07:53 +00:00
parent cdd732de07
commit 2f52b4e15c

View File

@ -38,6 +38,7 @@
#if wxUSE_PRINTING_ARCHITECTURE
#include "wx/msw/private.h"
#include "wx/msw/dib.h"
#include "wx/dcprint.h"
#include "math.h"
@ -50,7 +51,7 @@
#endif
// mingw32 defines GDI_ERROR incorrectly
#ifdef __GNUWIN32__
#if defined(__GNUWIN32__) || !defined(GDI_ERROR)
#undef GDI_ERROR
#define GDI_ERROR ((int)-1)
#endif
@ -278,83 +279,6 @@ static bool wxGetDefaultDeviceName(wxString& deviceName, wxString& portName)
return ( deviceName != wxT("") );
}
#if 0
// This uses defaults, except for orientation, so we should eliminate this function
// and use the 2nd form (passing wxPrintData) instead.
WXHDC wxGetPrinterDC(int orientation)
{
HDC hDC;
LPDEVMODE lpDevMode = NULL;
LPDEVNAMES lpDevNames;
LPSTR lpszDriverName;
LPSTR lpszDeviceName;
LPSTR lpszPortName;
PRINTDLG pd;
// __GNUWIN32__ has trouble believing PRINTDLG is 66 bytes - thinks it is 68
#ifdef __GNUWIN32__
pd.lStructSize = 66; // sizeof(PRINTDLG);
#else
pd.lStructSize = sizeof(PRINTDLG);
#endif
pd.hwndOwner = (HWND)NULL;
pd.hDevMode = NULL; // Will be created by PrintDlg
pd.hDevNames = NULL; // Ditto
pd.Flags = PD_RETURNDEFAULT;
pd.nCopies = 1;
if (!PrintDlg((LPPRINTDLG)&pd))
{
if ( pd.hDevMode )
GlobalFree(pd.hDevMode);
if (pd.hDevNames)
GlobalFree(pd.hDevNames);
return(0);
}
if (!pd.hDevNames)
{
if ( pd.hDevMode )
GlobalFree(pd.hDevMode);
}
lpDevNames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
lpszDriverName = (LPSTR)lpDevNames + lpDevNames->wDriverOffset;
lpszDeviceName = (LPSTR)lpDevNames + lpDevNames->wDeviceOffset;
lpszPortName = (LPSTR)lpDevNames + lpDevNames->wOutputOffset;
GlobalUnlock(pd.hDevNames);
if ( pd.hDevMode )
{
lpDevMode = (DEVMODE*) GlobalLock(pd.hDevMode);
lpDevMode->dmOrientation = orientation;
lpDevMode->dmFields |= DM_ORIENTATION;
}
#ifdef __WIN32__
hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (DEVMODE *)lpDevMode);
#else
hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (LPSTR)lpDevMode);
#endif
if (pd.hDevMode && lpDevMode)
GlobalUnlock(pd.hDevMode);
if (pd.hDevNames)
{
GlobalFree(pd.hDevNames);
pd.hDevNames=NULL;
}
if (pd.hDevMode)
{
GlobalFree(pd.hDevMode);
pd.hDevMode=NULL;
}
return (WXHDC) hDC;
}
#endif // 0
// Gets an HDC for the specified printer configuration
WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
{
@ -411,16 +335,47 @@ WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
// wxPrinterDC bit blitting/bitmap drawing
// ----------------------------------------------------------------------------
// Win16 doesn't define GDI_ERROR.
#ifndef GDI_ERROR
#define GDI_ERROR -1
#endif
// helper of DoDrawBitmap() and DoBlit()
static
bool DrawBitmapUsingStretchDIBits(HDC hdc,
const wxBitmap& bmp,
wxCoord x, wxCoord y)
{
wxDIB dib(bmp);
if ( !dib.IsOk() )
return FALSE;
// Just in case we want to go back to using 8 bits for
// any reason: set this to 0 for 8 bits.
#define wxUSE_DRAWBITMAP_24BITS 1
DIBSECTION ds;
if ( !::GetObject(dib.GetHandle(), sizeof(ds), &ds) )
{
wxLogLastError(_T("GetObject(DIBSECTION)"));
void wxPrinterDC::DoDrawBitmap(const wxBitmap &bmp,
return FALSE;
}
// ok, we've got all data we need, do blit it
if ( ::StretchDIBits
(
hdc,
x, y,
ds.dsBmih.biWidth, ds.dsBmih.biHeight,
0, 0,
ds.dsBmih.biWidth, ds.dsBmih.biHeight,
ds.dsBm.bmBits,
(LPBITMAPINFO)&ds.dsBmih,
DIB_RGB_COLORS,
SRCCOPY
) == GDI_ERROR )
{
wxLogLastError(wxT("StretchDIBits"));
return FALSE;
}
return TRUE;
}
void wxPrinterDC::DoDrawBitmap(const wxBitmap& bmp,
wxCoord x, wxCoord y,
bool useMask)
{
@ -429,83 +384,10 @@ void wxPrinterDC::DoDrawBitmap(const wxBitmap &bmp,
int width = bmp.GetWidth(),
height = bmp.GetHeight();
if ( ::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB )
{
#if wxUSE_DIB_FOR_BITMAP
if ( bmp.IsDIB() )
{
DIBSECTION dib;
if ( ::GetObject(GetHbitmapOf(bmp),
sizeof(dib),
&dib) == sizeof(dib) )
{
if ( ::StretchDIBits
(
GetHdc(),
x, y,
width, height,
0, 0,
width, height,
dib.dsBm.bmBits,
(LPBITMAPINFO)&dib.dsBmih,
DIB_RGB_COLORS,
SRCCOPY
) == GDI_ERROR )
{
wxLogLastError(wxT("StretchDIBits"));
}
}
else
{
wxLogLastError(wxT("GetObject"));
}
}
else
#endif // wxUSE_DIB_FOR_BITMAP
{
BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) );
memset( info, 0, sizeof( BITMAPINFOHEADER ) );
#if wxUSE_DRAWBITMAP_24BITS
int iBitsSize = (((width * 3) + 3 ) & ~3 ) * height;
#else
int iBitsSize = ((width + 3 ) & ~3 ) * height ;
#endif
void* bits = malloc( iBitsSize );
info->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
info->bmiHeader.biWidth = width;
info->bmiHeader.biHeight = height;
info->bmiHeader.biPlanes = 1;
#if wxUSE_DRAWBITMAP_24BITS
info->bmiHeader.biBitCount = 24;
#else
info->bmiHeader.biBitCount = 8;
#endif
info->bmiHeader.biCompression = BI_RGB;
ScreenHDC display;
if ( GetDIBits(display, GetHbitmapOf(bmp), 0,
bmp.GetHeight(), bits, info,
DIB_RGB_COLORS) )
{
if ( ::StretchDIBits(GetHdc(), x, y,
width, height,
0 , 0, width, height,
bits, info,
DIB_RGB_COLORS, SRCCOPY) == GDI_ERROR )
{
wxLogLastError(wxT("StretchDIBits"));
}
}
free(bits);
free(info);
}
}
else // no support for StretchDIBits()
if ( !(::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB) ||
!DrawBitmapUsingStretchDIBits(GetHdc(), bmp, x, y) )
{
// no support for StretchDIBits() or an error occured if we got here
wxMemoryDC memDC;
memDC.SelectObject(bmp);
@ -522,25 +404,25 @@ bool wxPrinterDC::DoBlit(wxCoord xdest, wxCoord ydest,
int WXUNUSED(rop), bool useMask,
wxCoord WXUNUSED(xsrcMask), wxCoord WXUNUSED(ysrcMask))
{
bool success = TRUE;
if ( useMask )
wxBitmap& bmp = source->GetSelectedBitmap();
wxMask *mask = useMask ? bmp.GetMask() : NULL;
if ( mask )
{
// If we are printing source colours are screen colours not printer
// colours and so we need copy the bitmap pixel by pixel.
RECT rect;
HDC dc_src = GetHdcOf(*source);
HDC dc_mask = ::CreateCompatibleDC(dc_src);
HDC dcSrc = GetHdcOf(*source);
MemoryHDC dcMask(dcSrc);
SelectInHDC selectMask(dcMask, (HBITMAP)mask->GetMaskBitmap());
::SelectObject(dc_mask, (HBITMAP) source->GetSelectedBitmap().GetMask()->GetMaskBitmap());
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
COLORREF cref = ::GetPixel(dc_mask, x, y);
COLORREF cref = ::GetPixel(dcMask, x, y);
if (cref)
{
HBRUSH brush = ::CreateSolidBrush(::GetPixel(dc_src, x, y));
HBRUSH brush = ::CreateSolidBrush(::GetPixel(dcSrc, x, y));
rect.left = xdest + x;
rect.right = rect.left + 1;
rect.top = ydest + y;
@ -550,115 +432,30 @@ bool wxPrinterDC::DoBlit(wxCoord xdest, wxCoord ydest,
}
}
}
::SelectObject(dc_mask, 0);
::DeleteDC(dc_mask);
}
else // no mask
{
if ( ::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB )
if ( !(::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB) ||
!DrawBitmapUsingStretchDIBits(GetHdc(), bmp, xsrc, ysrc) )
{
wxBitmap& bmp = source->GetSelectedBitmap();
int width = bmp.GetWidth(),
height = bmp.GetHeight();
#if wxUSE_DIB_FOR_BITMAP
if ( bmp.IsDIB() )
{
DIBSECTION dib;
if( ::GetObject(GetHbitmapOf(bmp),
sizeof(dib),
&dib) == sizeof(dib) )
{
if ( ::StretchDIBits
(
GetHdc(),
xdest, ydest,
width, height,
xsrc, ysrc,
width, height,
dib.dsBm.bmBits,
(LPBITMAPINFO)&dib.dsBmih,
DIB_RGB_COLORS,
SRCCOPY
) == GDI_ERROR )
{
wxLogLastError(wxT("StretchDIBits"));
}
}
else
{
wxLogLastError(wxT("GetObject"));
}
}
else
#endif // wxUSE_DIB_FOR_BITMAP
{
BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) );
#if wxUSE_DRAWBITMAP_24BITS
int iBitsSize = (((width * 3) + 3 ) & ~3 ) * height;
#else
int iBitsSize = ((width + 3 ) & ~3 ) * height ;
#endif
// no support for StretchDIBits
void* bits = malloc( iBitsSize );
memset( info , 0 , sizeof( BITMAPINFOHEADER ) );
info->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
info->bmiHeader.biWidth = width;
info->bmiHeader.biHeight = height;
info->bmiHeader.biPlanes = 1;
#if wxUSE_DRAWBITMAP_24BITS
info->bmiHeader.biBitCount = 24;
#else
info->bmiHeader.biBitCount = 8;
#endif
info->bmiHeader.biCompression = BI_RGB;
ScreenHDC display;
if ( !::GetDIBits(display, GetHbitmapOf(bmp), 0,
height, bits, info, DIB_RGB_COLORS) )
{
wxLogLastError(wxT("GetDIBits"));
success = FALSE;
}
if ( success )
{
success = ::StretchDIBits(GetHdc(), xdest, ydest,
width, height,
xsrc, ysrc,
width, height,
bits, info ,
DIB_RGB_COLORS,
SRCCOPY) != GDI_ERROR;
if ( !success )
{
wxLogLastError(wxT("StretchDIBits"));
}
}
free(bits);
free(info);
}
}
else // no support for StretchDIBits
{
// as we are printing, source colours are screen colours not
// printer colours and so we need copy the bitmap pixel by pixel.
HDC dc_src = GetHdcOf(*source);
HDC dcSrc = GetHdcOf(*source);
RECT rect;
for (int y = 0; y < height; y++)
{
// optimization: draw identical adjacent pixels together.
for (int x = 0; x < width; x++)
{
COLORREF col = ::GetPixel(dc_src, x, y);
COLORREF col = ::GetPixel(dcSrc, x, y);
HBRUSH brush = ::CreateSolidBrush( col );
rect.left = xdest + x;
rect.top = ydest + y;
while( (x + 1 < width) && (::GetPixel(dc_src, x + 1, y) == col ) )
while( (x + 1 < width) &&
(::GetPixel(dcSrc, x + 1, y) == col ) )
{
++x;
}
@ -671,7 +468,7 @@ bool wxPrinterDC::DoBlit(wxCoord xdest, wxCoord ydest,
}
}
return success;
return TRUE;
}
#endif