ObjectAbstract.php 34 KB

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