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 { 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: ~IFX_Edit_UndoItem()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