mirror of
https://github.com/MultiMote/niimbluelib.git
synced 2025-03-16 03:21:01 +03:00
Implement PrinterCheckLine
This commit is contained in:
parent
a453dfe497
commit
1ab81bc0bd
@ -57,10 +57,10 @@ PrintStart [1(u8)]
|
||||
Page:
|
||||
|
||||
```
|
||||
PrintClear [1(u8)]
|
||||
PageStart [1(u8)]
|
||||
SetPageSize [rows(u16), cols(u16)]
|
||||
PrintEmptyRow | PrintBitmapRow | PrintBitmapRowIndexed
|
||||
PrinterCheckLine [line(u16), 1(u8)] - after every 200 lines (data example: 00c701, 018f01, 025701, 031f01, ...)
|
||||
PageEnd [1(u8)]
|
||||
```
|
||||
|
||||
|
@ -90,7 +90,7 @@ export abstract class NiimbotAbstractClient extends EventEmitter<ClientEventMap>
|
||||
await this.sendPacket(packet, true);
|
||||
|
||||
if (packet.oneWay) {
|
||||
return new NiimbotPacket(ResponseCommandId.Invalid, []); // or undefined is better?
|
||||
return new NiimbotPacket(ResponseCommandId.In_Invalid, []); // or undefined is better?
|
||||
}
|
||||
|
||||
return this.waitForPacket(packet.validResponseIds, true, timeoutMs);
|
||||
|
@ -2,7 +2,7 @@ import { Utils } from ".";
|
||||
|
||||
/** @category Image encoder */
|
||||
export type ImageRow = {
|
||||
dataType: "void" | "pixels";
|
||||
dataType: "void" | "pixels" | "check";
|
||||
rowNumber: number;
|
||||
repeat: number;
|
||||
blackPixelsCount: number;
|
||||
@ -83,6 +83,18 @@ export class ImageEncoder {
|
||||
} else {
|
||||
rowsData.push(newPart);
|
||||
}
|
||||
|
||||
const sendRowCheck = row % 200 === 199;
|
||||
|
||||
if (sendRowCheck) {
|
||||
rowsData.push({
|
||||
dataType: "check",
|
||||
rowNumber: row,
|
||||
repeat: 0,
|
||||
rowData: undefined,
|
||||
blackPixelsCount: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +102,12 @@ export class ImageEncoder {
|
||||
}
|
||||
|
||||
/** printDirection = "left" rotates image to 90 degrees clockwise */
|
||||
public static isPixelNonWhite(iData: ImageData, x: number, y: number, printDirection: PrintDirection = "left"): boolean {
|
||||
public static isPixelNonWhite(
|
||||
iData: ImageData,
|
||||
x: number,
|
||||
y: number,
|
||||
printDirection: PrintDirection = "left"
|
||||
): boolean {
|
||||
let idx = y * iData.width + x;
|
||||
|
||||
if (printDirection === "left") {
|
||||
|
@ -55,7 +55,7 @@ export enum RequestCommandId {
|
||||
* @category Packets
|
||||
**/
|
||||
export enum ResponseCommandId {
|
||||
Invalid = -1,
|
||||
In_Invalid = -1,
|
||||
In_NotSupported = 0x00,
|
||||
In_Connect = 0xc2,
|
||||
In_CalibrateHeight = 0x69,
|
||||
|
@ -10,9 +10,20 @@ import {
|
||||
commandsMap,
|
||||
NiimbotCrc32Packet,
|
||||
} from ".";
|
||||
import { EncodedImage, ImageEncoder, ImageRow } from "../image_encoder";
|
||||
import { EncodedImage, ImageEncoder } from "../image_encoder";
|
||||
import { Utils } from "../utils";
|
||||
|
||||
export interface ImagePacketsGenerateOptions {
|
||||
/** Mode for "black pixel count" section of bitmap packet. */
|
||||
countsMode?: "auto" | "split" | "total";
|
||||
/** Disable PrintBitmapRowIndexed packet. */
|
||||
noIndexPacket?: boolean;
|
||||
/** Send PrinterCheckLine every 200 line. */
|
||||
enableCheckLine?: boolean;
|
||||
/** Printer head resolution. Used for "black pixel count" section calculation. */
|
||||
printheadPixels?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper class that generates various types of packets.
|
||||
* @category Packets
|
||||
@ -178,8 +189,14 @@ export class PacketGenerator {
|
||||
return this.mapped(TX.PrintEmptyRow, [...Utils.u16ToBytes(pos), repeats]);
|
||||
}
|
||||
|
||||
public static printBitmapRow(pos: number, repeats: number, data: Uint8Array, printheadPixels?: number): NiimbotPacket {
|
||||
const counts = Utils.countPixelsForBitmapPacket(data, printheadPixels ?? 0);
|
||||
public static printBitmapRow(
|
||||
pos: number,
|
||||
repeats: number,
|
||||
data: Uint8Array,
|
||||
printheadPixels: number,
|
||||
countsMode: "auto" | "split" | "total" = "auto"
|
||||
): NiimbotPacket {
|
||||
const counts = Utils.countPixelsForBitmapPacket(data, printheadPixels, countsMode);
|
||||
return this.mapped(TX.PrintBitmapRow, [...Utils.u16ToBytes(pos), ...counts.parts, repeats, ...data]);
|
||||
}
|
||||
|
||||
@ -189,9 +206,10 @@ export class PacketGenerator {
|
||||
pos: number,
|
||||
repeats: number,
|
||||
data: Uint8Array,
|
||||
printheadPixels?: number
|
||||
printheadPixels: number,
|
||||
countsMode: "auto" | "split" | "total" = "auto"
|
||||
): NiimbotPacket {
|
||||
const counts = Utils.countPixelsForBitmapPacket(data, printheadPixels ?? 0);
|
||||
const counts = Utils.countPixelsForBitmapPacket(data, printheadPixels ?? 0, countsMode);
|
||||
const indexes: Uint8Array = ImageEncoder.indexPixels(data);
|
||||
|
||||
if (counts.total > 6) {
|
||||
@ -209,18 +227,50 @@ export class PacketGenerator {
|
||||
return this.mapped(TX.WriteRFID, data);
|
||||
}
|
||||
|
||||
public static writeImageData(image: EncodedImage, printheadPixels?: number): NiimbotPacket[] {
|
||||
return image.rowsData.map((p: ImageRow) => {
|
||||
if (p.dataType === "pixels") {
|
||||
if (p.blackPixelsCount > 6) {
|
||||
return this.printBitmapRow(p.rowNumber, p.repeat, p.rowData!, printheadPixels);
|
||||
} else {
|
||||
return this.printBitmapRowIndexed(p.rowNumber, p.repeat, p.rowData!, printheadPixels);
|
||||
public static checkLine(line: number): NiimbotPacket {
|
||||
return this.mapped(TX.PrinterCheckLine, [...Utils.u16ToBytes(line), 0x01]);
|
||||
}
|
||||
|
||||
public static writeImageData(image: EncodedImage, options?: ImagePacketsGenerateOptions): NiimbotPacket[] {
|
||||
let out: NiimbotPacket[] = [];
|
||||
|
||||
for (const d of image.rowsData) {
|
||||
if (d.dataType === "pixels") {
|
||||
if (d.blackPixelsCount <= 6 && !options?.noIndexPacket) {
|
||||
out.push(
|
||||
this.printBitmapRowIndexed(
|
||||
d.rowNumber,
|
||||
d.repeat,
|
||||
d.rowData!,
|
||||
options?.printheadPixels ?? 0,
|
||||
options?.countsMode ?? "auto"
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return this.printEmptySpace(p.rowNumber, p.repeat);
|
||||
out.push(
|
||||
this.printBitmapRow(
|
||||
d.rowNumber,
|
||||
d.repeat,
|
||||
d.rowData!,
|
||||
options?.printheadPixels ?? 0,
|
||||
options?.countsMode ?? "auto"
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (d.dataType === "check" && options?.enableCheckLine) {
|
||||
out.push(this.checkLine(d.rowNumber));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (d.dataType === "void") {
|
||||
out.push(this.printEmptySpace(d.rowNumber, d.repeat));
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public static printTestPage(): NiimbotPacket {
|
||||
@ -232,11 +282,11 @@ export class PacketGenerator {
|
||||
}
|
||||
|
||||
public static startFirmwareUpgrade(version: string): NiimbotPacket {
|
||||
if(!/^\d+\.\d+$/.test(version)) {
|
||||
if (!/^\d+\.\d+$/.test(version)) {
|
||||
throw new Error("Invalid version format (x.x expected)");
|
||||
}
|
||||
|
||||
const [a, b] = version.split(".").map(p => parseInt(p));
|
||||
const [a, b] = version.split(".").map((p) => parseInt(p));
|
||||
|
||||
return this.mapped(TX.StartFirmwareUpgrade, [a, b]);
|
||||
}
|
||||
|
@ -17,20 +17,22 @@ export class B1PrintTask extends AbstractPrintTask {
|
||||
override printPage(image: EncodedImage, quantity?: number): Promise<void> {
|
||||
this.checkAddPage(quantity ?? 1);
|
||||
|
||||
return this.abstraction.sendAll([
|
||||
return this.abstraction.sendAll(
|
||||
[
|
||||
PacketGenerator.pageStart(),
|
||||
PacketGenerator.setPageSizeV3(image.rows, image.cols, quantity ?? 1),
|
||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
||||
...PacketGenerator.writeImageData(image, { printheadPixels: this.printheadPixels() }),
|
||||
PacketGenerator.pageEnd(),
|
||||
], this.printOptions.pageTimeoutMs);
|
||||
],
|
||||
this.printOptions.pageTimeoutMs
|
||||
);
|
||||
}
|
||||
|
||||
override waitForFinished(): Promise<void> {
|
||||
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
||||
|
||||
return this.abstraction.waitUntilPrintFinishedByStatusPoll(
|
||||
this.printOptions.totalPages,
|
||||
this.printOptions.statusPollIntervalMs
|
||||
).finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||
return this.abstraction
|
||||
.waitUntilPrintFinishedByStatusPoll(this.printOptions.totalPages, this.printOptions.statusPollIntervalMs)
|
||||
.finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||
}
|
||||
}
|
||||
|
@ -18,22 +18,28 @@ export class B21V1PrintTask extends AbstractPrintTask {
|
||||
this.checkAddPage(quantity ?? 1);
|
||||
|
||||
for (let i = 0; i < (quantity ?? 1); i++) {
|
||||
await this.abstraction.sendAll([
|
||||
PacketGenerator.printClear(),
|
||||
await this.abstraction.sendAll(
|
||||
[
|
||||
// PacketGenerator.printClear(),
|
||||
PacketGenerator.pageStart(),
|
||||
PacketGenerator.setPageSizeV2(image.rows, image.cols),
|
||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
||||
...PacketGenerator.writeImageData(image, {
|
||||
countsMode: "total",
|
||||
enableCheckLine: true,
|
||||
printheadPixels: this.printheadPixels(),
|
||||
}),
|
||||
PacketGenerator.pageEnd(),
|
||||
], this.printOptions.pageTimeoutMs);
|
||||
],
|
||||
this.printOptions.pageTimeoutMs
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
override waitForFinished(): Promise<void> {
|
||||
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
||||
|
||||
return this.abstraction.waitUntilPrintFinishedByPrintEndPoll(
|
||||
this.printOptions.totalPages,
|
||||
this.printOptions.statusPollIntervalMs
|
||||
).finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||
return this.abstraction
|
||||
.waitUntilPrintFinishedByPrintEndPoll(this.printOptions.totalPages, this.printOptions.statusPollIntervalMs)
|
||||
.finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||
}
|
||||
}
|
||||
|
@ -17,22 +17,24 @@ export class D110PrintTask extends AbstractPrintTask {
|
||||
override printPage(image: EncodedImage, quantity?: number): Promise<void> {
|
||||
this.checkAddPage(quantity ?? 1);
|
||||
|
||||
return this.abstraction.sendAll([
|
||||
return this.abstraction.sendAll(
|
||||
[
|
||||
PacketGenerator.printClear(),
|
||||
PacketGenerator.pageStart(),
|
||||
PacketGenerator.setPageSizeV2(image.rows, image.cols),
|
||||
PacketGenerator.setPrintQuantity(quantity ?? 1),
|
||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
||||
...PacketGenerator.writeImageData(image, { printheadPixels: this.printheadPixels() }),
|
||||
PacketGenerator.pageEnd(),
|
||||
], this.printOptions.pageTimeoutMs);
|
||||
],
|
||||
this.printOptions.pageTimeoutMs
|
||||
);
|
||||
}
|
||||
|
||||
override waitForFinished(): Promise<void> {
|
||||
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
||||
|
||||
return this.abstraction.waitUntilPrintFinishedByStatusPoll(
|
||||
this.printOptions.totalPages,
|
||||
this.printOptions.statusPollIntervalMs
|
||||
).finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||
return this.abstraction
|
||||
.waitUntilPrintFinishedByStatusPoll(this.printOptions.totalPages, this.printOptions.statusPollIntervalMs)
|
||||
.finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||
}
|
||||
}
|
||||
|
@ -17,14 +17,17 @@ export class OldD11PrintTask extends AbstractPrintTask {
|
||||
override printPage(image: EncodedImage, quantity: number): Promise<void> {
|
||||
this.checkAddPage(quantity ?? 1);
|
||||
|
||||
return this.abstraction.sendAll([
|
||||
return this.abstraction.sendAll(
|
||||
[
|
||||
PacketGenerator.printClear(),
|
||||
PacketGenerator.pageStart(),
|
||||
PacketGenerator.setPageSizeV1(image.rows),
|
||||
PacketGenerator.setPrintQuantity(quantity ?? 1),
|
||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
||||
...PacketGenerator.writeImageData(image, { printheadPixels: this.printheadPixels() }),
|
||||
PacketGenerator.pageEnd(),
|
||||
], this.printOptions.pageTimeoutMs);
|
||||
],
|
||||
this.printOptions.pageTimeoutMs
|
||||
);
|
||||
}
|
||||
|
||||
override waitForFinished(): Promise<void> {
|
||||
|
@ -10,27 +10,29 @@ export class V5PrintTask extends AbstractPrintTask {
|
||||
return this.abstraction.sendAll([
|
||||
PacketGenerator.setDensity(this.printOptions.density),
|
||||
PacketGenerator.setLabelType(this.printOptions.labelType),
|
||||
PacketGenerator.printStartV5(this.printOptions.totalPages, 0, 0)
|
||||
PacketGenerator.printStartV5(this.printOptions.totalPages, 0, 0),
|
||||
]);
|
||||
}
|
||||
|
||||
override printPage(image: EncodedImage, quantity?: number): Promise<void> {
|
||||
this.checkAddPage(quantity ?? 1);
|
||||
|
||||
return this.abstraction.sendAll([
|
||||
return this.abstraction.sendAll(
|
||||
[
|
||||
PacketGenerator.pageStart(),
|
||||
PacketGenerator.setPageSizeV4(image.rows, image.cols, quantity ?? 1, 0, false),
|
||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
||||
...PacketGenerator.writeImageData(image, { printheadPixels: this.printheadPixels() }),
|
||||
PacketGenerator.pageEnd(),
|
||||
], this.printOptions.pageTimeoutMs);
|
||||
],
|
||||
this.printOptions.pageTimeoutMs
|
||||
);
|
||||
}
|
||||
|
||||
override waitForFinished(): Promise<void> {
|
||||
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
||||
|
||||
return this.abstraction.waitUntilPrintFinishedByStatusPoll(
|
||||
this.printOptions.totalPages ?? 1,
|
||||
this.printOptions.statusPollIntervalMs
|
||||
).finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||
return this.abstraction
|
||||
.waitUntilPrintFinishedByStatusPoll(this.printOptions.totalPages ?? 1, this.printOptions.statusPollIntervalMs)
|
||||
.finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user