@kreiseck/kasseneck-api 0.13.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/README.md +31 -5
- package/dist/cjs/client/receipts.d.ts +7 -0
- package/dist/cjs/client/receipts.js +1 -0
- package/dist/cjs/kasse/drucker.d.ts +5 -0
- package/dist/cjs/kasse/drucker.js +9 -0
- package/dist/cjs/kasse/settings.js +5 -2
- package/dist/cjs/printing/escpos.d.ts +38 -4
- package/dist/cjs/printing/escpos.js +87 -15
- package/dist/cjs/printing/index.d.ts +2 -2
- package/dist/cjs/printing/index.js +5 -1
- package/dist/cjs/printing/qr-groesse.d.ts +26 -21
- package/dist/cjs/printing/qr-groesse.js +22 -8
- package/dist/cjs/react/index.d.ts +53 -0
- package/dist/cjs/react/index.js +81 -0
- package/dist/cjs/receipt/bild.d.ts +14 -0
- package/dist/cjs/receipt/bild.js +65 -0
- package/dist/cjs/receipt/blatt.d.ts +107 -0
- package/dist/cjs/receipt/blatt.js +137 -0
- package/dist/cjs/receipt/epos.d.ts +19 -8
- package/dist/cjs/receipt/epos.js +39 -20
- package/dist/cjs/receipt/grid.d.ts +1 -1
- package/dist/cjs/receipt/grid.js +9 -1
- package/dist/cjs/receipt/index.d.ts +4 -2
- package/dist/cjs/receipt/index.js +17 -1
- package/dist/cjs/receipt/layout-escpos.d.ts +31 -3
- package/dist/cjs/receipt/layout-escpos.js +58 -18
- package/dist/esm/client/receipts.d.ts +7 -0
- package/dist/esm/client/receipts.js +1 -0
- package/dist/esm/kasse/drucker.d.ts +5 -0
- package/dist/esm/kasse/drucker.js +9 -0
- package/dist/esm/kasse/settings.js +5 -2
- package/dist/esm/printing/escpos.d.ts +38 -4
- package/dist/esm/printing/escpos.js +84 -15
- package/dist/esm/printing/index.d.ts +2 -2
- package/dist/esm/printing/index.js +2 -2
- package/dist/esm/printing/qr-groesse.d.ts +26 -21
- package/dist/esm/printing/qr-groesse.js +21 -8
- package/dist/esm/react/index.d.ts +53 -0
- package/dist/esm/react/index.js +80 -1
- package/dist/esm/receipt/bild.d.ts +14 -0
- package/dist/esm/receipt/bild.js +62 -0
- package/dist/esm/receipt/blatt.d.ts +107 -0
- package/dist/esm/receipt/blatt.js +128 -0
- package/dist/esm/receipt/epos.d.ts +19 -8
- package/dist/esm/receipt/epos.js +40 -22
- package/dist/esm/receipt/grid.d.ts +1 -1
- package/dist/esm/receipt/grid.js +9 -1
- package/dist/esm/receipt/index.d.ts +4 -2
- package/dist/esm/receipt/index.js +4 -2
- package/dist/esm/receipt/layout-escpos.d.ts +31 -3
- package/dist/esm/receipt/layout-escpos.js +58 -20
- package/fixtures/erwartet/karte-eigener.blatt32.json +159 -0
- package/fixtures/erwartet/karte-eigener.blatt48.json +159 -0
- package/fixtures/erwartet/karte-gptom-ios.blatt32.json +231 -0
- package/fixtures/erwartet/karte-gptom-ios.blatt48.json +231 -0
- package/fixtures/erwartet/karte-gptom.blatt32.json +231 -0
- package/fixtures/erwartet/karte-gptom.blatt48.json +231 -0
- package/fixtures/erwartet/karte-hobex-cloud.blatt32.json +201 -0
- package/fixtures/erwartet/karte-hobex-cloud.blatt48.json +201 -0
- package/fixtures/erwartet/karte-hobex-hps.blatt32.json +225 -0
- package/fixtures/erwartet/karte-hobex-hps.blatt48.json +225 -0
- package/fixtures/erwartet/karte-mypos.blatt32.json +255 -0
- package/fixtures/erwartet/karte-mypos.blatt48.json +243 -0
- package/fixtures/erwartet/karte-stripe-eps.blatt32.json +195 -0
- package/fixtures/erwartet/karte-stripe-eps.blatt48.json +195 -0
- package/fixtures/erwartet/karte-stripe.blatt32.json +213 -0
- package/fixtures/erwartet/karte-stripe.blatt48.json +213 -0
- package/fixtures/erwartet/karte-sumup.blatt32.json +219 -0
- package/fixtures/erwartet/karte-sumup.blatt48.json +207 -0
- package/fixtures/erwartet/langer-artikelname.blatt32.json +177 -0
- package/fixtures/erwartet/langer-artikelname.blatt48.json +171 -0
- package/fixtures/erwartet/logo-probe-hoch.raster32.txt +120 -0
- package/fixtures/erwartet/logo-probe.raster32.txt +54 -0
- package/fixtures/erwartet/null-ausfall.blatt32.json +207 -0
- package/fixtures/erwartet/null-ausfall.blatt48.json +189 -0
- package/fixtures/erwartet/null-ausfall.grid32.txt +2 -0
- package/fixtures/erwartet/null-ausfall.grid48.txt +2 -0
- package/fixtures/erwartet/null-jahr.blatt32.json +213 -0
- package/fixtures/erwartet/null-jahr.blatt48.json +189 -0
- package/fixtures/erwartet/null-jahr.grid32.txt +2 -0
- package/fixtures/erwartet/null-jahr.grid48.txt +2 -0
- package/fixtures/erwartet/null-monat.blatt32.json +207 -0
- package/fixtures/erwartet/null-monat.blatt48.json +189 -0
- package/fixtures/erwartet/null-monat.grid32.txt +2 -0
- package/fixtures/erwartet/null-monat.grid48.txt +2 -0
- package/fixtures/erwartet/null-pruef.blatt32.json +207 -0
- package/fixtures/erwartet/null-pruef.blatt48.json +189 -0
- package/fixtures/erwartet/null-pruef.grid32.txt +2 -0
- package/fixtures/erwartet/null-pruef.grid48.txt +2 -0
- package/fixtures/erwartet/null-schluss.blatt32.json +207 -0
- package/fixtures/erwartet/null-schluss.blatt48.json +189 -0
- package/fixtures/erwartet/null-schluss.grid32.txt +2 -0
- package/fixtures/erwartet/null-schluss.grid48.txt +2 -0
- package/fixtures/erwartet/null-start.blatt32.json +207 -0
- package/fixtures/erwartet/null-start.blatt48.json +189 -0
- package/fixtures/erwartet/null-start.grid32.txt +2 -0
- package/fixtures/erwartet/null-start.grid48.txt +2 -0
- package/fixtures/erwartet/rabatt-chef-trinkgeld.blatt32.json +213 -0
- package/fixtures/erwartet/rabatt-chef-trinkgeld.blatt48.json +207 -0
- package/fixtures/erwartet/rabatt-einfach.blatt32.json +183 -0
- package/fixtures/erwartet/rabatt-einfach.blatt48.json +177 -0
- package/fixtures/erwartet/rabatt-trinkgeld.blatt32.json +213 -0
- package/fixtures/erwartet/rabatt-trinkgeld.blatt48.json +207 -0
- package/fixtures/erwartet/rabatt-wertgutschein.blatt32.json +219 -0
- package/fixtures/erwartet/rabatt-wertgutschein.blatt48.json +213 -0
- package/fixtures/erwartet/rabattzeilen.blatt32.json +201 -0
- package/fixtures/erwartet/rabattzeilen.blatt48.json +195 -0
- package/fixtures/erwartet/signaturausfall-verkauf.blatt32.json +195 -0
- package/fixtures/erwartet/signaturausfall-verkauf.blatt48.json +183 -0
- package/fixtures/erwartet/storno-rabatt.blatt32.json +249 -0
- package/fixtures/erwartet/storno-rabatt.blatt48.json +237 -0
- package/fixtures/erwartet/storno-rabatt.grid32.txt +2 -0
- package/fixtures/erwartet/storno-rabatt.grid48.txt +2 -0
- package/fixtures/erwartet/storno-teil.blatt32.json +207 -0
- package/fixtures/erwartet/storno-teil.blatt48.json +201 -0
- package/fixtures/erwartet/storno-teil.grid32.txt +2 -0
- package/fixtures/erwartet/storno-teil.grid48.txt +2 -0
- package/fixtures/erwartet/storno-voll.blatt32.json +219 -0
- package/fixtures/erwartet/storno-voll.blatt48.json +213 -0
- package/fixtures/erwartet/storno-voll.grid32.txt +2 -0
- package/fixtures/erwartet/storno-voll.grid48.txt +2 -0
- package/fixtures/erwartet/testkasse-verkauf.blatt32.json +225 -0
- package/fixtures/erwartet/testkasse-verkauf.blatt48.json +219 -0
- package/fixtures/erwartet/testkasse-verkauf.grid32.txt +5 -1
- package/fixtures/erwartet/testkasse-verkauf.grid48.txt +5 -1
- package/fixtures/erwartet/testsignatur-verkauf.blatt32.json +237 -0
- package/fixtures/erwartet/testsignatur-verkauf.blatt48.json +219 -0
- package/fixtures/erwartet/testsignatur-verkauf.grid32.txt +5 -1
- package/fixtures/erwartet/testsignatur-verkauf.grid48.txt +5 -1
- package/fixtures/erwartet/training.blatt32.json +237 -0
- package/fixtures/erwartet/training.blatt48.json +219 -0
- package/fixtures/erwartet/training.grid32.txt +2 -0
- package/fixtures/erwartet/training.grid48.txt +2 -0
- package/fixtures/erwartet/verkauf-bar.blatt32.json +177 -0
- package/fixtures/erwartet/verkauf-bar.blatt48.json +171 -0
- package/fixtures/erwartet/verkauf-karte.blatt32.json +177 -0
- package/fixtures/erwartet/verkauf-karte.blatt48.json +171 -0
- package/fixtures/erwartet/verkauf-kleinunternehmer.blatt32.json +183 -0
- package/fixtures/erwartet/verkauf-kleinunternehmer.blatt48.json +177 -0
- package/fixtures/hobex-hps-codes.json +1 -1
- package/fixtures/kasse-settings-standard.json +1 -1
- package/fixtures/kasse-texte.json +1 -1
- package/fixtures/manifest.json +109 -43
- package/fixtures/oberflaeche.json +1 -1
- package/package.json +1 -1
|
@@ -27,7 +27,7 @@ export interface GridLine {
|
|
|
27
27
|
text: string;
|
|
28
28
|
kind: GridLineKind;
|
|
29
29
|
bold: boolean;
|
|
30
|
-
/** Bei `banner
|
|
30
|
+
/** Bei `banner` (Rahmen- und Textzeilen): `warnung` = Test/Ausfall, `belegart` = Storno, Nullbeleg … */
|
|
31
31
|
ton?: 'belegart' | 'warnung';
|
|
32
32
|
/** Bei `qr`: die Nutzlast. */
|
|
33
33
|
qr?: string;
|
package/dist/cjs/receipt/grid.js
CHANGED
|
@@ -67,10 +67,18 @@ function renderReceiptGrid(layout, options = {}) {
|
|
|
67
67
|
for (const t of (0, escpos_js_1.wortzeilenText)(z.text, zeichen))
|
|
68
68
|
lines.push({ text: ausrichten(t, zeichen, z.align), kind: 'text', bold: z.bold });
|
|
69
69
|
break;
|
|
70
|
-
case 'banner':
|
|
70
|
+
case 'banner': {
|
|
71
|
+
// Der Rahmen ist Teil des Rasters: eine Zeile '=' ueber die volle Breite
|
|
72
|
+
// davor und danach. So setzt ihn jeder Weg -- Bildschirm, Bon, ePOS, PDF,
|
|
73
|
+
// myPOS -- Zeichen fuer Zeichen gleich. Vorher zeichnete jeder Weg seinen
|
|
74
|
+
// eigenen Rahmen (Rechteck, doppelt hoch, invers, gefuellt).
|
|
75
|
+
const rahmen = '='.repeat(zeichen);
|
|
76
|
+
lines.push({ text: rahmen, kind: 'banner', bold: true, ton: z.ton });
|
|
71
77
|
for (const t of (0, escpos_js_1.wortzeilenText)(z.text, zeichen))
|
|
72
78
|
lines.push({ text: ausrichten(t, zeichen, 'center'), kind: 'banner', bold: true, ton: z.ton });
|
|
79
|
+
lines.push({ text: rahmen, kind: 'banner', bold: true, ton: z.ton });
|
|
73
80
|
break;
|
|
81
|
+
}
|
|
74
82
|
case 'rule':
|
|
75
83
|
lines.push({ text: (z.char || '-').charAt(0).repeat(zeichen), kind: 'rule', bold: false });
|
|
76
84
|
break;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { type LayoutAlign, type LayoutColumn, type LayoutTextLine, type LayoutColumnsLine, type LayoutRuleLine, type LayoutSpaceLine, type LayoutQrLine, type LayoutLine, type ReceiptLayout, type BuildReceiptLayoutOptions, buildReceiptLayout, receiptSignatureFailed, receiptSignatureIsTest, receiptIsZero, receiptAmountsAreZero, receiptIsSmallBusinessConsistent, receiptZdaText, type Pruefangaben, AKTUELLES_REGELWERK, type LayoutBannerLine, type LayoutRegelwerk, SMALL_BUSINESS_NOTICE, formatCents, } from './layout.js';
|
|
2
|
-
export { type EscPosLayoutOptions, type EscPosLayoutErgebnis, type QrPrintMode, escPosLayoutBytes, escPosLayoutErgebnis, } from './layout-escpos.js';
|
|
2
|
+
export { type EscPosLayoutOptions, type EscPosLayoutErgebnis, type QrPrintMode, type DruckLogo, pruefeLogoRaster, escPosLayoutBytes, escPosLayoutErgebnis, } from './layout-escpos.js';
|
|
3
3
|
export { type GridLine, type GridLineKind, type ReceiptGrid, type RenderReceiptGridOptions, renderReceiptGrid, gridSpaltenBreiten, gridAlsText, ZEICHEN_JE_PAPIER, } from './grid.js';
|
|
4
|
-
export { type EposPrintXmlOptions, type EposPrintErgebnis, type EposDirectOptions, type EposResponse, EposConnectionError, eposPrintXml, eposPrintXmlErgebnis, eposXmlEscape, eposServiceUrl, eposSoapEnvelope, eposParseResponse, eposDirectPrint, eposDirectStatus } from './epos.js';
|
|
4
|
+
export { type EposPrintXmlOptions, type EposPrintErgebnis, type EposDirectOptions, type EposResponse, EposConnectionError, eposPrintXml, eposPrintXmlErgebnis, eposXmlEscape, eposBildXml, eposServiceUrl, eposSoapEnvelope, eposParseResponse, eposDirectPrint, eposDirectStatus } from './epos.js';
|
|
5
|
+
export { type LogoStufe, type BlattLogo, type LogoMass, type BlattBlock, type BelegBlatt, type BelegBlattOptionen, LOGO_STUFEN, LOGO_PIXEL_MAX, PUNKTE_JE_ZEICHEN, PUNKTE_JE_ZEILE, MARKE_TEXT, papierFuerZeichen, logoMass, logoPixelZulaessig, logoRasterMass, qrBlattAnteil, belegBlatt, } from './blatt.js';
|
|
6
|
+
export { logoRaster } from './bild.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.eposDirectStatus = exports.eposDirectPrint = exports.eposParseResponse = exports.eposSoapEnvelope = exports.eposServiceUrl = exports.eposXmlEscape = exports.eposPrintXmlErgebnis = exports.eposPrintXml = exports.EposConnectionError = exports.ZEICHEN_JE_PAPIER = exports.gridAlsText = exports.gridSpaltenBreiten = exports.renderReceiptGrid = exports.escPosLayoutErgebnis = exports.escPosLayoutBytes = exports.formatCents = exports.SMALL_BUSINESS_NOTICE = exports.AKTUELLES_REGELWERK = exports.receiptZdaText = exports.receiptIsSmallBusinessConsistent = exports.receiptAmountsAreZero = exports.receiptIsZero = exports.receiptSignatureIsTest = exports.receiptSignatureFailed = exports.buildReceiptLayout = void 0;
|
|
3
|
+
exports.logoRaster = exports.belegBlatt = exports.qrBlattAnteil = exports.logoRasterMass = exports.logoPixelZulaessig = exports.logoMass = exports.papierFuerZeichen = exports.MARKE_TEXT = exports.PUNKTE_JE_ZEILE = exports.PUNKTE_JE_ZEICHEN = exports.LOGO_PIXEL_MAX = exports.LOGO_STUFEN = exports.eposDirectStatus = exports.eposDirectPrint = exports.eposParseResponse = exports.eposSoapEnvelope = exports.eposServiceUrl = exports.eposBildXml = exports.eposXmlEscape = exports.eposPrintXmlErgebnis = exports.eposPrintXml = exports.EposConnectionError = exports.ZEICHEN_JE_PAPIER = exports.gridAlsText = exports.gridSpaltenBreiten = exports.renderReceiptGrid = exports.escPosLayoutErgebnis = exports.escPosLayoutBytes = exports.pruefeLogoRaster = exports.formatCents = exports.SMALL_BUSINESS_NOTICE = exports.AKTUELLES_REGELWERK = exports.receiptZdaText = exports.receiptIsSmallBusinessConsistent = exports.receiptAmountsAreZero = exports.receiptIsZero = exports.receiptSignatureIsTest = exports.receiptSignatureFailed = exports.buildReceiptLayout = void 0;
|
|
4
4
|
var layout_js_1 = require("./layout.js");
|
|
5
5
|
Object.defineProperty(exports, "buildReceiptLayout", { enumerable: true, get: function () { return layout_js_1.buildReceiptLayout; } });
|
|
6
6
|
Object.defineProperty(exports, "receiptSignatureFailed", { enumerable: true, get: function () { return layout_js_1.receiptSignatureFailed; } });
|
|
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "AKTUELLES_REGELWERK", { enumerable: true, get: f
|
|
|
13
13
|
Object.defineProperty(exports, "SMALL_BUSINESS_NOTICE", { enumerable: true, get: function () { return layout_js_1.SMALL_BUSINESS_NOTICE; } });
|
|
14
14
|
Object.defineProperty(exports, "formatCents", { enumerable: true, get: function () { return layout_js_1.formatCents; } });
|
|
15
15
|
var layout_escpos_js_1 = require("./layout-escpos.js");
|
|
16
|
+
Object.defineProperty(exports, "pruefeLogoRaster", { enumerable: true, get: function () { return layout_escpos_js_1.pruefeLogoRaster; } });
|
|
16
17
|
Object.defineProperty(exports, "escPosLayoutBytes", { enumerable: true, get: function () { return layout_escpos_js_1.escPosLayoutBytes; } });
|
|
17
18
|
Object.defineProperty(exports, "escPosLayoutErgebnis", { enumerable: true, get: function () { return layout_escpos_js_1.escPosLayoutErgebnis; } });
|
|
18
19
|
var grid_js_1 = require("./grid.js");
|
|
@@ -25,8 +26,23 @@ Object.defineProperty(exports, "EposConnectionError", { enumerable: true, get: f
|
|
|
25
26
|
Object.defineProperty(exports, "eposPrintXml", { enumerable: true, get: function () { return epos_js_1.eposPrintXml; } });
|
|
26
27
|
Object.defineProperty(exports, "eposPrintXmlErgebnis", { enumerable: true, get: function () { return epos_js_1.eposPrintXmlErgebnis; } });
|
|
27
28
|
Object.defineProperty(exports, "eposXmlEscape", { enumerable: true, get: function () { return epos_js_1.eposXmlEscape; } });
|
|
29
|
+
Object.defineProperty(exports, "eposBildXml", { enumerable: true, get: function () { return epos_js_1.eposBildXml; } });
|
|
28
30
|
Object.defineProperty(exports, "eposServiceUrl", { enumerable: true, get: function () { return epos_js_1.eposServiceUrl; } });
|
|
29
31
|
Object.defineProperty(exports, "eposSoapEnvelope", { enumerable: true, get: function () { return epos_js_1.eposSoapEnvelope; } });
|
|
30
32
|
Object.defineProperty(exports, "eposParseResponse", { enumerable: true, get: function () { return epos_js_1.eposParseResponse; } });
|
|
31
33
|
Object.defineProperty(exports, "eposDirectPrint", { enumerable: true, get: function () { return epos_js_1.eposDirectPrint; } });
|
|
32
34
|
Object.defineProperty(exports, "eposDirectStatus", { enumerable: true, get: function () { return epos_js_1.eposDirectStatus; } });
|
|
35
|
+
var blatt_js_1 = require("./blatt.js");
|
|
36
|
+
Object.defineProperty(exports, "LOGO_STUFEN", { enumerable: true, get: function () { return blatt_js_1.LOGO_STUFEN; } });
|
|
37
|
+
Object.defineProperty(exports, "LOGO_PIXEL_MAX", { enumerable: true, get: function () { return blatt_js_1.LOGO_PIXEL_MAX; } });
|
|
38
|
+
Object.defineProperty(exports, "PUNKTE_JE_ZEICHEN", { enumerable: true, get: function () { return blatt_js_1.PUNKTE_JE_ZEICHEN; } });
|
|
39
|
+
Object.defineProperty(exports, "PUNKTE_JE_ZEILE", { enumerable: true, get: function () { return blatt_js_1.PUNKTE_JE_ZEILE; } });
|
|
40
|
+
Object.defineProperty(exports, "MARKE_TEXT", { enumerable: true, get: function () { return blatt_js_1.MARKE_TEXT; } });
|
|
41
|
+
Object.defineProperty(exports, "papierFuerZeichen", { enumerable: true, get: function () { return blatt_js_1.papierFuerZeichen; } });
|
|
42
|
+
Object.defineProperty(exports, "logoMass", { enumerable: true, get: function () { return blatt_js_1.logoMass; } });
|
|
43
|
+
Object.defineProperty(exports, "logoPixelZulaessig", { enumerable: true, get: function () { return blatt_js_1.logoPixelZulaessig; } });
|
|
44
|
+
Object.defineProperty(exports, "logoRasterMass", { enumerable: true, get: function () { return blatt_js_1.logoRasterMass; } });
|
|
45
|
+
Object.defineProperty(exports, "qrBlattAnteil", { enumerable: true, get: function () { return blatt_js_1.qrBlattAnteil; } });
|
|
46
|
+
Object.defineProperty(exports, "belegBlatt", { enumerable: true, get: function () { return blatt_js_1.belegBlatt; } });
|
|
47
|
+
var bild_js_1 = require("./bild.js");
|
|
48
|
+
Object.defineProperty(exports, "logoRaster", { enumerable: true, get: function () { return bild_js_1.logoRaster; } });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type PosCodeTable, type PosCutMode, type PosPaperSize, type QrCorrection, type QrMatrix, type QrModulGroesse, type QrSize } from '../printing/index.js';
|
|
1
|
+
import { type PosCodeTable, type PosCutMode, type PosPaperSize, type QrCorrection, type QrMatrix, type QrModulGroesse, type QrSize, type RasterBild } from '../printing/index.js';
|
|
2
2
|
import type { ReceiptLayout } from './layout.js';
|
|
3
|
+
import { type BelegBlatt, type LogoStufe, type LogoMass } from './blatt.js';
|
|
3
4
|
/**
|
|
4
5
|
* Bruecke vom Layout-Modell zu ESC/POS-Bytes — der Bondrucker-Ausgabeweg.
|
|
5
6
|
*
|
|
@@ -28,6 +29,29 @@ import type { ReceiptLayout } from './layout.js';
|
|
|
28
29
|
* (`qrMatrix`), weil dieses Paket keine QR-Codes rechnet.
|
|
29
30
|
*/
|
|
30
31
|
export type QrPrintMode = 'native' | 'nativeModel1' | 'imageRaster';
|
|
32
|
+
/** Firmenlogo fuer den Druck: Stufe, Pixelmass des Originals und das fertige Rasterbild (`logoRaster`). */
|
|
33
|
+
export interface DruckLogo {
|
|
34
|
+
stufe: LogoStufe;
|
|
35
|
+
pxBreite: number;
|
|
36
|
+
pxHoehe: number;
|
|
37
|
+
raster: RasterBild;
|
|
38
|
+
}
|
|
39
|
+
/** Das Rasterbild muss genau so gross sein, wie das Blatt das Logo setzt -- sonst stuende am Bon ein anderes Logo als am Schirm. */
|
|
40
|
+
export declare function pruefeLogoRaster(logo: DruckLogo, mass: LogoMass, zeichen: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* Baut das Blatt fuer einen Druckweg (ESC/POS, ePOS) an EINER Stelle: die
|
|
43
|
+
* Zuordnung `DruckLogo` -> `BlattLogo` und die Groessenpruefung des mitgebrachten
|
|
44
|
+
* Rasterbilds teilen sich beide Wege -- ohne das muesste eine Aenderung daran an
|
|
45
|
+
* zwei Stellen nachgezogen werden. Wirft VOR jeder Ausgabe (also bevor der
|
|
46
|
+
* Aufrufer auch nur ein Byte/Zeichen geschrieben hat), wenn das Rasterbild nicht
|
|
47
|
+
* zur Logo-Stufe passt.
|
|
48
|
+
*/
|
|
49
|
+
export declare function blattFuerDruck(layout: ReceiptLayout, optionen: {
|
|
50
|
+
zeichen: number;
|
|
51
|
+
logo?: DruckLogo | null;
|
|
52
|
+
marke?: boolean;
|
|
53
|
+
qrGroesse: QrModulGroesse;
|
|
54
|
+
}): BelegBlatt;
|
|
31
55
|
export interface EscPosLayoutOptions {
|
|
32
56
|
/** Papierbreite; Vorgabe ist die des Layouts (dessen Spaltenbreiten daran haengen). */
|
|
33
57
|
paperSize?: PosPaperSize;
|
|
@@ -40,9 +64,9 @@ export interface EscPosLayoutOptions {
|
|
|
40
64
|
* dann passt der Aufrufer selbst auf, dass das Symbol aufs Papier geht.
|
|
41
65
|
*/
|
|
42
66
|
qrSize?: QrSize;
|
|
43
|
-
/** Fehlerkorrekturstufe des QR-Codes. */
|
|
67
|
+
/** Fehlerkorrekturstufe des QR-Codes; Vorgabe `M` (wie ePOS, Bildweg und Blatt). */
|
|
44
68
|
qrCorrection?: QrCorrection;
|
|
45
|
-
/** Deckel fuer die gerechnete Modulgroesse; Vorgabe `auto
|
|
69
|
+
/** Deckel fuer die gerechnete Modulgroesse; Vorgabe `auto` (hoechstens 6 Punkte je Modul). */
|
|
46
70
|
qrGroesse?: QrModulGroesse;
|
|
47
71
|
/** Druckweg des QR; Vorgabe `native` (der Bestandsweg). */
|
|
48
72
|
qrModus?: QrPrintMode;
|
|
@@ -54,6 +78,10 @@ export interface EscPosLayoutOptions {
|
|
|
54
78
|
* aus der QR-Bibliothek, die er ohnehin fuer den Bildschirm benutzt.
|
|
55
79
|
*/
|
|
56
80
|
qrMatrix?: (nutzlast: string) => QrMatrix;
|
|
81
|
+
/** Firmenlogo; ohne Angabe kein Logo (Bestand). */
|
|
82
|
+
logo?: DruckLogo | null;
|
|
83
|
+
/** "erstellt mit Kasseneck" am Ende (Konto-Flag `kreiseck_logo`). */
|
|
84
|
+
marke?: boolean;
|
|
57
85
|
}
|
|
58
86
|
/**
|
|
59
87
|
* Der Bytestrom **samt** dem, was dem QR unterwegs zugestossen ist.
|
|
@@ -1,9 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pruefeLogoRaster = pruefeLogoRaster;
|
|
4
|
+
exports.blattFuerDruck = blattFuerDruck;
|
|
3
5
|
exports.escPosLayoutBytes = escPosLayoutBytes;
|
|
4
6
|
exports.escPosLayoutErgebnis = escPosLayoutErgebnis;
|
|
5
7
|
const index_js_1 = require("../printing/index.js");
|
|
8
|
+
const blatt_js_1 = require("./blatt.js");
|
|
6
9
|
const grid_js_1 = require("./grid.js");
|
|
10
|
+
/** Das Rasterbild muss genau so gross sein, wie das Blatt das Logo setzt -- sonst stuende am Bon ein anderes Logo als am Schirm. */
|
|
11
|
+
function pruefeLogoRaster(logo, mass, zeichen) {
|
|
12
|
+
const soll = (0, blatt_js_1.logoRasterMass)(mass, zeichen);
|
|
13
|
+
if (logo.raster.breite !== soll.breite || logo.raster.hoehe !== soll.hoehe) {
|
|
14
|
+
throw new Error(`Logo-Raster ${logo.raster.breite}x${logo.raster.hoehe} passt nicht zum Blatt (${soll.breite}x${soll.hoehe})`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Baut das Blatt fuer einen Druckweg (ESC/POS, ePOS) an EINER Stelle: die
|
|
19
|
+
* Zuordnung `DruckLogo` -> `BlattLogo` und die Groessenpruefung des mitgebrachten
|
|
20
|
+
* Rasterbilds teilen sich beide Wege -- ohne das muesste eine Aenderung daran an
|
|
21
|
+
* zwei Stellen nachgezogen werden. Wirft VOR jeder Ausgabe (also bevor der
|
|
22
|
+
* Aufrufer auch nur ein Byte/Zeichen geschrieben hat), wenn das Rasterbild nicht
|
|
23
|
+
* zur Logo-Stufe passt.
|
|
24
|
+
*/
|
|
25
|
+
function blattFuerDruck(layout, optionen) {
|
|
26
|
+
const blattOptionen = {
|
|
27
|
+
zeichen: optionen.zeichen,
|
|
28
|
+
marke: optionen.marke === true,
|
|
29
|
+
qrGroesse: optionen.qrGroesse,
|
|
30
|
+
};
|
|
31
|
+
if (optionen.logo)
|
|
32
|
+
blattOptionen.logo = { stufe: optionen.logo.stufe, pxBreite: optionen.logo.pxBreite, pxHoehe: optionen.logo.pxHoehe };
|
|
33
|
+
const blatt = (0, blatt_js_1.belegBlatt)(layout, blattOptionen);
|
|
34
|
+
const logoBlock = blatt.bloecke.find((b) => b.art === 'logo');
|
|
35
|
+
if (optionen.logo && logoBlock && logoBlock.art === 'logo')
|
|
36
|
+
pruefeLogoRaster(optionen.logo, logoBlock, blatt.zeichen);
|
|
37
|
+
return blatt;
|
|
38
|
+
}
|
|
7
39
|
/**
|
|
8
40
|
* Druckbar gemachtes Layout: Texte durch [escPosPrintableText] (Codepage,
|
|
9
41
|
* "EUR" statt "€", Striche), damit das Raster mit den Zeichen rechnet, die
|
|
@@ -72,6 +104,13 @@ function escPosLayoutErgebnis(layout, options = {}) {
|
|
|
72
104
|
* `qrFehler` aus `escPosQrCode`, und der Beleg geht ohne QR hinaus.
|
|
73
105
|
*/
|
|
74
106
|
const qrZeile = (nutzlast) => {
|
|
107
|
+
// Ein Inhalt, der in keine QR-Version passt, laesst sich weder als Befehl
|
|
108
|
+
// noch als Bild drucken -- beide Wege wuerfen. Der Beleg geht ohne QR
|
|
109
|
+
// hinaus und sagt es ueber `qrFehler`, wie das Blatt (Anteil 0).
|
|
110
|
+
if (nutzlast !== '' && !(0, index_js_1.qrPasstInVersion)(nutzlast)) {
|
|
111
|
+
doc.qrFehler = 'QR-Inhalt passt in keine QR-Version -- Beleg ohne QR';
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
75
114
|
const raster = options.qrMatrix;
|
|
76
115
|
if (nutzlast !== '' && raster !== undefined) {
|
|
77
116
|
if (modus === 'imageRaster') {
|
|
@@ -98,27 +137,28 @@ function escPosLayoutErgebnis(layout, options = {}) {
|
|
|
98
137
|
}
|
|
99
138
|
(0, index_js_1.escPosQrCode)(doc, nutzlast, qrOptionen);
|
|
100
139
|
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
140
|
+
// `blattFuerDruck` prueft das Logo-Raster bereits VOR der Rueckgabe -- die
|
|
141
|
+
// Schleife unten schreibt darum nie ein Byte auf ein falsch grosses Logo.
|
|
142
|
+
const blatt = blattFuerDruck(druckbaresLayout(layout), {
|
|
143
|
+
zeichen: grid_js_1.ZEICHEN_JE_PAPIER[paperSize],
|
|
144
|
+
logo: options.logo,
|
|
145
|
+
marke: options.marke,
|
|
146
|
+
qrGroesse: options.qrGroesse ?? 'auto',
|
|
147
|
+
});
|
|
148
|
+
for (const block of blatt.bloecke) {
|
|
149
|
+
switch (block.art) {
|
|
107
150
|
case 'qr':
|
|
108
|
-
qrZeile(
|
|
151
|
+
qrZeile(block.nutzlast);
|
|
109
152
|
break;
|
|
110
|
-
case '
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// weiss-auf-schwarz und sah damit anders aus als jede Anzeige).
|
|
114
|
-
const rahmen = '='.repeat(grid_js_1.ZEICHEN_JE_PAPIER[paperSize]);
|
|
115
|
-
(0, index_js_1.escPosText)(doc, rahmen, { styles: { align: 'left', bold: true } });
|
|
116
|
-
(0, index_js_1.escPosText)(doc, zeile.text.trimEnd(), { styles: { align: 'left', bold: true, height: 2 } });
|
|
117
|
-
(0, index_js_1.escPosText)(doc, rahmen, { styles: { align: 'left', bold: true } });
|
|
153
|
+
case 'logo':
|
|
154
|
+
if (options.logo)
|
|
155
|
+
(0, index_js_1.escPosRasterBild)(doc, options.logo.raster, { align: 'center' });
|
|
118
156
|
break;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
157
|
+
case 'zeile':
|
|
158
|
+
if (block.leer)
|
|
159
|
+
(0, index_js_1.escPosFeed)(doc, 1);
|
|
160
|
+
else
|
|
161
|
+
(0, index_js_1.escPosText)(doc, block.text.trimEnd(), { styles: { align: 'left', bold: block.fett } });
|
|
122
162
|
break;
|
|
123
163
|
}
|
|
124
164
|
}
|
|
@@ -2,6 +2,7 @@ import { ReceiptType, type ReceiptTypeKey, KeckPaymentMethod, type KeckPaymentMe
|
|
|
2
2
|
import { type Receipt, type ReceiptCompany, type ReceiptItem, type Voucher, type ReceiptSummary, type ReportMonth, type CancellationItem, type CancellationOf, type CancellationReason } from '../models/index.js';
|
|
3
3
|
import type { InternerTransport } from './aufrufe.js';
|
|
4
4
|
import type { Pruefangaben, ReceiptLayout } from '../receipt/layout.js';
|
|
5
|
+
import type { LogoStufe } from '../receipt/blatt.js';
|
|
5
6
|
/**
|
|
6
7
|
* Beleg-Endpunkte — Zwilling der Beleg-Aufrufe in
|
|
7
8
|
* kasseneck_api/lib/kasseneck_api.dart.
|
|
@@ -168,6 +169,12 @@ export interface ReceiptWithCompany {
|
|
|
168
169
|
* fuer Clients, die das Layout selbst bauen; null bei altem Backend.
|
|
169
170
|
*/
|
|
170
171
|
pruefangaben: Pruefangaben | null;
|
|
172
|
+
/**
|
|
173
|
+
* Groesse des Firmenlogos am Beleg (Kasse-Einstellung `logoSkala` des
|
|
174
|
+
* Betriebs). Bildschirm, Bon und PDF setzen das Logo in genau dieser Stufe;
|
|
175
|
+
* liefert das Backend sie nicht (alt), gilt `M` -- der Bestandswert.
|
|
176
|
+
*/
|
|
177
|
+
logoStufe: LogoStufe;
|
|
171
178
|
}
|
|
172
179
|
/**
|
|
173
180
|
* Gemeinsame Umsetzung aller Belegarten (Zwilling von `_createReceipt`).
|
|
@@ -567,5 +567,6 @@ function belegMitFirmaAusHuelle(daten, functionName) {
|
|
|
567
567
|
kopfId: typeof d.kopfId === 'string' ? d.kopfId : null,
|
|
568
568
|
layout,
|
|
569
569
|
pruefangaben: pa ? { karteRegistriertAm: text(pa.karteRegistriertAm), kasseRegistriertAm: text(pa.kasseRegistriertAm) } : null,
|
|
570
|
+
logoStufe: d.logo_skala === 'S' || d.logo_skala === 'M' || d.logo_skala === 'L' || d.logo_skala === 'XL' ? d.logo_skala : 'M',
|
|
570
571
|
};
|
|
571
572
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { InternerTransport } from '../client/aufrufe.js';
|
|
2
2
|
import type { ReceiptLayout } from '../receipt/layout.js';
|
|
3
|
+
import type { DruckLogo } from '../receipt/layout-escpos.js';
|
|
3
4
|
/**
|
|
4
5
|
* Netzwerk-Bondrucker ueber Epson "Server Direct Print": das Backend fuehrt
|
|
5
6
|
* je Konto Drucker mit einer geheimen Abhol-URL; die Kasse legt Druckjobs
|
|
@@ -46,6 +47,10 @@ export interface CreatePrintJobOptions {
|
|
|
46
47
|
receiptId?: string;
|
|
47
48
|
titel?: string;
|
|
48
49
|
quelle?: string;
|
|
50
|
+
/** Firmenlogo als fertiges Rasterbild (`logoRaster`); der Server dekodiert keine Bilder. */
|
|
51
|
+
logo?: DruckLogo | null;
|
|
52
|
+
/** "erstellt mit Kasseneck" am Ende (Konto-Flag `kreiseck_logo`). */
|
|
53
|
+
marke?: boolean;
|
|
49
54
|
}
|
|
50
55
|
export declare function createPrintJob(rufen: InternerTransport, o: CreatePrintJobOptions): Promise<DruckJob>;
|
|
51
56
|
export declare function getPrintJob(rufen: InternerTransport, o: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { rasterZeilenBase64 } from '../printing/index.js';
|
|
1
2
|
const text = (v) => (typeof v === 'string' && v ? v : null);
|
|
2
3
|
const zahl = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : null);
|
|
3
4
|
export async function listMyPrinters(rufen) {
|
|
@@ -22,6 +23,14 @@ export async function createPrintJob(rufen, o) {
|
|
|
22
23
|
params.titel = o.titel;
|
|
23
24
|
if (o.quelle)
|
|
24
25
|
params.quelle = o.quelle;
|
|
26
|
+
if (o.logo) {
|
|
27
|
+
params.logo = {
|
|
28
|
+
stufe: o.logo.stufe, pxBreite: o.logo.pxBreite, pxHoehe: o.logo.pxHoehe,
|
|
29
|
+
breite: o.logo.raster.breite, hoehe: o.logo.raster.hoehe, zeilen: rasterZeilenBase64(o.logo.raster),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (o.marke === true)
|
|
33
|
+
params.marke = true;
|
|
25
34
|
const daten = await rufen('createPrintJob', params);
|
|
26
35
|
return { jobId: String(daten?.jobId ?? ''), status: text(daten?.status) ?? 'offen', ergebnis: null };
|
|
27
36
|
}
|
|
@@ -112,8 +112,11 @@ export const KASSE_TASTEN_STANDARD = Object.freeze({
|
|
|
112
112
|
korbLeeren: ['Mod+C'],
|
|
113
113
|
});
|
|
114
114
|
export const KASSE_BETRIEB_STANDARD = Object.freeze({
|
|
115
|
-
// Petrol
|
|
116
|
-
|
|
115
|
+
// Das Petrol der Marke: die Aktionsfarbe des Design-Systems (Rolle `brand`).
|
|
116
|
+
// Stand bis September 2026 auf dem Wert des alten Markenhandbuchs,
|
|
117
|
+
// der um 0,07 in OKLab danebenlag. Unsichtbar, aber es war die letzte Stelle
|
|
118
|
+
// im Haus, an der eine zweite Zahl fuer dieselbe Farbe stand.
|
|
119
|
+
logoText: 'K', logoAn: true, logoGroesse: 'M', wasserzeichen: 'anmeldung', farbe: '#136B6B',
|
|
117
120
|
stil: 'klar', schrift: 'M', schriftEinst: 'S', kachelstil: 'streifen', uhr: true,
|
|
118
121
|
sperrbild: true, foto: true, autoAbMin: 0, abNachVerkauf: false, schnellLogin: true,
|
|
119
122
|
preisAnzeigen: true, ustAnzeigen: false, emoji: true, katFarben: true, freiErlaubt: true,
|
|
@@ -24,8 +24,9 @@
|
|
|
24
24
|
* CP437-Plaetze umkodiert (ä = 0x84, ü = 0x81, ß = 0xE1, ...). Zeichen ohne
|
|
25
25
|
* CP437-Platz werden zu `?` — weiterhin ein Byte je Zeichen.
|
|
26
26
|
*
|
|
27
|
-
* Nicht enthalten (bewusst):
|
|
28
|
-
* Druckermodelle, Kassenlade, 1D-Barcodes.
|
|
27
|
+
* Nicht enthalten (bewusst): Bilddekodierung (PNG/JPEG liest die Huelle),
|
|
28
|
+
* Capability-Profile einzelner Druckermodelle, Kassenlade, 1D-Barcodes.
|
|
29
|
+
* Fertige einfarbige Rasterbilder (Logo) gehen ueber [escPosRasterBild].
|
|
29
30
|
*/
|
|
30
31
|
import { type QrModulGroesse } from './qr-groesse.js';
|
|
31
32
|
/** Papierbreite der Bonrolle. */
|
|
@@ -103,6 +104,7 @@ export interface EscPosQrOptions {
|
|
|
103
104
|
* die Regel in `qr-groesse.ts`.
|
|
104
105
|
*/
|
|
105
106
|
size?: QrSize;
|
|
107
|
+
/** Fehlerkorrektur; Vorgabe `M` wie auf allen Druckwegen (siehe `qrCodeBytes`). */
|
|
106
108
|
correction?: QrCorrection;
|
|
107
109
|
/** Deckel fuer die gerechnete Modulgroesse; wirkungslos neben `size`. */
|
|
108
110
|
groesse?: QrModulGroesse;
|
|
@@ -255,6 +257,12 @@ export declare function escPosRow(doc: EscPosDocument, columns: readonly PosColu
|
|
|
255
257
|
* es wird kein Bild uebertragen.
|
|
256
258
|
*
|
|
257
259
|
* Bei Kasseneck-Belegen steht hier der maschinenlesbare RKSV-Code.
|
|
260
|
+
*
|
|
261
|
+
* Fehlerkorrektur ohne Angabe: **M** (bis 0.13: L). Die Groessenrechnung
|
|
262
|
+
* (`qrModulAnzahl`), das Blatt (Anteil am Bildschirm und im PDF), der
|
|
263
|
+
* ePOS-Weg (`level_m`) und der Bildweg rechnen alle mit M — druckte der
|
|
264
|
+
* native Befehl mit L, kaeme fuer manche Nutzlasten ein kleineres Symbol
|
|
265
|
+
* heraus als der Bildschirm zeigt.
|
|
258
266
|
*/
|
|
259
267
|
export declare function qrCodeBytes(text: string, options?: {
|
|
260
268
|
size?: QrSize;
|
|
@@ -266,8 +274,8 @@ export declare function qrCodeBytes(text: string, options?: {
|
|
|
266
274
|
* **gerechneter** Modulgroesse, sofern `options.size` sie nicht festlegt.
|
|
267
275
|
*
|
|
268
276
|
* Ohne `size` entscheidet die Regel aus `qr-groesse.ts`: so gross wie
|
|
269
|
-
* moeglich, gedeckelt durch `options.groesse` (Vorgabe `auto` =
|
|
270
|
-
*
|
|
277
|
+
* moeglich, gedeckelt durch `options.groesse` (Vorgabe `auto` = hoechstens 6
|
|
278
|
+
* Punkte je Modul, wie im Flutter-Zwilling). Passt das Symbol auch mit der
|
|
271
279
|
* Ausnahmegroesse nicht aufs Papier, geht **kein** QR-Befehl hinaus und
|
|
272
280
|
* `doc.qrFehler` sagt warum: der Drucker schneidet ein zu breites Symbol
|
|
273
281
|
* nicht ab, er laesst es weg — ein Befehl, von dem man weiss, dass er nichts
|
|
@@ -300,4 +308,30 @@ export declare function qrRasterPunkte(paperSize: PosPaperSize, moduleAnzahl: nu
|
|
|
300
308
|
groesse?: QrModulGroesse;
|
|
301
309
|
ruhezoneModule?: number;
|
|
302
310
|
}): number;
|
|
311
|
+
/**
|
|
312
|
+
* Einfarbiges Rasterbild in Druckpunkten, zeilenweise: `punkte[y * breite + x]`,
|
|
313
|
+
* 1 = schwarz. Entsteht fuer das Firmenlogo in `logoRaster` (receipt/bild.ts).
|
|
314
|
+
*/
|
|
315
|
+
export interface RasterBild {
|
|
316
|
+
readonly breite: number;
|
|
317
|
+
readonly hoehe: number;
|
|
318
|
+
readonly punkte: Uint8Array;
|
|
319
|
+
}
|
|
320
|
+
/** Die Rasterzeilen als Bytes: MSB zuerst, jede Zeile auf volle Bytes aufgefuellt. */
|
|
321
|
+
export declare function rasterZeilenBytes(bild: RasterBild): Uint8Array;
|
|
322
|
+
/**
|
|
323
|
+
* Die Rasterzeilen als Base64 -- ohne Buffer, laeuft im Browser und in Node.
|
|
324
|
+
* Eine Stelle fuer ePOS-`<image>` und den Druckjob an den Server.
|
|
325
|
+
*/
|
|
326
|
+
export declare function rasterZeilenBase64(bild: RasterBild): string;
|
|
327
|
+
/**
|
|
328
|
+
* Ein Rasterbild (`GS v 0`) -- das Firmenlogo am Bon.
|
|
329
|
+
*
|
|
330
|
+
* Anders als `escPosQrRaster` folgt KEIN Zeilenvorschub: `GS v 0` schiebt das
|
|
331
|
+
* Papier um die Bildhoehe, ein LF danach waere eine zusaetzliche Leerzeile,
|
|
332
|
+
* die Bildschirm und PDF nicht haben. Die Luft um das Logo kommt aus dem Blatt.
|
|
333
|
+
*/
|
|
334
|
+
export declare function escPosRasterBild(doc: EscPosDocument, bild: RasterBild, options?: {
|
|
335
|
+
align?: PosAlign;
|
|
336
|
+
}): void;
|
|
303
337
|
export {};
|
|
@@ -24,8 +24,9 @@
|
|
|
24
24
|
* CP437-Plaetze umkodiert (ä = 0x84, ü = 0x81, ß = 0xE1, ...). Zeichen ohne
|
|
25
25
|
* CP437-Platz werden zu `?` — weiterhin ein Byte je Zeichen.
|
|
26
26
|
*
|
|
27
|
-
* Nicht enthalten (bewusst):
|
|
28
|
-
* Druckermodelle, Kassenlade, 1D-Barcodes.
|
|
27
|
+
* Nicht enthalten (bewusst): Bilddekodierung (PNG/JPEG liest die Huelle),
|
|
28
|
+
* Capability-Profile einzelner Druckermodelle, Kassenlade, 1D-Barcodes.
|
|
29
|
+
* Fertige einfarbige Rasterbilder (Logo) gehen ueber [escPosRasterBild].
|
|
29
30
|
*/
|
|
30
31
|
import { QR_DRUCK_PUNKTE, QR_MINDEST_PUNKTE, QR_MODUL_DECKEL, QR_RUHEZONE_MODULE, qrGroesseFuer, } from './qr-groesse.js';
|
|
31
32
|
// -------------------------------------------------------------- Befehlsbytes
|
|
@@ -581,13 +582,19 @@ export function escPosRow(doc, columns) {
|
|
|
581
582
|
* es wird kein Bild uebertragen.
|
|
582
583
|
*
|
|
583
584
|
* Bei Kasseneck-Belegen steht hier der maschinenlesbare RKSV-Code.
|
|
585
|
+
*
|
|
586
|
+
* Fehlerkorrektur ohne Angabe: **M** (bis 0.13: L). Die Groessenrechnung
|
|
587
|
+
* (`qrModulAnzahl`), das Blatt (Anteil am Bildschirm und im PDF), der
|
|
588
|
+
* ePOS-Weg (`level_m`) und der Bildweg rechnen alle mit M — druckte der
|
|
589
|
+
* native Befehl mit L, kaeme fuer manche Nutzlasten ein kleineres Symbol
|
|
590
|
+
* heraus als der Bildschirm zeigt.
|
|
584
591
|
*/
|
|
585
592
|
export function qrCodeBytes(text, options = {}) {
|
|
586
593
|
const size = options.size ?? 4;
|
|
587
594
|
if (!istGanzzahl(size) || size < 1 || size > 8) {
|
|
588
595
|
throw new Error('QR-Modulgroesse muss eine Ganzzahl im Bereich 1..8 sein');
|
|
589
596
|
}
|
|
590
|
-
const correction = options.correction ?? '
|
|
597
|
+
const correction = options.correction ?? 'M';
|
|
591
598
|
const stufe = QR_KORREKTUR[correction];
|
|
592
599
|
if (stufe === undefined) {
|
|
593
600
|
throw new Error(`Unbekannte QR-Fehlerkorrektur: ${String(correction)}`);
|
|
@@ -628,8 +635,8 @@ export function qrCodeBytes(text, options = {}) {
|
|
|
628
635
|
* **gerechneter** Modulgroesse, sofern `options.size` sie nicht festlegt.
|
|
629
636
|
*
|
|
630
637
|
* Ohne `size` entscheidet die Regel aus `qr-groesse.ts`: so gross wie
|
|
631
|
-
* moeglich, gedeckelt durch `options.groesse` (Vorgabe `auto` =
|
|
632
|
-
*
|
|
638
|
+
* moeglich, gedeckelt durch `options.groesse` (Vorgabe `auto` = hoechstens 6
|
|
639
|
+
* Punkte je Modul, wie im Flutter-Zwilling). Passt das Symbol auch mit der
|
|
633
640
|
* Ausnahmegroesse nicht aufs Papier, geht **kein** QR-Befehl hinaus und
|
|
634
641
|
* `doc.qrFehler` sagt warum: der Drucker schneidet ein zu breites Symbol
|
|
635
642
|
* nicht ab, er laesst es weg — ein Befehl, von dem man weiss, dass er nichts
|
|
@@ -714,9 +721,10 @@ export function escPosQrRaster(doc, matrix, options = {}) {
|
|
|
714
721
|
if (!istGanzzahl(punkte) || punkte < 1) {
|
|
715
722
|
throw new Error('punkteJeModul muss eine Ganzzahl >= 1 sein');
|
|
716
723
|
}
|
|
724
|
+
// Modulraster (samt Ruhezone) auf Druckpunkte skaliert -- dieselbe Bitquelle
|
|
725
|
+
// wie das Logo, nur aus einem QR-Modul-Bool statt aus Graustufen gewonnen.
|
|
717
726
|
const breite = gesamtModule * punkte;
|
|
718
|
-
const
|
|
719
|
-
const daten = new Uint8Array(byteJeZeile * breite);
|
|
727
|
+
const bildpunkte = new Uint8Array(breite * breite);
|
|
720
728
|
for (let y = 0; y < breite; y++) {
|
|
721
729
|
const modulY = Math.floor(y / punkte) - ruhezone;
|
|
722
730
|
if (modulY < 0 || modulY >= module)
|
|
@@ -728,18 +736,14 @@ export function escPosQrRaster(doc, matrix, options = {}) {
|
|
|
728
736
|
continue;
|
|
729
737
|
if (zeile[modulX] !== true)
|
|
730
738
|
continue;
|
|
731
|
-
|
|
732
|
-
daten[i] = daten[i] | (0x80 >> (x & 7));
|
|
739
|
+
bildpunkte[y * breite + x] = 1;
|
|
733
740
|
}
|
|
734
741
|
}
|
|
742
|
+
const daten = rasterZeilenBytes({ breite, hoehe: breite, punkte: bildpunkte });
|
|
735
743
|
escPosSetStyles(doc, { align: options.align ?? 'center' });
|
|
736
744
|
// GS v 0 m xL xH yL yH d1...dk — m = 0: normale Dichte, 1:1.
|
|
737
|
-
anhaengen(doc,
|
|
738
|
-
|
|
739
|
-
byteJeZeile & 0xff, (byteJeZeile >> 8) & 0xff,
|
|
740
|
-
breite & 0xff, (breite >> 8) & 0xff,
|
|
741
|
-
...daten,
|
|
742
|
-
]);
|
|
745
|
+
anhaengen(doc, rasterBildKopf(breite, breite));
|
|
746
|
+
anhaengen(doc, daten);
|
|
743
747
|
anhaengen(doc, [ZEILENUMBRUCH]);
|
|
744
748
|
if ((options.align ?? 'center') !== 'left') {
|
|
745
749
|
escPosSetStyles(doc, { align: 'left' });
|
|
@@ -755,3 +759,68 @@ export function qrRasterPunkte(paperSize, moduleAnzahl, options = {}) {
|
|
|
755
759
|
const deckel = QR_MODUL_DECKEL[options.groesse ?? 'auto'];
|
|
756
760
|
return Math.max(1, Math.min(deckel, Math.floor(QR_DRUCK_PUNKTE[paperSize] / (moduleAnzahl + 2 * ruhezone))));
|
|
757
761
|
}
|
|
762
|
+
/** Die Rasterzeilen als Bytes: MSB zuerst, jede Zeile auf volle Bytes aufgefuellt. */
|
|
763
|
+
export function rasterZeilenBytes(bild) {
|
|
764
|
+
if (!istGanzzahl(bild.breite) || bild.breite < 1 || !istGanzzahl(bild.hoehe) || bild.hoehe < 1) {
|
|
765
|
+
throw new Error('Rasterbild ohne gueltiges Mass');
|
|
766
|
+
}
|
|
767
|
+
if (bild.punkte.length !== bild.breite * bild.hoehe)
|
|
768
|
+
throw new Error('Rasterbild: Punkte passen nicht zum Mass');
|
|
769
|
+
const byteJeZeile = Math.ceil(bild.breite / 8);
|
|
770
|
+
const daten = new Uint8Array(byteJeZeile * bild.hoehe);
|
|
771
|
+
for (let y = 0; y < bild.hoehe; y++) {
|
|
772
|
+
for (let x = 0; x < bild.breite; x++) {
|
|
773
|
+
if (bild.punkte[y * bild.breite + x] !== 1)
|
|
774
|
+
continue;
|
|
775
|
+
const i = y * byteJeZeile + (x >> 3);
|
|
776
|
+
daten[i] = daten[i] | (0x80 >> (x & 7));
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
return daten;
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Die Rasterzeilen als Base64 -- ohne Buffer, laeuft im Browser und in Node.
|
|
783
|
+
* Eine Stelle fuer ePOS-`<image>` und den Druckjob an den Server.
|
|
784
|
+
*/
|
|
785
|
+
export function rasterZeilenBase64(bild) {
|
|
786
|
+
const bytes = rasterZeilenBytes(bild);
|
|
787
|
+
let binaer = '';
|
|
788
|
+
for (let i = 0; i < bytes.length; i += 0x8000) {
|
|
789
|
+
binaer += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
|
|
790
|
+
}
|
|
791
|
+
return btoa(binaer);
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Der `GS v 0`-Kopf (Byte-Breite, Zeilenhoehe) -- die Rasterzeilen selbst
|
|
795
|
+
* haengt der Aufrufer an. Gemeinsame Rahmung fuer das Logo (`escPosRasterBild`)
|
|
796
|
+
* und den QR-Bildweg (`escPosQrRaster`): beide drucken dasselbe Bildkommando,
|
|
797
|
+
* nur mit unterschiedlichem Nachlauf (Zeilenvorschub ja/nein).
|
|
798
|
+
*/
|
|
799
|
+
function rasterBildKopf(breite, hoehe) {
|
|
800
|
+
const byteJeZeile = Math.ceil(breite / 8);
|
|
801
|
+
return [GS, 0x76, 0x30, 0x00, byteJeZeile & 0xff, (byteJeZeile >> 8) & 0xff, hoehe & 0xff, (hoehe >> 8) & 0xff];
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* Ein Rasterbild (`GS v 0`) -- das Firmenlogo am Bon.
|
|
805
|
+
*
|
|
806
|
+
* Anders als `escPosQrRaster` folgt KEIN Zeilenvorschub: `GS v 0` schiebt das
|
|
807
|
+
* Papier um die Bildhoehe, ein LF danach waere eine zusaetzliche Leerzeile,
|
|
808
|
+
* die Bildschirm und PDF nicht haben. Die Luft um das Logo kommt aus dem Blatt.
|
|
809
|
+
*/
|
|
810
|
+
export function escPosRasterBild(doc, bild, options = {}) {
|
|
811
|
+
// Masse pruefen, BEVOR gepackt wird: ein zu breites Bild soll nicht erst
|
|
812
|
+
// Speicher fuer seine Rasterzeilen belegen. `GS v 0` traegt die Hoehe in zwei
|
|
813
|
+
// Bytes (yL yH) -- ueber 65535 Punkte liefe sie still ueber und der Drucker
|
|
814
|
+
// laese den Rest des Bilds als Befehle.
|
|
815
|
+
if (bild.breite > QR_DRUCK_PUNKTE[doc.paperSize])
|
|
816
|
+
throw new Error('Rasterbild breiter als der Druckkopf');
|
|
817
|
+
if (bild.hoehe > 0xffff)
|
|
818
|
+
throw new Error('Rasterbild hoeher als 65535 Punkte');
|
|
819
|
+
const daten = rasterZeilenBytes(bild);
|
|
820
|
+
escPosSetStyles(doc, { align: options.align ?? 'center' });
|
|
821
|
+
anhaengen(doc, rasterBildKopf(bild.breite, bild.hoehe));
|
|
822
|
+
anhaengen(doc, daten);
|
|
823
|
+
if ((options.align ?? 'center') !== 'left') {
|
|
824
|
+
escPosSetStyles(doc, { align: 'left' });
|
|
825
|
+
}
|
|
826
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { type PosPaperSize, type PosAlign, type PosFont, type PosCutMode, type PosCodeTable, type PosTextSize, type QrSize, type QrCorrection, type QrMatrix, type PosStyles, type PosColumn, type EscPosOptions, type EscPosTextOptions, type EscPosHrOptions, type EscPosQrOptions, type EscPosQrRasterOptions, type EscPosDocument, createEscPosDocument, escPosBytes, escPosReset, escPosSetGlobalCodeTable, escPosSetGlobalFont, escPosSetStyles, escPosText, escPosEmptyLines, escPosFeed, escPosCut, escPosHr, escPosRow, escPosQrCode, escPosQrRaster, qrRasterPunkte, encodeEscPosText, qrCodeBytes, escPosMaxCharsPerLine, escPosWortzeilen, wortzeilenText, } from './escpos.js';
|
|
2
|
-
export { type QrModulGroesse, type QrGroesse, QR_MODUL_DECKEL, QR_RUHEZONE_MODULE, QR_MINDEST_PUNKTE, QR_AUSNAHME_PUNKTE, QR_HOECHST_PUNKTE, QR_DRUCK_PUNKTE, qrModulAnzahl, qrGroesseBerechnen, qrGroesseFuer, } from './qr-groesse.js';
|
|
1
|
+
export { type PosPaperSize, type PosAlign, type PosFont, type PosCutMode, type PosCodeTable, type PosTextSize, type QrSize, type QrCorrection, type QrMatrix, type PosStyles, type PosColumn, type EscPosOptions, type EscPosTextOptions, type EscPosHrOptions, type EscPosQrOptions, type EscPosQrRasterOptions, type EscPosDocument, createEscPosDocument, escPosBytes, escPosReset, escPosSetGlobalCodeTable, escPosSetGlobalFont, escPosSetStyles, escPosText, escPosEmptyLines, escPosFeed, escPosCut, escPosHr, escPosRow, escPosQrCode, escPosQrRaster, qrRasterPunkte, type RasterBild, rasterZeilenBytes, rasterZeilenBase64, escPosRasterBild, encodeEscPosText, qrCodeBytes, escPosMaxCharsPerLine, escPosWortzeilen, wortzeilenText, } from './escpos.js';
|
|
2
|
+
export { type QrModulGroesse, type QrGroesse, QR_MODUL_DECKEL, QR_RUHEZONE_MODULE, QR_MINDEST_PUNKTE, QR_AUSNAHME_PUNKTE, QR_HOECHST_PUNKTE, QR_DRUCK_PUNKTE, qrModulAnzahl, qrPasstInVersion, qrGroesseBerechnen, qrGroesseFuer, } from './qr-groesse.js';
|
|
3
3
|
export { escPosPrintableText } from './printable.js';
|
|
4
4
|
export { type UsbEndpointLike, type UsbAlternateLike, type UsbInterfaceLike, type UsbConfigurationLike, type UsbTransferOutResultLike, type UsbWriterLike, type UsbIdentityLike, type UsbDeviceLike, type UsbPrinterEndpoint, type UsbPrinterConnection, USB_VENDOR_EPSON, USB_CLASS_PRINTER, UsbTimeoutError, usbDeviceKey, usbFindPrinterEndpoint, usbWriteAll, usbConnectPrinter, usbPrint, usbDisconnect, } from './webusb.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createEscPosDocument, escPosBytes, escPosReset, escPosSetGlobalCodeTable, escPosSetGlobalFont, escPosSetStyles, escPosText, escPosEmptyLines, escPosFeed, escPosCut, escPosHr, escPosRow, escPosQrCode, escPosQrRaster, qrRasterPunkte, encodeEscPosText, qrCodeBytes, escPosMaxCharsPerLine, escPosWortzeilen, wortzeilenText, } from './escpos.js';
|
|
2
|
-
export { QR_MODUL_DECKEL, QR_RUHEZONE_MODULE, QR_MINDEST_PUNKTE, QR_AUSNAHME_PUNKTE, QR_HOECHST_PUNKTE, QR_DRUCK_PUNKTE, qrModulAnzahl, qrGroesseBerechnen, qrGroesseFuer, } from './qr-groesse.js';
|
|
1
|
+
export { createEscPosDocument, escPosBytes, escPosReset, escPosSetGlobalCodeTable, escPosSetGlobalFont, escPosSetStyles, escPosText, escPosEmptyLines, escPosFeed, escPosCut, escPosHr, escPosRow, escPosQrCode, escPosQrRaster, qrRasterPunkte, rasterZeilenBytes, rasterZeilenBase64, escPosRasterBild, encodeEscPosText, qrCodeBytes, escPosMaxCharsPerLine, escPosWortzeilen, wortzeilenText, } from './escpos.js';
|
|
2
|
+
export { QR_MODUL_DECKEL, QR_RUHEZONE_MODULE, QR_MINDEST_PUNKTE, QR_AUSNAHME_PUNKTE, QR_HOECHST_PUNKTE, QR_DRUCK_PUNKTE, qrModulAnzahl, qrPasstInVersion, qrGroesseBerechnen, qrGroesseFuer, } from './qr-groesse.js';
|
|
3
3
|
export { escPosPrintableText } from './printable.js';
|
|
4
4
|
export { USB_VENDOR_EPSON, USB_CLASS_PRINTER, UsbTimeoutError, usbDeviceKey, usbFindPrinterEndpoint, usbWriteAll, usbConnectPrinter, usbPrint, usbDisconnect, } from './webusb.js';
|