render static method
Setzt das Zeilenmodell ins Raster; charsPerLine fehlt → nach paperSize (32/48).
Implementation
static ReceiptGrid render(ReceiptLayout layout, {int? charsPerLine}) {
final n0 = charsPerLine ?? (layout.paperSize == 'mm80' ? charsPer80mm : charsPer58mm);
final n = n0 < 8 ? 8 : n0;
final leer = ' ' * n;
final out = <GridLine>[];
for (final z in layout.lines) {
switch (z) {
case LayoutTextLine():
for (final t in wrapWords(z.text, n)) {
out.add(GridLine(text: _ausrichten(t, n, z.align), kind: GridLineKind.text, bold: z.bold));
}
case LayoutBannerLine():
// Der Rahmen ist Teil des Rasters (Zwilling von renderReceiptGrid ab
// npm 0.14.0): '=' ueber die volle Breite davor und danach. So setzt
// ihn jeder Weg zeichengleich -- vorher druckte der Bon doppelt hoch
// und invers, der Bildschirm fuellte schwarz, das PDF zog ein Rechteck.
final rahmen = '=' * n;
out.add(GridLine(text: rahmen, kind: GridLineKind.banner, bold: true, warning: z.warning));
for (final t in wrapWords(z.text, n)) {
out.add(GridLine(text: _ausrichten(t, n, LayoutAlign.center), kind: GridLineKind.banner, bold: true, warning: z.warning));
}
out.add(GridLine(text: rahmen, kind: GridLineKind.banner, bold: true, warning: z.warning));
case LayoutRuleLine():
out.add(GridLine(text: (z.char.isEmpty ? '-' : z.char[0]) * n, kind: GridLineKind.rule));
case LayoutSpaceLine():
for (var i = 0; i < z.lines; i++) {
out.add(GridLine(text: leer, kind: GridLineKind.space));
}
case LayoutQrLine():
out.add(GridLine(text: _ausrichten('[QR-Code]', n, LayoutAlign.center), kind: GridLineKind.qr, qr: z.data));
case LayoutColumnsLine():
final breiten = gridColumnWidths(z.columns.map((c) => c.width).toList(), n);
final inhalt = <int>[for (var i = 0; i < breiten.length; i++) i < breiten.length - 1 ? (breiten[i] - 1 < 1 ? 1 : breiten[i] - 1) : breiten[i]];
final teile = <List<String>>[for (var i = 0; i < z.columns.length; i++) wrapWords(z.columns[i].text, inhalt[i])];
// Fließregel (wie renderReceiptGrid): läuft nur EINE Spalte über die erste Zeile
// hinaus, bekommt ihr Rest die volle Breite; laufen mehrere weiter, bleibt das Raster.
final weiterlaufend = <int>[for (var i = 0; i < teile.length; i++) if (teile[i].length > 1) i];
final fliesst = weiterlaufend.length == 1 && z.columns.length > 1;
var zeilen = 1;
if (!fliesst) {
for (final t in teile) {
if (t.length > zeilen) zeilen = t.length;
}
}
for (var r = 0; r < zeilen; r++) {
final sb = StringBuffer();
for (var i = 0; i < z.columns.length; i++) {
final zelle = _ausrichten(r < teile[i].length ? teile[i][r] : '', inhalt[i], z.columns[i].align);
sb.write(i < breiten.length - 1 ? zelle + ' ' * (breiten[i] - inhalt[i]) : zelle);
}
final text = sb.toString();
out.add(GridLine(text: text.length == n ? text : _ausrichten(text, n, LayoutAlign.left), kind: GridLineKind.columns));
}
if (fliesst) {
final i = weiterlaufend.first;
final rest = _restNach(z.columns[i].text, teile[i].first);
for (final t in wrapWords(rest, n)) {
out.add(GridLine(text: _ausrichten(t, n, z.columns[i].align), kind: GridLineKind.columns));
}
}
}
}
return ReceiptGrid(lines: out, charsPerLine: n);
}