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