Emulador de impresora POS (ESC/POS) para Windows, escrito en Rust. Crea una impresora virtual que cualquier aplicación puede usar para imprimir tickets, y muestra en pantalla una previsualización del documento junto con el historial de peticiones recibidas.
- Servidor TCP en el puerto 9100 (protocolo RAW, estándar en impresoras térmicas de red). Cualquier aplicación que sepa imprimir a
127.0.0.1:9100puede enviar documentos. - Impresora registrada en Windows: la app crea la impresora
POS Printer Emulatorconectada a un puerto RAW local (POSEmulator→127.0.0.1:9100), usando automáticamente el driver genérico POS disponible (Generic / Text Only,Generic / ESC/POS, ...). Aparece en el diálogo de impresión de cualquier programa y se puede "imprimir" sin tocar el código. - Previsualización en tiempo real: cada documento se renderiza como bitmap (58/80/112 mm de papel) con zoom, y se puede exportar a PNG.
- Historial de peticiones: lista de trabajos con hora, origen, tamaño, hexdump de los bytes crudos y resumen de los comandos ESC/POS detectados.
- Registro y desinstalación de la impresora desde la propia interfaz (con reintento elevado vía UAC si se requieren permisos de administrador).
- Texto, alineación (izquierda/centro/derecha), negrita, subrayado (simple/doble), inverso (
GS b,GS B, bit 6 deESC !), cursiva (ESC 4/ESC 5), tamaño doble (ancho/alto), fuente A/B (ESC !,ESC %), espaciado entre caracteres (ESC SP,GS SP). - UTF-8 multibyte: las secuencias UTF-8 válidas (á, ñ, €, emoji...) se decodifican automáticamente; el resto de bytes altos se decodifican por codepage.
- Envoltorio automático: las líneas que exceden el ancho de papel/área de impresión saltan de línea como una impresora real.
- Codepages: CP437, CP850, CP858, CP866, CP1252 (
ESC t). - Avance de línea/puntos (
LF,FF,ESC d,ESC J), espaciado de línea (ESC 3,ESC A). - Posicionamiento: posición absoluta (
ESC $,GS $) y relativa (ESC \,GS \), márgenes izquierdo (ESC l,ESC L,GS L) y área de impresión (ESC W,GS W). - Cortes de papel completo/parcial (
ESC i,ESC v,GS V), apertura de cajón (ESC p). - Códigos de barras 1D (
GS k: CODE39, EAN-13, EAN-8, Code 128, ITF, UPC-A...) con HRI; EAN/UPC/Code 128/ITF/Code 39 se dibujan con módulos reales (barras y espacios reales, dígito de control calculado/verificado). - Códigos 2D: QR (
GS ( kcn=49, incl. modelo/tamaño/ECC y store+print) y PDF417 (GS ( kcn=48). - Imágenes raster (
GS v 0) y bitmap (ESC *). - Logos NV: definir (
FS q,GS ( L,GS 8 L) e imprimir con escalado (FS p,GS /,GS 8 H). - Transmit de códigos 2D:
GS ( kfn 81 (QR y PDF417) devuelve los datos almacenados por el socket, como una impresora real. - Modo página:
GS P(área y entrada),GS T(dirección), texto con posicionamiento absoluto y descarga conESC FF. - Fuente fija tipo térmica: cada carácter ocupa una celda de ancho constante (12×24 fuente A, 9×17 fuente B), como una térmica real.
- Estado simulado configurable en la GUI: toggles de papel agotado, casi-fin, tapa abierta, error y cajón abierto; los bits de
DLE EOT,DLE ENQ,GS ry ASB cambian en consecuencia. - Zumbador:
ESC ( Cfn 0x06 (aviso sonoro, registrado en el resumen). - Fuentes descargadas:
ESC &yGS ( A(almacenadas y resumidas). - Respuestas de estado en tiempo real:
DLE EOT 1..8/10..19,DLE ENQ,GS r(estado de impresora/offline/error/papel/recovery/búfer, escritas al socket como en una impresora real). - Estado automático (ASB):
GS a nenvía los 4 bytes de estado al activarse y empuja automáticamente los cambios de estado posteriores (un hilo vigila la máquina de estado mientras la conexión esté activa). - Mecánica física: el avance usa unidades de movimiento vertical reales (1/203", ~0.125 mm); botones Feed y Corte en la GUI que envían
ESC J nyGS V 66por el mismo pipeline que una aplicación real. - Memoria NV persistente: logos, fuentes descargadas y densidad se guardan en un fichero binario (
%LOCALAPPDATA%\pos_printer_emulator\nv.bin) y se restauran entre sesiones.
- Windows 10/11 (registro de impresora).
- Rust (edición 2024, rustc ≥ 1.85) para compilar.
cargo run --releaseEl binario se genera en target\release\pos_printer_emulator.exe y no muestra ventana de consola.
Nota: la dependencia
pdf4170.2.1 se provee envendor/pdf417(el crate publicado incluye#![feature(const_mut_refs)], estable desde Rust 1.83, que rompe el compilador stable; se patchea localmente vía[patch.crates-io]).
cargo testSuite de 28 pruebas: parser (estilos, posicionamiento y márgenes, corte, QR/PDF417, UTF-8, ASB, raster GS 8 L/H, escalas GS /, modo página, transmit fn 81, zumbador y fuentes descargadas), estado simulado (state.rs), módulos de barcode reales (barcode.rs: EAN/Code 128/ITF/Code 39), persistencia NV (nvstore.rs) y pruebas de integración por socket real (server.rs) que verifican DLE EOT completo, ASB push y el transmit de QR.
-
Ejecuta la aplicación. El servidor TCP 9100 arranca automáticamente.
-
(Opcional) Pulsa Registrar impresora en Windows. Si tu usuario no es administrador, usa Reintentar como administrador (UAC).
-
Envía un documento:
-
Pulsa Enviar documento de prueba en la barra superior, o
-
desde otra aplicación elige la impresora
POS Printer Emulatore imprime, o -
usa
netcat/curl/tu propio código contra127.0.0.1:9100:python -c "import socket;socket.create_connection(('127.0.0.1',9100)).sendall(b'Hello ESC/POS\n')"
-
-
Selecciona el trabajo en el panel izquierdo para ver el preview, el hexdump y el resumen de comandos.
Para dejar de usar la impresora, pulsa Quitar impresora.
Nota: los comandos
Add-Printer/Remove-Printerrequieren permisos de administrador. Si la app no los tiene, se mostrará la opción de reintentar con elevación UAC.
┌─────────────────────────────────┐
Aplicaciones ──TCP──▶│ Servidor RAW 127.0.0.1:9100 │
(diálogo imprimir, └──────────────────┬──────────────┘
scripts, red) ▼
┌─────────────────────────────────┐
│ Parser ESC/POS ──▶ Items │
└──────────────────┬──────────────┘
▼
┌─────────────────────────────────┐
│ Renderer (ab_glyph + font8x8) │──▶ Preview PNG
└─────────────────────────────────┘
| Módulo | Responsabilidad |
|---|---|
server.rs |
Listener TCP 9100, un hilo por conexión, límites de jobs, respuestas real-time (DLE EOT 1..19, DLE ENQ, GS r, ASB push) y transmit fn 81. |
parser.rs |
Convierte bytes ESC/POS en una lista de ítems renderizables y genera el resumen. |
render.rs |
Dibuja el ticket en un bitmap RGBA (fuentes del sistema + fallback de 8×8). |
barcode.rs |
Dígitos de control y patrones de módulos reales (EAN/UPC, Code 128, ITF, Code 39) + validación de GS k. |
barcode2d.rs |
Genera QR (qrcode) y PDF417 (pdf417) como bitmap. |
codepages.rs |
Tablas de conversión CP437/850/858/866/1252. |
printer.rs |
Scripts PowerShell para registrar/quitar la impresora (con UAC). |
nvstore.rs |
Persistencia NV entre sesiones (fichero binario). |
sample.rs |
Documento de prueba con texto, QR/PDF417 (+transmit), barcode (EAN-13, Code 128, ITF), logos NV (FS q, GS 8 L, escalas GS /), modo página, buzzer y fuente descargada. |
main.rs |
Interfaz egui/eframe. |
- Solo funciona en Windows para el registro de la impresora (el servidor TCP es multiplataforma).
- Las fuentes descargadas (
ESC &,GS ( A) se reconocen y almacenan, pero no se renderizan aún; el modo página soporta la dirección 0 (izquierda→derecha, arriba→abajo). - El puerto RAW simula el envío de la aplicación a la impresora; no es un driver de impresora USB virtual (eso requeriría un driver de kernel firmado). El resultado es equivalente para la mayoría de software de punto de venta.