10 #include "flutter/fml/string_conversion.h"
17 bool IsLeadingSurrogate(char32_t code_point) {
18 return (code_point & 0xFFFFFC00) == 0xD800;
21 bool IsTrailingSurrogate(char32_t code_point) {
22 return (code_point & 0xFFFFFC00) == 0xDC00;
34 text_ = fml::Utf8ToUtf16(text);
50 if (!editable_range().Contains(range)) {
58 size_t cursor_offset) {
59 if (!composing_ || !
text_range().Contains(range)) {
62 composing_range_ = range;
75 if (text.length() == 0 && composing_range_.
collapsed()) {
79 composing_range_.
collapsed() ? selection_ : composing_range_;
80 text_.replace(rangeToDelete.
start(), rangeToDelete.
length(), text);
81 composing_range_.
set_end(composing_range_.
start() + text.length());
100 selection_ = composing_range_;
108 bool TextInputModel::DeleteSelected() {
112 size_t start = selection_.
start();
113 text_.erase(start, selection_.
length());
114 selection_ = TextRange(start);
117 composing_range_ = selection_;
124 AddText(std::u16string({
static_cast<char16_t
>(c)}));
126 char32_t to_decompose = c - 0x10000;
129 static_cast<char16_t
>((to_decompose >> 10) + 0xd800),
131 static_cast<char16_t
>((to_decompose % 0x400) + 0xdc00),
140 text_.erase(composing_range_.
start(), composing_range_.
length());
142 composing_range_.
set_end(composing_range_.
start() + text.length());
144 size_t position = selection_.
position();
145 text_.insert(position, text);
146 selection_ =
TextRange(position + text.length());
150 AddText(fml::Utf8ToUtf16(text));
154 if (DeleteSelected()) {
158 size_t position = selection_.
position();
159 if (position != editable_range().start()) {
160 int count = IsTrailingSurrogate(text_.at(position - 1)) ? 2 : 1;
161 text_.erase(position - count, count);
162 selection_ =
TextRange(position - count);
164 composing_range_.
set_end(composing_range_.
end() - count);
172 if (DeleteSelected()) {
176 size_t position = selection_.
position();
177 if (position < editable_range().end()) {
178 int count = IsLeadingSurrogate(text_.at(position)) ? 2 : 1;
179 text_.erase(position, count);
181 composing_range_.
set_end(composing_range_.
end() - count);
189 size_t max_pos = editable_range().
end();
190 size_t start = selection_.
extent();
191 if (offset_from_cursor < 0) {
192 for (
int i = 0; i < -offset_from_cursor; i++) {
195 if (start == editable_range().start()) {
199 start -= IsTrailingSurrogate(text_.at(start - 1)) ? 2 : 1;
202 for (
int i = 0; i < offset_from_cursor && start != max_pos; i++) {
203 start += IsLeadingSurrogate(text_.at(start)) ? 2 : 1;
208 for (
int i = 0; i < count && end != max_pos; i++) {
209 end += IsLeadingSurrogate(text_.at(start)) ? 2 : 1;
216 auto deleted_length = end - start;
217 text_.erase(start, deleted_length);
220 selection_ =
TextRange(offset_from_cursor <= 0 ? start : selection_.
start());
224 composing_range_.
set_end(composing_range_.
end() - deleted_length);
230 size_t min_pos = editable_range().
start();
239 size_t max_pos = editable_range().
end();
248 size_t min_pos = editable_range().
start();
257 size_t max_pos = editable_range().
end();
272 size_t position = selection_.
position();
273 if (position != editable_range().end()) {
274 int count = IsLeadingSurrogate(text_.at(position)) ? 2 : 1;
275 selection_ =
TextRange(position + count);
288 size_t position = selection_.
position();
289 if (position != editable_range().start()) {
290 int count = IsTrailingSurrogate(text_.at(position - 1)) ? 2 : 1;
291 selection_ =
TextRange(position - count);
298 return fml::Utf16ToUtf8(text_);
304 auto leading_text = text_.substr(0, selection_.
extent());
305 return fml::Utf16ToUtf8(leading_text).size();