Skip to content

Commit

Permalink
Merge branch 'develop' into viewer-testing-structure
Browse files Browse the repository at this point in the history
  • Loading branch information
primo-ppcg authored Apr 23, 2024
2 parents 68c4fd5 + a41fc18 commit 330f951
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 14 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/dotnet - test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: .NET

on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]

jobs:
build-windows:

runs-on: windows-latest

steps:
- uses: actions/checkout@v2
- name: Setup .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
- name: Restore dependencies
working-directory: ./src
run: dotnet restore
- name: Build
working-directory: ./src
run: dotnet build --configuration Release --no-restore /p:NoWarn=1591
- name: Test
working-directory: ./src
run: dotnet test --configuration Release --no-restore --no-build --verbosity normal

build-linux:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Setup .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
- name: Restore dependencies
working-directory: ./src
run: dotnet restore
- name: Build
working-directory: ./src
run: dotnet build --configuration Release --no-restore /p:NoWarn=1591
- name: Test
working-directory: ./src
run: dotnet test --configuration Release --no-restore --no-build --verbosity normal


2 changes: 1 addition & 1 deletion src/BinaryKits.Zpl.Viewer.UnitTest/DrawerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ public void InvertColor()
Common.DefaultPrint(test2, "inverted2.png");
}
}
}
}
8 changes: 4 additions & 4 deletions src/BinaryKits.Zpl.Viewer.WebApi/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<head>
<meta charset="utf-8" />
<title>BinaryKits.Zpl.Viewer.WebApi</title>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/axios@0.21.1/dist/axios.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/bootstrap@4.4.0/dist/css/bootstrap.css" />
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.css" />
</head>
<body>
<div id="app" class="container-fluid mt-1">
Expand Down Expand Up @@ -209,4 +209,4 @@ <h4>Label rendering error</h4>
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
</html>
4 changes: 2 additions & 2 deletions src/BinaryKits.Zpl.Viewer/BinaryKits.Zpl.Viewer.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net472;netstandard2.0;net6.0</TargetFrameworks>
Expand All @@ -23,7 +23,7 @@

<ItemGroup>
<PackageReference Include="BarcodeLib" Version="2.4.0" />
<PackageReference Include="SkiaSharp" Version="2.88.3" />
<PackageReference Include="SkiaSharp" Version="2.88.6" />
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.88.3" />
<PackageReference Include="ZXing.Net" Version="0.16.9" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class FieldDataZplCommandAnalyzer : ZplCommandAnalyzerBase
private static readonly Regex qrCodeFieldDataMixedRegex = new Regex(@"^D\d{4}[0-9A-F-a-f]{2},(?<correction>[HQML])(?<input>[AM]),(?<data>.+)$", RegexOptions.Compiled);
private static readonly Regex qrCodeFieldDataModeRegex = new Regex(@"^(?:[ANK]|(?:B(?<count>\d{4})))(?<data>.+)$", RegexOptions.Compiled);

public FieldDataZplCommandAnalyzer(VirtualPrinter virtualPrinter) : base("^FD", virtualPrinter) { }
public FieldDataZplCommandAnalyzer(VirtualPrinter virtualPrinter, string prefix="^FD") : base(prefix, virtualPrinter) { }

///<inheritdoc/>
public override ZplElementBase Analyze(string zplCommand)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace BinaryKits.Zpl.Viewer.CommandAnalyzers
{
// todo: fix virtual printer, must enable the MC command
// todo: factor out common parts from FieldDataZplCommandAnalyzer so both can inherit
// This is currently just a hack to be able to visualize single ups zpl.
// The FV command is normally used with the MC command when printing multiple labels of a same pattern.
// The MC command allows us to "save" the first label as a template
// using FDs as static elements of template and FVs as variable parts.
// Subsequent labels only require FV to draw the variable parts.
public class FieldVariableZplCommandAnalyzer : FieldDataZplCommandAnalyzer
{
public FieldVariableZplCommandAnalyzer(VirtualPrinter virtualPrinter): base(virtualPrinter, "^FV") { }
}
}
83 changes: 82 additions & 1 deletion src/BinaryKits.Zpl.Viewer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,85 @@ foreach (var labelInfo in analyzeInfo.LabelInfos)
var imageData = drawer.Draw(labelInfo.ZplElements);
//imageData is bytes of png image
}
```
```

# Adding Barcode support
Also applies to other "drawables", like shapes and graphics.

