-
-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Drop BarcodeLib dependency * don't inline regex
- Loading branch information
1 parent
9dafc53
commit f949ad6
Showing
28 changed files
with
817 additions
and
345 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 16 additions & 6 deletions
22
src/BinaryKits.Zpl.Viewer.WebApi/Labels/Test/BarcodeEAN13-102x152.zpl2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 26 additions & 91 deletions
117
src/BinaryKits.Zpl.Viewer/ElementDrawers/Barcode128ElementDrawer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,138 +1,73 @@ | ||
using BarcodeLib; | ||
using BinaryKits.Zpl.Label.Elements; | ||
using BinaryKits.Zpl.Viewer.Helpers; | ||
using BinaryKits.Zpl.Viewer.Symologies; | ||
using SkiaSharp; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Drawing; | ||
using System.Text.RegularExpressions; | ||
|
||
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>() | ||
{ | ||
{ ">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); | ||
|
||
// As defined in BarcodeLib.Symbologies.Code128 | ||
private static readonly string FNC1 = Convert.ToChar(200).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.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", ""); | ||
|
||
string content = barcode.Content; | ||
Code128CodeSet codeSet = Code128CodeSet.Code128B; | ||
bool gs1 = false; | ||
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 | ||
codeSet = Code128CodeSet.Code128B; | ||
} | ||
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 | ||
codeSet = Code128CodeSet.Code128; | ||
} | ||
else if (barcode.Mode == "D") | ||
{ | ||
//D (UCC/EAN mode, field data must contain GS1 numbers) | ||
barcodeType = TYPE.CODE128C; | ||
|
||
if (!content.StartsWith(FNC1)) | ||
{ | ||
content = FNC1 + content; | ||
} | ||
codeSet = Code128CodeSet.Code128C; | ||
gs1 = true; | ||
} | ||
else if (barcode.Mode == "U") | ||
{ | ||
//U (UCC case mode, field data must contain 19 digits) | ||
barcodeType = TYPE.CODE128C; | ||
codeSet = Code128CodeSet.Code128C; | ||
gs1 = true; | ||
content = content.PadLeft(19, '0').Substring(0, 19); | ||
int checksum = 0; | ||
for (int i = 0; i < 19; i++) | ||
{ | ||
checksum += (content[i] - 48) * (i % 2 * 2 + 7); | ||
} | ||
interpretation = string.Format("{0}{1}", interpretation, checksum % 10); | ||
content = string.Format("{0}{1}{2}", FNC1, content, checksum % 10); | ||
content = $">8{content}{checksum % 10}"; | ||
} | ||
|
||
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 (data, interpretation) = ZplCode128Symbology.Encode(content, codeSet, gs1); | ||
using var resizedImage = this.BoolArrayToSKBitmap(data.ToArray(), 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 * 10f, 100f); | ||
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, options); | ||
} | ||
} | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.