ObjectAbstract.php 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Barcode
  17. * @subpackage Object
  18. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * Class for generate Barcode
  24. *
  25. * @category Zend
  26. * @package Zend_Barcode
  27. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  28. * @license http://framework.zend.com/license/new-bsd New BSD License
  29. */
  30. abstract class Zend_Barcode_Object_ObjectAbstract
  31. {
  32. /**
  33. * Namespace of the barcode for autoloading
  34. * @var string
  35. */
  36. protected $_barcodeNamespace = 'Zend_Barcode_Object';
  37. /**
  38. * Set of drawing instructions
  39. * @var array
  40. */
  41. protected $_instructions = array();
  42. /**
  43. * Barcode type
  44. * @var string
  45. */
  46. protected $_type = null;
  47. /**
  48. * Height of the object
  49. * @var integer
  50. */
  51. protected $_height = null;
  52. /**
  53. * Width of the object
  54. * @var integer
  55. */
  56. protected $_width = null;
  57. /**
  58. * Height of the bar
  59. * @var integer
  60. */
  61. protected $_barHeight = 50;
  62. /**
  63. * Width of a thin bar
  64. * @var integer
  65. */
  66. protected $_barThinWidth = 1;
  67. /**
  68. * Width of a thick bar
  69. * @var integer
  70. */
  71. protected $_barThickWidth = 3;
  72. /**
  73. * Factor to multiply bar and font measure
  74. * (barHeight, barThinWidth, barThickWidth & fontSize)
  75. * @var integer
  76. */
  77. protected $_factor = 1;
  78. /**
  79. * Font and bars color of the object
  80. * @var integer
  81. */
  82. protected $_foreColor = 0x000000;
  83. /**
  84. * Background color of the object
  85. * @var integer
  86. */
  87. protected $_backgroundColor = 0xFFFFFF;
  88. /**
  89. * Activate/deactivate border of the object
  90. * @var boolean
  91. */
  92. protected $_withBorder = false;
  93. /**
  94. * Orientation of the barcode in degrees
  95. * @var float
  96. */
  97. protected $_orientation = 0;
  98. /**
  99. * Offset from the top the object
  100. * (calculated from the orientation)
  101. * @var integer
  102. */
  103. protected $_offsetTop = null;
  104. /**
  105. * Offset from the left the object
  106. * (calculated from the orientation)
  107. * @var integer
  108. */
  109. protected $_offsetLeft = null;
  110. /**
  111. * Text to display
  112. * @var string
  113. */
  114. protected $_text = null;
  115. /**
  116. * Display (or not) human readable text
  117. * @var boolean
  118. */
  119. protected $_drawText = true;
  120. /**
  121. * Adjust (or not) position of human readable characters with barcode
  122. * @var boolean
  123. */
  124. protected $_stretchText = false;
  125. /**
  126. * Font resource
  127. * - integer (1 to 5): corresponds to GD included fonts
  128. * - string: corresponds to path of a TTF font
  129. * @var integer|string
  130. */
  131. protected $_font = null;
  132. /**
  133. * Font size
  134. * @var float
  135. */
  136. protected $_fontSize = 10;
  137. /**
  138. * Drawing of checksum
  139. * @var boolean
  140. */
  141. protected $_withChecksum = false;
  142. /**
  143. * Drawing of checksum inside text
  144. * @var boolean
  145. */
  146. protected $_withChecksumInText = false;
  147. /**
  148. * Fix barcode length (numeric or string like 'even')
  149. * @var $_barcodeLength integer | string
  150. */
  151. protected $_barcodeLength = null;
  152. /**
  153. * Activate automatic addition of leading zeros
  154. * if barcode length is fixed
  155. * @var $_addLeadingZeros boolean
  156. */
  157. protected $_addLeadingZeros = true;
  158. /**
  159. * TTF font name: can be set before instanciation of the object
  160. * @var string
  161. */
  162. protected static $_staticFont = null;
  163. /**
  164. * Constructor
  165. * @param array|Zend_Config $options
  166. * @return void
  167. */
  168. public function __construct($options = null)
  169. {
  170. if (self::$_staticFont !== null) {
  171. $this->_font = self::$_staticFont;
  172. }
  173. if ($options instanceof Zend_Config) {
  174. $options = $options->toArray();
  175. }
  176. if (is_array($options)) {
  177. $this->setOptions($options);
  178. }
  179. $this->_type = strtolower(substr(get_class($this), strlen($this->_barcodeNamespace) + 1));
  180. }
  181. /**
  182. * Set barcode state from options array
  183. * @param array $options
  184. * @return Zend_Barcode_Object
  185. */
  186. public function setOptions($options)
  187. {
  188. foreach ($options as $key => $value) {
  189. $method = 'set' . $key;
  190. if (method_exists($this, $method)) {
  191. $this->$method($value);
  192. }
  193. }
  194. return $this;
  195. }
  196. /**
  197. * Set barcode state from config object
  198. * @param Zend_Config $config
  199. * @return Zend_Barcode_Object
  200. */
  201. public function setConfig(Zend_Config $config)
  202. {
  203. return $this->setOptions($config->toArray());
  204. }
  205. /**
  206. * Set barcode namespace for autoloading
  207. *
  208. * @param string $namespace
  209. * @return Zend_Barcode_Object
  210. */
  211. public function setBarcodeNamespace($namespace)
  212. {
  213. $this->_barcodeNamespace = $namespace;
  214. return $this;
  215. }
  216. /**
  217. * Retrieve barcode namespace
  218. *
  219. * @return string
  220. */
  221. public function getBarcodeNamespace()
  222. {
  223. return $this->_barcodeNamespace;
  224. }
  225. /**
  226. * Retrieve type of barcode
  227. * @return string
  228. */
  229. public function getType()
  230. {
  231. return $this->_type;
  232. }
  233. /**
  234. * Set height of the barcode bar
  235. * @param integer $value
  236. * @return Zend_Barcode_Object
  237. * @throw Zend_Barcode_Object_Exception
  238. */
  239. public function setBarHeight($value)
  240. {
  241. if (intval($value) <= 0) {
  242. require_once 'Zend/Barcode/Object/Exception.php';
  243. throw new Zend_Barcode_Object_Exception(
  244. 'Bar height must be greater than 0'
  245. );
  246. }
  247. $this->_barHeight = intval($value);
  248. return $this;
  249. }
  250. /**
  251. * Get height of the barcode bar
  252. * @return integer
  253. */
  254. public function getBarHeight()
  255. {
  256. return $this->_barHeight;
  257. }
  258. /**
  259. * Set thickness of thin bar
  260. * @param integer $value
  261. * @return Zend_Barcode_Object
  262. * @throw Zend_Barcode_Object_Exception
  263. */
  264. public function setBarThinWidth($value)
  265. {
  266. if (intval($value) <= 0) {
  267. require_once 'Zend/Barcode/Object/Exception.php';
  268. throw new Zend_Barcode_Object_Exception(
  269. 'Bar width must be greater than 0'
  270. );
  271. }
  272. $this->_barThinWidth = intval($value);
  273. return $this;
  274. }
  275. /**
  276. * Get thickness of thin bar
  277. * @return integer
  278. */
  279. public function getBarThinWidth()
  280. {
  281. return $this->_barThinWidth;
  282. }
  283. /**
  284. * Set thickness of thick bar
  285. * @param integer $value
  286. * @return Zend_Barcode_Object
  287. * @throw Zend_Barcode_Object_Exception
  288. */
  289. public function setBarThickWidth($value)
  290. {
  291. if (intval($value) <= 0) {
  292. require_once 'Zend/Barcode/Object/Exception.php';
  293. throw new Zend_Barcode_Object_Exception(
  294. 'Bar width must be greater than 0'
  295. );
  296. }
  297. $this->_barThickWidth = intval($value);
  298. return $this;
  299. }
  300. /**
  301. * Get thickness of thick bar
  302. * @return integer
  303. */
  304. public function getBarThickWidth()
  305. {
  306. return $this->_barThickWidth;
  307. }
  308. /**
  309. * Set factor applying to
  310. * thinBarWidth - thickBarWidth - barHeight - fontSize
  311. * @param integer $value
  312. * @return Zend_Barcode_Object
  313. * @throw Zend_Barcode_Object_Exception
  314. */
  315. public function setFactor($value)
  316. {
  317. if (floatval($value) <= 0) {
  318. require_once 'Zend/Barcode/Object/Exception.php';
  319. throw new Zend_Barcode_Object_Exception(
  320. 'Factor must be greater than 0'
  321. );
  322. }
  323. $this->_factor = floatval($value);
  324. return $this;
  325. }
  326. /**
  327. * Get factor applying to
  328. * thinBarWidth - thickBarWidth - barHeight - fontSize
  329. * @return integer
  330. */
  331. public function getFactor()
  332. {
  333. return $this->_factor;
  334. }
  335. /**
  336. * Set color of the barcode and text
  337. * @param string $value
  338. * @return Zend_Barcode_Object
  339. * @throw Zend_Barcode_Object_Exception
  340. */
  341. public function setForeColor($value)
  342. {
  343. if (preg_match('`\#[0-9A-F]{6}`', $value)) {
  344. $this->_foreColor = hexdec($value);
  345. } elseif (is_numeric($value) && $value >= 0 && $value <= 16777125) {
  346. $this->_foreColor = intval($value);
  347. } else {
  348. require_once 'Zend/Barcode/Object/Exception.php';
  349. throw new Zend_Barcode_Object_Exception(
  350. 'Text color must be set as #[0-9A-F]{6}'
  351. );
  352. }
  353. return $this;
  354. }
  355. /**
  356. * Retrieve color of the barcode and text
  357. * @return unknown
  358. */
  359. public function getForeColor()
  360. {
  361. return $this->_foreColor;
  362. }
  363. /**
  364. * Set the color of the background
  365. * @param integer $value
  366. * @return Zend_Barcode_Object
  367. * @throw Zend_Barcode_Object_Exception
  368. */
  369. public function setBackgroundColor($value)
  370. {
  371. if (preg_match('`\#[0-9A-F]{6}`', $value)) {
  372. $this->_backgroundColor = hexdec($value);
  373. } elseif (is_numeric($value) && $value >= 0 && $value <= 16777125) {
  374. $this->_backgroundColor = intval($value);
  375. } else {
  376. require_once 'Zend/Barcode/Object/Exception.php';
  377. throw new Zend_Barcode_Object_Exception(
  378. 'Background color must be set as #[0-9A-F]{6}'
  379. );
  380. }
  381. return $this;
  382. }
  383. /**
  384. * Retrieve background color of the image
  385. * @return integer
  386. */
  387. public function getBackgroundColor()
  388. {
  389. return $this->_backgroundColor;
  390. }
  391. /**
  392. * Activate/deactivate drawing of the bar
  393. * @param boolean $value
  394. * @return Zend_Barcode_Object
  395. */
  396. public function setWithBorder($value)
  397. {
  398. $this->_withBorder = (bool) $value;
  399. return $this;
  400. }
  401. /**
  402. * Retrieve if border are draw or not
  403. * @return boolean
  404. */
  405. public function getWithBorder()
  406. {
  407. return $this->_withBorder;
  408. }
  409. /**
  410. * Allow fast inversion of font/bars color and background color
  411. * @return Zend_Barcode_Object
  412. */
  413. public function setReverseColor()
  414. {
  415. $tmp = $this->_foreColor;
  416. $this->_foreColor = $this->_backgroundColor;
  417. $this->_backgroundColor = $tmp;
  418. return $this;
  419. }
  420. /**
  421. * Set orientation of barcode and text
  422. * @param float $value
  423. * @return Zend_Barcode_Object
  424. * @throw Zend_Barcode_Object_Exception
  425. */
  426. public function setOrientation($value)
  427. {
  428. $this->_orientation = floatval($value) - floor(floatval($value) / 360) * 360;
  429. return $this;
  430. }
  431. /**
  432. * Retrieve orientation of barcode and text
  433. * @return float
  434. */
  435. public function getOrientation()
  436. {
  437. return $this->_orientation;
  438. }
  439. /**
  440. * Set text to encode
  441. * @param string $value
  442. * @return Zend_Barcode_Object
  443. */
  444. public function setText($value)
  445. {
  446. $this->_text = trim($value);
  447. return $this;
  448. }
  449. /**
  450. * Retrieve text to encode
  451. * @return string
  452. */
  453. public function getText()
  454. {
  455. $text = $this->_text;
  456. if ($this->_withChecksum) {
  457. $text .= $this->getChecksum($this->_text);
  458. }
  459. return $this->_addLeadingZeros($text);
  460. }
  461. /**
  462. * Automatically add leading zeros if barcode length is fixed
  463. * @param string $text
  464. * @param boolean $withoutChecksum
  465. */
  466. protected function _addLeadingZeros($text, $withoutChecksum = false)
  467. {
  468. if ($this->_barcodeLength && $this->_addLeadingZeros) {
  469. if (is_int($this->_barcodeLength)) {
  470. $length = $withoutChecksum ? ($this->_barcodeLength - 1) : $this->_barcodeLength;
  471. if (strlen($text) < $length) {
  472. $text = str_repeat('0', $length - strlen($text)) . $text;
  473. }
  474. } else {
  475. if ($this->_barcodeLength == 'even') {
  476. $omitChecksum = (int) $this->_withChecksum && $withoutChecksum;
  477. $text = ((strlen($text) - $omitChecksum) % 2 ? '0' . $text : $text);
  478. }
  479. }
  480. }
  481. return $text;
  482. }
  483. /**
  484. * Retrieve text to encode
  485. * @return string
  486. */
  487. public function getRawText()
  488. {
  489. return $this->_text;
  490. }
  491. /**
  492. * Retrieve text to display
  493. * @return string
  494. */
  495. public function getTextToDisplay()
  496. {
  497. if ($this->_withChecksumInText) {
  498. return $this->getText();
  499. } else {
  500. return $this->_addLeadingZeros($this->_text, true);
  501. }
  502. }
  503. /**
  504. * Activate/deactivate drawing of text to encode
  505. * @param boolean $value
  506. * @return Zend_Barcode_Object
  507. */
  508. public function setDrawText($value)
  509. {
  510. $this->_drawText = (bool) $value;
  511. return $this;
  512. }
  513. /**
  514. * Retrieve if drawing of text to encode is enabled
  515. * @return boolean
  516. */
  517. public function getDrawText()
  518. {
  519. return $this->_drawText;
  520. }
  521. /**
  522. * Activate/deactivate the adjustment of the position
  523. * of the characters to the position of the bars
  524. * @param boolean $value
  525. * @return Zend_Barcode_Object
  526. * @throw Zend_Barcode_Object_Exception
  527. */
  528. public function setStretchText($value)
  529. {
  530. $this->_stretchText = (bool) $value;
  531. return $this;
  532. }
  533. /**
  534. * Retrieve if the adjustment of the position of the characters
  535. * to the position of the bars is enabled
  536. * @return boolean
  537. */
  538. public function getStretchText()
  539. {
  540. return $this->_stretchText;
  541. }
  542. /**
  543. * Activate/deactivate the automatic generation
  544. * of the checksum character
  545. * added to the barcode text
  546. * @param boolean $value
  547. * @return Zend_Barcode_Object
  548. */
  549. public function setWithChecksum($value)
  550. {
  551. $this->_withChecksum = (bool) $value;
  552. return $this;
  553. }
  554. /**
  555. * Retrieve if the checksum character is automatically
  556. * added to the barcode text
  557. * @return boolean
  558. */
  559. public function getWithChecksum()
  560. {
  561. return $this->_withChecksum;
  562. }
  563. /**
  564. * Activate/deactivate the automatic generation
  565. * of the checksum character
  566. * added to the barcode text
  567. * @param boolean $value
  568. * @return Zend_Barcode_Object
  569. * @throw Zend_Barcode_Object_Exception
  570. */
  571. public function setWithChecksumInText($value)
  572. {
  573. $this->_withChecksumInText = (bool) $value;
  574. return $this;
  575. }
  576. /**
  577. * Retrieve if the checksum character is automatically
  578. * added to the barcode text
  579. * @return boolean
  580. */
  581. public function getWithChecksumInText()
  582. {
  583. return $this->_withChecksumInText;
  584. }
  585. /**
  586. * Set the font for all instances of barcode
  587. * @param string $font
  588. * @return void
  589. */
  590. public static function setBarcodeFont($font)
  591. {
  592. if (is_string($font) || (is_int($font) && $font >= 1 && $font <= 5)) {
  593. self::$_staticFont = $font;
  594. }
  595. }
  596. /**
  597. * Set the font:
  598. * - if integer between 1 and 5, use gd built-in fonts
  599. * - if string, $value is assumed to be the path to a TTF font
  600. * @param integer|string $value
  601. * @return Zend_Barcode_Object
  602. * @throw Zend_Barcode_Object_Exception
  603. */
  604. public function setFont($value)
  605. {
  606. if (is_int($value) && $value >= 1 && $value <= 5) {
  607. if (!extension_loaded('gd')) {
  608. require_once 'Zend/Barcode/Object/Exception.php';
  609. throw new Zend_Barcode_Object_Exception(
  610. 'GD extension is required to use numeric font'
  611. );
  612. }
  613. // Case of numeric font with GD
  614. $this->_font = $value;
  615. // In this case font size is given by:
  616. $this->_fontSize = imagefontheight($value);
  617. } elseif (is_string($value)) {
  618. $this->_font = $value;
  619. } else {
  620. require_once 'Zend/Barcode/Object/Exception.php';
  621. throw new Zend_Barcode_Object_Exception(sprintf(
  622. 'Invalid font "%s" provided to setFont()',
  623. $value
  624. ));
  625. }
  626. return $this;
  627. }
  628. /**
  629. * Retrieve the font
  630. * @return integer|string
  631. */
  632. public function getFont()
  633. {
  634. return $this->_font;
  635. }
  636. /**
  637. * Set the size of the font in case of TTF
  638. * @param float $value
  639. * @return Zend_Barcode_Object
  640. * @throw Zend_Barcode_Object_Exception
  641. */
  642. public function setFontSize($value)
  643. {
  644. if (is_numeric($this->_font)) {
  645. // Case of numeric font with GD
  646. return $this;
  647. }
  648. if (!is_numeric($value)) {
  649. require_once 'Zend/Barcode/Object/Exception.php';
  650. throw new Zend_Barcode_Object_Exception(
  651. 'Font size must be a numeric value'
  652. );
  653. }
  654. $this->_fontSize = $value;
  655. return $this;
  656. }
  657. /**
  658. * Retrieve the size of the font in case of TTF
  659. * @return float
  660. */
  661. public function getFontSize()
  662. {
  663. return $this->_fontSize;
  664. }
  665. /**
  666. * Quiet zone before first bar
  667. * and after the last bar
  668. * @return integer
  669. */
  670. public function getQuietZone()
  671. {
  672. return 10 * $this->_barThinWidth * $this->_factor;
  673. }
  674. /**
  675. * Add an instruction in the array of instructions
  676. * @param array $instruction
  677. */
  678. protected function _addInstruction(array $instruction)
  679. {
  680. $this->_instructions[] = $instruction;
  681. }
  682. /**
  683. * Retrieve the set of drawing instructions
  684. * @return array
  685. */
  686. public function getInstructions()
  687. {
  688. return $this->_instructions;
  689. }
  690. /**
  691. * Add a polygon drawing instruction in the set of instructions
  692. * @param array $points
  693. * @param integer $color
  694. * @param boolean $filled
  695. */
  696. protected function _addPolygon(array $points, $color = null, $filled = true)
  697. {
  698. if ($color === null) {
  699. $color = $this->_foreColor;
  700. }
  701. $this->_addInstruction(array(
  702. 'type' => 'polygon',
  703. 'points' => $points,
  704. 'color' => $color,
  705. 'filled' => $filled,
  706. ));
  707. }
  708. /**
  709. * Add a text drawing instruction in the set of instructions
  710. * @param string $text
  711. * @param float $size
  712. * @param array $position
  713. * @param string $font
  714. * @param integer $color
  715. * @param string $alignment
  716. * @param float $orientation
  717. */
  718. protected function _addText(
  719. $text,
  720. $size,
  721. $position,
  722. $font,
  723. $color,
  724. $alignment = 'center',
  725. $orientation = 0
  726. ) {
  727. if ($color === null) {
  728. $color = $this->_foreColor;
  729. }
  730. $this->_addInstruction(array(
  731. 'type' => 'text',
  732. 'text' => $text,
  733. 'size' => $size,
  734. 'position' => $position,
  735. 'font' => $font,
  736. 'color' => $color,
  737. 'alignment' => $alignment,
  738. 'orientation' => $orientation,
  739. ));
  740. }
  741. /**
  742. * Checking of parameters after all settings
  743. * @return void
  744. */
  745. public function checkParams()
  746. {
  747. $this->_checkText();
  748. $this->_checkFontAndOrientation();
  749. $this->_checkParams();
  750. return true;
  751. }
  752. /**
  753. * Check if a text is really provided to barcode
  754. * @return void
  755. * @throw Zend_Barcode_Object_Exception
  756. */
  757. protected function _checkText($value = null)
  758. {
  759. if ($value === null) {
  760. $value = $this->_text;
  761. }
  762. if (!strlen($value)) {
  763. require_once 'Zend/Barcode/Object/Exception.php';
  764. throw new Zend_Barcode_Object_Exception(
  765. 'A text must be provide to Barcode before drawing'
  766. );
  767. }
  768. $this->validateText($value);
  769. }
  770. /**
  771. * Check the ratio between the thick and the thin bar
  772. * @param integer $min
  773. * @param integer $max
  774. * @return void
  775. * @throw Zend_Barcode_Object_Exception
  776. */
  777. protected function _checkRatio($min = 2, $max = 3)
  778. {
  779. $ratio = $this->_barThickWidth / $this->_barThinWidth;
  780. if (!($ratio >= $min && $ratio <= $max)) {
  781. require_once 'Zend/Barcode/Object/Exception.php';
  782. throw new Zend_Barcode_Object_Exception(sprintf(
  783. 'Ratio thick/thin bar must be between %0.1f and %0.1f (actual %0.3f)',
  784. $min,
  785. $max,
  786. $ratio
  787. ));
  788. }
  789. }
  790. /**
  791. * Drawing with an angle is just allow TTF font
  792. * @return void
  793. * @throw Zend_Barcode_Object_Exception
  794. */
  795. protected function _checkFontAndOrientation()
  796. {
  797. if (is_numeric($this->_font) && $this->_orientation != 0) {
  798. require_once 'Zend/Barcode/Object/Exception.php';
  799. throw new Zend_Barcode_Object_Exception(
  800. 'Only drawing with TTF font allow orientation of the barcode.'
  801. );
  802. }
  803. }
  804. /**
  805. * Width of the result image
  806. * (before any rotation)
  807. * @return integer
  808. */
  809. protected function _calculateWidth()
  810. {
  811. return (int) $this->_withBorder
  812. + $this->_calculateBarcodeWidth()
  813. + (int) $this->_withBorder;
  814. }
  815. /**
  816. * Calculate the width of the barcode
  817. * @return integer
  818. */
  819. abstract protected function _calculateBarcodeWidth();
  820. /**
  821. * Height of the result object
  822. * @return integer
  823. */
  824. protected function _calculateHeight()
  825. {
  826. return (int) $this->_withBorder * 2
  827. + $this->_calculateBarcodeHeight()
  828. + (int) $this->_withBorder * 2;
  829. }
  830. /**
  831. * Height of the barcode
  832. * @return integer
  833. */
  834. protected function _calculateBarcodeHeight()
  835. {
  836. $textHeight = 0;
  837. $extraHeight = 0;
  838. if ($this->_drawText) {
  839. $textHeight += $this->_fontSize;
  840. $extraHeight = 2;
  841. }
  842. return ($this->_barHeight + $textHeight) * $this->_factor + $extraHeight;
  843. }
  844. /**
  845. * Get height of the result object
  846. * @return integer
  847. */
  848. public function getHeight($recalculate = false)
  849. {
  850. if ($this->_height === null || $recalculate) {
  851. $this->_height =
  852. abs($this->_calculateHeight() * cos($this->_orientation / 180 * pi()))
  853. + abs($this->_calculateWidth() * sin($this->_orientation / 180 * pi()));
  854. }
  855. return $this->_height;
  856. }
  857. /**
  858. * Get width of the result object
  859. * @return integer
  860. */
  861. public function getWidth($recalculate = false)
  862. {
  863. if ($this->_width === null || $recalculate) {
  864. $this->_width =
  865. abs($this->_calculateWidth() * cos($this->_orientation / 180 * pi()))
  866. + abs($this->_calculateHeight() * sin($this->_orientation / 180 * pi()));
  867. }
  868. return $this->_width;
  869. }
  870. /**
  871. * Calculate the offset from the left of the object
  872. * if an orientation is activated
  873. * @param boolean $recalculate
  874. * @return float
  875. */
  876. public function getOffsetLeft($recalculate = false)
  877. {
  878. if ($this->_offsetLeft === null || $recalculate) {
  879. $this->_offsetLeft = - min(array(
  880. 0 * cos(
  881. $this->_orientation / 180 * pi()) - 0 * sin(
  882. $this->_orientation / 180 * pi()),
  883. 0 * cos(
  884. $this->_orientation / 180 * pi()) - $this->_calculateBarcodeHeight() * sin(
  885. $this->_orientation / 180 * pi()),
  886. $this->_calculateBarcodeWidth() * cos(
  887. $this->_orientation / 180 * pi()) - $this->_calculateBarcodeHeight() * sin(
  888. $this->_orientation / 180 * pi()),
  889. $this->_calculateBarcodeWidth() * cos(
  890. $this->_orientation / 180 * pi()) - 0 * sin(
  891. $this->_orientation / 180 * pi()),
  892. ));
  893. }
  894. return $this->_offsetLeft;
  895. }
  896. /**
  897. * Calculate the offset from the top of the object
  898. * if an orientation is activated
  899. * @param boolean $recalculate
  900. * @return float
  901. */
  902. public function getOffsetTop($recalculate = false)
  903. {
  904. if ($this->_offsetTop === null || $recalculate) {
  905. $this->_offsetTop = - min(array(
  906. 0 * cos(
  907. $this->_orientation / 180 * pi()) + 0 * sin(
  908. $this->_orientation / 180 * pi()),
  909. $this->_calculateBarcodeHeight() * cos(
  910. $this->_orientation / 180 * pi()) + 0 * sin(
  911. $this->_orientation / 180 * pi()),
  912. $this->_calculateBarcodeHeight() * cos(
  913. $this->_orientation / 180 * pi()) + $this->_calculateBarcodeWidth() * sin(
  914. $this->_orientation / 180 * pi()),
  915. 0 * cos(
  916. $this->_orientation / 180 * pi()) + $this->_calculateBarcodeWidth() * sin(
  917. $this->_orientation / 180 * pi()),
  918. ));
  919. }
  920. return $this->_offsetTop;
  921. }
  922. /**
  923. * Apply rotation on a point in X/Y dimensions
  924. * @param float $x1 x-position before rotation
  925. * @param float $y1 y-position before rotation
  926. * @return array Array of two elements corresponding to the new XY point
  927. */
  928. protected function _rotate($x1, $y1)
  929. {
  930. $x2 = $x1 * cos($this->_orientation / 180 * pi())
  931. - $y1 * sin($this->_orientation / 180 * pi())
  932. + $this->getOffsetLeft();
  933. $y2 = $y1 * cos($this->_orientation / 180 * pi())
  934. + $x1 * sin($this->_orientation / 180 * pi())
  935. + $this->getOffsetTop();
  936. return array(intval($x2) , intval($y2));
  937. }
  938. /**
  939. * Complete drawing of the barcode
  940. * @return array Table of instructions
  941. */
  942. public function draw()
  943. {
  944. $this->checkParams();
  945. $this->_drawBarcode();
  946. $this->_drawBorder();
  947. $this->_drawText();
  948. return $this->getInstructions();
  949. }
  950. /**
  951. * Draw the barcode
  952. * @return void
  953. */
  954. protected function _drawBarcode()
  955. {
  956. $barcodeTable = $this->_prepareBarcode();
  957. $this->_preDrawBarcode();
  958. $xpos = (int) $this->_withBorder;
  959. $ypos = (int) $this->_withBorder;
  960. $point1 = $this->_rotate(0, 0);
  961. $point2 = $this->_rotate(0, $this->_calculateHeight() - 1);
  962. $point3 = $this->_rotate(
  963. $this->_calculateWidth() - 1,
  964. $this->_calculateHeight() - 1
  965. );
  966. $point4 = $this->_rotate($this->_calculateWidth() - 1, 0);
  967. $this->_addPolygon(array(
  968. $point1,
  969. $point2,
  970. $point3,
  971. $point4
  972. ), $this->_backgroundColor);
  973. $xpos += $this->getQuietZone();
  974. $barLength = $this->_barHeight * $this->_factor;
  975. foreach ($barcodeTable as $bar) {
  976. $width = $bar[1] * $this->_factor;
  977. if ($bar[0]) {
  978. $point1 = $this->_rotate($xpos, $ypos + $bar[2] * $barLength);
  979. $point2 = $this->_rotate($xpos, $ypos + $bar[3] * $barLength);
  980. $point3 = $this->_rotate(
  981. $xpos + $width - 1,
  982. $ypos + $bar[3] * $barLength
  983. );
  984. $point4 = $this->_rotate(
  985. $xpos + $width - 1,
  986. $ypos + $bar[2] * $barLength
  987. );
  988. $this->_addPolygon(array(
  989. $point1,
  990. $point2,
  991. $point3,
  992. $point4,
  993. ));
  994. }
  995. $xpos += $width;
  996. }
  997. $this->_postDrawBarcode();
  998. }
  999. /**
  1000. * Partial function to draw border
  1001. * @return void
  1002. */
  1003. protected function _drawBorder()
  1004. {
  1005. if ($this->_withBorder) {
  1006. $point1 = $this->_rotate(0, 0);
  1007. $point2 = $this->_rotate($this->_calculateWidth() - 1, 0);
  1008. $point3 = $this->_rotate(
  1009. $this->_calculateWidth() - 1,
  1010. $this->_calculateHeight() - 1
  1011. );
  1012. $point4 = $this->_rotate(0, $this->_calculateHeight() - 1);
  1013. $this->_addPolygon(array(
  1014. $point1,
  1015. $point2,
  1016. $point3,
  1017. $point4,
  1018. $point1,
  1019. ), $this->_foreColor, false);
  1020. }
  1021. }
  1022. /**
  1023. * Partial function to draw text
  1024. * @return void
  1025. */
  1026. protected function _drawText()
  1027. {
  1028. if ($this->_drawText) {
  1029. $text = $this->getTextToDisplay();
  1030. if ($this->_stretchText) {
  1031. $textLength = strlen($text);
  1032. $space = ($this->_calculateWidth() - 2 * $this->getQuietZone()) / $textLength;
  1033. for ($i = 0; $i < $textLength; $i ++) {
  1034. $leftPosition = $this->getQuietZone() + $space * ($i + 0.5);
  1035. $this->_addText(
  1036. $text{$i},
  1037. $this->_fontSize * $this->_factor,
  1038. $this->_rotate(
  1039. $leftPosition,
  1040. (int) $this->_withBorder * 2
  1041. + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1
  1042. ),
  1043. $this->_font,
  1044. $this->_foreColor,
  1045. 'center',
  1046. - $this->_orientation
  1047. );
  1048. }
  1049. } else {
  1050. $this->_addText(
  1051. $text,
  1052. $this->_fontSize * $this->_factor,
  1053. $this->_rotate(
  1054. $this->_calculateWidth() / 2,
  1055. (int) $this->_withBorder * 2
  1056. + $this->_factor * ($this->_barHeight + $this->_fontSize) + 1
  1057. ),
  1058. $this->_font,
  1059. $this->_foreColor,
  1060. 'center',
  1061. - $this->_orientation
  1062. );
  1063. }
  1064. }
  1065. }
  1066. /**
  1067. * Each child must verify allowed characters
  1068. *
  1069. * @return void
  1070. */
  1071. abstract public function validateText($value);
  1072. protected function _validateText($value, $options = array())
  1073. {
  1074. $validatorName = (isset($options['validator'])) ? $options['validator'] : $this->getType();
  1075. $validator = new Zend_Validate_Barcode(array(
  1076. 'adapter' => $validatorName,
  1077. 'checksum' => false,
  1078. ));
  1079. $checksumCharacter = (isset($options['substituteChecksumCharacter'])) ? $options['substituteChecksumCharacter'] : '';
  1080. if (isset($options['automaticPrepend'])) {
  1081. if (is_int($this->_barcodeLength)) {
  1082. if (strlen($value) < ($this->_barcodeLength)) {
  1083. $length = $this->_barcodeLength - strlen($checksumCharacter);
  1084. $value = str_repeat($options['automaticPrepend'], $length - strlen($value)) . $value;
  1085. }
  1086. } else {
  1087. if ($this->_barcodeLength == 'even') {
  1088. $value = (strlen($value) % 2 ? $options['automaticPrepend'] . $value : $value);
  1089. }
  1090. }
  1091. }
  1092. if (!$validator->isValid($value . $checksumCharacter)) {
  1093. $message = implode("\n", $validator->getMessages());
  1094. /**
  1095. * @see Zend_Barcode_Object_Exception
  1096. */
  1097. require_once 'Zend/Barcode/Object/Exception.php';
  1098. throw new Zend_Barcode_Object_Exception($message);
  1099. }
  1100. }
  1101. /**
  1102. * Each child must prepare the barcode and return
  1103. * a table like array(
  1104. * 0 => array(
  1105. * 0 => int (visible(black) or not(white))
  1106. * 1 => int (width of the bar)
  1107. * 2 => float (0->1 position from the top of the beginning of the bar in %)
  1108. * 3 => float (0->1 position from the top of the end of the bar in %)
  1109. * ),
  1110. * 1 => ...
  1111. * )
  1112. *
  1113. * @return array
  1114. */
  1115. abstract protected function _prepareBarcode();
  1116. /**
  1117. * Checking of parameters after all settings
  1118. *
  1119. * @return void
  1120. */
  1121. abstract protected function _checkParams();
  1122. /**
  1123. * Allow each child to draw something else
  1124. *
  1125. * @return void
  1126. */
  1127. protected function _preDrawBarcode()
  1128. {
  1129. }
  1130. /**
  1131. * Allow each child to draw something else
  1132. * (ex: bearer bars in interleaved 2 of 5 code)
  1133. *
  1134. * @return void
  1135. */
  1136. protected function _postDrawBarcode()
  1137. {
  1138. }
  1139. }