@thermal-print/escpos 0.1.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/LICENSE +21 -0
- package/README.md +193 -0
- package/dist/command-adapters/escbematech-adapter.d.ts +30 -0
- package/dist/command-adapters/escbematech-adapter.d.ts.map +1 -0
- package/dist/command-adapters/escbematech-adapter.js +175 -0
- package/dist/command-adapters/escpos-adapter.d.ts +25 -0
- package/dist/command-adapters/escpos-adapter.d.ts.map +1 -0
- package/dist/command-adapters/escpos-adapter.js +144 -0
- package/dist/command-adapters/index.d.ts +11 -0
- package/dist/command-adapters/index.d.ts.map +1 -0
- package/dist/command-adapters/index.js +14 -0
- package/dist/command-adapters/types.d.ts +78 -0
- package/dist/command-adapters/types.d.ts.map +1 -0
- package/dist/command-adapters/types.js +8 -0
- package/dist/commands/escbematech.d.ts +867 -0
- package/dist/commands/escbematech.d.ts.map +1 -0
- package/dist/commands/escbematech.js +1387 -0
- package/dist/commands/escpos.d.ts +582 -0
- package/dist/commands/escpos.d.ts.map +1 -0
- package/dist/commands/escpos.js +1048 -0
- package/dist/converter.d.ts +47 -0
- package/dist/converter.d.ts.map +1 -0
- package/dist/converter.js +92 -0
- package/dist/encodings/cp860.d.ts +25 -0
- package/dist/encodings/cp860.d.ts.map +1 -0
- package/dist/encodings/cp860.js +187 -0
- package/dist/generator.d.ts +118 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +383 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/styles.d.ts +72 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +210 -0
- package/dist/traverser.d.ts +60 -0
- package/dist/traverser.d.ts.map +1 -0
- package/dist/traverser.js +285 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/package.json +31 -0
|
@@ -0,0 +1,1048 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ESC/POS Command Set
|
|
4
|
+
*
|
|
5
|
+
* Comprehensive ESC/POS thermal printer command bytes for MP-4200 TH.
|
|
6
|
+
* Reference: ESC/POS Command Manual
|
|
7
|
+
*
|
|
8
|
+
* This file contains all documented ESC/POS commands organized by category.
|
|
9
|
+
* Commands are compatible with standard ESC/POS thermal printers.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.UNDERLINE_2DOT = exports.UNDERLINE_1DOT = exports.UPSIDE_DOWN_OFF = exports.UPSIDE_DOWN_ON = exports.ROTATE_90_OFF = exports.ROTATE_90_ON = exports.SELECT_FONT_D = exports.selectFont = exports.CharacterFont = exports.DOUBLE_STRIKE_OFF = exports.DOUBLE_STRIKE_ON = exports.CLEAR_TABS = exports.setTabPositions = exports.setCharacterSpacing = exports.setRelativePosition = exports.setAbsolutePosition = exports.realtimePulse = exports.realtimeRequest = exports.transmitRealtimeStatus = exports.encodeText = exports.generateRasterImage = exports.generateQRCode = exports.CODEPAGE_WPC1252 = exports.CODEPAGE_CP860 = exports.CODEPAGE_CP437 = exports.cutWithFeed = exports.CUT_PARTIAL = exports.CUT_FULL = exports.feedLines = exports.LINE_FEED = exports.LINE_SPACING_DEFAULT = exports.setLineSpacing = exports.calculateCharacterSize = exports.UNDERLINE_OFF = exports.UNDERLINE_ON = exports.BOLD_OFF = exports.BOLD_ON = exports.ALIGN_RIGHT = exports.ALIGN_CENTER = exports.ALIGN_LEFT = exports.INIT = exports.GS = exports.FS = exports.ESC = exports.CAN = exports.DLE = exports.CR = exports.FF = exports.LF = exports.HT = void 0;
|
|
13
|
+
exports.selectCharacterSize = exports.generatePDF417 = exports.printPDF417 = exports.storePDF417Data = exports.setPDF417ErrorCorrection = exports.setPDF417RowHeight = exports.setPDF417Width = exports.setPDF417Rows = exports.setPDF417Columns = exports.printBarcodeCODE128 = exports.printBarcodeCODE93 = exports.printBarcodeCODABAR = exports.printBarcodeITF = exports.printBarcodeCODE39 = exports.printBarcodeEAN8 = exports.printBarcodeEAN13 = exports.printBarcodeUPCE = exports.printBarcodeUPCA = exports.printBarcodeWithLength = exports.printBarcode = exports.BarcodeType = exports.setBarcodeWidth = exports.setBarcodeHeight = exports.setBarcodeFont = exports.setBarcodeHRI = exports.BarcodeHRIPosition = exports.defineNVBitImage = exports.printNVBitImage = exports.printDownloadedBitImage = exports.DownloadedImageMode = exports.defineDownloadedBitImage = exports.printBitImage = exports.BitImageMode = exports.setCodePage = exports.CodePage = exports.selectInternationalCharset = exports.InternationalCharset = exports.disablePanelButtons = exports.enablePanelButtons = exports.selectPaperSensorStop = exports.selectPaperSensorOutput = exports.generatePulse = exports.selectPeripheral = exports.cutAndFeedPartial = exports.cutAndFeedFull = exports.CUT_PARTIAL_ESC = exports.CUT_FULL_ESC = exports.printAndReverseFeed = exports.printAndFeed = exports.LINE_SPACING_DEFAULT_ALT = void 0;
|
|
14
|
+
exports.executeTestPrint = exports.CANCEL = exports.UNIDIRECTIONAL_OFF = exports.UNIDIRECTIONAL_ON = exports.executeMacro = exports.END_MACRO = exports.START_MACRO = exports.setPrintingAreaWidth = exports.setLeftMargin = exports.requestStatus = exports.StatusType = exports.requestPrinterID = exports.PrinterIDType = exports.disableASB = exports.enableASB = exports.setCharacterSmoothing = exports.setCharacterColor = exports.REVERSE_PRINT_OFF = exports.REVERSE_PRINT_ON = void 0;
|
|
15
|
+
const cp860_1 = require("../encodings/cp860");
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// CONTROL CHARACTERS
|
|
18
|
+
// ============================================================================
|
|
19
|
+
exports.HT = 0x09; // Horizontal Tab
|
|
20
|
+
exports.LF = 0x0a; // Line Feed
|
|
21
|
+
exports.FF = 0x0c; // Form Feed
|
|
22
|
+
exports.CR = 0x0d; // Carriage Return
|
|
23
|
+
exports.DLE = 0x10; // Data Link Escape
|
|
24
|
+
exports.CAN = 0x18; // Cancel
|
|
25
|
+
exports.ESC = 0x1b; // Escape
|
|
26
|
+
exports.FS = 0x1c; // File Separator
|
|
27
|
+
exports.GS = 0x1d; // Group Separator
|
|
28
|
+
// Initialize printer
|
|
29
|
+
// ESC @ - Reset printer to default state
|
|
30
|
+
exports.INIT = [exports.ESC, 0x40];
|
|
31
|
+
// Text alignment
|
|
32
|
+
// ESC a n - Set text alignment (n: 0=left, 1=center, 2=right)
|
|
33
|
+
exports.ALIGN_LEFT = [exports.ESC, 0x61, 0x00];
|
|
34
|
+
exports.ALIGN_CENTER = [exports.ESC, 0x61, 0x01];
|
|
35
|
+
exports.ALIGN_RIGHT = [exports.ESC, 0x61, 0x02];
|
|
36
|
+
// Text emphasis
|
|
37
|
+
// ESC E n - Turn bold on/off (n: 0=off, 1=on)
|
|
38
|
+
exports.BOLD_ON = [exports.ESC, 0x45, 0x01];
|
|
39
|
+
exports.BOLD_OFF = [exports.ESC, 0x45, 0x00];
|
|
40
|
+
// ESC - n - Turn underline on/off (n: 0=off, 1=on, 2=double)
|
|
41
|
+
exports.UNDERLINE_ON = [exports.ESC, 0x2d, 0x01];
|
|
42
|
+
exports.UNDERLINE_OFF = [exports.ESC, 0x2d, 0x00];
|
|
43
|
+
/**
|
|
44
|
+
* Calculate character size using ESC ! command (compatible with more printers)
|
|
45
|
+
* ESC ! only supports up to 2x2 character size
|
|
46
|
+
* @param width - Width multiplier (1 or 2)
|
|
47
|
+
* @param height - Height multiplier (1 or 2)
|
|
48
|
+
* @param bold - Whether text should be bold (optional, default: false)
|
|
49
|
+
* @returns ESC/POS ESC ! n command bytes
|
|
50
|
+
*/
|
|
51
|
+
const calculateCharacterSize = (width, height, bold = false) => {
|
|
52
|
+
// ESC ! command format:
|
|
53
|
+
// Bit 0: Character font (0=Font A, 1=Font B)
|
|
54
|
+
// Bit 3: Emphasis (bold)
|
|
55
|
+
// Bit 4: Double-height
|
|
56
|
+
// Bit 5: Double-width
|
|
57
|
+
// Bit 7: Underline
|
|
58
|
+
// Use Font B as base (9×17 dots)
|
|
59
|
+
// Note: Font D (16×24 dots) is selected separately via ESC U command
|
|
60
|
+
// and will override this font selection
|
|
61
|
+
let n = 0x01; // Font B
|
|
62
|
+
// Set double-height bit (bit 4 = 0x10)
|
|
63
|
+
if (height >= 2) {
|
|
64
|
+
n |= 0x10;
|
|
65
|
+
}
|
|
66
|
+
// Set double-width bit (bit 5 = 0x20)
|
|
67
|
+
if (width >= 2) {
|
|
68
|
+
n |= 0x20;
|
|
69
|
+
}
|
|
70
|
+
// Set bold/emphasis bit (bit 3 = 0x08)
|
|
71
|
+
if (bold) {
|
|
72
|
+
n |= 0x08;
|
|
73
|
+
}
|
|
74
|
+
return [exports.ESC, 0x21, n];
|
|
75
|
+
};
|
|
76
|
+
exports.calculateCharacterSize = calculateCharacterSize;
|
|
77
|
+
// Line spacing
|
|
78
|
+
// ESC 3 n - Set line spacing to n dots
|
|
79
|
+
// Note: Using minimum of 18 dots for consistency with ESC/Bematech protocol
|
|
80
|
+
const setLineSpacing = (dots) => {
|
|
81
|
+
const value = Math.max(18, Math.min(255, dots));
|
|
82
|
+
return [exports.ESC, 0x33, value];
|
|
83
|
+
};
|
|
84
|
+
exports.setLineSpacing = setLineSpacing;
|
|
85
|
+
// Default line spacing (30 dots = ~3.75mm)
|
|
86
|
+
exports.LINE_SPACING_DEFAULT = [exports.ESC, 0x33, 30];
|
|
87
|
+
// Paper control
|
|
88
|
+
// LF - Line feed (move paper up one line)
|
|
89
|
+
exports.LINE_FEED = [exports.LF];
|
|
90
|
+
// ESC d n - Print and feed n lines
|
|
91
|
+
const feedLines = (lines) => [exports.ESC, 0x64, lines];
|
|
92
|
+
exports.feedLines = feedLines;
|
|
93
|
+
// GS V m - Paper cut
|
|
94
|
+
// m: 0=full cut, 1=partial cut
|
|
95
|
+
exports.CUT_FULL = [exports.GS, 0x56, 0x00];
|
|
96
|
+
exports.CUT_PARTIAL = [exports.GS, 0x56, 0x01];
|
|
97
|
+
// Alternative: GS V m n - Cut with feed
|
|
98
|
+
const cutWithFeed = (lines) => [exports.GS, 0x56, 0x41, lines];
|
|
99
|
+
exports.cutWithFeed = cutWithFeed;
|
|
100
|
+
// Character code table
|
|
101
|
+
// ESC t n - Select character code table
|
|
102
|
+
// Common tables: 0=CP437, 3=CP860 (Portuguese), 16=WPC1252
|
|
103
|
+
exports.CODEPAGE_CP437 = [exports.ESC, 0x74, 0x00]; // USA
|
|
104
|
+
exports.CODEPAGE_CP860 = [exports.ESC, 0x74, 0x03]; // Portuguese
|
|
105
|
+
exports.CODEPAGE_WPC1252 = [exports.ESC, 0x74, 0x10]; // Windows Latin-1
|
|
106
|
+
// Barcode and QR Code
|
|
107
|
+
// QR Code: GS ( k pL pH cn fn n1 n2 [data]
|
|
108
|
+
// This is a complex command, implemented as a function
|
|
109
|
+
/**
|
|
110
|
+
* Generate QR Code command
|
|
111
|
+
* @param data - QR code data (URL or text)
|
|
112
|
+
* @param size - QR code module size (1-16, default 6)
|
|
113
|
+
* @returns ESC/POS command bytes
|
|
114
|
+
*/
|
|
115
|
+
const generateQRCode = (data, size = 6) => {
|
|
116
|
+
const commands = [];
|
|
117
|
+
// QR Code model (function 165, cn=49, fn=65, n=48/49/50)
|
|
118
|
+
// Model 2 (most common)
|
|
119
|
+
commands.push(exports.GS, 0x28, 0x6b, 0x04, 0x00, 0x31, 0x41, 0x32, 0x00);
|
|
120
|
+
// QR Code size (function 167, cn=49, fn=67, n=size)
|
|
121
|
+
commands.push(exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x43, size);
|
|
122
|
+
// QR Code error correction (function 169, cn=49, fn=69, n=48-51)
|
|
123
|
+
// 48=L(7%), 49=M(15%), 50=Q(25%), 51=H(30%)
|
|
124
|
+
commands.push(exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x45, 0x31);
|
|
125
|
+
// Store QR code data (function 180, cn=49, fn=80)
|
|
126
|
+
const dataBytes = new TextEncoder().encode(data);
|
|
127
|
+
const pL = (dataBytes.length + 3) % 256;
|
|
128
|
+
const pH = Math.floor((dataBytes.length + 3) / 256);
|
|
129
|
+
commands.push(exports.GS, 0x28, 0x6b, pL, pH, 0x31, 0x50, 0x30);
|
|
130
|
+
commands.push(...Array.from(dataBytes));
|
|
131
|
+
// Print QR code (function 181, cn=49, fn=81)
|
|
132
|
+
commands.push(exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x51, 0x30);
|
|
133
|
+
return commands;
|
|
134
|
+
};
|
|
135
|
+
exports.generateQRCode = generateQRCode;
|
|
136
|
+
/**
|
|
137
|
+
* Generate raster image command (GS v 0)
|
|
138
|
+
* @param imageData - Monochrome bitmap data (1 bit per pixel, 1=black, 0=white)
|
|
139
|
+
* @param width - Image width in pixels
|
|
140
|
+
* @param height - Image height in pixels
|
|
141
|
+
* @returns ESC/POS command bytes
|
|
142
|
+
*/
|
|
143
|
+
const generateRasterImage = (imageData, width, height) => {
|
|
144
|
+
const commands = [];
|
|
145
|
+
// Calculate bytes per line (width in bytes, rounded up to nearest byte)
|
|
146
|
+
const bytesPerLine = Math.ceil(width / 8);
|
|
147
|
+
// GS v 0 m xL xH yL yH d1...dk
|
|
148
|
+
// m = 0 (normal), 1 (double width), 2 (double height), 3 (quadruple)
|
|
149
|
+
// xL xH = width in bytes (little endian)
|
|
150
|
+
// yL yH = height in dots (little endian)
|
|
151
|
+
// d1...dk = raster image data
|
|
152
|
+
commands.push(exports.GS, 0x76, 0x30, 0x00); // GS v 0 m (m=0: normal)
|
|
153
|
+
// Width in bytes (little endian)
|
|
154
|
+
commands.push(bytesPerLine & 0xff);
|
|
155
|
+
commands.push((bytesPerLine >> 8) & 0xff);
|
|
156
|
+
// Height in dots (little endian)
|
|
157
|
+
commands.push(height & 0xff);
|
|
158
|
+
commands.push((height >> 8) & 0xff);
|
|
159
|
+
// Add image data
|
|
160
|
+
commands.push(...imageData);
|
|
161
|
+
return commands;
|
|
162
|
+
};
|
|
163
|
+
exports.generateRasterImage = generateRasterImage;
|
|
164
|
+
/**
|
|
165
|
+
* Text encoding helper
|
|
166
|
+
* Converts string to CP860 byte array for Brazilian Portuguese thermal printers
|
|
167
|
+
*/
|
|
168
|
+
const encodeText = (text) => {
|
|
169
|
+
// CP860 is the standard codepage for Portuguese thermal printers
|
|
170
|
+
// Supports: ç Ç á é í ó ú à ã õ â ê ô and other Portuguese characters
|
|
171
|
+
return (0, cp860_1.encodeCP860)(text);
|
|
172
|
+
};
|
|
173
|
+
exports.encodeText = encodeText;
|
|
174
|
+
// ============================================================================
|
|
175
|
+
// REAL-TIME COMMANDS
|
|
176
|
+
// ============================================================================
|
|
177
|
+
/**
|
|
178
|
+
* DLE EOT n - Transmit real-time status
|
|
179
|
+
* n = 1: Transmit printer status
|
|
180
|
+
* n = 2: Transmit offline status
|
|
181
|
+
* n = 3: Transmit error status
|
|
182
|
+
* n = 4: Transmit paper roll sensor status
|
|
183
|
+
*/
|
|
184
|
+
const transmitRealtimeStatus = (n) => [
|
|
185
|
+
exports.DLE,
|
|
186
|
+
0x04,
|
|
187
|
+
n,
|
|
188
|
+
];
|
|
189
|
+
exports.transmitRealtimeStatus = transmitRealtimeStatus;
|
|
190
|
+
/**
|
|
191
|
+
* DLE ENQ n - Real-time request to printer
|
|
192
|
+
* n = 1: Recover from error and restart printing
|
|
193
|
+
* n = 2: Clear buffer
|
|
194
|
+
*/
|
|
195
|
+
const realtimeRequest = (n) => [exports.DLE, 0x05, n];
|
|
196
|
+
exports.realtimeRequest = realtimeRequest;
|
|
197
|
+
/**
|
|
198
|
+
* DLE DC4 fn a b - Generate pulse in real-time
|
|
199
|
+
* fn = 1: Generate pulse
|
|
200
|
+
* a = drawer (0 or 1)
|
|
201
|
+
* b = pulse time
|
|
202
|
+
*/
|
|
203
|
+
const realtimePulse = (drawer, pulseTime) => [
|
|
204
|
+
exports.DLE,
|
|
205
|
+
0x14,
|
|
206
|
+
0x01,
|
|
207
|
+
drawer,
|
|
208
|
+
pulseTime,
|
|
209
|
+
];
|
|
210
|
+
exports.realtimePulse = realtimePulse;
|
|
211
|
+
// ============================================================================
|
|
212
|
+
// TEXT POSITION & LAYOUT
|
|
213
|
+
// ============================================================================
|
|
214
|
+
/**
|
|
215
|
+
* ESC $ nL nH - Set absolute print position
|
|
216
|
+
* Position = ((nH × 256) + nL) × (horizontal motion unit)
|
|
217
|
+
*/
|
|
218
|
+
const setAbsolutePosition = (position) => {
|
|
219
|
+
const nL = position & 0xff;
|
|
220
|
+
const nH = (position >> 8) & 0xff;
|
|
221
|
+
return [exports.ESC, 0x24, nL, nH];
|
|
222
|
+
};
|
|
223
|
+
exports.setAbsolutePosition = setAbsolutePosition;
|
|
224
|
+
/**
|
|
225
|
+
* ESC \ nL nH - Set relative print position
|
|
226
|
+
* Relative position = ((nH × 256) + nL) × (horizontal motion unit)
|
|
227
|
+
* Supports negative values (two's complement)
|
|
228
|
+
*/
|
|
229
|
+
const setRelativePosition = (position) => {
|
|
230
|
+
const nL = position & 0xff;
|
|
231
|
+
const nH = (position >> 8) & 0xff;
|
|
232
|
+
return [exports.ESC, 0x5c, nL, nH];
|
|
233
|
+
};
|
|
234
|
+
exports.setRelativePosition = setRelativePosition;
|
|
235
|
+
/**
|
|
236
|
+
* ESC SP n - Set right-side character spacing
|
|
237
|
+
* Range: 0 ≤ n ≤ 255
|
|
238
|
+
* Spacing = n × (horizontal motion unit)
|
|
239
|
+
*/
|
|
240
|
+
const setCharacterSpacing = (dots) => [
|
|
241
|
+
exports.ESC,
|
|
242
|
+
0x20,
|
|
243
|
+
Math.max(0, Math.min(255, dots)),
|
|
244
|
+
];
|
|
245
|
+
exports.setCharacterSpacing = setCharacterSpacing;
|
|
246
|
+
/**
|
|
247
|
+
* ESC D n1...nk NUL - Set horizontal tab positions
|
|
248
|
+
* n1-nk: Tab positions (1-255), up to 32 positions
|
|
249
|
+
* Must be in ascending order, terminated with NUL
|
|
250
|
+
*/
|
|
251
|
+
const setTabPositions = (positions) => {
|
|
252
|
+
const validPositions = positions
|
|
253
|
+
.filter((p) => p >= 1 && p <= 255)
|
|
254
|
+
.slice(0, 32)
|
|
255
|
+
.sort((a, b) => a - b);
|
|
256
|
+
return [exports.ESC, 0x44, ...validPositions, 0x00];
|
|
257
|
+
};
|
|
258
|
+
exports.setTabPositions = setTabPositions;
|
|
259
|
+
/**
|
|
260
|
+
* ESC D NUL - Cancel all horizontal tab positions
|
|
261
|
+
*/
|
|
262
|
+
exports.CLEAR_TABS = [exports.ESC, 0x44, 0x00];
|
|
263
|
+
// ============================================================================
|
|
264
|
+
// TEXT EMPHASIS & STYLES
|
|
265
|
+
// ============================================================================
|
|
266
|
+
/**
|
|
267
|
+
* ESC G n - Turn double-strike mode on/off
|
|
268
|
+
* n = 0 or 48: Turn off double-strike mode
|
|
269
|
+
* n = 1 or 49: Turn on double-strike mode
|
|
270
|
+
*/
|
|
271
|
+
exports.DOUBLE_STRIKE_ON = [exports.ESC, 0x47, 0x01];
|
|
272
|
+
exports.DOUBLE_STRIKE_OFF = [exports.ESC, 0x47, 0x00];
|
|
273
|
+
/**
|
|
274
|
+
* Character font selection
|
|
275
|
+
*/
|
|
276
|
+
var CharacterFont;
|
|
277
|
+
(function (CharacterFont) {
|
|
278
|
+
CharacterFont[CharacterFont["FONT_A"] = 0] = "FONT_A";
|
|
279
|
+
CharacterFont[CharacterFont["FONT_B"] = 1] = "FONT_B";
|
|
280
|
+
CharacterFont[CharacterFont["FONT_C"] = 2] = "FONT_C";
|
|
281
|
+
})(CharacterFont || (exports.CharacterFont = CharacterFont = {}));
|
|
282
|
+
/**
|
|
283
|
+
* ESC M n - Select character font
|
|
284
|
+
* n = 0 or 48: Font A (12×24)
|
|
285
|
+
* n = 1 or 49: Font B (9×17)
|
|
286
|
+
* n = 2 or 50: Font C (printer dependent)
|
|
287
|
+
*/
|
|
288
|
+
const selectFont = (font) => [exports.ESC, 0x4d, font];
|
|
289
|
+
exports.selectFont = selectFont;
|
|
290
|
+
/**
|
|
291
|
+
* ESC U - Select Font D (Phoenix printers only)
|
|
292
|
+
* Font D: 16×24 dots
|
|
293
|
+
* Warning: This is a Phoenix-specific feature and may not work on all printers
|
|
294
|
+
*/
|
|
295
|
+
exports.SELECT_FONT_D = [exports.ESC, 0x51];
|
|
296
|
+
/**
|
|
297
|
+
* ESC V n - Turn 90° clockwise rotation mode on/off
|
|
298
|
+
* n = 0 or 48: Turn off 90° clockwise rotation mode
|
|
299
|
+
* n = 1 or 49: Turn on 90° clockwise rotation mode
|
|
300
|
+
*/
|
|
301
|
+
exports.ROTATE_90_ON = [exports.ESC, 0x56, 0x01];
|
|
302
|
+
exports.ROTATE_90_OFF = [exports.ESC, 0x56, 0x00];
|
|
303
|
+
/**
|
|
304
|
+
* ESC { n - Turn upside-down printing mode on/off
|
|
305
|
+
* n = 0 or 48: Turn off upside-down printing mode
|
|
306
|
+
* n = 1 or 49: Turn on upside-down printing mode
|
|
307
|
+
*/
|
|
308
|
+
exports.UPSIDE_DOWN_ON = [exports.ESC, 0x7b, 0x01];
|
|
309
|
+
exports.UPSIDE_DOWN_OFF = [exports.ESC, 0x7b, 0x00];
|
|
310
|
+
/**
|
|
311
|
+
* ESC - n - Turn underline mode on/off with thickness selection
|
|
312
|
+
* n = 0 or 48: Turn off underline mode
|
|
313
|
+
* n = 1 or 49: Turn on underline mode (1-dot thick)
|
|
314
|
+
* n = 2 or 50: Turn on underline mode (2-dots thick)
|
|
315
|
+
*/
|
|
316
|
+
exports.UNDERLINE_1DOT = [exports.ESC, 0x2d, 0x01];
|
|
317
|
+
exports.UNDERLINE_2DOT = [exports.ESC, 0x2d, 0x02];
|
|
318
|
+
// ============================================================================
|
|
319
|
+
// LINE SPACING & PAPER CONTROL (ADDITIONAL)
|
|
320
|
+
// ============================================================================
|
|
321
|
+
/**
|
|
322
|
+
* ESC 2 - Select default line spacing
|
|
323
|
+
* Sets line spacing to approximately 4.23mm (1/6 inch)
|
|
324
|
+
*/
|
|
325
|
+
exports.LINE_SPACING_DEFAULT_ALT = [exports.ESC, 0x32, 0x5];
|
|
326
|
+
/**
|
|
327
|
+
* ESC J n - Print and feed paper
|
|
328
|
+
* Range: 0 ≤ n ≤ 255
|
|
329
|
+
* Feed amount = n × (vertical motion unit)
|
|
330
|
+
*/
|
|
331
|
+
const printAndFeed = (dots) => [
|
|
332
|
+
exports.ESC,
|
|
333
|
+
0x4a,
|
|
334
|
+
Math.max(0, Math.min(255, dots)),
|
|
335
|
+
];
|
|
336
|
+
exports.printAndFeed = printAndFeed;
|
|
337
|
+
/**
|
|
338
|
+
* ESC K n - Print and reverse feed
|
|
339
|
+
* Range: 0 ≤ n ≤ 255
|
|
340
|
+
* Reverse feed amount = n × (vertical motion unit)
|
|
341
|
+
*/
|
|
342
|
+
const printAndReverseFeed = (dots) => [
|
|
343
|
+
exports.ESC,
|
|
344
|
+
0x4b,
|
|
345
|
+
Math.max(0, Math.min(255, dots)),
|
|
346
|
+
];
|
|
347
|
+
exports.printAndReverseFeed = printAndReverseFeed;
|
|
348
|
+
// ============================================================================
|
|
349
|
+
// PAPER CUTTING (ADDITIONAL)
|
|
350
|
+
// ============================================================================
|
|
351
|
+
/**
|
|
352
|
+
* ESC i - Full cut
|
|
353
|
+
* Executes a full cut (cuts paper completely)
|
|
354
|
+
*/
|
|
355
|
+
exports.CUT_FULL_ESC = [exports.ESC, 0x69];
|
|
356
|
+
/**
|
|
357
|
+
* ESC m - Partial cut
|
|
358
|
+
* Executes a partial cut (leaves connection point)
|
|
359
|
+
*/
|
|
360
|
+
exports.CUT_PARTIAL_ESC = [exports.ESC, 0x6d];
|
|
361
|
+
/**
|
|
362
|
+
* GS V m n - Cut paper and feed
|
|
363
|
+
* m = 65 (0x41): Feed then full cut
|
|
364
|
+
* m = 66 (0x42): Feed then partial cut
|
|
365
|
+
* n = feed amount before cut
|
|
366
|
+
*/
|
|
367
|
+
const cutAndFeedFull = (dots) => [
|
|
368
|
+
exports.GS,
|
|
369
|
+
0x56,
|
|
370
|
+
0x41,
|
|
371
|
+
Math.max(0, Math.min(255, dots)),
|
|
372
|
+
];
|
|
373
|
+
exports.cutAndFeedFull = cutAndFeedFull;
|
|
374
|
+
const cutAndFeedPartial = (dots) => [
|
|
375
|
+
exports.GS,
|
|
376
|
+
0x56,
|
|
377
|
+
0x42,
|
|
378
|
+
Math.max(0, Math.min(255, dots)),
|
|
379
|
+
];
|
|
380
|
+
exports.cutAndFeedPartial = cutAndFeedPartial;
|
|
381
|
+
// ============================================================================
|
|
382
|
+
// PERIPHERAL DEVICE CONTROL
|
|
383
|
+
// ============================================================================
|
|
384
|
+
/**
|
|
385
|
+
* ESC = n - Select peripheral device
|
|
386
|
+
* n = 0: Disabled
|
|
387
|
+
* n = 1: Enabled
|
|
388
|
+
*/
|
|
389
|
+
const selectPeripheral = (enabled) => [
|
|
390
|
+
exports.ESC,
|
|
391
|
+
0x3d,
|
|
392
|
+
enabled ? 0x01 : 0x00,
|
|
393
|
+
];
|
|
394
|
+
exports.selectPeripheral = selectPeripheral;
|
|
395
|
+
/**
|
|
396
|
+
* ESC p m t1 t2 - Generate pulse
|
|
397
|
+
* m = 0 or 48: Drawer kick-out connector pin 2
|
|
398
|
+
* m = 1 or 49: Drawer kick-out connector pin 5
|
|
399
|
+
* t1 = ON time (0-255, units of 100ms)
|
|
400
|
+
* t2 = OFF time (0-255, units of 100ms)
|
|
401
|
+
*/
|
|
402
|
+
const generatePulse = (connector, onTime, offTime) => [
|
|
403
|
+
exports.ESC,
|
|
404
|
+
0x70,
|
|
405
|
+
connector,
|
|
406
|
+
Math.max(0, Math.min(255, onTime)),
|
|
407
|
+
Math.max(0, Math.min(255, offTime)),
|
|
408
|
+
];
|
|
409
|
+
exports.generatePulse = generatePulse;
|
|
410
|
+
/**
|
|
411
|
+
* ESC c 3 n - Select paper sensor(s) to output paper-end signals
|
|
412
|
+
* n is a bitmask for sensor selection
|
|
413
|
+
*/
|
|
414
|
+
const selectPaperSensorOutput = (sensorMask) => [
|
|
415
|
+
exports.ESC,
|
|
416
|
+
0x63,
|
|
417
|
+
0x33,
|
|
418
|
+
sensorMask,
|
|
419
|
+
];
|
|
420
|
+
exports.selectPaperSensorOutput = selectPaperSensorOutput;
|
|
421
|
+
/**
|
|
422
|
+
* ESC c 4 n - Select paper sensor(s) to stop printing
|
|
423
|
+
* n is a bitmask for sensor selection
|
|
424
|
+
*/
|
|
425
|
+
const selectPaperSensorStop = (sensorMask) => [
|
|
426
|
+
exports.ESC,
|
|
427
|
+
0x63,
|
|
428
|
+
0x34,
|
|
429
|
+
sensorMask,
|
|
430
|
+
];
|
|
431
|
+
exports.selectPaperSensorStop = selectPaperSensorStop;
|
|
432
|
+
/**
|
|
433
|
+
* ESC c 5 n - Enable/disable panel buttons
|
|
434
|
+
* n = 0: Enable panel buttons
|
|
435
|
+
* n = 1: Disable panel buttons
|
|
436
|
+
*/
|
|
437
|
+
const enablePanelButtons = () => [exports.ESC, 0x63, 0x35, 0x00];
|
|
438
|
+
exports.enablePanelButtons = enablePanelButtons;
|
|
439
|
+
const disablePanelButtons = () => [exports.ESC, 0x63, 0x35, 0x01];
|
|
440
|
+
exports.disablePanelButtons = disablePanelButtons;
|
|
441
|
+
// ============================================================================
|
|
442
|
+
// CHARACTER CODE TABLES
|
|
443
|
+
// ============================================================================
|
|
444
|
+
/**
|
|
445
|
+
* International character set selection
|
|
446
|
+
*/
|
|
447
|
+
var InternationalCharset;
|
|
448
|
+
(function (InternationalCharset) {
|
|
449
|
+
InternationalCharset[InternationalCharset["USA"] = 0] = "USA";
|
|
450
|
+
InternationalCharset[InternationalCharset["FRANCE"] = 1] = "FRANCE";
|
|
451
|
+
InternationalCharset[InternationalCharset["GERMANY"] = 2] = "GERMANY";
|
|
452
|
+
InternationalCharset[InternationalCharset["UK"] = 3] = "UK";
|
|
453
|
+
InternationalCharset[InternationalCharset["DENMARK_I"] = 4] = "DENMARK_I";
|
|
454
|
+
InternationalCharset[InternationalCharset["SWEDEN"] = 5] = "SWEDEN";
|
|
455
|
+
InternationalCharset[InternationalCharset["ITALY"] = 6] = "ITALY";
|
|
456
|
+
InternationalCharset[InternationalCharset["SPAIN_I"] = 7] = "SPAIN_I";
|
|
457
|
+
InternationalCharset[InternationalCharset["JAPAN"] = 8] = "JAPAN";
|
|
458
|
+
InternationalCharset[InternationalCharset["NORWAY"] = 9] = "NORWAY";
|
|
459
|
+
InternationalCharset[InternationalCharset["DENMARK_II"] = 10] = "DENMARK_II";
|
|
460
|
+
InternationalCharset[InternationalCharset["SPAIN_II"] = 11] = "SPAIN_II";
|
|
461
|
+
InternationalCharset[InternationalCharset["LATIN_AMERICA"] = 12] = "LATIN_AMERICA";
|
|
462
|
+
InternationalCharset[InternationalCharset["KOREA"] = 13] = "KOREA";
|
|
463
|
+
})(InternationalCharset || (exports.InternationalCharset = InternationalCharset = {}));
|
|
464
|
+
/**
|
|
465
|
+
* ESC R n - Select international character set
|
|
466
|
+
*/
|
|
467
|
+
const selectInternationalCharset = (charset) => [exports.ESC, 0x52, charset];
|
|
468
|
+
exports.selectInternationalCharset = selectInternationalCharset;
|
|
469
|
+
/**
|
|
470
|
+
* Extended code page enumeration
|
|
471
|
+
*/
|
|
472
|
+
var CodePage;
|
|
473
|
+
(function (CodePage) {
|
|
474
|
+
CodePage[CodePage["CP437"] = 0] = "CP437";
|
|
475
|
+
CodePage[CodePage["CP850"] = 2] = "CP850";
|
|
476
|
+
CodePage[CodePage["CP860"] = 3] = "CP860";
|
|
477
|
+
CodePage[CodePage["CP863"] = 4] = "CP863";
|
|
478
|
+
CodePage[CodePage["CP865"] = 5] = "CP865";
|
|
479
|
+
CodePage[CodePage["CP851"] = 11] = "CP851";
|
|
480
|
+
CodePage[CodePage["CP853"] = 12] = "CP853";
|
|
481
|
+
CodePage[CodePage["CP857"] = 13] = "CP857";
|
|
482
|
+
CodePage[CodePage["CP737"] = 14] = "CP737";
|
|
483
|
+
CodePage[CodePage["CP928"] = 16] = "CP928";
|
|
484
|
+
CodePage[CodePage["CP866"] = 17] = "CP866";
|
|
485
|
+
CodePage[CodePage["CP852"] = 18] = "CP852";
|
|
486
|
+
CodePage[CodePage["CP858"] = 19] = "CP858";
|
|
487
|
+
CodePage[CodePage["WPC1252"] = 16] = "WPC1252";
|
|
488
|
+
})(CodePage || (exports.CodePage = CodePage = {}));
|
|
489
|
+
/**
|
|
490
|
+
* ESC t n - Select character code table
|
|
491
|
+
*/
|
|
492
|
+
const setCodePage = (page) => [exports.ESC, 0x74, page];
|
|
493
|
+
exports.setCodePage = setCodePage;
|
|
494
|
+
// ============================================================================
|
|
495
|
+
// GRAPHICS - BIT IMAGE
|
|
496
|
+
// ============================================================================
|
|
497
|
+
/**
|
|
498
|
+
* Bit image modes for ESC *
|
|
499
|
+
*/
|
|
500
|
+
var BitImageMode;
|
|
501
|
+
(function (BitImageMode) {
|
|
502
|
+
BitImageMode[BitImageMode["MODE_8_SINGLE"] = 0] = "MODE_8_SINGLE";
|
|
503
|
+
BitImageMode[BitImageMode["MODE_8_DOUBLE"] = 1] = "MODE_8_DOUBLE";
|
|
504
|
+
BitImageMode[BitImageMode["MODE_24_SINGLE"] = 32] = "MODE_24_SINGLE";
|
|
505
|
+
BitImageMode[BitImageMode["MODE_24_DOUBLE"] = 33] = "MODE_24_DOUBLE";
|
|
506
|
+
})(BitImageMode || (exports.BitImageMode = BitImageMode = {}));
|
|
507
|
+
/**
|
|
508
|
+
* ESC * m nL nH d1...dk - Print bit image
|
|
509
|
+
* m: Bit image mode
|
|
510
|
+
* nL, nH: Number of data columns (nL + nH × 256)
|
|
511
|
+
* d1...dk: Bit image data
|
|
512
|
+
*/
|
|
513
|
+
const printBitImage = (mode, width, data) => {
|
|
514
|
+
const nL = width & 0xff;
|
|
515
|
+
const nH = (width >> 8) & 0xff;
|
|
516
|
+
return [exports.ESC, 0x2a, mode, nL, nH, ...data];
|
|
517
|
+
};
|
|
518
|
+
exports.printBitImage = printBitImage;
|
|
519
|
+
// ============================================================================
|
|
520
|
+
// GRAPHICS - DOWNLOADED BIT IMAGE
|
|
521
|
+
// ============================================================================
|
|
522
|
+
/**
|
|
523
|
+
* GS * x y d1...dk - Define downloaded bit image
|
|
524
|
+
* x: Number of bytes in horizontal direction (1 ≤ x ≤ 255)
|
|
525
|
+
* y: Number of bytes in vertical direction (1 ≤ y ≤ 48)
|
|
526
|
+
* Horizontal dots = x × 8
|
|
527
|
+
* Vertical dots = y × 8
|
|
528
|
+
*/
|
|
529
|
+
const defineDownloadedBitImage = (x, y, data) => {
|
|
530
|
+
const xVal = Math.max(1, Math.min(255, x));
|
|
531
|
+
const yVal = Math.max(1, Math.min(48, y));
|
|
532
|
+
return [exports.GS, 0x2a, xVal, yVal, ...data];
|
|
533
|
+
};
|
|
534
|
+
exports.defineDownloadedBitImage = defineDownloadedBitImage;
|
|
535
|
+
/**
|
|
536
|
+
* Downloaded image print modes
|
|
537
|
+
*/
|
|
538
|
+
var DownloadedImageMode;
|
|
539
|
+
(function (DownloadedImageMode) {
|
|
540
|
+
DownloadedImageMode[DownloadedImageMode["NORMAL"] = 0] = "NORMAL";
|
|
541
|
+
DownloadedImageMode[DownloadedImageMode["DOUBLE_WIDTH"] = 1] = "DOUBLE_WIDTH";
|
|
542
|
+
DownloadedImageMode[DownloadedImageMode["DOUBLE_HEIGHT"] = 2] = "DOUBLE_HEIGHT";
|
|
543
|
+
DownloadedImageMode[DownloadedImageMode["QUADRUPLE"] = 3] = "QUADRUPLE";
|
|
544
|
+
})(DownloadedImageMode || (exports.DownloadedImageMode = DownloadedImageMode = {}));
|
|
545
|
+
/**
|
|
546
|
+
* GS / m - Print downloaded bit image
|
|
547
|
+
* m: Print mode (0-3)
|
|
548
|
+
*/
|
|
549
|
+
const printDownloadedBitImage = (mode) => [exports.GS, 0x2f, mode];
|
|
550
|
+
exports.printDownloadedBitImage = printDownloadedBitImage;
|
|
551
|
+
// ============================================================================
|
|
552
|
+
// GRAPHICS - NV BIT IMAGE
|
|
553
|
+
// ============================================================================
|
|
554
|
+
/**
|
|
555
|
+
* FS p n m - Print NV bit image
|
|
556
|
+
* n: NV bit image number (1-255)
|
|
557
|
+
* m: Print mode (0-3, same as DownloadedImageMode)
|
|
558
|
+
*/
|
|
559
|
+
const printNVBitImage = (imageNumber, mode) => [exports.FS, 0x70, Math.max(1, Math.min(255, imageNumber)), mode];
|
|
560
|
+
exports.printNVBitImage = printNVBitImage;
|
|
561
|
+
/**
|
|
562
|
+
* FS q n [xL xH yL yH d1...dk]1...n - Define NV bit image
|
|
563
|
+
* n: Number of NV bit images to define (1-255)
|
|
564
|
+
* For each image:
|
|
565
|
+
* xL, xH: Width in bytes ((xH × 256 + xL) × 8 dots)
|
|
566
|
+
* yL, yH: Height in bytes ((yH × 256 + yL) × 8 dots)
|
|
567
|
+
* d1...dk: Bit image data
|
|
568
|
+
*/
|
|
569
|
+
const defineNVBitImage = (images) => {
|
|
570
|
+
const result = [exports.FS, 0x71, Math.min(images.length, 255)];
|
|
571
|
+
for (const img of images.slice(0, 255)) {
|
|
572
|
+
const xL = img.width & 0xff;
|
|
573
|
+
const xH = (img.width >> 8) & 0xff;
|
|
574
|
+
const yL = img.height & 0xff;
|
|
575
|
+
const yH = (img.height >> 8) & 0xff;
|
|
576
|
+
result.push(xL, xH, yL, yH, ...img.data);
|
|
577
|
+
}
|
|
578
|
+
return result;
|
|
579
|
+
};
|
|
580
|
+
exports.defineNVBitImage = defineNVBitImage;
|
|
581
|
+
// ============================================================================
|
|
582
|
+
// BARCODE CONFIGURATION
|
|
583
|
+
// ============================================================================
|
|
584
|
+
/**
|
|
585
|
+
* Barcode HRI (Human Readable Interpretation) position
|
|
586
|
+
*/
|
|
587
|
+
var BarcodeHRIPosition;
|
|
588
|
+
(function (BarcodeHRIPosition) {
|
|
589
|
+
BarcodeHRIPosition[BarcodeHRIPosition["NOT_PRINTED"] = 0] = "NOT_PRINTED";
|
|
590
|
+
BarcodeHRIPosition[BarcodeHRIPosition["ABOVE"] = 1] = "ABOVE";
|
|
591
|
+
BarcodeHRIPosition[BarcodeHRIPosition["BELOW"] = 2] = "BELOW";
|
|
592
|
+
BarcodeHRIPosition[BarcodeHRIPosition["BOTH"] = 3] = "BOTH";
|
|
593
|
+
})(BarcodeHRIPosition || (exports.BarcodeHRIPosition = BarcodeHRIPosition = {}));
|
|
594
|
+
/**
|
|
595
|
+
* GS H n - Select HRI character print position
|
|
596
|
+
*/
|
|
597
|
+
const setBarcodeHRI = (position) => [
|
|
598
|
+
exports.GS,
|
|
599
|
+
0x48,
|
|
600
|
+
position,
|
|
601
|
+
];
|
|
602
|
+
exports.setBarcodeHRI = setBarcodeHRI;
|
|
603
|
+
/**
|
|
604
|
+
* GS f n - Select font for HRI characters
|
|
605
|
+
* n = 0 or 48: Font A
|
|
606
|
+
* n = 1 or 49: Font B
|
|
607
|
+
*/
|
|
608
|
+
const setBarcodeFont = (fontB) => [
|
|
609
|
+
exports.GS,
|
|
610
|
+
0x66,
|
|
611
|
+
fontB ? 0x01 : 0x00,
|
|
612
|
+
];
|
|
613
|
+
exports.setBarcodeFont = setBarcodeFont;
|
|
614
|
+
/**
|
|
615
|
+
* GS h n - Set barcode height
|
|
616
|
+
* Range: 1 ≤ n ≤ 255 (in dots)
|
|
617
|
+
* Default: 162
|
|
618
|
+
*/
|
|
619
|
+
const setBarcodeHeight = (height) => [
|
|
620
|
+
exports.GS,
|
|
621
|
+
0x68,
|
|
622
|
+
Math.max(1, Math.min(255, height)),
|
|
623
|
+
];
|
|
624
|
+
exports.setBarcodeHeight = setBarcodeHeight;
|
|
625
|
+
/**
|
|
626
|
+
* GS w n - Set barcode width
|
|
627
|
+
* Range: 2 ≤ n ≤ 6 (module width in dots)
|
|
628
|
+
* Default: 3
|
|
629
|
+
*/
|
|
630
|
+
const setBarcodeWidth = (width) => [
|
|
631
|
+
exports.GS,
|
|
632
|
+
0x77,
|
|
633
|
+
Math.max(2, Math.min(6, width)),
|
|
634
|
+
];
|
|
635
|
+
exports.setBarcodeWidth = setBarcodeWidth;
|
|
636
|
+
// ============================================================================
|
|
637
|
+
// BARCODE PRINTING
|
|
638
|
+
// ============================================================================
|
|
639
|
+
/**
|
|
640
|
+
* Barcode symbologies
|
|
641
|
+
*/
|
|
642
|
+
var BarcodeType;
|
|
643
|
+
(function (BarcodeType) {
|
|
644
|
+
BarcodeType[BarcodeType["UPC_A"] = 0] = "UPC_A";
|
|
645
|
+
BarcodeType[BarcodeType["UPC_E"] = 1] = "UPC_E";
|
|
646
|
+
BarcodeType[BarcodeType["EAN13"] = 2] = "EAN13";
|
|
647
|
+
BarcodeType[BarcodeType["EAN8"] = 3] = "EAN8";
|
|
648
|
+
BarcodeType[BarcodeType["CODE39"] = 4] = "CODE39";
|
|
649
|
+
BarcodeType[BarcodeType["ITF"] = 5] = "ITF";
|
|
650
|
+
BarcodeType[BarcodeType["CODABAR"] = 6] = "CODABAR";
|
|
651
|
+
BarcodeType[BarcodeType["CODE93"] = 72] = "CODE93";
|
|
652
|
+
BarcodeType[BarcodeType["CODE128"] = 73] = "CODE128";
|
|
653
|
+
})(BarcodeType || (exports.BarcodeType = BarcodeType = {}));
|
|
654
|
+
/**
|
|
655
|
+
* GS k m d1...dk NUL - Print barcode (NUL-terminated)
|
|
656
|
+
* For barcode types 0-6 (UPC-A, UPC-E, EAN-13, EAN-8, CODE39, ITF, CODABAR)
|
|
657
|
+
*/
|
|
658
|
+
const printBarcode = (type, data) => {
|
|
659
|
+
const bytes = data.split("").map((c) => c.charCodeAt(0));
|
|
660
|
+
return [exports.GS, 0x6b, type, ...bytes, 0x00];
|
|
661
|
+
};
|
|
662
|
+
exports.printBarcode = printBarcode;
|
|
663
|
+
/**
|
|
664
|
+
* GS k m n d1...dn - Print barcode (length-specified)
|
|
665
|
+
* For barcode types 65-73 (with length prefix)
|
|
666
|
+
*/
|
|
667
|
+
const printBarcodeWithLength = (type, data) => {
|
|
668
|
+
const bytes = data.split("").map((c) => c.charCodeAt(0));
|
|
669
|
+
return [exports.GS, 0x6b, type, bytes.length, ...bytes];
|
|
670
|
+
};
|
|
671
|
+
exports.printBarcodeWithLength = printBarcodeWithLength;
|
|
672
|
+
/**
|
|
673
|
+
* Print UPC-A barcode
|
|
674
|
+
* Requires 11-12 digits
|
|
675
|
+
*/
|
|
676
|
+
const printBarcodeUPCA = (data) => {
|
|
677
|
+
if (!/^\d{11,12}$/.test(data)) {
|
|
678
|
+
throw new Error("UPC-A requires 11-12 digits");
|
|
679
|
+
}
|
|
680
|
+
return (0, exports.printBarcode)(BarcodeType.UPC_A, data.slice(0, 12));
|
|
681
|
+
};
|
|
682
|
+
exports.printBarcodeUPCA = printBarcodeUPCA;
|
|
683
|
+
/**
|
|
684
|
+
* Print UPC-E barcode
|
|
685
|
+
* Requires 6-8 digits
|
|
686
|
+
*/
|
|
687
|
+
const printBarcodeUPCE = (data) => {
|
|
688
|
+
if (!/^\d{6,8}$/.test(data)) {
|
|
689
|
+
throw new Error("UPC-E requires 6-8 digits");
|
|
690
|
+
}
|
|
691
|
+
return (0, exports.printBarcode)(BarcodeType.UPC_E, data);
|
|
692
|
+
};
|
|
693
|
+
exports.printBarcodeUPCE = printBarcodeUPCE;
|
|
694
|
+
/**
|
|
695
|
+
* Print EAN-13 barcode
|
|
696
|
+
* Requires 12-13 digits
|
|
697
|
+
*/
|
|
698
|
+
const printBarcodeEAN13 = (data) => {
|
|
699
|
+
if (!/^\d{12,13}$/.test(data)) {
|
|
700
|
+
throw new Error("EAN-13 requires 12-13 digits");
|
|
701
|
+
}
|
|
702
|
+
return (0, exports.printBarcode)(BarcodeType.EAN13, data.slice(0, 13));
|
|
703
|
+
};
|
|
704
|
+
exports.printBarcodeEAN13 = printBarcodeEAN13;
|
|
705
|
+
/**
|
|
706
|
+
* Print EAN-8 barcode
|
|
707
|
+
* Requires 7-8 digits
|
|
708
|
+
*/
|
|
709
|
+
const printBarcodeEAN8 = (data) => {
|
|
710
|
+
if (!/^\d{7,8}$/.test(data)) {
|
|
711
|
+
throw new Error("EAN-8 requires 7-8 digits");
|
|
712
|
+
}
|
|
713
|
+
return (0, exports.printBarcode)(BarcodeType.EAN8, data);
|
|
714
|
+
};
|
|
715
|
+
exports.printBarcodeEAN8 = printBarcodeEAN8;
|
|
716
|
+
/**
|
|
717
|
+
* Print CODE39 barcode
|
|
718
|
+
* Supports: 0-9, A-Z, space, and symbols ($ % + - . /)
|
|
719
|
+
*/
|
|
720
|
+
const printBarcodeCODE39 = (data) => {
|
|
721
|
+
if (!/^[0-9A-Z $%+\-.\/]+$/.test(data)) {
|
|
722
|
+
throw new Error("CODE39 supports: 0-9, A-Z, space, $%+-./ only");
|
|
723
|
+
}
|
|
724
|
+
return (0, exports.printBarcode)(BarcodeType.CODE39, data);
|
|
725
|
+
};
|
|
726
|
+
exports.printBarcodeCODE39 = printBarcodeCODE39;
|
|
727
|
+
/**
|
|
728
|
+
* Print ITF barcode (Interleaved 2 of 5)
|
|
729
|
+
* Requires even number of digits
|
|
730
|
+
*/
|
|
731
|
+
const printBarcodeITF = (data) => {
|
|
732
|
+
if (!/^\d+$/.test(data) || data.length % 2 !== 0) {
|
|
733
|
+
throw new Error("ITF requires even number of digits");
|
|
734
|
+
}
|
|
735
|
+
return (0, exports.printBarcode)(BarcodeType.ITF, data);
|
|
736
|
+
};
|
|
737
|
+
exports.printBarcodeITF = printBarcodeITF;
|
|
738
|
+
/**
|
|
739
|
+
* Print CODABAR barcode
|
|
740
|
+
* Supports: 0-9, A-D, and symbols ($ + - . / :)
|
|
741
|
+
*/
|
|
742
|
+
const printBarcodeCODABAR = (data) => {
|
|
743
|
+
if (!/^[A-D][0-9A-D $+\-.\/:]*[A-D]$/.test(data)) {
|
|
744
|
+
throw new Error("CODABAR must start and end with A-D, and contain 0-9, A-D, $+-./:");
|
|
745
|
+
}
|
|
746
|
+
return (0, exports.printBarcode)(BarcodeType.CODABAR, data);
|
|
747
|
+
};
|
|
748
|
+
exports.printBarcodeCODABAR = printBarcodeCODABAR;
|
|
749
|
+
/**
|
|
750
|
+
* Print CODE93 barcode
|
|
751
|
+
* Supports all ASCII characters (0-127)
|
|
752
|
+
*/
|
|
753
|
+
const printBarcodeCODE93 = (data) => {
|
|
754
|
+
return (0, exports.printBarcodeWithLength)(BarcodeType.CODE93, data);
|
|
755
|
+
};
|
|
756
|
+
exports.printBarcodeCODE93 = printBarcodeCODE93;
|
|
757
|
+
/**
|
|
758
|
+
* Print CODE128 barcode
|
|
759
|
+
* Supports all ASCII characters (0-127)
|
|
760
|
+
*/
|
|
761
|
+
const printBarcodeCODE128 = (data) => {
|
|
762
|
+
return (0, exports.printBarcodeWithLength)(BarcodeType.CODE128, data);
|
|
763
|
+
};
|
|
764
|
+
exports.printBarcodeCODE128 = printBarcodeCODE128;
|
|
765
|
+
// ============================================================================
|
|
766
|
+
// 2D CODES - PDF417
|
|
767
|
+
// ============================================================================
|
|
768
|
+
/**
|
|
769
|
+
* GS ( k pL pH cn fn [parameters] - PDF417 commands
|
|
770
|
+
* cn = 0x30 (function code 48 for PDF417)
|
|
771
|
+
*/
|
|
772
|
+
/**
|
|
773
|
+
* Set PDF417 number of columns
|
|
774
|
+
* fn = 0x41, n = number of columns (0 or 1-30)
|
|
775
|
+
*/
|
|
776
|
+
const setPDF417Columns = (columns) => {
|
|
777
|
+
const col = Math.max(0, Math.min(30, columns));
|
|
778
|
+
return [exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x30, 0x41, col];
|
|
779
|
+
};
|
|
780
|
+
exports.setPDF417Columns = setPDF417Columns;
|
|
781
|
+
/**
|
|
782
|
+
* Set PDF417 number of rows
|
|
783
|
+
* fn = 0x42, n = number of rows (0 or 3-90)
|
|
784
|
+
*/
|
|
785
|
+
const setPDF417Rows = (rows) => {
|
|
786
|
+
const row = rows === 0 ? 0 : Math.max(3, Math.min(90, rows));
|
|
787
|
+
return [exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x30, 0x42, row];
|
|
788
|
+
};
|
|
789
|
+
exports.setPDF417Rows = setPDF417Rows;
|
|
790
|
+
/**
|
|
791
|
+
* Set PDF417 module width
|
|
792
|
+
* fn = 0x43, n = module width (2-8 dots)
|
|
793
|
+
*/
|
|
794
|
+
const setPDF417Width = (width) => {
|
|
795
|
+
const w = Math.max(2, Math.min(8, width));
|
|
796
|
+
return [exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x30, 0x43, w];
|
|
797
|
+
};
|
|
798
|
+
exports.setPDF417Width = setPDF417Width;
|
|
799
|
+
/**
|
|
800
|
+
* Set PDF417 row height
|
|
801
|
+
* fn = 0x44, n = row height (2-8 dots)
|
|
802
|
+
*/
|
|
803
|
+
const setPDF417RowHeight = (height) => {
|
|
804
|
+
const h = Math.max(2, Math.min(8, height));
|
|
805
|
+
return [exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x30, 0x44, h];
|
|
806
|
+
};
|
|
807
|
+
exports.setPDF417RowHeight = setPDF417RowHeight;
|
|
808
|
+
/**
|
|
809
|
+
* Set PDF417 error correction level
|
|
810
|
+
* fn = 0x45, m = 48 (standard mode), n = level (0-8)
|
|
811
|
+
*/
|
|
812
|
+
const setPDF417ErrorCorrection = (level) => {
|
|
813
|
+
const lvl = Math.max(0, Math.min(8, level));
|
|
814
|
+
return [exports.GS, 0x28, 0x6b, 0x04, 0x00, 0x30, 0x45, 0x30, lvl];
|
|
815
|
+
};
|
|
816
|
+
exports.setPDF417ErrorCorrection = setPDF417ErrorCorrection;
|
|
817
|
+
/**
|
|
818
|
+
* Store PDF417 data
|
|
819
|
+
* fn = 0x50, m = 48 (standard mode), followed by data
|
|
820
|
+
*/
|
|
821
|
+
const storePDF417Data = (data) => {
|
|
822
|
+
const bytes = new TextEncoder().encode(data);
|
|
823
|
+
const pL = (bytes.length + 3) & 0xff;
|
|
824
|
+
const pH = ((bytes.length + 3) >> 8) & 0xff;
|
|
825
|
+
return [exports.GS, 0x28, 0x6b, pL, pH, 0x30, 0x50, 0x30, ...Array.from(bytes)];
|
|
826
|
+
};
|
|
827
|
+
exports.storePDF417Data = storePDF417Data;
|
|
828
|
+
/**
|
|
829
|
+
* Print PDF417 symbol
|
|
830
|
+
* fn = 0x51, m = 48 (standard mode)
|
|
831
|
+
*/
|
|
832
|
+
const printPDF417 = () => [
|
|
833
|
+
exports.GS,
|
|
834
|
+
0x28,
|
|
835
|
+
0x6b,
|
|
836
|
+
0x03,
|
|
837
|
+
0x00,
|
|
838
|
+
0x30,
|
|
839
|
+
0x51,
|
|
840
|
+
0x30,
|
|
841
|
+
];
|
|
842
|
+
exports.printPDF417 = printPDF417;
|
|
843
|
+
/**
|
|
844
|
+
* Generate complete PDF417 barcode
|
|
845
|
+
* Convenience function that combines all PDF417 commands
|
|
846
|
+
*/
|
|
847
|
+
const generatePDF417 = (data, options) => {
|
|
848
|
+
const commands = [];
|
|
849
|
+
if (options?.columns !== undefined) {
|
|
850
|
+
commands.push(...(0, exports.setPDF417Columns)(options.columns));
|
|
851
|
+
}
|
|
852
|
+
if (options?.rows !== undefined) {
|
|
853
|
+
commands.push(...(0, exports.setPDF417Rows)(options.rows));
|
|
854
|
+
}
|
|
855
|
+
if (options?.width !== undefined) {
|
|
856
|
+
commands.push(...(0, exports.setPDF417Width)(options.width));
|
|
857
|
+
}
|
|
858
|
+
if (options?.rowHeight !== undefined) {
|
|
859
|
+
commands.push(...(0, exports.setPDF417RowHeight)(options.rowHeight));
|
|
860
|
+
}
|
|
861
|
+
if (options?.errorCorrection !== undefined) {
|
|
862
|
+
commands.push(...(0, exports.setPDF417ErrorCorrection)(options.errorCorrection));
|
|
863
|
+
}
|
|
864
|
+
commands.push(...(0, exports.storePDF417Data)(data));
|
|
865
|
+
commands.push(...(0, exports.printPDF417)());
|
|
866
|
+
return commands;
|
|
867
|
+
};
|
|
868
|
+
exports.generatePDF417 = generatePDF417;
|
|
869
|
+
// ============================================================================
|
|
870
|
+
// CHARACTER EFFECTS (ADVANCED)
|
|
871
|
+
// ============================================================================
|
|
872
|
+
/**
|
|
873
|
+
* GS ! n - Select character size
|
|
874
|
+
* Supports 1-8x width and height multipliers
|
|
875
|
+
* Bits 0-2: Width (0-7 for 1x-8x)
|
|
876
|
+
* Bits 4-6: Height (0-7 for 1x-8x)
|
|
877
|
+
*/
|
|
878
|
+
const selectCharacterSize = (widthMultiplier, heightMultiplier) => {
|
|
879
|
+
const w = Math.max(0, Math.min(7, widthMultiplier - 1));
|
|
880
|
+
const h = Math.max(0, Math.min(7, heightMultiplier - 1));
|
|
881
|
+
const n = (w & 0x07) | ((h & 0x07) << 4);
|
|
882
|
+
return [exports.GS, 0x21, n];
|
|
883
|
+
};
|
|
884
|
+
exports.selectCharacterSize = selectCharacterSize;
|
|
885
|
+
/**
|
|
886
|
+
* GS B n - Turn white/black reverse printing mode on/off
|
|
887
|
+
* n = 0 or 48: Turn off white/black reverse mode
|
|
888
|
+
* n = 1 or 49: Turn on white/black reverse mode
|
|
889
|
+
*/
|
|
890
|
+
exports.REVERSE_PRINT_ON = [exports.GS, 0x42, 0x01];
|
|
891
|
+
exports.REVERSE_PRINT_OFF = [exports.GS, 0x42, 0x00];
|
|
892
|
+
/**
|
|
893
|
+
* GS ( N pL pH fn n - Select character effects
|
|
894
|
+
* fn = 48: Set character color
|
|
895
|
+
* fn = 49: Set character smoothing
|
|
896
|
+
*/
|
|
897
|
+
const setCharacterColor = (color) => [
|
|
898
|
+
exports.GS,
|
|
899
|
+
0x28,
|
|
900
|
+
0x4e,
|
|
901
|
+
0x02,
|
|
902
|
+
0x00,
|
|
903
|
+
0x30,
|
|
904
|
+
color,
|
|
905
|
+
];
|
|
906
|
+
exports.setCharacterColor = setCharacterColor;
|
|
907
|
+
const setCharacterSmoothing = (enabled) => [
|
|
908
|
+
exports.GS,
|
|
909
|
+
0x28,
|
|
910
|
+
0x4e,
|
|
911
|
+
0x02,
|
|
912
|
+
0x00,
|
|
913
|
+
0x31,
|
|
914
|
+
enabled ? 0x01 : 0x00,
|
|
915
|
+
];
|
|
916
|
+
exports.setCharacterSmoothing = setCharacterSmoothing;
|
|
917
|
+
// ============================================================================
|
|
918
|
+
// STATUS COMMANDS
|
|
919
|
+
// ============================================================================
|
|
920
|
+
/**
|
|
921
|
+
* GS a n - Enable/disable Automatic Status Back (ASB)
|
|
922
|
+
* n is a bitmask for status types to enable
|
|
923
|
+
*/
|
|
924
|
+
const enableASB = (statusBits) => [
|
|
925
|
+
exports.GS,
|
|
926
|
+
0x61,
|
|
927
|
+
statusBits,
|
|
928
|
+
];
|
|
929
|
+
exports.enableASB = enableASB;
|
|
930
|
+
const disableASB = () => [exports.GS, 0x61, 0x00];
|
|
931
|
+
exports.disableASB = disableASB;
|
|
932
|
+
/**
|
|
933
|
+
* Printer ID types for GS I command
|
|
934
|
+
*/
|
|
935
|
+
var PrinterIDType;
|
|
936
|
+
(function (PrinterIDType) {
|
|
937
|
+
PrinterIDType[PrinterIDType["PRINTER_MODEL"] = 1] = "PRINTER_MODEL";
|
|
938
|
+
PrinterIDType[PrinterIDType["TYPE_ID"] = 2] = "TYPE_ID";
|
|
939
|
+
PrinterIDType[PrinterIDType["ROM_VERSION"] = 65] = "ROM_VERSION";
|
|
940
|
+
PrinterIDType[PrinterIDType["FONT_TYPE"] = 66] = "FONT_TYPE";
|
|
941
|
+
PrinterIDType[PrinterIDType["MANUFACTURER"] = 67] = "MANUFACTURER";
|
|
942
|
+
})(PrinterIDType || (exports.PrinterIDType = PrinterIDType = {}));
|
|
943
|
+
/**
|
|
944
|
+
* GS I n - Transmit printer ID
|
|
945
|
+
*/
|
|
946
|
+
const requestPrinterID = (type) => [
|
|
947
|
+
exports.GS,
|
|
948
|
+
0x49,
|
|
949
|
+
type,
|
|
950
|
+
];
|
|
951
|
+
exports.requestPrinterID = requestPrinterID;
|
|
952
|
+
/**
|
|
953
|
+
* Status types for GS r command
|
|
954
|
+
*/
|
|
955
|
+
var StatusType;
|
|
956
|
+
(function (StatusType) {
|
|
957
|
+
StatusType[StatusType["PAPER_SENSOR"] = 1] = "PAPER_SENSOR";
|
|
958
|
+
StatusType[StatusType["DRAWER_SENSOR"] = 2] = "DRAWER_SENSOR";
|
|
959
|
+
StatusType[StatusType["INK_SENSOR"] = 4] = "INK_SENSOR";
|
|
960
|
+
StatusType[StatusType["PAPER_ROLL_SENSOR"] = 18] = "PAPER_ROLL_SENSOR";
|
|
961
|
+
})(StatusType || (exports.StatusType = StatusType = {}));
|
|
962
|
+
/**
|
|
963
|
+
* GS r n - Transmit status
|
|
964
|
+
*/
|
|
965
|
+
const requestStatus = (type) => [exports.GS, 0x72, type];
|
|
966
|
+
exports.requestStatus = requestStatus;
|
|
967
|
+
// ============================================================================
|
|
968
|
+
// MARGINS & PRINT AREA
|
|
969
|
+
// ============================================================================
|
|
970
|
+
/**
|
|
971
|
+
* GS L nL nH - Set left margin
|
|
972
|
+
* Left margin = ((nH × 256) + nL) × (horizontal motion unit)
|
|
973
|
+
*/
|
|
974
|
+
const setLeftMargin = (dots) => {
|
|
975
|
+
const nL = dots & 0xff;
|
|
976
|
+
const nH = (dots >> 8) & 0xff;
|
|
977
|
+
return [exports.GS, 0x4c, nL, nH];
|
|
978
|
+
};
|
|
979
|
+
exports.setLeftMargin = setLeftMargin;
|
|
980
|
+
/**
|
|
981
|
+
* GS W nL nH - Set printing area width
|
|
982
|
+
* Width = ((nH × 256) + nL) × (horizontal motion unit)
|
|
983
|
+
*/
|
|
984
|
+
const setPrintingAreaWidth = (dots) => {
|
|
985
|
+
const nL = dots & 0xff;
|
|
986
|
+
const nH = (dots >> 8) & 0xff;
|
|
987
|
+
return [exports.GS, 0x57, nL, nH];
|
|
988
|
+
};
|
|
989
|
+
exports.setPrintingAreaWidth = setPrintingAreaWidth;
|
|
990
|
+
// ============================================================================
|
|
991
|
+
// MACRO FUNCTIONS
|
|
992
|
+
// ============================================================================
|
|
993
|
+
/**
|
|
994
|
+
* GS : - Start/end macro definition
|
|
995
|
+
* First call starts macro definition
|
|
996
|
+
* Second call ends macro definition
|
|
997
|
+
*/
|
|
998
|
+
exports.START_MACRO = [exports.GS, 0x3a];
|
|
999
|
+
exports.END_MACRO = [exports.GS, 0x3a];
|
|
1000
|
+
/**
|
|
1001
|
+
* GS ^ r t m - Execute macro
|
|
1002
|
+
* r: Number of times to execute macro (0-255)
|
|
1003
|
+
* t: Waiting time between executions (0-255, units of 100ms)
|
|
1004
|
+
* m: Macro execution mode (0 or 1)
|
|
1005
|
+
*/
|
|
1006
|
+
const executeMacro = (repeatCount, waitTime, mode) => [
|
|
1007
|
+
exports.GS,
|
|
1008
|
+
0x5e,
|
|
1009
|
+
Math.max(0, Math.min(255, repeatCount)),
|
|
1010
|
+
Math.max(0, Math.min(255, waitTime)),
|
|
1011
|
+
mode,
|
|
1012
|
+
];
|
|
1013
|
+
exports.executeMacro = executeMacro;
|
|
1014
|
+
// ============================================================================
|
|
1015
|
+
// MISCELLANEOUS
|
|
1016
|
+
// ============================================================================
|
|
1017
|
+
/**
|
|
1018
|
+
* ESC U n - Turn unidirectional printing mode on/off
|
|
1019
|
+
* n = 0 or 48: Turn off unidirectional printing
|
|
1020
|
+
* n = 1 or 49: Turn on unidirectional printing
|
|
1021
|
+
*/
|
|
1022
|
+
exports.UNIDIRECTIONAL_ON = [exports.ESC, 0x55, 0x01];
|
|
1023
|
+
exports.UNIDIRECTIONAL_OFF = [exports.ESC, 0x55, 0x00];
|
|
1024
|
+
/**
|
|
1025
|
+
* CAN - Cancel print data in page mode
|
|
1026
|
+
* Deletes all print data in the current printable area
|
|
1027
|
+
*/
|
|
1028
|
+
exports.CANCEL = [exports.CAN];
|
|
1029
|
+
/**
|
|
1030
|
+
* ESC ( A pL pH n m r t - Execute test print
|
|
1031
|
+
* pL pH = 2 (fixed)
|
|
1032
|
+
* n = paper pattern (1-3)
|
|
1033
|
+
* m = mode (0-2)
|
|
1034
|
+
* r = number of times to repeat
|
|
1035
|
+
* t = interval time
|
|
1036
|
+
*/
|
|
1037
|
+
const executeTestPrint = (pattern, mode, repeat) => [
|
|
1038
|
+
exports.ESC,
|
|
1039
|
+
0x28,
|
|
1040
|
+
0x41,
|
|
1041
|
+
0x02,
|
|
1042
|
+
0x00,
|
|
1043
|
+
Math.max(1, Math.min(3, pattern)),
|
|
1044
|
+
Math.max(0, Math.min(2, mode)),
|
|
1045
|
+
repeat,
|
|
1046
|
+
0x00,
|
|
1047
|
+
];
|
|
1048
|
+
exports.executeTestPrint = executeTestPrint;
|