NielsLeenheer / ReceiptPrinterEncoder

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

Unable to print arabic #26

Open vinothmoorthkumar opened 6 years ago

vinothmoorthkumar commented 6 years ago

Its printing ????. I can able to print chines...But arabic is not printing Please help

encoder .codepage('cp864') .text('جريدة') .newline() .cut('partial') .encode()

NielsLeenheer commented 6 years ago

I've done a quick test and it appear that the data I get back from iconv-lite, which does the code page translation, already contain the question marks. So it is not an issue with the printer or EscPosEncoder itself.

I'm not exactly sure why that is happening, except that the unicode code points in the string "جريدة" are not in the translation table. Perhaps the strings needs to be normalised or something. I'll follow up once I have more information.

vinothmoorthkumar commented 6 years ago

Thank you. Its is working fine. Actually codepage i wrong what i gave.. Now its printing but it is printing arabic from left to right. I want to print from right to left. Please help

NielsLeenheer commented 6 years ago

The problem with ESC/POS printers is that they are pretty dumb. You can basically print the arabic characters that the codepage provides and that is it. Things like right-to-left support and glyph shaping is simply not supported.

My advice for proper arabic printing is to create a bitmap, draw a text string and print that.

vinothmoorthkumar commented 6 years ago

Can you please give me any example.. please

tresf commented 6 years ago

The problem with ESC/POS printers is that they are pretty dumb. You can basically print the arabic characters that the codepage provides and that is it. Things like right-to-left support and glyph shaping is simply not supported.

Just got an Epson TM-T88VI which is the latest T88 model at the time of writing this and there are some Arabic settings using a special Epson utility. Here's some more information: https://github.com/qzind/tray/pull/339#issuecomment-404016953

We're using a 3rd party library -- ICU -- that can get the UTF-8 glyph shaping and simplify it to IBM864. It's written in Java and C++: http://site.icu-project.org/#TOC-What-is-ICU-

NielsLeenheer commented 6 years ago

Yes, I am aware of ICU and that would indeed work. However I am not aware of a Javascript implementation of ICU, apart from an enscriptem compiled C version. But that has a pretty high footprint to include with the library.

Mapbox actually uses Enscriptem compiled subset of ICU for pretty much the same purpose, rendering Arabic script on a WebGL map: https://github.com/mapbox/mapbox-gl-rtl-text

williamrizqallah commented 5 years ago

Thank you. Its is working fine. Actually codepage i wrong what i gave.. Now its printing but it is printing arabic from left to right. I want to print from right to left. Please help

Hi @vinothmoorthkumar How did you manage to print Arabic text?

tresf commented 5 years ago

How did you manage to print Arabic text?

Chiming in, if you have the IBM-864 characters (NOT the UTF-8) characters and a printer that supports IBM-864, this should work. As noted above, the bytes may need to be swapped.

Since 99% of websites are UTF-8, this makes Arabic very difficult natively (hence the conversation about about the ICU translation). Feel free to email me directly for more info about how I solved this problem. I believe most programmers give up with Arabic and send a raster image or PDF instead.

williamrizqallah commented 5 years ago

@tresf Could you send me an example, please

williamrizqallah commented 5 years ago

@tresf This is my case

encodeWords(word){ this.encoder = new EscPosEncoder(); let result = this.encoder .codepage('cp864') .text(word) .encode(); return result; }

tresf commented 5 years ago

@williamrizqallah out of respect of this project, I'm not going to cross-reference my solution, it's in Java and for a commercial product. My email address is in my GitHub profile if interested.

vinothmoorthkumar commented 5 years ago

@williamrizqallah I m using https://www.npmjs.com/package/canvas Canvas. I m creating canvas image and printing using https://www.npmjs.com/package/escpos

williamrizqallah commented 5 years ago

@vinothmoorthkumar Thanks for your response

Could you please show me an example

sanik commented 4 years ago

Did you manage to solve this problem?

vinothmoorthkumar commented 4 years ago

Here is my code

`const { createCanvas, loadImage, Image } = require('canvas'); var escpos = require('escpos');

canvas= createCanvas(580, 700) var ctx = canvas.getContext("2d"); ctx.textAlign = "center"; ctx.font = "30px bold"; ctx.fillText('مرحبا بالعالم',50, 50);

device.open(function () { escpos.Image.load(canvas.toDataURL(), function (rasterimage) { printer.raster(rasterimage) printer.cut() printer.close() }); }); `

musahaidari commented 4 years ago

Just modified @vinothmoorthkumar code little bit to work with printer and node-thermal-printer:

const importedThermalPrinter = require('node-thermal-printer').printer;
const thermalPrinterTypes = require('node-thermal-printer').types;
const printer = require('printer');

const fetchedPrinter = printer.getPrinter('POS-80');

const createCanvas = require('canvas');

