import 'dart:convert'; import 'dart:typed_data'; import 'package:desktop_plugin/image/card_image.dart'; import 'package:desktop_plugin/print/pavo/pavo_ffi.dart'; import 'package:desktop_plugin/print/pavo/pavo_printer.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:image/image.dart'; String dataUrl(Image img) => 'data:image/png;base64,${base64.encode(encodePng(img))}'; void main() { group('CardImage 像素层转换', () { test('横向图缩放到 1014×642,纯红转 BGR 字节序正确', () { final img = Image(width: 100, height: 50); fill(img, color: ColorRgb8(255, 0, 0)); final card = CardImage.fromDataUrl(dataUrl(img)); expect(card.isLandscape, isTrue); expect(card.width, 1014); expect(card.height, 642); final bgr = card.toBgr24(); expect(bgr.length, 1014 * 642 * 3); // 红色像素 → BGR 序 [B=0, G=0, R=255] expect(bgr[0], 0); expect(bgr[1], 0); expect(bgr[2], 255); // 中间像素一致(无行对齐错位/跨行污染) final mid = (642 ~/ 2) * 1014 * 3 + (1014 ~/ 2) * 3; expect(bgr[mid], 0); expect(bgr[mid + 1], 0); expect(bgr[mid + 2], 255); }); test('纵向图缩放到 642×1014,纯蓝转 BGR 正确', () { final img = Image(width: 50, height: 100); fill(img, color: ColorRgb8(0, 0, 255)); final card = CardImage.fromDataUrl(dataUrl(img)); expect(card.isLandscape, isFalse); expect(card.width, 642); expect(card.height, 1014); final bgr = card.toBgr24(); // 蓝色像素 → BGR 序 [B=255, G=0, R=0] expect(bgr[0], 255); expect(bgr[1], 0); expect(bgr[2], 0); }); test('透明像素铺白,避免黑底', () { // 注意:image v4 的 Image() 默认是 3 通道不透明黑,透明图必须显式 numChannels: 4 final img = Image(width: 100, height: 50, numChannels: 4); // RGBA(0,0,0,0) 全透明 final card = CardImage.fromDataUrl(dataUrl(img)); final bgr = card.toBgr24(); expect(bgr[0], 255); expect(bgr[1], 255); expect(bgr[2], 255); }); test('灰度转换:红 ≈ 76、白 = 255(K 层白底黑字语义)', () { final red = Image(width: 100, height: 50); fill(red, color: ColorRgb8(255, 0, 0)); final card = CardImage.fromDataUrl(dataUrl(red)); final gray = card.toGray8(); expect(gray.length, 1014 * 642); expect(gray[0], 255 * 299 ~/ 1000); // = 76 expect(gray.every((g) => g == 76), isTrue); final white = Image(width: 100, height: 50); fill(white, color: ColorRgb8(255, 255, 255)); expect(CardImage.fromDataUrl(dataUrl(white)).toGray8()[0], 255); }); test('空 data URL 报错', () { expect(() => CardImage.fromDataUrl(''), throwsArgumentError); }); }); group('PavoPrinter 纯 Dart 工具', () { test('decodeAuto 识别 UTF-8 / UTF-16 打印机名', () { // 纯 ASCII:UTF-8 解码即可正确还原(NUL 计入可打印率,两种编码都可能命中 UTF-8 路径) final ascii = Uint8List.fromList('HiTi CS-200e'.codeUnits); expect(PavoPrinter.decodeAuto(ascii).startsWith('HiTi CS-200e'), isTrue); // 纯中文:UTF-8 解码得乱码(可打印率低),走 UTF-16 路径正确还原 // (ASCII 混中文时 NUL 也计入可打印率,可能仍走 UTF-8 路径——与 C# 行为一致) final name = '证卡打印机'; final bytes = []; for (final c in name.codeUnits) { bytes..add(c & 0xff)..add(c >> 8); } expect(PavoPrinter.decodeAuto(Uint8List.fromList(bytes)), name); }); test('statusTextOf 状态文案', () { expect(PavoPrinter.statusTextOf(0), '就绪'); expect(PavoPrinter.statusTextOf(PavoApi.dsOutOfRibbon), '色带已用尽,请更换色带'); expect(PavoPrinter.statusTextOf(0x12345678), contains('设备状态异常')); }); }); }