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:
parent
cdd732de07
commit
2f52b4e15c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user