EAN/UPC Barcodes in PDF Forms

Something interesting came up recently, and it took me a bit longer than expected to actually make it work… I was asked about how one would add EAN13 or UPC barcodes to a PDF form. My shooting from the hip answer was: Just download and install the corresponding barcode font and use it. Pretty straight forward. And had this been about a 3 of 9 barcode or some other simple barcode, then that would have been the correct answer, but once I tried to do this with an EAN13 font, I ran into a few problems.

So, I did some research. It turns out that with the EAN/UPC barcode, there is no simple 1:1 relationship between the character we want to encode and the sequence of bars and gaps. You can find a lot more about how this works here: https://softmatic.com/barcode-ean-13.html

A simple internet search did bring up an open source font for this type of barcodes: https://graphicore.github.io/librebarcode/documentation/ean13.html The actual font file can be downloaded here https://github.com/graphicore/librebarcode/releases or can be accessed via Google Fonts.

The documentation for this project also seems to imply that one can just install the font, select it and it should work. There is however one caveat: The font file uses the “calt” or Contextual Alternatives feature in the OpenType font, and without support for this, the “Standard Input Method” outlined will not work. Unfortunately, Acrobat does not seem to support this feature, so when I created a form field, selected the barcode font and added some data, I did not end up with a valid barcode:

Screenshot of an invalid barcode with two thin lines for every character in the string 01234567890

This is what I would have expected:

Screenshot of a barcode for the value 0123456789012

This is not a valid EAN/UPC barcode because the checksum is not correct, but it demonstrates the difference between the completely wrong code in the “Standard Input Method” example.

The Libre Barcode documentation allows for two alternative input methods, but both of them require some heavy lifting to convert the text string to a sequence of glyphs that when rendered will produce the correct barcode. For the following, we are considering the “Compatible Input Method”. After some searching, I found some information with a Visual Basic program to perform this conversion, which of course would not be applicable to the PDF forms environment. I used the VB program as inspiration and created an implementation in JavaScript.

My solution requires three steps:

  1. Download and install the Libre Barcode EAN13 font
  2. Create a document level JavaScript with the function to convert a 12 or 13 digit string into a “Compatible Input Method” string
  3. Use some JavaScript in the form field’s calculation script to perform this conversion and then display the string using the barcode font

Download and Install the Font

Use the link from above to download the font and then use your operating system’s process to install it. This will be different for macOS vs. Windows.

Document Level Script

To setup the document level script. open the “JavaScripts” tools in Acrobat and select “Document JavaScript” from the toolbar. This will bring up a window in which you can create a new document level script. Enter convert_ean13 as the name of the script and click on the “Add” button. This will bring up the JavaScript editor. Copy and paste the following script to replace the function stub already there:

function convert_ean13(ch_in) {
	/* this is based on VB script from https://github.com/graphicore/librebarcode/issues/44
	input: string with 12 digits (the barcode without the checksum)
	       or
	       string with 13 digits (the barcode with the checksum)
	return: a string using the "compatible input method" for the barcode
	*/

	ean13 = ""; // initialize the return string

	// do we have an all numeric input? 
	if (!/\d+/.test(ch_in)) {
		console.println("ERROR: input string is not numeric - " + ch_in);
		return "";
	}

	// do we have 12 or 13 input characters? 
	if (ch_in.length == 12) {
		// calculate the checksum
		var checksum = 0;
		for (var i = 0; i < 12; i++) {
			var digit = Number(ch_in.charAt(i));
			if (i % 2) {
				checksum += 3 * digit;
			} else {
				checksum += digit;
			}
		}
		checksum = (10 - (checksum % 10)) % 10;
		// add the new digit at the end of the input string
		ch_in = ch_in.toString() + checksum.toString();
	} else if (ch_in.length == 13) {
		// nothing to do, we already have a checksum
	} else {
		console.println("ERROR: wrong number of characters - " + ch_in);
		return "";
	}

	// at this point we have a 13 string input 
	ean13 = ch_in.charAt(0);
	ean13 = ean13 + String.fromCharCode(65 + Number(ch_in.charAt(1)));

	var first = Number(ch_in.charAt(0));
	for (var i = 2; i < 7; i++) {
		var tableA = false;
		switch (i) {
			case 2:
				if (first >= 0 && first <= 3) {
					tableA = true;
				}
				break;
			case 3:
				switch (first) {
					case 0:
					case 4:
					case 7:
					case 8:
						tableA = true;
						break;
				}
				break;
			case 4:
				switch (first) {
					case 0:
					case 1:
					case 4:
					case 5:
					case 9:
						tableA = true;
						break;
				}
				break;
			case 5:
				switch (first) {
					case 0:
					case 2:
					case 5:
					case 6:
					case 7:
						tableA = true;
						break;
				}
			case 6:
				switch (first) {
					case 0:
					case 3:
					case 6:
					case 9:
						tableA = true;
						break;
				}
				break;
		}
		if (tableA) {
			ean13 = ean13 + String.fromCharCode(65 + Number(ch_in.charAt(i)));
		} else {
			ean13 = ean13 + String.fromCharCode(75 + Number(ch_in.charAt(i)));
		}
	}
	// add the middle separator
	ean13 = ean13 + "*";
	for (i = 7; i < 13; i++) {
		ean13 = ean13 + String.fromCharCode(97 + Number(ch_in.charAt(i)));
	}
	ean13 = ean13 + "+";
	return ean13;
}

Save this script and start to work on your form.

Create Barcode Form Field

In your form, create a text field and bring up the text field's properties dialog. Go to the General tab and make the field read-only if that is required (e.g. if you are using a different input field to collect the barcode string, or if the string gets calculated). Then go to the Appearance tab and select the "Libre Barcode EAN13 Text" font. If you installed the font while Acrobat was open, you will have to save the document and restart Acrobat before the font will show up in the list.

And finally, go to the Calculate tab and select to use a custom calculation script. The following script collects information form another field, in which a product naem will be entered, and then the corresponding barcode string is looked up in a JavaScript data structure, and that string is then converted to our "Compatible Input Method" string and displayed. Use the following script for that:

// Get the text from the field "SomeText", then do a lookup operation to find the code for the corresponding barcode and display 
// that barcode in this field. This requires that the field is configured with the correct barcode font. 

// ideally, the follwing "map" would be stored in a document level script
// data mapping
var mapToBarcode = { 
"Product1" : "404142434445",
"Product2" : "302928272625",
"Product3" : "012345678901",
// add more products
};

// the text we need to map:
var textToMap = this.getField("SomeText").value;
var textToDisplay = "";

if (textToMap) {
    textToDisplay  = mapToBarcode[textToMap];
    if (typeof textToDisplay == "undefined") {
        // cannot map the product code
        console.println("ERROR: Cannot map product: " + textToMap);
        textToDisplay = "";
    }
    event.value = convert_ean13(textToDisplay);
}

To make this script work, add anther text field named "SomeText" and enter either "Product1", "Product2", or "Product3" in that field and see the corresponding barcode displayed in the barcode field. Please keep in mind that the EAN barcodes have very strict rules about size (see the first link in this post about the details).

So, this is how you add an EAN/UPC barcode to a PDF form. A bit more complicated than just "install the font and use it". Here is a link to a sample file: https://khkonsulting.com/files/blog/barcode.pdf

This entry was posted in Uncategorized and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *