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:
|
Page:
|
||||||
|
|
||||||
```
|
```
|
||||||
PrintClear [1(u8)]
|
|
||||||
PageStart [1(u8)]
|
PageStart [1(u8)]
|
||||||
SetPageSize [rows(u16), cols(u16)]
|
SetPageSize [rows(u16), cols(u16)]
|
||||||
PrintEmptyRow | PrintBitmapRow | PrintBitmapRowIndexed
|
PrintEmptyRow | PrintBitmapRow | PrintBitmapRowIndexed
|
||||||
|
PrinterCheckLine [line(u16), 1(u8)] - after every 200 lines (data example: 00c701, 018f01, 025701, 031f01, ...)
|
||||||
PageEnd [1(u8)]
|
PageEnd [1(u8)]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ export abstract class NiimbotAbstractClient extends EventEmitter<ClientEventMap>
|
|||||||
await this.sendPacket(packet, true);
|
await this.sendPacket(packet, true);
|
||||||
|
|
||||||
if (packet.oneWay) {
|
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);
|
return this.waitForPacket(packet.validResponseIds, true, timeoutMs);
|
||||||
|
@ -2,7 +2,7 @@ import { Utils } from ".";
|
|||||||
|
|
||||||
/** @category Image encoder */
|
/** @category Image encoder */
|
||||||
export type ImageRow = {
|
export type ImageRow = {
|
||||||
dataType: "void" | "pixels";
|
dataType: "void" | "pixels" | "check";
|
||||||
rowNumber: number;
|
rowNumber: number;
|
||||||
repeat: number;
|
repeat: number;
|
||||||
blackPixelsCount: number;
|
blackPixelsCount: number;
|
||||||
@ -83,14 +83,31 @@ export class ImageEncoder {
|
|||||||
} else {
|
} else {
|
||||||
rowsData.push(newPart);
|
rowsData.push(newPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sendRowCheck = row % 200 === 199;
|
||||||
|
|
||||||
|
if (sendRowCheck) {
|
||||||
|
rowsData.push({
|
||||||
|
dataType: "check",
|
||||||
|
rowNumber: row,
|
||||||
|
repeat: 0,
|
||||||
|
rowData: undefined,
|
||||||
|
blackPixelsCount: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { cols, rows, rowsData };
|
return { cols, rows, rowsData };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** printDirection = "left" rotates image to 90 degrees clockwise */
|
/** 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;
|
let idx = y * iData.width + x;
|
||||||
|
|
||||||
if (printDirection === "left") {
|
if (printDirection === "left") {
|
||||||
|
@ -55,7 +55,7 @@ export enum RequestCommandId {
|
|||||||
* @category Packets
|
* @category Packets
|
||||||
**/
|
**/
|
||||||
export enum ResponseCommandId {
|
export enum ResponseCommandId {
|
||||||
Invalid = -1,
|
In_Invalid = -1,
|
||||||
In_NotSupported = 0x00,
|
In_NotSupported = 0x00,
|
||||||
In_Connect = 0xc2,
|
In_Connect = 0xc2,
|
||||||
In_CalibrateHeight = 0x69,
|
In_CalibrateHeight = 0x69,
|
||||||
|
@ -10,9 +10,20 @@ import {
|
|||||||
commandsMap,
|
commandsMap,
|
||||||
NiimbotCrc32Packet,
|
NiimbotCrc32Packet,
|
||||||
} from ".";
|
} from ".";
|
||||||
import { EncodedImage, ImageEncoder, ImageRow } from "../image_encoder";
|
import { EncodedImage, ImageEncoder } from "../image_encoder";
|
||||||
import { Utils } from "../utils";
|
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.
|
* A helper class that generates various types of packets.
|
||||||
* @category Packets
|
* @category Packets
|
||||||
@ -178,8 +189,14 @@ export class PacketGenerator {
|
|||||||
return this.mapped(TX.PrintEmptyRow, [...Utils.u16ToBytes(pos), repeats]);
|
return this.mapped(TX.PrintEmptyRow, [...Utils.u16ToBytes(pos), repeats]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static printBitmapRow(pos: number, repeats: number, data: Uint8Array, printheadPixels?: number): NiimbotPacket {
|
public static printBitmapRow(
|
||||||
const counts = Utils.countPixelsForBitmapPacket(data, printheadPixels ?? 0);
|
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]);
|
return this.mapped(TX.PrintBitmapRow, [...Utils.u16ToBytes(pos), ...counts.parts, repeats, ...data]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,9 +206,10 @@ export class PacketGenerator {
|
|||||||
pos: number,
|
pos: number,
|
||||||
repeats: number,
|
repeats: number,
|
||||||
data: Uint8Array,
|
data: Uint8Array,
|
||||||
printheadPixels?: number
|
printheadPixels: number,
|
||||||
|
countsMode: "auto" | "split" | "total" = "auto"
|
||||||
): NiimbotPacket {
|
): NiimbotPacket {
|
||||||
const counts = Utils.countPixelsForBitmapPacket(data, printheadPixels ?? 0);
|
const counts = Utils.countPixelsForBitmapPacket(data, printheadPixels ?? 0, countsMode);
|
||||||
const indexes: Uint8Array = ImageEncoder.indexPixels(data);
|
const indexes: Uint8Array = ImageEncoder.indexPixels(data);
|
||||||
|
|
||||||
if (counts.total > 6) {
|
if (counts.total > 6) {
|
||||||
@ -209,18 +227,50 @@ export class PacketGenerator {
|
|||||||
return this.mapped(TX.WriteRFID, data);
|
return this.mapped(TX.WriteRFID, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static writeImageData(image: EncodedImage, printheadPixels?: number): NiimbotPacket[] {
|
public static checkLine(line: number): NiimbotPacket {
|
||||||
return image.rowsData.map((p: ImageRow) => {
|
return this.mapped(TX.PrinterCheckLine, [...Utils.u16ToBytes(line), 0x01]);
|
||||||
if (p.dataType === "pixels") {
|
}
|
||||||
if (p.blackPixelsCount > 6) {
|
|
||||||
return this.printBitmapRow(p.rowNumber, p.repeat, p.rowData!, printheadPixels);
|
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 {
|
} else {
|
||||||
return this.printBitmapRowIndexed(p.rowNumber, p.repeat, p.rowData!, printheadPixels);
|
out.push(
|
||||||
|
this.printBitmapRow(
|
||||||
|
d.rowNumber,
|
||||||
|
d.repeat,
|
||||||
|
d.rowData!,
|
||||||
|
options?.printheadPixels ?? 0,
|
||||||
|
options?.countsMode ?? "auto"
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
continue;
|
||||||
return this.printEmptySpace(p.rowNumber, p.repeat);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
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 {
|
public static printTestPage(): NiimbotPacket {
|
||||||
@ -232,11 +282,11 @@ export class PacketGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static startFirmwareUpgrade(version: string): NiimbotPacket {
|
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)");
|
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]);
|
return this.mapped(TX.StartFirmwareUpgrade, [a, b]);
|
||||||
}
|
}
|
||||||
|
@ -17,20 +17,22 @@ export class B1PrintTask extends AbstractPrintTask {
|
|||||||
override printPage(image: EncodedImage, quantity?: number): Promise<void> {
|
override printPage(image: EncodedImage, quantity?: number): Promise<void> {
|
||||||
this.checkAddPage(quantity ?? 1);
|
this.checkAddPage(quantity ?? 1);
|
||||||
|
|
||||||
return this.abstraction.sendAll([
|
return this.abstraction.sendAll(
|
||||||
PacketGenerator.pageStart(),
|
[
|
||||||
PacketGenerator.setPageSizeV3(image.rows, image.cols, quantity ?? 1),
|
PacketGenerator.pageStart(),
|
||||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
PacketGenerator.setPageSizeV3(image.rows, image.cols, quantity ?? 1),
|
||||||
PacketGenerator.pageEnd(),
|
...PacketGenerator.writeImageData(image, { printheadPixels: this.printheadPixels() }),
|
||||||
], this.printOptions.pageTimeoutMs);
|
PacketGenerator.pageEnd(),
|
||||||
|
],
|
||||||
|
this.printOptions.pageTimeoutMs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override waitForFinished(): Promise<void> {
|
override waitForFinished(): Promise<void> {
|
||||||
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
||||||
|
|
||||||
return this.abstraction.waitUntilPrintFinishedByStatusPoll(
|
return this.abstraction
|
||||||
this.printOptions.totalPages,
|
.waitUntilPrintFinishedByStatusPoll(this.printOptions.totalPages, this.printOptions.statusPollIntervalMs)
|
||||||
this.printOptions.statusPollIntervalMs
|
.finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||||
).finally(() => this.abstraction.setDefaultPacketTimeout());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,22 +18,28 @@ export class B21V1PrintTask extends AbstractPrintTask {
|
|||||||
this.checkAddPage(quantity ?? 1);
|
this.checkAddPage(quantity ?? 1);
|
||||||
|
|
||||||
for (let i = 0; i < (quantity ?? 1); i++) {
|
for (let i = 0; i < (quantity ?? 1); i++) {
|
||||||
await this.abstraction.sendAll([
|
await this.abstraction.sendAll(
|
||||||
PacketGenerator.printClear(),
|
[
|
||||||
PacketGenerator.pageStart(),
|
// PacketGenerator.printClear(),
|
||||||
PacketGenerator.setPageSizeV2(image.rows, image.cols),
|
PacketGenerator.pageStart(),
|
||||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
PacketGenerator.setPageSizeV2(image.rows, image.cols),
|
||||||
PacketGenerator.pageEnd(),
|
...PacketGenerator.writeImageData(image, {
|
||||||
], this.printOptions.pageTimeoutMs);
|
countsMode: "total",
|
||||||
|
enableCheckLine: true,
|
||||||
|
printheadPixels: this.printheadPixels(),
|
||||||
|
}),
|
||||||
|
PacketGenerator.pageEnd(),
|
||||||
|
],
|
||||||
|
this.printOptions.pageTimeoutMs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override waitForFinished(): Promise<void> {
|
override waitForFinished(): Promise<void> {
|
||||||
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
||||||
|
|
||||||
return this.abstraction.waitUntilPrintFinishedByPrintEndPoll(
|
return this.abstraction
|
||||||
this.printOptions.totalPages,
|
.waitUntilPrintFinishedByPrintEndPoll(this.printOptions.totalPages, this.printOptions.statusPollIntervalMs)
|
||||||
this.printOptions.statusPollIntervalMs
|
.finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||||
).finally(() => this.abstraction.setDefaultPacketTimeout());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,22 +17,24 @@ export class D110PrintTask extends AbstractPrintTask {
|
|||||||
override printPage(image: EncodedImage, quantity?: number): Promise<void> {
|
override printPage(image: EncodedImage, quantity?: number): Promise<void> {
|
||||||
this.checkAddPage(quantity ?? 1);
|
this.checkAddPage(quantity ?? 1);
|
||||||
|
|
||||||
return this.abstraction.sendAll([
|
return this.abstraction.sendAll(
|
||||||
PacketGenerator.printClear(),
|
[
|
||||||
PacketGenerator.pageStart(),
|
PacketGenerator.printClear(),
|
||||||
PacketGenerator.setPageSizeV2(image.rows, image.cols),
|
PacketGenerator.pageStart(),
|
||||||
PacketGenerator.setPrintQuantity(quantity ?? 1),
|
PacketGenerator.setPageSizeV2(image.rows, image.cols),
|
||||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
PacketGenerator.setPrintQuantity(quantity ?? 1),
|
||||||
PacketGenerator.pageEnd(),
|
...PacketGenerator.writeImageData(image, { printheadPixels: this.printheadPixels() }),
|
||||||
], this.printOptions.pageTimeoutMs);
|
PacketGenerator.pageEnd(),
|
||||||
|
],
|
||||||
|
this.printOptions.pageTimeoutMs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override waitForFinished(): Promise<void> {
|
override waitForFinished(): Promise<void> {
|
||||||
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
||||||
|
|
||||||
return this.abstraction.waitUntilPrintFinishedByStatusPoll(
|
return this.abstraction
|
||||||
this.printOptions.totalPages,
|
.waitUntilPrintFinishedByStatusPoll(this.printOptions.totalPages, this.printOptions.statusPollIntervalMs)
|
||||||
this.printOptions.statusPollIntervalMs
|
.finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||||
).finally(() => this.abstraction.setDefaultPacketTimeout());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,17 @@ export class OldD11PrintTask extends AbstractPrintTask {
|
|||||||
override printPage(image: EncodedImage, quantity: number): Promise<void> {
|
override printPage(image: EncodedImage, quantity: number): Promise<void> {
|
||||||
this.checkAddPage(quantity ?? 1);
|
this.checkAddPage(quantity ?? 1);
|
||||||
|
|
||||||
return this.abstraction.sendAll([
|
return this.abstraction.sendAll(
|
||||||
PacketGenerator.printClear(),
|
[
|
||||||
PacketGenerator.pageStart(),
|
PacketGenerator.printClear(),
|
||||||
PacketGenerator.setPageSizeV1(image.rows),
|
PacketGenerator.pageStart(),
|
||||||
PacketGenerator.setPrintQuantity(quantity ?? 1),
|
PacketGenerator.setPageSizeV1(image.rows),
|
||||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
PacketGenerator.setPrintQuantity(quantity ?? 1),
|
||||||
PacketGenerator.pageEnd(),
|
...PacketGenerator.writeImageData(image, { printheadPixels: this.printheadPixels() }),
|
||||||
], this.printOptions.pageTimeoutMs);
|
PacketGenerator.pageEnd(),
|
||||||
|
],
|
||||||
|
this.printOptions.pageTimeoutMs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override waitForFinished(): Promise<void> {
|
override waitForFinished(): Promise<void> {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { EncodedImage } from "../image_encoder";
|
import { EncodedImage } from "../image_encoder";
|
||||||
import { PacketGenerator } from "../packets";
|
import { PacketGenerator } from "../packets";
|
||||||
import { AbstractPrintTask } from "./AbstractPrintTask";
|
import { AbstractPrintTask } from "./AbstractPrintTask";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10,27 +10,29 @@ export class V5PrintTask extends AbstractPrintTask {
|
|||||||
return this.abstraction.sendAll([
|
return this.abstraction.sendAll([
|
||||||
PacketGenerator.setDensity(this.printOptions.density),
|
PacketGenerator.setDensity(this.printOptions.density),
|
||||||
PacketGenerator.setLabelType(this.printOptions.labelType),
|
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> {
|
override printPage(image: EncodedImage, quantity?: number): Promise<void> {
|
||||||
this.checkAddPage(quantity ?? 1);
|
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.pageStart(),
|
||||||
...PacketGenerator.writeImageData(image, this.printheadPixels()),
|
PacketGenerator.setPageSizeV4(image.rows, image.cols, quantity ?? 1, 0, false),
|
||||||
PacketGenerator.pageEnd(),
|
...PacketGenerator.writeImageData(image, { printheadPixels: this.printheadPixels() }),
|
||||||
], this.printOptions.pageTimeoutMs);
|
PacketGenerator.pageEnd(),
|
||||||
|
],
|
||||||
|
this.printOptions.pageTimeoutMs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
override waitForFinished(): Promise<void> {
|
override waitForFinished(): Promise<void> {
|
||||||
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
this.abstraction.setPacketTimeout(this.printOptions.statusTimeoutMs);
|
||||||
|
|
||||||
return this.abstraction.waitUntilPrintFinishedByStatusPoll(
|
return this.abstraction
|
||||||
this.printOptions.totalPages ?? 1,
|
.waitUntilPrintFinishedByStatusPoll(this.printOptions.totalPages ?? 1, this.printOptions.statusPollIntervalMs)
|
||||||
this.printOptions.statusPollIntervalMs
|
.finally(() => this.abstraction.setDefaultPacketTimeout());
|
||||||
).finally(() => this.abstraction.setDefaultPacketTimeout());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user