• Welcome to PlanetSquires Forums.
 

C# Headers and functions

Started by Petrus Vorster, November 04, 2022, 06:40:56 AM

Previous topic - Next topic

Petrus Vorster

Hi All

It seems that C++ and C# forums has a lot of headers and tools.

Since I am always busy with barcodes, and those needs to be in international accepted standards, I am wondering if one can get a c header for those functions, how it can be used in Freebasic, especially the WINFBE designer.

My old powerbasic barcode creator DPI's does not meet the standards.
I need to up this to work on a reasonable label printer and be placed on documents or in-house products.

Some ideas would be great.

-Peter
-Regards
Peter

Paul Squires

Hi Peter,

I've seen that you asked similar questions in the past about barcodes and SVG and printer output, etc. Let's get you settled away with some solutions.  :)

Give me a little bit of time to read up on EAN128 barcodes and I will see if I can convert some existing code or find a good "C" library. It is not feasible to use C++ or C# because they do not integrate easily into FB.

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

Hi Peter,

Here is my conversion of the EAN128 barcode code. Please check it to ensure that it generates the correct sequence of "1" and "0"'s. I modified Nathan Durland's old PB code and converted it to use lookup table arrays and a couple of other optimizations. I assume that Nathan's code was correct.

Once you are confident that the code produced by my code is correct, then we can move on to using the output to generate some type of image file (SVG, metafile, PNG, etc). After that then we can tackle the printing.

' Based on code by Nathan Durland
' https://www.planetsquires.com/protect/forum/index.php?msg=27564

' Converted by Paul Squires to use lookup table arrays
' and other optimizations.

dim shared EAN128Pattern(32 to 95) as string * 11 => _
   { "11011001100","11001101100","11001100110","10010011000","10010001100","10001001100", _
     "10011001000","10011000100","10001100100","11001001000","11001000100","11000100100", _
     "10110011100","10011011100","10011001110","10111001100","10011101100","10011100110", _
     "11001110010","11001011100","11001001110","11011100100","11001110100","11101101110", _
     "11101001100","11100101100","11100100110","11101100100","11100110100","11100110010", _
     "11011011000","11011000110","11000110110","10100011000","10001011000","10001000110", _
     "10110001000","10001101000","10001100010","11010001000","11000101000","11000100010", _
     "10110111000","10110001110","10001101110","10111011000","10111000110","10001110110", _
     "11101110110","11010001110","11000101110","11011101000","11011100010","11011101110", _
     "11101011000","11101000110","11100010110","11101101000","11101100010","11100011010", _
     "11101111010","11001000010","11110001010","10100110000" }

dim shared EAN128CheckSum(0 to 104) as string * 11 => _
   { "11011001100","11001101100","11001100110","10010011000","10010001100","10001001100", _
     "10011001000","10011000100","10001100100","11001001000","11001000100","11000100100", _
     "10110011100","10011011100","10011001110","10111001100","10011101100","10011100110", _
     "11001110010","11001011100","11001001110","11011100100","11001110100","11101101110", _
     "11101001100","11100101100","11100100110","11101100100","11100110100","11100110010", _
     "11011011000","11011000110","11000110110","10100011000","10001011000","10001000110", _
     "10110001000","10001101000","10001100010","11010001000","11000101000","11000100010", _
     "10110111000","10110001110","10001101110","10111011000","10111000110","10001110110", _
     "11101110110","11010001110","11000101110","11011101000","11011100010","11011101110", _
     "11101011000","11101000110","11100010110","11101101000","11101100010","11100011010", _
     "11101111010","11001000010","11110001010","10100110000","10100001100","10010110000", _
     "10010000110","10000101100","10000100110","10110010000","10110000100","10011010000", _
     "10011000010","10000110100","10000110010","11000010010","11001010000","11110111010", _
     "11000010100","10001111010","10100111100","10010111100","10010011110","10111100100", _
     "10011110100","10011110010","11110100100","11110010100","11110010010","11011011110", _
     "11011110110","11110110110","10101111000","10100011110","10001011110","10111101000", _
     "10111100010","11110101000","11110100010","10111011110","10100001000","11101011110", _
     "11110101110","11010000100","11010010000" }

