fxet_edit.h revision 5ae9d0c6fd838a2967cca72aa5751b51dadc2769
1// Copyright 2014 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 FPDFSDK_FXEDIT_FXET_EDIT_H_
8#define FPDFSDK_FXEDIT_FXET_EDIT_H_
9
10#include <deque>
11#include <memory>
12#include <vector>
13
14#include "core/fpdfdoc/cpvt_secprops.h"
15#include "core/fpdfdoc/cpvt_wordprops.h"
16#include "fpdfsdk/fxedit/fx_edit.h"
17
18class CFFL_FormFiller;
19class CFX_Edit;
20class CFX_Edit_Iterator;
21class CFX_Edit_Provider;
22class CFX_RenderDevice;
23class CFX_SystemHandler;
24class CPDF_PageObjectHolder;
25class CPDF_TextObject;
26class CPWL_Edit;
27class CPWL_EditCtrl;
28
29class IFX_Edit_UndoItem;
30
31struct CFX_Edit_LineRect {
32  CFX_Edit_LineRect(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine)
33      : m_wrLine(wrLine), m_rcLine(rcLine) {}
34
35  CPVT_WordRange m_wrLine;
36  CFX_FloatRect m_rcLine;
37};
38
39class CFX_Edit_LineRectArray {
40 public:
41  CFX_Edit_LineRectArray();
42  virtual ~CFX_Edit_LineRectArray();
43
44  void operator=(CFX_Edit_LineRectArray&& rects);
45  void Add(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine);
46
47  int32_t GetSize() const;
48  CFX_Edit_LineRect* GetAt(int32_t nIndex) const;
49
50 private:
51  std::vector<std::unique_ptr<CFX_Edit_LineRect>> m_LineRects;
52};
53
54class CFX_Edit_RectArray {
55 public:
56  CFX_Edit_RectArray();
57  virtual ~CFX_Edit_RectArray();
58
59  void Clear();
60  void Add(const CFX_FloatRect& rect);
61
62  int32_t GetSize() const;
63  CFX_FloatRect* GetAt(int32_t nIndex) const;
64
65 private:
66  std::vector<std::unique_ptr<CFX_FloatRect>> m_Rects;
67};
68
69class CFX_Edit_Refresh {
70 public:
71  CFX_Edit_Refresh();
72  virtual ~CFX_Edit_Refresh();
73
74  void BeginRefresh();
75  void Push(const CPVT_WordRange& linerange, const CFX_FloatRect& rect);
76  void NoAnalyse();
77  void AddRefresh(const CFX_FloatRect& rect);
78  const CFX_Edit_RectArray* GetRefreshRects() const;
79  void EndRefresh();
80
81 private:
82  CFX_Edit_LineRectArray m_NewLineRects;
83  CFX_Edit_LineRectArray m_OldLineRects;
84  CFX_Edit_RectArray m_RefreshRects;
85};
86
87class CFX_Edit_Select {
88 public:
89  CFX_Edit_Select();
90  CFX_Edit_Select(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
91  explicit CFX_Edit_Select(const CPVT_WordRange& range);
92
93  void Default();
94  void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
95  void SetBeginPos(const CPVT_WordPlace& begin);
96  void SetEndPos(const CPVT_WordPlace& end);
97
98  CPVT_WordRange ConvertToWordRange() const;
99  bool IsExist() const;
100
101  CPVT_WordPlace BeginPos;
102  CPVT_WordPlace EndPos;
103};
104
105class CFX_Edit_Undo {
106 public:
107  explicit CFX_Edit_Undo(int32_t nBufsize);
108  virtual ~CFX_Edit_Undo();
109
110  void AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem);
111  void Undo();
112  void Redo();
113  bool CanUndo() const;
114  bool CanRedo() const;
115  bool IsModified() const;
116  void Reset();
117
118 private:
119  void RemoveHeads();
120  void RemoveTails();
121
122  std::deque<std::unique_ptr<IFX_Edit_UndoItem>> m_UndoItemStack;
123  size_t m_nCurUndoPos;
124  size_t m_nBufSize;
125  bool m_bModified;
126  bool m_bVirgin;
127  bool m_bWorking;
128};
129
130class IFX_Edit_UndoItem {
131 public:
132  virtual ~IFX_Edit_UndoItem() {}
133
134  virtual void Undo() = 0;
135  virtual void Redo() = 0;
136  virtual CFX_WideString GetUndoTitle() const = 0;
137};
138
139class CFX_Edit_UndoItem : public IFX_Edit_UndoItem {
140 public:
141  CFX_Edit_UndoItem();
142  ~CFX_Edit_UndoItem() override;
143
144  CFX_WideString GetUndoTitle() const override;
145
146  void SetFirst(bool bFirst);
147  void SetLast(bool bLast);
148  bool IsLast();
149
150 private:
151  bool m_bFirst;
152  bool m_bLast;
153};
154
155class CFX_Edit_GroupUndoItem : public IFX_Edit_UndoItem {
156 public:
157  explicit CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle);
158  ~CFX_Edit_GroupUndoItem() override;
159
160  // IFX_Edit_UndoItem
161  void Undo() override;
162  void Redo() override;
163  CFX_WideString GetUndoTitle() const override;
164
165  void AddUndoItem(std::unique_ptr<CFX_Edit_UndoItem> pUndoItem);
166  void UpdateItems();
167
168 private:
169  CFX_WideString m_sTitle;
170  std::vector<std::unique_ptr<CFX_Edit_UndoItem>> m_Items;
171};
172
173class CFXEU_InsertWord : public CFX_Edit_UndoItem {
174 public:
175  CFXEU_InsertWord(CFX_Edit* pEdit,
176                   const CPVT_WordPlace& wpOldPlace,
177                   const CPVT_WordPlace& wpNewPlace,
178                   uint16_t word,
179                   int32_t charset,
180                   const CPVT_WordProps* pWordProps);
181  ~CFXEU_InsertWord() override;
182
183  // CFX_Edit_UndoItem
184  void Redo() override;
185  void Undo() override;
186
187 private:
188  CFX_Edit* m_pEdit;
189
190  CPVT_WordPlace m_wpOld;
191  CPVT_WordPlace m_wpNew;
192  uint16_t m_Word;
193  int32_t m_nCharset;
194  CPVT_WordProps m_WordProps;
195};
196
197class CFXEU_InsertReturn : public CFX_Edit_UndoItem {
198 public:
199  CFXEU_InsertReturn(CFX_Edit* pEdit,
200                     const CPVT_WordPlace& wpOldPlace,
201                     const CPVT_WordPlace& wpNewPlace,
202                     const CPVT_SecProps* pSecProps,
203                     const CPVT_WordProps* pWordProps);
204  ~CFXEU_InsertReturn() override;
205
206  // CFX_Edit_UndoItem
207  void Redo() override;
208  void Undo() override;
209
210 private:
211  CFX_Edit* m_pEdit;
212
213  CPVT_WordPlace m_wpOld;
214  CPVT_WordPlace m_wpNew;
215  CPVT_SecProps m_SecProps;
216  CPVT_WordProps m_WordProps;
217};
218
219class CFXEU_Backspace : public CFX_Edit_UndoItem {
220 public:
221  CFXEU_Backspace(CFX_Edit* pEdit,
222                  const CPVT_WordPlace& wpOldPlace,
223                  const CPVT_WordPlace& wpNewPlace,
224                  uint16_t word,
225                  int32_t charset,
226                  const CPVT_SecProps& SecProps,
227                  const CPVT_WordProps& WordProps);
228  ~CFXEU_Backspace() override;
229
230  // CFX_Edit_UndoItem
231  void Redo() override;
232  void Undo() override;
233
234 private:
235  CFX_Edit* m_pEdit;
236
237  CPVT_WordPlace m_wpOld;
238  CPVT_WordPlace m_wpNew;
239  uint16_t m_Word;
240  int32_t m_nCharset;
241  CPVT_SecProps m_SecProps;
242  CPVT_WordProps m_WordProps;
243};
244
245class CFXEU_Delete : public CFX_Edit_UndoItem {
246 public:
247  CFXEU_Delete(CFX_Edit* pEdit,
248               const CPVT_WordPlace& wpOldPlace,
249               const CPVT_WordPlace& wpNewPlace,
250               uint16_t word,
251               int32_t charset,
252               const CPVT_SecProps& SecProps,
253               const CPVT_WordProps& WordProps,
254               bool bSecEnd);
255  ~CFXEU_Delete() override;
256
257  // CFX_Edit_UndoItem
258  void Redo() override;
259  void Undo() override;
260
261 private:
262  CFX_Edit* m_pEdit;
263
264  CPVT_WordPlace m_wpOld;
265  CPVT_WordPlace m_wpNew;
266  uint16_t m_Word;
267  int32_t m_nCharset;
268  CPVT_SecProps m_SecProps;
269  CPVT_WordProps m_WordProps;
270  bool m_bSecEnd;
271};
272
273class CFXEU_Clear : public CFX_Edit_UndoItem {
274 public:
275  CFXEU_Clear(CFX_Edit* pEdit,
276              const CPVT_WordRange& wrSel,
277              const CFX_WideString& swText);
278  ~CFXEU_Clear() override;
279
280  // CFX_Edit_UndoItem
281  void Redo() override;
282  void Undo() override;
283
284 private:
285  CFX_Edit* m_pEdit;
286
287  CPVT_WordRange m_wrSel;
288  CFX_WideString m_swText;
289};
290
291class CFXEU_InsertText : public CFX_Edit_UndoItem {
292 public:
293  CFXEU_InsertText(CFX_Edit* pEdit,
294                   const CPVT_WordPlace& wpOldPlace,
295                   const CPVT_WordPlace& wpNewPlace,
296                   const CFX_WideString& swText,
297                   int32_t charset);
298  ~CFXEU_InsertText() override;
299
300  // CFX_Edit_UndoItem
301  void Redo() override;
302  void Undo() override;
303
304 private:
305  CFX_Edit* m_pEdit;
306
307  CPVT_WordPlace m_wpOld;
308  CPVT_WordPlace m_wpNew;
309  CFX_WideString m_swText;
310  int32_t m_nCharset;
311};
312
313class CFX_Edit {
314 public:
315  static CFX_ByteString GetEditAppearanceStream(CFX_Edit* pEdit,
316                                                const CFX_PointF& ptOffset,
317                                                const CPVT_WordRange* pRange,
318                                                bool bContinuous,
319                                                uint16_t SubWord);
320  static CFX_ByteString GetSelectAppearanceStream(CFX_Edit* pEdit,
321                                                  const CFX_PointF& ptOffset,
322                                                  const CPVT_WordRange* pRange);
323  static void DrawEdit(CFX_RenderDevice* pDevice,
324                       CFX_Matrix* pUser2Device,
325                       CFX_Edit* pEdit,
326                       FX_COLORREF crTextFill,
327                       const CFX_FloatRect& rcClip,
328                       const CFX_PointF& ptOffset,
329                       const CPVT_WordRange* pRange,
330                       CFX_SystemHandler* pSystemHandler,
331                       CFFL_FormFiller* pFFLData);
332
333  CFX_Edit();
334  ~CFX_Edit();
335
336  void SetFontMap(IPVT_FontMap* pFontMap);
337  void SetNotify(CPWL_EditCtrl* pNotify);
338  void SetOprNotify(CPWL_Edit* pOprNotify);
339
340  // Returns an iterator for the contents. Should not be released.
341  CFX_Edit_Iterator* GetIterator();
342  IPVT_FontMap* GetFontMap();
343  void Initialize();
344
345  // Set the bounding box of the text area.
346  void SetPlateRect(const CFX_FloatRect& rect);
347  void SetScrollPos(const CFX_PointF& point);
348
349  // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right])
350  void SetAlignmentH(int32_t nFormat, bool bPaint);
351  // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right])
352  void SetAlignmentV(int32_t nFormat, bool bPaint);
353
354  // Set the substitution character for hidden text.
355  void SetPasswordChar(uint16_t wSubWord, bool bPaint);
356
357  // Set the maximum number of words in the text.
358  void SetLimitChar(int32_t nLimitChar);
359  void SetCharArray(int32_t nCharArray);
360  void SetCharSpace(FX_FLOAT fCharSpace);
361  void SetMultiLine(bool bMultiLine, bool bPaint);
362  void SetAutoReturn(bool bAuto, bool bPaint);
363  void SetAutoFontSize(bool bAuto, bool bPaint);
364  void SetAutoScroll(bool bAuto, bool bPaint);
365  void SetFontSize(FX_FLOAT fFontSize);
366  void SetTextOverflow(bool bAllowed, bool bPaint);
367  void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl);
368  void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl);
369  void OnVK_UP(bool bShift, bool bCtrl);
370  void OnVK_DOWN(bool bShift, bool bCtrl);
371  void OnVK_LEFT(bool bShift, bool bCtrl);
372  void OnVK_RIGHT(bool bShift, bool bCtrl);
373  void OnVK_HOME(bool bShift, bool bCtrl);
374  void OnVK_END(bool bShift, bool bCtrl);
375  void SetText(const CFX_WideString& sText);
376  bool InsertWord(uint16_t word, int32_t charset);
377  bool InsertReturn();
378  bool Backspace();
379  bool Delete();
380  bool Clear();
381  bool InsertText(const CFX_WideString& sText, int32_t charset);
382  bool Redo();
383  bool Undo();
384  int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const;
385  CPVT_WordPlace WordIndexToWordPlace(int32_t index) const;
386  CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const;
387  int32_t GetCaret() const;
388  CPVT_WordPlace GetCaretWordPlace() const;
389  CFX_WideString GetSelText() const;
390  CFX_WideString GetText() const;
391  FX_FLOAT GetFontSize() const;
392  uint16_t GetPasswordChar() const;
393  CFX_PointF GetScrollPos() const;
394  int32_t GetCharArray() const;
395  CFX_FloatRect GetContentRect() const;
396  CFX_WideString GetRangeText(const CPVT_WordRange& range) const;
397  int32_t GetHorzScale() const;
398  FX_FLOAT GetCharSpace() const;
399  int32_t GetTotalWords() const;
400  void SetSel(int32_t nStartChar, int32_t nEndChar);
401  void GetSel(int32_t& nStartChar, int32_t& nEndChar) const;
402  void SelectAll();
403  void SelectNone();
404  bool IsSelected() const;
405  void Paint();
406  void EnableRefresh(bool bRefresh);
407  void RefreshWordRange(const CPVT_WordRange& wr);
408  void SetCaret(int32_t nPos);
409  CPVT_WordRange GetWholeWordRange() const;
410  CPVT_WordRange GetSelectWordRange() const;
411  void EnableUndo(bool bUndo);
412  void EnableOprNotify(bool bNotify);
413  bool IsTextFull() const;
414  bool IsTextOverflow() const;
415  bool CanUndo() const;
416  bool CanRedo() const;
417  CPVT_WordRange GetVisibleWordRange() const;
418
419  bool Empty();
420
421  CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place,
422                              const CFX_WideString& sText,
423                              int32_t charset);
424  int32_t GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset);
425
426  int32_t GetTotalLines() const;
427
428 private:
429  friend class CFX_Edit_Iterator;
430  friend class CFXEU_InsertWord;
431  friend class CFXEU_InsertReturn;
432  friend class CFXEU_Backspace;
433  friend class CFXEU_Delete;
434  friend class CFXEU_Clear;
435  friend class CFXEU_InsertText;
436
437  void SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
438
439  void RearrangeAll();
440  void RearrangePart(const CPVT_WordRange& range);
441  void ScrollToCaret();
442  void SetScrollInfo();
443  void SetScrollPosX(FX_FLOAT fx);
444  void SetScrollPosY(FX_FLOAT fy);
445  void SetScrollLimit();
446  void SetContentChanged();
447
448  bool InsertWord(uint16_t word,
449                  int32_t charset,
450                  const CPVT_WordProps* pWordProps,
451                  bool bAddUndo,
452                  bool bPaint);
453  bool InsertReturn(const CPVT_SecProps* pSecProps,
454                    const CPVT_WordProps* pWordProps,
455                    bool bAddUndo,
456                    bool bPaint);
457  bool Backspace(bool bAddUndo, bool bPaint);
458  bool Delete(bool bAddUndo, bool bPaint);
459  bool Clear(bool bAddUndo, bool bPaint);
460  bool InsertText(const CFX_WideString& sText,
461                  int32_t charset,
462                  bool bAddUndo,
463                  bool bPaint);
464  void PaintInsertText(const CPVT_WordPlace& wpOld,
465                       const CPVT_WordPlace& wpNew);
466
467  inline CFX_PointF VTToEdit(const CFX_PointF& point) const;
468  inline CFX_PointF EditToVT(const CFX_PointF& point) const;
469  inline CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const;
470
471  void Refresh();
472  void RefreshPushLineRects(const CPVT_WordRange& wr);
473
474  void SetCaret(const CPVT_WordPlace& place);
475  void SetCaretInfo();
476  void SetCaretOrigin();
477
478  void AddEditUndoItem(std::unique_ptr<CFX_Edit_UndoItem> pEditUndoItem);
479
480 private:
481  std::unique_ptr<CPDF_VariableText> m_pVT;
482  CPWL_EditCtrl* m_pNotify;
483  CPWL_Edit* m_pOprNotify;
484  std::unique_ptr<CFX_Edit_Provider> m_pVTProvider;
485  CPVT_WordPlace m_wpCaret;
486  CPVT_WordPlace m_wpOldCaret;
487  CFX_Edit_Select m_SelState;
488  CFX_PointF m_ptScrollPos;
489  CFX_PointF m_ptRefreshScrollPos;
490  bool m_bEnableScroll;
491  std::unique_ptr<CFX_Edit_Iterator> m_pIterator;
492  CFX_Edit_Refresh m_Refresh;
493  CFX_PointF m_ptCaret;
494  CFX_Edit_Undo m_Undo;
495  int32_t m_nAlignment;
496  bool m_bNotifyFlag;
497  bool m_bEnableOverflow;
498  bool m_bEnableRefresh;
499  CFX_FloatRect m_rcOldContent;
500  bool m_bEnableUndo;
501  bool m_bOprNotify;
502  CFX_Edit_GroupUndoItem* m_pGroupUndoItem;
503};
504
505class CFX_Edit_Iterator {
506 public:
507  CFX_Edit_Iterator(CFX_Edit* pEdit, CPDF_VariableText::Iterator* pVTIterator);
508  ~CFX_Edit_Iterator();
509
510  bool NextWord();
511  bool PrevWord();
512  bool GetWord(CPVT_Word& word) const;
513  bool GetLine(CPVT_Line& line) const;
514  bool GetSection(CPVT_Section& section) const;
515  void SetAt(int32_t nWordIndex);
516  void SetAt(const CPVT_WordPlace& place);
517  const CPVT_WordPlace& GetAt() const;
518
519 private:
520  CFX_Edit* m_pEdit;
521  CPDF_VariableText::Iterator* m_pVTIterator;
522};
523
524class CFX_Edit_Provider : public CPDF_VariableText::Provider {
525 public:
526  explicit CFX_Edit_Provider(IPVT_FontMap* pFontMap);
527  ~CFX_Edit_Provider() override;
528
529  IPVT_FontMap* GetFontMap();
530
531  // CPDF_VariableText::Provider:
532  int32_t GetCharWidth(int32_t nFontIndex, uint16_t word) override;
533  int32_t GetTypeAscent(int32_t nFontIndex) override;
534  int32_t GetTypeDescent(int32_t nFontIndex) override;
535  int32_t GetWordFontIndex(uint16_t word,
536                           int32_t charset,
537                           int32_t nFontIndex) override;
538  int32_t GetDefaultFontIndex() override;
539  bool IsLatinWord(uint16_t word) override;
540
541 private:
542  IPVT_FontMap* m_pFontMap;
543};
544
545#endif  // FPDFSDK_FXEDIT_FXET_EDIT_H_
546