row method

List<int> row(
  1. List<PosColumn> cols
)

Print a row.

A row contains up to 12 columns. A column has a width between 1 and 12. Total width of columns in one row must be equal 12.

Implementation

List<int> row(List<PosColumn> cols) {
  List<int> bytes = [];
  final isSumValid = cols.fold(0, (int sum, col) => sum + col.width) == 12;
  if (!isSumValid) {
    throw Exception('Total columns width must be equal to 12');
  }
  bool isNextRow = false;
  List<PosColumn> nextRow = <PosColumn>[];

  for (int i = 0; i < cols.length; ++i) {
    int colInd =
        cols.sublist(0, i).fold(0, (int sum, col) => sum + col.width);
    double charWidth = _getCharWidth(cols[i].styles);
    double fromPos = _colIndToPosition(colInd);
    final double toPos =
        _colIndToPosition(colInd + cols[i].width) - spaceBetweenRows;
    int maxCharactersNb = ((toPos - fromPos) / charWidth).floor();

    if (!cols[i].containsChinese) {
      // CASE 1: containsChinese = false
      Uint8List encodedToPrint = cols[i].textEncoded != null
          ? cols[i].textEncoded!
          : _encode(cols[i].text);

      // If the col's content is too long, split it to the next row
      int realCharactersNb = encodedToPrint.length;
      if (realCharactersNb > maxCharactersNb) {
        // Print max possible and split to the next row
        Uint8List encodedToPrintNextRow =
            encodedToPrint.sublist(maxCharactersNb);
        encodedToPrint = encodedToPrint.sublist(0, maxCharactersNb);
        isNextRow = true;
        nextRow.add(PosColumn(
            textEncoded: encodedToPrintNextRow,
            width: cols[i].width,
            styles: cols[i].styles));
      } else {
        // Insert an empty col
        nextRow.add(PosColumn(
            text: '', width: cols[i].width, styles: cols[i].styles));
      }
      // end rows splitting
      bytes += _text(
        encodedToPrint,
        styles: cols[i].styles,
        colInd: colInd,
        colWidth: cols[i].width,
      );
    } else {
      // CASE 1: containsChinese = true
      // Split text into multiple lines if it too long
      int counter = 0;
      int splitPos = 0;
      for (int p = 0; p < cols[i].text.length; ++p) {
        final int w = _isChinese(cols[i].text[p]) ? 2 : 1;
        if (counter + w >= maxCharactersNb) {
          break;
        }
        counter += w;
        splitPos += 1;
      }
      String toPrintNextRow = cols[i].text.substring(splitPos);
      String toPrint = cols[i].text.substring(0, splitPos);

      if (toPrintNextRow.isNotEmpty) {
        isNextRow = true;
        nextRow.add(PosColumn(
            text: toPrintNextRow,
            containsChinese: true,
            width: cols[i].width,
            styles: cols[i].styles));
      } else {
        // Insert an empty col
        nextRow.add(PosColumn(
            text: '', width: cols[i].width, styles: cols[i].styles));
      }

      // Print current row
      final list = _getLexemes(toPrint);
      final List<String> lexemes = list[0];
      final List<bool> isLexemeChinese = list[1];

      // Print each lexeme using codetable OR kanji
      for (var j = 0; j < lexemes.length; ++j) {
        bytes += _text(
          _encode(lexemes[j], isKanji: isLexemeChinese[j]),
          styles: cols[i].styles,
          colInd: colInd,
          colWidth: cols[i].width,
          isKanji: isLexemeChinese[j],
        );
        // Define the absolute position only once (we print one line only)
        // colInd = null;
      }
    }
  }

  bytes += emptyLines(1);

  if (isNextRow) {
    row(nextRow);
  }
  return bytes;
}