'//
'//
function CreateEAN128( byval src as string ) as string
   '-------------------------------------------------------
   ' This function encodes the given string into a string
   ' of 1's and 0's; this is the pattern for the bars in
   ' the bar code
   '-------------------------------------------------------

   dim as long checksum = 103     ' checksum modulus
   dim as string z                ' output string used to construct the barcode
   dim as long ch                 ' individual character in the src string
   dim as long chcheck            ' individual character checksum

   ' Convert the incoming src source string to all uppercase and
   ' ensure no leading or trailing spaces.
   src = ucase(trim(src))
 
   z = "0000000000"    & _    ' leading quiet zone
       "11010000100"          ' 2 1 1 4 1 2  Start Class A

   for i as long = 0 to len(src) - 1
      ch = src[i]
      if (ch >= 32) andalso (ch <= 95) then
         z = z & EAN128Pattern(ch)
         chcheck = (ch - 32)
         checksum = checksum + (chcheck * i)
      else
         ? "invalid character: "; chr(ch)  
      end if
   next

   checksum = (checksum mod 103)
   z = z & EAN128CheckSum(checksum)
  
   z = z & "1100011101011"  & _   ' 2 3 3 1 1 1 2 Stop (7 patts.)
           "0000000000"           ' trailing quiet zone

   function = z

end function



'------------------------------------------------------------------------------------------------------------------------
' MAIN ENTRY POINT - TEST CODE

dim as string teststring = "Paul Squires"

? "teststring: "; teststring
? "EAN128 barcode: "; CreateEAN128(teststring)

sleep

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Petrus Vorster

Hi Paul

This is amazing.
Some barcodes are easy like 3 of 9. Simple.
The 128C is quite something else. (and then there is QR!)

I got it to work perfectly in Powerbasic with the help of many people.
You create the encoded string with the check digit, then use a font to create PNG.
But for some reason, my font did not scale up correctly.
And every good font you need to pay for!

I will check tonight at home.
Someone else on the forum once asked me about this too privately some time ago. I think he has one of those Toshiba sorting robots and wanted to print these on the fly so the bot could move the heavy stuff automatically on a conveyor belt.
My barcoder worked, but it was not up to EU standards.

in .NET its a simple as Encodedstring$ = EAN128barcode(Originalstring$).
I never checked how they draw the lines though in .net. (Too much stuff going on there)

The only way to really and quickly test it, is having a good quality scanner on hand that can scan straight of the screen.
You create the test-string, print to PNG on-screen and scan it.

I appreciate it that you went out of your way with all your workload.
Regards,

Peter
-Regards
Peter

Petrus Vorster

Hi Paul

This looks perfectly fine.
Now to convert that into an actual Barcode....

Nathan is quite the expert on barcodes.
This is also MUCH different than how we did it in Powerbasic.
We build a string with ASCII characters, leading and ending character + Check digit.
It looked weird, but it worked once you turn that into  barcode font.

The binary string , I am afraid I am completely lost.  :o

Regards, Peter
-Regards
Peter

Paul Squires

Hi Peter,

I will research more into this. I am thinking that I could output the string to an EMF raster image that I should be able to load into WinFBE's image control which uses Jose's image control behind the scenes using GDI+. From there, it is just a hopefully simple jump to printing it.

I think that I will also research for any "C" DLL's that already do all of this stuff. Creating barcode, creating image file, etc... Might be easier than creating everything from scratch. I'd only then have to compile the DLL for 32/64 bit and create the header file.

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

Hi Peter,

I did a bit more internet searching tonight and rather than re-invent everything from scratch, why not just distribute a standalone EXE with your app that generates the barcode image for you!

Here is the best one that I could find that allows you to create the barcode from a command line program.

https://zint.org.uk/manual/chapter/4

I have attached that zint.exe command line program to this email.

In your application, you would simply need to shell to the zint program and feed it your data via the command line. The zint program will then generate the barcode image which you could then display in your program. The end user would never know that your program is shelling to the barcode exe because you can suppress the "DOS" like command window that would flash on the screen.

Seems to be the easiest, low effort, high reward way of doing accomplishing your barcode needs.



Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

Quote from: Petrus Vorster on November 04, 2022, 01:28:58 PMNow to convert that into an actual Barcode....
We build a string with ASCII characters, leading and ending character + Check digit.
It looked weird, but it worked once you turn that into  barcode font.
The binary string , I am afraid I am completely lost.

Pretty simple. You would loop through the string and for every "1" you would draw a line in your image. For a "0" you would just leave the space blank. The hard part would be setting up the image and outputting the commands that actually draw the lines. Depending on the image format (PNG, EMF, etc) then it could involve a little bit of work. Once you have the image generated then the rest is easy.... just load it into your image control.

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Petrus Vorster

Hi Paul

The old VB6 examples I had also went this way of drawing the barcode yourself.
Then some bright guy came up with a font which made it much easier.

I have never done any form of line drawing in Freebasic yet.
That would be an interesting journey.

Regards,

Peter
-Regards
Peter

Paul Squires

The reason I suggest using the external program to generate the barcode and image is that the source code that I posted does not handle CODE A, CODE B, CODE C stuff in Code128 format? Not that I know much about that stuff but I have seen it in all of the source code that I have reviewed related to Code128/EAN128 format. I think it is just a way of creating a more efficient barcode and/or handling special character.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer