^PA - Advanced Text Properties
Turns on bidirectional layout, character shaping and OpenType features.
^PA switches on the parts of text layout that go beyond one glyph after another:
- the reorder of right-to-left runs
- the contextual form of a letter
- the OpenType tables of a font
Arabic, Hebrew and the Indic scripts need at least one of them to be readable. All four settings are off by default, so the ZPL default is the naive one: bytes in, glyphs out, left to right.
Syntax
^PAa,b,c,dSupport
Recognised as valid ZPL and not implemented yet, so it has no effect on the output.
The renderer does not parse this command yet. No font here carries a Hebrew or Indic glyph, so those scripts draw nothing; Arabic draws unjoined isolated forms on the faces that carry it. — not pinned by a test
Labelary renders this command. Scheduled for milestone 5.9.
Parameters
aDefault glyphoptional · one of a setWhat to print where the font has no glyph for a character.
- Default
- the previously set value, or 0
- Invalid value
- discarded, and the current value is kept
- Test coverage
- No documented value is exercised by a test (0, 1). The invalid-value rule is not pinned by a test.
0- Print a space for a character the font lacks (default)
1- Print the font's own default glyph for a missing character
bBidirectional text layoutoptional · one of a setWhether the renderer applies the Unicode bidirectional algorithm.
- Default
- the previously set value, or 0
- Invalid value
- discarded, and the current value is kept
- Test coverage
- No documented value is exercised by a test (0, 1). The invalid-value rule is not pinned by a test.
0- Off. Characters print in the order they appear (default)
1- On. The renderer reorders right-to-left runs for display
cCharacter shapingoptional · one of a setWhether the renderer substitutes glyphs by their neighbors.
- Default
- the previously set value, or 0
- Invalid value
- discarded, and the current value is kept
- Test coverage
- No documented value is exercised by a test (0, 1). The invalid-value rule is not pinned by a test.
0- Off (default)
1- On. The renderer selects contextual forms, as Arabic requires
dOpenType table supportoptional · one of a setWhether the renderer applies OpenType layout features.
- Default
- the previously set value, or 0
- Invalid value
- discarded, and the current value is kept
- Test coverage
- No documented value is exercised by a test (0, 1). The invalid-value rule is not pinned by a test.
0- Off (default)
1- On. The renderer uses the font's OpenType layout tables
Behavior
The command sets printer state rather than field state: it applies to the fields
that follow, and stays in force until the next ^PA changes it. Each argument is
independent, and an omitted argument keeps the previous value rather than defaults
to 0, so ^PA,,1 turns shaping on and leaves the rest alone.
The first argument is a diagnostic aid as much as a layout switch. ^PA0 prints a
space for a character the font has no glyph for, and that space looks like an
intended one. ^PA1 prints the font's .notdef glyph instead, usually an empty
box, which makes a missing glyph visible. Turn it on where text comes out
unexpectedly short.
Measured against Labelary on 2026-08-22: the third argument covers both the joining
of letterforms and the placement of combining marks, and the fourth changed nothing
on any probe. A value outside 0 and 1 is named and dropped, as in Value 2 is not a valid bidi layout flag (0/1) and was ignored.
Shaping and bidirectional layout are properties of the layout engine, not of the
encoding, so ^PA is not a substitute for ^CI28. Neither command is a substitute
for a font that contains the glyphs, which for these scripts means a ~DU
download.
Differences from the specification
Labelary against the ZPL II guide
Where Labelary — our compatibility target — behaves differently from the printed specification.
^PAis absent from the 2006 guide; Labelary's reference is the only description of it used here. — not pinned by a test
zpl.tools against Labelary
Where our output differs from Labelary for the same input. These are the differences that break a migration.
- Labelary honors the default-glyph argument: with
^PA1, a character the font has no glyph for prints as the font's.notdefbox. We measured that the renderer ignores^PA, so such a character always prints as a space. — not pinned by a test - No font in this renderer holds a Hebrew glyph, so a Hebrew field draws nothing where Labelary's scalable faces draw the word. Measured 2026-08-22:
^CI28^FDשלוםat 150 dots is 13,712 dots of ink on Labelary's face0and blank here. — not pinned: the only case that exercises it records a known issue (test_pa_hebrew_prints_nothing_where_labelary_prints_the_word) - Face
Ais DejaVu Sans Mono, which carries isolated Arabic, so an Arabic field draws unjoined letterforms in logical order here. Labelary has no face that can show Arabic at all and answersField data contains characters which the field font cannot display. — not pinned: the only case that exercises it records a known issue (test_pa_arabic_on_face_a_draws_isolated_forms) - Labelary reorders a right-to-left run when the bidirectional layout flag is 1, pixel for pixel as if the string were written backwards. We do not read the flag, so the run keeps its logical order. — not pinned: the only case that exercises it records a known issue (
test_pa_bidi_flag_leaves_the_run_in_logical_order) - Labelary joins Arabic letterforms and stacks combining marks over their bases when the character shaping flag is 1, measured against a downloaded TrueType font. We do not read the flag, and no glyph substitution or mark positioning happens here. — not pinned by a test
- Labelary names each flag it rejects, as in
Value 2 is not a valid bidi layout flag (0/1) and was ignored, and keeps the previous value. We report the command unsupported and read none of its four arguments. — pinned bytest_pa_out_of_range_flags_go_unreported
Example
The same field twice, once with the .notdef glyph turned on and once with it off.
^XA
^CI28
^PA1
^FO50,40^A0N,40^FDprice العربية each^FS
^PA0
^FO50,110^A0N,40^FDprice العربية each^FS
^XZ
Related commands
^CIChange International Font / EncodingSelects the character encoding of the field data.^A@Use Font Name to Call FontSelects a downloaded or built-in font by file name rather than by letter.^TBText BlockWraps text inside a box of a given width and height, clipping the overflow.^FLFont LinkChains a fallback font onto a base font for characters the base font lacks.