@kreiseck/kasseneck-api 0.13.1 → 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.
Files changed (172) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +127 -21
  3. package/dist/cjs/client/auth.d.ts +4 -4
  4. package/dist/cjs/client/auth.js +3 -3
  5. package/dist/cjs/client/cashregisters.d.ts +1 -1
  6. package/dist/cjs/client/cashregisters.js +1 -1
  7. package/dist/cjs/client/errors.d.ts +1 -1
  8. package/dist/cjs/client/errors.js +2 -2
  9. package/dist/cjs/client/receipts.d.ts +8 -1
  10. package/dist/cjs/client/receipts.js +2 -1
  11. package/dist/cjs/client/transport.d.ts +1 -1
  12. package/dist/cjs/client/transport.js +2 -2
  13. package/dist/cjs/kasse/drucker.d.ts +5 -0
  14. package/dist/cjs/kasse/drucker.js +9 -0
  15. package/dist/cjs/kasse/settings.js +5 -2
  16. package/dist/cjs/models/cashregister.d.ts +2 -2
  17. package/dist/cjs/models/receipt-company.d.ts +1 -1
  18. package/dist/cjs/printing/escpos.d.ts +38 -4
  19. package/dist/cjs/printing/escpos.js +87 -15
  20. package/dist/cjs/printing/index.d.ts +2 -2
  21. package/dist/cjs/printing/index.js +5 -1
  22. package/dist/cjs/printing/qr-groesse.d.ts +26 -21
  23. package/dist/cjs/printing/qr-groesse.js +22 -8
  24. package/dist/cjs/react/index.d.ts +53 -0
  25. package/dist/cjs/react/index.js +81 -0
  26. package/dist/cjs/receipt/bild.d.ts +14 -0
  27. package/dist/cjs/receipt/bild.js +65 -0
  28. package/dist/cjs/receipt/blatt.d.ts +107 -0
  29. package/dist/cjs/receipt/blatt.js +137 -0
  30. package/dist/cjs/receipt/epos.d.ts +19 -8
  31. package/dist/cjs/receipt/epos.js +39 -20
  32. package/dist/cjs/receipt/grid.d.ts +1 -1
  33. package/dist/cjs/receipt/grid.js +9 -1
  34. package/dist/cjs/receipt/index.d.ts +4 -2
  35. package/dist/cjs/receipt/index.js +17 -1
  36. package/dist/cjs/receipt/layout-escpos.d.ts +31 -3
  37. package/dist/cjs/receipt/layout-escpos.js +58 -18
  38. package/dist/cjs/register/index.d.ts +1 -1
  39. package/dist/cjs/register/index.js +1 -1
  40. package/dist/cjs/register/pairing.d.ts +2 -2
  41. package/dist/esm/client/auth.d.ts +4 -4
  42. package/dist/esm/client/auth.js +3 -3
  43. package/dist/esm/client/cashregisters.d.ts +1 -1
  44. package/dist/esm/client/cashregisters.js +1 -1
  45. package/dist/esm/client/errors.d.ts +1 -1
  46. package/dist/esm/client/errors.js +2 -2
  47. package/dist/esm/client/receipts.d.ts +8 -1
  48. package/dist/esm/client/receipts.js +2 -1
  49. package/dist/esm/client/transport.d.ts +1 -1
  50. package/dist/esm/client/transport.js +2 -2
  51. package/dist/esm/kasse/drucker.d.ts +5 -0
  52. package/dist/esm/kasse/drucker.js +9 -0
  53. package/dist/esm/kasse/settings.js +5 -2
  54. package/dist/esm/models/cashregister.d.ts +2 -2
  55. package/dist/esm/models/receipt-company.d.ts +1 -1
  56. package/dist/esm/printing/escpos.d.ts +38 -4
  57. package/dist/esm/printing/escpos.js +84 -15
  58. package/dist/esm/printing/index.d.ts +2 -2
  59. package/dist/esm/printing/index.js +2 -2
  60. package/dist/esm/printing/qr-groesse.d.ts +26 -21
  61. package/dist/esm/printing/qr-groesse.js +21 -8
  62. package/dist/esm/react/index.d.ts +53 -0
  63. package/dist/esm/react/index.js +80 -1
  64. package/dist/esm/receipt/bild.d.ts +14 -0
  65. package/dist/esm/receipt/bild.js +62 -0
  66. package/dist/esm/receipt/blatt.d.ts +107 -0
  67. package/dist/esm/receipt/blatt.js +128 -0
  68. package/dist/esm/receipt/epos.d.ts +19 -8
  69. package/dist/esm/receipt/epos.js +40 -22
  70. package/dist/esm/receipt/grid.d.ts +1 -1
  71. package/dist/esm/receipt/grid.js +9 -1
  72. package/dist/esm/receipt/index.d.ts +4 -2
  73. package/dist/esm/receipt/index.js +4 -2
  74. package/dist/esm/receipt/layout-escpos.d.ts +31 -3
  75. package/dist/esm/receipt/layout-escpos.js +58 -20
  76. package/dist/esm/register/index.d.ts +1 -1
  77. package/dist/esm/register/index.js +1 -1
  78. package/dist/esm/register/pairing.d.ts +2 -2
  79. package/fixtures/erwartet/karte-eigener.blatt32.json +159 -0
  80. package/fixtures/erwartet/karte-eigener.blatt48.json +159 -0
  81. package/fixtures/erwartet/karte-gptom-ios.blatt32.json +231 -0
  82. package/fixtures/erwartet/karte-gptom-ios.blatt48.json +231 -0
  83. package/fixtures/erwartet/karte-gptom.blatt32.json +231 -0
  84. package/fixtures/erwartet/karte-gptom.blatt48.json +231 -0
  85. package/fixtures/erwartet/karte-hobex-cloud.blatt32.json +201 -0
  86. package/fixtures/erwartet/karte-hobex-cloud.blatt48.json +201 -0
  87. package/fixtures/erwartet/karte-hobex-hps.blatt32.json +225 -0
  88. package/fixtures/erwartet/karte-hobex-hps.blatt48.json +225 -0
  89. package/fixtures/erwartet/karte-mypos.blatt32.json +255 -0
  90. package/fixtures/erwartet/karte-mypos.blatt48.json +243 -0
  91. package/fixtures/erwartet/karte-stripe-eps.blatt32.json +195 -0
  92. package/fixtures/erwartet/karte-stripe-eps.blatt48.json +195 -0
  93. package/fixtures/erwartet/karte-stripe.blatt32.json +213 -0
  94. package/fixtures/erwartet/karte-stripe.blatt48.json +213 -0
  95. package/fixtures/erwartet/karte-sumup.blatt32.json +219 -0
  96. package/fixtures/erwartet/karte-sumup.blatt48.json +207 -0
  97. package/fixtures/erwartet/langer-artikelname.blatt32.json +177 -0
  98. package/fixtures/erwartet/langer-artikelname.blatt48.json +171 -0
  99. package/fixtures/erwartet/logo-probe-hoch.raster32.txt +120 -0
  100. package/fixtures/erwartet/logo-probe.raster32.txt +54 -0
  101. package/fixtures/erwartet/null-ausfall.blatt32.json +207 -0
  102. package/fixtures/erwartet/null-ausfall.blatt48.json +189 -0
  103. package/fixtures/erwartet/null-ausfall.grid32.txt +2 -0
  104. package/fixtures/erwartet/null-ausfall.grid48.txt +2 -0
  105. package/fixtures/erwartet/null-jahr.blatt32.json +213 -0
  106. package/fixtures/erwartet/null-jahr.blatt48.json +189 -0
  107. package/fixtures/erwartet/null-jahr.grid32.txt +2 -0
  108. package/fixtures/erwartet/null-jahr.grid48.txt +2 -0
  109. package/fixtures/erwartet/null-monat.blatt32.json +207 -0
  110. package/fixtures/erwartet/null-monat.blatt48.json +189 -0
  111. package/fixtures/erwartet/null-monat.grid32.txt +2 -0
  112. package/fixtures/erwartet/null-monat.grid48.txt +2 -0
  113. package/fixtures/erwartet/null-pruef.blatt32.json +207 -0
  114. package/fixtures/erwartet/null-pruef.blatt48.json +189 -0
  115. package/fixtures/erwartet/null-pruef.grid32.txt +2 -0
  116. package/fixtures/erwartet/null-pruef.grid48.txt +2 -0
  117. package/fixtures/erwartet/null-schluss.blatt32.json +207 -0
  118. package/fixtures/erwartet/null-schluss.blatt48.json +189 -0
  119. package/fixtures/erwartet/null-schluss.grid32.txt +2 -0
  120. package/fixtures/erwartet/null-schluss.grid48.txt +2 -0
  121. package/fixtures/erwartet/null-start.blatt32.json +207 -0
  122. package/fixtures/erwartet/null-start.blatt48.json +189 -0
  123. package/fixtures/erwartet/null-start.grid32.txt +2 -0
  124. package/fixtures/erwartet/null-start.grid48.txt +2 -0
  125. package/fixtures/erwartet/rabatt-chef-trinkgeld.blatt32.json +213 -0
  126. package/fixtures/erwartet/rabatt-chef-trinkgeld.blatt48.json +207 -0
  127. package/fixtures/erwartet/rabatt-einfach.blatt32.json +183 -0
  128. package/fixtures/erwartet/rabatt-einfach.blatt48.json +177 -0
  129. package/fixtures/erwartet/rabatt-trinkgeld.blatt32.json +213 -0
  130. package/fixtures/erwartet/rabatt-trinkgeld.blatt48.json +207 -0
  131. package/fixtures/erwartet/rabatt-wertgutschein.blatt32.json +219 -0
  132. package/fixtures/erwartet/rabatt-wertgutschein.blatt48.json +213 -0
  133. package/fixtures/erwartet/rabattzeilen.blatt32.json +201 -0
  134. package/fixtures/erwartet/rabattzeilen.blatt48.json +195 -0
  135. package/fixtures/erwartet/signaturausfall-verkauf.blatt32.json +195 -0
  136. package/fixtures/erwartet/signaturausfall-verkauf.blatt48.json +183 -0
  137. package/fixtures/erwartet/storno-rabatt.blatt32.json +249 -0
  138. package/fixtures/erwartet/storno-rabatt.blatt48.json +237 -0
  139. package/fixtures/erwartet/storno-rabatt.grid32.txt +2 -0
  140. package/fixtures/erwartet/storno-rabatt.grid48.txt +2 -0
  141. package/fixtures/erwartet/storno-teil.blatt32.json +207 -0
  142. package/fixtures/erwartet/storno-teil.blatt48.json +201 -0
  143. package/fixtures/erwartet/storno-teil.grid32.txt +2 -0
  144. package/fixtures/erwartet/storno-teil.grid48.txt +2 -0
  145. package/fixtures/erwartet/storno-voll.blatt32.json +219 -0
  146. package/fixtures/erwartet/storno-voll.blatt48.json +213 -0
  147. package/fixtures/erwartet/storno-voll.grid32.txt +2 -0
  148. package/fixtures/erwartet/storno-voll.grid48.txt +2 -0
  149. package/fixtures/erwartet/testkasse-verkauf.blatt32.json +225 -0
  150. package/fixtures/erwartet/testkasse-verkauf.blatt48.json +219 -0
  151. package/fixtures/erwartet/testkasse-verkauf.grid32.txt +5 -1
  152. package/fixtures/erwartet/testkasse-verkauf.grid48.txt +5 -1
  153. package/fixtures/erwartet/testsignatur-verkauf.blatt32.json +237 -0
  154. package/fixtures/erwartet/testsignatur-verkauf.blatt48.json +219 -0
  155. package/fixtures/erwartet/testsignatur-verkauf.grid32.txt +5 -1
  156. package/fixtures/erwartet/testsignatur-verkauf.grid48.txt +5 -1
  157. package/fixtures/erwartet/training.blatt32.json +237 -0
  158. package/fixtures/erwartet/training.blatt48.json +219 -0
  159. package/fixtures/erwartet/training.grid32.txt +2 -0
  160. package/fixtures/erwartet/training.grid48.txt +2 -0
  161. package/fixtures/erwartet/verkauf-bar.blatt32.json +177 -0
  162. package/fixtures/erwartet/verkauf-bar.blatt48.json +171 -0
  163. package/fixtures/erwartet/verkauf-karte.blatt32.json +177 -0
  164. package/fixtures/erwartet/verkauf-karte.blatt48.json +171 -0
  165. package/fixtures/erwartet/verkauf-kleinunternehmer.blatt32.json +183 -0
  166. package/fixtures/erwartet/verkauf-kleinunternehmer.blatt48.json +177 -0
  167. package/fixtures/hobex-hps-codes.json +1 -1
  168. package/fixtures/kasse-settings-standard.json +1 -1
  169. package/fixtures/kasse-texte.json +1 -1
  170. package/fixtures/manifest.json +109 -43
  171. package/fixtures/oberflaeche.json +1 -1
  172. package/package.json +20 -5
