From cbcf6e3cc1861e45251d251fac4ef104c6ac58ba Mon Sep 17 00:00:00 2001 From: primo-ppcg Date: Tue, 28 May 2024 13:54:53 +0700 Subject: [PATCH] Add Field Justification Add field justification parameter for `^FW`, `^FO`, and `^FT`. --- .../Elements/ZplElementBase.cs | 17 +++++++++++ .../Elements/ZplFieldOrientation.cs | 11 +++++-- .../Elements/ZplFieldOrigin.cs | 13 +++++---- .../Elements/ZplFieldTypeset.cs | 13 +++++---- .../Elements/ZplPositionedElementBase.cs | 7 +++-- .../Elements/ZplTextField.cs | 6 ++-- .../FieldJustification.cs | 25 ++++++++++++++++ .../FieldDataZplCommandAnalyzer.cs | 7 ++++- .../FieldOrientationZplCommandAnalyzer.cs | 6 ++++ .../FieldOriginZplCommandAnalzer.cs | 6 ++++ .../FieldSeparatorZplCommandAnalyzer.cs | 1 + .../FieldTypesetZplCommandAnalyzer.cs | 6 ++++ .../ZplCommandAnalyzerBase.cs | 11 +++++++ .../ElementDrawers/TextFieldElementDrawer.cs | 23 +++++++++++++++ src/BinaryKits.Zpl.Viewer/VirtualPrinter.cs | 29 +++++++++++++++---- 15 files changed, 157 insertions(+), 24 deletions(-) create mode 100644 src/BinaryKits.Zpl.Label/FieldJustification.cs diff --git a/src/BinaryKits.Zpl.Label/Elements/ZplElementBase.cs b/src/BinaryKits.Zpl.Label/Elements/ZplElementBase.cs index 99b82f5a..ac10e2b7 100644 --- a/src/BinaryKits.Zpl.Label/Elements/ZplElementBase.cs +++ b/src/BinaryKits.Zpl.Label/Elements/ZplElementBase.cs @@ -61,6 +61,23 @@ public string RenderFieldOrientation(FieldOrientation fieldOrientation) throw new NotImplementedException("Unknown Field Orientation"); } + public string RenderFieldJustification(FieldJustification fieldJustification) + { + switch (fieldJustification) + { + case FieldJustification.None: + return string.Empty; + case FieldJustification.Left: + return "0"; + case FieldJustification.Right: + return "1"; + case FieldJustification.Auto: + return "2"; + } + + throw new NotImplementedException("Unknown Field Justification"); + } + public string RenderLineColor(LineColor lineColor) { switch (lineColor) diff --git a/src/BinaryKits.Zpl.Label/Elements/ZplFieldOrientation.cs b/src/BinaryKits.Zpl.Label/Elements/ZplFieldOrientation.cs index e7290894..b82408fa 100644 --- a/src/BinaryKits.Zpl.Label/Elements/ZplFieldOrientation.cs +++ b/src/BinaryKits.Zpl.Label/Elements/ZplFieldOrientation.cs @@ -8,16 +8,23 @@ namespace BinaryKits.Zpl.Label.Elements public class ZplFieldOrientation : ZplElementBase { public FieldOrientation FieldOrientation { get; private set; } + public FieldJustification FieldJustification { get; private set; } - public ZplFieldOrientation(FieldOrientation fieldOrientation) + /// + /// Field Orientation + /// + /// + /// + public ZplFieldOrientation(FieldOrientation fieldOrientation, FieldJustification fieldJustification = FieldJustification.None) { this.FieldOrientation = fieldOrientation; + this.FieldJustification = fieldJustification; } /// public override IEnumerable Render(ZplRenderOptions context) { - return new[] { $"^FW{RenderFieldOrientation(this.FieldOrientation)}" }; + return new[] { $"^FW{RenderFieldOrientation(this.FieldOrientation)},{RenderFieldJustification(this.FieldJustification)}" }; } } diff --git a/src/BinaryKits.Zpl.Label/Elements/ZplFieldOrigin.cs b/src/BinaryKits.Zpl.Label/Elements/ZplFieldOrigin.cs index 7f8d48cc..56e3219b 100644 --- a/src/BinaryKits.Zpl.Label/Elements/ZplFieldOrigin.cs +++ b/src/BinaryKits.Zpl.Label/Elements/ZplFieldOrigin.cs @@ -14,23 +14,26 @@ public class ZplFieldOrigin : ZplElementBase { public int PositionX { get; protected set; } public int PositionY { get; protected set; } + public FieldJustification FieldJustification { get; protected set; } /// /// Field Origin /// /// X Position (0-32000) /// Y Position (0-32000) - public ZplFieldOrigin(int positionX, int positionY) + /// + public ZplFieldOrigin(int positionX, int positionY, FieldJustification fieldJustification = FieldJustification.None) { - PositionX = positionX; - PositionY = positionY; + this.PositionX = positionX; + this.PositionY = positionY; + this.FieldJustification = fieldJustification; } /// public override IEnumerable Render(ZplRenderOptions context) { //^FO50,50 - return new string[] { $"^FO{context.Scale(PositionX)},{context.Scale(PositionY)}" }; + return new string[] { $"^FO{context.Scale(this.PositionX)},{context.Scale(this.PositionY)},{RenderFieldJustification(this.FieldJustification)}" }; } /// @@ -41,7 +44,7 @@ public override IEnumerable Render(ZplRenderOptions context) /// public ZplFieldOrigin Offset(int offsetX, int offsetY) { - return new ZplFieldOrigin(PositionX + offsetX, PositionY + offsetY); + return new ZplFieldOrigin(this.PositionX + offsetX, this.PositionY + offsetY, this.FieldJustification); } } } diff --git a/src/BinaryKits.Zpl.Label/Elements/ZplFieldTypeset.cs b/src/BinaryKits.Zpl.Label/Elements/ZplFieldTypeset.cs index 1a6142a7..7d6ab589 100644 --- a/src/BinaryKits.Zpl.Label/Elements/ZplFieldTypeset.cs +++ b/src/BinaryKits.Zpl.Label/Elements/ZplFieldTypeset.cs @@ -16,23 +16,26 @@ public class ZplFieldTypeset : ZplElementBase { public int PositionX { get; protected set; } public int PositionY { get; protected set; } + public FieldJustification FieldJustification { get; protected set; } /// /// Field Typeset /// /// X Position (0-32000) /// Y Position (0-32000) - public ZplFieldTypeset(int positionX, int positionY) + /// + public ZplFieldTypeset(int positionX, int positionY, FieldJustification fieldJustification = FieldJustification.None) { - PositionX = positionX; - PositionY = positionY; + this.PositionX = positionX; + this.PositionY = positionY; + this.FieldJustification = fieldJustification; } /// public override IEnumerable Render(ZplRenderOptions context) { //^FO50,50 - return new string[] { $"^FT{context.Scale(PositionX)},{context.Scale(PositionY)}" }; + return new string[] { $"^FT{context.Scale(this.PositionX)},{context.Scale(this.PositionY)},{RenderFieldJustification(this.FieldJustification)}" }; } /// @@ -43,7 +46,7 @@ public override IEnumerable Render(ZplRenderOptions context) /// public ZplFieldTypeset Offset(int offsetX, int offsetY) { - return new ZplFieldTypeset(PositionX + offsetX, PositionY + offsetY); + return new ZplFieldTypeset(this.PositionX + offsetX, this.PositionY + offsetY, this.FieldJustification); } } } diff --git a/src/BinaryKits.Zpl.Label/Elements/ZplPositionedElementBase.cs b/src/BinaryKits.Zpl.Label/Elements/ZplPositionedElementBase.cs index 9f9be178..2e6f42c9 100644 --- a/src/BinaryKits.Zpl.Label/Elements/ZplPositionedElementBase.cs +++ b/src/BinaryKits.Zpl.Label/Elements/ZplPositionedElementBase.cs @@ -16,17 +16,18 @@ public abstract class ZplPositionedElementBase : ZplElementBase /// /// /// Use FieldTypeset - public ZplPositionedElementBase(int positionX, int positionY, bool bottomToTop = false) : base() + /// + public ZplPositionedElementBase(int positionX, int positionY, bool bottomToTop = false, FieldJustification fieldJustification = FieldJustification.None) : base() { if (bottomToTop) { - FieldTypeset = new ZplFieldTypeset(positionX, positionY); + FieldTypeset = new ZplFieldTypeset(positionX, positionY, fieldJustification); PositionX = positionX; PositionY = positionY; return; } - FieldOrigin = new ZplFieldOrigin(positionX, positionY); + FieldOrigin = new ZplFieldOrigin(positionX, positionY, fieldJustification); PositionX = positionX; PositionY = positionY; } diff --git a/src/BinaryKits.Zpl.Label/Elements/ZplTextField.cs b/src/BinaryKits.Zpl.Label/Elements/ZplTextField.cs index de40f751..445f5a24 100644 --- a/src/BinaryKits.Zpl.Label/Elements/ZplTextField.cs +++ b/src/BinaryKits.Zpl.Label/Elements/ZplTextField.cs @@ -30,6 +30,7 @@ public class ZplTextField : ZplPositionedElementBase, IFormatElement /// /// /// + /// public ZplTextField( string text, int positionX, @@ -38,8 +39,9 @@ public ZplTextField( NewLineConversionMethod newLineConversion = NewLineConversionMethod.ToSpace, bool useHexadecimalIndicator = true, bool reversePrint = false, - bool bottomToTop = false) - : base(positionX, positionY, bottomToTop) + bool bottomToTop = false, + FieldJustification fieldJustification = FieldJustification.None) + : base(positionX, positionY, bottomToTop, fieldJustification) { Text = text; Font = font; diff --git a/src/BinaryKits.Zpl.Label/FieldJustification.cs b/src/BinaryKits.Zpl.Label/FieldJustification.cs new file mode 100644 index 00000000..de94f7b0 --- /dev/null +++ b/src/BinaryKits.Zpl.Label/FieldJustification.cs @@ -0,0 +1,25 @@ +namespace BinaryKits.Zpl.Label +{ + /// + /// Text Alignment + /// + public enum FieldJustification + { + /// + /// None + /// + None, + /// + /// Left + /// + Left, + /// + /// Right + /// + Right, + /// + /// Auto (script dependent) + /// + Auto + } +} diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs index 1f7406a6..0703d726 100644 --- a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldDataZplCommandAnalyzer.cs @@ -34,6 +34,11 @@ public override ZplElementBase Analyze(string zplCommand) int x = 0; int y = 0; bool bottomToTop = false; + var fieldJustification = this.VirtualPrinter.NextElementFieldJustification; + if (fieldJustification == FieldJustification.None) + { + fieldJustification = this.VirtualPrinter.FieldJustification; + } if (this.VirtualPrinter.NextElementPosition != null) { @@ -110,7 +115,7 @@ public override ZplElementBase Analyze(string zplCommand) return new ZplFieldBlock(text, x, y, width, font, maxLineCount, lineSpace, textJustification, hangingIndent, reversePrint: reversePrint, bottomToTop: bottomToTop); } - return new ZplTextField(text, x, y, font, reversePrint: reversePrint, bottomToTop: bottomToTop); + return new ZplTextField(text, x, y, font, reversePrint: reversePrint, bottomToTop: bottomToTop, fieldJustification: fieldJustification); } private (ErrorCorrectionLevel, string) ParseQrCodeFieldData(QrCodeBarcodeFieldData qrCode, string text) diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldOrientationZplCommandAnalyzer.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldOrientationZplCommandAnalyzer.cs index c98a8cbc..468ef0ca 100644 --- a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldOrientationZplCommandAnalyzer.cs +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldOrientationZplCommandAnalyzer.cs @@ -16,6 +16,12 @@ public override ZplElementBase Analyze(string zplCommand) this.VirtualPrinter.SetFieldOrientation(fieldOrientation); } + if (zplDataParts.Length > 1) + { + var fieldJustification = ConvertFieldJustification(zplDataParts[1]); + this.VirtualPrinter.SetFieldJustification(fieldJustification); + } + return null; } } diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldOriginZplCommandAnalzer.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldOriginZplCommandAnalzer.cs index 15d0d904..95d38ceb 100644 --- a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldOriginZplCommandAnalzer.cs +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldOriginZplCommandAnalzer.cs @@ -27,6 +27,12 @@ public override ZplElementBase Analyze(string zplCommand) y = tmpint; } + if (zplDataParts.Length > 2) + { + var fieldJustification = ConvertFieldJustification(zplDataParts[2]); + this.VirtualPrinter.SetNextElementFieldJustification(fieldJustification); + } + if (this.VirtualPrinter.LabelHomePosition != null) { x += this.VirtualPrinter.LabelHomePosition.X; diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldSeparatorZplCommandAnalyzer.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldSeparatorZplCommandAnalyzer.cs index 16f56867..339bf302 100644 --- a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldSeparatorZplCommandAnalyzer.cs +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldSeparatorZplCommandAnalyzer.cs @@ -31,6 +31,7 @@ public override ZplElementBase Analyze(string zplCommand) this.VirtualPrinter.ClearNextElementFieldData(); this.VirtualPrinter.ClearNextElementFieldReverse(); this.VirtualPrinter.ClearNextElementFieldUseHexadecimalIndicator(); + this.VirtualPrinter.ClearNextElementFieldJustification(); this.VirtualPrinter.ClearNextFont(); this.VirtualPrinter.ClearComments(); diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldTypesetZplCommandAnalyzer.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldTypesetZplCommandAnalyzer.cs index 1c6b20b7..14b34675 100644 --- a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldTypesetZplCommandAnalyzer.cs +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/FieldTypesetZplCommandAnalyzer.cs @@ -27,6 +27,12 @@ public override ZplElementBase Analyze(string zplCommand) y = tmpint; } + if (zplDataParts.Length > 2) + { + var fieldJustification = ConvertFieldJustification(zplDataParts[2]); + this.VirtualPrinter.SetNextElementFieldJustification(fieldJustification); + } + if (this.VirtualPrinter.LabelHomePosition != null) { x += this.VirtualPrinter.LabelHomePosition.X; diff --git a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/ZplCommandAnalyzerBase.cs b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/ZplCommandAnalyzerBase.cs index 6ad19467..826cf3d7 100644 --- a/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/ZplCommandAnalyzerBase.cs +++ b/src/BinaryKits.Zpl.Viewer/CommandAnalyzers/ZplCommandAnalyzerBase.cs @@ -41,6 +41,17 @@ protected FieldOrientation ConvertFieldOrientation(string fieldOrientation) }; } + protected FieldJustification ConvertFieldJustification(string fieldJustification) + { + return fieldJustification switch + { + "0" => FieldJustification.Left, + "1" => FieldJustification.Right, + "2" => FieldJustification.Auto, + _ => this.VirtualPrinter.FieldJustification, + }; + } + protected ErrorCorrectionLevel ConvertErrorCorrectionLevel(string errorCorrection) { return errorCorrection switch diff --git a/src/BinaryKits.Zpl.Viewer/ElementDrawers/TextFieldElementDrawer.cs b/src/BinaryKits.Zpl.Viewer/ElementDrawers/TextFieldElementDrawer.cs index 3659e855..a0b6537a 100644 --- a/src/BinaryKits.Zpl.Viewer/ElementDrawers/TextFieldElementDrawer.cs +++ b/src/BinaryKits.Zpl.Viewer/ElementDrawers/TextFieldElementDrawer.cs @@ -30,6 +30,7 @@ public override void Draw(ZplElementBase element, DrawerOptions options) { float x = textField.PositionX; float y = textField.PositionY; + var fieldJustification = Label.FieldJustification.None; var font = textField.Font; @@ -84,6 +85,7 @@ public override void Draw(ZplElementBase element, DrawerOptions options) case Label.FieldOrientation.Normal: break; } + fieldJustification = textField.FieldOrigin.FieldJustification; } else { @@ -101,6 +103,7 @@ public override void Draw(ZplElementBase element, DrawerOptions options) case Label.FieldOrientation.Normal: break; } + fieldJustification = textField.FieldTypeset.FieldJustification; } if (matrix != SKMatrix.Empty) @@ -118,7 +121,27 @@ public override void Draw(ZplElementBase element, DrawerOptions options) skPaint.BlendMode = SKBlendMode.Xor; } + if (fieldJustification == Label.FieldJustification.Left) + { + skPaint.TextAlign = SKTextAlign.Left; + } + else if (fieldJustification == Label.FieldJustification.Right) + { + skPaint.TextAlign = SKTextAlign.Right; + } + else if (fieldJustification == Label.FieldJustification.Auto) + { + var buffer = new HarfBuzzSharp.Buffer(); + buffer.AddUtf16(displayText); + buffer.GuessSegmentProperties(); + if (buffer.Direction == HarfBuzzSharp.Direction.RightToLeft) + { + skPaint.TextAlign = SKTextAlign.Right; + } + } + this._skCanvas.DrawShapedText(displayText, x, y, skPaint); + } } } diff --git a/src/BinaryKits.Zpl.Viewer/VirtualPrinter.cs b/src/BinaryKits.Zpl.Viewer/VirtualPrinter.cs index 5b119927..5199aae9 100644 --- a/src/BinaryKits.Zpl.Viewer/VirtualPrinter.cs +++ b/src/BinaryKits.Zpl.Viewer/VirtualPrinter.cs @@ -11,6 +11,7 @@ public class VirtualPrinter public FieldDataBase NextElementFieldData { get; private set; } public FieldBlock NextElementFieldBlock { get; private set; } public FieldOrientation FieldOrientation { get; private set; } = FieldOrientation.Normal; + public FieldJustification FieldJustification { get; private set; } = FieldJustification.None; public int FontWidth { get; private set; } = 0; public int FontHeight { get; private set; } = 10; public string FontName { get; private set; } = "0"; @@ -23,6 +24,7 @@ public class VirtualPrinter public bool NextElementFieldReverse { get; private set; } public bool NextElementFieldUseHexadecimalIndicator { get; private set; } + public FieldJustification NextElementFieldJustification { get; private set; } = FieldJustification.None; public bool LabelReverse { get; private set; } public BarcodeInfo BarcodeInfo { get; private set; } @@ -84,24 +86,34 @@ public void SetNextElementFieldReverse() this.NextElementFieldReverse = true; } + public void ClearNextElementFieldReverse() + { + this.NextElementFieldReverse = false; + } + public void SetNextElementFieldUseHexadecimalIndicator() { this.NextElementFieldUseHexadecimalIndicator = true; } - public void SetLabelReverse(bool reverse) + public void ClearNextElementFieldUseHexadecimalIndicator() { - this.LabelReverse = reverse; + this.NextElementFieldUseHexadecimalIndicator = false; } - public void ClearNextElementFieldReverse() + public void SetNextElementFieldJustification(FieldJustification fieldJustification) { - this.NextElementFieldReverse = false; + this.NextElementFieldJustification = fieldJustification; } - public void ClearNextElementFieldUseHexadecimalIndicator() + public void ClearNextElementFieldJustification() { - this.NextElementFieldUseHexadecimalIndicator = false; + this.NextElementFieldJustification = FieldJustification.None; + } + + public void SetLabelReverse(bool reverse) + { + this.LabelReverse = reverse; } public void SetFieldOrientation(FieldOrientation fieldOrientation) { @@ -112,6 +124,11 @@ public void SetFieldOrientation(FieldOrientation fieldOrientation) { } } + public void SetFieldJustification(FieldJustification fieldJustification) + { + this.FieldJustification = fieldJustification; + } + public void SetFontWidth(int fontWidth) { this.FontWidth = fontWidth;