BCGcode39extended.barcode.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /**
  3. *--------------------------------------------------------------------
  4. *
  5. * Sub-Class - Code 39 Extended
  6. *
  7. *--------------------------------------------------------------------
  8. * Copyright (C) Jean-Sebastien Goupil
  9. * http://www.barcodephp.com
  10. */
  11. include_once('BCGParseException.php');
  12. include_once('BCGcode39.barcode.php');
  13. class BCGcode39extended extends BCGcode39 {
  14. const EXTENDED_1 = 39;
  15. const EXTENDED_2 = 40;
  16. const EXTENDED_3 = 41;
  17. const EXTENDED_4 = 42;
  18. protected $indcheck, $data;
  19. /**
  20. * Constructor.
  21. */
  22. public function __construct() {
  23. parent::__construct();
  24. // We just put parenthesis around special characters.
  25. $this->keys[self::EXTENDED_1] = '($)';
  26. $this->keys[self::EXTENDED_2] = '(/)';
  27. $this->keys[self::EXTENDED_3] = '(+)';
  28. $this->keys[self::EXTENDED_4] = '(%)';
  29. }
  30. /**
  31. * Parses the text before displaying it.
  32. *
  33. * @param mixed $text
  34. */
  35. public function parse($text) {
  36. $this->text = $text;
  37. $data = array();
  38. $indcheck = array();
  39. $c = strlen($this->text);
  40. for ($i = 0; $i < $c; $i++) {
  41. $pos = array_search($this->text[$i], $this->keys);
  42. if ($pos === false) {
  43. // Search in extended?
  44. $extended = self::getExtendedVersion($this->text[$i]);
  45. if ($extended === false) {
  46. throw new BCGParseException('code39extended', 'The character \'' . $this->text[$i] . '\' is not allowed.');
  47. } else {
  48. $extc = strlen($extended);
  49. for ($j = 0; $j < $extc; $j++) {
  50. $v = $extended[$j];
  51. if ($v === '$') {
  52. $indcheck[] = self::EXTENDED_1;
  53. $data[] = $this->code[self::EXTENDED_1];
  54. } elseif ($v === '%') {
  55. $indcheck[] = self::EXTENDED_2;
  56. $data[] = $this->code[self::EXTENDED_2];
  57. } elseif ($v === '/') {
  58. $indcheck[] = self::EXTENDED_3;
  59. $data[] = $this->code[self::EXTENDED_3];
  60. } elseif ($v === '+') {
  61. $indcheck[] = self::EXTENDED_4;
  62. $data[] = $this->code[self::EXTENDED_4];
  63. } else {
  64. $pos2 = array_search($v, $this->keys);
  65. $indcheck[] = $pos2;
  66. $data[] = $this->code[$pos2];
  67. }
  68. }
  69. }
  70. } else {
  71. $indcheck[] = $pos;
  72. $data[] = $this->code[$pos];
  73. }
  74. }
  75. $this->setData(array($indcheck, $data));
  76. $this->addDefaultLabel();
  77. }
  78. /**
  79. * Draws the barcode.
  80. *
  81. * @param resource $im
  82. */
  83. public function draw($im) {
  84. // Starting *
  85. $this->drawChar($im, $this->code[$this->starting], true);
  86. $c = count($this->data);
  87. for ($i = 0; $i < $c; $i++) {
  88. $this->drawChar($im, $this->data[$i], true);
  89. }
  90. // Checksum (rarely used)
  91. if ($this->checksum === true) {
  92. $this->drawChar($im, $this->code[$this->checksumValue % 43], true);
  93. }
  94. // Ending *
  95. $this->drawChar($im, $this->code[$this->ending], true);
  96. $this->drawText($im, 0, 0, $this->positionX, $this->thickness);
  97. }
  98. /**
  99. * Returns the maximal size of a barcode.
  100. *
  101. * @param int $w
  102. * @param int $h
  103. * @return int[]
  104. */
  105. public function getDimension($w, $h) {
  106. $textlength = 13 * count($this->data);
  107. $startlength = 13;
  108. $checksumlength = 0;
  109. if ($this->checksum === true) {
  110. $checksumlength = 13;
  111. }
  112. $endlength = 13;
  113. $w += $startlength + $textlength + $checksumlength + $endlength;
  114. $h += $this->thickness;
  115. return BCGBarcode1D::getDimension($w, $h);
  116. }
  117. /**
  118. * Validates the input.
  119. */
  120. protected function validate() {
  121. $c = count($this->data);
  122. if ($c === 0) {
  123. throw new BCGParseException('code39extended', 'No data has been entered.');
  124. }
  125. parent::validate();
  126. }
  127. /**
  128. * Overloaded method to calculate checksum.
  129. */
  130. protected function calculateChecksum() {
  131. $this->checksumValue = 0;
  132. $c = count($this->indcheck);
  133. for ($i = 0; $i < $c; $i++) {
  134. $this->checksumValue += $this->indcheck[$i];
  135. }
  136. $this->checksumValue = $this->checksumValue % 43;
  137. }
  138. /**
  139. * Saves data into the classes.
  140. *
  141. * This method will save data, calculate real column number
  142. * (if -1 was selected), the real error level (if -1 was
  143. * selected)... It will add Padding to the end and generate
  144. * the error codes.
  145. *
  146. * @param array $data
  147. */
  148. private function setData($data) {
  149. $this->indcheck = $data[0];
  150. $this->data = $data[1];
  151. $this->calculateChecksum();
  152. }
  153. /**
  154. * Returns the extended reprensentation of the character.
  155. *
  156. * @param string $char
  157. * @return string
  158. */
  159. private static function getExtendedVersion($char) {
  160. $o = ord($char);
  161. if ($o === 0) {
  162. return '%U';
  163. } elseif ($o >= 1 && $o <= 26) {
  164. return '$' . chr($o + 64);
  165. } elseif (($o >= 33 && $o <= 44) || $o === 47 || $o === 48) {
  166. return '/' . chr($o + 32);
  167. } elseif ($o >= 97 && $o <= 122) {
  168. return '+' . chr($o - 32);
  169. } elseif ($o >= 27 && $o <= 31) {
  170. return '%' . chr($o + 38);
  171. } elseif ($o >= 59 && $o <= 63) {
  172. return '%' . chr($o + 11);
  173. } elseif ($o >= 91 && $o <= 95) {
  174. return '%' . chr($o - 16);
  175. } elseif ($o >= 123 && $o <= 127) {
  176. return '%' . chr($o - 43);
  177. } elseif ($o === 64) {
  178. return '%V';
  179. } elseif ($o === 96) {
  180. return '%W';
  181. } elseif ($o > 127) {
  182. return false;
  183. } else {
  184. return $char;
  185. }
  186. }
  187. }
  188. ?>