ObjectAbstract.php 32 KB

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