| // Copyright 2014 PDFium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| |
| #ifndef FPDFSDK_PWL_CPWL_EDIT_IMPL_H_ |
| #define FPDFSDK_PWL_CPWL_EDIT_IMPL_H_ |
| |
| #include <deque> |
| #include <memory> |
| #include <utility> |
| #include <vector> |
| |
| #include "core/fpdfdoc/cpdf_variabletext.h" |
| #include "core/fpdfdoc/cpvt_wordrange.h" |
| #include "core/fxcrt/unowned_ptr.h" |
| #include "core/fxge/dib/fx_dib.h" |
| |
| #define FX_EDIT_ISLATINWORD(u) \ |
| (u == 0x2D || (u <= 0x005A && u >= 0x0041) || \ |
| (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0)) |
| |
| class CFFL_FormFiller; |
| class CPWL_EditImpl; |
| class CPWL_EditImpl_Iterator; |
| class CPWL_EditImpl_Provider; |
| class CFX_RenderDevice; |
| class CPWL_Edit; |
| class CPWL_EditCtrl; |
| class IPWL_SystemHandler; |
| class IFX_Edit_UndoItem; |
| |
| struct CPWL_EditImpl_LineRect { |
| CPWL_EditImpl_LineRect(const CPVT_WordRange& wrLine, |
| const CFX_FloatRect& rcLine) |
| : m_wrLine(wrLine), m_rcLine(rcLine) {} |
| |
| CPVT_WordRange m_wrLine; |
| CFX_FloatRect m_rcLine; |
| }; |
| |
| class CPWL_EditImpl_Refresh { |
| public: |
| CPWL_EditImpl_Refresh(); |
| ~CPWL_EditImpl_Refresh(); |
| |
| void BeginRefresh(); |
| void Push(const CPVT_WordRange& linerange, const CFX_FloatRect& rect); |
| void NoAnalyse(); |
| std::vector<CFX_FloatRect>* GetRefreshRects(); |
| void EndRefresh(); |
| |
| private: |
| void Add(const CFX_FloatRect& new_rect); |
| |
| std::vector<CPWL_EditImpl_LineRect> m_NewLineRects; |
| std::vector<CPWL_EditImpl_LineRect> m_OldLineRects; |
| std::vector<CFX_FloatRect> m_RefreshRects; |
| }; |
| |
| class CPWL_EditImpl_Select { |
| public: |
| CPWL_EditImpl_Select(); |
| explicit CPWL_EditImpl_Select(const CPVT_WordRange& range); |
| |
| void Reset(); |
| void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end); |
| void SetEndPos(const CPVT_WordPlace& end); |
| |
| CPVT_WordRange ConvertToWordRange() const; |
| bool IsEmpty() const; |
| |
| CPVT_WordPlace BeginPos; |
| CPVT_WordPlace EndPos; |
| }; |
| |
| class CPWL_EditImpl_Undo { |
| public: |
| CPWL_EditImpl_Undo(); |
| ~CPWL_EditImpl_Undo(); |
| |
| void AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem); |
| void Undo(); |
| void Redo(); |
| bool CanUndo() const; |
| bool CanRedo() const; |
| |
| private: |
| void RemoveHeads(); |
| void RemoveTails(); |
| |
| std::deque<std::unique_ptr<IFX_Edit_UndoItem>> m_UndoItemStack; |
| size_t m_nCurUndoPos; |
| bool m_bWorking; |
| }; |
| |
| class IFX_Edit_UndoItem { |
| public: |
| virtual ~IFX_Edit_UndoItem() = default; |
| |
| // Undo/Redo the current undo item and returns the number of additional items |
| // to be processed in |m_UndoItemStack| to fully undo/redo the action. (An |
| // example is CFXEU_ReplaceSelection::Undo(), if CFXEU_ReplaceSelection marks |
| // the end of a replace action, CFXEU_ReplaceSelection::Undo() returns 3 |
| // because 3 more undo items need to be processed to revert the replace |
| // action: insert text, clear selection and the CFXEU_ReplaceSelection which |
| // marks the beginning of replace action.) Implementations should return 0 by |
| // default. |
| virtual int Undo() = 0; |
| virtual int Redo() = 0; |
| }; |
| |
| class CFXEU_InsertWord final : public IFX_Edit_UndoItem { |
| public: |
| CFXEU_InsertWord(CPWL_EditImpl* pEdit, |
| const CPVT_WordPlace& wpOldPlace, |
| const CPVT_WordPlace& wpNewPlace, |
| uint16_t word, |
| int32_t charset); |
| ~CFXEU_InsertWord() override; |
| |
| // IFX_Edit_UndoItem: |
| int Redo() override; |
| int Undo() override; |
| |
| private: |
| UnownedPtr<CPWL_EditImpl> m_pEdit; |
| |
| CPVT_WordPlace m_wpOld; |
| CPVT_WordPlace m_wpNew; |
| uint16_t m_Word; |
| int32_t m_nCharset; |
| }; |
| |
| class CFXEU_InsertReturn final : public IFX_Edit_UndoItem { |
| public: |
| CFXEU_InsertReturn(CPWL_EditImpl* pEdit, |
| const CPVT_WordPlace& wpOldPlace, |
| const CPVT_WordPlace& wpNewPlace); |
| ~CFXEU_InsertReturn() override; |
| |
| // IFX_Edit_UndoItem: |
| int Redo() override; |
| int Undo() override; |
| |
| private: |
| UnownedPtr<CPWL_EditImpl> m_pEdit; |
| |
| CPVT_WordPlace m_wpOld; |
| CPVT_WordPlace m_wpNew; |
| }; |
| |
| class CFXEU_ReplaceSelection final : public IFX_Edit_UndoItem { |
| public: |
| CFXEU_ReplaceSelection(CPWL_EditImpl* pEdit, bool bIsEnd); |
| ~CFXEU_ReplaceSelection() override; |
| |
| // IFX_Edit_UndoItem: |
| int Redo() override; |
| int Undo() override; |
| |
| private: |
| bool IsEnd() const { return m_bEnd; } |
| |
| UnownedPtr<CPWL_EditImpl> m_pEdit; |
| const bool m_bEnd; // indicate whether this is the end of replace action |
| }; |
| |
| class CFXEU_Backspace final : public IFX_Edit_UndoItem { |
| public: |
| CFXEU_Backspace(CPWL_EditImpl* pEdit, |
| const CPVT_WordPlace& wpOldPlace, |
| const CPVT_WordPlace& wpNewPlace, |
| uint16_t word, |
| int32_t charset); |
| ~CFXEU_Backspace() override; |
| |
| // IFX_Edit_UndoItem: |
| int Redo() override; |
| int Undo() override; |
| |
| private: |
| UnownedPtr<CPWL_EditImpl> m_pEdit; |
| |
| CPVT_WordPlace m_wpOld; |
| CPVT_WordPlace m_wpNew; |
| uint16_t m_Word; |
| int32_t m_nCharset; |
| }; |
| |
| class CFXEU_Delete final : public IFX_Edit_UndoItem { |
| public: |
| CFXEU_Delete(CPWL_EditImpl* pEdit, |
| const CPVT_WordPlace& wpOldPlace, |
| const CPVT_WordPlace& wpNewPlace, |
| uint16_t word, |
| int32_t charset, |
| bool bSecEnd); |
| ~CFXEU_Delete() override; |
| |
| // IFX_Edit_UndoItem: |
| int Redo() override; |
| int Undo() override; |
| |
| private: |
| UnownedPtr<CPWL_EditImpl> m_pEdit; |
| |
| CPVT_WordPlace m_wpOld; |
| CPVT_WordPlace m_wpNew; |
| uint16_t m_Word; |
| int32_t m_nCharset; |
| bool m_bSecEnd; |
| }; |
| |
| class CFXEU_Clear final : public IFX_Edit_UndoItem { |
| public: |
| CFXEU_Clear(CPWL_EditImpl* pEdit, |
| const CPVT_WordRange& wrSel, |
| const WideString& swText); |
| ~CFXEU_Clear() override; |
| |
| // IFX_Edit_UndoItem: |
| int Redo() override; |
| int Undo() override; |
| |
| private: |
| UnownedPtr<CPWL_EditImpl> m_pEdit; |
| |
| CPVT_WordRange m_wrSel; |
| WideString m_swText; |
| }; |
| |
| class CFXEU_InsertText final : public IFX_Edit_UndoItem { |
| public: |
| CFXEU_InsertText(CPWL_EditImpl* pEdit, |
| const CPVT_WordPlace& wpOldPlace, |
| const CPVT_WordPlace& wpNewPlace, |
| const WideString& swText, |
| int32_t charset); |
| ~CFXEU_InsertText() override; |
| |
| // IFX_Edit_UndoItem: |
| int Redo() override; |
| int Undo() override; |
| |
| private: |
| UnownedPtr<CPWL_EditImpl> m_pEdit; |
| |
| CPVT_WordPlace m_wpOld; |
| CPVT_WordPlace m_wpNew; |
| WideString m_swText; |
| int32_t m_nCharset; |
| }; |
| |
| class CPWL_EditImpl { |
| public: |
| static void DrawEdit(CFX_RenderDevice* pDevice, |
| const CFX_Matrix& mtUser2Device, |
| CPWL_EditImpl* pEdit, |
| FX_COLORREF crTextFill, |
| const CFX_FloatRect& rcClip, |
| const CFX_PointF& ptOffset, |
| const CPVT_WordRange* pRange, |
| IPWL_SystemHandler* pSystemHandler, |
| CFFL_FormFiller* pFFLData); |
| |
| CPWL_EditImpl(); |
| ~CPWL_EditImpl(); |
| |
| void SetFontMap(IPVT_FontMap* pFontMap); |
| void SetNotify(CPWL_EditCtrl* pNotify); |
| void SetOperationNotify(CPWL_Edit* pOperationNotify); |
| |
| // Returns an iterator for the contents. Should not be released. |
| CPWL_EditImpl_Iterator* GetIterator(); |
| IPVT_FontMap* GetFontMap(); |
| void Initialize(); |
| |
| // Set the bounding box of the text area. |
| void SetPlateRect(const CFX_FloatRect& rect); |
| void SetScrollPos(const CFX_PointF& point); |
| |
| // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right]) |
| void SetAlignmentH(int32_t nFormat, bool bPaint); |
| // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right]) |
| void SetAlignmentV(int32_t nFormat, bool bPaint); |
| |
| // Set the substitution character for hidden text. |
| void SetPasswordChar(uint16_t wSubWord, bool bPaint); |
| |
| // Set the maximum number of words in the text. |
| void SetLimitChar(int32_t nLimitChar); |
| void SetCharArray(int32_t nCharArray); |
| void SetCharSpace(float fCharSpace); |
| void SetMultiLine(bool bMultiLine, bool bPaint); |
| void SetAutoReturn(bool bAuto, bool bPaint); |
| void SetAutoFontSize(bool bAuto, bool bPaint); |
| void SetAutoScroll(bool bAuto, bool bPaint); |
| void SetFontSize(float fFontSize); |
| void SetTextOverflow(bool bAllowed, bool bPaint); |
| void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl); |
| void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl); |
| void OnVK_UP(bool bShift, bool bCtrl); |
| void OnVK_DOWN(bool bShift, bool bCtrl); |
| void OnVK_LEFT(bool bShift, bool bCtrl); |
| void OnVK_RIGHT(bool bShift, bool bCtrl); |
| void OnVK_HOME(bool bShift, bool bCtrl); |
| void OnVK_END(bool bShift, bool bCtrl); |
| void SetText(const WideString& sText); |
| bool InsertWord(uint16_t word, int32_t charset); |
| bool InsertReturn(); |
| bool Backspace(); |
| bool Delete(); |
| bool ClearSelection(); |
| bool InsertText(const WideString& sText, int32_t charset); |
| void ReplaceSelection(const WideString& text); |
| bool Redo(); |
| bool Undo(); |
| CPVT_WordPlace WordIndexToWordPlace(int32_t index) const; |
| CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const; |
| int32_t GetCaret() const; |
| CPVT_WordPlace GetCaretWordPlace() const; |
| WideString GetSelectedText() const; |
| WideString GetText() const; |
| float GetFontSize() const; |
| uint16_t GetPasswordChar() const; |
| CFX_PointF GetScrollPos() const; |
| int32_t GetCharArray() const; |
| CFX_FloatRect GetContentRect() const; |
| WideString GetRangeText(const CPVT_WordRange& range) const; |
| float GetCharSpace() const; |
| void SetSelection(int32_t nStartChar, int32_t nEndChar); |
| std::pair<int32_t, int32_t> GetSelection() const; |
| void SelectAll(); |
| void SelectNone(); |
| bool IsSelected() const; |
| void Paint(); |
| void EnableRefresh(bool bRefresh); |
| void RefreshWordRange(const CPVT_WordRange& wr); |
| CPVT_WordRange GetWholeWordRange() const; |
| CPVT_WordRange GetSelectWordRange() const; |
| void EnableUndo(bool bUndo); |
| bool IsTextFull() const; |
| bool IsTextOverflow() const; |
| bool CanUndo() const; |
| bool CanRedo() const; |
| CPVT_WordRange GetVisibleWordRange() const; |
| |
| bool Clear(); |
| |
| CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place, |
| const WideString& sText, |
| int32_t charset); |
| int32_t GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset); |
| |
| int32_t GetTotalLines() const; |
| |
| ByteString GetPDFWordString(int32_t nFontIndex, |
| uint16_t Word, |
| uint16_t SubWord); |
| |
| void SetSelection(const CPVT_WordPlace& begin, const CPVT_WordPlace& end); |
| |
| bool Delete(bool bAddUndo, bool bPaint); |
| bool Clear(bool bAddUndo, bool bPaint); |
| bool InsertText(const WideString& sText, |
| int32_t charset, |
| bool bAddUndo, |
| bool bPaint); |
| bool InsertWord(uint16_t word, int32_t charset, bool bAddUndo, bool bPaint); |
| bool InsertReturn(bool bAddUndo, bool bPaint); |
| bool Backspace(bool bAddUndo, bool bPaint); |
| void SetCaret(const CPVT_WordPlace& place); |
| |
| CFX_PointF VTToEdit(const CFX_PointF& point) const; |
| |
| private: |
| void RearrangeAll(); |
| void RearrangePart(const CPVT_WordRange& range); |
| void ScrollToCaret(); |
| void SetScrollInfo(); |
| void SetScrollPosX(float fx); |
| void SetScrollPosY(float fy); |
| void SetScrollLimit(); |
| void SetContentChanged(); |
| |
| void PaintInsertText(const CPVT_WordPlace& wpOld, |
| const CPVT_WordPlace& wpNew); |
| |
| CFX_PointF EditToVT(const CFX_PointF& point) const; |
| CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const; |
| |
| void Refresh(); |
| void RefreshPushLineRects(const CPVT_WordRange& wr); |
| |
| void SetCaretInfo(); |
| void SetCaretOrigin(); |
| |
| void AddEditUndoItem(std::unique_ptr<IFX_Edit_UndoItem> pEditUndoItem); |
| |
| std::unique_ptr<CPWL_EditImpl_Provider> m_pVTProvider; |
| std::unique_ptr<CPDF_VariableText> m_pVT; // Must outlive |m_pVTProvider|. |
| UnownedPtr<CPWL_EditCtrl> m_pNotify; |
| UnownedPtr<CPWL_Edit> m_pOperationNotify; |
| CPVT_WordPlace m_wpCaret; |
| CPVT_WordPlace m_wpOldCaret; |
| CPWL_EditImpl_Select m_SelState; |
| CFX_PointF m_ptScrollPos; |
| CFX_PointF m_ptRefreshScrollPos; |
| bool m_bEnableScroll; |
| std::unique_ptr<CPWL_EditImpl_Iterator> m_pIterator; |
| CPWL_EditImpl_Refresh m_Refresh; |
| CFX_PointF m_ptCaret; |
| CPWL_EditImpl_Undo m_Undo; |
| int32_t m_nAlignment; |
| bool m_bNotifyFlag; |
| bool m_bEnableOverflow; |
| bool m_bEnableRefresh; |
| CFX_FloatRect m_rcOldContent; |
| bool m_bEnableUndo; |
| }; |
| |
| class CPWL_EditImpl_Iterator { |
| public: |
| CPWL_EditImpl_Iterator(CPWL_EditImpl* pEdit, |
| CPDF_VariableText::Iterator* pVTIterator); |
| ~CPWL_EditImpl_Iterator(); |
| |
| bool NextWord(); |
| bool PrevWord(); |
| bool GetWord(CPVT_Word& word) const; |
| bool GetLine(CPVT_Line& line) const; |
| void SetAt(int32_t nWordIndex); |
| void SetAt(const CPVT_WordPlace& place); |
| const CPVT_WordPlace& GetAt() const; |
| |
| private: |
| UnownedPtr<CPWL_EditImpl> m_pEdit; |
| CPDF_VariableText::Iterator* m_pVTIterator; |
| }; |
| |
| class CPWL_EditImpl_Provider final : public CPDF_VariableText::Provider { |
| public: |
| explicit CPWL_EditImpl_Provider(IPVT_FontMap* pFontMap); |
| ~CPWL_EditImpl_Provider() override; |
| |
| IPVT_FontMap* GetFontMap() const; |
| |
| // CPDF_VariableText::Provider: |
| int GetCharWidth(int32_t nFontIndex, uint16_t word) override; |
| int32_t GetTypeAscent(int32_t nFontIndex) override; |
| int32_t GetTypeDescent(int32_t nFontIndex) override; |
| int32_t GetWordFontIndex(uint16_t word, |
| int32_t charset, |
| int32_t nFontIndex) override; |
| int32_t GetDefaultFontIndex() override; |
| bool IsLatinWord(uint16_t word) override; |
| |
| private: |
| IPVT_FontMap* m_pFontMap; |
| }; |
| |
| #endif // FPDFSDK_PWL_CPWL_EDIT_IMPL_H_ |