zpl.tools
Label geometry

^LH - Label Home

Moves the origin that every field position is measured from.

^LH moves the point that ^FO and ^FT measure from, so a whole layout moves without a change to one field coordinate. Its usual job is preprinted stock. Set the home position below and right of the preprinted area. Then write the rest of the format as though the label started there. ^LH is not retroactive. A field already written stays where it is, so the guide recommends ^LH among the first commands in a format.

Syntax

^LHx,y

Support

Supportedparsed: full · state: full · rendered: full

Every documented parameter renders the same output Labelary produces.

Labelary renders this command.

Parameters

xX-axis homeoptional · dots

Dots to shift the origin right. Every ^FO and ^FT *after* this command is relative to the new origin; fields already drawn do not move.

Default
0
Accepted range
0 to 32000 dots
Invalid value
clamped to the nearest allowed value. A value outside 0 to 32000 clamps to the nearest bound; an omitted argument reads as 0.
Test coverage
Bounds pinned: above the maximum (99999). No test at the minimum or maximum. The invalid-value rule is not pinned by a test.
yY-axis homeoptional · dots

Dots to shift the origin down.

Default
0
Accepted range
0 to 32000 dots
Invalid value
clamped to the nearest allowed value. A value outside 0 to 32000 clamps to the nearest bound; an omitted argument reads as 0.
Test coverage
Bounds pinned: above the maximum (99999). No test at the minimum or maximum. The invalid-value rule is not pinned by a test.

Behavior

Three commands move a whole label, and they compose rather than override one another. For a field at ^FOx,y the final position is x + ^LH.x - ^LS across and y + ^LH.y + ^LT down. The renderer applies ^LH and ^LS as it places each field, so both reach only what follows them. It applies ^LT to the finished label, so ^LT moves everything, including a field written before it. A second ^LH halfway through a format therefore splits the label into two coordinate systems, and a second ^LT does not.

^LH accepts positive offsets only. The range starts at 0, so ^LH cannot pull content back above or to the left of the label edge. Use a negative ^LS to move right, or a negative ^LT to move up.

The guide asks for ^LH before the first ^FS, for compatibility with an older printer. The renderer does not enforce that, and a later ^LH does take effect for the fields after it. A format that depends on the loose behavior does not reproduce on the hardware.

On a printer the home position is a saved configuration setting and survives a power cycle, so the previous job can displace a format that assumes 0,0. Every request here starts from 0,0.

Tested behavior

Differences from the specification

zpl.tools against the ZPL II guide

Where our renderer behaves differently from the specification.

  • On a printer ^LH persists in configuration and survives a power cycle. Here it lasts for the label format that sets it. — not pinned by a test
  • A negative argument uses its magnitude, so ^LH-100,-50 moves the origin to 100,50. The guide's range for either argument starts at 0. Each one reports Value -100 is negative, but negative values are not allowed; used 100 instead. Labelary agrees, measured on 2026-08-21. — not pinned by a test

Example

The border is drawn before ^LH, so it stays on the true label edge. Everything after it is measured from 60,40, which is why the two ^FO0,… fields land inside the border rather than on it:

^XA
^FO0,0^GB812,406,4^FS
^LH60,40
^FO0,0^A0N,40,40^FDOrigin moved to 60,40^FS
^FO0,60^GB200,40,40^FS
^XZ

Open in viewer