EgoPDF.Barcodes
1.1.0
dotnet add package EgoPDF.Barcodes --version 1.1.0
NuGet\Install-Package EgoPDF.Barcodes -Version 1.1.0
<PackageReference Include="EgoPDF.Barcodes" Version="1.1.0" />
<PackageVersion Include="EgoPDF.Barcodes" Version="1.1.0" />
<PackageReference Include="EgoPDF.Barcodes" />
paket add EgoPDF.Barcodes --version 1.1.0
#r "nuget: EgoPDF.Barcodes, 1.1.0"
#:package EgoPDF.Barcodes@1.1.0
#addin nuget:?package=EgoPDF.Barcodes&version=1.1.0
#tool nuget:?package=EgoPDF.Barcodes&version=1.1.0
EgoPDF.Barcodes
Render barcodes (1D + 2D) and Zebra ZPL II labels to PDF on top of EgoPDF.Generator and ZXing.Net.
Preview. The API is in flux. Bug reports and PRs welcome; expect breaking changes between preview versions.
Renamed from
EgoPDF.Zpl. The previous name only described half of what the package does (the ZPL parser); barcode rendering is the other half and the more broadly useful part, so the package now leads with it.
Quick start (ZPL → PDF)
using Ego.PDF;
using Ego.PDF.Data;
using Ego.PDF.Barcodes.Zpl;
using var pdf = new FPdf("label.pdf");
pdf.SetUnitConverionFactor(UnitEnum.Point, 203);
// Optional: load a TTF for the monospace ZPL fonts (^A?, ^CFA).
// Without this, ^A? falls back to whatever font is currently set.
pdf.LoadFont("robotomonob", "path/to/RobotoMono-Bold.ttf");
pdf.AddFont("robotomonob", "");
// Optional: a condensed font backs the scalable proportional ^AP..^AV
// slots. With it, ^AV* renders at the tight Zebra-V proportions used
// on real courier labels; without it, those fields fall back to the
// variable font with PDF Tz horizontal compression -- legible but
// visibly squeezed at aggressive ^AV widths.
pdf.LoadFont("robotocondensed", "path/to/RobotoCondensed-VariableFont_wght.ttf");
pdf.AddFont("robotocondensed", "");
pdf.SetFont("helvetica", "B", 16);
var zpl = new PdfZpl(pdf, dpi: 203);
zpl.SetLabelSize(812, 1218); // 4" x 6" at 203 dpi
zpl.SetVariableFont("helvetica", "B"); // mapped to ZPL font "0"
zpl.SetMonospaceFont("robotomonob"); // mapped to ZPL fonts "A".."V"
zpl.SetCondensedFont("robotocondensed"); // optional: ^AP..^AV proportional
zpl.Print(@"
^XA
^FO50,50^FDHello from EgoPDF.Barcodes!^FS
^FO50,200^BCN,80,N,N,N^FD12345678^FS
^XZ
");
pdf.Close();
Supported ZPL commands
Layout
^XA / ^XZ, ^FO, ^FT, ^FD, ^FS, ^FX, ^FH, ^FW, ^FR,
^FB, ^FN, ^CF, ^CI, ^LH, ^LL, ^PW,
^DF + ^XF (template + field substitution),
^A? (A-V, plus the proportional ^A0).
Graphics
^GB, ^GC, ^GE, ^GD,
^GF (inline ASCII bitmap with the ZPL RLE compression),
^XG (recall a host-registered graphic via
PdfZpl.RegisterGraphic(name, filePath)).
Barcodes
| ZPL command | Symbology |
|---|---|
^BC |
Code 128 |
^B3 |
Code 39 |
^B2 |
Interleaved 2 of 5 |
^BK |
Codabar |
^BE |
EAN-13 |
^B8 |
EAN-8 |
^BU |
UPC-A |
^B9 |
UPC-E |
^BM |
MSI |
^B7 |
PDF417 |
^BQ |
QR Code |
^BX |
Data Matrix |
^BO |
Aztec |
All 1D symbologies honour orientation N (no rotation) and B
(rotated 90° CCW). 2D symbologies honour N, B, R, I.
What it doesn't do
- Print to a Zebra device. Output is PDF, not ZPL → ZPL.
- Implement the full ZPL command surface. Printer-state commands
(
^MD,^PR,^JM,^IL,^IS,^DG,^DY,^DU,^LR,^LS,^PM,^PO,^PF) are silently accepted as no-ops. - Reproduce Zebra's bitmap fonts byte-for-byte — the package uses whatever TTF the host registers, so visible metrics differ slightly from what a real printer would emit. Pre-pick a label width to match the physical roll if you care about absolute sizing.
Targets
- net8.0
- net9.0
License
MIT. "ZPL" and "Zebra" are trademarks of Zebra Technologies; this package is not affiliated with or endorsed by them.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- EgoPDF.Generator (>= 2.3.1)
- ZXing.Net (>= 0.16.10)
-
net9.0
- EgoPDF.Generator (>= 2.3.1)
- ZXing.Net (>= 0.16.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.0 | 4 | 6/10/2026 |
| 1.0.0 | 51 | 6/7/2026 |
| 1.0.0-preview.3 | 61 | 6/6/2026 |
| 1.0.0-preview.2 | 49 | 6/2/2026 |
1.1.0: major ZPL ^A?h,w fidelity pass.
* Proportional slots (Font 0 + P-V): em and Tz now follow Labelary's pixel-perfect quantization — hMul = round(h / native_h), wMul = round(w / native_w), em = max(native_h × 0.82, 0.81 × hMul × native_h), ScaleX = wMul / hMul. Validated against a Font P probe (h=30/60/120 × w=15/30/60/120/240) plus every C.B / PUERTO / 46520 / VALENCIA / PAGADO / 0 Eur. field on the SEUR 1485 portrait label; em matches Labelary exactly and Tz within ~5%.
* Monospace bitmap fonts (A-H, O): same hMul/wMul quantization with a dynamic Roboto Mono "M" advance, matching Labelary's renders for ^ADR,45,25 / ^ADR,40,9 / ^ADR,17,9.
* ^BY parser: accepts decimal values ("3.0", "2.0") in InvariantCulture. The previous int.TryParse silently fell back to the default 2-dot module width on locales that disagreed with "3.0", halving every barcode's length.
* ^BC: trailing mode flag parsed; mode A (Automatic) drops the FORCE_CODESET_B hint so digit-only payloads compact into Subset C. ^BC dispatches B / R orientations through DrawRotatedBars so ^BCR stops rendering horizontally on rotated labels.
* Code 39 ^B3: hand-rolled encoder honours ^BY's wide:narrow ratio (ZXing locks 2:1), skips the 10-module quiet zone ZXing always emits, and prints the "*" start/stop chars in the human-readable line that Zebra and Labelary both show.
* ^B?R captions: rendered on the left side of the rotated bar stack with a font size proportional to bar length; ZebraTracking takes the actual glyph height instead of the field-level Thickness.
* ^FO + ^A?R and ^FO + ^B?R: anchor convention corrected — bars sit at print-frame top-left of the rotated bbox; text gets a 30%-of-ascent right padding so glyphs clear the FO column. Fixed ^FO + ^B?R which was previously treating the anchor as top-right and pushing bars off the left edge.
* Font 0 (^A0): prefers the host's CondensedFont when registered and honours explicit h/w with horizontal compression so e.g. CL1 at ^A0R,140,90 lands narrower than the font's natural ~95-dot advance.
* ~DG download-graphic + ^XG recall: ~DG payloads live OUTSIDE ^XA…^XZ so they're now harvested up at Print() before ZplParser splits on the blocks; ^XG looks up the decoded bitmap in the new _storedGraphics; ^FT shifts the anchor up by image height (Zebra's ^FT bitmap convention). SEUR 1490's ~DG000.GRF letter-mark renders.
* New PdfZpl.SetCondensedFontScale knob: global em multiplier applied whenever a field renders with the condensed slot. Lets the host nudge an under-sized font family up a few percent without rewriting individual ^A?h,w numbers.
* Removed the experimental SetMetricFont knob and the Liberation Sans Narrow Bold TTF that backed it — after the pixel-perfect rewrite the metric anchor was only buying ~4% width drift mitigation and not worth the extra TTF dependency.
* ^FR (Field Reverse): sample, controller endpoint, web demo link and visual baseline removed. The white-text-over-prior-^GB approximation broke more SEUR 1485 fields than it fixed. The code path inside FieldDefinition.Draw remains commented for a future XOR strategy.
1.0.0: first stable release. Late-2026 ZPL fidelity pass on top of the preview series: ^AV* condensed proportional path with native aspect lock (h scales with w when w < h*71/80, matching real Zebra V), SetCondensedFont hook for picking the font that backs ^AP..^AV; ^A?B and ^B?B rotated-text / rotated-barcode anchor split between ^FO (top-left of rotated bbox) and ^FT (first-char baseline) so portrait courier labels and rotated landscape labels both place fields where their authors meant; ^B2 (Interleaved 2 of 5) hand-rolled encoder honours the ^BY wide:narrow ratio (ZXing's writer was hard-coded to 1:3) and the Mod-10 check digit when the trailing checkDigit=Y flag is set; ^BC respects an explicit height parameter and a leading ^A?h,w that picks the caption font; bottom-up rotated barcodes get their interpretation line printed alongside the bars. New GetSampleCourierPortrait + visual baseline + WebDemo entry covers the pattern end-to-end. ^FR (Field Reverse) handling on text fields from preview.3 is unchanged.