support for using DIBs for wxBitmap implementation (patch 649866)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18524 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
f178ab7e82
commit
0becd47010
@ -31,6 +31,7 @@ wxGTK:
|
|||||||
|
|
||||||
wxMSW:
|
wxMSW:
|
||||||
|
|
||||||
|
- possibility to use DIBs for wxBitmap implementation (Derry Bryson)
|
||||||
- wxStaticBitmap doesn't stretch its bitmap any longer (like other ports)
|
- wxStaticBitmap doesn't stretch its bitmap any longer (like other ports)
|
||||||
- support for accelerator keys in the owner drawn menus (Derry Bryson)
|
- support for accelerator keys in the owner drawn menus (Derry Bryson)
|
||||||
- wxCaret::SetSize() doesn't hide the caret any longer as it used to
|
- wxCaret::SetSize() doesn't hide the caret any longer as it used to
|
||||||
|
@ -63,6 +63,10 @@ public:
|
|||||||
|
|
||||||
// optional mask for transparent drawing
|
// optional mask for transparent drawing
|
||||||
wxMask *m_bitmapMask;
|
wxMask *m_bitmapMask;
|
||||||
|
|
||||||
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
|
WXHANDLE m_hFileMap; // file mapping handle for large DIB's
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -177,6 +181,11 @@ public:
|
|||||||
void SetHBITMAP(WXHBITMAP bmp) { SetHandle((WXHANDLE)bmp); }
|
void SetHBITMAP(WXHBITMAP bmp) { SetHandle((WXHANDLE)bmp); }
|
||||||
WXHBITMAP GetHBITMAP() const { return (WXHBITMAP)GetHandle(); }
|
WXHBITMAP GetHBITMAP() const { return (WXHBITMAP)GetHandle(); }
|
||||||
|
|
||||||
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
|
void SetHFileMap(WXHANDLE hFileMap) { GetBitmapData()->m_hFileMap = hFileMap; }
|
||||||
|
WXHANDLE GetHFileMap() const { return GetBitmapData()->m_hFileMap; }
|
||||||
|
#endif // wxUSE_DIB_FOR_BITMAP
|
||||||
|
|
||||||
void SetSelectedInto(wxDC *dc) { if (GetBitmapData()) GetBitmapData()->m_selectedInto = dc; }
|
void SetSelectedInto(wxDC *dc) { if (GetBitmapData()) GetBitmapData()->m_selectedInto = dc; }
|
||||||
wxDC *GetSelectedInto() const { return (GetBitmapData() ? GetBitmapData()->m_selectedInto : (wxDC*) NULL); }
|
wxDC *GetSelectedInto() const { return (GetBitmapData() ? GetBitmapData()->m_selectedInto : (wxDC*) NULL); }
|
||||||
|
|
||||||
@ -209,6 +218,11 @@ protected:
|
|||||||
bool CreateFromImage(const wxImage& image, int depth);
|
bool CreateFromImage(const wxImage& image, int depth);
|
||||||
#endif // wxUSE_IMAGE
|
#endif // wxUSE_IMAGE
|
||||||
|
|
||||||
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
|
void *CreateDIB(int width, int height, int depth);
|
||||||
|
void CopyDIBLine(void* src, void* dest, int count) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
// common part of CopyFromIcon/CopyFromCursor for Win32
|
// common part of CopyFromIcon/CopyFromCursor for Win32
|
||||||
|
@ -636,6 +636,10 @@
|
|||||||
// wxDC cacheing implementation
|
// wxDC cacheing implementation
|
||||||
#define wxUSE_DC_CACHEING 1
|
#define wxUSE_DC_CACHEING 1
|
||||||
|
|
||||||
|
// Set this to 1 to enable the use of DIB's for wxBitmap to support
|
||||||
|
// bitmaps > 16MB on Win95/98/Me. Set to 0 to use DDB's only.
|
||||||
|
#define wxUSE_DIB_FOR_BITMAP 0
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// common dialogs
|
// common dialogs
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Name: bitmap.cpp
|
// Name: bitmap.cpp
|
||||||
// Purpose: wxBitmap
|
// Purpose: wxBitmap
|
||||||
// Author: Julian Smart
|
// Author: Julian Smart
|
||||||
@ -81,6 +81,9 @@ wxBitmapRefData::wxBitmapRefData()
|
|||||||
m_numColors = 0;
|
m_numColors = 0;
|
||||||
m_bitmapMask = NULL;
|
m_bitmapMask = NULL;
|
||||||
m_hBitmap = (WXHBITMAP) NULL;
|
m_hBitmap = (WXHBITMAP) NULL;
|
||||||
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
|
m_hFileMap = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxBitmapRefData::Free()
|
void wxBitmapRefData::Free()
|
||||||
@ -99,6 +102,14 @@ void wxBitmapRefData::Free()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
|
if(m_hFileMap)
|
||||||
|
{
|
||||||
|
::CloseHandle((void*)m_hFileMap);
|
||||||
|
m_hFileMap = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
delete m_bitmapMask;
|
delete m_bitmapMask;
|
||||||
m_bitmapMask = NULL;
|
m_bitmapMask = NULL;
|
||||||
}
|
}
|
||||||
@ -341,41 +352,122 @@ bool wxBitmap::Create(int w, int h, int d)
|
|||||||
|
|
||||||
m_refData = new wxBitmapRefData;
|
m_refData = new wxBitmapRefData;
|
||||||
|
|
||||||
GetBitmapData()->m_width = w;
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
GetBitmapData()->m_height = h;
|
if ( w && h && d >= 16 )
|
||||||
GetBitmapData()->m_depth = d;
|
|
||||||
|
|
||||||
HBITMAP hbmp;
|
|
||||||
#ifndef __WXMICROWIN__
|
|
||||||
if ( d > 0 )
|
|
||||||
{
|
{
|
||||||
hbmp = ::CreateBitmap(w, h, 1, d, NULL);
|
if ( !CreateDIB(w, h, d) )
|
||||||
if ( !hbmp )
|
return FALSE;
|
||||||
{
|
|
||||||
wxLogLastError(wxT("CreateBitmap"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif // wxUSE_DIB_FOR_BITMAP
|
||||||
{
|
{
|
||||||
ScreenHDC dc;
|
GetBitmapData()->m_width = w;
|
||||||
hbmp = ::CreateCompatibleBitmap(dc, w, h);
|
GetBitmapData()->m_height = h;
|
||||||
if ( !hbmp )
|
GetBitmapData()->m_depth = d;
|
||||||
|
|
||||||
|
HBITMAP hbmp;
|
||||||
|
#ifndef __WXMICROWIN__
|
||||||
|
if ( d > 0 )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("CreateCompatibleBitmap"));
|
hbmp = ::CreateBitmap(w, h, 1, d, NULL);
|
||||||
|
if ( !hbmp )
|
||||||
|
{
|
||||||
|
wxLogLastError(wxT("CreateBitmap"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // !__WXMICROWIN__
|
||||||
|
{
|
||||||
|
ScreenHDC dc;
|
||||||
|
hbmp = ::CreateCompatibleBitmap(dc, w, h);
|
||||||
|
if ( !hbmp )
|
||||||
|
{
|
||||||
|
wxLogLastError(wxT("CreateCompatibleBitmap"));
|
||||||
|
}
|
||||||
|
|
||||||
|
GetBitmapData()->m_depth = wxDisplayDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
GetBitmapData()->m_depth = wxDisplayDepth();
|
SetHBITMAP((WXHBITMAP)hbmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetHBITMAP((WXHBITMAP)hbmp);
|
|
||||||
|
|
||||||
#if WXWIN_COMPATIBILITY_2
|
#if WXWIN_COMPATIBILITY_2
|
||||||
GetBitmapData()->m_ok = hbmp != 0;
|
GetBitmapData()->m_ok = hbmp != 0;
|
||||||
#endif // WXWIN_COMPATIBILITY_2
|
#endif // WXWIN_COMPATIBILITY_2
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
|
|
||||||
|
void *wxBitmap::CreateDIB(int width, int height, int depth)
|
||||||
|
{
|
||||||
|
void *dibBits;
|
||||||
|
const int infosize = sizeof(BITMAPINFOHEADER);
|
||||||
|
|
||||||
|
BITMAPINFO *info = (BITMAPINFO *)malloc(infosize);
|
||||||
|
if ( info )
|
||||||
|
{
|
||||||
|
memset(info, 0, infosize);
|
||||||
|
|
||||||
|
info->bmiHeader.biSize = infosize;
|
||||||
|
info->bmiHeader.biWidth = width;
|
||||||
|
info->bmiHeader.biHeight = height;
|
||||||
|
info->bmiHeader.biPlanes = 1;
|
||||||
|
info->bmiHeader.biBitCount = depth;
|
||||||
|
info->bmiHeader.biCompression = BI_RGB;
|
||||||
|
info->bmiHeader.biSizeImage =
|
||||||
|
(((width * (depth/8)) + sizeof(DWORD) - 1) /
|
||||||
|
sizeof(DWORD) * sizeof(DWORD)) * height;
|
||||||
|
info->bmiHeader.biXPelsPerMeter = 0;
|
||||||
|
info->bmiHeader.biYPelsPerMeter = 0;
|
||||||
|
info->bmiHeader.biClrUsed = 0;
|
||||||
|
info->bmiHeader.biClrImportant = 0;
|
||||||
|
GetBitmapData()->m_hFileMap =
|
||||||
|
(WXHANDLE)::CreateFileMapping
|
||||||
|
(
|
||||||
|
INVALID_HANDLE_VALUE,
|
||||||
|
0,
|
||||||
|
PAGE_READWRITE | SEC_COMMIT,
|
||||||
|
0,
|
||||||
|
info->bmiHeader.biSizeImage,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
// No need to report an error here. If it fails, we just won't use a
|
||||||
|
// file mapping and CreateDIBSection will just allocate memory for us.
|
||||||
|
GetBitmapData()->m_handle =
|
||||||
|
(WXHANDLE)::CreateDIBSection
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
info,
|
||||||
|
DIB_RGB_COLORS,
|
||||||
|
&dibBits,
|
||||||
|
(HANDLE)GetBitmapData()->m_hFileMap,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !GetBitmapData()->m_handle )
|
||||||
|
wxLogLastError(wxT("CreateDIBSection"));
|
||||||
|
|
||||||
|
SetWidth(width);
|
||||||
|
SetHeight(height);
|
||||||
|
SetDepth(depth);
|
||||||
|
|
||||||
|
free(info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxFAIL_MSG( wxT("could not allocate memory for DIB header") );
|
||||||
|
|
||||||
|
dibBits = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dibBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_DIB_FOR_BITMAP
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxImage to/from conversions
|
// wxImage to/from conversions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -397,7 +489,6 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
|
|||||||
// so the 'depth' argument is ignored.
|
// so the 'depth' argument is ignored.
|
||||||
|
|
||||||
HDC hScreenDC = ::GetDC(NULL);
|
HDC hScreenDC = ::GetDC(NULL);
|
||||||
// printf("Screen planes = %d, bpp = %d\n", hScreenDC->psd->planes, hScreenDC->psd->bpp);
|
|
||||||
int screenDepth = ::GetDeviceCaps(hScreenDC, BITSPIXEL);
|
int screenDepth = ::GetDeviceCaps(hScreenDC, BITSPIXEL);
|
||||||
|
|
||||||
HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC, image.GetWidth(), image.GetHeight());
|
HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC, image.GetWidth(), image.GetHeight());
|
||||||
@ -503,16 +594,56 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
#else
|
#else // !__WXMICROWIN__
|
||||||
wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
|
wxCHECK_MSG( image.Ok(), FALSE, wxT("invalid image") )
|
||||||
|
|
||||||
m_refData = new wxBitmapRefData();
|
m_refData = new wxBitmapRefData();
|
||||||
|
|
||||||
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
|
int h = image.GetHeight();
|
||||||
|
int w = image.GetWidth();
|
||||||
|
unsigned char *dibBits = (unsigned char*)CreateDIB(w, h, 24);
|
||||||
|
if ( !dibBits )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// DIBs are stored in bottom to top order so we need to copy bits line by
|
||||||
|
// line and starting from the end
|
||||||
|
const int srcBytesPerLine = w * 3;
|
||||||
|
const int dstBytesPerLine = (srcBytesPerLine + sizeof(DWORD) - 1) /
|
||||||
|
sizeof(DWORD) * sizeof(DWORD);
|
||||||
|
const unsigned char *src = image.GetData() + ((h - 1) * srcBytesPerLine);
|
||||||
|
for ( int i = 0; i < h; i++ )
|
||||||
|
{
|
||||||
|
// copy one DIB line
|
||||||
|
int x = w;
|
||||||
|
const unsigned char *rgbBits = src;
|
||||||
|
while ( x-- )
|
||||||
|
{
|
||||||
|
// also, the order of RGB is inversed for DIBs
|
||||||
|
*dibBits++ = rgbBits[2];
|
||||||
|
*dibBits++ = rgbBits[1];
|
||||||
|
*dibBits++ = rgbBits[0];
|
||||||
|
|
||||||
|
rgbBits += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass to the next line
|
||||||
|
src -= srcBytesPerLine;
|
||||||
|
dibBits += dstBytesPerLine - srcBytesPerLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( image.HasMask() )
|
||||||
|
{
|
||||||
|
SetMask(new wxMask(*this, wxColour(image.GetMaskRed(),
|
||||||
|
image.GetMaskGreen(),
|
||||||
|
image.GetMaskBlue())));
|
||||||
|
}
|
||||||
|
#else // wxUSE_DIB_FOR_BITMAP
|
||||||
// sizeLimit is the MS upper limit for the DIB size
|
// sizeLimit is the MS upper limit for the DIB size
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
int sizeLimit = 1024*768*3;
|
int sizeLimit = 1024*768*3;
|
||||||
#else
|
#else
|
||||||
int sizeLimit = 0x7fff ;
|
int sizeLimit = 0x7fff;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// width and height of the device-dependent bitmap
|
// width and height of the device-dependent bitmap
|
||||||
@ -726,6 +857,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
|
|||||||
::ReleaseDC(NULL, hdc);
|
::ReleaseDC(NULL, hdc);
|
||||||
free(lpDIBh);
|
free(lpDIBh);
|
||||||
free(lpBits);
|
free(lpBits);
|
||||||
|
#endif // wxUSE_DIB_FOR_BITMAP
|
||||||
|
|
||||||
#if WXWIN_COMPATIBILITY_2
|
#if WXWIN_COMPATIBILITY_2
|
||||||
// check the wxBitmap object
|
// check the wxBitmap object
|
||||||
@ -733,7 +865,7 @@ bool wxBitmap::CreateFromImage( const wxImage& image, int depth )
|
|||||||
#endif // WXWIN_COMPATIBILITY_2
|
#endif // WXWIN_COMPATIBILITY_2
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
#endif
|
#endif // __WXMICROWIN__/!__WXMICROWIN__
|
||||||
}
|
}
|
||||||
|
|
||||||
wxImage wxBitmap::ConvertToImage() const
|
wxImage wxBitmap::ConvertToImage() const
|
||||||
@ -799,8 +931,7 @@ wxImage wxBitmap::ConvertToImage() const
|
|||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
|
||||||
#else // __MICROWIN__
|
#else // !__WXMICROWIN__
|
||||||
|
|
||||||
wxImage image;
|
wxImage image;
|
||||||
|
|
||||||
wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
|
wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
|
||||||
@ -925,7 +1056,7 @@ wxImage wxBitmap::ConvertToImage() const
|
|||||||
free(lpBits);
|
free(lpBits);
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
#endif
|
#endif // __WXMICROWIN__/!__WXMICROWIN__
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_IMAGE
|
#endif // wxUSE_IMAGE
|
||||||
|
@ -431,45 +431,78 @@ void wxPrinterDC::DoDrawBitmap(const wxBitmap &bmp,
|
|||||||
|
|
||||||
if ( ::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB )
|
if ( ::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB )
|
||||||
{
|
{
|
||||||
BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) );
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
memset( info, 0, sizeof( BITMAPINFOHEADER ) );
|
if(bmp.GetHFileMap()) // we already have a dib
|
||||||
|
|
||||||
#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,
|
DIBSECTION dib;
|
||||||
width, height,
|
if ( ::GetObject(GetHbitmapOf(bmp),
|
||||||
0 , 0, width, height,
|
sizeof(dib),
|
||||||
bits, info,
|
&dib) == sizeof(dib) )
|
||||||
DIB_RGB_COLORS, SRCCOPY) == GDI_ERROR )
|
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("StretchDIBits"));
|
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 ) );
|
||||||
|
|
||||||
free(bits);
|
#if wxUSE_DRAWBITMAP_24BITS
|
||||||
free(info);
|
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()
|
else // no support for StretchDIBits()
|
||||||
{
|
{
|
||||||
@ -493,9 +526,8 @@ bool wxPrinterDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
|||||||
|
|
||||||
if ( useMask )
|
if ( useMask )
|
||||||
{
|
{
|
||||||
// If we are printing source colours are screen colours
|
// If we are printing source colours are screen colours not printer
|
||||||
// not printer colours and so we need copy the bitmap
|
// colours and so we need copy the bitmap pixel by pixel.
|
||||||
// pixel by pixel.
|
|
||||||
RECT rect;
|
RECT rect;
|
||||||
HDC dc_src = GetHdcOf(*source);
|
HDC dc_src = GetHdcOf(*source);
|
||||||
HDC dc_mask = ::CreateCompatibleDC(dc_src);
|
HDC dc_mask = ::CreateCompatibleDC(dc_src);
|
||||||
@ -528,58 +560,97 @@ bool wxPrinterDC::DoBlit(wxCoord xdest, wxCoord ydest,
|
|||||||
wxBitmap& bmp = source->GetSelectedBitmap();
|
wxBitmap& bmp = source->GetSelectedBitmap();
|
||||||
int width = bmp.GetWidth(),
|
int width = bmp.GetWidth(),
|
||||||
height = bmp.GetHeight();
|
height = bmp.GetHeight();
|
||||||
|
#if wxUSE_DIB_FOR_BITMAP
|
||||||
BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) );
|
if(bmp.GetHFileMap()) // we already have a dib
|
||||||
int iBitsSize = ((width + 3 ) & ~3 ) * height;
|
|
||||||
|
|
||||||
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;
|
|
||||||
info->bmiHeader.biBitCount = 8;
|
|
||||||
info->bmiHeader.biCompression = BI_RGB;
|
|
||||||
|
|
||||||
ScreenHDC display;
|
|
||||||
if ( !::GetDIBits(display, GetHbitmapOf(bmp), 0,
|
|
||||||
height, bits, info, DIB_RGB_COLORS) )
|
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("GetDIBits"));
|
DIBSECTION dib;
|
||||||
|
if( ::GetObject(GetHbitmapOf(bmp),
|
||||||
success = FALSE;
|
sizeof(dib),
|
||||||
}
|
&dib) == sizeof(dib) )
|
||||||
|
|
||||||
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"));
|
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
|
||||||
|
|
||||||
free(bits);
|
void* bits = malloc( iBitsSize );
|
||||||
free(info);
|
|
||||||
|
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
|
else // no support for StretchDIBits
|
||||||
{
|
{
|
||||||
// as we are printing, source colours are screen colours not printer
|
// as we are printing, source colours are screen colours not
|
||||||
// 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 dc_src = GetHdcOf(*source);
|
||||||
RECT rect;
|
RECT rect;
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
// This is Stefan Csomor's optimisation, where identical adjacent
|
// optimization: draw identical adjacent pixels together.
|
||||||
// pixels are drawn 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(dc_src, x, y);
|
||||||
|
Loading…
Reference in New Issue
Block a user