Update lib to ESCPOS v3.0
This commit is contained in:
parent
c630253fda
commit
03f02a95d9
@ -24,7 +24,7 @@ Component Version License GPL Compatible
|
||||
-------------------------------------------------------------------------------------
|
||||
PHP libraries:
|
||||
EvalMath 1.0 BSD Yes Safe math expressions evaluation
|
||||
Escpos-php 2.2 MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers
|
||||
Escpos-php 3.0 MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers
|
||||
GeoIP2 0.2.0 Apache License 2.0 Yes Lib to make geoip convert
|
||||
Mobiledetect 2.8.41 MIT License Yes Detect mobile devices browsers
|
||||
NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package)
|
||||
|
||||
@ -177,7 +177,7 @@ NEW: triggers on mailing
|
||||
NEW: add function for listiong objects from directory
|
||||
NEW: Add helplist property to describe fields of obects
|
||||
NEW: Add hook in loadLotStock() in html.formproduct.class.php file, add hook 'llxFooter', Add hook online sign
|
||||
NEW: Update lib parsedownto 1.7.4, phpspreadsheet lib to v1.12
|
||||
NEW: Update lib parsedownto 1.7.4, phpspreadsheet lib to v1.12, ESCPOS v3.0
|
||||
NEW: Support contact in post() document API
|
||||
NEW: updating in modulbuilder on tab Menu when adding object
|
||||
NEW: Add/Edit permissions in ModuleBuilder
|
||||
|
||||
4
htdocs/includes/mike42/escpos-php/.gitignore
vendored
4
htdocs/includes/mike42/escpos-php/.gitignore
vendored
@ -4,7 +4,9 @@
|
||||
.buildpath
|
||||
|
||||
# doxygen files
|
||||
doc
|
||||
doc/html
|
||||
doc/latex
|
||||
doc/doxygen_sqlite3.db
|
||||
|
||||
# composer files
|
||||
vendor/
|
||||
|
||||
@ -5,24 +5,19 @@ sudo: required
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
- nightly
|
||||
- hhvm-3.21
|
||||
- hhvm-nightly
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
- php: hhvm-nightly
|
||||
|
||||
before_install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get install -y imagemagick ghostscript
|
||||
- sudo apt-get install -y imagemagick ghostscript unifont
|
||||
|
||||
install:
|
||||
- composer install
|
||||
|
||||
@ -165,43 +165,27 @@ If you use any other printer with this code, please [let us know](https://github
|
||||
### Include the library
|
||||
|
||||
#### Composer
|
||||
If you are using composer, then add `mike42/escpos-php` as a dependency:
|
||||
|
||||
This library is designed for use with the `composer` PHP dependency manager. Simply add the `mike42/escpos-php` package to get started:
|
||||
|
||||
```bash
|
||||
composer require mike42/escpos-php
|
||||
```
|
||||
|
||||
In this case, you would include composer's auto-loader at the top of your source files:
|
||||
|
||||
```php
|
||||
<?php
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
```
|
||||
|
||||
#### Manually
|
||||
If you don't have composer available, then simply download the code and include `autoload.php`:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/mike42/escpos-php vendor/mike42/escpos-php
|
||||
```
|
||||
|
||||
```php
|
||||
<?php
|
||||
require __DIR__ . '/vendor/mike42/escpos-php/autoload.php';
|
||||
```
|
||||
If you haven't used `composer` before, you can read about it at [getcomposer.org](https://getcomposer.org/).
|
||||
|
||||
#### Requirements
|
||||
|
||||
To maintain compatibility with as many systems as possible, this driver has few
|
||||
hard dependencies:
|
||||
This project has few hard dependencies:
|
||||
|
||||
- PHP 5.4 or above.
|
||||
- `mbstring` extension, since the driver accepts UTF-8 encoding.
|
||||
- PHP 7.0 or newer.
|
||||
- `json` extension, used to load bundled printer definitions (see [documentation](https://www.php.net/manual/en/book.json.php))
|
||||
- `intl` extension, used for character encoding (see [documentation](https://www.php.net/manual/en/book.intl.php))
|
||||
- `zlib` extension, used for de-compressing bundled resources (see [documentation](https://www.php.net/manual/en/book.zlib.php)).
|
||||
|
||||
It is also suggested that you install either `imagick` or `gd`, so that you can
|
||||
print images.
|
||||
It is also suggested that you install either `imagick` or `gd`, as these can be used to speed up image processing.
|
||||
|
||||
A number of optional packages can be added to enable more specific features. These
|
||||
A number of optional extensions can be added to enable more specific features. These
|
||||
are described in the "suggest" section of [composer.json](https://github.com/mike42/escpos-php/tree/master/composer.json).
|
||||
|
||||
### The 'Hello World' receipt
|
||||
@ -272,6 +256,7 @@ try {
|
||||
```
|
||||
|
||||
While a serial printer might use:
|
||||
|
||||
```php
|
||||
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
|
||||
use Mike42\Escpos\Printer;
|
||||
@ -279,7 +264,7 @@ $connector = new FilePrintConnector("/dev/ttyS0");
|
||||
$printer = new Printer($connector);
|
||||
```
|
||||
|
||||
For each OS/interface combination that's supported, there are examples in the compatibility section of how a `PrintConnector` would be constructed. If you can't get a `PrintConnector` to work, then be sure to include the working print command in bug.
|
||||
For each OS/interface combination that's supported, there are examples in the compatibility section of how a `PrintConnector` would be constructed. If you can't get a `PrintConnector` to work, then be sure to include the working print command in your issue.
|
||||
|
||||
### Using a CapabilityProfile
|
||||
|
||||
@ -308,6 +293,7 @@ $printer = new Printer($connector, $profile);
|
||||
For a list of available profiles, or to have support for your printer improved, please see the upstream [receipt-print-hq/escpos-printer-db](https://github.com/receipt-print-hq/escpos-printer-db) project.
|
||||
|
||||
### Tips & examples
|
||||
|
||||
On Linux, your printer device file will be somewhere like `/dev/lp0` (parallel), `/dev/usb/lp1` (USB), `/dev/ttyUSB0` (USB-Serial), `/dev/ttyS0` (serial).
|
||||
|
||||
On Windows, the device files will be along the lines of `LPT1` (parallel) or `COM1` (serial). Use the `WindowsPrintConnector` to tap into system printing on Windows (eg. [Windows USB](https://github.com/mike42/escpos-php/tree/master/example/interface/windows-usb.php), [SMB](https://github.com/mike42/escpos-php/tree/master/example/interface/smb.php) or [Windows LPT](https://github.com/mike42/escpos-php/tree/master/example/interface/windows-lpt.php)) - this submits print jobs via a queue rather than communicating directly with the printer.
|
||||
@ -564,9 +550,9 @@ Posts I've written up for people who are learning how to use receipt printers:
|
||||
|
||||
This code is MIT licensed, and you are encouraged to contribute any modifications back to the project.
|
||||
|
||||
For development, it's suggested that you load `imagick`, `gd` and `Xdebug` PHP exensions, and install `composer`.
|
||||
For development, it's suggested that you load `imagick`, `gd` and `Xdebug` PHP extensions.
|
||||
|
||||
The tests are executed on [Travis CI](https://travis-ci.org/mike42/escpos-php) over PHP 5.4, 5.5, 5.6, 7.0, 7.1 and 7.2, plus the latest LTS version of HHVM, 3.21. Older versions of PHP are not supported in current releases.
|
||||
The tests are executed on [Travis CI](https://travis-ci.org/mike42/escpos-php) over PHP 7.0, 7.1, 7.2 and 7.3. Older versions of PHP are not supported in current release, nor is HHVM.
|
||||
|
||||
Fetch a copy of this code and load dependencies with composer:
|
||||
|
||||
|
||||
@ -1,38 +1,44 @@
|
||||
{
|
||||
"name": "mike42/escpos-php",
|
||||
"type": "library",
|
||||
"description": "PHP receipt printer library for use with ESC/POS-compatible thermal and impact printers",
|
||||
"homepage": "https://github.com/mike42/escpos-php",
|
||||
"keywords": ["receipt", "print", "escpos", "ESC-POS", "driver"],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Billington",
|
||||
"email": "michael.billington@gmail.com"
|
||||
"name" : "mike42/escpos-php",
|
||||
"type" : "library",
|
||||
"description" : "PHP receipt printer library for use with ESC/POS-compatible thermal and impact printers",
|
||||
"homepage" : "https://github.com/mike42/escpos-php",
|
||||
"keywords" : [
|
||||
"barcode",
|
||||
"epson",
|
||||
"receipt-printer",
|
||||
"printer",
|
||||
"escpos"
|
||||
],
|
||||
"license" : "MIT",
|
||||
"authors" : [{
|
||||
"name" : "Michael Billington",
|
||||
"email" : "michael.billington@gmail.com"
|
||||
}
|
||||
],
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "5.4.0"
|
||||
"config" : {
|
||||
"platform" : {
|
||||
"php" : "7.0.0"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0",
|
||||
"ext-mbstring": "*"
|
||||
"require" : {
|
||||
"php" : ">=7.0.0",
|
||||
"ext-json" : "*",
|
||||
"ext-intl" : "*",
|
||||
"ext-zlib" : "*",
|
||||
"mike42/gfx-php" : "^0.6"
|
||||
},
|
||||
"suggest": {
|
||||
"guzzlehttp/guzzle": "Allows the use of the ApiConnector to send print jobs over HTTP.",
|
||||
"ext-imagick": "Will be used for image printing if present. Required for PDF printing or use of custom fonts.",
|
||||
"ext-gd": "Used for image printing if present."
|
||||
"suggest" : {
|
||||
"ext-imagick" : "Will be used for image printing if present. Required for PDF printing or use of custom fonts.",
|
||||
"ext-gd" : "Used for image printing if present."
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8",
|
||||
"squizlabs/php_codesniffer": "^3.2",
|
||||
"guzzlehttp/guzzle": "^5.3"
|
||||
"require-dev" : {
|
||||
"phpunit/phpunit" : "^6.5",
|
||||
"squizlabs/php_codesniffer" : "^3.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Mike42\\": "src/Mike42"
|
||||
"autoload" : {
|
||||
"psr-4" : {
|
||||
"Mike42\\" : "src/Mike42"
|
||||
}
|
||||
}
|
||||
}
|
||||
1024
htdocs/includes/mike42/escpos-php/composer.lock
generated
1024
htdocs/includes/mike42/escpos-php/composer.lock
generated
File diff suppressed because it is too large
Load Diff
142
htdocs/includes/mike42/escpos-php/doc/FAQ.md
Normal file
142
htdocs/includes/mike42/escpos-php/doc/FAQ.md
Normal file
@ -0,0 +1,142 @@
|
||||
# Frequently Asked Questions (FAQ)
|
||||
|
||||
## Can I print to File Format X with this?
|
||||
|
||||
If you are trying to generate XPS, PDF or DOCX or HTML files from PHP, then you are most likely in the wrong place.
|
||||
|
||||
The purpose of this driver it to generate binary ESC/POS code, which is understood by many embedded thermal receipt and impact printers.
|
||||
|
||||
## I have Printer X. Can I use this driver?
|
||||
|
||||
If the printer understands ESC/POS, and you know how to get raw binary data to it, then yes. Otherwise, no.
|
||||
|
||||
The [list of printers that are known to work](https://github.com/mike42/escpos-php/blob/development/README.md#printers) is crowd-sourced. We appreciate it when developers try out the driver, then [file information on the bug tracker](https://github.com/mike42/escpos-php/issues/new) with some information about which features worked on their model of printer.
|
||||
|
||||
To see how well your printer works, first check that it supports ESC/POS, then begin by attempting to send the text "Hello World" to your printer on the command-line, from the computer that will run PHP.
|
||||
|
||||
Once you solve this, [try to do the same from PHP](https://github.com/mike42/escpos-php/blob/development/README.md#basic-usage) using the default profile. Further details are in the [README](https://github.com/mike42/escpos-php/blob/development/README.md) file.
|
||||
|
||||
## Can you add support for Printer X?
|
||||
|
||||
Features vary between printers, so we collaborate on an ESC/POS printer compatibility database to collect known differences: [receipt-print-hq/escpos-printer-db](https://github.com/receipt-print-hq/escpos-printer-db).
|
||||
|
||||
If you encounter garbage output when you try to print images or special characters, then please submit a test page and a link to vendor documentation to the `escpos-printer-db` project, so that support can be improved for future versions.
|
||||
|
||||
## I have a printer that does not understand ESC/POS. Can I use this driver?
|
||||
|
||||
No. The purpose of this driver it to generate binary ESC/POS code. If your printer doesn't understand that, then this code wont be much use to you.
|
||||
|
||||
Some printers do have an emulation mode for ESC/POS. The vendor docs will tell if this is the case, and how to enable it.
|
||||
|
||||
## Why do I get this error when I try to print?
|
||||
|
||||
Start by testing that you can send text to your printer outside of escpos-php. The examples linked to in the README are commented with some commands to get you started.
|
||||
|
||||
Generally, initial setup problems seem to have one of these causes:
|
||||
|
||||
1. You are writing to the wrong place. Writing to `LPT1` does not output to parallel port on Linux, and `/dev/ttyS0` is not a serial printer on Windows.
|
||||
2. The printer has not been set up to accept printing the way you expect. This means permissions on Linux, network printers being configured, and shared printers having user accounts and firewalls set up correctly on the print server.
|
||||
3. Your printer actually doesn't work (rare but possible).
|
||||
|
||||
To be clear, these are not escpos-php issues: No amount of PHP code can set up your printer for you. Instead, the driver relies on developers determining how their setup is going to work before using a connector to transport data to their printer.
|
||||
|
||||
Once you have a working command to send text to your printer (from the PHP server), you are ready to use escpos-php. You can try to use a PrintConnector now, based on your operating system and printer interface. A table is located in the README to help you select the right one.
|
||||
|
||||
The connectors are-
|
||||
|
||||
- `FilePrintConnector` and `NetworkPrintConnector` directly use files or network sockets.
|
||||
- `WindowsPrintConnector` and `CupsPrintConnector` tie in with Windows and Unix system printing.
|
||||
- `DummyPrintConnector` does not connect to a real printer, and can be used to save ESC/POS receipts to a database, for example.
|
||||
|
||||
At this point, you might find that the way you would like to print is not supported by escpos-php. You can post your printing command as a feature request on the issue tracker.
|
||||
|
||||
Lastly, you may run in to the final common trap:
|
||||
|
||||
4. Your PHP is not running with the same sort of permissions as your login account. Again, no amount of PHP code can fix this. For example, on LAMP, your `www-data` user needs to be in the `lp` group, while on WAMP, `Local Service` account may run in to problems. SELinux and firewalls are also worth a look.
|
||||
|
||||
When printing fails, you can expect a PHP Exception that explains what went wrong. They are all clues:
|
||||
|
||||
- `Warning: copy(\\pc\printer): failed to open stream: Permission denied`
|
||||
- `/dev/usb/lp0: Permission denied`
|
||||
- `User name or password is incorrect`
|
||||
|
||||
Ensure that while you are developing, you configure PHP to show error messages, so that you can see these problems.
|
||||
|
||||
Please file a bug if you think that there is a specific situation which escpos-php could provide better error messages for.
|
||||
|
||||
## Can I print over the network?
|
||||
|
||||
Certainly, as long as your printer is available over the network.
|
||||
|
||||
- `NetworkPrintConnector` will speak directly to an Ethernet-connected printer on port 9100.
|
||||
|
||||
For USB or Serial printers, you need to install the printer on a computer and then share it, so that it becomes network-accessible.
|
||||
|
||||
- `WindowsPrintConnector` will connect to Windows shared printers from Windows or Linux (Linux users will need Samba).
|
||||
- `CupsPrintConnector` will connect to CUPS-shared printers from Linux or Mac.
|
||||
|
||||
Always start by testing your shared printer setup outside of escpos-php. The examples linked to in the README are commented with some example commands to get you started. Typically, networks, firewalls and permissions need to be set up.
|
||||
|
||||
Once you have a working command to send text to your printer (from the PHP server), you are ready to use escpos-php.
|
||||
|
||||
If you have any issues at this stage, please ask on the issue tracker, and include the commands that you used to verify your setup.
|
||||
|
||||
## Can I print from my server on the Internet?
|
||||
|
||||
Since PHP is a server-side language, escpos-php is a server-side print library. The driver is able to transport data between a server and a printer in a few different ways, all of them server-side. For example, you may print to a USB printer *connected to the server running PHP*, or an Ethernet printer *on a network accessible to the server*.
|
||||
|
||||
Many developers dream of having an application that is hosted on the public Internet, with POS terminals accessing it, and printing via a web browser. Because the webserver cannot see the printer in this sort of setup, a server-side print driver is not much use.
|
||||
|
||||
Because of this, there are no cut-and-paste recipes available, but here are two top-level approaches you could take:
|
||||
|
||||
1. Architect your application so that the server can see your printer
|
||||
2. Use an application which runs client-side to deliver print data instead
|
||||
|
||||
### Option 1: Allow the server to print
|
||||
|
||||
Server-side printing is viable if the server can get to the printer. Here are some ways it could work:
|
||||
|
||||
- Run your server on the LAN instead, and read the section above about printing over the network
|
||||
- Set up a VPN so that your cloud-hosted server can also access the LAN
|
||||
- Expose the printer via some other secure tunnel to the server, via SSH or TLS
|
||||
|
||||
Please do your own research to determine how these may apply to your setup- the escpos-php issue tracker is not a place where you should be requesting network support.
|
||||
|
||||
### Option 2: Use client software to print
|
||||
|
||||
If you aren't able to set up some network infrastructure to implement the above, then you cannot use a server-side print driver.
|
||||
|
||||
Here are some browser-based printing tools which you may like to consider instead.
|
||||
|
||||
- Use system printing with a vendor driver, and some good `@media print` CSS
|
||||
- [Chrome Raw Print](https://github.com/receipt-print-hq/chrome-raw-print) app
|
||||
- [qz](https://qz.io/)
|
||||
- [ePOS-Device SDK for JavaScript](https://reference.epson-biz.com/modules/ref_epos_device_js_en/index.php?content_id=139). Requires network interface card that supports ePOS (UB-E04/R04)
|
||||
|
||||
Please direct queries about client-side printing products to the appropriate project.
|
||||
|
||||
## Why is image printing slow?
|
||||
|
||||
Three things tend to slow down the image processing:
|
||||
|
||||
1. Slow PHP code
|
||||
2. Data link
|
||||
3. The printer itself
|
||||
|
||||
First, ensure you have the Imagick plugin loaded. The driver will avoid a slower image processing implementation once you've got it.
|
||||
|
||||
Next, connect over a faster interface. Serial printers have a low bit-rate, and the printer spends a lot of time waiting for data. If you have USB or Ethernet, then use it (note: storing graphics to the printer memory is not currently implemented).
|
||||
|
||||
Lastly, the printer will go faster if you use less pixels. Since images are two-dimensional, scaling down by 50% removes 75% of the pixels. The driver can then print at a half the density, so that your lower resolution image appears the same size when printed.
|
||||
|
||||
## How can I get the status of the printer?
|
||||
|
||||
This feature is not implemented, but a solution for some Epson printers is planned.
|
||||
|
||||
Only `FilePrintConnector` or `NetworkPrintConnector` will support reading from the printer, ensure that you migrate to those if you would like these features.
|
||||
|
||||
## How do I produce this complex layout?
|
||||
|
||||
ESC/POS "page mode" is not currently supported, which would allow some printers to render some more complex layouts natively
|
||||
|
||||
Since the output is raster anyway, it is suggested that you render your output to an image and print that instead. The driver supports PDF printing via Imagick, and an example that uses `wkhtmltoimage` is available in the repository.
|
||||
20
htdocs/includes/mike42/escpos-php/doc/Makefile
Normal file
20
htdocs/includes/mike42/escpos-php/doc/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
html: escpos.doxyfile
|
||||
# Compile
|
||||
doxygen escpos.doxyfile
|
||||
# Filter out warnings on README.md- doxygen cannot handle image links that
|
||||
# are used there: [](https://example.com/image)
|
||||
sed -i '/README.md\:/d' warnings.log
|
||||
# Show warnings log
|
||||
cat warnings.log
|
||||
# Return failure if there were any doc warnings
|
||||
[ ! -s warnings.log ]
|
||||
|
||||
latex: html
|
||||
# Do nothing
|
||||
|
||||
xml: html
|
||||
xsltproc xml/combine.xslt xml/index.xml > all.xml
|
||||
|
||||
clean:
|
||||
rm --preserve-root -Rf html latex xml doxygen_sqlite3.db all.xml warnings.log
|
||||
|
||||
2352
htdocs/includes/mike42/escpos-php/doc/escpos.doxyfile
Normal file
2352
htdocs/includes/mike42/escpos-php/doc/escpos.doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
@ -113,7 +113,7 @@ class CapabilityProfile
|
||||
* @param array $profileData
|
||||
* Profile data from disk.
|
||||
*/
|
||||
protected function __construct($profileId, array $profileData)
|
||||
protected function __construct(string $profileId, array $profileData)
|
||||
{
|
||||
// Basic primitive fields
|
||||
$this->profileId = $profileId;
|
||||
@ -137,16 +137,16 @@ class CapabilityProfile
|
||||
*
|
||||
* @return string Hash of the code page data structure, to identify it for caching.
|
||||
*/
|
||||
public function getCodePageCacheKey()
|
||||
public function getCodePageCacheKey() : string
|
||||
{
|
||||
return $this->codePageCacheKey;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array Associtive array of CodePage objects, indicating which encodings the printer supports.
|
||||
* @return array Associative array of CodePage objects, indicating which encodings the printer supports.
|
||||
*/
|
||||
public function getCodePages()
|
||||
public function getCodePages() : array
|
||||
{
|
||||
return $this->codePages;
|
||||
}
|
||||
@ -174,7 +174,7 @@ class CapabilityProfile
|
||||
*
|
||||
* @return string ID of the profile.
|
||||
*/
|
||||
public function getId()
|
||||
public function getId() : string
|
||||
{
|
||||
return $this->profileId;
|
||||
}
|
||||
@ -183,7 +183,7 @@ class CapabilityProfile
|
||||
*
|
||||
* @return string Name of the printer.
|
||||
*/
|
||||
public function getName()
|
||||
public function getName() : string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
@ -192,7 +192,7 @@ class CapabilityProfile
|
||||
*
|
||||
* @return boolean True if Barcode B command is supported, false otherwise
|
||||
*/
|
||||
public function getSupportsBarcodeB()
|
||||
public function getSupportsBarcodeB() : bool
|
||||
{
|
||||
return $this->getFeature('barcodeB') === true;
|
||||
}
|
||||
@ -201,7 +201,7 @@ class CapabilityProfile
|
||||
*
|
||||
* @return boolean True if Bit Image Raster command is supported, false otherwise
|
||||
*/
|
||||
public function getSupportsBitImageRaster()
|
||||
public function getSupportsBitImageRaster() : bool
|
||||
{
|
||||
return $this->getFeature('bitImageRaster') === true;
|
||||
}
|
||||
@ -210,7 +210,7 @@ class CapabilityProfile
|
||||
*
|
||||
* @return boolean True if Graphics command is supported, false otherwise
|
||||
*/
|
||||
public function getSupportsGraphics()
|
||||
public function getSupportsGraphics() : bool
|
||||
{
|
||||
return $this->getFeature('graphics') === true;
|
||||
}
|
||||
@ -219,17 +219,16 @@ class CapabilityProfile
|
||||
*
|
||||
* @return boolean True if PDF417 code command is supported, false otherwise
|
||||
*/
|
||||
public function getSupportsPdf417Code()
|
||||
public function getSupportsPdf417Code() : bool
|
||||
{
|
||||
// TODO submit 'pdf417Code' as a new feature to be tracked in upstream profiles
|
||||
return $this->getFeature('qrCode') === true;
|
||||
return $this->getFeature('pdf417Code') === true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean True if QR code command is supported, false otherwise
|
||||
*/
|
||||
public function getSupportsQrCode()
|
||||
public function getSupportsQrCode(): bool
|
||||
{
|
||||
return $this->getFeature('qrCode') === true;
|
||||
}
|
||||
@ -238,7 +237,7 @@ class CapabilityProfile
|
||||
*
|
||||
* @return boolean True if Star mode commands are supported, false otherwise
|
||||
*/
|
||||
public function getSupportsStarCommands()
|
||||
public function getSupportsStarCommands(): bool
|
||||
{
|
||||
return $this->getFeature('starCommands') === true;
|
||||
}
|
||||
@ -247,7 +246,7 @@ class CapabilityProfile
|
||||
*
|
||||
* @return string Vendor of this printer.
|
||||
*/
|
||||
public function getVendor()
|
||||
public function getVendor() : string
|
||||
{
|
||||
return $this->vendor;
|
||||
}
|
||||
@ -258,7 +257,7 @@ class CapabilityProfile
|
||||
* Feature that does not exist
|
||||
* @return array Three most similar feature names that do exist.
|
||||
*/
|
||||
protected function suggestFeatureName($featureName)
|
||||
protected function suggestFeatureName(string $featureName) : array
|
||||
{
|
||||
return self::suggestNearest($featureName, array_keys($this->features), 3);
|
||||
}
|
||||
@ -267,7 +266,7 @@ class CapabilityProfile
|
||||
*
|
||||
* @return array Names of all profiles that exist.
|
||||
*/
|
||||
public static function getProfileNames()
|
||||
public static function getProfileNames() : array
|
||||
{
|
||||
self::loadCapabilitiesDataFile();
|
||||
return array_keys(self::$profiles);
|
||||
@ -281,7 +280,7 @@ class CapabilityProfile
|
||||
* @throws InvalidArgumentException Where the ID does not exist. Some similarly-named profiles will be suggested in the Exception text.
|
||||
* @return CapabilityProfile The CapabilityProfile that was requested.
|
||||
*/
|
||||
public static function load($profileName)
|
||||
public static function load(string $profileName)
|
||||
{
|
||||
self::loadCapabilitiesDataFile();
|
||||
if (! isset(self::$profiles[$profileName])) {
|
||||
@ -315,7 +314,7 @@ class CapabilityProfile
|
||||
* @param int $num
|
||||
* Number of suggestions to return
|
||||
*/
|
||||
public static function suggestNearest($input, array $choices, $num)
|
||||
public static function suggestNearest(string $input, array $choices, int $num) : array
|
||||
{
|
||||
$distances = array_fill_keys($choices, PHP_INT_MAX);
|
||||
foreach ($distances as $word => $_) {
|
||||
@ -331,7 +330,7 @@ class CapabilityProfile
|
||||
* profile name that does not exist
|
||||
* @return array Three similar profile names that do exist, plus 'simple' and 'default' for good measure.
|
||||
*/
|
||||
protected static function suggestProfileName($profileName)
|
||||
protected static function suggestProfileName(string $profileName) : array
|
||||
{
|
||||
$suggestions = self::suggestNearest($profileName, array_keys(self::$profiles), 3);
|
||||
$alwaysSuggest = [
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of escpos-php: PHP receipt printer library for use with
|
||||
* ESC/POS-compatible thermal and impact printers.
|
||||
*
|
||||
* Copyright (c) 2014-16 Michael Billington < michael.billington@gmail.com >,
|
||||
* incorporating modifications by others. See CONTRIBUTORS.md for a full list.
|
||||
*
|
||||
* This software is distributed under the terms of the MIT license. See LICENSE.md
|
||||
* for details.
|
||||
*/
|
||||
namespace Mike42\Escpos\CapabilityProfiles;
|
||||
|
||||
use Mike42\Escpos\CapabilityProfile;
|
||||
|
||||
class DefaultCapabilityProfile
|
||||
{
|
||||
public static function getInstance()
|
||||
{
|
||||
return CapabilityProfile::load('default');
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of escpos-php: PHP receipt printer library for use with
|
||||
* ESC/POS-compatible thermal and impact printers.
|
||||
*
|
||||
* Copyright (c) 2014-16 Michael Billington < michael.billington@gmail.com >,
|
||||
* incorporating modifications by others. See CONTRIBUTORS.md for a full list.
|
||||
*
|
||||
* This software is distributed under the terms of the MIT license. See LICENSE.md
|
||||
* for details.
|
||||
*/
|
||||
namespace Mike42\Escpos\CapabilityProfiles;
|
||||
|
||||
use Mike42\Escpos\CapabilityProfile;
|
||||
|
||||
class EposTepCapabilityProfile
|
||||
{
|
||||
public static function getInstance()
|
||||
{
|
||||
return CapabilityProfile::load('TEP-200M');
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of escpos-php: PHP receipt printer library for use with
|
||||
* ESC/POS-compatible thermal and impact printers.
|
||||
*
|
||||
* Copyright (c) 2014-16 Michael Billington < michael.billington@gmail.com >,
|
||||
* incorporating modifications by others. See CONTRIBUTORS.md for a full list.
|
||||
*
|
||||
* This software is distributed under the terms of the MIT license. See LICENSE.md
|
||||
* for details.
|
||||
*/
|
||||
namespace Mike42\Escpos\CapabilityProfiles;
|
||||
|
||||
use Mike42\Escpos\CapabilityProfile;
|
||||
|
||||
class P822DCapabilityProfile
|
||||
{
|
||||
public static function getInstance()
|
||||
{
|
||||
return CapabilityProfile::load('P822D');
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of escpos-php: PHP receipt printer library for use with
|
||||
* ESC/POS-compatible thermal and impact printers.
|
||||
*
|
||||
* Copyright (c) 2014-16 Michael Billington < michael.billington@gmail.com >,
|
||||
* incorporating modifications by others. See CONTRIBUTORS.md for a full list.
|
||||
*
|
||||
* This software is distributed under the terms of the MIT license. See LICENSE.md
|
||||
* for details.
|
||||
*/
|
||||
namespace Mike42\Escpos\CapabilityProfiles;
|
||||
|
||||
use Mike42\Escpos\CapabilityProfile;
|
||||
|
||||
class SimpleCapabilityProfile
|
||||
{
|
||||
public static function getInstance()
|
||||
{
|
||||
return CapabilityProfile::load('simple');
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of escpos-php: PHP receipt printer library for use with
|
||||
* ESC/POS-compatible thermal and impact printers.
|
||||
*
|
||||
* Copyright (c) 2014-16 Michael Billington < michael.billington@gmail.com >,
|
||||
* incorporating modifications by others. See CONTRIBUTORS.md for a full list.
|
||||
*
|
||||
* This software is distributed under the terms of the MIT license. See LICENSE.md
|
||||
* for details.
|
||||
*/
|
||||
namespace Mike42\Escpos\CapabilityProfiles;
|
||||
|
||||
use Mike42\Escpos\CapabilityProfile;
|
||||
|
||||
class StarCapabilityProfile
|
||||
{
|
||||
public static function getInstance()
|
||||
{
|
||||
return CapabilityProfile::load('SP2000');
|
||||
}
|
||||
}
|
||||
@ -18,23 +18,23 @@ use \InvalidArgumentException;
|
||||
* Class to handle data about a particular CodePage, as loaded from the receipt print
|
||||
* database.
|
||||
*
|
||||
* Also computes map between UTF-8 and this encoding if necessary, using the iconv library.
|
||||
* Also computes map between UTF-8 and this encoding if necessary, using the intl library.
|
||||
*/
|
||||
class CodePage
|
||||
{
|
||||
/**
|
||||
* The input encoding for generating character maps with iconv.
|
||||
* Value to use when no character is set. This is a space in ASCII.
|
||||
*/
|
||||
const INPUT_ENCODING = "UTF-8";
|
||||
const MISSING_CHAR_CODE = 0x20;
|
||||
|
||||
/**
|
||||
* @var string $data
|
||||
* @var array|null $data
|
||||
* Data string, null if not known (can be computed with iconv)
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @var string $iconv
|
||||
* @var string|null $iconv
|
||||
* Iconv encoding name, null if not known
|
||||
*/
|
||||
protected $iconv;
|
||||
@ -52,7 +52,7 @@ class CodePage
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string $notes
|
||||
* @var string|null $notes
|
||||
* Notes on this code page, or null if not set.
|
||||
*/
|
||||
protected $notes;
|
||||
@ -70,28 +70,27 @@ class CodePage
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->name = isset($codePageData['name']) ? $codePageData['name'] : $id;
|
||||
$this->data = isset($codePageData['data']) ? implode("", $codePageData['data']) : null;
|
||||
$this->data = isset($codePageData['data']) ? self::encodingArrayFromData($codePageData['data']) : null;
|
||||
$this->iconv = isset($codePageData['iconv']) ? $codePageData['iconv'] : null;
|
||||
$this->notes = isset($codePageData['notes']) ? $codePageData['notes'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a 128-character data string representing this encoding.
|
||||
* It will be
|
||||
* calculated and cached if it was not previously known.
|
||||
* Get a 128-entry array of unicode code-points from this code page.
|
||||
*
|
||||
* @throws InvalidArgumentException Where the data is now known or computable.
|
||||
* @return string Data for this encoding.
|
||||
* @return array Data for this encoding.
|
||||
*/
|
||||
public function getData()
|
||||
public function getDataArray() : array
|
||||
{
|
||||
// Make string
|
||||
if ($this->data !== null) {
|
||||
// Return data if known
|
||||
return $this->data;
|
||||
}
|
||||
if ($this->iconv !== null) {
|
||||
// Calculate with iconv if we know the encoding name
|
||||
$this->data = self::generateEncodingMap($this->iconv);
|
||||
$this->data = self::generateEncodingArray($this->iconv);
|
||||
return $this->data;
|
||||
}
|
||||
// Can't encode..
|
||||
@ -100,7 +99,7 @@ class CodePage
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string Iconv encoding name, or blank if not set.
|
||||
* @return string|null Iconv encoding name, or null if not set.
|
||||
*/
|
||||
public function getIconv()
|
||||
{
|
||||
@ -111,15 +110,15 @@ class CodePage
|
||||
*
|
||||
* @return string Unique identifier of the code page.
|
||||
*/
|
||||
public function getId()
|
||||
public function getId() : string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the code page.
|
||||
* @return string Name of the code page.
|
||||
*/
|
||||
public function getName()
|
||||
public function getName() : string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
@ -127,7 +126,7 @@ class CodePage
|
||||
/**
|
||||
* The notes may explain quirks about a code-page, such as a source if it's non-standard or un-encodeable.
|
||||
*
|
||||
* @return string Notes on the code page, or null if not set.
|
||||
* @return string|null Notes on the code page, or null if not set.
|
||||
*/
|
||||
public function getNotes()
|
||||
{
|
||||
@ -147,35 +146,53 @@ class CodePage
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an iconv encoding name, generate a 128-character UTF-8 string, containing code points 128-255.
|
||||
* Given an ICU encoding name, generate a 128-entry array, with the unicode code points
|
||||
* for the character at positions 128-255 in this code page.
|
||||
*
|
||||
* This string is used to map UTF-8 characters to their location in this code page.
|
||||
*
|
||||
* @param string $iconvName
|
||||
* Name of the encoding
|
||||
* @return string 128-character string in UTF-8.
|
||||
* @param string $encodingName Name of the encoding
|
||||
* @return array 128-entry array of code points
|
||||
*/
|
||||
protected static function generateEncodingMap($iconvName)
|
||||
protected static function generateEncodingArray(string $encodingName) : array
|
||||
{
|
||||
// Start with array of blanks (" " indicates unknown character).
|
||||
$charMap = array_fill(0, 128, " ");
|
||||
// Set up converter for encoding
|
||||
$missingChar = chr(self::MISSING_CHAR_CODE);
|
||||
// Throws a lot of warnings for ambiguous code pages, but fallbacks seem fine.
|
||||
$converter = @new \UConverter("UTF-8", $encodingName);
|
||||
$converter -> setSubstChars($missingChar);
|
||||
// Loop through 128 code points
|
||||
for ($char = 128; $char <= 255; $char ++) {
|
||||
// Try to identify the UTF-8 character that would go here
|
||||
$utf8 = @iconv($iconvName, self::INPUT_ENCODING, chr($char));
|
||||
if ($utf8 == '') {
|
||||
$intArray = array_fill(0, 128, self::MISSING_CHAR_CODE);
|
||||
for ($char = 128; $char <= 255; $char++) {
|
||||
// Try to identify the UTF-8 character at this position in the code page
|
||||
$encodingChar = chr($char);
|
||||
$utf8 = $converter ->convert($encodingChar, false);
|
||||
if ($utf8 === $missingChar) {
|
||||
// Cannot be mapped to unicode
|
||||
continue;
|
||||
}
|
||||
if (iconv(self::INPUT_ENCODING, $iconvName, $utf8) != chr($char)) {
|
||||
// Avoid non-canonical conversions (no known examples)
|
||||
$reverse = $converter ->convert($utf8, true);
|
||||
if ($reverse !== $encodingChar) {
|
||||
// Avoid conversions which don't reverse well (eg. multi-byte code pages)
|
||||
continue;
|
||||
}
|
||||
// Replace the ' ' with the correct character if we found it
|
||||
$charMap[$char - 128] = $utf8;
|
||||
// Replace space with the correct character if we found it
|
||||
$intArray[$char - 128] = \IntlChar::ord($utf8);
|
||||
}
|
||||
// Join into a 128-character string and return.
|
||||
$charMapStr = implode("", $charMap);
|
||||
assert(mb_strlen($charMapStr, self::INPUT_ENCODING) == 128);
|
||||
return $charMapStr;
|
||||
assert(count($intArray) == 128);
|
||||
return $intArray;
|
||||
}
|
||||
|
||||
|
||||
private static function encodingArrayFromData(array $data) : array
|
||||
{
|
||||
$text = implode("", $data); // Join lines
|
||||
$codePointIterator = \IntlBreakIterator::createCodePointInstance();
|
||||
$codePointIterator -> setText($text);
|
||||
$ret = array_fill(0, 128, self::MISSING_CHAR_CODE);
|
||||
for ($i = 0; ($codePointIterator -> next() > 0) && ($i < 128); $i++) {
|
||||
$codePoint = $codePointIterator -> getLastCodePoint();
|
||||
$ret[$i] = $codePoint;
|
||||
}
|
||||
assert(count($ret) == 128);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ class AuresCustomerDisplay extends Printer
|
||||
* AuresCustomerDisplay::TEXT_VERTICAL_SCROLL or
|
||||
* AuresCustomerDisplay::TEXT_HORIZONTAL_SCROLL
|
||||
*/
|
||||
public function selectTextScrollMode($mode = AuresCustomerDisplay::TEXT_VERTICAL_SCROLL)
|
||||
public function selectTextScrollMode(int $mode = AuresCustomerDisplay::TEXT_VERTICAL_SCROLL)
|
||||
{
|
||||
self::validateInteger($mode, 1, 3, __FUNCTION__);
|
||||
$this->connector->write("\x1F" . chr($mode));
|
||||
@ -122,9 +122,8 @@ class AuresCustomerDisplay extends Printer
|
||||
*
|
||||
* @see \Mike42\Escpos\Printer::text()
|
||||
*/
|
||||
public function text($str = "")
|
||||
public function text(string $str)
|
||||
{
|
||||
self::validateString($str, __FUNCTION__);
|
||||
// Need to intercept line-feeds, since "\n" is insufficient on this device.
|
||||
foreach (explode("\n", $str) as $id => $line) {
|
||||
if ($id > 0) {
|
||||
@ -140,7 +139,7 @@ class AuresCustomerDisplay extends Printer
|
||||
*
|
||||
* @see \Mike42\Escpos\Printer::feed()
|
||||
*/
|
||||
public function feed($lines = 1)
|
||||
public function feed(int $lines = 1)
|
||||
{
|
||||
self::validateInteger($lines, 1, 255, __FUNCTION__);
|
||||
for ($i = 0; $i < $lines; $i ++) {
|
||||
|
||||
@ -14,6 +14,9 @@ namespace Mike42\Escpos;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use Mike42\Escpos\GdEscposImage;
|
||||
use Mike42\Escpos\ImagickEscposImage;
|
||||
use Mike42\Escpos\NativeEscposImage;
|
||||
|
||||
/**
|
||||
* This class deals with images in raster formats, and converts them into formats
|
||||
@ -192,7 +195,7 @@ abstract class EscposImage
|
||||
*
|
||||
* @param string|null $filename Filename to load from.
|
||||
*/
|
||||
protected function loadImageData($filename = null)
|
||||
protected function loadImageData(string $filename = null)
|
||||
{
|
||||
// Load image in to string of 1's and 0's, also set width & height
|
||||
$this -> setImgWidth(0);
|
||||
@ -312,7 +315,7 @@ abstract class EscposImage
|
||||
* @return string[]
|
||||
* Array of column format data, one item per row.
|
||||
*/
|
||||
private function getColumnFormat($highDensity)
|
||||
private function getColumnFormat(bool $highDensity)
|
||||
{
|
||||
$out = [];
|
||||
$i = 0;
|
||||
@ -335,7 +338,7 @@ abstract class EscposImage
|
||||
* @return NULL|string
|
||||
* Column format data, or null if there is no more data (when iterating)
|
||||
*/
|
||||
private function getColumnFormatLine($lineNo, $highDensity)
|
||||
private function getColumnFormatLine(int $lineNo, bool $highDensity)
|
||||
{
|
||||
// Currently double density in both directions, very experimental
|
||||
$widthPixels = $this -> getWidth();
|
||||
@ -421,8 +424,8 @@ abstract class EscposImage
|
||||
*
|
||||
*/
|
||||
public static function load(
|
||||
$filename,
|
||||
$allowOptimisations = true,
|
||||
string $filename,
|
||||
bool $allowOptimisations = true,
|
||||
array $preferred = ['imagick', 'gd', 'native']
|
||||
) {
|
||||
/* Fail early if file is not readble */
|
||||
@ -431,28 +434,28 @@ abstract class EscposImage
|
||||
}
|
||||
$ext = pathinfo($filename, PATHINFO_EXTENSION);
|
||||
/* Choose the first implementation which can handle this format */
|
||||
foreach ($preferred as $implemetnation) {
|
||||
if ($implemetnation === 'imagick') {
|
||||
foreach ($preferred as $implementation) {
|
||||
if ($implementation === 'imagick') {
|
||||
if (!self::isImagickLoaded()) {
|
||||
// Skip option if Imagick is not loaded
|
||||
continue;
|
||||
}
|
||||
return new \Mike42\Escpos\ImagickEscposImage($filename, $allowOptimisations);
|
||||
} elseif ($implemetnation === 'gd') {
|
||||
return new ImagickEscposImage($filename, $allowOptimisations);
|
||||
} elseif ($implementation === 'gd') {
|
||||
if (!self::isGdLoaded()) {
|
||||
// Skip option if GD not loaded
|
||||
continue;
|
||||
}
|
||||
return new \Mike42\Escpos\GdEscposImage($filename, $allowOptimisations);
|
||||
} elseif ($implemetnation === 'native') {
|
||||
if (!in_array($ext, ['wbmp', 'pbm', 'bmp'])) {
|
||||
// Pure PHP is fastest way to generate raster output from wbmp and pbm formats.
|
||||
return new GdEscposImage($filename, $allowOptimisations);
|
||||
} elseif ($implementation === 'native') {
|
||||
if (!in_array($ext, ['bmp', 'gif', 'pbm', 'png', 'ppm', 'pgm', 'wbmp'])) {
|
||||
// Pure PHP may also be fastest way to generate raster output from wbmp and pbm formats.
|
||||
continue;
|
||||
}
|
||||
return new \Mike42\Escpos\NativeEscposImage($filename, $allowOptimisations);
|
||||
return new NativeEscposImage($filename, $allowOptimisations);
|
||||
} else {
|
||||
// Something else on the 'preferred' list.
|
||||
throw new InvalidArgumentException("'$implemetnation' is not a known EscposImage implementation");
|
||||
throw new InvalidArgumentException("'$implementation' is not a known EscposImage implementation");
|
||||
}
|
||||
}
|
||||
throw new InvalidArgumentException("No suitable EscposImage implementation found for '$filename'.");
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Mike42\Escpos\Experimental\Unifont;
|
||||
|
||||
class ColumnFormatGlyph
|
||||
{
|
||||
public $width;
|
||||
public $data;
|
||||
|
||||
public function segment(int $maxWidth)
|
||||
{
|
||||
if ($this->width <= $maxWidth) {
|
||||
return [$this];
|
||||
}
|
||||
$dataChunks = str_split($this->data, $maxWidth * 3);
|
||||
$ret = [];
|
||||
foreach ($dataChunks as $chunk) {
|
||||
$g = new ColumnFormatGlyph();
|
||||
$g->data = $chunk;
|
||||
$g->width = strlen($chunk) / 3;
|
||||
$ret[] = $g;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Mike42\Escpos\Experimental\Unifont;
|
||||
|
||||
interface ColumnFormatGlyphFactory
|
||||
{
|
||||
public function getGlyph($codePoint);
|
||||
}
|
||||
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace Mike42\Escpos\Experimental\Unifont;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Mike42\Escpos\Printer;
|
||||
|
||||
class FontMap
|
||||
{
|
||||
protected $printer;
|
||||
|
||||
const MIN = 0x20;
|
||||
const MAX = 0x7E;
|
||||
const FONT_A_WIDTH = 12;
|
||||
const FONT_B_WIDTH = 9;
|
||||
|
||||
// Map memory locations to code points
|
||||
protected $memory;
|
||||
|
||||
// Map unicode code points to bytes
|
||||
protected $chars;
|
||||
|
||||
// next available slot
|
||||
protected $next = 0;
|
||||
|
||||
public function __construct(ColumnFormatGlyphFactory $glyphFactory, Printer $printer)
|
||||
{
|
||||
$this -> printer = $printer;
|
||||
$this -> glyphFactory = $glyphFactory;
|
||||
$this -> reset();
|
||||
}
|
||||
|
||||
public function cacheChars(array $codePoints)
|
||||
{
|
||||
// TODO flush existing cache to fill with these chars.
|
||||
}
|
||||
|
||||
public function writeChar(int $codePoint)
|
||||
{
|
||||
if (!$this -> addChar($codePoint, true)) {
|
||||
throw new InvalidArgumentException("Code point $codePoint not available");
|
||||
}
|
||||
$data = implode($this -> chars[$codePoint]);
|
||||
$this -> printer -> getPrintConnector() -> write($data);
|
||||
}
|
||||
|
||||
public function reset()
|
||||
{
|
||||
$this -> chars = [];
|
||||
$this -> memory = array_fill(0, (\Mike42\Escpos\Experimental\Unifont\FontMap::MAX - FontMap::MIN) + 1, -1);
|
||||
}
|
||||
|
||||
public function occupied($id)
|
||||
{
|
||||
return $this -> memory[$id] !== -1;
|
||||
}
|
||||
|
||||
public function evict($id)
|
||||
{
|
||||
if (!$this -> occupied($id)) {
|
||||
return true;
|
||||
}
|
||||
unset($this -> chars[$this -> memory[$id]]);
|
||||
$this -> memory[$id] = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function addChar(int $codePoint, $evict = true)
|
||||
{
|
||||
if (isset($this -> chars[$codePoint])) {
|
||||
// Char already available
|
||||
return true;
|
||||
}
|
||||
// Get glyph
|
||||
$glyph = $this -> glyphFactory -> getGlyph($codePoint);
|
||||
$glyphParts = $glyph -> segment(self::FONT_B_WIDTH);
|
||||
//print_r($glyphParts);
|
||||
//
|
||||
// Clear count($glyphParts) of space from $start
|
||||
$start = $this -> next;
|
||||
$chars = [];
|
||||
$submit = [];
|
||||
for ($i = 0; $i < count($glyphParts); $i++) {
|
||||
$id = ($this -> next + $i) % count($this -> memory);
|
||||
if ($this -> occupied($id)) {
|
||||
if ($evict) {
|
||||
$this -> evict($id);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$thisChar = $id + self::MIN;
|
||||
$chars[] = chr($thisChar);
|
||||
$submit[$thisChar] = $glyphParts[$i];
|
||||
}
|
||||
|
||||
// Success in locating memory space, move along counters
|
||||
$this -> next = ($this -> next + count($glyphParts)) % count($this -> memory);
|
||||
$this -> submitCharsToPrinterFont($submit);
|
||||
$this -> memory[$start] = $codePoint;
|
||||
$this -> chars[$codePoint] = $chars;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function submitCharsToPrinterFont(array $chars)
|
||||
{
|
||||
ksort($chars);
|
||||
// TODO We can sort into batches of contiguous characters here.
|
||||
foreach ($chars as $char => $glyph) {
|
||||
$verticalBytes = 3;
|
||||
$data = Printer::ESC . "&" . chr($verticalBytes) . chr($char) . chr($char) . chr($glyph -> width) . $glyph -> data;
|
||||
$this -> printer -> getPrintConnector() -> write($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Mike42\Escpos\Experimental\Unifont;
|
||||
|
||||
class UnifontGlyphFactory implements ColumnFormatGlyphFactory
|
||||
{
|
||||
protected $unifontFile;
|
||||
|
||||
public static function colFormat16(array $in)
|
||||
{
|
||||
// Map 16 x 16 bit unifont (32 bytes) to 16 x 24 ESC/POS column format image (48 bytes).
|
||||
return UnifontGlyphFactory::colFormat8($in, 2, 1) . UnifontGlyphFactory::colFormat8($in, 2, 2);
|
||||
}
|
||||
|
||||
public static function colFormat8(array $in, $chars = 1, $idx = 1)
|
||||
{
|
||||
// Map 8 x 16 bit unifont (32 bytes) to 8 x 24 ESC/POS column format image (24 bytes).
|
||||
return implode([
|
||||
chr(
|
||||
(($in[0 * $chars + $idx] & 0x80)) |
|
||||
(($in[1 * $chars + $idx] & 0x80) >> 1) |
|
||||
(($in[2 * $chars + $idx] & 0x80) >> 2) |
|
||||
(($in[3 * $chars + $idx] & 0x80) >> 3) |
|
||||
(($in[4 * $chars + $idx] & 0x80) >> 4) |
|
||||
(($in[5 * $chars + $idx] & 0x80) >> 5) |
|
||||
(($in[6 * $chars + $idx] & 0x80) >> 6) |
|
||||
(($in[7 * $chars + $idx] & 0x80) >> 7)
|
||||
),
|
||||
chr(
|
||||
(($in[8 * $chars + $idx] & 0x80)) |
|
||||
(($in[9 * $chars + $idx] & 0x80) >> 1) |
|
||||
(($in[10 * $chars + $idx] & 0x80) >> 2) |
|
||||
(($in[11 * $chars + $idx] & 0x80) >> 3) |
|
||||
(($in[12 * $chars + $idx] & 0x80) >> 4) |
|
||||
(($in[13 * $chars + $idx] & 0x80) >> 5) |
|
||||
(($in[14 * $chars + $idx] & 0x80) >> 6) |
|
||||
(($in[15 * $chars + $idx] & 0x80) >> 7)
|
||||
),
|
||||
chr(0),
|
||||
chr(
|
||||
(($in[0 * $chars + $idx] & 0x40) << 1) |
|
||||
(($in[1 * $chars + $idx] & 0x40)) |
|
||||
(($in[2 * $chars + $idx] & 0x40) >> 1) |
|
||||
(($in[3 * $chars + $idx] & 0x40) >> 2) |
|
||||
(($in[4 * $chars + $idx] & 0x40) >> 3) |
|
||||
(($in[5 * $chars + $idx] & 0x40) >> 4) |
|
||||
(($in[6 * $chars + $idx] & 0x40) >> 5) |
|
||||
(($in[7 * $chars + $idx] & 0x40) >> 6)
|
||||
),
|
||||
chr(
|
||||
(($in[8 * $chars + $idx] & 0x40) << 1) |
|
||||
(($in[9 * $chars + $idx] & 0x40) >> 0) |
|
||||
(($in[10 * $chars + $idx] & 0x40) >> 1) |
|
||||
(($in[11 * $chars + $idx] & 0x40) >> 2) |
|
||||
(($in[12 * $chars + $idx] & 0x40) >> 3) |
|
||||
(($in[13 * $chars + $idx] & 0x40) >> 4) |
|
||||
(($in[14 * $chars + $idx] & 0x40) >> 5) |
|
||||
(($in[15 * $chars + $idx] & 0x40) >> 6)
|
||||
),
|
||||
chr(0),
|
||||
chr(
|
||||
(($in[0 * $chars + $idx] & 0x20) << 2) |
|
||||
(($in[1 * $chars + $idx] & 0x20) << 1) |
|
||||
(($in[2 * $chars + $idx] & 0x20)) |
|
||||
(($in[3 * $chars + $idx] & 0x20) >> 1) |
|
||||
(($in[4 * $chars + $idx] & 0x20) >> 2) |
|
||||
(($in[5 * $chars + $idx] & 0x20) >> 3) |
|
||||
(($in[6 * $chars + $idx] & 0x20) >> 4) |
|
||||
(($in[7 * $chars + $idx] & 0x20) >> 5)
|
||||
),
|
||||
chr(
|
||||
(($in[8 * $chars + $idx] & 0x20) << 2) |
|
||||
(($in[9 * $chars + $idx] & 0x20) << 1) |
|
||||
(($in[10 * $chars + $idx] & 0x20)) |
|
||||
(($in[11 * $chars + $idx] & 0x20) >> 1) |
|
||||
(($in[12 * $chars + $idx] & 0x20) >> 2) |
|
||||
(($in[13 * $chars + $idx] & 0x20) >> 3) |
|
||||
(($in[14 * $chars + $idx] & 0x20) >> 4) |
|
||||
(($in[15 * $chars + $idx] & 0x20) >> 5)
|
||||
),
|
||||
chr(0),
|
||||
chr(
|
||||
(($in[0 * $chars + $idx] & 0x10) << 3) |
|
||||
(($in[1 * $chars + $idx] & 0x10) << 2) |
|
||||
(($in[2 * $chars + $idx] & 0x10) << 1) |
|
||||
(($in[3 * $chars + $idx] & 0x10)) |
|
||||
(($in[4 * $chars + $idx] & 0x10) >> 1) |
|
||||
(($in[5 * $chars + $idx] & 0x10) >> 2) |
|
||||
(($in[6 * $chars + $idx] & 0x10) >> 3) |
|
||||
(($in[7 * $chars + $idx] & 0x10) >> 4)
|
||||
),
|
||||
chr(
|
||||
(($in[8 * $chars + $idx] & 0x10) << 3) |
|
||||
(($in[9 * $chars + $idx] & 0x10) << 2) |
|
||||
(($in[10 * $chars + $idx] & 0x10) << 1) |
|
||||
(($in[11 * $chars + $idx] & 0x10)) |
|
||||
(($in[12 * $chars + $idx] & 0x10) >> 1) |
|
||||
(($in[13 * $chars + $idx] & 0x10) >> 2) |
|
||||
(($in[14 * $chars + $idx] & 0x10) >> 3) |
|
||||
(($in[15 * $chars + $idx] & 0x10) >> 4)
|
||||
),
|
||||
chr(0),
|
||||
chr(
|
||||
(($in[0 * $chars + $idx] & 0x08) << 4) |
|
||||
(($in[1 * $chars + $idx] & 0x08) << 3) |
|
||||
(($in[2 * $chars + $idx] & 0x08) << 2) |
|
||||
(($in[3 * $chars + $idx] & 0x08) << 1) |
|
||||
(($in[4 * $chars + $idx] & 0x08)) |
|
||||
(($in[5 * $chars + $idx] & 0x08) >> 1) |
|
||||
(($in[6 * $chars + $idx] & 0x08) >> 2) |
|
||||
(($in[7 * $chars + $idx] & 0x08) >> 3)
|
||||
),
|
||||
chr(
|
||||
(($in[8 * $chars + $idx] & 0x08) << 4) |
|
||||
(($in[9 * $chars + $idx] & 0x08) << 3) |
|
||||
(($in[10 * $chars + $idx] & 0x08) << 2) |
|
||||
(($in[11 * $chars + $idx] & 0x08) << 1) |
|
||||
(($in[12 * $chars + $idx] & 0x08)) |
|
||||
(($in[13 * $chars + $idx] & 0x08) >> 1) |
|
||||
(($in[14 * $chars + $idx] & 0x08) >> 2) |
|
||||
(($in[15 * $chars + $idx] & 0x08) >> 3)
|
||||
),
|
||||
chr(0),
|
||||
chr(
|
||||
(($in[0 * $chars + $idx] & 0x04) << 5) |
|
||||
(($in[1 * $chars + $idx] & 0x04) << 4) |
|
||||
(($in[2 * $chars + $idx] & 0x04) << 3) |
|
||||
(($in[3 * $chars + $idx] & 0x04) << 2) |
|
||||
(($in[4 * $chars + $idx] & 0x04) << 1) |
|
||||
(($in[5 * $chars + $idx] & 0x04)) |
|
||||
(($in[6 * $chars + $idx] & 0x04) >> 1) |
|
||||
(($in[7 * $chars + $idx] & 0x04) >> 2)
|
||||
),
|
||||
chr(
|
||||
(($in[8 * $chars + $idx] & 0x04) << 5) |
|
||||
(($in[9 * $chars + $idx] & 0x04) << 4) |
|
||||
(($in[10 * $chars + $idx] & 0x04) << 3) |
|
||||
(($in[11 * $chars + $idx] & 0x04) << 2) |
|
||||
(($in[12 * $chars + $idx] & 0x04) << 1) |
|
||||
(($in[13 * $chars + $idx] & 0x04)) |
|
||||
(($in[14 * $chars + $idx] & 0x04) >> 1) |
|
||||
(($in[15 * $chars + $idx] & 0x04) >> 2)
|
||||
),
|
||||
chr(0),
|
||||
chr(
|
||||
(($in[0 * $chars + $idx] & 0x02) << 6) |
|
||||
(($in[1 * $chars + $idx] & 0x02) << 5) |
|
||||
(($in[2 * $chars + $idx] & 0x02) << 4) |
|
||||
(($in[3 * $chars + $idx] & 0x02) << 3) |
|
||||
(($in[4 * $chars + $idx] & 0x02) << 2) |
|
||||
(($in[5 * $chars + $idx] & 0x02) << 1) |
|
||||
(($in[6 * $chars + $idx] & 0x02)) |
|
||||
(($in[7 * $chars + $idx] & 0x02) >> 1)
|
||||
),
|
||||
chr(
|
||||
(($in[8 * $chars + $idx] & 0x02) << 6) |
|
||||
(($in[9 * $chars + $idx] & 0x02) << 5) |
|
||||
(($in[10 * $chars + $idx] & 0x02) << 4) |
|
||||
(($in[11 * $chars + $idx] & 0x02) << 3) |
|
||||
(($in[12 * $chars + $idx] & 0x02) << 2) |
|
||||
(($in[13 * $chars + $idx] & 0x02) << 1) |
|
||||
(($in[14 * $chars + $idx] & 0x02)) |
|
||||
(($in[15 * $chars + $idx] & 0x02) >> 1)
|
||||
),
|
||||
chr(0),
|
||||
chr(
|
||||
(($in[0 * $chars + $idx] & 0x01) << 7) |
|
||||
(($in[1 * $chars + $idx] & 0x01) << 6) |
|
||||
(($in[2 * $chars + $idx] & 0x01) << 5) |
|
||||
(($in[3 * $chars + $idx] & 0x01) << 4) |
|
||||
(($in[4 * $chars + $idx] & 0x01) << 3) |
|
||||
(($in[5 * $chars + $idx] & 0x01) << 2) |
|
||||
(($in[6 * $chars + $idx] & 0x01) << 1) |
|
||||
(($in[7 * $chars + $idx] & 0x01))
|
||||
),
|
||||
chr(
|
||||
(($in[8 * $chars + $idx] & 0x01) << 7) |
|
||||
(($in[9 * $chars + $idx] & 0x01) << 6) |
|
||||
(($in[10 * $chars + $idx] & 0x01) << 5) |
|
||||
(($in[11 * $chars + $idx] & 0x01) << 4) |
|
||||
(($in[12 * $chars + $idx] & 0x01) << 3) |
|
||||
(($in[13 * $chars + $idx] & 0x01) << 2) |
|
||||
(($in[14 * $chars + $idx] & 0x01) >> 1) |
|
||||
(($in[15 * $chars + $idx] & 0x01))
|
||||
),
|
||||
chr(0)
|
||||
]);
|
||||
}
|
||||
|
||||
public function __construct(array $unifontFile)
|
||||
{
|
||||
$this -> unifontFile = $unifontFile;
|
||||
}
|
||||
|
||||
public function getGlyph($codePoint)
|
||||
{
|
||||
// Binary search for correct line.
|
||||
$min = 0;
|
||||
$max = count($this -> unifontFile) - 1;
|
||||
$foundId = 0;
|
||||
// Bias toward low side if file is > 255.
|
||||
$m = min(count($this -> unifontFile) - 1, 255);
|
||||
while ($min <= $max) {
|
||||
$thisCodePoint = hexdec(substr($this -> unifontFile[$m], 0, 4));
|
||||
if ($codePoint === $thisCodePoint) {
|
||||
$foundId = $m;
|
||||
break;
|
||||
} else if ($codePoint < $thisCodePoint) {
|
||||
$max = $m - 1;
|
||||
} else {
|
||||
$min = $m + 1;
|
||||
}
|
||||
$m = floor(($min + $max) / 2);
|
||||
}
|
||||
$unifontLine = $this -> unifontFile[$foundId];
|
||||
|
||||
// Convert to column format
|
||||
$binStr = unpack("C*", pack("H*", substr($unifontLine, 5)));
|
||||
$bytes = count($binStr);
|
||||
if ($bytes == 32) {
|
||||
$width = 16;
|
||||
$colFormat = UnifontGlyphFactory::colFormat16($binStr);
|
||||
} else if ($bytes == 16) {
|
||||
$width = 8;
|
||||
$colFormat = UnifontGlyphFactory::colFormat8($binStr);
|
||||
}
|
||||
// Write to obj
|
||||
$glyph = new ColumnFormatGlyph();
|
||||
$glyph -> width = $width;
|
||||
$glyph -> data = $colFormat;
|
||||
return $glyph;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Mike42\Escpos\Experimental\Unifont;
|
||||
|
||||
use Mike42\Escpos\PrintBuffers\PrintBuffer;
|
||||
use Mike42\Escpos\Printer;
|
||||
|
||||
class UnifontPrintBuffer implements PrintBuffer
|
||||
{
|
||||
private $printer;
|
||||
private $fontMap;
|
||||
private $started;
|
||||
private $unifont;
|
||||
|
||||
public function __construct(string $unifontFilename)
|
||||
{
|
||||
// Create UnifontGlyphFactory by reading from file
|
||||
$unifont = file_get_contents($unifontFilename);
|
||||
if ($unifont === false) {
|
||||
throw new \Exception("Could not read $unifontFilename");
|
||||
}
|
||||
$unifontFileLines = explode("\n", $unifont);
|
||||
$this -> unifont = new UnifontGlyphFactory($unifontFileLines);
|
||||
// Everything else is null
|
||||
$this -> printer = null;
|
||||
$this -> fontMap = null;
|
||||
$this -> started = false;
|
||||
}
|
||||
|
||||
public function writeChar(int $codePoint)
|
||||
{
|
||||
if ($codePoint == 10) {
|
||||
$this -> write("\n");
|
||||
} else if ($codePoint == 13) {
|
||||
// Ignore CR char
|
||||
} else {
|
||||
// Straight column-format prints
|
||||
$this -> fontMap -> writeChar($codePoint);
|
||||
}
|
||||
}
|
||||
|
||||
public function writeText(string $text)
|
||||
{
|
||||
if (!$this -> started) {
|
||||
$mode = Printer::MODE_FONT_B | Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH;
|
||||
$this -> printer -> getPrintConnector() -> write(Printer::ESC . "!" . chr($mode));
|
||||
$this -> printer -> selectUserDefinedCharacterSet(true);
|
||||
}
|
||||
// Normalize text - this replaces combining characters with composed glyphs, and also helps us eliminated bad UTF-8 early
|
||||
$text = \Normalizer::normalize($text);
|
||||
if ($text === false) {
|
||||
throw new \Exception("Input must be UTF-8");
|
||||
}
|
||||
// Iterate code points
|
||||
$codePointIterator = \IntlBreakIterator::createCodePointInstance();
|
||||
$codePointIterator->setText($text);
|
||||
while ($codePointIterator->next() > 0) {
|
||||
$codePoint = $codePointIterator->getLastCodePoint();
|
||||
$this->writeChar($codePoint);
|
||||
}
|
||||
}
|
||||
|
||||
public function flush()
|
||||
{
|
||||
}
|
||||
|
||||
public function setPrinter(Printer $printer = null)
|
||||
{
|
||||
$this -> printer = $printer;
|
||||
$this -> fontMap = new FontMap($this -> unifont, $this -> printer);
|
||||
}
|
||||
|
||||
public function writeTextRaw(string $text)
|
||||
{
|
||||
}
|
||||
|
||||
public function getPrinter()
|
||||
{
|
||||
return $this -> printer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to the underlying connector.
|
||||
*
|
||||
* @param string $data
|
||||
*/
|
||||
private function write($data)
|
||||
{
|
||||
$this -> printer -> getPrintConnector() -> write($data);
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
* This file is part of escpos-php: PHP receipt printer library for use with
|
||||
* ESC/POS-compatible thermal and impact printers.
|
||||
*
|
||||
* Copyright (c) 2014-16 Michael Billington < michael.billington@gmail.com >,
|
||||
* Copyright (c) 2014-18 Michael Billington < michael.billington@gmail.com >,
|
||||
* incorporating modifications by others. See CONTRIBUTORS.md for a full list.
|
||||
*
|
||||
* This software is distributed under the terms of the MIT license. See LICENSE.md
|
||||
@ -12,7 +12,6 @@
|
||||
|
||||
namespace Mike42\Escpos;
|
||||
|
||||
use Mike42\Escpos\EscposImage;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
@ -27,7 +26,7 @@ class GdEscposImage extends EscposImage
|
||||
* @throws Exception if the image format is not supported,
|
||||
* or the file cannot be opened.
|
||||
*/
|
||||
protected function loadImageData($filename = null)
|
||||
protected function loadImageData(string $filename = null)
|
||||
{
|
||||
if ($filename === null) {
|
||||
/* Set to blank image */
|
||||
|
||||
@ -14,7 +14,6 @@ namespace Mike42\Escpos;
|
||||
|
||||
use Exception;
|
||||
use Imagick;
|
||||
use Mike42\Escpos\EscposImage;
|
||||
|
||||
/**
|
||||
* Implementation of EscposImage using the Imagick PHP plugin.
|
||||
@ -26,12 +25,12 @@ class ImagickEscposImage extends EscposImage
|
||||
*
|
||||
* @param Imagick $im Image to load from
|
||||
*/
|
||||
public function readImageFromImagick(\Imagick $im)
|
||||
public function readImageFromImagick(Imagick $im)
|
||||
{
|
||||
/* Strip transparency */
|
||||
$im = self::alphaRemove($im);
|
||||
/* Threshold */
|
||||
$im -> setImageType(\Imagick::IMGTYPE_TRUECOLOR); // Remove transparency (good for PDF's)
|
||||
$im -> setImageType(Imagick::IMGTYPE_TRUECOLOR); // Remove transparency (good for PDF's)
|
||||
$max = $im->getQuantumRange();
|
||||
$max = $max["quantumRangeLong"];
|
||||
$im -> thresholdImage(0.5 * $max);
|
||||
@ -89,7 +88,7 @@ class ImagickEscposImage extends EscposImage
|
||||
* @throws Exception if the image format is not supported,
|
||||
* or the file cannot be opened.
|
||||
*/
|
||||
protected function loadImageData($filename = null)
|
||||
protected function loadImageData(string $filename = null)
|
||||
{
|
||||
if ($filename === null) {
|
||||
/* Set to blank image */
|
||||
@ -109,7 +108,7 @@ class ImagickEscposImage extends EscposImage
|
||||
* Height of printed line in dots. 8 or 24.
|
||||
* @return string[]
|
||||
*/
|
||||
private function getColumnFormatFromImage(Imagick $im, $lineHeight)
|
||||
private function getColumnFormatFromImage(Imagick $im, int $lineHeight)
|
||||
{
|
||||
$imgWidth = $im->getimagewidth();
|
||||
if ($imgWidth == $lineHeight) {
|
||||
@ -212,7 +211,7 @@ class ImagickEscposImage extends EscposImage
|
||||
* or invalid page number is requested.
|
||||
* @return array Array of images, retrieved from the PDF file.
|
||||
*/
|
||||
public static function loadPdf($pdfFile, $pageWidth = 550)
|
||||
public static function loadPdf($pdfFile, int $pageWidth = 550)
|
||||
{
|
||||
if (!EscposImage::isImagickLoaded()) {
|
||||
throw new Exception(__FUNCTION__ . " requires imagick extension.");
|
||||
@ -222,7 +221,7 @@ class ImagickEscposImage extends EscposImage
|
||||
* density to use to achieve $pageWidth
|
||||
*/
|
||||
try {
|
||||
$image = new \Imagick();
|
||||
$image = new Imagick();
|
||||
$testRes = 2; // Test resolution
|
||||
$image -> setresolution($testRes, $testRes);
|
||||
/* Load document just to measure geometry */
|
||||
@ -265,9 +264,9 @@ class ImagickEscposImage extends EscposImage
|
||||
*/
|
||||
private static function alphaRemove(Imagick $im)
|
||||
{
|
||||
$flat = new \Imagick();
|
||||
$flat = new Imagick();
|
||||
$flat -> newImage($im -> getimagewidth(), $im -> getimageheight(), "white", $im -> getimageformat());
|
||||
$flat -> compositeimage($im, \Imagick::COMPOSITE_OVER, 0, 0);
|
||||
$flat -> compositeimage($im, Imagick::COMPOSITE_OVER, 0, 0);
|
||||
return $flat;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,13 +12,26 @@
|
||||
|
||||
namespace Mike42\Escpos;
|
||||
|
||||
use Mike42\Escpos\EscposImage;
|
||||
use Mike42\GfxPhp\Image;
|
||||
|
||||
/**
|
||||
* Implementation of EscposImage using only native PHP.
|
||||
* TODO: wbmp, pbm, bmp files.
|
||||
*/
|
||||
class NativeEscposImage extends EscposImage
|
||||
{
|
||||
|
||||
protected function loadImageData(string $filename = null)
|
||||
{
|
||||
$image = Image::fromFile($filename) -> toRgb() -> toBlackAndWhite();
|
||||
$imgHeight = $image -> getHeight();
|
||||
$imgWidth = $image -> getWidth();
|
||||
$imgData = str_repeat("\0", $imgHeight * $imgWidth);
|
||||
for ($y = 0; $y < $imgHeight; $y++) {
|
||||
for ($x = 0; $x < $imgWidth; $x++) {
|
||||
$imgData[$y * $imgWidth + $x] = $image -> getPixel($x, $y) == 0 ? 0: 1;
|
||||
}
|
||||
}
|
||||
$this -> setImgWidth($imgWidth);
|
||||
$this -> setImgHeight($imgHeight);
|
||||
$this -> setImgData($imgData);
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
namespace Mike42\Escpos\PrintBuffers;
|
||||
|
||||
use LogicException;
|
||||
use Mike42\Escpos\CodePage;
|
||||
use Mike42\Escpos\Printer;
|
||||
|
||||
/**
|
||||
@ -27,11 +28,6 @@ class EscposPrintBuffer implements PrintBuffer
|
||||
*/
|
||||
const COMPRESS_CACHE = true;
|
||||
|
||||
/**
|
||||
* The input encoding of the buffer.
|
||||
*/
|
||||
const INPUT_ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
* Un-recognised characters will be replaced with this.
|
||||
*/
|
||||
@ -39,13 +35,13 @@ class EscposPrintBuffer implements PrintBuffer
|
||||
|
||||
/**
|
||||
* @var array $available
|
||||
* This array Maps ESC/POS character tables to names iconv encodings
|
||||
* Map code points to printer-specific code page numbers which contain them
|
||||
*/
|
||||
private $available = null;
|
||||
|
||||
/**
|
||||
* @var array $encode
|
||||
* Maps of UTF-8 to code-pages
|
||||
* Map code pages to a map of code points to encoding-specific characters 128-255
|
||||
*/
|
||||
private $encode = null;
|
||||
|
||||
@ -84,42 +80,43 @@ class EscposPrintBuffer implements PrintBuffer
|
||||
}
|
||||
}
|
||||
|
||||
public function writeText($text)
|
||||
public function writeText(string $text)
|
||||
{
|
||||
if ($this -> printer == null) {
|
||||
if ($this->printer == null) {
|
||||
throw new LogicException("Not attached to a printer.");
|
||||
}
|
||||
if ($text == null) {
|
||||
return;
|
||||
// Normalize text - this replaces combining characters with composed glyphs, and also helps us eliminated bad UTF-8 early
|
||||
$text = \Normalizer::normalize($text);
|
||||
if ($text === false) {
|
||||
throw new \Exception("Input must be UTF-8");
|
||||
}
|
||||
if (!mb_detect_encoding($text, self::INPUT_ENCODING, true)) {
|
||||
// Assume that the user has already put non-UTF8 into the target encoding.
|
||||
return $this -> writeTextRaw($text);
|
||||
}
|
||||
$i = 0;
|
||||
$j = 0;
|
||||
$len = mb_strlen($text, self::INPUT_ENCODING);
|
||||
while ($i < $len) {
|
||||
$matching = true;
|
||||
if (($encoding = $this -> identifyText(mb_substr($text, $i, 1, self::INPUT_ENCODING))) === false) {
|
||||
// Un-encodeable text
|
||||
$encoding = $this -> getPrinter() -> getCharacterTable();
|
||||
}
|
||||
$i++;
|
||||
$j = 1;
|
||||
do {
|
||||
$char = mb_substr($text, $i, 1, self::INPUT_ENCODING);
|
||||
$matching = !isset($this -> available[$char]) || isset($this -> available[$char][$encoding]);
|
||||
// Iterate code points
|
||||
$codePointIterator = \IntlBreakIterator::createCodePointInstance();
|
||||
$codePointIterator->setText($text);
|
||||
$encoding = $this->printer->getCharacterTable();
|
||||
$currentBlock = [];
|
||||
while ($codePointIterator->next() > 0) {
|
||||
// Write each code point
|
||||
$codePoint = $codePointIterator->getLastCodePoint();
|
||||
// See if we need to change code pages
|
||||
$matching = !isset($this->available[$codePoint]) || isset($this->encode[$encoding][$codePoint]);
|
||||
if ($matching) {
|
||||
$i++;
|
||||
$j++;
|
||||
$currentBlock[] = $codePoint;
|
||||
} else {
|
||||
// Write what we have
|
||||
$this->writeTextUsingEncoding($currentBlock, $encoding);
|
||||
// New encoding..
|
||||
$encoding = self::identifyText($codePoint);
|
||||
$currentBlock = [$codePoint];
|
||||
}
|
||||
} while ($matching && $i < $len);
|
||||
$this -> writeTextUsingEncoding(mb_substr($text, $i - $j, $j, self::INPUT_ENCODING), $encoding);
|
||||
}
|
||||
// Write out last bytes
|
||||
if (count($currentBlock) != 0) {
|
||||
$this->writeTextUsingEncoding($currentBlock, $encoding);
|
||||
}
|
||||
}
|
||||
|
||||
public function writeTextRaw($text)
|
||||
public function writeTextRaw(string $text)
|
||||
{
|
||||
if ($this -> printer == null) {
|
||||
throw new LogicException("Not attached to a printer.");
|
||||
@ -148,24 +145,17 @@ class EscposPrintBuffer implements PrintBuffer
|
||||
* Return an encoding which we can start to use for outputting this text.
|
||||
* Later parts of the text need not be included in the returned code page.
|
||||
*
|
||||
* @param string $text Input text to check.
|
||||
* @param int $codePoint Code point to check.
|
||||
* @return boolean|integer Code page number, or FALSE if the text is not
|
||||
* printable on any supported encoding.
|
||||
*/
|
||||
private function identifyText($text)
|
||||
private function identifyText(int $codePoint)
|
||||
{
|
||||
// TODO Replace this with an algorithm to choose the encoding which will
|
||||
// encode the farthest into the string, to minimise code page changes.
|
||||
$char = mb_substr($text, 0, 1, self::INPUT_ENCODING);
|
||||
if (!isset($this -> available[$char])) {
|
||||
if (!isset($this -> available[$codePoint])) {
|
||||
/* Character not available anywhere */
|
||||
return false;
|
||||
}
|
||||
foreach ($this -> available[$char] as $encodingNo => $true) {
|
||||
/* Return first code-page where it is available */
|
||||
return $encodingNo;
|
||||
}
|
||||
return false;
|
||||
return $this -> available[$codePoint];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -198,32 +188,39 @@ class EscposPrintBuffer implements PrintBuffer
|
||||
}
|
||||
|
||||
/* Generate conversion tables */
|
||||
$encodeLegacy = [];
|
||||
$encode = [];
|
||||
$available = [];
|
||||
|
||||
foreach ($supportedCodePages as $num => $codePage) {
|
||||
$encode[$num] = [];
|
||||
$encodeLegacy[$num] = [];
|
||||
if (!$codePage -> isEncodable()) {
|
||||
continue;
|
||||
}
|
||||
$map = $codePage -> getData();
|
||||
$map = $codePage -> getDataArray();
|
||||
$encodeMap = [];
|
||||
for ($char = 128; $char <= 255; $char++) {
|
||||
$utf8 = mb_substr($map, $char - 128, 1, self::INPUT_ENCODING);
|
||||
if ($utf8 == " ") { // Skip placeholders
|
||||
$codePoint = $map[$char - 128];
|
||||
if ($codePoint == CodePage::MISSING_CHAR_CODE) { // Skip placeholders
|
||||
continue;
|
||||
}
|
||||
if (!isset($available[$utf8])) {
|
||||
$available[$utf8] = [];
|
||||
$encodeMap[$codePoint] = $char;
|
||||
if (!isset($available[$codePoint])) {
|
||||
$available[$codePoint] = $num;
|
||||
}
|
||||
$available[$utf8][$num] = true;
|
||||
$encode[$num][$utf8] = chr($char);
|
||||
}
|
||||
$encode[$num] = $encodeMap;
|
||||
}
|
||||
|
||||
/* Use generated data */
|
||||
$dataArray = ["available" => $available, "encode" => $encode, "key" => $cacheKey];
|
||||
$this -> available = $dataArray["available"];
|
||||
$this -> encode = $dataArray["encode"];
|
||||
$dataArray = [
|
||||
"available" => $available,
|
||||
"encode" => $encode,
|
||||
"key" => $cacheKey
|
||||
];
|
||||
$this -> available = $available;
|
||||
$this -> encode = $encode;
|
||||
|
||||
$cacheData = serialize($dataArray);
|
||||
if (self::COMPRESS_CACHE) {
|
||||
$cacheData = gzcompress($cacheData);
|
||||
@ -235,31 +232,35 @@ class EscposPrintBuffer implements PrintBuffer
|
||||
/**
|
||||
* Encode a block of text using the specified map, and write it to the printer.
|
||||
*
|
||||
* @param string $text Text to print, UTF-8 format.
|
||||
* @param array $codePoints Text to print, as list of unicode code points
|
||||
* @param integer $encodingNo Encoding number to use- assumed to exist.
|
||||
*/
|
||||
private function writeTextUsingEncoding($text, $encodingNo)
|
||||
private function writeTextUsingEncoding(array $codePoints, int $encodingNo)
|
||||
{
|
||||
$encodeMap = $this -> encode[$encodingNo];
|
||||
$len = mb_strlen($text, self::INPUT_ENCODING);
|
||||
$len = count($codePoints);
|
||||
|
||||
$rawText = str_repeat(self::REPLACEMENT_CHAR, $len);
|
||||
$j = 0;
|
||||
$bytesWritten = 0;
|
||||
$cr = 0x0D; // extra character from line endings on Windows
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$char = mb_substr($text, $i, 1, self::INPUT_ENCODING);
|
||||
if (isset($encodeMap[$char])) {
|
||||
$rawText[$j] = $encodeMap[$char];
|
||||
} elseif (self::asciiCheck($char)) {
|
||||
$rawText[$j] = $char;
|
||||
} elseif ($char === "\r") {
|
||||
/* Skip past Windows line endings (UTF-8 usage) */
|
||||
$codePoint = $codePoints[$i];
|
||||
if (isset($encodeMap[$codePoint])) {
|
||||
// Printable via selected code page
|
||||
$rawText[$bytesWritten] = chr($encodeMap[$codePoint]);
|
||||
} elseif (($codePoint > 31 && $codePoint < 127) || $codePoint == 10) {
|
||||
// Printable as ASCII
|
||||
$rawText[$bytesWritten] = chr($codePoint);
|
||||
} elseif ($codePoint === $cr) {
|
||||
// Skip past Windows line endings, LF is fine
|
||||
continue;
|
||||
}
|
||||
$j++;
|
||||
$bytesWritten++;
|
||||
}
|
||||
if ($this -> printer -> getCharacterTable() != $encodingNo) {
|
||||
$this -> printer -> selectCharacterTable($encodingNo);
|
||||
}
|
||||
$this -> writeTextRaw(substr($rawText, 0, $j));
|
||||
$this -> writeTextRaw(substr($rawText, 0, $bytesWritten));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -267,7 +268,7 @@ class EscposPrintBuffer implements PrintBuffer
|
||||
*
|
||||
* @param string $data
|
||||
*/
|
||||
private function write($data)
|
||||
private function write(string $data)
|
||||
{
|
||||
$this -> printer -> getPrintConnector() -> write($data);
|
||||
}
|
||||
@ -279,7 +280,7 @@ class EscposPrintBuffer implements PrintBuffer
|
||||
* @param boolean $extended True to allow 128-256 values also (excluded by default)
|
||||
* @return boolean True if the character is printable, false if it is not.
|
||||
*/
|
||||
private static function asciiCheck($char, $extended = false)
|
||||
private static function asciiCheck(string $char, bool $extended = false)
|
||||
{
|
||||
if (strlen($char) != 1) {
|
||||
// Multi-byte string
|
||||
|
||||
@ -60,7 +60,7 @@ class ImagePrintBuffer implements PrintBuffer
|
||||
$this -> printer = $printer;
|
||||
}
|
||||
|
||||
public function writeText($text)
|
||||
public function writeText(string $text)
|
||||
{
|
||||
if ($this -> printer == null) {
|
||||
throw new LogicException("Not attached to a printer.");
|
||||
@ -102,7 +102,7 @@ class ImagePrintBuffer implements PrintBuffer
|
||||
$this -> printer -> bitImage($escposImage, $size);
|
||||
}
|
||||
|
||||
public function writeTextRaw($text)
|
||||
public function writeTextRaw(string $text)
|
||||
{
|
||||
if ($this -> printer == null) {
|
||||
throw new LogicException("Not attached to a printer.");
|
||||
@ -120,7 +120,7 @@ class ImagePrintBuffer implements PrintBuffer
|
||||
* @param string $font
|
||||
* Font name or a filename
|
||||
*/
|
||||
public function setFont($font)
|
||||
public function setFont(string $font)
|
||||
{
|
||||
$this->font = $font;
|
||||
}
|
||||
@ -128,7 +128,7 @@ class ImagePrintBuffer implements PrintBuffer
|
||||
/**
|
||||
* Numeric font size for rendering text to image
|
||||
*/
|
||||
public function setFontSize($fontSize)
|
||||
public function setFontSize(int $fontSize)
|
||||
{
|
||||
$this->fontSize = $fontSize;
|
||||
}
|
||||
|
||||
@ -52,12 +52,12 @@ interface PrintBuffer
|
||||
*
|
||||
* @param string $text Text to print
|
||||
*/
|
||||
public function writeText($text);
|
||||
public function writeText(string $text);
|
||||
|
||||
/**
|
||||
* Accept 8-bit text in the current encoding and add it to the buffer.
|
||||
*
|
||||
* @param string $text Text to print, already the target encoding.
|
||||
*/
|
||||
public function writeTextRaw($text);
|
||||
public function writeTextRaw(string $text);
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Mike42\Escpos\PrintConnectors;
|
||||
|
||||
use Guzzle\Http\Client;
|
||||
use Guzzle\Http\Message\Request;
|
||||
use Guzzle\Http\Message\Response;
|
||||
use Exception;
|
||||
|
||||
class ApiPrintConnector implements PrintConnector
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $stream;
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
protected $httpClient;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $printerId;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $apiToken;
|
||||
|
||||
/**
|
||||
* Construct new connector
|
||||
*
|
||||
* @param string $host
|
||||
* @param string $printerId
|
||||
* @param string $apiToken
|
||||
*/
|
||||
public function __construct($host, $printerId, $apiToken)
|
||||
{
|
||||
$this->httpClient = new Client(['base_uri' => $host]);
|
||||
$this->printerId = $printerId;
|
||||
$this->apiToken = $apiToken;
|
||||
|
||||
$this->stream = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Print connectors should cause a NOTICE if they are deconstructed
|
||||
* when they have not been finalized.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (! empty($this->stream)) {
|
||||
trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish using this print connector (close file, socket, send
|
||||
* accumulated output, etc).
|
||||
*/
|
||||
public function finalize()
|
||||
{
|
||||
/** @var Request $request */
|
||||
$request = $this->httpClient->post(
|
||||
'printers/'.$this->printerId.'/print?api_token='.$this->apiToken,
|
||||
null,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
/** @var Response $response */
|
||||
$response = $request->send();
|
||||
|
||||
if (! $response->isSuccessful()) {
|
||||
throw new Exception(
|
||||
sprintf('Failed to print. API returned "%s: %s"', $response->getStatusCode(), $response->getReasonPhrase())
|
||||
);
|
||||
}
|
||||
|
||||
$this->stream = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from the printer.
|
||||
*
|
||||
* @param string $len Length of data to read.
|
||||
* @return string Data read from the printer.
|
||||
*/
|
||||
public function read($len)
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to the print connector.
|
||||
*
|
||||
* @param string $data The data to write
|
||||
*/
|
||||
public function write($data)
|
||||
{
|
||||
$this->stream .= $data;
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,9 @@ class CupsPrintConnector implements PrintConnector
|
||||
|
||||
// Build command to work on data
|
||||
$tmpfname = tempnam(sys_get_temp_dir(), 'print-');
|
||||
if ($tmpfname==false) dol_syslog("CupsPrintConnector.php::Permission denied to write into target directory ".sys_get_temp_dir(), LOG_WARNING);
|
||||
if ($tmpfname === false) {
|
||||
throw new Exception("Failed to create temp file for printing.");
|
||||
}
|
||||
file_put_contents($tmpfname, $data);
|
||||
$cmd = sprintf(
|
||||
"lp -d %s %s",
|
||||
@ -135,7 +137,7 @@ class CupsPrintConnector implements PrintConnector
|
||||
* Read data from the printer.
|
||||
*
|
||||
* @param string $len Length of data to read.
|
||||
* @return Data read from the printer, or false where reading is not possible.
|
||||
* @return string Data read from the printer, or false where reading is not possible.
|
||||
*/
|
||||
public function read($len)
|
||||
{
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace Mike42\Escpos\PrintConnectors;
|
||||
|
||||
/**
|
||||
* Wrap multiple connectors up, to print to several printers at the same time.
|
||||
*/
|
||||
class MultiplePrintConnector implements PrintConnector
|
||||
{
|
||||
private $connectors;
|
||||
|
||||
public function __construct(PrintConnector ...$connectors)
|
||||
{
|
||||
$this -> connectors = $connectors;
|
||||
}
|
||||
|
||||
public function finalize()
|
||||
{
|
||||
foreach ($this -> connectors as $connector) {
|
||||
$connector -> finalize();
|
||||
}
|
||||
}
|
||||
|
||||
public function read($len)
|
||||
{
|
||||
// Cannot write
|
||||
return false;
|
||||
}
|
||||
|
||||
public function write($data)
|
||||
{
|
||||
foreach ($this -> connectors as $connector) {
|
||||
$connector -> write($data);
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -34,7 +34,7 @@ interface PrintConnector
|
||||
* Read data from the printer.
|
||||
*
|
||||
* @param string $len Length of data to read.
|
||||
* @return Data read from the printer, or false where reading is not possible.
|
||||
* @return string Data read from the printer, or false where reading is not possible.
|
||||
*/
|
||||
public function read($len);
|
||||
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
<?php
|
||||
namespace Mike42\Escpos\PrintConnectors;
|
||||
|
||||
/**
|
||||
* This file is part of escpos-php: PHP receipt printer library for use with
|
||||
* ESC/POS-compatible thermal and impact printers.
|
||||
|
||||
@ -286,6 +286,9 @@ class WindowsPrintConnector implements PrintConnector
|
||||
}
|
||||
/* Final print-out */
|
||||
$filename = tempnam(sys_get_temp_dir(), "escpos");
|
||||
if ($filename === false) {
|
||||
throw new Exception("Failed to create temp file for printing.");
|
||||
}
|
||||
file_put_contents($filename, $data);
|
||||
if (!$this -> runCopy($filename, $device)) {
|
||||
throw new Exception("Failed to copy file to printer");
|
||||
|
||||
@ -17,7 +17,6 @@ use InvalidArgumentException;
|
||||
use Mike42\Escpos\PrintBuffers\PrintBuffer;
|
||||
use Mike42\Escpos\PrintBuffers\EscposPrintBuffer;
|
||||
use Mike42\Escpos\PrintConnectors\PrintConnector;
|
||||
use Mike42\Escpos\CapabilityProfile;
|
||||
|
||||
/**
|
||||
* Main class for ESC/POS code generation
|
||||
@ -388,7 +387,7 @@ class Printer
|
||||
* available barcode types vary between printers.
|
||||
* @throws InvalidArgumentException Where the length or characters used in $content is invalid for the requested barcode format.
|
||||
*/
|
||||
public function barcode($content, $type = Printer::BARCODE_CODE39)
|
||||
public function barcode(string $content, int $type = Printer::BARCODE_CODE39)
|
||||
{
|
||||
/* Validate input */
|
||||
self::validateInteger($type, 65, 73, __FUNCTION__, "Barcode type");
|
||||
@ -454,7 +453,7 @@ class Printer
|
||||
* (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and
|
||||
* `Printer::IMG_DOUBLE_WIDTH` flags.
|
||||
*/
|
||||
public function bitImage(EscposImage $img, $size = Printer::IMG_DEFAULT)
|
||||
public function bitImage(EscposImage $img, int $size = Printer::IMG_DEFAULT)
|
||||
{
|
||||
self::validateInteger($size, 0, 3, __FUNCTION__);
|
||||
$rasterData = $img -> toRasterFormat();
|
||||
@ -474,7 +473,7 @@ class Printer
|
||||
* (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and
|
||||
* `Printer::IMG_DOUBLE_WIDTH` flags.
|
||||
*/
|
||||
public function bitImageColumnFormat(EscposImage $img, $size = Printer::IMG_DEFAULT)
|
||||
public function bitImageColumnFormat(EscposImage $img, int $size = Printer::IMG_DEFAULT)
|
||||
{
|
||||
$highDensityVertical = ! (($size & self::IMG_DOUBLE_HEIGHT) == Printer::IMG_DOUBLE_HEIGHT);
|
||||
$highDensityHorizontal = ! (($size & self::IMG_DOUBLE_WIDTH) == Printer::IMG_DOUBLE_WIDTH);
|
||||
@ -509,7 +508,7 @@ class Printer
|
||||
* @param int $mode Cut mode, either Printer::CUT_FULL or Printer::CUT_PARTIAL. If not specified, `Printer::CUT_FULL` will be used.
|
||||
* @param int $lines Number of lines to feed
|
||||
*/
|
||||
public function cut($mode = Printer::CUT_FULL, $lines = 3)
|
||||
public function cut(int $mode = Printer::CUT_FULL, int $lines = 3)
|
||||
{
|
||||
// TODO validation on cut() inputs
|
||||
$this -> connector -> write(self::GS . "V" . chr($mode) . chr($lines));
|
||||
@ -520,7 +519,7 @@ class Printer
|
||||
*
|
||||
* @param int $lines Number of lines to feed
|
||||
*/
|
||||
public function feed($lines = 1)
|
||||
public function feed(int $lines = 1)
|
||||
{
|
||||
self::validateInteger($lines, 1, 255, __FUNCTION__);
|
||||
if ($lines <= 1) {
|
||||
@ -552,14 +551,14 @@ class Printer
|
||||
*
|
||||
* @param int $lines number of lines to feed. If not specified, 1 line will be fed.
|
||||
*/
|
||||
public function feedReverse($lines = 1)
|
||||
public function feedReverse(int $lines = 1)
|
||||
{
|
||||
self::validateInteger($lines, 1, 255, __FUNCTION__);
|
||||
$this -> connector -> write(self::ESC . "e" . chr($lines));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number
|
||||
* @return int
|
||||
*/
|
||||
public function getCharacterTable()
|
||||
{
|
||||
@ -609,7 +608,7 @@ class Printer
|
||||
* (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and
|
||||
* `Printer::IMG_DOUBLE_WIDTH` flags.
|
||||
*/
|
||||
public function graphics(EscposImage $img, $size = Printer::IMG_DEFAULT)
|
||||
public function graphics(EscposImage $img, int $size = Printer::IMG_DEFAULT)
|
||||
{
|
||||
self::validateInteger($size, 0, 3, __FUNCTION__);
|
||||
$rasterData = $img -> toRasterFormat();
|
||||
@ -648,9 +647,8 @@ class Printer
|
||||
* start/end bars, or truncated code Printer::PDF417_TRUNCATED with start bars only.
|
||||
* @throws Exception If this profile indicates that PDF417 code is not supported
|
||||
*/
|
||||
public function pdf417Code($content, $width = 3, $heightMultiplier = 3, $dataColumnCount = 0, $ec = 0.10, $options = Printer::PDF417_STANDARD)
|
||||
public function pdf417Code(string $content, int $width = 3, int $heightMultiplier = 3, int $dataColumnCount = 0, float $ec = 0.10, int $options = Printer::PDF417_STANDARD)
|
||||
{
|
||||
self::validateString($content, __FUNCTION__, 'content');
|
||||
self::validateInteger($width, 2, 8, __FUNCTION__, 'width');
|
||||
self::validateInteger($heightMultiplier, 2, 8, __FUNCTION__, 'heightMultiplier');
|
||||
self::validateInteger($dataColumnCount, 0, 30, __FUNCTION__, 'dataColumnCount');
|
||||
@ -687,7 +685,7 @@ class Printer
|
||||
* @param int $on_ms pulse ON time, in milliseconds.
|
||||
* @param int $off_ms pulse OFF time, in milliseconds.
|
||||
*/
|
||||
public function pulse($pin = 0, $on_ms = 120, $off_ms = 240)
|
||||
public function pulse(int $pin = 0, int $on_ms = 120, int $off_ms = 240)
|
||||
{
|
||||
self::validateInteger($pin, 0, 1, __FUNCTION__);
|
||||
self::validateInteger($on_ms, 1, 511, __FUNCTION__);
|
||||
@ -703,9 +701,8 @@ class Printer
|
||||
* @param int $size Pixel size to use. Must be 1-16 (default 3)
|
||||
* @param int $model QR code model to use. Must be one of Printer::QR_MODEL_1, Printer::QR_MODEL_2 (default) or Printer::QR_MICRO (not supported by all printers).
|
||||
*/
|
||||
public function qrCode($content, $ec = Printer::QR_ECLEVEL_L, $size = 3, $model = Printer::QR_MODEL_2)
|
||||
public function qrCode(string $content, int $ec = Printer::QR_ECLEVEL_L, int$size = 3, int $model = Printer::QR_MODEL_2)
|
||||
{
|
||||
self::validateString($content, __FUNCTION__);
|
||||
self::validateInteger($ec, 0, 3, __FUNCTION__);
|
||||
self::validateInteger($size, 1, 16, __FUNCTION__);
|
||||
self::validateInteger($model, 1, 3, __FUNCTION__);
|
||||
@ -734,7 +731,7 @@ class Printer
|
||||
*
|
||||
* @param int $table The table to select. Available code tables are model-specific.
|
||||
*/
|
||||
public function selectCharacterTable($table = 0)
|
||||
public function selectCharacterTable(int $table = 0)
|
||||
{
|
||||
self::validateInteger($table, 0, 255, __FUNCTION__);
|
||||
$supported = $this -> profile -> getCodePages();
|
||||
@ -763,7 +760,7 @@ class Printer
|
||||
*
|
||||
* @param int $mode The mode to use. Default is Printer::MODE_FONT_A, with no special formatting. This has a similar effect to running initialize().
|
||||
*/
|
||||
public function selectPrintMode($mode = Printer::MODE_FONT_A)
|
||||
public function selectPrintMode(int $mode = Printer::MODE_FONT_A)
|
||||
{
|
||||
$allModes = Printer::MODE_FONT_B | self::MODE_EMPHASIZED | self::MODE_DOUBLE_HEIGHT | self::MODE_DOUBLE_WIDTH | self::MODE_UNDERLINE;
|
||||
if (!is_integer($mode) || $mode < 0 || ($mode & $allModes) != $mode) {
|
||||
@ -773,12 +770,22 @@ class Printer
|
||||
$this -> connector -> write(self::ESC . "!" . chr($mode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Select user-defined character set.
|
||||
*
|
||||
* @param bool $on True to enable user-defined character set, false to use built-in characters sets.
|
||||
*/
|
||||
public function selectUserDefinedCharacterSet($on = true)
|
||||
{
|
||||
$this -> connector -> write(self::ESC . "%". ($on ? chr(1) : chr(0)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set barcode height.
|
||||
*
|
||||
* @param int $height Height in dots. If not specified, 8 will be used.
|
||||
*/
|
||||
public function setBarcodeHeight($height = 8)
|
||||
public function setBarcodeHeight(int $height = 8)
|
||||
{
|
||||
self::validateInteger($height, 1, 255, __FUNCTION__);
|
||||
$this -> connector -> write(self::GS . "h" . chr($height));
|
||||
@ -790,7 +797,7 @@ class Printer
|
||||
* @param int $width Bar width in dots. If not specified, 3 will be used.
|
||||
* Values above 6 appear to have no effect.
|
||||
*/
|
||||
public function setBarcodeWidth($width = 3)
|
||||
public function setBarcodeWidth(int $width = 3)
|
||||
{
|
||||
self::validateInteger($width, 1, 255, __FUNCTION__);
|
||||
$this -> connector -> write(self::GS . "w" . chr($width));
|
||||
@ -803,7 +810,7 @@ class Printer
|
||||
* or any combination of Printer::BARCODE_TEXT_ABOVE and Printer::BARCODE_TEXT_BELOW
|
||||
* flags to display the text.
|
||||
*/
|
||||
public function setBarcodeTextPosition($position = Printer::BARCODE_TEXT_NONE)
|
||||
public function setBarcodeTextPosition(int $position = Printer::BARCODE_TEXT_NONE)
|
||||
{
|
||||
self::validateInteger($position, 0, 3, __FUNCTION__, "Barcode text position");
|
||||
$this -> connector -> write(self::GS . "H" . chr($position));
|
||||
@ -814,7 +821,7 @@ class Printer
|
||||
*
|
||||
* @param boolean $on true for double strike, false for no double strike
|
||||
*/
|
||||
public function setDoubleStrike($on = true)
|
||||
public function setDoubleStrike(bool $on = true)
|
||||
{
|
||||
self::validateBoolean($on, __FUNCTION__);
|
||||
$this -> connector -> write(self::ESC . "G". ($on ? chr(1) : chr(0)));
|
||||
@ -825,7 +832,7 @@ class Printer
|
||||
*
|
||||
* @param int $color Color to use. Must be either Printer::COLOR_1 (default), or Printer::COLOR_2.
|
||||
*/
|
||||
public function setColor($color = Printer::COLOR_1)
|
||||
public function setColor(int $color = Printer::COLOR_1)
|
||||
{
|
||||
self::validateInteger($color, 0, 1, __FUNCTION__, "Color");
|
||||
$this -> connector -> write(self::ESC . "r" . chr($color));
|
||||
@ -836,7 +843,7 @@ class Printer
|
||||
*
|
||||
* @param boolean $on true for emphasis, false for no emphasis
|
||||
*/
|
||||
public function setEmphasis($on = true)
|
||||
public function setEmphasis(bool $on = true)
|
||||
{
|
||||
self::validateBoolean($on, __FUNCTION__);
|
||||
$this -> connector -> write(self::ESC . "E". ($on ? chr(1) : chr(0)));
|
||||
@ -847,7 +854,7 @@ class Printer
|
||||
*
|
||||
* @param int $font The font to use. Must be either Printer::FONT_A, Printer::FONT_B, or Printer::FONT_C.
|
||||
*/
|
||||
public function setFont($font = Printer::FONT_A)
|
||||
public function setFont(int $font = Printer::FONT_A)
|
||||
{
|
||||
self::validateInteger($font, 0, 2, __FUNCTION__);
|
||||
$this -> connector -> write(self::ESC . "M" . chr($font));
|
||||
@ -858,7 +865,7 @@ class Printer
|
||||
*
|
||||
* @param int $justification One of Printer::JUSTIFY_LEFT, Printer::JUSTIFY_CENTER, or Printer::JUSTIFY_RIGHT.
|
||||
*/
|
||||
public function setJustification($justification = Printer::JUSTIFY_LEFT)
|
||||
public function setJustification(int $justification = Printer::JUSTIFY_LEFT)
|
||||
{
|
||||
self::validateInteger($justification, 0, 2, __FUNCTION__);
|
||||
$this -> connector -> write(self::ESC . "a" . chr($justification));
|
||||
@ -872,7 +879,7 @@ class Printer
|
||||
* @param int|null $height The height of each line, in dots. If not set, the printer
|
||||
* will reset to its default line spacing.
|
||||
*/
|
||||
public function setLineSpacing($height = null)
|
||||
public function setLineSpacing(int $height = null)
|
||||
{
|
||||
if ($height === null) {
|
||||
// Reset to default
|
||||
@ -888,7 +895,7 @@ class Printer
|
||||
*
|
||||
* @param int $margin The left margin to set on to the print area, in dots.
|
||||
*/
|
||||
public function setPrintLeftMargin($margin = 0)
|
||||
public function setPrintLeftMargin(int $margin = 0)
|
||||
{
|
||||
self::validateInteger($margin, 0, 65535, __FUNCTION__);
|
||||
$this -> connector -> write(Printer::GS . 'L' . self::intLowHigh($margin, 2));
|
||||
@ -900,7 +907,7 @@ class Printer
|
||||
*
|
||||
* @param int $width The width of the page print area, in dots.
|
||||
*/
|
||||
public function setPrintWidth($width = 512)
|
||||
public function setPrintWidth(int $width = 512)
|
||||
{
|
||||
self::validateInteger($width, 1, 65535, __FUNCTION__);
|
||||
$this -> connector -> write(Printer::GS . 'W' . self::intLowHigh($width, 2));
|
||||
@ -932,7 +939,7 @@ class Printer
|
||||
*
|
||||
* @param boolean $on True to enable, false to disable.
|
||||
*/
|
||||
public function setReverseColors($on = true)
|
||||
public function setReverseColors(bool $on = true)
|
||||
{
|
||||
self::validateBoolean($on, __FUNCTION__);
|
||||
$this -> connector -> write(self::GS . "B" . ($on ? chr(1) : chr(0)));
|
||||
@ -944,30 +951,21 @@ class Printer
|
||||
* @param int $widthMultiplier Multiple of the regular height to use (range 1 - 8)
|
||||
* @param int $heightMultiplier Multiple of the regular height to use (range 1 - 8)
|
||||
*/
|
||||
public function setTextSize($widthMultiplier, $heightMultiplier)
|
||||
public function setTextSize(int $widthMultiplier, int $heightMultiplier)
|
||||
{
|
||||
self::validateInteger($widthMultiplier, 1, 8, __FUNCTION__);
|
||||
self::validateInteger($heightMultiplier, 1, 8, __FUNCTION__);
|
||||
$c = pow(2, 4) * ($widthMultiplier - 1) + ($heightMultiplier - 1);
|
||||
$c = (2 << 3) * ($widthMultiplier - 1) + ($heightMultiplier - 1);
|
||||
$this -> connector -> write(self::GS . "!" . chr($c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set underline for printed text.
|
||||
*
|
||||
* Argument can be true/false, or one of UNDERLINE_NONE,
|
||||
* UNDERLINE_SINGLE or UNDERLINE_DOUBLE.
|
||||
*
|
||||
* @param int $underline Either true/false, or one of Printer::UNDERLINE_NONE, Printer::UNDERLINE_SINGLE or Printer::UNDERLINE_DOUBLE. Defaults to Printer::UNDERLINE_SINGLE.
|
||||
*/
|
||||
public function setUnderline($underline = Printer::UNDERLINE_SINGLE)
|
||||
public function setUnderline(int $underline = Printer::UNDERLINE_SINGLE)
|
||||
{
|
||||
/* Map true/false to underline constants */
|
||||
if ($underline === true) {
|
||||
$underline = Printer::UNDERLINE_SINGLE;
|
||||
} elseif ($underline === false) {
|
||||
$underline = Printer::UNDERLINE_NONE;
|
||||
}
|
||||
/* Set the underline */
|
||||
self::validateInteger($underline, 0, 2, __FUNCTION__);
|
||||
$this -> connector -> write(self::ESC . "-" . chr($underline));
|
||||
@ -978,9 +976,8 @@ class Printer
|
||||
*
|
||||
* @param boolean $on True to enable, false to disable.
|
||||
*/
|
||||
public function setUpsideDown($on = true)
|
||||
public function setUpsideDown(bool $on = true)
|
||||
{
|
||||
self::validateBoolean($on, __FUNCTION__);
|
||||
$this -> connector -> write(self::ESC . "{" . ($on ? chr(1) : chr(0)));
|
||||
}
|
||||
|
||||
@ -990,26 +987,25 @@ class Printer
|
||||
* Text should either be followed by a line-break, or feed() should be called
|
||||
* after this to clear the print buffer.
|
||||
*
|
||||
* @param string $str Text to print
|
||||
* @param string $str Text to print, as UTF-8
|
||||
*/
|
||||
public function text($str = "")
|
||||
public function text(string $str)
|
||||
{
|
||||
self::validateString($str, __FUNCTION__);
|
||||
$this -> buffer -> writeText((string)$str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Chinese text to the buffer. This is a specific workaround for the common Zijang printer- The printer will be switched to a two-byte mode and sent GBK-encoded text.
|
||||
* Add Chinese text to the buffer. This is a specific workaround for Zijang printers-
|
||||
* The printer will be switched to a two-byte mode and sent GBK-encoded text.
|
||||
*
|
||||
* Support for this will be merged into a print buffer.
|
||||
*
|
||||
* @param string $str Text to print, as UTF-8
|
||||
*/
|
||||
public function textChinese($str = "")
|
||||
public function textChinese(string $str = "")
|
||||
{
|
||||
self::validateString($str, __FUNCTION__);
|
||||
$this -> connector -> write(self::FS . "&");
|
||||
$str = iconv("UTF-8", "GBK//IGNORE", $str);
|
||||
$str = \UConverter::transcode($str, "GBK", "UTF-8");
|
||||
$this -> buffer -> writeTextRaw((string)$str);
|
||||
$this -> connector -> write(self::FS . ".");
|
||||
}
|
||||
@ -1022,9 +1018,8 @@ class Printer
|
||||
*
|
||||
* @param string $str Text to print
|
||||
*/
|
||||
public function textRaw($str = "")
|
||||
public function textRaw(string $str = "")
|
||||
{
|
||||
self::validateString($str, __FUNCTION__);
|
||||
$this -> buffer -> writeTextRaw((string)$str);
|
||||
}
|
||||
|
||||
@ -1037,7 +1032,7 @@ class Printer
|
||||
* @param string $m Modifier/variant for function. Often '0' where used.
|
||||
* @throws InvalidArgumentException Where the input lengths are bad.
|
||||
*/
|
||||
protected function wrapperSend2dCodeData($fn, $cn, $data = '', $m = '')
|
||||
protected function wrapperSend2dCodeData(string $fn, string $cn, string$data = '', string $m = '')
|
||||
{
|
||||
if (strlen($m) > 1 || strlen($cn) != 1 || strlen($fn) != 1) {
|
||||
throw new InvalidArgumentException("wrapperSend2dCodeData: cn and fn must be one character each.");
|
||||
@ -1054,7 +1049,7 @@ class Printer
|
||||
* @param string $data Data to send.
|
||||
* @throws InvalidArgumentException Where the input lengths are bad.
|
||||
*/
|
||||
protected function wrapperSendGraphicsData($m, $fn, $data = '')
|
||||
protected function wrapperSendGraphicsData(string $m, string $fn, string$data = '')
|
||||
{
|
||||
if (strlen($m) != 1 || strlen($fn) != 1) {
|
||||
throw new InvalidArgumentException("wrapperSendGraphicsData: m and fn must be one character each.");
|
||||
@ -1070,7 +1065,7 @@ class Printer
|
||||
* @param boolean $long True to use 4 bytes, false to use 2
|
||||
* @return string
|
||||
*/
|
||||
protected static function dataHeader(array $inputs, $long = true)
|
||||
protected static function dataHeader(array $inputs, bool $long = true)
|
||||
{
|
||||
$outp = [];
|
||||
foreach ($inputs as $input) {
|
||||
@ -1090,7 +1085,7 @@ class Printer
|
||||
* @param int $input Input number
|
||||
* @param int $length The number of bytes to output (1 - 4).
|
||||
*/
|
||||
protected static function intLowHigh($input, $length)
|
||||
protected static function intLowHigh(int $input, int $length)
|
||||
{
|
||||
$maxInput = (256 << ($length * 8) - 1);
|
||||
self::validateInteger($length, 1, 4, __FUNCTION__);
|
||||
@ -1109,7 +1104,7 @@ class Printer
|
||||
* @param boolean $test the input to test
|
||||
* @param string $source the name of the function calling this
|
||||
*/
|
||||
protected static function validateBoolean($test, $source)
|
||||
protected static function validateBoolean(bool $test, string $source)
|
||||
{
|
||||
if (!($test === true || $test === false)) {
|
||||
throw new InvalidArgumentException("Argument to $source must be a boolean");
|
||||
@ -1125,7 +1120,7 @@ class Printer
|
||||
* @param string $source the name of the function calling this
|
||||
* @param string $argument the name of the invalid parameter
|
||||
*/
|
||||
protected static function validateFloat($test, $min, $max, $source, $argument = "Argument")
|
||||
protected static function validateFloat(float $test, float $min, float $max, string $source, string $argument = "Argument")
|
||||
{
|
||||
if (!is_numeric($test)) {
|
||||
throw new InvalidArgumentException("$argument given to $source must be a float, but '$test' was given.");
|
||||
@ -1144,7 +1139,7 @@ class Printer
|
||||
* @param string $source the name of the function calling this
|
||||
* @param string $argument the name of the invalid parameter
|
||||
*/
|
||||
protected static function validateInteger($test, $min, $max, $source, $argument = "Argument")
|
||||
protected static function validateInteger(int $test, int $min, int $max, string $source, string $argument = "Argument")
|
||||
{
|
||||
self::validateIntegerMulti($test, [[$min, $max]], $source, $argument);
|
||||
}
|
||||
@ -1158,7 +1153,7 @@ class Printer
|
||||
* @param string $source the name of the function calling this
|
||||
* @param string $argument the name of the invalid parameter
|
||||
*/
|
||||
protected static function validateIntegerMulti($test, array $ranges, $source, $argument = "Argument")
|
||||
protected static function validateIntegerMulti(int $test, array $ranges, string $source, string $argument = "Argument")
|
||||
{
|
||||
if (!is_integer($test)) {
|
||||
throw new InvalidArgumentException("$argument given to $source must be a number, but '$test' was given.");
|
||||
@ -1184,21 +1179,6 @@ class Printer
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an exception if the argument given can't be cast to a string
|
||||
*
|
||||
* @param string $test the input to test
|
||||
* @param string $source the name of the function calling this
|
||||
* @param string $argument the name of the parameter being validated
|
||||
* @throws InvalidArgumentException Where the argument is not valid
|
||||
*/
|
||||
protected static function validateString($test, $source, $argument = "Argument")
|
||||
{
|
||||
if (is_object($test) && !method_exists($test, '__toString')) {
|
||||
throw new InvalidArgumentException("$argument to $source must be a string");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an exception if the argument doesn't match the given regex.
|
||||
*
|
||||
@ -1208,7 +1188,7 @@ class Printer
|
||||
* @param string $argument the name of the parameter being validated
|
||||
* @throws InvalidArgumentException Where the argument is not valid
|
||||
*/
|
||||
protected static function validateStringRegex($test, $source, $regex, $argument = "Argument")
|
||||
protected static function validateStringRegex(string $test, string $source, string $regex, string $argument = "Argument")
|
||||
{
|
||||
if (preg_match($regex, $test) === 0) {
|
||||
throw new InvalidArgumentException("$argument given to $source is invalid. It should match regex '$regex', but '$test' was given.");
|
||||
|
||||
@ -173,6 +173,11 @@
|
||||
"name": "CP855",
|
||||
"python_encode": "cp855"
|
||||
},
|
||||
"CP856": {
|
||||
"iconv": "CP856",
|
||||
"name": "CP856",
|
||||
"python_encode": "cp856"
|
||||
},
|
||||
"CP857": {
|
||||
"iconv": "CP857",
|
||||
"name": "CP857",
|
||||
@ -235,6 +240,11 @@
|
||||
"name": "CP932",
|
||||
"python_encode": "cp932"
|
||||
},
|
||||
"ISO_8859-1": {
|
||||
"iconv": "ISO_8859-1",
|
||||
"name": "ISO_8859-1",
|
||||
"python_encode": "latin_1"
|
||||
},
|
||||
"ISO_8859-15": {
|
||||
"iconv": "ISO_8859-15",
|
||||
"name": "ISO_8859-15",
|
||||
@ -245,11 +255,41 @@
|
||||
"name": "ISO_8859-2",
|
||||
"python_encode": "iso8859_2"
|
||||
},
|
||||
"ISO_8859-3": {
|
||||
"iconv": "ISO_8859-3",
|
||||
"name": "ISO_8859-3",
|
||||
"python_encode": "iso8859_3"
|
||||
},
|
||||
"ISO_8859-4": {
|
||||
"iconv": "ISO_8859-4",
|
||||
"name": "ISO_8859-4",
|
||||
"python_encode": "iso8859_4"
|
||||
},
|
||||
"ISO_8859-5": {
|
||||
"iconv": "ISO_8859-5",
|
||||
"name": "ISO_8859-5",
|
||||
"python_encode": "iso8859_5"
|
||||
},
|
||||
"ISO_8859-6": {
|
||||
"iconv": "ISO_8859-6",
|
||||
"name": "ISO_8859-6",
|
||||
"python_encode": "iso8859_6"
|
||||
},
|
||||
"ISO_8859-7": {
|
||||
"iconv": "ISO_8859-7",
|
||||
"name": "ISO_8859-7",
|
||||
"python_encode": "iso8859_7"
|
||||
},
|
||||
"ISO_8859-8": {
|
||||
"iconv": "ISO_8859-8",
|
||||
"name": "ISO_8859-8",
|
||||
"python_encode": "iso8859_8"
|
||||
},
|
||||
"ISO_8859-9": {
|
||||
"iconv": "ISO_8859-9",
|
||||
"name": "ISO_8859-9",
|
||||
"python_encode": "iso8859_9"
|
||||
},
|
||||
"OXHOO-EUROPEAN": {
|
||||
"data": [
|
||||
"\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5",
|
||||
@ -337,6 +377,74 @@
|
||||
"notes": "This is a two-line, ESC/POS-aware customer display from Oxhoo. The ESC/POS command mode can be activated persistently by sending:\n\n echo -ne \"\\n\\x02\\x05\\x43\\x31\\x03\" > /dev/ttyUSB0\n",
|
||||
"vendor": "Oxhoo"
|
||||
},
|
||||
"CT-S651": {
|
||||
"codePages": {
|
||||
"0": "CP437",
|
||||
"1": "CP932",
|
||||
"2": "CP850",
|
||||
"3": "CP860",
|
||||
"4": "CP863",
|
||||
"5": "CP865",
|
||||
"6": "CP852",
|
||||
"7": "CP866",
|
||||
"8": "CP857",
|
||||
"9": "CP1252",
|
||||
"16": "CP1252",
|
||||
"17": "CP866",
|
||||
"18": "CP852",
|
||||
"19": "CP858",
|
||||
"20": "Unknown",
|
||||
"21": "Unknown",
|
||||
"25": "Unknown",
|
||||
"26": "Unknown",
|
||||
"30": "TCVN-3-1",
|
||||
"31": "TCVN-3-2",
|
||||
"40": "CP864",
|
||||
"255": "Unknown"
|
||||
},
|
||||
"colors": {
|
||||
"0": "black",
|
||||
"1": "red"
|
||||
},
|
||||
"features": {
|
||||
"barcodeA": true,
|
||||
"barcodeB": true,
|
||||
"bitImageColumn": true,
|
||||
"bitImageRaster": true,
|
||||
"graphics": true,
|
||||
"highDensity": true,
|
||||
"paperFullCut": true,
|
||||
"paperPartCut": true,
|
||||
"pdf417Code": true,
|
||||
"pulseBel": true,
|
||||
"pulseStandard": true,
|
||||
"qrCode": true,
|
||||
"starCommands": false
|
||||
},
|
||||
"fonts": {
|
||||
"0": {
|
||||
"columns": 48,
|
||||
"name": "Font A"
|
||||
},
|
||||
"1": {
|
||||
"columns": 64,
|
||||
"name": "Font B"
|
||||
},
|
||||
"2": {
|
||||
"columns": 72,
|
||||
"name": "Font C"
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
"width": {
|
||||
"mm": 80,
|
||||
"pixels": 640
|
||||
}
|
||||
},
|
||||
"name": "CT-S651",
|
||||
"notes": "Citizen CT-S651 profile. This is a two-color thermal printer, supporting paper sizes from 58mm up to 83mm\n",
|
||||
"vendor": "Citizen"
|
||||
},
|
||||
"NT-5890K": {
|
||||
"codePages": {
|
||||
"0": "CP437",
|
||||
@ -781,6 +889,91 @@
|
||||
"notes": "POS-5890 thermal printer series, also marketed under various other names.\n",
|
||||
"vendor": "Zjiang"
|
||||
},
|
||||
"RP326": {
|
||||
"codePages": {
|
||||
"0": "CP437",
|
||||
"1": "Unknown",
|
||||
"2": "CP850",
|
||||
"3": "CP860",
|
||||
"4": "CP863",
|
||||
"5": "CP865",
|
||||
"6": "CP1251",
|
||||
"7": "CP866",
|
||||
"8": "Unknown",
|
||||
"9": "Unknown",
|
||||
"10": "Unknown",
|
||||
"15": "CP862",
|
||||
"16": "CP1252",
|
||||
"17": "CP1253",
|
||||
"18": "CP852",
|
||||
"19": "CP858",
|
||||
"20": "Unknown",
|
||||
"21": "Unknown",
|
||||
"22": "Unknown",
|
||||
"23": "ISO_8859-1",
|
||||
"24": "CP737",
|
||||
"25": "CP1257",
|
||||
"26": "Unknown",
|
||||
"27": "CP720",
|
||||
"28": "CP855",
|
||||
"29": "CP857",
|
||||
"30": "CP1250",
|
||||
"31": "CP775",
|
||||
"32": "CP1254",
|
||||
"33": "CP1255",
|
||||
"34": "CP1256",
|
||||
"35": "CP1258",
|
||||
"36": "ISO_8859-2",
|
||||
"37": "ISO_8859-3",
|
||||
"38": "ISO_8859-4",
|
||||
"39": "ISO_8859-5",
|
||||
"40": "ISO_8859-6",
|
||||
"41": "ISO_8859-7",
|
||||
"42": "ISO_8859-8",
|
||||
"43": "ISO_8859-9",
|
||||
"44": "ISO_8859-15",
|
||||
"45": "Unknown",
|
||||
"46": "CP856",
|
||||
"47": "CP874"
|
||||
},
|
||||
"colors": {
|
||||
"0": "black"
|
||||
},
|
||||
"features": {
|
||||
"barcodeA": true,
|
||||
"barcodeB": true,
|
||||
"bitImageColumn": true,
|
||||
"bitImageRaster": true,
|
||||
"graphics": false,
|
||||
"highDensity": true,
|
||||
"paperFullCut": true,
|
||||
"paperPartCut": true,
|
||||
"pdf417Code": true,
|
||||
"pulseBel": false,
|
||||
"pulseStandard": true,
|
||||
"qrCode": true,
|
||||
"starCommands": false
|
||||
},
|
||||
"fonts": {
|
||||
"0": {
|
||||
"columns": 42,
|
||||
"name": "Font A"
|
||||
},
|
||||
"1": {
|
||||
"columns": 56,
|
||||
"name": "Font B"
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
"width": {
|
||||
"mm": "Unknown",
|
||||
"pixels": "Unknown"
|
||||
}
|
||||
},
|
||||
"name": "RP326",
|
||||
"notes": "",
|
||||
"vendor": "Rongta"
|
||||
},
|
||||
"SP2000": {
|
||||
"codePages": {
|
||||
"0": "CP437",
|
||||
@ -871,6 +1064,65 @@
|
||||
"notes": "Star SP2000 impact printer series with ESC/POS emulation enabled",
|
||||
"vendor": "Star Micronics"
|
||||
},
|
||||
"Sunmi-V2": {
|
||||
"codePages": {
|
||||
"0": "CP437",
|
||||
"2": "CP850",
|
||||
"3": "CP860",
|
||||
"4": "CP863",
|
||||
"5": "CP865",
|
||||
"13": "CP857",
|
||||
"14": "CP737",
|
||||
"15": "ISO_8859-7",
|
||||
"16": "CP1252",
|
||||
"17": "CP866",
|
||||
"18": "CP852",
|
||||
"19": "CP858",
|
||||
"21": "CP874",
|
||||
"33": "CP775",
|
||||
"34": "CP855",
|
||||
"36": "CP862",
|
||||
"37": "CP864",
|
||||
"254": "CP855"
|
||||
},
|
||||
"colors": {
|
||||
"0": "black"
|
||||
},
|
||||
"features": {
|
||||
"barcodeA": true,
|
||||
"barcodeB": true,
|
||||
"bitImageColumn": false,
|
||||
"bitImageRaster": true,
|
||||
"graphics": false,
|
||||
"highDensity": true,
|
||||
"paperFullCut": false,
|
||||
"paperPartCut": false,
|
||||
"pdf417Code": true,
|
||||
"pulseBel": false,
|
||||
"pulseStandard": true,
|
||||
"qrCode": true,
|
||||
"starCommands": false
|
||||
},
|
||||
"fonts": {
|
||||
"0": {
|
||||
"columns": 32,
|
||||
"name": "Font A"
|
||||
},
|
||||
"1": {
|
||||
"columns": 42,
|
||||
"name": "Font B"
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
"width": {
|
||||
"mm": 57.5,
|
||||
"pixels": 384
|
||||
}
|
||||
},
|
||||
"name": "Sunmi V2",
|
||||
"notes": "Sunmi mini-POS Android device with a built-in Virtual Bluetooth thermal printer.\n",
|
||||
"vendor": "Sunmi"
|
||||
},
|
||||
"TEP-200M": {
|
||||
"codePages": {
|
||||
"0": "CP437",
|
||||
@ -1333,8 +1585,8 @@
|
||||
},
|
||||
"media": {
|
||||
"width": {
|
||||
"mm": "Unknown",
|
||||
"pixels": "Unknown"
|
||||
"mm": 80,
|
||||
"pixels": 512
|
||||
}
|
||||
},
|
||||
"name": "TM-T88IV",
|
||||
@ -1380,14 +1632,92 @@
|
||||
},
|
||||
"media": {
|
||||
"width": {
|
||||
"mm": "Unknown",
|
||||
"pixels": "Unknown"
|
||||
"mm": 80,
|
||||
"pixels": 512
|
||||
}
|
||||
},
|
||||
"name": "TM-T88IV South Asia",
|
||||
"notes": "Epson TM-T88IV profile (South Asia models)\n",
|
||||
"vendor": "Epson"
|
||||
},
|
||||
"TM-T88V": {
|
||||
"codePages": {
|
||||
"0": "CP437",
|
||||
"1": "CP932",
|
||||
"2": "CP850",
|
||||
"3": "CP860",
|
||||
"4": "CP863",
|
||||
"5": "CP865",
|
||||
"11": "CP851",
|
||||
"12": "CP853",
|
||||
"13": "CP857",
|
||||
"14": "CP737",
|
||||
"15": "ISO_8859-7",
|
||||
"16": "CP1252",
|
||||
"17": "CP866",
|
||||
"18": "CP852",
|
||||
"19": "CP858",
|
||||
"30": "TCVN-3-1",
|
||||
"31": "TCVN-3-2",
|
||||
"32": "CP720",
|
||||
"33": "CP775",
|
||||
"34": "CP855",
|
||||
"35": "CP861",
|
||||
"36": "CP862",
|
||||
"37": "CP864",
|
||||
"38": "CP869",
|
||||
"39": "ISO_8859-2",
|
||||
"40": "ISO_8859-15",
|
||||
"41": "CP1098",
|
||||
"45": "CP1250",
|
||||
"46": "CP1251",
|
||||
"47": "CP1253",
|
||||
"48": "CP1254",
|
||||
"49": "CP1255",
|
||||
"50": "CP1256",
|
||||
"51": "CP1257",
|
||||
"52": "CP1258",
|
||||
"53": "RK1048",
|
||||
"255": "Unknown"
|
||||
},
|
||||
"colors": {
|
||||
"0": "black"
|
||||
},
|
||||
"features": {
|
||||
"barcodeA": true,
|
||||
"barcodeB": true,
|
||||
"bitImageColumn": true,
|
||||
"bitImageRaster": true,
|
||||
"graphics": true,
|
||||
"highDensity": true,
|
||||
"paperFullCut": true,
|
||||
"paperPartCut": true,
|
||||
"pdf417Code": true,
|
||||
"pulseBel": false,
|
||||
"pulseStandard": true,
|
||||
"qrCode": true,
|
||||
"starCommands": false
|
||||
},
|
||||
"fonts": {
|
||||
"0": {
|
||||
"columns": 42,
|
||||
"name": "Font A"
|
||||
},
|
||||
"1": {
|
||||
"columns": 56,
|
||||
"name": "Font B"
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
"width": {
|
||||
"mm": 80,
|
||||
"pixels": 512
|
||||
}
|
||||
},
|
||||
"name": "TM-T88V",
|
||||
"notes": "Epson TM-T88V profile\n",
|
||||
"vendor": "Epson"
|
||||
},
|
||||
"TM-U220": {
|
||||
"codePages": {
|
||||
"0": "CP437"
|
||||
@ -1611,6 +1941,52 @@
|
||||
"notes": "Star TUP500 thermal printer series with ESC/POS emulation enabled",
|
||||
"vendor": "Star Micronics"
|
||||
},
|
||||
"ZJ-5870": {
|
||||
"codePages": {
|
||||
"0": "CP437",
|
||||
"1": "CP932",
|
||||
"2": "CP850",
|
||||
"3": "CP860",
|
||||
"4": "CP863",
|
||||
"5": "CP865",
|
||||
"16": "CP1252",
|
||||
"17": "CP866",
|
||||
"18": "CP852"
|
||||
},
|
||||
"colors": {
|
||||
"0": "black"
|
||||
},
|
||||
"features": {
|
||||
"barcodeA": false,
|
||||
"barcodeB": false,
|
||||
"bitImageColumn": true,
|
||||
"bitImageRaster": true,
|
||||
"graphics": false,
|
||||
"highDensity": false,
|
||||
"paperFullCut": false,
|
||||
"paperPartCut": false,
|
||||
"pdf417Code": false,
|
||||
"pulseBel": false,
|
||||
"pulseStandard": true,
|
||||
"qrCode": false,
|
||||
"starCommands": false
|
||||
},
|
||||
"fonts": {
|
||||
"0": {
|
||||
"columns": 32,
|
||||
"name": "Font A"
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
"width": {
|
||||
"mm": 48,
|
||||
"pixels": 384
|
||||
}
|
||||
},
|
||||
"name": "ZJ-5870 Thermal Receipt Printer",
|
||||
"notes": "ESC/POS Profile for ZiJiang ZJ-5870 Thermal Receipt Printer, which may be branded AGPtEK or Esky, and identifies itself as a POS-58 Thermal Printer on selftest. This profile is suitable for alphanumberic character mode, but is untested on Chinese character mode. (Change modes by holding down feed button during power-on until the mode LED turns off, then release immediately.)\n",
|
||||
"vendor": "ZiJiang"
|
||||
},
|
||||
"default": {
|
||||
"codePages": {
|
||||
"0": "CP437",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user