aboutsummaryrefslogtreecommitdiff
path: root/ricochet/src/tui/text.cc
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-10-26 21:27:00 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-10-26 21:27:00 +0800
commite138e537bfb18a48391a973723940eec544dd8e1 (patch)
tree2c1bbc3625b9ea4652094793e26b33c4783a66f2 /ricochet/src/tui/text.cc
parent032b82c13e157a048ac13a540dfd18be9667fe49 (diff)
downloadrcc-project-e138e537bfb18a48391a973723940eec544dd8e1.tar.gz
rcc-project-e138e537bfb18a48391a973723940eec544dd8e1.tar.xz
feat(tui): add reusable text input component
Diffstat (limited to 'ricochet/src/tui/text.cc')
-rw-r--r--ricochet/src/tui/text.cc20
1 files changed, 20 insertions, 0 deletions
diff --git a/ricochet/src/tui/text.cc b/ricochet/src/tui/text.cc
index b2c64b8..95b324b 100644
--- a/ricochet/src/tui/text.cc
+++ b/ricochet/src/tui/text.cc
@@ -24,6 +24,7 @@
#include <stdexcept>
#include <unicode/ubrk.h>
#include <unicode/uchar.h>
+#include <unicode/unistr.h>
#include <unicode/utext.h>
#include <utility>
@@ -65,6 +66,25 @@ WordKind word_kind( UChar32 codepoint )
TextService::TextService( std::size_t glyph_capacity ) : glyph_capacity_( glyph_capacity ) {}
+std::string TextService::encode( std::u32string_view input ) const
+{
+ // ICU's UTF-32 conversion takes a signed 32-bit length, like its break iterator.
+ if ( input.size() > INT32_MAX ) {
+ throw std::length_error( "Input exceeds ICU conversion length capacity" );
+ }
+ const std::vector<UChar32> codepoints( input.begin(), input.end() );
+ // fromUTF32 requires a non-null pointer even for a zero-length input.
+ const UChar32 empty = 0;
+ const auto converted = icu::UnicodeString::fromUTF32( codepoints.empty() ? &empty : codepoints.data(),
+ static_cast<int32_t>( codepoints.size() ) );
+ if ( converted.isBogus() ) {
+ throw std::runtime_error( "ICU could not convert editor input" );
+ }
+ std::string result;
+ converted.toUTF8String( result );
+ return result;
+}
+
TextAnalysis TextService::analyze( std::string_view utf8, bool line_breaks, bool tabs ) const
{
// ICU BreakIterator exposes int32_t native offsets even with a UTF-8 UText.