@@ -0,0 +1,107 @@
1
+ import type { PosPaperSize } from '../printing/escpos.js';
2
+ import { type QrModulGroesse } from '../printing/index.js';
3
+ import type { ReceiptLayout } from './layout.js';
4
+ /**
5
+ * Das Beleg-Blatt: die vollstaendige Folge dessen, was auf dem Papier steht --
6
+ * Rasterzeilen, Firmenlogo, QR und Marke, mit Groessen als Anteil der
7
+ * Blattbreite und in Zeilen.
8
+ *
9
+ * Bis 0.13 setzte jeder Zeichner das Raster selbst zusammen und entschied
10
+ * Logo-Ort, Logo-Groesse, Rahmen und QR-Groesse fuer sich. Heraus kamen
11
+ * fuenf verschiedene Belege (Panel: Logo ueber dem Testkassen-Rahmen, PDF:
12
+ * Logo auf dem Rahmen, App: kein Logo). Hier steht das jetzt einmal.
13
+ *
14
+ * Masseinheit ist der Druckkopf (Epson Font A, 203 dpi): ein Zeichen ist 12
15
+ * Punkte breit, eine Zeile 24 Punkte hoch. Am Bildschirm ist eine Zeile `2ch`,
16
+ * im PDF zwei Zeichenbreiten.
17
+ */
18
+ export type LogoStufe = 'S' | 'M' | 'L' | 'XL';
19
+ /** Kasten je Stufe: Anteil der Blattbreite und Hoehe in Zeilen (Werte der Web-Kasse). */
20
+ export declare const LOGO_STUFEN: Readonly<Record<LogoStufe, {
21
+ readonly breiteAnteil: number;
22
+ readonly hoeheZeilen: number;
23
+ }>>;
24
+ export declare const PUNKTE_JE_ZEICHEN = 12;
25
+ export declare const PUNKTE_JE_ZEILE = 24;
26
+ /** Die Marke am Belegende (Konto-Flag `kreiseck_logo`) -- Text, damit jeder Weg sie gleich setzt. */
27
+ export declare const MARKE_TEXT = "erstellt mit Kasseneck";
28
+ export interface BlattLogo {
29
+ stufe: LogoStufe;
30
+ /** Pixelmass des Originalbilds -- ohne das laesst sich nicht einpassen. */
31
+ pxBreite: number;
32
+ pxHoehe: number;
33
+ }
34
+ export interface LogoMass {
35
+ /** Anteil der Blattbreite (0..1). */
36
+ breiteAnteil: number;
37
+ /** Hoehe in Zeilen (nicht ganzzahlig). */
38
+ hoeheZeilen: number;
39
+ }
40
+ export type BlattBlock = {
41
+ readonly art: 'zeile';
42
+ readonly text: string;
43
+ readonly fett: boolean;
44
+ readonly leer: boolean;
45
+ } | {
46
+ readonly art: 'logo';
47
+ readonly breiteAnteil: number;
48
+ readonly hoeheZeilen: number;
49
+ } | {
50
+ readonly art: 'qr';
51
+ readonly nutzlast: string;
52
+ readonly breiteAnteil: number;
53
+ };
54
+ export interface BelegBlatt {
55
+ readonly zeichen: number;
56
+ readonly bloecke: readonly BlattBlock[];
57
+ }
58
+ export interface BelegBlattOptionen {
59
+ /** Zeichen je Zeile; Vorgabe nach `layout.paperSize` (32/48). */
60
+ zeichen?: number;
61
+ /** Firmenlogo; ohne Angabe kein Logo-Block. */
62
+ logo?: BlattLogo | null;
63
+ /** "erstellt mit Kasseneck" am Ende. */
64
+ marke?: boolean;
65
+ /** Geraete-Einstellung fuer die QR-Modulgroesse; Vorgabe `auto` (hoechstens 6 Punkte je Modul) — wie die Druckwege. */
66
+ qrGroesse?: QrModulGroesse;
67
+ }
68
+ /**
69
+ * 32 Zeichen sind 58 mm, 48 sind 80 mm; andere Breiten behalten das Papier des
70
+ * Layouts. Der QR-Anteil (`qrBlattAnteil`) wird dann fuer die Kopfbreite
71
+ * DIESES Papiers gerechnet, nicht fuer die gewaehlte Zeichenzahl.
72
+ */
73
+ export declare function papierFuerZeichen(zeichen: number, vorgabe: PosPaperSize): PosPaperSize;
74
+ /**
75
+ * Obergrenze der Logo-Pixel, die der Bildschirm noch anzeigen darf -- exakt
76
+ * dieselbe Grenze wie im Druck-Kit (`LOGO_PIXEL_MAX` in `druck-logo.ts`):
77
+ * Bon und ePOS lehnen ein Logo ueber 4096x4096px schon beim Rastern ab (ein
78
+ * grosses Bild blockiert das Geraet). Ohne diese Grenze wuerde der
79
+ * Bildschirm ein Logo zeigen, das der Bon nie druckt -- Bildschirm und
80
+ * Papier waeren sich uneins, genau das soll das Beleg-Blatt verhindern.
81
+ */
82
+ export declare const LOGO_PIXEL_MAX = 4096;
83
+ /** Reine Pruefung, ob ein Logo dieser Pixelmasse noch angezeigt/gedruckt werden darf. */
84
+ export declare function logoPixelZulaessig(breite: number, hoehe: number): boolean;
85
+ /**
86
+ * Das Logo in den Kasten seiner Stufe einpassen -- **nie hochrechnen**: ein
87
+ * Bildpixel wird hoechstens ein Druckpunkt. Ein kleines Logo bleibt klein,
88
+ * statt am Bon verwaschen zu werden (so hielten es PDF und Web-Kasse schon).
89
+ */
90
+ export declare function logoMass(logo: BlattLogo, zeichen: number): LogoMass;
91
+ /** Das Mass in ganzen Druckpunkten -- so gross muss das Rasterbild fuer den Bon sein. */
92
+ export declare function logoRasterMass(mass: LogoMass, zeichen: number): {
93
+ breite: number;
94
+ hoehe: number;
95
+ };
96
+ /**
97
+ * Anteil der Blattbreite, den der QR am Drucker einnimmt -- dieselbe Rechnung
98
+ * wie der Druckweg (nativ, sonst der Bildweg). Bildschirm und PDF zeigen den
99
+ * QR in genau dieser Groesse. Leere Nutzlast: 0 (kein Symbol).
100
+ *
101
+ * Der Kasten **schliesst die Ruhezone von 4 Modulen je Seite ein** und setzt
102
+ * Fehlerkorrektur M voraus. Ein Zeichner (`renderQr`, PDF) muss das Symbol
103
+ * darum mit Fehlerkorrektur M und einer Ruhezone von 4 Modulen zeichnen, die
104
+ * den Kasten ganz ausfuellt -- sonst stimmt die Modulgroesse nicht mit dem Bon.
105
+ */
106
+ export declare function qrBlattAnteil(nutzlast: string, papier: PosPaperSize, groesse?: QrModulGroesse): number;
107
+ export declare function belegBlatt(layout: ReceiptLayout, optionen?: BelegBlattOptionen): BelegBlatt;
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LOGO_PIXEL_MAX = exports.MARKE_TEXT = exports.PUNKTE_JE_ZEILE = exports.PUNKTE_JE_ZEICHEN = exports.LOGO_STUFEN = void 0;
4
+ exports.papierFuerZeichen = papierFuerZeichen;
5
+ exports.logoPixelZulaessig = logoPixelZulaessig;
6
+ exports.logoMass = logoMass;
7
+ exports.logoRasterMass = logoRasterMass;
8
+ exports.qrBlattAnteil = qrBlattAnteil;
9
+ exports.belegBlatt = belegBlatt;
10
+ const index_js_1 = require("../printing/index.js");
11
+ const grid_js_1 = require("./grid.js");
12
+ /** Kasten je Stufe: Anteil der Blattbreite und Hoehe in Zeilen (Werte der Web-Kasse). */
13
+ exports.LOGO_STUFEN = {
14
+ S: { breiteAnteil: 0.42, hoeheZeilen: 5 },
15
+ M: { breiteAnteil: 0.62, hoeheZeilen: 8 },
16
+ L: { breiteAnteil: 0.8, hoeheZeilen: 12 },
17
+ XL: { breiteAnteil: 0.94, hoeheZeilen: 16 },
18
+ };
19
+ exports.PUNKTE_JE_ZEICHEN = 12;
20
+ exports.PUNKTE_JE_ZEILE = 24;
21
+ /** Die Marke am Belegende (Konto-Flag `kreiseck_logo`) -- Text, damit jeder Weg sie gleich setzt. */
22
+ exports.MARKE_TEXT = 'erstellt mit Kasseneck';
23
+ /**
24
+ * 32 Zeichen sind 58 mm, 48 sind 80 mm; andere Breiten behalten das Papier des
25
+ * Layouts. Der QR-Anteil (`qrBlattAnteil`) wird dann fuer die Kopfbreite
26
+ * DIESES Papiers gerechnet, nicht fuer die gewaehlte Zeichenzahl.
27
+ */
28
+ function papierFuerZeichen(zeichen, vorgabe) {
29
+ if (zeichen === grid_js_1.ZEICHEN_JE_PAPIER.mm58)
30
+ return 'mm58';
31
+ if (zeichen === grid_js_1.ZEICHEN_JE_PAPIER.mm80)
32
+ return 'mm80';
33
+ return vorgabe;
34
+ }
35
+ /**
36
+ * Obergrenze der Logo-Pixel, die der Bildschirm noch anzeigen darf -- exakt
37
+ * dieselbe Grenze wie im Druck-Kit (`LOGO_PIXEL_MAX` in `druck-logo.ts`):
38
+ * Bon und ePOS lehnen ein Logo ueber 4096x4096px schon beim Rastern ab (ein
39
+ * grosses Bild blockiert das Geraet). Ohne diese Grenze wuerde der
40
+ * Bildschirm ein Logo zeigen, das der Bon nie druckt -- Bildschirm und
41
+ * Papier waeren sich uneins, genau das soll das Beleg-Blatt verhindern.
42
+ */
43
+ exports.LOGO_PIXEL_MAX = 4096;
44
+ /** Reine Pruefung, ob ein Logo dieser Pixelmasse noch angezeigt/gedruckt werden darf. */
45
+ function logoPixelZulaessig(breite, hoehe) {
46
+ return breite > 0 && hoehe > 0 && breite <= exports.LOGO_PIXEL_MAX && hoehe <= exports.LOGO_PIXEL_MAX;
47
+ }
48
+ /**
49
+ * Das Logo in den Kasten seiner Stufe einpassen -- **nie hochrechnen**: ein
50
+ * Bildpixel wird hoechstens ein Druckpunkt. Ein kleines Logo bleibt klein,
51
+ * statt am Bon verwaschen zu werden (so hielten es PDF und Web-Kasse schon).
52
+ */
53
+ function logoMass(logo, zeichen) {
54
+ if (!(logo.pxBreite > 0) || !(logo.pxHoehe > 0))
55
+ throw new Error('Logo ohne Pixelmass');
56
+ const stufe = exports.LOGO_STUFEN[logo.stufe];
57
+ if (stufe === undefined)
58
+ throw new Error(`Unbekannte Logo-Stufe: ${String(logo.stufe)}`);
59
+ const blattPunkte = zeichen * exports.PUNKTE_JE_ZEICHEN;
60
+ const faktor = Math.min((stufe.breiteAnteil * blattPunkte) / logo.pxBreite, (stufe.hoeheZeilen * exports.PUNKTE_JE_ZEILE) / logo.pxHoehe, 1);
61
+ return {
62
+ breiteAnteil: (logo.pxBreite * faktor) / blattPunkte,
63
+ hoeheZeilen: (logo.pxHoehe * faktor) / exports.PUNKTE_JE_ZEILE,
64
+ };
65
+ }
66
+ /** Das Mass in ganzen Druckpunkten -- so gross muss das Rasterbild fuer den Bon sein. */
67
+ function logoRasterMass(mass, zeichen) {
68
+ return {
69
+ breite: Math.max(1, Math.round(mass.breiteAnteil * zeichen * exports.PUNKTE_JE_ZEICHEN)),
70
+ hoehe: Math.max(1, Math.round(mass.hoeheZeilen * exports.PUNKTE_JE_ZEILE)),
71
+ };
72
+ }
73
+ /**
74
+ * Anteil der Blattbreite, den der QR am Drucker einnimmt -- dieselbe Rechnung
75
+ * wie der Druckweg (nativ, sonst der Bildweg). Bildschirm und PDF zeigen den
76
+ * QR in genau dieser Groesse. Leere Nutzlast: 0 (kein Symbol).
77
+ *
78
+ * Der Kasten **schliesst die Ruhezone von 4 Modulen je Seite ein** und setzt
79
+ * Fehlerkorrektur M voraus. Ein Zeichner (`renderQr`, PDF) muss das Symbol
80
+ * darum mit Fehlerkorrektur M und einer Ruhezone von 4 Modulen zeichnen, die
81
+ * den Kasten ganz ausfuellt -- sonst stimmt die Modulgroesse nicht mit dem Bon.
82
+ */
83
+ function qrBlattAnteil(nutzlast, papier, groesse = 'auto') {
84
+ if (nutzlast === '')
85
+ return 0;
86
+ // Ein Inhalt, der in keine QR-Version passt (Fehlerkorrektur M, hoechstens
87
+ // 2331 Byte), wuerde hier `qrGroesseFuer` -> `qrModulAnzahl` zum Werfen
88
+ // bringen -- und riss damit jeden Zeichner mit, der das Blatt baut
89
+ // (Bildschirm, Bon, PDF). 0, wie bei leerer Nutzlast: der Beleg steht ohne
90
+ // QR, statt gar nicht zu stehen. `qrModulAnzahl` selbst wirft weiter -- wer
91
+ // es ausserhalb des Blatts aufruft, soll den Fehler sehen.
92
+ if (!(0, index_js_1.qrPasstInVersion)(nutzlast))
93
+ return 0;
94
+ const papierPunkte = index_js_1.QR_DRUCK_PUNKTE[papier];
95
+ const mass = (0, index_js_1.qrGroesseFuer)({ nutzlast, papierbreitePunkte: papierPunkte, groesse });
96
+ if (mass.passt)
97
+ return mass.breitePunkte / papierPunkte;
98
+ return ((mass.module + 2 * index_js_1.QR_RUHEZONE_MODULE) * (0, index_js_1.qrRasterPunkte)(papier, mass.module, { groesse })) / papierPunkte;
99
+ }
100
+ function zentriert(text, zeichen) {
101
+ const t = text.length > zeichen ? text.slice(0, zeichen) : text;
102
+ const links = Math.floor((zeichen - t.length) / 2);
103
+ return ' '.repeat(links) + t + ' '.repeat(zeichen - t.length - links);
104
+ }
105
+ function belegBlatt(layout, optionen = {}) {
106
+ const grid = (0, grid_js_1.renderReceiptGrid)(layout, optionen.zeichen === undefined ? {} : { zeichen: optionen.zeichen });
107
+ const zeichen = grid.zeichen;
108
+ const papier = papierFuerZeichen(zeichen, layout.paperSize);
109
+ const qrGroesse = optionen.qrGroesse ?? 'auto';
110
+ const leerzeile = { art: 'zeile', text: ' '.repeat(zeichen), fett: false, leer: true };
111
+ const block = (z) => z.kind === 'qr'
112
+ ? { art: 'qr', nutzlast: z.qr ?? '', breiteAnteil: qrBlattAnteil(z.qr ?? '', papier, qrGroesse) }
113
+ : { art: 'zeile', text: z.text, fett: z.bold, leer: z.kind === 'space' };
114
+ const bloecke = [];
115
+ let i = 0;
116
+ if (optionen.logo) {
117
+ // Fuehrende Aufdrucke (Testkasse, Testsignatur) bleiben ganz oben: wer den
118
+ // Beleg sieht, sieht zuerst, dass er nicht gilt.
119
+ while (i < grid.lines.length && grid.lines[i].kind === 'banner') {
120
+ bloecke.push(block(grid.lines[i]));
121
+ i += 1;
122
+ }
123
+ // Die Leerzeilen gehoeren zum Vertrag: kein Zeichner kann das Logo an einen
124
+ // Rahmen oder an den Firmennamen kleben.
125
+ if (i > 0)
126
+ bloecke.push(leerzeile);
127
+ bloecke.push({ art: 'logo', ...logoMass(optionen.logo, zeichen) });
128
+ bloecke.push(leerzeile);
129
+ }
130
+ for (; i < grid.lines.length; i += 1)
131
+ bloecke.push(block(grid.lines[i]));
132
+ if (optionen.marke === true) {
133
+ bloecke.push(leerzeile);
134
+ bloecke.push({ art: 'zeile', text: zentriert(exports.MARKE_TEXT, zeichen), fett: false, leer: false });
135
+ }
136
+ return { zeichen, bloecke };
137
+ }
@@ -1,11 +1,12 @@
1
1
  import type { ReceiptLayout } from './layout.js';
