1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Posprint\Printers; |
4
|
|
|
|
5
|
|
|
/* |
6
|
|
|
* Default class for POS thermal printers. |
7
|
|
|
* |
8
|
|
|
* From this class all other are extended. |
9
|
|
|
* In the child classes should be included all the commands that are different |
10
|
|
|
* from those in this class, especially those specific to particular brand and |
11
|
|
|
* model of printer |
12
|
|
|
* |
13
|
|
|
* NOTE: It was built around the commands of the Epson TM-T20, |
14
|
|
|
* so in theory the Epson class will be almost empty just extending this class. |
15
|
|
|
* |
16
|
|
|
* CodePage default CP437 |
17
|
|
|
* CountyPage default LATIN |
18
|
|
|
* |
19
|
|
|
* @category NFePHP |
20
|
|
|
* @package Posprint |
21
|
|
|
* @copyright Copyright (c) 2016 |
22
|
|
|
* @license http://www.gnu.org/licenses/lesser.html LGPL v3 |
23
|
|
|
* @author Roberto L. Machado <linux.rlm at gmail dot com> |
24
|
|
|
* @link http://github.com/nfephp-org/posprint for the canonical source repository |
25
|
|
|
*/ |
26
|
|
|
|
27
|
|
|
use Posprint\Printers\PrinterInterface; |
28
|
|
|
use Posprint\Connectors\ConnectorInterface; |
29
|
|
|
use Posprint\Connectors\Buffer; |
30
|
|
|
use Posprint\Graphics\Graphics; |
31
|
|
|
use Posprint\Printers\Barcodes\Barcode1DAnalysis; |
32
|
|
|
use RuntimeException; |
33
|
|
|
use InvalidArgumentException; |
34
|
|
|
|
35
|
|
|
abstract class DefaultPrinter implements PrinterInterface |
36
|
|
|
{ |
37
|
|
|
//set standards |
38
|
|
|
const NUL = "\x0"; //Nulo |
39
|
|
|
const EOT = "\x4"; //EOT fim da transmissão |
40
|
|
|
const ENQ = "\x5"; //ENQ colocar na fila Pedido de status 1 |
41
|
|
|
const HT = "\x9"; //tabulação horizontal |
42
|
|
|
const VT = "\xb"; //tabulação vertical |
43
|
|
|
const LF = "\x0a"; //Inicia a impressão e avança uma linha |
44
|
|
|
const FF = "\x0c"; //avança pagina |
45
|
|
|
const CR = "\x0d"; //retorno de carro |
46
|
|
|
const DLE = "\x10"; //Data Link Escape |
47
|
|
|
const CAN = "\x18"; //CAN Cancela linha enviada |
48
|
|
|
const BEL = "\x07"; //BEL sinal sonoro |
49
|
|
|
const ESC = "\x1b"; //escape |
50
|
|
|
const FS = "\x1c"; //FS |
51
|
|
|
const GS = "\x1d"; //GS |
52
|
|
|
const SO = "\x0e"; //SO Inicia modo expandido |
53
|
|
|
const DC1 = "\x11"; //DC1 Inicia modo enfatizado |
54
|
|
|
const DC2 = "\x12"; //DC2 Cancela modo condensado |
55
|
|
|
const DC3 = "\x13"; //DC3 Cancela modo enfatizado |
56
|
|
|
const DC4 = "\x14"; //DC4 Controle de dispositivo 4 Inicia modo normal |
57
|
|
|
const SI = "\x0f"; //Seleciona modo condensado |
58
|
|
|
const EM = "\x19"; //Avança 4 linhas |
59
|
|
|
const DEL = "\x7f"; //Cancela último caracter |
60
|
|
|
const NAK = "\x15"; // |
61
|
|
|
const SYN = "\x16"; //Sincronismo |
62
|
|
|
const NOTRANS = false; //not translate characters codepage |
63
|
|
|
const TRANS = true; //perform a character convertion to codepage |
64
|
|
|
const ACK = '\x06'; //Acknowledge |
65
|
|
|
//Cut types |
66
|
|
|
const CUT_FULL = 65; |
67
|
|
|
const CUT_PARTIAL = 66; |
68
|
|
|
//Image sizing options |
69
|
|
|
const IMG_DEFAULT = 0; |
70
|
|
|
const IMG_DOUBLE_WIDTH = 1; |
71
|
|
|
const IMG_DOUBLE_HEIGHT = 2; |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* List all available region pages. |
75
|
|
|
* |
76
|
|
|
* @var array |
77
|
|
|
*/ |
78
|
|
|
protected $aRegion = array( |
79
|
|
|
'USA', |
80
|
|
|
'FRANCE', |
81
|
|
|
'GERMANY', |
82
|
|
|
'UK', |
83
|
|
|
'DENMARK', |
84
|
|
|
'SWEDEN', |
85
|
|
|
'ITALY', |
86
|
|
|
'SPAIN', |
87
|
|
|
'JAPAN', |
88
|
|
|
'NORWAY', |
89
|
|
|
'DENMARK2', |
90
|
|
|
'SPAIN2', |
91
|
|
|
'LATIN', |
92
|
|
|
'KOREA', |
93
|
|
|
'SLOVENIA', |
94
|
|
|
'CHINA', |
95
|
|
|
'VIETNAM', |
96
|
|
|
'ARABIA' |
97
|
|
|
); |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* List all available code pages. |
101
|
|
|
* |
102
|
|
|
* @var array |
103
|
|
|
*/ |
104
|
|
|
protected $aCodePage = array( |
105
|
|
|
'CP437' => array('conv' => '437', 'table' => '0', 'desc' => 'PC437: USA, Standard Europe'), |
106
|
|
|
'CP850' => array('conv' => '850', 'table' => '2', 'desc' => 'PC850: Multilingual'), |
107
|
|
|
'CP860' => array('conv' => '860', 'table' => '3', 'desc' => 'PC860: Portuguese'), |
108
|
|
|
'CP863' => array('conv' => '863', 'table' => '4', 'desc' => 'PC863: Canadian-French'), |
109
|
|
|
'CP865' => array('conv' => '865', 'table' => '5', 'desc' => 'PC865: Nordic'), |
110
|
|
|
'CP851' => array('conv' => '851', 'table' => '11', 'desc' => 'PC851: Greek'), |
111
|
|
|
'CP853' => array('conv' => '853', 'table' => '12', 'desc' => 'PC853: Turkish'), |
112
|
|
|
'CP857' => array('conv' => '857', 'table' => '13', 'desc' => 'PC857: Turkish'), |
113
|
|
|
'CP737' => array('conv' => '737', 'table' => '14', 'desc' => 'PC737: Greek'), |
114
|
|
|
'ISO8859-7' => array('conv' => 'ISO8859-7', 'table' => '15', 'desc' => 'ISO8859-7: Greek'), |
115
|
|
|
'CP866' => array('conv' => '866', 'table' => '17', 'desc' => 'PC866: Cyrillic #2'), |
116
|
|
|
'CP852' => array('conv' => '852', 'table' => '18', 'desc' => 'PC852: Latin2'), |
117
|
|
|
'CP858' => array('conv' => '858', 'table' => '19', 'desc' => 'PC858: Euro'), |
118
|
|
|
'CP720' => array('conv' => '720', 'table' => '32', 'desc' => 'PC720: Arabic'), |
119
|
|
|
'CP855' => array('conv' => '855', 'table' => '34', 'desc' => 'PC855: Cyrillic'), |
120
|
|
|
'CP861' => array('conv' => '861', 'table' => '35', 'desc' => 'PC861: Icelandic'), |
121
|
|
|
'CP862' => array('conv' => '862', 'table' => '36', 'desc' => 'PC862: Hebrew'), |
122
|
|
|
'CP864' => array('conv' => '864', 'table' => '37', 'desc' => 'PC864: Arabic'), |
123
|
|
|
'CP869' => array('conv' => '869', 'table' => '38', 'desc' => 'PC869: Greek'), |
124
|
|
|
'ISO8859-2' => array('conv' => 'ISO8859-2', 'table' => '39', 'desc' => 'ISO8859-2: Latin2'), |
125
|
|
|
'ISO8859-15' => array('conv' => 'ISO8859-15', 'table' => '40', 'desc' => 'ISO8859-15: Latin9'), |
126
|
|
|
'WINDOWS-1250' => array('conv' => 'WINDOWS-1250', 'table' => '45', 'desc' => 'WPC1250: Latin2'), |
127
|
|
|
'WINDOWS-1251' => array('conv' => 'WINDOWS-1251', 'table' => '46', 'desc' => 'WPC1251: Cyrillic'), |
128
|
|
|
'WINDOWS-1252' => array('conv' => 'WINDOWS-1252', 'table' => '47', 'desc' => 'WPC1253: Greek'), |
129
|
|
|
'WINDOWS-1254' => array('conv' => 'WINDOWS-1254', 'table' => '48', 'desc' => 'WPC1254: Turkish'), |
130
|
|
|
'WINDOWS-1255' => array('conv' => 'WINDOWS-1255', 'table' => '49', 'desc' => 'WPC1255: Hebrew'), |
131
|
|
|
'WINDOWS-1256' => array('conv' => 'WINDOWS-1256', 'table' => '50', 'desc' => 'WPC1256: Arabic'), |
132
|
|
|
'WINDOWS-1257' => array('conv' => 'WINDOWS-1257', 'table' => '51', 'desc' => 'WPC1257: Baltic Rim'), |
133
|
|
|
'WINDOWS-1258' => array('conv' => 'WINDOWS-1258', 'table' => '52', 'desc' => 'WPC1258: Vietnamese'), |
134
|
|
|
); |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Seleted code page |
138
|
|
|
* Defined in printer class. |
139
|
|
|
* @var string |
140
|
|
|
*/ |
141
|
|
|
protected $codepage = 'CP437'; |
142
|
|
|
/** |
143
|
|
|
* Number of codpage in printer memory. |
144
|
|
|
* @var int |
145
|
|
|
*/ |
146
|
|
|
protected $charsetTableNum = 0; |
147
|
|
|
/** |
148
|
|
|
* Selected Region character page |
149
|
|
|
* Defined in printer class. |
150
|
|
|
* @var string |
151
|
|
|
*/ |
152
|
|
|
protected $region = 'LATIN'; |
153
|
|
|
/** |
154
|
|
|
* List all avaiable fonts |
155
|
|
|
* @var array |
156
|
|
|
*/ |
157
|
|
|
protected $aFont = array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D', 4 => 'E', 97 => 'SA', 98 => 'SB'); |
158
|
|
|
/** |
159
|
|
|
* Selected internal font. |
160
|
|
|
* @var string |
161
|
|
|
*/ |
162
|
|
|
protected $font = 'A'; |
163
|
|
|
/** |
164
|
|
|
* Resolution in dpi. |
165
|
|
|
* @var int |
166
|
|
|
*/ |
167
|
|
|
public $dpi = 203; //dots per inch |
168
|
|
|
/** |
169
|
|
|
* Resolution in dpmm. |
170
|
|
|
* @var int |
171
|
|
|
*/ |
172
|
|
|
public $dpmm = 8; //dots per mm |
173
|
|
|
/** |
174
|
|
|
* Maximum width paper. |
175
|
|
|
* @var int |
176
|
|
|
*/ |
177
|
|
|
public $widthMaxmm = 80;//mm |
178
|
|
|
/** |
179
|
|
|
* Selected Width paper. |
180
|
|
|
* @var int |
181
|
|
|
*/ |
182
|
|
|
public $widthPaper = 80;//mm |
183
|
|
|
/** |
184
|
|
|
* Maximum width for printed area. |
185
|
|
|
* @var int |
186
|
|
|
*/ |
187
|
|
|
public $widthPrint = 72;//mm |
188
|
|
|
/** |
189
|
|
|
* Maximum width for printed area in dots. |
190
|
|
|
* @var int |
191
|
|
|
*/ |
192
|
|
|
public $widthMaxdots = 576;//dots |
193
|
|
|
/** |
194
|
|
|
* Maximum number of characters per line. |
195
|
|
|
* @var int |
196
|
|
|
*/ |
197
|
|
|
public $maxchars = 48;//max characters per line |
198
|
|
|
|
199
|
|
|
//protected property standards |
200
|
|
|
/** |
201
|
|
|
* Connector to printer. |
202
|
|
|
* @var ConnectorInterface|null |
203
|
|
|
*/ |
204
|
|
|
protected $connector = null; |
205
|
|
|
/** |
206
|
|
|
* Seleted printer mode. |
207
|
|
|
* @var string |
208
|
|
|
*/ |
209
|
|
|
protected $printerMode = 'normal'; |
210
|
|
|
/** |
211
|
|
|
* Selected bold mode. |
212
|
|
|
* @var bool |
213
|
|
|
*/ |
214
|
|
|
protected $boldMode = false; |
215
|
|
|
/** |
216
|
|
|
* Selected italic mode. |
217
|
|
|
* @var bool |
218
|
|
|
*/ |
219
|
|
|
protected $italicMode = false; |
220
|
|
|
/** |
221
|
|
|
* Selected condenced mode. |
222
|
|
|
* @var bool |
223
|
|
|
*/ |
224
|
|
|
protected $condensedMode = false; |
225
|
|
|
/** |
226
|
|
|
* Selected expanded mode. |
227
|
|
|
* @var bool |
228
|
|
|
*/ |
229
|
|
|
protected $expandedMode = false; |
230
|
|
|
/** |
231
|
|
|
* Seleted double higth mode. |
232
|
|
|
* @var bool |
233
|
|
|
*/ |
234
|
|
|
protected $doubleHeigth = false; |
235
|
|
|
/** |
236
|
|
|
* Selected reverse colors mode. |
237
|
|
|
* @var bool |
238
|
|
|
*/ |
239
|
|
|
protected $reverseColors = false; |
240
|
|
|
/** |
241
|
|
|
* Selected under lined mode. |
242
|
|
|
* @var bool |
243
|
|
|
*/ |
244
|
|
|
protected $underlineMode = false; |
245
|
|
|
/** |
246
|
|
|
* Selected rotate 90 degrees mode |
247
|
|
|
* @var bool |
248
|
|
|
*/ |
249
|
|
|
protected $rotateMode = false; |
250
|
|
|
/** |
251
|
|
|
* Buffer class. |
252
|
|
|
* @var Buffer |
253
|
|
|
*/ |
254
|
|
|
protected $buffer = null; |
255
|
|
|
/** |
256
|
|
|
* Acceptable barcodes list |
257
|
|
|
* @var array |
258
|
|
|
*/ |
259
|
|
|
protected $barcode1Dlist = [ |
260
|
|
|
'UPC_A' => 65, |
261
|
|
|
'UPC_E' => 66, |
262
|
|
|
'EAN13' => 67, |
263
|
|
|
'EAN8' => 68, |
264
|
|
|
'CODE39' => 69, |
265
|
|
|
'I25' => 70, |
266
|
|
|
'CODABAR' => 71, |
267
|
|
|
'CODE93' => 72, |
268
|
|
|
'CODE128' => 73, |
269
|
|
|
'GS1128' => 74, |
270
|
|
|
'GS1DATABAROMINI' => 75, |
271
|
|
|
'GS1DATABARTRUNC' => 76, |
272
|
|
|
'GS1DATABARLIMIT' => 77, |
273
|
|
|
'GS1DATABAREXPAN' => 78 |
274
|
|
|
]; |
275
|
|
|
/** |
276
|
|
|
* List of supported models |
277
|
|
|
* @var array |
278
|
|
|
*/ |
279
|
|
|
protected $modelList = [ |
280
|
|
|
'T20' |
281
|
|
|
]; |
282
|
|
|
/** |
283
|
|
|
* Selected model |
284
|
|
|
* @var string |
285
|
|
|
*/ |
286
|
|
|
protected $printerModel = 'T20'; |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* Class constructor |
290
|
|
|
* Instantiates the data buffer. |
291
|
|
|
* |
292
|
|
|
* @param ConnectorInterface $conn |
293
|
|
|
*/ |
294
|
|
|
public function __construct(ConnectorInterface $conn = null) |
295
|
|
|
{ |
296
|
|
|
if (!is_null($conn)) { |
297
|
|
|
$this->connector = $conn; |
298
|
|
|
} |
299
|
|
|
$this->buffer = new Buffer(); |
300
|
|
|
} |
301
|
|
|
|
302
|
|
|
/** |
303
|
|
|
* Return default printer model |
304
|
|
|
* @param string $model |
305
|
|
|
* @return string|array |
306
|
|
|
*/ |
307
|
|
|
public function defaultModel($model = null) |
308
|
|
|
{ |
309
|
|
|
if (!is_null($model)) { |
310
|
|
|
$model = strtoupper(trim($model)); |
311
|
|
|
if ($model == 'ALL') { |
312
|
|
|
return $this->modelList; |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
if (array_key_exists($model, $this->modelList)) { |
316
|
27 |
|
$this->printerModel = $model; |
317
|
|
|
} |
318
|
27 |
|
return $model; |
319
|
|
|
} |
320
|
|
|
|
321
|
27 |
|
/** |
322
|
27 |
|
* Returns a default region for codepage |
323
|
|
|
* if param $region is null will return actual default region from class |
324
|
|
|
* if param $region is 'all' will return a array with all avaiable regions |
325
|
|
|
* if param $region is a string will set the region parameter of class and returns it. |
326
|
|
|
* NOTE: This command do not set the printer, only class parameters |
327
|
|
|
* |
328
|
|
|
* @param string $region |
329
|
20 |
|
* @return string|array |
330
|
|
|
*/ |
331
|
20 |
|
public function defaultRegionPage($region = null) |
332
|
20 |
|
{ |
333
|
20 |
|
if (!is_null($region)) { |
334
|
|
|
$region = strtoupper(trim($region)); |
335
|
|
|
if ($region == 'ALL') { |
336
|
20 |
|
return $this->aRegion; |
337
|
20 |
|
} |
338
|
|
|
$reg = array_search($region, $this->aRegion, true); |
339
|
|
|
if ($reg !== false) { |
340
|
20 |
|
$this->region = $region; |
341
|
|
|
} |
342
|
|
|
} |
343
|
|
|
return $this->region; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* Returns a default codepage |
348
|
|
|
* if param $codepage is null will return actual default codepage from class |
349
|
|
|
* if param $codepage is 'all' will return a array with all avaiable codepages |
350
|
|
|
* if param $codepage is a string will set the codepage parameter of class and returns it. |
351
|
|
|
* NOTE: This command do not set the printer, only class parameters |
352
|
|
|
* |
353
|
21 |
|
* @param string $codepage |
354
|
|
|
* @return string|array |
355
|
21 |
|
*/ |
356
|
2 |
|
public function defaultCodePage($codepage = null) |
357
|
2 |
|
{ |
358
|
1 |
|
if (!is_null($codepage)) { |
359
|
|
|
$codepage = strtoupper(trim($codepage)); |
360
|
2 |
|
if ($codepage == 'ALL') { |
361
|
2 |
|
return array_keys($this->aCodePage); |
362
|
2 |
|
} |
363
|
2 |
|
if (array_key_exists($codepage, $this->aCodePage)) { |
364
|
2 |
|
$this->codepage = $codepage; |
365
|
21 |
|
$table = $this->aCodePage[$codepage]; |
366
|
|
|
$this->charsetTableNum = $table['table']; |
367
|
|
|
} |
368
|
|
|
} |
369
|
|
|
return $this->codepage; |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
/** |
373
|
|
|
* Returns the default printer font |
374
|
|
|
* A - Font A (12 x 24) |
375
|
|
|
* B - Font B (9 x 17) |
376
|
|
|
* C - Font C |
377
|
|
|
* D - Font D |
378
|
21 |
|
* E - Font E |
379
|
|
|
* Special A |
380
|
21 |
|
* Special B |
381
|
3 |
|
* Default Font A. |
382
|
3 |
|
* if param $font is null will return actual default font from class |
383
|
1 |
|
* if param $font is 'all' will return a array with all avaiable printer fonts |
384
|
|
|
* if param $font is a string will set the font parameter of class and returns it. |
385
|
3 |
|
* NOTE: This command do not set the printer, only class parameters |
386
|
3 |
|
* |
387
|
3 |
|
* @param string $font |
388
|
3 |
|
* @return array|string |
389
|
3 |
|
*/ |
390
|
3 |
|
public function defaultFont($font = null) |
391
|
21 |
|
{ |
392
|
|
|
if (!is_null($font)) { |
393
|
|
|
$font = strtoupper(trim($font)); |
394
|
|
|
if ($font == 'ALL') { |
395
|
|
|
//return array |
396
|
|
|
return $this->aFont; |
397
|
|
|
} |
398
|
|
|
//set $this->font |
399
|
|
|
$fonts = array_flip($this->aFont); |
400
|
|
|
$keys = array_keys($fonts); |
401
|
|
|
$reg = array_search($font, $keys, true); |
402
|
|
|
if ($reg !== false) { |
403
|
|
|
$this->font = $font; |
404
|
|
|
} |
405
|
|
|
} |
406
|
|
|
return $this->font; |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
/** |
410
|
|
|
* initialize printer |
411
|
|
|
* Clears the data in the print buffer and resets the printer modes to |
412
|
22 |
|
* the modes that were in effect when the power was turned on. |
413
|
|
|
*/ |
414
|
22 |
|
public function initialize() |
415
|
3 |
|
{ |
416
|
3 |
|
$this->rotateMode = false; |
417
|
|
|
$this->boldMode = false; |
418
|
1 |
|
$this->italicMode = false; |
419
|
|
|
$this->underlineMode = false; |
420
|
|
|
$this->printerMode = 'normal'; |
421
|
2 |
|
$this->defaultModel(); |
422
|
2 |
|
$this->defaultCodePage(); |
423
|
2 |
|
$this->defaultRegionPage(); |
424
|
2 |
|
$this->defaultFont(); |
425
|
2 |
|
$this->buffer->write(self::ESC.'@'); |
426
|
2 |
|
$this->setPrintMode(); |
427
|
2 |
|
$this->setFont(); |
428
|
21 |
|
$this->setCodePage(); |
429
|
|
|
$this->setRegionPage(); |
430
|
|
|
} |
431
|
|
|
|
432
|
|
|
/** |
433
|
|
|
* Set the printer mode. |
434
|
|
|
*/ |
435
|
|
|
abstract public function setPrintMode($mode = null); |
436
|
21 |
|
|
437
|
|
|
/** |
438
|
21 |
|
* Set a codepage table in printer. |
439
|
21 |
|
* |
440
|
21 |
|
* @param string $codepage |
441
|
21 |
|
*/ |
442
|
21 |
|
public function setCodePage($codepage = null) |
443
|
21 |
|
{ |
444
|
21 |
|
$codepage = $this->defaultCodePage($codepage); |
|
|
|
|
445
|
21 |
|
$this->buffer->write(self::ESC.'t'.chr($this->charsetTableNum)); |
446
|
21 |
|
} |
447
|
21 |
|
|
448
|
21 |
|
/** |
449
|
21 |
|
* Set a region page. |
450
|
21 |
|
* The numeric key of array $this->aRegion is the command parameter. |
451
|
21 |
|
* |
452
|
21 |
|
* @param string $region |
453
|
|
|
*/ |
454
|
|
|
public function setRegionPage($region = null) |
455
|
|
|
{ |
456
|
|
|
$region = $this->defaultRegionPage($region); |
457
|
|
|
$mode = array_keys($this->aRegion, $region, true); |
458
|
|
|
$this->buffer->write(self::ESC.'R'.chr($mode[0])); |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
/** |
462
|
|
|
* Set a printer font |
463
|
|
|
* If send a valid font name will set the printer otherelse a default font is selected |
464
|
20 |
|
* |
465
|
|
|
* @param string $font |
466
|
20 |
|
*/ |
467
|
20 |
|
public function setFont($font = null) |
468
|
20 |
|
{ |
469
|
|
|
$font = $this->defaultFont($font); |
470
|
|
|
$mode = array_keys($this->aFont, $font, true); |
471
|
|
|
$this->buffer->write(self::ESC.'M'.chr($mode[0])); |
472
|
|
|
} |
473
|
|
|
|
474
|
|
|
/** |
475
|
|
|
* Set emphasys mode on or off. |
476
|
20 |
|
*/ |
477
|
|
|
public function setBold() |
478
|
20 |
|
{ |
479
|
20 |
|
$mode = 1; |
480
|
20 |
|
if ($this->boldMode) { |
481
|
20 |
|
$mode = 0; |
482
|
|
|
} |
483
|
|
|
$this->boldMode = ! $this->boldMode; |
484
|
|
|
$this->buffer->write(self::ESC . 'E' . chr($mode)); |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
/** |
488
|
|
|
* Set underline mode on or off. |
489
|
20 |
|
*/ |
490
|
|
|
public function setUnderlined() |
491
|
20 |
|
{ |
492
|
20 |
|
$mode = 1; |
493
|
20 |
|
if ($this->underlineMode) { |
494
|
20 |
|
$mode = 0; |
495
|
|
|
} |
496
|
|
|
$this->underlineMode = ! $this->underlineMode; |
497
|
|
|
$this->buffer->write(self::ESC . '-' . chr($mode)); |
498
|
|
|
} |
499
|
1 |
|
|
500
|
|
|
/** |
501
|
1 |
|
* Set italic mode on or off |
502
|
1 |
|
* |
503
|
1 |
|
* @return bool |
504
|
1 |
|
*/ |
505
|
1 |
|
public function setItalic() |
506
|
1 |
|
{ |
507
|
1 |
|
//dont exists in this printer |
508
|
|
|
} |
509
|
|
|
|
510
|
|
|
/** |
511
|
|
|
* Aligns all data in one line to the selected layout in standard mode. |
512
|
1 |
|
* L - left C - center R - rigth |
513
|
|
|
* |
514
|
1 |
|
* @param string $align |
515
|
1 |
|
*/ |
516
|
1 |
|
public function setAlign($align = null) |
517
|
1 |
|
{ |
518
|
1 |
|
if (is_null($align)) { |
519
|
1 |
|
$align = 'L'; |
520
|
1 |
|
} |
521
|
|
|
$value = strtoupper($align); |
522
|
|
|
switch ($value) { |
523
|
|
|
case 'C': |
524
|
|
|
$mode = 1; |
525
|
|
|
break; |
526
|
|
|
case 'R': |
527
|
|
|
$mode = 2; |
528
|
|
|
break; |
529
|
|
|
default: |
530
|
|
|
$mode = 0; |
531
|
|
|
} |
532
|
|
|
$this->buffer->write(self::ESC . 'a' . chr($mode)); |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
/** |
536
|
|
|
* Turns white/black reverse print On or Off for characters. |
537
|
|
|
* n = odd: On, n = even: Off. |
538
|
1 |
|
*/ |
539
|
|
|
public function setReverseColors() |
540
|
1 |
|
{ |
541
|
|
|
$mode = 0; |
542
|
|
|
$this->reverseColors = ! $this->reverseColors; |
543
|
1 |
|
if ($this->reverseColors) { |
544
|
|
|
$mode = 1; |
545
|
1 |
|
} |
546
|
1 |
|
$this->buffer->write(self::GS.'B'.chr($mode)); |
547
|
1 |
|
} |
548
|
1 |
|
|
549
|
|
|
/** |
550
|
|
|
* Set expanded mode. |
551
|
1 |
|
* @param int $size multiplies normal size 1 - 8 |
552
|
1 |
|
*/ |
553
|
1 |
|
public function setExpanded($size = null) |
554
|
1 |
|
{ |
555
|
1 |
|
$size = self::validateInteger($size, 1, 8, 1); |
556
|
|
|
$aSize = [ |
557
|
|
|
[0, 0], |
558
|
|
|
[16, 1], |
559
|
|
|
[32, 2], |
560
|
|
|
[48, 3], |
561
|
1 |
|
[64, 4], |
562
|
|
|
[80, 5], |
563
|
1 |
|
[96, 6], |
564
|
1 |
|
[112, 7] |
565
|
1 |
|
]; |
566
|
1 |
|
$mode = $aSize[$size-1][0] + $aSize[$size-1][1]; |
567
|
1 |
|
$this->buffer->write(self::ESC.'!'.chr($mode)); |
568
|
1 |
|
} |
569
|
1 |
|
|
570
|
|
|
/** |
571
|
|
|
* Set condensed mode. |
572
|
|
|
* @return void |
573
|
|
|
*/ |
574
|
|
|
public function setCondensed() |
575
|
|
|
{ |
576
|
1 |
|
$this->setExpanded(1); |
577
|
|
|
$this->setFont('B'); |
578
|
1 |
|
} |
579
|
|
|
|
580
|
1 |
|
/** |
581
|
1 |
|
* Set rotate 90 degrees. |
582
|
1 |
|
* @return void |
583
|
1 |
|
*/ |
584
|
1 |
|
public function setRotate90() |
585
|
1 |
|
{ |
586
|
1 |
|
$this->rotateMode = !$this->rotateMode; |
587
|
1 |
|
$mode = 0; |
588
|
1 |
|
if ($this->rotateMode) { |
589
|
1 |
|
$mode = 1; |
590
|
1 |
|
} |
591
|
1 |
|
$this->buffer->write(self::ESC.'V'.chr($mode)); |
592
|
|
|
} |
593
|
|
|
|
594
|
|
|
/** |
595
|
|
|
* Send message or command to buffer |
596
|
|
|
* when sending commands is not required to convert characters, |
597
|
|
|
* so the variable may translate by false. |
598
|
|
|
* @param string $text |
599
|
|
|
*/ |
600
|
|
|
public function text($text = '') |
601
|
|
|
{ |
602
|
|
|
$text = $this->translate($text); |
603
|
|
|
$this->buffer->write($text); |
604
|
|
|
} |
605
|
1 |
|
|
606
|
|
|
/** |
607
|
1 |
|
* Set horizontal and vertical motion units |
608
|
1 |
|
* $horizontal => character spacing 1/x" |
609
|
1 |
|
* $vertical => line spacing 1/y". |
610
|
1 |
|
* @param int $horizontal |
611
|
1 |
|
* @param int $vertical |
612
|
1 |
|
*/ |
613
|
1 |
|
public function setSpacing($horizontal = 30, $vertical = 30) |
614
|
|
|
{ |
615
|
|
|
$horizontal = self::validateInteger($horizontal, 0, 255, 30); |
616
|
|
|
$vertical = self::validateInteger($vertical, 0, 255, 30); |
617
|
|
|
$this->buffer->write(self::GS.'P'.chr($horizontal).chr($vertical)); |
618
|
|
|
} |
619
|
|
|
|
620
|
|
|
/** |
621
|
|
|
* Set right-side character spacing |
622
|
1 |
|
* 0 ≤ n ≤ 255 => 1/x". |
623
|
|
|
* @param int $value |
624
|
1 |
|
*/ |
625
|
1 |
|
public function setCharSpacing($value = 3) |
626
|
1 |
|
{ |
627
|
|
|
$value = self::validateInteger($value, 0, 255, 0); |
628
|
|
|
$this->buffer->write(self::ESC.' '.chr($value)); |
629
|
|
|
} |
630
|
|
|
|
631
|
|
|
/** |
632
|
|
|
* Line spacing |
633
|
|
|
* The default is set to zero and 30/180 " |
634
|
|
|
* any different number of zero will generate multiples of. |
635
|
|
|
* n 1/180-inch vertical motion |
636
|
1 |
|
* normal paragraph 30/180" => 4.23 mm |
637
|
|
|
* @param int $value |
638
|
1 |
|
*/ |
639
|
1 |
|
public function setParagraph($value = 0) |
640
|
1 |
|
{ |
641
|
1 |
|
$value = self::validateInteger($value, 0, 255, 0); |
642
|
|
|
$paragraph = ceil($value); |
643
|
|
|
if ($paragraph == 0) { |
644
|
|
|
$this->buffer->write(self::ESC.'2'); |
645
|
|
|
return; |
646
|
|
|
} |
647
|
|
|
if ($paragraph < 25) { |
648
|
|
|
$paragraph = 25; |
649
|
1 |
|
} elseif ($paragraph > 255) { |
650
|
|
|
$paragraph = 255; |
651
|
1 |
|
} |
652
|
1 |
|
$this->buffer->write(self::ESC.'3'.chr($paragraph)); |
653
|
1 |
|
} |
654
|
|
|
|
655
|
|
|
/** |
656
|
|
|
* Prints data and feeds paper n lines |
657
|
|
|
* ESC d n Prints data and feeds paper n lines. |
658
|
|
|
* @param int|null $lines |
659
|
|
|
*/ |
660
|
|
|
public function lineFeed($lines = 1) |
661
|
|
|
{ |
662
|
|
|
$lines = self::validateInteger($lines, 0, 255, 1); |
663
|
|
|
if ($lines == 1) { |
664
|
1 |
|
$this->buffer->write(self::LF); |
665
|
|
|
return; |
666
|
1 |
|
} |
667
|
1 |
|
$this->buffer->write(self::ESC.'d'.chr($lines)); |
668
|
1 |
|
} |
669
|
1 |
|
|
670
|
1 |
|
/** |
671
|
|
|
* Prints data and feeds paper n dots |
672
|
1 |
|
* ESC J n Prints data and feeds paper n dots. |
673
|
|
|
* @param int $dots |
674
|
1 |
|
*/ |
675
|
|
|
public function dotFeed($dots = 1) |
676
|
|
|
{ |
677
|
1 |
|
$dots = self::validateInteger($dots, 0, 80, 0); |
678
|
1 |
|
$this->buffer->write(self::ESC.'J'.chr($dots)); |
679
|
|
|
} |
680
|
|
|
|
681
|
|
|
/** |
682
|
|
|
* Generate a pulse, for opening a cash drawer if one is connected. |
683
|
|
|
* The default settings should open an Epson drawer. |
684
|
|
|
* @param int $pin 0 or 1, for pin 2 or pin 5 kick-out connector respectively. |
685
|
|
|
* @param int $on_ms pulse ON time, in milliseconds. |
686
|
1 |
|
* @param int $off_ms pulse OFF time, in milliseconds. |
687
|
|
|
*/ |
688
|
1 |
|
public function pulse($pin = 0, $on_ms = 120, $off_ms = 240) |
689
|
1 |
|
{ |
690
|
1 |
|
$pin = self::validateInteger($pin, 0, 1, 0); |
691
|
1 |
|
$on_ms = self::validateInteger($on_ms, 1, 511, 120); |
692
|
|
|
$off_ms = self::validateInteger($off_ms, 1, 511, 240); |
693
|
1 |
|
$this->buffer->write(self::ESC.'p'.chr($pin + 48).chr($on_ms / 2).chr($off_ms / 2)); |
694
|
1 |
|
} |
695
|
|
|
|
696
|
|
|
/** |
697
|
|
|
* Cut the paper. |
698
|
|
|
* @param int $mode FULL or PARTIAL. If not specified, FULL will be used. |
699
|
|
|
* @param int $lines Number of lines to feed after cut |
700
|
|
|
*/ |
701
|
|
|
public function cut($mode = 'PARTIAL', $lines = 3) |
702
|
1 |
|
{ |
703
|
|
|
$lines = self::validateInteger($lines, 1, 10, 3); |
704
|
1 |
|
if ($mode == 'FULL') { |
705
|
1 |
|
$mode = self::CUT_FULL; |
706
|
1 |
|
} else { |
707
|
|
|
$mode = self::CUT_PARTIAL; |
708
|
|
|
} |
709
|
|
|
$this->buffer->write(self::GS.'V'.chr($mode).chr($lines)); |
710
|
|
|
} |
711
|
|
|
|
712
|
|
|
/** |
713
|
|
|
* Implements barcodes 1D |
714
|
|
|
* GS k m n d1...dn |
715
|
|
|
* Prints bar code. n specifies the data length. |
716
|
1 |
|
* m bar code system number of d (=k) |
717
|
|
|
* "A" UPC-A 11 or 12 |
718
|
1 |
|
* "B" UPC-E 6, 7, 8, 11 or 12 |
719
|
1 |
|
* "C" JAN13 / EAN13 12 or 13 |
720
|
1 |
|
* "D" JAN8 / EAN8 7 or 8 |
721
|
1 |
|
* "E" CODE39 1 or more |
722
|
1 |
|
* "F" ITF even |
723
|
|
|
* "G" CODABAR (NW-7) 2 or more |
724
|
|
|
* "H" CODE93 1–255 |
725
|
|
|
* "I" CODE128 2–255 |
726
|
|
|
* "J" GS1-128 2–255 |
727
|
|
|
* "K" GS1 DataBar Omnidirectional 13 |
728
|
|
|
* "L" GS1 DataBar Truncated 13 |
729
|
|
|
* "M" GS1 DataBar Limited 13 |
730
|
1 |
|
* "N" GS1 DataBar Expanded 2–255. |
731
|
|
|
* |
732
|
1 |
|
* GS h n Sets bar code height to n dots. |
733
|
1 |
|
* GS w n Sets bar width of bar code. n = 2–6 (thin–thick) |
734
|
1 |
|
* GS H n Selects print position of HRI characters. |
735
|
1 |
|
* n = 0, "0": Not printed |
736
|
1 |
|
* n = 1, "1": Above the bar code |
737
|
|
|
* n = 2, "2": Below the bar code |
738
|
1 |
|
* n = 3, "3": Both above and below the bar code |
739
|
1 |
|
* GS f n Selects font for the HRI characters. |
740
|
|
|
* n = 0, "0": Font A, |
741
|
|
|
* n = 1, "1": Font B |
742
|
|
|
* |
743
|
|
|
* @param string $data |
744
|
|
|
* @param string $type Default CODE128 |
745
|
|
|
* @param int $height |
746
|
|
|
* @param int $lineWidth |
747
|
|
|
* @param string $txtPosition |
748
|
|
|
* @param string $txtFont |
749
|
|
|
*/ |
750
|
|
|
public function barcode( |
751
|
|
|
$data = '123456', |
752
|
|
|
$type = 'CODE128', |
753
|
|
|
$height = 162, |
754
|
|
|
$lineWidth = 2, |
755
|
|
|
$txtPosition = 'none', |
756
|
|
|
$txtFont = '' |
757
|
|
|
) { |
758
|
|
|
switch ($txtPosition) { |
759
|
|
|
case 'Above': |
760
|
|
|
$tPos = 1; |
761
|
|
|
break; |
762
|
|
|
case 'Below': |
763
|
|
|
$tPos = 2; |
764
|
|
|
break; |
765
|
|
|
case 'Both': |
766
|
|
|
$tPos = 3; |
767
|
|
|
break; |
768
|
|
|
default: |
769
|
|
|
//none |
770
|
|
|
$tPos = 0; |
771
|
|
|
} |
772
|
|
|
$font = 0; |
773
|
|
|
if ($txtFont === 'B') { |
774
|
|
|
$font = 1; |
775
|
|
|
} |
776
|
|
|
if (! $data = Barcodes\Barcode1DAnalysis::validate($data, $type)) { |
777
|
|
|
throw new \InvalidArgumentException('Data or barcode type is incorrect.'); |
778
|
|
|
} |
779
|
1 |
|
if (! array_key_exists($type, $this->barcode1Dlist)) { |
780
|
|
|
throw new \InvalidArgumentException('This barcode type is not listed.'); |
781
|
|
|
} |
782
|
|
|
$id = $this->barcode1Dlist[$type]; |
783
|
|
|
if (is_null($id)) { |
784
|
|
|
return; |
785
|
|
|
} |
786
|
|
|
$height = self::validateInteger($height, 1, 255, 4); |
787
|
|
|
$lineWidth = self::validateInteger($lineWidth, 1, 6, 2); |
788
|
1 |
|
$nlen = strlen($data); |
789
|
|
|
//set barcode height |
790
|
|
|
$this->buffer->write(self::GS.'h'.chr($height)); |
791
|
1 |
|
//set barcode bar width |
792
|
|
|
$this->buffer->write(self::GS.'w'.chr($lineWidth)); |
793
|
|
|
//Selects print position of HRI characters. |
794
|
1 |
|
$this->buffer->write(self::GS.'H'.chr($tPos)); |
795
|
|
|
//Selects font for the HRI characters. |
796
|
|
|
$this->buffer->write(self::GS.'f'.chr($font)); |
797
|
1 |
|
//Print barcode |
798
|
|
|
$this->buffer->write(self::GS.'k'.chr($id).chr($nlen).$data); |
799
|
1 |
|
} |
800
|
1 |
|
|
801
|
1 |
|
/** |
802
|
1 |
|
* Print PDF 417 2D barcode |
803
|
|
|
* @param string $data |
804
|
|
|
* @param integer $ecc |
805
|
1 |
|
* @param integer $pheight |
806
|
|
|
* @param integer $pwidth |
807
|
|
|
* @param integer $colunms |
808
|
1 |
|
* @return boolean |
809
|
|
|
*/ |
810
|
|
|
public function barcodePDF417($data = '', $ecc = 5, $pheight = 2, $pwidth = 2, $colunms = 3) |
811
|
1 |
|
{ |
812
|
1 |
|
if (empty($data)) { |
813
|
|
|
return false; |
814
|
|
|
} |
815
|
1 |
|
$ecc = self::validateInteger($ecc, 0, 8, 5); |
816
|
1 |
|
$pheight = self::validateInteger($pheight, 1, 8, 2); |
817
|
1 |
|
$n = $ecc + 48; |
818
|
|
|
$length = strlen($data); |
819
|
1 |
|
$pH = intval($length / 256); |
820
|
|
|
$pL = ($length % 256); |
821
|
1 |
|
//Set the number of columns in the data region |
822
|
|
|
//GS ( k pL pH cn fn n |
823
|
1 |
|
//29 40 107 3 0 48 65 n |
|
|
|
|
824
|
|
|
$this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(65).chr(0)); |
825
|
1 |
|
//Set the number of rows |
826
|
|
|
//GS ( k pL pH cn fn n |
827
|
1 |
|
//29 40 107 3 0 48 66 n |
|
|
|
|
828
|
1 |
|
$this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(66).chr(0)); |
829
|
|
|
//Set the width of the module |
830
|
|
|
//GS ( k pL pH cn fn n |
831
|
|
|
//29 40 107 3 0 48 67 n |
|
|
|
|
832
|
|
|
$this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(67).chr(0)); |
833
|
|
|
//Set the row height |
834
|
|
|
//GS ( k pL pH cn fn n |
835
|
|
|
//29 40 107 3 0 48 68 n |
|
|
|
|
836
|
|
|
//pheight 3 or 5 time pwidth |
837
|
|
|
$this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(68).chr($pheight)); |
838
|
|
|
//Set the error correction level |
839
|
|
|
//GS ( k pL pH cn fn m n |
840
|
|
|
//29 40 107 4 0 48 69 m n n = 48 - 56 |
841
|
|
|
$this->buffer->write(self::GS."(k".chr(4).chr(0).chr(48).chr(69).chr(58).chr($n)); |
842
|
|
|
//Select the options |
843
|
|
|
//GS ( k pL pH cn fn n |
844
|
|
|
//29 40 107 3 0 48 70 n |
|
|
|
|
845
|
|
|
$this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(70).chr(0)); |
846
|
|
|
//Store the data in the symbol storage area |
847
|
|
|
//GS ( k pL pH cn fn m d1...dk |
848
|
|
|
//29 40 107 pL pH 48 80 48 d1...dk |
|
|
|
|
849
|
|
|
$this->buffer->write(self::GS."(k".chr($pL).chr($pH).chr(48).chr(80).chr(48).$data); |
850
|
|
|
//Print the symbol data in the symbol storage area |
851
|
|
|
//GS ( k pL pH cn fn m |
852
|
|
|
//29 40 107 3 0 48 81 m |
|
|
|
|
853
|
|
|
$this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(81).chr(0)); |
854
|
|
|
} |
855
|
|
|
|
856
|
|
|
/** |
857
|
|
|
* Prints QRCode |
858
|
|
|
* @param string $data barcode data |
859
|
|
|
* @param string $level correction level L,M,Q ou H |
860
|
|
|
* @param int $modelo QRCode model 1, 2 ou 0 Micro |
861
|
|
|
* @param int $wmod width bar 3 ~ 16 |
862
|
|
|
*/ |
863
|
|
|
public function barcodeQRCode($data = '', $level = 'L', $modelo = 2, $wmod = 4) |
864
|
|
|
{ |
865
|
|
|
//set model of QRCode |
866
|
|
|
$n1 = 50; |
867
|
|
|
if ($modelo == 1) { |
868
|
|
|
$n1 = 49; |
869
|
|
|
} |
870
|
|
|
//select QR model |
871
|
|
|
$this->buffer->write(self::GS."(k".chr(4).chr(0).chr(49).chr(65).chr($n1).chr(0)); |
872
|
|
|
//set module bar width |
873
|
|
|
$this->buffer->write(self::GS."(k".chr(3).chr(0).chr(49).chr(67).chr($wmod)); |
874
|
|
|
//set error correction level |
875
|
|
|
$level = strtoupper($level); |
876
|
|
|
switch ($level) { |
877
|
|
|
case 'L': |
878
|
|
|
$n = 48; |
879
|
|
|
break; |
880
|
|
|
case 'M': |
881
|
|
|
$n = 49; |
882
|
|
|
break; |
883
|
|
|
case 'Q': |
884
|
|
|
$n = 50; |
885
|
|
|
break; |
886
|
|
|
case 'H': |
887
|
|
|
$n = 51; |
888
|
|
|
break; |
889
|
|
|
default: |
890
|
|
|
$n = 49; |
891
|
|
|
} |
892
|
|
|
$this->buffer->write(self::GS."(k".chr(3).chr(0).chr(49).chr(69).chr($n)); |
893
|
1 |
|
//set data for QR Code assuming print only alphanumeric data |
894
|
|
|
$len = strlen($data) + 3; |
895
|
|
|
$pH = ($len / 256); |
896
|
1 |
|
$pL = $len % 256; |
897
|
1 |
|
$this->buffer->write(self::GS."(k".chr($pL).chr($pH).chr(49).chr(80).chr(48).$data); |
898
|
|
|
//Print QR Code |
899
|
|
|
$this->buffer->write(self::GS."(k".chr(3).chr(0).chr(49).chr(81).chr(48)); |
900
|
|
|
} |
901
|
1 |
|
|
902
|
|
|
/** |
903
|
1 |
|
* Return all data buffer. |
904
|
|
|
* |
905
|
1 |
|
* @param string $type specifies the return format |
906
|
|
|
*/ |
907
|
1 |
|
public function getBuffer($type = '') |
908
|
|
|
{ |
909
|
|
|
switch ($type) { |
910
|
1 |
|
case 'binA': |
911
|
1 |
|
//returns a binary array of buffer |
912
|
1 |
|
$resp = $this->buffer->getDataBinary(true); |
913
|
|
|
break; |
914
|
|
|
case 'binS': |
915
|
|
|
//returns a binary string of buffer |
916
|
|
|
$resp = $this->buffer->getDataBinary(false); |
917
|
|
|
break; |
918
|
|
|
case 'b64A': |
919
|
|
|
//returns a base64 encoded array of buffer |
920
|
|
|
$resp = $this->buffer->getDataBase64(true); |
921
|
|
|
break; |
922
|
1 |
|
case 'b64S': |
923
|
|
|
//returns a base64 encoded string of buffer |
924
|
1 |
|
$resp = $this->buffer->getDataBase64(false); |
925
|
1 |
|
break; |
926
|
1 |
|
case 'json': |
927
|
1 |
|
//returns a json encoded of array buffer |
928
|
|
|
$resp = $this->buffer->getDataJson(); |
929
|
1 |
|
break; |
930
|
1 |
|
case 'readA': |
931
|
|
|
//returns a human readable format of array buffer |
932
|
|
|
//only for debug reasons |
933
|
|
|
$resp = $this->buffer->getDataReadable(true); |
934
|
|
|
break; |
935
|
|
|
default: |
936
|
|
|
//returns a human readable format of string buffer |
937
|
20 |
|
//only for debug reasons |
938
|
|
|
$resp = $this->buffer->getDataReadable(false); |
939
|
|
|
} |
940
|
20 |
|
return $resp; |
941
|
|
|
} |
942
|
|
|
|
943
|
|
|
/** |
944
|
20 |
|
* Send commands from buffer to connector printer. |
945
|
|
|
* @param ConnectorInterface $conn |
946
|
20 |
|
* @return string|void |
947
|
20 |
|
*/ |
948
|
|
|
public function send(ConnectorInterface $conn = null) |
949
|
|
|
{ |
950
|
|
|
if (!is_null($conn)) { |
951
|
|
|
$this->connector = $conn; |
952
|
|
|
} |
953
|
|
|
if (is_null($this->connector)) { |
954
|
|
|
return $this->getBuffer(); |
955
|
|
|
} |
956
|
|
|
$aCmds = $this->getBuffer('binA'); |
957
|
|
|
foreach ($aCmds as $cmd) { |
|
|
|
|
958
|
|
|
$this->connector->write($cmd); |
959
|
|
|
} |
960
|
|
|
} |
961
|
|
|
|
962
|
|
|
/** |
963
|
|
|
* Insert a image. |
964
|
|
|
* |
965
|
|
|
* @param string $filename Path to image file |
966
|
|
|
* @param int $width |
967
|
|
|
* @param int $height |
968
|
|
|
* @param int $size 0-normal 1-Double Width 2-Double Heigth |
969
|
|
|
* @throws RuntimeException |
970
|
20 |
|
*/ |
971
|
|
|
public function putImage($filename = '', $width = null, $height = null, $size = 0) |
972
|
|
|
{ |
973
|
|
|
try { |
974
|
|
|
$img = new Graphics($filename, $width, $height); |
975
|
|
|
} catch (RuntimeException $e) { |
976
|
|
|
throw new RuntimeException($e->getMessage()); |
977
|
|
|
} catch (InvalidArgumentException $e) { |
978
|
|
|
throw new RuntimeException($e->getMessage()); |
979
|
|
|
} |
980
|
|
|
$size = self::validateInteger($size, 0, 3, 0); |
981
|
|
|
$imgHeader = self::dataHeader(array($img->getWidth(), $img->getHeight()), true); |
982
|
|
|
$tone = '0'; |
983
|
|
|
$colors = '1'; |
984
|
|
|
$xm = (($size & self::IMG_DOUBLE_WIDTH) == self::IMG_DOUBLE_WIDTH) ? chr(2) : chr(1); |
985
|
|
|
$ym = (($size & self::IMG_DOUBLE_HEIGHT) == self::IMG_DOUBLE_HEIGHT) ? chr(2) : chr(1); |
986
|
|
|
$header = $tone.$xm.$ym.$colors.$imgHeader; |
987
|
|
|
$this->sendGraphicsData('0', 'p', $header.$img->getRasterImage()); |
988
|
|
|
$this->sendGraphicsData('0', '2'); |
989
|
|
|
} |
990
|
|
|
|
991
|
|
|
/** |
992
|
|
|
* Close and clean buffer |
993
|
|
|
* All data will be lost. |
994
|
|
|
*/ |
995
|
|
|
public function close() |
996
|
|
|
{ |
997
|
|
|
$this->buffer->close(); |
998
|
|
|
} |
999
|
1 |
|
|
1000
|
|
|
/** |
1001
|
|
|
* Wrapper for GS ( L, to calculate and send correct data length. |
1002
|
1 |
|
* |
1003
|
1 |
|
* @param string $m Modifier/variant for function. Usually '0'. |
1004
|
|
|
* @param string $fn Function number to use, as character. |
1005
|
|
|
* @param string $data Data to send. |
1006
|
|
|
*/ |
1007
|
|
|
protected function sendGraphicsData($m, $fn, $data = '') |
1008
|
1 |
|
{ |
1009
|
1 |
|
$header = $this->intLowHigh(strlen($data) + 2, 2); |
1010
|
1 |
|
$this->buffer->write(self::GS.'(L'.$header.$m.$fn.$data); |
1011
|
1 |
|
} |
1012
|
1 |
|
|
1013
|
1 |
|
/** |
1014
|
1 |
|
* Generate two characters for a number: |
1015
|
1 |
|
* In lower and higher parts, or more parts as needed. |
1016
|
1 |
|
* |
1017
|
1 |
|
* @param int $input Input number |
1018
|
|
|
* @param int $length The number of bytes to output (1 - 4). |
1019
|
|
|
*/ |
1020
|
|
|
protected static function intLowHigh($input, $length) |
1021
|
|
|
{ |
1022
|
|
|
$maxInput = (256 << ($length * 8) - 1); |
|
|
|
|
1023
|
|
|
$outp = ''; |
1024
|
|
|
for ($i = 0; $i < $length; ++$i) { |
1025
|
|
|
$outp .= chr($input % 256); |
1026
|
|
|
$input = (int) ($input / 256); |
1027
|
|
|
} |
1028
|
|
|
return $outp; |
1029
|
|
|
} |
1030
|
|
|
|
1031
|
|
|
/** |
1032
|
|
|
* Convert widths and heights to characters. |
1033
|
|
|
* Used before sending graphics to set the size. |
1034
|
|
|
* |
1035
|
1 |
|
* @param array $inputs |
1036
|
|
|
* @param bool $long True to use 4 bytes, false to use 2 |
1037
|
1 |
|
* @return string |
1038
|
1 |
|
*/ |
1039
|
1 |
|
protected static function dataHeader(array $inputs, $long = true) |
1040
|
|
|
{ |
1041
|
|
|
$outp = array(); |
1042
|
|
|
foreach ($inputs as $input) { |
1043
|
|
|
if ($long) { |
1044
|
|
|
$outp[] = self::intLowHigh($input, 2); |
1045
|
|
|
} else { |
1046
|
|
|
$input = self::validateInteger($input, 0, 255, 0); |
1047
|
|
|
$outp[] = chr($input); |
1048
|
1 |
|
} |
1049
|
|
|
} |
1050
|
1 |
|
return implode('', $outp); |
1051
|
1 |
|
} |
1052
|
1 |
|
|
1053
|
1 |
|
/** |
1054
|
1 |
|
* Verify if the argument given is not a boolean. |
1055
|
1 |
|
* |
1056
|
1 |
|
* @param bool $test the input to test |
1057
|
|
|
* @param bool $default the default value |
1058
|
|
|
* @return bool |
1059
|
|
|
*/ |
1060
|
|
|
protected static function validateBoolean($test, $default) |
1061
|
|
|
{ |
1062
|
|
|
if (!($test === true || $test === false)) { |
1063
|
|
|
return $default; |
1064
|
|
|
} |
1065
|
|
|
return $test; |
1066
|
|
|
} |
1067
|
1 |
|
|
1068
|
|
|
/** |
1069
|
1 |
|
* Verify if the argument given is not an integer within the specified range. |
1070
|
1 |
|
* will return default instead |
1071
|
1 |
|
* @param int|null $test the input to test |
1072
|
1 |
|
* @param int $min the minimum allowable value (inclusive) |
1073
|
1 |
|
* @param int $max the maximum allowable value (inclusive) |
1074
|
|
|
* @param int $default the default value |
1075
|
|
|
* @return int|null |
1076
|
|
|
*/ |
1077
|
1 |
|
protected static function validateInteger($test, $min, $max, $default) |
1078
|
1 |
|
{ |
1079
|
|
|
if (!is_integer($test) || $test < $min || $test > $max) { |
1080
|
|
|
return $default; |
1081
|
|
|
} |
1082
|
|
|
return $test; |
1083
|
|
|
} |
1084
|
|
|
|
1085
|
|
|
/** |
1086
|
|
|
* Translate the text from UTF-8 for the specified codepage |
1087
|
|
|
* this translation uses "iconv" and admits texts ONLY in UTF-8. |
1088
|
|
|
* |
1089
|
|
|
* @param string $text |
1090
|
|
|
* @return string |
1091
|
|
|
*/ |
1092
|
|
|
protected function translate($text = '') |
1093
|
|
|
{ |
1094
|
|
|
if (empty($this->codepage)) { |
1095
|
|
|
$this->defaultCodePage(); |
1096
|
|
|
} |
1097
|
|
|
$codep = $this->aCodePage[$this->codepage]; |
1098
|
|
|
if (!empty($codep)) { |
1099
|
|
|
$text = @iconv('UTF-8', $codep['conv'], $text); |
1100
|
|
|
} |
1101
|
|
|
return $text; |
1102
|
|
|
} |
1103
|
|
|
} |
1104
|
|
|
|
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.