ObjectAbstract.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  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-2010 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-2010 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. /**
  1103. * Standard validation for most of barcode objects
  1104. * @param string $value
  1105. * @param array $options
  1106. */
  1107. protected function _validateText($value, $options = array())
  1108. {
  1109. $validatorName = (isset($options['validator'])) ? $options['validator'] : $this->getType();
  1110. $validator = new Zend_Validate_Barcode(array(
  1111. 'adapter' => $validatorName,
  1112. 'checksum' => false,
  1113. ));
  1114. $checksumCharacter = '';
  1115. $withChecksum = false;
  1116. if ($this->_mandatoryChecksum) {
  1117. $checksumCharacter = $this->_substituteChecksumCharacter;
  1118. $withChecksum = true;
  1119. }
  1120. $value = $this->_addLeadingZeros($value, $withChecksum) . $checksumCharacter;
  1121. if (!$validator->isValid($value)) {
  1122. $message = implode("\n", $validator->getMessages());
  1123. /**
  1124. * @see Zend_Barcode_Object_Exception
  1125. */
  1126. require_once 'Zend/Barcode/Object/Exception.php';
  1127. throw new Zend_Barcode_Object_Exception($message);
  1128. }
  1129. }
  1130. /**
  1131. * Each child must prepare the barcode and return
  1132. * a table like array(
  1133. * 0 => array(
  1134. * 0 => int (visible(black) or not(white))
  1135. * 1 => int (width of the bar)
  1136. * 2 => float (0->1 position from the top of the beginning of the bar in %)
  1137. * 3 => float (0->1 position from the top of the end of the bar in %)
  1138. * ),
  1139. * 1 => ...
  1140. * )
  1141. *
  1142. * @return array
  1143. */
  1144. abstract protected function _prepareBarcode();
  1145. /**
  1146. * Checking of parameters after all settings
  1147. *
  1148. * @return void
  1149. */
  1150. abstract protected function _checkParams();
  1151. /**
  1152. * Allow each child to draw something else
  1153. *
  1154. * @return void
  1155. */
  1156. protected function _preDrawBarcode()
  1157. {
  1158. }
  1159. /**
  1160. * Allow each child to draw something else
  1161. * (ex: bearer bars in interleaved 2 of 5 code)
  1162. *
  1163. * @return void
  1164. */
  1165. protected function _postDrawBarcode()
  1166. {
  1167. }
  1168. }