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 190 // |undo_remaining_|. The default value of |undo_remaining_| in 191 // UndoReplaceSelection is 3. because 3 more undo items need to be processed 192 // to revert the replace action: insert text, clear selection and the 193 // UndoReplaceSelection which marks the beginning of replace action. If 194 // CPWL_EditImpl::ClearSelection() returns false, the value of 195 // |undo_remaining_| in UndoReplaceSelection needs to be set to 2) 196 // Implementations should return 0 by default. 197 virtual int Undo() = 0; 198 virtual int Redo() = 0; set_undo_remaining(int undo_remaining)199 void set_undo_remaining(int undo_remaining) { 200 undo_remaining_ = undo_remaining; 201 } undo_remaining()202 int undo_remaining() const { return undo_remaining_; } 203 204 private: 205 int undo_remaining_ = 0; 206 }; 207 208 class UndoStack { 209 public: 210 UndoStack(); 211 ~UndoStack(); 212 213 void AddItem(std::unique_ptr<UndoItemIface> pItem); 214 void Undo(); 215 void Redo(); 216 bool CanUndo() const; 217 bool CanRedo() const; 218 // GetLastAddItem() will never return null, so it can only be called after 219 // calling AddItem(). 220 UndoItemIface* GetLastAddItem(); 221 222 private: 223 void RemoveHeads(); 224 void RemoveTails(); 225 226 std::deque<std::unique_ptr<UndoItemIface>> m_UndoItemStack; 227 size_t m_nCurUndoPos = 0; 228 bool m_bWorking = false; 229 }; 230 231 class Provider; 232 class UndoBackspace; 233 class UndoClear; 234 class UndoDelete; 235 class UndoInsertReturn; 236 class UndoInsertText; 237 class UndoInsertWord; 238 class UndoReplaceSelection; 239 240 bool IsTextOverflow() const; 241 bool Clear(); 242 CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place, 243 const WideString& sText, 244 FX_Charset charset); 245 FX_Charset GetCharSetFromUnicode(uint16_t word, FX_Charset nOldCharset); 246 int32_t GetTotalLines() const; 247 void SetSelection(const CPVT_WordPlace& begin, const CPVT_WordPlace& end); 248 bool Delete(bool bAddUndo); 249 bool Clear(bool bAddUndo); 250 bool InsertText(const WideString& sText, FX_Charset charset, bool bAddUndo); 251 bool InsertWord(uint16_t word, FX_Charset charset, bool bAddUndo); 252 bool InsertReturn(bool bAddUndo); 253 bool Backspace(bool bAddUndo); 254 void SetCaret(const CPVT_WordPlace& place); 255 256 CFX_PointF VTToEdit(const CFX_PointF& point) const; 257 258 void RearrangeAll(); 259 void RearrangePart(const CPVT_WordRange& range); 260 void ScrollToCaret(); 261 void SetScrollInfo(); 262 void SetScrollPosX(float fx); 263 void SetScrollPosY(float fy); 264 void SetScrollLimit(); 265 void SetContentChanged(); 266 267 void PaintInsertText(const CPVT_WordPlace& wpOld, 268 const CPVT_WordPlace& wpNew); 269 270 CFX_PointF EditToVT(const CFX_PointF& point) const; 271 CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const; 272 273 void Refresh(); 274 void RefreshPushLineRects(const CPVT_WordRange& wr); 275 276 void SetCaretInfo(); 277 void SetCaretOrigin(); 278 279 void AddEditUndoItem(std::unique_ptr<UndoItemIface> pEditUndoItem); 280 281 bool m_bEnableScroll = false; 282 bool m_bNotifyFlag = false; 283 bool m_bEnableOverflow = false; 284 bool m_bEnableRefresh = true; 285 bool m_bEnableUndo = true; 286 int32_t m_nAlignment = 0; 287 std::unique_ptr<Provider> m_pVTProvider; 288 std::unique_ptr<CPVT_VariableText> m_pVT; // Must outlive |m_pVTProvider|. 289 UnownedPtr<CPWL_Edit> m_pNotify; 290 CPVT_WordPlace m_wpCaret; 291 CPVT_WordPlace m_wpOldCaret; 292 SelectState m_SelState; 293 CFX_PointF m_ptScrollPos; 294 CFX_PointF m_ptRefreshScrollPos; 295 std::unique_ptr<Iterator> m_pIterator; 296 RefreshState m_Refresh; 297 CFX_PointF m_ptCaret; 298 UndoStack m_Undo; 299 CFX_FloatRect m_rcOldContent; 300 }; 301 302 #endif // FPDFSDK_PWL_CPWL_EDIT_IMPL_H_ 303