@thermal-label/brother-ql-core 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -12
- package/data/devices.json +442 -24
- package/data/media.json +56 -56
- package/dist/__tests__/devices.test.js +1 -0
- package/dist/__tests__/devices.test.js.map +1 -1
- package/dist/__tests__/media.test.js +7 -7
- package/dist/__tests__/protocol.test.js +1 -1
- package/dist/__tests__/status.test.js +56 -15
- package/dist/__tests__/status.test.js.map +1 -1
- package/dist/devices.d.ts +711 -2
- package/dist/devices.d.ts.map +1 -1
- package/dist/devices.generated.d.ts +44 -11
- package/dist/devices.generated.d.ts.map +1 -1
- package/dist/devices.generated.js +77 -32
- package/dist/devices.generated.js.map +1 -1
- package/dist/devices.js +6 -2
- package/dist/devices.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/media.d.ts +1 -1
- package/dist/media.generated.d.ts.map +1 -1
- package/dist/media.generated.js +114 -112
- package/dist/media.generated.js.map +1 -1
- package/dist/media.js +3 -3
- package/dist/protocol.js +4 -4
- package/dist/status.d.ts +8 -5
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +43 -7
- package/dist/status.js.map +1 -1
- package/dist/types.d.ts +7 -14
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/devices.test.ts +1 -0
- package/src/__tests__/media.test.ts +7 -7
- package/src/__tests__/protocol.test.ts +1 -1
- package/src/__tests__/status.test.ts +66 -16
- package/src/devices.generated.ts +98 -40
- package/src/devices.ts +7 -2
- package/src/index.ts +10 -0
- package/src/media.generated.ts +115 -114
- package/src/media.ts +3 -3
- package/src/protocol.ts +4 -4
- package/src/status.ts +47 -8
- package/src/types.ts +7 -14
package/src/media.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { MEDIA };
|
|
|
8
8
|
* Resolve per-head-family geometry for a media entry against the
|
|
9
9
|
* engine that's about to print it.
|
|
10
10
|
*
|
|
11
|
-
* DK entries fall back to the flat `
|
|
11
|
+
* DK entries fall back to the flat `printableDots` / `leftMarginPins` /
|
|
12
12
|
* `rightMarginPins` fields on the entry — the same values every QL
|
|
13
13
|
* code path read before the head-family split landed. TZe and HSe
|
|
14
14
|
* entries dispatch on `engine.headDots`: 128 picks `geometry.narrow`,
|
|
@@ -23,14 +23,14 @@ export function resolveTapeGeometry(
|
|
|
23
23
|
): TapeGeometry {
|
|
24
24
|
if (media.tapeSystem === 'dk') {
|
|
25
25
|
if (
|
|
26
|
-
typeof media.
|
|
26
|
+
typeof media.printableDots !== 'number' ||
|
|
27
27
|
typeof media.leftMarginPins !== 'number' ||
|
|
28
28
|
typeof media.rightMarginPins !== 'number'
|
|
29
29
|
) {
|
|
30
30
|
throw new Error(`DK media ${media.id.toString()} missing flat geometry fields`);
|
|
31
31
|
}
|
|
32
32
|
return {
|
|
33
|
-
|
|
33
|
+
printableDots: media.printableDots,
|
|
34
34
|
leftMarginPins: media.leftMarginPins,
|
|
35
35
|
rightMarginPins: media.rightMarginPins,
|
|
36
36
|
};
|
package/src/protocol.ts
CHANGED
|
@@ -229,14 +229,14 @@ function resolveEncoderGeometry(
|
|
|
229
229
|
): TapeGeometry {
|
|
230
230
|
if (media.tapeSystem === 'dk') {
|
|
231
231
|
if (
|
|
232
|
-
typeof media.
|
|
232
|
+
typeof media.printableDots !== 'number' ||
|
|
233
233
|
typeof media.leftMarginPins !== 'number' ||
|
|
234
234
|
typeof media.rightMarginPins !== 'number'
|
|
235
235
|
) {
|
|
236
236
|
throw new Error(`DK media ${media.id.toString()} missing flat geometry fields`);
|
|
237
237
|
}
|
|
238
238
|
return {
|
|
239
|
-
|
|
239
|
+
printableDots: media.printableDots,
|
|
240
240
|
leftMarginPins: media.leftMarginPins,
|
|
241
241
|
rightMarginPins: media.rightMarginPins,
|
|
242
242
|
};
|
|
@@ -329,10 +329,10 @@ function encodeRasterJob(pages: PageData[], options: JobOptions, ctx: EncodeCont
|
|
|
329
329
|
if (compress) chunks.push(buildCompression(true));
|
|
330
330
|
|
|
331
331
|
// Each raster row must cover the full print head width (derived from media geometry).
|
|
332
|
-
// leftMarginPins +
|
|
332
|
+
// leftMarginPins + printableDots + rightMarginPins = head pin count (720 / 1296 / 128 / 560).
|
|
333
333
|
const geometry = resolveEncoderGeometry(media, engine);
|
|
334
334
|
const leftMarginPins = geometry.leftMarginPins;
|
|
335
|
-
const totalPins = leftMarginPins + geometry.
|
|
335
|
+
const totalPins = leftMarginPins + geometry.printableDots + geometry.rightMarginPins;
|
|
336
336
|
const rowByteLen = Math.ceil(totalPins / 8);
|
|
337
337
|
|
|
338
338
|
// Rows interleaved per raster line (matches Python brother_ql behaviour).
|
package/src/status.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PrintEngine, PrinterError } from '@thermal-label/contracts';
|
|
1
|
+
import type { PrintEngine, PrinterError, StatusDetail } from '@thermal-label/contracts';
|
|
2
2
|
import type { BrotherQLStatus } from './types.js';
|
|
3
3
|
import { findMediaByDimensions } from './media.js';
|
|
4
4
|
|
|
@@ -37,15 +37,18 @@ const ERROR_INFO_2: { bit: number; code: string; message: string }[] = [
|
|
|
37
37
|
* byte 11 — media type (0x0A continuous, 0x0B die-cut)
|
|
38
38
|
* byte 17 — media length (mm), 0 for continuous
|
|
39
39
|
* byte 18 — status type (0x02 = error response)
|
|
40
|
+
* byte 19 — phase type (0x00 receiving, 0x01 printing)
|
|
41
|
+
* byte 22 — notification (0x03 cooling started, 0x04 cooling finished)
|
|
40
42
|
* byte 25 — bit 7 set when the loaded roll is two-color (DK-22251);
|
|
41
43
|
* clear on single-color rolls. See scripts/STATUS-CAPTURE.md.
|
|
42
44
|
*
|
|
43
45
|
* `detectedMedia` is resolved against the media registry via
|
|
44
|
-
* `findMediaByDimensions`.
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
46
|
+
* `findMediaByDimensions`.
|
|
47
|
+
*
|
|
48
|
+
* `details` carries the contracts-standard `StatusDetail[]` diagnostic
|
|
49
|
+
* rows the harness renders verbatim: the print phase (always present)
|
|
50
|
+
* and the head-cooling notification (only when the printer reports
|
|
51
|
+
* one).
|
|
49
52
|
*/
|
|
50
53
|
export function parseStatus(
|
|
51
54
|
bytes: Uint8Array,
|
|
@@ -62,6 +65,8 @@ export function parseStatus(
|
|
|
62
65
|
const mediaTypeByte = view.getUint8(11);
|
|
63
66
|
const mediaLengthMm = view.getUint8(17);
|
|
64
67
|
const statusType = view.getUint8(18);
|
|
68
|
+
const phaseType = view.getUint8(19);
|
|
69
|
+
const notification = view.getUint8(22);
|
|
65
70
|
const twoColorFlag = (view.getUint8(25) & 0x80) !== 0;
|
|
66
71
|
|
|
67
72
|
const errors: PrinterError[] = [];
|
|
@@ -81,9 +86,43 @@ export function parseStatus(
|
|
|
81
86
|
ready: errors.length === 0 && statusType !== 0x02,
|
|
82
87
|
mediaLoaded,
|
|
83
88
|
...(detected === undefined ? {} : { detectedMedia: detected }),
|
|
84
|
-
...(mediaLoaded ? { twoColorRoll: twoColorFlag } : {}),
|
|
85
89
|
errors,
|
|
86
|
-
|
|
90
|
+
details: buildStatusDetails(phaseType, notification),
|
|
87
91
|
rawBytes: bytes,
|
|
88
92
|
};
|
|
89
93
|
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Build the contracts-standard `StatusDetail[]` rows for a parsed
|
|
97
|
+
* Brother QL status.
|
|
98
|
+
*
|
|
99
|
+
* - The print-phase row (byte 19) is always emitted — it is the most
|
|
100
|
+
* useful "is the device doing anything" signal for a stuck report.
|
|
101
|
+
* - The head-cooling row (byte 22) is emitted only when the printer
|
|
102
|
+
* reports a cooling notification; `0x00` (none) produces no row so a
|
|
103
|
+
* normal idle status stays uncluttered. "Cooling started" is a
|
|
104
|
+
* `warn` (printing is paused), "cooling finished" is plain `info`.
|
|
105
|
+
*/
|
|
106
|
+
function buildStatusDetails(phaseType: number, notification: number): StatusDetail[] {
|
|
107
|
+
const details: StatusDetail[] = [];
|
|
108
|
+
|
|
109
|
+
details.push({
|
|
110
|
+
label: 'Print phase',
|
|
111
|
+
value: phaseType === 0x01 ? 'printing' : 'receiving',
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (notification === 0x03) {
|
|
115
|
+
details.push({
|
|
116
|
+
label: 'Head cooling',
|
|
117
|
+
value: 'cooling started',
|
|
118
|
+
severity: 'warn',
|
|
119
|
+
});
|
|
120
|
+
} else if (notification === 0x04) {
|
|
121
|
+
details.push({
|
|
122
|
+
label: 'Head cooling',
|
|
123
|
+
value: 'cooling finished',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return details;
|
|
128
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -25,13 +25,13 @@ export type TapeSystem = 'dk' | 'tze' | 'hse-2to1' | 'hse-3to1';
|
|
|
25
25
|
*
|
|
26
26
|
* Brother's PT-P / PT-E line ships two head families with different
|
|
27
27
|
* per-tape pin layouts. The same TZe id maps to different
|
|
28
|
-
* `
|
|
28
|
+
* `printableDots` / `leftMarginPins` / `rightMarginPins` values on a
|
|
29
29
|
* 128-pin head (PT-E550W, PT-P750W) versus a 560-pin head (PT-P900,
|
|
30
30
|
* P900W, P950NW, P910BT). DK media leaves these unset and resolves via
|
|
31
31
|
* the flat fields on `BrotherQLMedia` directly.
|
|
32
32
|
*/
|
|
33
33
|
export interface TapeGeometry {
|
|
34
|
-
|
|
34
|
+
printableDots: number;
|
|
35
35
|
leftMarginPins: number;
|
|
36
36
|
rightMarginPins: number;
|
|
37
37
|
}
|
|
@@ -104,7 +104,7 @@ export interface BrotherQLMedia extends MediaDescriptor {
|
|
|
104
104
|
*/
|
|
105
105
|
geometry?: { narrow?: TapeGeometry; wide?: TapeGeometry };
|
|
106
106
|
/** DK-only flat geometry. PT-* entries populate `geometry` instead. */
|
|
107
|
-
|
|
107
|
+
printableDots?: number;
|
|
108
108
|
leftMarginPins?: number;
|
|
109
109
|
rightMarginPins?: number;
|
|
110
110
|
/** Die-cut masked area in dots (registration windows). */
|
|
@@ -112,18 +112,11 @@ export interface BrotherQLMedia extends MediaDescriptor {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
|
-
* Brother QL status —
|
|
116
|
-
*
|
|
117
|
-
*
|
|
115
|
+
* Brother QL status — the plain contract `PrinterStatus`. Brother QL
|
|
116
|
+
* adds no structural extension: driver-specific diagnostic facts (print
|
|
117
|
+
* phase, head cooling) ride in the contract-standard `details[]` rows.
|
|
118
118
|
*/
|
|
119
|
-
export
|
|
120
|
-
editorLiteMode: boolean;
|
|
121
|
-
/**
|
|
122
|
-
* True when the loaded roll reports two-color capability via byte 25
|
|
123
|
-
* bit 7 of the status response. Undefined when no media is loaded.
|
|
124
|
-
*/
|
|
125
|
-
twoColorRoll?: boolean;
|
|
126
|
-
}
|
|
119
|
+
export type BrotherQLStatus = PrinterStatus;
|
|
127
120
|
|
|
128
121
|
export interface PageData {
|
|
129
122
|
bitmap: LabelBitmap;
|