1<?php 2 3namespace jucksearm\barcode\lib; 4 5use jucksearm\barcode\lib\Barcode2D; 6 7class DatamatrixFactory 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, 'DATAMATRIX'); 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->margin > 0) { 157 $scale['frame'] = $this->size - ($this->_borderPx * 2); 158 $scale['margin'] = round($this->size * ($this->margin / 100)); 159 $scale['area'] = $scale['frame'] - (($scale['margin'] * 2)); 160 $scale['size'] = floor($scale['area'] / $bcd['num_cols']); 161 $scale['posX'] = $scale['margin'] + floor(($scale['area'] - ($bcd['num_cols'] * $scale['size'])) / 2); 162 $scale['posY'] = $scale['posX']; 163 } else { 164 $scale['frame'] = $this->size; 165 $scale['margin'] = 0; 166 $scale['area'] = $this->size; 167 $scale['size'] = floor($scale['area'] / $bcd['num_cols']); 168 $scale['posX'] = floor(($scale['frame'] - ($bcd['num_cols'] * $scale['size'])) / 2); 169 $scale['posY'] = $scale['posX']; 170 } 171 172 if ($this->size < $scale['frame']) 173 throw new \Exception('This size not render.'); 174 175 return (object) $scale; 176 } 177 178 public function getDatamatrixHtmlData() 179 { 180 $bcd = $this->barcode->getBarcodeArray(); 181 $color = $this->hexColor; 182 $scale = $this->scale; 183 184 if ($this->margin > 0) { 185 $datamatrixData = '<div style="position:absolute; border: solid '.$this->_borderPx.'px '.$this->hexColor.'; width:'.($this->size - 2).'px; height:'.($this->size - 2).'px">'; 186 } else { 187 $datamatrixData = '<div style="position:absolute; width:'.$this->size.'px; height:'.$this->size.'px">'; 188 } 189 190 $datamatrixData .= '<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"; 191 192 $w = $scale->size; 193 $h = $scale->size; 194 195 // print bars 196 $y = 0; 197 // for each row 198 for ($r = 0; $r < $bcd['num_rows']; ++$r) { 199 $x = 0; 200 // for each column 201 for ($c = 0; $c < $bcd['num_cols']; ++$c) { 202 if ($bcd['bcode'][$r][$c] == 1) { 203 // draw a single barcode cell 204 $datamatrixData .= '<div style="background-color:'.$color.';width:'.$w.'px;height:'.$h.'px;position:absolute;left:'.$x.'px;top:'.$y.'px;"> </div>'."\n"; 205 } 206 $x += $w; 207 } 208 $y += $h; 209 } 210 211 $datamatrixData .= '</div>'."\n"; 212 213 $datamatrixData .= '</div>'."\n"; 214 215 return $datamatrixData; 216 } 217 218 public function getDatamatrixPngData() 219 { 220 $bcd = $this->barcode->getBarcodeArray(); 221 $this->_borderPx = 0; 222 $color = $this->rgbColor; 223 $scale = $this->scale; 224 225 $w = $bcd['num_cols'] * $scale->size; 226 $h = $bcd['num_rows'] * $scale->size; 227 228 if (function_exists('imagecreate')) { 229 $png = imagecreate($w, $h); 230 $bgcol = imagecolorallocate($png, 255, 255, 255); 231 imagecolortransparent($png, $bgcol); 232 $fgcol = imagecolorallocate($png, $color[0], $color[1], $color[2]); 233 } else { 234 return false; 235 } 236 237 // print bars 238 $y = 0; 239 // for each row 240 for ($r = 0; $r < $bcd['num_rows']; ++$r) { 241 $x = 0; 242 // for each column 243 for ($c = 0; $c < $bcd['num_cols']; ++$c) { 244 if ($bcd['bcode'][$r][$c] == 1) { 245 imagefilledrectangle($png, $x, $y, ($x + $scale->size - 1), ($y + $scale->size - 1), $fgcol); 246 } 247 $x += $scale->size; 248 } 249 $y += $scale->size; 250 } 251 252 $frame = imagecreatetruecolor($this->size, $this->size); 253 $blank = imagecreate($this->size, $this->size); 254 imagecolorallocate($blank, 255, 255, 255); 255 imagecopyresampled($frame, $blank, 0, 0, 0, 0, imagesx($blank), imagesy($blank), imagesx($blank), imagesy($blank)); 256 imagedestroy($blank); 257 imagecopyresampled($frame, $png, $scale->posX, $scale->posY, 0, 0, imagesx($png), imagesy($png), imagesx($png), imagesy($png)); 258 imagedestroy($png); 259 260 if ($this->file === null) { 261 ob_start(); 262 imagepng($frame); 263 $datamatrixData = ob_get_clean(); 264 } else { 265 preg_match("/\.png$/", $this->file, $output); 266 if (count($output) == 0) 267 throw new \Exception('Incorrect file extension format.'); 268 269 $filePath = explode(DIRECTORY_SEPARATOR, $this->file); 270 if (count($filePath) == 1 ) { 271 $savePath = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.$this->file; 272 } else { 273 $savePath = $this->file; 274 } 275 276 if (!@imagepng($frame, $savePath)) 277 throw new \Exception('Not found save path.'); 278 279 $datamatrixData = file_get_contents($savePath); 280 } 281 282 imagedestroy($frame); 283 284 return $datamatrixData; 285 } 286 287 public function getDatamatrixSvgData() 288 { 289 $bcd = $this->barcode->getBarcodeArray(); 290 $color = $this->hexColor; 291 $scale = $this->scale; 292 293 $w = $bcd['num_cols'] * $scale->size; 294 $h = $bcd['num_rows'] * $scale->size; 295 296 $repstr = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); 297 $datamatrixData = '<'.'?'.'xml version="1.0" standalone="no"'.'?'.'>'."\n"; 298 $datamatrixData .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'."\n"; 299 $datamatrixData .= '<svg width="'.$this->size.'" height="'.$this->size.'" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'."\n"; 300 $datamatrixData .= "\t".'<desc>'.strtr($bcd['code'], $repstr).'</desc>'."\n"; 301 302 if ($this->margin > 0) { 303 $datamatrixData .= "\t".'<g id="border" fill="none" stroke="'.$color.'">'."\n"; 304 $datamatrixData .= "\t\t".'<rect height="'.$this->size.'" width="'.$this->size.'" y="0" x="0" />'."\n"; 305 $datamatrixData .= "\t".'</g>'."\n"; 306 } 307 308 $datamatrixData .= "\t".'<g id="bars" fill="'.$color.'" stroke="none">'."\n"; 309 // print bars 310 $y = $scale->posY; 311 // for each row 312 for ($r = 0; $r < $bcd['num_rows']; ++$r) { 313 $x = $scale->posX; 314 // for each column 315 for ($c = 0; $c < $bcd['num_cols']; ++$c) { 316 if ($bcd['bcode'][$r][$c] == 1) { 317 // draw a single barcode cell 318 $datamatrixData .= "\t\t".'<rect x="'.$x.'" y="'.$y.'" width="'.$scale->size.'" height="'.$scale->size.'" />'."\n"; 319 } 320 $x += $scale->size; 321 } 322 $y += $scale->size; 323 } 324 $datamatrixData .= "\t".'</g>'."\n"; 325 326 $datamatrixData .= '</svg>'."\n"; 327 328 if ($this->file != null) { 329 preg_match("/\.svg$/", $this->file, $output); 330 if (count($output) == 0) 331 throw new \Exception('Incorrect file extension format.'); 332 333 $filePath = explode(DIRECTORY_SEPARATOR, $this->file); 334 if (count($filePath) == 1 ) { 335 $savePath = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.$this->file; 336 } else { 337 $savePath = $this->file; 338 } 339 340 if (!@file_put_contents($savePath, $datamatrixData)) 341 throw new \Exception('Not found save path.'); 342 } 343 344 return $datamatrixData; 345 } 346 347 public function renderHTML() 348 { 349 $datamatrixData = $this->getDatamatrixHtmlData(); 350 351 header('Content-Type: text/html'); 352 header('Content-Length: '.strlen($datamatrixData)); 353 header('Cache-Control: no-cache'); 354 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 355 356 echo $datamatrixData; 357 } 358 359 public function renderPNG() 360 { 361 $datamatrixData = $this->getDatamatrixPngData(); 362 363 header('Content-Type: image/png'); 364 header('Content-Length: '.strlen($datamatrixData)); 365 header('Cache-Control: no-cache'); 366 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 367 368 echo $datamatrixData; 369 } 370 371 public function renderSVG() 372 { 373 $datamatrixData = $this->getDatamatrixSvgData(); 374 375 header('Content-Type: image/svg+xml'); 376 header('Content-Length: '.strlen($datamatrixData)); 377 header('Cache-Control: no-cache'); 378 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 379 380 echo $datamatrixData; 381 } 382}