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