1<?php 2 3namespace Mpdf\Barcode; 4 5use Mpdf\Utils\UtfString; 6 7/** 8 * C128 barcodes. 9 * Very capable code, excellent density, high reliability; in very wide use world-wide 10 */ 11class Code128 extends \Mpdf\Barcode\AbstractBarcode implements \Mpdf\Barcode\BarcodeInterface 12{ 13 14 /** 15 * @param string $code 16 * @param string $type 17 * @param bool $ean 18 */ 19 public function __construct($code, $type = 'B', $ean = false) 20 { 21 $this->init($code, $type, $ean); 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'] = 0; // TOP/BOTTOM light margin = x X-dim (non-spec.) 28 } 29 30 /** 31 * @param string $code 32 * @param string $type 33 * @param bool $ean 34 */ 35 protected function init($code, $type, $ean) 36 { 37 $code = UtfString::strcode2utf($code); // mPDF 5.7.1 Allows e.g. <barcode code="5432
1068" type="C128A" /> 38 39 $chr = [ 40 '212222', /* 00 */ 41 '222122', /* 01 */ 42 '222221', /* 02 */ 43 '121223', /* 03 */ 44 '121322', /* 04 */ 45 '131222', /* 05 */ 46 '122213', /* 06 */ 47 '122312', /* 07 */ 48 '132212', /* 08 */ 49 '221213', /* 09 */ 50 '221312', /* 10 */ 51 '231212', /* 11 */ 52 '112232', /* 12 */ 53 '122132', /* 13 */ 54 '122231', /* 14 */ 55 '113222', /* 15 */ 56 '123122', /* 16 */ 57 '123221', /* 17 */ 58 '223211', /* 18 */ 59 '221132', /* 19 */ 60 '221231', /* 20 */ 61 '213212', /* 21 */ 62 '223112', /* 22 */ 63 '312131', /* 23 */ 64 '311222', /* 24 */ 65 '321122', /* 25 */ 66 '321221', /* 26 */ 67 '312212', /* 27 */ 68 '322112', /* 28 */ 69 '322211', /* 29 */ 70 '212123', /* 30 */ 71 '212321', /* 31 */ 72 '232121', /* 32 */ 73 '111323', /* 33 */ 74 '131123', /* 34 */ 75 '131321', /* 35 */ 76 '112313', /* 36 */ 77 '132113', /* 37 */ 78 '132311', /* 38 */ 79 '211313', /* 39 */ 80 '231113', /* 40 */ 81 '231311', /* 41 */ 82 '112133', /* 42 */ 83 '112331', /* 43 */ 84 '132131', /* 44 */ 85 '113123', /* 45 */ 86 '113321', /* 46 */ 87 '133121', /* 47 */ 88 '313121', /* 48 */ 89 '211331', /* 49 */ 90 '231131', /* 50 */ 91 '213113', /* 51 */ 92 '213311', /* 52 */ 93 '213131', /* 53 */ 94 '311123', /* 54 */ 95 '311321', /* 55 */ 96 '331121', /* 56 */ 97 '312113', /* 57 */ 98 '312311', /* 58 */ 99 '332111', /* 59 */ 100 '314111', /* 60 */ 101 '221411', /* 61 */ 102 '431111', /* 62 */ 103 '111224', /* 63 */ 104 '111422', /* 64 */ 105 '121124', /* 65 */ 106 '121421', /* 66 */ 107 '141122', /* 67 */ 108 '141221', /* 68 */ 109 '112214', /* 69 */ 110 '112412', /* 70 */ 111 '122114', /* 71 */ 112 '122411', /* 72 */ 113 '142112', /* 73 */ 114 '142211', /* 74 */ 115 '241211', /* 75 */ 116 '221114', /* 76 */ 117 '413111', /* 77 */ 118 '241112', /* 78 */ 119 '134111', /* 79 */ 120 '111242', /* 80 */ 121 '121142', /* 81 */ 122 '121241', /* 82 */ 123 '114212', /* 83 */ 124 '124112', /* 84 */ 125 '124211', /* 85 */ 126 '411212', /* 86 */ 127 '421112', /* 87 */ 128 '421211', /* 88 */ 129 '212141', /* 89 */ 130 '214121', /* 90 */ 131 '412121', /* 91 */ 132 '111143', /* 92 */ 133 '111341', /* 93 */ 134 '131141', /* 94 */ 135 '114113', /* 95 */ 136 '114311', /* 96 */ 137 '411113', /* 97 */ 138 '411311', /* 98 */ 139 '113141', /* 99 */ 140 '114131', /* 100 */ 141 '311141', /* 101 */ 142 '411131', /* 102 */ 143 '211412', /* 103 START A */ 144 '211214', /* 104 START B */ 145 '211232', /* 105 START C */ 146 '233111', /* STOP */ 147 '200000' /* END */ 148 ]; 149 150 switch (strtoupper($type)) { 151 case 'RAW': 152 $newCode=''; 153 $startid = false; 154 foreach (explode(" ", $code) as $v) { 155 if (is_numeric($v) && round($v, 0) == $v) { 156 if ($v>=0 && $v<=105) { 157 if ($startid===false) { 158 $startid=$v; 159 } else { 160 $newCode.=chr($v); 161 } 162 } else { 163 throw new \Mpdf\Barcode\BarcodeException('Invalid CODE128RAW barcode value. 0-105 needed'); 164 } 165 } else { 166 //double spaces generates empty $v any other is not allowed 167 if ($v!='') { 168 throw new \Mpdf\Barcode\BarcodeException('Invalid CODE128RAW barcode value. 0-105 needed'); 169 } 170 } 171 } 172 if ($startid<103 || $startid>105) { 173 throw new \Mpdf\Barcode\BarcodeException('Invalid CODE128RAW startid value. Must 103,104 or 105 (for A,B or C)'); 174 } 175 $keys=''; 176 for ($i = 0; $i <= 105; ++$i) { 177 $keys .= chr($i); 178 } 179 $code=$newCode; 180 break; 181 case 'A': 182 $startid = 103; 183 $keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'; 184 for ($i = 0; $i < 32; ++$i) { 185 $keys .= chr($i); 186 } 187 break; 188 case 'B': 189 $startid = 104; 190 $keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~' . chr(127); 191 break; 192 case 'C': 193 $startid = 105; 194 $keys = ''; 195 if ((strlen($code) % 2) != 0) { 196 // The length of barcode value must be even ($code). You must pad the number with zeros 197 throw new \Mpdf\Barcode\BarcodeException('Invalid CODE128C barcode value'); 198 } 199 for ($i = 0; $i <= 99; ++$i) { 200 $keys .= chr($i); 201 } 202 $newCode = ''; 203 $hclen = (strlen($code) / 2); 204 for ($i = 0; $i < $hclen; ++$i) { 205 if ($code[2 * $i]<"0" || $code[2 * $i]>"9" || $code[2 * $i + 1]<"0" || $code[2 * $i + 1]>"9") { 206 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid character "%s" in CODE128C barcode value', $code[$i])); 207 } 208 $newCode .= chr((int) ($code[2 * $i] . $code[2 * $i + 1])); 209 } 210 $code = $newCode; 211 break; 212 default: 213 throw new \Mpdf\Barcode\BarcodeException('Invalid CODE128 barcode type'); 214 } 215 216 // calculate check character 217 $sum = $startid; 218 219 // Add FNC 1 - which identifies it as EAN-128 220 if ($ean) { 221 $code = chr(102) . $code; 222 } 223 $clen = strlen($code); 224 for ($i = 0; $i < $clen; ++$i) { 225 if ($ean && $i == 0) { 226 $sum += 102; 227 } else { 228 if (strpos($keys, $code[$i]) === false) { 229 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid character "%s" in CODE128'.$type.' barcode value', $code[$i])); 230 } 231 $sum += (strpos($keys, $code[$i]) * ($i + 1)); 232 } 233 } 234 $check = ($sum % 103); 235 $checkdigit = $check; 236 237 // add start, check and stop codes 238 $code = chr($startid) . $code . chr($check) . chr(106) . chr(107); 239 $bararray = ['code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => []]; 240 $k = 0; 241 $len = strlen($code); 242 243 for ($i = 0; $i < $len; ++$i) { 244 245 $ck = strpos($keys, $code[$i]); 246 if (($i == 0) || ($ean && $i == 1) | ($i > ($len - 4))) { 247 $char_num = ord($code[$i]); 248 $seq = $chr[$char_num]; 249 } elseif (($ck >= 0) && isset($chr[$ck])) { 250 $seq = $chr[$ck]; 251 } else { 252 // invalid character 253 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid character "%s" in CODE128C barcode value', $code[$i])); 254 } 255 for ($j = 0; $j < 6; ++$j) { 256 if (($j % 2) == 0) { 257 $t = true; // bar 258 } else { 259 $t = false; // space 260 } 261 $w = $seq[$j]; 262 $bararray['bcode'][$k] = ['t' => $t, 'w' => $w, 'h' => 1, 'p' => 0]; 263 $bararray['maxw'] += $w; 264 ++$k; 265 } 266 } 267 268 $bararray['checkdigit'] = $checkdigit; 269 $this->data = $bararray; 270 } 271 272 public function getType() 273 { 274 return 'CODE128'; 275 } 276 277} 278