CrossEscPos.Abstractions
1.3.0
See the version list below for details.
dotnet add package CrossEscPos.Abstractions --version 1.3.0
NuGet\Install-Package CrossEscPos.Abstractions -Version 1.3.0
<PackageReference Include="CrossEscPos.Abstractions" Version="1.3.0" />
<PackageVersion Include="CrossEscPos.Abstractions" Version="1.3.0" />
<PackageReference Include="CrossEscPos.Abstractions" />
paket add CrossEscPos.Abstractions --version 1.3.0
#r "nuget: CrossEscPos.Abstractions, 1.3.0"
#:package CrossEscPos.Abstractions@1.3.0
#addin nuget:?package=CrossEscPos.Abstractions&version=1.3.0
#tool nuget:?package=CrossEscPos.Abstractions&version=1.3.0
ESC/POS Receipt Printer Emulator
π¨οΈ This app emulates a networked receipt printer to test your ESC/POS commands against.
About
- Cross-platform application (Avalonia 12 + SkiaSharp + .NET 10), runs on Windows, macOS and Linux
- Listens for ESC/POS commands over TCP/IP and (optionally) a serial port
- Logs commands and visually represents the resulting receipt(s)
- Renders 1D barcodes and 2D codes (QR, PDF417, DataMatrix, Aztec), bit images, and page mode
- Answers status queries (
DLE EOT,GS r, Automatic Status Back) β simulate paper-out, cover, drawer, offline and error states from the Printer state panel - Signals buzzer / cash-drawer events with a sound and on-screen toast
- Configure the TCP listen address/port and serial port live from the UI
- Export rendered tickets to PNG β all in one image, or one file per cut
- It support different text formattings in the same line, although a few combinations were tested.
Cross-platform fork. This project began as a cross-platform port of roydejong/EscPosEmulator (originally a Windows/WPF app). It has been migrated to Avalonia + SkiaSharp + .NET 10 so it runs on Windows, macOS and Linux, and extended with barcode/QR rendering and a serial transport. All credit for the original emulator goes to the upstream author. See From WPF to Avalonia for before/after screenshots and what the migration took.
π· This is an unfinished experiment. Use at your own risk and keep your expectations low. π
Download
Pre-built, self-contained apps (no .NET install required) are published on the Releases page:
| Platform | Artifact |
|---|---|
| Windows (x64) | CrossEscPos-win-x64.zip |
| Linux (x64) | CrossEscPos-linux-x64.tar.gz |
| macOS (Intel) | CrossEscPos-osx-x64.zip (.app bundle) |
| macOS (Apple Silicon) | CrossEscPos-osx-arm64.zip (.app bundle) |
| Browser | No download: run it online (GitHub Pages) |
Releases are produced by the Release GitHub Actions workflow on
each v* tag.
macOS first launch. The
.appis ad-hoc signed but not notarized (no paid Apple Developer ID). macOS quarantines anything downloaded from the internet, so on first launch you may see "CrossEscPos is damaged and can't be opened" (especially on Apple Silicon). Clear the quarantine flag once, then open it:xattr -dr com.apple.quarantine /path/to/CrossEscPos.app open /path/to/CrossEscPos.app(Right-click β Open also works once the quarantine is cleared.)
Built with
- .NET 10 Β· Avalonia 12 Β· SkiaSharp (rendering) Β· CommunityToolkit.Mvvm (MVVM)
- ZXing.Net (1D barcodes) Β· QRCoder (QR codes) Β· Ardalis.SmartEnum (class-based enums) Β· System.IO.Ports (serial)
- ESC-POS-.NET (the Monitor test client) Β· LibUsbDotNet (direct USB printing)
From WPF to Avalonia: what the migration cost
Entered in the Avalonia Port Challenge. The same write-up is on the project site, next to a live browser demo.
| Before: WPF, Windows only | After: Avalonia 12 on macOS |
|---|---|
| After: Linux | After: browser (WebAssembly) |
Starting point
The upstream app (roydejong/EscPosEmulator, last
updated July 2025) targeted net9.0-windows7.0 with UseWPF: 48 C#/XAML files, about 2,400 lines.
Windows was wired in at four levels:
- Rendering. Every receipt line drew itself with GDI+ (
System.Drawing.BitmapandGraphics), which is Windows-only on .NET 6 and later. The GDI+ types were part of the core interface,IReceiptPrintable.Render(Bitmap, Graphics, int, int). To show a receipt, the window saved each bitmap into a BMPMemoryStreamand loaded it back as a WPFBitmapImage. - UI. Code-behind only.
MainWindow.xaml.cscreatedImagecontrols by hand, found them again by a GUID-derivedName, and added or removed them from aStackPanel. - OS calls. A
user32!FlashWindowP/Invoke andSystem.Media.SystemSoundssignalled new jobs. - Assumptions. TCP was the only transport, and the test receipt was read from the current working directory.
The ESC/POS interpreter (one command class per opcode, registered in EscPosInterpreter) had no UI
or Windows dependency, so its design carried over unchanged. It is now the headless
CrossEscPos.Core package.
What changed, and what each part cost
| Area | WPF original | Avalonia port | What it took |
|---|---|---|---|
| Rendering | GDI+ Bitmap / Graphics |
SkiaSharp, later behind a backend-neutral IReceiptCanvas, plus a fully managed ImageSharp backend |
The biggest single job. The text-line renderer (styles, sizes, justification, underline) was rewritten. System fonts differ per OS, so the same receipt measured differently on each; embedding JetBrains Mono (OFL) made output identical everywhere. The ImageSharp backend later needed its advance widths matched to Skia's. |
| UI | XAML + code-behind | AXAML + MVVM (CommunityToolkit.Mvvm); receipts bound to a reusable ReceiptView control |
The markup ported almost line for line: Window, DockPanel, StackPanel and ScrollViewer all exist in Avalonia. The work was moving the code-behind into view models and bindings. |
| Win32 calls | FlashWindow, SystemSounds |
INotificationService: afplay on macOS, Console.Beep on Windows, paplay/aplay on Linux, plus an in-window toast |
Avalonia has no cross-platform system-sound API, so each OS gets its own strategy. |
| Files | Relative to the working directory | Avalonia StorageProvider for PNG export; app-relative asset paths |
The working-directory assumption broke in the packaged app and was fixed right after the first release. |
| Transports | TCP | TCP and serial (System.IO.Ports); the Monitor adds direct USB (libusb) |
Port names differ per OS (COM3, /dev/ttyUSB0, /dev/cu.*). A Homebrew-installed libusb wasn't found until the app added the usual install paths to NATIVE_DLL_SEARCH_DIRECTORIES at startup. |
| Packaging | One Windows .exe |
Self-contained win-x64, linux-x64, osx-x64 and osx-arm64 builds from one CI matrix; a script builds the macOS .app |
Unsigned macOS bundles were reported as "damaged", so the bundle is now ad-hoc signed. Notarization needs a paid Apple ID, so the README documents clearing the quarantine flag instead. |
| Browser | n/a | The same app as an Avalonia WASM head (net10.0-browser) |
Platform edges sit behind IPlatformServices. A browser can't listen on TCP, so an ASP.NET Core SignalR host opens the socket and relays jobs to the page. Serial and USB go through Web Serial and WebUSB via JS interop. The storage API's save picker failed in the browser, so export downloads a JS blob instead. |
The numbers
- Time: 7 days with commits over 5 weeks, per the git history. The port and desktop parity landed on June 5β6, 2026 (PRs #1β#7), the layered-package refactor on June 20β21 (#8β#10), and the browser head on July 4β7 (#11β#16).
- Size: from 48 files and ~2.4k lines to 168 files and ~10k lines of C# and AXAML, across 11 projects, 2 samples and 2 test projects. Most of the growth is new features (barcodes, 2D codes, status commands, printer-state simulation, the Monitor, serial/USB, the browser head), not port overhead. The port PR itself (#1) was +2,525 / β487 lines across 60 files.
- Tests: 131 xUnit tests (89 test methods). They run the interpreter against a synthetic render backend, which proves the core is headless, and exercise the controls with Avalonia.Headless.
- Tools: built with AI assistance (Claude Code); the commits carry
Co-Authored-Bytrailers.
What was easy, and what hurt
- Easy: XAML to AXAML, the Fluent theme,
Dispatcher.UIThread, and headless UI testing. The UI layer was the smallest part of the port. - Hurt: removing GDI+. It was part of the core interfaces, not just the view, so the renderer had to be redesigned before anything else could move. After that came per-OS native dependencies (libusb, fontconfig on Linux, macOS signing) and the browser sandbox (no sockets, no raw file system).
- Would do again: put the drawing surface behind an interface first. Once
IReceiptCanvasexisted, the ImageSharp backend (a community contribution) and the browser head each landed within a few days.
Supported commands
β οΈ Support is currently limited to only a subset of ESC/POS. Even the commands listed here may only be partially implemented.
- Raw Text
- LF: Line feed
- CR: Carriage return
- ESC Commands:
- Initialize printer (
ESC @) - Toggle italic (
ESC 4/ESC 5) [possibly deprecated?] - Select font (
ESC M) - Select charset (
ESC R) - Select character table (
ESC t) - Select justification (
ESC a) - Select line spacing (
ESC 2/ESC 3) - Toggle emphasis (
ESC E) - Toggle underline (
ESC -) - Set print text mode (
ESC !) - Full cut (
ESC m) - Partial cut (
ESC i) - Print and feed n lines (
ESC d) - Print and feed paper (
ESC J) - Generate pulse / kick cash drawer (
ESC p m t1 t2) - Select character code table (
ESC t) β PC437/850/852/858/860/863/865/866/1252 remapped to Unicode - Beeper (
ESC ( A) - Bit image (
ESC *) β 8-dot and 24-dot inline raster - Page mode: select page / standard mode (
ESC L/ESC S), print area (ESC W), direction (ESC T), absolute position (ESC $) - User-defined characters (
ESC &/ESC %/ESC ?) β parsed & stored
- Initialize printer (
- Control characters:
- Buzzer / beeper (
BEL, 0x07) - Form feed (
FF) β prints the page in page mode - Cancel (
CAN) β cancels page data
- Buzzer / beeper (
- DLE (real-time) Commands:
- Real-time status (
DLE EOT n, n=1-4) - Real-time request / recover (
DLE ENQ) - Real-time cash-drawer pulse (
DLE DC4 1 m t)
- Real-time status (
- FS Commands:
- Print stored logo (
FS p n m) - Auto cut (
FS } 0x60 n)
- Print stored logo (
- GS Commands:
- Select character size
- Select cut mode and cut paper
- Paper eject (
GS e n [m t]) - Print raster image (
GS v 0 [m xL xH yL yH ...pixels]) - Print 1D barcode (
GS k) β UPC-A/E, EAN-13/8, CODE39, CODE93, CODE128, ITF, CODABAR (both function A & B forms) - Set barcode height / module width (
GS h/GS w) - Select HRI text position / font (
GS H/GS f) - Print 2D symbols (
GS ( k) β QR Code (cn=49), PDF417 (cn=48), DataMatrix (cn=54), Aztec (cn=55) - Status / transmit-back: paper & drawer status (
GS r), printer ID (GS I), Automatic Status Back (GS a) - Download bit image: define (
GS *) and print (GS /) - Set motion units (
GS P), absolute/relative vertical position (GS $/GS \) - Config (accepted/ignored): user setup (
GS ( E), print control (GS ( K), response request (GS ( H)
The emulator is bidirectional: status commands (DLE EOT, GS r, GS I) and Automatic Status
Back reply to the host over the same TCP/serial connection, driven by the Printer state panel
(right side) where you can simulate paper-out/near-end, cover open, cash-drawer open/closed,
offline, and error conditions. Like a real device, the emulator refuses to print while it isn't
ready (out of paper, cover open, offline, or in an error state) and shows a notification instead.
Barcodes and QR codes render inline on the receipt, with optional HRI text:
Not yet implemented
A few things remain partial or unimplemented:
- Page-mode coordinate system β page mode buffers output and rasterizes it on
FF, but absolute/relative positioning (ESC $,GS $,GS \) and print direction (ESC T) are accepted as no-ops rather than fully positioned. - User-defined glyph substitution β
ESC &glyphs are parsed and stored, but the inline text renderer still draws the font glyph rather than the custom bitmap. - MaxiCode / GS1 DataBar / Composite 2D symbologies (
GS ( kcn=50/51/52). - Graphics commands
GS ( L/GS 8 L(NV/raster graphics store-and-print) and otherESC *-family densities. - Real-time
DLE DC4functions other than the cash-drawer pulse (power-off, recover-and-cancel, buzzer). - Katakana / CJK code pages render as missing glyphs since the bundled Latin font has no such glyphs.
Contributions welcome β new commands follow the simple BaseCommand pattern in
EscPos/Commands and are registered in
EscPosInterpreter.RegisterCommands.
Connecting
The emulator accepts ESC/POS data over two transports. Both can be changed live from the UI (left panel): pick a TCP listen address and port and Start/Stop the listener, or select a serial port + baud and Open/Close it (β³ refreshes the port list). The environment variables below set the initial values at startup:
| Variable | Default | Meaning |
|---|---|---|
ESCPOS_LISTEN_ADDRESS |
0.0.0.0 |
Initial TCP bind address (0.0.0.0 = all interfaces, 127.0.0.1 = localhost). |
ESCPOS_TCP_PORT |
9100 |
Initial TCP listen port. Set to off / 0 to start with TCP stopped. |
ESCPOS_SERIAL_PORT |
(unset) | Serial device to auto-open (e.g. /dev/ttys004, COM3). Unset = serial closed. |
ESCPOS_SERIAL_BAUD |
9600 |
Serial baud rate. |
ESCPOS_DEBUG_DUMP |
(off) | Set to 1 to dump every received payload to last_* files. |
ESCPOS_RENDER_BACKEND |
skia |
Render backend: skia (default) or imagesharp (managed). The --backend arg overrides it. |
Examples:
# (run is shorthand for: dotnet run --project src/CrossEscPos.App.Desktop)
dotnet run --project src/CrossEscPos.App.Desktop # TCP only, port 9100
ESCPOS_TCP_PORT=9200 dotnet run --project src/CrossEscPos.App.Desktop # TCP on 9200
ESCPOS_SERIAL_PORT=/dev/ttys004 dotnet run --project src/CrossEscPos.App.Desktop # TCP 9100 + serial
ESCPOS_TCP_PORT=off ESCPOS_SERIAL_PORT=COM3 dotnet run --project src/CrossEscPos.App.Desktop # serial only
Pick the render backend (for A/B testing the two rendering libraries) with --backend skia
(default) or --backend imagesharp (the managed, no-native backend). The active backend is shown in
the window title bar.
dotnet run --project src/CrossEscPos.App.Desktop -- --backend imagesharp # managed ImageSharp backend
dotnet run --project src/CrossEscPos.App.Desktop -- --backend skia # default SkiaSharp backend
The status panel shows the active TCP endpoint and serial port.
Testing serial without hardware (app-to-app on one machine)
You don't need a USB serial adapter. Create a virtual serial bridge β a pair of linked ports β then point the emulator at one end and your POS application (or a shell) at the other. Bytes written to one end appear on the other.
macOS / Linux β using socat (brew install socat /
apt install socat). A helper script is included:
./scripts/serial-bridge.sh
# It prints a linked pair, e.g.:
# PORT A (emulator): /dev/ttys004
# PORT B (your app): /dev/ttys005
# Leave it running.
Then, in two more terminals:
# Terminal 2 β run the emulator on port A
ESCPOS_SERIAL_PORT=/dev/ttys004 dotnet run --project src/CrossEscPos.App.Desktop
# Terminal 3 β send a receipt from "another app" on port B
cat test_receipt.txt > /dev/ttys005
# β¦or from your own program, just open /dev/ttys005 like a normal serial port
# (9600 8N1) and write ESC/POS bytes to it.
The receipt appears in the emulator window. Because the interpreter is stateful across reads, fragmented serial writes (commands split across packets) are handled correctly.
Windows β install com0com and create a linked pair
(e.g. COM3 β COM4). Run the emulator with ESCPOS_SERIAL_PORT=COM3 and have your application
write to COM4.
Monitor (built-in test client)
Sending test jobs is the monitor's job β the emulator is the device, the monitor is the POS-side client that drives it over the wire (just like a real application would). The Monitor is shared by both heads: click Open monitorβ¦ to launch it β a window on desktop, an in-page overlay in the browser. Its test jobs and status display are identical; only the transport differs:
- Desktop (built on ESC-POS-.NET) β pick a transport:
- TCP/IP β connect to the emulator's listener (or any networked printer).
- Serial β pick a port + baud; pairs with the emulator's serial transport via a virtual port bridge.
- USB β print directly to a real USB printer selected from the connected-device list (by
VID:PID), via libusb. This is send-only (no status), and needs native libusb installed
(macOS
brew install libusb, Debian/Ubuntuapt install libusb-1.0-0; bundled on Windows) and the OS not already holding the device.
- Browser β sends over the SignalR proxy (the
CrossEscPos.Hosthub) to the in-page emulator, for a full round-trip without any native transport.
It then lets you exercise the target without writing any code:
- Print a sample receipt, all 1D barcodes, or QR / PDF417 / DataMatrix / Aztec.
- Send the full feature test receipt, open the cash drawer, buzz, or cut.
- Watch the printer status the emulator reports back: toggle paper-out / cover / drawer / offline in the Printer state panel and the monitor's status display updates live (via Automatic Status Back), confirming the emulator's status responses are wire-correct. When the printer isn't ready, the emulator drops the job and shows a notification, just like real hardware.
Toggling the emulator's Printer state panel pushes status to the monitor in real time β here the printer reports paper low and a recoverable error, so the monitor shows Not ready:
Exporting tickets
Each cut (ESC i / ESC m / GS V) starts a new receipt β a "page". The Export buttons in the
left panel save the rendered tickets as PNG:
- Export all (single image) β stacks every receipt into one tall PNG (a save dialog).
- Export each cut (folder) β writes one
receipt_NNN.pngper cut into a chosen folder.
Architecture & packages
The emulator is split into layered, independently-publishable packages so the rendering backend is
swappable and the core runs headless (and in the browser). The namespace is unified under
CrossEscPos.* (organized by feature/directory, not by package), so types resolve across assemblies.
| Package | Namespace(s) | Role | Depends on |
|---|---|---|---|
CrossEscPos.Abstractions |
CrossEscPos, CrossEscPos.Graphics |
Backend-agnostic rendering + printer contracts (IReceiptCanvas, IReceiptImage, IReceiptImageFactory, ITypefaceProvider, IImageEncoder, IReceiptPrintable, IPrinterResponder) |
β |
CrossEscPos.Core |
CrossEscPos.Emulator, CrossEscPos.EscPos, β¦ |
Headless ESC/POS interpreter, printer state machine, receipt document model, barcode/QR generation. ESC/POS code maps (2D families, code tables, barcode systems, status requests) are behaviour-carrying SmartEnums, not magic-number switches |
Abstractions, QRCoder, ZXing.Net, Ardalis.SmartEnum |
CrossEscPos.Rendering.Skia |
CrossEscPos.Rendering.Skia |
The default render backend (SkiaSharp). Swap it for another IReceiptImageFactory/ITypefaceProvider/IImageEncoder |
Abstractions, SkiaSharp |
CrossEscPos.Rendering.ImageSharp |
CrossEscPos.Rendering.ImageSharp |
A 100% managed render backend (ImageSharp) β no native dependency, so it runs in Blazor WASM without a native relink. Same output as the Skia backend | Abstractions, SixLabors.ImageSharp.Drawing |
CrossEscPos.Transports |
CrossEscPos.Transports |
TCP / serial / USB transports (desktop only) | Core, System.IO.Ports, LibUsbDotNet, ESC-POS-.NET |
CrossEscPos.Controls |
CrossEscPos.Controls |
Reusable Avalonia controls (ReceiptView, PrinterStatePanel) β host apps consume these. Backend-agnostic (no SkiaSharp dependency) |
Core, Avalonia |
Core carries no UI and no graphics-backend dependency, so the library works headless or in WASM.
The host (desktop, browser, or your own app) is the composition root: it picks a backend and injects it.
var imageFactory = new SkiaImageFactory();
var typefaces = new SkiaTypefaceProvider();
var printer = new ReceiptPrinter(PaperConfiguration.Default, imageFactory, typefaces);
printer.FeedEscPos(escPosBytes); // byte[] β ESC/POS is binary
using var image = printer.CurrentReceipt.Render(); // IReceiptImage
new SkiaImageEncoder().EncodePng(image, outputStream);
π¦ Package usage guides: docs/packages/ β getting started, the core
emulator, rendering & custom backends (Skia + managed ImageSharp), the Avalonia controls, and the
transports. The desktop and browser apps are one shared Avalonia app (src/CrossEscPos.App).
π Full reference & guides: the project wiki, including a step-by-step Adding a render backend guide.
Building & running
Requires the .NET 10 SDK (and the wasm-tools workload for the browser head:
dotnet workload install wasm-tools).
# Desktop app (Windows / macOS / Linux)
dotnet run --project src/CrossEscPos.App.Desktop
# Headless: ESC/POS bytes -> PNG, no UI, no Avalonia
dotnet run --project samples/CrossEscPos.Headless -- test_receipt.txt out.png
# Browser: the SAME app in the browser (Avalonia WASM head) β full parity with desktop
dotnet run --project src/CrossEscPos.App.Browser
# Web host: serves the browser app AND the SignalR broker on one origin, giving it TCP reception
# (browsers can't open raw sockets). First run publishes the WASM app into wwwroot (cached after).
# Browse to the printed URL; the emulator opens the TCP port itself.
dotnet run --project samples/CrossEscPos.Host
# Tests (unit + headless UI)
dotnet test CrossEscPos.slnx
One app, two heads. The desktop and browser apps are the same Avalonia application
(src/CrossEscPos.App) β the same views, view models, receipts, printer-state
panel, PNG export, and the Monitor test-client. Only the platform edges differ, injected via
IPlatformServices:
| Desktop head | Browser head | |
|---|---|---|
| Transports | TCP + serial | Web Serial + WebUSB + SignalR TCP proxy |
| Export | native save dialog | browser download (same Avalonia storage API) |
| Monitor | test-client window | in-page overlay (SignalR round-trip) |
A browser can't open a raw TCP listen socket, so the browser head connects over SignalR to
samples/CrossEscPos.Host β one ASP.NET Core host that serves the WASM app
and runs the broker. The emulator asks the host to open a TCP listener on the address:port you choose;
POS software connects there and its jobs bridge to the in-page emulator, with status flowing back. The
same hub carries the browser Monitor's jobs, so it round-trips against the in-page emulator too.
- Windows / macOS: no extra setup β native rendering libraries ship with the Avalonia packages.
- Linux: install the usual font/render native deps if they are missing, e.g.
sudo apt install libfontconfig1 libfreetype6(Debian/Ubuntu).
Testing
Two test projects under tests/:
CrossEscPos.Core.Testsβ emulation coverage. ESC/POS sequences are fed through the interpreter and the observable results (rendered draws, printer state, host responses, events) asserted: text and control characters, styling (emphasis/italic/size/justification), cutting and feeding, 1D/2D barcodes and bit images, status/transmit-back (DLE EOT,GS r,GS I,GS a), cash drawer and buzzer, real-time commands, code pages, page mode and not-ready handling β plus exactStatusByteBuilderbit layouts and theSmartEnumcode maps. Rendering goes to a synthetic backend, so the suite runs with no SkiaSharp (proving the core is headless).CrossEscPos.Controls.Testsβ headless Avalonia UI tests for the controls (two-way state binding, receipt image rendering).
dotnet test CrossEscPos.slnx
Fonts & license
Receipt text is rendered with JetBrains Mono, embedded in the
CrossEscPos.Rendering.Skia package (under
src/CrossEscPos.Rendering.Skia/Assets/Fonts/) so output
is identical across platforms and works in the browser sandbox (no file IO). JetBrains Mono is licensed
under the SIL Open Font License 1.1; the full license text is included at
src/CrossEscPos.Rendering.Skia/Assets/Fonts/OFL.txt. Per the OFL, the font is redistributed here under its
original license and "JetBrains Mono" is a trademark of JetBrains s.r.o. To swap in a different
monospace font, replace the receipt-mono*.ttf files (and keep its license alongside).
Emulated printer
This program emulates a printer with the following specifications:
- 80mm paper width
- 72mm printing width
- 180x180dpi
- ASCII Font A/B: 12x24 pixels
- Automatic line feed
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- No dependencies.
NuGet packages (4)
Showing the top 4 NuGet packages that depend on CrossEscPos.Abstractions:
| Package | Downloads |
|---|---|
|
CrossEscPos.Core
Headless ESC/POS emulator: byte-stream interpreter, printer state machine, receipt document model and barcode/QR generation. Renders through the CrossEscPos.Abstractions surface, so it carries no UI or graphics-backend dependency and runs headless or in WASM. |
|
|
CrossEscPos.Rendering.Skia
SkiaSharp implementation of the CrossEscPos rendering abstraction (canvas, image, image factory, typeface provider and PNG encoder). The default render backend; works on desktop and in the browser (Avalonia ships the SkiaSharp WASM natives). Fonts are embedded. |
|
|
CrossEscPos.Controls
Reusable Avalonia controls for hosting the CrossEscPos emulator: ReceiptView (renders the live receipt stream), PrinterStatePanel (online/paper/cover/drawer/error), and PNG export helpers. Backend-agnostic β depends on the rendering abstraction, not on SkiaSharp. |
|
|
CrossEscPos.Rendering.ImageSharp
ImageSharp implementation of the CrossEscPos rendering abstraction (canvas, image, image factory, typeface provider and PNG encoder). A fully managed, WASM-safe render backend β no native dependencies β mirroring the SkiaSharp backend so the interpreter produces identical output. Fonts are embedded. |
GitHub repositories
This package is not used by any popular GitHub repositories.