-
Notifications
You must be signed in to change notification settings - Fork 7
/
example.html
245 lines (232 loc) · 11.2 KB
/
example.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
<!--
* This file is part of WebPrint
*
* @author Michael Wallace
*
* Copyright (C) 2015 Michael Wallace, WallaceIT
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-2.1.html
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
-->
<!DOCTYPE html>
<html>
<head>
<title>WebPrint ESC/P Example</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="webprint.js"></script>
<script>
var populatePrinters = function(printers){
var printerlist = $("#printerlist");
printerlist.html('');
for (var i in printers){
printerlist.append('<option value="'+printers[i]+'">'+printers[i]+'</option>');
}
};
var populatePorts = function(ports){
var portlist = $("#portlist");
portlist.html('');
for (var i in ports){
portlist.append('<option value="'+ports[i]+'">'+ports[i]+'</option>');
}
if ($("#portlist option").length)
webprint.openPort($("#portlist option:first-child").val(), {baud:"9600", databits:"8", stopbits:"1", parity:"1", flow:"none"});
};
webprint = new WebPrint(true, {
relayHost: "127.0.0.1",
relayPort: "8080",
listPrinterCallback: populatePrinters,
listPortsCallback: populatePorts,
readyCallback: function(){
webprint.requestPorts();
webprint.requestPrinters();
getESCPImageString("https://wallaceit.com.au/webprint/wallaceit_receipt_logo.png", function (imgdata) {
imgData = imgdata;
console.log("image loaded");
});
}
});
// ESC/P receipt generation
var imgData = '';
getEscSample = function(cut, image){
var data = '';
if (image)
data+= imgData; // add the logo
data+= esc_init + esc_a_c + esc_double + 'Heading Text' + "\n" + font_reset; // heading centered example
data+= esc_bold_on + 'bold text' + "\n" + font_reset; // bold example
data+= 'standard text' + "\n"; // normal
data+= esc_a_r + 'right aligned text' + "\n" + font_reset; // right aligned
data+= esc_a_l + esc_ul_on + 'underlined text' + "\n" + font_reset; // underlined
data+= esc_bold_on + esc_ul_on + 'bold underlined text' + "\n" + font_reset; // bold underlined
// 2 column table
data+= getEscTableRow("left text", "right text", false, false);
data+= getEscTableRow("left text", "right text", true, true);
// cut the ticket
if (cut)
data+= "\n\n\n\n" + gs_cut + "\r";
return data;
};
var esc_init = "\x1B" + "\x40"; // initialize printer
var esc_p = "\x1B" + "\x70" + "\x30"; // open drawer
var gs_cut = "\x1D" + "\x56" + "\x4E"; // cut paper
var esc_a_l = "\x1B" + "\x61" + "\x30"; // align left
var esc_a_c = "\x1B" + "\x61" + "\x31"; // align center
var esc_a_r = "\x1B" + "\x61" + "\x32"; // align right
var esc_double = "\x1B" + "\x21" + "\x31"; // heading
var font_reset = "\x1B" + "\x21" + "\x02"; // styles off
var esc_ul_on = "\x1B" + "\x2D" + "\x31"; // underline on
var esc_bold_on = "\x1B" + "\x45" + "\x31"; // emphasis on
var esc_bold_off = "\x1B" + "\x45" + "\x30"; // emphasis off
function getEscTableRow(leftstr, rightstr, bold, underline) {
var pad = "";
if (leftstr.length + rightstr.length > 48) {
var clip = (leftstr.length + rightstr) - 48; // get amount to clip
leftstr = leftstr.substring(0, (leftstr.length - (clip + 3)));
pad = ".. ";
} else {
var num = 48 - (leftstr.length + rightstr.length);
for (num; num > 0; num--) {
pad += " ";
}
}
var row = leftstr + pad + (underline ? esc_ul_on : '') + rightstr + (underline ? font_reset : '') + "\n";
if (bold) { // format row
row = esc_bold_on + row + esc_bold_off;
}
return row;
}
function getESCPImageString(url, callback) {
img = new Image();
img.onload = function () {
// Create an empty canvas element
//var canvas = document.createElement("canvas");
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
// Copy the image contents to the canvas
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
// get image slices and append commands
var bytedata = esc_init + esc_a_c + getESCPImageSlices(ctx, canvas) + font_reset;
//alert(bytedata);
callback(bytedata);
};
img.src = url;
}
function getESCPImageSlices(context, canvas) {
var width = canvas.width;
var height = canvas.height;
var nL = Math.round(width % 256);
var nH = Math.round(height / 256);
var dotDensity = 33;
// read each pixel and put into a boolean array
var imageData = context.getImageData(0, 0, width, height);
imageData = imageData.data;
// create a boolean array of pixels
var pixArr = [];
for (var pix = 0; pix < imageData.length; pix += 4) {
pixArr.push((imageData[pix] == 0));
}
// create the byte array
var final = [];
// this function adds bytes to the array
function appendBytes() {
for (var i = 0; i < arguments.length; i++) {
final.push(arguments[i]);
}
}
// Set the line spacing to 24 dots, the height of each "stripe" of the image that we're drawing.
appendBytes(0x1B, 0x33, 24);
// Starting from x = 0, read 24 bits down. The offset variable keeps track of our global 'y'position in the image.
// keep making these 24-dot stripes until we've executed past the height of the bitmap.
var offset = 0;
while (offset < height) {
// append the ESCP bit image command
appendBytes(0x1B, 0x2A, dotDensity, nL, nH);
for (var x = 0; x < width; ++x) {
// Remember, 24 dots = 24 bits = 3 bytes. The 'k' variable keeps track of which of those three bytes that we're currently scribbling into.
for (var k = 0; k < 3; ++k) {
var slice = 0;
// The 'b' variable keeps track of which bit in the byte we're recording.
for (var b = 0; b < 8; ++b) {
// Calculate the y position that we're currently trying to draw.
var y = (((offset / 8) + k) * 8) + b;
// Calculate the location of the pixel we want in the bit array. It'll be at (y * width) + x.
var i = (y * width) + x;
// If the image (or this stripe of the image)
// is shorter than 24 dots, pad with zero.
var bit;
if (pixArr.hasOwnProperty(i)) bit = pixArr[i] ? 0x01 : 0x00; else bit = 0x00;
// Finally, store our bit in the byte that we're currently scribbling to. Our current 'b' is actually the exact
// opposite of where we want it to be in the byte, so subtract it from 7, shift our bit into place in a temp
// byte, and OR it with the target byte to get it into the final byte.
slice |= bit << (7 - b); // shift bit and record byte
}
// Phew! Write the damn byte to the buffer
appendBytes(slice);
}
}
// We're done with this 24-dot high pass. Render a newline to bump the print head down to the next line and keep on trucking.
offset += 24;
appendBytes(10);
}
// Restore the line spacing to the default of 30 dots.
appendBytes(0x1B, 0x33, 30);
// convert the array into a bytestring and return
final = ArrayToByteStr(final);
return final;
}
/**
* @return {string}
*/
function ArrayToByteStr(array) {
var s = '';
for (var i = 0; i < array.length; i++) {
s += String.fromCharCode(array[i]);
}
return s;
}
</script>
</head>
<body>
<div>
<h3>Webprint Demo</h3>
<p>
This example shows how you can use webprint to print to ESC/P printers.
</p>
<h4>USB & OS installed printers</h4>
<p>
Printers: <select id="printerlist"></select>
<button onclick="webprint.requestPrinters();">Refresh</button><br/>
<button onclick="webprint.printRaw(esc_init+esc_p+esc_init, $('#printerlist').val());">Cash Draw</button><br/>
<button onclick="webprint.printRaw(getEscSample($('#cutter').is(':checked'),$('#image').is(':checked')), $('#printerlist').val());">Print</button><br/>
</p>
<h4>Serial Printing</h4>
<p>
Ports: <select onchange='webprint.openPort($("#portlist").val(), {baud:"9600", databits:"8", stopbits:"1", parity:"1", flow:"none"});' id="portlist"></select>
<button onclick="webprint.requestPorts();">Refresh</button><br/>
<button onclick="webprint.printSerial(esc_init+esc_p+esc_init, $('#portlist').val());">Cash Draw</button><br/>
<button onclick="webprint.printSerial(getEscSample($('#cutter').is(':checked'),$('#image').is(':checked')), $('#portlist').val());">Print Serial</button><br/>
</p>
<h4>Network Printing:</h4>
<p>
Host: <input id="tcphost" type="text" value="192.168.1.87" /> Port <input id="tcpport" type="text" size="5" value="9100" />
<button onclick="webprint.printTcp(esc_init+esc_p+esc_init, $('#tcphost').val()+':'+$('#tcpport').val());">Cash Draw</button><br/>
<button onclick="webprint.printTcp(getEscSample($('#cutter').is(':checked'),$('#image').is(':checked')), $('#tcphost').val()+':'+$('#tcpport').val());">Print Network</button><br/>
</p>
<h4>Print Options</h4>
<p>
Cutter: <input id="cutter" type="checkbox" checked="checked"/><br/>
Image: <input id="image" type="checkbox" checked="checked"/>
</p>
</div>
</body>
</html>