Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation on how to add barcode support #198

Merged
merged 1 commit into from
Apr 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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