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