141 lines
6.6 KiB
PHP
141 lines
6.6 KiB
PHP
<?php
|
|
// Simplified Barcode Generator for Code 128 and Code 39
|
|
// Generates SVG output.
|
|
|
|
class BarcodeGenerator
|
|
{
|
|
private $barcode_codes;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->barcode_codes = $this->getCode128Map();
|
|
}
|
|
|
|
public function getBarcode($code, $narrowBarWidth = 0.25, $height = 11.5, $foregroundColor = 'black', $quietZoneMM = 4, $type = 'C128')
|
|
{
|
|
$barcodeData = ($type === 'C39') ? $this->getBarcodeData39($code) : $this->getBarcodeData($code);
|
|
if (!$barcodeData) return '';
|
|
|
|
$bars = '';
|
|
$x = $quietZoneMM;
|
|
|
|
$barArray = str_split($barcodeData['bars']);
|
|
for ($i = 0; $i < count($barArray); $i++) {
|
|
$val = (int)$barArray[$i];
|
|
$width = $narrowBarWidth * $val;
|
|
if ($i % 2 == 0) { // Even indices are bars
|
|
$bars .= '<rect x="' . $x . '" y="0" width="' . $width . '" height="' . $height . '" fill="' . $foregroundColor . '" />';
|
|
}
|
|
$x += $width;
|
|
}
|
|
|
|
$totalWidth = $x + $quietZoneMM;
|
|
// Using crispEdges for maximum sharpness on thermal printers
|
|
$svg = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="' . $totalWidth . 'mm" height="' . $height . 'mm" viewBox="0 0 ' . $totalWidth . ' ' . $height . '" shape-rendering="crispEdges">';
|
|
$svg .= '<rect width="' . $totalWidth . '" height="' . $height . '" fill="white" />';
|
|
$svg .= $bars;
|
|
$svg .= '</svg>';
|
|
|
|
return $svg;
|
|
}
|
|
|
|
private function getBarcodeData($code)
|
|
{
|
|
$code = str_replace(' ', '', strtoupper(trim($code)));
|
|
$len = strlen($code);
|
|
$indices = [104]; // Start B
|
|
|
|
for ($i = 0; $i < $len; $i++) {
|
|
$char = $code[$i];
|
|
$val = $this->getCharValue('B', $char);
|
|
if ($val !== null) {
|
|
$indices[] = $val;
|
|
}
|
|
}
|
|
|
|
$sum = $indices[0];
|
|
for ($i = 1; $i < count($indices); $i++) {
|
|
$sum += ($indices[$i] * $i);
|
|
}
|
|
$checksum = $sum % 103;
|
|
$indices[] = $checksum;
|
|
$indices[] = 106; // Stop
|
|
|
|
$bars = '';
|
|
foreach ($indices as $index) {
|
|
if (isset($this->barcode_codes['bars'][$index])) {
|
|
$bars .= $this->barcode_codes['bars'][$index];
|
|
}
|
|
}
|
|
|
|
return ['bars' => $bars];
|
|
}
|
|
|
|
private function getBarcodeData39($code)
|
|
{
|
|
$code = '*' . strtoupper(trim($code)) . '*';
|
|
$map = [
|
|
'0' => '111221211', '1' => '211211112', '2' => '112211112', '3' => '212211111',
|
|
'4' => '111221112', '5' => '211221111', '6' => '112221111', '7' => '111211212',
|
|
'8' => '211211211', '9' => '112211211', 'A' => '211112112', 'B' => '112112112',
|
|
'C' => '212112111', 'D' => '111122112', 'E' => '211122111', 'F' => '112122111',
|
|
'G' => '111112212', 'H' => '211112211', 'I' => '112112211', 'J' => '111122211',
|
|
'K' => '211111122', 'L' => '112111122', 'M' => '212111121', 'N' => '111121122',
|
|
'O' => '211121121', 'P' => '112121121', 'Q' => '111111222', 'R' => '211111221',
|
|
'S' => '112111221', 'T' => '111121221', 'U' => '221111112', 'V' => '122111112',
|
|
'W' => '222111111', 'X' => '121121112', 'Y' => '221121111', 'Z' => '122121111',
|
|
'-' => '121111212', '.' => '221111211', ' ' => '122111211', '*' => '121121211',
|
|
'$' => '121212111', '/' => '121211121', '+' => '121112121', '%' => '111212121'
|
|
];
|
|
|
|
$bars = '';
|
|
for ($i = 0; $i < strlen($code); $i++) {
|
|
$char = $code[$i];
|
|
if (isset($map[$char])) {
|
|
$bars .= $map[$char] . '1'; // Add a narrow space between characters
|
|
}
|
|
}
|
|
return ['bars' => rtrim($bars, '1')];
|
|
}
|
|
|
|
private function getCharValue($set, $char)
|
|
{
|
|
if (isset($this->barcode_codes[$set][$char])) {
|
|
return $this->barcode_codes[$set][$char];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private function getCode128Map()
|
|
{
|
|
return [
|
|
'B' => [
|
|
' ' => 0, '!' => 1, '"' => 2, '#' => 3, '$' => 4, '%' => 5, '&' => 6, '\'' => 7,
|
|
'(' => 8, ')' => 9, '*' => 10, '+' => 11, ',' => 12, '-' => 13, '.' => 14, '/' => 15,
|
|
'0' => 16, '1' => 17, '2' => 18, '3' => 19, '4' => 20, '5' => 21, '6' => 22, '7' => 23,
|
|
'8' => 24, '9' => 25, ':' => 26, ';' => 27, '<' => 28, '=' => 29, '>' => 30, '?' => 31,
|
|
'@' => 32, 'A' => 33, 'B' => 34, 'C' => 35, 'D' => 36, 'E' => 37, 'F' => 38, 'G' => 39,
|
|
'H' => 40, 'I' => 41, 'J' => 42, 'K' => 43, 'L' => 44, 'M' => 45, 'N' => 46, 'O' => 47,
|
|
'P' => 48, 'Q' => 49, 'R' => 50, 'S' => 51, 'T' => 52, 'U' => 53, 'V' => 54, 'W' => 55,
|
|
'X' => 56, 'Y' => 57, 'Z' => 58, '[' => 59, '\\' => 60, ']' => 61, '^' => 62, '_' => 63,
|
|
'`' => 64, 'a' => 65, 'b' => 66, 'c' => 67, 'd' => 68, 'e' => 69, 'f' => 70, 'g' => 71,
|
|
'h' => 72, 'i' => 73, 'j' => 74, 'k' => 75, 'l' => 76, 'm' => 77, 'n' => 78, 'o' => 79,
|
|
'p' => 80, 'q' => 81, 'r' => 82, 's' => 83, 't' => 84, 'u' => 85, 'v' => 86, 'w' => 87,
|
|
'x' => 88, 'y' => 89, 'z' => 90, '{' => 91, '|' => 92, '}' => 93, '~' => 94
|
|
],
|
|
'bars' => [
|
|
'212222', '222122', '222221', '121223', '121322', '131222', '122213', '122312', '132212', '221213', // 0-9
|
|
'221312', '231212', '112232', '122132', '122231', '113222', '123122', '123221', '223211', '221132', // 10-19
|
|
'221231', '213212', '223112', '312131', '311222', '321122', '321221', '312212', '322112', '322211', // 20-29
|
|
'212123', '212321', '232121', '111323', '131123', '131321', '112313', '132113', '132311', '211313', // 30-39
|
|
'231113', '231311', '112133', '112331', '132131', '113123', '113321', '133121', '313121', '211331', // 40-49
|
|
'231131', '213113', '213311', '213131', '311123', '311321', '331121', '312113', '312311', '332111', // 50-59
|
|
'314111', '221411', '431111', '111224', '111413', '121124', '121421', '141122', '141221', '112214', // 60-69
|
|
'112412', '122114', '122411', '142112', '142211', '241211', '221114', '413111', '241112', '134111', // 70-79
|
|
'111242', '121142', '121241', '114212', '124112', '124211', '411212', '421112', '421211', '212141', // 80-89
|
|
'214121', '412121', '111143', '111341', '131141', '114113', '114311', '411113', '411311', '113141', // 90-99
|
|
'114131', '311141', '411131', '211412', '211214', '211232', '2331112' // 100-106
|
|
]
|
|
];
|
|
}
|
|
} |