File indexing completed on 2024-12-22 05:36:29
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Barcode 0017 * @subpackage Object 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * Class for generate Barcode 0025 * 0026 * @category Zend 0027 * @package Zend_Barcode 0028 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0029 * @license http://framework.zend.com/license/new-bsd New BSD License 0030 */ 0031 abstract class Zend_Barcode_Object_ObjectAbstract 0032 { 0033 /** 0034 * Namespace of the barcode for autoloading 0035 * 0036 * @var string 0037 */ 0038 protected $_barcodeNamespace = 'Zend_Barcode_Object'; 0039 0040 /** 0041 * Set of drawing instructions 0042 * 0043 * @var array 0044 */ 0045 protected $_instructions = array(); 0046 0047 /** 0048 * Barcode type 0049 * 0050 * @var string 0051 */ 0052 protected $_type = null; 0053 0054 /** 0055 * Height of the object 0056 * 0057 * @var integer 0058 */ 0059 protected $_height = null; 0060 0061 /** 0062 * Width of the object 0063 * 0064 * @var integer 0065 */ 0066 protected $_width = null; 0067 0068 /** 0069 * Height of the bar 0070 * 0071 * @var integer 0072 */ 0073 protected $_barHeight = 50; 0074 0075 /** 0076 * Width of a thin bar 0077 * 0078 * @var integer 0079 */ 0080 protected $_barThinWidth = 1; 0081 0082 /** 0083 * Width of a thick bar 0084 * 0085 * @var integer 0086 */ 0087 protected $_barThickWidth = 3; 0088 0089 /** 0090 * Factor to multiply bar and font measure 0091 * (barHeight, barThinWidth, barThickWidth & fontSize) 0092 * 0093 * @var integer 0094 */ 0095 protected $_factor = 1; 0096 0097 /** 0098 * Font and bars color of the object 0099 * 0100 * @var integer 0101 */ 0102 protected $_foreColor = 0x000000; 0103 0104 /** 0105 * Background color of the object 0106 * 0107 * @var integer 0108 */ 0109 protected $_backgroundColor = 0xFFFFFF; 0110 0111 /** 0112 * Activate/deactivate border of the object 0113 * 0114 * @var boolean 0115 */ 0116 protected $_withBorder = false; 0117 0118 /** 0119 * Activate/deactivate drawing of quiet zones 0120 * 0121 * @var boolean 0122 */ 0123 protected $_withQuietZones = true; 0124 0125 /** 0126 * Force quiet zones even if 0127 * 0128 * @var boolean 0129 */ 0130 protected $_mandatoryQuietZones = false; 0131 0132 /** 0133 * Orientation of the barcode in degrees 0134 * 0135 * @var float 0136 */ 0137 protected $_orientation = 0; 0138 0139 /** 0140 * Offset from the top the object 0141 * (calculated from the orientation) 0142 * 0143 * @var integer 0144 */ 0145 protected $_offsetTop = null; 0146 0147 /** 0148 * Offset from the left the object 0149 * (calculated from the orientation) 0150 * 0151 * @var integer 0152 */ 0153 protected $_offsetLeft = null; 0154 0155 /** 0156 * Text to display 0157 * 0158 * @var string 0159 */ 0160 protected $_text = null; 0161 0162 /** 0163 * Display (or not) human readable text 0164 * 0165 * @var boolean 0166 */ 0167 protected $_drawText = true; 0168 0169 /** 0170 * Adjust (or not) position of human readable characters with barcode 0171 * 0172 * @var boolean 0173 */ 0174 protected $_stretchText = false; 0175 0176 /** 0177 * Font resource 0178 * - integer (1 to 5): corresponds to GD included fonts 0179 * - string: corresponds to path of a TTF font 0180 * 0181 * @var integer|string 0182 */ 0183 protected $_font = null; 0184 0185 /** 0186 * Font size 0187 * 0188 * @var float 0189 */ 0190 protected $_fontSize = 10; 0191 0192 /** 0193 * Drawing of checksum 0194 * 0195 * @var boolean 0196 */ 0197 protected $_withChecksum = false; 0198 0199 /** 0200 * Drawing of checksum inside text 0201 * 0202 * @var boolean 0203 */ 0204 protected $_withChecksumInText = false; 0205 0206 /** 0207 * Fix barcode length (numeric or string like 'even') 0208 * 0209 * @var $_barcodeLength integer | string 0210 */ 0211 protected $_barcodeLength = null; 0212 0213 /** 0214 * Activate automatic addition of leading zeros 0215 * if barcode length is fixed 0216 * 0217 * @var $_addLeadingZeros boolean 0218 */ 0219 protected $_addLeadingZeros = true; 0220 0221 /** 0222 * Activation of mandatory checksum 0223 * to deactivate unauthorized modification 0224 * 0225 * @var $_mandatoryChecksum boolean 0226 */ 0227 protected $_mandatoryChecksum = false; 0228 0229 /** 0230 * Character used to substitute checksum character for validation 0231 * 0232 * @var $_substituteChecksumCharacter mixed 0233 */ 0234 protected $_substituteChecksumCharacter = 0; 0235 0236 /** 0237 * TTF font name: can be set before instanciation of the object 0238 * 0239 * @var string 0240 */ 0241 protected static $_staticFont = null; 0242 0243 /** 0244 * Constructor 0245 * 0246 * @param array|Zend_Config $options 0247 */ 0248 public function __construct($options = null) 0249 { 0250 $this->_getDefaultOptions(); 0251 if (self::$_staticFont !== null) { 0252 $this->_font = self::$_staticFont; 0253 } 0254 if ($options instanceof Zend_Config) { 0255 $options = $options->toArray(); 0256 } 0257 if (is_array($options)) { 0258 $this->setOptions($options); 0259 } 0260 $this->_type = strtolower( 0261 substr(get_class($this), strlen($this->_barcodeNamespace) + 1) 0262 ); 0263 if ($this->_mandatoryChecksum) { 0264 $this->_withChecksum = true; 0265 $this->_withChecksumInText = true; 0266 } 0267 } 0268 0269 /** 0270 * Set default options for particular object 0271 */ 0272 protected function _getDefaultOptions() 0273 { 0274 } 0275 0276 /** 0277 * Set barcode state from options array 0278 * 0279 * @param array $options 0280 * @return $this 0281 */ 0282 public function setOptions($options) 0283 { 0284 foreach ($options as $key => $value) { 0285 $method = 'set' . $key; 0286 if (method_exists($this, $method)) { 0287 $this->$method($value); 0288 } 0289 } 0290 return $this; 0291 } 0292 0293 /** 0294 * Set barcode state from config object 0295 * 0296 * @param Zend_Config $config 0297 * @return $this 0298 */ 0299 public function setConfig(Zend_Config $config) 0300 { 0301 return $this->setOptions($config->toArray()); 0302 } 0303 0304 /** 0305 * Set barcode namespace for autoloading 0306 * 0307 * @param string $namespace 0308 * @return $this 0309 */ 0310 public function setBarcodeNamespace($namespace) 0311 { 0312 $this->_barcodeNamespace = $namespace; 0313 return $this; 0314 } 0315 0316 /** 0317 * Retrieve barcode namespace 0318 * 0319 * @return string 0320 */ 0321 public function getBarcodeNamespace() 0322 { 0323 return $this->_barcodeNamespace; 0324 } 0325 0326 /** 0327 * Retrieve type of barcode 0328 * 0329 * @return string 0330 */ 0331 public function getType() 0332 { 0333 return $this->_type; 0334 } 0335 0336 /** 0337 * Set height of the barcode bar 0338 * 0339 * @param integer $value 0340 * @return $this 0341 * @throws Zend_Barcode_Object_Exception 0342 */ 0343 public function setBarHeight($value) 0344 { 0345 if (intval($value) <= 0) { 0346 // require_once 'Zend/Barcode/Object/Exception.php'; 0347 throw new Zend_Barcode_Object_Exception( 0348 'Bar height must be greater than 0' 0349 ); 0350 } 0351 $this->_barHeight = intval($value); 0352 return $this; 0353 } 0354 0355 /** 0356 * Get height of the barcode bar 0357 * 0358 * @return integer 0359 */ 0360 public function getBarHeight() 0361 { 0362 return $this->_barHeight; 0363 } 0364 0365 /** 0366 * Set thickness of thin bar 0367 * 0368 * @param integer $value 0369 * @return $this 0370 * @throws Zend_Barcode_Object_Exception 0371 */ 0372 public function setBarThinWidth($value) 0373 { 0374 if (intval($value) <= 0) { 0375 // require_once 'Zend/Barcode/Object/Exception.php'; 0376 throw new Zend_Barcode_Object_Exception( 0377 'Bar width must be greater than 0' 0378 ); 0379 } 0380 $this->_barThinWidth = intval($value); 0381 return $this; 0382 } 0383 0384 /** 0385 * Get thickness of thin bar 0386 * 0387 * @return integer 0388 */ 0389 public function getBarThinWidth() 0390 { 0391 return $this->_barThinWidth; 0392 } 0393 0394 /** 0395 * Set thickness of thick bar 0396 * 0397 * @param integer $value 0398 * @return $this 0399 * @throws Zend_Barcode_Object_Exception 0400 */ 0401 public function setBarThickWidth($value) 0402 { 0403 if (intval($value) <= 0) { 0404 // require_once 'Zend/Barcode/Object/Exception.php'; 0405 throw new Zend_Barcode_Object_Exception( 0406 'Bar width must be greater than 0' 0407 ); 0408 } 0409 $this->_barThickWidth = intval($value); 0410 return $this; 0411 } 0412 0413 /** 0414 * Get thickness of thick bar 0415 * 0416 * @return integer 0417 */ 0418 public function getBarThickWidth() 0419 { 0420 return $this->_barThickWidth; 0421 } 0422 0423 /** 0424 * Set factor applying to 0425 * thinBarWidth - thickBarWidth - barHeight - fontSize 0426 * 0427 * @param int|float|string|bool $value 0428 * @return $this 0429 * @throws Zend_Barcode_Object_Exception 0430 */ 0431 public function setFactor($value) 0432 { 0433 if (floatval($value) <= 0) { 0434 // require_once 'Zend/Barcode/Object/Exception.php'; 0435 throw new Zend_Barcode_Object_Exception( 0436 'Factor must be greater than 0' 0437 ); 0438 } 0439 $this->_factor = floatval($value); 0440 return $this; 0441 } 0442 0443 /** 0444 * Get factor applying to 0445 * thinBarWidth - thickBarWidth - barHeight - fontSize 0446 * 0447 * @return integer 0448 */ 0449 public function getFactor() 0450 { 0451 return $this->_factor; 0452 } 0453 0454 /** 0455 * Set color of the barcode and text 0456 * 0457 * @param string $value 0458 * @return $this 0459 * @throws Zend_Barcode_Object_Exception 0460 */ 0461 public function setForeColor($value) 0462 { 0463 if (preg_match('`\#[0-9A-F]{6}`', $value)) { 0464 $this->_foreColor = hexdec($value); 0465 } elseif (is_numeric($value) && $value >= 0 && $value <= 16777125) { 0466 $this->_foreColor = intval($value); 0467 } else { 0468 // require_once 'Zend/Barcode/Object/Exception.php'; 0469 throw new Zend_Barcode_Object_Exception( 0470 'Text color must be set as #[0-9A-F]{6}' 0471 ); 0472 } 0473 return $this; 0474 } 0475 0476 /** 0477 * Retrieve color of the barcode and text 0478 * 0479 * @return unknown 0480 */ 0481 public function getForeColor() 0482 { 0483 return $this->_foreColor; 0484 } 0485 0486 /** 0487 * Set the color of the background 0488 * 0489 * @param integer $value 0490 * @return $this 0491 * @throws Zend_Barcode_Object_Exception 0492 */ 0493 public function setBackgroundColor($value) 0494 { 0495 if (preg_match('`\#[0-9A-F]{6}`', $value)) { 0496 $this->_backgroundColor = hexdec($value); 0497 } elseif (is_numeric($value) && $value >= 0 && $value <= 16777125) { 0498 $this->_backgroundColor = intval($value); 0499 } else { 0500 // require_once 'Zend/Barcode/Object/Exception.php'; 0501 throw new Zend_Barcode_Object_Exception( 0502 'Background color must be set as #[0-9A-F]{6}' 0503 ); 0504 } 0505 return $this; 0506 } 0507 0508 /** 0509 * Retrieve background color of the image 0510 * 0511 * @return integer 0512 */ 0513 public function getBackgroundColor() 0514 { 0515 return $this->_backgroundColor; 0516 } 0517 0518 /** 0519 * Activate/deactivate drawing of the bar 0520 * 0521 * @param boolean $value 0522 * @return $this 0523 */ 0524 public function setWithBorder($value) 0525 { 0526 $this->_withBorder = (bool) $value; 0527 return $this; 0528 } 0529 0530 /** 0531 * Retrieve if border are draw or not 0532 * 0533 * @return boolean 0534 */ 0535 public function getWithBorder() 0536 { 0537 return $this->_withBorder; 0538 } 0539 0540 /** 0541 * Activate/deactivate drawing of the quiet zones 0542 * 0543 * @param boolean $value 0544 * @return $this 0545 */ 0546 public function setWithQuietZones($value) 0547 { 0548 $this->_withQuietZones = (bool) $value; 0549 return $this; 0550 } 0551 0552 /** 0553 * Retrieve if quiet zones are draw or not 0554 * 0555 * @return boolean 0556 */ 0557 public function getWithQuietZones() 0558 { 0559 return $this->_withQuietZones; 0560 } 0561 0562 /** 0563 * Allow fast inversion of font/bars color and background color 0564 * 0565 * @return $this 0566 */ 0567 public function setReverseColor() 0568 { 0569 $tmp = $this->_foreColor; 0570 $this->_foreColor = $this->_backgroundColor; 0571 $this->_backgroundColor = $tmp; 0572 0573 return $this; 0574 } 0575 0576 /** 0577 * Set orientation of barcode and text 0578 * 0579 * @param int|float|string|bool $value 0580 * @return $this 0581 * @throws Zend_Barcode_Object_Exception 0582 */ 0583 public function setOrientation($value) 0584 { 0585 $value = floatval($value); 0586 $this->_orientation = $value - floor($value / 360) * 360; 0587 return $this; 0588 } 0589 0590 /** 0591 * Retrieve orientation of barcode and text 0592 * 0593 * @return float 0594 */ 0595 public function getOrientation() 0596 { 0597 return $this->_orientation; 0598 } 0599 0600 /** 0601 * Set text to encode 0602 * 0603 * @param string $value 0604 * @return $this 0605 */ 0606 public function setText($value) 0607 { 0608 $this->_text = trim($value); 0609 return $this; 0610 } 0611 0612 /** 0613 * Retrieve text to encode 0614 * 0615 * @return string 0616 */ 0617 public function getText() 0618 { 0619 $text = $this->_text; 0620 if ($this->_withChecksum) { 0621 $text .= $this->getChecksum($this->_text); 0622 } 0623 return $this->_addLeadingZeros($text); 0624 } 0625 0626 /** 0627 * Automatically add leading zeros if barcode length is fixed 0628 * 0629 * @param string $text 0630 * @param boolean $withoutChecksum 0631 * @return string 0632 */ 0633 protected function _addLeadingZeros($text, $withoutChecksum = false) 0634 { 0635 if ($this->_barcodeLength && $this->_addLeadingZeros) { 0636 $omitChecksum = (int) ($this->_withChecksum && $withoutChecksum); 0637 if (is_int($this->_barcodeLength)) { 0638 $length = $this->_barcodeLength - $omitChecksum; 0639 if (strlen($text) < $length) { 0640 $text = str_repeat('0', $length - strlen($text)) . $text; 0641 } 0642 } else { 0643 if ($this->_barcodeLength == 'even') { 0644 $text = ((strlen($text) - $omitChecksum) % 2 ? '0' . $text : $text); 0645 } 0646 } 0647 } 0648 return $text; 0649 } 0650 0651 /** 0652 * Retrieve text to encode 0653 * 0654 * @return string 0655 */ 0656 public function getRawText() 0657 { 0658 return $this->_text; 0659 } 0660 0661 /** 0662 * Retrieve text to display 0663 * 0664 * @return string 0665 */ 0666 public function getTextToDisplay() 0667 { 0668 if ($this->_withChecksumInText) { 0669 return $this->getText(); 0670 } else { 0671 return $this->_addLeadingZeros($this->_text, true); 0672 } 0673 } 0674 0675 /** 0676 * Activate/deactivate drawing of text to encode 0677 * 0678 * @param boolean $value 0679 * @return $this 0680 */ 0681 public function setDrawText($value) 0682 { 0683 $this->_drawText = (bool) $value; 0684 return $this; 0685 } 0686 0687 /** 0688 * Retrieve if drawing of text to encode is enabled 0689 * 0690 * @return boolean 0691 */ 0692 public function getDrawText() 0693 { 0694 return $this->_drawText; 0695 } 0696 0697 /** 0698 * Activate/deactivate the adjustment of the position 0699 * of the characters to the position of the bars 0700 * 0701 * @param boolean $value 0702 * @return $this 0703 * @throws Zend_Barcode_Object_Exception 0704 */ 0705 public function setStretchText($value) 0706 { 0707 $this->_stretchText = (bool) $value; 0708 return $this; 0709 } 0710 0711 /** 0712 * Retrieve if the adjustment of the position of the characters 0713 * to the position of the bars is enabled 0714 * 0715 * @return boolean 0716 */ 0717 public function getStretchText() 0718 { 0719 return $this->_stretchText; 0720 } 0721 0722 /** 0723 * Activate/deactivate the automatic generation 0724 * of the checksum character 0725 * added to the barcode text 0726 * 0727 * @param boolean $value 0728 * @return $this 0729 */ 0730 public function setWithChecksum($value) 0731 { 0732 if (!$this->_mandatoryChecksum) { 0733 $this->_withChecksum = (bool) $value; 0734 } 0735 return $this; 0736 } 0737 0738 /** 0739 * Retrieve if the checksum character is automatically 0740 * added to the barcode text 0741 * 0742 * @return boolean 0743 */ 0744 public function getWithChecksum() 0745 { 0746 return $this->_withChecksum; 0747 } 0748 0749 /** 0750 * Activate/deactivate the automatic generation 0751 * of the checksum character 0752 * added to the barcode text 0753 * 0754 * @param boolean $value 0755 * @return $this 0756 * @throws Zend_Barcode_Object_Exception 0757 */ 0758 public function setWithChecksumInText($value) 0759 { 0760 if (!$this->_mandatoryChecksum) { 0761 $this->_withChecksumInText = (bool) $value; 0762 } 0763 0764 return $this; 0765 } 0766 0767 /** 0768 * Retrieve if the checksum character is automatically 0769 * added to the barcode text 0770 * 0771 * @return boolean 0772 */ 0773 public function getWithChecksumInText() 0774 { 0775 return $this->_withChecksumInText; 0776 } 0777 0778 /** 0779 * Set the font for all instances of barcode 0780 * 0781 * @param string $font 0782 */ 0783 public static function setBarcodeFont($font) 0784 { 0785 if (is_string($font) || (is_int($font) && $font >= 1 && $font <= 5)) { 0786 self::$_staticFont = $font; 0787 } 0788 } 0789 0790 /** 0791 * Set the font: 0792 * - if integer between 1 and 5, use gd built-in fonts 0793 * - if string, $value is assumed to be the path to a TTF font 0794 * 0795 * @param integer|string $value 0796 * @return $this 0797 * @throws Zend_Barcode_Object_Exception 0798 */ 0799 public function setFont($value) 0800 { 0801 if (is_int($value) && $value >= 1 && $value <= 5) { 0802 if (!extension_loaded('gd')) { 0803 // require_once 'Zend/Barcode/Object/Exception.php'; 0804 throw new Zend_Barcode_Object_Exception( 0805 'GD extension is required to use numeric font' 0806 ); 0807 } 0808 0809 // Case of numeric font with GD 0810 $this->_font = $value; 0811 0812 // In this case font size is given by: 0813 $this->_fontSize = imagefontheight($value); 0814 } elseif (is_string($value)) { 0815 $this->_font = $value; 0816 } else { 0817 // require_once 'Zend/Barcode/Object/Exception.php'; 0818 throw new Zend_Barcode_Object_Exception( 0819 sprintf( 0820 'Invalid font "%s" provided to setFont()', 0821 $value 0822 ) 0823 ); 0824 } 0825 return $this; 0826 } 0827 0828 /** 0829 * Retrieve the font 0830 * 0831 * @return integer|string 0832 */ 0833 public function getFont() 0834 { 0835 return $this->_font; 0836 } 0837 0838 /** 0839 * Set the size of the font in case of TTF 0840 * 0841 * @param float $value 0842 * @return $this 0843 * @throws Zend_Barcode_Object_Exception 0844 */ 0845 public function setFontSize($value) 0846 { 0847 if (is_numeric($this->_font)) { 0848 // Case of numeric font with GD 0849 return $this; 0850 } 0851 0852 if (!is_numeric($value)) { 0853 // require_once 'Zend/Barcode/Object/Exception.php'; 0854 throw new Zend_Barcode_Object_Exception( 0855 'Font size must be a numeric value' 0856 ); 0857 } 0858 0859 $this->_fontSize = $value; 0860 return $this; 0861 } 0862 0863 /** 0864 * Retrieve the size of the font in case of TTF 0865 * 0866 * @return float 0867 */ 0868 public function getFontSize() 0869 { 0870 return $this->_fontSize; 0871 } 0872 0873 /** 0874 * Quiet zone before first bar 0875 * and after the last bar 0876 * 0877 * @return integer 0878 */ 0879 public function getQuietZone() 0880 { 0881 if ($this->_withQuietZones || $this->_mandatoryQuietZones) { 0882 return 10 * $this->_barThinWidth * $this->_factor; 0883 } else { 0884 return 0; 0885 } 0886 } 0887 0888 /** 0889 * Add an instruction in the array of instructions 0890 * 0891 * @param array $instruction 0892 */ 0893 protected function _addInstruction(array $instruction) 0894 { 0895 $this->_instructions[] = $instruction; 0896 } 0897 0898 /** 0899 * Retrieve the set of drawing instructions 0900 * 0901 * @return array 0902 */ 0903 public function getInstructions() 0904 { 0905 return $this->_instructions; 0906 } 0907 0908 /** 0909 * Add a polygon drawing instruction in the set of instructions 0910 * 0911 * @param array $points 0912 * @param integer $color 0913 * @param boolean $filled 0914 */ 0915 protected function _addPolygon(array $points, $color = null, $filled = true) 0916 { 0917 if ($color === null) { 0918 $color = $this->_foreColor; 0919 } 0920 $this->_addInstruction( 0921 array( 0922 'type' => 'polygon', 0923 'points' => $points, 0924 'color' => $color, 0925 'filled' => $filled, 0926 ) 0927 ); 0928 } 0929 0930 /** 0931 * Add a text drawing instruction in the set of instructions 0932 * 0933 * @param string $text 0934 * @param float $size 0935 * @param array $position 0936 * @param string $font 0937 * @param integer $color 0938 * @param string $alignment 0939 * @param float|int $orientation 0940 */ 0941 protected function _addText( 0942 $text, 0943 $size, 0944 $position, 0945 $font, 0946 $color, 0947 $alignment = 'center', 0948 $orientation = 0 0949 ) { 0950 if ($color === null) { 0951 $color = $this->_foreColor; 0952 } 0953 $this->_addInstruction( 0954 array( 0955 'type' => 'text', 0956 'text' => $text, 0957 'size' => $size, 0958 'position' => $position, 0959 'font' => $font, 0960 'color' => $color, 0961 'alignment' => $alignment, 0962 'orientation' => $orientation, 0963 ) 0964 ); 0965 } 0966 0967 /** 0968 * Checking of parameters after all settings 0969 * 0970 * @return bool 0971 */ 0972 public function checkParams() 0973 { 0974 $this->_checkText(); 0975 $this->_checkFontAndOrientation(); 0976 $this->_checkParams(); 0977 return true; 0978 } 0979 0980 /** 0981 * Check if a text is really provided to barcode 0982 * 0983 * @param string|null $value 0984 * @throws Zend_Barcode_Object_Exception 0985 */ 0986 protected function _checkText($value = null) 0987 { 0988 if ($value === null) { 0989 $value = $this->_text; 0990 } 0991 if (!strlen($value)) { 0992 // require_once 'Zend/Barcode/Object/Exception.php'; 0993 throw new Zend_Barcode_Object_Exception( 0994 'A text must be provide to Barcode before drawing' 0995 ); 0996 } 0997 $this->validateText($value); 0998 } 0999 1000 /** 1001 * Check the ratio between the thick and the thin bar 1002 * 1003 * @param int $min 1004 * @param int $max 1005 * @throws Zend_Barcode_Object_Exception 1006 */ 1007 protected function _checkRatio($min = 2, $max = 3) 1008 { 1009 $ratio = $this->_barThickWidth / $this->_barThinWidth; 1010 if (!($ratio >= $min && $ratio <= $max)) { 1011 // require_once 'Zend/Barcode/Object/Exception.php'; 1012 throw new Zend_Barcode_Object_Exception( 1013 sprintf( 1014 'Ratio thick/thin bar must be between %0.1f and %0.1f (actual %0.3f)', 1015 $min, 1016 $max, 1017 $ratio 1018 ) 1019 ); 1020 } 1021 } 1022 1023 /** 1024 * Drawing with an angle is just allow TTF font 1025 * 1026 * @throws Zend_Barcode_Object_Exception 1027 */ 1028 protected function _checkFontAndOrientation() 1029 { 1030 if (is_numeric($this->_font) && $this->_orientation != 0) { 1031 // require_once 'Zend/Barcode/Object/Exception.php'; 1032 throw new Zend_Barcode_Object_Exception( 1033 'Only drawing with TTF font allow orientation of the barcode.' 1034 ); 1035 } 1036 } 1037 1038 /** 1039 * Width of the result image (before any rotation) 1040 * 1041 * @return integer 1042 */ 1043 protected function _calculateWidth() 1044 { 1045 return (int) $this->_withBorder 1046 + $this->_calculateBarcodeWidth() 1047 + (int) $this->_withBorder; 1048 } 1049 1050 /** 1051 * Calculate the width of the barcode 1052 * 1053 * @return integer 1054 */ 1055 abstract protected function _calculateBarcodeWidth(); 1056 1057 /** 1058 * Height of the result object 1059 * 1060 * @return int 1061 */ 1062 protected function _calculateHeight() 1063 { 1064 return (int) $this->_withBorder * 2 1065 + $this->_calculateBarcodeHeight() 1066 + (int) $this->_withBorder * 2; 1067 } 1068 1069 /** 1070 * Height of the barcode 1071 * 1072 * @return int 1073 */ 1074 protected function _calculateBarcodeHeight() 1075 { 1076 $textHeight = 0; 1077 $extraHeight = 0; 1078 if ($this->_drawText) { 1079 $textHeight += $this->_fontSize; 1080 $extraHeight = 2; 1081 } 1082 1083 return ($this->_barHeight + $textHeight) * $this->_factor 1084 + $extraHeight; 1085 } 1086 1087 /** 1088 * Get height of the result object 1089 * 1090 * @param bool $recalculate 1091 * @return int 1092 */ 1093 public function getHeight($recalculate = false) 1094 { 1095 if ($this->_height === null || $recalculate) { 1096 $this->_height = 1097 abs( 1098 $this->_calculateHeight() * cos( 1099 $this->_orientation / 180 * pi() 1100 ) 1101 ) 1102 + abs( 1103 $this->_calculateWidth() * sin( 1104 $this->_orientation / 180 * pi() 1105 ) 1106 ); 1107 } 1108 return $this->_height; 1109 } 1110 1111 /** 1112 * Get width of the result object 1113 * 1114 * @param bool $recalculate 1115 * @return int 1116 */ 1117 public function getWidth($recalculate = false) 1118 { 1119 if ($this->_width === null || $recalculate) { 1120 $this->_width = 1121 abs( 1122 $this->_calculateWidth() * cos( 1123 $this->_orientation / 180 * pi() 1124 ) 1125 ) 1126 + abs( 1127 $this->_calculateHeight() * sin( 1128 $this->_orientation / 180 * pi() 1129 ) 1130 ); 1131 } 1132 return $this->_width; 1133 } 1134 1135 /** 1136 * Calculate the offset from the left of the object 1137 * if an orientation is activated 1138 * 1139 * @param bool $recalculate 1140 * @return float 1141 */ 1142 public function getOffsetLeft($recalculate = false) 1143 { 1144 if ($this->_offsetLeft === null || $recalculate) { 1145 $this->_offsetLeft = - min(array( 1146 0 * cos( 1147 $this->_orientation / 180 * pi()) - 0 * sin( 1148 $this->_orientation / 180 * pi()), 1149 0 * cos( 1150 $this->_orientation / 180 * pi()) - $this->_calculateBarcodeHeight() * sin( 1151 $this->_orientation / 180 * pi()), 1152 $this->_calculateBarcodeWidth() * cos( 1153 $this->_orientation / 180 * pi()) - $this->_calculateBarcodeHeight() * sin( 1154 $this->_orientation / 180 * pi()), 1155 $this->_calculateBarcodeWidth() * cos( 1156 $this->_orientation / 180 * pi()) - 0 * sin( 1157 $this->_orientation / 180 * pi()), 1158 )); 1159 } 1160 return $this->_offsetLeft; 1161 } 1162 1163 /** 1164 * Calculate the offset from the top of the object 1165 * if an orientation is activated 1166 * 1167 * @param bool $recalculate 1168 * @return float 1169 */ 1170 public function getOffsetTop($recalculate = false) 1171 { 1172 if ($this->_offsetTop === null || $recalculate) { 1173 $this->_offsetTop = - min(array( 1174 0 * cos( 1175 $this->_orientation / 180 * pi()) + 0 * sin( 1176 $this->_orientation / 180 * pi()), 1177 $this->_calculateBarcodeHeight() * cos( 1178 $this->_orientation / 180 * pi()) + 0 * sin( 1179 $this->_orientation / 180 * pi()), 1180 $this->_calculateBarcodeHeight() * cos( 1181 $this->_orientation / 180 * pi()) + $this->_calculateBarcodeWidth() * sin( 1182 $this->_orientation / 180 * pi()), 1183 0 * cos( 1184 $this->_orientation / 180 * pi()) + $this->_calculateBarcodeWidth() * sin( 1185 $this->_orientation / 180 * pi()), 1186 )); 1187 } 1188 return $this->_offsetTop; 1189 } 1190 1191 /** 1192 * Apply rotation on a point in X/Y dimensions 1193 * 1194 * @param float $x1 x-position before rotation 1195 * @param float $y1 y-position before rotation 1196 * @return array Array of two elements corresponding to the new XY point 1197 */ 1198 protected function _rotate($x1, $y1) 1199 { 1200 $x2 = $x1 * cos($this->_orientation / 180 * pi()) 1201 - $y1 * sin($this->_orientation / 180 * pi()) 1202 + $this->getOffsetLeft(); 1203 $y2 = $y1 * cos($this->_orientation / 180 * pi()) 1204 + $x1 * sin($this->_orientation / 180 * pi()) 1205 + $this->getOffsetTop(); 1206 1207 return array( 1208 intval($x2), 1209 intval($y2) 1210 ); 1211 } 1212 1213 /** 1214 * Complete drawing of the barcode 1215 * 1216 * @return array Table of instructions 1217 */ 1218 public function draw() 1219 { 1220 $this->checkParams(); 1221 $this->_drawBarcode(); 1222 $this->_drawBorder(); 1223 $this->_drawText(); 1224 return $this->getInstructions(); 1225 } 1226 1227 /** 1228 * Draw the barcode 1229 */ 1230 protected function _drawBarcode() 1231 { 1232 $barcodeTable = $this->_prepareBarcode(); 1233 1234 $this->_preDrawBarcode(); 1235 1236 $xpos = (int) $this->_withBorder; 1237 $ypos = (int) $this->_withBorder; 1238 1239 $point1 = $this->_rotate(0, 0); 1240 $point2 = $this->_rotate(0, $this->_calculateHeight() - 1); 1241 $point3 = $this->_rotate( 1242 $this->_calculateWidth() - 1, 1243 $this->_calculateHeight() - 1 1244 ); 1245 $point4 = $this->_rotate($this->_calculateWidth() - 1, 0); 1246 1247 $this->_addPolygon( 1248 array( 1249 $point1, 1250 $point2, 1251 $point3, 1252 $point4 1253 ), $this->_backgroundColor 1254 ); 1255 1256 $xpos += $this->getQuietZone(); 1257 $barLength = $this->_barHeight * $this->_factor; 1258 1259 foreach ($barcodeTable as $bar) { 1260 $width = $bar[1] * $this->_factor; 1261 if ($bar[0]) { 1262 $point1 = $this->_rotate($xpos, $ypos + $bar[2] * $barLength); 1263 $point2 = $this->_rotate($xpos, $ypos + $bar[3] * $barLength); 1264 $point3 = $this->_rotate( 1265 $xpos + $width - 1, 1266 $ypos + $bar[3] * $barLength 1267 ); 1268 $point4 = $this->_rotate( 1269 $xpos + $width - 1, 1270 $ypos + $bar[2] * $barLength 1271 ); 1272 $this->_addPolygon( 1273 array( 1274 $point1, 1275 $point2, 1276 $point3, 1277 $point4, 1278 ) 1279 ); 1280 } 1281 $xpos += $width; 1282 } 1283 1284 $this->_postDrawBarcode(); 1285 } 1286 1287 /** 1288 * Partial function to draw border 1289 */ 1290 protected function _drawBorder() 1291 { 1292 if ($this->_withBorder) { 1293 $point1 = $this->_rotate(0, 0); 1294 $point2 = $this->_rotate($this->_calculateWidth() - 1, 0); 1295 $point3 = $this->_rotate( 1296 $this->_calculateWidth() - 1, 1297 $this->_calculateHeight() - 1 1298 ); 1299 $point4 = $this->_rotate(0, $this->_calculateHeight() - 1); 1300 $this->_addPolygon( 1301 array( 1302 $point1, 1303 $point2, 1304 $point3, 1305 $point4, 1306 $point1, 1307 ), $this->_foreColor, false 1308 ); 1309 } 1310 } 1311 1312 /** 1313 * Partial function to draw text 1314 */ 1315 protected function _drawText() 1316 { 1317 if ($this->_drawText) { 1318 $text = $this->getTextToDisplay(); 1319 if ($this->_stretchText) { 1320 $textLength = strlen($text); 1321 $space = ($this->_calculateWidth() - 2 * $this->getQuietZone()) / $textLength; 1322 for ($i = 0; $i < $textLength; $i ++) { 1323 $leftPosition = $this->getQuietZone() + $space * ($i + 0.5); 1324 $this->_addText( 1325 $text{$i}, 1326 $this->_fontSize * $this->_factor, 1327 $this->_rotate( 1328 $leftPosition, 1329 (int) $this->_withBorder * 2 1330 + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1 1331 ), 1332 $this->_font, 1333 $this->_foreColor, 1334 'center', 1335 - $this->_orientation 1336 ); 1337 } 1338 } else { 1339 $this->_addText( 1340 $text, 1341 $this->_fontSize * $this->_factor, 1342 $this->_rotate( 1343 $this->_calculateWidth() / 2, 1344 (int) $this->_withBorder * 2 1345 + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1 1346 ), 1347 $this->_font, 1348 $this->_foreColor, 1349 'center', 1350 - $this->_orientation 1351 ); 1352 } 1353 } 1354 } 1355 1356 /** 1357 * Check for invalid characters 1358 * 1359 * @param string $value Text to be ckecked 1360 */ 1361 public function validateText($value) 1362 { 1363 $this->_validateText($value); 1364 } 1365 1366 /** 1367 * Standard validation for most of barcode objects 1368 * 1369 * @param string $value 1370 * @param array $options 1371 * @throws Zend_Barcode_Object_Exception 1372 */ 1373 protected function _validateText($value, $options = array()) 1374 { 1375 $validatorName = (isset($options['validator'])) ? $options['validator'] : $this->getType(); 1376 1377 $validator = new Zend_Validate_Barcode( 1378 array( 1379 'adapter' => $validatorName, 1380 'checksum' => false, 1381 ) 1382 ); 1383 1384 $checksumCharacter = ''; 1385 $withChecksum = false; 1386 if ($this->_mandatoryChecksum) { 1387 $checksumCharacter = $this->_substituteChecksumCharacter; 1388 $withChecksum = true; 1389 } 1390 1391 $value = $this->_addLeadingZeros($value, $withChecksum) 1392 . $checksumCharacter; 1393 1394 if (!$validator->isValid($value)) { 1395 $message = implode("\n", $validator->getMessages()); 1396 1397 /** 1398 * @see Zend_Barcode_Object_Exception 1399 */ 1400 // require_once 'Zend/Barcode/Object/Exception.php'; 1401 throw new Zend_Barcode_Object_Exception($message); 1402 } 1403 } 1404 1405 /** 1406 * Each child must prepare the barcode and return 1407 * a table like array( 1408 * 0 => array( 1409 * 0 => int (visible(black) or not(white)) 1410 * 1 => int (width of the bar) 1411 * 2 => float (0->1 position from the top of the beginning of the bar in %) 1412 * 3 => float (0->1 position from the top of the end of the bar in %) 1413 * ), 1414 * 1 => ... 1415 * ) 1416 * 1417 * @return array 1418 */ 1419 abstract protected function _prepareBarcode(); 1420 1421 /** 1422 * Checking of parameters after all settings 1423 */ 1424 abstract protected function _checkParams(); 1425 1426 /** 1427 * Allow each child to draw something else 1428 */ 1429 protected function _preDrawBarcode() 1430 { 1431 } 1432 1433 /** 1434 * Allow each child to draw something else 1435 * (ex: bearer bars in interleaved 2 of 5 code) 1436 */ 1437 protected function _postDrawBarcode() 1438 { 1439 } 1440 }