1<?php 2 3namespace jucksearm\barcode\lib; 4 5use jucksearm\barcode\lib\Barcode2D; 6 7class PDF417Factory 8{ 9 private $_attributes; 10 private $_borderPx = 1; 11 private $_marginPx = 5; 12 private $_scalePx = 1; 13 14 public function __construct() 15 { 16 $this->_attributes = [ 17 'code' => null, 18 'file' => null, 19 'size' => 100, 20 'margin' => 1, 21 'color' => '000', 22 ]; 23 } 24 25 public function __set($name, $value) 26 { 27 $setter = 'set' . $name; 28 if (method_exists($this, $setter)) { 29 // set property 30 $this->$setter($value); 31 32 return; 33 } 34 } 35 36 public function __get($name) 37 { 38 $getter = 'get' . $name; 39 if (method_exists($this, $getter)) { 40 // read property 41 return $this->$getter(); 42 } 43 } 44 45 public function setAttribute($name, $value) 46 { 47 if ($value === null) return; 48 49 $this->_attributes[$name] = $value; 50 } 51 52 public function getAttribute($name) 53 { 54 return $this->_attributes[$name]; 55 } 56 57 public function setAttributes($attrs = []) 58 { 59 array_merge($this->_attributes, $attrs); 60 } 61 62 public function getAttributes() 63 { 64 return $this->_attributes; 65 } 66 67 public function setCode($value) 68 { 69 $this->setAttribute('code', $value); 70 return $this; 71 } 72 73 public function getCode() 74 { 75 return $this->getAttribute('code'); 76 } 77 78 public function setFile($value) 79 { 80 $this->setAttribute('file', $value); 81 return $this; 82 } 83 84 public function getFile() 85 { 86 return $this->getAttribute('file'); 87 } 88 89 public function setSize($value) 90 { 91 $this->setAttribute('size', $value); 92 return $this; 93 } 94 95 public function getSize() 96 { 97 return $this->getAttribute('size') * $this->_scalePx; 98 } 99 100 public function setMargin($value) 101 { 102 $this->setAttribute('margin', $value); 103 return $this; 104 } 105 106 public function getMargin() 107 { 108 return $this->getAttribute('margin'); 109 } 110 111 public function setColor($value) 112 { 113 $this->setAttribute('color', $value); 114 return $this; 115 } 116 117 public function getColor() 118 { 119 return $this->getAttribute('color'); 120 } 121 122 public function getBarcode() 123 { 124 return new Barcode2D($this->code, 'PDF417'); 125 } 126 127 public function getHexColor() 128 { 129 $color = $this->color; 130 131 return '#'.$color; 132 } 133 134 public function getRgbColor() 135 { 136 $color = $this->color; 137 138 if (strlen($color) > 3) { 139 $r = hexdec(substr($color, 0, 2)); 140 $g = hexdec(substr($color, 2, 2)); 141 $b = hexdec(substr($color, 4, 2)); 142 } else { 143 $r = hexdec(substr($color, 0, 1).substr($color, 0, 1)); 144 $g = hexdec(substr($color, 1, 1).substr($color, 1, 1)); 145 $b = hexdec(substr($color, 2, 1).substr($color, 2, 1)); 146 } 147 148 return [$r, $g, $b]; 149 } 150 151 private function getScale() 152 { 153 $scale = []; 154 $bcd = $this->barcode->getBarcodeArray(); 155 156 if ($this->size < $bcd['num_cols']) 157 throw new \Exception('This size not render.'); 158 159 if ($this->margin > 0) { 160 $scale['frameX'] = $this->size - ($this->_borderPx * 2); 161 $scale['margin'] = round($this->size * ($this->margin / 100)); 162 $scale['area'] = $scale['frameX'] - (($scale['margin'] * 2)); 163 $scale['size'] = floor($scale['area'] / $bcd['num_cols']); 164 $scale['posX'] = $scale['margin'] + floor(($scale['area'] - ($bcd['num_cols'] * $scale['size'])) / 2); 165 $scale['posY'] = $scale['posX']; 166 $scale['frameY'] = ($bcd['num_rows'] * $scale['size']) + ($scale['posY'] * 2); 167 } else { 168 $scale['frameX'] = $this->size; 169 $scale['margin'] = 0; 170 $scale['area'] = $this->size; 171 $scale['size'] = floor($scale['area'] / $bcd['num_cols']); 172 $scale['posX'] = floor(($scale['frameX'] - ($bcd['num_cols'] * $scale['size'])) / 2); 173 $scale['posY'] = $scale['posX']; 174 $scale['frameY'] = ($bcd['num_rows'] * $scale['size']) + ($scale['posY'] * 2); 175 } 176// exit; 177 178 179 return (object) $scale; 180 } 181 182 public function getPDF417HtmlData() 183 { 184 $bcd = $this->barcode->getBarcodeArray(); 185 $color = $this->hexColor; 186 $scale = $this->scale; 187 188 if ($this->margin > 0) { 189 $pdf417Data = '<div style="position:absolute; border: solid '.$this->_borderPx.'px '.$this->hexColor.'; width:'.$scale->frameX.'px; height:'.$scale->frameY.'px">'; 190 } else { 191 $pdf417Data = '<div style="position:absolute; width:'.$scale->frameX.'px; height:'.$scale->frameY.'px">'; 192 } 193 194 $pdf417Data .= '<div style="font-size:0;position:absolute; width:'.($scale->size * $bcd['num_cols']).'px;height:'.($scale->size * $bcd['num_rows']).'px; top:'.$scale->posY.'px; left:'.$scale->posX.'px" z-index:1;>'."\n"; 195 196 $w = $scale->size; 197 $h = $scale->size; 198 199 // print bars 200 $y = 0; 201 // for each row 202 for ($r = 0; $r < $bcd['num_rows']; ++$r) { 203 $x = 0; 204 // for each column 205 for ($c = 0; $c < $bcd['num_cols']; ++$c) { 206 if ($bcd['bcode'][$r][$c] == 1) { 207 // draw a single barcode cell 208 $pdf417Data .= '<div style="background-color:'.$color.';width:'.$w.'px;height:'.$h.'px;position:absolute;left:'.$x.'px;top:'.$y.'px;"> </div>'."\n"; 209 } 210 $x += $w; 211 } 212 $y += $h; 213 } 214 215 $pdf417Data .= '</div>'."\n"; 216 217 $pdf417Data .= '</div>'."\n"; 218 219 return $pdf417Data; 220 } 221 222 public function getPDF417PngData() 223 { 224 $bcd = $this->barcode->getBarcodeArray(); 225 $this->_borderPx = 0; 226 $color = $this->rgbColor; 227 $scale = $this->scale; 228 229 $w = $bcd['num_cols'] * $scale->size; 230 $h = $bcd['num_rows'] * $scale->size; 231 232 if (function_exists('imagecreate')) { 233 $png = imagecreate($w, $h); 234 $bgcol = imagecolorallocate($png, 255, 255, 255); 235 imagecolortransparent($png, $bgcol); 236 $fgcol = imagecolorallocate($png, $color[0], $color[1], $color[2]); 237 } else { 238 return false; 239 } 240 241 // print bars 242 $y = 0; 243 // for each row 244 for ($r = 0; $r < $bcd['num_rows']; ++$r) { 245 $x = 0; 246 // for each column 247 for ($c = 0; $c < $bcd['num_cols']; ++$c) { 248 if ($bcd['bcode'][$r][$c] == 1) { 249 imagefilledrectangle($png, $x, $y, ($x + $scale->size - 1), ($y + $scale->size - 1), $fgcol); 250 } 251 $x += $scale->size; 252 } 253 $y += $scale->size; 254 } 255 256 $frame = imagecreatetruecolor($scale->frameX, $scale->frameY); 257 $blank = imagecreate($this->size, $this->size); 258 imagecolorallocate($blank, 255, 255, 255); 259 imagecopyresampled($frame, $blank, 0, 0, 0, 0, imagesx($blank), imagesy($blank), imagesx($blank), imagesy($blank)); 260 imagedestroy($blank); 261 imagecopyresampled($frame, $png, $scale->posX, $scale->posY, 0, 0, imagesx($png), imagesy($png), imagesx($png), imagesy($png)); 262 imagedestroy($png); 263 264 if ($this->file === null) { 265 ob_start(); 266 imagepng($frame); 267 $pdf417Data = ob_get_clean(); 268 } else { 269 preg_match("/\.png$/", $this->file, $output); 270 if (count($output) == 0) 271 throw new \Exception('Incorrect file extension format.'); 272 273 $filePath = explode(DIRECTORY_SEPARATOR, $this->file); 274 if (count($filePath) == 1 ) { 275 $savePath = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.$this->file; 276 } else { 277 $savePath = $this->file; 278 } 279 280 if (!@imagepng($frame, $savePath)) 281 throw new \Exception('Not found save path.'); 282 283 $pdf417Data = file_get_contents($savePath); 284 } 285 286 imagedestroy($frame); 287 288 return $pdf417Data; 289 } 290 291 public function getPDF417SvgData() 292 { 293 $bcd = $this->barcode->getBarcodeArray(); 294 $color = $this->hexColor; 295 $scale = $this->scale; 296 297 $w = $bcd['num_cols'] * $scale->size; 298 $h = $bcd['num_rows'] * $scale->size; 299 300 $repstr = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); 301 $pdf417Data = '<'.'?'.'xml version="1.0" standalone="no"'.'?'.'>'."\n"; 302 $pdf417Data .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'."\n"; 303 $pdf417Data .= '<svg width="'.$scale->frameX.'" height="'.$scale->frameY.'" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'."\n"; 304 $pdf417Data .= "\t".'<desc>'.strtr($bcd['code'], $repstr).'</desc>'."\n"; 305 306 if ($this->margin > 0) { 307 $pdf417Data .= "\t".'<g id="border" fill="none" stroke="'.$color.'">'."\n"; 308 $pdf417Data .= "\t\t".'<rect height="'.$scale->frameY.'" width="'.$scale->frameX.'" y="0" x="0" />'."\n"; 309 $pdf417Data .= "\t".'</g>'."\n"; 310 } 311 312 $pdf417Data .= "\t".'<g id="bars" fill="'.$color.'" stroke="none">'."\n"; 313 // print bars 314 $y = $scale->posY; 315 // for each row 316 for ($r = 0; $r < $bcd['num_rows']; ++$r) { 317 $x = $scale->posX; 318 // for each column 319 for ($c = 0; $c < $bcd['num_cols']; ++$c) { 320 if ($bcd['bcode'][$r][$c] == 1) { 321 // draw a single barcode cell 322 $pdf417Data .= "\t\t".'<rect x="'.$x.'" y="'.$y.'" width="'.$scale->size.'" height="'.$scale->size.'" />'."\n"; 323 } 324 $x += $scale->size; 325 } 326 $y += $scale->size; 327 } 328 $pdf417Data .= "\t".'</g>'."\n"; 329 330 $pdf417Data .= '</svg>'."\n"; 331 332 if ($this->file != null) { 333 preg_match("/\.svg$/", $this->file, $output); 334 if (count($output) == 0) 335 throw new \Exception('Incorrect file extension format.'); 336 337 $filePath = explode(DIRECTORY_SEPARATOR, $this->file); 338 if (count($filePath) == 1 ) { 339 $savePath = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.$this->file; 340 } else { 341 $savePath = $this->file; 342 } 343 344 if (!@file_put_contents($savePath, $pdf417Data)) 345 throw new \Exception('Not found save path.'); 346 } 347 348 return $pdf417Data; 349 } 350 351 public function renderHTML() 352 { 353 $pdf417Data = $this->getPDF417HtmlData(); 354 355 header('Content-Type: text/html'); 356 header('Content-Length: '.strlen($pdf417Data)); 357 header('Cache-Control: no-cache'); 358 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 359 360 echo $pdf417Data; 361 } 362 363 public function renderPNG() 364 { 365 $pdf417Data = $this->getPDF417PngData(); 366 367 header('Content-Type: image/png'); 368 header('Content-Length: '.strlen($pdf417Data)); 369 header('Cache-Control: no-cache'); 370 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 371 372 echo $pdf417Data; 373 } 374 375 public function renderSVG() 376 { 377 $pdf417Data = $this->getPDF417SvgData(); 378 379 header('Content-Type: image/svg+xml'); 380 header('Content-Length: '.strlen($pdf417Data)); 381 header('Cache-Control: no-cache'); 382 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 383 384 echo $pdf417Data; 385 } 386}