7#include "xfa/fde/cfde_texteditengine.h"
12#include "core/fxcrt/check.h"
13#include "core/fxcrt/check_op.h"
14#include "core/fxcrt/compiler_specific.h"
15#include "core/fxcrt/fx_extension.h"
16#include "core/fxcrt/numerics/safe_conversions.h"
17#include "core/fxcrt/stl_util.h"
18#include "core/fxge/text_char_pos.h"
19#include "xfa/fde/cfde_textout.h"
20#include "xfa/fde/cfde_wordbreak_data.h"
21#include "xfa/fgas/font/cfgas_gefont.h"
27class InsertOperation
final :
public CFDE_TextEditEngine::
Operation {
29 InsertOperation(CFDE_TextEditEngine* engine,
32 : engine_(engine), start_idx_(start_idx), added_text_(added_text) {}
34 ~InsertOperation()
override =
default;
36 void Redo()
const override {
37 engine_->Insert(start_idx_, added_text_,
38 CFDE_TextEditEngine::RecordOperation::kSkipRecord);
41 void Undo()
const override {
42 engine_->Delete(start_idx_, added_text_.GetLength(),
43 CFDE_TextEditEngine::RecordOperation::kSkipRecord);
52class DeleteOperation
final :
public CFDE_TextEditEngine::
Operation {
54 DeleteOperation(CFDE_TextEditEngine* engine,
57 : engine_(engine), start_idx_(start_idx), removed_text_(removed_text) {}
59 ~DeleteOperation()
override =
default;
61 void Redo()
const override {
62 engine_->Delete(start_idx_, removed_text_.GetLength(),
63 CFDE_TextEditEngine::RecordOperation::kSkipRecord);
66 void Undo()
const override {
67 engine_->Insert(start_idx_, removed_text_,
68 CFDE_TextEditEngine::RecordOperation::kSkipRecord);
77class ReplaceOperation
final :
public CFDE_TextEditEngine::
Operation {
79 ReplaceOperation(CFDE_TextEditEngine* engine,
83 : insert_op_(engine, start_idx, added_text),
84 delete_op_(engine, start_idx, removed_text) {}
86 ~ReplaceOperation()
override =
default;
88 void Redo()
const override {
93 void Undo()
const override {
99 InsertOperation insert_op_;
100 DeleteOperation delete_op_;
127 content_.resize(gap_size_);
128 operation_buffer_.resize(max_edit_operations_);
130 text_break_.SetFontSize(font_size_);
131 text_break_.SetLineBreakTolerance(2.0f);
132 text_break_.SetTabWidth(36);
140 gap_size_ = kGapSize;
143 content_.resize(gap_size_);
150 max_edit_operations_ = max;
151 operation_buffer_.resize(max);
156void CFDE_TextEditEngine::AdjustGap(size_t idx, size_t length) {
157 static const size_t char_size =
sizeof(WideString::CharType);
160 if (idx < gap_position_) {
161 UNSAFE_TODO(FXSYS_memmove(content_.data() + idx + gap_size_,
162 content_.data() + idx,
163 (gap_position_ - idx) * char_size));
165 }
else if (idx > gap_position_) {
166 UNSAFE_TODO(FXSYS_memmove(content_.data() + gap_position_,
167 content_.data() + gap_position_ + gap_size_,
168 (idx - gap_position_) * char_size));
173 if (length >= gap_size_) {
174 size_t new_gap_size = length + kGapSize;
175 content_.resize(text_length_ + new_gap_size);
177 UNSAFE_TODO(FXSYS_memmove(content_.data() + gap_position_ + new_gap_size,
178 content_.data() + gap_position_ + gap_size_,
179 (text_length_ - gap_position_) * char_size));
181 gap_size_ = new_gap_size;
185size_t CFDE_TextEditEngine::CountCharsExceedingSize(
const WideString& text,
186 size_t num_to_check) {
187 if (!limit_horizontal_area_ && !limit_vertical_area_)
191 text_out->SetLineSpace(line_spacing_);
192 text_out->SetFont(font_);
193 text_out->SetFontSize(font_size_);
199 if (is_linewrap_enabled_) {
201 text_rect.width = available_width_;
203 text_rect
.width = kPageWidthMax;
205 text_out->SetStyles(style);
207 size_t length = text.GetLength();
210 float vertical_height = line_spacing_ * visible_line_count_;
211 size_t chars_exceeding_size = 0;
213 for (size_t i = 0; i < num_to_check; i++) {
214 text_out->CalcLogicSize(temp, &text_rect);
215 if (limit_horizontal_area_ && text_rect.width <= available_width_)
217 if (limit_vertical_area_ && text_rect
.height <= vertical_height)
220 ++chars_exceeding_size;
223 temp = temp.First(length);
226 return chars_exceeding_size;
229void CFDE_TextEditEngine::
Insert(size_t idx,
236 idx = std::min(idx, text_length_);
239 change.selection_start = idx;
240 change.selection_end = idx;
245 if (delegate_ && (add_operation != RecordOperation::kSkipRecord &&
246 add_operation != RecordOperation::kSkipNotify)) {
247 delegate_->OnTextWillChange(&change);
252 idx = change.selection_start;
255 if (change.selection_end != change.selection_start)
259 idx = std::min(idx, text_length_);
262 size_t length = text.GetLength();
268 bool exceeded_limit =
false;
275 if (has_character_limit_ && text_length_ + length > character_limit_) {
278 character_limit_ = text_length_ + length;
281 CHECK(text_length_ <= character_limit_);
282 length = character_limit_ - text_length_;
283 exceeded_limit =
true;
286 AdjustGap(idx, length);
288 if (validation_enabled_ || limit_horizontal_area_ || limit_vertical_area_) {
290 if (gap_position_ > 0) {
291 str += WideStringView(make_span(content_).first(gap_position_));
295 if (text_length_ - gap_position_ > 0) {
296 str += WideStringView(make_span(content_).subspan(
297 gap_position_ + gap_size_, text_length_ - gap_position_));
300 if (validation_enabled_ && delegate_ && !delegate_->OnValidate(str)) {
307 size_t chars_exceeding = CountCharsExceedingSize(str, length);
308 if (chars_exceeding > 0) {
310 if (chars_exceeding == length) {
312 delegate_->NotifyTextFull();
318 exceeded_limit =
true;
319 length -= chars_exceeding;
325 std::make_unique<InsertOperation>(
this, gap_position_, text));
333 fxcrt::Copy(text.span().first(length),
334 make_span(content_).subspan(gap_position_));
336 gap_position_ += length;
338 text_length_ += length;
347 delegate_->NotifyTextFull();
349 delegate_->OnTextChanged();
353void CFDE_TextEditEngine::AddOperationRecord(std::unique_ptr<Operation> op) {
354 size_t last_insert_position = next_operation_index_to_insert_ == 0
355 ? max_edit_operations_ - 1
356 : next_operation_index_to_insert_ - 1;
361 if (next_operation_index_to_undo_ != last_insert_position) {
362 if (next_operation_index_to_undo_ > last_insert_position) {
365 while (last_insert_position != 0) {
366 operation_buffer_[last_insert_position].reset();
367 --last_insert_position;
369 operation_buffer_[0].reset();
373 last_insert_position = max_edit_operations_ - 1;
377 while (next_operation_index_to_undo_ != last_insert_position) {
378 operation_buffer_[last_insert_position].reset();
379 --last_insert_position;
385 ++last_insert_position;
386 if (last_insert_position >= max_edit_operations_)
387 last_insert_position = 0;
389 operation_buffer_[last_insert_position] = std::move(op);
390 next_operation_index_to_insert_ =
391 (last_insert_position + 1) % max_edit_operations_;
392 next_operation_index_to_undo_ = last_insert_position;
396 for (
auto& record : operation_buffer_)
399 next_operation_index_to_undo_ = max_edit_operations_ - 1;
400 next_operation_index_to_insert_ = 0;
410 wchar_t ch = GetChar(pos - 1);
411 if (ch !=
'\r' && ch !=
'\n')
420 if (pos >= text_length_)
424 wchar_t ch = GetChar(pos);
426 while (pos < text_length_ && (ch ==
'\r' || ch ==
'\n')) {
435 size_t line_start = GetIndexAtStartOfLine(pos);
440 size_t dist = pos - line_start;
446 ch = GetChar(line_start);
447 }
while (line_start != 0 && (ch ==
'\r' || ch ==
'\n'));
453 size_t prior_start = GetIndexAtStartOfLine(line_start);
457 if (prior_start + dist > line_start)
458 return GetIndexAtEndOfLine(line_start);
460 return prior_start + dist;
464 size_t line_end = GetIndexAtEndOfLine(pos);
465 if (line_end == text_length_)
471 ch = GetChar(line_end);
472 }
while (line_end < text_length_ && (ch ==
'\r' || ch ==
'\n'));
474 if (line_end == text_length_)
478 size_t dist = pos - GetIndexAtStartOfLine(pos);
482 size_t next_line_end = GetIndexAtEndOfLine(line_end);
483 if (line_end + dist > next_line_end)
484 return next_line_end;
486 return line_end + dist;
493 wchar_t ch = GetChar(pos);
495 if (ch ==
'\r' || ch ==
'\n')
500 ch = GetChar(pos - 1);
501 if (ch ==
'\r' || ch ==
'\n')
511 if (pos >= text_length_)
514 wchar_t ch = GetChar(pos);
516 if (ch ==
'\r' || ch ==
'\n')
523 }
while (pos < text_length_ && (ch !=
'\r' && ch !=
'\n'));
530 limit_horizontal_area_ = val;
535 limit_vertical_area_ = val;
539 return operation_buffer_[next_operation_index_to_undo_] !=
nullptr &&
540 next_operation_index_to_undo_ != next_operation_index_to_insert_;
544 size_t idx = (next_operation_index_to_undo_ + 1) % max_edit_operations_;
545 return idx != next_operation_index_to_insert_ &&
546 operation_buffer_[idx] !=
nullptr;
549bool CFDE_TextEditEngine::
Redo() {
553 next_operation_index_to_undo_ =
554 (next_operation_index_to_undo_ + 1) % max_edit_operations_;
555 operation_buffer_[next_operation_index_to_undo_]->Redo();
559bool CFDE_TextEditEngine::
Undo() {
563 operation_buffer_[next_operation_index_to_undo_]->Undo();
564 next_operation_index_to_undo_ = next_operation_index_to_undo_ == 0
565 ? max_edit_operations_ - 1
566 : next_operation_index_to_undo_ - 1;
581 return contents_bounding_box_;
585 if (width == available_width_)
590 available_width_ = width;
591 if (is_linewrap_enabled_)
592 text_break_.SetLineWidth(width);
600 if (has_character_limit_ == limit)
603 has_character_limit_ = limit;
604 character_limit_ = std::max(character_limit_, text_length_);
612 if (character_limit_ == limit)
617 character_limit_ = std::max(limit, text_length_);
628 font_ = std::move(font);
629 text_break_.SetFont(font_);
638 if (font_size_ == size)
642 text_break_.SetFontSize(font_size_);
647 int32_t old_tab_width = text_break_.GetTabWidth();
648 text_break_.SetTabWidth(width);
649 if (old_tab_width == text_break_.GetTabWidth())
656 if (alignment == character_alignment_)
659 character_alignment_ = alignment;
660 text_break_.SetAlignment(alignment);
665 if (visible_line_count_ == count)
668 visible_line_count_ = std::max(
static_cast<size_t>(1), count);
673 if (is_multiline_ == val)
683 text_break_.SetLayoutStyles(style);
688 if (is_linewrap_enabled_ == val)
691 is_linewrap_enabled_ = val;
692 text_break_.SetLineWidth(is_linewrap_enabled_ ? available_width_
698 if (is_comb_text_ == enable)
701 is_comb_text_ = enable;
710 text_break_.SetLayoutStyles(style);
714void CFDE_TextEditEngine::SetCombTextWidth() {
715 size_t width = available_width_;
716 if (has_character_limit_)
717 width /= character_limit_;
719 text_break_.SetCombWidth(width);
723 if (text_length_ == 0)
726 has_selection_ =
true;
727 selection_.start_idx = 0;
728 selection_.count = text_length_;
732 has_selection_ =
false;
733 selection_.start_idx = 0;
734 selection_.count = 0;
737void CFDE_TextEditEngine::
SetSelection(size_t start_idx, size_t count) {
743 if (start_idx > text_length_)
745 if (start_idx + count > text_length_)
746 count = text_length_ - start_idx;
748 has_selection_ =
true;
749 selection_.start_idx = start_idx;
750 selection_.count = count;
758 if (selection_.start_idx < gap_position_) {
760 if (selection_.start_idx + selection_.count < gap_position_) {
761 text += WideStringView(
762 make_span(content_).subspan(selection_.start_idx, selection_.count));
767 text += WideStringView(make_span(content_).subspan(
768 selection_.start_idx, gap_position_ - selection_.start_idx));
770 if (selection_.count - (gap_position_ - selection_.start_idx) > 0) {
772 text += WideStringView(make_span(content_).subspan(
773 gap_position_ + gap_size_,
774 selection_.count - (gap_position_ - selection_.start_idx)));
781 text += WideStringView(make_span(content_).subspan(
782 gap_size_ + selection_.start_idx, selection_.count));
791 return Delete(selection_.start_idx, selection_.count, add_operation);
797 if (start_idx >= text_length_)
803 if (delegate_ && (add_operation != RecordOperation::kSkipRecord &&
804 add_operation != RecordOperation::kSkipNotify)) {
806 change.selection_start = start_idx;
807 change.selection_end = start_idx + length;
809 delegate_->OnTextWillChange(&change);
814 start_idx = change.selection_start;
815 length = change.selection_end - change.selection_start;
818 if (start_idx >= text_length_)
822 length = std::min(length, text_length_ - start_idx);
823 AdjustGap(start_idx + length, 0);
826 WideStringView(make_span(content_).subspan(start_idx, length)));
829 AddOperationRecord(std::make_unique<DeleteOperation>(
this, start_idx, ret));
834 gap_position_ = start_idx;
837 text_length_ -= length;
842 if (!change.text.IsEmpty())
843 Insert(start_idx, change.text, RecordOperation::kSkipRecord);
846 delegate_->OnTextChanged();
856 change.selection_start = selection_.start_idx;
857 change.selection_end = selection_.start_idx + selection_.count;
862 delegate_->OnTextWillChange(&change);
867 selection_.start_idx = change.selection_start;
868 selection_.count = change.selection_end - change.selection_start;
871 size_t start_idx = selection_.start_idx;
873 Insert(gap_position_, rep, RecordOperation::kSkipRecord);
876 std::make_unique<ReplaceOperation>(
this, start_idx, txt, rep));
881 if (gap_position_ > 0) {
882 str += WideStringView(make_span(content_).first(gap_position_));
884 if (text_length_ - gap_position_ > 0) {
885 str += WideStringView(make_span(content_).subspan(
886 gap_position_ + gap_size_, text_length_ - gap_position_));
895wchar_t CFDE_TextEditEngine::
GetChar(size_t idx)
const {
896 if (idx >= text_length_)
899 return password_alias_;
901 return idx < gap_position_
903 : content_[gap_position_ + gap_size_ + (idx - gap_position_)];
909 return idx < char_widths_.size() ? char_widths_[idx] : 0;
916 auto start_it = text_piece_info_.begin();
917 for (; start_it < text_piece_info_.end(); ++start_it) {
918 if (start_it->rtPiece.top <= point.y &&
919 point.y < start_it->rtPiece.bottom())
924 if (start_it == text_piece_info_.end())
927 auto end_it = start_it;
928 for (; end_it < text_piece_info_.end(); ++end_it) {
931 if (end_it->rtPiece.bottom() <= point.y || point.y < end_it->rtPiece.top)
935 if (end_it == text_piece_info_.end())
938 size_t start_it_idx = start_it->nStart;
939 for (; start_it <= end_it; ++start_it) {
940 bool piece_contains_point_vertically =
941 (point.y >= start_it->rtPiece.top &&
942 point.y < start_it->rtPiece.bottom());
943 if (!piece_contains_point_vertically)
946 std::vector<CFX_RectF> rects = GetCharRects(*start_it);
947 for (size_t i = 0; i < rects.size(); ++i) {
948 bool character_contains_point_horizontally =
949 (point.x >= rects[i].left && point.x < rects[i].right());
950 if (!character_contains_point_horizontally)
956 bool closer_to_left =
957 (point.x - rects[i].left < rects[i].right() - point.x);
958 size_t caret_pos = closer_to_left ? i : i + 1;
959 size_t pos = start_it->nStart + caret_pos;
960 if (pos >= text_length_)
963 wchar_t wch = GetChar(pos);
964 if (wch == L'\n' || wch == L'\r') {
965 if (wch == L'\n' && pos > 0 && GetChar(pos - 1) == L'\r')
978 size_t pos = std::min(
979 static_cast<size_t>(start_it->nStart + start_it->nCount), text_length_);
985 bool is_last_line = (std::next(start_it) == text_piece_info_.end());
986 if (!is_last_line && pos > 0) {
987 wchar_t previous_char = GetChar(pos - 1);
988 if (previous_char == L' ' || previous_char == L'\n' ||
989 previous_char == L'\r') {
997 if (start_it == text_piece_info_.end())
999 if (start_it == end_it)
1000 return start_it->nStart;
1004 return end_it->nStart;
1007std::vector<CFX_RectF> CFDE_TextEditEngine::GetCharRects(
1009 if (piece.nCount < 1)
1010 return std::vector<CFX_RectF>();
1012 CFGAS_TxtBreak::
Run tr;
1013 tr.pEdtEngine =
this;
1018 tr.dwStyles = text_break_.GetLayoutStyles();
1021 return text_break_.GetCharRects(tr);
1026 if (piece.nCount < 1)
1027 return std::vector<TextCharPos>();
1029 CFGAS_TxtBreak::
Run tr;
1030 tr.pEdtEngine =
this;
1035 tr.dwStyles = text_break_.GetLayoutStyles();
1039 std::vector<TextCharPos> data(text_break_.GetDisplayPos(tr, {}));
1040 text_break_.GetDisplayPos(tr, data);
1044void CFDE_TextEditEngine::RebuildPieces() {
1045 text_break_.EndBreak(CFGAS_Char::BreakType::kParagraph);
1046 text_break_.ClearBreakPieces();
1048 char_widths_.clear();
1049 text_piece_info_.clear();
1055 bool initialized_bounding_box =
false;
1057 size_t current_piece_start = 0;
1058 float current_line_start = 0;
1065 password_mode_ ? password_alias_ : iter.GetChar());
1066 if (iter.IsEOF(
false) && CFX_BreakTypeNoneOrPiece(break_status))
1067 break_status = text_break_.EndBreak(CFGAS_Char::BreakType::kParagraph);
1071 int32_t piece_count = text_break_.CountBreakPieces();
1072 for (int32_t i = 0; i < piece_count; ++i) {
1080 txtEdtPiece
.nStart = checked_cast<int32_t>(current_piece_start);
1087 text_piece_info_.push_back(txtEdtPiece);
1089 if (initialized_bounding_box) {
1092 contents_bounding_box_
= txtEdtPiece
.rtPiece;
1093 initialized_bounding_box =
true;
1096 current_piece_start += txtEdtPiece
.nCount;
1097 for (int32_t k = 0; k < txtEdtPiece.nCount; ++k)
1098 char_widths_.push_back(piece->GetChar(k)->m_iCharWidth);
1101 current_line_start += line_spacing_;
1102 text_break_.ClearBreakPieces();
1106 bool bounds_smaller = contents_bounding_box_.width < available_width_;
1107 if (IsAlignedRight() && bounds_smaller) {
1108 delta = available_width_ - contents_bounding_box_.width;
1109 }
else if (IsAlignedCenter() && bounds_smaller) {
1110 delta = (available_width_ - contents_bounding_box_.width) / 2.0f;
1114 float offset = delta - contents_bounding_box_
.left;
1115 for (
auto& info : text_piece_info_)
1116 info.rtPiece.Offset(offset, 0.0f);
1121 contents_bounding_box_
.height -= line_spacing_ - font_size_;
1122 text_piece_info_.back().rtPiece.height = font_size_;
1126 int32_t start_idx) {
1128 DCHECK(
static_cast<size_t>(start_idx) <= text_length_);
1133 auto it = text_piece_info_.begin();
1134 for (; it != text_piece_info_.end(); ++it) {
1135 if (it->nStart <= start_idx && start_idx < it->nStart + it->nCount)
1138 CHECK_NE(it, text_piece_info_.end());
1139 return {it->nBidiLevel, GetCharRects(*it)[start_idx - it->nStart]};
1148 auto it = text_piece_info_.begin();
1149 for (; it != text_piece_info_.end(); ++it) {
1150 if (it->nStart <= start_idx && start_idx < it->nStart + it->nCount)
1153 if (it == text_piece_info_.end())
1154 return std::vector<CFX_RectF>();
1156 int32_t end_idx = start_idx + count - 1;
1157 std::vector<CFX_RectF> rects;
1158 while (it != text_piece_info_.end()) {
1160 if (it->nStart <= end_idx && end_idx < it->nStart + it->nCount) {
1161 std::vector<CFX_RectF> arr = GetCharRects(*it);
1163 piece.Union(arr[end_idx - it->nStart]);
1164 rects.push_back(piece);
1167 rects.push_back(it->rtPiece);
1176 if (idx > text_length_)
1182 size_t start_idx = iter.FindNextBreakPos(
true);
1183 size_t end_idx = iter.FindNextBreakPos(
false);
1184 return {start_idx, end_idx - start_idx + 1};
1193 if (bPrev && current_position_ == -1)
1195 if (!bPrev && current_position_ > -1 &&
1196 static_cast<size_t>(current_position_) == engine_->GetLength()) {
1201 --current_position_;
1203 ++current_position_;
1207 return engine_->GetChar(current_position_);
1211 nIndex = std::min(nIndex, engine_->GetLength());
1212 current_position_ = checked_cast<int32_t>(nIndex);
1216 return bPrev ? current_position_ == -1
1217 : current_position_ > -1 &&
1218 static_cast<size_t>(current_position_) ==
1219 engine_->GetLength();
1224 return current_position_ > -1 ? current_position_ : 0;
1246 int32_t nFlags = GetBreakFlagsFor(eCurType, eNextType);
1248 if (BreakFlagsChanged(nFlags, ePreType)) {
1257 int32_t nFlags = GetBreakFlagsFor(eNextType, eCurType);
1265 if (BreakFlagsChanged(nFlags, eNextType)) {
1272 eCurType = eNextType;
1275 return current_position_ > -1 ? current_position_ : 0;
#define FX_TXTCHARSTYLE_OddBidiLevel
bool CFX_BreakTypeNoneOrPiece(CFGAS_Char::BreakType type)
int32_t GetCharCount() const
int32_t GetStartPos() const
uint32_t GetCharStyles() const
int32_t GetBidiLevel() const
void Offset(float dx, float dy)
constexpr CFX_RectF()=default
CFX_RectF & operator=(const CFX_RectF &other)=default
void Union(const CFX_RectF &rt)
WideString & operator+=(const WideString &str)
WideString & operator=(WideString &&that) noexcept
bool IsEOF(bool bPrev) const
Iterator(const CFDE_TextEditEngine *engine)
size_t FindNextBreakPos(bool bPrev)
void SetAt(size_t nIndex)
wchar_t GetChar(size_t idx) const override
CFX_RectF GetContentsBoundingBox()
RetainPtr< CFGAS_GEFont > GetFont() const
size_t GetIndexLeft(size_t pos) const
WideString GetSelectedText() const
size_t GetIndexDown(size_t pos) const
size_t GetIndexForPoint(const CFX_PointF &point)
int32_t GetWidthOfChar(size_t idx) override
void SetAvailableWidth(size_t width)
std::vector< TextCharPos > GetDisplayPos(const FDE_TEXTEDITPIECE &info)
void Insert(size_t idx, const WideString &text, RecordOperation add_operation=RecordOperation::kInsertRecord)
void SetSelection(size_t start_idx, size_t count)
std::pair< int32_t, CFX_RectF > GetCharacterInfo(int32_t start_idx)
void SetTabWidth(float width)
void SetAlignment(uint32_t alignment)
std::pair< size_t, size_t > BoundsForWordAt(size_t idx) const
bool CanGenerateCharacterInfo() const
void ClearOperationRecords()
WideString GetText() const
std::vector< CFX_RectF > GetCharacterRectsInRange(int32_t start_idx, int32_t count)
void ReplaceSelectedText(const WideString &str)
~CFDE_TextEditEngine() override
void LimitVerticalScroll(bool val)
size_t GetIndexUp(size_t pos) const
void EnableLineWrap(bool val)
void EnableMultiLine(bool val)
void SetFontSize(float size)
size_t GetIndexAtStartOfLine(size_t pos) const
WideString DeleteSelectedText(RecordOperation add_operation=RecordOperation::kInsertRecord)
void SetHasCharacterLimit(bool limit)
void SetFont(RetainPtr< CFGAS_GEFont > font)
void SetVisibleLineCount(size_t lines)
void LimitHorizontalScroll(bool val)
size_t GetIndexRight(size_t pos) const
void SetCombText(bool enable)
size_t GetIndexAtEndOfLine(size_t pos) const
void SetMaxEditOperationsForTesting(size_t max)
WideString Delete(size_t start_idx, size_t length, RecordOperation add_operation=RecordOperation::kInsertRecord)
void SetCharacterLimit(size_t limit)
CFX_PTemplate< float > CFX_PointF
WordBreakProperty FX_GetWordBreakProperty(wchar_t wcCodePoint)
bool FX_CheckStateChangeForWordBreak(WordBreakProperty from, WordBreakProperty to)
fxcrt::WideStringView WideStringView
fxcrt::WideString WideString