I guess you realize from the comments that this is kind of difficult to help with.
I'm not sure how much it will help, but I'd like to give some general tips about how you might approach this.
First of all, I'd probably throw away what you have and start over. I've NEVER regretted throwing away code--it always helps your code in the long run and you learn a lot more the second time through.
Secondly, start small. Make something that works--even if it just reads in the values and proves they were read in properly, then expand it. Test CONSTANTLY. Whenever you add to your code, add a line to your test to ensure the new code works as well as everything that has come before it
This way if anything breaks, you'll know exactly what broke it--the last thing you edited.
To do this kind of quick test, you should either learn to use JUnit for unit testing or have a main made just for testing so that you can hit a single button and get an immediate answer. (JUnit really isn't hard and it's built into Eclipse. Oh yeah, next hint). .
USE ECLIPSE or NetBeans!
These are all things that experienced programmers just know and do automatically. A little investment of time and effort in the beginning can save a LOT of pain in the long run.
The Code 128 barcode includes three modes. The "A" in your ^BC means that the barcode algorithm will automatically select the best mode based on the placement of where the letters are mixed in with the numbers, and/or how many numbers are in a row. This results in barcodes that vary in length depending on their content.
You can change that A to an N. This will make the width easy to estimate, even if it's not the most space efficient.
For the N option: count 106 dots, total, for the bookends, and 33 dots for each digit.
For the N + Subset C option: If you can say for sure that you will always have an even number of digits (no letters, spaces, or other symbols). You can force the barcode into subset C mode. Count 104 dots for the bookends, and 33 dots for every two digits. But you must have an even number of digits.
^BCN,100,Y,N,Y,N
^FD>;1422335544^FS
The >;
tells ZPL to render this as subset C.
If you know that you will need to support alphanumeric barcodes, then stick with the A. This is where things get harder.
You will need to model the barcode algorithm in your programming language of choice. Perhaps you could find an existing library, as Code 128 is a very popular barcode. Use the library to render the barcode in memory. You may have to play with the parameters to get it to produce a barcode equal to your ZPL output. Then have your program use the output of the library to determine the width of the barcode.
If your barcode is always going to be 13 digits, then automatic centering is a moot point. The barcode will always be the same width, even in automatic mode. Find the ^FO
that looks like it's centered on the label, and stick with that. This barcode is 368 dots wide. Try ^FO121,90
.
I didn't calculate the width of the barcode, I measured it by rendering the label to a Gif and then examining the label in a paint program that would let me count the dots.
Best Answer
I'm posting my solution in case someone is looking for it. As E_S mentions, in order to center a barcode in a label you have to calculate it by code following these steps:
(^BY2)
(eg: 8 dots / mm)
. so if you have a80 mm
wide label,80 * 8 = 640 dots
(">:", ">5", etc.)
count as one character, and that characters inmode C
are stored in pairs. For more information onmode C
, refer to http://en.wikipedia.org/wiki/Code_128>:S/N:941001-0114-0001
you have to count [start code B] + [20 characters] + [check digit] = 22>:S/N:>5941001>6->50114>6->50001
you have to count[start code B] + [4 characters for 'S/N:'] + [mode C invocation] + [3 characters for '941001'] + [mode B invocation] + [1 characters for '-'] + [mode C invocation] + [2 characters for '0114'] + [mode B invocation] + [1 characters for '-'] + [mode C invocation] + [2 characters for '0001'] + [check digit] = 20
stop code
that has 2 extra units (that is a total of 13)((chars counted [22 or 20] * 11) + (stop char * 13)) * narrow bar width = 510 dots or 466 dots
round((label width - barcode width) / 2)
and use that to position the barcode with^FT
That's it! Hope it helps someone!