mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-12-26 22:50:29 +01:00
367 lines
11 KiB
PHP
367 lines
11 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Copyright (c) 2014 Michael Billington <michael.billington@gmail.com>,
|
||
|
* with additions by Warren Doyle (wdoyle)
|
||
|
* modified by Benedikt Sauter changed all fwrite to this->str 24.01.2016
|
||
|
* modified by Benedikt Sauter add qrCode,wrapperSend2dCodeData,intLowHigh from https://github.com/mike42/escpos-php/blob/master/src/Mike42/Escpos/Printer.php 05.03.2016
|
||
|
*
|
||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
* of this software and associated documentation files (the "Software"), to deal
|
||
|
* in the Software without restriction, including without limitation the rights
|
||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
* copies of the Software, and to permit persons to whom the Software is
|
||
|
* furnished to do so, subject to the following conditions:
|
||
|
*
|
||
|
* The above copyright notice and this permission notice shall be included in all
|
||
|
* copies or substantial portions of the Software.
|
||
|
*
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||
|
* SOFTWARE.
|
||
|
*
|
||
|
* If you wish to expand this library you can use the below link:
|
||
|
* http://content.epson.de/fileadmin/content/files/RSD/downloads/escpos.pdf
|
||
|
*/
|
||
|
define("DEBUG_MODE", 0);
|
||
|
|
||
|
if(DEBUG_MODE == 1)
|
||
|
{
|
||
|
error_reporting(E_ALL);
|
||
|
ini_set("display_errors", 1);
|
||
|
}
|
||
|
|
||
|
class phpprint {
|
||
|
/* ASCII codes */
|
||
|
const NUL = "\x00";
|
||
|
const LF = "\x0a";
|
||
|
const ESC = "\x1b";
|
||
|
const GS = "\x1d";
|
||
|
|
||
|
/* Print mode constants */
|
||
|
const MODE_FONT_A = 0;
|
||
|
const MODE_FONT_B = 1;
|
||
|
const MODE_EMPHASIZED = 8;
|
||
|
const MODE_DOUBLE_HEIGHT = 16;
|
||
|
const MODE_DOUBLE_WIDTH = 32;
|
||
|
const MODE_UNDERLINE = 128;
|
||
|
|
||
|
/* Fonts */
|
||
|
const FONT_A = 0;
|
||
|
const FONT_B = 1;
|
||
|
const FONT_C = 2;
|
||
|
|
||
|
/* Justifications */
|
||
|
const JUSTIFY_LEFT = 0;
|
||
|
const JUSTIFY_CENTER = 1;
|
||
|
const JUSTIFY_RIGHT = 2;
|
||
|
|
||
|
/* Cut types */
|
||
|
const CUT_FULL = 65;
|
||
|
const CUT_PARTIAL = 66;
|
||
|
|
||
|
/* Barcode types */
|
||
|
const BARCODE_UPCA = 0;
|
||
|
const BARCODE_UPCE = 1;
|
||
|
const BARCODE_JAN13 = 2;
|
||
|
const BARCODE_JAN8 = 3;
|
||
|
const BARCODE_CODE39 = 4;
|
||
|
const BARCODE_ITF = 5;
|
||
|
const BARCODE_CODABAR = 6;
|
||
|
private $fp;
|
||
|
|
||
|
/* QR code error correction levels */
|
||
|
const QR_ECLEVEL_L = 0;
|
||
|
const QR_ECLEVEL_M = 1;
|
||
|
const QR_ECLEVEL_Q = 2;
|
||
|
const QR_ECLEVEL_H = 3;
|
||
|
|
||
|
/* QR code models */
|
||
|
const QR_MODEL_1 = 1;
|
||
|
const QR_MODEL_2 = 2;
|
||
|
const QR_MICRO = 3;
|
||
|
|
||
|
/** @var string $txt */
|
||
|
public $txt;
|
||
|
|
||
|
/** @var string $str */
|
||
|
public $str;
|
||
|
|
||
|
protected $pdfCommands = [];
|
||
|
|
||
|
function __construct($head = null) {
|
||
|
//THIS IS THE SERIAL PORT YOU ARE OPENING
|
||
|
//$fp = fopen($head,"w");
|
||
|
//$this -> fp = $fp;
|
||
|
$this -> initialize();
|
||
|
}
|
||
|
|
||
|
public function getPdfCommands(): array
|
||
|
{
|
||
|
return $this->pdfCommands;
|
||
|
}
|
||
|
|
||
|
// Funktion am 12.02.2016 durch Benedikt Sauter hinzugefuegt
|
||
|
function uml($text)
|
||
|
{
|
||
|
$rw=$text;
|
||
|
$rw=str_replace("Ä",chr(142),$rw);
|
||
|
$rw=str_replace("Ö",chr(153),$rw);
|
||
|
$rw=str_replace("Ü",chr(154),$rw);
|
||
|
$rw=str_replace("ä",chr(132),$rw);
|
||
|
$rw=str_replace("ö",chr(148),$rw);
|
||
|
$rw=str_replace("ü",chr(129),$rw);
|
||
|
$rw=str_replace("ß",chr(225),$rw);
|
||
|
return $rw;
|
||
|
}
|
||
|
/**
|
||
|
* Add text to the buffer
|
||
|
*
|
||
|
* @param string $str Text to print
|
||
|
*/
|
||
|
function text($str = "") {
|
||
|
if(DEBUG_MODE == 1)
|
||
|
echo $str;
|
||
|
|
||
|
//fwrite($this -> fp, $str);
|
||
|
$this->str .= $this->uml($str);
|
||
|
$this->txt .= $str;
|
||
|
$this->pdfCommands[] = ['type' => 'text', 'value' => $str];
|
||
|
}
|
||
|
/**
|
||
|
* Print and feed line / Print and feed n lines
|
||
|
*
|
||
|
* @param int $lines Number of lines to feed
|
||
|
*/
|
||
|
function feed($lines = 1) {
|
||
|
if($lines <= 1) {
|
||
|
//fwrite($this -> fp, self::LF);
|
||
|
$this->str .= self::LF;
|
||
|
$this->txt .= "\r\n";
|
||
|
$this->pdfCommands[] = ['type' => 'text', 'value' => "\r\n"];
|
||
|
} else {
|
||
|
//fwrite($this -> fp, self::ESC . "d" . chr($lines));
|
||
|
$this->str .= self::ESC . "d" . chr($lines);
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* Select print mode(s).
|
||
|
*
|
||
|
* Arguments should be OR'd together MODE_* constants:
|
||
|
* MODE_FONT_A
|
||
|
* MODE_FONT_B
|
||
|
* MODE_EMPHASIZED
|
||
|
* MODE_DOUBLE_HEIGHT
|
||
|
* MODE_DOUBLE_WIDTH
|
||
|
* MODE_UNDERLINE
|
||
|
*
|
||
|
* @param int $mode
|
||
|
*/
|
||
|
function select_print_mode($mode = self::NUL) {
|
||
|
//fwrite($this -> fp, self::ESC . "!" . chr($mode));
|
||
|
$this->str .= self::ESC . "!" . chr($mode);
|
||
|
$this->pdfCommands[] = ['type' => 'print_mode', 'value' => $mode];
|
||
|
}
|
||
|
function reverse_mode($rev = 0) {
|
||
|
//fwrite($this -> fp, self::GS . "B" . chr($rev));
|
||
|
$this->str .= self::GS . "B" . chr($rev);
|
||
|
}
|
||
|
/**
|
||
|
* Turn underline mode on/off
|
||
|
*
|
||
|
* @param int $underline 0 for no underline, 1 for underline, 2 for heavy underline
|
||
|
*/
|
||
|
function set_underline($underline = 1) {
|
||
|
//fwrite($this -> fp, self::ESC . "-". chr($underline));
|
||
|
$this->str .= self::ESC . "-". chr($underline);
|
||
|
$this->pdfCommands[] = ['type' => 'underline', 'value' => $underline];
|
||
|
}
|
||
|
/**
|
||
|
* Initialize printer
|
||
|
*/
|
||
|
function initialize() {
|
||
|
//fwrite($this -> fp, self::ESC . "@");
|
||
|
$this->str .= self::ESC . "@";
|
||
|
}
|
||
|
/**
|
||
|
* Turn emphasized mode on/off
|
||
|
*
|
||
|
* @param boolean $on true for emphasis, false for no emphasis
|
||
|
*/
|
||
|
function set_emphasis($on = false) {
|
||
|
//fwrite($this -> fp, self::ESC . "E". ($on ? chr(1) : chr(0)));
|
||
|
$this->str .= self::ESC . "E". ($on ? chr(1) : chr(0));
|
||
|
}
|
||
|
/**
|
||
|
* Turn double-strike mode on/off
|
||
|
*
|
||
|
* @param boolean $on true for double strike, false for no double strike
|
||
|
*/
|
||
|
function set_double_strike($on = false) {
|
||
|
//fwrite($this -> fp, self::ESC . "G". ($on ? chr(1) : chr(0)));
|
||
|
$this->str .= self::ESC . "G". ($on ? chr(1) : chr(0));
|
||
|
}
|
||
|
/**
|
||
|
* Select character font.
|
||
|
* Font must be FONT_A, FONT_B, or FONT_C.
|
||
|
*
|
||
|
* @param int $font
|
||
|
*/
|
||
|
function set_font($font = self::FONT_A) {
|
||
|
//fwrite($this -> fp, self::ESC . "M" . chr($font));
|
||
|
$this->str .= self::ESC . "M" . chr($font);
|
||
|
$this->pdfCommands[] = ['type' => 'font', 'value' => $font];
|
||
|
}
|
||
|
/**
|
||
|
* Select justification
|
||
|
* Justification must be JUSTIFY_LEFT, JUSTIFY_CENTER, or JUSTIFY_RIGHT.
|
||
|
*/
|
||
|
function set_justification($justification = self::JUSTIFY_LEFT) {
|
||
|
//fwrite($this -> fp, self::ESC . "a" . chr($justification));
|
||
|
$this->str .= self::ESC . "a" . chr($justification);
|
||
|
$this->pdfCommands[] = ['type' => 'justification', 'value' => $justification];
|
||
|
}
|
||
|
/**
|
||
|
* Print and reverse feed n lines
|
||
|
*
|
||
|
* @param int $lines number of lines to feed
|
||
|
*/
|
||
|
function feed_reverse($lines = 1) {
|
||
|
//fwrite($this -> fp, self::ESC . "e" . chr($lines));
|
||
|
$this->str .= self::ESC . "e" . chr($lines);
|
||
|
}
|
||
|
/**
|
||
|
* Cut the paper
|
||
|
*
|
||
|
* @param int $mode Cut mode, either CUT_FULL or CUT_PARTIAL
|
||
|
* @param int $lines Number of lines to feed
|
||
|
*/
|
||
|
function cut($mode = self::CUT_FULL, $lines = 3) {
|
||
|
//fwrite($this -> fp, self::GS . "V" . chr($mode) . chr($lines));
|
||
|
$this->str .= self::GS . "V" . chr($mode) . chr($lines);
|
||
|
}
|
||
|
|
||
|
|
||
|
function qrCode($content, $ec = self::QR_ECLEVEL_L, $size = 3, $model = self::QR_MODEL_2) {
|
||
|
if($content == "") {
|
||
|
return;
|
||
|
}
|
||
|
$cn = '1'; // Code type for QR code
|
||
|
// Select model: 1, 2 or micro.
|
||
|
$this -> wrapperSend2dCodeData(chr(65), $cn, chr(48 + $model) . chr(0));
|
||
|
// Set dot size.
|
||
|
$this -> wrapperSend2dCodeData(chr(67), $cn, chr($size));
|
||
|
// Set error correction level: L, M, Q, or H
|
||
|
$this -> wrapperSend2dCodeData(chr(69), $cn, chr(48 + $ec));
|
||
|
// Send content & print
|
||
|
$this -> wrapperSend2dCodeData(chr(80), $cn, $content, '0');
|
||
|
$this -> wrapperSend2dCodeData(chr(81), $cn, '', '0');
|
||
|
$this->pdfCommands[] = ['type' => 'qr_code', 'value' => $content, 'ec' => $ec, 'size' => $size, 'model' => $model];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Wrapper for GS ( k, to calculate and send correct data length.
|
||
|
*
|
||
|
* @param string $fn Function to use
|
||
|
* @param string $cn Output code type. Affects available data
|
||
|
* @param string $data Data to send.
|
||
|
* @param string $m Modifier/variant for function. Often '0' where used.
|
||
|
* @throws InvalidArgumentException Where the input lengths are bad.
|
||
|
*/
|
||
|
private function wrapperSend2dCodeData($fn, $cn, $data = '', $m = '') {
|
||
|
$header = $this -> intLowHigh(strlen($data) + strlen($m) + 2, 2);
|
||
|
$this->str .= self::GS . "(k" . $header . $cn . $fn . $m . $data;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Generate two characters for a number: In lower and higher parts, or more parts as needed.
|
||
|
* @param int $int Input number
|
||
|
* @param int $length The number of bytes to output (1 - 4).
|
||
|
*/
|
||
|
private static function intLowHigh($input, $length) {
|
||
|
$maxInput = (256 << ($length * 8) - 1);
|
||
|
$outp = "";
|
||
|
for($i = 0; $i < $length; $i++) {
|
||
|
$outp .= chr($input % 256);
|
||
|
$input = (int)($input / 256);
|
||
|
}
|
||
|
return $outp;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Set barcode height
|
||
|
*
|
||
|
* @param int $height Height in dots
|
||
|
*/
|
||
|
function set_barcode_height($height = 8) {
|
||
|
//fwrite($this -> fp, self::GS . "h" . chr($height));
|
||
|
$this->str .= self::GS . "h" . chr($height);
|
||
|
}
|
||
|
/**
|
||
|
* Print a barcode
|
||
|
*
|
||
|
* @param string $content
|
||
|
* @param int $type
|
||
|
*/
|
||
|
function barcode($content, $type = self::BARCODE_CODE39) {
|
||
|
//fwrite($this -> fp, self::GS . "k" . chr($type) . $content . self::NUL);
|
||
|
$this->str .= self::GS . "k" . chr($type) . $content . self::NUL;
|
||
|
}
|
||
|
/**
|
||
|
* This will generate a Barcode and print it directly to the Printer
|
||
|
*
|
||
|
* @param string $content
|
||
|
* @param int $type
|
||
|
* @param int $height
|
||
|
*
|
||
|
*/
|
||
|
function generateBarcode($content, $type, $height)
|
||
|
{
|
||
|
$this->set_barcode_height($height);
|
||
|
$this->barcode($content, $type);
|
||
|
$this->feed();
|
||
|
}
|
||
|
/*
|
||
|
*
|
||
|
* This will increase the font used on the page whilst it is true
|
||
|
* @param bool $on
|
||
|
*
|
||
|
*/
|
||
|
function enlargePrint($on = false)
|
||
|
{
|
||
|
if($on == true)
|
||
|
$this->select_print_mode(self::MODE_DOUBLE_HEIGHT);
|
||
|
else
|
||
|
$this->select_print_mode();
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This will print an empty line
|
||
|
*/
|
||
|
function newline()
|
||
|
{
|
||
|
$this->text("\n");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Generate a pulse, for opening a cash drawer if one is connected.
|
||
|
* The default settings should open an Epson drawer.
|
||
|
*
|
||
|
* @param int $pin 0 or 1, for pin 2 or pin 5 kick-out connector respectively.
|
||
|
* @param int $on_ms pulse ON time, in milliseconds.
|
||
|
* @param int $off_ms pulse OFF time, in milliseconds.
|
||
|
*/
|
||
|
function pulse($pin = 0, $on_ms = 120, $off_ms = 240) {
|
||
|
//fwrite($this -> fp, self::ESC . "p" . chr($m + 48) . chr($t1 / 2) . chr($t2 / 2));
|
||
|
$this->str .= chr(27). chr(112). chr(0). chr(100). chr(250);
|
||
|
//self::ESC . "p" . chr($m + 48) . chr($t1 / 2) . chr($t2 / 2);
|
||
|
}
|
||
|
}
|