PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Barcode/Object/Code128.php

https://bitbucket.org/fabiancarlos/feature_seguimentos
PHP | 391 lines | 215 code | 30 blank | 146 comment | 42 complexity | 14fd91ba4fbe2315e6aa8fe87e0c8f5f MD5 | raw file
  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-2011 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Code25.php 20096 2010-01-06 02:05:09Z bkarwin $
  21. */
  22. /**
  23. * @see Zend_Barcode_Object_ObjectAbstract
  24. */
  25. require_once 'Zend/Barcode/Object/ObjectAbstract.php';
  26. /**
  27. * @see Zend_Validate_Barcode
  28. */
  29. require_once 'Zend/Validate/Barcode.php';
  30. /**
  31. * Class for generate Code128 barcode
  32. *
  33. * @category Zend
  34. * @package Zend_Barcode
  35. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  36. * @license http://framework.zend.com/license/new-bsd New BSD License
  37. */
  38. class Zend_Barcode_Object_Code128 extends Zend_Barcode_Object_ObjectAbstract
  39. {
  40. /**
  41. * Drawing of checksum
  42. * (even if it's sometime optional, most of time it's required)
  43. * @var boolean
  44. */
  45. protected $_withChecksum = true;
  46. /**
  47. * @var array
  48. */
  49. protected $_convertedText = array();
  50. protected $_codingMap = array(
  51. 0 => "11011001100", 1 => "11001101100", 2 => "11001100110",
  52. 3 => "10010011000", 4 => "10010001100", 5 => "10001001100",
  53. 6 => "10011001000", 7 => "10011000100", 8 => "10001100100",
  54. 9 => "11001001000", 10 => "11001000100", 11 => "11000100100",
  55. 12 => "10110011100", 13 => "10011011100", 14 => "10011001110",
  56. 15 => "10111001100", 16 => "10011101100", 17 => "10011100110",
  57. 18 => "11001110010", 19 => "11001011100", 20 => "11001001110",
  58. 21 => "11011100100", 22 => "11001110100", 23 => "11101101110",
  59. 24 => "11101001100", 25 => "11100101100", 26 => "11100100110",
  60. 27 => "11101100100", 28 => "11100110100", 29 => "11100110010",
  61. 30 => "11011011000", 31 => "11011000110", 32 => "11000110110",
  62. 33 => "10100011000", 34 => "10001011000", 35 => "10001000110",
  63. 36 => "10110001000", 37 => "10001101000", 38 => "10001100010",
  64. 39 => "11010001000", 40 => "11000101000", 41 => "11000100010",
  65. 42 => "10110111000", 43 => "10110001110", 44 => "10001101110",
  66. 45 => "10111011000", 46 => "10111000110", 47 => "10001110110",
  67. 48 => "11101110110", 49 => "11010001110", 50 => "11000101110",
  68. 51 => "11011101000", 52 => "11011100010", 53 => "11011101110",
  69. 54 => "11101011000", 55 => "11101000110", 56 => "11100010110",
  70. 57 => "11101101000", 58 => "11101100010", 59 => "11100011010",
  71. 60 => "11101111010", 61 => "11001000010", 62 => "11110001010",
  72. 63 => "10100110000", 64 => "10100001100", 65 => "10010110000",
  73. 66 => "10010000110", 67 => "10000101100", 68 => "10000100110",
  74. 69 => "10110010000", 70 => "10110000100", 71 => "10011010000",
  75. 72 => "10011000010", 73 => "10000110100", 74 => "10000110010",
  76. 75 => "11000010010", 76 => "11001010000", 77 => "11110111010",
  77. 78 => "11000010100", 79 => "10001111010", 80 => "10100111100",
  78. 81 => "10010111100", 82 => "10010011110", 83 => "10111100100",
  79. 84 => "10011110100", 85 => "10011110010", 86 => "11110100100",
  80. 87 => "11110010100", 88 => "11110010010", 89 => "11011011110",
  81. 90 => "11011110110", 91 => "11110110110", 92 => "10101111000",
  82. 93 => "10100011110", 94 => "10001011110", 95 => "10111101000",
  83. 96 => "10111100010", 97 => "11110101000", 98 => "11110100010",
  84. 99 => "10111011110", 100 => "10111101110", 101 => "11101011110",
  85. 102 => "11110101110",
  86. 103 => "11010000100", 104 => "11010010000", 105 => "11010011100",
  87. 106 => "1100011101011");
  88. /**
  89. * Character sets ABC
  90. * @var array
  91. */
  92. protected $_charSets = array(
  93. 'A' => array(
  94. ' ', '!', '"', '#', '$', '%', '&', "'",
  95. '(', ')', '*', '+', ',', '-', '.', '/',
  96. '0', '1', '2', '3', '4', '5', '6', '7',
  97. '8', '9', ':', ';', '<', '=', '>', '?',
  98. '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  99. 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  100. 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  101. 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
  102. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  103. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  104. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  105. 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
  106. 'FNC3', 'FNC2', 'SHIFT', 'Code C', 'Code B', 'FNC4', 'FNC1',
  107. 'START A', 'START B', 'START C', 'STOP'),
  108. 'B' => array(
  109. ' ', '!', '"', '#', '$', '%', '&', "'",
  110. '(', ')', '*', '+', ',', '-', '.', '/',
  111. '0', '1', '2', '3', '4', '5', '6', '7',
  112. '8', '9', ':', ';', '<', '=', '>', '?',
  113. '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  114. 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  115. 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  116. 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
  117. '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
  118. 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
  119. 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
  120. 'x', 'y', 'z', '{', '|', '}', '~', 0x7F,
  121. 'FNC3', 'FNC2', 'SHIFT', 'Code C', 'FNC4', 'Code A', 'FNC1',
  122. 'START A', 'START B', 'START C', 'STOP',),
  123. 'C' => array(
  124. '00', '01', '02', '03', '04', '05', '06', '07', '08', '09',
  125. '10', '11', '12', '13', '14', '15', '16', '17', '18', '19',
  126. '20', '21', '22', '23', '24', '25', '26', '27', '28', '29',
  127. '30', '31', '32', '33', '34', '35', '36', '37', '38', '39',
  128. '40', '41', '42', '43', '44', '45', '46', '47', '48', '49',
  129. '50', '51', '52', '53', '54', '55', '56', '57', '58', '59',
  130. '60', '61', '62', '63', '64', '65', '66', '67', '68', '69',
  131. '70', '71', '72', '73', '74', '75', '76', '77', '78', '79',
  132. '80', '81', '82', '83', '84', '85', '86', '87', '88', '89',
  133. '90', '91', '92', '93', '94', '95', '96', '97', '98', '99',
  134. 'Code B', 'Code A', 'FNC1', 'START A', 'START B', 'START C', 'STOP'));
  135. /*'A' => array(
  136. ' '=>0, '!'=>1, '"'=>2, '#'=>3, '$'=>4, '%'=>5, '&'=>6, "'"=>7,
  137. '('=>8, ')'=>9, '*'=>10, '+'=>11, ','=>12, '-'=>13, '.'=>14, '/'=>15,
  138. '0'=>16, '1'=>17, '2'=>18, '3'=>19, '4'=>20, '5'=>21, '6'=>22, '7'=>23,
  139. '8'=>24, '9'=>25, ':'=>26, ';'=>27, '<'=>28, '='=>29, '>'=>30, '?'=>31,
  140. '@'=>32, 'A'=>33, 'B'=>34, 'C'=>35, 'D'=>36, 'E'=>37, 'F'=>38, 'G'=>39,
  141. 'H'=>40, 'I'=>41, 'J'=>42, 'K'=>43, 'L'=>44, 'M'=>45, 'N'=>46, 'O'=>47,
  142. 'P'=>48, 'Q'=>49, 'R'=>50, 'S'=>51, 'T'=>52, 'U'=>53, 'V'=>54, 'W'=>55,
  143. 'X'=>56, 'Y'=>57, 'Z'=>58, '['=>59, '\\'=>60, ']'=>61, '^'=>62, '_'=>63,
  144. 0x00=>64, 0x01=>65, 0x02=>66, 0x03=>67, 0x04=>68, 0x05=>69, 0x06=>70, 0x07=>71,
  145. 0x08=>72, 0x09=>73, 0x0A=>74, 0x0B=>75, 0x0C=>76, 0x0D=>77, 0x0E=>78, 0x0F=>79,
  146. 0x10=>80, 0x11=>81, 0x12=>82, 0x13=>83, 0x14=>84, 0x15=>85, 0x16=>86, 0x17=>87,
  147. 0x18=>88, 0x19=>89, 0x1A=>90, 0x1B=>91, 0x1C=>92, 0x1D=>93, 0x1E=>94, 0x1F=>95,
  148. 'FNC3'=>96, 'FNC2'=>97, 'SHIFT'=>98, 'Code C'=>99, 'Code B'=>100, 'FNC4'=>101, 'FNC1'=>102, 'START A'=>103,
  149. 'START B'=>104, 'START C'=>105, 'STOP'=>106),
  150. 'B' => array(
  151. ' '=>0, '!'=>1, '"'=>2, '#'=>3, '$'=>4, '%'=>5, '&'=>6, "'"=>7,
  152. '('=>8, ')'=>9, '*'=>10, '+'=>11, ','=>12, '-'=>13, '.'=>14, '/'=>15,
  153. '0'=>16, '1'=>17, '2'=>18, '3'=>19, '4'=>20, '5'=>21, '6'=>22, '7'=>23,
  154. '8'=>24, '9'=>25, ':'=>26, ';'=>27, '<'=>28, '='=>29, '>'=>30, '?'=>31,
  155. '@'=>32, 'A'=>33, 'B'=>34, 'C'=>35, 'D'=>36, 'E'=>37, 'F'=>38, 'G'=>39,
  156. 'H'=>40, 'I'=>41, 'J'=>42, 'K'=>43, 'L'=>44, 'M'=>45, 'N'=>46, 'O'=>47,
  157. 'P'=>48, 'Q'=>49, 'R'=>50, 'S'=>51, 'T'=>52, 'U'=>53, 'V'=>54, 'W'=>55,
  158. 'X'=>56, 'Y'=>57, 'Z'=>58, '['=>59, '\\'=>60, ']'=>61, '^'=>62, '_'=>63,
  159. '`' =>64, 'a'=>65, 'b'=>66, 'c'=>67, 'd'=>68, 'e'=>69, 'f'=>70, 'g'=>71,
  160. 'h'=>72, 'i'=>73, 'j'=>74, 'k'=>75, 'l'=>76, 'm'=>77, 'n'=>78, 'o'=>79,
  161. 'p'=>80, 'q'=>81, 'r'=>82, 's'=>83, 't'=>84, 'u'=>85, 'v'=>86, 'w'=>87,
  162. 'x'=>88, 'y'=>89, 'z'=>90, '{'=>91, '|'=>92, '}'=>93, '~'=>94, 0x7F=>95,
  163. 'FNC3'=>96, 'FNC2'=>97, 'SHIFT'=>98, 'Code C'=>99, 'FNC4'=>100, 'Code A'=>101, 'FNC1'=>102, 'START A'=>103,
  164. 'START B'=>104, 'START C'=>105, 'STOP'=>106,),
  165. 'C' => array(
  166. '00'=>0, '01'=>1, '02'=>2, '03'=>3, '04'=>4, '05'=>5, '06'=>6, '07'=>7, '08'=>8, '09'=>9,
  167. '10'=>10, '11'=>11, '12'=>12, '13'=>13, '14'=>14, '15'=>15, '16'=>16, '17'=>17, '18'=>18, '19'=>19,
  168. '20'=>20, '21'=>21, '22'=>22, '23'=>23, '24'=>24, '25'=>25, '26'=>26, '27'=>27, '28'=>28, '29'=>29,
  169. '30'=>30, '31'=>31, '32'=>32, '33'=>33, '34'=>34, '35'=>35, '36'=>36, '37'=>37, '38'=>38, '39'=>39,
  170. '40'=>40, '41'=>41, '42'=>42, '43'=>43, '44'=>44, '45'=>45, '46'=>46, '47'=>47, '48'=>48, '49'=>49,
  171. '50'=>50, '51'=>51, '52'=>52, '53'=>53, '54'=>54, '55'=>55, '56'=>56, '57'=>57, '58'=>58, '59'=>59,
  172. '60'=>60, '61'=>61, '62'=>62, '63'=>63, '64'=>64, '65'=>65, '66'=>66, '67'=>67, '68'=>68, '69'=>69,
  173. '70'=>70, '71'=>71, '72'=>72, '73'=>73, '74'=>74, '75'=>75, '76'=>76, '77'=>77, '78'=>78, '79'=>79,
  174. '80'=>80, '81'=>81, '82'=>82, '83'=>83, '84'=>84, '85'=>85, '86'=>86, '87'=>87, '88'=>88, '89'=>89,
  175. '90'=>90, '91'=>91, '92'=>92, '93'=>93, '94'=>94, '95'=>95, '96'=>96, '97'=>97, '98'=>98, '99'=>99,
  176. 'Code B'=>100, 'Code A'=>101, 'FNC1'=>102, 'START A'=>103, 'START B'=>104, 'START C'=>105, 'STOP'=>106));*/
  177. /**
  178. * Width of the barcode (in pixels)
  179. * @return integer
  180. */
  181. protected function _calculateBarcodeWidth()
  182. {
  183. $quietZone = $this->getQuietZone();
  184. // Each characters contain 11 bars...
  185. $characterLength = 11 * $this->_barThinWidth * $this->_factor;
  186. $convertedChars = count($this->_convertToBarcodeChars($this->getText()));
  187. if ($this->_withChecksum) {
  188. $convertedChars++;
  189. }
  190. $encodedData = $convertedChars * $characterLength;
  191. // ...except the STOP character (13)
  192. $encodedData += $characterLength + 2 * $this->_barThinWidth * $this->_factor;
  193. $width = $quietZone + $encodedData + $quietZone;
  194. return $width;
  195. }
  196. /**
  197. * Partial check of code128 barcode
  198. * @return void
  199. */
  200. protected function _checkParams()
  201. {
  202. }
  203. /**
  204. * Prepare array to draw barcode
  205. * @return array
  206. */
  207. protected function _prepareBarcode()
  208. {
  209. $barcodeTable = array();
  210. $convertedChars = $this->_convertToBarcodeChars($this->getText());
  211. if ($this->_withChecksum) {
  212. $convertedChars[] = $this->getChecksum($this->getText());
  213. }
  214. // STOP CHARACTER
  215. $convertedChars[] = 106;
  216. foreach ($convertedChars as $barcodeChar) {
  217. $barcodePattern = $this->_codingMap[$barcodeChar];
  218. foreach (str_split($barcodePattern) as $c) {
  219. $barcodeTable[] = array($c, $this->_barThinWidth, 0, 1);
  220. }
  221. }
  222. return $barcodeTable;
  223. }
  224. /**
  225. * Checks if the next $length chars of $string starting at $pos are numeric.
  226. * Returns false if the end of the string is reached.
  227. * @param string $string String to search
  228. * @param int $pos Starting position
  229. * @param int $length Length to search
  230. * @return bool
  231. */
  232. protected static function _isDigit($string, $pos, $length = 2)
  233. {
  234. if ($pos + $length > strlen($string)) {
  235. return false;
  236. }
  237. for ($i = $pos; $i < $pos + $length; $i++) {
  238. if (!is_numeric($string[$i])) {
  239. return false;
  240. }
  241. }
  242. return true;
  243. }
  244. /**
  245. * Convert string to barcode string
  246. * @return array
  247. */
  248. protected function _convertToBarcodeChars($string)
  249. {
  250. $string = (string) $string;
  251. if (!strlen($string)) {
  252. return array();
  253. }
  254. if (isset($this->_convertedText[md5($string)])) {
  255. return $this->_convertedText[md5($string)];
  256. }
  257. $currentCharset = null;
  258. $sum = 0;
  259. $fak = 0;
  260. $result = array();
  261. for ($pos = 0; $pos < strlen($string); $pos++) {
  262. $char = $string[$pos];
  263. $code = null;
  264. if (self::_isDigit($string, $pos, 4) && $currentCharset != 'C'
  265. || self::_isDigit($string, $pos, 2) && $currentCharset == 'C') {
  266. /**
  267. * Switch to C if the next 4 chars are numeric or stay C if the next 2
  268. * chars are numeric
  269. */
  270. if ($currentCharset != 'C') {
  271. if ($pos == 0) {
  272. $code = array_search("START C", $this->_charSets['C']);
  273. } else {
  274. $code = array_search("Code C", $this->_charSets[$currentCharset]);
  275. }
  276. $result[] = $code;
  277. $currentCharset = 'C';
  278. }
  279. } else if (in_array($char, $this->_charSets['B']) && $currentCharset != 'B'
  280. && !(in_array($char, $this->_charSets['A']) && $currentCharset == 'A')) {
  281. /**
  282. * Switch to B as B contains the char and B is not the current charset.
  283. */
  284. if ($pos == 0) {
  285. $code = array_search("START B", $this->_charSets['B']);
  286. } else {
  287. $code = array_search("Code B", $this->_charSets[$currentCharset]);
  288. }
  289. $result[] = $code;
  290. $currentCharset = 'B';
  291. } else if (array_key_exists($char, $this->_charSets['A']) && $currentCharset != 'A'
  292. && !(array_key_exists($char, $this->_charSets['B']) && $currentCharset == 'B')) {
  293. /**
  294. * Switch to C as C contains the char and C is not the current charset.
  295. */
  296. if ($pos == 0) {
  297. $code = array_search("START A", $this->_charSets['A']);
  298. } else {
  299. $code =array_search("Code A", $this->_charSets[$currentCharset]);
  300. }
  301. $result[] = $code;
  302. $currentCharset = 'A';
  303. }
  304. if ($currentCharset == 'C') {
  305. $code = array_search(substr($string, $pos, 2), $this->_charSets['C']);
  306. $pos++; //Two chars from input
  307. } else {
  308. $code = array_search($string[$pos], $this->_charSets[$currentCharset]);
  309. }
  310. $result[] = $code;
  311. }
  312. $this->_convertedText[md5($string)] = $result;
  313. return $result;
  314. }
  315. /**
  316. * Set text to encode
  317. * @param string $value
  318. * @return Zend_Barcode_Object
  319. */
  320. public function setText($value)
  321. {
  322. $this->_text = $value;
  323. return $this;
  324. }
  325. /**
  326. * Retrieve text to encode
  327. * @return string
  328. */
  329. public function getText()
  330. {
  331. return $this->_text;
  332. }
  333. /**
  334. * Get barcode checksum
  335. *
  336. * @param string $text
  337. * @return int
  338. */
  339. public function getChecksum($text)
  340. {
  341. $tableOfChars = $this->_convertToBarcodeChars($text);
  342. $sum = $tableOfChars[0];
  343. unset($tableOfChars[0]);
  344. $k = 1;
  345. foreach ($tableOfChars as $char) {
  346. $sum += ($k++) * $char;
  347. }
  348. $checksum = $sum % 103;
  349. return $checksum;
  350. }
  351. /**
  352. * Standard validation for most of barcode objects
  353. * @param string $value
  354. * @param array $options
  355. */
  356. protected function _validateText($value, $options = array())
  357. {
  358. // @TODO: add code128 validator
  359. return true;
  360. }
  361. }