1<?php 2 3namespace Mpdf\Barcode; 4 5/** 6 * Interleaved 2 of 5 barcodes. 7 * Compact numeric code, widely used in industry, air cargo 8 * Contains digits (0 to 9) and encodes the data in the width of both bars and spaces. 9 */ 10class I25 extends \Mpdf\Barcode\AbstractBarcode implements \Mpdf\Barcode\BarcodeInterface 11{ 12 13 /** 14 * @param string $code 15 * @param float $topBottomMargin 16 * @param float $printRatio 17 * @param bool $checksum 18 */ 19 public function __construct($code, $topBottomMargin, $printRatio, $checksum = false) 20 { 21 $this->init($code, $printRatio, $checksum); 22 23 $this->data['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.) 24 $this->data['nom-H'] = 10; // Nominal value for Height of Full bar in mm (non-spec.) 25 $this->data['lightmL'] = 10; // LEFT light margin = x X-dim (spec.) 26 $this->data['lightmR'] = 10; // RIGHT light margin = x X-dim (spec.) 27 $this->data['lightTB'] = $topBottomMargin; // TOP/BOTTOM light margin = x X-dim (non-spec.) 28 } 29 30 /** 31 * @param string $code 32 * @param float $printRatio 33 * @param bool $checksum 34 */ 35 private function init($code, $printRatio, $checksum) 36 { 37 $chr = [ 38 '0' => '11221', 39 '1' => '21112', 40 '2' => '12112', 41 '3' => '22111', 42 '4' => '11212', 43 '5' => '21211', 44 '6' => '12211', 45 '7' => '11122', 46 '8' => '21121', 47 '9' => '12121', 48 'A' => '11', 49 'Z' => '21', 50 ]; 51 52 $checkdigit = ''; 53 if ($checksum) { 54 // add checksum 55 $checkdigit = $this->checksum($code); 56 $code .= $checkdigit; 57 } 58 if ((strlen($code) % 2) != 0) { 59 // add leading zero if code-length is odd 60 $code = '0' . $code; 61 } 62 // add start and stop codes 63 $code = 'AA' . strtolower($code) . 'ZA'; 64 65 $bararray = ['code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => []]; 66 $k = 0; 67 $clen = strlen($code); 68 for ($i = 0; $i < $clen; $i = ($i + 2)) { 69 $charBar = $code[$i]; 70 $charSpace = $code[$i + 1]; 71 if ((!isset($chr[$charBar])) or (!isset($chr[$charSpace]))) { 72 // invalid character 73 throw new \Mpdf\Barcode\BarcodeException('Invalid I25 barcode value'); 74 } 75 // create a bar-space sequence 76 $seq = ''; 77 $chrlen = strlen($chr[$charBar]); 78 for ($s = 0; $s < $chrlen; $s++) { 79 $seq .= $chr[$charBar][$s] . $chr[$charSpace][$s]; 80 } 81 $seqlen = strlen($seq); 82 for ($j = 0; $j < $seqlen; ++$j) { 83 if (($j % 2) == 0) { 84 $t = true; // bar 85 } else { 86 $t = false; // space 87 } 88 $x = $seq[$j]; 89 if ($x == 2) { 90 $w = $printRatio; 91 } else { 92 $w = 1; 93 } 94 95 $bararray['bcode'][$k] = ['t' => $t, 'w' => $w, 'h' => 1, 'p' => 0]; 96 $bararray['maxw'] += $w; 97 ++$k; 98 } 99 } 100 $bararray['checkdigit'] = $checkdigit; 101 102 $this->data = $bararray; 103 } 104 105 /** 106 * Checksum for standard 2 of 5 barcodes. 107 * 108 * @param string $code 109 * @return int 110 */ 111 private function checksum($code) 112 { 113 $len = strlen($code); 114 $sum = 0; 115 for ($i = 0; $i < $len; $i += 2) { 116 $sum += $code[$i]; 117 } 118 $sum *= 3; 119 for ($i = 1; $i < $len; $i += 2) { 120 $sum += ($code[$i]); 121 } 122 $r = $sum % 10; 123 if ($r > 0) { 124 $r = (10 - $r); 125 } 126 return $r; 127 } 128 129 /** 130 * @inheritdoc 131 */ 132 public function getType() 133 { 134 return 'I25'; 135 } 136 137} 138