xref: /aosp_15_r20/external/pdfium/fpdfsdk/pwl/cpwl_edit_impl.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2014 The PDFium Authors
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 FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
8 #define FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
9 
10 #include <deque>
11 #include <memory>
12 #include <utility>
13 #include <vector>
14 
15 #include "core/fpdfdoc/cpvt_variabletext.h"
16 #include "core/fpdfdoc/cpvt_wordrange.h"
17 #include "core/fxcrt/bytestring.h"
18 #include "core/fxcrt/fx_codepage_forward.h"
19 #include "core/fxcrt/unowned_ptr.h"
20 #include "core/fxge/dib/fx_dib.h"
21 #include "fpdfsdk/pwl/ipwl_fillernotify.h"
22 
23 class CFX_RenderDevice;
24 class CPWL_Edit;
25 
26 class CPWL_EditImpl {
27  public:
28   class Iterator {
29    public:
30     Iterator(CPWL_EditImpl* pEdit, CPVT_VariableText::Iterator* pVTIterator);
31     ~Iterator();
32 
33     bool NextWord();
34     bool GetWord(CPVT_Word& word) const;
35     bool GetLine(CPVT_Line& line) const;
36     void SetAt(int32_t nWordIndex);
37     void SetAt(const CPVT_WordPlace& place);
38     const CPVT_WordPlace& GetAt() const;
39 
40    private:
41     UnownedPtr<CPWL_EditImpl> m_pEdit;
42     UnownedPtr<CPVT_VariableText::Iterator> m_pVTIterator;
43   };
44 
45   CPWL_EditImpl();
46   ~CPWL_EditImpl();
47 
48   void DrawEdit(CFX_RenderDevice* pDevice,
49                 const CFX_Matrix& mtUser2Device,
50                 FX_COLORREF crTextFill,
51                 const CFX_FloatRect& rcClip,
52                 const CFX_PointF& ptOffset,
53                 const CPVT_WordRange* pRange,
54                 IPWL_FillerNotify* pFillerNotify,
55                 IPWL_FillerNotify::PerWindowData* pSystemData);
56 
57   void SetFontMap(IPVT_FontMap* pFontMap);
58   void SetNotify(CPWL_Edit* pNotify);
59 
60   // Returns an iterator for the contents. Should not be released.
61   Iterator* GetIterator();
62   IPVT_FontMap* GetFontMap();
63   void Initialize();
64 
65   // Set the bounding box of the text area.
66   void SetPlateRect(const CFX_FloatRect& rect);
67   void SetScrollPos(const CFX_PointF& point);
68 
69   // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right])
70   void SetAlignmentH(int32_t nFormat);
71 
72   // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right])
73   void SetAlignmentV(int32_t nFormat);
74 
75   // Set the substitution character for hidden text.
76   void SetPasswordChar(uint16_t wSubWord);
77 
78   // Set the maximum number of words in the text.
79   void SetLimitChar(int32_t nLimitChar);
80   void SetCharArray(int32_t nCharArray);
81   void SetMultiLine(bool bMultiLine);
82   void SetAutoReturn(bool bAuto);
83   void SetAutoFontSize(bool bAuto);
84   void SetAutoScroll(bool bAuto);
85   void SetFontSize(float fFontSize);
86   void SetTextOverflow(bool bAllowed);
87   void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl);
88   void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl);
89   void OnVK_UP(bool bShift);
90   void OnVK_DOWN(bool bShift);
91   void OnVK_LEFT(bool bShift);
92   void OnVK_RIGHT(bool bShift);
93   void OnVK_HOME(bool bShift, bool bCtrl);
94   void OnVK_END(bool bShift, bool bCtrl);
95   void SetText(const WideString& sText);
96   bool InsertWord(uint16_t word, FX_Charset charset);
97   bool InsertReturn();
98   bool Backspace();
99   bool Delete();
100   bool ClearSelection();
101   bool InsertText(const WideString& sText, FX_Charset charset);
102   void ReplaceAndKeepSelection(const WideString& text);
103   void ReplaceSelection(const WideString& text);
104   bool Redo();
105   bool Undo();
106   CPVT_WordPlace WordIndexToWordPlace(int32_t index) const;
107   CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const;
108   int32_t GetCaret() const;
109   CPVT_WordPlace GetCaretWordPlace() const;
110   WideString GetSelectedText() const;
111   WideString GetText() const;
112   float GetFontSize() const;
113   uint16_t GetPasswordChar() const;
114   CFX_PointF GetScrollPos() const;
115   int32_t GetCharArray() const;
116   CFX_FloatRect GetContentRect() const;
117   WideString GetRangeText(const CPVT_WordRange& range) const;
118   void SetSelection(int32_t nStartChar, int32_t nEndChar);
119   std::pair<int32_t, int32_t> GetSelection() const;
120   void SelectAll();
121   void SelectNone();
122   bool IsSelected() const;
123   void Paint();
124   void EnableRefresh(bool bRefresh);
125   void RefreshWordRange(const CPVT_WordRange& wr);
126   CPVT_WordRange GetWholeWordRange() const;
127   CPVT_WordRange GetSelectWordRange() const;
128   void EnableUndo(bool bUndo);
129   bool IsTextFull() const;
130   bool CanUndo() const;
131   bool CanRedo() const;
132   CPVT_WordRange GetVisibleWordRange() const;
133 
134   ByteString GetPDFWordString(int32_t nFontIndex,
135                               uint16_t Word,
136                               uint16_t SubWord);
137 
138  private:
139   class RefreshState {
140    public:
141     RefreshState();
142     ~RefreshState();
143 
144     void BeginRefresh();
145     void Push(const CPVT_WordRange& linerange, const CFX_FloatRect& rect);
146     void NoAnalyse();
147     std::vector<CFX_FloatRect>* GetRefreshRects();
148     void EndRefresh();
149 
150    private:
151     struct LineRect {
LineRectLineRect152       LineRect(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine)
153           : m_wrLine(wrLine), m_rcLine(rcLine) {}
154 
155       CPVT_WordRange m_wrLine;
156       CFX_FloatRect m_rcLine;
157     };
158 
159     void Add(const CFX_FloatRect& new_rect);
160 
161     std::vector<LineRect> m_NewLineRects;
162     std::vector<LineRect> m_OldLineRects;
163     std::vector<CFX_FloatRect> m_RefreshRects;
164   };
165 
166   class SelectState {
167    public:
168     SelectState();
169     explicit SelectState(const CPVT_WordRange& range);
170 
171     void Reset();
172     void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
173     void SetEndPos(const CPVT_WordPlace& end);
174 
175     CPVT_WordRange ConvertToWordRange() const;
176     bool IsEmpty() const;
177 
178     CPVT_WordPlace BeginPos;
179     CPVT_WordPlace EndPos;
180   };
181 
182   class UndoItemIface {
183    public:
184     virtual ~UndoItemIface() = default;
185 
186     // Undo/Redo the current undo item and returns the number of additional
187     // items to be processed in |m_UndoItemStack| to fully undo/redo the action.
188     // (An example is UndoReplaceSelection::Undo(), if UndoReplaceSelection
189     // marks the end of a replace action, UndoReplaceSelection::Undo() returns 3
190     // because 3 more undo items need to be processed to revert the replace
191     // action: insert text, clear selection and the UndoReplaceSelection which
192     // marks the beginning of replace action.) Implementations should return 0
193     // by default.
194     virtual int Undo() = 0;
195     virtual int Redo() = 0;
196   };
197 
198   class UndoStack {
199    public:
200     UndoStack();
201     ~UndoStack();
202 
203     void AddItem(std::unique_ptr<UndoItemIface> pItem);
204     void Undo();
205     void Redo();
206     bool CanUndo() const;
207     bool CanRedo() const;
208 
209    private:
210     void RemoveHeads();
211     void RemoveTails();
212 
213     std::deque<std::unique_ptr<UndoItemIface>> m_UndoItemStack;
214     size_t m_nCurUndoPos = 0;
215     bool m_bWorking = false;
216   };
217 
218   class Provider;
219   class UndoBackspace;
220   class UndoClear;
221   class UndoDelete;
222   class UndoInsertReturn;
223   class UndoInsertText;
224   class UndoInsertWord;
225   class UndoReplaceSelection;
226 
227   bool IsTextOverflow() const;
228   bool Clear();
229   CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place,
230                               const WideString& sText,
231                               FX_Charset charset);
232   FX_Charset GetCharSetFromUnicode(uint16_t word, FX_Charset nOldCharset);
233   int32_t GetTotalLines() const;
234   void SetSelection(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
235   bool Delete(bool bAddUndo);
236   bool Clear(bool bAddUndo);
237   bool InsertText(const WideString& sText, FX_Charset charset, bool bAddUndo);
238   bool InsertWord(uint16_t word, FX_Charset charset, bool bAddUndo);
239   bool InsertReturn(bool bAddUndo);
240   bool Backspace(bool bAddUndo);
241   void SetCaret(const CPVT_WordPlace& place);
242 
243   CFX_PointF VTToEdit(const CFX_PointF& point) const;
244 
245   void RearrangeAll();
246   void RearrangePart(const CPVT_WordRange& range);
247   void ScrollToCaret();
248   void SetScrollInfo();
249   void SetScrollPosX(float fx);
250   void SetScrollPosY(float fy);
251   void SetScrollLimit();
252   void SetContentChanged();
253 
254   void PaintInsertText(const CPVT_WordPlace& wpOld,
255                        const CPVT_WordPlace& wpNew);
256 
257   CFX_PointF EditToVT(const CFX_PointF& point) const;
258   CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const;
259 
260   void Refresh();
261   void RefreshPushLineRects(const CPVT_WordRange& wr);
262 
263   void SetCaretInfo();
264   void SetCaretOrigin();
265 
266   void AddEditUndoItem(std::unique_ptr<UndoItemIface> pEditUndoItem);
267 
268   bool m_bEnableScroll = false;
269   bool m_bNotifyFlag = false;
270   bool m_bEnableOverflow = false;
271   bool m_bEnableRefresh = true;
272   bool m_bEnableUndo = true;
273   int32_t m_nAlignment = 0;
274   std::unique_ptr<Provider> m_pVTProvider;
275   std::unique_ptr<CPVT_VariableText> m_pVT;  // Must outlive |m_pVTProvider|.
276   UnownedPtr<CPWL_Edit> m_pNotify;
277   CPVT_WordPlace m_wpCaret;
278   CPVT_WordPlace m_wpOldCaret;
279   SelectState m_SelState;
280   CFX_PointF m_ptScrollPos;
281   CFX_PointF m_ptRefreshScrollPos;
282   std::unique_ptr<Iterator> m_pIterator;
283   RefreshState m_Refresh;
284   CFX_PointF m_ptCaret;
285   UndoStack m_Undo;
286   CFX_FloatRect m_rcOldContent;
287 };
288 
289 #endif  // FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
290