2
2
  import type { PosPaperSize } from '../printing/escpos.js';
3
- import { type QrModulGroesse } from '../printing/index.js';
3
+ import { type QrModulGroesse, type RasterBild } from '../printing/index.js';
4
+ import { type DruckLogo } from './layout-escpos.js';
4
5
  /**
5
6
  * ePOS-Print XML (Epson TM-Drucker: Server Direct Print, ePOS-Print ueber
6
7
  * HTTP) -- **aus dem Zeichenraster**: jede Rasterzeile wird eine <text>-Zeile
7
- * mit exakt N Zeichen und Zeilenumbruch, Aufdrucke doppelt hoch (Warnungen
8
- * invers), QR als <symbol>, Leerraum als <feed>, am Ende Schnitt. Kein
8
+ * mit exakt N Zeichen und Zeilenumbruch, Aufdrucke als Rahmen aus
9
+ * Rasterzeilen, QR als <symbol>, Leerraum als <feed>, am Ende Schnitt. Kein
9
10
  * eigenes Setzen -- was Bildschirm, ESC/POS und PDF zeigen, druckt der Epson
10
11
  * Zeile fuer Zeile genauso.
11
12
  *
@@ -22,16 +23,20 @@ export interface EposPrintXmlOptions {
22
23
  */
