Skip to content

Commit

Permalink
Drop BarcodeLib dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
primo-ppcg committed Jun 24, 2023
1 parent 92bf320 commit 23a4a12
Show file tree
Hide file tree
Showing 20 changed files with 401 additions and 247 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
^XA

^FO10,10
^BY3
^FO60,10
^BY1
^BEN,50,Y
^FD123456789012^FS

^FO60,90
^BY2
^BEN,100,Y
^FD123456789012^FS

^FO10,160
^FO60,230
^BY3
^BEN,150,Y
^FD123456789012^FS

^FO60,430
^BY4
^BEN,100,Y
^BEN,200,Y
^FD123456789012^FS

^FO10,320
^FO60,700
^BY5
^BEN,100,Y
^BEN,250,Y
^FD123456789012^FS

^XZ
1 change: 0 additions & 1 deletion src/BinaryKits.Zpl.Viewer/BinaryKits.Zpl.Viewer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BarcodeLib" Version="2.4.0" />
<PackageReference Include="SkiaSharp" Version="2.88.3" />
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.88.3" />
<PackageReference Include="ZXing.Net" Version="0.16.9" />
Expand Down
71 changes: 33 additions & 38 deletions src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs
Original file line number Diff line number Diff line change
@@ -1,52 +1,47 @@
using BarcodeLib;
using BinaryKits.Zpl.Label.Elements;
using BinaryKits.Zpl.Viewer.Helpers;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text.RegularExpressions;
using ZXing.OneD;

namespace BinaryKits.Zpl.Viewer.ElementDrawers
{
/// <summary>
/// Drawer for Code 128 Barcode elements
/// </summary>
public class Barcode128ElementDrawer : BarcodeDrawerBase
{

/// <summary>
/// Start sequence lookups.
/// <see href="https://supportcommunity.zebra.com/s/article/Creating-GS1-Barcodes-with-Zebra-Printers-for-Data-Matrix-and-Code-128-using-ZPL"/>
/// </summary>
private static readonly Dictionary<string, TYPE> startCodeMap = new Dictionary<string, TYPE>()
private static readonly Dictionary<string, Code128EncodingOptions.Codesets> startCodeMap = new()
{
{ ">9", TYPE.CODE128A },
{ ">:", TYPE.CODE128B },
{ ">;", TYPE.CODE128C }
{ ">9", Code128EncodingOptions.Codesets.A },
{ ">:", Code128EncodingOptions.Codesets.B },
{ ">;", Code128EncodingOptions.Codesets.C }
};

private static readonly Regex startCodeRegex = new Regex(@"^(>[9:;])(.+)$", RegexOptions.Compiled);
private static readonly Regex invalidInvocationRegex = new Regex(@"(?<!^)>[9:;]", RegexOptions.Compiled);

// As defined in BarcodeLib.Symbologies.Code128
private static readonly string FNC1 = Convert.ToChar(200).ToString();
// As defined in ZXing.OneD.Code128Writer
private static readonly string FNC1 = Convert.ToChar(241).ToString();

///<inheritdoc/>
public override bool CanDraw(ZplElementBase element)
{
return element is ZplBarcode128;
}

///<inheritdoc/>
public override void Draw(ZplElementBase element)
{
Draw(element, new DrawerOptions());
}

///<inheritdoc/>
public override void Draw(ZplElementBase element, DrawerOptions options)
{
if (element is ZplBarcode128 barcode)
{
var barcodeType = TYPE.CODE128B;
var encodingOptions = new Code128EncodingOptions();
encodingOptions.Margin = 0;
// remove any start sequences not at the start of the content (invalid invocation)
string content = invalidInvocationRegex.Replace(barcode.Content, "");
string interpretation = content;
Expand All @@ -55,22 +50,26 @@ public override void Draw(ZplElementBase element, DrawerOptions options)
Match startCodeMatch = startCodeRegex.Match(content);
if (startCodeMatch.Success)
{
barcodeType = startCodeMap[startCodeMatch.Groups[1].Value];
encodingOptions.ForceCodeset = startCodeMap[startCodeMatch.Groups[1].Value];
content = startCodeMatch.Groups[2].Value;
interpretation = content;
}
else
{
encodingOptions.ForceCodeset = Code128EncodingOptions.Codesets.B;
}
// support hand-rolled GS1
content = content.Replace(">8", FNC1);
interpretation = interpretation.Replace(">8", "");
// TODO: support remaining escapes within a barcode
}
else if (barcode.Mode == "A")
{
barcodeType = TYPE.CODE128; // dynamic
encodingOptions.CompactEncoding = true;
}
else if (barcode.Mode == "D")
{
barcodeType = TYPE.CODE128C;
encodingOptions.GS1Format = true;
content = content.Replace(">8", FNC1);
interpretation = interpretation.Replace(">8", "");
if (!content.StartsWith(FNC1))
Expand All @@ -80,7 +79,7 @@ public override void Draw(ZplElementBase element, DrawerOptions options)
}
else if (barcode.Mode == "U")
{
barcodeType = TYPE.CODE128C;
encodingOptions.ForceCodeset = Code128EncodingOptions.Codesets.C;
content = content.PadLeft(19, '0').Substring(0, 19);
int checksum = 0;
for (int i = 0; i < 19; i++)
Expand All @@ -94,26 +93,22 @@ public override void Draw(ZplElementBase element, DrawerOptions options)
float x = barcode.PositionX;
float y = barcode.PositionY;

float labelFontSize = Math.Min(barcode.ModuleWidth * 7.2f, 72f);
var labelTypeFace = options.FontLoader("A");
var labelFont = new SKFont(labelTypeFace, labelFontSize).ToSystemDrawingFont();
int labelHeight = barcode.PrintInterpretationLine ? labelFont.Height : 0;
int labelHeightOffset = barcode.PrintInterpretationLineAboveCode ? labelHeight : 0;
var writer = new Code128Writer();
var result = writer.encode(content, ZXing.BarcodeFormat.CODE_128, 0, 0, encodingOptions.Hints);
using var resizedImage = this.BitArrayToSKBitmap(result.getRow(0, null), barcode.Height, barcode.ModuleWidth);
var png = resizedImage.Encode(SKEncodedImageFormat.Png, 100).ToArray();
this.DrawBarcode(png, x, y, resizedImage.Width, resizedImage.Height, barcode.FieldOrigin != null, barcode.FieldOrientation);

var barcodeElement = new Barcode
if (barcode.PrintInterpretationLine)
{
BarWidth = barcode.ModuleWidth,
BackColor = Color.Transparent,
Height = barcode.Height + labelHeight,
IncludeLabel = barcode.PrintInterpretationLine,
LabelPosition = barcode.PrintInterpretationLineAboveCode ? LabelPositions.TOPCENTER : LabelPositions.BOTTOMCENTER,
LabelFont = labelFont,
AlternateLabel = interpretation
};

using var image = barcodeElement.Encode(barcodeType, content);
this.DrawBarcode(this.GetImageData(image), barcode.Height, image.Width, barcode.FieldOrigin != null, x, y, labelHeightOffset, barcode.FieldOrientation);
// TODO: use font 0, auto scale for Mode D
float labelFontSize = Math.Min(barcode.ModuleWidth * 9f, 90f);
var labelTypeFace = options.FontLoader("A");
var labelFont = new SKFont(labelTypeFace, labelFontSize);
this.DrawInterpretationLine(interpretation, labelFont, x, y, resizedImage.Width, resizedImage.Height, barcode.FieldOrigin != null, barcode.FieldOrientation, barcode.PrintInterpretationLineAboveCode);
}
}
}

}
}
48 changes: 20 additions & 28 deletions src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode39ElementDrawer.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using BarcodeLib;
using BinaryKits.Zpl.Label.Elements;
using BinaryKits.Zpl.Viewer.Helpers;
using SkiaSharp;
using System;
using System.Drawing;
using ZXing.OneD;

