2
0

ObjectAbstract.php 33 KB

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