23
24
  qrBreite?: number;
24
25
  /**
25
- * Deckel fuer die gerechnete QR-Modulgroesse; Vorgabe `mittel`.
26
+ * Deckel fuer die gerechnete QR-Modulgroesse; Vorgabe `auto` (hoechstens 6
27
+ * Punkte je Modul) -- wie ESC/POS, Blatt und der Flutter-Zwilling.
26
28
  *
27
- * Warum `mittel` und nicht `auto`: `auto` deckelt beim Bestandswert des
28
- * **ESC/POS**-Befehls dieses Pakets (4), dieser Weg druckt aber seit jeher
29
- * mit 6. Die Vorgabe nennt den Bestandswert dieses Wegs also ausdruecklich,
30
- * damit ohne Wahl kein Byte anders herauskommt.
29
+ * Bis 0.13 stand hier `mittel`, weil `auto` damals beim ESC/POS-Wert 4
30
+ * deckelte und dieser Weg seit jeher mit 6 druckt. Seit `auto` ueberall 6
31
+ * heisst, ist das derselbe Wert: ohne Wahl kommt kein Byte anders heraus.
31
32
  */
32
33
  qrGroesse?: QrModulGroesse;
33
34
  /** Papierschnitt am Ende, Vorgabe true. */
34
35
  cut?: boolean;
