^FB - Field Block
Word-wraps the field's text into a block of a given width.
^FB turns the field that follows into a block of a fixed width, and wraps the
text across as many lines as the block accepts. It is the only command that breaks
lines automatically in ZPL. Without it, a long ^FD runs off the edge of the
label and the overhang is lost. The line limit defaults to one, so ^FB600
alone wraps nothing.
Syntax
^FBa,b,c,d,eSupport
Every documented parameter renders the same output Labelary produces.
Labelary renders this command.
Parameters
aBlock widthoptional · dotsWidth of the text block. Text wraps at this width rather than running off the label.
- Default
- 0
- Accepted range
- 0 to the label width dots
- Invalid value
- discarded, and the default applies. A width of 0, or one narrower than a single character, leaves nowhere to fit a word. The guide says the text does not print; Labelary instead breaks after every character.
- Test coverage
- Bounds pinned: minimum (0), past what the shape can hold (99999). No test at the maximum. The invalid-value rule is pinned by 2 tests.
bMaximum linesoptional · integerHow many lines the block can occupy. The renderer drops no extra text: it prints every remaining line on top of the last one.
- Default
- 1
- Accepted range
- 1 to 9999 lines
- Invalid value
- clamped to the nearest allowed value. 0 clamps to 1, and a value above 9999 clamps to 9999. The renderer reports each as an invalid argument.
- Test coverage
- Bounds pinned: below the minimum (0), above the maximum (10000). No test at the minimum or maximum. The invalid-value rule is not pinned by a test.
cLine spacing changeoptional · dotsDots to add to (or, when negative, remove from) the space between lines.
- Default
- 0
- Accepted range
- -9999 to 9999 dots
- Invalid value
- clamped to the nearest allowed value. A value outside the range clamps to the bound it crossed.
- Test coverage
- No test at the minimum, maximum or one step outside the range. The invalid-value rule is pinned by 1 test.
dText justificationoptional · one of a setHow each line sits within the block width.
- Default
- L
- Invalid value
- discarded, and the default applies. Any other value left-justifies.
- Test coverage
- Values exercised: L, C, R, J. The invalid-value rule is pinned by 2 tests, including the diagnostic it emits.
L- Left (default)
C- Centered within the block width
R- Right
J- Justified, with word spacing stretched so both edges line up, except on the last line
eHanging indentoptional · dotsIndent applied to the second and every following line, leaving the first line flush.
- Default
- 0
- Accepted range
- 0 to 9999 dots
- Invalid value
- clamped to the nearest allowed value. A value above 9999 clamps to 9999, and reports an invalid argument.
- Test coverage
- Bounds pinned: above the maximum (10000). No test at the minimum or maximum. The invalid-value rule is pinned by 1 test.
Behavior
^FB belongs to one field and ends with it at ^FS. It must precede the ^FD it
applies to. Origin, font and rotation come from the field, and the block sits
inside them: d=C centers within the block width, not on the label.
A printer does not discard text that needs more lines than the limit accepts. It prints every remaining line on top of the last one, which gives an unreadable overstrike rather than a short address. The renderer does neither, and adds lines below the block. Check the length in advance, because the limit does not trim.
The block wraps at spaces. Labelary and a printer break a word wider than the block mid-word, and the renderer lets it overhang. A block width of 0 leaves room for nothing: the guide states the text does not print, and Labelary breaks after every character.
\& in the field data forces a line break. The renderer splits the data at each
\& first, then wraps each part to the block width. A forced break counts against
the line limit like any other line.
Justification J stretches the spaces between words until both edges line up, and
leaves the last line left-aligned. It differs from the justification argument of
^FO, ^FT and ^FW: those move the whole block relative to its origin, while
^FB's d aligns the lines within the block.
Known issues
2 known divergences from the reference render. Each is measured, tracked, and pinned by a test — so the output stays wrong in exactly these ways until the issues are fixed, rather than drifting.
A line wider than its block is right-aligned on the block's right edge, so it hangs off the left of the block Labelary starts it in
What the label says differs — a scanner or a person reads something other than the reference.
Tracked in docs/company/plan/phase-5/labelary-parity-findings-2026-08-22.md. Pinned so it cannot change unnoticed by test_fb_right_justified_over_wide_line_hangs_left.
A zero-width block keeps each word on one line where Labelary breaks it after every character
What the label says differs — a scanner or a person reads something other than the reference.
Tracked in docs/company/plan/phase-5/labelary-parity-findings-2026-08-22.md. Pinned so it cannot change unnoticed by test_fb_zero_width_keeps_whole_words.
Tested behavior
Differences from the specification
zpl.tools against the ZPL II guide
Where our renderer behaves differently from the specification.
- The line-spacing argument
cadds to the font-height line pitch, and a negative value tightens it, matching Labelary (measured 2026-08-14). — pinned bytest_fb_line_spacing_widens_the_line_pitch - The hanging-indent argument
eshifts every line but the first right by its value, matching Labelary (measured 2026-08-14). — pinned bytest_fb_hanging_indent_shifts_the_following_lines - The line limit
bpositions the block against an^FTbaseline, and text past it prints on top of the last line rather than flowing on, matching Labelary (measured 2026-08-14). — pinned bytest_fb_line_limit_does_not_truncate,test_fr_inverts_a_stacked_overflow_line_twice - Justification
Jstretches the word spacing of every line except the block's last content line, so each stretched line touches both edges, matching Labelary (measured 2026-08-14). — pinned bytest_fb_justified_differs_from_left,test_fb_justified_stretches_indented_lines,test_fb_justified_touches_both_edges,test_fb_justify_on_a_single_word_matches_left
zpl.tools against Labelary
Where our output differs from Labelary for the same input. These are the differences that break a migration.
- A word wider than the block is broken across lines at the last character whose advance fits, matching Labelary. The wrap measures a line's advance, bearings included, against the block's full width, and a line whose advance equals that width still fits (measured 2026-08-18). — pinned by
test_fb_does_not_break_inside_a_word
Example
The same text justified and left-aligned in a 600-dot block, with rules marking the block width:
^XA
^FO40,20^GB600,1,1^FS
^FO40,30^A0N,24,24^FB600,3,0,J
^FDjustified mode stretches the word spacing of every line except the last one so that both edges align^FS
^FO40,130^GB600,1,1^FS
^FO40,140^A0N,24,24^FB600,3,0,L
^FDleft mode leaves the ragged right edge alone which is the ordinary behaviour for a text block^FS
^XZ
Related commands
^FDField DataSupplies the text or barcode content of the field.^FOField OriginSets the top-left corner of the next field.^FTField TypesetPositions the next field by its text baseline rather than its top edge.^AScalable / Bitmapped FontSelects the font, rotation and size for the following field.