using System; using System.Drawing; using System.Text; using System.Text.RegularExpressions; namespace ANSCENTER { /// /// Unicode helper for LabVIEW .NET interop. /// All methods are static — no instance creation needed. /// In LabVIEW: use Invoke Node with class type ANSCENTER.ANSUnicodeHelper. /// Thread-safe: no shared mutable state. /// public class ANSUnicodeHelper { // Pre-compiled regex — compiled once at class load, zero per-call cost private static readonly Regex UnicodeEscapeRegex = new Regex(@"\\u([0-9a-fA-F]{4})", RegexOptions.Compiled); /// /// Constructor for LabVIEW (if needed). Lightweight, no state. /// public ANSUnicodeHelper() { } /// /// Decodes \uXXXX escape sequences to Unicode characters. /// ASCII strings pass through unchanged (zero allocation). /// public static string Decode(string input) { if (string.IsNullOrEmpty(input)) return input ?? string.Empty; if (input.IndexOf("\\u", StringComparison.Ordinal) < 0) return input; return UnicodeEscapeRegex.Replace(input, match => { int codepoint = Convert.ToInt32(match.Groups[1].Value, 16); return ((char)codepoint).ToString(); }); } /// /// Draws Unicode string at position (x, y). /// public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, float x, float y) { if (g == null || string.IsNullOrEmpty(escapedText)) return; g.DrawString(Decode(escapedText), font, brush, x, y); } /// /// Draws Unicode string at position (x, y) with StringFormat. /// public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, float x, float y, StringFormat format) { if (g == null || string.IsNullOrEmpty(escapedText)) return; g.DrawString(Decode(escapedText), font, brush, x, y, format); } /// /// Draws Unicode string at PointF with StringFormat. /// public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, PointF point, StringFormat format) { if (g == null || string.IsNullOrEmpty(escapedText)) return; g.DrawString(Decode(escapedText), font, brush, point, format); } /// /// Draws Unicode string inside a RectangleF with word wrapping. /// public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, RectangleF layoutRect) { if (g == null || string.IsNullOrEmpty(escapedText)) return; g.DrawString(Decode(escapedText), font, brush, layoutRect); } /// /// Draws Unicode string inside a RectangleF with StringFormat. /// public static void DrawString(Graphics g, string escapedText, Font font, Brush brush, RectangleF layoutRect, StringFormat format) { if (g == null || string.IsNullOrEmpty(escapedText)) return; g.DrawString(Decode(escapedText), font, brush, layoutRect, format); } /// /// Measures Unicode string size after decoding. /// public static SizeF MeasureString(Graphics g, string escapedText, Font font) { if (g == null || string.IsNullOrEmpty(escapedText)) return SizeF.Empty; return g.MeasureString(Decode(escapedText), font); } /// /// Measures Unicode string size with layout area and StringFormat. /// public static SizeF MeasureString(Graphics g, string escapedText, Font font, SizeF layoutArea, StringFormat format) { if (g == null || string.IsNullOrEmpty(escapedText)) return SizeF.Empty; return g.MeasureString(Decode(escapedText), font, layoutArea, format); } /// /// Checks if string contains \uXXXX escapes. /// public static bool HasUnicodeEscapes(string input) { if (string.IsNullOrEmpty(input)) return false; return input.IndexOf("\\u", StringComparison.Ordinal) >= 0; } /// /// Checks if string is pure ASCII. /// public static bool IsAsciiOnly(string input) { if (string.IsNullOrEmpty(input)) return true; foreach (char c in input) { if (c > 127) return false; } return true; } } }