namespace BinaryKits.Zpl.Viewer.ElementDrawers
{
/// <summary>
/// Drawer for Code 39 Barcode elements
/// </summary>
public class Barcode39ElementDrawer : BarcodeDrawerBase
{
///<inheritdoc/>
Expand All @@ -15,12 +16,6 @@ public override bool CanDraw(ZplElementBase element)
return element is ZplBarcode39;
}

///<inheritdoc/>
public override void Draw(ZplElementBase element)
{
Draw(element, new DrawerOptions());
}

///<inheritdoc/>
public override void Draw(ZplElementBase element, DrawerOptions options)
{
Expand All @@ -29,28 +24,25 @@ public override void Draw(ZplElementBase element, DrawerOptions options)
float x = barcode.PositionX;
float y = barcode.PositionY;

var content = barcode.Content;
var interpretation = string.Format("*{0}*", content.Trim('*'));
var content = barcode.Content.Trim('*');
var interpretation = string.Format("*{0}*", content);

float labelFontSize = Math.Min(barcode.ModuleWidth * 7.2f, 72f);
var labelTypeFace = options.FontLoader("A");
var labelFont = new SKFont(labelTypeFace, labelFontSize).ToSystemDrawingFont();
int labelHeight = barcode.PrintInterpretationLine ? labelFont.Height : 0;
int labelHeightOffset = barcode.PrintInterpretationLineAboveCode ? labelHeight : 0;
var writer = new Code39Writer();
var result = writer.encode(content);
int narrow = barcode.ModuleWidth;
int wide = (int)Math.Floor(barcode.WideBarToNarrowBarWidthRatio * narrow);
result = this.AdjustWidths(result, wide, narrow);
using var resizedImage = this.BoolArrayToSKBitmap(result, barcode.Height);
var png = resizedImage.Encode(SKEncodedImageFormat.Png, 100).ToArray();
this.DrawBarcode(png, x, y, resizedImage.Width, resizedImage.Height, barcode.FieldOrigin != null, barcode.FieldOrientation);

var barcodeElement = new Barcode
if (barcode.PrintInterpretationLine)
{
BarWidth = barcode.ModuleWidth,
BackColor = Color.Transparent,
Height = barcode.Height + labelHeight,
IncludeLabel = barcode.PrintInterpretationLine,
LabelPosition = barcode.PrintInterpretationLineAboveCode ? LabelPositions.TOPCENTER : LabelPositions.BOTTOMCENTER,
LabelFont = labelFont,
AlternateLabel = interpretation
};

using var image = barcodeElement.Encode(TYPE.CODE39Extended, content);
this.DrawBarcode(this.GetImageData(image), barcode.Height, image.Width, barcode.FieldOrigin != null, x, y, labelHeightOffset, barcode.FieldOrientation);
float labelFontSize = Math.Min(barcode.ModuleWidth * 9f, 90f);
var labelTypeFace = options.FontLoader("A");
var labelFont = new SKFont(labelTypeFace, labelFontSize);
this.DrawInterpretationLine(interpretation, labelFont, x, y, resizedImage.Width, resizedImage.Height, barcode.FieldOrigin != null, barcode.FieldOrientation, barcode.PrintInterpretationLineAboveCode);
}
}
}
}
Expand Down
Loading

0 comments on commit 23a4a12

Please sign in to comment.