canvas = createCanvas(580, 700)
var ctx = canvas.getContext("2d");
ctx.textAlign = "left";
ctx.font = "30px bold";
ctx.fillText(' مرحبا بالعالم', 50, 50);

const thermalPrinter = new importedThermalPrinter({
    type: thermalPrinterTypes.EPSON,
})
thermalPrinter.printImageBuffer(canvas.toBuffer()).then((s) => {

    printer.printDirect({
        data: thermalPrinter.getBuffer(),
        printer: fetchedPrinter.name,
        type: "RAW",
        success: function (job_id) {
            console.log('OK :' + job_id);
        },
        error: function (err) {
            console.error(err);
        }
    });
}, (e) => {
    console.error(e);
});
alimuhnad commented 4 years ago

u can use .codepage('iso88596') or .codepage('windows1256') it will work

jadallah commented 3 years ago

hello my printer is print ?????? when use .codepage('iso88596') or .codepage('windows1256') any fix please

Waheed-Rumaneh commented 3 years ago

hello my printer is print ?????? when use .codepage('iso88596') or .codepage('windows1256') any fix please

@jadallah

use encoding: 'Arabic', codepage: 22,

amalnafia commented 3 years ago

@Waheed-Rumaneh it did not work

Waheed-Rumaneh commented 3 years ago

@amalnafia

yes i researched about it and it's worked for some printer Each printer have difference code so you can't build a general code

the best way i used and it's worked prefect :

amalnafia commented 3 years ago

@Waheed-Rumaneh

i am working with android device

jadallah commented 3 years ago

@amalnafia i was able to print arabic by make the invoice as photo with server side then use this plugin to print photo and it work perfect

bazl-E commented 2 years ago

EscPosEncode

does this works,which converter are you using

blackangiliq commented 2 years ago

u can use this

you can check this

this repo use 3 laiblary

secreenshot to convert widget to image and image library to convert it to uint8 and pos_print to print it ass u love to show

https://github.com/blackangiliq/flutter_pos_printer_spport_arabic

laithbzour commented 2 years ago

you need to convert text to bitmap image .. if image too height then after convert to bitmap split image to chunk note : you must get max width of printer to rescale image

yaser-elbatal commented 2 years ago

how can you print arabic ?

yaser-elbatal commented 2 years ago

Thank you. Its is working fine. Actually codepage i wrong what i gave.. Now its printing but it is printing arabic from left to right. I want to print from right to left. Please help

How you solve it to be able print Arabic ?

laithbzour commented 2 years ago

@yaser-elbatal use this command before print : byte[] ESC_ALIGN_LEFT = new byte[] { 0x1b, 'a', 0x00 }; byte[] ESC_ALIGN_RIGHT = new byte[] { 0x1b, 'a', 0x02 }; byte[] ESC_ALIGN_CENTER = new byte[] { 0x1b, 'a', 0x01 };

thanks

yaser-elbatal commented 2 years ago

@yaser-elbatal use this command before print : byte[] ESC_ALIGN_LEFT = new byte[] { 0x1b, 'a', 0x00 }; byte[] ESC_ALIGN_RIGHT = new byte[] { 0x1b, 'a', 0x02 }; byte[] ESC_ALIGN_CENTER = new byte[] { 0x1b, 'a', 0x01 };

thanks

with EscPosEncoder or Canvas ? can you share code please ? @laithbzour

alimuhnad commented 2 years ago

I fix this problem by ...... 1-make the text as image 2-print the image as base64 I used this method in 2018 but i forget to close the issue .... There is no another way for Arabic language

laithbzour commented 2 years ago

@yaser-elbatal sure : try { EscPosPrinter printer = new EscPosPrinter(MyBluetoothPrintersConnections.selectFirstPairedOne(), 203, 58f, 20); StringBuilder textToPrint = new StringBuilder(); splitImage(yourBitmap, splitImg->{ textToPrint.append("[C]" + PrinterTextParserImg.bitmapToHexadecimalString(printer, splitImg) + "\n"+ "[L]\n"); }); textToPrint.append("[C]--------------------------------\n"); printer.printFormattedTextAndCut(textToPrint.toString()); } catch (EscPosConnectionException e) { e.printStackTrace(); } catch (EscPosEncodingException e) { e.printStackTrace(); } catch (EscPosBarcodeException e) { e.printStackTrace(); } catch (EscPosParserException e) { e.printStackTrace(); }

laithbzour commented 2 years ago

@yaser-elbatal

use this lib to build bitmap from text :
compile 'com.github.danielfelgar:draw-receipt:0.1.3'

private  Bitmap greatBitmapText(String text){
    ImageBuilder  receipt = new ImageBuilder(400);
            receipt.setMargin(5, 1).
            setAlign(Paint.Align.LEFT). ---> change it to "CENTER" or "RIGHT" 
            setColor(Color.parseColor("#85929E")).
            setTextSize(28).
            addText(text)
    return receipt.build();
}