From 637a5a9fbb6e34baad110758d552e4375e0184c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20der=20Garde?= Date: Tue, 26 Mar 2024 17:12:55 +0100 Subject: [PATCH 1/3] Improved: Code128 charset usage Improved: PDF417 scaling Improved: DHL uses a decimal height for PDF417 Improved: PDF417 size when no column value is given --- .../Elements/ZplPDF417.cs | 4 ++++ .../FieldDataZplCommandAnalyzer.cs | 2 +- .../PDF417BarcodeCommandAnalyzer.cs | 11 ++++++++++ .../ElementDrawers/Barcode128ElementDrawer.cs | 22 +++++++++++++------ .../ElementDrawers/PDF417ElementDrawer.cs | 15 ++++++++++--- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/BinaryKits.Zpl.Label/Elements/ZplPDF417.cs b/src/BinaryKits.Zpl.Label/Elements/ZplPDF417.cs index 74142c9b..41a231e7 100644 --- a/src/BinaryKits.Zpl.Label/Elements/ZplPDF417.cs +++ b/src/BinaryKits.Zpl.Label/Elements/ZplPDF417.cs @@ -9,6 +9,7 @@ public class ZplPDF417 : ZplPositionedElementBase, IFormatElement { public int Height { get; protected set; } + public int ModuleWidth { get; protected set; } public string Content { get; protected set; } public FieldOrientation FieldOrientation { get; protected set; } public int? Columns { get; protected set; } @@ -23,6 +24,7 @@ public class ZplPDF417 : ZplPositionedElementBase, IFormatElement /// /// /// + /// /// 1-30: Number of data columns to encode. Default will auto balance 1:2 row to column /// 3-90. Number of data columns to encode. Default will auto balance 1:2 row to column /// Truncate right row indicators and stop pattern @@ -34,6 +36,7 @@ public ZplPDF417( int positionX, int positionY, int height = 8, + int moduleWidth = 2, int? columns = null, int? rows = null, bool compact = false, @@ -45,6 +48,7 @@ public ZplPDF417( { FieldOrientation = fieldOrientation; Height = height; + ModuleWidth = moduleWidth; Columns = columns; Rows = rows; Compact = compact; diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs index 0121a75f..2e35d1f4 100644 --- a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs @@ -78,7 +78,7 @@ public override ZplElementBase Analyze(string zplCommand) } if (this.VirtualPrinter.NextElementFieldData is PDF417FieldData pdf147) { - return new ZplPDF417(text, x, y, pdf147.Height, pdf147.Columns, pdf147.Rows, pdf147.Compact, pdf147.SecurityLevel, pdf147.FieldOrientation, bottomToTop); + return new ZplPDF417(text, x, y, pdf147.Height, moduleWidth, pdf147.Columns, pdf147.Rows, pdf147.Compact, pdf147.SecurityLevel, pdf147.FieldOrientation, bottomToTop); } } diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/PDF417BarcodeCommandAnalyzer.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/PDF417BarcodeCommandAnalyzer.cs index 28cfd388..6d696c90 100644 --- a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/PDF417BarcodeCommandAnalyzer.cs +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/PDF417BarcodeCommandAnalyzer.cs @@ -2,6 +2,7 @@ using BinaryKits.Zpl.Label.Elements; using BinaryKits.Zpl.Viewer.Models; using System; +using System.Globalization; namespace BinaryKits.Zpl.Viewer.CommandAnalyzers { @@ -33,6 +34,16 @@ public override ZplElementBase Analyze(string zplCommand) { height = tmpint; } + else if (zplDataParts.Length > 1) + { + //Sometimes a decimal is given, this works around that. + var tempDecimal = Convert.ToDecimal(zplDataParts[1], new CultureInfo("en-US")); + var tempHeight = (int)Math.Floor(tempDecimal); + if (tempHeight > 0) + { + height = tempHeight; + } + } int securityLevel = 0; if (zplDataParts.Length > 2 && int.TryParse(zplDataParts[2], out tmpint)) diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs index 5bcd5e0c..fe8c1bfc 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs @@ -18,13 +18,15 @@ public class Barcode128ElementDrawer : BarcodeDrawerBase /// private static readonly Dictionary startCodeMap = new Dictionary() { + { ">6", TYPE.CODE128A }, { ">9", TYPE.CODE128A }, { ">:", TYPE.CODE128B }, - { ">;", TYPE.CODE128C } + { ">;", TYPE.CODE128C }, + { ">5", TYPE.CODE128C }, }; - private static readonly Regex startCodeRegex = new Regex(@"^(>[9:;])(.+)$", RegexOptions.Compiled); - private static readonly Regex invalidInvocationRegex = new Regex(@"(?[9:;]", RegexOptions.Compiled); + private static readonly Regex startCodeRegex = new Regex(@"(>[569:;])(.+)", RegexOptions.Compiled); + private static readonly Regex invalidInvocationRegex = new Regex(@"(?[569:;]", RegexOptions.Compiled); // As defined in BarcodeLib.Symbologies.Code128 private static readonly string FNC1 = Convert.ToChar(200).ToString(); @@ -52,13 +54,19 @@ public override void Draw(ZplElementBase element, DrawerOptions options) string interpretation = content; if (string.IsNullOrEmpty(barcode.Mode) || barcode.Mode == "N") { - Match startCodeMatch = startCodeRegex.Match(content); + Match startCodeMatch = startCodeRegex.Match(barcode.Content); if (startCodeMatch.Success) { - barcodeType = startCodeMap[startCodeMatch.Groups[1].Value]; - content = startCodeMatch.Groups[2].Value; - interpretation = content; + barcodeType = TYPE.CODE128; + //TODO: Instead of using the auto type, switch type for each part of the content + //>:+B210AC>50270>6/$+2>5023080000582>6L + //[TYPE.CODE128B]+B210AC + //[TYPE.CODE128C]0270 + //[TYPE.CODE128A]+/$+2 + //[TYPE.CODE128C]023080000582 + //[TYPE.CODE128A]L } + // support hand-rolled GS1 content = content.Replace(">8", FNC1); interpretation = interpretation.Replace(">8", ""); diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/PDF417ElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/PDF417ElementDrawer.cs index c96348dc..ee61fcc0 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/PDF417ElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/PDF417ElementDrawer.cs @@ -56,6 +56,15 @@ public override void Draw(ZplElementBase element) { mincols = 1; maxcols = 30; + + if (pdf417.Rows != null) + { + //When column count isn't defined, and rows count is, + // the col/row ratio is calculated using the algorithm in: ZXing.PDF417.Internal.PDF417.determineDimensions + // to allow a range for that algorithm, we divide the given row amount by 2. + // as the algorithm goes from highest to lowest, this usually produces an acceptable result + minrows /= 2; + } } var writer = new PDF417Writer(); var hints = new Dictionary { @@ -64,8 +73,8 @@ public override void Draw(ZplElementBase element) //{ EncodeHintType.PDF417_AUTO_ECI, true }, //{ EncodeHintType.DISABLE_ECI, true }, { EncodeHintType.PDF417_COMPACTION, Compaction.AUTO}, - { EncodeHintType.PDF417_ASPECT_RATIO, 3 }, // height of a single bar relative to width - { EncodeHintType.PDF417_IMAGE_ASPECT_RATIO, 2.0f }, // zpl default, proportions of columns to rows + { EncodeHintType.PDF417_ASPECT_RATIO, PDF417AspectRatio.AUTO }, // height of a single bar relative to width + { EncodeHintType.PDF417_IMAGE_ASPECT_RATIO, 1.0f }, // zpl default 2.0f, proportions of columns to rows //1.0f looks closer to labelary { EncodeHintType.MARGIN, 0 }, // its an int { EncodeHintType.ERROR_CORRECTION, ConvertErrorCorrection(pdf417.SecurityLevel) }, { EncodeHintType.PDF417_DIMENSIONS, new Dimensions(mincols, maxcols, minrows, maxrows) }, @@ -73,7 +82,7 @@ public override void Draw(ZplElementBase element) var default_bitmatrix = writer.encode(pdf417.Content, BarcodeFormat.PDF_417, 0, 0, hints); - var upscaled = proportional_upscale(default_bitmatrix, 3); + var upscaled = proportional_upscale(default_bitmatrix, pdf417.ModuleWidth); var result = vertical_scale(upscaled, pdf417.Height); using var resizedImage = this.BitMatrixToSKBitmap(result, 1); From 1a9a2e06d4044a2289268f48516397624d7871d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20der=20Garde?= Date: Fri, 5 Apr 2024 11:45:18 +0200 Subject: [PATCH 2/3] Improved: PDF417 uses correct vertical scaling now --- .../BinaryKits.Zpl.Viewer.WebApi.csproj | 3 + .../Labels/Test/BarcodePDF417-102x152.zpl2 | 104 ++++++++++++++++++ .../ElementDrawers/PDF417ElementDrawer.cs | 24 ++-- 3 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 src/BinaryKits.Zpl.Viewer.WebApi/Labels/Test/BarcodePDF417-102x152.zpl2 diff --git a/src/BinaryKits.Zpl.Viewer.WebApi/BinaryKits.Zpl.Viewer.WebApi.csproj b/src/BinaryKits.Zpl.Viewer.WebApi/BinaryKits.Zpl.Viewer.WebApi.csproj index 5bee3af9..40479dec 100644 --- a/src/BinaryKits.Zpl.Viewer.WebApi/BinaryKits.Zpl.Viewer.WebApi.csproj +++ b/src/BinaryKits.Zpl.Viewer.WebApi/BinaryKits.Zpl.Viewer.WebApi.csproj @@ -126,6 +126,9 @@ PreserveNewest + + PreserveNewest + diff --git a/src/BinaryKits.Zpl.Viewer.WebApi/Labels/Test/BarcodePDF417-102x152.zpl2 b/src/BinaryKits.Zpl.Viewer.WebApi/Labels/Test/BarcodePDF417-102x152.zpl2 new file mode 100644 index 00000000..3401bb89 --- /dev/null +++ b/src/BinaryKits.Zpl.Viewer.WebApi/Labels/Test/BarcodePDF417-102x152.zpl2 @@ -0,0 +1,104 @@ +^XA + +^FO10,10 +^BY1 +^B7N,4 +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FX This one looks half-height on Zebra +^FO120,10 +^BY1 +^B7N,4,,,,Y +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FX Difference for security level +^FO10,90 +^BY1 +^B7N,4,3 +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FO120,90 +^BY1 +^B7N,4,4 +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FO250,90 +^BY1 +^B7N,4,5 +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FO400,90 +^BY1 +^B7N,4,6 +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FX Labelary is wrong on this one +^FO570,90 +^BY1 +^B7N,4,6,,,Y +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FO10,210 +^BY1 +^B7N,4,5,6 +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FO210,210 +^BY1 +^B7N,4,5,6,20 +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FX Difference for missing columns +^FO10,300 +^BY1 +^B7N,4,5,8,24,N +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FO250,300 +^BY1 +^B7N,4,5,,24,N +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FX DHL real-world test vs corrected +^FO10,400 +^BY2 +^B7N,6.7,5,,30,N +^FD +UNH+2876965+IFTMIN:D:96B:UN+DHL5.6.0/AWESOME'BGM+787+999994760001+9'DTM+186:20240312:102'TSR+++10'TOD+Z02++CPT'NAD+OS+0464651'NAD+CN+++MEVR. SOME PERSONE+STREET 17 E+SOMEPLACE++0+DE'CTA+GR'COM+SOMEEMAIL@GMAIL.COM:EM'GID+0+1'MEA+WT++KGM:2'PCI+ZZ1+JVGL09999999999994760001'UNT+13+123546798' +^FS + +^FX Difference in blocks between all three sources. (This, Zebra and Labelary) +^FO10,590 +^BY2 +^B7N,6,5,9,30,N +^FD +UNH+2876965+IFTMIN:D:96B:UN+DHL5.6.0/AWESOME'BGM+787+999994760001+9'DTM+186:20240312:102'TSR+++10'TOD+Z02++CPT'NAD+OS+0464651'NAD+CN+++MEVR. SOME PERSONE+STREET 17 E+SOMEPLACE++0+DE'CTA+GR'COM+SOMEEMAIL@GMAIL.COM:EM'GID+0+1'MEA+WT++KGM:2'PCI+ZZ1+JVGL09999999999994760001'UNT+13+123546798' +^FS + +^FX Difference in blocks with Labelary but not with Zebra printed result +^FO10,780 +^BY2 +^B7N,4,5,6 +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FO380,780 +^BY2 +^B7N,4,5,6 +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789^FS + +^FO10,840 +^BY3 +^B7N,4,5,8,24,N +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FO10,950 +^BY4 +^B7N,4,6,7,24,N +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^FO10,1060 +^BY5 +^B7N,4,6,4,36,N +^FDABCDEFGHIJKLMNOPQRSTUVWXYZ^FS + +^XZ \ No newline at end of file diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/PDF417ElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/PDF417ElementDrawer.cs index ee61fcc0..3c2d4b30 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/PDF417ElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/PDF417ElementDrawer.cs @@ -68,23 +68,25 @@ public override void Draw(ZplElementBase element) } var writer = new PDF417Writer(); var hints = new Dictionary { - { EncodeHintType.CHARACTER_SET, "UTF-8" }, + // { EncodeHintType.CHARACTER_SET, "ISO-8859-1" }, { EncodeHintType.PDF417_COMPACT, pdf417.Compact }, //{ EncodeHintType.PDF417_AUTO_ECI, true }, //{ EncodeHintType.DISABLE_ECI, true }, { EncodeHintType.PDF417_COMPACTION, Compaction.AUTO}, - { EncodeHintType.PDF417_ASPECT_RATIO, PDF417AspectRatio.AUTO }, // height of a single bar relative to width - { EncodeHintType.PDF417_IMAGE_ASPECT_RATIO, 1.0f }, // zpl default 2.0f, proportions of columns to rows //1.0f looks closer to labelary + { EncodeHintType.PDF417_ASPECT_RATIO, PDF417AspectRatio.A3 }, // height of a single bar relative to width + { EncodeHintType.PDF417_IMAGE_ASPECT_RATIO, 1.0f }, // zpl default 2.0f, proportions of columns to rows //1.0f looks closer to printed Zebra label { EncodeHintType.MARGIN, 0 }, // its an int { EncodeHintType.ERROR_CORRECTION, ConvertErrorCorrection(pdf417.SecurityLevel) }, { EncodeHintType.PDF417_DIMENSIONS, new Dimensions(mincols, maxcols, minrows, maxrows) }, }; var default_bitmatrix = writer.encode(pdf417.Content, BarcodeFormat.PDF_417, 0, 0, hints); - + + //PDF417_ASPECT_RATIO set to 3, we need to multiply that with pdf417.ModuleWidth (defined by ^BY) + var bar_height = pdf417.ModuleWidth * 3; var upscaled = proportional_upscale(default_bitmatrix, pdf417.ModuleWidth); - var result = vertical_scale(upscaled, pdf417.Height); - + var result = vertical_scale(upscaled, pdf417.Height, bar_height); + using var resizedImage = this.BitMatrixToSKBitmap(result, 1); { var png = resizedImage.Encode(SKEncodedImageFormat.Png, 100).ToArray(); @@ -116,14 +118,12 @@ private BitMatrix proportional_upscale(BitMatrix old, int scale) { return upscaled; } - // needed to match labelary + // needed to match zebra and labelary // zebra assumptions: // - we can only set the height in zpl in points, not the width - // - each bar is 3 "points" thick, until ^BY is implemented - // - because we have PDF417_ASPECT_RATIO set to 3, and upscaling to 3, the height of a single bar is now 9 - // we only need to scale to the bar height/9 - private BitMatrix vertical_scale(BitMatrix old_matrix, int new_bar_height) { - int old_bar_height = 9; + // - each bar is ^BY "points" thick + // - because we have PDF417_ASPECT_RATIO set to 3, the height of a single bar is now 3 * ^BY + private BitMatrix vertical_scale(BitMatrix old_matrix, int new_bar_height, int old_bar_height) { int width = old_matrix.Width; int rows = old_matrix.Height / old_bar_height; // logical rows; From d7a3c182da245c8df9157172f12b2446b1d10161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20der=20Garde?= Date: Thu, 18 Apr 2024 11:16:32 +0200 Subject: [PATCH 3/3] Improved: GS1 type support Improved: Code128 invocation filtering --- .../BinaryKits.Zpl.Viewer.WebApi.csproj | 3 + .../Labels/Test/GS1-102x152.zpl2 | 18 ++++++ .../ElementDrawers/Barcode128ElementDrawer.cs | 63 +++++++++---------- .../ElementDrawers/DataMatrixElementDrawer.cs | 16 ++++- .../ElementDrawers/QrCodeElementDrawer.cs | 15 ++++- 5 files changed, 76 insertions(+), 39 deletions(-) create mode 100644 src/BinaryKits.Zpl.Viewer.WebApi/Labels/Test/GS1-102x152.zpl2 diff --git a/src/BinaryKits.Zpl.Viewer.WebApi/BinaryKits.Zpl.Viewer.WebApi.csproj b/src/BinaryKits.Zpl.Viewer.WebApi/BinaryKits.Zpl.Viewer.WebApi.csproj index 40479dec..351dd746 100644 --- a/src/BinaryKits.Zpl.Viewer.WebApi/BinaryKits.Zpl.Viewer.WebApi.csproj +++ b/src/BinaryKits.Zpl.Viewer.WebApi/BinaryKits.Zpl.Viewer.WebApi.csproj @@ -129,6 +129,9 @@ PreserveNewest + + PreserveNewest + diff --git a/src/BinaryKits.Zpl.Viewer.WebApi/Labels/Test/GS1-102x152.zpl2 b/src/BinaryKits.Zpl.Viewer.WebApi/Labels/Test/GS1-102x152.zpl2 new file mode 100644 index 00000000..0e3fc7f1 --- /dev/null +++ b/src/BinaryKits.Zpl.Viewer.WebApi/Labels/Test/GS1-102x152.zpl2 @@ -0,0 +1,18 @@ +^XA + +^FX all should produce 011234567890123121123456 + +^FT101,59^A0N,31,30^FH\^CI28^FDGS1-128 : ^FS^CI27 +^BY2,3,54^FT110,134^BCN,,N,N +^FH\^FD>;>8011234567890123121123456^FS + +^FT101,174^A0N,31,30^FH\^CI28^FDGS1-DataMatrix : ^FS^CI27 +^FT185,324^BXN,6,200,0,0,1,_,1 +^FH\^FD_1011234567890123121123456^FS + +^FT548,174^A0N,31,30^FH\^CI28^FDGS1-QR: ^FS^CI27 +^FO642,206^BQN,2,5 +^FH\^FD>;>8011234567890123121123456^FS + +^PQ1,0,1,Y +^XZ \ No newline at end of file diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs index fe8c1bfc..fdc542a0 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs @@ -3,7 +3,6 @@ using BinaryKits.Zpl.Viewer.Helpers; using SkiaSharp; using System; -using System.Collections.Generic; using System.Drawing; using System.Text.RegularExpressions; @@ -11,22 +10,12 @@ namespace BinaryKits.Zpl.Viewer.ElementDrawers { public class Barcode128ElementDrawer : BarcodeDrawerBase { - /// /// Start sequence lookups. /// /// - private static readonly Dictionary startCodeMap = new Dictionary() - { - { ">6", TYPE.CODE128A }, - { ">9", TYPE.CODE128A }, - { ">:", TYPE.CODE128B }, - { ">;", TYPE.CODE128C }, - { ">5", TYPE.CODE128C }, - }; - - private static readonly Regex startCodeRegex = new Regex(@"(>[569:;])(.+)", RegexOptions.Compiled); - private static readonly Regex invalidInvocationRegex = new Regex(@"(?[569:;]", RegexOptions.Compiled); + private static readonly Regex startCodeRegex = new Regex(@"(>[9:;])", RegexOptions.Compiled); + private static readonly Regex invalidInvocationRegex = new Regex(@"(?[<0=12345679:;]", RegexOptions.Compiled); //>8 has limited support here // As defined in BarcodeLib.Symbologies.Code128 private static readonly string FNC1 = Convert.ToChar(200).ToString(); @@ -48,39 +37,42 @@ public override void Draw(ZplElementBase element, DrawerOptions options) { if (element is ZplBarcode128 barcode) { - var barcodeType = TYPE.CODE128B; - // remove any start sequences not at the start of the content (invalid invocation) - string content = invalidInvocationRegex.Replace(barcode.Content, ""); + var barcodeType = TYPE.CODE128; + + //remove the start code form the content we only support the globals N,A,D,U and our barcode library doesn't support these types + string content = startCodeRegex.Replace(barcode.Content, ""); string interpretation = content; + + // remove any start sequences not at the start of the content (invalid invocation) + content = invalidInvocationRegex.Replace(content, ""); + interpretation = content; + + // support hand-rolled GS1 + content = content.Replace(">8", FNC1); + interpretation = interpretation.Replace(">8", ""); + if (string.IsNullOrEmpty(barcode.Mode) || barcode.Mode == "N") { - Match startCodeMatch = startCodeRegex.Match(barcode.Content); - if (startCodeMatch.Success) - { - barcodeType = TYPE.CODE128; - //TODO: Instead of using the auto type, switch type for each part of the content - //>:+B210AC>50270>6/$+2>5023080000582>6L - //[TYPE.CODE128B]+B210AC - //[TYPE.CODE128C]0270 - //[TYPE.CODE128A]+/$+2 - //[TYPE.CODE128C]023080000582 - //[TYPE.CODE128A]L - } - - // support hand-rolled GS1 - content = content.Replace(">8", FNC1); - interpretation = interpretation.Replace(">8", ""); - // TODO: support remaining escapes within a barcode + barcodeType = TYPE.CODE128; // dynamic + //TODO: Instead of using the auto type, switch type for each part of the content + // - Current library doesn't support that. + //>:+B210AC>50270>6/$+2>5023080000582>6L + //[TYPE.CODE128B]+B210AC + //[TYPE.CODE128C]0270 + //[TYPE.CODE128B]+/$+2 + //[TYPE.CODE128C]023080000582 + //[TYPE.CODE128B]L } else if (barcode.Mode == "A") { + //A (automatic mode, the ZPL engine automatically determines the subsets that are used to encode the data) barcodeType = TYPE.CODE128; // dynamic } else if (barcode.Mode == "D") { + //D (UCC/EAN mode, field data must contain GS1 numbers) barcodeType = TYPE.CODE128C; - content = content.Replace(">8", FNC1); - interpretation = interpretation.Replace(">8", ""); + if (!content.StartsWith(FNC1)) { content = FNC1 + content; @@ -88,6 +80,7 @@ public override void Draw(ZplElementBase element, DrawerOptions options) } else if (barcode.Mode == "U") { + //U (UCC case mode, field data must contain 19 digits) barcodeType = TYPE.CODE128C; content = content.PadLeft(19, '0').Substring(0, 19); int checksum = 0; diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/DataMatrixElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/DataMatrixElementDrawer.cs index d2cf127e..adc92990 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/DataMatrixElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/DataMatrixElementDrawer.cs @@ -1,6 +1,7 @@ using BinaryKits.Zpl.Label.Elements; using SkiaSharp; using System.Collections.Generic; +using System.Text.RegularExpressions; using ZXing; using ZXing.Datamatrix; using ZXing.Datamatrix.Encoder; @@ -29,11 +30,22 @@ public override void Draw(ZplElementBase element) float x = dataMatrix.PositionX; float y = dataMatrix.PositionY; + // support hand-rolled GS1 + bool gs1Mode = false; + var content = dataMatrix.Content; + if (Regex.Match(content, @"(^_1)", RegexOptions.None).Success) + { + content = Regex.Replace(content, @"(^_1)", ""); + gs1Mode = true; + } + var writer = new DataMatrixWriter(); var hints = new Dictionary { - { EncodeHintType.DATA_MATRIX_SHAPE, SymbolShapeHint.FORCE_SQUARE } + { EncodeHintType.DATA_MATRIX_SHAPE, SymbolShapeHint.FORCE_SQUARE }, + { EncodeHintType.DATA_MATRIX_COMPACT, gs1Mode }, + { EncodeHintType.GS1_FORMAT, gs1Mode } }; - var result = writer.encode(dataMatrix.Content, BarcodeFormat.DATA_MATRIX, 0, 0, hints); + var result = writer.encode(content, BarcodeFormat.DATA_MATRIX, 0, 0, hints); using var resizedImage = this.BitMatrixToSKBitmap(result, dataMatrix.Height); { diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/QrCodeElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/QrCodeElementDrawer.cs index 2fdb1316..38fcf52d 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/QrCodeElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/QrCodeElementDrawer.cs @@ -2,6 +2,7 @@ using BinaryKits.Zpl.Label.Elements; using SkiaSharp; using System.Collections.Generic; +using System.Text.RegularExpressions; using ZXing; using ZXing.QrCode; @@ -22,6 +23,15 @@ public override void Draw(ZplElementBase element) { float x = qrcode.PositionX; float y = qrcode.PositionY; + + // support hand-rolled GS1 + bool gs1Mode = false; + var content = qrcode.Content; + if (Regex.Match(content, @"(^>;>8)", RegexOptions.None).Success) + { + content = Regex.Replace(content, @"(^>;>8)", ""); + gs1Mode = true; + } int verticalQuietZone = 10; @@ -30,9 +40,10 @@ public override void Draw(ZplElementBase element) { EncodeHintType.ERROR_CORRECTION, CovertErrorCorrection(qrcode.ErrorCorrectionLevel) }, { EncodeHintType.QR_MASK_PATTERN, qrcode.MaskValue }, { EncodeHintType.CHARACTER_SET, "UTF-8" }, - { EncodeHintType.MARGIN, 0 } + { EncodeHintType.MARGIN, 0 }, + { EncodeHintType.GS1_FORMAT, gs1Mode } }; - var result = writer.encode(qrcode.Content, BarcodeFormat.QR_CODE, 0, 0, hints); + var result = writer.encode(content, BarcodeFormat.QR_CODE, 0, 0, hints); using var resizedImage = this.BitMatrixToSKBitmap(result, qrcode.MagnificationFactor);