Skip to content

Commit

Permalink
Implement Aztec Barcode
Browse files Browse the repository at this point in the history
  • Loading branch information
primo-ppcg committed May 30, 2024
1 parent 7961201 commit af2ea1e
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 5 deletions.
76 changes: 76 additions & 0 deletions src/BinaryKits.Zpl.Label/Elements/ZplAztecBarcode.cs
Original file line number Diff line number Diff line change
@@ -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; }

/// <summary>
/// Aztec Bar Code
/// </summary>
/// <param name="content"></param>
/// <param name="positionX"></param>
/// <param name="positionY"></param>
/// <param name="magnificationFactor"></param>
/// <param name="extendedChannel">extended channel interpretation code indicator</param>
/// <param name="errorControl">error control and symbol size/type indicator</param>
/// <param name="menuSymbol">menu symbol indicator</param>
/// <param name="symbolCount">number of symbols for structured append</param>
/// <param name="idField">optional ID field for structured append</param>
/// <param name="useHexadecimalIndicator"></param>
/// <param name="fieldOrientation"></param>
/// <param name="bottomToTop"></param>
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;
}

///<inheritdoc/>
public override IEnumerable<string> Render(ZplRenderOptions context)
{
var result = new List<string>();
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;
}

/// <inheritdoc />
public void SetTemplateContent(string content)
{
this.Content = content;
}
}
}
14 changes: 12 additions & 2 deletions src/BinaryKits.Zpl.Label/Elements/ZplElementBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;

namespace BinaryKits.Zpl.Label.Elements
Expand All @@ -8,7 +8,7 @@ public abstract class ZplElementBase
public List<string> Comments { get; protected set; }

/// <summary>
/// Indicate the rendering process whether this elemenet can be skipped
/// Indicate the rendering process whether this element can be skipped
/// </summary>
public bool IsEnabled { get; set; }

Expand Down Expand Up @@ -108,6 +108,16 @@ public string RenderErrorCorrectionLevel(ErrorCorrectionLevel errorCorrectionLev
throw new NotImplementedException("Unknown Error Correction Level");
}

/// <summary>
/// Render Zpl char for boolean
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public string RenderBoolean(bool value)
{
return value ? "Y" : "N";
}

public string ToZplString()
{
return ToZplString(new ZplRenderOptions());
Expand Down
Original file line number Diff line number Diff line change
@@ -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) { }

///<inheritdoc/>
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;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
///<inheritdoc/>
public override bool CanDraw(ZplElementBase element)
{
return element is ZplAztecBarcode;
}

///<inheritdoc/>
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);
}
}
}
}
16 changes: 16 additions & 0 deletions src/BinaryKits.Zpl.Viewer/Models/AztecBarcodeFieldData.cs
Original file line number Diff line number Diff line change
@@ -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; }

}
}
2 changes: 1 addition & 1 deletion src/BinaryKits.Zpl.Viewer/ZplAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public AnalyzeInfo Analyze(string zplData)
var elementAnalyzers = new List<IZplCommandAnalyzer>
{
fieldDataAnalyzer,
new AztecBarcodeZplCommandAnalyzer(this._virtualPrinter),
new BarCodeFieldDefaultZplCommandAnalyzer(this._virtualPrinter),
new ChangeAlphanumericDefaultFontZplCommandAnalyzer(this._virtualPrinter),
new Code39BarcodeZplCommandAnalyzer(this._virtualPrinter),
Expand Down Expand Up @@ -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<LabelInfo>();
Expand Down
5 changes: 3 additions & 2 deletions src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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()
};
Expand Down

0 comments on commit af2ea1e

Please sign in to comment.