Skip to content

Expose System.Globalization.CharUnicodeInfo.GetBidiCategory #44464

Closed
@OronDF343

Description

@OronDF343

Background and Motivation

Currently, there is no public API for determining whether a Unicode character is strongly right-to-left, strongly left-to-right or neutral. Such an API can be useful when displaying text in right-to-left and left-to-right languages simultaneously.

Proposed API

StrongBidiCategory.cs

-    internal enum StrongBidiCategory
+    public enum StrongBidiCategory
     {
     ...

CharUnicodeInfo.cs

     public static partial class CharUnicodeInfo
     {
     ...
+        public static StrongBidiCategory GetBidiCategory(char ch)
+        {
+            return GetBidiCategoryNoBoundsChecks(ch);
+        }
+
+        public static StrongBidiCategory GetBidiCategory(int codePoint)
+        {
+            if (!UnicodeUtility.IsValidCodePoint((uint)codePoint))
+            {
+                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.codePoint);
+            }
+
+            return GetBidiCategoryNoBoundsChecks((uint)codePoint);
+        }

-        internal static StrongBidiCategory GetBidiCategory(string s, int index)
+        public static StrongBidiCategory GetBidiCategory(string s, int index)
         {
     ...

Usage Examples

For example, this API can be used to determine the direction to which a block of text should be aligned, based on the first character that is strongly RTL or strongly LTR:

using System.Globalization;

public bool IsRtl(string str)
{
    var cat = StrongBidiCategory.Other;
    for (var i = 0; i < str.Length && cat == StrongBidiCategory.Other; ++i)
    {
        cat = CharUnicodeInfo.GetBidiCategory(str, i);
    }
    return cat == StrongBidiCategory.StrongRightToLeft;
}

Alternative Designs

The above proposed API was designed to match the existing public overloads of GetUnicodeCategory. Another welcome addition would be overloads accepting ReadOnlySpan<char> for each of the methods accepting string s, int index.

In .NET Framework, there is a similar internal function with the same name, but it returns BidiCategory, an enum that represents the actual BIDI category rather that just the "strong" one. For some use-cases, it may be beneficial to get the more detailed information rather than just a simplified version of it. Therefore, the alternative option would be to instead add new APIs that return BidiCategory, plus an extension method that converts BidiCategory to StrongBidiCategory.

Risks

Since the proposed API already exists internally, there should no risks for development on newer platforms such as .NET 5. Implementing the alternative design using BidiCategory rather than StrongBidiCategory may require naming changes and therefore changes to any code which calls the internal APIs.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions