• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef XFA_FDE_CFDE_TEXTEDITENGINE_H_
8 #define XFA_FDE_CFDE_TEXTEDITENGINE_H_
9 
10 #include <memory>
11 #include <utility>
12 #include <vector>
13 
14 #include "core/fxcrt/fx_string.h"
15 #include "core/fxcrt/retain_ptr.h"
16 #include "core/fxge/fx_dib.h"
17 #include "xfa/fgas/layout/cfx_txtbreak.h"
18 
19 class CFGAS_GEFont;
20 class TextCharPos;
21 
22 struct FDE_TEXTEDITPIECE {
23   FDE_TEXTEDITPIECE();
24   FDE_TEXTEDITPIECE(const FDE_TEXTEDITPIECE& that);
25   ~FDE_TEXTEDITPIECE();
26 
27   CFX_RectF rtPiece;
28   int32_t nStart = 0;
29   int32_t nCount = 0;
30   int32_t nBidiLevel = 0;
31   uint32_t dwCharStyles = 0;
32 };
33 
34 inline FDE_TEXTEDITPIECE::FDE_TEXTEDITPIECE() = default;
35 inline FDE_TEXTEDITPIECE::FDE_TEXTEDITPIECE(const FDE_TEXTEDITPIECE& that) =
36     default;
37 inline FDE_TEXTEDITPIECE::~FDE_TEXTEDITPIECE() = default;
38 
39 class CFDE_TextEditEngine : public CFX_TxtBreak::Engine {
40  public:
41   class Iterator {
42    public:
43     explicit Iterator(const CFDE_TextEditEngine* engine);
44     ~Iterator();
45 
46     void Next(bool bPrev);
47     wchar_t GetChar() const;
48     void SetAt(size_t nIndex);
49     size_t FindNextBreakPos(bool bPrev);
50     bool IsEOF(bool bPrev) const;
51 
52    private:
53     UnownedPtr<const CFDE_TextEditEngine> engine_;
54     int32_t current_position_;
55   };
56 
57   class Operation {
58    public:
59     virtual ~Operation() = default;
60     virtual void Redo() const = 0;
61     virtual void Undo() const = 0;
62   };
63 
64   struct TextChange {
65     WideString text;
66     WideString previous_text;
67     size_t selection_start;
68     size_t selection_end;
69     bool cancelled;
70   };
71 
72   class Delegate {
73    public:
74     virtual ~Delegate() = default;
75     virtual void NotifyTextFull() = 0;
76     virtual void OnCaretChanged() = 0;
77     virtual void OnTextWillChange(TextChange* change) = 0;
78     virtual void OnTextChanged() = 0;
79     virtual void OnSelChanged() = 0;
80     virtual bool OnValidate(const WideString& wsText) = 0;
81     virtual void SetScrollOffset(float fScrollOffset) = 0;
82   };
83 
84   enum class RecordOperation { kInsertRecord, kSkipRecord, kSkipNotify };
85 
86   CFDE_TextEditEngine();
87   ~CFDE_TextEditEngine() override;
88 
89   // CFX_TxtBreak::Engine:
90   wchar_t GetChar(size_t idx) const override;
91   size_t GetWidthOfChar(size_t idx) override;
92 
SetDelegate(Delegate * delegate)93   void SetDelegate(Delegate* delegate) { delegate_ = delegate; }
94   void Clear();
95 
96   void Insert(size_t idx,
97               const WideString& text,
98               RecordOperation add_operation = RecordOperation::kInsertRecord);
99   WideString Delete(
100       size_t start_idx,
101       size_t length,
102       RecordOperation add_operation = RecordOperation::kInsertRecord);
103   WideString GetText() const;
104   size_t GetLength() const;
105 
106   // Non-const so we can force a layout.
107   CFX_RectF GetContentsBoundingBox();
108   void SetAvailableWidth(size_t width);
109 
110   void SetFont(RetainPtr<CFGAS_GEFont> font);
111   RetainPtr<CFGAS_GEFont> GetFont() const;
112   void SetFontSize(float size);
GetFontSize()113   float GetFontSize() const { return font_size_; }
SetFontColor(FX_ARGB color)114   void SetFontColor(FX_ARGB color) { font_color_ = color; }
GetFontColor()115   FX_ARGB GetFontColor() const { return font_color_; }
116 
117   void SetAlignment(uint32_t alignment);
GetLineSpace()118   float GetLineSpace() const { return line_spacing_; }
SetLineSpace(float space)119   void SetLineSpace(float space) { line_spacing_ = space; }
SetAliasChar(wchar_t alias)120   void SetAliasChar(wchar_t alias) { password_alias_ = alias; }
121   void SetHasCharacterLimit(bool limit);
122   void SetCharacterLimit(size_t limit);
123   void SetCombText(bool enable);
124   void SetTabWidth(float width);
125   void SetVisibleLineCount(size_t lines);
126 
EnableValidation(bool val)127   void EnableValidation(bool val) { validation_enabled_ = val; }
EnablePasswordMode(bool val)128   void EnablePasswordMode(bool val) { password_mode_ = val; }
129   void EnableMultiLine(bool val);
130   void EnableLineWrap(bool val);
131   void LimitHorizontalScroll(bool val);
132   void LimitVerticalScroll(bool val);
133 
134   bool CanUndo() const;
135   bool CanRedo() const;
136   bool Redo();
137   bool Undo();
138   void ClearOperationRecords();
139 
140   // This is not const it can trigger a |Layout|.
141   size_t GetIndexBefore(size_t pos);
142   size_t GetIndexLeft(size_t pos) const;
143   size_t GetIndexRight(size_t pos) const;
144   size_t GetIndexUp(size_t pos) const;
145   size_t GetIndexDown(size_t pos) const;
146   size_t GetIndexAtStartOfLine(size_t pos) const;
147   size_t GetIndexAtEndOfLine(size_t pos) const;
148 
149   void SelectAll();
150   void SetSelection(size_t start_idx, size_t count);
151   void ClearSelection();
HasSelection()152   bool HasSelection() const { return has_selection_; }
153   // Returns <start_idx, count> of the selection.
GetSelection()154   std::pair<size_t, size_t> GetSelection() const {
155     return {selection_.start_idx, selection_.count};
156   }
157   WideString GetSelectedText() const;
158   WideString DeleteSelectedText(
159       RecordOperation add_operation = RecordOperation::kInsertRecord);
160   void ReplaceSelectedText(const WideString& str);
161 
162   void Layout();
163 
164   // Non-const so we can force a Layout() if needed.
165   size_t GetIndexForPoint(const CFX_PointF& point);
166   // <start_idx, count>
167   std::pair<size_t, size_t> BoundsForWordAt(size_t idx) const;
168 
169   // Returns <bidi level, character rect>
170   std::pair<int32_t, CFX_RectF> GetCharacterInfo(int32_t start_idx);
171   std::vector<CFX_RectF> GetCharacterRectsInRange(int32_t start_idx,
172                                                   int32_t count);
173 
GetTextPieces()174   const std::vector<FDE_TEXTEDITPIECE>& GetTextPieces() {
175     // Force a layout if needed.
176     Layout();
177     return text_piece_info_;
178   }
179 
180   std::vector<TextCharPos> GetDisplayPos(const FDE_TEXTEDITPIECE& info);
181 
182   void SetMaxEditOperationsForTesting(size_t max);
183 
184  private:
185   void SetCombTextWidth();
186   void AdjustGap(size_t idx, size_t length);
187   void RebuildPieces();
188   size_t CountCharsExceedingSize(const WideString& str, size_t num_to_check);
189   void AddOperationRecord(std::unique_ptr<Operation> op);
190 
IsAlignedRight()191   bool IsAlignedRight() const {
192     return !!(character_alignment_ & CFX_TxtLineAlignment_Left);
193   }
194 
IsAlignedCenter()195   bool IsAlignedCenter() const {
196     return !!(character_alignment_ & CFX_TxtLineAlignment_Center);
197   }
198   std::vector<CFX_RectF> GetCharRects(const FDE_TEXTEDITPIECE& piece);
199 
200   struct Selection {
201     size_t start_idx;
202     size_t count;
203   };
204 
205   CFX_RectF contents_bounding_box_;
206   UnownedPtr<Delegate> delegate_;
207   std::vector<FDE_TEXTEDITPIECE> text_piece_info_;
208   std::vector<size_t> char_widths_;
209   CFX_TxtBreak text_break_;
210   RetainPtr<CFGAS_GEFont> font_;
211   FX_ARGB font_color_;
212   float font_size_;
213   float line_spacing_;
214   std::vector<WideString::CharType> content_;
215   size_t text_length_;
216 
217   // See e.g. https://en.wikipedia.org/wiki/Gap_buffer
218   size_t gap_position_;
219   size_t gap_size_;
220 
221   size_t available_width_;
222   size_t character_limit_;
223   size_t visible_line_count_;
224   // Ring buffer of edit operations
225   std::vector<std::unique_ptr<Operation>> operation_buffer_;
226   // Next edit operation to undo.
227   size_t next_operation_index_to_undo_;
228   // Next index to insert an edit operation into.
229   size_t next_operation_index_to_insert_;
230   size_t max_edit_operations_;
231   uint32_t character_alignment_;
232   bool has_character_limit_;
233   bool is_comb_text_;
234   bool is_dirty_;
235   bool validation_enabled_;
236   bool is_multiline_;
237   bool is_linewrap_enabled_;
238   bool limit_horizontal_area_;
239   bool limit_vertical_area_;
240   bool password_mode_;
241   wchar_t password_alias_;
242   bool has_selection_;
243   Selection selection_;
244 };
245 
246 #endif  // XFA_FDE_CFDE_TEXTEDITENGINE_H_
247