// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; namespace SixLabors.Fonts.Unicode { /// /// Contains extension methods for memory types. /// public static class MemoryExtensions { /// /// Returns an enumeration of from the provided span. /// /// The read-only span of char elements representing the text to enumerate. /// /// Invalid UTF-16 sequences will be represented in the enumeration by . /// /// The . public static SpanCodePointEnumerator EnumerateCodePoints(this ReadOnlySpan span) => new(span); /// /// Returns an enumeration of from the provided span. /// /// The span of char elements representing the text to enumerate. /// /// Invalid UTF-16 sequences will be represented in the enumeration by . /// /// The . public static SpanCodePointEnumerator EnumerateCodePoints(this Span span) => new(span); /// /// Returns the number of code points in the provided text. /// /// The text to enumerate. /// The number of code points. public static int GetCodePointCount(this string text) => text.AsSpan().GetCodePointCount(); /// /// Returns the number of code points in the provided span. /// /// The read-only span of char elements representing the text to enumerate. /// The number of code points. public static int GetCodePointCount(this ReadOnlySpan span) => CodePoint.GetCodePointCount(span); /// /// Returns the number of code points in the provided span. /// /// The span of char elements representing the text to enumerate. /// The number of code points. public static int GetCodePointCount(this Span span) => CodePoint.GetCodePointCount(span); /// /// Returns an enumeration of grapheme clusters from the provided span. /// /// The read-only span of char elements representing the text to enumerate. /// /// Invalid UTF-16 sequences are treated as while determining grapheme boundaries. /// /// The . public static SpanGraphemeEnumerator EnumerateGraphemes(this ReadOnlySpan span) => new(span); /// /// Returns an enumeration of grapheme clusters from the provided span with terminal-width metadata. /// /// The read-only span of char elements representing the text to enumerate. /// /// The terminal width options used to resolve . /// /// /// Invalid UTF-16 sequences are treated as while determining grapheme boundaries. /// Terminal width options affect only the width metadata on each returned cluster; they do not affect grapheme segmentation. /// /// The . public static SpanGraphemeEnumerator EnumerateGraphemes(this ReadOnlySpan span, TerminalWidthOptions terminalWidthOptions) => new(span, terminalWidthOptions); /// /// Returns an enumeration of grapheme clusters from the provided span. /// /// The span of char elements representing the text to enumerate. /// /// Invalid UTF-16 sequences are treated as while determining grapheme boundaries. /// /// The . public static SpanGraphemeEnumerator EnumerateGraphemes(this Span span) => new(span); /// /// Returns an enumeration of grapheme clusters from the provided span with terminal-width metadata. /// /// The span of char elements representing the text to enumerate. /// /// The terminal width options used to resolve . /// /// /// Invalid UTF-16 sequences are treated as while determining grapheme boundaries. /// Terminal width options affect only the width metadata on each returned cluster; they do not affect grapheme segmentation. /// /// The . public static SpanGraphemeEnumerator EnumerateGraphemes(this Span span, TerminalWidthOptions terminalWidthOptions) => new(span, terminalWidthOptions); /// /// Returns an enumeration of Unicode word-boundary segments from the provided span. /// /// The read-only span of char elements representing the text to enumerate. /// /// Invalid UTF-16 sequences are treated as while determining word boundaries. /// /// The . public static SpanWordEnumerator EnumerateWordSegments(this ReadOnlySpan span) => new(span); /// /// Returns an enumeration of Unicode word-boundary segments from the provided span. /// /// The span of char elements representing the text to enumerate. /// /// Invalid UTF-16 sequences are treated as while determining word boundaries. /// /// The . public static SpanWordEnumerator EnumerateWordSegments(this Span span) => new(span); /// /// Returns the terminal cell width of the provided text. /// /// The text to measure. /// /// The terminal cell width, or -1 when the configured control-character policy treats /// any grapheme cluster in the text as non-printable. /// public static int GetTerminalCellWidth(this string text) => text.AsSpan().GetTerminalCellWidth(); /// /// Returns the terminal cell width of the provided text. /// /// The text to measure. /// The terminal width options to apply while measuring. /// /// The terminal cell width, or -1 when the configured control-character policy treats /// any grapheme cluster in the text as non-printable. /// public static int GetTerminalCellWidth(this string text, TerminalWidthOptions terminalWidthOptions) => text.AsSpan().GetTerminalCellWidth(terminalWidthOptions); /// /// Returns the terminal cell width of the provided span. /// /// The read-only span of char elements representing the text to measure. /// /// The terminal cell width, or -1 when the configured control-character policy treats /// any grapheme cluster in the text as non-printable. /// public static int GetTerminalCellWidth(this ReadOnlySpan span) => span.GetTerminalCellWidth(default); /// /// Returns the terminal cell width of the provided span. /// /// The read-only span of char elements representing the text to measure. /// The terminal width options to apply while measuring. /// /// The terminal cell width, or -1 when the configured control-character policy treats /// any grapheme cluster in the text as non-printable. /// public static int GetTerminalCellWidth(this ReadOnlySpan span, TerminalWidthOptions terminalWidthOptions) { int width = 0; SpanGraphemeEnumerator enumerator = new(span, terminalWidthOptions); while (enumerator.MoveNext()) { int terminalCellWidth = enumerator.Current.TerminalCellWidth; if (terminalCellWidth < 0) { return -1; } width += terminalCellWidth; } return width; } /// /// Returns the terminal cell width of the provided span. /// /// The span of char elements representing the text to measure. /// /// The terminal cell width, or -1 when the configured control-character policy treats /// any grapheme cluster in the text as non-printable. /// public static int GetTerminalCellWidth(this Span span) => ((ReadOnlySpan)span).GetTerminalCellWidth(); /// /// Returns the terminal cell width of the provided span. /// /// The span of char elements representing the text to measure. /// The terminal width options to apply while measuring. /// /// The terminal cell width, or -1 when the configured control-character policy treats /// any grapheme cluster in the text as non-printable. /// public static int GetTerminalCellWidth(this Span span, TerminalWidthOptions terminalWidthOptions) => ((ReadOnlySpan)span).GetTerminalCellWidth(terminalWidthOptions); /// /// Returns the number of grapheme clusters in the provided text. /// /// The text to enumerate. /// The number of grapheme clusters. public static int GetGraphemeCount(this string text) => text.AsSpan().GetGraphemeCount(); /// /// Returns the number of grapheme clusters in the provided span. /// /// The read-only span of char elements representing the text to enumerate. /// The number of grapheme clusters. public static int GetGraphemeCount(this ReadOnlySpan span) { int count = 0; SpanGraphemeEnumerator enumerator = new(span); while (enumerator.MoveNext()) { count++; } return count; } /// /// Returns the number of grapheme clusters in the provided span. /// /// The span of char elements representing the text to enumerate. /// The number of grapheme clusters. public static int GetGraphemeCount(this Span span) { int count = 0; SpanGraphemeEnumerator enumerator = new(span); while (enumerator.MoveNext()) { count++; } return count; } } }