36
+ /** Firmenlogo; ohne Angabe kein Logo. */
37
+ logo?: DruckLogo | null;
38
+ /** "erstellt mit Kasseneck" am Ende. */
39
+ marke?: boolean;
35
40
  }
36
41
  /**
37
42
  * Das XML **samt** dem, was dem QR unterwegs zugestossen ist -- dieselbe
@@ -45,6 +50,8 @@ export interface EposPrintErgebnis {
45
50
  qrAusweich: string | null;
46
51
  }
47
52
  export declare function eposXmlEscape(text: string): string;
53
+ /** Ein Rasterbild als ePOS-`<image>` (einfarbig, Punktmass, Rasterzeilen Base64). */
54
+ export declare function eposBildXml(bild: RasterBild): string;
48
55
  /** Nur das XML; wer die QR-Meldungen braucht, nimmt [eposPrintXmlErgebnis]. */
49
56
  export declare function eposPrintXml(layout: ReceiptLayout, options?: EposPrintXmlOptions): string;
50
57
  /**
@@ -77,6 +84,10 @@ export interface EposDirectOptions {
77
84
  qrBreite?: number;
78
85
  /** Deckel fuer die gerechnete QR-Modulgroesse; siehe [EposPrintXmlOptions.qrGroesse]. */
79
86
  qrGroesse?: QrModulGroesse;
