/lib/tcpdf/barcodes.php
PHP | 2288 lines | 1835 code | 39 blank | 414 comment | 244 complexity | 36dd9e7e62024450e49e9d5690aaa780 MD5 | raw file
Possible License(s): MIT, AGPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, Apache-2.0, LGPL-2.1, BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- <?php
- //============================================================+
- // File name : barcodes.php
- // Version : 1.0.021
- // Begin : 2008-06-09
- // Last Update : 2011-09-15
- // Author : Nicola Asuni - Tecnick.com S.r.l - Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com
- // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
- // -------------------------------------------------------------------
- // Copyright (C) 2008-2011 Nicola Asuni - Tecnick.com S.r.l.
- //
- // This file is part of TCPDF software library.
- //
- // TCPDF is free software: you can redistribute it and/or modify it
- // under the terms of the GNU Lesser General Public License as
- // published by the Free Software Foundation, either version 3 of the
- // License, or (at your option) any later version.
- //
- // TCPDF is distributed in the hope that it will be useful, but
- // WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- // See the GNU Lesser General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public License
- // along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
- //
- // See LICENSE.TXT file for more information.
- // -------------------------------------------------------------------
- //
- // Description : PHP class to creates array representations for
- // common 1D barcodes to be used with TCPDF.
- //
- //============================================================+
- /**
- * @file
- * PHP class to creates array representations for common 1D barcodes to be used with TCPDF.
- * @package com.tecnick.tcpdf
- * @author Nicola Asuni
- * @version 1.0.021
- */
- /**
- * @class TCPDFBarcode
- * PHP class to creates array representations for common 1D barcodes to be used with TCPDF (http://www.tcpdf.org).<br>
- * @package com.tecnick.tcpdf
- * @version 1.0.021
- * @author Nicola Asuni
- */
- class TCPDFBarcode {
- /**
- * Array representation of barcode.
- * @protected
- */
- protected $barcode_array;
- /**
- * This is the class constructor.
- * Return an array representations for common 1D barcodes:<ul>
- * <li>$arrcode['code'] code to be printed on text label</li>
- * <li>$arrcode['maxh'] max barcode height</li>
- * <li>$arrcode['maxw'] max barcode width</li>
- * <li>$arrcode['bcode'][$k] single bar or space in $k position</li>
- * <li>$arrcode['bcode'][$k]['t'] bar type: true = bar, false = space.</li>
- * <li>$arrcode['bcode'][$k]['w'] bar width in units.</li>
- * <li>$arrcode['bcode'][$k]['h'] bar height in units.</li>
- * <li>$arrcode['bcode'][$k]['p'] bar top position (0 = top, 1 = middle)</li></ul>
- * @param $code (string) code to print
- * @param $type (string) type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128 : CODE 128</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extention</li><li>EAN5 : 5-Digits UPC-Based Extention</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
- * @public
- */
- public function __construct($code, $type) {
- $this->setBarcode($code, $type);
- }
- /**
- * Return an array representations of barcode.
- * @return array
- * @public
- */
- public function getBarcodeArray() {
- return $this->barcode_array;
- }
- /**
- * Send barcode as SVG image object to the standard output.
- * @param $w (int) Minimum width of a single bar in user units.
- * @param $h (int) Height of barcode in user units.
- * @param $color (string) Foreground color (in SVG format) for bar elements (background is transparent).
- * @public
- */
- public function getBarcodeSVG($w=2, $h=30, $color='black') {
- // send headers
- $code = $this->getBarcodeSVGcode($w, $h, $color);
- header('Content-Type: application/svg+xml');
- header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
- header('Pragma: public');
- header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
- header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
- header('Content-Disposition: inline; filename="'.md5($code).'.svg";');
- //header('Content-Length: '.strlen($code));
- echo $code;
- }
- /**
- * Return a SVG string representation of barcode.
- * @param $w (int) Minimum width of a single bar in user units.
- * @param $h (int) Height of barcode in user units.
- * @param $color (string) Foreground color (in SVG format) for bar elements (background is transparent).
- * @return string SVG code.
- * @public
- */
- public function getBarcodeSVGcode($w=2, $h=30, $color='black') {
- // replace table for special characters
- $repstr = array("\0" => '', '&' => '&', '<' => '<', '>' => '>');
- $svg = '<'.'?'.'xml version="1.0" standalone="no"'.'?'.'>'."\n";
- $svg .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'."\n";
- $svg .= '<svg width="'.round(($this->barcode_array['maxw'] * $w), 3).'" height="'.$h.'" version="1.1" xmlns="http://www.w3.org/2000/svg">'."\n";
- $svg .= "\t".'<desc>'.strtr($this->barcode_array['code'], $repstr).'</desc>'."\n";
- $svg .= "\t".'<g id="bars" fill="'.$color.'" stroke="none">'."\n";
- // print bars
- $x = 0;
- foreach ($this->barcode_array['bcode'] as $k => $v) {
- $bw = round(($v['w'] * $w), 3);
- $bh = round(($v['h'] * $h / $this->barcode_array['maxh']), 3);
- if ($v['t']) {
- $y = round(($v['p'] * $h / $this->barcode_array['maxh']), 3);
- // draw a vertical bar
- $svg .= "\t\t".'<rect x="'.$x.'" y="'.$y.'" width="'.$bw.'" height="'.$bh.'" />'."\n";
- }
- $x += $bw;
- }
- $svg .= "\t".'</g>'."\n";
- $svg .= '</svg>'."\n";
- return $svg;
- }
- /**
- * Return an HTML representation of barcode.
- * @param $w (int) Width of a single bar element in pixels.
- * @param $h (int) Height of a single bar element in pixels.
- * @param $color (string) Foreground color for bar elements (background is transparent).
- * @return string HTML code.
- * @public
- */
- public function getBarcodeHTML($w=2, $h=30, $color='black') {
- // replace table for special characters
- $html = '<div style="font-size:0;position:relative;">'."\n";
- // print bars
- $x = 0;
- foreach ($this->barcode_array['bcode'] as $k => $v) {
- $bw = round(($v['w'] * $w), 3);
- $bh = round(($v['h'] * $h / $this->barcode_array['maxh']), 3);
- if ($v['t']) {
- $y = round(($v['p'] * $h / $this->barcode_array['maxh']), 3);
- // draw a vertical bar
- $html .= '<div style="background-color:'.$color.';width:'.$bw.'px;height:'.$bh.'px;position:absolute;left:'.$x.'px;top:'.$y.'px;"> </div>'."\n";
- }
- $x += $bw;
- }
- $html .= '</div>'."\n";
- return $html;
- }
- /**
- * Return a PNG image representation of barcode (requires GD or Imagick library).
- * @param $w (int) Width of a single bar element in pixels.
- * @param $h (int) Height of a single bar element in pixels.
- * @param $color (array) RGB (0-255) foreground color for bar elements (background is transparent).
- * @return image or false in case of error.
- * @public
- */
- public function getBarcodePNG($w=2, $h=30, $color=array(0,0,0)) {
- // calculate image size
- $width = ($this->barcode_array['maxw'] * $w);
- $height = $h;
- if (function_exists('imagecreate')) {
- // GD library
- $imagick = false;
- $png = imagecreate($width, $height);
- $bgcol = imagecolorallocate($png, 255, 255, 255);
- imagecolortransparent($png, $bgcol);
- $fgcol = imagecolorallocate($png, $color[0], $color[1], $color[2]);
- } elseif (extension_loaded('imagick')) {
- $imagick = true;
- $bgcol = new imagickpixel('rgb(255,255,255');
- $fgcol = new imagickpixel('rgb('.$color[0].','.$color[1].','.$color[2].')');
- $png = new Imagick();
- $png->newImage($width, $height, 'none', 'png');
- $bar = new imagickdraw();
- $bar->setfillcolor($fgcol);
- } else {
- return false;
- }
- // print bars
- $x = 0;
- foreach ($this->barcode_array['bcode'] as $k => $v) {
- $bw = round(($v['w'] * $w), 3);
- $bh = round(($v['h'] * $h / $this->barcode_array['maxh']), 3);
- if ($v['t']) {
- $y = round(($v['p'] * $h / $this->barcode_array['maxh']), 3);
- // draw a vertical bar
- if ($imagick) {
- $bar->rectangle($x, $y, ($x + $bw), ($y + $bh));
- } else {
- imagefilledrectangle($png, $x, $y, ($x + $bw), ($y + $bh), $fgcol);
- }
- }
- $x += $bw;
- }
- // send headers
- header('Content-Type: image/png');
- header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
- header('Pragma: public');
- header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
- header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
- if ($imagick) {
- $png->drawimage($bar);
- echo $png;
- } else {
- imagepng($png);
- imagedestroy($png);
- }
- }
- /**
- * Set the barcode.
- * @param $code (string) code to print
- * @param $type (string) type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128 : CODE 128</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extention</li><li>EAN5 : 5-Digits UPC-Based Extention</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
- * @return array barcode array
- * @public
- */
- public function setBarcode($code, $type) {
- switch (strtoupper($type)) {
- case 'C39': { // CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
- $arrcode = $this->barcode_code39($code, false, false);
- break;
- }
- case 'C39+': { // CODE 39 with checksum
- $arrcode = $this->barcode_code39($code, false, true);
- break;
- }
- case 'C39E': { // CODE 39 EXTENDED
- $arrcode = $this->barcode_code39($code, true, false);
- break;
- }
- case 'C39E+': { // CODE 39 EXTENDED + CHECKSUM
- $arrcode = $this->barcode_code39($code, true, true);
- break;
- }
- case 'C93': { // CODE 93 - USS-93
- $arrcode = $this->barcode_code93($code);
- break;
- }
- case 'S25': { // Standard 2 of 5
- $arrcode = $this->barcode_s25($code, false);
- break;
- }
- case 'S25+': { // Standard 2 of 5 + CHECKSUM
- $arrcode = $this->barcode_s25($code, true);
- break;
- }
- case 'I25': { // Interleaved 2 of 5
- $arrcode = $this->barcode_i25($code, false);
- break;
- }
- case 'I25+': { // Interleaved 2 of 5 + CHECKSUM
- $arrcode = $this->barcode_i25($code, true);
- break;
- }
- case 'C128': { // CODE 128
- $arrcode = $this->barcode_c128($code, '');
- break;
- }
- case 'C128A': { // CODE 128 A
- $arrcode = $this->barcode_c128($code, 'A');
- break;
- }
- case 'C128B': { // CODE 128 B
- $arrcode = $this->barcode_c128($code, 'B');
- break;
- }
- case 'C128C': { // CODE 128 C
- $arrcode = $this->barcode_c128($code, 'C');
- break;
- }
- case 'EAN2': { // 2-Digits UPC-Based Extention
- $arrcode = $this->barcode_eanext($code, 2);
- break;
- }
- case 'EAN5': { // 5-Digits UPC-Based Extention
- $arrcode = $this->barcode_eanext($code, 5);
- break;
- }
- case 'EAN8': { // EAN 8
- $arrcode = $this->barcode_eanupc($code, 8);
- break;
- }
- case 'EAN13': { // EAN 13
- $arrcode = $this->barcode_eanupc($code, 13);
- break;
- }
- case 'UPCA': { // UPC-A
- $arrcode = $this->barcode_eanupc($code, 12);
- break;
- }
- case 'UPCE': { // UPC-E
- $arrcode = $this->barcode_eanupc($code, 6);
- break;
- }
- case 'MSI': { // MSI (Variation of Plessey code)
- $arrcode = $this->barcode_msi($code, false);
- break;
- }
- case 'MSI+': { // MSI + CHECKSUM (modulo 11)
- $arrcode = $this->barcode_msi($code, true);
- break;
- }
- case 'POSTNET': { // POSTNET
- $arrcode = $this->barcode_postnet($code, false);
- break;
- }
- case 'PLANET': { // PLANET
- $arrcode = $this->barcode_postnet($code, true);
- break;
- }
- case 'RMS4CC': { // RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)
- $arrcode = $this->barcode_rms4cc($code, false);
- break;
- }
- case 'KIX': { // KIX (Klant index - Customer index)
- $arrcode = $this->barcode_rms4cc($code, true);
- break;
- }
- case 'IMB': { // IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
- $arrcode = $this->barcode_imb($code);
- break;
- }
- case 'CODABAR': { // CODABAR
- $arrcode = $this->barcode_codabar($code);
- break;
- }
- case 'CODE11': { // CODE 11
- $arrcode = $this->barcode_code11($code);
- break;
- }
- case 'PHARMA': { // PHARMACODE
- $arrcode = $this->barcode_pharmacode($code);
- break;
- }
- case 'PHARMA2T': { // PHARMACODE TWO-TRACKS
- $arrcode = $this->barcode_pharmacode2t($code);
- break;
- }
- default: {
- $this->barcode_array = false;
- $arrcode = false;
- break;
- }
- }
- $this->barcode_array = $arrcode;
- }
- /**
- * CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
- * General-purpose code in very wide use world-wide
- * @param $code (string) code to represent.
- * @param $extended (boolean) if true uses the extended mode.
- * @param $checksum (boolean) if true add a checksum to the code.
- * @return array barcode representation.
- * @protected
- */
- protected function barcode_code39($code, $extended=false, $checksum=false) {
- $chr['0'] = '111331311';
- $chr['1'] = '311311113';
- $chr['2'] = '113311113';
- $chr['3'] = '313311111';
- $chr['4'] = '111331113';
- $chr['5'] = '311331111';
- $chr['6'] = '113331111';
- $chr['7'] = '111311313';
- $chr['8'] = '311311311';
- $chr['9'] = '113311311';
- $chr['A'] = '311113113';
- $chr['B'] = '113113113';
- $chr['C'] = '313113111';
- $chr['D'] = '111133113';
- $chr['E'] = '311133111';
- $chr['F'] = '113133111';
- $chr['G'] = '111113313';
- $chr['H'] = '311113311';
- $chr['I'] = '113113311';
- $chr['J'] = '111133311';
- $chr['K'] = '311111133';
- $chr['L'] = '113111133';
- $chr['M'] = '313111131';
- $chr['N'] = '111131133';
- $chr['O'] = '311131131';
- $chr['P'] = '113131131';
- $chr['Q'] = '111111333';
- $chr['R'] = '311111331';
- $chr['S'] = '113111331';
- $chr['T'] = '111131331';
- $chr['U'] = '331111113';
- $chr['V'] = '133111113';
- $chr['W'] = '333111111';
- $chr['X'] = '131131113';
- $chr['Y'] = '331131111';
- $chr['Z'] = '133131111';
- $chr['-'] = '131111313';
- $chr['.'] = '331111311';
- $chr[' '] = '133111311';
- $chr['$'] = '131313111';
- $chr['/'] = '131311131';
- $chr['+'] = '131113131';
- $chr['%'] = '111313131';
- $chr['*'] = '131131311';
- $code = strtoupper($code);
- if ($extended) {
- // extended mode
- $code = $this->encode_code39_ext($code);
- }
- if ($code === false) {
- return false;
- }
- if ($checksum) {
- // checksum
- $code .= $this->checksum_code39($code);
- }
- // add start and stop codes
- $code = '*'.$code.'*';
- $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
- $k = 0;
- $clen = strlen($code);
- for ($i = 0; $i < $clen; ++$i) {
- $char = $code{$i};
- if(!isset($chr[$char])) {
- // invalid character
- return false;
- }
- for ($j = 0; $j < 9; ++$j) {
- if (($j % 2) == 0) {
- $t = true; // bar
- } else {
- $t = false; // space
- }
- $w = $chr[$char]{$j};
- $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
- $bararray['maxw'] += $w;
- ++$k;
- }
- // intercharacter gap
- $bararray['bcode'][$k] = array('t' => false, 'w' => 1, 'h' => 1, 'p' => 0);
- $bararray['maxw'] += 1;
- ++$k;
- }
- return $bararray;
- }
- /**
- * Encode a string to be used for CODE 39 Extended mode.
- * @param $code (string) code to represent.
- * @return encoded string.
- * @protected
- */
- protected function encode_code39_ext($code) {
- $encode = array(
- chr(0) => '%U', chr(1) => '$A', chr(2) => '$B', chr(3) => '$C',
- chr(4) => '$D', chr(5) => '$E', chr(6) => '$F', chr(7) => '$G',
- chr(8) => '$H', chr(9) => '$I', chr(10) => '$J', chr(11) => '£K',
- chr(12) => '$L', chr(13) => '$M', chr(14) => '$N', chr(15) => '$O',
- chr(16) => '$P', chr(17) => '$Q', chr(18) => '$R', chr(19) => '$S',
- chr(20) => '$T', chr(21) => '$U', chr(22) => '$V', chr(23) => '$W',
- chr(24) => '$X', chr(25) => '$Y', chr(26) => '$Z', chr(27) => '%A',
- chr(28) => '%B', chr(29) => '%C', chr(30) => '%D', chr(31) => '%E',
- chr(32) => ' ', chr(33) => '/A', chr(34) => '/B', chr(35) => '/C',
- chr(36) => '/D', chr(37) => '/E', chr(38) => '/F', chr(39) => '/G',
- chr(40) => '/H', chr(41) => '/I', chr(42) => '/J', chr(43) => '/K',
- chr(44) => '/L', chr(45) => '-', chr(46) => '.', chr(47) => '/O',
- chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3',
- chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7',
- chr(56) => '8', chr(57) => '9', chr(58) => '/Z', chr(59) => '%F',
- chr(60) => '%G', chr(61) => '%H', chr(62) => '%I', chr(63) => '%J',
- chr(64) => '%V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C',
- chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G',
- chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K',
- chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O',
- chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S',
- chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W',
- chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => '%K',
- chr(92) => '%L', chr(93) => '%M', chr(94) => '%N', chr(95) => '%O',
- chr(96) => '%W', chr(97) => '+A', chr(98) => '+B', chr(99) => '+C',
- chr(100) => '+D', chr(101) => '+E', chr(102) => '+F', chr(103) => '+G',
- chr(104) => '+H', chr(105) => '+I', chr(106) => '+J', chr(107) => '+K',
- chr(108) => '+L', chr(109) => '+M', chr(110) => '+N', chr(111) => '+O',
- chr(112) => '+P', chr(113) => '+Q', chr(114) => '+R', chr(115) => '+S',
- chr(116) => '+T', chr(117) => '+U', chr(118) => '+V', chr(119) => '+W',
- chr(120) => '+X', chr(121) => '+Y', chr(122) => '+Z', chr(123) => '%P',
- chr(124) => '%Q', chr(125) => '%R', chr(126) => '%S', chr(127) => '%T');
- $code_ext = '';
- $clen = strlen($code);
- for ($i = 0 ; $i < $clen; ++$i) {
- if (ord($code{$i}) > 127) {
- return false;
- }
- $code_ext .= $encode[$code{$i}];
- }
- return $code_ext;
- }
- /**
- * Calculate CODE 39 checksum (modulo 43).
- * @param $code (string) code to represent.
- * @return char checksum.
- * @protected
- */
- protected function checksum_code39($code) {
- $chars = array(
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
- 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
- 'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%');
- $sum = 0;
- $clen = strlen($code);
- for ($i = 0 ; $i < $clen; ++$i) {
- $k = array_keys($chars, $code{$i});
- $sum += $k[0];
- }
- $j = ($sum % 43);
- return $chars[$j];
- }
- /**
- * CODE 93 - USS-93
- * Compact code similar to Code 39
- * @param $code (string) code to represent.
- * @return array barcode representation.
- * @protected
- */
- protected function barcode_code93($code) {
- $chr[48] = '131112'; // 0
- $chr[49] = '111213'; // 1
- $chr[50] = '111312'; // 2
- $chr[51] = '111411'; // 3
- $chr[52] = '121113'; // 4
- $chr[53] = '121212'; // 5
- $chr[54] = '121311'; // 6
- $chr[55] = '111114'; // 7
- $chr[56] = '131211'; // 8
- $chr[57] = '141111'; // 9
- $chr[65] = '211113'; // A
- $chr[66] = '211212'; // B
- $chr[67] = '211311'; // C
- $chr[68] = '221112'; // D
- $chr[69] = '221211'; // E
- $chr[70] = '231111'; // F
- $chr[71] = '112113'; // G
- $chr[72] = '112212'; // H
- $chr[73] = '112311'; // I
- $chr[74] = '122112'; // J
- $chr[75] = '132111'; // K
- $chr[76] = '111123'; // L
- $chr[77] = '111222'; // M
- $chr[78] = '111321'; // N
- $chr[79] = '121122'; // O
- $chr[80] = '131121'; // P
- $chr[81] = '212112'; // Q
- $chr[82] = '212211'; // R
- $chr[83] = '211122'; // S
- $chr[84] = '211221'; // T
- $chr[85] = '221121'; // U
- $chr[86] = '222111'; // V
- $chr[87] = '112122'; // W
- $chr[88] = '112221'; // X
- $chr[89] = '122121'; // Y
- $chr[90] = '123111'; // Z
- $chr[45] = '121131'; // -
- $chr[46] = '311112'; // .
- $chr[32] = '311211'; //
- $chr[36] = '321111'; // $
- $chr[47] = '112131'; // /
- $chr[43] = '113121'; // +
- $chr[37] = '211131'; // %
- $chr[128] = '121221'; // ($)
- $chr[129] = '311121'; // (/)
- $chr[130] = '122211'; // (+)
- $chr[131] = '312111'; // (%)
- $chr[42] = '111141'; // start-stop
- $code = strtoupper($code);
- $encode = array(
- chr(0) => chr(131).'U', chr(1) => chr(128).'A', chr(2) => chr(128).'B', chr(3) => chr(128).'C',
- chr(4) => chr(128).'D', chr(5) => chr(128).'E', chr(6) => chr(128).'F', chr(7) => chr(128).'G',
- chr(8) => chr(128).'H', chr(9) => chr(128).'I', chr(10) => chr(128).'J', chr(11) => '£K',
- chr(12) => chr(128).'L', chr(13) => chr(128).'M', chr(14) => chr(128).'N', chr(15) => chr(128).'O',
- chr(16) => chr(128).'P', chr(17) => chr(128).'Q', chr(18) => chr(128).'R', chr(19) => chr(128).'S',
- chr(20) => chr(128).'T', chr(21) => chr(128).'U', chr(22) => chr(128).'V', chr(23) => chr(128).'W',
- chr(24) => chr(128).'X', chr(25) => chr(128).'Y', chr(26) => chr(128).'Z', chr(27) => chr(131).'A',
- chr(28) => chr(131).'B', chr(29) => chr(131).'C', chr(30) => chr(131).'D', chr(31) => chr(131).'E',
- chr(32) => ' ', chr(33) => chr(129).'A', chr(34) => chr(129).'B', chr(35) => chr(129).'C',
- chr(36) => chr(129).'D', chr(37) => chr(129).'E', chr(38) => chr(129).'F', chr(39) => chr(129).'G',
- chr(40) => chr(129).'H', chr(41) => chr(129).'I', chr(42) => chr(129).'J', chr(43) => chr(129).'K',
- chr(44) => chr(129).'L', chr(45) => '-', chr(46) => '.', chr(47) => chr(129).'O',
- chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3',
- chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7',
- chr(56) => '8', chr(57) => '9', chr(58) => chr(129).'Z', chr(59) => chr(131).'F',
- chr(60) => chr(131).'G', chr(61) => chr(131).'H', chr(62) => chr(131).'I', chr(63) => chr(131).'J',
- chr(64) => chr(131).'V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C',
- chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G',
- chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K',
- chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O',
- chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S',
- chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W',
- chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => chr(131).'K',
- chr(92) => chr(131).'L', chr(93) => chr(131).'M', chr(94) => chr(131).'N', chr(95) => chr(131).'O',
- chr(96) => chr(131).'W', chr(97) => chr(130).'A', chr(98) => chr(130).'B', chr(99) => chr(130).'C',
- chr(100) => chr(130).'D', chr(101) => chr(130).'E', chr(102) => chr(130).'F', chr(103) => chr(130).'G',
- chr(104) => chr(130).'H', chr(105) => chr(130).'I', chr(106) => chr(130).'J', chr(107) => chr(130).'K',
- chr(108) => chr(130).'L', chr(109) => chr(130).'M', chr(110) => chr(130).'N', chr(111) => chr(130).'O',
- chr(112) => chr(130).'P', chr(113) => chr(130).'Q', chr(114) => chr(130).'R', chr(115) => chr(130).'S',
- chr(116) => chr(130).'T', chr(117) => chr(130).'U', chr(118) => chr(130).'V', chr(119) => chr(130).'W',
- chr(120) => chr(130).'X', chr(121) => chr(130).'Y', chr(122) => chr(130).'Z', chr(123) => chr(131).'P',
- chr(124) => chr(131).'Q', chr(125) => chr(131).'R', chr(126) => chr(131).'S', chr(127) => chr(131).'T');
- $code_ext = '';
- $clen = strlen($code);
- for ($i = 0 ; $i < $clen; ++$i) {
- if (ord($code{$i}) > 127) {
- return false;
- }
- $code_ext .= $encode[$code{$i}];
- }
- // checksum
- $code_ext .= $this->checksum_code93($code_ext);
- // add start and stop codes
- $code = '*'.$code_ext.'*';
- $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
- $k = 0;
- $clen = strlen($code);
- for ($i = 0; $i < $clen; ++$i) {
- $char = ord($code{$i});
- if(!isset($chr[$char])) {
- // invalid character
- return false;
- }
- for ($j = 0; $j < 6; ++$j) {
- if (($j % 2) == 0) {
- $t = true; // bar
- } else {
- $t = false; // space
- }
- $w = $chr[$char]{$j};
- $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
- $bararray['maxw'] += $w;
- ++$k;
- }
- }
- $bararray['bcode'][$k] = array('t' => true, 'w' => 1, 'h' => 1, 'p' => 0);
- $bararray['maxw'] += 1;
- ++$k;
- return $bararray;
- }
- /**
- * Calculate CODE 93 checksum (modulo 47).
- * @param $code (string) code to represent.
- * @return string checksum code.
- * @protected
- */
- protected function checksum_code93($code) {
- $chars = array(
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
- 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
- 'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%',
- '<', '=', '>', '?');
- // translate special characters
- $code = strtr($code, chr(128).chr(131).chr(129).chr(130), '<=>?');
- $len = strlen($code);
- // calculate check digit C
- $p = 1;
- $check = 0;
- for ($i = ($len - 1); $i >= 0; --$i) {
- $k = array_keys($chars, $code{$i});
- $check += ($k[0] * $p);
- ++$p;
- if ($p > 20) {
- $p = 1;
- }
- }
- $check %= 47;
- $c = $chars[$check];
- $code .= $c;
- // calculate check digit K
- $p = 1;
- $check = 0;
- for ($i = $len; $i >= 0; --$i) {
- $k = array_keys($chars, $code{$i});
- $check += ($k[0] * $p);
- ++$p;
- if ($p > 15) {
- $p = 1;
- }
- }
- $check %= 47;
- $k = $chars[$check];
- $checksum = $c.$k;
- // resto respecial characters
- $checksum = strtr($checksum, '<=>?', chr(128).chr(131).chr(129).chr(130));
- return $checksum;
- }
- /**
- * Checksum for standard 2 of 5 barcodes.
- * @param $code (string) code to process.
- * @return int checksum.
- * @protected
- */
- protected function checksum_s25($code) {
- $len = strlen($code);
- $sum = 0;
- for ($i = 0; $i < $len; $i+=2) {
- $sum += $code{$i};
- }
- $sum *= 3;
- for ($i = 1; $i < $len; $i+=2) {
- $sum += ($code{$i});
- }
- $r = $sum % 10;
- if($r > 0) {
- $r = (10 - $r);
- }
- return $r;
- }
- /**
- * MSI.
- * Variation of Plessey code, with similar applications
- * Contains digits (0 to 9) and encodes the data only in the width of bars.
- * @param $code (string) code to represent.
- * @param $checksum (boolean) if true add a checksum to the code (modulo 11)
- * @return array barcode representation.
- * @protected
- */
- protected function barcode_msi($code, $checksum=false) {
- $chr['0'] = '100100100100';
- $chr['1'] = '100100100110';
- $chr['2'] = '100100110100';
- $chr['3'] = '100100110110';
- $chr['4'] = '100110100100';
- $chr['5'] = '100110100110';
- $chr['6'] = '100110110100';
- $chr['7'] = '100110110110';
- $chr['8'] = '110100100100';
- $chr['9'] = '110100100110';
- $chr['A'] = '110100110100';
- $chr['B'] = '110100110110';
- $chr['C'] = '110110100100';
- $chr['D'] = '110110100110';
- $chr['E'] = '110110110100';
- $chr['F'] = '110110110110';
- if ($checksum) {
- // add checksum
- $clen = strlen($code);
- $p = 2;
- $check = 0;
- for ($i = ($clen - 1); $i >= 0; --$i) {
- $check += (hexdec($code{$i}) * $p);
- ++$p;
- if ($p > 7) {
- $p = 2;
- }
- }
- $check %= 11;
- if ($check > 0) {
- $check = 11 - $check;
- }
- $code .= $check;
- }
- $seq = '110'; // left guard
- $clen = strlen($code);
- for ($i = 0; $i < $clen; ++$i) {
- $digit = $code{$i};
- if (!isset($chr[$digit])) {
- // invalid character
- return false;
- }
- $seq .= $chr[$digit];
- }
- $seq .= '1001'; // right guard
- $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
- return $this->binseq_to_array($seq, $bararray);
- }
- /**
- * Standard 2 of 5 barcodes.
- * Used in airline ticket marking, photofinishing
- * Contains digits (0 to 9) and encodes the data only in the width of bars.
- * @param $code (string) code to represent.
- * @param $checksum (boolean) if true add a checksum to the code
- * @return array barcode representation.
- * @protected
- */
- protected function barcode_s25($code, $checksum=false) {
- $chr['0'] = '10101110111010';
- $chr['1'] = '11101010101110';
- $chr['2'] = '10111010101110';
- $chr['3'] = '11101110101010';
- $chr['4'] = '10101110101110';
- $chr['5'] = '11101011101010';
- $chr['6'] = '10111011101010';
- $chr['7'] = '10101011101110';
- $chr['8'] = '10101110111010';
- $chr['9'] = '10111010111010';
- if ($checksum) {
- // add checksum
- $code .= $this->checksum_s25($code);
- }
- if((strlen($code) % 2) != 0) {
- // add leading zero if code-length is odd
- $code = '0'.$code;
- }
- $seq = '11011010';
- $clen = strlen($code);
- for ($i = 0; $i < $clen; ++$i) {
- $digit = $code{$i};
- if (!isset($chr[$digit])) {
- // invalid character
- return false;
- }
- $seq .= $chr[$digit];
- }
- $seq .= '1101011';
- $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
- return $this->binseq_to_array($seq, $bararray);
- }
- /**
- * Convert binary barcode sequence to TCPDF barcode array.
- * @param $seq (string) barcode as binary sequence.
- * @param $bararray (array) barcode array.
- * òparam array $bararray TCPDF barcode array to fill up
- * @return array barcode representation.
- * @protected
- */
- protected function binseq_to_array($seq, $bararray) {
- $len = strlen($seq);
- $w = 0;
- $k = 0;
- for ($i = 0; $i < $len; ++$i) {
- $w += 1;
- if (($i == ($len - 1)) OR (($i < ($len - 1)) AND ($seq{$i} != $seq{($i+1)}))) {
- if ($seq{$i} == '1') {
- $t = true; // bar
- } else {
- $t = false; // space
- }
- $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
- $bararray['maxw'] += $w;
- ++$k;
- $w = 0;
- }
- }
- return $bararray;
- }
- /**
- * Interleaved 2 of 5 barcodes.
- * Compact numeric code, widely used in industry, air cargo
- * Contains digits (0 to 9) and encodes the data in the width of both bars and spaces.
- * @param $code (string) code to represent.
- * @param $checksum (boolean) if true add a checksum to the code
- * @return array barcode representation.
- * @protected
- */
- protected function barcode_i25($code, $checksum=false) {
- $chr['0'] = '11221';
- $chr['1'] = '21112';
- $chr['2'] = '12112';
- $chr['3'] = '22111';
- $chr['4'] = '11212';
- $chr['5'] = '21211';
- $chr['6'] = '12211';
- $chr['7'] = '11122';
- $chr['8'] = '21121';
- $chr['9'] = '12121';
- $chr['A'] = '11';
- $chr['Z'] = '21';
- if ($checksum) {
- // add checksum
- $code .= $this->checksum_s25($code);
- }
- if((strlen($code) % 2) != 0) {
- // add leading zero if code-length is odd
- $code = '0'.$code;
- }
- // add start and stop codes
- $code = 'AA'.strtolower($code).'ZA';
- $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
- $k = 0;
- $clen = strlen($code);
- for ($i = 0; $i < $clen; $i = ($i + 2)) {
- $char_bar = $code{$i};
- $char_space = $code{$i+1};
- if((!isset($chr[$char_bar])) OR (!isset($chr[$char_space]))) {
- // invalid character
- return false;
- }
- // create a bar-space sequence
- $seq = '';
- $chrlen = strlen($chr[$char_bar]);
- for ($s = 0; $s < $chrlen; $s++){
- $seq .= $chr[$char_bar]{$s} . $chr[$char_space]{$s};
- }
- $seqlen = strlen($seq);
- for ($j = 0; $j < $seqlen; ++$j) {
- if (($j % 2) == 0) {
- $t = true; // bar
- } else {
- $t = false; // space
- }
- $w = $seq{$j};
- $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
- $bararray['maxw'] += $w;
- ++$k;
- }
- }
- return $bararray;
- }
- /**
- * C128 barcodes.
- * Very capable code, excellent density, high reliability; in very wide use world-wide
- * @param $code (string) code to represent.
- * @param $type (string) barcode type: A, B, C or empty for automatic switch (AUTO mode)
- * @return array barcode representation.
- * @protected
- */
- protected function barcode_c128($code, $type='') {
- $chr = array(
- '212222', /* 00 */
- '222122', /* 01 */
- '222221', /* 02 */
- '121223', /* 03 */
- '121322', /* 04 */
- '131222', /* 05 */
- '122213', /* 06 */
- '122312', /* 07 */
- '132212', /* 08 */
- '221213', /* 09 */
- '221312', /* 10 */
- '231212', /* 11 */
- '112232', /* 12 */
- '122132', /* 13 */
- '122231', /* 14 */
- '113222', /* 15 */
- '123122', /* 16 */
- '123221', /* 17 */
- '223211', /* 18 */
- '221132', /* 19 */
- '221231', /* 20 */
- '213212', /* 21 */
- '223112', /* 22 */
- '312131', /* 23 */
- '311222', /* 24 */
- '321122', /* 25 */
- '321221', /* 26 */
- '312212', /* 27 */
- '322112', /* 28 */
- '322211', /* 29 */
- '212123', /* 30 */
- '212321', /* 31 */
- '232121', /* 32 */
- '111323', /* 33 */
- '131123', /* 34 */
- '131321', /* 35 */
- '112313', /* 36 */
- '132113', /* 37 */
- '132311', /* 38 */
- '211313', /* 39 */
- '231113', /* 40 */
- '231311', /* 41 */
- '112133', /* 42 */
- '112331', /* 43 */
- '132131', /* 44 */
- '113123', /* 45 */
- '113321', /* 46 */
- '133121', /* 47 */
- '313121', /* 48 */
- '211331', /* 49 */
- '231131', /* 50 */
- '213113', /* 51 */
- '213311', /* 52 */
- '213131', /* 53 */
- '311123', /* 54 */
- '311321', /* 55 */
- '331121', /* 56 */
- '312113', /* 57 */
- '312311', /* 58 */
- '332111', /* 59 */
- '314111', /* 60 */
- '221411', /* 61 */
- '431111', /* 62 */
- '111224', /* 63 */
- '111422', /* 64 */
- '121124', /* 65 */
- '121421', /* 66 */
- '141122', /* 67 */
- '141221', /* 68 */
- '112214', /* 69 */
- '112412', /* 70 */
- '122114', /* 71 */
- '122411', /* 72 */
- '142112', /* 73 */
- '142211', /* 74 */
- '241211', /* 75 */
- '221114', /* 76 */
- '413111', /* 77 */
- '241112', /* 78 */
- '134111', /* 79 */
- '111242', /* 80 */
- '121142', /* 81 */
- '121241', /* 82 */
- '114212', /* 83 */
- '124112', /* 84 */
- '124211', /* 85 */
- '411212', /* 86 */
- '421112', /* 87 */
- '421211', /* 88 */
- '212141', /* 89 */
- '214121', /* 90 */
- '412121', /* 91 */
- '111143', /* 92 */
- '111341', /* 93 */
- '131141', /* 94 */
- '114113', /* 95 */
- '114311', /* 96 */
- '411113', /* 97 */
- '411311', /* 98 */
- '113141', /* 99 */
- '114131', /* 100 */
- '311141', /* 101 */
- '411131', /* 102 */
- '211412', /* 103 START A */
- '211214', /* 104 START B */
- '211232', /* 105 START C */
- '233111', /* STOP */
- '200000' /* END */
- );
- // ASCII characters for code A (ASCII 00 - 95)
- $keys_a = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_';
- $keys_a .= chr(0).chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8).chr(9);
- $keys_a .= chr(10).chr(11).chr(12).chr(13).chr(14).chr(15).chr(16).chr(17).chr(18).chr(19);
- $keys_a .= chr(20).chr(21).chr(22).chr(23).chr(24).chr(25).chr(26).chr(27).chr(28).chr(29);
- $keys_a .= chr(30).chr(31);
- // ASCII characters for code B (ASCII 32 - 127)
- $keys_b = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'.chr(127);
- // special codes
- $fnc_a = array(241 => 102, 242 => 97, 243 => 96, 244 => 101);
- $fnc_b = array(241 => 102, 242 => 97, 243 => 96, 244 => 100);
- // array of symbols
- $code_data = array();
- // lenght of the code
- $len = strlen($code);
- switch(strtoupper($type)) {
- case 'A': { // MODE A
- $startid = 103;
- for ($i = 0; $i < $len; ++$i) {
- $char = $code{$i};
- $char_id = ord($char);
- if (($char_id >= 241) AND ($char_id <= 244)) {
- $code_data[] = $fnc_a[$char_id];
- } elseif (($char_id >= 0) AND ($char_id <= 95)) {
- $code_data[] = strpos($keys_a, $char);
- } else {
- return false;
- }
- }
- break;
- }
- case 'B': { // MODE B
- $startid = 104;
- for ($i = 0; $i < $len; ++$i) {
- $char = $code{$i};
- $char_id = ord($char);
- if (($char_id >= 241) AND ($char_id <= 244)) {
- $code_data[] = $fnc_b[$char_id];
- } elseif (($char_id >= 32) AND ($char_id <= 127)) {
- $code_data[] = strpos($keys_b, $char);
- } else {
- return false;
- }
- }
- break;
- }
- case 'C': { // MODE C
- $startid = 105;
- if (ord($code{0}) == 241) {
- $code_data[] = 102;
- $code = substr($code, 1);
- --$len;
- }
- if (($len % 2) != 0) {
- // the length must be even
- return false;
- }
- for ($i = 0; $i < $len; $i+=2) {
- $chrnum = $code{$i}.$code{$i+1};
- if (preg_match('/([0-9]{2})/', $chrnum) > 0) {
- $code_data[] = intval($chrnum);
- } else {
- return false;
- }
- }
- break;
- }
- default: { // MODE AUTO
- // split code into sequences
- $sequence = array();
- // get numeric sequences (if any)
- $numseq = array();
- preg_match_all('/([0-9]{4,})/', $code, $numseq, PREG_OFFSET_CAPTURE);
- if (isset($numseq[1]) AND !empty($numseq[1])) {
- $end_offset = 0;
- foreach ($numseq[1] as $val) {
- $offset = $val[1];
- if ($offset > $end_offset) {
- // non numeric sequence
- $sequence = array_merge($sequence, $this->get128ABsequence(substr($code, $end_offset, ($offset - $end_offset))));
- }
- // numeric sequence
- $slen = strlen($val[0]);
- if (($slen % 2) != 0) {
- // the length must be even
- --$slen;
- }
- $sequence[] = array('C', substr($code, $offset, $slen), $slen);
- $end_offset = $offset + $slen;
- }
- if ($end_offset < $len) {
- $sequence = array_merge($sequence, $this->get128ABsequence(substr($code, $end_offset)));
- }
- } else {
- // text code (non C mode)
- $sequence = array_merge($sequence, $this->get128ABsequence($code));
- }
- // process the sequence
- foreach ($sequence as $key => $seq) {
- switch($seq[0]) {
- case 'A': {
- if ($key == 0) {
- $startid = 103;
- } elseif ($sequence[($key - 1)][0] != 'A') {
- if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'B') AND (!isset($sequence[($key - 1)][3]))) {
- // single character shift
- $code_data[] = 98;
- // mark shift
- $sequence[$key][3] = true;
- } elseif (!isset($sequence[($key - 1)][3])) {
- $code_data[] = 101;
- }
- }
- for ($i = 0; $i < $seq[2]; ++$i) {
- $char = $seq[1]{$i};
- $char_id = ord($char);
- if (($char_id >= 241) AND ($char_id <= 244)) {
- $code_data[] = $fnc_a[$char_id];
- } else {
- $code_data[] = strpos($keys_a, $char);
- }
- }
- break;
- }
- case 'B': {
- if ($key == 0) {
- $tmpchr = ord($seq[1]{0});
- if (($seq[2] == 1) AND ($tmpchr >= 241) AND ($tmpchr <= 244) AND isset($sequence[($key + 1)]) AND ($sequence[($key + 1)][0] != 'B')) {
- switch ($sequence[($key + 1)][0]) {
- case 'A': {
- $startid = 103;
- $sequence[$key][0] = 'A';
- $code_data[] = $fnc_a[$tmpchr];
- break;
- }
- case 'C': {
- $startid = 105;
- $sequence[$key][0] = 'C';
- $code_data[] = $fnc_a[$tmpchr];
- break;
- }
- }
- break;
- } else {
- $startid = 104;
- }
- } elseif ($sequence[($key - 1)][0] != 'B') {
- if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'A') AND (!isset($sequence[($key - 1)][3]))) {
- // single character shift
- $code_data[] = 98;
- // mark shift
- $sequence[$key][3] = true;
- } elseif (!isset($sequence[($key - 1)][3])) {
- $code_data[] = 100;
- }
- }
- for ($i = 0; $i < $seq[2]; ++$i) {
- $char = $seq[1]{$i};
- $char_id = ord($char);
- if (($char_id >= 241) AND ($char_id <= 244)) {
- $code_data[] = $fnc_b[$char_id];
- } else {
- $code_data[] = strpos($keys_b, $char);
- }
- }
- break;
- }
- case 'C': {
- if ($key == 0) {
- $startid = 105;
- } elseif ($sequence[($key - 1)][0] != 'C') {
- $code_data[] = 99;
- }
- for ($i = 0; $i < $seq[2]; $i+=2) {
- $chrnum = $seq[1]{$i}.$seq[1]{$i+1};
- $code_data[] = intval($chrnum);
- }
- break;
- }
- }
- }
- }
- }
- // calculate check character
- $sum = $startid;
- foreach ($code_data as $key => $val) {
- $sum += ($val * ($key + 1));
- }
- // add check character
- $code_data[] = ($sum % 103);
- // add stop sequence
- $code_data[] = 106;
- $code_data[] = 107;
- // add start code at the beginning
- array_unshift($code_data, $startid);
- // build barcode array
- $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
- foreach ($code_data as $val) {
- $seq = $chr[$val];
- for ($j = 0; $j < 6; ++$j) {
- if (($j % 2) == 0) {
- $t = true; // bar
- } else {
- $t = false; // space
- }
- $w = $seq{$j};
- $bararray['bcode'][] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
- $bararray['maxw'] += $w;
- }
- }
- return $bararray;
- }
- /**
- * Split text code in A/B sequence for 128 code
- * @param $code (string) code to split.
- * @return array sequence
- * @protected
- */
- protected function get128ABsequence($code) {
- $len = strlen($code);
- $sequence = array();
- // get A sequences (if any)
- $numseq = array();
- preg_match_all('/([\0-\31])/', $code, $numseq, PREG_OFFSET_CAPTURE);
- if (isset($numseq[1]) AND !empty($numseq[1])) {
- $end_offset = 0;
- foreach ($numseq[1] as $val) {
- $offset = $val[1];
- if ($offset > $end_offset) {
- // B sequence
- $sequence[] = array('B', substr($code, $end_offset, ($offset - $end_offset)), ($offset - $end_offset));
- }
- // A sequence
- $slen = strlen($val[0]);
- $sequence[] = array('A', substr($code, $offset, $slen), $slen);
- $end_offset = $offset + $slen;
- }
- if ($end_offset < $len) {
- $sequence[] = array('B', substr($code, $end_offset), ($len - $end_offset));
- }
- } else {
- // only B sequence
- $sequence[] = array('B', $code, $len);
- }
- return $sequence;
- }
- /**
- * EAN13 and UPC-A barcodes.
- * EAN13: European Article Numbering international retail product code
- * UPC-A: Universal product code seen on almost all retail products in the USA and Canada
- * UPC-E: Short version of UPC symbol
- * @param $code (string) code to represent.
- * @param $len (string) barcode type: 6 = UPC-E, 8 = EAN8, 13 = EAN13, 12 = UPC-A
- * @return array barcode representation.
- * @protected
- */
- protected function barcode_eanupc($code, $len=13) {
- $upce = false;
- if ($len == 6) {
- $len = 12; // UPC-A
- $upce = true; // UPC-E mode
- }
- $data_len = $len - 1;
- //Padding
- $code = str_pad($code, $data_len, '0', STR_PAD_LEFT);
- $code_len = strlen($code);
- // calculate check digit
- $sum_a = 0;
- for ($i = 1; $i < $data_len; $i+=2) {
- $sum_a += $code{$i};
- }
- if ($len > 12) {
- $sum_a *= 3;
- }
- $sum_b = 0;
- for ($i = 0; $i < $data_len; $i+=2) {
- $sum_b += ($code{$i});
- }
- if ($len < 13) {
- $sum_b *= 3;
- }
- $r = ($sum_a + $sum_b) % 10;
- if($r > 0) {
- $r = (10 - $r);
- }
- if ($code_len == $data_len) {
- // add check digit
- $code .= $r;
- } elseif ($r !== intval($code{$data_len})) {
- // wrong checkdigit
- return false;
- }
- if ($len == 12) {
- // UPC-A
- $code = '0'.$code;
- ++$len;
- }
- if ($upce) {
- // convert UPC-A to UPC-E
- $tmp = substr($code, 4, 3);
- if (($tmp == '000') OR ($tmp == '100') OR ($tmp == '200')) {
- // manufacturer code ends in 000, 100, or 200
- $upce_code = substr($code, 2, 2).substr($code, 9, 3).substr($code, 4, 1);
- } else {
- $tmp = substr($code, 5, 2);
- if ($tmp == '00') {
- // manufacturer code ends in 00
- $upce_code = substr($code, 2, 3).substr($code, 10, 2).'3';
- } else {
- $tmp = substr($code, 6, 1);
- if ($tmp == '0') {
- // manufacturer code ends in 0
- $upce_code = substr($code, 2, 4).substr($code, 11, 1).'4';
- } else {
- // manufacturer code does not end in zero
- $upce_code = substr($code, 2, 5).substr($code, 11, 1);
- }
- }
- }
- }
- //Convert digits to bars
- $codes = array(
- 'A'=>array( // left odd parity
- '0'=>'0001101',
- '1'=>'0011001',
- '2'=>'0010011',
- '3'=>'0111101',
- '4'=>'0100011',
- '5'=>'0110001',
- '6'=>'0101111',
- '7'=>'0111011',
- '8'=>'0110111',
- '9'=>'0001011'),
- 'B'=>array( // left even parity
- '0'=>'0100111',
- '1'=>'0110011',
- '2'=>'0011011',
- '3'=>'0100001',
- '4'=>'0011101',
- '5'=>'0111001',
- '6'=>'0000101',
- '7'=>'0010001',
- '8'=>'0001001',
- '9'=>'0010111'),
- 'C'=>array( // right
- '0'=>'1110010',
- '1'=>'1100110',
- '2'=>'1101100',
- '3'=>'1000010',
- '4'=>'1011100',
- '5'=>'1001110',
- '6'=>'1010000',
- '7'=>'1000100',
- '8'=>'1001000',
- '9'=>'1110100')
- );
- $parities = array(
- '0'=>array('A','A','A','A','A','A'),
- '1'=>array('A','A','B','A','B','B'),
- '2'=>array('A','A','B','B','A','B'),
- '3'=>array('A','A','B','B','B','A'),
- '4'=>array('A','B','A','A','B','B'),
- '5'=>array('A','B','B','A','A','B'),
- '6'=>array('A','B','B','B','A','A'),
- '7'=>array('A','B','A','B','A','B'),
- '8'=>array('A','B','A','B','B','A'),
- '9'=>array('A','B','B','A','B','A')
- );
- $upce_parities = array();
- $upce_parities[0] = array(
- '0'=>array('B','B','B','A','A','A'),
- '1'=>array('B','B','A','B','A','A'),
- '2'=>array('B','B','A','A','B','A'),
- '3'=>array('B','B','A','A','A','B'),
- '4'=>array('B','A','B','B','A','A'),
- '5'=>array('B','A','A','B','B','A'),
- '6'=>array('B','A','A','A','B','B'),
- '7'=>array('B','A','B','A','B','A'),
- '8'=>array('B','A','B','A','A','B'),
- '9'=>array('B','A','A','B','A','B')
- );
- $upce_parities[1] = array(
- '0'=>array('A','A','A','B','B','B'),
- '1'=>array('A','A','B','A','B','B'),
- '2'=>array('A','A','B','B','A','B'),
- '3'=>array('A','A','B','B','B','A'),
- '4'=>array('A','B','A','A','B','B'),
- '5'=>array('A','B','B','A','A','B'),
- '6'=>array('A','B','B','B','A','A'),
- '7'=>array('A','B','A','B','A','B'),
- '8'=>array('A','B','A','B','B','A'),
- '9'=>array('A','B','B','A','B','A')
- );
- $k = 0;
- $seq = '101'; // left guard bar
- if ($upce) {
- $bararray = array('code' => $upce_code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
- $p = $upce_parities[$code{1}][$r];
- for ($i = 0; $i < 6; ++$i) {
- $seq .= $codes[$p[$i]][$upce_code{$i}];
- }
- $seq .= '010101'; // right guard bar
- } else {
- $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
- $half_len = ceil($len / 2);
- if ($len == 8) {
- for ($i = 0; $i < $half_len; ++$i) {
- $seq .= $codes['A'][$code{$i}];
- }
- } else {
- $p = $parities[$code{0}];
- for ($i = 1; $i < $half_len; ++$i) {
- $seq .= $codes[$p[$i-1]][$code{$i}];
- }
- }
- $seq .= '01010'; // center guard bar
- for ($i = $half_len; $i < $len; ++$i) {
- $seq .= $codes['C'][$code{$i}];
- }
- $seq .= '101'; // right guard bar
- }
- $clen = strlen($seq);
- $w = 0;
- for ($i = 0; $i < $clen; ++$i) {
- $w += 1;
- if (($i == ($clen - 1)) OR (($i < ($clen - 1)) AND ($seq{$i} != $seq{($i+1)}))) {
- if ($seq{$i} == '1') {
- $t = true; // bar
- } else {
- $t = false; // space
- }
- $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
- $bararray['maxw'] += $w;
- ++$k;
- $w = 0;
- }
- }
- return $bararray;
- }
- /**
- * UPC-Based Extentions
- * 2-Digit Ext.: Used to indicate magazines and newspaper issue numbers
- * 5-Digit Ext.: Used to mark suggested retail price of books
- * @param $code (string) code to represent.
- * @param $len (string) barcode type: 2 = 2-Digit, 5 = 5-Digit
- * @return array barcode representation.
- * @protected
- */
- protected function barcode_eanext($code, $len=5) {
- //Padding
- $code = str_pad($code, $len, '0', STR_PAD_LEFT);
- // calculate check digit
- if ($len == 2) {
- $r = $code % 4;
- } elseif ($len == 5) {
- $r = (3 * ($code{0} + $code{2} + $code{4})) + (9 * ($code{1} + $code{3}));
- $r %= 10;
- } else {
- return false;
- }
- //Convert digits to bars
- $codes = array(
- 'A'=>array( // left odd parity
- '0'=>'0001101',
- '1'=>'0011001',
- '2'=>'0010011',
- '3'=>'0111101',
- '4'=>'0100011',
- '5'=>'0110001',
- '6'=>'0101111',
- '7'=>'0111011',
- '8'=>'0110111',
- '9'=>'0001011'),
- 'B'=>array( // left even parity
- '0'=>'0100111',
- '1'=>'0110011',
- '2'=>'0011011',
- '3'=>'0100001',
- '4'=>'0011101',
- '5'=>'0111001',
- '6'=>'0000101',
- '7'=>'0010001',
- '8'=>'0001001',
- '9'=>'0010111')
- );
- $parities = array();
- $parities[2] = array(
- '0'=>array('A','A'),
- '1'=>array('A','B'),
- '2'=>array('B','A'),
- '3'=>array('B','B')
- );
- $parities[5] = array(
- '0'=>array('B','B','A','A','A'),
- '1'=>array('B','A','B','A','A'),
- '2'=>array('B','A','A','B','A'),
- '3'=>array('B','A','A','A','B'),
- '4'=>array('A','B','B','A','A'),
- '5'=>array('A','A','B','B','A'),
- '6'=>arr…
Large files files are truncated, but you can click here to view the full file