diff options
Diffstat (limited to 'source/codes/Codabar.mc')
| -rw-r--r-- | source/codes/Codabar.mc | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/source/codes/Codabar.mc b/source/codes/Codabar.mc new file mode 100644 index 0000000..63c78bb --- /dev/null +++ b/source/codes/Codabar.mc @@ -0,0 +1,58 @@ +// Author: cirakg & claude ai +// Summary: Codabar encoder: start and stop characters A-D (added as A...A when missing), wide bars 2 modules (as zxing). + +import Toybox.Lang; + +module Codabar { + + const ALPHABET = "0123456789-$:/.+ABCD"; // lint: allow-literal (Codabar character set) + // Seven elements per character, first element = bit 6, 1 = wide. + const PATTERNS = [0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, + 0x00C, 0x018, 0x045, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E]; + const FIRST_GUARD = 16; // index of 'A' + + function encode(text as String) as Codes.LinearCode or Codes.CodeError { + var upper = text.toUpper(); + var chars = upper.toCharArray(); + if (chars.size() == 0) { + return new Codes.CodeError("Codabar needs some digits"); + } + var startsGuarded = isGuard(chars[0]); + var endsGuarded = chars.size() > 1 && isGuard(chars[chars.size() - 1]); + var note = null; + if (startsGuarded != endsGuarded) { + return new Codes.CodeError("Codabar: use start and stop characters (A-D) at both ends or at neither"); + } + if (!startsGuarded) { + upper = "A" + upper + "A"; + chars = upper.toCharArray(); + note = "start and stop characters A...A added"; + } + var m = []b; + for (var i = 0; i < chars.size(); i++) { + var v = ALPHABET.find(chars[i].toString()); + var inner = i > 0 && i < chars.size() - 1; + if (v == null || (inner && v >= FIRST_GUARD)) { + return new Codes.CodeError("Codabar: '" + chars[i] + "' isn't allowed there (0-9 - $ : / . + between A-D)"); + } + if (i > 0) { + m.add(0); // narrow gap + } + var pattern = PATTERNS[v] as Number; + for (var k = 6; k >= 0; k--) { + var width = ((pattern >> k) & 1) == 1 ? 2 : 1; + for (var w = 0; w < width; w++) { + m.add((6 - k) % 2 == 0 ? 1 : 0); + } + } + } + m.add(0); // zxing also ends with a narrow gap (inside the quiet zone) + var code = new Codes.LinearCode(m, upper); + code.note = note; + return code; + } + + function isGuard(c as Char) as Boolean { + return c >= 'A' && c <= 'D'; + } +} |