## Common barcodes still missing support
### 1D
- [ ] Code 93: Supported by Xzing.net
- [ ] MSI: Supported by Xzing.net
- [ ] Codabar/NW7: Supported by Xzing.net
- [ ] Databar/RSS-14: Not supported by Xzing.net
- [ ] [Code 11](https://web.archive.org/web/20070202060711/http://www.barcodeisland.com/code11.phtml): Not supported by Xzing.net, simple to implement

### 2D
- [ ] Maxicode: Not supported by Xzing.net, required for UPS labels
- [ ] Aztec: Supported by Xzing.net
- [ ] Micro pdf417: Not supported by Xzing.net
- ascii data only
- appears to be a subset of pdf417
- [ ] Micro QrCode: Not supported by Xzing.net
- appears to be a subset of QrCode
- [ ] Composite: Not supported by Xzing.net, simple to implement

## Examples
- [EAN Barcode](https://github.com/BinaryKits/BinaryKits.Zpl/commit/3fac409732e19be9e047ee71f942ba1f68c6fa5c)
- [Datamatrix Barcode](https://github.com/BinaryKits/BinaryKits.Zpl/commit/f79d01512eee7e3d16246e932877ca6d4aa4e306)
- [PDF417 Barcode](https://github.com/BinaryKits/BinaryKits.Zpl/pull/190/files)

## Steps
Generally, looking at files in the directory for each step should give you a clue on how to implement a file.

### 1: Create the abstract element
This is a class used to represent the barcode with all it's settings, mostly to be used for zpl generation.
We are currently in the middle of a (stalled) refactor which leads to some amount of code duplication.
A class should be created in these `<project>/<directory>`:
- `BinaryKits.Zpl.Label/Elements/`
- `BinaryKits.Zpl.Protocol/Commands/`

For 2d barcodes, implement `ZplPositionedElementBase` and `IFormatElement`, for 1d barcodes, subclass `ZplBarcode`

### 2: Create a model in `BinaryKits.Zpl.Viewer/Models/`
This one is only used for the viewer project and should contain mostly the same properties as the class created in the previous step.

### 3: Create the command analyzer in `BinaryKits.Zpl.Viewer/CommandAnalyzers/`
This is where you write the code for parsing zpl to the Model/Element.

- Subclass from `ZplCommandAnalyzerBase`
- Use `this.SplitCommand` get all the zpl arguments
- Remember to check that the length of args array is long enough before trying to parse at an index
- Remember to set the defaults each parameter before parsing
- There are parameters stored in the virtual printer such as `^BY`
- Otherwise use the defaults as described in the zpl programming manual
- Because there is always data to encode, set the next field data encountered by the virtual printer to return the content to the model

### 4: Add an entry to `BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs`
This is to make sure that we grab the `text`, the model from the previous step it into a new instance of the abstract element.

Find the massive `if` chain following `if (this.VirtualPrinter.NextElementFieldData != null)` and add an entry for your mode.

Architecturally, this type of hard binding is probably not good. We should probably fix this.

### 5: Add an entry to `BinaryKits.Zpl.Viewer/ZPLAnalyzer.cs`
Find the List `elementAnalyzers` and instantiate your analyzer there.

### 6: Create a drawer in `BinaryKits.Zpl.Viewer/ElementDrawers`
- Subclass `BarcodeDrawerBase`
- Implement `CanDraw` by checking against the abstract element in step 1.
- Implement `Draw`. Working from the end:
- The end goal is to write some pixels (a skia bitmap) to the base canvas with `this.DrawBarcode`
- Those pixels will be obtained by converting an abstract barcode drawing to a png `SKBitmap`
- The abstract drawing will be generated by calling an external library with the correct parameters obtained from the abstract element
- Zxing.net uses hints to pass in extra parameters
- Some adaptative helper functions may needed to convert between the library types and skia bitmaps or binarykit.zpl models
- `BarcodeDrawerBase` may have some helper functions needed

### 7: Add an entry to `BinaryKits.Zpl.Viewer/ZPLElementDrawer.cs`
Find the array `this._elementDrawers` and instantiate your drawer there.

### 8: Create a test in to `BinaryKits.Zpl.Viewer.UnitTest/DrawerTest.cs`
- todo: load data from BinaryKits.Zpl.Viewer.UnitTest/Data/zpl like in the webapi project
- Use the `DefaultPrint` function when possible, you can pass dimensions, density and drawer options
- todo: an empty custom file `BinaryKits.Zpl.Viewer.UnitTest/Data/zpl/custom.zpl2` is not under vcs to enable quick testing
25 changes: 20 additions & 5 deletions src/BinaryKits.Zpl.Viewer/ZplAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public AnalyzeInfo Analyze(string zplData)
new FieldBlockZplCommandAnalyzer(this._virtualPrinter),
new FieldHexadecimalZplCommandAnalyzer(this._virtualPrinter),
new FieldNumberCommandAnalyzer(this._virtualPrinter),
new FieldVariableZplCommandAnalyzer(this._virtualPrinter),
new FieldReversePrintZplCommandAnalyzer(this._virtualPrinter),
new LabelReversePrintZplCommandAnalyzer(this._virtualPrinter),
new FieldSeparatorZplCommandAnalyzer(this._virtualPrinter, fieldDataAnalyzer),
Expand Down Expand Up @@ -121,6 +122,11 @@ public AnalyzeInfo Analyze(string zplData)
return analyzeInfo;
}

// When adding new commands: 1 per line, always upper case, comment why if possible
private string[] ignoredCommands = {
"CI", // may be implemented in the future, but for now always set to CI128
};

private string[] SplitZplCommands(string zplData)
{
if (string.IsNullOrWhiteSpace(zplData))
Expand All @@ -133,32 +139,41 @@ private string[] SplitZplCommands(string zplData)
char tilde = '~';
List<string> results = new(200);
StringBuilder buffer = new(2000);
HashSet<string> ignoredCommandsHS = new HashSet<string>(ignoredCommands);
for (int i = 0; i < cleanZpl.Length; i++)
{
char c = cleanZpl[i];
if (c == caret || c == tilde)
{
string command = buffer.ToString();
buffer.Clear();

// all commands have at least 3 chars, even ^A because of required font parameter
if (command.Length > 2)
{
PatchCommand(ref command, ref caret, ref tilde);
results.Add(command);
if (command.Substring(1, 2) == "CT")

var commandLetters = command.Substring(1, 2).ToUpper();

if (ignoredCommandsHS.Contains(commandLetters)) {
continue;
}
else if (commandLetters == "CT")
{
tilde = command[3];
results.RemoveAt(results.Count - 1);
}
else if (command.Substring(1, 2) == "CC")
else if (commandLetters == "CC")
{
caret = command[3];
results.RemoveAt(results.Count - 1);
} else {
results.Add(command);
}
}
// likely invalid command
else if (command.Trim().Length > 0) {
results.Add(command.Trim());
}
// no else case, multiple ^ or ~ in a row should not be valid commands to be processed
}
buffer.Append(c);
}
Expand Down

0 comments on commit 330f951

Please sign in to comment.