diff --git a/src/BinaryKits.Zpl.Label/Elements/ZplAztecBarcode.cs b/src/BinaryKits.Zpl.Label/Elements/ZplAztecBarcode.cs new file mode 100644 index 0000000..7921fde --- /dev/null +++ b/src/BinaryKits.Zpl.Label/Elements/ZplAztecBarcode.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; + +namespace BinaryKits.Zpl.Label.Elements +{ + public class ZplAztecBarcode : ZplPositionedElementBase, IFormatElement + { + public int MagnificationFactor { get; protected set; } + public bool ExtendedChannel { get; protected set; } + public int ErrorControl { get; protected set; } + public bool MenuSymbol { get; protected set; } + public int SymbolCount { get; protected set; } + public string IdField { get; protected set; } + public string Content { get; protected set; } + public bool UseHexadecimalIndicator { get; protected set; } + public FieldOrientation FieldOrientation { get; protected set; } + + /// + /// Aztec Bar Code + /// + /// + /// + /// + /// + /// extended channel interpretation code indicator + /// error control and symbol size/type indicator + /// menu symbol indicator + /// number of symbols for structured append + /// optional ID field for structured append + /// + /// + /// + public ZplAztecBarcode( + string content, + int positionX, + int positionY, + int magnificationFactor = 2, + bool extendedChannel = false, + int errorControl = 0, + bool menuSymbol = false, + int symbolCount = 1, + string idField = null, + bool useHexadecimalIndicator = true, + FieldOrientation fieldOrientation = FieldOrientation.Normal, + bool bottomToTop = false + ) + : base(positionX, positionY, bottomToTop) + { + this.Content = content; + this.MagnificationFactor = magnificationFactor; + this.ExtendedChannel = extendedChannel; + this.ErrorControl = errorControl; + this.SymbolCount = symbolCount; + this.IdField = idField; + this.UseHexadecimalIndicator = useHexadecimalIndicator; + this.FieldOrientation = fieldOrientation; + } + + /// + public override IEnumerable Render(ZplRenderOptions context) + { + var result = new List(); + result.AddRange(RenderPosition(context)); + result.Add($"^BO{RenderFieldOrientation(this.FieldOrientation)},{this.MagnificationFactor},{RenderBoolean(this.ExtendedChannel)}," + + $"{this.ErrorControl},{RenderBoolean(this.MenuSymbol)},{this.SymbolCount},{this.IdField}"); + result.Add($"^FD{this.Content}^FS"); + + return result; + } + + /// + public void SetTemplateContent(string content) + { + this.Content = content; + } + } +} diff --git a/src/BinaryKits.Zpl.Label/Elements/ZplElementBase.cs b/src/BinaryKits.Zpl.Label/Elements/ZplElementBase.cs index ac10e2b..a4fa753 100644 --- a/src/BinaryKits.Zpl.Label/Elements/ZplElementBase.cs +++ b/src/BinaryKits.Zpl.Label/Elements/ZplElementBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace BinaryKits.Zpl.Label.Elements @@ -8,7 +8,7 @@ public abstract class ZplElementBase public List Comments { get; protected set; } /// - /// Indicate the rendering process whether this elemenet can be skipped + /// Indicate the rendering process whether this element can be skipped /// public bool IsEnabled { get; set; } @@ -108,6 +108,16 @@ public string RenderErrorCorrectionLevel(ErrorCorrectionLevel errorCorrectionLev throw new NotImplementedException("Unknown Error Correction Level"); } + /// + /// Render Zpl char for boolean + /// + /// + /// + public string RenderBoolean(bool value) + { + return value ? "Y" : "N"; + } + public string ToZplString() { return ToZplString(new ZplRenderOptions()); diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/AztecBarcodeZplCommandAnalyzer.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/AztecBarcodeZplCommandAnalyzer.cs new file mode 100644 index 0000000..32a0b94 --- /dev/null +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/AztecBarcodeZplCommandAnalyzer.cs @@ -0,0 +1,69 @@ +using BinaryKits.Zpl.Label.Elements; +using BinaryKits.Zpl.Viewer.Models; + +namespace BinaryKits.Zpl.Viewer.CommandAnalyzers +{ + public class AztecBarcodeZplCommandAnalyzer : ZplCommandAnalyzerBase + { + public AztecBarcodeZplCommandAnalyzer(VirtualPrinter virtualPrinter) : base("^BO", virtualPrinter) { } + + /// + public override ZplElementBase Analyze(string zplCommand) + { + var zplDataParts = this.SplitCommand(zplCommand); + + int tmpint; + var fieldOrientation = this.ConvertFieldOrientation(zplDataParts[0]); + int magnificationFactor = 2; + bool extendedChannel = false; + int errorControl = 0; + bool menuSymbol = false; + int symbolCount = 1; + string idField = null; + + if (zplDataParts.Length > 1 && int.TryParse(zplDataParts[1], out tmpint)) + { + magnificationFactor = tmpint; + } + + if (zplDataParts.Length > 2) + { + extendedChannel = ConvertBoolean(zplDataParts[2]); + } + + if (zplDataParts.Length > 3 && int.TryParse(zplDataParts[3], out tmpint)) + { + errorControl = tmpint; + } + + if (zplDataParts.Length > 4) + { + menuSymbol = ConvertBoolean(zplDataParts[4]); + } + + if (zplDataParts.Length > 5 && int.TryParse(zplDataParts[5], out tmpint)) + { + symbolCount = tmpint; + } + + if (zplDataParts.Length > 6) + { + idField = zplDataParts[6]; + } + + this.VirtualPrinter.SetNextElementFieldData(new AztecBarcodeFieldData + { + FieldOrientation = fieldOrientation, + MagnificationFactor = magnificationFactor, + ExtendedChannel = extendedChannel, + ErrorControl = errorControl, + MenuSymbol = menuSymbol, + SymbolCount = symbolCount, + IdField = idField + }); + + return null; + } + + } +} diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs index 0703d72..e58d47b 100644 --- a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs @@ -94,6 +94,10 @@ public override ZplElementBase Analyze(string zplCommand) { return new ZplPDF417(text, x, y, pdf147.Height, moduleWidth, pdf147.Columns, pdf147.Rows, pdf147.Compact, pdf147.SecurityLevel, pdf147.FieldOrientation, bottomToTop); } + if (this.VirtualPrinter.NextElementFieldData is AztecBarcodeFieldData aztec) + { + return new ZplAztecBarcode(text, x, y, aztec.MagnificationFactor, aztec.ExtendedChannel, aztec.ErrorControl, aztec.MenuSymbol, aztec.SymbolCount, aztec.IdField, useHexadecimalIndicator, aztec.FieldOrientation, bottomToTop); + } } var font = this.GetFontFromVirtualPrinter(); diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/AztecBarcodeElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/AztecBarcodeElementDrawer.cs new file mode 100644 index 0000000..2f43cca --- /dev/null +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/AztecBarcodeElementDrawer.cs @@ -0,0 +1,64 @@ +using BinaryKits.Zpl.Label.Elements; +using BinaryKits.Zpl.Viewer.Helpers; + +using SkiaSharp; + +using ZXing.Aztec; + +namespace BinaryKits.Zpl.Viewer.ElementDrawers +{ + public class AztecBarcodeElementDrawer : BarcodeDrawerBase + { + /// + public override bool CanDraw(ZplElementBase element) + { + return element is ZplAztecBarcode; + } + + /// + public override void Draw(ZplElementBase element) + { + if (element is ZplAztecBarcode aztecBarcode) + { + float x = aztecBarcode.PositionX; + float y = aztecBarcode.PositionY; + + var content = aztecBarcode.Content; + + if (aztecBarcode.UseHexadecimalIndicator) + { + content = content.ReplaceHexEscapes(); + } + + var writer = new AztecWriter(); + var options = new AztecEncodingOptions(); + if (aztecBarcode.ErrorControl >= 1 && aztecBarcode.ErrorControl <= 99) + { + options.ErrorCorrection = aztecBarcode.ErrorControl; + } + else if (aztecBarcode.ErrorControl >= 101 && aztecBarcode.ErrorControl <= 104) + { + options.Layers = 100 - aztecBarcode.ErrorControl; + } + else if (aztecBarcode.ErrorControl >= 201 && aztecBarcode.ErrorControl <= 232) + { + options.Layers = aztecBarcode.ErrorControl - 200; + } + else if (aztecBarcode.ErrorControl == 300) + { + options.PureBarcode = true; + } + else + { + // default options + } + + var result = writer.encode(content, ZXing.BarcodeFormat.AZTEC, 0, 0, options.Hints); + + using var resizedImage = this.BitMatrixToSKBitmap(result, aztecBarcode.MagnificationFactor); + var png = resizedImage.Encode(SKEncodedImageFormat.Png, 100).ToArray(); + this.DrawBarcode(png, x, y, resizedImage.Width, resizedImage.Height, aztecBarcode.FieldOrigin != null, aztecBarcode.FieldOrientation); + } + } + } +} diff --git a/src/BinaryKits.Zpl.Viewer/Models/AztecBarcodeFieldData.cs b/src/BinaryKits.Zpl.Viewer/Models/AztecBarcodeFieldData.cs new file mode 100644 index 0000000..7d89e44 --- /dev/null +++ b/src/BinaryKits.Zpl.Viewer/Models/AztecBarcodeFieldData.cs @@ -0,0 +1,16 @@ +using BinaryKits.Zpl.Label; + +namespace BinaryKits.Zpl.Viewer.Models +{ + public class AztecBarcodeFieldData : FieldDataBase + { + public FieldOrientation FieldOrientation { get; set; } + public int MagnificationFactor { get; set; } + public bool ExtendedChannel { get; set; } + public int ErrorControl { get; set; } + public bool MenuSymbol { get; set; } + public int SymbolCount { get; set; } + public string IdField { get; set; } + + } +} diff --git a/src/BinaryKits.Zpl.Viewer/ZplAnalyzer.cs b/src/BinaryKits.Zpl.Viewer/ZplAnalyzer.cs index fb79d97..2b31075 100644 --- a/src/BinaryKits.Zpl.Viewer/ZplAnalyzer.cs +++ b/src/BinaryKits.Zpl.Viewer/ZplAnalyzer.cs @@ -37,6 +37,7 @@ public AnalyzeInfo Analyze(string zplData) var elementAnalyzers = new List { fieldDataAnalyzer, + new AztecBarcodeZplCommandAnalyzer(this._virtualPrinter), new BarCodeFieldDefaultZplCommandAnalyzer(this._virtualPrinter), new ChangeAlphanumericDefaultFontZplCommandAnalyzer(this._virtualPrinter), new Code39BarcodeZplCommandAnalyzer(this._virtualPrinter), @@ -70,7 +71,6 @@ public AnalyzeInfo Analyze(string zplData) new RecallFormatCommandAnalyzer(this._virtualPrinter), new RecallGraphicZplCommandAnalyzer(this._virtualPrinter), new ScalableBitmappedFontZplCommandAnalyzer(this._virtualPrinter), - }; var labelInfos = new List(); diff --git a/src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs index a94c33b..70f2c5d 100644 --- a/src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs @@ -24,6 +24,7 @@ public ZplElementDrawer(IPrinterStorage printerStorage, DrawerOptions drawerOpti this._printerStorage = printerStorage; this._elementDrawers = new IElementDrawer[] { + new AztecBarcodeElementDrawer(), new Barcode128ElementDrawer(), new Barcode39ElementDrawer(), new Barcode93ElementDrawer(), @@ -33,11 +34,11 @@ public ZplElementDrawer(IPrinterStorage printerStorage, DrawerOptions drawerOpti new GraphicBoxElementDrawer(), new GraphicCircleElementDrawer(), new GraphicFieldElementDrawer(), - new Interleaved2of5BarcodeDrawer(), new ImageMoveElementDrawer(), + new Interleaved2of5BarcodeDrawer(), new MaxiCodeElementDrawer(), - new QrCodeElementDrawer(), new Pdf417ElementDrawer(), + new QrCodeElementDrawer(), new RecallGraphicElementDrawer(), new TextFieldElementDrawer() };