PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/www/libs/Zend/Barcode/Object/Code128.php

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