• 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/cfx_renderdevice.h"
17 #include "core/fxge/fx_dib.h"
18 #include "xfa/fgas/layout/cfx_txtbreak.h"
19 
20 class CFGAS_GEFont;
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 {
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   class Delegate {
65    public:
66     virtual ~Delegate() = default;
67     virtual void NotifyTextFull() = 0;
68     virtual void OnCaretChanged() = 0;
69     virtual void OnTextChanged(const WideString& prevText) = 0;
70     virtual void OnSelChanged() = 0;
71     virtual bool OnValidate(const WideString& wsText) = 0;
72     virtual void SetScrollOffset(float fScrollOffset) = 0;
73   };
74 
75   enum class RecordOperation {
76     kInsertRecord,
77     kSkipRecord,
78   };
79 
80   CFDE_TextEditEngine();
81   ~CFDE_TextEditEngine();
82 
SetDelegate(Delegate * delegate)83   void SetDelegate(Delegate* delegate) { delegate_ = delegate; }
84   void Clear();
85 
86   void Insert(size_t idx,
87               const WideString& text,
88               RecordOperation add_operation = RecordOperation::kInsertRecord);
89   WideString Delete(
90       size_t start_idx,
91       size_t length,
92       RecordOperation add_operation = RecordOperation::kInsertRecord);
93   WideString GetText() const;
94   size_t GetLength() const;
95 
96   // Non-const so we can force a layout.
97   CFX_RectF GetContentsBoundingBox();
98   void SetAvailableWidth(size_t width);
99 
100   void SetFont(RetainPtr<CFGAS_GEFont> font);
101   RetainPtr<CFGAS_GEFont> GetFont() const;
102   void SetFontSize(float size);
GetFontSize()103   float GetFontSize() const { return font_size_; }
SetFontColor(FX_ARGB color)104   void SetFontColor(FX_ARGB color) { font_color_ = color; }
GetFontColor()105   FX_ARGB GetFontColor() const { return font_color_; }
106   float GetFontAscent() const;
107 
108   void SetAlignment(uint32_t alignment);
GetLineSpace()109   float GetLineSpace() const { return line_spacing_; }
SetLineSpace(float space)110   void SetLineSpace(float space) { line_spacing_ = space; }
SetAliasChar(wchar_t alias)111   void SetAliasChar(wchar_t alias) { password_alias_ = alias; }
112   void SetHasCharacterLimit(bool limit);
113   void SetCharacterLimit(size_t limit);
114   void SetCombText(bool enable);
115   void SetTabWidth(float width);
116   void SetVisibleLineCount(size_t lines);
117 
EnableValidation(bool val)118   void EnableValidation(bool val) { validation_enabled_ = val; }
EnablePasswordMode(bool val)119   void EnablePasswordMode(bool val) { password_mode_ = val; }
120   void EnableMultiLine(bool val);
121   void EnableLineWrap(bool val);
122   void LimitHorizontalScroll(bool val);
123   void LimitVerticalScroll(bool val);
124 
125   bool CanUndo() const;
126   bool CanRedo() const;
127   bool Redo();
128   bool Undo();
129   void ClearOperationRecords();
130 
131   // This is not const it can trigger a |Layout|.
132   size_t GetIndexBefore(size_t pos);
133   size_t GetIndexLeft(size_t pos) const;
134   size_t GetIndexRight(size_t pos) const;
135   size_t GetIndexUp(size_t pos) const;
136   size_t GetIndexDown(size_t pos) const;
137   size_t GetIndexAtStartOfLine(size_t pos) const;
138   size_t GetIndexAtEndOfLine(size_t pos) const;
139 
140   void SelectAll();
141   void SetSelection(size_t start_idx, size_t count);
142   void ClearSelection();
HasSelection()143   bool HasSelection() const { return has_selection_; }
144   // Returns <start_idx, count> of the selection.
GetSelection()145   std::pair<size_t, size_t> GetSelection() const {
146     return {selection_.start_idx, selection_.count};
147   }
148   WideString GetSelectedText() const;
149   WideString DeleteSelectedText(
150       RecordOperation add_operation = RecordOperation::kInsertRecord);
151   void ReplaceSelectedText(const WideString& str);
152 
153   void Layout();
154 
155   wchar_t GetChar(size_t idx) const;
156   // Non-const so we can force a Layout() if needed.
157   size_t GetWidthOfChar(size_t idx);
158   // Non-const so we can force a Layout() if needed.
159   size_t GetIndexForPoint(const CFX_PointF& point);
160   // <start_idx, count>
161   std::pair<size_t, size_t> BoundsForWordAt(size_t idx) const;
162 
163   // Returns <bidi level, character rect>
164   std::pair<int32_t, CFX_RectF> GetCharacterInfo(int32_t start_idx);
165   std::vector<CFX_RectF> GetCharacterRectsInRange(int32_t start_idx,
166                                                   int32_t count);
167 
GetTextBreak()168   CFX_TxtBreak* GetTextBreak() { return &text_break_; }
169 
GetTextPieces()170   const std::vector<FDE_TEXTEDITPIECE>& GetTextPieces() {
171     // Force a layout if needed.
172     Layout();
173     return text_piece_info_;
174   }
175 
176   std::vector<FXTEXT_CHARPOS> GetDisplayPos(const FDE_TEXTEDITPIECE& info);
177 
178   void SetMaxEditOperationsForTesting(size_t max);
179 
180  private:
181   void SetCombTextWidth();
182   void AdjustGap(size_t idx, size_t length);
183   void RebuildPieces();
184   size_t CountCharsExceedingSize(const WideString& str, size_t num_to_check);
185   void AddOperationRecord(std::unique_ptr<Operation> op);
186 
IsAlignedRight()187   bool IsAlignedRight() const {
188     return !!(character_alignment_ & CFX_TxtLineAlignment_Left);
189   }
190 
IsAlignedCenter()191   bool IsAlignedCenter() const {
192     return !!(character_alignment_ & CFX_TxtLineAlignment_Center);
193   }
194   std::vector<CFX_RectF> GetCharRects(const FDE_TEXTEDITPIECE& piece);
195 
196   struct Selection {
197     size_t start_idx;
198     size_t count;
199   };
200 
201   CFX_RectF contents_bounding_box_;
202   UnownedPtr<Delegate> delegate_;
203   std::vector<FDE_TEXTEDITPIECE> text_piece_info_;
204   std::vector<size_t> char_widths_;
205   CFX_TxtBreak text_break_;
206   RetainPtr<CFGAS_GEFont> font_;
207   FX_ARGB font_color_;
208   float font_size_;
209   float line_spacing_;
210   std::vector<WideString::CharType> content_;
211   size_t text_length_;
212   size_t gap_position_;
213   size_t gap_size_;
214   size_t available_width_;
215   size_t character_limit_;
216   size_t visible_line_count_;
217   // Ring buffer of edit operations
218   std::vector<std::unique_ptr<Operation>> operation_buffer_;
219   // Next edit operation to undo.
220   size_t next_operation_index_to_undo_;
221   // Next index to insert an edit operation into.
222   size_t next_operation_index_to_insert_;
223   size_t max_edit_operations_;
224   uint32_t character_alignment_;
225   bool has_character_limit_;
226   bool is_comb_text_;
227   bool is_dirty_;
228   bool validation_enabled_;
229   bool is_multiline_;
230   bool is_linewrap_enabled_;
231   bool limit_horizontal_area_;
232   bool limit_vertical_area_;
233   bool password_mode_;
234   wchar_t password_alias_;
235   bool has_selection_;
236   Selection selection_;
237 };
238 
239 #endif  // XFA_FDE_CFDE_TEXTEDITENGINE_H_
240