• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_PWL_CPWL_EDIT_IMPL_H_
8 #define FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
9 
10 #include <deque>
11 #include <memory>
12 #include <vector>
13 
14 #include "core/fpdfdoc/cpdf_variabletext.h"
15 #include "core/fpdfdoc/cpvt_wordrange.h"
16 #include "core/fxcrt/unowned_ptr.h"
17 #include "core/fxge/fx_dib.h"
18 
19 #define FX_EDIT_ISLATINWORD(u)                  \
20   (u == 0x2D || (u <= 0x005A && u >= 0x0041) || \
21    (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0))
22 
23 class CFFL_FormFiller;
24 class CPWL_EditImpl;
25 class CPWL_EditImpl_Iterator;
26 class CPWL_EditImpl_Provider;
27 class CFX_RenderDevice;
28 class CPWL_Edit;
29 class CPWL_EditCtrl;
30 class IPWL_SystemHandler;
31 class IFX_Edit_UndoItem;
32 
33 struct CPWL_EditImpl_LineRect {
CPWL_EditImpl_LineRectCPWL_EditImpl_LineRect34   CPWL_EditImpl_LineRect(const CPVT_WordRange& wrLine,
35                          const CFX_FloatRect& rcLine)
36       : m_wrLine(wrLine), m_rcLine(rcLine) {}
37 
38   CPVT_WordRange m_wrLine;
39   CFX_FloatRect m_rcLine;
40 };
41 
42 class CPWL_EditImpl_Refresh {
43  public:
44   CPWL_EditImpl_Refresh();
45   ~CPWL_EditImpl_Refresh();
46 
47   void BeginRefresh();
48   void Push(const CPVT_WordRange& linerange, const CFX_FloatRect& rect);
49   void NoAnalyse();
50   std::vector<CFX_FloatRect>* GetRefreshRects();
51   void EndRefresh();
52 
53  private:
54   void Add(const CFX_FloatRect& new_rect);
55 
56   std::vector<CPWL_EditImpl_LineRect> m_NewLineRects;
57   std::vector<CPWL_EditImpl_LineRect> m_OldLineRects;
58   std::vector<CFX_FloatRect> m_RefreshRects;
59 };
60 
61 class CPWL_EditImpl_Select {
62  public:
63   CPWL_EditImpl_Select();
64   explicit CPWL_EditImpl_Select(const CPVT_WordRange& range);
65 
66   void Reset();
67   void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
68   void SetEndPos(const CPVT_WordPlace& end);
69 
70   CPVT_WordRange ConvertToWordRange() const;
71   bool IsEmpty() const;
72 
73   CPVT_WordPlace BeginPos;
74   CPVT_WordPlace EndPos;
75 };
76 
77 class CPWL_EditImpl_Undo {
78  public:
79   CPWL_EditImpl_Undo();
80   ~CPWL_EditImpl_Undo();
81 
82   void AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem);
83   void Undo();
84   void Redo();
85   bool CanUndo() const;
86   bool CanRedo() const;
87 
88  private:
89   void RemoveHeads();
90   void RemoveTails();
91 
92   std::deque<std::unique_ptr<IFX_Edit_UndoItem>> m_UndoItemStack;
93   size_t m_nCurUndoPos;
94   bool m_bWorking;
95 };
96 
97 class IFX_Edit_UndoItem {
98  public:
99   virtual ~IFX_Edit_UndoItem() = default;
100 
101   // Undo/Redo the current undo item and returns the number of additional items
102   // to be processed in |m_UndoItemStack| to fully undo/redo the action. (An
103   // example is CFXEU_ReplaceSelection::Undo(), if CFXEU_ReplaceSelection marks
104   // the end of a replace action, CFXEU_ReplaceSelection::Undo() returns 3
105   // because 3 more undo items need to be processed to revert the replace
106   // action: insert text, clear selection and the CFXEU_ReplaceSelection which
107   // marks the beginning of replace action.) Implementations should return 0 by
108   // default.
109   virtual int Undo() = 0;
110   virtual int Redo() = 0;
111 };
112 
113 class CFXEU_InsertWord final : public IFX_Edit_UndoItem {
114  public:
115   CFXEU_InsertWord(CPWL_EditImpl* pEdit,
116                    const CPVT_WordPlace& wpOldPlace,
117                    const CPVT_WordPlace& wpNewPlace,
118                    uint16_t word,
119                    int32_t charset);
120   ~CFXEU_InsertWord() override;
121 
122   // IFX_Edit_UndoItem:
123   int Redo() override;
124   int Undo() override;
125 
126  private:
127   UnownedPtr<CPWL_EditImpl> m_pEdit;
128 
129   CPVT_WordPlace m_wpOld;
130   CPVT_WordPlace m_wpNew;
131   uint16_t m_Word;
132   int32_t m_nCharset;
133 };
134 
135 class CFXEU_InsertReturn final : public IFX_Edit_UndoItem {
136  public:
137   CFXEU_InsertReturn(CPWL_EditImpl* pEdit,
138                      const CPVT_WordPlace& wpOldPlace,
139                      const CPVT_WordPlace& wpNewPlace);
140   ~CFXEU_InsertReturn() override;
141 
142   // IFX_Edit_UndoItem:
143   int Redo() override;
144   int Undo() override;
145 
146  private:
147   UnownedPtr<CPWL_EditImpl> m_pEdit;
148 
149   CPVT_WordPlace m_wpOld;
150   CPVT_WordPlace m_wpNew;
151 };
152 
153 class CFXEU_ReplaceSelection final : public IFX_Edit_UndoItem {
154  public:
155   CFXEU_ReplaceSelection(CPWL_EditImpl* pEdit, bool bIsEnd);
156   ~CFXEU_ReplaceSelection() override;
157 
158   // IFX_Edit_UndoItem:
159   int Redo() override;
160   int Undo() override;
161 
162  private:
IsEnd()163   bool IsEnd() const { return m_bEnd; }
164 
165   UnownedPtr<CPWL_EditImpl> m_pEdit;
166   const bool m_bEnd;  // indicate whether this is the end of replace action
167 };
168 
169 class CFXEU_Backspace final : public IFX_Edit_UndoItem {
170  public:
171   CFXEU_Backspace(CPWL_EditImpl* pEdit,
172                   const CPVT_WordPlace& wpOldPlace,
173                   const CPVT_WordPlace& wpNewPlace,
174                   uint16_t word,
175                   int32_t charset);
176   ~CFXEU_Backspace() override;
177 
178   // IFX_Edit_UndoItem:
179   int Redo() override;
180   int Undo() override;
181 
182  private:
183   UnownedPtr<CPWL_EditImpl> m_pEdit;
184 
185   CPVT_WordPlace m_wpOld;
186   CPVT_WordPlace m_wpNew;
187   uint16_t m_Word;
188   int32_t m_nCharset;
189 };
190 
191 class CFXEU_Delete final : public IFX_Edit_UndoItem {
192  public:
193   CFXEU_Delete(CPWL_EditImpl* pEdit,
194                const CPVT_WordPlace& wpOldPlace,
195                const CPVT_WordPlace& wpNewPlace,
196                uint16_t word,
197                int32_t charset,
198                bool bSecEnd);
199   ~CFXEU_Delete() override;
200 
201   // IFX_Edit_UndoItem:
202   int Redo() override;
203   int Undo() override;
204 
205  private:
206   UnownedPtr<CPWL_EditImpl> m_pEdit;
207 
208   CPVT_WordPlace m_wpOld;
209   CPVT_WordPlace m_wpNew;
210   uint16_t m_Word;
211   int32_t m_nCharset;
212   bool m_bSecEnd;
213 };
214 
215 class CFXEU_Clear final : public IFX_Edit_UndoItem {
216  public:
217   CFXEU_Clear(CPWL_EditImpl* pEdit,
218               const CPVT_WordRange& wrSel,
219               const WideString& swText);
220   ~CFXEU_Clear() override;
221 
222   // IFX_Edit_UndoItem:
223   int Redo() override;
224   int Undo() override;
225 
226  private:
227   UnownedPtr<CPWL_EditImpl> m_pEdit;
228 
229   CPVT_WordRange m_wrSel;
230   WideString m_swText;
231 };
232 
233 class CFXEU_InsertText final : public IFX_Edit_UndoItem {
234  public:
235   CFXEU_InsertText(CPWL_EditImpl* pEdit,
236                    const CPVT_WordPlace& wpOldPlace,
237                    const CPVT_WordPlace& wpNewPlace,
238                    const WideString& swText,
239                    int32_t charset);
240   ~CFXEU_InsertText() override;
241 
242   // IFX_Edit_UndoItem:
243   int Redo() override;
244   int Undo() override;
245 
246  private:
247   UnownedPtr<CPWL_EditImpl> m_pEdit;
248 
249   CPVT_WordPlace m_wpOld;
250   CPVT_WordPlace m_wpNew;
251   WideString m_swText;
252   int32_t m_nCharset;
253 };
254 
255 class CPWL_EditImpl {
256  public:
257   static void DrawEdit(CFX_RenderDevice* pDevice,
258                        const CFX_Matrix& mtUser2Device,
259                        CPWL_EditImpl* pEdit,
260                        FX_COLORREF crTextFill,
261                        const CFX_FloatRect& rcClip,
262                        const CFX_PointF& ptOffset,
263                        const CPVT_WordRange* pRange,
264                        IPWL_SystemHandler* pSystemHandler,
265                        CFFL_FormFiller* pFFLData);
266 
267   CPWL_EditImpl();
268   ~CPWL_EditImpl();
269 
270   void SetFontMap(IPVT_FontMap* pFontMap);
271   void SetNotify(CPWL_EditCtrl* pNotify);
272   void SetOperationNotify(CPWL_Edit* pOperationNotify);
273 
274   // Returns an iterator for the contents. Should not be released.
275   CPWL_EditImpl_Iterator* GetIterator();
276   IPVT_FontMap* GetFontMap();
277   void Initialize();
278 
279   // Set the bounding box of the text area.
280   void SetPlateRect(const CFX_FloatRect& rect);
281   void SetScrollPos(const CFX_PointF& point);
282 
283   // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right])
284   void SetAlignmentH(int32_t nFormat, bool bPaint);
285   // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right])
286   void SetAlignmentV(int32_t nFormat, bool bPaint);
287 
288   // Set the substitution character for hidden text.
289   void SetPasswordChar(uint16_t wSubWord, bool bPaint);
290 
291   // Set the maximum number of words in the text.
292   void SetLimitChar(int32_t nLimitChar);
293   void SetCharArray(int32_t nCharArray);
294   void SetCharSpace(float fCharSpace);
295   void SetMultiLine(bool bMultiLine, bool bPaint);
296   void SetAutoReturn(bool bAuto, bool bPaint);
297   void SetAutoFontSize(bool bAuto, bool bPaint);
298   void SetAutoScroll(bool bAuto, bool bPaint);
299   void SetFontSize(float fFontSize);
300   void SetTextOverflow(bool bAllowed, bool bPaint);
301   void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl);
302   void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl);
303   void OnVK_UP(bool bShift, bool bCtrl);
304   void OnVK_DOWN(bool bShift, bool bCtrl);
305   void OnVK_LEFT(bool bShift, bool bCtrl);
306   void OnVK_RIGHT(bool bShift, bool bCtrl);
307   void OnVK_HOME(bool bShift, bool bCtrl);
308   void OnVK_END(bool bShift, bool bCtrl);
309   void SetText(const WideString& sText);
310   bool InsertWord(uint16_t word, int32_t charset);
311   bool InsertReturn();
312   bool Backspace();
313   bool Delete();
314   bool ClearSelection();
315   bool InsertText(const WideString& sText, int32_t charset);
316   void ReplaceSelection(const WideString& text);
317   bool Redo();
318   bool Undo();
319   CPVT_WordPlace WordIndexToWordPlace(int32_t index) const;
320   CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const;
321   int32_t GetCaret() const;
322   CPVT_WordPlace GetCaretWordPlace() const;
323   WideString GetSelectedText() const;
324   WideString GetText() const;
325   float GetFontSize() const;
326   uint16_t GetPasswordChar() const;
327   CFX_PointF GetScrollPos() const;
328   int32_t GetCharArray() const;
329   CFX_FloatRect GetContentRect() const;
330   WideString GetRangeText(const CPVT_WordRange& range) const;
331   float GetCharSpace() const;
332   void SetSelection(int32_t nStartChar, int32_t nEndChar);
333   void GetSelection(int32_t& nStartChar, int32_t& nEndChar) const;
334   void SelectAll();
335   void SelectNone();
336   bool IsSelected() const;
337   void Paint();
338   void EnableRefresh(bool bRefresh);
339   void RefreshWordRange(const CPVT_WordRange& wr);
340   CPVT_WordRange GetWholeWordRange() const;
341   CPVT_WordRange GetSelectWordRange() const;
342   void EnableUndo(bool bUndo);
343   bool IsTextFull() const;
344   bool IsTextOverflow() const;
345   bool CanUndo() const;
346   bool CanRedo() const;
347   CPVT_WordRange GetVisibleWordRange() const;
348 
349   bool Clear();
350 
351   CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place,
352                               const WideString& sText,
353                               int32_t charset);
354   int32_t GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset);
355 
356   int32_t GetTotalLines() const;
357 
358   ByteString GetPDFWordString(int32_t nFontIndex,
359                               uint16_t Word,
360                               uint16_t SubWord);
361 
362   void SetSelection(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
363 
364   bool Delete(bool bAddUndo, bool bPaint);
365   bool Clear(bool bAddUndo, bool bPaint);
366   bool InsertText(const WideString& sText,
367                   int32_t charset,
368                   bool bAddUndo,
369                   bool bPaint);
370   bool InsertWord(uint16_t word, int32_t charset, bool bAddUndo, bool bPaint);
371   bool InsertReturn(bool bAddUndo, bool bPaint);
372   bool Backspace(bool bAddUndo, bool bPaint);
373   void SetCaret(const CPVT_WordPlace& place);
374 
375   CFX_PointF VTToEdit(const CFX_PointF& point) const;
376 
377  private:
378   void RearrangeAll();
379   void RearrangePart(const CPVT_WordRange& range);
380   void ScrollToCaret();
381   void SetScrollInfo();
382   void SetScrollPosX(float fx);
383   void SetScrollPosY(float fy);
384   void SetScrollLimit();
385   void SetContentChanged();
386 
387   void PaintInsertText(const CPVT_WordPlace& wpOld,
388                        const CPVT_WordPlace& wpNew);
389 
390   CFX_PointF EditToVT(const CFX_PointF& point) const;
391   CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const;
392 
393   void Refresh();
394   void RefreshPushLineRects(const CPVT_WordRange& wr);
395 
396   void SetCaretInfo();
397   void SetCaretOrigin();
398 
399   void AddEditUndoItem(std::unique_ptr<IFX_Edit_UndoItem> pEditUndoItem);
400 
401   std::unique_ptr<CPWL_EditImpl_Provider> m_pVTProvider;
402   std::unique_ptr<CPDF_VariableText> m_pVT;  // Must outlive |m_pVTProvider|.
403   UnownedPtr<CPWL_EditCtrl> m_pNotify;
404   UnownedPtr<CPWL_Edit> m_pOperationNotify;
405   CPVT_WordPlace m_wpCaret;
406   CPVT_WordPlace m_wpOldCaret;
407   CPWL_EditImpl_Select m_SelState;
408   CFX_PointF m_ptScrollPos;
409   CFX_PointF m_ptRefreshScrollPos;
410   bool m_bEnableScroll;
411   std::unique_ptr<CPWL_EditImpl_Iterator> m_pIterator;
412   CPWL_EditImpl_Refresh m_Refresh;
413   CFX_PointF m_ptCaret;
414   CPWL_EditImpl_Undo m_Undo;
415   int32_t m_nAlignment;
416   bool m_bNotifyFlag;
417   bool m_bEnableOverflow;
418   bool m_bEnableRefresh;
419   CFX_FloatRect m_rcOldContent;
420   bool m_bEnableUndo;
421 };
422 
423 class CPWL_EditImpl_Iterator {
424  public:
425   CPWL_EditImpl_Iterator(CPWL_EditImpl* pEdit,
426                          CPDF_VariableText::Iterator* pVTIterator);
427   ~CPWL_EditImpl_Iterator();
428 
429   bool NextWord();
430   bool PrevWord();
431   bool GetWord(CPVT_Word& word) const;
432   bool GetLine(CPVT_Line& line) const;
433   void SetAt(int32_t nWordIndex);
434   void SetAt(const CPVT_WordPlace& place);
435   const CPVT_WordPlace& GetAt() const;
436 
437  private:
438   UnownedPtr<CPWL_EditImpl> m_pEdit;
439   CPDF_VariableText::Iterator* m_pVTIterator;
440 };
441 
442 class CPWL_EditImpl_Provider final : public CPDF_VariableText::Provider {
443  public:
444   explicit CPWL_EditImpl_Provider(IPVT_FontMap* pFontMap);
445   ~CPWL_EditImpl_Provider() override;
446 
447   IPVT_FontMap* GetFontMap() const;
448 
449   // CPDF_VariableText::Provider:
450   uint32_t GetCharWidth(int32_t nFontIndex, uint16_t word) override;
451   int32_t GetTypeAscent(int32_t nFontIndex) override;
452   int32_t GetTypeDescent(int32_t nFontIndex) override;
453   int32_t GetWordFontIndex(uint16_t word,
454                            int32_t charset,
455                            int32_t nFontIndex) override;
456   int32_t GetDefaultFontIndex() override;
457   bool IsLatinWord(uint16_t word) override;
458 
459  private:
460   IPVT_FontMap* m_pFontMap;
461 };
462 
463 #endif  // FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
464