1<?php 2 3namespace Mpdf\Barcode; 4 5/** 6 * UPC-Based Extentions 7 * 2-Digit Ext.: Used to indicate magazines and newspaper issue numbers 8 * 5-Digit Ext.: Used to mark suggested retail price of books 9 */ 10class EanExt extends \Mpdf\Barcode\AbstractBarcode implements \Mpdf\Barcode\BarcodeInterface 11{ 12 13 /** 14 * @param string $code 15 * @param int $length 16 * @param float $leftMargin 17 * @param float $rightMargin 18 * @param float $xDim 19 * @param float $barHeight 20 * @param float $separatorMargin 21 */ 22 public function __construct($code, $length, $leftMargin, $rightMargin, $xDim, $barHeight, $separatorMargin) 23 { 24 $this->init($code, $length); 25 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) 30 $this->data['sepM'] = $separatorMargin; // SEPARATION margin = x X-dim (http://web.archive.org/web/19990501035133/http://www.uc-council.org/d36-d.htm) 31 } 32 33 /** 34 * @param string $code 35 * @param int $length 36 */ 37 private function init($code, $length = 5) 38 { 39 // Padding 40 $code = str_pad($code, $length, '0', STR_PAD_LEFT); 41 42 // Calculate check digit 43 if ($length == 2) { 44 $r = $code % 4; 45 } elseif ($length == 5) { 46 $r = (3 * ($code[0] + $code[2] + $code[4])) + (9 * ($code[1] + $code[3])); 47 $r %= 10; 48 } else { 49 throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid EAN barcode value "%s"', $code)); 50 } 51 52 // Convert digits to bars 53 $codes = [ 54 'A' => [ // left odd parity 55 '0' => '0001101', 56 '1' => '0011001', 57 '2' => '0010011', 58 '3' => '0111101', 59 '4' => '0100011', 60 '5' => '0110001', 61 '6' => '0101111', 62 '7' => '0111011', 63 '8' => '0110111', 64 '9' => '0001011'], 65 'B' => [ // left even parity 66 '0' => '0100111', 67 '1' => '0110011', 68 '2' => '0011011', 69 '3' => '0100001', 70 '4' => '0011101', 71 '5' => '0111001', 72 '6' => '0000101', 73 '7' => '0010001', 74 '8' => '0001001', 75 '9' => '0010111'] 76 ]; 77 $parities = []; 78 $parities[2] = [ 79 '0' => ['A', 'A'], 80 '1' => ['A', 'B'], 81 '2' => ['B', 'A'], 82 '3' => ['B', 'B'] 83 ]; 84 $parities[5] = [ 85 '0' => ['B', 'B', 'A', 'A', 'A'], 86 '1' => ['B', 'A', 'B', 'A', 'A'], 87 '2' => ['B', 'A', 'A', 'B', 'A'], 88 '3' => ['B', 'A', 'A', 'A', 'B'], 89 '4' => ['A', 'B', 'B', 'A', 'A'], 90 '5' => ['A', 'A', 'B', 'B', 'A'], 91 '6' => ['A', 'A', 'A', 'B', 'B'], 92 '7' => ['A', 'B', 'A', 'B', 'A'], 93 '8' => ['A', 'B', 'A', 'A', 'B'], 94 '9' => ['A', 'A', 'B', 'A', 'B'] 95 ]; 96 $p = $parities[$length][$r]; 97 $seq = '1011'; // left guard bar 98 $seq .= $codes[$p[0]][$code[0]]; 99 for ($i = 1; $i < $length; ++$i) { 100 $seq .= '01'; // separator 101 $seq .= $codes[$p[$i]][$code[$i]]; 102 } 103 104 $bararray = ['code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => []]; 105 106 $this->data = $this->binseqToArray($seq, $bararray); 107 } 108 109 public function getType() 110 { 111 return 'EAN EXT'; 112 } 113 114} 115