ObjectAbstract.php 30 KB

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