From 556198b74cf51d2aa6150057a0750070d675976c Mon Sep 17 00:00:00 2001 From: Daniel Knapik Date: Tue, 18 Jun 2024 13:47:01 +1000 Subject: [PATCH] Updated ZplElementDrawer to draw a label to an external SKSurface. Updated element drawers to concat the element rotation matrix to support label viewer rotation. --- .../ElementDrawers/BarcodeDrawerBase.cs | 8 +- .../BarcodeEAN13ElementDrawer.cs | 4 +- .../ElementDrawers/FieldBlockElementDrawer.cs | 4 +- .../ElementDrawers/TextFieldElementDrawer.cs | 4 +- src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs | 76 +++++++++++++++++++ 5 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/BarcodeDrawerBase.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/BarcodeDrawerBase.cs index eead6e1..12cf61c 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/BarcodeDrawerBase.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/BarcodeDrawerBase.cs @@ -37,7 +37,9 @@ protected void DrawBarcode( if (matrix != SKMatrix.Empty) { - this._skCanvas.SetMatrix(matrix); + var currentMatrix = _skCanvas.TotalMatrix; + var concatMatrix = SKMatrix.Concat(currentMatrix, matrix); + this._skCanvas.SetMatrix(concatMatrix); } this._skCanvas.DrawBitmap(SKBitmap.Decode(barcodeImageData), x, y); @@ -65,7 +67,9 @@ protected void DrawInterpretationLine( if (matrix != SKMatrix.Empty) { - this._skCanvas.SetMatrix(matrix); + var currentMatrix = _skCanvas.TotalMatrix; + var concatMatrix = SKMatrix.Concat(currentMatrix, matrix); + this._skCanvas.SetMatrix(concatMatrix); } var textBounds = new SKRect(); diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/BarcodeEAN13ElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/BarcodeEAN13ElementDrawer.cs index c0ca0b1..4b207fd 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/BarcodeEAN13ElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/BarcodeEAN13ElementDrawer.cs @@ -90,7 +90,9 @@ private void DrawEAN13InterpretationLine( if (matrix != SKMatrix.Empty) { - this._skCanvas.SetMatrix(matrix); + var currentMatrix = _skCanvas.TotalMatrix; + var concatMatrix = SKMatrix.Concat(currentMatrix, matrix); + this._skCanvas.SetMatrix(concatMatrix); } var textBounds = new SKRect(); diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/FieldBlockElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/FieldBlockElementDrawer.cs index 5e59cdb..72c2f87 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/FieldBlockElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/FieldBlockElementDrawer.cs @@ -128,7 +128,9 @@ public override void Draw(ZplElementBase element, DrawerOptions options) if (matrix != SKMatrix.Empty) { - this._skCanvas.SetMatrix(matrix); + var currentMatrix = _skCanvas.TotalMatrix; + var concatMatrix = SKMatrix.Concat(currentMatrix, matrix); + this._skCanvas.SetMatrix(concatMatrix); } foreach (var textLine in textLines) diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/TextFieldElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/TextFieldElementDrawer.cs index a0b6537..a47a54f 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/TextFieldElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/TextFieldElementDrawer.cs @@ -108,7 +108,9 @@ public override void Draw(ZplElementBase element, DrawerOptions options) if (matrix != SKMatrix.Empty) { - this._skCanvas.SetMatrix(matrix); + var currentMatrix = _skCanvas.TotalMatrix; + var concatMatrix = SKMatrix.Concat(currentMatrix, matrix); + this._skCanvas.SetMatrix(concatMatrix); } if (textField.FieldTypeset == null) diff --git a/src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs index 70f2c5d..226b683 100644 --- a/src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ZplElementDrawer.cs @@ -238,6 +238,82 @@ public List DrawMulti( return result; } + /// + /// Draw the label on the provided surface + /// + /// Skia Surface + /// Zpl elements + /// Label width in millimeter + /// Label height in millimeter + /// Dots per millimeter + /// + public void DrawSurface(SKSurface surface, + ZplElementBase[] elements, + double labelWidth = 101.6, + double labelHeight = 152.4, + int printDensityDpmm = 8) + { + var result = new List(); + var imageHistory = new List(); + var labelImageWidth = Convert.ToInt32(labelWidth * printDensityDpmm); + var labelImageHeight = Convert.ToInt32(labelHeight * printDensityDpmm); + + var skCanvas = surface.Canvas; + //This has an issue with AvaloniaUI making the window transparent. + skCanvas.Clear(SKColors.Transparent); + + foreach (var element in elements) + { + var drawer = this._elementDrawers.SingleOrDefault(o => o.CanDraw(element)); + if (drawer == null) + { + continue; + } + + try + { + if (drawer.IsReverseDraw(element)) + { + //basically only ZplGraphicBox/Circle depending on requirements + using var skBitmapInvert = new SKBitmap(labelImageWidth, labelImageHeight); + using var skCanvasInvert = new SKCanvas(skBitmapInvert); + skCanvasInvert.Clear(SKColors.Transparent); + + drawer.Prepare(this._printerStorage, skCanvasInvert); + drawer.Draw(element, _drawerOptions); + + //use color inversion on an reverse draw white element + if (drawer.IsWhiteDraw(element)) + { + this.InvertDrawWhite(skCanvas, skBitmapInvert); + } + else + { + this.InvertDraw(skCanvas, skBitmapInvert); + } + + continue; + } + + drawer.Prepare(this._printerStorage, skCanvas); + drawer.Draw(element, _drawerOptions); + + continue; + } + catch (Exception ex) + { + if (element is ZplBarcode barcodeElement) + throw new Exception($"Error on zpl element \"{barcodeElement.Content}\": {ex.Message}", ex); + else if (element is ZplDataMatrix dataMatrixElement) + throw new Exception($"Error on zpl element \"{dataMatrixElement.Content}\": {ex.Message}", ex); + else + { + throw; + } + } + } + } + /** * PDF transparency and SKBlendMode are not very good friends, SKBlendMode.Xor behaves as SKBlendMode.SrcOver. *