// Author: cirakg & claude ai // Summary: Code 39 encoder: 43 characters, optional mod-43 check character, wide bars 2 modules (as zxing). import Toybox.Lang; module Code39 { const ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; // lint: allow-literal (Code 39 character set) // Nine elements per character, bit 8 first, 1 = wide; index 43 is '*'. const PATTERNS = [ 0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x0A8, 0x0A2, 0x08A, 0x02A, 0x094 ]; const STAR = 43; // withCheck adds the mod-43 check character (the sum of the character // values modulo 43). function encode(text as String, withCheck as Boolean) as Codes.LinearCode or Codes.CodeError { var chars = text.toCharArray(); if (chars.size() == 0) { return new Codes.CodeError("Code 39 needs some text"); } var values = [] as Array; var sum = 0; for (var i = 0; i < chars.size(); i++) { var v = ALPHABET.find(chars[i].toString()); if (v == null) { return new Codes.CodeError("Code 39: '" + chars[i] + "' (position " + (i + 1) + ") isn't allowed (0-9, A-Z, space, - . $ / + %)"); } values.add(v); sum += v; } var readable = text; if (withCheck) { values.add(sum % 43); readable += ALPHABET.substring(sum % 43, sum % 43 + 1); } var m = []b; addChar(m, STAR); for (var i = 0; i < values.size(); i++) { m.add(0); // narrow gap between characters addChar(m, values[i]); } m.add(0); addChar(m, STAR); return new Codes.LinearCode(m, readable); } function addChar(m as ByteArray, value as Number) as Void { var pattern = PATTERNS[value] as Number; for (var i = 8; i >= 0; i--) { var width = ((pattern >> i) & 1) == 1 ? 2 : 1; var bar = (8 - i) % 2 == 0; for (var k = 0; k < width; k++) { m.add(bar ? 1 : 0); } } } }