87
+ /** Firmenlogo; ohne Angabe kein Logo. */
88
+ logo?: DruckLogo | null;
89
+ /** "erstellt mit Kasseneck" am Ende. */
90
+ marke?: boolean;
80
91
  timeoutMs?: number;
81
92
  }
82
93
  export interface EposResponse {
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EposConnectionError = void 0;
4
4
  exports.eposXmlEscape = eposXmlEscape;
5
+ exports.eposBildXml = eposBildXml;
5
6
  exports.eposPrintXml = eposPrintXml;
6
7
  exports.eposPrintXmlErgebnis = eposPrintXmlErgebnis;
7
8
  exports.eposServiceUrl = eposServiceUrl;
@@ -11,9 +12,14 @@ exports.eposDirectPrint = eposDirectPrint;
11
12
  exports.eposDirectStatus = eposDirectStatus;
12
13
  const index_js_1 = require("../printing/index.js");
13
14
  const grid_js_1 = require("./grid.js");
15
+ const layout_escpos_js_1 = require("./layout-escpos.js");
14
16
  function eposXmlEscape(text) {
15
17
  return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
16
18
  }
19
+ /** Ein Rasterbild als ePOS-`<image>` (einfarbig, Punktmass, Rasterzeilen Base64). */
20
+ function eposBildXml(bild) {
21
+ return `<image width="${bild.breite}" height="${bild.hoehe}" color="color_1" mode="mono">${(0, index_js_1.rasterZeilenBase64)(bild)}</image>`;
22
+ }
17
23
  const NS = 'http://www.epson-pos.com/schemas/2011/03/epos-print';
18
24
  /** Nur das XML; wer die QR-Meldungen braucht, nimmt [eposPrintXmlErgebnis]. */
19
25
  function eposPrintXml(layout, options = {}) {
@@ -30,8 +36,9 @@ function eposPrintXml(layout, options = {}) {
30
36
  * laesst es weg; genau daran fehlte am echten Beleg der QR.
31
37
  */
32
38
  function eposPrintXmlErgebnis(layout, options = {}) {
33
- const grid = (0, grid_js_1.renderReceiptGrid)(layout, { zeichen: options.zeichen ?? grid_js_1.ZEICHEN_JE_PAPIER[layout.paperSize] });
34
- const deckel = options.qrGroesse ?? 'mittel';
39
+ const zeichen = options.zeichen ?? grid_js_1.ZEICHEN_JE_PAPIER[layout.paperSize];
40
+ const deckel = options.qrGroesse ?? 'auto';
41
+ const blatt = (0, layout_escpos_js_1.blattFuerDruck)(layout, { zeichen, logo: options.logo, marke: options.marke, qrGroesse: deckel });
35
42
  const fest = options.qrBreite === undefined
36
43
  ? null
37
44
  : Math.min(16, Math.max(3, Math.floor(options.qrBreite)));
@@ -50,6 +57,12 @@ function eposPrintXmlErgebnis(layout, options = {}) {
50
57
  return fest;
51
58
  if (nutzlast === '')
52
59
  return index_js_1.QR_MODUL_DECKEL[deckel];
60
+ // Passt der Inhalt in keine QR-Version, gibt es kein Symbol, das der
61
+ // Drucker setzen koennte -- wie beim Blatt (Anteil 0) geht der Beleg ohne QR.
62
+ if (!(0, index_js_1.qrPasstInVersion)(nutzlast)) {
63
+ qrFehler = 'QR-Inhalt passt in keine QR-Version -- Beleg ohne QR';
64
+ return null;
65
+ }
53
66
  const mass = (0, index_js_1.qrGroesseFuer)({
54
67
  nutzlast,
55
68
  papierbreitePunkte: index_js_1.QR_DRUCK_PUNKTE[layout.paperSize],
@@ -74,32 +87,34 @@ function eposPrintXmlErgebnis(layout, options = {}) {
74
87
  out.push('<text font="font_a"/>');
75
88
  out.push('<text align="left"/>');
76
89
  out.push('<text width="1" height="1" reverse="false" em="false"/>');
77
- for (const z of grid.lines) {
78
- switch (z.kind) {
79
- case 'space':
80
- out.push('<feed line="1"/>');
90
+ for (const block of blatt.bloecke) {
91
+ switch (block.art) {
92
+ case 'zeile':
93
+ if (block.leer)
94
+ out.push('<feed line="1"/>');
95
+ else if (block.fett) {
96
+ out.push(`<text em="true">${eposXmlEscape(block.text)}&#10;</text>`);
97
+ out.push('<text em="false"/>');
98
+ }
99
+ else
100
+ out.push(`<text>${eposXmlEscape(block.text)}&#10;</text>`);
101
+ break;
102
+ case 'logo':
103
+ if (options.logo) {
104
+ out.push('<text align="center"/>');
105
+ out.push(eposBildXml(options.logo.raster));
106
+ out.push('<text align="left"/>');
107
+ }
81
108
  break;
82
109
  case 'qr': {
83
- const breite = qrBreiteFuer(z.qr ?? '');
110
+ const breite = qrBreiteFuer(block.nutzlast);
84
111
  if (breite === null)
85
112
  break;
86
113
  out.push('<text align="center"/>');
87
- out.push(`<symbol type="qrcode_model_2" level="level_m" width="${breite}" height="0" size="0">${eposXmlEscape(z.qr ?? '')}</symbol>`);
114
+ out.push(`<symbol type="qrcode_model_2" level="level_m" width="${breite}" height="0" size="0">${eposXmlEscape(block.nutzlast)}</symbol>`);
88
115
  out.push('<text align="left"/>');
89
116
  break;
90
117
  }
91
- case 'banner':
92
- out.push(`<text width="1" height="2" reverse="${z.ton === 'warnung' ? 'true' : 'false'}" em="true">${eposXmlEscape(z.text)}&#10;</text>`);
93
- out.push('<text width="1" height="1" reverse="false" em="false"/>');
94
- break;
95
- default:
96
- if (z.bold)
97
- out.push(`<text em="true">${eposXmlEscape(z.text)}&#10;</text>`);
98
- else
99
- out.push(`<text>${eposXmlEscape(z.text)}&#10;</text>`);
100
- if (z.bold)
101
- out.push('<text em="false"/>');
102
- break;
103
118
  }
104
119
  }
105
120
  if (options.cut !== false) {
@@ -220,6 +235,10 @@ function eposDirectPrint(layout, o, fetchFn = fetch) {
220
235
  xmlOptionen.qrBreite = o.qrBreite;
221
236
  if (o.qrGroesse !== undefined)
222
237
  xmlOptionen.qrGroesse = o.qrGroesse;
238
+ if (o.logo)
239
+ xmlOptionen.logo = o.logo;
240
+ if (o.marke !== undefined)
241
+ xmlOptionen.marke = o.marke;
223
242
  return eposDirectSend(eposPrintXml({ ...layout, paperSize: papier }, xmlOptionen), o, fetchFn);
224
243
  }
225
244
  /** Verbindungstest: leeres Dokument, druckt nichts, liefert den Druckerstatus. */
@@ -27,7 +27,7 @@ export interface GridLine {
27
27
  text: string;
28
28
  kind: GridLineKind;
29
29
  bold: boolean;
30
- /** Bei `banner`: `warnung` = invers/auffaellig, `belegart` = Rahmen. */
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;
@@ -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.