1<?php 2/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */ 3 4/** 5 * Image_Barcode2_Driver_Code39 class 6 * 7 * Image_Barcode2_Code39 creates Code 3 of 9 ( Code39 ) barcode images. 8 * It's implementation borrows heavily for the perl module GD::Barcode::Code39 9 * 10 * PHP versions 5 11 * 12 * LICENSE: This source file is subject to version 3.0 of the PHP license 13 * that is available through the world-wide-web at the following URI: 14 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 15 * the PHP License and are unable to obtain it through the web, please 16 * send a note to license@php.net so we can mail you a copy immediately. 17 * 18 * @category Image 19 * @package Image_Barcode2 20 * @author Ryan Briones <ryanbriones@webxdesign.org> 21 * @copyright 2005 The PHP Group 22 * @license http://www.php.net/license/3_0.txt PHP License 3.0 23 * @link http://pear.php.net/package/Image_Barcode2 24 */ 25 26require_once 'Image/Barcode2/Driver.php'; 27require_once 'Image/Barcode2/Common.php'; 28require_once 'Image/Barcode2/DualWidth.php'; 29require_once 'Image/Barcode2/Exception.php'; 30 31/** 32 * Code 3 of 9 33 * 34 * Package which provides a method to create Code 3 of 9 using GD library. 35 * 36 * @category Image 37 * @package Image_Barcode2 38 * @author Ryan Briones <ryanbriones@webxdesign.org> 39 * @copyright 2005 The PHP Group 40 * @license http://www.php.net/license/3_0.txt PHP License 3.0 41 * @version Release: @package_version@ 42 * @link http://pear.php.net/package/Image_Barcode2 43 * @since Image_Barcode2 0.5 44 */ 45class Image_Barcode2_Driver_Code39 extends Image_Barcode2_Common implements Image_Barcode2_Driver, Image_Barcode2_DualWidth 46{ 47 /** 48 * Coding map 49 * @var array 50 */ 51 private $_codingmap = array( 52 '0' => '000110100', 53 '1' => '100100001', 54 '2' => '001100001', 55 '3' => '101100000', 56 '4' => '000110001', 57 '5' => '100110000', 58 '6' => '001110000', 59 '7' => '000100101', 60 '8' => '100100100', 61 '9' => '001100100', 62 'A' => '100001001', 63 'B' => '001001001', 64 'C' => '101001000', 65 'D' => '000011001', 66 'E' => '100011000', 67 'F' => '001011000', 68 'G' => '000001101', 69 'H' => '100001100', 70 'I' => '001001100', 71 'J' => '000011100', 72 'K' => '100000011', 73 'L' => '001000011', 74 'M' => '101000010', 75 'N' => '000010011', 76 'O' => '100010010', 77 'P' => '001010010', 78 'Q' => '000000111', 79 'R' => '100000110', 80 'S' => '001000110', 81 'T' => '000010110', 82 'U' => '110000001', 83 'V' => '011000001', 84 'W' => '111000000', 85 'X' => '010010001', 86 'Y' => '110010000', 87 'Z' => '011010000', 88 '-' => '010000101', 89 '*' => '010010100', 90 '+' => '010001010', 91 '$' => '010101000', 92 '%' => '000101010', 93 '/' => '010100010', 94 '.' => '110000100', 95 ' ' => '011000100' 96 ); 97 98 /** 99 * Class constructor 100 * 101 * @param Image_Barcode2_Writer $writer Library to use. 102 */ 103 public function __construct(Image_Barcode2_Writer $writer) 104 { 105 parent::__construct($writer); 106 $this->setBarcodeHeight(50); 107 $this->setBarcodeWidthThin(1); 108 $this->setBarcodeWidthThick(3); 109 } 110 111 112 /** 113 * Validate barcode 114 * 115 * @return void 116 * @throws Image_Barcode2_Exception 117 */ 118 public function validate() 119 { 120 // Check barcode for invalid characters 121 if (preg_match("/[^0-9A-Z\-*+\$%\/. ]/", $this->getBarcode())) { 122 throw new Image_Barcode2_Exception('Invalid barcode'); 123 } 124 } 125 126 127 /** 128 * Make an image resource using the GD image library 129 * 130 * @return resource The Barcode Image (TM) 131 * 132 * @author Ryan Briones <ryanbriones@webxdesign.org> 133 */ 134 public function draw() 135 { 136 $text = $this->getBarcode(); 137 $writer = $this->getWriter(); 138 $fontsize = $this->getFontSize(); 139 140 // add start and stop * characters 141 $final_text = '*' . $text . '*'; 142 143 $barcode = ''; 144 foreach (str_split($final_text) as $character) { 145 $barcode .= $this->_dumpCode($this->_codingmap[$character] . '0'); 146 } 147 148 $barcode_len = strlen($barcode); 149 150 // Create GD image object 151 $img = $writer->imagecreate($barcode_len, $this->getBarcodeHeight()); 152 153 // Allocate black and white colors to the image 154 $black = $writer->imagecolorallocate($img, 0, 0, 0); 155 $white = $writer->imagecolorallocate($img, 255, 255, 255); 156 $font_height = $writer->imagefontheight($fontsize); 157 $font_width = $writer->imagefontwidth($fontsize); 158 159 // fill background with white color 160 $writer->imagefill($img, 0, 0, $white); 161 162 // Initialize X position 163 $xpos = 0; 164 165 // draw barcode bars to image 166 foreach (str_split($barcode) as $character_code) { 167 if ($character_code == 0) { 168 $writer->imageline( 169 $img, 170 $xpos, 171 0, 172 $xpos, 173 $this->getBarcodeHeight() - $font_height - 1, 174 $white 175 ); 176 } else { 177 $writer->imageline( 178 $img, 179 $xpos, 180 0, 181 $xpos, 182 $this->getBarcodeHeight() - $font_height - 1, 183 $black 184 ); 185 } 186 187 $xpos++; 188 } 189 190 // draw text under barcode 191 if ($this->showText) { 192 $writer->imagestring( 193 $img, 194 $fontsize, 195 ($barcode_len - $font_width * strlen($text)) / 2, 196 $this->getBarcodeHeight() - $font_height, 197 $text, 198 $black 199 ); 200 } 201 202 203 return $img; 204 } 205 206 207 /** 208 * _dumpCode is a PHP implementation of dumpCode from the Perl module 209 * GD::Barcode::Code39. I royally screwed up when trying to do the thing 210 * my own way the first time. This way works. 211 * 212 * @param string $code Code39 barcode code 213 * 214 * @return string $result barcode line code 215 * @access private 216 * @author Ryan Briones <ryanbriones@webxdesign.org> 217 */ 218 private function _dumpCode($code) 219 { 220 $result = ''; 221 $color = 1; // 1: Black, 0: White 222 223 // if $bit is 1, line is wide; if $bit is 0 line is thin 224 foreach (str_split($code) as $bit) { 225 if ($bit == 1) { 226 $result .= str_repeat($color, $this->getBarcodeWidthThick()); 227 } else { 228 $result .= str_repeat($color, $this->getBarcodeWidthThin()); 229 } 230 231 $color = ($color == 0) ? 1 : 0; 232 } 233 234 return $result; 235 } 236} 237