Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple bug fixes collection #85

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 109 additions & 88 deletions lib/src/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
*/

import 'dart:convert';
import 'dart:ffi';
import 'dart:typed_data' show Uint8List;
import 'package:hex/hex.dart';
import 'package:image/image.dart';
import 'package:gbk_codec/gbk_codec.dart';
// import 'package:gbk_codec/gbk_codec.dart';
import 'package:esc_pos_utils/src/text_with_type.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'enums.dart';
import 'commands.dart';
Expand Down Expand Up @@ -65,42 +67,56 @@ class Generator {
return charsPerLine;
}

Uint8List _encode(String text, {bool isKanji = false}) {
// replace some non-ascii characters
text = text
.replaceAll("’", "'")
.replaceAll("´", "'")
.replaceAll("»", '"')
.replaceAll(" ", ' ')
.replaceAll("•", '.');
if (!isKanji) {
return latin1.encode(text);
} else {
return Uint8List.fromList(gbk_bytes.encode(text));
// Uint8List _encode(String text, {bool isKanji = false}) {
// // replace some non-ascii characters
// text = text
// .replaceAll("’", "'")
// .replaceAll("´", "'")
// .replaceAll("»", '"')
// .replaceAll(" ", ' ')
// .replaceAll("•", '.');
// if (!isKanji) {
// return latin1.encode(text);
// } else {
// return Uint8List.fromList(gbk_bytes.encode(text));
// }
// }

// List _getLexemes(String text) {
// final List<String> lexemes = [];
// final List<bool> isLexemeChinese = [];
List<TextWithType> _splitByTextType(String text) {
if (text.isEmpty) {
return [];
}
}

List _getLexemes(String text) {
final List<String> lexemes = [];
final List<bool> isLexemeChinese = [];
final List<TextWithType> textWithType = [];
int start = 0;
int end = 0;
bool curLexemeChinese = _isChinese(text[0]);
for (var i = 1; i < text.length; ++i) {
if (curLexemeChinese == _isChinese(text[i])) {
end += 1;
} else {
lexemes.add(text.substring(start, end + 1));
isLexemeChinese.add(curLexemeChinese);
// lexemes.add(text.substring(start, end + 1));
// isLexemeChinese.add(curLexemeChinese);
textWithType.add(TextWithType.fromText(
text: text.substring(start, end + 1),
isCjk: curLexemeChinese,
));
start = i;
end = i;
curLexemeChinese = !curLexemeChinese;
}
}
lexemes.add(text.substring(start, end + 1));
isLexemeChinese.add(curLexemeChinese);
// lexemes.add(text.substring(start, end + 1));
// isLexemeChinese.add(curLexemeChinese);
textWithType.add(TextWithType.fromText(
text: text.substring(start, end + 1),
isCjk: curLexemeChinese,
));
return textWithType;

return <dynamic>[lexemes, isLexemeChinese];
// return <dynamic>[lexemes, isLexemeChinese];
}

/// Break text into chinese/non-chinese lexemes
Expand Down Expand Up @@ -351,15 +367,23 @@ class Generator {
List<int> bytes = [];
if (!containsChinese) {
bytes += _text(
_encode(text, isKanji: containsChinese),
// _encode(text, isKanji: containsChinese),
[TextWithType.fromText(text: text, isCjk: containsChinese)],
styles: styles,
isKanji: containsChinese,
// isKanji: containsChinese,
maxCharsPerLine: maxCharsPerLine,
);
// Ensure at least one line break after the text
bytes += emptyLines(linesAfter + 1);
} else {
bytes += _mixedKanji(text, styles: styles, linesAfter: linesAfter);
// bytes += _mixedKanji(text, styles: styles, linesAfter: linesAfter);
bytes += _text(
_splitByTextType(text),
styles: styles,
maxCharsPerLine: maxCharsPerLine,
);
// Ensure at least one line break after the text
bytes += emptyLines(linesAfter + 1);
}
return bytes;
}
Expand Down Expand Up @@ -479,17 +503,25 @@ class Generator {

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

// If the col's content is too long, split it to the next row
int realCharactersNb = encodedToPrint.length;
// int realCharactersNb = encodedToPrint.length;
int realCharactersNb = textWithType.encodedBytes.length;
if (realCharactersNb > maxCharactersNb) {
// Print max possible and split to the next row
Uint8List encodedToPrintNextRow =
encodedToPrint.sublist(maxCharactersNb);
encodedToPrint = encodedToPrint.sublist(0, maxCharactersNb);
// encodedToPrint.sublist(maxCharactersNb);
// encodedToPrint = encodedToPrint.sublist(0, maxCharactersNb);
textWithType.encodedBytes.sublist(maxCharactersNb);
textWithType = TextWithType.fromEncoded(
encodedBytes:
textWithType.encodedBytes.sublist(0, maxCharactersNb));
isNextRow = true;
nextRow.add(PosColumn(
textEncoded: encodedToPrintNextRow,
Expand All @@ -498,11 +530,12 @@ class Generator {
} else {
// Insert an empty col
nextRow.add(PosColumn(
text: '', width: cols[i].width, styles: cols[i].styles));
text: ' ', width: cols[i].width, styles: cols[i].styles));
}
// end rows splitting
bytes += _text(
encodedToPrint,
// encodedToPrint,
[textWithType],
styles: cols[i].styles,
colInd: colInd,
colWidth: cols[i].width,
Expand Down Expand Up @@ -533,33 +566,41 @@ class Generator {
} else {
// Insert an empty col
nextRow.add(PosColumn(
text: '', width: cols[i].width, styles: cols[i].styles));
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;
}
// final list = _getLexemes(toPrint);
// final List<String> lexemes = list[0];
// final List<bool> isLexemeChinese = list[1];

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

bytes += emptyLines(1);

if (isNextRow) {
row(nextRow);
bytes += row(nextRow);
}
return bytes;
}
Expand Down Expand Up @@ -749,7 +790,8 @@ class Generator {
int? maxCharsPerLine,
}) {
List<int> bytes = [];
bytes += _text(textBytes, styles: styles, maxCharsPerLine: maxCharsPerLine);
bytes += _text([TextWithType.fromEncoded(encodedBytes: textBytes)],
styles: styles, maxCharsPerLine: maxCharsPerLine);
// Ensure at least one line break after the text
bytes += emptyLines(linesAfter + 1);
return bytes;
Expand All @@ -761,10 +803,11 @@ class Generator {
///
/// [colInd] range: 0..11. If null: do not define the position
List<int> _text(
Uint8List textBytes, {
// Uint8List textBytes, {
List<TextWithType> textWithTypes, {
PosStyles styles = const PosStyles(),
int? colInd = 0,
bool isKanji = false,
// bool isKanji = false,
int colWidth = 12,
int? maxCharsPerLine,
}) {
Expand All @@ -779,7 +822,12 @@ class Generator {
// Update fromPos
final double toPos =
_colIndToPosition(colInd + colWidth) - spaceBetweenRows;
final double textLen = textBytes.length * charWidth;
// final double textLen = textBytes.length * charWidth;
final int textByteLength = textWithTypes.fold(
0,
(int previousValue, textWithType) =>
previousValue + textWithType.encodedBytes.length);
final double textLen = textByteLength * charWidth;

if (styles.align == PosAlign.right) {
fromPos = toPos - textLen;
Expand All @@ -800,39 +848,12 @@ class Generator {
);
}

bytes += setStyles(styles, isKanji: isKanji);
// bytes += setStyles(styles, isKanji: isKanji);
textWithTypes.forEach((textWithType) {
bytes += setStyles(styles, isKanji: textWithType.isCjk);

bytes += textBytes;
return bytes;
}

/// Prints one line of styled mixed (chinese and latin symbols) text
List<int> _mixedKanji(
String text, {
PosStyles styles = const PosStyles(),
int linesAfter = 0,
int? maxCharsPerLine,
}) {
List<int> bytes = [];
final list = _getLexemes(text);
final List<String> lexemes = list[0];
final List<bool> isLexemeChinese = list[1];

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

bytes += emptyLines(linesAfter + 1);
bytes += textWithType.encodedBytes;
});
return bytes;
}
// ************************ (end) Internal command generators ************************
Expand Down
3 changes: 1 addition & 2 deletions lib/src/pos_column.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ class PosColumn {
if (width < 1 || width > 12) {
throw Exception('Column width must be between 1..12');
}
if (text != null &&
text.length > 0 &&
if (text.length > 0 &&
textEncoded != null &&
textEncoded!.length > 0) {
throw Exception(
Expand Down
44 changes: 44 additions & 0 deletions lib/src/text_with_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'dart:convert';
import 'dart:typed_data';

import 'package:gbk_codec/gbk_codec.dart';

class TextWithType {
TextWithType.fromText({
required this.text,
this.isCjk = false,
}) {
if (text!.length == 0) {
throw Exception('text should be passed');
}
encodedBytes = _encodeText(text!, isCjk: isCjk);
}

TextWithType.fromEncoded({
required this.encodedBytes,
this.isCjk = false,
}) {
if (encodedBytes.length == 0) {
throw Exception('encodedBytes should be passed');
}
}

String? text;
bool isCjk;
late Uint8List encodedBytes;

Uint8List _encodeText(String text, {bool isCjk = false}) {
// replace some non-ascii characters
text = text
.replaceAll("’", "'")
.replaceAll("´", "'")
.replaceAll("»", '"')
.replaceAll(" ", ' ')
.replaceAll("•", '.');
if (!isCjk) {
return latin1.encode(text);
} else {
return Uint8List.fromList(gbk_bytes.encode(text));
}
}
}
Loading