Windows98 printing fixes from October. Also, added dummy Makefile in src/

This commit is contained in:
William Kendrick 2003-12-19 19:46:49 +00:00
parent 7804219dcb
commit 1e60f10112
5 changed files with 217 additions and 204 deletions

View file

@ -7,7 +7,7 @@ bill@newbreedsoftware.com
http://www.newbreedsoftware.com/tuxpaint/ http://www.newbreedsoftware.com/tuxpaint/
2003.Dec.19 (0.9.13) [cvs] 2003.Dec.19 (0.9.13)
* Translated into Basque (eu_ES) * Translated into Basque (eu_ES)
Juan Irigoien <juanirigoien@irakasle.net> Juan Irigoien <juanirigoien@irakasle.net>
@ -22,7 +22,7 @@ http://www.newbreedsoftware.com/tuxpaint/
* Added stamp controls to mirror, flip and resize stamps before placing * Added stamp controls to mirror, flip and resize stamps before placing
them. Some stamps can be set to not be mirror-, flip- or resize-able. them. Some stamps can be set to not be mirror-, flip- or resize-able.
(Place "noflip", "nomirror" and/or "noresize" in the stamps' ".dat" (Place "noflip" and/or "nomirror" in the stamps' ".dat"
option files.) Stamps can have alternative mirror-images (e.g., to option files.) Stamps can have alternative mirror-images (e.g., to
show a shape the opposite direction, but not have backwards text on it). show a shape the opposite direction, but not have backwards text on it).
Create "filename_mirror.png" image files. [PENDING] Create "filename_mirror.png" image files. [PENDING]

2
src/Makefile Normal file
View file

@ -0,0 +1,2 @@
all:
cd .. ; make

View file

@ -11123,14 +11123,18 @@ void do_print(void)
} }
#else #else
#ifdef WIN32 #ifdef WIN32
/* Win32 */ /* Win32 */
char f[512]; char f[512];
int show = (SDL_GetModState() & KMOD_ALT) && !fullscreen;
int show = (SDL_GetModState() & KMOD_ALT) && !fullscreen; snprintf(f, sizeof(f), "%s/%s", savedir, "print.cfg");
snprintf(f, sizeof(f), "%s/%s", savedir, "print.cfg"); {
SurfacePrint(canvas, use_print_config?f:NULL, show); const char *error = SurfacePrint(canvas, use_print_config?f:NULL, show);
if ( error ) fprintf(stderr, "%s\n", error);
}
#elif defined(__BEOS__) #elif defined(__BEOS__)
/* BeOS */ /* BeOS */

View file

@ -1,10 +1,11 @@
/* win32_print.c */ /* win32_print.c */
/* printing support for Tux Paint */ /* printing support for Tux Paint */
/* John Popplewell <john@johnnypops.demon.co.uk> */ /* John Popplewell <john@johnnypops.demon.co.uk> */
/* Sept. 30, 2002 - Oct. 17, 2002 */ /* Sept. 30, 2002 - Oct. 17, 2002 */
/* Oct. 07, 2003 - added banding support */
/* - prints using 24-bit (not 32-bit) bitmap */
#include "SDL_syswm.h" #include "SDL_syswm.h"
#include "win32_print.h" #include "win32_print.h"
@ -13,12 +14,9 @@
#define NOREF(x) ((x)=(x)) #define NOREF(x) ((x)=(x))
#define GETHINST(hWnd) ((HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE )) #define GETHINST(hWnd) ((HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE ))
#define MIR( id ) (MAKEINTRESOURCE( id )) #define MIR( id ) (MAKEINTRESOURCE( id ))
static int bPrint = FALSE;
static HWND hDlgCancel = NULL;
static PRINTDLG global_pd = { static PRINTDLG global_pd = {
sizeof(PRINTDLG), sizeof(PRINTDLG),
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@ -31,50 +29,11 @@ static PRINTDLG global_pd = {
NULL, NULL,
}; };
//static DEVMODE *devmode = NULL;
BOOL CALLBACK AbortProc( HDC hDC, int nCode ) static SDL_Surface *make24bitDIB( SDL_Surface *surf )
{
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_PixelFormat pixfmt;
SDL_Surface *surf32; SDL_Surface *surf24;
SDL_Surface *surfDIB; SDL_Surface *surfDIB;
Uint8 *src,*dst; Uint8 *src,*dst;
Uint32 linesize; Uint32 linesize;
@ -82,16 +41,16 @@ static SDL_Surface *make32bitDIB( SDL_Surface *surf )
memset( &pixfmt, 0, sizeof(pixfmt) ); memset( &pixfmt, 0, sizeof(pixfmt) );
pixfmt.palette = NULL; pixfmt.palette = NULL;
pixfmt.BitsPerPixel = 32; pixfmt.BitsPerPixel = 24;
pixfmt.BytesPerPixel= 4; pixfmt.BytesPerPixel= 3;
pixfmt.Rmask = 0x00FF0000; pixfmt.Rmask = 0x00FF0000;
pixfmt.Gmask = 0x0000FF00; pixfmt.Gmask = 0x0000FF00;
pixfmt.Bmask = 0x000000FF; pixfmt.Bmask = 0x000000FF;
pixfmt.Amask = 0xFF000000; pixfmt.Amask = 0;
pixfmt.Rshift = 16; pixfmt.Rshift = 16;
pixfmt.Gshift = 8; pixfmt.Gshift = 8;
pixfmt.Bshift = 0; pixfmt.Bshift = 0;
pixfmt.Ashift = 24; pixfmt.Ashift = 0;
pixfmt.Rloss = 0; pixfmt.Rloss = 0;
pixfmt.Gloss = 0; pixfmt.Gloss = 0;
pixfmt.Bloss = 0; pixfmt.Bloss = 0;
@ -99,21 +58,21 @@ static SDL_Surface *make32bitDIB( SDL_Surface *surf )
pixfmt.colorkey = 0; pixfmt.colorkey = 0;
pixfmt.alpha = 0; pixfmt.alpha = 0;
surf32 = SDL_ConvertSurface( surf, &pixfmt, SDL_SWSURFACE ); surf24 = SDL_ConvertSurface( surf, &pixfmt, SDL_SWSURFACE );
surfDIB = SDL_CreateRGBSurface( SDL_SWSURFACE, surf32->w, surf32->h, 32, surfDIB = SDL_CreateRGBSurface( SDL_SWSURFACE, surf24->w, surf24->h, 24,
pixfmt.Rmask, pixfmt.Gmask, pixfmt.Bmask, pixfmt.Amask ); pixfmt.Rmask, pixfmt.Gmask, pixfmt.Bmask, pixfmt.Amask );
linesize = surf32->w*sizeof(Uint32); /* Flip top2bottom */ linesize = surf24->w * 3; // Flip top2bottom
dst = surfDIB->pixels; dst = surfDIB->pixels;
src = ((Uint8*)surf32->pixels)+((surf32->h-1)*surf32->pitch); src = ((Uint8*)surf24->pixels)+((surf24->h-1)*surf24->pitch);
for ( i = 0; i < surf32->h; ++i ) for ( i = 0; i < surf24->h; ++i )
{ {
memcpy( dst, src, linesize ); memcpy( dst, src, linesize );
src -= surf32->pitch; src -= surf24->pitch;
dst += surfDIB->pitch; dst += surfDIB->pitch;
} }
SDL_FreeSurface( surf32 ); /* Free temp surface */ SDL_FreeSurface( surf24 ); // Free temp surface
return surfDIB; return surfDIB;
} }
@ -142,21 +101,10 @@ static int GetDefaultPrinterStrings( char *device, char *driver, char *output )
if ( output ) strcpy( output, out ); if ( output ) strcpy( output, out );
return 1; return 1;
} }
return 0; return 0;
} }
#define dmDeviceNameSize 32
static HDC GetDefaultPrinterDC( void )
{
char device[MAX_PATH],driver[MAX_PATH],output[MAX_PATH];
if ( GetDefaultPrinterStrings( device, driver, output ) )
return CreateDC( driver, device, output, NULL );
return NULL;
}
static HANDLE LoadCustomPrinterHDEVMODE( HWND hWnd, const char *filepath ) static HANDLE LoadCustomPrinterHDEVMODE( HWND hWnd, const char *filepath )
{ {
@ -167,10 +115,15 @@ static HANDLE LoadCustomPrinterHDEVMODE( HWND hWnd, const char *filepath )
DEVMODE *devmode = NULL; DEVMODE *devmode = NULL;
int res; int res;
FILE *fp = NULL; FILE *fp = NULL;
int block_size;
int block_read;
if ( !GetDefaultPrinterStrings( device, NULL, NULL ) ) if ( (fp = fopen( filepath, "rb" )) == NULL )
return NULL; return NULL;
if ( fread( device, 1, dmDeviceNameSize, fp ) != dmDeviceNameSize )
goto err_exit;
if (!OpenPrinter( device, &hPrinter, NULL )) if (!OpenPrinter( device, &hPrinter, NULL ))
return NULL; return NULL;
@ -193,15 +146,11 @@ static HANDLE LoadCustomPrinterHDEVMODE( HWND hWnd, const char *filepath )
if ( res != IDOK ) if ( res != IDOK )
goto err_exit; goto err_exit;
if ( (fp = fopen( filepath, "rb" )) != NULL ) block_size = devmode->dmSize + devmode->dmDriverExtra;
{ block_read = fread( devmode, 1, block_size, fp );
int block_size = devmode->dmSize + devmode->dmDriverExtra; if ( block_size != block_read )
int block_read = fread( devmode, 1, block_size, fp ); goto err_exit;
fclose(fp);
fclose( fp );
if ( block_size != block_read )
goto err_exit;
}
res = DocumentProperties( hWnd, hPrinter, device, devmode, devmode, res = DocumentProperties( hWnd, hPrinter, device, devmode, devmode,
DM_IN_BUFFER|DM_OUT_BUFFER); DM_IN_BUFFER|DM_OUT_BUFFER);
@ -213,6 +162,7 @@ static HANDLE LoadCustomPrinterHDEVMODE( HWND hWnd, const char *filepath )
return hDevMode; return hDevMode;
err_exit: err_exit:
if ( fp ) fclose( fp );
if ( devmode ) GlobalUnlock( hDevMode ); if ( devmode ) GlobalUnlock( hDevMode );
if ( hDevMode ) GlobalFree( hDevMode ); if ( hDevMode ) GlobalFree( hDevMode );
if ( hPrinter ) ClosePrinter( hPrinter ); if ( hPrinter ) ClosePrinter( hPrinter );
@ -229,11 +179,15 @@ static int SaveCustomPrinterHDEVMODE( HWND hWnd, const char *filepath, HANDLE hD
{ {
DEVMODE *devmode = (DEVMODE*)GlobalLock( hDevMode ); DEVMODE *devmode = (DEVMODE*)GlobalLock( hDevMode );
int block_size = devmode->dmSize + devmode->dmDriverExtra; int block_size = devmode->dmSize + devmode->dmDriverExtra;
int block_writ = fwrite( devmode, 1, block_size, fp ); int block_written;
char devname[dmDeviceNameSize];
strcpy( devname, (const char*)devmode->dmDeviceName );
fwrite( devname, 1, sizeof(devname), fp );
block_written = fwrite( devmode, 1, block_size, fp );
GlobalUnlock( hDevMode ); GlobalUnlock( hDevMode );
fclose( fp ); fclose( fp );
return block_size == block_writ; return block_size == block_written;
} }
return 0; return 0;
} }
@ -270,49 +224,71 @@ static HDC GetCustomPrinterDC( HWND hWnd, const char *printcfg, int show )
} }
static HDC GetDefaultPrinterDC( void )
{
char device[MAX_PATH],driver[MAX_PATH],output[MAX_PATH];
if ( GetDefaultPrinterStrings( device, driver, output ) )
return CreateDC( driver, device, output, NULL );
return NULL;
}
static HDC GetPrinterDC( HWND hWnd, const char *printcfg, int show )
{
if ( !printcfg ) return GetDefaultPrinterDC();
return GetCustomPrinterDC( hWnd, printcfg, show );
}
static int IsBandingRequired( HDC hPrinter )
{
OSVERSIONINFO osvi;
int indata = NEXTBAND;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if ( GetVersionEx( &osvi ) && (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) )
return Escape( hPrinter, QUERYESCSUPPORT, sizeof(int), (LPCSTR)&indata, NULL );
return 0;
}
int IsPrinterAvailable( void ) int IsPrinterAvailable( void )
{ {
return (GetDefaultPrinterStrings( NULL, NULL, NULL ) != 0); return (GetDefaultPrinterStrings( NULL, NULL, NULL ) != 0);
} }
int SurfacePrint( SDL_Surface *surf, const char *printcfg, int showdialog ) const char *SurfacePrint( SDL_Surface *surf, const char *printcfg, int showdialog )
{ {
int res = 0; char *res = NULL;
HWND hWnd; HWND hWnd;
DOCINFO di; DOCINFO di;
int nError; int nError;
SDL_SysWMinfo wminfo; SDL_SysWMinfo wminfo;
HDC hDCwindow; HDC hDCwindow;
HDC hDCprinter; HDC hDCprinter;
BITMAPINFOHEADER bmih; BITMAPINFOHEADER bmih;
SDL_Surface *surf32 = NULL; SDL_Surface *surf24 = NULL;
RECT rc; RECT rc;
float fLogPelsX1, fLogPelsY1, fLogPelsX2, fLogPelsY2; float fLogPelsX1, fLogPelsY1, fLogPelsX2, fLogPelsY2;
float fScaleX, fScaleY; float fScaleX, fScaleY;
int cWidthPels, xLeft, yTop; int cWidthPels, xLeft, yTop;
float subscaler,subscalerx,subscalery; float subscaler,subscalerx,subscalery;
int hDCCaps; int hDCCaps;
HANDLE hOldObject = NULL;
HBITMAP hbm = NULL; HBITMAP hbm = NULL;
HDC hdcMem = NULL; HDC hdcMem = NULL;
SDL_VERSION(&wminfo.version); SDL_VERSION(&wminfo.version);
if ( !SDL_GetWMInfo( &wminfo ) ) if ( !SDL_GetWMInfo( &wminfo ) )
return -1; return "win32_print: SDL_GetWMInfo() failed.";
hWnd = wminfo.window; hWnd = wminfo.window;
hDCprinter = GetPrinterDC( hWnd, printcfg, showdialog );
if ( !printcfg )
hDCprinter = GetDefaultPrinterDC();
else
hDCprinter = GetCustomPrinterDC( hWnd, printcfg, showdialog );
if ( !hDCprinter ) if ( !hDCprinter )
return -1; return "win32_print: GetPrinterDC() failed.";
bPrint = TRUE;
SetAbortProc( hDCprinter, AbortProc );
hDlgCancel = CreateDialog( GETHINST(hWnd), MIR(IDD_ABORTDLG), hWnd, (DLGPROC)AbortPrintJob );
EnableWindow( hWnd, FALSE ); EnableWindow( hWnd, FALSE );
di.cbSize = sizeof(DOCINFO); di.cbSize = sizeof(DOCINFO);
@ -324,23 +300,23 @@ int SurfacePrint( SDL_Surface *surf, const char *printcfg, int showdialog )
nError = StartDoc( hDCprinter, &di ); nError = StartDoc( hDCprinter, &di );
if ( nError == SP_ERROR ) if ( nError == SP_ERROR )
{ {
res = -2; res = "win32_print: StartDoc() failed.";
goto error; goto error;
} }
nError = StartPage(hDCprinter); nError = StartPage( hDCprinter );
if (nError <= 0) if (nError <= 0)
{ {
res = -3; res = "win32_print: StartPage() failed.";
goto error; goto error;
} }
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
surf32 = make32bitDIB( surf ); surf24 = make24bitDIB( surf );
if ( !surf32 ) if ( !surf24 )
{ {
res = -4; res = "win32_print: make24bitDIB() failed.";
goto error; goto error;
} }
@ -348,21 +324,27 @@ int SurfacePrint( SDL_Surface *surf, const char *printcfg, int showdialog )
bmih.biSize = sizeof(bmih); bmih.biSize = sizeof(bmih);
bmih.biPlanes = 1; bmih.biPlanes = 1;
bmih.biCompression = BI_RGB; bmih.biCompression = BI_RGB;
bmih.biBitCount = 32; bmih.biBitCount = 24;
bmih.biWidth = surf32->w; bmih.biWidth = surf24->w;
bmih.biHeight = surf32->h; bmih.biHeight = surf24->h;
GetClientRect( hWnd, &rc ); GetClientRect( hWnd, &rc );
subscalerx = (float)rc.right/surf32->w; subscalerx = (float)rc.right/surf24->w;
subscalery = (float)rc.bottom/surf32->h; subscalery = (float)rc.bottom/surf24->h;
subscaler = subscalery; subscaler = subscalery;
if ( subscalerx < subscalery ) if ( subscalerx < subscalery )
subscaler = subscalerx; subscaler = subscalerx;
hDCwindow = GetDC( hWnd ); hDCwindow = GetDC( hWnd );
if ( !hDCwindow )
{
res = "win32_print: failed to get window DC.";
goto error;
}
fLogPelsX1 = (float)GetDeviceCaps(hDCwindow, LOGPIXELSX); fLogPelsX1 = (float)GetDeviceCaps(hDCwindow, LOGPIXELSX);
fLogPelsY1 = (float)GetDeviceCaps(hDCwindow, LOGPIXELSY); fLogPelsY1 = (float)GetDeviceCaps(hDCwindow, LOGPIXELSY);
ReleaseDC( hWnd, hDCwindow ); ReleaseDC( hWnd, hDCwindow );
fLogPelsX2 = (float)GetDeviceCaps(hDCprinter, LOGPIXELSX); fLogPelsX2 = (float)GetDeviceCaps(hDCprinter, LOGPIXELSX);
fLogPelsY2 = (float)GetDeviceCaps(hDCprinter, LOGPIXELSY); fLogPelsY2 = (float)GetDeviceCaps(hDCprinter, LOGPIXELSY);
@ -386,41 +368,69 @@ int SurfacePrint( SDL_Surface *surf, const char *printcfg, int showdialog )
hDCCaps = GetDeviceCaps(hDCprinter, RASTERCAPS); hDCCaps = GetDeviceCaps(hDCprinter, RASTERCAPS);
if ( hDCCaps & RC_STRETCHDIB ) if (hDCCaps & RC_PALETTE)
{ {
StretchDIBits(hDCprinter, xLeft, yTop, res = "win32_print: printer context requires palette.";
(int)(fScaleX*bmih.biWidth), goto error;
(int)(fScaleY*bmih.biHeight),
0, 0, bmih.biWidth, bmih.biHeight,
surf32->pixels, (BITMAPINFO*)&bmih,
DIB_RGB_COLORS, SRCCOPY);
} }
else
if ( hDCCaps & RC_STRETCHBLT ) if ( IsBandingRequired( hDCprinter ) )
{ {
hbm = CreateDIBitmap(hDCprinter, &bmih, CBM_INIT, RECT rcBand = { 0 };
surf32->pixels, (const BITMAPINFO*)&bmih, 0); RECT rcPrinter;
if ( hbm ) RECT rcImage;
SetRect( &rcPrinter, xLeft, yTop, (int)(fScaleX*bmih.biWidth), (int)(fScaleY*bmih.biHeight) );
SetRect( &rcImage, 0, 0, bmih.biWidth, bmih.biHeight );
while ( Escape(hDCprinter, NEXTBAND, 0, NULL, &rcBand) )
{ {
hdcMem = CreateCompatibleDC( hDCprinter ); if ( IsRectEmpty( &rcBand) ) break;
if ( hdcMem ) if ( IntersectRect( &rcBand, &rcBand, &rcPrinter ) )
{ {
hOldObject = SelectObject(hdcMem, hbm); rcImage.top = (int)(0.5f+(float)rcBand.top/fScaleX);
if ( hOldObject ) rcImage.bottom = (int)(0.5f+(float)rcBand.bottom/fScaleX);
SetStretchBltMode( hDCprinter, COLORONCOLOR );
nError = StretchDIBits(hDCprinter, rcBand.left, rcBand.top,
rcBand.right - rcBand.left,
rcBand.bottom - rcBand.top,
rcImage.left, rcImage.top,
rcImage.right - rcImage.left,
rcImage.bottom - rcImage.top,
surf24->pixels, (BITMAPINFO*)&bmih,
DIB_RGB_COLORS, SRCCOPY);
if ( nError == GDI_ERROR )
{ {
StretchBlt(hDCprinter, xLeft, yTop, res = "win32_print: StretchDIBits() failed.";
(int)(fScaleX*bmih.biWidth), goto error;
(int)(fScaleY*bmih.biHeight),
hdcMem, 0, 0, bmih.biWidth, bmih.biHeight, SRCCOPY);
SelectObject(hdcMem, hOldObject);
} }
} }
} }
} }
else else
{ {
res = -10; if ( hDCCaps & RC_STRETCHDIB )
goto error; {
SetStretchBltMode(hDCprinter, COLORONCOLOR);
nError = StretchDIBits(hDCprinter, xLeft, yTop,
(int)(fScaleX*bmih.biWidth),
(int)(fScaleY*bmih.biHeight),
0, 0, bmih.biWidth, bmih.biHeight,
surf24->pixels, (BITMAPINFO*)&bmih,
DIB_RGB_COLORS, SRCCOPY);
if ( nError == GDI_ERROR )
{
res = "win32_print: StretchDIBits() failed.";
goto error;
}
}
else
{
res = "win32_print: StretchDIBits() not available.";
goto error;
}
} }
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
@ -428,7 +438,7 @@ int SurfacePrint( SDL_Surface *surf, const char *printcfg, int showdialog )
nError = EndPage( hDCprinter ); nError = EndPage( hDCprinter );
if ( nError <= 0 ) if ( nError <= 0 )
{ {
res = -9; res = "win32_print: EndPage() failed.";
goto error; goto error;
} }
@ -437,13 +447,10 @@ int SurfacePrint( SDL_Surface *surf, const char *printcfg, int showdialog )
error: error:
if ( hdcMem ) DeleteDC( hdcMem ); if ( hdcMem ) DeleteDC( hdcMem );
if ( hbm ) DeleteObject( hbm ); if ( hbm ) DeleteObject( hbm );
if ( surf32 ) SDL_FreeSurface( surf32 ); if ( surf24 ) SDL_FreeSurface( surf24 );
EnableWindow( hWnd, TRUE ); EnableWindow( hWnd, TRUE );
DestroyWindow( hDlgCancel );
DeleteDC( hDCprinter ); DeleteDC( hDCprinter );
return res; return res;
} }

View file

@ -14,9 +14,9 @@
#endif #endif
/* if printcfg is NULL, uses the default printer */ /* if printcfg is NULL, uses the default printer */
extern int SurfacePrint( SDL_Surface *surf, extern const char *SurfacePrint( SDL_Surface *surf,
const char *printcfg, const char *printcfg,
int showdialog ); int showdialog );
extern int IsPrinterAvailable( void ); extern int IsPrinterAvailable( void );
#endif #endif