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:
@@ -38,6 +38,7 @@
|
|||||||
#if wxUSE_PRINTING_ARCHITECTURE
|
#if wxUSE_PRINTING_ARCHITECTURE
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
|
#include "wx/msw/dib.h"
|
||||||
#include "wx/dcprint.h"
|
#include "wx/dcprint.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// mingw32 defines GDI_ERROR incorrectly
|
// mingw32 defines GDI_ERROR incorrectly
|
||||||
#ifdef __GNUWIN32__
|
#if defined(__GNUWIN32__) || !defined(GDI_ERROR)
|
||||||
#undef GDI_ERROR
|
#undef GDI_ERROR
|
||||||
#define GDI_ERROR ((int)-1)
|
#define GDI_ERROR ((int)-1)
|
||||||
#endif
|
#endif
|
||||||
@@ -278,83 +279,6 @@ static bool wxGetDefaultDeviceName(wxString& deviceName, wxString& portName)
|
|||||||
return ( deviceName != wxT("") );
|
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
|
// Gets an HDC for the specified printer configuration
|
||||||
WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
|
WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
|
||||||
{
|
{
|
||||||
@@ -411,16 +335,47 @@ WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
|
|||||||
// wxPrinterDC bit blitting/bitmap drawing
|
// wxPrinterDC bit blitting/bitmap drawing
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Win16 doesn't define GDI_ERROR.
|
// helper of DoDrawBitmap() and DoBlit()
|
||||||
#ifndef GDI_ERROR
|
static
|
||||||
#define GDI_ERROR -1
|
bool DrawBitmapUsingStretchDIBits(HDC hdc,
|
||||||
#endif
|
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
|
DIBSECTION ds;
|
||||||
// any reason: set this to 0 for 8 bits.
|
if ( !::GetObject(dib.GetHandle(), sizeof(ds), &ds) )
|
||||||
#define wxUSE_DRAWBITMAP_24BITS 1
|
{
|
||||||
|
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,
|
wxCoord x, wxCoord y,
|
||||||
bool useMask)
|
bool useMask)
|
||||||
{
|
{
|
||||||
@@ -429,83 +384,10 @@ void wxPrinterDC::DoDrawBitmap(const wxBitmap &bmp,
|
|||||||
int width = bmp.GetWidth(),
|
int width = bmp.GetWidth(),
|
||||||
height = bmp.GetHeight();
|
height = bmp.GetHeight();
|
||||||
|
|
||||||
if ( ::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB )
|
if ( !(::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB) ||
|
||||||
{
|
!DrawBitmapUsingStretchDIBits(GetHdc(), bmp, x, y) )
|
||||||
#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()
|
|
||||||
{
|
{
|
||||||
|
// no support for StretchDIBits() or an error occured if we got here
|
||||||
wxMemoryDC memDC;
|
wxMemoryDC memDC;
|
||||||
memDC.SelectObject(bmp);
|
memDC.SelectObject(bmp);
|
||||||
|
|
||||||
@@ -522,25 +404,25 @@ bool wxPrinterDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
|||||||
int WXUNUSED(rop), bool useMask,
|
int WXUNUSED(rop), bool useMask,
|
||||||
wxCoord WXUNUSED(xsrcMask), wxCoord WXUNUSED(ysrcMask))
|
wxCoord WXUNUSED(xsrcMask), wxCoord WXUNUSED(ysrcMask))
|
||||||
{
|
{
|
||||||
bool success = TRUE;
|
wxBitmap& bmp = source->GetSelectedBitmap();
|
||||||
|
wxMask *mask = useMask ? bmp.GetMask() : NULL;
|
||||||
if ( useMask )
|
if ( mask )
|
||||||
{
|
{
|
||||||
// If we are printing source colours are screen colours not printer
|
// If we are printing source colours are screen colours not printer
|
||||||
// colours and so we need copy the bitmap pixel by pixel.
|
// colours and so we need copy the bitmap pixel by pixel.
|
||||||
RECT rect;
|
RECT rect;
|
||||||
HDC dc_src = GetHdcOf(*source);
|
HDC dcSrc = GetHdcOf(*source);
|
||||||
HDC dc_mask = ::CreateCompatibleDC(dc_src);
|
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 x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
COLORREF cref = ::GetPixel(dc_mask, x, y);
|
COLORREF cref = ::GetPixel(dcMask, x, y);
|
||||||
if (cref)
|
if (cref)
|
||||||
{
|
{
|
||||||
HBRUSH brush = ::CreateSolidBrush(::GetPixel(dc_src, x, y));
|
HBRUSH brush = ::CreateSolidBrush(::GetPixel(dcSrc, x, y));
|
||||||
rect.left = xdest + x;
|
rect.left = xdest + x;
|
||||||
rect.right = rect.left + 1;
|
rect.right = rect.left + 1;
|
||||||
rect.top = ydest + y;
|
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
|
else // no mask
|
||||||
{
|
{
|
||||||
if ( ::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB )
|
if ( !(::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB) ||
|
||||||
|
!DrawBitmapUsingStretchDIBits(GetHdc(), bmp, xsrc, ysrc) )
|
||||||
{
|
{
|
||||||
wxBitmap& bmp = source->GetSelectedBitmap();
|
// no support for StretchDIBits
|
||||||
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
|
|
||||||
|
|
||||||
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
|
// as we are printing, source colours are screen colours not
|
||||||
// printer colours and so we need copy the bitmap pixel by pixel.
|
// printer colours and so we need copy the bitmap pixel by pixel.
|
||||||
HDC dc_src = GetHdcOf(*source);
|
HDC dcSrc = GetHdcOf(*source);
|
||||||
RECT rect;
|
RECT rect;
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
// optimization: draw identical adjacent pixels together.
|
// optimization: draw identical adjacent pixels together.
|
||||||
for (int x = 0; x < width; x++)
|
for (int x = 0; x < width; x++)
|
||||||
{
|
{
|
||||||
COLORREF col = ::GetPixel(dc_src, x, y);
|
COLORREF col = ::GetPixel(dcSrc, x, y);
|
||||||
HBRUSH brush = ::CreateSolidBrush( col );
|
HBRUSH brush = ::CreateSolidBrush( col );
|
||||||
|
|
||||||
rect.left = xdest + x;
|
rect.left = xdest + x;
|
||||||
rect.top = ydest + y;
|
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;
|
++x;
|
||||||
}
|
}
|
||||||
@@ -671,7 +468,7 @@ bool wxPrinterDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user