Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for right-to-left text output #6

Closed
sysxlabs opened this issue Mar 16, 2015 · 27 comments
Closed

Add support for right-to-left text output #6

sysxlabs opened this issue Mar 16, 2015 · 27 comments

Comments

@sysxlabs
Copy link

Hi Mike,

I am here with yet another change. I want to add Arabic Printing support for thermal printers also. can you please write a function to change the code page.

Thanks,

Sam

@sysxlabs sysxlabs changed the title Change Codepage Change Codepage #enhancement Mar 16, 2015
@mike42
Copy link
Owner

mike42 commented Mar 16, 2015

Sure, good suggestion.

This would take the form of a function to switch between the (default) CP437 and the Arabic character sets Windows-1256, CP720 and CP864, as well as a new textRaw() function which behaves the same as the current text() function. In the long run, text() is likely to be modified to accept UTF-8 and auto-switch code pages when needed.

This is will be a simple change, but it will be quite annoying to work with, as you'll have to encode each character in hex according to the new code page.

mike42 added a commit that referenced this issue Mar 17, 2015
@mike42
Copy link
Owner

mike42 commented Mar 17, 2015

Hi Sam,

Can you try sending the output of example/character-set.php to your printer and get me a description of what it prints? I have the three code pages displaying on my TM-T20, but I'd be interested to know how it goes.

I'll leave this enhancement open, as there is still more to do in the character encoding space.

@mike42 mike42 changed the title Change Codepage #enhancement Change Codepage Mar 17, 2015
@sysxlabs
Copy link
Author

sysxlabs commented Apr 2, 2015

Hi Mike,

PFA is the result of the script on my printer
result

@mike42
Copy link
Owner

mike42 commented Apr 3, 2015

Ah drats, the character code support is not what I'd hoped.

I'm not finding any documentation online about what codepages your (E-Pos TEP 220m?) supports, do you have any documentation that might help?

To fill you in, this is what I'm seeing on my Epson TM-T20.

2015-04-character-test

@sysxlabs
Copy link
Author

sysxlabs commented Apr 3, 2015

i do't know that this information can help you or not, but this is the test print from my thermal printer. EPOS TEP 220m
img_1744
img_1745

@sysxlabs
Copy link
Author

sysxlabs commented Apr 3, 2015

i found the following receipt printed by the same EPOS TEP 220M printer in one of the hyper market here.
img_1850

@mike42
Copy link
Owner

mike42 commented Apr 5, 2015

Thanks, this post contains a lot of very useful information.

I had assumed (incorrectly) that the character code tables were the same between Epson and non-Epson models, but the test print confirms that they are different, and explains why your printer was spitting out Hebrew with my code.

I'll see if I can put together another test. Two quick queries-

  • Are you able to type out one of the strings on this receipt so that I can use it in a test?
  • I understand that Arabic is a right-to-left character set- can you confirm whether it is written here RTL?

@sysxlabs
Copy link
Author

sysxlabs commented Apr 5, 2015

Please try this string for the test.
ص.ب. ١١٠٦ ر.ب. ٣١١ صحار، سلطنة عمان

You are right Arabic is RTL, but in the example receipt it is not written RTL. But I have sen some receipts where Arabic is written in RTL orientation.

@mike42
Copy link
Owner

mike42 commented Apr 5, 2015

First attempt- I'm using iconv to convert the string from UTF8 to CP864 and CP1256 (It looks like both will be needed) Some of the characters are visibly different.

  • Can you confirm whether this is a font thing or if the characters are actually incorrect?
  • Are you able to repeat this output on your printer using the code below?

2015-04-receipt-test

I haven't yet sorted out text direction, but if we have the characters, and your output is similar, then this will be a good starting point to code Arabic support into the driver properly.

<?php
require_once(dirname(__FILE__) . "/Escpos.php");
$printer = new Escpos();
$str = "ص.ب. ١١٠٦ ر.ب. ٣١١ صحار، سلطنة عمان";

// Epson character tables
//$try = array(
//  37 => 'CP864',
//  50 => 'CP1256');

// E-pos TEP 200M character tables
$try = array(
    28 => 'CP864',
    34 => 'CP1256');

foreach($try as $targetNumber => $targetEncoding) {
    $map = makeMap($targetEncoding);
    $outp = convert($str, $map);
    $printer -> selectCharacterTable($targetNumber);
    $printer -> textRaw(strrev($outp) . "\n");
}
$printer -> cut();

function convert($str, $map) {
    // Convert UTF8 to the target encoding
    $len = mb_strlen($str);
    $outp = str_repeat("?", $len); 
    for($i = 0; $i < $len; $i++) {
        $utf8 = mb_substr($str, $i, 1);
        if(isset($map[$utf8])) {
            $outp[$i] = $map[$utf8];
        }
    }
    return $outp;
}

function makeMap($targetEncoding) {
    // Make map of target encoding v UTF-8
    $map = array();
    for($i = 0; $i < 255; $i++) {
        $native = chr($i);
        $utf8 = @iconv($targetEncoding, 'UTF-8', $native);
        if($utf8 == '') {
            continue;
        }
        $map[$utf8] = $native;
    }
    return $map;
}

@sysxlabs
Copy link
Author

sysxlabs commented Apr 5, 2015

Can you confirm whether this is a font thing or if the characters are actually incorrect?
The First Line is incorrect, the number is printing in wrong order, the number should be ١١٠٦ but it is being printed in reverse order. For your under standing ١١٠٦ = 1106, but the first line shows number 6011. same goes for the second number in first line.

Line two is correct as it is printing the correct letter in Arabic language. but it needs further improvement.

Are you able to repeat this output on your printer using the code below?
Here is the output from my printer.
img_2234
img_2235

Image 2234 shows the output of your script. Whereas, image 2235 shows the result for different code pages that i think can print anything meaningful.
I use the following code to print image 2235

<?php
require_once(dirname(__FILE__) . "/../Escpos.php");
$fp = fopen ("LPT2", "w");
$printer = new Escpos($fp);
$str = "ص.ب. ١١٠٦ ر.ب. ٣١١ صحار، سلطنة عمان";

// Epson character tables
//$try = array(
//  37 => 'CP864',
//  50 => 'CP1256');

// E-pos TEP 200M character tables
$try = array(
    28 => 'CP864',
    29 => 'CPW1001',
    33 => 'CP720',
    34 => 'CP1256' ,
    63 => 'CP864',
    34 => 'CP1256',
    82 => 'CP1001'
    );

foreach($try as $targetNumber => $targetEncoding) {
    $map = makeMap($targetEncoding);
    $outp = convert($str, $map);
    $printer -> selectCharacterTable($targetNumber);
    $printer -> text($targetNumber." : ".$targetEncoding. "\n");
    $printer -> textRaw(strrev($outp) . "\n");
}

$printer -> feed(2);
$printer -> cut();

function convert($str, $map) {
    // Convert UTF8 to the target encoding
    $len = mb_strlen($str);
    $outp = str_repeat("?", $len); 
    for($i = 0; $i < $len; $i++) {
        $utf8 = mb_substr($str, $i, 1);
        if(isset($map[$utf8])) {
            $outp[$i] = $map[$utf8];
        }
    }
    return $outp;
}

function makeMap($targetEncoding) {
    // Make map of target encoding v UTF-8
    $map = array();
    for($i = 0; $i < 255; $i++) {
        $native = chr($i);
        $utf8 = @iconv($targetEncoding, 'UTF-8', $native);
        if($utf8 == '') {
            continue;
        }
        $map[$utf8] = $native;
    }
    return $map;
}

@mike42
Copy link
Owner

mike42 commented Apr 6, 2015

Ok, not to worry. Our computers are generating different output. This means that either your text editor has different encoding to mine (UTF-8), our our versions of iconv are different. Either of these can be worked around.

Re the number-direction, I can see that one, and I'll need to script up a Unicode layout engine to render this correctly.

I have three more things I'd like you to run to get to the bottom of this.

(1) I need to rule out the character encoding of your text editor as a factor. I was expecting UTF-8

<?php
$str = "ص.ب. ١١٠٦ ر.ب. ٣١١ صحار، سلطنة عمان";
echo base64_encode($str) . "\n";
// I get 2LUu2KguINmh2aHZoNmmINixLtioLiDZo9mh2aEg2LXYrdin2LHYjCDYs9mE2LfZhtipINi52YXYp9mG

(2) I've switched of error-supression on iconv here, and had it spit out character code tables so that you can see them. This should print out several boxes containing available Arabic characters, and lots of notes about not being able to convert things. I'm more interested in the errors that it outputs from iconv:

<?php
/* Changing these for my setup */
require_once(dirname(__FILE__) . "/../Escpos.php");
$fp = fopen ("LPT2", "w");
$printer = new Escpos($fp);
// Using base64-encoded UTF-8 in case the above text is not UTF-8
$str = base64_decode("2LUu2KguINmh2aHZoNmmINixLtioLiDZo9mh2aEg2LXYrdin2LHYjCDYs9mE2LfZhtipINi52YXYp9mG");

// Epson character tables
//$try = array(
//  37 => 'CP864',
//  50 => 'CP1256');

// E-pos TEP 200M character tables
$try = array(
    28 => 'CP864',
    29 => 'CPW1001',
    33 => 'CP720',
    34 => 'CP1256' ,
    63 => 'CP864',
    34 => 'CP1256',
    82 => 'CP1001'
    );

foreach($try as $targetNumber => $targetEncoding) {
    $map = makeMap($targetEncoding);
    $outp = convert($str, $map);

    /* Print test output */
    $printer -> selectCharacterTable($targetNumber);
    $printer -> text($targetNumber." : ".$targetEncoding. "\n");
    if(count($map) == 0) {
        $printer -> text("Can't make $targetEncoding output with iconv.\n");
    } else {
         $printer -> textRaw(strrev($outp) . "\n");
    }
    compactCharTable($printer, 8);
}

$printer -> feed(2);
$printer -> cut();

function convert($str, $map) {
    // Convert UTF8 to the target encoding
    $len = mb_strlen($str);
    $outp = str_repeat("?", $len); 
    for($i = 0; $i < $len; $i++) {
        $utf8 = mb_substr($str, $i, 1);
        if(isset($map[$utf8])) {
            $outp[$i] = $map[$utf8];
        }
    }
    return $outp;
}

function makeMap($targetEncoding) {
    // Make map of target encoding v UTF-8
    $map = array();
    for($i = 0; $i < 255; $i++) {
        $native = chr($i);
        $utf8 = iconv($targetEncoding, 'UTF-8', $native);
        if($utf8 == '') {
            continue;
        }
        $map[$utf8] = $native;
    }
    return $map;
}

function compactCharTable($printer, $start = 2) {
    // Output a table of characters for a code
    $chars = str_repeat(' ', 256);
    for($i = 0; $i < 255; $i++) {
        $chars[$i] = ($i > 32 && $i != 127) ? chr($i) : ' ';
    }

    $printer -> setEmphasis(true);
    $printer -> textRaw("  0123456789ABCDEF\n");
    $printer -> setEmphasis(false);
    for($y = $start; $y < 16; $y++) {
        $printer -> setEmphasis(true);
        $printer -> textRaw(strtoupper(dechex($y)) . " ");
        $printer -> setEmphasis(false);
        $printer -> textRaw(substr($chars,$y * 16, 16) . "\n");
    }
}

(3) I've run the above script on my computer and saved the output, so this version should look similar to the above, but I'm hoping it contains the strings that I sent yesterday, under CP1256 and CP864 (I have no automated way to generate output in the other code pages). I'm most interested in the strings here:

<?php
$fp = fopen ("LPT2", "w");
$str = "G0AbdBwyOCA6IENQODY0Cj8/Pz8gPz8/Pz8grD8/Pz8gsbGzIC4/Lj8gtrCxsSAuPy4/ChtFASAg".
    "MDEyMzQ1Njc4OUFCQ0RFRgobRQAbRQE4IBtFAICBgoOEhYaHiImKi4yNjo8KG0UBOSAbRQCQkZKT".
    "lJWWl5iZmpucnZ6fChtFAUEgG0UAoKGio6SlpqeoqaqrrK2urwobRQFCIBtFALCxsrO0tba3uLm6".
    "u7y9vr8KG0UBQyAbRQDAwcLDxMXGx8jJysvMzc7PChtFAUQgG0UA0NHS09TV1tfY2drb3N3e3wob".
    "RQFFIBtFAODh4uPk5ebn6Onq6+zt7u8KG0UBRiAbRQDw8fLz9PX29/j5+vv8/f4gCht0HTI5IDog".
    "Q1BXMTAwMQpDYW4ndCBtYWtlIENQVzEwMDEgb3V0cHV0IHdpdGggaWNvbnYuChtFASAgMDEyMzQ1".
    "Njc4OUFCQ0RFRgobRQAbRQE4IBtFAICBgoOEhYaHiImKi4yNjo8KG0UBOSAbRQCQkZKTlJWWl5iZ".
    "mpucnZ6fChtFAUEgG0UAoKGio6SlpqeoqaqrrK2urwobRQFCIBtFALCxsrO0tba3uLm6u7y9vr8K".
    "G0UBQyAbRQDAwcLDxMXGx8jJysvMzc7PChtFAUQgG0UA0NHS09TV1tfY2drb3N3e3wobRQFFIBtF".
    "AODh4uPk5ebn6Onq6+zt7u8KG0UBRiAbRQDw8fLz9PX29/j5+vv8/f4gCht0ITMzIDogQ1A3MjAK".
    "Q2FuJ3QgbWFrZSBDUDcyMCBvdXRwdXQgd2l0aCBpY29udi4KG0UBICAwMTIzNDU2Nzg5QUJDREVG".
    "ChtFABtFATggG0UAgIGCg4SFhoeIiYqLjI2OjwobRQE5IBtFAJCRkpOUlZaXmJmam5ydnp8KG0UB".
    "QSAbRQCgoaKjpKWmp6ipqqusra6vChtFAUIgG0UAsLGys7S1tre4ubq7vL2+vwobRQFDIBtFAMDB".
    "wsPExcbHyMnKy8zNzs8KG0UBRCAbRQDQ0dLT1NXW19jZ2tvc3d7fChtFAUUgG0UA4OHi4+Tl5ufo".
    "6err7O3u7wobRQFGIBtFAPDx8vP09fb3+Pn6+/z9/iAKG3QiMzQgOiBDUDEyNTYK5Mfj2iDJ5Njh".
    "0yCh0cfN1SA/Pz8gLsgu0SA/Pz8/IC7ILtUKG0UBICAwMTIzNDU2Nzg5QUJDREVGChtFABtFATgg".
    "G0UAgIGCg4SFhoeIiYqLjI2OjwobRQE5IBtFAJCRkpOUlZaXmJmam5ydnp8KG0UBQSAbRQCgoaKj".
    "pKWmp6ipqqusra6vChtFAUIgG0UAsLGys7S1tre4ubq7vL2+vwobRQFDIBtFAMDBwsPExcbHyMnK".
    "y8zNzs8KG0UBRCAbRQDQ0dLT1NXW19jZ2tvc3d7fChtFAUUgG0UA4OHi4+Tl5ufo6err7O3u7wob".
    "RQFGIBtFAPDx8vP09fb3+Pn6+/z9/iAKG3Q/NjMgOiBDUDg2NAo/Pz8/ID8/Pz8/IKw/Pz8/ILGx".
    "syAuPy4/ILawsbEgLj8uPwobRQEgIDAxMjM0NTY3ODlBQkNERUYKG0UAG0UBOCAbRQCAgYKDhIWG".
    "h4iJiouMjY6PChtFATkgG0UAkJGSk5SVlpeYmZqbnJ2enwobRQFBIBtFAKChoqOkpaanqKmqq6yt".
    "rq8KG0UBQiAbRQCwsbKztLW2t7i5uru8vb6/ChtFAUMgG0UAwMHCw8TFxsfIycrLzM3OzwobRQFE".
    "IBtFANDR0tPU1dbX2Nna29zd3t8KG0UBRSAbRQDg4eLj5OXm5+jp6uvs7e7vChtFAUYgG0UA8PHy".
    "8/T19vf4+fr7/P3+IAobdFI4MiA6IENQMTAwMQpDYW4ndCBtYWtlIENQMTAwMSBvdXRwdXQgd2l0".
    "aCBpY29udi4KG0UBICAwMTIzNDU2Nzg5QUJDREVGChtFABtFATggG0UAgIGCg4SFhoeIiYqLjI2O".
    "jwobRQE5IBtFAJCRkpOUlZaXmJmam5ydnp8KG0UBQSAbRQCgoaKjpKWmp6ipqqusra6vChtFAUIg".
    "G0UAsLGys7S1tre4ubq7vL2+vwobRQFDIBtFAMDBwsPExcbHyMnKy8zNzs8KG0UBRCAbRQDQ0dLT".
    "1NXW19jZ2tvc3d7fChtFAUUgG0UA4OHi4+Tl5ufo6err7O3u7wobRQFGIBtFAPDx8vP09fb3+Pn6".
    "+/z9/iAKG2QCHVZBAw==";
fwrite($fp, base64_decode($str));

Thanks for sticking with this. I know it's a lot of questions, but we should have a better library in the end!

@sysxlabs
Copy link
Author

sysxlabs commented Apr 8, 2015

Hi Mike,

Answers to your question.

  1. output for the following script:
<?php
$str = "ص.ب. ١١٠٦ ر.ب. ٣١١ صحار، سلطنة عمان";
echo base64_encode($str) . "\n";

My output:
2LUu2KguINmh2aHZoNmmINixLtioLiDZo9mh2aEg2LXYrdin2LHYjCDYs9mE2LfZhtipINi52YXYp9mG

for question 2 and 3, please see the attached file
result 1

@mike42
Copy link
Owner

mike42 commented Apr 8, 2015

Thanks. This output is enough for me to start coding with.

Looks like your iconv is fine, I just forgot to specify the encoding on mb_* functions- If this is all it is, your mb_internal_encoding() should be different. Can you send me the output to the below test?

<?php
// Check internal encoding, the previous scripts assumed UTF-8
echo mb_internal_encoding() . "\n\n";

// Lengths seem to be different on your computer
$str = "ص.ب. ١١٠٦ ر.ب. ٣١١ صحار، سلطنة عمان";
echo mb_strlen($str) . "\n";
echo mb_strlen($str, 'UTF-8') . "\n";
?>

Output for me (should be different for you if I've debugged this right):

UTF-8

35
35

This is quite an extensive thing to implement properly, so it will take me a few weeks to get it working in a cross-platform, cross-printer way.

In the meantime, if I know that this is the only remaining issue, I'll be able to put together a minimal example to send your test string to your specific printer, which should hopefully solve your immediate issue.

@sysxlabs
Copy link
Author

sysxlabs commented Apr 8, 2015

Hi Mike,
this is the output of the script on my PC.
ISO-8859-1 60 35

the output is in the same line even there is "\n" for line break, but still the output is on the same line

@sysxlabs
Copy link
Author

Hi Mike, you have any updates for me related to this enhancement?

@mike42
Copy link
Owner

mike42 commented Apr 26, 2015

Hi,

Nothing quite yet. I'm working on a snippet which will let you pass mixed RTL/LTR unicode text to the printer as a series of text chunks labelled with code-page and direction, but it's not yet complete.

@mike42
Copy link
Owner

mike42 commented Apr 28, 2015

Hello,

Added a new RTLBuffer utility in the 06-encoding branch, based on the information you've provided. See example/rtl-example.php, modified slightly below for your EPOS TEP 220m printer:

<?php
require_once(dirname(__FILE__) . "/../Escpos.php");
require_once(dirname(__FILE__) . "/../src/RTLBuffer.php");

/*
 * Example of how to use the current work-around for bi-directional text.
 */

// Instantiate printer as normal
$printer = new Escpos();

// Different character tables for each printer
// $epsonEncodings = array( // Epson character tables used for testing
        // 'CP437' => 0,
        // 'CP1256' => 50,
        // 'CP864' => 37);
$eposEncodings = array( // E-pos TEP 200M character tables
        'CP437' => 0,
        'CP1256' => 34,
        'CP864' => 63);
$buf = new RTLBuffer($printer, $eposEncodings, array('CP1256'));

// Call one output() statement per line.
$buf -> output("ص.ب. ١١٠٦ ر.ب. ٣١١ صحار، سلطنة عمان");
$printer -> feed(2);
$printer -> cut();
$printer -> close();

Which will hopefully get this output:

2015-04-rtl-example

This is not a very smart algorithm, so try not to send anything too complex :). It works like this:

  • Read the string, and assign characters in "chunks" to code-pages which they can be found in. If the characters are in CP437 (western scripts), they are LTR, remaining characters from CP1256 (Arabic) are RTL, and if they fall through to CP864 (Arabic again), they are LTR again (the numerals).
  • Write the chunks to the printer from end-to-start, converting from UTF-8 to the correct code-page, changing code-pages on the printer, and selectively reversing the RTL chunks of text.

I'm simply not cut out to attempt to produce combined characters correctly, but hopefully this un-sohisticated text layout engine is sufficient for your use case. Let me know how it goes!

@sysxlabs
Copy link
Author

Hi Mike, I cannot find the mentioned files, have you updated the code in the repo?

example/rtl-example.php
src/RTLBuffer.php

@mike42
Copy link
Owner

mike42 commented Apr 29, 2015

Hi Sam,

It's in the 06-encoding branch- You can view it online here, or pull &check out on the command-line with something like this:

git pull
git checkout 06-encoding

@sysxlabs
Copy link
Author

Sorry Mike,

My mistake, i overlooked that line...

i already tested this script, the output on my printer is exactly same as your output. But this doesn't suffice my requirement. But this is indeed a good way to printout numerals and individual letters.

Mike, i checked with few vendors who provide arabic text printing on the thermal printers. They are using another approach, they convert the arabic text to png image on the fly and then print it.

Also there is one library named PHP-Ar, that might help you in this enhancement.

@mike42
Copy link
Owner

mike42 commented May 2, 2015

Hi Sam,

Very different approach. There are some improvements in the pipeline around image support (#16 #13), so I may be able to add in some text helper functions somewhere. I'm sure a text-as-graphics option would also be useful for others (it lets you use non-monospace fonts, additional characters, and so on).

Some quick tests with PHP-Ar seem to show:

  • It seems you can use it to re-order and join characters (visually good results I think), though I can only get western numerals to output. Can you rate the usefulness of this sort of output to your use case?

a

  • PHP-Ar comes with some assumptions around input encoding and default encoding, so rather than load and call it directly within escpos-php (which is being designed to only accept UTF-8), I'll simply include an example of how to use it. This is so that if there are issues with the printed text, users will need to be able to isolate which product is causing the problem.
  • The joined characters printed by PHP-Ar cannot be iconv'd to Windows-1256 for printing using existing code, sadly, so this will be an image-only enhancement from here.

This was referenced May 3, 2015
@mike42 mike42 changed the title Change Codepage Add support for right-to-left text output May 3, 2015
mike42 added a commit that referenced this issue Jul 17, 2015
@mike42
Copy link
Owner

mike42 commented Jul 17, 2015

It looks like due to the complexity of the script and the characteristics of mixed LTR/RTL text, it is not feasible to implement a native esc/pos text rendering of Arabic text in this driver at the moment. I've uploaded the example script which I've been working with, which uses the PHP-Ar to adjust the byte order for printing, and ImagePrintBuffer to rasterise the unicode text for printing, which is a useful workaround.

It shows a number of limitations, but also illustrates the fact that it should be possible to make a system which prints Arabic:

  • ImageMagick accepts LTR byte order only, so RTL text will print backwards.
  • You need to use western numerals (PHP-Ar leaves placeholders in the example string)
  • Text alignment is not supported in the ImagePrintBuffer, so everything is left-aligned.
  • Fonts cannot be configured in the ImagePrintBuffer, leading to ??? on some systems. Hard-code the buffer to print in a better font (FreeSans, the DroidSans Arabic fonts, or MS Core font Arial work well), until Font handling in ImagePrintBuffer #31 is resolved.

Because most of these limitations are covered by other missing functionality (alignment, fonts), deficiencies in features available in external libraries (ImageMagick, PHP-Ar), no more action is likely in this bug report as far as I can. If there's no new information or feedback on the image-based print example for a few weeks, I'll go ahead and close this thread.

@blady911
Copy link

blady911 commented Jun 16, 2016

Hi Guys,

I was able to print Arabic letters with above code when using below code page:

$targetNumber=63; $targetEncoding='(Arabic)';

@mike42
Copy link
Owner

mike42 commented Nov 4, 2016

I'm going to close this issue off, as the discussion has run its course, and the remaining scope does not appear to be technically feasible to implement. Specifically, I don't know of a high-quality way to transform bi-directional Arabic text from UTF-8 to native ESC/POS (using the legacy code pages that are built into the printer).

The original use case (Arabic printing on receipts) can now be achieved via images, using the PHP-Ar library and ImagePrintBuffer. Thanks all for your help developing this-

I'm open to suggestions that would allow this to be implemented with native ESC/POS output, which would be faster and more readable. Please follow up if you can demonstrate a snippet that will transform UTF-8 bi-directional Arabic text to these legacy code pages, and I'll work on it as a new feature request.

@Kamran2452
Copy link

Well i found a work around on this issue what I converted my print file to html first with wkhtmltopdf along with all the data then converted it to a Low Resolution png image using this command
$command = '"C:\wkhtmltopdf\wkhtmltoimage.exe" --zoom 2 --width "550" --disable-smart-width '. $source . ' "'. $dest .'"';
$command = exec($command);
--zoom stands for zooming the image twice since the image will be very small in it's original size.

Here is the code for printing the image to escpos.

`<?php
require DIR . '/../../../vendor/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
use Mike42\Escpos\PrintConnectors\NetworkPrintConnector;

$connector = null;
$connector = new NetworkPrintConnector($printer,9100);
$printer = new Printer($connector);

try {
/* Set up command */

$source = $filename;
$width = 550;
$dest = $filename . ".png";
$command = '"C:\wkhtmltopdf\wkhtmltoimage.exe" --zoom 2  --width "550" --disable-smart-width '. $source . ' "'. $dest .'"';
$command = exec($command);
/* Load up the image */
try {
    $tux = EscposImage::load($dest, true);
    $printer -> bitImage($tux);
    $printer -> feed();
    $printer -> cut();
} catch (Exception $e) {
    unlink($dest);
    throw $e;
}
unlink($dest);
unlink($filename);

} catch (Exception $e) {
echo $e -> getMessage();
} finally {
$printer -> close();
}
`
In default file included with this repositorsy the value is
$tux = EscposImage::load($dest, false);
It took a lot of time to print then changing the bit to true made it pretty fast haven't had the time to read it but it did the trick.

Print

@jasonjagape
Copy link

hi mike i just have a question why is it that the justify_center sometimes work and sometimes it doesn`t in my POS-58 thermal printer?

@muawiamohammed
Copy link

muawiamohammed commented Feb 19, 2022

hi mike42
Printed successfully .
لكل شخص يبحث عن استخدام اللغة العربية في هذة المكتبة تمت الطباعة بنجاح.

                 $fontPath =  "/../Arabic-4.0/I18N/Arabic/Examples/GD/ae_AlHor.ttf";

                $textUtf8 = "مركز التهامي الطبي \n  كمال علي  \n الاسم" . "\n N0 ".'4'. "\n Date : ".'2022-1-18'. "\n الخدمات المطلوبة";

                $fontSize = 35;
                mb_internal_encoding("UTF-8");
                $Arabic = new I18N_Arabic('Glyphs');
                $textLine = explode("\n", $textUtf8);
                /*
                * Set up and use an image print buffer with a suitable font
                */
                $buffer = new ImagePrintBuffer();
                $buffer -> setFont($fontPath);
                $buffer -> setFontSize($fontSize);
        
                
                $profile = CapabilityProfile::load("default");
                $connector = new WindowsPrintConnector("smb://SERVER/Tysso");
        
                $printer = new Printer($connector, $profile);
                $printer -> setPrintBuffer($buffer);

                $printer->setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW);
                $printer->setJustification(Printer::JUSTIFY_CENTER);
                foreach($textLine as $text) {
                    $printer -> text($text . "\n");
                    $printer -> feed(1);
                }

                $printer->barcode("01234444", Printer::BARCODE_CODE39);
                
                $printer -> cut();
                $printer -> close();

WhatsApp Image 2022-02-19 at 10 14 03 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants