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, $quiet_zone_left = null, $quiet_zone_right = null) 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'] = ($quiet_zone_left !== null ? $quiet_zone_left : 10); // LEFT light margin = x X-dim (spec.) 26 $this->data['lightmR'] = ($quiet_zone_right !== null ? $quiet_zone_right : 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 152 case 'RAW': 153 154 $newCode=''; 155 $startid = false; 156 157 foreach (explode(" ", $code) as $v) { 158 159 if (is_numeric($v) && round($v, 0) == $v) { 160 161 if ($v>=0 && $v<=105) { 162 if ($startid===false) { 163 $startid=$v; 164 } else { 165 $newCode.=chr($v); 166 } 167 } else { 168 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid CODE128RAW barcode value "%s". 0-105 needed', $code)); 169 } 170 171 } else { 172 //double spaces generates empty $v any other is not allowed 173 if ($v!='') { 174 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid CODE128RAW barcode value "%s". 0-105 needed', $code)); 175 } 176 } 177 } 178 179 if ($startid < 103 || $startid > 105) { 180 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid CODE128RAW startid value "%s". Must be 103, 104 or 105 (for A, B or C)', $startid)); 181 } 182 183 $keys=''; 184 185 for ($i = 0; $i <= 105; ++$i) { 186 $keys .= chr($i); 187 } 188 189 $code=$newCode; 190 191 break; 192 193 case 'A': 194 195 $startid = 103; 196 $keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'; 197 198 for ($i = 0; $i < 32; ++$i) { 199 $keys .= chr($i); 200 } 201 202 break; 203 204 case 'B': 205 206 $startid = 104; 207 208 $keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~' . chr(127); 209 210 break; 211 212 case 'C': 213 214 $startid = 105; 215 $keys = ''; 216 217 if ((strlen($code) % 2) != 0) { 218 // The length of barcode value must be even ($code). You must pad the number with zeros 219 throw new \Mpdf\Barcode\BarcodeException('Invalid CODE128C barcode value'); 220 } 221 222 for ($i = 0; $i <= 99; ++$i) { 223 $keys .= chr($i); 224 } 225 226 $newCode = ''; 227 $hclen = (strlen($code) / 2); 228 229 for ($i = 0; $i < $hclen; ++$i) { 230 if ($code[2 * $i]<"0" || $code[2 * $i]>"9" || $code[2 * $i + 1]<"0" || $code[2 * $i + 1]>"9") { 231 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid character "%s" in CODE128C barcode value "%s"', $code[$i], $code)); 232 } 233 $newCode .= chr((int) ($code[2 * $i] . $code[2 * $i + 1])); 234 } 235 236 $code = $newCode; 237 238 break; 239 240 default: 241 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid CODE128 barcode type "%s"', $type)); 242 } 243 244 // calculate check character 245 $sum = $startid; 246 247 // Add FNC 1 - which identifies it as EAN-128 248 if ($ean) { 249 $code = chr(102) . $code; 250 } 251 252 $clen = strlen($code); 253 for ($i = 0; $i < $clen; ++$i) { 254 if ($ean && $i == 0) { 255 $sum += 102; 256 } else { 257 if (strpos($keys, $code[$i]) === false) { 258 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid character "%s" in CODE128%s barcode value "%s"', $code[$i], $type, $code)); 259 } 260 $sum += (strpos($keys, $code[$i]) * ($i + 1)); 261 } 262 } 263 264 $check = ($sum % 103); 265 $checkdigit = $check; 266 267 // add start, check and stop codes 268 $code = chr($startid) . $code . chr($check) . chr(106) . chr(107); 269 $bararray = ['code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => []]; 270 $k = 0; 271 $len = strlen($code); 272 273 for ($i = 0; $i < $len; ++$i) { 274 275 $ck = strpos($keys, $code[$i]); 276 if (($i == 0) || ($ean && $i == 1) | ($i > ($len - 4))) { 277 $char_num = ord($code[$i]); 278 $seq = $chr[$char_num]; 279 } elseif (($ck >= 0) && isset($chr[$ck])) { 280 $seq = $chr[$ck]; 281 } else { 282 // invalid character 283 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid character "%s" in CODE128C barcode value "%s"', $code[$i], $code)); 284 } 285 286 for ($j = 0; $j < 6; ++$j) { 287 if (($j % 2) == 0) { 288 $t = true; // bar 289 } else { 290 $t = false; // space 291 } 292 $w = $seq[$j]; 293 $bararray['bcode'][$k] = ['t' => $t, 'w' => $w, 'h' => 1, 'p' => 0]; 294 $bararray['maxw'] += $w; 295 ++$k; 296 } 297 } 298 299 $bararray['checkdigit'] = $checkdigit; 300 $this->data = $bararray; 301 } 302 303 public function getType() 304 { 305 return 'CODE128'; 306 } 307 308} 309