diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs index 79f3b33..503d871 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs @@ -34,13 +34,12 @@ public override void Draw(ZplElementBase element, DrawerOptions options) } else if (barcode.Mode == "D") { - codeSet = Code128CodeSet.Code128C; + codeSet = Code128CodeSet.Code128; gs1 = true; } else if (barcode.Mode == "U") { codeSet = Code128CodeSet.Code128C; - gs1 = true; content = content.PadLeft(19, '0').Substring(0, 19); int checksum = 0; for (int i = 0; i < 19; i++) diff --git a/src/BinaryKits.Zpl.Viewer/Symologies/ZplCode128Symbology.cs b/src/BinaryKits.Zpl.Viewer/Symologies/ZplCode128Symbology.cs index a303a02..85340f5 100644 --- a/src/BinaryKits.Zpl.Viewer/Symologies/ZplCode128Symbology.cs +++ b/src/BinaryKits.Zpl.Viewer/Symologies/ZplCode128Symbology.cs @@ -22,6 +22,12 @@ public class ZplCode128Symbology private static readonly Regex startCRegex = new Regex(@"^\d{4}", RegexOptions.Compiled); private static readonly Regex digitPairRegex = new Regex(@"^\d\d", RegexOptions.Compiled); + // GS1 specific + private static readonly Regex gs1SwitchCRegex = new Regex(@"^\d\d(?:\d\d|>8)+(?!\d)", RegexOptions.Compiled); + private static readonly Regex gs1StartCRegex = new Regex(@"^(?:\d\d|>8){2}", RegexOptions.Compiled); + private static readonly Regex gs1DigitPairRegex = new Regex(@"^(?:\d\d|>8)", RegexOptions.Compiled); + private static readonly Regex fnc1Regex = new Regex(@"^>8", RegexOptions.Compiled); + private static readonly Regex startCodeRegex = new Regex(@"^(>[9:;])(.+)$", RegexOptions.Compiled); private static readonly Dictionary invocationMap = new Dictionary() { @@ -44,6 +50,12 @@ public class ZplCode128Symbology { ">;", Code128CodeSet.Code128C } }; + private static readonly Dictionary codeSetCodeMap = new Dictionary() { + { Code128CodeSet.Code128A, CODE_A }, + { Code128CodeSet.Code128B, CODE_B }, + { Code128CodeSet.Code128C, CODE_C } + }; + private const string FNC_1 = "FNC_1"; private const string FNC_2 = "FNC_2"; private const string FNC_3 = "FNC_3"; @@ -208,7 +220,20 @@ static ZplCode128Symbology() { public static (List, string) Encode(string content, Code128CodeSet initialCodeSet, bool gs1) { List result = new List(); - var (data, interpretation) = Analyze(content, initialCodeSet); + List data; + string interpretation; + if (gs1) + { + (data, interpretation) = AnalyzeGS1(content); + } + else if (initialCodeSet == Code128CodeSet.Code128) + { + (data, interpretation) = AnalyzeAuto(content); + } + else + { + (data, interpretation) = Analyze(content, initialCodeSet); + } // TODO: magic constant FNC_1 if (gs1 && data[1] != 102) @@ -265,11 +290,6 @@ private static (List, string) Analyze(string content, Code128CodeSet initia startCodeMatch = startCodeRegex.Match(content); } - if (codeSet == Code128CodeSet.Code128) - { - return AnalyzeAuto(content); - } - (var codeChars, var codeMap) = codeMaps[codeSet]; data.Add((int)codeSet); @@ -303,8 +323,14 @@ private static (List, string) Analyze(string content, Code128CodeSet initia } else if (startCodeMap.ContainsKey(symbol)) { - codeSet = startCodeMap[symbol]; - (codeChars, codeMap) = codeMaps[codeSet]; + Code128CodeSet newCodeSet = startCodeMap[symbol]; + if (newCodeSet != codeSet) + { + int value = codeMap[codeSetCodeMap[newCodeSet]]; + data.Add(value); + codeSet = newCodeSet; + (codeChars, codeMap) = codeMaps[codeSet]; + } } else { @@ -322,6 +348,8 @@ private static (List, string) Analyze(string content, Code128CodeSet initia } else { + int value = codeMap[CODE_B]; + data.Add(value); codeSet = Code128CodeSet.Code128B; (codeChars, codeMap) = codeMaps[codeSet]; } @@ -387,5 +415,58 @@ private static (List, string) AnalyzeAuto(string content) return (data, interpretation); } + private static (List, string) AnalyzeGS1(string content) + { + List data = new List(); + string interpretation = ""; + Code128CodeSet codeSet = Code128CodeSet.Code128B; + var codeMap = codeBMap; + if (gs1StartCRegex.IsMatch(content)) + { + codeSet = Code128CodeSet.Code128C; + codeMap = codeCMap; + } + data.Add((int)codeSet); + + while (content.Length > 0) + { + if (codeSet != Code128CodeSet.Code128C && gs1SwitchCRegex.IsMatch(content)) + { + data.Add(codeMap[CODE_C]); + codeSet = Code128CodeSet.Code128C; + codeMap = codeCMap; + } + else if (codeSet == Code128CodeSet.Code128C && !gs1DigitPairRegex.IsMatch(content)) + { + data.Add(codeMap[CODE_B]); + codeSet = Code128CodeSet.Code128B; + codeMap = codeBMap; + } + else if (fnc1Regex.IsMatch(content)) + { + content = content.Substring(2); + data.Add(codeMap[FNC_1]); + } + else + { + string symbol = content[0].ToString(); + if (codeSet == Code128CodeSet.Code128C) + { + symbol += content[1]; + content = content.Substring(2); + } + else + { + content = content.Substring(1); + } + + data.Add(codeMap[symbol]); + interpretation += symbol; + } + } + + return (data, interpretation); + } + } }