From 188c2064404842d1a3d5977f8cc150b3b37b69f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Fri, 22 Aug 2025 12:00:07 +0200 Subject: [PATCH] 2025-08-22 12:00 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/hbzebra/coredraw.c * contrib/hbzebra/hbzebra.hbx + added new PRG function: hb_zebra_getsize( , @, @ ) -> it calculates size in points of the created barcode and returns 0 on success or error code + contrib/hbzebra/tests/gtgfx.prg + borrowed from Viktor's fork, thanks 2014-09-18 22:32 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + added on-screen barcode example, created by elch (with some minor cleanups) https://groups.google.com/d/msg/harbour-users/_Wht51JZGgE/ZXyvaJNH9ggJ https://github.com/vszakats/hb/commit/feb4fc0e204388fd88ce0456564894469355affa * contrib/sddoci/core.c * map ostrlen() to strlen() or wcslen() in OCI_CHARSET_UNICODE builds ; TOFIX: this library uses wchar_t for unicode strings, it means that in *nixes where wchar_t is 32-bit integer mapping to Harbour HB_WCHAR is wrong and has to be fixed * include/hbapifs.h * src/harbour.def * src/rtl/filebuf.c + added new C function: HB_BOOL hb_fileSave( const char * pszFileName, const void * buffer, HB_SIZE nSize ); * include/harbour.hbx * src/harbour.def * src/rtl/vfile.c + added new PRG function: hb_vfSave( , ) --> * src/rtl/vfile.c * set FError() code in hb_vfLoad() --- ChangeLog.txt | 40 ++++++++++++- contrib/hbzebra/coredraw.c | 50 +++++++++++++++++ contrib/hbzebra/hbzebra.hbx | 1 + contrib/hbzebra/tests/gtgfx.prg | 99 +++++++++++++++++++++++++++++++++ contrib/sddoci/core.c | 6 ++ include/harbour.hbx | 1 + include/hbapifs.h | 1 + src/harbour.def | 2 + src/rtl/filebuf.c | 26 +++++++++ src/rtl/vfile.c | 16 ++++++ 10 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 contrib/hbzebra/tests/gtgfx.prg diff --git a/ChangeLog.txt b/ChangeLog.txt index b961e473ce..b808041f21 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,44 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2025-08-22 12:00 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * contrib/hbzebra/coredraw.c + * contrib/hbzebra/hbzebra.hbx + + added new PRG function: + hb_zebra_getsize( , @, @ ) -> + it calculates size in points of the created barcode and returns 0 on + success or error code + + + contrib/hbzebra/tests/gtgfx.prg + + borrowed from Viktor's fork, thanks + 2014-09-18 22:32 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com) + + added on-screen barcode example, created by elch + (with some minor cleanups) + https://groups.google.com/d/msg/harbour-users/_Wht51JZGgE/ZXyvaJNH9ggJ + https://github.com/vszakats/hb/commit/feb4fc0e204388fd88ce0456564894469355affa + + * contrib/sddoci/core.c + * map ostrlen() to strlen() or wcslen() in OCI_CHARSET_UNICODE builds + ; TOFIX: this library uses wchar_t for unicode strings, it means that + in *nixes where wchar_t is 32-bit integer mapping to Harbour + HB_WCHAR is wrong and has to be fixed + + * include/hbapifs.h + * src/harbour.def + * src/rtl/filebuf.c + + added new C function: + HB_BOOL hb_fileSave( const char * pszFileName, + const void * buffer, HB_SIZE nSize ); + + * include/harbour.hbx + * src/harbour.def + * src/rtl/vfile.c + + added new PRG function: + hb_vfSave( , ) --> + + * src/rtl/vfile.c + * set FError() code in hb_vfLoad() + 2025-08-17 18:27 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/gtqtc/gtqtc.h * contrib/gtqtc/gtqtc1.cpp @@ -425,7 +463,7 @@ we are switching to: http://timestamp.comodoca.com/authenticode ; It allows the user to choose the algorithm: SHA256 or SHA384, by appending ?td=sha384 to above URL - + 2025-01-24 15:02 UTC+0100 Aleksander Czajczynski (hb fki.pl) * contrib/hbct/dattime3.c ! fixed in block variable declaration for strict ANSI C compat diff --git a/contrib/hbzebra/coredraw.c b/contrib/hbzebra/coredraw.c index 99de084fe1..893a463ece 100644 --- a/contrib/hbzebra/coredraw.c +++ b/contrib/hbzebra/coredraw.c @@ -134,3 +134,53 @@ HB_FUNC( HB_ZEBRA_DRAW ) hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } } + +int hb_zebra_getsize( PHB_ZEBRA pZebra, int * piWidth, int * piHeight ) +{ + HB_SIZE n, nLen; + int iRow, iCol, iMaxCol = pZebra->iCol, iWidth, iHeight; + + if( pZebra->iError != 0 ) + { + *piWidth = *piHeight = 0; + return HB_ZEBRA_ERROR_INVALIDZEBRA; + } + + nLen = hb_bitbuffer_len( pZebra->pBits ); + iWidth = iHeight = 0; + iCol = iRow = 1; + for( n = 0; n < nLen; n++ ) + { + if( hb_bitbuffer_get( pZebra->pBits, n ) ) + { + if( iCol > iWidth ) + iWidth = iCol; + if( iRow > iHeight ) + iHeight = iRow; + } + if( iCol++ == iMaxCol ) + { + ++iRow; + iCol = 1; + } + } + + *piWidth = iWidth; + *piHeight = iHeight; + + return 0; +} + +HB_FUNC( HB_ZEBRA_GETSIZE ) +{ + PHB_ZEBRA pZebra = hb_zebra_param( 1 ); + + if( pZebra ) + { + int iWidth, iHeight; + + hb_retni( hb_zebra_getsize( pZebra, &iWidth, &iHeight ) ); + hb_storni( iWidth, 2 ); + hb_storni( iHeight, 3 ); + } +} diff --git a/contrib/hbzebra/hbzebra.hbx b/contrib/hbzebra/hbzebra.hbx index 24c8098873..4d7f021009 100644 --- a/contrib/hbzebra/hbzebra.hbx +++ b/contrib/hbzebra/hbzebra.hbx @@ -39,6 +39,7 @@ DYNAMIC hb_zebra_destroy DYNAMIC hb_zebra_draw DYNAMIC hb_zebra_getcode DYNAMIC hb_zebra_geterror +DYNAMIC hb_zebra_getsize #if defined( __HBEXTREQ__ ) .OR. defined( __HBEXTERN__HBZEBRA__REQUEST ) #uncommand DYNAMIC => EXTERNAL diff --git a/contrib/hbzebra/tests/gtgfx.prg b/contrib/hbzebra/tests/gtgfx.prg new file mode 100644 index 0000000000..f359faed0a --- /dev/null +++ b/contrib/hbzebra/tests/gtgfx.prg @@ -0,0 +1,99 @@ +/* Copyright 2010 Viktor Szakats */ + +/* Adapted to OS independent hb_gfxFilledRect() 2014 elch + Choose a graphics-capable GT at link time. + Notice that in GTWVT graphics is not persistent */ + +#require "hbzebra" + +#include "hbgtinfo.ch" +#include "hbgfx.ch" + +#define _SCALE_ 2 /* modifies y: font height, x: pixel */ + +PROCEDURE Main() + + SetMode( 21 * _SCALE_, 80 ) + SetColor( "B*/W" ) /* blink attribute for light white background in graphic GT */ + + CLS + + DrawBarcode( 1, 32, 1, "EAN13", "477012345678" ) + DrawBarcode( 2, 32, 1, "EAN8", "1234567" ) + DrawBarcode( 3, 32, 1, "UPCA", "01234567891" ) + DrawBarcode( 4, 32, 1, "UPCE", "123456" ) + DrawBarcode( 5, 32, 1, "CODE39", "ABC123" ) + DrawBarcode( 6, 32, 1, "CODE39", "ABC123", HB_ZEBRA_FLAG_CHECKSUM + HB_ZEBRA_FLAG_WIDE3 ) + DrawBarcode( 7, 32, 1, "ITF", "12345678901", HB_ZEBRA_FLAG_CHECKSUM ) + DrawBarcode( 8, 32, 1, "MSI", "1234567", HB_ZEBRA_FLAG_CHECKSUM ) + DrawBarcode( 9, 32, 1, "CODABAR", "40156", HB_ZEBRA_FLAG_WIDE3 ) + DrawBarcode( 10, 32, 1, "CODE93", "ABC-123" ) + DrawBarcode( 11, 32, 1, "CODE11", "1234567890", HB_ZEBRA_FLAG_CHECKSUM + HB_ZEBRA_FLAG_WIDE3 ) + DrawBarcode( 12, 32, 1, "CODE128", "Code 128" ) + DrawBarcode( 13, 32, 1, "PDF417", "Hello, World of Harbour!!! It's 2D barcode PDF417 :)" ) + DrawBarcode( 17, 32, 1, "DATAMATRIX", "Hello, World of Harbour!!! It's 2D barcode DataMatrix :)" ) + DrawBarcode( 19, 32, 1, "QRCODE", "https://en.wikipedia.org/wiki/QR_Code" ) + + WAIT + + RETURN + +STATIC PROCEDURE DrawBarcode( nY, nX, nLineWidth, cType, cCode, nFlags ) + + LOCAL hZebra, nLineHeight, cTxt, nYPixel + LOCAL nColor := hb_gfxMakeColor( 0, 0, 0 ) /* RGB black */ + + IF nLineWidth < 1 /* smaller as one pixel impossible */ + nLineWidth := 1 + ENDIF + + SWITCH cType + CASE "EAN13" ; hZebra := hb_zebra_create_ean13( cCode, nFlags ) ; EXIT + CASE "EAN8" ; hZebra := hb_zebra_create_ean8( cCode, nFlags ) ; EXIT + CASE "UPCA" ; hZebra := hb_zebra_create_upca( cCode, nFlags ) ; EXIT + CASE "UPCE" ; hZebra := hb_zebra_create_upce( cCode, nFlags ) ; EXIT + CASE "CODE39" ; hZebra := hb_zebra_create_code39( cCode, nFlags ) ; EXIT + CASE "ITF" ; hZebra := hb_zebra_create_itf( cCode, nFlags ) ; EXIT + CASE "MSI" ; hZebra := hb_zebra_create_msi( cCode, nFlags ) ; EXIT + CASE "CODABAR" ; hZebra := hb_zebra_create_codabar( cCode, nFlags ) ; EXIT + CASE "CODE93" ; hZebra := hb_zebra_create_code93( cCode, nFlags ) ; EXIT + CASE "CODE11" ; hZebra := hb_zebra_create_code11( cCode, nFlags ) ; EXIT + CASE "CODE128" ; hZebra := hb_zebra_create_code128( cCode, nFlags ) ; EXIT + CASE "PDF417" ; hZebra := hb_zebra_create_pdf417( cCode, nFlags ); nLineHeight := nLineWidth * 3 ; EXIT + CASE "DATAMATRIX" ; hZebra := hb_zebra_create_datamatrix( cCode, nFlags ); nLineHeight := nLineWidth ; EXIT + CASE "QRCODE" ; hZebra := hb_zebra_create_qrcode( cCode, nFlags ); nLineHeight := nLineWidth ; EXIT + ENDSWITCH + + nY *= _SCALE_ + nYPixel := nY * hb_gtInfo( HB_GTI_FONTSIZE ) + nLineWidth *= _SCALE_ + + IF hZebra != NIL + IF hb_zebra_geterror( hZebra ) == 0 + IF nLineHeight == NIL + nLineHeight := 16 + ENDIF + hb_dispOutAt( nY, nX - 31, cType ) + cTxt := hb_zebra_getcode( hZebra ) + IF Len( cTxt ) > nX - 12 + cTxt := Left( cTxt, nX - 12 - 4 ) + "..." + ENDIF + hb_dispOutAt( nY, nx - 20, cTxt ) + hb_zebra_draw_gfx( hZebra, nColor, nX * hb_gtInfo( HB_GTI_FONTWIDTH ), nYPixel, nLineWidth, nLineHeight * _SCALE_ ) + ELSE + ? "Type", cType, "Code", cCode, "Error", hb_zebra_geterror( hZebra ) + ENDIF + hb_zebra_destroy( hZebra ) + ELSE + ? "Invalid barcode type", cType + ENDIF + + RETURN + +STATIC FUNCTION hb_zebra_draw_gfx( hZebra, nColor, ... ) + + IF hb_zebra_geterror( hZebra ) != 0 + RETURN HB_ZEBRA_ERROR_INVALIDZEBRA + ENDIF + + RETURN hb_zebra_draw( hZebra, {| x, y, w, h | hb_gfxfilledRect( y, x, y + h, x + w, nColor ) }, ... ) diff --git a/contrib/sddoci/core.c b/contrib/sddoci/core.c index 89d1a3f29f..dd8bf63979 100644 --- a/contrib/sddoci/core.c +++ b/contrib/sddoci/core.c @@ -80,6 +80,9 @@ #define D_HB_ITEMPUTSTR( itm, str ) hb_itemPutStrU16( itm, HB_CDP_ENDIAN_NATIVE, str ) #define D_HB_ITEMPUTSTRLEN( itm, str, len ) hb_itemPutStrLenU16( itm, HB_CDP_ENDIAN_NATIVE, str, len ) #define D_HB_CHAR HB_WCHAR + #ifndef ostrlen + #define ostrlen wcslen + #endif #else #define D_HB_ARRAYGETSTR( arr, n, phstr, plen ) hb_arrayGetStr( arr, n, hb_setGetOSCP(), phstr, plen ) #define D_HB_ITEMCOPYSTR( itm, str, len ) hb_itemCopyStr( itm, hb_setGetOSCP(), str, len ) @@ -87,6 +90,9 @@ #define D_HB_ITEMPUTSTR( itm, str ) hb_itemPutStr( itm, hb_setGetOSCP(), str ) #define D_HB_ITEMPUTSTRLEN( itm, str, len ) hb_itemPutStrLen( itm, hb_setGetOSCP(), str, len ) #define D_HB_CHAR char + #ifndef ostrlen + #define ostrlen strlen + #endif #endif diff --git a/include/harbour.hbx b/include/harbour.hbx index ec9130b7a7..b03b43c700 100644 --- a/include/harbour.hbx +++ b/include/harbour.hbx @@ -973,6 +973,7 @@ DYNAMIC hb_vfRead DYNAMIC hb_vfReadAt DYNAMIC hb_vfReadLen DYNAMIC hb_vfRename +DYNAMIC hb_vfSave DYNAMIC hb_vfSeek DYNAMIC hb_vfSize DYNAMIC hb_vfTempFile diff --git a/include/hbapifs.h b/include/hbapifs.h index 828af0e714..5fa861c3cb 100644 --- a/include/hbapifs.h +++ b/include/hbapifs.h @@ -467,6 +467,7 @@ extern HB_EXPORT HB_BOOL hb_fileIsLocalName( const char * pszFileName ); extern HB_EXPORT HB_SIZE hb_fileResult( HB_SIZE nSize ); extern HB_EXPORT HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize, HB_SIZE * pnSize ); extern HB_EXPORT HB_BYTE * hb_fileLoadData( PHB_FILE pFile, HB_SIZE nMaxSize, HB_SIZE * pnSize ); +extern HB_EXPORT HB_BOOL hb_fileSave( const char * pszFileName, const void * buffer, HB_SIZE nSize ); /* interface to PRG level hb_vf*() file pointer items */ extern HB_EXPORT PHB_FILE hb_fileParam( int iParam ); diff --git a/src/harbour.def b/src/harbour.def index d4813b8f98..519f6501ff 100644 --- a/src/harbour.def +++ b/src/harbour.def @@ -1166,6 +1166,7 @@ HB_FUN_HB_VFREAD HB_FUN_HB_VFREADAT HB_FUN_HB_VFREADLEN HB_FUN_HB_VFRENAME +HB_FUN_HB_VFSAVE HB_FUN_HB_VFSEEK HB_FUN_HB_VFSIZE HB_FUN_HB_VFTEMPFILE @@ -2517,6 +2518,7 @@ hb_fileRegisterFull hb_fileRegisterPart hb_fileRename hb_fileResult +hb_fileSave hb_fileSeek hb_fileSize hb_fileSizeGet diff --git a/src/rtl/filebuf.c b/src/rtl/filebuf.c index bd081a78b7..1c57942be1 100644 --- a/src/rtl/filebuf.c +++ b/src/rtl/filebuf.c @@ -1645,3 +1645,29 @@ HB_BYTE * hb_fileLoad( const char * pszFileName, HB_SIZE nMaxSize, return pFileBuf; } + +HB_BOOL hb_fileSave( const char * pszFileName, const void * buffer, HB_SIZE nSize ) +{ + HB_BOOL fResult = HB_FALSE; + PHB_FILE pFile = hb_fileExtOpen( pszFileName, NULL, + FO_READWRITE | FO_EXCLUSIVE | FO_PRIVATE | + FXO_TRUNCATE | FXO_SHARELOCK, + NULL, NULL ); + if( pFile != NULL ) + { + const HB_BYTE * pData = buffer; + + while( nSize > 0 ) + { + HB_SIZE nWritten = hb_fileWrite( pFile, pData, nSize, 0 ); + if( nWritten == 0 || nWritten == ( HB_SIZE ) FS_ERROR ) + break; + nSize -= nWritten; + pData += nWritten; + } + fResult = nSize == 0; + + hb_fileClose( pFile ); + } + return fResult; +} diff --git a/src/rtl/vfile.c b/src/rtl/vfile.c index 26bee6c6a3..0b2922fc4b 100644 --- a/src/rtl/vfile.c +++ b/src/rtl/vfile.c @@ -910,9 +910,25 @@ HB_FUNC( HB_VFLOAD ) { HB_SIZE nSize; char * pBuffer = ( char * ) hb_fileLoad( pszFileName, hb_parns( 2 ), &nSize ); + hb_fsSetFError( hb_fsError() ); if( pBuffer ) hb_retclen_buffer( pBuffer, nSize ); } else hb_errRT_BASE_SubstR( EG_ARG, 2021, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } + +/* hb_vfSave( , ) --> */ +HB_FUNC( HB_VFSAVE ) +{ + const char * pszFileName = hb_parc( 1 ); + const char * pszFileBody = hb_parc( 2 ); + + if( pszFileName && pszFileBody ) + { + hb_retl( hb_fileSave( pszFileName, pszFileBody, hb_parclen( 2 ) ) ); + hb_fsSetFError( hb_fsError() ); + } + else + hb_errRT_BASE_SubstR( EG_ARG, 2021, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +}