@thermal-label/brother-ql-core 0.0.1 → 0.2.1
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/dist/__tests__/colour.test.d.ts +2 -0
- package/dist/__tests__/colour.test.d.ts.map +1 -0
- package/dist/__tests__/colour.test.js +106 -0
- package/dist/__tests__/colour.test.js.map +1 -0
- package/dist/__tests__/devices.test.js +16 -2
- package/dist/__tests__/devices.test.js.map +1 -1
- package/dist/__tests__/media.test.js +17 -6
- package/dist/__tests__/media.test.js.map +1 -1
- package/dist/__tests__/preview.test.d.ts +2 -0
- package/dist/__tests__/preview.test.d.ts.map +1 -0
- package/dist/__tests__/preview.test.js +41 -0
- package/dist/__tests__/preview.test.js.map +1 -0
- package/dist/__tests__/status.test.js +28 -22
- package/dist/__tests__/status.test.js.map +1 -1
- package/dist/colour.d.ts +26 -0
- package/dist/colour.d.ts.map +1 -0
- package/dist/colour.js +84 -0
- package/dist/colour.js.map +1 -0
- package/dist/devices.d.ts +40 -21
- package/dist/devices.d.ts.map +1 -1
- package/dist/devices.js +38 -19
- package/dist/devices.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/media.d.ts +31 -4
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +73 -23
- package/dist/media.js.map +1 -1
- package/dist/preview.d.ts +13 -0
- package/dist/preview.d.ts.map +1 -0
- package/dist/preview.js +32 -0
- package/dist/preview.js.map +1 -0
- package/dist/protocol.d.ts +2 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +4 -4
- package/dist/protocol.js.map +1 -1
- package/dist/status.d.ts +20 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +59 -44
- package/dist/status.js.map +1 -1
- package/dist/types.d.ts +36 -30
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -2
- package/src/__tests__/colour.test.ts +126 -0
- package/src/__tests__/devices.test.ts +18 -2
- package/src/__tests__/media.test.ts +17 -6
- package/src/__tests__/preview.test.ts +52 -0
- package/src/__tests__/status.test.ts +31 -22
- package/src/colour.ts +101 -0
- package/src/devices.ts +41 -22
- package/src/index.ts +31 -9
- package/src/media.ts +86 -27
- package/src/preview.ts +34 -0
- package/src/protocol.ts +6 -6
- package/src/status.ts +63 -47
- package/src/types.ts +38 -33
package/src/devices.ts
CHANGED
|
@@ -1,199 +1,214 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type BrotherQLDevice } from './types.js';
|
|
2
2
|
|
|
3
3
|
const MASS_STORAGE_PIDS = new Set([0x20aa, 0x20ab]);
|
|
4
4
|
|
|
5
5
|
export const DEVICES = {
|
|
6
6
|
QL_820NWB: {
|
|
7
7
|
name: 'QL-820NWB',
|
|
8
|
+
family: 'brother-ql',
|
|
9
|
+
transports: ['usb', 'webusb', 'tcp', 'serial', 'web-serial'],
|
|
8
10
|
vid: 0x04f9,
|
|
9
11
|
pid: 0x20a7,
|
|
10
12
|
headPins: 720,
|
|
11
13
|
bytesPerRow: 90,
|
|
12
14
|
twoColor: true,
|
|
13
15
|
network: 'wifi+wired',
|
|
14
|
-
bluetooth: false,
|
|
15
16
|
autocut: true,
|
|
16
17
|
compression: true,
|
|
17
18
|
editorLite: true,
|
|
18
19
|
},
|
|
19
20
|
QL_820NWBc: {
|
|
20
21
|
name: 'QL-820NWBc',
|
|
22
|
+
family: 'brother-ql',
|
|
23
|
+
transports: ['usb', 'webusb', 'tcp', 'serial', 'web-serial'],
|
|
21
24
|
vid: 0x04f9,
|
|
22
25
|
pid: 0x209d,
|
|
23
26
|
headPins: 720,
|
|
24
27
|
bytesPerRow: 90,
|
|
25
28
|
twoColor: true,
|
|
26
29
|
network: 'wifi+wired',
|
|
27
|
-
bluetooth: false,
|
|
28
30
|
autocut: true,
|
|
29
31
|
compression: true,
|
|
30
32
|
editorLite: true,
|
|
31
33
|
},
|
|
32
34
|
QL_810W: {
|
|
33
35
|
name: 'QL-810W',
|
|
36
|
+
family: 'brother-ql',
|
|
37
|
+
transports: ['usb', 'webusb', 'tcp'],
|
|
34
38
|
vid: 0x04f9,
|
|
35
39
|
pid: 0x209c,
|
|
36
40
|
headPins: 720,
|
|
37
41
|
bytesPerRow: 90,
|
|
38
42
|
twoColor: true,
|
|
39
43
|
network: 'wifi',
|
|
40
|
-
bluetooth: false,
|
|
41
44
|
autocut: true,
|
|
42
45
|
compression: true,
|
|
43
46
|
editorLite: true,
|
|
44
47
|
},
|
|
45
48
|
QL_800: {
|
|
46
49
|
name: 'QL-800',
|
|
50
|
+
family: 'brother-ql',
|
|
51
|
+
transports: ['usb', 'webusb'],
|
|
47
52
|
vid: 0x04f9,
|
|
48
53
|
pid: 0x209b,
|
|
49
54
|
headPins: 720,
|
|
50
55
|
bytesPerRow: 90,
|
|
51
56
|
twoColor: true,
|
|
52
57
|
network: 'none',
|
|
53
|
-
bluetooth: false,
|
|
54
58
|
autocut: true,
|
|
55
59
|
compression: true,
|
|
56
60
|
editorLite: true,
|
|
57
61
|
},
|
|
58
62
|
QL_720NW: {
|
|
59
63
|
name: 'QL-720NW',
|
|
64
|
+
family: 'brother-ql',
|
|
65
|
+
transports: ['usb', 'webusb', 'tcp'],
|
|
60
66
|
vid: 0x04f9,
|
|
61
67
|
pid: 0x2045,
|
|
62
68
|
headPins: 720,
|
|
63
69
|
bytesPerRow: 90,
|
|
64
70
|
twoColor: false,
|
|
65
71
|
network: 'wired',
|
|
66
|
-
bluetooth: false,
|
|
67
72
|
autocut: true,
|
|
68
73
|
compression: true,
|
|
69
74
|
editorLite: false,
|
|
70
75
|
},
|
|
71
76
|
QL_710W: {
|
|
72
77
|
name: 'QL-710W',
|
|
78
|
+
family: 'brother-ql',
|
|
79
|
+
transports: ['usb', 'webusb', 'tcp'],
|
|
73
80
|
vid: 0x04f9,
|
|
74
81
|
pid: 0x2044,
|
|
75
82
|
headPins: 720,
|
|
76
83
|
bytesPerRow: 90,
|
|
77
84
|
twoColor: false,
|
|
78
85
|
network: 'wifi',
|
|
79
|
-
bluetooth: false,
|
|
80
86
|
autocut: true,
|
|
81
87
|
compression: true,
|
|
82
88
|
editorLite: true,
|
|
83
89
|
},
|
|
84
90
|
QL_700: {
|
|
85
91
|
name: 'QL-700',
|
|
92
|
+
family: 'brother-ql',
|
|
93
|
+
transports: ['usb', 'webusb'],
|
|
86
94
|
vid: 0x04f9,
|
|
87
95
|
pid: 0x2042,
|
|
88
96
|
headPins: 720,
|
|
89
97
|
bytesPerRow: 90,
|
|
90
98
|
twoColor: false,
|
|
91
99
|
network: 'none',
|
|
92
|
-
bluetooth: false,
|
|
93
100
|
autocut: true,
|
|
94
101
|
compression: true,
|
|
95
102
|
editorLite: true,
|
|
96
103
|
},
|
|
97
104
|
QL_600: {
|
|
98
105
|
name: 'QL-600',
|
|
106
|
+
family: 'brother-ql',
|
|
107
|
+
transports: ['usb', 'webusb'],
|
|
99
108
|
vid: 0x04f9,
|
|
100
109
|
pid: 0x2100,
|
|
101
110
|
headPins: 720,
|
|
102
111
|
bytesPerRow: 90,
|
|
103
112
|
twoColor: false,
|
|
104
113
|
network: 'none',
|
|
105
|
-
bluetooth: false,
|
|
106
114
|
autocut: true,
|
|
107
115
|
compression: true,
|
|
108
116
|
editorLite: false,
|
|
109
117
|
},
|
|
110
118
|
QL_580N: {
|
|
111
119
|
name: 'QL-580N',
|
|
120
|
+
family: 'brother-ql',
|
|
121
|
+
transports: ['usb', 'webusb', 'tcp'],
|
|
112
122
|
vid: 0x04f9,
|
|
113
123
|
pid: 0x201b,
|
|
114
124
|
headPins: 720,
|
|
115
125
|
bytesPerRow: 90,
|
|
116
126
|
twoColor: false,
|
|
117
127
|
network: 'wired',
|
|
118
|
-
bluetooth: false,
|
|
119
128
|
autocut: true,
|
|
120
129
|
compression: true,
|
|
121
130
|
editorLite: false,
|
|
122
131
|
},
|
|
123
132
|
QL_570: {
|
|
124
133
|
name: 'QL-570',
|
|
134
|
+
family: 'brother-ql',
|
|
135
|
+
transports: ['usb', 'webusb'],
|
|
125
136
|
vid: 0x04f9,
|
|
126
137
|
pid: 0x2019,
|
|
127
138
|
headPins: 720,
|
|
128
139
|
bytesPerRow: 90,
|
|
129
140
|
twoColor: false,
|
|
130
141
|
network: 'none',
|
|
131
|
-
bluetooth: false,
|
|
132
142
|
autocut: true,
|
|
133
143
|
compression: true,
|
|
134
144
|
editorLite: false,
|
|
135
145
|
},
|
|
136
146
|
QL_560: {
|
|
137
147
|
name: 'QL-560',
|
|
148
|
+
family: 'brother-ql',
|
|
149
|
+
transports: ['usb', 'webusb'],
|
|
138
150
|
vid: 0x04f9,
|
|
139
151
|
pid: 0x2018,
|
|
140
152
|
headPins: 720,
|
|
141
153
|
bytesPerRow: 90,
|
|
142
154
|
twoColor: false,
|
|
143
155
|
network: 'none',
|
|
144
|
-
bluetooth: false,
|
|
145
156
|
autocut: true,
|
|
146
157
|
compression: false,
|
|
147
158
|
editorLite: false,
|
|
148
159
|
},
|
|
149
160
|
QL_550: {
|
|
150
161
|
name: 'QL-550',
|
|
162
|
+
family: 'brother-ql',
|
|
163
|
+
transports: ['usb', 'webusb'],
|
|
151
164
|
vid: 0x04f9,
|
|
152
165
|
pid: 0x2016,
|
|
153
166
|
headPins: 720,
|
|
154
167
|
bytesPerRow: 90,
|
|
155
168
|
twoColor: false,
|
|
156
169
|
network: 'none',
|
|
157
|
-
bluetooth: false,
|
|
158
170
|
autocut: false,
|
|
159
171
|
compression: false,
|
|
160
172
|
editorLite: false,
|
|
161
173
|
},
|
|
162
174
|
QL_500: {
|
|
163
175
|
name: 'QL-500',
|
|
176
|
+
family: 'brother-ql',
|
|
177
|
+
transports: ['usb', 'webusb'],
|
|
164
178
|
vid: 0x04f9,
|
|
165
179
|
pid: 0x2013,
|
|
166
180
|
headPins: 720,
|
|
167
181
|
bytesPerRow: 90,
|
|
168
182
|
twoColor: false,
|
|
169
183
|
network: 'none',
|
|
170
|
-
bluetooth: false,
|
|
171
184
|
autocut: false,
|
|
172
185
|
compression: false,
|
|
173
186
|
editorLite: false,
|
|
174
187
|
},
|
|
175
188
|
QL_650TD: {
|
|
176
189
|
name: 'QL-650TD',
|
|
190
|
+
family: 'brother-ql',
|
|
191
|
+
transports: ['usb', 'webusb'],
|
|
177
192
|
vid: 0x04f9,
|
|
178
193
|
pid: 0x201c,
|
|
179
194
|
headPins: 720,
|
|
180
195
|
bytesPerRow: 90,
|
|
181
196
|
twoColor: false,
|
|
182
197
|
network: 'none',
|
|
183
|
-
bluetooth: false,
|
|
184
198
|
autocut: true,
|
|
185
199
|
compression: true,
|
|
186
200
|
editorLite: false,
|
|
187
201
|
},
|
|
188
202
|
QL_1100: {
|
|
189
203
|
name: 'QL-1100',
|
|
204
|
+
family: 'brother-ql',
|
|
205
|
+
transports: ['usb', 'webusb'],
|
|
190
206
|
vid: 0x04f9,
|
|
191
207
|
pid: 0x20a8,
|
|
192
208
|
headPins: 1296,
|
|
193
209
|
bytesPerRow: 162,
|
|
194
210
|
twoColor: false,
|
|
195
211
|
network: 'none',
|
|
196
|
-
bluetooth: false,
|
|
197
212
|
autocut: true,
|
|
198
213
|
compression: true,
|
|
199
214
|
editorLite: true,
|
|
@@ -201,13 +216,14 @@ export const DEVICES = {
|
|
|
201
216
|
},
|
|
202
217
|
QL_1110NWB: {
|
|
203
218
|
name: 'QL-1110NWB',
|
|
219
|
+
family: 'brother-ql',
|
|
220
|
+
transports: ['usb', 'webusb', 'tcp'],
|
|
204
221
|
vid: 0x04f9,
|
|
205
222
|
pid: 0x20a9,
|
|
206
223
|
headPins: 1296,
|
|
207
224
|
bytesPerRow: 162,
|
|
208
225
|
twoColor: false,
|
|
209
226
|
network: 'wifi+wired',
|
|
210
|
-
bluetooth: false,
|
|
211
227
|
autocut: true,
|
|
212
228
|
compression: true,
|
|
213
229
|
editorLite: true,
|
|
@@ -215,46 +231,49 @@ export const DEVICES = {
|
|
|
215
231
|
},
|
|
216
232
|
QL_1115NWB: {
|
|
217
233
|
name: 'QL-1115NWB',
|
|
234
|
+
family: 'brother-ql',
|
|
235
|
+
transports: ['usb', 'webusb', 'tcp'],
|
|
218
236
|
vid: 0x04f9,
|
|
219
237
|
pid: 0x20ac,
|
|
220
238
|
headPins: 1296,
|
|
221
239
|
bytesPerRow: 162,
|
|
222
240
|
twoColor: false,
|
|
223
241
|
network: 'wifi+wired',
|
|
224
|
-
bluetooth: false,
|
|
225
242
|
autocut: true,
|
|
226
243
|
compression: true,
|
|
227
244
|
editorLite: true,
|
|
228
245
|
},
|
|
229
246
|
QL_1050: {
|
|
230
247
|
name: 'QL-1050',
|
|
248
|
+
family: 'brother-ql',
|
|
249
|
+
transports: ['usb', 'webusb'],
|
|
231
250
|
vid: 0x04f9,
|
|
232
251
|
pid: 0x2027,
|
|
233
252
|
headPins: 1296,
|
|
234
253
|
bytesPerRow: 162,
|
|
235
254
|
twoColor: false,
|
|
236
255
|
network: 'none',
|
|
237
|
-
bluetooth: false,
|
|
238
256
|
autocut: true,
|
|
239
257
|
compression: true,
|
|
240
258
|
editorLite: false,
|
|
241
259
|
},
|
|
242
260
|
QL_1060N: {
|
|
243
261
|
name: 'QL-1060N',
|
|
262
|
+
family: 'brother-ql',
|
|
263
|
+
transports: ['usb', 'webusb', 'tcp'],
|
|
244
264
|
vid: 0x04f9,
|
|
245
265
|
pid: 0x2028,
|
|
246
266
|
headPins: 1296,
|
|
247
267
|
bytesPerRow: 162,
|
|
248
268
|
twoColor: false,
|
|
249
269
|
network: 'wired',
|
|
250
|
-
bluetooth: false,
|
|
251
270
|
autocut: true,
|
|
252
271
|
compression: true,
|
|
253
272
|
editorLite: false,
|
|
254
273
|
},
|
|
255
|
-
} as const satisfies Record<string,
|
|
274
|
+
} as const satisfies Record<string, BrotherQLDevice>;
|
|
256
275
|
|
|
257
|
-
export function findDevice(vid: number, pid: number):
|
|
276
|
+
export function findDevice(vid: number, pid: number): BrotherQLDevice | undefined {
|
|
258
277
|
return Object.values(DEVICES).find(d => d.vid === vid && d.pid === pid);
|
|
259
278
|
}
|
|
260
279
|
|
package/src/index.ts
CHANGED
|
@@ -1,22 +1,44 @@
|
|
|
1
1
|
export type { LabelBitmap, RawImageData } from '@mbtech-nl/bitmap';
|
|
2
2
|
export { renderText, renderImage, rotateBitmap, flipHorizontal } from '@mbtech-nl/bitmap';
|
|
3
3
|
|
|
4
|
+
export type {
|
|
5
|
+
DeviceDescriptor,
|
|
6
|
+
MediaDescriptor,
|
|
7
|
+
PreviewOptions,
|
|
8
|
+
PreviewPlane,
|
|
9
|
+
PreviewResult,
|
|
10
|
+
PrintOptions,
|
|
11
|
+
PrinterAdapter,
|
|
12
|
+
PrinterError,
|
|
13
|
+
PrinterStatus,
|
|
14
|
+
Transport,
|
|
15
|
+
TransportType,
|
|
16
|
+
} from '@thermal-label/contracts';
|
|
17
|
+
|
|
18
|
+
export { MediaNotSpecifiedError, UnsupportedOperationError } from '@thermal-label/contracts';
|
|
19
|
+
|
|
4
20
|
export { DEVICES, findDevice, isMassStorageMode } from './devices.js';
|
|
5
|
-
export {
|
|
21
|
+
export {
|
|
22
|
+
DEFAULT_MEDIA,
|
|
23
|
+
MEDIA,
|
|
24
|
+
findMedia,
|
|
25
|
+
findMediaByDimensions,
|
|
26
|
+
findMediaByWidth,
|
|
27
|
+
} from './media.js';
|
|
6
28
|
export { encodeJob } from './protocol.js';
|
|
7
29
|
export { parseStatus, STATUS_REQUEST } from './status.js';
|
|
30
|
+
export { isRedish, splitTwoColor, type TwoColorOptions, type TwoColorResult } from './colour.js';
|
|
31
|
+
export { createPreviewOffline } from './preview.js';
|
|
8
32
|
|
|
9
33
|
export type {
|
|
10
|
-
|
|
11
|
-
|
|
34
|
+
BrotherQLDevice,
|
|
35
|
+
BrotherQLMedia,
|
|
36
|
+
BrotherQLStatus,
|
|
12
37
|
ColorMode,
|
|
38
|
+
HeadWidth,
|
|
39
|
+
JobOptions,
|
|
40
|
+
MediaType,
|
|
13
41
|
NetworkSupport,
|
|
14
|
-
DeviceDescriptor,
|
|
15
|
-
MediaDescriptor,
|
|
16
42
|
PageData,
|
|
17
43
|
PageOptions,
|
|
18
|
-
JobOptions,
|
|
19
|
-
PrinterStatus,
|
|
20
|
-
TextPrintOptions,
|
|
21
|
-
ImagePrintOptions,
|
|
22
44
|
} from './types.js';
|
package/src/media.ts
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type BrotherQLMedia, type MediaType } from './types.js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Registry of supported Brother QL consumables.
|
|
5
|
+
*
|
|
6
|
+
* Entries are keyed by the firmware media id — the same number the
|
|
7
|
+
* printer reports in the 32-byte status response. `heightMm` is
|
|
8
|
+
* omitted for continuous media (variable length) and set for die-cut
|
|
9
|
+
* labels (fixed length). Only DK-22251 has `colorCapable: true` — the
|
|
10
|
+
* driver uses that to run two-colour plane separation before sending
|
|
11
|
+
* the raster.
|
|
12
|
+
*/
|
|
13
|
+
export const MEDIA: Record<number, BrotherQLMedia> = {
|
|
4
14
|
// Continuous length tape
|
|
5
15
|
257: {
|
|
6
16
|
id: 257,
|
|
7
17
|
name: '12mm continuous',
|
|
8
18
|
type: 'continuous',
|
|
9
19
|
widthMm: 12,
|
|
10
|
-
|
|
20
|
+
colorCapable: false,
|
|
11
21
|
printAreaDots: 106,
|
|
12
22
|
leftMarginPins: 585,
|
|
13
23
|
rightMarginPins: 29,
|
|
@@ -17,7 +27,7 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
17
27
|
name: '29mm continuous (DK-22210)',
|
|
18
28
|
type: 'continuous',
|
|
19
29
|
widthMm: 29,
|
|
20
|
-
|
|
30
|
+
colorCapable: false,
|
|
21
31
|
printAreaDots: 306,
|
|
22
32
|
leftMarginPins: 408,
|
|
23
33
|
rightMarginPins: 6,
|
|
@@ -27,7 +37,7 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
27
37
|
name: '38mm continuous (DK-22225)',
|
|
28
38
|
type: 'continuous',
|
|
29
39
|
widthMm: 38,
|
|
30
|
-
|
|
40
|
+
colorCapable: false,
|
|
31
41
|
printAreaDots: 413,
|
|
32
42
|
leftMarginPins: 295,
|
|
33
43
|
rightMarginPins: 12,
|
|
@@ -37,7 +47,7 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
37
47
|
name: '50mm continuous (DK-22246)',
|
|
38
48
|
type: 'continuous',
|
|
39
49
|
widthMm: 50,
|
|
40
|
-
|
|
50
|
+
colorCapable: false,
|
|
41
51
|
printAreaDots: 554,
|
|
42
52
|
leftMarginPins: 154,
|
|
43
53
|
rightMarginPins: 12,
|
|
@@ -47,7 +57,7 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
47
57
|
name: '54mm continuous (DK-22214)',
|
|
48
58
|
type: 'continuous',
|
|
49
59
|
widthMm: 54,
|
|
50
|
-
|
|
60
|
+
colorCapable: false,
|
|
51
61
|
printAreaDots: 590,
|
|
52
62
|
leftMarginPins: 130,
|
|
53
63
|
rightMarginPins: 0,
|
|
@@ -57,7 +67,7 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
57
67
|
name: '62mm continuous (DK-22205)',
|
|
58
68
|
type: 'continuous',
|
|
59
69
|
widthMm: 62,
|
|
60
|
-
|
|
70
|
+
colorCapable: false,
|
|
61
71
|
printAreaDots: 696,
|
|
62
72
|
leftMarginPins: 12,
|
|
63
73
|
rightMarginPins: 12,
|
|
@@ -67,18 +77,17 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
67
77
|
name: '62mm continuous two-color (DK-22251)',
|
|
68
78
|
type: 'continuous',
|
|
69
79
|
widthMm: 62,
|
|
70
|
-
|
|
80
|
+
colorCapable: true,
|
|
71
81
|
printAreaDots: 696,
|
|
72
82
|
leftMarginPins: 12,
|
|
73
83
|
rightMarginPins: 12,
|
|
74
|
-
twoColorTape: true,
|
|
75
84
|
},
|
|
76
85
|
260: {
|
|
77
86
|
id: 260,
|
|
78
87
|
name: '102mm continuous (DK-22243)',
|
|
79
88
|
type: 'continuous',
|
|
80
89
|
widthMm: 102,
|
|
81
|
-
|
|
90
|
+
colorCapable: false,
|
|
82
91
|
printAreaDots: 1164,
|
|
83
92
|
leftMarginPins: 76,
|
|
84
93
|
rightMarginPins: 56,
|
|
@@ -90,7 +99,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
90
99
|
name: '17×54mm die-cut (DK-11204)',
|
|
91
100
|
type: 'die-cut',
|
|
92
101
|
widthMm: 17,
|
|
93
|
-
|
|
102
|
+
heightMm: 54,
|
|
103
|
+
colorCapable: false,
|
|
94
104
|
printAreaDots: 165,
|
|
95
105
|
leftMarginPins: 0,
|
|
96
106
|
rightMarginPins: 0,
|
|
@@ -101,7 +111,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
101
111
|
name: '17×87mm die-cut (DK-11203)',
|
|
102
112
|
type: 'die-cut',
|
|
103
113
|
widthMm: 17,
|
|
104
|
-
|
|
114
|
+
heightMm: 87,
|
|
115
|
+
colorCapable: false,
|
|
105
116
|
printAreaDots: 165,
|
|
106
117
|
leftMarginPins: 0,
|
|
107
118
|
rightMarginPins: 0,
|
|
@@ -112,7 +123,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
112
123
|
name: '23×23mm die-cut',
|
|
113
124
|
type: 'die-cut',
|
|
114
125
|
widthMm: 23,
|
|
115
|
-
|
|
126
|
+
heightMm: 23,
|
|
127
|
+
colorCapable: false,
|
|
116
128
|
printAreaDots: 236,
|
|
117
129
|
leftMarginPins: 0,
|
|
118
130
|
rightMarginPins: 0,
|
|
@@ -123,7 +135,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
123
135
|
name: '29×90mm die-cut (DK-11201)',
|
|
124
136
|
type: 'die-cut',
|
|
125
137
|
widthMm: 29,
|
|
126
|
-
|
|
138
|
+
heightMm: 90,
|
|
139
|
+
colorCapable: false,
|
|
127
140
|
printAreaDots: 306,
|
|
128
141
|
leftMarginPins: 0,
|
|
129
142
|
rightMarginPins: 0,
|
|
@@ -134,7 +147,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
134
147
|
name: '38×90mm die-cut (DK-11218)',
|
|
135
148
|
type: 'die-cut',
|
|
136
149
|
widthMm: 38,
|
|
137
|
-
|
|
150
|
+
heightMm: 90,
|
|
151
|
+
colorCapable: false,
|
|
138
152
|
printAreaDots: 413,
|
|
139
153
|
leftMarginPins: 0,
|
|
140
154
|
rightMarginPins: 0,
|
|
@@ -145,7 +159,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
145
159
|
name: '39×48mm die-cut (DK-11219)',
|
|
146
160
|
type: 'die-cut',
|
|
147
161
|
widthMm: 39,
|
|
148
|
-
|
|
162
|
+
heightMm: 48,
|
|
163
|
+
colorCapable: false,
|
|
149
164
|
printAreaDots: 425,
|
|
150
165
|
leftMarginPins: 0,
|
|
151
166
|
rightMarginPins: 0,
|
|
@@ -156,7 +171,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
156
171
|
name: '52×29mm die-cut',
|
|
157
172
|
type: 'die-cut',
|
|
158
173
|
widthMm: 52,
|
|
159
|
-
|
|
174
|
+
heightMm: 29,
|
|
175
|
+
colorCapable: false,
|
|
160
176
|
printAreaDots: 578,
|
|
161
177
|
leftMarginPins: 0,
|
|
162
178
|
rightMarginPins: 0,
|
|
@@ -167,7 +183,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
167
183
|
name: '62×29mm die-cut (DK-11209)',
|
|
168
184
|
type: 'die-cut',
|
|
169
185
|
widthMm: 62,
|
|
170
|
-
|
|
186
|
+
heightMm: 29,
|
|
187
|
+
colorCapable: false,
|
|
171
188
|
printAreaDots: 696,
|
|
172
189
|
leftMarginPins: 0,
|
|
173
190
|
rightMarginPins: 0,
|
|
@@ -178,7 +195,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
178
195
|
name: '62×100mm die-cut (DK-11202)',
|
|
179
196
|
type: 'die-cut',
|
|
180
197
|
widthMm: 62,
|
|
181
|
-
|
|
198
|
+
heightMm: 100,
|
|
199
|
+
colorCapable: false,
|
|
182
200
|
printAreaDots: 696,
|
|
183
201
|
leftMarginPins: 0,
|
|
184
202
|
rightMarginPins: 0,
|
|
@@ -189,7 +207,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
189
207
|
name: '102×51mm die-cut (DK-11240)',
|
|
190
208
|
type: 'die-cut',
|
|
191
209
|
widthMm: 102,
|
|
192
|
-
|
|
210
|
+
heightMm: 51,
|
|
211
|
+
colorCapable: false,
|
|
193
212
|
printAreaDots: 1164,
|
|
194
213
|
leftMarginPins: 0,
|
|
195
214
|
rightMarginPins: 0,
|
|
@@ -200,7 +219,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
200
219
|
name: '102×152mm die-cut (DK-11241)',
|
|
201
220
|
type: 'die-cut',
|
|
202
221
|
widthMm: 102,
|
|
203
|
-
|
|
222
|
+
heightMm: 152,
|
|
223
|
+
colorCapable: false,
|
|
204
224
|
printAreaDots: 1164,
|
|
205
225
|
leftMarginPins: 0,
|
|
206
226
|
rightMarginPins: 0,
|
|
@@ -211,7 +231,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
211
231
|
name: '12mm Ø die-cut',
|
|
212
232
|
type: 'die-cut',
|
|
213
233
|
widthMm: 12,
|
|
214
|
-
|
|
234
|
+
heightMm: 12,
|
|
235
|
+
colorCapable: false,
|
|
215
236
|
printAreaDots: 94,
|
|
216
237
|
leftMarginPins: 0,
|
|
217
238
|
rightMarginPins: 0,
|
|
@@ -222,7 +243,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
222
243
|
name: '24mm Ø die-cut (DK-11221)',
|
|
223
244
|
type: 'die-cut',
|
|
224
245
|
widthMm: 24,
|
|
225
|
-
|
|
246
|
+
heightMm: 24,
|
|
247
|
+
colorCapable: false,
|
|
226
248
|
printAreaDots: 236,
|
|
227
249
|
leftMarginPins: 0,
|
|
228
250
|
rightMarginPins: 0,
|
|
@@ -233,7 +255,8 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
233
255
|
name: '58mm Ø die-cut (DK-11207)',
|
|
234
256
|
type: 'die-cut',
|
|
235
257
|
widthMm: 58,
|
|
236
|
-
|
|
258
|
+
heightMm: 58,
|
|
259
|
+
colorCapable: false,
|
|
237
260
|
printAreaDots: 618,
|
|
238
261
|
leftMarginPins: 0,
|
|
239
262
|
rightMarginPins: 0,
|
|
@@ -241,10 +264,46 @@ export const MEDIA: Record<number, MediaDescriptor> = {
|
|
|
241
264
|
},
|
|
242
265
|
};
|
|
243
266
|
|
|
244
|
-
|
|
267
|
+
/**
|
|
268
|
+
* Default media when `createPreview()` is called without media and
|
|
269
|
+
* without a detected roll. 62mm continuous (DK-22205) is the common
|
|
270
|
+
* single-colour shipping roll.
|
|
271
|
+
*/
|
|
272
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- DK-22205 is a hard-coded registry key
|
|
273
|
+
export const DEFAULT_MEDIA: BrotherQLMedia = MEDIA[259]!;
|
|
274
|
+
|
|
275
|
+
export function findMedia(id: number): BrotherQLMedia | undefined {
|
|
245
276
|
return MEDIA[id];
|
|
246
277
|
}
|
|
247
278
|
|
|
248
|
-
export function findMediaByWidth(widthMm: number, type: MediaType):
|
|
279
|
+
export function findMediaByWidth(widthMm: number, type: MediaType): BrotherQLMedia[] {
|
|
249
280
|
return Object.values(MEDIA).filter(m => m.widthMm === widthMm && m.type === type);
|
|
250
281
|
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Match status-response dimensions to a media registry entry.
|
|
285
|
+
*
|
|
286
|
+
* @param widthMm media width in mm (status byte 10)
|
|
287
|
+
* @param heightMm media length in mm (status byte 17) — 0 = continuous
|
|
288
|
+
* @param twoColorMode true when the status response indicates the
|
|
289
|
+
* printer is configured for two-colour media. When
|
|
290
|
+
* both DK-22205 (259) and DK-22251 (251) match the
|
|
291
|
+
* dimensions, the flag picks the right one.
|
|
292
|
+
*/
|
|
293
|
+
export function findMediaByDimensions(
|
|
294
|
+
widthMm: number,
|
|
295
|
+
heightMm: number,
|
|
296
|
+
twoColorMode = false,
|
|
297
|
+
): BrotherQLMedia | undefined {
|
|
298
|
+
if (heightMm === 0) {
|
|
299
|
+
const continuousMatches = Object.values(MEDIA).filter(
|
|
300
|
+
m => m.type === 'continuous' && m.widthMm === widthMm,
|
|
301
|
+
);
|
|
302
|
+
if (continuousMatches.length === 0) return undefined;
|
|
303
|
+
const preferred = continuousMatches.find(m => m.colorCapable === twoColorMode);
|
|
304
|
+
return preferred ?? continuousMatches[0];
|
|
305
|
+
}
|
|
306
|
+
return Object.values(MEDIA).find(
|
|
307
|
+
m => m.type === 'die-cut' && m.widthMm === widthMm && m.heightMm === heightMm,
|
|
308
|
+
);
|
|
309
|
+
}
|
package/src/preview.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* eslint-disable import-x/consistent-type-specifier-style */
|
|
2
|
+
import { renderImage, type RawImageData } from '@mbtech-nl/bitmap';
|
|
3
|
+
import type { PreviewResult } from '@thermal-label/contracts';
|
|
4
|
+
import { splitTwoColor } from './colour.js';
|
|
5
|
+
import { type BrotherQLMedia } from './types.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Offline preview without a live printer connection.
|
|
9
|
+
*
|
|
10
|
+
* Two-colour aware: when `media.colorCapable` is true (DK-22251), the
|
|
11
|
+
* image is split into a black and a red plane via `splitTwoColor()` —
|
|
12
|
+
* exactly what `print()` does for that media. Single-colour media
|
|
13
|
+
* returns one black plane.
|
|
14
|
+
*/
|
|
15
|
+
export function createPreviewOffline(image: RawImageData, media: BrotherQLMedia): PreviewResult {
|
|
16
|
+
if (media.colorCapable) {
|
|
17
|
+
const { black, red } = splitTwoColor(image);
|
|
18
|
+
return {
|
|
19
|
+
planes: [
|
|
20
|
+
{ name: 'black', bitmap: black, displayColor: '#000000' },
|
|
21
|
+
{ name: 'red', bitmap: red, displayColor: '#ff0000' },
|
|
22
|
+
],
|
|
23
|
+
media,
|
|
24
|
+
assumed: false,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const bitmap = renderImage(image, { dither: true });
|
|
29
|
+
return {
|
|
30
|
+
planes: [{ name: 'black', bitmap, displayColor: '#000000' }],
|
|
31
|
+
media,
|
|
32
|
+
assumed: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
package/src/protocol.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getRow, createBitmap } from '@mbtech-nl/bitmap';
|
|
2
|
-
import { type
|
|
2
|
+
import { type BrotherQLMedia, type PageData, type JobOptions, type PageOptions } from './types.js';
|
|
3
3
|
|
|
4
4
|
export function buildInvalidate(): Uint8Array {
|
|
5
5
|
return new Uint8Array(200);
|
|
@@ -22,7 +22,7 @@ export function buildStatusNotification(enabled: boolean): Uint8Array {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function buildPrintInfo(
|
|
25
|
-
media:
|
|
25
|
+
media: BrotherQLMedia,
|
|
26
26
|
rowCount: number,
|
|
27
27
|
pageIndex: number,
|
|
28
28
|
): Uint8Array {
|
|
@@ -38,7 +38,7 @@ export function buildPrintInfo(
|
|
|
38
38
|
buf[3] = validFlags;
|
|
39
39
|
buf[4] = mediaType;
|
|
40
40
|
buf[5] = media.widthMm;
|
|
41
|
-
buf[6] = media.
|
|
41
|
+
buf[6] = media.heightMm ?? 0;
|
|
42
42
|
// rowCount little-endian at bytes 7-8 (offsets 4-5 in param block)
|
|
43
43
|
buf[7] = rowCount & 0xff;
|
|
44
44
|
buf[8] = (rowCount >> 8) & 0xff;
|
|
@@ -161,12 +161,12 @@ export function encodeJob(pages: PageData[], options: JobOptions = {}): Uint8Arr
|
|
|
161
161
|
const compress = opts.compress ?? false;
|
|
162
162
|
const { bitmap, media } = page;
|
|
163
163
|
|
|
164
|
-
//
|
|
164
|
+
// colorCapable media (e.g. DK-22251) requires two-color mode even for black-only jobs.
|
|
165
165
|
// Auto-create an empty red plane when the tape demands it but caller didn't supply one.
|
|
166
|
-
const twoColor = page.redBitmap !== undefined || media.
|
|
166
|
+
const twoColor = page.redBitmap !== undefined || media.colorCapable;
|
|
167
167
|
const redBitmap =
|
|
168
168
|
page.redBitmap ??
|
|
169
|
-
(media.
|
|
169
|
+
(media.colorCapable ? createBitmap(bitmap.widthPx, bitmap.heightPx) : undefined);
|
|
170
170
|
|
|
171
171
|
if (twoColor && redBitmap !== undefined) {
|
|
172
172
|
if (bitmap.widthPx !== redBitmap.widthPx || bitmap.heightPx !== redBitmap.heightPx) {
|