ESC/POS RAW Printing corruption

743 views
Skip to first unread message

Mat Withers

unread,
Jan 18, 2017, 4:51:56 AM1/18/17
to qz-print
Hi

I'm trying to print to an Epson TM-U295 slip printer in raw mode. It's partially working but  suspect I'm having a problem with BYTE VALUES that are extended ASCII codes. I'm trying to print all values with UTF escaping. For example the code:

(function() {
  var config, data;
  
  config = qz.configs.create({file: 'C:\\TMP\\JS-TEST.OUT', encoding: 'UTF-8'})

  data = [
    '\u001B@',
    '\u001BL',
    '\u001BT\u0000',
    '\u001BW\u0095\u0000\u00B1\u0000\u000C\u0000\u0009\u0000',
    '\f',
    '\u001Bq'
  ];

  qz.print(config, data)['catch'](function(e) {
    console.error(e);
  });

}).call(this);

When printed to file and examined in a hex editor becomes:

1B 40
1B 4C
1B 54 00
1B 57 3F 00 B1 00 0C 00 09 00
34 38 0A
0C
1B 71

As you can see the 4th row down, 3rd byte in has been switched from 0x95 to 0x3F. In bigger jobs I'm seeing quite a few values being switch to 3F (ASCII FOR ?)

Am i missing something or approaching ESC/POS printing in the wrong way ?

Thanks in advance for any insight or help anyone can provide.

Mat

Tres Finocchiaro

unread,
Jan 18, 2017, 10:14:15 AM1/18/17
to Mat Withers, qz-print
Mat,

I think you have a typo which is causing QZ Tray to ignore encoding.


-  config = qz.configs.create({file: 'C:\\TMP\\JS-TEST.OUT', encoding: 'UTF-8'})
+  config = qz.configs.create({file: 'C:\\TMP\\JS-TEST.OUT'}, {encoding: 'UTF-8'})

--
You received this message because you are subscribed to the Google Groups "qz-print" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qz-print+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mat Withers

unread,
Jan 18, 2017, 11:16:11 AM1/18/17
to qz-print, m...@caremeds.co.uk
Hi Tres

Thanks for the reply. i've changed my code an now they result is:

1B 40
1B 4C
1B 54 00
1B 57 C2 95 00 C2 B1 00 0C 00 09 00
34 38 0A
0C
1B 71

On line 4 it has added 0xC2 in front of the 0x95 - which is different to replacing it with 0x3F like it was before. I assume this is as a result of 0x95 (148) being the only ascii extended character in my output. I've checked the javascript arriving at the browser and the data is fine at that point so i know the issue isn't server side (my app is written in ruby on rails)

Any other idea's

Thanks again

Mat


To unsubscribe from this group and stop receiving emails from it, send an email to qz-print+u...@googlegroups.com.

Tres Finocchiaro

unread,
Jan 18, 2017, 11:30:55 AM1/18/17
to Mat Withers, qz-print
Mat,

I would expect UTF8 to force Java to write the file using 4-byte characters.  If you are observing 2-byte characters, something is wrong with the Java code.  We'll review.


To unsubscribe from this group and stop receiving emails from it, send an email to qz-print+unsubscribe@googlegroups.com.

Mat Withers

unread,
Jan 18, 2017, 11:42:20 AM1/18/17
to qz-print, m...@caremeds.co.uk

Hi Tres

Is there a way to Base64 encode my ESC/POS data to avoid the extended chars and then supply the Base54 encoded string in my data array ? I know you can do this when supplying qztray image data but can you do it with raw data ? If so this would presumably resolve the issue.

regards

Mat



On Wednesday, January 18, 2017 at 4:30:55 PM UTC, Tres Finocchiaro wrote:
Mat,

Tres Finocchiaro

unread,
Jan 18, 2017, 11:51:24 AM1/18/17
to Mat Withers, qz-print
Mat,

Yes, you can base64 encode, but that would only circumvent a bugs with JS.  If 4-byte chars are being sent to QZ Tray and the encoding is set to accept them, the flavor from JS shouldn't matter.

Mat Withers

