PDFPipe

Linear (1D) / Code 39

Code 39 barcode in a PDF

The old alphanumeric workhorse: uppercase letters and digits, no mandatory check digit, and considerably wider than the alternatives.

Where the symbol comes from

This API renders HTML to PDF. It does not generate barcodes, so the Code 39 symbol itself is produced by an encoder in your own stack and placed in the markup, either as inline SVG or as a data URI. That split matters more than it sounds: the encoders are mature and correct, and almost every barcode that will not scan failed for a layout reason rather than an encoding one. Everything below is about the layout half.

What it can encode

Forty-three characters: digits, uppercase A to Z, space, and the symbols minus, full stop, dollar, slash, plus and percent. No lower case. An extended mode encodes full ASCII by using pairs of characters, at double the width, which is rarely worth it.

The check digit, and who computes it

Optional, and that is unusual. Code 39 is self-checking, meaning a single printing defect produces an invalid character rather than a wrong one, so a check digit is not required. A modulo 43 check character exists and some standards mandate it, so whether you need one is a question about the specification you are working to rather than about the symbology.

Size and quiet zone

The two measurements that decide whether a scanner accepts the symbol, and the two most often lost when a design is adjusted to fit.

  • X-dimension: Typically 0.19mm or larger. Because each character needs nine elements rather than the three of Code 128, the same data is substantially wider, and the practical constraint is usually the label rather than the minimum.
  • Quiet zone: 10 times the X-dimension at each end, with a common minimum of 6.4mm. The start and stop characters are both an asterisk, which appears in the symbol but is not part of your data.

Where it is used

  • defence, automotive and aerospace standards that were written decades ago and have not changed
  • internal asset tagging, where the human-readable value is uppercase alphanumeric anyway
  • laboratory and library systems with long-lived scanner estates

Placing it in the markup

The quiet zone is padding on the container rather than part of the encoder's output, so it survives a change of encoder. Dimensions are in millimetres, because a bar width is a physical measurement and a percentage makes it depend on whatever the container happens to be.

html
<figure class="code39">
  <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0i..." alt="Asset tag RVH-AHU-003">
  <figcaption>*RVH-AHU-003*</figcaption>
</figure>

<style>
.code39 {
  margin: 0;
  padding: 0 7mm;
}
.code39 img {
  /* Code 39 is wide. Twelve characters at a usable X-dimension is
     already most of the width of a small label, which is the real
     reason to reach for Code 128 instead when you have the choice. */
  width: 88mm;
  height: 16mm;
  display: block;
}
.code39 figcaption {
  font: 9pt/1.2 "IBM Plex Mono", monospace;
  letter-spacing: 0.1em;
  margin-top: 1.5mm;
}
</style>

What goes wrong on paper

Underestimating the width. Code 39 needs roughly half again the space of Code 128 for the same content, so a label that was designed around a Code 128 symbol and then switched to Code 39 for compatibility either overflows or gets scaled down past a usable X-dimension. Decide the symbology before the label, not after.

First thing to check when it will not scan

Check for lower case in the data. Code 39 has no lower case characters, and encoders handle that differently: some uppercase silently, some drop the character, some fail. If the scanned value does not match what you sent, character set is the first place to look.

Vector, not a bitmap

Encode to SVG wherever the encoder offers it. A rasterised barcode is resampled when the PDF is printed, and at 203 or 300 dots per inch the bar edges land between printer dots, so the ratio of bar to space drifts by a fraction of a millimetre. That fraction is the whole tolerance. An SVG stays vector inside the PDF and is rendered at the printer's own resolution, which removes the entire failure mode. Where a bitmap is unavoidable, generate it at the final physical size and set image-rendering so nothing smooths the edges.

Frequently asked

Does this API generate Code 39 symbols?

No. It renders HTML to PDF. The symbol is produced by a barcode library in your own application and embedded in the markup as SVG or as a data URI, which is the same way you would put any other generated graphic into a document. What this API is responsible for is that the symbol reaches the page at the size and position you specified.

Why does it scan on screen and fail on paper?

Three reasons, in order of frequency. The quiet zone is present on screen because the browser window is white and absent on paper because the label is not. The symbol was sized as a percentage, so it came out at a different physical width than the one that was tested. Or it is a bitmap, and printing resampled it so the bar-to-space ratio moved outside tolerance.

Can I scale the symbol to fit the space I have?

Uniformly, within the range the symbology allows, and never on one axis. Typically 0.19mm or larger. Because each character needs nine elements rather than the three of Code 128, the same data is substantially wider, and the practical constraint is usually the label rather than the minimum. is the constraint on the way down. Scaling one axis changes the bar-to-space ratio on a linear symbology and makes a 2D symbol non-square, and neither survives a scanner.

Other symbologies

Codes of the same kind, and one from each of the other kinds.

Paste the markup into the playground with your own encoder's output and see what comes out at the real page size.