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