unread,
Jan 19, 2017, 5:47:40 AM1/19/17
to qz-print, m...@caremeds.co.uk
Hi Tres

Base64 encoding it worked perfectly. The only reason I was using unicode was to get the non ascii values into javascript. Using the Base64 method meant that I could generate a raw binary print file server side then encode it to send as is.

Thanks for all your help.

Cheers

Mat

Tres Finocchiaro

unread,
Jan 19, 2017, 10:23:10 AM1/19/17
to Mat Withers, qz-print
Base64 encoding it worked perfectly. The only reason I was using unicode was to get the non ascii values into javascript. Using the Base64 method meant that I could generate a raw binary print file server side then encode it to send as is.

Thanks for the update.  Although you've circumvented your problem, I'm still a bit concerned about the way the bytes were actually sent using the unicode method.

  • The JS file itself should be UTF8 encoded.  Pay close attention to BOM on the file.
  • The HTML content should explicitly define the page as using UTF8, usually with the META tag.
If both of these steps were taken and the data was getting translated by QZ Tray, we have a bug.  Not all clients have the convenience of base64 (they may use web forms and JavaScript to print dynamically).  The '\u0000' syntax should work and be valid.

-Tres


--

Mat Withers

unread,
Jan 19, 2017, 11:01:17 AM1/19/17
to qz-print, m...@caremeds.co.uk
Hi Tres

I definitely have a 'charset="utf-8"' meta tag in my document. Don't full understand the BOM part (Byte ordered marking ?) I was having issues with hex 0x80 to 0x9F (which I was coding as \u0080 .. \u0095). According to http://www.utf8-chartable.de/ these are marked as 'control' characters and the table there gives their UTF-8 Hex values as 'C2 80' .. 'C2 9F'

Could this be the source of the extra C2's ?

Regards

Mat

Tres Finocchiaro

unread,
Jan 20, 2017, 12:41:01 AM1/20/17
to Mat Withers, qz-print
Confirmed.  You're completely right, somewhere along the lines the unicode is taking over and changing the underlying data.

Can you try this instead?

var config, data;

config = qz.configs.create({file: 'C:\\TMP\\JS-TEST.OUT'}, {encoding: 'UTF-8'
})

data = [{
	format: "hex",
	data: 
		'x1B' + 'x40' + 
		'x1B' + 'x4C' +
		'x1B' + 'x54' + 'x00' +
		'x1B' + 'x57' + 'x95' + 'x00' + 'xB1' + 'x00' + 'x0C' + 'x00' + 'x09' + 'x00' +
		'x09' +
		'x1B' + 'x71'
}];
qz.print(config, data)

On a side note, I'm not sure exactly where the \xC295 versus \x0095  assumption is being made.  I have a feeling it is in JavaScript, but I'm having difficulty proving it.

-Tres

--

Tres Finocchiaro

unread,
Jan 20, 2017, 1:02:30 AM1/20/17
to Mat Withers, qz-print
JavaScript appears to be handling the bytes just fine, so the bug likely lies in how Jetty is interpreting the data via WebSocket.

Proof of this is the following code prints without the bugged hex characters.

String.prototype.hexEncode = function(){
	var hex, i;

	var result = "";
	for (i=0; i<this.length; i++) {
		hex = this.charCodeAt(i).toString(16);
		result += "x" + ("0"+hex).slice(-2);
	}

	return result;
}

data = [
	
'\u001B@',
	'\u001BL',
	'\u001BT\u0000',
	'\u001BW\u0095\u0000\u00B1\u0000\u000C\u0000\u0009\u0000',
	'\f',
	'\u001Bq'
];

// re-encode as pure hex
for (var i = 0; i < data.length; i++) {
	data[i] = { format: "hex", data: data[i].hexEncode() };
}

Mat Withers

unread,
Jan 20, 2017, 3:50:00 AM1/20/17
to qz-print, m...@caremeds.co.uk
Hi Tres

You are correct - this works fine. i didn't know about the format: 'hex' options - but now I do I'm going to use it instead of the Base64 option.

Regards

Mat
Reply all
Reply to author
Forward
0 new messages