tuxpaint-pencil-sharpener/src/win32_print.c-old
2003-02-24 01:46:52 +00:00

301 lines
7.5 KiB
Text

/* win32_print.c */
/* printing support for Tux Paint */
/* John Popplewell <john@johnnypops.demon.co.uk> */
/* Sept. 30, 2002 - Oct. 17, 2002 */
#include "SDL_syswm.h"
#include "win32_print.h"
#include "resource.h"
#define NOREF(x) ((x)=(x))
#define GETHINST(hWnd) ((HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE ))
#define MIR( id ) (MAKEINTRESOURCE( id ))
static int bPrint;
static HWND hDlgCancel;
static int GetPrinterContext( HWND hWnd, PRINTDLG *pd )
{
pd->hwndOwner = hWnd;
pd->Flags = PD_RETURNDC;
pd->nFromPage = 0xFFFF;
pd->nToPage = 0xFFFF;
pd->nMinPage = 0xFFFF;
pd->nMaxPage = 0xFFFF;
pd->nCopies = 1;
return PrintDlg( pd );
}
BOOL CALLBACK AbortProc( HDC hDC, int nCode )
{
MSG msg;
NOREF(nCode);
NOREF(hDC);
while ( PeekMessage( (LPMSG)&msg, (HWND)NULL, 0, 0, PM_REMOVE) )
{
if ( !IsDialogMessage( hDlgCancel, (LPMSG)&msg ) )
{
TranslateMessage( (LPMSG)&msg );
DispatchMessage( (LPMSG)&msg );
}
}
return bPrint;
}
LRESULT CALLBACK AbortPrintJob( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
NOREF(hDlg);
NOREF(lParam);
NOREF(wParam);
NOREF(message);
switch ( message )
{
case WM_INITDIALOG :
return TRUE;
case WM_COMMAND :
bPrint = FALSE;
return TRUE;
default :
return FALSE;
}
}
static SDL_Surface *make32bitDIB( SDL_Surface *surf )
{
SDL_PixelFormat pixfmt;
SDL_Surface *surf32;
SDL_Surface *surfDIB;
Uint8 *src,*dst;
Uint32 linesize;
int i;
memset( &pixfmt, 0, sizeof(pixfmt) );
pixfmt.palette = NULL;
pixfmt.BitsPerPixel = 32;
pixfmt.BytesPerPixel= 4;
pixfmt.Rmask = 0x00FF0000;
pixfmt.Gmask = 0x0000FF00;
pixfmt.Bmask = 0x000000FF;
pixfmt.Amask = 0xFF000000;
pixfmt.Rshift = 16;
pixfmt.Gshift = 8;
pixfmt.Bshift = 0;
pixfmt.Ashift = 24;
pixfmt.Rloss = 0;
pixfmt.Gloss = 0;
pixfmt.Bloss = 0;
pixfmt.Aloss = 0;
pixfmt.colorkey = 0;
pixfmt.alpha = 0;
surf32 = SDL_ConvertSurface( surf, &pixfmt, SDL_SWSURFACE );
surfDIB = SDL_CreateRGBSurface( SDL_SWSURFACE, surf32->w, surf32->h, 32,
pixfmt.Rmask, pixfmt.Gmask, pixfmt.Bmask, pixfmt.Amask );
linesize = surf32->w*sizeof(Uint32); /* Flip top2bottom */
dst = surfDIB->pixels;
src = ((Uint8*)surf32->pixels)+((surf32->h-1)*surf32->pitch);
for ( i = 0; i < surf32->h; ++i )
{
memcpy( dst, src, linesize );
src -= surf32->pitch;
dst += surfDIB->pitch;
}
SDL_FreeSurface( surf32 ); /* Free temp surface */
return surfDIB;
}
int IsPrinterAvailable( void )
{
char *section = "windows";
char *key = "device";
char *def = "NODEFAULTPRINTER";
char buff[256];
if ( !GetProfileString( section, key, def, buff, sizeof(buff) ) )
return 0;
return (strcmp( buff, def ) != 0);
}
int SurfacePrint( SDL_Surface *surf )
{
int res = 0;
HWND hWnd;
PRINTDLG pd;
DOCINFO di;
int nError;
SDL_SysWMinfo wminfo;
HDC hDC;
BITMAPINFOHEADER bmih;
SDL_Surface *surf32 = NULL;
RECT rc;
float fLogPelsX1, fLogPelsY1, fLogPelsX2, fLogPelsY2;
float fScaleX, fScaleY;
int cWidthPels, xLeft, yTop;
float subscaler,subscalerx,subscalery;
int hDCCaps;
HANDLE hOldObject = NULL;
HBITMAP hbm = NULL;
HDC hdcMem = NULL;
SDL_VERSION(&wminfo.version);
if ( !SDL_GetWMInfo( &wminfo ) )
return -1;
hWnd = wminfo.window;
memset( &pd, 0, sizeof(PRINTDLG) );
pd.lStructSize = sizeof(PRINTDLG);
if ( !GetPrinterContext( hWnd, &pd ) || (pd.hDC == NULL) )
return -1;
bPrint = TRUE;
SetAbortProc( pd.hDC, AbortProc );
hDlgCancel = CreateDialog( GETHINST(hWnd), MIR(IDD_ABORTDLG), hWnd, (DLGPROC)AbortPrintJob );
EnableWindow( hWnd, FALSE );
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = "Tux Paint";
di.lpszOutput = (LPTSTR)NULL;
di.lpszDatatype = (LPTSTR)NULL;
di.fwType = 0;
nError = StartDoc( pd.hDC, &di );
if ( nError == SP_ERROR )
{
res = -2;
goto error;
}
nError = StartPage(pd.hDC);
if (nError <= 0)
{
res = -3;
goto error;
}
//////////////////////////////////////////////////////////////////////////////////////
surf32 = make32bitDIB( surf );
if ( !surf32 )
{
res = -4;
goto error;
}
memset( &bmih,0, sizeof(bmih) );
bmih.biSize = sizeof(bmih);
bmih.biPlanes = 1;
bmih.biCompression = BI_RGB;
bmih.biBitCount = 32;
bmih.biWidth = surf32->w;
bmih.biHeight = surf32->h;
GetClientRect( hWnd, &rc );
subscalerx = (float)rc.right/surf32->w;
subscalery = (float)rc.bottom/surf32->h;
subscaler = subscalery;
if ( subscalerx < subscalery )
subscaler = subscalerx;
hDC = GetDC( hWnd );
fLogPelsX1 = (float)GetDeviceCaps(hDC, LOGPIXELSX);
fLogPelsY1 = (float)GetDeviceCaps(hDC, LOGPIXELSY);
ReleaseDC( hWnd, hDC );
fLogPelsX2 = (float)GetDeviceCaps(pd.hDC, LOGPIXELSX);
fLogPelsY2 = (float)GetDeviceCaps(pd.hDC, LOGPIXELSY);
if (fLogPelsX1 > fLogPelsX2)
fScaleX = (fLogPelsX1/fLogPelsX2);
else
fScaleX = (fLogPelsX2/fLogPelsX1);
if (fLogPelsY1 > fLogPelsY2)
fScaleY = (fLogPelsY1/fLogPelsY2);
else
fScaleY = (fLogPelsY2/fLogPelsY1);
fScaleX *= subscaler;
fScaleY *= subscaler;
yTop = 0;
cWidthPels = GetDeviceCaps(pd.hDC, PHYSICALWIDTH);
xLeft = ((cWidthPels - ((int)(fScaleX*bmih.biWidth)))/2)-
GetDeviceCaps(pd.hDC, PHYSICALOFFSETX);
hDCCaps = GetDeviceCaps(pd.hDC, RASTERCAPS);
if ( hDCCaps & RC_STRETCHDIB )
{
StretchDIBits(pd.hDC, xLeft, yTop,
(int)(fScaleX*bmih.biWidth),
(int)(fScaleY*bmih.biHeight),
0, 0, bmih.biWidth, bmih.biHeight,
surf32->pixels, (BITMAPINFO*)&bmih,
DIB_RGB_COLORS, SRCCOPY);
}
else
if ( hDCCaps & RC_STRETCHBLT )
{
hbm = CreateDIBitmap(pd.hDC, &bmih, CBM_INIT,
surf32->pixels, (const BITMAPINFO*)&bmih, 0);
if ( hbm )
{
hdcMem = CreateCompatibleDC( pd.hDC );
if ( hdcMem )
{
hOldObject = SelectObject(hdcMem, hbm);
if ( hOldObject )
{
StretchBlt(pd.hDC, xLeft, yTop,
(int)(fScaleX*bmih.biWidth),
(int)(fScaleY*bmih.biHeight),
hdcMem, 0, 0, bmih.biWidth, bmih.biHeight, SRCCOPY);
SelectObject(hdcMem, hOldObject);
}
}
}
}
else
{
res = -10;
goto error;
}
//////////////////////////////////////////////////////////////////////////////////////
nError = EndPage( pd.hDC );
if ( nError <= 0 )
{
res = -9;
goto error;
}
EndDoc( pd.hDC );
error:
if ( hdcMem ) DeleteDC( hdcMem );
if ( hbm ) DeleteObject( hbm );
if ( surf32 ) SDL_FreeSurface( surf32 );
EnableWindow( hWnd, TRUE );
DestroyWindow( hDlgCancel );
DeleteDC( pd.hDC );
return res;
}