namespace Toolkit.UI.Controls.Avalonia; internal class PersonPictureInitialsGenerator { public static PersonPictureCharacterType GetCharacterType(string content) { PersonPictureCharacterType result = PersonPictureCharacterType.Other; if (content is { Length: > 0 }) { for (int i = 0; i < 3; i++) { if ((i >= content.Length) || (content[i] == '\0') || (content[i] == 0xFEFF)) { break; } char character = content[i]; PersonPictureCharacterType evaluationResult = GetCharacterType(character); switch (evaluationResult) { case PersonPictureCharacterType.Glyph: result = PersonPictureCharacterType.Glyph; break; case PersonPictureCharacterType.Symbolic: if (result != PersonPictureCharacterType.Glyph) { result = PersonPictureCharacterType.Symbolic; } break; case PersonPictureCharacterType.Standard: if ((result != PersonPictureCharacterType.Glyph) && (result != PersonPictureCharacterType.Symbolic)) { result = PersonPictureCharacterType.Standard; } break; default: break; } } } return result; } public static PersonPictureCharacterType GetCharacterType(char character) { // IPA Extensions if ((character >= 0x0250) && (character <= 0x02AF)) { return PersonPictureCharacterType.Glyph; } // Arabic if ((character >= 0x0600) && (character <= 0x06FF)) { return PersonPictureCharacterType.Glyph; } // Arabic Supplement if ((character >= 0x0750) && (character <= 0x077F)) { return PersonPictureCharacterType.Glyph; } // Arabic Extended-A if ((character >= 0x08A0) && (character <= 0x08FF)) { return PersonPictureCharacterType.Glyph; } // Arabic Presentation Forms-A if ((character >= 0xFB50) && (character <= 0xFDFF)) { return PersonPictureCharacterType.Glyph; } // Arabic Presentation Forms-B if ((character >= 0xFE70) && (character <= 0xFEFF)) { return PersonPictureCharacterType.Glyph; } // Devanagari if ((character >= 0x0900) && (character <= 0x097F)) { return PersonPictureCharacterType.Glyph; } // Devanagari Extended if ((character >= 0xA8E0) && (character <= 0xA8FF)) { return PersonPictureCharacterType.Glyph; } // Bengali if ((character >= 0x0980) && (character <= 0x09FF)) { return PersonPictureCharacterType.Glyph; } // Gurmukhi if ((character >= 0x0A00) && (character <= 0x0A7F)) { return PersonPictureCharacterType.Glyph; } // Gujarati if ((character >= 0x0A80) && (character <= 0x0AFF)) { return PersonPictureCharacterType.Glyph; } // Oriya if ((character >= 0x0B00) && (character <= 0x0B7F)) { return PersonPictureCharacterType.Glyph; } // Tamil if ((character >= 0x0B80) && (character <= 0x0BFF)) { return PersonPictureCharacterType.Glyph; } // Telugu if ((character >= 0x0C00) && (character <= 0x0C7F)) { return PersonPictureCharacterType.Glyph; } // Kannada if ((character >= 0x0C80) && (character <= 0x0CFF)) { return PersonPictureCharacterType.Glyph; } // Malayalam if ((character >= 0x0D00) && (character <= 0x0D7F)) { return PersonPictureCharacterType.Glyph; } // Sinhala if ((character >= 0x0D80) && (character <= 0x0DFF)) { return PersonPictureCharacterType.Glyph; } // Thai if ((character >= 0x0E00) && (character <= 0x0E7F)) { return PersonPictureCharacterType.Glyph; } // Lao if ((character >= 0x0E80) && (character <= 0x0EFF)) { return PersonPictureCharacterType.Glyph; } // SYMBOLIC // // CJK Unified Ideographs if ((character >= 0x4E00) && (character <= 0x9FFF)) { return PersonPictureCharacterType.Symbolic; } // CJK Unified Ideographs Extension if ((character >= 0x3400) && (character <= 0x4DBF)) { return PersonPictureCharacterType.Symbolic; } // CJK Unified Ideographs Extension B if ((character >= 0x20000) && (character <= 0x2A6DF)) { return PersonPictureCharacterType.Symbolic; } // CJK Unified Ideographs Extension C if ((character >= 0x2A700) && (character <= 0x2B73F)) { return PersonPictureCharacterType.Symbolic; } // CJK Unified Ideographs Extension D if ((character >= 0x2B740) && (character <= 0x2B81F)) { return PersonPictureCharacterType.Symbolic; } // CJK Radicals Supplement if ((character >= 0x2E80) && (character <= 0x2EFF)) { return PersonPictureCharacterType.Symbolic; } // CJK Symbols and Punctuation if ((character >= 0x3000) && (character <= 0x303F)) { return PersonPictureCharacterType.Symbolic; } // CJK Strokes if ((character >= 0x31C0) && (character <= 0x31EF)) { return PersonPictureCharacterType.Symbolic; } // Enclosed CJK Letters and Months if ((character >= 0x3200) && (character <= 0x32FF)) { return PersonPictureCharacterType.Symbolic; } // CJK Compatibility if ((character >= 0x3300) && (character <= 0x33FF)) { return PersonPictureCharacterType.Symbolic; } // CJK Compatibility Ideographs if ((character >= 0xF900) && (character <= 0xFAFF)) { return PersonPictureCharacterType.Symbolic; } // CJK Compatibility Forms if ((character >= 0xFE30) && (character <= 0xFE4F)) { return PersonPictureCharacterType.Symbolic; } // CJK Compatibility Ideographs Supplement if ((character >= 0x2F800) && (character <= 0x2FA1F)) { return PersonPictureCharacterType.Symbolic; } // Greek and Coptic if ((character >= 0x0370) && (character <= 0x03FF)) { return PersonPictureCharacterType.Symbolic; } // Hebrew if ((character >= 0x0590) && (character <= 0x05FF)) { return PersonPictureCharacterType.Symbolic; } // Armenian if ((character >= 0x0530) && (character <= 0x058F)) { return PersonPictureCharacterType.Symbolic; } // LATIN // // Basic Latin if ((character > 0x0000) && (character <= 0x007F)) { return PersonPictureCharacterType.Standard; } // Latin-1 Supplement if ((character >= 0x0080) && (character <= 0x00FF)) { return PersonPictureCharacterType.Standard; } // Latin Extended-A if ((character >= 0x0100) && (character <= 0x017F)) { return PersonPictureCharacterType.Standard; } // Latin Extended-B if ((character >= 0x0180) && (character <= 0x024F)) { return PersonPictureCharacterType.Standard; } // Latin Extended-C if ((character >= 0x2C60) && (character <= 0x2C7F)) { return PersonPictureCharacterType.Standard; } // Latin Extended-D if ((character >= 0xA720) && (character <= 0xA7FF)) { return PersonPictureCharacterType.Standard; } // Latin Extended-E if ((character >= 0xAB30) && (character <= 0xAB6F)) { return PersonPictureCharacterType.Standard; } // Latin Extended Additional if ((character >= 0x1E00) && (character <= 0x1EFF)) { return PersonPictureCharacterType.Standard; } // Cyrillic if ((character >= 0x0400) && (character <= 0x04FF)) { return PersonPictureCharacterType.Standard; } // Cyrillic Supplement if ((character >= 0x0500) && (character <= 0x052F)) { return PersonPictureCharacterType.Standard; } // Combining Diacritical Marks if ((character >= 0x0300) && (character <= 0x036F)) { return PersonPictureCharacterType.Standard; } return PersonPictureCharacterType.Other; } public static string InitialsFromDisplayName(string contactDisplayName) { PersonPictureCharacterType type = GetCharacterType(contactDisplayName); if (type == PersonPictureCharacterType.Standard) { string displayName = contactDisplayName; StripTrailingBrackets(ref displayName); string[] words = Split(displayName, ' '); if (words.Length == 1) { string firstWord = words.First(); string result = GetFirstFullCharacter(firstWord); return result.ToUpper(); } else if (words.Length > 1) { string firstWord = words.First(); string lastWord = words.Last(); string result = GetFirstFullCharacter(firstWord); result += GetFirstFullCharacter(lastWord); return result.ToUpper(); } else { return string.Empty; } } else { return string.Empty; } } private static string GetFirstFullCharacter(string str) { int start = 0; while (start < str.Length) { char character = str[start]; // Omit ! " # $ % & ' ( ) * + , - . / if ((character >= 0x0021) && (character <= 0x002F)) { start++; continue; } // Omit : ; < = > ? @ if ((character >= 0x003A) && (character <= 0x0040)) { start++; continue; } // Omit { | } ~ if ((character >= 0x007B) && (character <= 0x007E)) { start++; continue; } break; } if (start >= str.Length) { start = 0; } int index = start + 1; while (index < str.Length) { char character = str[index]; if ((character < 0x0300) || (character > 0x036F)) { break; } index++; } int strLength = index - start; return SafeSubstring(str, start, strLength); } private static string SafeSubstring(string value, int startIndex, int length) { if (value is null) { throw new ArgumentNullException(nameof(value)); } if (startIndex > value.Length) { return string.Empty; } if (length > value.Length - startIndex) { length = value.Length - startIndex; } return value.Substring(startIndex, length); } private static string[] Split(string source, char delim, int maxIterations = 25) { return source.Split(new[] { delim }, maxIterations); } private static void StripTrailingBrackets(ref string source) { string[] delimiters = { "{}", "()", "[]" }; if (source.Length == 0) { return; } foreach (var delimiter in delimiters) { if (source[source.Length - 1] != delimiter[1]) { continue; } var start = source.LastIndexOf(delimiter[0]); if (start == -1) { continue; } source = source.Remove(start); return; } } }