zpl.tools
Bar codes

^BC - Code 128 Bar Code

The most common symbology for shipping and GS1 application identifiers, with four data-encoding modes.

^BC prints a Code 128 symbol. The symbology is variable length and continuous, and it encodes the full ASCII range through three character subsets. Code 128 is the symbology behind most shipping labels, and the D mode encodes GS1-128 data with application identifiers.

Syntax

^BCo,h,f,g,e,m

Support

Partially supportedparsed: full · state: full · rendered: partial

The command renders, with the caveat below.

All four modes render, and mode U defaults its interpretation line above the symbol. One behavior is absent. The renderer parses the e GS1 check-digit argument but never applies it, which changes the printed label. Write the e check digit into the data. — pinned by test_difference_between_mode_annotation

Labelary renders this command.

Parameters

oBar code orientationoptional · one of a set

Rotation of the symbol and interpretation line.

Default
the orientation set by ^FW, which itself defaults to N
Invalid value
discarded, and the default applies. The renderer reports an unrecognized character as invalid, and uses the default.
Test coverage
Values exercised: N, R, I, B. The invalid-value rule is pinned by 1 test.
N
No rotation (default)
R
Rotated 90° clockwise
I
Rotated 180°. The symbol reads upside down
B
Rotated 270° clockwise
hBar code heightoptional · dots

Height of the bars, without the interpretation line.

Default
the height set by ^BY, which itself defaults to 10 dots
Accepted range
1 to 32000 dots
Invalid value
clamped to the nearest allowed value. We measured this against live Labelary on 2026-07-12. The renderer clamps an out-of-range value to the violated bound, and does not ignore it.
Test coverage
Bounds pinned: minimum (1), below the minimum (0), above the maximum (40000). No test at the maximum. The invalid-value rule is not pinned by a test.
fPrint interpretation lineoptional · Y or N

Whether the renderer prints the interpretation line.

Default
Y
Invalid value
discarded, and the default applies. The renderer reports any character except Y or N, and uses the default.
Test coverage
No documented value is exercised by a test (Y, N). The invalid-value rule is pinned by 1 test.
Y
Print the text (default)
N
Print the symbol only
gInterpretation line aboveoptional · Y or N

Where the interpretation line sits. It has no effect without that line.

Default
N in modes A, N and D, and Y in mode U
Invalid value
discarded, and the default applies. The renderer reports any character except Y or N, and uses the default.
Test coverage
Values exercised: Y, N. The invalid-value rule is not pinned by a test.
Y
Above the symbol
N
Below the symbol (default)
eGS1 mod 10 check digitoptional · Y or Nnot honoured by zpl.tools

The renderer appends the GS1 (UCC) mod-10 check digit to the encoded data.

Default
N
Invalid value
discarded, and the default applies. The renderer reports any character except Y or N, and adds no check digit.
Test coverage
No documented value is exercised by a test (Y, N). The invalid-value rule is not pinned by a test.
Y
Add the check digit
N
No check digit (default)
mModeoptional · one of a set

How the renderer turns the field data into Code 128 subsets.

Default
N
Invalid value
discarded, and the default applies. Any other value defaults to mode N. This matches the printer.
Test coverage
Values exercised: N, U, A, D. The invalid-value rule is pinned by 1 test.
N
No mode. The field data chooses the subsets explicitly with the >9, >: and >; invocation codes. (default)
U
UCC case mode. The field data must be 19 digits. The renderer computes the twentieth check digit.
A
Automatic mode. The renderer chooses the subsets. The >9, >: and >; invocation codes are data here rather than selectors.
D
UCC/EAN mode for GS1-128 data. This mode also shrinks the interpretation line to the symbol width.

Behavior

The symbol always carries a mod-103 check character. That character is part of the encoding and not of the data, it never appears in the interpretation line, and nothing turns it off. The e argument adds a second check digit, a mod-10 digit for UCC data, and the printer prints the second digit beside the first. It is not a switch for the mod-103 character.

Subset selection

In the default mode N an invocation code in the field data selects the subset:

CodeSubsetEncodes
>9AUpper case, digits, control characters
>:BUpper and lower case, digits, punctuation
>;CDigit pairs — twice the density, digits only

Mode A selects the subset instead. It examines the data, shifts subsets where necessary, and moves to subset C at every run of four or more digits, where the density gain occurs.

The UCC modes

Mode U expects exactly 19 digits and computes a twentieth digit as the check digit. Neither other length is an error: the printer truncates more than 19 digits, and pads fewer than 19 digits with zeros on the right. Both results give a symbol that scans and an interpretation line that is wrong. Check the length before use.

Mode D is the GS1-128 mode, also called the UCC/EAN mode. It starts in the correct subset and inserts FNC1 to mark the symbol as GS1. It removes parentheses and spaces before encoding and still prints them in the human-readable text.

Mode D also scales the interpretation line to the width of the symbol and not to the current font size. The text can come out larger than the same data in mode N.

In this mode the data and not the argument decides the check digit. We measured this against Labelary on 2026-07-29 with application identifier 00, which defines an 18-digit SSCC. With all 18 digits, the renderer treats the last as the check digit and recomputes it, so (00)000123456789012345 prints as (00)000123456789012343. With 17 digits, the renderer adds and pads nothing, and the line prints exactly as supplied.

Do not give mode D a partial field and expect completion.

The width of the label limits the field data. For a rotated symbol, the length of the label limits it. The data does not wrap.

Known issues

Tested behavior

Differences from the specification

zpl.tools against the ZPL II guide

Where our renderer behaves differently from the specification.

  • The guide takes the default orientation from ^FW. The renderer applies ^FW to text fields only. A barcode after ^FWR prints unrotated unless its own o argument rotates it. — not pinned by a test
  • The renderer parses the e GS1 mod-10 check-digit argument and ignores it. Mode U computes its own, so this affects only the other three modes. — pinned by test_prefix_parsing

Example

Plain Code 128, subset B chosen explicitly, with the interpretation line below:

^XA
^FO50,50^BY3
^BCN,100,Y,N,N
^FD>:SHIP-12345^FS
^XZ

Open in viewer

GS1-128 in mode D, encoding an SSCC under application identifier 00. The parentheses print but are not encoded, and the final digit prints as 3 — the recomputed check digit — rather than the 5 supplied:

^XA
^FO50,50^BY3
^BCN,120,Y,N,N,D
^FD(00)000123456789012345^FS
^XZ

Open in viewer