Skip to content

ui::TextAnalyzer

Header: winui/render/TextAnalyzer.hpp.

Unicode text segmentation and case mapping over UTF-8: where a caret may stop, what counts as a word character, and how CharacterCasing changes typed text.

The base class is itself the built-in, deterministic implementation. A cluster is a code point plus its trailing combining marks, variation selectors, emoji modifiers and ZWJ sequences, and casing covers Latin, Greek and Cyrillic. A platform analyzer overrides whichever members it can answer better, and the library installs one with set_text_analyzer() at start-up. Every offset is a byte offset on a code-point boundary.

Example:

// The editing keys of a custom text control.
const ui::TextAnalyzer& analyzer = ui::text_analyzer();

const std::string text  = "Hello world";
std::size_t       caret = 0;
caret = analyzer.next_cluster(text, caret);     // 1: Right arrow from the start
caret = analyzer.previous_cluster(text, caret); // 0: and back

// Ctrl+Right: past the rest of the word, then past the spaces after it.
while (caret < text.size() && analyzer.is_word_char(ui::code_point_at(text, caret)))
{
    caret = analyzer.next_cluster(text, caret);
}
while (caret < text.size() && !analyzer.is_word_char(ui::code_point_at(text, caret)))
{
    caret = analyzer.next_cluster(text, caret);
}
// caret == 6, the start of "world"

// A double-click selects the word under the pointer.
const auto [start, end] = ui::word_run(text, 8, true); // {6, 11}: "world"

// Typed text in an upper-case field.
const std::string typed = analyzer.to_upper("hello"); // "HELLO"

~TextAnalyzer

virtual ~TextAnalyzer() = default

next_cluster

virtual std::size_t next_cluster(std::string_view text, std::size_t pos) const

The grapheme-cluster boundary after pos: where Right arrow and Delete stop. text.size() at or past the end.

previous_cluster

virtual std::size_t previous_cluster(std::string_view text, std::size_t pos) const

The grapheme-cluster boundary before pos: where Left arrow and Backspace stop. 0 at the start.

is_word_char

virtual bool is_word_char(char32_t code_point) const

Whether code_point belongs to a word: letters, digits, marks and '_'.

to_upper

virtual std::string to_upper(std::string_view text) const

text in upper case, which may change its length ("ß" stays one code point here but can become "SS" on a platform that does full case mapping).

to_lower

virtual std::string to_lower(std::string_view text) const

text in lower case.