Description
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
- internal enum StrongBidiCategory
+ public enum StrongBidiCategory
{
...
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.