diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 36c098c2b5..7414ca6bca 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,30 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-01-24 19:40 UTC+0100 Xavi (jarabal/at/gmail.com) + * contrib/hbwin/win_prn1.c + + Added support for printing RAW compressed formats JPEG and PNG BitMaps. + + Added new PRGs functions: win_TypeBitMap() and win_CheckPrnDrvFormat() + Example of use in the class win_BMP() + * Changes in WIN_LOADBITMAPFILE, WIN_DRAWBITMAP to support new formats. + + * contrib/hbwin/win_tprn.prg + + Extended the class win_BMP() to allow printing compressed formats JPEG and PNG + if the printer driver allows. + + Added method CheckPrnDrvFormat( oPrn, @cErrMsg ) for check printer driver. + + New VAR INT Type. Type of BitMap: 1 == BM, 2 == JPEG, 3 == PNG + + New VAR array DimXY. Original Image Dimensions X Y in pixels. + * New parameter aDimXY in LoadFile( cFileName, aDimXY ) + * New parameter aDimXY in Draw( oPrn, aRectangle, aDimXY ) + to introduce the original image dimensions in pixels X Y. + Some printer drivers may require the insertion of the original image dimensions + for processing, others read from the data source and by default only need have + aDimXY := { 1, 1 } + * Use DimXY VAR of win_BMP() in method DrawBitMap( oBmp ) of win_PRN() + + * src/compiler/hbusage.c + + Added author ID mail + 2010-01-24 14:30 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * utils/hbmk2/hbmk2.prg + Added support to recognize .C (uppercase .c) extension as C++ file. diff --git a/harbour/contrib/hbwin/win_prn1.c b/harbour/contrib/hbwin/win_prn1.c index b68d0c5163..c5973fbb79 100644 --- a/harbour/contrib/hbwin/win_prn1.c +++ b/harbour/contrib/hbwin/win_prn1.c @@ -510,6 +510,29 @@ HB_FUNC( WIN_GETDOCUMENTPROPERTIES ) /* Functions for loading & printing bitmaps */ +/* Type BitMap: 1 == BM, 2 == JPEG, 3 == PNG [jarabal] */ +static int hbwin_TypeBitMap( const void *pImgBuf ) +{ + int iType = 0; + + if( pImgBuf ) + { + if( memcmp( pImgBuf, "BM", 2 ) == 0 ) + iType = 1; + else if( memcmp( pImgBuf, "\377\330\377", 3 ) == 0 ) + iType = 2; + else if( memcmp( pImgBuf, "\211PNG", 4 ) == 0 ) + iType = 3; + } + + return iType; +} + +HB_FUNC( WIN_TYPEBITMAP ) +{ + hb_retni( hbwin_TypeBitMap( hb_parc( 1 ) ) ); +} + HB_FUNC( WIN_LOADBITMAPFILE ) { HB_FHANDLE fhnd = hb_fsOpen( hb_parcx( 1 ), FO_READ | FO_SHARED ); @@ -526,11 +549,11 @@ HB_FUNC( WIN_LOADBITMAPFILE ) [vszakats] */ if( ulSize > 2 && ulSize <= ( 32 * 1024 * 1024 ) ) { - BITMAPFILEHEADER * pbmfh = ( BITMAPFILEHEADER * ) hb_xgrab( ulSize ); + void * pbmfh = hb_xgrab( ulSize ); hb_fsSeek( fhnd, 0, FS_SET ); - if( hb_fsReadLarge( fhnd, pbmfh, ulSize ) == ulSize && pbmfh->bfType == *( WORD * ) "BM" ) + if( hb_fsReadLarge( fhnd, pbmfh, ulSize ) == ulSize && hbwin_TypeBitMap( pbmfh ) ) hb_retclen_buffer( ( char * ) pbmfh, ( HB_SIZE ) ulSize ); else hb_xfree( pbmfh ); @@ -540,39 +563,118 @@ HB_FUNC( WIN_LOADBITMAPFILE ) } } +/* Some compilers don't implement these define [jarabal] */ +#ifndef CHECKJPEGFORMAT +#define CHECKJPEGFORMAT 4119 +#endif +#ifndef CHECKPNGFORMAT +#define CHECKPNGFORMAT 4120 +#endif + +static HB_BOOL hbwin_CheckPrnDrvFormat( HDC hDC, int iType, const void *pImgBuf, ULONG ulSize, PHB_ITEM pItmErrMsg ) +{ + if( hDC && iType && pImgBuf && ulSize >= sizeof( BITMAPCOREHEADER ) ) + { + if( iType == 1 ) + return HB_TRUE; + else + { + int iRes = iType = (iType == 2 ? CHECKJPEGFORMAT : CHECKPNGFORMAT); + + iRes = ExtEscape( hDC, QUERYESCSUPPORT, sizeof(iRes), ( LPCSTR ) &iRes, 0, 0 ); + if( iRes > 0 ) + { + if( ExtEscape( hDC, iType, ulSize, ( LPCSTR ) pImgBuf, sizeof(iRes), ( LPSTR ) &iRes ) > 0 ) + { + if( pItmErrMsg && iRes != 1 ) + hb_itemPutC( pItmErrMsg, "CHECKFORMAT failure" ); + + return iRes == 1; + } + else + { + if( pItmErrMsg ) + hb_itemPutC( pItmErrMsg, "Invalid source devmode for ESCSUPPORT" ); + + return HB_FALSE; + } + } + else + { + if( pItmErrMsg ) + hb_itemPutC( pItmErrMsg, "QUERYESCSUPPORT Not Implemented" ); + + return HB_FALSE; + } + } + } + else + return HB_FALSE; +} + +HB_FUNC( WIN_CHECKPRNDRVFORMAT ) +{ + const char * pImgBuf = hb_parc( 2 ); + + hb_retl( hbwin_CheckPrnDrvFormat( hbwapi_par_HDC( 1 ), hbwin_TypeBitMap( pImgBuf ), pImgBuf, hb_parclen( 2 ), hb_param( 3, HB_IT_BYREF ) ) ); +} + HB_FUNC( WIN_DRAWBITMAP ) { + BITMAPINFO * pbmi; + BYTE * pBits = NULL; HDC hDC = hbwapi_par_HDC( 1 ); + ULONG ulSize = hb_parclen( 2 ); + BITMAPFILEHEADER * pbmfh = ( BITMAPFILEHEADER * ) hb_parc( 2 ); + int cxDib = hb_parni( 7 ), cyDib = hb_parni( 8 ), iType = hbwin_TypeBitMap( pbmfh ); /* TOFIX: No check is done on 2nd parameter which is a large security hole and may cause GPF in simple error cases. [vszakats] */ - if( hDC && hb_parclen( 2 ) > 2 ) + if( hbwin_CheckPrnDrvFormat( hDC, iType, pbmfh, ulSize, NULL ) ) { - BITMAPFILEHEADER * pbmfh = ( BITMAPFILEHEADER * ) hb_parc( 2 ); - BITMAPINFO * pbmi = ( BITMAPINFO * ) ( pbmfh + 1 ); - BYTE * pBits; - int cxDib, cyDib; - - pBits = ( BYTE * ) pbmfh + pbmfh->bfOffBits; - - /* Remember there are 2 types of BitMap File */ - if( pbmi->bmiHeader.biSize == sizeof( BITMAPCOREHEADER ) ) + if( iType == 1 ) { - cxDib = ( ( BITMAPCOREHEADER * ) pbmi )->bcWidth; - cyDib = ( ( BITMAPCOREHEADER * ) pbmi )->bcHeight; + pbmi = ( BITMAPINFO * ) ( pbmfh + 1 ); + pBits = ( BYTE * ) pbmfh + pbmfh->bfOffBits; + + /* Remember there are 2 types of BitMap File */ + if( pbmi->bmiHeader.biSize == sizeof( BITMAPCOREHEADER ) ) + { + cxDib = ( ( BITMAPCOREHEADER * ) pbmi )->bcWidth; + cyDib = ( ( BITMAPCOREHEADER * ) pbmi )->bcHeight; + } + else + { + cxDib = pbmi->bmiHeader.biWidth; + cyDib = abs( pbmi->bmiHeader.biHeight ); + } + } + else if( cxDib && cyDib ) + { + BITMAPINFO bmi; + + memset( &bmi, 0, sizeof( bmi ) ); + bmi.bmiHeader.biSize = sizeof( BITMAPINFO ); + bmi.bmiHeader.biWidth = cxDib; + bmi.bmiHeader.biHeight = -cyDib; /* top-down image */ + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 0; + bmi.bmiHeader.biCompression = (iType == 2 ? BI_JPEG : BI_PNG); + bmi.bmiHeader.biSizeImage = ulSize; + pbmi = &bmi; + pBits = ( BYTE * ) pbmfh; + } + + if( pBits ) + { + SetStretchBltMode( hDC, COLORONCOLOR ); + hb_retl( StretchDIBits( hDC, hb_parni( 3 ), hb_parni( 4 ), hb_parni( 5 ), hb_parni( 6 ), + 0, 0, cxDib, cyDib, pBits, pbmi, + DIB_RGB_COLORS, SRCCOPY ) != ( int ) GDI_ERROR ); } else - { - cxDib = pbmi->bmiHeader.biWidth; - cyDib = abs( pbmi->bmiHeader.biHeight ); - } - - SetStretchBltMode( hDC, COLORONCOLOR ); - - hb_retl( StretchDIBits( hDC, hb_parni( 3 ), hb_parni( 4 ), hb_parni( 5 ), hb_parni( 6 ), - 0, 0, cxDib, cyDib, pBits, pbmi, - DIB_RGB_COLORS, SRCCOPY ) != ( int ) GDI_ERROR ); + hb_retl( HB_FALSE ); } else hb_retl( HB_FALSE ); @@ -580,15 +682,16 @@ HB_FUNC( WIN_DRAWBITMAP ) HB_FUNC( WIN_BITMAPDIMENSIONS ) { - if( hb_parclen( 1 ) > 1 ) + BITMAPFILEHEADER * pbmfh = ( BITMAPFILEHEADER * ) hb_parc( 1 ); + + if( hb_parclen( 1 ) >= sizeof( BITMAPCOREHEADER ) && hbwin_TypeBitMap( pbmfh ) == 1 ) { - BITMAPFILEHEADER * pbmfh = ( BITMAPFILEHEADER * ) hb_parc( 1 ); + int cxDib, cyDib; BITMAPINFO * pbmi = ( BITMAPINFO * ) ( pbmfh + 1 ); - int cxDib, cyDib; - + /* Remember there are 2 types of BitMap File */ if( pbmi->bmiHeader.biSize == sizeof( BITMAPCOREHEADER ) ) - { /* Remember there are 2 types of BitMap File */ + { cxDib = ( ( BITMAPCOREHEADER * ) pbmi )->bcWidth; cyDib = ( ( BITMAPCOREHEADER * ) pbmi )->bcHeight; } diff --git a/harbour/contrib/hbwin/win_tprn.prg b/harbour/contrib/hbwin/win_tprn.prg index 4d2f89ce98..9418b23806 100644 --- a/harbour/contrib/hbwin/win_tprn.prg +++ b/harbour/contrib/hbwin/win_tprn.prg @@ -732,7 +732,7 @@ METHOD GetTextHeight( cString ) CLASS WIN_PRN METHOD DrawBitMap( oBmp ) CLASS WIN_PRN LOCAL lResult := .F. IF ::BitMapsOk .AND. ::CheckPage() .AND. ! Empty( oBmp:BitMap ) - IF ( lResult := win_DrawBitMap( ::hPrinterDc, oBmp:BitMap, oBmp:Rect[ 1 ], oBmp:Rect[ 2 ], oBmp:rect[ 3 ], oBmp:Rect[ 4 ] ) ) + IF ( lResult := win_DrawBitMap( ::hPrinterDc, oBmp:BitMap, oBmp:Rect[ 1 ], oBmp:Rect[ 2 ], oBmp:Rect[ 3 ], oBmp:Rect[ 4 ], oBmp:DimXY[ 1 ], oBmp:DimXY[ 2 ] ) ) ::HavePrinted := .T. ENDIF ENDIF @@ -776,11 +776,14 @@ CREATE CLASS WIN_BMP EXPORTED: METHOD New() - METHOD LoadFile( cFileName ) + METHOD LoadFile( cFileName, aDimXY ) METHOD Create() METHOD Destroy() - METHOD Draw( oPrn, aRectangle ) + METHOD Draw( oPrn, aRectangle, aDimXY ) + METHOD CheckPrnDrvFormat( oPrn, cErrMsg ) + VAR Type INIT 0 // Type BitMap: 1 == BM, 2 == JPEG, 3 == PNG + VAR DimXY INIT { 0, 0 } // Image Dimensions X Y pixels VAR Rect INIT { 0, 0, 0, 0 } // Coordinates to print BitMap // XDest, // x-coord of destination upper-left corner // YDest, // y-coord of destination upper-left corner @@ -794,10 +797,21 @@ ENDCLASS METHOD New() CLASS WIN_BMP RETURN Self -METHOD LoadFile( cFileName ) CLASS WIN_BMP +METHOD LoadFile( cFileName, aDimXY ) CLASS WIN_BMP ::FileName := cFileName + IF ValType( aDimXY ) == "A" + ::DimXY := aDimXY + ELSE + ::DimXY := { 1, 1 } // Driver using the original dimensions + ENDIF ::Bitmap := win_LoadBitMapFile( ::FileName ) - RETURN ! Empty( ::Bitmap ) + IF Empty( ::Bitmap ) + ::Type := 0 + ::DimXY := { 0, 0 } + ELSE + ::Type := win_TypeBitMap( ::Bitmap ) + ENDIF + RETURN ::Type > 0 METHOD Create() CLASS WIN_BMP // Compatibility function for Alaska Xbase++ RETURN Self @@ -805,10 +819,18 @@ METHOD Create() CLASS WIN_BMP // Compatibility function for Alaska Xbase++ METHOD Destroy() CLASS WIN_BMP // Compatibility function for Alaska Xbase++ RETURN NIL -METHOD Draw( oPrn, aRectangle ) CLASS WIN_BMP // Pass a WIN_PRN object reference & Rectangle array - ::Rect := aRectangle +METHOD Draw( oPrn, aRectangle, aDimXY ) CLASS WIN_BMP // Pass a WIN_PRN object reference & Rectangle array [& Image Dimensions X Y pixels array] + IF ValType( aRectangle ) == "A" + ::Rect := aRectangle + ENDIF + IF ValType( aDimXY ) == "A" + ::DimXY := aDimXY + ENDIF RETURN oPrn:DrawBitMap( Self ) +METHOD CheckPrnDrvFormat( oPrn, cErrMsg ) CLASS WIN_BMP + RETURN win_CheckPrnDrvFormat( oPrn:hPrinterDc, ::Bitmap, @cErrMsg ) + #ifdef HB_COMPAT_XPP /* Compatibility Class for Alaska Xbase++ */ diff --git a/harbour/src/compiler/hbusage.c b/harbour/src/compiler/hbusage.c index 81b377e814..386833fd1a 100644 --- a/harbour/src/compiler/hbusage.c +++ b/harbour/src/compiler/hbusage.c @@ -260,6 +260,7 @@ void hb_compPrintCredits( HB_COMP_DECL ) "Viktor Szakats (harbour.01 syenar.hu)\n" "Vladimir Kazimirchik \n" "Walter Negro \n" + "Xavi \n" ); }