red-agate-barcode
Version:
red-agate barcode tag library.
235 lines • 8.68 kB
JavaScript
// Copyright (c) 2017, Shellyl_N and Authors
// license: ISC
// https://github.com/shellyln
import { barcodeBasePropsDefault, BarcodeBase } from './BarcodeBase';
import { charactersMap, fullAsciiMap } from './data/Code128.data';
export const code128PropsDefault = Object.assign({}, barcodeBasePropsDefault, {
elementWidth: 0.33,
useLatin1: false,
raw: false
});
export class Code128 extends BarcodeBase {
constructor(props) {
super(Object.assign({}, code128PropsDefault, props), charactersMap);
}
calcSymbolSize(data, startChar, stopChar, cdChar) {
const props = this.props;
// module width (bar + space + gap)
const mw = props.elementWidth * 11;
return {
// total width (quiet + data + start + stop + cd)
tw: props.quietWidth * 2 + mw * data.length + props.elementWidth * 13,
// total height (quiet + bar + text)
th: props.quietHeight * 2 + props.height + (props.drawText ? props.textHeight : 0)
};
}
calcMod103Checksum(data) {
let v = charactersMap.get(data[0]);
if (v === void 0) {
throw new Error("code128: character is out of range.");
}
let s = v.index % 103;
for (let i = 1; i < data.length; i++) {
v = charactersMap.get(data[i]);
if (v === void 0) {
throw new Error("code128: character is out of range.");
}
s = (s + v.index * i) % 103;
}
return s;
}
encodeData(data) {
if (this.props.raw) {
return { data, startChar: "", stopChar: "\x6A" };
}
let d = "";
let cLimit = 4;
let mode = null; // 0: A, 1: B, 2: C
let scanned = 0;
const detC = (i) => {
let j = i + 1;
let continuing = 1;
for (; j < data.length; j++) {
const c2 = data.charCodeAt(j);
if (0x30 <= c2 && c2 <= 0x39) {
continuing++;
}
else if (c2 === 0x80) {
if (continuing % 2)
break;
}
else {
break;
}
}
if (j >= data.length && j - i >= 4) {
return true;
}
else {
return (j - i >= cLimit) ? true : false;
}
};
const encodeC = (i) => {
// code C
d += mode === null ? "\x69" : "\x63"; // start / change mode
let j = i, v = 0, continuing = 0;
for (; j < data.length; j++) {
let c2 = data.charCodeAt(j);
if (0x30 <= c2 && c2 <= 0x39) {
v = v * 10 + (c2 - 0x30);
continuing++;
if (continuing % 2 === 0) {
d += String.fromCharCode(v);
v = 0;
}
}
else {
if (this.props.useLatin1 && c2 > 127) {
c2 -= 128;
}
if (c2 === 0x80) {
if (continuing % 2) {
break;
}
else {
d += "\x66"; // FNC1
}
}
else {
break;
}
}
}
if (j < data.length || continuing % 2) {
mode = detAB(j);
d += mode === 0 ? "\x65" : "\x64";
}
if (continuing % 2) {
const z = fullAsciiMap.get(0x30 + v);
if (z === void 0) {
throw new Error("code128: character is out of range.");
}
if (mode === null) {
throw new Error("code128: mode === null. Assertion failed.");
}
d += z[mode];
}
return j;
};
const detAB = (i) => {
let cA = 0, cB = 0;
let j = Math.max(i, scanned);
for (; j < data.length; j++) {
let c2 = data.charCodeAt(j);
if (this.props.useLatin1 && c2 > 127) {
c2 -= 128;
}
const z = fullAsciiMap.get(c2);
if (z === void 0) {
throw new Error("code128: character is out of range.");
}
const bA = z[0];
const bB = z[1];
if (bA === void 0 || bB === void 0) {
break;
}
}
const N = Math.min(data.length, j + 6);
for (; j < N; j++) {
let c2 = data.charCodeAt(j);
if (this.props.useLatin1 && c2 > 127) {
c2 -= 128;
}
const z = fullAsciiMap.get(c2);
if (z === void 0) {
throw new Error("code128: character is out of range.");
}
const bA = z[0];
if (bA === void 0)
cA++;
const bB = z[1];
if (bB === void 0)
cB++;
}
scanned = j;
const mode2 = mode === null ? 1 : mode;
if (cA < cB)
return (cB - cA) < 2 ? mode2 : 0;
else if (cA > cB)
return (cA - cB) < 2 ? mode2 : 1;
else
return mode2;
};
for (let i = 0; i < data.length;) {
const ci = data.charCodeAt(i);
let done = false, latin1 = false;
if ((0x30 <= ci && ci <= 0x39) ||
(!this.props.useLatin1 && ci === 0x80) ||
(this.props.useLatin1 && ci === 0x100)) {
if (detC(i)) {
i = encodeC(i);
done = true;
}
cLimit = 6;
}
if (!done) {
let c2 = data.charCodeAt(i);
if (this.props.useLatin1 && c2 > 127) {
c2 -= 128;
if (128 <= c2 && c2 <= 135) {
// FNC1-4, CODE A-C, SHIFT A-B
if (c2 === 131) {
latin1 = true; // escape FNC4
}
}
else {
latin1 = true;
}
}
const z = fullAsciiMap.get(c2);
if (z === void 0) {
throw new Error("code128: character is out of range.");
}
let b = mode !== null ? z[mode] : void 0;
if (b === void 0) {
const newMode = detAB(i);
if (mode === newMode) {
d += "\x62"; // shift
b = z[(mode + 1) % 2];
}
else {
if (mode === null)
d += mode === 0 ? "\x67" : "\x68"; // start
else
d += mode === 0 ? "\x64" : "\x65"; // change mode
mode = newMode;
b = z[mode];
}
}
if (b === null) {
throw new Error("code128: character is out of range.");
}
if (latin1) {
const fnc4 = fullAsciiMap.get(131);
if (fnc4 === void 0) {
throw new Error("code128: character is out of range.");
}
if (mode === null) {
throw new Error("code128: mode === null. Assertion failed.");
}
d += fnc4[mode]; // FNC4
}
d += b;
i++;
}
}
d += String.fromCharCode(this.calcMod103Checksum(d));
return { data: d, startChar: "", stopChar: "\x6A" };
}
getBarSpaceWidth() {
const props = this.props;
const w = props.elementWidth;
return [0, w, w * 2, w * 3, w * 4];
}
}
//# sourceMappingURL=Code128.js.map