3 namespace Mpdf\Barcode
;
6 * EAN13 and UPC-A barcodes.
7 * EAN13: European Article Numbering international retail product code
8 * UPC-A: Universal product code seen on almost all retail products in the USA and Canada
9 * UPC-E: Short version of UPC symbol
11 class EanUpc
extends \Mpdf\Barcode\AbstractBarcode
implements \Mpdf\Barcode\BarcodeInterface
17 * @param float $leftMargin
18 * @param float $rightMargin
20 * @param float $barHeight
22 public function __construct($code, $length, $leftMargin, $rightMargin, $xDim, $barHeight)
24 $this->init($code, $length);
26 $this->data
['lightmL'] = $leftMargin; // LEFT light margin = x X-dim (http://www.gs1uk.org)
27 $this->data
['lightmR'] = $rightMargin; // RIGHT light margin = x X-dim (http://www.gs1uk.org)
28 $this->data
['nom-X'] = $xDim; // Nominal value for X-dim in mm (http://www.gs1uk.org)
29 $this->data
['nom-H'] = $barHeight; // Nominal bar height in mm incl. numerals (http://www.gs1uk.org)
36 private function init($code, $length)
42 $length = 12; // UPC-A
43 $upce = true; // UPC-E mode
45 $dataLength = $length - 1;
48 $code = str_pad($code, $dataLength, '0', STR_PAD_LEFT
);
49 $codeLength = strlen($code);
51 // Calculate check digit
53 for ($i = 1; $i < $dataLength; $i +
= 2) {
61 for ($i = 0; $i < $dataLength; $i +
= 2) {
62 $sum_b +
= ($code[$i]);
69 $r = ($sum_a +
$sum_b) %
10;
74 if ($codeLength == $dataLength) {
78 } elseif ($r !== (int) $code[$dataLength]) {
80 throw new \Mpdf\Barcode\
BarcodeException('Invalid EAN UPC barcode value');
90 // Convert UPC-A to UPC-E
91 $tmp = substr($code, 4, 3);
92 $prodCode = (int) substr($code, 7, 5); // product code
94 if (($tmp == '000') or ($tmp == '100') or ($tmp == '200')) {
95 // Manufacturer code ends in 000, 100, or 200
96 $upceCode = substr($code, 2, 2) . substr($code, 9, 3) . substr($code, 4, 1);
97 if ($prodCode > 999) {
101 $tmp = substr($code, 5, 2);
103 // Manufacturer code ends in 00
104 $upceCode = substr($code, 2, 3) . substr($code, 10, 2) . '3';
105 if ($prodCode > 99) {
109 $tmp = substr($code, 6, 1);
111 // Manufacturer code ends in 0
112 $upceCode = substr($code, 2, 4) . substr($code, 11, 1) . '4';
117 // Manufacturer code does not end in zero
118 $upceCode = substr($code, 2, 5) . substr($code, 11, 1);
126 throw new \Mpdf\Barcode\
BarcodeException('UPC-A cannot produce a valid UPC-E barcode');
130 // Convert digits to bars
132 'A' => [// left odd parity
143 'B' => [// left even parity
168 '0' => ['A', 'A', 'A', 'A', 'A', 'A'],
169 '1' => ['A', 'A', 'B', 'A', 'B', 'B'],
170 '2' => ['A', 'A', 'B', 'B', 'A', 'B'],
171 '3' => ['A', 'A', 'B', 'B', 'B', 'A'],
172 '4' => ['A', 'B', 'A', 'A', 'B', 'B'],
173 '5' => ['A', 'B', 'B', 'A', 'A', 'B'],
174 '6' => ['A', 'B', 'B', 'B', 'A', 'A'],
175 '7' => ['A', 'B', 'A', 'B', 'A', 'B'],
176 '8' => ['A', 'B', 'A', 'B', 'B', 'A'],
177 '9' => ['A', 'B', 'B', 'A', 'B', 'A']
182 '0' => ['B', 'B', 'B', 'A', 'A', 'A'],
183 '1' => ['B', 'B', 'A', 'B', 'A', 'A'],
184 '2' => ['B', 'B', 'A', 'A', 'B', 'A'],
185 '3' => ['B', 'B', 'A', 'A', 'A', 'B'],
186 '4' => ['B', 'A', 'B', 'B', 'A', 'A'],
187 '5' => ['B', 'A', 'A', 'B', 'B', 'A'],
188 '6' => ['B', 'A', 'A', 'A', 'B', 'B'],
189 '7' => ['B', 'A', 'B', 'A', 'B', 'A'],
190 '8' => ['B', 'A', 'B', 'A', 'A', 'B'],
191 '9' => ['B', 'A', 'A', 'B', 'A', 'B']
195 '0' => ['A', 'A', 'A', 'B', 'B', 'B'],
196 '1' => ['A', 'A', 'B', 'A', 'B', 'B'],
197 '2' => ['A', 'A', 'B', 'B', 'A', 'B'],
198 '3' => ['A', 'A', 'B', 'B', 'B', 'A'],
199 '4' => ['A', 'B', 'A', 'A', 'B', 'B'],
200 '5' => ['A', 'B', 'B', 'A', 'A', 'B'],
201 '6' => ['A', 'B', 'B', 'B', 'A', 'A'],
202 '7' => ['A', 'B', 'A', 'B', 'A', 'B'],
203 '8' => ['A', 'B', 'A', 'B', 'B', 'A'],
204 '9' => ['A', 'B', 'B', 'A', 'B', 'A']
208 $seq = '101'; // left guard bar
210 if ($upce && isset($upceCode)) {
211 $bararray = ['code' => $upceCode, 'maxw' => 0, 'maxh' => 1, 'bcode' => []];
212 $p = $upceParities[$code{1}][$r];
213 for ($i = 0; $i < 6; ++
$i) {
214 $seq .= $codes[$p[$i]][$upceCode[$i]];
216 $seq .= '010101'; // right guard bar
218 $bararray = ['code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => []];
219 $halfLen = ceil($length / 2);
221 for ($i = 0; $i < $halfLen; ++
$i) {
222 $seq .= $codes['A'][$code[$i]];
225 $p = $parities[$code{0}];
226 for ($i = 1; $i < $halfLen; ++
$i) {
227 $seq .= $codes[$p[$i - 1]][$code[$i]];
230 $seq .= '01010'; // center guard bar
231 for ($i = $halfLen; $i < $length; ++
$i) {
232 $seq .= $codes['C'][$code[(int) $i]];
234 $seq .= '101'; // right guard bar
237 $clen = strlen($seq);
239 for ($i = 0; $i < $clen; ++
$i) {
241 if (($i == ($clen - 1)) or (($i < ($clen - 1)) and ($seq[$i] != $seq[($i +
1)]))) {
242 if ($seq[$i] == '1') {
247 $bararray['bcode'][$k] = ['t' => $t, 'w' => $w, 'h' => 1, 'p' => 0];
248 $bararray['maxw'] +
= $w;
253 $bararray['checkdigit'] = $checkdigit;
255 $this->data
= $bararray;
261 public function getType()