Home | History | Annotate | Download | only in pwl
      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 CFX_SystemHandler;
     29 class CPWL_Edit;
     30 class CPWL_EditCtrl;
     31 class IFX_Edit_UndoItem;
     32 
     33 struct CPWL_EditImpl_LineRect {
     34   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() {}
    100 
    101   virtual void Undo() = 0;
    102   virtual void Redo() = 0;
    103 };
    104 
    105 class CFXEU_InsertWord : public IFX_Edit_UndoItem {
    106  public:
    107   CFXEU_InsertWord(CPWL_EditImpl* pEdit,
    108                    const CPVT_WordPlace& wpOldPlace,
    109                    const CPVT_WordPlace& wpNewPlace,
    110                    uint16_t word,
    111                    int32_t charset);
    112   ~CFXEU_InsertWord() override;
    113 
    114   // IFX_Edit_UndoItem:
    115   void Redo() override;
    116   void Undo() override;
    117 
    118  private:
    119   UnownedPtr<CPWL_EditImpl> m_pEdit;
    120 
    121   CPVT_WordPlace m_wpOld;
    122   CPVT_WordPlace m_wpNew;
    123   uint16_t m_Word;
    124   int32_t m_nCharset;
    125 };
    126 
    127 class CFXEU_InsertReturn : public IFX_Edit_UndoItem {
    128  public:
    129   CFXEU_InsertReturn(CPWL_EditImpl* pEdit,
    130                      const CPVT_WordPlace& wpOldPlace,
    131                      const CPVT_WordPlace& wpNewPlace);
    132   ~CFXEU_InsertReturn() override;
    133 
    134   // IFX_Edit_UndoItem:
    135   void Redo() override;
    136   void Undo() override;
    137 
    138  private:
    139   UnownedPtr<CPWL_EditImpl> m_pEdit;
    140 
    141   CPVT_WordPlace m_wpOld;
    142   CPVT_WordPlace m_wpNew;
    143 };
    144 
    145 class CFXEU_Backspace : public IFX_Edit_UndoItem {
    146  public:
    147   CFXEU_Backspace(CPWL_EditImpl* pEdit,
    148                   const CPVT_WordPlace& wpOldPlace,
    149                   const CPVT_WordPlace& wpNewPlace,
    150                   uint16_t word,
    151                   int32_t charset);
    152   ~CFXEU_Backspace() override;
    153 
    154   // IFX_Edit_UndoItem:
    155   void Redo() override;
    156   void Undo() override;
    157 
    158  private:
    159   UnownedPtr<CPWL_EditImpl> m_pEdit;
    160 
    161   CPVT_WordPlace m_wpOld;
    162   CPVT_WordPlace m_wpNew;
    163   uint16_t m_Word;
    164   int32_t m_nCharset;
    165 };
    166 
    167 class CFXEU_Delete : public IFX_Edit_UndoItem {
    168  public:
    169   CFXEU_Delete(CPWL_EditImpl* pEdit,
    170                const CPVT_WordPlace& wpOldPlace,
    171                const CPVT_WordPlace& wpNewPlace,
    172                uint16_t word,
    173                int32_t charset,
    174                bool bSecEnd);
    175   ~CFXEU_Delete() override;
    176 
    177   // IFX_Edit_UndoItem:
    178   void Redo() override;
    179   void Undo() override;
    180 
    181  private:
    182   UnownedPtr<CPWL_EditImpl> m_pEdit;
    183 
    184   CPVT_WordPlace m_wpOld;
    185   CPVT_WordPlace m_wpNew;
    186   uint16_t m_Word;
    187   int32_t m_nCharset;
    188   bool m_bSecEnd;
    189 };
    190 
    191 class CFXEU_Clear : public IFX_Edit_UndoItem {
    192  public:
    193   CFXEU_Clear(CPWL_EditImpl* pEdit,
    194               const CPVT_WordRange& wrSel,
    195               const WideString& swText);
    196   ~CFXEU_Clear() override;
    197 
    198   // IFX_Edit_UndoItem:
    199   void Redo() override;
    200   void Undo() override;
    201 
    202  private:
    203   UnownedPtr<CPWL_EditImpl> m_pEdit;
    204 
    205   CPVT_WordRange m_wrSel;
    206   WideString m_swText;
    207 };
    208 
    209 class CFXEU_InsertText : public IFX_Edit_UndoItem {
    210  public:
    211   CFXEU_InsertText(CPWL_EditImpl* pEdit,
    212                    const CPVT_WordPlace& wpOldPlace,
    213                    const CPVT_WordPlace& wpNewPlace,
    214                    const WideString& swText,
    215                    int32_t charset);
    216   ~CFXEU_InsertText() override;
    217 
    218   // IFX_Edit_UndoItem:
    219   void Redo() override;
    220   void Undo() override;
    221 
    222  private:
    223   UnownedPtr<CPWL_EditImpl> m_pEdit;
    224 
    225   CPVT_WordPlace m_wpOld;
    226   CPVT_WordPlace m_wpNew;
    227   WideString m_swText;
    228   int32_t m_nCharset;
    229 };
    230 
    231 class CPWL_EditImpl {
    232  public:
    233   static void DrawEdit(CFX_RenderDevice* pDevice,
    234                        const CFX_Matrix& mtUser2Device,
    235                        CPWL_EditImpl* pEdit,
    236                        FX_COLORREF crTextFill,
    237                        const CFX_FloatRect& rcClip,
    238                        const CFX_PointF& ptOffset,
    239                        const CPVT_WordRange* pRange,
    240                        CFX_SystemHandler* pSystemHandler,
    241                        CFFL_FormFiller* pFFLData);
    242 
    243   CPWL_EditImpl();
    244   ~CPWL_EditImpl();
    245 
    246   void SetFontMap(IPVT_FontMap* pFontMap);
    247   void SetNotify(CPWL_EditCtrl* pNotify);
    248   void SetOperationNotify(CPWL_Edit* pOperationNotify);
    249 
    250   // Returns an iterator for the contents. Should not be released.
    251   CPWL_EditImpl_Iterator* GetIterator();
    252   IPVT_FontMap* GetFontMap();
    253   void Initialize();
    254 
    255   // Set the bounding box of the text area.
    256   void SetPlateRect(const CFX_FloatRect& rect);
    257   void SetScrollPos(const CFX_PointF& point);
    258 
    259   // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right])
    260   void SetAlignmentH(int32_t nFormat, bool bPaint);
    261   // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right])
    262   void SetAlignmentV(int32_t nFormat, bool bPaint);
    263 
    264   // Set the substitution character for hidden text.
    265   void SetPasswordChar(uint16_t wSubWord, bool bPaint);
    266 
    267   // Set the maximum number of words in the text.
    268   void SetLimitChar(int32_t nLimitChar);
    269   void SetCharArray(int32_t nCharArray);
    270   void SetCharSpace(float fCharSpace);
    271   void SetMultiLine(bool bMultiLine, bool bPaint);
    272   void SetAutoReturn(bool bAuto, bool bPaint);
    273   void SetAutoFontSize(bool bAuto, bool bPaint);
    274   void SetAutoScroll(bool bAuto, bool bPaint);
    275   void SetFontSize(float fFontSize);
    276   void SetTextOverflow(bool bAllowed, bool bPaint);
    277   void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl);
    278   void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl);
    279   void OnVK_UP(bool bShift, bool bCtrl);
    280   void OnVK_DOWN(bool bShift, bool bCtrl);
    281   void OnVK_LEFT(bool bShift, bool bCtrl);
    282   void OnVK_RIGHT(bool bShift, bool bCtrl);
    283   void OnVK_HOME(bool bShift, bool bCtrl);
    284   void OnVK_END(bool bShift, bool bCtrl);
    285   void SetText(const WideString& sText);
    286   bool InsertWord(uint16_t word, int32_t charset);
    287   bool InsertReturn();
    288   bool Backspace();
    289   bool Delete();
    290   bool ClearSelection();
    291   bool InsertText(const WideString& sText, int32_t charset);
    292   bool Redo();
    293   bool Undo();
    294   CPVT_WordPlace WordIndexToWordPlace(int32_t index) const;
    295   CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const;
    296   int32_t GetCaret() const;
    297   CPVT_WordPlace GetCaretWordPlace() const;
    298   WideString GetSelectedText() const;
    299   WideString GetText() const;
    300   float GetFontSize() const;
    301   uint16_t GetPasswordChar() const;
    302   CFX_PointF GetScrollPos() const;
    303   int32_t GetCharArray() const;
    304   CFX_FloatRect GetContentRect() const;
    305   WideString GetRangeText(const CPVT_WordRange& range) const;
    306   int32_t GetHorzScale() const;
    307   float GetCharSpace() const;
    308   void SetSelection(int32_t nStartChar, int32_t nEndChar);
    309   void GetSelection(int32_t& nStartChar, int32_t& nEndChar) const;
    310   void SelectAll();
    311   void SelectNone();
    312   bool IsSelected() const;
    313   void Paint();
    314   void EnableRefresh(bool bRefresh);
    315   void RefreshWordRange(const CPVT_WordRange& wr);
    316   CPVT_WordRange GetWholeWordRange() const;
    317   CPVT_WordRange GetSelectWordRange() const;
    318   void EnableUndo(bool bUndo);
    319   bool IsTextFull() const;
    320   bool IsTextOverflow() const;
    321   bool CanUndo() const;
    322   bool CanRedo() const;
    323   CPVT_WordRange GetVisibleWordRange() const;
    324 
    325   bool Empty();
    326 
    327   CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place,
    328                               const WideString& sText,
    329                               int32_t charset);
    330   int32_t GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset);
    331 
    332   int32_t GetTotalLines() const;
    333 
    334   ByteString GetPDFWordString(int32_t nFontIndex,
    335                               uint16_t Word,
    336                               uint16_t SubWord);
    337 
    338   void SetSelection(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
    339 
    340   bool Delete(bool bAddUndo, bool bPaint);
    341   bool Clear(bool bAddUndo, bool bPaint);
    342   bool InsertText(const WideString& sText,
    343                   int32_t charset,
    344                   bool bAddUndo,
    345                   bool bPaint);
    346   bool InsertWord(uint16_t word, int32_t charset, bool bAddUndo, bool bPaint);
    347   bool InsertReturn(bool bAddUndo, bool bPaint);
    348   bool Backspace(bool bAddUndo, bool bPaint);
    349   void SetCaret(const CPVT_WordPlace& place);
    350 
    351   CFX_PointF VTToEdit(const CFX_PointF& point) const;
    352 
    353  private:
    354   void RearrangeAll();
    355   void RearrangePart(const CPVT_WordRange& range);
    356   void ScrollToCaret();
    357   void SetScrollInfo();
    358   void SetScrollPosX(float fx);
    359   void SetScrollPosY(float fy);
    360   void SetScrollLimit();
    361   void SetContentChanged();
    362 
    363   void PaintInsertText(const CPVT_WordPlace& wpOld,
    364                        const CPVT_WordPlace& wpNew);
    365 
    366   CFX_PointF EditToVT(const CFX_PointF& point) const;
    367   CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const;
    368 
    369   void Refresh();
    370   void RefreshPushLineRects(const CPVT_WordRange& wr);
    371 
    372   void SetCaretInfo();
    373   void SetCaretOrigin();
    374 
    375   void AddEditUndoItem(std::unique_ptr<IFX_Edit_UndoItem> pEditUndoItem);
    376 
    377   std::unique_ptr<CPDF_VariableText> m_pVT;
    378   UnownedPtr<CPWL_EditCtrl> m_pNotify;
    379   UnownedPtr<CPWL_Edit> m_pOperationNotify;
    380   std::unique_ptr<CPWL_EditImpl_Provider> m_pVTProvider;
    381   CPVT_WordPlace m_wpCaret;
    382   CPVT_WordPlace m_wpOldCaret;
    383   CPWL_EditImpl_Select m_SelState;
    384   CFX_PointF m_ptScrollPos;
    385   CFX_PointF m_ptRefreshScrollPos;
    386   bool m_bEnableScroll;
    387   std::unique_ptr<CPWL_EditImpl_Iterator> m_pIterator;
    388   CPWL_EditImpl_Refresh m_Refresh;
    389   CFX_PointF m_ptCaret;
    390   CPWL_EditImpl_Undo m_Undo;
    391   int32_t m_nAlignment;
    392   bool m_bNotifyFlag;
    393   bool m_bEnableOverflow;
    394   bool m_bEnableRefresh;
    395   CFX_FloatRect m_rcOldContent;
    396   bool m_bEnableUndo;
    397 };
    398 
    399 class CPWL_EditImpl_Iterator {
    400  public:
    401   CPWL_EditImpl_Iterator(CPWL_EditImpl* pEdit,
    402                          CPDF_VariableText::Iterator* pVTIterator);
    403   ~CPWL_EditImpl_Iterator();
    404 
    405   bool NextWord();
    406   bool PrevWord();
    407   bool GetWord(CPVT_Word& word) const;
    408   bool GetLine(CPVT_Line& line) const;
    409   void SetAt(int32_t nWordIndex);
    410   void SetAt(const CPVT_WordPlace& place);
    411   const CPVT_WordPlace& GetAt() const;
    412 
    413  private:
    414   UnownedPtr<CPWL_EditImpl> m_pEdit;
    415   CPDF_VariableText::Iterator* m_pVTIterator;
    416 };
    417 
    418 class CPWL_EditImpl_Provider : public CPDF_VariableText::Provider {
    419  public:
    420   explicit CPWL_EditImpl_Provider(IPVT_FontMap* pFontMap);
    421   ~CPWL_EditImpl_Provider() override;
    422 
    423   IPVT_FontMap* GetFontMap() const;
    424 
    425   // CPDF_VariableText::Provider:
    426   int32_t GetCharWidth(int32_t nFontIndex, uint16_t word) override;
    427   int32_t GetTypeAscent(int32_t nFontIndex) override;
    428   int32_t GetTypeDescent(int32_t nFontIndex) override;
    429   int32_t GetWordFontIndex(uint16_t word,
    430                            int32_t charset,
    431                            int32_t nFontIndex) override;
    432   int32_t GetDefaultFontIndex() override;
    433   bool IsLatinWord(uint16_t word) override;
    434 
    435  private:
    436   IPVT_FontMap* m_pFontMap;
    437 };
    438 
    439 #endif  // FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
    440