NielsLeenheer / ReceiptPrinterEncoder

Create a set of commands that can be send to any receipt printer that supports ESC/POS, StarLine or StarPRNT
MIT License
183 stars 17 forks source link

Horizontal Rule not getting printed correctly #14

Closed madVis closed 2 months ago

madVis commented 2 months ago

I'm trying to print horizontal rule but instead it's printing some other special characters. I've tried printing both 'single' and 'double' style.

encoder.initialize()
.rule({ style: 'double' })
        .line("Hello World!")
        .rule({ style: 'single' })
        .encode()

IMG_0424

NielsLeenheer commented 2 months ago

It looks like your printer is set to double byte mode by default. What type of printer are you using?

madVis commented 2 months ago

Thanks for the help. The codepage was set to CP437, but the byte mode was double. I changed it to single-byte mode, and then the horizontal rule printed correctly. However, I'm curious why normal text prints correctly with CP437 in double-byte mode, but the horizontal rule does not.

I'm using a Shreyans bluetooth thermal printer.

NielsLeenheer commented 2 months ago

In double byte mode the printer looks at the first character and checks if it is using the top half of the byte (0x80 or higher). If it is, then it is a double byte character. If it isn't, it assumes it is just ASCII. So if you print ASCII text in double byte mode, it just works fine. But if you print a horizontal line using CP437, it will encode that character using the top half of the byte. So the printer will interpret it as a double byte character.

For example:

A line segment (─) is 0xc4 in CP437. So if you place multiple segments after each other you will get a line with that byte repeated. And in double byte mode using GB18030, 0xc4c4 is mapped to unicode character U+54EA (哪), which is exactly what you are seeing on your receipt.

And similarly:

A double line segment (═) is 0xcd in CP437. So if you place multiple segments after each other you will get a line with that byte repeated. And in double byte mode using GB18030, 0xcdcd is mapped to unicode character U+5C6F (屯), which is again exactly what you are seeing on your receipt.

NielsLeenheer commented 2 months ago

Oh, btw, the upcoming release will turn off double byte mode when you initialise the printer. So it will always be in the correct mode for the code pages.

madVis commented 2 months ago

Thanks for the clarification! I understand the behavior now. However, I have a follow-up question:

For any code page like GB18030 (say for Chinese, Korean etc), will the encoder automatically switch to double-byte mode when necessary (i.e., enable Kanji mode)? If not, do I need to manually turn double-byte mode on before printing Chinese characters?

Also, if I print lines or characters using CP437 after printing Chinese text, would I need to switch back to single-byte mode, or does it handle that automatically?

Thanks again for your help!

NielsLeenheer commented 2 months ago

Right now this library does not have proper double byte support. Mainly because I personally haven't had the need to look into it, and adding it would increase the size of the library by.... a lot. The tables needed for this are huge.

But it is on the list. Probably as some sort of optional dependency.

madVis commented 1 month ago

@NielsLeenheer I've got a few doubts regarding double-byte mode and codepages. It would be really helpful if you could clarify the following:

Thanks in advance for your help!

NielsLeenheer commented 1 month ago

First of all, double byte encoding is different from codepages. Chinese, Japanese and Korean use double byte encoding, while western languages and also Hebrew, Arabic and Thai use codepages.

This library does not support double byte encoding.

But it is possible to switch to double byte mode, encode it yourself and switch back, and add the bytes required for that using the raw() command. You do need to switch back every time you want to use a function from the library, such as lines, because the library expects to be in single byte mode. Also using double byte mode in boxes and tables will cause issues, because double byte characters are wider than single byte characters, so the alignment will be off.

So not ideal.