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;
78 text_.replace(composing_range_.
start(), composing_range_.
length(),
text);
93 selection_ = composing_range_;
101 bool TextInputModel::DeleteSelected() {
105 size_t start = selection_.
start();
106 text_.erase(start, selection_.
length());
107 selection_ = TextRange(start);
110 composing_range_ = selection_;
117 AddText(std::u16string({
static_cast<char16_t
>(c)}));
119 char32_t to_decompose = c - 0x10000;
122 static_cast<char16_t
>((to_decompose >> 10) + 0xd800),
124 static_cast<char16_t
>((to_decompose % 0x400) + 0xdc00),
133 text_.erase(composing_range_.
start(), composing_range_.
length());
137 size_t position = selection_.
position();
138 text_.insert(position,
text);
147 if (DeleteSelected()) {
151 size_t position = selection_.
position();
152 if (position != editable_range().start()) {
153 int count = IsTrailingSurrogate(text_.at(position - 1)) ? 2 : 1;
154 text_.erase(position - count, count);
155 selection_ =
TextRange(position - count);
157 composing_range_.
set_end(composing_range_.
end() - count);
165 if (DeleteSelected()) {
169 size_t position = selection_.
position();
170 if (position < editable_range().end()) {
171 int count = IsLeadingSurrogate(text_.at(position)) ? 2 : 1;
172 text_.erase(position, count);
174 composing_range_.
set_end(composing_range_.
end() - count);
182 size_t max_pos = editable_range().
end();
183 size_t start = selection_.
extent();
184 if (offset_from_cursor < 0) {
185 for (
int i = 0; i < -offset_from_cursor; i++) {
188 if (start == editable_range().start()) {
192 start -= IsTrailingSurrogate(text_.at(start - 1)) ? 2 : 1;
195 for (
int i = 0; i < offset_from_cursor && start != max_pos; i++) {
196 start += IsLeadingSurrogate(text_.at(start)) ? 2 : 1;
201 for (
int i = 0; i < count && end != max_pos; i++) {
202 end += IsLeadingSurrogate(text_.at(start)) ? 2 : 1;
209 auto deleted_length = end - start;
210 text_.erase(start, deleted_length);
213 selection_ =
TextRange(offset_from_cursor <= 0 ? start : selection_.
start());
217 composing_range_.
set_end(composing_range_.
end() - deleted_length);
223 size_t min_pos = editable_range().
start();
232 size_t max_pos = editable_range().
end();
241 size_t min_pos = editable_range().
start();
250 size_t max_pos = editable_range().
end();
265 size_t position = selection_.
position();
266 if (position != editable_range().end()) {
267 int count = IsLeadingSurrogate(text_.at(position)) ? 2 : 1;
268 selection_ =
TextRange(position + count);
281 size_t position = selection_.
position();
282 if (position != editable_range().start()) {
283 int count = IsTrailingSurrogate(text_.at(position - 1)) ? 2 : 1;
284 selection_ =
TextRange(position - count);
291 return fml::Utf16ToUtf8(text_);
297 auto leading_text = text_.substr(0, selection_.
extent());
298 return fml::Utf16ToUtf8(leading_text).size();