blob: 5b84c9b95e6f3ccd1351c7c1addf7d8eeeb90dbd [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
dsinclair0bb385b2016-09-29 17:03:59 -07007#include "fpdfsdk/fxedit/fxet_edit.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -08008
Lei Zhang375a8642016-01-11 11:59:17 -08009#include <algorithm>
thestigd4c34f22016-09-28 17:04:51 -070010#include <memory>
11#include <utility>
Lei Zhang375a8642016-01-11 11:59:17 -080012
dsinclairbc5e6d22016-10-04 11:08:49 -070013#include "core/fpdfapi/font/cpdf_font.h"
dsinclair41872fa2016-10-04 11:29:35 -070014#include "core/fpdfapi/page/cpdf_pageobject.h"
15#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
16#include "core/fpdfapi/page/cpdf_pathobject.h"
17#include "core/fpdfapi/page/cpdf_textobject.h"
dsinclair488b7ad2016-10-04 11:55:50 -070018#include "core/fpdfapi/parser/fpdf_parser_decode.h"
dsinclair69d9c682016-10-04 12:18:35 -070019#include "core/fpdfapi/render/cpdf_renderoptions.h"
20#include "core/fpdfapi/render/cpdf_textrenderer.h"
dsinclair1727aee2016-09-29 13:12:56 -070021#include "core/fpdfdoc/cpvt_section.h"
22#include "core/fpdfdoc/cpvt_word.h"
23#include "core/fpdfdoc/ipvt_fontmap.h"
Dan Sinclairf51a02a2017-04-19 12:46:53 -040024#include "core/fxcrt/fx_codepage.h"
dsinclair74a34fc2016-09-29 16:41:42 -070025#include "core/fxge/cfx_graphstatedata.h"
26#include "core/fxge/cfx_pathdata.h"
27#include "core/fxge/cfx_renderdevice.h"
dsinclaire35af1e2016-07-13 11:26:20 -070028#include "fpdfsdk/cfx_systemhandler.h"
dsinclair0bb385b2016-09-29 17:03:59 -070029#include "fpdfsdk/fxedit/fx_edit.h"
dsinclaire35af1e2016-07-13 11:26:20 -070030#include "fpdfsdk/pdfwindow/PWL_Edit.h"
31#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
tsepez36eb4bd2016-10-03 15:24:27 -070032#include "third_party/base/ptr_util.h"
Tom Sepez3509d162017-01-30 13:22:02 -080033#include "third_party/base/stl_util.h"
dsinclaire35af1e2016-07-13 11:26:20 -070034
dsinclair8f4bf9a2016-05-04 13:51:51 -070035namespace {
36
37const int kEditUndoMaxItems = 10000;
38
dsinclaire35af1e2016-07-13 11:26:20 -070039CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) {
40 if (strWords.GetLength() > 0)
41 return PDF_EncodeString(strWords) + " Tj\n";
42 return CFX_ByteString();
43}
44
45CFX_ByteString GetFontSetString(IPVT_FontMap* pFontMap,
46 int32_t nFontIndex,
Dan Sinclair05df0752017-03-14 14:43:42 -040047 float fFontSize) {
dsinclaire35af1e2016-07-13 11:26:20 -070048 if (!pFontMap)
49 return CFX_ByteString();
50
51 CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
52 if (sFontAlias.GetLength() <= 0 || fFontSize <= 0)
53 return CFX_ByteString();
54
55 CFX_ByteTextBuf sRet;
56 sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
57 return sRet.MakeString();
58}
59
dsinclaire35af1e2016-07-13 11:26:20 -070060void DrawTextString(CFX_RenderDevice* pDevice,
Dan Sinclairf528eee2017-02-14 11:52:07 -050061 const CFX_PointF& pt,
dsinclaire35af1e2016-07-13 11:26:20 -070062 CPDF_Font* pFont,
Dan Sinclair05df0752017-03-14 14:43:42 -040063 float fFontSize,
dsinclaire35af1e2016-07-13 11:26:20 -070064 CFX_Matrix* pUser2Device,
65 const CFX_ByteString& str,
66 FX_ARGB crTextFill,
dsinclaire35af1e2016-07-13 11:26:20 -070067 int32_t nHorzScale) {
Dan Sinclaira0061af2017-02-23 09:25:17 -050068 CFX_PointF pos = pUser2Device->Transform(pt);
dsinclaire35af1e2016-07-13 11:26:20 -070069
70 if (pFont) {
71 if (nHorzScale != 100) {
72 CFX_Matrix mt(nHorzScale / 100.0f, 0, 0, 1, 0, 0);
73 mt.Concat(*pUser2Device);
74
75 CPDF_RenderOptions ro;
76 ro.m_Flags = RENDER_CLEARTYPE;
77 ro.m_ColorMode = RENDER_COLOR_NORMAL;
78
Dan Sinclaira0061af2017-02-23 09:25:17 -050079 CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize,
80 &mt, str, crTextFill, nullptr, &ro);
dsinclaire35af1e2016-07-13 11:26:20 -070081 } else {
82 CPDF_RenderOptions ro;
83 ro.m_Flags = RENDER_CLEARTYPE;
84 ro.m_ColorMode = RENDER_COLOR_NORMAL;
85
Dan Sinclaira0061af2017-02-23 09:25:17 -050086 CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize,
87 pUser2Device, str, crTextFill, nullptr,
88 &ro);
dsinclaire35af1e2016-07-13 11:26:20 -070089 }
90 }
91}
92
dsinclair8f4bf9a2016-05-04 13:51:51 -070093} // namespace
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070094
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit* pEdit,
dsinclairc7a73492016-04-05 12:01:42 -070096 CPDF_VariableText::Iterator* pVTIterator)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097 : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {}
98
99CFX_Edit_Iterator::~CFX_Edit_Iterator() {}
100
tsepez4cf55152016-11-02 14:37:54 -0700101bool CFX_Edit_Iterator::NextWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700102 return m_pVTIterator->NextWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700103}
104
tsepez4cf55152016-11-02 14:37:54 -0700105bool CFX_Edit_Iterator::PrevWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700106 return m_pVTIterator->PrevWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700107}
108
tsepez4cf55152016-11-02 14:37:54 -0700109bool CFX_Edit_Iterator::GetWord(CPVT_Word& word) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110 ASSERT(m_pEdit);
111
112 if (m_pVTIterator->GetWord(word)) {
113 word.ptWord = m_pEdit->VTToEdit(word.ptWord);
tsepez4cf55152016-11-02 14:37:54 -0700114 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700115 }
tsepez4cf55152016-11-02 14:37:54 -0700116 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700117}
118
tsepez4cf55152016-11-02 14:37:54 -0700119bool CFX_Edit_Iterator::GetLine(CPVT_Line& line) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120 ASSERT(m_pEdit);
121
122 if (m_pVTIterator->GetLine(line)) {
123 line.ptLine = m_pEdit->VTToEdit(line.ptLine);
tsepez4cf55152016-11-02 14:37:54 -0700124 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125 }
tsepez4cf55152016-11-02 14:37:54 -0700126 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700127}
128
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129void CFX_Edit_Iterator::SetAt(int32_t nWordIndex) {
130 m_pVTIterator->SetAt(nWordIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700131}
132
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace& place) {
134 m_pVTIterator->SetAt(place);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700135}
136
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137const CPVT_WordPlace& CFX_Edit_Iterator::GetAt() const {
138 return m_pVTIterator->GetAt();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700139}
140
dsinclairc7a73492016-04-05 12:01:42 -0700141CFX_Edit_Provider::CFX_Edit_Provider(IPVT_FontMap* pFontMap)
142 : CPDF_VariableText::Provider(pFontMap), m_pFontMap(pFontMap) {
Lei Zhang96660d62015-12-14 18:27:25 -0800143 ASSERT(m_pFontMap);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700144}
145
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146CFX_Edit_Provider::~CFX_Edit_Provider() {}
147
dsinclairc7a73492016-04-05 12:01:42 -0700148IPVT_FontMap* CFX_Edit_Provider::GetFontMap() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149 return m_pFontMap;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700150}
151
npm41d6bbe2016-09-14 11:54:44 -0700152int32_t CFX_Edit_Provider::GetCharWidth(int32_t nFontIndex, uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
tsepezc3255f52016-03-25 14:52:27 -0700154 uint32_t charcode = word;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700155
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156 if (pPDFFont->IsUnicodeCompatible())
157 charcode = pPDFFont->CharCodeFromUnicode(word);
158 else
159 charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);
160
Wei Li89409932016-03-28 10:33:33 -0700161 if (charcode != CPDF_Font::kInvalidCharCode)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162 return pPDFFont->GetCharWidthF(charcode);
163 }
164
165 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700166}
167
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168int32_t CFX_Edit_Provider::GetTypeAscent(int32_t nFontIndex) {
169 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
170 return pPDFFont->GetTypeAscent();
171
172 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700173}
174
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175int32_t CFX_Edit_Provider::GetTypeDescent(int32_t nFontIndex) {
176 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
177 return pPDFFont->GetTypeDescent();
178
179 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700180}
181
Tom Sepez62a70f92016-03-21 15:00:20 -0700182int32_t CFX_Edit_Provider::GetWordFontIndex(uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 int32_t charset,
184 int32_t nFontIndex) {
185 return m_pFontMap->GetWordFontIndex(word, charset, nFontIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700186}
187
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188int32_t CFX_Edit_Provider::GetDefaultFontIndex() {
189 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700190}
191
tsepez4cf55152016-11-02 14:37:54 -0700192bool CFX_Edit_Provider::IsLatinWord(uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193 return FX_EDIT_ISLATINWORD(word);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700194}
195
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196CFX_Edit_Refresh::CFX_Edit_Refresh() {}
197
198CFX_Edit_Refresh::~CFX_Edit_Refresh() {}
199
200void CFX_Edit_Refresh::BeginRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800201 m_RefreshRects.Clear();
202 m_OldLineRects = std::move(m_NewLineRects);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700203}
204
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205void CFX_Edit_Refresh::Push(const CPVT_WordRange& linerange,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800206 const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207 m_NewLineRects.Add(linerange, rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700208}
209
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210void CFX_Edit_Refresh::NoAnalyse() {
211 {
212 for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
213 if (CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i))
214 m_RefreshRects.Add(pOldRect->m_rcLine);
215 }
216
217 {
218 for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
219 if (CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i))
220 m_RefreshRects.Add(pNewRect->m_rcLine);
221 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700222}
223
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const {
225 return &m_RefreshRects;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700226}
227
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228void CFX_Edit_Refresh::EndRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800229 m_RefreshRects.Clear();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700230}
231
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize)
233 : m_nCurUndoPos(0),
234 m_nBufSize(nBufsize),
tsepez4cf55152016-11-02 14:37:54 -0700235 m_bWorking(false) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700236
237CFX_Edit_Undo::~CFX_Edit_Undo() {
238 Reset();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700239}
240
tsepez4cf55152016-11-02 14:37:54 -0700241bool CFX_Edit_Undo::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 return m_nCurUndoPos > 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700243}
244
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700245void CFX_Edit_Undo::Undo() {
tsepez4cf55152016-11-02 14:37:54 -0700246 m_bWorking = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 if (m_nCurUndoPos > 0) {
Tom Sepez3509d162017-01-30 13:22:02 -0800248 m_UndoItemStack[m_nCurUndoPos - 1]->Undo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 m_nCurUndoPos--;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 }
tsepez4cf55152016-11-02 14:37:54 -0700251 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700252}
253
tsepez4cf55152016-11-02 14:37:54 -0700254bool CFX_Edit_Undo::CanRedo() const {
Tom Sepez3509d162017-01-30 13:22:02 -0800255 return m_nCurUndoPos < m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256}
257
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258void CFX_Edit_Undo::Redo() {
tsepez4cf55152016-11-02 14:37:54 -0700259 m_bWorking = true;
Tom Sepez3509d162017-01-30 13:22:02 -0800260 if (m_nCurUndoPos < m_UndoItemStack.size()) {
261 m_UndoItemStack[m_nCurUndoPos]->Redo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700262 m_nCurUndoPos++;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 }
tsepez4cf55152016-11-02 14:37:54 -0700264 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700265}
266
Tom Sepez3509d162017-01-30 13:22:02 -0800267void CFX_Edit_Undo::AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 ASSERT(!m_bWorking);
Lei Zhang96660d62015-12-14 18:27:25 -0800269 ASSERT(pItem);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270 ASSERT(m_nBufSize > 1);
Tom Sepez3509d162017-01-30 13:22:02 -0800271 if (m_nCurUndoPos < m_UndoItemStack.size())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272 RemoveTails();
273
Lei Zhang1a89e362017-03-23 15:27:25 -0700274 if (m_UndoItemStack.size() >= m_nBufSize)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275 RemoveHeads();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276
Tom Sepez3509d162017-01-30 13:22:02 -0800277 m_UndoItemStack.push_back(std::move(pItem));
278 m_nCurUndoPos = m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700279}
280
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281void CFX_Edit_Undo::RemoveHeads() {
Tom Sepez3509d162017-01-30 13:22:02 -0800282 ASSERT(m_UndoItemStack.size() > 1);
283 m_UndoItemStack.pop_front();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700284}
285
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286void CFX_Edit_Undo::RemoveTails() {
Tom Sepez3509d162017-01-30 13:22:02 -0800287 while (m_UndoItemStack.size() > m_nCurUndoPos)
288 m_UndoItemStack.pop_back();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700289}
290
291void CFX_Edit_Undo::Reset() {
Tom Sepez3509d162017-01-30 13:22:02 -0800292 m_UndoItemStack.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293 m_nCurUndoPos = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294}
295
tsepez4cf55152016-11-02 14:37:54 -0700296CFX_Edit_UndoItem::CFX_Edit_UndoItem() : m_bFirst(true), m_bLast(true) {}
weili625ad662016-06-15 11:21:33 -0700297
298CFX_Edit_UndoItem::~CFX_Edit_UndoItem() {}
299
Tom Sepez3509d162017-01-30 13:22:02 -0800300CFX_WideString CFX_Edit_UndoItem::GetUndoTitle() const {
301 return CFX_WideString();
weili625ad662016-06-15 11:21:33 -0700302}
303
tsepez4cf55152016-11-02 14:37:54 -0700304void CFX_Edit_UndoItem::SetFirst(bool bFirst) {
weili625ad662016-06-15 11:21:33 -0700305 m_bFirst = bFirst;
306}
307
tsepez4cf55152016-11-02 14:37:54 -0700308void CFX_Edit_UndoItem::SetLast(bool bLast) {
weili625ad662016-06-15 11:21:33 -0700309 m_bLast = bLast;
310}
311
tsepez4cf55152016-11-02 14:37:54 -0700312bool CFX_Edit_UndoItem::IsLast() {
weili625ad662016-06-15 11:21:33 -0700313 return m_bLast;
314}
315
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700316CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit* pEdit,
317 const CPVT_WordPlace& wpOldPlace,
318 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700319 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700320 int32_t charset,
321 const CPVT_WordProps* pWordProps)
322 : m_pEdit(pEdit),
323 m_wpOld(wpOldPlace),
324 m_wpNew(wpNewPlace),
325 m_Word(word),
326 m_nCharset(charset),
327 m_WordProps() {
328 if (pWordProps)
329 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700330}
331
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700332CFXEU_InsertWord::~CFXEU_InsertWord() {}
333
334void CFXEU_InsertWord::Redo() {
335 if (m_pEdit) {
336 m_pEdit->SelectNone();
337 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700338 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700340}
341
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700342void CFXEU_InsertWord::Undo() {
343 if (m_pEdit) {
344 m_pEdit->SelectNone();
345 m_pEdit->SetCaret(m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700346 m_pEdit->Backspace(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700347 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700348}
349
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700350CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit* pEdit,
351 const CPVT_WordPlace& wpOldPlace,
352 const CPVT_WordPlace& wpNewPlace,
353 const CPVT_SecProps* pSecProps,
354 const CPVT_WordProps* pWordProps)
355 : m_pEdit(pEdit),
356 m_wpOld(wpOldPlace),
357 m_wpNew(wpNewPlace),
358 m_SecProps(),
359 m_WordProps() {
360 if (pSecProps)
361 m_SecProps = *pSecProps;
362 if (pWordProps)
363 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700364}
365
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366CFXEU_InsertReturn::~CFXEU_InsertReturn() {}
367
368void CFXEU_InsertReturn::Redo() {
369 if (m_pEdit) {
370 m_pEdit->SelectNone();
371 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700372 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700373 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700374}
375
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376void CFXEU_InsertReturn::Undo() {
377 if (m_pEdit) {
378 m_pEdit->SelectNone();
379 m_pEdit->SetCaret(m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700380 m_pEdit->Backspace(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700381 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700382}
383
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384CFXEU_Backspace::CFXEU_Backspace(CFX_Edit* pEdit,
385 const CPVT_WordPlace& wpOldPlace,
386 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700387 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700388 int32_t charset,
389 const CPVT_SecProps& SecProps,
390 const CPVT_WordProps& WordProps)
391 : m_pEdit(pEdit),
392 m_wpOld(wpOldPlace),
393 m_wpNew(wpNewPlace),
394 m_Word(word),
395 m_nCharset(charset),
396 m_SecProps(SecProps),
397 m_WordProps(WordProps) {}
398
399CFXEU_Backspace::~CFXEU_Backspace() {}
400
401void CFXEU_Backspace::Redo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700402 if (!m_pEdit)
403 return;
404
405 m_pEdit->SelectNone();
406 m_pEdit->SetCaret(m_wpOld);
407 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700408}
409
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700410void CFXEU_Backspace::Undo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700411 if (!m_pEdit)
412 return;
413
414 m_pEdit->SelectNone();
415 m_pEdit->SetCaret(m_wpNew);
416 if (m_wpNew.nSecIndex != m_wpOld.nSecIndex)
417 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
418 else
419 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700420}
421
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700422CFXEU_Delete::CFXEU_Delete(CFX_Edit* pEdit,
423 const CPVT_WordPlace& wpOldPlace,
424 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700425 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700426 int32_t charset,
427 const CPVT_SecProps& SecProps,
428 const CPVT_WordProps& WordProps,
tsepez4cf55152016-11-02 14:37:54 -0700429 bool bSecEnd)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700430 : m_pEdit(pEdit),
431 m_wpOld(wpOldPlace),
432 m_wpNew(wpNewPlace),
433 m_Word(word),
434 m_nCharset(charset),
435 m_SecProps(SecProps),
436 m_WordProps(WordProps),
437 m_bSecEnd(bSecEnd) {}
438
439CFXEU_Delete::~CFXEU_Delete() {}
440
441void CFXEU_Delete::Redo() {
442 if (m_pEdit) {
443 m_pEdit->SelectNone();
444 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700445 m_pEdit->Delete(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700446 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700447}
448
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700449void CFXEU_Delete::Undo() {
450 if (m_pEdit) {
451 m_pEdit->SelectNone();
452 m_pEdit->SetCaret(m_wpNew);
453 if (m_bSecEnd) {
tsepez4cf55152016-11-02 14:37:54 -0700454 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700455 } else {
tsepez4cf55152016-11-02 14:37:54 -0700456 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700457 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700458 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700459}
460
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461CFXEU_Clear::CFXEU_Clear(CFX_Edit* pEdit,
462 const CPVT_WordRange& wrSel,
463 const CFX_WideString& swText)
464 : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {}
465
466CFXEU_Clear::~CFXEU_Clear() {}
467
468void CFXEU_Clear::Redo() {
469 if (m_pEdit) {
470 m_pEdit->SelectNone();
471 m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
tsepez4cf55152016-11-02 14:37:54 -0700472 m_pEdit->Clear(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700473 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700474}
475
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700476void CFXEU_Clear::Undo() {
477 if (m_pEdit) {
478 m_pEdit->SelectNone();
479 m_pEdit->SetCaret(m_wrSel.BeginPos);
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400480 m_pEdit->InsertText(m_swText, FX_CHARSET_Default, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700481 m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
482 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700483}
484
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700485CFXEU_InsertText::CFXEU_InsertText(CFX_Edit* pEdit,
486 const CPVT_WordPlace& wpOldPlace,
487 const CPVT_WordPlace& wpNewPlace,
488 const CFX_WideString& swText,
dsinclairefd5a992016-07-18 10:04:07 -0700489 int32_t charset)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700490 : m_pEdit(pEdit),
491 m_wpOld(wpOldPlace),
492 m_wpNew(wpNewPlace),
493 m_swText(swText),
dsinclairefd5a992016-07-18 10:04:07 -0700494 m_nCharset(charset) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700495
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700496CFXEU_InsertText::~CFXEU_InsertText() {}
497
498void CFXEU_InsertText::Redo() {
499 if (m_pEdit && IsLast()) {
500 m_pEdit->SelectNone();
501 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700502 m_pEdit->InsertText(m_swText, m_nCharset, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700503 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700504}
505
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506void CFXEU_InsertText::Undo() {
507 if (m_pEdit) {
508 m_pEdit->SelectNone();
509 m_pEdit->SetSel(m_wpOld, m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700510 m_pEdit->Clear(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700511 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700512}
513
dsinclaire35af1e2016-07-13 11:26:20 -0700514// static
515CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500516 const CFX_PointF& ptOffset,
dsinclaire35af1e2016-07-13 11:26:20 -0700517 const CPVT_WordRange* pRange,
tsepez4cf55152016-11-02 14:37:54 -0700518 bool bContinuous,
dsinclaire35af1e2016-07-13 11:26:20 -0700519 uint16_t SubWord) {
520 CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
521 if (pRange)
522 pIterator->SetAt(pRange->BeginPos);
523 else
524 pIterator->SetAt(0);
525
526 CFX_ByteTextBuf sEditStream;
527 CFX_ByteTextBuf sWords;
528 int32_t nCurFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500529 CFX_PointF ptOld;
530 CFX_PointF ptNew;
dsinclaire35af1e2016-07-13 11:26:20 -0700531 CPVT_WordPlace oldplace;
tsepez63f545c2016-09-13 16:08:49 -0700532
dsinclaire35af1e2016-07-13 11:26:20 -0700533 while (pIterator->NextWord()) {
534 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700535 if (pRange && place > pRange->EndPos)
dsinclaire35af1e2016-07-13 11:26:20 -0700536 break;
537
538 if (bContinuous) {
539 if (place.LineCmp(oldplace) != 0) {
540 if (sWords.GetSize() > 0) {
541 sEditStream << GetWordRenderString(sWords.MakeString());
542 sWords.Clear();
543 }
544
545 CPVT_Word word;
546 if (pIterator->GetWord(word)) {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500547 ptNew = CFX_PointF(word.ptWord.x + ptOffset.x,
548 word.ptWord.y + ptOffset.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700549 } else {
550 CPVT_Line line;
551 pIterator->GetLine(line);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500552 ptNew = CFX_PointF(line.ptLine.x + ptOffset.x,
553 line.ptLine.y + ptOffset.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700554 }
555
556 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
557 sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
558 << " Td\n";
559
560 ptOld = ptNew;
561 }
562 }
563
564 CPVT_Word word;
565 if (pIterator->GetWord(word)) {
566 if (word.nFontIndex != nCurFontIndex) {
567 if (sWords.GetSize() > 0) {
568 sEditStream << GetWordRenderString(sWords.MakeString());
569 sWords.Clear();
570 }
571 sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
572 word.fFontSize);
573 nCurFontIndex = word.nFontIndex;
574 }
575
576 sWords << GetPDFWordString(pEdit->GetFontMap(), nCurFontIndex,
577 word.Word, SubWord);
578 }
579
580 oldplace = place;
581 } else {
582 CPVT_Word word;
583 if (pIterator->GetWord(word)) {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500584 ptNew =
585 CFX_PointF(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700586
587 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
588 sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
589 << " Td\n";
590 ptOld = ptNew;
591 }
592
593 if (word.nFontIndex != nCurFontIndex) {
594 sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
595 word.fFontSize);
596 nCurFontIndex = word.nFontIndex;
597 }
598
599 sEditStream << GetWordRenderString(GetPDFWordString(
600 pEdit->GetFontMap(), nCurFontIndex, word.Word, SubWord));
601 }
602 }
603 }
604
605 if (sWords.GetSize() > 0) {
606 sEditStream << GetWordRenderString(sWords.MakeString());
607 sWords.Clear();
608 }
609
610 CFX_ByteTextBuf sAppStream;
611 if (sEditStream.GetSize() > 0) {
612 int32_t nHorzScale = pEdit->GetHorzScale();
613 if (nHorzScale != 100) {
614 sAppStream << nHorzScale << " Tz\n";
615 }
616
Dan Sinclair05df0752017-03-14 14:43:42 -0400617 float fCharSpace = pEdit->GetCharSpace();
dsinclair448c4332016-08-02 12:07:35 -0700618 if (!IsFloatZero(fCharSpace)) {
dsinclaire35af1e2016-07-13 11:26:20 -0700619 sAppStream << fCharSpace << " Tc\n";
620 }
621
622 sAppStream << sEditStream;
623 }
624
625 return sAppStream.MakeString();
626}
627
628// static
629CFX_ByteString CFX_Edit::GetSelectAppearanceStream(
630 CFX_Edit* pEdit,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500631 const CFX_PointF& ptOffset,
dsinclaire35af1e2016-07-13 11:26:20 -0700632 const CPVT_WordRange* pRange) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700633 if (!pRange || pRange->IsEmpty())
dsinclaire35af1e2016-07-13 11:26:20 -0700634 return CFX_ByteString();
635
636 CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
637 pIterator->SetAt(pRange->BeginPos);
638
639 CFX_ByteTextBuf sRet;
640 while (pIterator->NextWord()) {
641 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700642 if (place > pRange->EndPos)
dsinclaire35af1e2016-07-13 11:26:20 -0700643 break;
644
645 CPVT_Word word;
646 CPVT_Line line;
647 if (pIterator->GetWord(word) && pIterator->GetLine(line)) {
648 sRet << word.ptWord.x + ptOffset.x << " "
649 << line.ptLine.y + line.fLineDescent << " " << word.fWidth << " "
650 << line.fLineAscent - line.fLineDescent << " re\nf\n";
651 }
652 }
653
654 return sRet.MakeString();
655}
656
657// static
dsinclaire35af1e2016-07-13 11:26:20 -0700658void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice,
659 CFX_Matrix* pUser2Device,
660 CFX_Edit* pEdit,
661 FX_COLORREF crTextFill,
dsinclaire35af1e2016-07-13 11:26:20 -0700662 const CFX_FloatRect& rcClip,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500663 const CFX_PointF& ptOffset,
dsinclaire35af1e2016-07-13 11:26:20 -0700664 const CPVT_WordRange* pRange,
665 CFX_SystemHandler* pSystemHandler,
dsinclair8faac622016-09-15 12:41:50 -0700666 CFFL_FormFiller* pFFLData) {
dsinclaire35af1e2016-07-13 11:26:20 -0700667 const bool bContinuous =
668 pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
669 uint16_t SubWord = pEdit->GetPasswordChar();
Dan Sinclair05df0752017-03-14 14:43:42 -0400670 float fFontSize = pEdit->GetFontSize();
dsinclaire35af1e2016-07-13 11:26:20 -0700671 CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
672 int32_t nHorzScale = pEdit->GetHorzScale();
673
674 FX_COLORREF crCurFill = crTextFill;
675 FX_COLORREF crOldFill = crCurFill;
676
tsepez4cf55152016-11-02 14:37:54 -0700677 bool bSelect = false;
dsinclaire35af1e2016-07-13 11:26:20 -0700678 const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
679 const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
680
681 CFX_ByteTextBuf sTextBuf;
682 int32_t nFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500683 CFX_PointF ptBT;
dsinclaire35af1e2016-07-13 11:26:20 -0700684 pDevice->SaveState();
dsinclaire35af1e2016-07-13 11:26:20 -0700685 if (!rcClip.IsEmpty()) {
686 CFX_FloatRect rcTemp = rcClip;
687 pUser2Device->TransformRect(rcTemp);
688 pDevice->SetClip_Rect(rcTemp.ToFxRect());
689 }
690
691 CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
692 if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
693 if (pRange)
694 pIterator->SetAt(pRange->BeginPos);
695 else
696 pIterator->SetAt(0);
697
698 CPVT_WordPlace oldplace;
699 while (pIterator->NextWord()) {
700 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700701 if (pRange && place > pRange->EndPos)
dsinclaire35af1e2016-07-13 11:26:20 -0700702 break;
703
Tom Sepez52f69b32017-03-21 13:42:38 -0700704 if (!wrSelect.IsEmpty()) {
705 bSelect = place > wrSelect.BeginPos && place <= wrSelect.EndPos;
dsinclaire35af1e2016-07-13 11:26:20 -0700706 crCurFill = bSelect ? crWhite : crTextFill;
707 }
708 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
709 crCurFill = crTextFill;
710 crOldFill = crCurFill;
711 }
712 CPVT_Word word;
713 if (pIterator->GetWord(word)) {
714 if (bSelect) {
715 CPVT_Line line;
716 pIterator->GetLine(line);
717
718 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
719 CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
720 word.ptWord.x + word.fWidth,
721 line.ptLine.y + line.fLineAscent);
722 rc.Intersect(rcClip);
723 pSystemHandler->OutputSelectedRect(pFFLData, rc);
724 } else {
725 CFX_PathData pathSelBK;
726 pathSelBK.AppendRect(
727 word.ptWord.x, line.ptLine.y + line.fLineDescent,
728 word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent);
729
730 pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
731 FXFILL_WINDING);
732 }
733 }
734
735 if (bContinuous) {
736 if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
737 crOldFill != crCurFill) {
738 if (sTextBuf.GetLength() > 0) {
739 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500740 pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700741 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
Dan Sinclaira0061af2017-02-23 09:25:17 -0500742 sTextBuf.MakeString(), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700743
744 sTextBuf.Clear();
745 }
746 nFontIndex = word.nFontIndex;
747 ptBT = word.ptWord;
748 crOldFill = crCurFill;
749 }
750
751 sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word,
752 SubWord)
753 .AsStringC();
754 } else {
755 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500756 pDevice, CFX_PointF(word.ptWord.x + ptOffset.x,
757 word.ptWord.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700758 pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
759 GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord),
Dan Sinclaira0061af2017-02-23 09:25:17 -0500760 crCurFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700761 }
762 oldplace = place;
763 }
764 }
765
766 if (sTextBuf.GetLength() > 0) {
Dan Sinclaira0061af2017-02-23 09:25:17 -0500767 DrawTextString(pDevice,
768 CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
769 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
770 sTextBuf.MakeString(), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700771 }
772 }
773
774 pDevice->RestoreState(false);
775}
776
dsinclaire35af1e2016-07-13 11:26:20 -0700777CFX_Edit::CFX_Edit()
778 : m_pVT(new CPDF_VariableText),
thestig821d59e2016-05-11 12:59:22 -0700779 m_pNotify(nullptr),
780 m_pOprNotify(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700781 m_wpCaret(-1, -1, -1),
782 m_wpOldCaret(-1, -1, -1),
783 m_SelState(),
tsepez4cf55152016-11-02 14:37:54 -0700784 m_bEnableScroll(false),
dsinclair8f4bf9a2016-05-04 13:51:51 -0700785 m_Undo(kEditUndoMaxItems),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700786 m_nAlignment(0),
tsepez4cf55152016-11-02 14:37:54 -0700787 m_bNotifyFlag(false),
788 m_bEnableOverflow(false),
789 m_bEnableRefresh(true),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700790 m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f),
tsepez4cf55152016-11-02 14:37:54 -0700791 m_bEnableUndo(true),
Lei Zhang1a89e362017-03-23 15:27:25 -0700792 m_bOprNotify(false) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700793
Lei Zhang1a89e362017-03-23 15:27:25 -0700794CFX_Edit::~CFX_Edit() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700795
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700796void CFX_Edit::Initialize() {
797 m_pVT->Initialize();
798 SetCaret(m_pVT->GetBeginWordPlace());
799 SetCaretOrigin();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700800}
801
dsinclairc7a73492016-04-05 12:01:42 -0700802void CFX_Edit::SetFontMap(IPVT_FontMap* pFontMap) {
tsepez36eb4bd2016-10-03 15:24:27 -0700803 m_pVTProvider = pdfium::MakeUnique<CFX_Edit_Provider>(pFontMap);
thestig821d59e2016-05-11 12:59:22 -0700804 m_pVT->SetProvider(m_pVTProvider.get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700805}
806
dsinclaire35af1e2016-07-13 11:26:20 -0700807void CFX_Edit::SetNotify(CPWL_EditCtrl* pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700808 m_pNotify = pNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700809}
810
dsinclaire35af1e2016-07-13 11:26:20 -0700811void CFX_Edit::SetOprNotify(CPWL_Edit* pOprNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700812 m_pOprNotify = pOprNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700813}
814
dsinclaire35af1e2016-07-13 11:26:20 -0700815CFX_Edit_Iterator* CFX_Edit::GetIterator() {
tsepez36eb4bd2016-10-03 15:24:27 -0700816 if (!m_pIterator) {
817 m_pIterator =
818 pdfium::MakeUnique<CFX_Edit_Iterator>(this, m_pVT->GetIterator());
819 }
thestig821d59e2016-05-11 12:59:22 -0700820 return m_pIterator.get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700821}
822
dsinclairc7a73492016-04-05 12:01:42 -0700823IPVT_FontMap* CFX_Edit::GetFontMap() {
thestig821d59e2016-05-11 12:59:22 -0700824 return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700825}
826
dsinclairefd5a992016-07-18 10:04:07 -0700827void CFX_Edit::SetPlateRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700828 m_pVT->SetPlateRect(rect);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500829 m_ptScrollPos = CFX_PointF(rect.left, rect.top);
dsinclairefd5a992016-07-18 10:04:07 -0700830 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700831}
832
tsepez4cf55152016-11-02 14:37:54 -0700833void CFX_Edit::SetAlignmentH(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700834 m_pVT->SetAlignment(nFormat);
835 if (bPaint)
836 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700837}
838
tsepez4cf55152016-11-02 14:37:54 -0700839void CFX_Edit::SetAlignmentV(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700840 m_nAlignment = nFormat;
841 if (bPaint)
842 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700843}
844
tsepez4cf55152016-11-02 14:37:54 -0700845void CFX_Edit::SetPasswordChar(uint16_t wSubWord, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700846 m_pVT->SetPasswordChar(wSubWord);
847 if (bPaint)
848 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700849}
850
dsinclairefd5a992016-07-18 10:04:07 -0700851void CFX_Edit::SetLimitChar(int32_t nLimitChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700852 m_pVT->SetLimitChar(nLimitChar);
dsinclairefd5a992016-07-18 10:04:07 -0700853 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700854}
855
dsinclairefd5a992016-07-18 10:04:07 -0700856void CFX_Edit::SetCharArray(int32_t nCharArray) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700857 m_pVT->SetCharArray(nCharArray);
dsinclairefd5a992016-07-18 10:04:07 -0700858 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700859}
860
Dan Sinclair05df0752017-03-14 14:43:42 -0400861void CFX_Edit::SetCharSpace(float fCharSpace) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700862 m_pVT->SetCharSpace(fCharSpace);
dsinclairefd5a992016-07-18 10:04:07 -0700863 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700864}
865
tsepez4cf55152016-11-02 14:37:54 -0700866void CFX_Edit::SetMultiLine(bool bMultiLine, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700867 m_pVT->SetMultiLine(bMultiLine);
868 if (bPaint)
869 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700870}
871
tsepez4cf55152016-11-02 14:37:54 -0700872void CFX_Edit::SetAutoReturn(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700873 m_pVT->SetAutoReturn(bAuto);
874 if (bPaint)
875 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700876}
877
tsepez4cf55152016-11-02 14:37:54 -0700878void CFX_Edit::SetAutoFontSize(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700879 m_pVT->SetAutoFontSize(bAuto);
880 if (bPaint)
881 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700882}
883
Dan Sinclair05df0752017-03-14 14:43:42 -0400884void CFX_Edit::SetFontSize(float fFontSize) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700885 m_pVT->SetFontSize(fFontSize);
dsinclairefd5a992016-07-18 10:04:07 -0700886 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700887}
888
tsepez4cf55152016-11-02 14:37:54 -0700889void CFX_Edit::SetAutoScroll(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700890 m_bEnableScroll = bAuto;
891 if (bPaint)
892 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700893}
894
tsepez4cf55152016-11-02 14:37:54 -0700895void CFX_Edit::SetTextOverflow(bool bAllowed, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700896 m_bEnableOverflow = bAllowed;
897 if (bPaint)
898 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700899}
900
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700901void CFX_Edit::SetSel(int32_t nStartChar, int32_t nEndChar) {
902 if (m_pVT->IsValid()) {
903 if (nStartChar == 0 && nEndChar < 0) {
904 SelectAll();
905 } else if (nStartChar < 0) {
906 SelectNone();
907 } else {
908 if (nStartChar < nEndChar) {
909 SetSel(m_pVT->WordIndexToWordPlace(nStartChar),
910 m_pVT->WordIndexToWordPlace(nEndChar));
911 } else {
912 SetSel(m_pVT->WordIndexToWordPlace(nEndChar),
913 m_pVT->WordIndexToWordPlace(nStartChar));
914 }
915 }
916 }
917}
918
919void CFX_Edit::SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700920 if (!m_pVT->IsValid())
921 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700922
Tom Sepez52f69b32017-03-21 13:42:38 -0700923 SelectNone();
924 m_SelState.Set(begin, end);
925 SetCaret(m_SelState.EndPos);
926 ScrollToCaret();
927 if (!m_SelState.IsEmpty())
928 Refresh();
929 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700930}
931
932void CFX_Edit::GetSel(int32_t& nStartChar, int32_t& nEndChar) const {
933 nStartChar = -1;
934 nEndChar = -1;
Tom Sepez52f69b32017-03-21 13:42:38 -0700935 if (!m_pVT->IsValid())
936 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700937
Tom Sepez52f69b32017-03-21 13:42:38 -0700938 if (m_SelState.IsEmpty()) {
939 nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
940 nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
941 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700942 }
Tom Sepez52f69b32017-03-21 13:42:38 -0700943 if (m_SelState.BeginPos < m_SelState.EndPos) {
944 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
945 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
946 return;
947 }
948 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
949 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700950}
951
952int32_t CFX_Edit::GetCaret() const {
953 if (m_pVT->IsValid())
954 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
955
956 return -1;
957}
958
959CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const {
960 return m_wpCaret;
961}
962
963CFX_WideString CFX_Edit::GetText() const {
964 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700965 if (!m_pVT->IsValid())
966 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700967
thestig821d59e2016-05-11 12:59:22 -0700968 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
969 pIterator->SetAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700970
thestig821d59e2016-05-11 12:59:22 -0700971 CPVT_Word wordinfo;
972 CPVT_WordPlace oldplace = pIterator->GetAt();
973 while (pIterator->NextWord()) {
974 CPVT_WordPlace place = pIterator->GetAt();
thestig821d59e2016-05-11 12:59:22 -0700975 if (pIterator->GetWord(wordinfo))
976 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700977 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700978 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700979 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700980 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700981 return swRet;
982}
983
984CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange& range) const {
985 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700986 if (!m_pVT->IsValid())
987 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700988
thestig821d59e2016-05-11 12:59:22 -0700989 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
990 CPVT_WordRange wrTemp = range;
991 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
992 m_pVT->UpdateWordPlace(wrTemp.EndPos);
993 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700994
thestig821d59e2016-05-11 12:59:22 -0700995 CPVT_Word wordinfo;
996 CPVT_WordPlace oldplace = wrTemp.BeginPos;
997 while (pIterator->NextWord()) {
998 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700999 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -07001000 break;
thestig821d59e2016-05-11 12:59:22 -07001001 if (pIterator->GetWord(wordinfo))
1002 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -07001003 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -07001004 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -07001005 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001006 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001007 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001008}
1009
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001010CFX_WideString CFX_Edit::GetSelText() const {
1011 return GetRangeText(m_SelState.ConvertToWordRange());
1012}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001013
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001014int32_t CFX_Edit::GetTotalLines() const {
thestig821d59e2016-05-11 12:59:22 -07001015 int32_t nLines = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001016
thestig821d59e2016-05-11 12:59:22 -07001017 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1018 pIterator->SetAt(0);
1019 while (pIterator->NextLine())
1020 ++nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001021
thestig821d59e2016-05-11 12:59:22 -07001022 return nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001023}
1024
1025CPVT_WordRange CFX_Edit::GetSelectWordRange() const {
1026 return m_SelState.ConvertToWordRange();
1027}
1028
tsepeza31da742016-09-08 11:28:14 -07001029void CFX_Edit::SetText(const CFX_WideString& sText) {
dsinclairefd5a992016-07-18 10:04:07 -07001030 Empty();
Dan Sinclairf51a02a2017-04-19 12:46:53 -04001031 DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_CHARSET_Default);
dsinclairefd5a992016-07-18 10:04:07 -07001032 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001033}
1034
tsepez4cf55152016-11-02 14:37:54 -07001035bool CFX_Edit::InsertWord(uint16_t word, int32_t charset) {
1036 return InsertWord(word, charset, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001037}
1038
tsepez4cf55152016-11-02 14:37:54 -07001039bool CFX_Edit::InsertReturn() {
1040 return InsertReturn(nullptr, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001041}
1042
tsepez4cf55152016-11-02 14:37:54 -07001043bool CFX_Edit::Backspace() {
1044 return Backspace(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001045}
1046
tsepez4cf55152016-11-02 14:37:54 -07001047bool CFX_Edit::Delete() {
1048 return Delete(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001049}
1050
tsepez4cf55152016-11-02 14:37:54 -07001051bool CFX_Edit::Clear() {
1052 return Clear(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001053}
1054
tsepez4cf55152016-11-02 14:37:54 -07001055bool CFX_Edit::InsertText(const CFX_WideString& sText, int32_t charset) {
1056 return InsertText(sText, charset, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001057}
1058
Dan Sinclair05df0752017-03-14 14:43:42 -04001059float CFX_Edit::GetFontSize() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001060 return m_pVT->GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001061}
1062
Tom Sepez62a70f92016-03-21 15:00:20 -07001063uint16_t CFX_Edit::GetPasswordChar() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001064 return m_pVT->GetPasswordChar();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001065}
1066
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001067int32_t CFX_Edit::GetCharArray() const {
1068 return m_pVT->GetCharArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001069}
1070
Tom Sepez281a9ea2016-02-26 14:24:28 -08001071CFX_FloatRect CFX_Edit::GetContentRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001072 return VTToEdit(m_pVT->GetContentRect());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001073}
1074
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001075int32_t CFX_Edit::GetHorzScale() const {
1076 return m_pVT->GetHorzScale();
1077}
1078
Dan Sinclair05df0752017-03-14 14:43:42 -04001079float CFX_Edit::GetCharSpace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001080 return m_pVT->GetCharSpace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001081}
1082
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001083CPVT_WordRange CFX_Edit::GetWholeWordRange() const {
1084 if (m_pVT->IsValid())
1085 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001086
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001087 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001088}
1089
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001090CPVT_WordRange CFX_Edit::GetVisibleWordRange() const {
1091 if (m_bEnableOverflow)
1092 return GetWholeWordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001093
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001094 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001095 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001096
Dan Sinclairf528eee2017-02-14 11:52:07 -05001097 CPVT_WordPlace place1 =
1098 m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001099 CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
Dan Sinclairf528eee2017-02-14 11:52:07 -05001100 EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001101
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001102 return CPVT_WordRange(place1, place2);
1103 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001104
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001105 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001106}
1107
Dan Sinclairf528eee2017-02-14 11:52:07 -05001108CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_PointF& point) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001109 if (m_pVT->IsValid()) {
1110 return m_pVT->SearchWordPlace(EditToVT(point));
1111 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001112
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001113 return CPVT_WordPlace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001114}
1115
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001116void CFX_Edit::Paint() {
1117 if (m_pVT->IsValid()) {
1118 RearrangeAll();
1119 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001120 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001121 SetCaretOrigin();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001122 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001123 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001124}
1125
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001126void CFX_Edit::RearrangeAll() {
1127 if (m_pVT->IsValid()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001128 m_pVT->UpdateWordPlace(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001129 m_pVT->RearrangeAll();
1130 m_pVT->UpdateWordPlace(m_wpCaret);
1131 SetScrollInfo();
1132 SetContentChanged();
1133 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001134}
1135
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001136void CFX_Edit::RearrangePart(const CPVT_WordRange& range) {
1137 if (m_pVT->IsValid()) {
1138 m_pVT->UpdateWordPlace(m_wpCaret);
1139 m_pVT->RearrangePart(range);
1140 m_pVT->UpdateWordPlace(m_wpCaret);
1141 SetScrollInfo();
1142 SetContentChanged();
1143 }
1144}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001145
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001146void CFX_Edit::SetContentChanged() {
dsinclaira2919b32016-07-13 10:55:48 -07001147 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001148 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001149 if (rcContent.Width() != m_rcOldContent.Width() ||
1150 rcContent.Height() != m_rcOldContent.Height()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001151 m_rcOldContent = rcContent;
1152 }
1153 }
1154}
1155
1156void CFX_Edit::SelectAll() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001157 if (!m_pVT->IsValid())
1158 return;
1159 m_SelState = CFX_Edit_Select(GetWholeWordRange());
1160 SetCaret(m_SelState.EndPos);
1161 ScrollToCaret();
1162 Refresh();
1163 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001164}
1165
1166void CFX_Edit::SelectNone() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001167 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
1168 return;
1169
1170 m_SelState.Reset();
1171 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001172}
1173
tsepez4cf55152016-11-02 14:37:54 -07001174bool CFX_Edit::IsSelected() const {
Tom Sepez52f69b32017-03-21 13:42:38 -07001175 return !m_SelState.IsEmpty();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001176}
1177
Dan Sinclairf528eee2017-02-14 11:52:07 -05001178CFX_PointF CFX_Edit::VTToEdit(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001179 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1180 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001181
Dan Sinclair05df0752017-03-14 14:43:42 -04001182 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001183
1184 switch (m_nAlignment) {
1185 case 0:
1186 fPadding = 0.0f;
1187 break;
1188 case 1:
1189 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1190 break;
1191 case 2:
1192 fPadding = rcPlate.Height() - rcContent.Height();
1193 break;
1194 }
1195
Dan Sinclairf528eee2017-02-14 11:52:07 -05001196 return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
1197 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001198}
1199
Dan Sinclairf528eee2017-02-14 11:52:07 -05001200CFX_PointF CFX_Edit::EditToVT(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001201 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1202 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001203
Dan Sinclair05df0752017-03-14 14:43:42 -04001204 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001205
1206 switch (m_nAlignment) {
1207 case 0:
1208 fPadding = 0.0f;
1209 break;
1210 case 1:
1211 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1212 break;
1213 case 2:
1214 fPadding = rcPlate.Height() - rcContent.Height();
1215 break;
1216 }
1217
Dan Sinclairf528eee2017-02-14 11:52:07 -05001218 return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
1219 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001220}
1221
Tom Sepez281a9ea2016-02-26 14:24:28 -08001222CFX_FloatRect CFX_Edit::VTToEdit(const CFX_FloatRect& rect) const {
Dan Sinclairf528eee2017-02-14 11:52:07 -05001223 CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
1224 CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001225
Tom Sepez281a9ea2016-02-26 14:24:28 -08001226 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1227 ptRightTop.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001228}
1229
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001230void CFX_Edit::SetScrollInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001231 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001232 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1233 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001234
1235 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001236 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001237 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001238 m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
1239 rcContent.bottom, rcContent.top,
1240 rcPlate.Height() / 3, rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001241 }
1242 }
1243}
1244
Dan Sinclair05df0752017-03-14 14:43:42 -04001245void CFX_Edit::SetScrollPosX(float fx) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001246 if (!m_bEnableScroll)
1247 return;
1248
1249 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001250 if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001251 m_ptScrollPos.x = fx;
dsinclairefd5a992016-07-18 10:04:07 -07001252 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001253 }
1254 }
1255}
1256
Dan Sinclair05df0752017-03-14 14:43:42 -04001257void CFX_Edit::SetScrollPosY(float fy) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001258 if (!m_bEnableScroll)
1259 return;
1260
1261 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001262 if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001263 m_ptScrollPos.y = fy;
dsinclairefd5a992016-07-18 10:04:07 -07001264 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001265
dsinclaira2919b32016-07-13 10:55:48 -07001266 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001267 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001268 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001269 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001270 m_pNotify->IOnSetScrollPosY(fy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001271 }
1272 }
1273 }
1274 }
1275}
1276
Dan Sinclairf528eee2017-02-14 11:52:07 -05001277void CFX_Edit::SetScrollPos(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001278 SetScrollPosX(point.x);
1279 SetScrollPosY(point.y);
1280 SetScrollLimit();
1281 SetCaretInfo();
1282}
1283
Dan Sinclairf528eee2017-02-14 11:52:07 -05001284CFX_PointF CFX_Edit::GetScrollPos() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001285 return m_ptScrollPos;
1286}
1287
1288void CFX_Edit::SetScrollLimit() {
1289 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001290 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1291 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001292
1293 if (rcPlate.Width() > rcContent.Width()) {
1294 SetScrollPosX(rcPlate.left);
1295 } else {
dsinclair448c4332016-08-02 12:07:35 -07001296 if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001297 SetScrollPosX(rcContent.left);
dsinclair448c4332016-08-02 12:07:35 -07001298 } else if (IsFloatBigger(m_ptScrollPos.x,
1299 rcContent.right - rcPlate.Width())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001300 SetScrollPosX(rcContent.right - rcPlate.Width());
1301 }
1302 }
1303
1304 if (rcPlate.Height() > rcContent.Height()) {
1305 SetScrollPosY(rcPlate.top);
1306 } else {
dsinclair448c4332016-08-02 12:07:35 -07001307 if (IsFloatSmaller(m_ptScrollPos.y,
1308 rcContent.bottom + rcPlate.Height())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001309 SetScrollPosY(rcContent.bottom + rcPlate.Height());
dsinclair448c4332016-08-02 12:07:35 -07001310 } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001311 SetScrollPosY(rcContent.top);
1312 }
1313 }
1314 }
1315}
1316
1317void CFX_Edit::ScrollToCaret() {
1318 SetScrollLimit();
1319
thestig821d59e2016-05-11 12:59:22 -07001320 if (!m_pVT->IsValid())
1321 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001322
thestig821d59e2016-05-11 12:59:22 -07001323 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1324 pIterator->SetAt(m_wpCaret);
1325
Dan Sinclairf528eee2017-02-14 11:52:07 -05001326 CFX_PointF ptHead;
1327 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001328 CPVT_Word word;
1329 CPVT_Line line;
1330 if (pIterator->GetWord(word)) {
1331 ptHead.x = word.ptWord.x + word.fWidth;
1332 ptHead.y = word.ptWord.y + word.fAscent;
1333 ptFoot.x = word.ptWord.x + word.fWidth;
1334 ptFoot.y = word.ptWord.y + word.fDescent;
1335 } else if (pIterator->GetLine(line)) {
1336 ptHead.x = line.ptLine.x;
1337 ptHead.y = line.ptLine.y + line.fLineAscent;
1338 ptFoot.x = line.ptLine.x;
1339 ptFoot.y = line.ptLine.y + line.fLineDescent;
1340 }
1341
Dan Sinclairf528eee2017-02-14 11:52:07 -05001342 CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1343 CFX_PointF ptFootEdit = VTToEdit(ptFoot);
thestig821d59e2016-05-11 12:59:22 -07001344 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
dsinclair448c4332016-08-02 12:07:35 -07001345 if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
1346 if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
1347 IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
thestig821d59e2016-05-11 12:59:22 -07001348 SetScrollPosX(ptHead.x);
dsinclair448c4332016-08-02 12:07:35 -07001349 } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
thestig821d59e2016-05-11 12:59:22 -07001350 SetScrollPosX(ptHead.x - rcPlate.Width());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001351 }
thestig821d59e2016-05-11 12:59:22 -07001352 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001353
dsinclair448c4332016-08-02 12:07:35 -07001354 if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
1355 if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
1356 IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
1357 if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
thestig821d59e2016-05-11 12:59:22 -07001358 SetScrollPosY(ptFoot.y + rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001359 }
dsinclair448c4332016-08-02 12:07:35 -07001360 } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
1361 if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
thestig821d59e2016-05-11 12:59:22 -07001362 SetScrollPosY(ptHead.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001363 }
1364 }
1365 }
1366}
1367
dsinclairefd5a992016-07-18 10:04:07 -07001368void CFX_Edit::Refresh() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001369 if (m_bEnableRefresh && m_pVT->IsValid()) {
1370 m_Refresh.BeginRefresh();
1371 RefreshPushLineRects(GetVisibleWordRange());
1372
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001373 m_Refresh.NoAnalyse();
1374 m_ptRefreshScrollPos = m_ptScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001375
dsinclaira2919b32016-07-13 10:55:48 -07001376 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001377 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001378 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001379 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001380 if (const CFX_Edit_RectArray* pRects = m_Refresh.GetRefreshRects()) {
1381 for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
1382 m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
1383 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001384 }
1385 }
1386
1387 m_Refresh.EndRefresh();
1388 }
1389}
1390
1391void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001392 if (!m_pVT->IsValid())
1393 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001394
thestig821d59e2016-05-11 12:59:22 -07001395 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1396 CPVT_WordPlace wpBegin = wr.BeginPos;
1397 m_pVT->UpdateWordPlace(wpBegin);
1398 CPVT_WordPlace wpEnd = wr.EndPos;
1399 m_pVT->UpdateWordPlace(wpEnd);
1400 pIterator->SetAt(wpBegin);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001401
thestig821d59e2016-05-11 12:59:22 -07001402 CPVT_Line lineinfo;
1403 do {
1404 if (!pIterator->GetLine(lineinfo))
1405 break;
1406 if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
1407 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001408
thestig821d59e2016-05-11 12:59:22 -07001409 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1410 lineinfo.ptLine.y + lineinfo.fLineDescent,
1411 lineinfo.ptLine.x + lineinfo.fLineWidth,
1412 lineinfo.ptLine.y + lineinfo.fLineAscent);
1413
1414 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1415 VTToEdit(rcLine));
1416 } while (pIterator->NextLine());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001417}
1418
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001419void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001420 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1421 CPVT_WordRange wrTemp = wr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001422
thestig821d59e2016-05-11 12:59:22 -07001423 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1424 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1425 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001426
thestig821d59e2016-05-11 12:59:22 -07001427 CPVT_Word wordinfo;
1428 CPVT_Line lineinfo;
1429 CPVT_WordPlace place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001430
thestig821d59e2016-05-11 12:59:22 -07001431 while (pIterator->NextWord()) {
1432 place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -07001433 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -07001434 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001435
thestig821d59e2016-05-11 12:59:22 -07001436 pIterator->GetWord(wordinfo);
1437 pIterator->GetLine(lineinfo);
thestig821d59e2016-05-11 12:59:22 -07001438 if (place.LineCmp(wrTemp.BeginPos) == 0 ||
1439 place.LineCmp(wrTemp.EndPos) == 0) {
1440 CFX_FloatRect rcWord(wordinfo.ptWord.x,
1441 lineinfo.ptLine.y + lineinfo.fLineDescent,
1442 wordinfo.ptWord.x + wordinfo.fWidth,
1443 lineinfo.ptLine.y + lineinfo.fLineAscent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001444
dsinclaira2919b32016-07-13 10:55:48 -07001445 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001446 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001447 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001448 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001449 CFX_FloatRect rcRefresh = VTToEdit(rcWord);
1450 m_pNotify->IOnInvalidateRect(&rcRefresh);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001451 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001452 }
thestig821d59e2016-05-11 12:59:22 -07001453 } else {
1454 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1455 lineinfo.ptLine.y + lineinfo.fLineDescent,
1456 lineinfo.ptLine.x + lineinfo.fLineWidth,
1457 lineinfo.ptLine.y + lineinfo.fLineAscent);
1458
dsinclaira2919b32016-07-13 10:55:48 -07001459 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001460 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001461 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001462 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001463 CFX_FloatRect rcRefresh = VTToEdit(rcLine);
1464 m_pNotify->IOnInvalidateRect(&rcRefresh);
thestig821d59e2016-05-11 12:59:22 -07001465 }
1466 }
1467
1468 pIterator->NextLine();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001469 }
1470 }
1471}
1472
1473void CFX_Edit::SetCaret(const CPVT_WordPlace& place) {
1474 m_wpOldCaret = m_wpCaret;
1475 m_wpCaret = place;
1476}
1477
1478void CFX_Edit::SetCaretInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001479 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001480 if (!m_bNotifyFlag) {
thestig821d59e2016-05-11 12:59:22 -07001481 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1482 pIterator->SetAt(m_wpCaret);
tsepez63f545c2016-09-13 16:08:49 -07001483
Dan Sinclairf528eee2017-02-14 11:52:07 -05001484 CFX_PointF ptHead;
1485 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001486 CPVT_Word word;
1487 CPVT_Line line;
1488 if (pIterator->GetWord(word)) {
1489 ptHead.x = word.ptWord.x + word.fWidth;
1490 ptHead.y = word.ptWord.y + word.fAscent;
1491 ptFoot.x = word.ptWord.x + word.fWidth;
1492 ptFoot.y = word.ptWord.y + word.fDescent;
1493 } else if (pIterator->GetLine(line)) {
1494 ptHead.x = line.ptLine.x;
1495 ptHead.y = line.ptLine.y + line.fLineAscent;
1496 ptFoot.x = line.ptLine.x;
1497 ptFoot.y = line.ptLine.y + line.fLineDescent;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001498 }
1499
Lei Zhanga8c2b912017-03-22 17:41:02 -07001500 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001501 m_bNotifyFlag = true;
Tom Sepez52f69b32017-03-21 13:42:38 -07001502 m_pNotify->IOnSetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead),
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001503 VTToEdit(ptFoot), m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001504 }
1505 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001506}
1507
Dan Sinclairf528eee2017-02-14 11:52:07 -05001508void CFX_Edit::OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001509 if (!m_pVT->IsValid())
1510 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001511
Tom Sepez52f69b32017-03-21 13:42:38 -07001512 SelectNone();
1513 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1514 m_SelState.Set(m_wpCaret, m_wpCaret);
1515 ScrollToCaret();
1516 SetCaretOrigin();
1517 SetCaretInfo();
1518}
1519
1520void CFX_Edit::OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl) {
1521 if (!m_pVT->IsValid())
1522 return;
1523
1524 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1525 if (m_wpCaret == m_wpOldCaret)
1526 return;
1527
1528 m_SelState.SetEndPos(m_wpCaret);
1529 ScrollToCaret();
1530 Refresh();
1531 SetCaretOrigin();
1532 SetCaretInfo();
1533}
1534
1535void CFX_Edit::OnVK_UP(bool bShift, bool bCtrl) {
1536 if (!m_pVT->IsValid())
1537 return;
1538
1539 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1540 if (bShift) {
1541 if (m_SelState.IsEmpty())
1542 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1543 else
1544 m_SelState.SetEndPos(m_wpCaret);
1545
1546 if (m_wpOldCaret != m_wpCaret) {
1547 ScrollToCaret();
1548 Refresh();
1549 SetCaretInfo();
1550 }
1551 } else {
1552 SelectNone();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001553 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001554 SetCaretInfo();
1555 }
1556}
1557
Tom Sepez52f69b32017-03-21 13:42:38 -07001558void CFX_Edit::OnVK_DOWN(bool bShift, bool bCtrl) {
1559 if (!m_pVT->IsValid())
1560 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001561
Tom Sepez52f69b32017-03-21 13:42:38 -07001562 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1563 if (bShift) {
1564 if (m_SelState.IsEmpty())
1565 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1566 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001567 m_SelState.SetEndPos(m_wpCaret);
1568
Tom Sepez52f69b32017-03-21 13:42:38 -07001569 if (m_wpOldCaret != m_wpCaret) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001570 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001571 Refresh();
Tom Sepez52f69b32017-03-21 13:42:38 -07001572 SetCaretInfo();
1573 }
1574 } else {
1575 SelectNone();
1576 ScrollToCaret();
1577 SetCaretInfo();
1578 }
1579}
1580
1581void CFX_Edit::OnVK_LEFT(bool bShift, bool bCtrl) {
1582 if (!m_pVT->IsValid())
1583 return;
1584
1585 if (bShift) {
1586 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1587 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1588 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1589 }
1590 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1591 if (m_SelState.IsEmpty())
1592 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1593 else
1594 m_SelState.SetEndPos(m_wpCaret);
1595
1596 if (m_wpOldCaret != m_wpCaret) {
1597 ScrollToCaret();
1598 Refresh();
1599 SetCaretInfo();
1600 }
1601 } else {
1602 if (!m_SelState.IsEmpty()) {
1603 if (m_SelState.BeginPos < m_SelState.EndPos)
1604 SetCaret(m_SelState.BeginPos);
1605 else
1606 SetCaret(m_SelState.EndPos);
1607
1608 SelectNone();
1609 ScrollToCaret();
1610 SetCaretInfo();
1611 } else {
1612 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1613 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1614 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1615 }
1616 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1617 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001618 SetCaretOrigin();
1619 SetCaretInfo();
1620 }
1621 }
1622}
1623
tsepez4cf55152016-11-02 14:37:54 -07001624void CFX_Edit::OnVK_RIGHT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001625 if (!m_pVT->IsValid())
1626 return;
1627
1628 if (bShift) {
1629 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1630 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1631 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001632 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1633
Tom Sepez52f69b32017-03-21 13:42:38 -07001634 if (m_SelState.IsEmpty())
1635 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1636 else
1637 m_SelState.SetEndPos(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001638
Tom Sepez52f69b32017-03-21 13:42:38 -07001639 if (m_wpOldCaret != m_wpCaret) {
1640 ScrollToCaret();
1641 Refresh();
1642 SetCaretInfo();
1643 }
1644 } else {
1645 if (!m_SelState.IsEmpty()) {
1646 if (m_SelState.BeginPos > m_SelState.EndPos)
1647 SetCaret(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001648 else
Tom Sepez52f69b32017-03-21 13:42:38 -07001649 SetCaret(m_SelState.EndPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001650
Tom Sepez52f69b32017-03-21 13:42:38 -07001651 SelectNone();
1652 ScrollToCaret();
1653 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001654 } else {
Tom Sepez52f69b32017-03-21 13:42:38 -07001655 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1656 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1657 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001658 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001659 }
Tom Sepez52f69b32017-03-21 13:42:38 -07001660 ScrollToCaret();
1661 SetCaretOrigin();
1662 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001663 }
1664 }
1665}
1666
tsepez4cf55152016-11-02 14:37:54 -07001667void CFX_Edit::OnVK_HOME(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001668 if (!m_pVT->IsValid())
1669 return;
1670
1671 if (bShift) {
1672 if (bCtrl)
1673 SetCaret(m_pVT->GetBeginWordPlace());
1674 else
1675 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1676
1677 if (m_SelState.IsEmpty())
1678 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1679 else
1680 m_SelState.SetEndPos(m_wpCaret);
1681
1682 ScrollToCaret();
1683 Refresh();
1684 SetCaretInfo();
1685 } else {
1686 if (!m_SelState.IsEmpty()) {
1687 SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos));
1688 SelectNone();
1689 ScrollToCaret();
1690 SetCaretInfo();
1691 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001692 if (bCtrl)
1693 SetCaret(m_pVT->GetBeginWordPlace());
1694 else
1695 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1696
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001697 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001698 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001699 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001700 }
1701 }
1702}
1703
tsepez4cf55152016-11-02 14:37:54 -07001704void CFX_Edit::OnVK_END(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001705 if (!m_pVT->IsValid())
1706 return;
1707
1708 if (bShift) {
1709 if (bCtrl)
1710 SetCaret(m_pVT->GetEndWordPlace());
1711 else
1712 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1713
1714 if (m_SelState.IsEmpty())
1715 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1716 else
1717 m_SelState.SetEndPos(m_wpCaret);
1718
1719 ScrollToCaret();
1720 Refresh();
1721 SetCaretInfo();
1722 } else {
1723 if (!m_SelState.IsEmpty()) {
1724 SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos));
1725 SelectNone();
1726 ScrollToCaret();
1727 SetCaretInfo();
1728 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001729 if (bCtrl)
1730 SetCaret(m_pVT->GetEndWordPlace());
1731 else
1732 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1733
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001734 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001735 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001736 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001737 }
1738 }
1739}
1740
tsepez4cf55152016-11-02 14:37:54 -07001741bool CFX_Edit::InsertWord(uint16_t word,
1742 int32_t charset,
1743 const CPVT_WordProps* pWordProps,
1744 bool bAddUndo,
1745 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001746 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001747 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001748
Tom Sepez3509d162017-01-30 13:22:02 -08001749 m_pVT->UpdateWordPlace(m_wpCaret);
1750 SetCaret(m_pVT->InsertWord(m_wpCaret, word,
1751 GetCharSetFromUnicode(word, charset), pWordProps));
1752 m_SelState.Set(m_wpCaret, m_wpCaret);
1753 if (m_wpCaret == m_wpOldCaret)
1754 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001755
Tom Sepez3509d162017-01-30 13:22:02 -08001756 if (bAddUndo && m_bEnableUndo) {
1757 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertWord>(
1758 this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001759 }
Tom Sepez3509d162017-01-30 13:22:02 -08001760 if (bPaint)
1761 PaintInsertText(m_wpOldCaret, m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001762
Tom Sepez3509d162017-01-30 13:22:02 -08001763 if (m_bOprNotify && m_pOprNotify)
1764 m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
1765
1766 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001767}
1768
tsepez4cf55152016-11-02 14:37:54 -07001769bool CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps,
1770 const CPVT_WordProps* pWordProps,
1771 bool bAddUndo,
1772 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001773 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001774 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001775
Tom Sepez3509d162017-01-30 13:22:02 -08001776 m_pVT->UpdateWordPlace(m_wpCaret);
1777 SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
1778 m_SelState.Set(m_wpCaret, m_wpCaret);
1779 if (m_wpCaret == m_wpOldCaret)
1780 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001781
Tom Sepez3509d162017-01-30 13:22:02 -08001782 if (bAddUndo && m_bEnableUndo) {
1783 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertReturn>(
1784 this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001785 }
Tom Sepez3509d162017-01-30 13:22:02 -08001786 if (bPaint) {
1787 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1788 ScrollToCaret();
1789 Refresh();
1790 SetCaretOrigin();
1791 SetCaretInfo();
1792 }
1793 if (m_bOprNotify && m_pOprNotify)
1794 m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001795
Tom Sepez3509d162017-01-30 13:22:02 -08001796 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001797}
1798
tsepez4cf55152016-11-02 14:37:54 -07001799bool CFX_Edit::Backspace(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001800 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1801 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001802
Tom Sepez3509d162017-01-30 13:22:02 -08001803 CPVT_Section section;
1804 CPVT_Word word;
1805 if (bAddUndo) {
1806 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1807 pIterator->SetAt(m_wpCaret);
1808 pIterator->GetSection(section);
1809 pIterator->GetWord(word);
1810 }
1811 m_pVT->UpdateWordPlace(m_wpCaret);
1812 SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1813 m_SelState.Set(m_wpCaret, m_wpCaret);
1814 if (m_wpCaret == m_wpOldCaret)
1815 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001816
Tom Sepez3509d162017-01-30 13:22:02 -08001817 if (bAddUndo && m_bEnableUndo) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001818 if (m_wpCaret.nSecIndex != m_wpOldCaret.nSecIndex) {
Tom Sepez3509d162017-01-30 13:22:02 -08001819 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1820 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1821 section.SecProps, section.WordProps));
1822 } else {
1823 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1824 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1825 section.SecProps, word.WordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001826 }
1827 }
Tom Sepez3509d162017-01-30 13:22:02 -08001828 if (bPaint) {
1829 RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
1830 ScrollToCaret();
1831 Refresh();
1832 SetCaretOrigin();
1833 SetCaretInfo();
1834 }
1835 if (m_bOprNotify && m_pOprNotify)
1836 m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001837
Tom Sepez3509d162017-01-30 13:22:02 -08001838 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001839}
1840
tsepez4cf55152016-11-02 14:37:54 -07001841bool CFX_Edit::Delete(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001842 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1843 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001844
Tom Sepez3509d162017-01-30 13:22:02 -08001845 CPVT_Section section;
1846 CPVT_Word word;
1847 if (bAddUndo) {
1848 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1849 pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1850 pIterator->GetSection(section);
1851 pIterator->GetWord(word);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001852 }
Tom Sepez3509d162017-01-30 13:22:02 -08001853 m_pVT->UpdateWordPlace(m_wpCaret);
1854 bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1855 SetCaret(m_pVT->DeleteWord(m_wpCaret));
1856 m_SelState.Set(m_wpCaret, m_wpCaret);
1857 if (bAddUndo && m_bEnableUndo) {
1858 if (bSecEnd) {
1859 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1860 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1861 section.SecProps, section.WordProps, bSecEnd));
1862 } else {
1863 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1864 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1865 section.SecProps, word.WordProps, bSecEnd));
1866 }
1867 }
1868 if (bPaint) {
1869 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1870 ScrollToCaret();
1871 Refresh();
1872 SetCaretOrigin();
1873 SetCaretInfo();
1874 }
1875 if (m_bOprNotify && m_pOprNotify)
1876 m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001877
Tom Sepez3509d162017-01-30 13:22:02 -08001878 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001879}
1880
tsepez4cf55152016-11-02 14:37:54 -07001881bool CFX_Edit::Empty() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001882 if (m_pVT->IsValid()) {
1883 m_pVT->DeleteWords(GetWholeWordRange());
1884 SetCaret(m_pVT->GetBeginWordPlace());
1885
tsepez4cf55152016-11-02 14:37:54 -07001886 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001887 }
1888
tsepez4cf55152016-11-02 14:37:54 -07001889 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001890}
1891
tsepez4cf55152016-11-02 14:37:54 -07001892bool CFX_Edit::Clear(bool bAddUndo, bool bPaint) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001893 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
tsepez4cf55152016-11-02 14:37:54 -07001894 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001895
thestig821d59e2016-05-11 12:59:22 -07001896 CPVT_WordRange range = m_SelState.ConvertToWordRange();
dsinclaira2919b32016-07-13 10:55:48 -07001897 if (bAddUndo && m_bEnableUndo)
Tom Sepez3509d162017-01-30 13:22:02 -08001898 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Clear>(this, range, GetSelText()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001899
thestig821d59e2016-05-11 12:59:22 -07001900 SelectNone();
1901 SetCaret(m_pVT->DeleteWords(range));
1902 m_SelState.Set(m_wpCaret, m_wpCaret);
thestig821d59e2016-05-11 12:59:22 -07001903 if (bPaint) {
1904 RearrangePart(range);
1905 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001906 Refresh();
thestig821d59e2016-05-11 12:59:22 -07001907 SetCaretOrigin();
1908 SetCaretInfo();
1909 }
thestig821d59e2016-05-11 12:59:22 -07001910 if (m_bOprNotify && m_pOprNotify)
1911 m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);
1912
tsepez4cf55152016-11-02 14:37:54 -07001913 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001914}
1915
tsepez4cf55152016-11-02 14:37:54 -07001916bool CFX_Edit::InsertText(const CFX_WideString& sText,
1917 int32_t charset,
1918 bool bAddUndo,
1919 bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001920 if (IsTextOverflow())
tsepez4cf55152016-11-02 14:37:54 -07001921 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001922
1923 m_pVT->UpdateWordPlace(m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001924 SetCaret(DoInsertText(m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001925 m_SelState.Set(m_wpCaret, m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001926 if (m_wpCaret == m_wpOldCaret)
tsepez4cf55152016-11-02 14:37:54 -07001927 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001928
tsepeza31da742016-09-08 11:28:14 -07001929 if (bAddUndo && m_bEnableUndo) {
Tom Sepez3509d162017-01-30 13:22:02 -08001930 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertText>(
1931 this, m_wpOldCaret, m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001932 }
tsepeza31da742016-09-08 11:28:14 -07001933 if (bPaint)
1934 PaintInsertText(m_wpOldCaret, m_wpCaret);
1935
1936 if (m_bOprNotify && m_pOprNotify)
1937 m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
1938
tsepez4cf55152016-11-02 14:37:54 -07001939 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001940}
1941
1942void CFX_Edit::PaintInsertText(const CPVT_WordPlace& wpOld,
1943 const CPVT_WordPlace& wpNew) {
1944 if (m_pVT->IsValid()) {
1945 RearrangePart(CPVT_WordRange(wpOld, wpNew));
1946 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001947 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001948 SetCaretOrigin();
1949 SetCaretInfo();
1950 }
1951}
1952
tsepez4cf55152016-11-02 14:37:54 -07001953bool CFX_Edit::Redo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001954 if (m_bEnableUndo) {
1955 if (m_Undo.CanRedo()) {
1956 m_Undo.Redo();
tsepez4cf55152016-11-02 14:37:54 -07001957 return true;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001958 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001959 }
1960
tsepez4cf55152016-11-02 14:37:54 -07001961 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001962}
1963
tsepez4cf55152016-11-02 14:37:54 -07001964bool CFX_Edit::Undo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001965 if (m_bEnableUndo) {
1966 if (m_Undo.CanUndo()) {
1967 m_Undo.Undo();
tsepez4cf55152016-11-02 14:37:54 -07001968 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001969 }
1970 }
1971
tsepez4cf55152016-11-02 14:37:54 -07001972 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001973}
1974
1975void CFX_Edit::SetCaretOrigin() {
thestig821d59e2016-05-11 12:59:22 -07001976 if (!m_pVT->IsValid())
1977 return;
1978
1979 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1980 pIterator->SetAt(m_wpCaret);
1981 CPVT_Word word;
1982 CPVT_Line line;
1983 if (pIterator->GetWord(word)) {
1984 m_ptCaret.x = word.ptWord.x + word.fWidth;
1985 m_ptCaret.y = word.ptWord.y;
1986 } else if (pIterator->GetLine(line)) {
1987 m_ptCaret.x = line.ptLine.x;
1988 m_ptCaret.y = line.ptLine.y;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001989 }
1990}
1991
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001992CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const {
1993 if (m_pVT->IsValid())
1994 return m_pVT->WordIndexToWordPlace(index);
1995
1996 return CPVT_WordPlace();
1997}
1998
tsepez4cf55152016-11-02 14:37:54 -07001999bool CFX_Edit::IsTextFull() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002000 int32_t nTotalWords = m_pVT->GetTotalWords();
2001 int32_t nLimitChar = m_pVT->GetLimitChar();
2002 int32_t nCharArray = m_pVT->GetCharArray();
2003
2004 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
2005 (nCharArray > 0 && nTotalWords >= nCharArray);
2006}
2007
tsepez4cf55152016-11-02 14:37:54 -07002008bool CFX_Edit::IsTextOverflow() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002009 if (!m_bEnableScroll && !m_bEnableOverflow) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002010 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
2011 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002012
dsinclair448c4332016-08-02 12:07:35 -07002013 if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
2014 IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
tsepez4cf55152016-11-02 14:37:54 -07002015 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002016 }
2017
dsinclair448c4332016-08-02 12:07:35 -07002018 if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
tsepez4cf55152016-11-02 14:37:54 -07002019 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002020 }
2021
tsepez4cf55152016-11-02 14:37:54 -07002022 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002023}
2024
tsepez4cf55152016-11-02 14:37:54 -07002025bool CFX_Edit::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002026 if (m_bEnableUndo) {
2027 return m_Undo.CanUndo();
2028 }
2029
tsepez4cf55152016-11-02 14:37:54 -07002030 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002031}
2032
tsepez4cf55152016-11-02 14:37:54 -07002033bool CFX_Edit::CanRedo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002034 if (m_bEnableUndo) {
2035 return m_Undo.CanRedo();
2036 }
2037
tsepez4cf55152016-11-02 14:37:54 -07002038 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002039}
2040
tsepez4cf55152016-11-02 14:37:54 -07002041void CFX_Edit::EnableRefresh(bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002042 m_bEnableRefresh = bRefresh;
2043}
2044
tsepez4cf55152016-11-02 14:37:54 -07002045void CFX_Edit::EnableUndo(bool bUndo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002046 m_bEnableUndo = bUndo;
2047}
2048
tsepez4cf55152016-11-02 14:37:54 -07002049void CFX_Edit::EnableOprNotify(bool bNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002050 m_bOprNotify = bNotify;
2051}
2052
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002053CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place,
tsepeza31da742016-09-08 11:28:14 -07002054 const CFX_WideString& sText,
dsinclairefd5a992016-07-18 10:04:07 -07002055 int32_t charset) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002056 CPVT_WordPlace wp = place;
2057
2058 if (m_pVT->IsValid()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002059 for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
Tom Sepez62a70f92016-03-21 15:00:20 -07002060 uint16_t word = sText[i];
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002061 switch (word) {
2062 case 0x0D:
dsinclairefd5a992016-07-18 10:04:07 -07002063 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002064 if (sText[i + 1] == 0x0A)
2065 i++;
2066 break;
2067 case 0x0A:
dsinclairefd5a992016-07-18 10:04:07 -07002068 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002069 if (sText[i + 1] == 0x0D)
2070 i++;
2071 break;
2072 case 0x09:
2073 word = 0x20;
2074 default:
2075 wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
dsinclairefd5a992016-07-18 10:04:07 -07002076 nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002077 break;
2078 }
2079 }
2080 }
2081
2082 return wp;
2083}
2084
Tom Sepez62a70f92016-03-21 15:00:20 -07002085int32_t CFX_Edit::GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset) {
dsinclairc7a73492016-04-05 12:01:42 -07002086 if (IPVT_FontMap* pFontMap = GetFontMap())
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002087 return pFontMap->CharSetFromUnicode(word, nOldCharset);
2088 return nOldCharset;
2089}
2090
Tom Sepez3509d162017-01-30 13:22:02 -08002091void CFX_Edit::AddEditUndoItem(
2092 std::unique_ptr<CFX_Edit_UndoItem> pEditUndoItem) {
Lei Zhang1a89e362017-03-23 15:27:25 -07002093 m_Undo.AddItem(std::move(pEditUndoItem));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002094}
2095
weili625ad662016-06-15 11:21:33 -07002096CFX_Edit_LineRectArray::CFX_Edit_LineRectArray() {}
2097
Tom Sepez3509d162017-01-30 13:22:02 -08002098CFX_Edit_LineRectArray::~CFX_Edit_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07002099
Tom Sepez3509d162017-01-30 13:22:02 -08002100void CFX_Edit_LineRectArray::operator=(CFX_Edit_LineRectArray&& that) {
2101 m_LineRects = std::move(that.m_LineRects);
weili625ad662016-06-15 11:21:33 -07002102}
2103
2104void CFX_Edit_LineRectArray::Add(const CPVT_WordRange& wrLine,
2105 const CFX_FloatRect& rcLine) {
Tom Sepez3509d162017-01-30 13:22:02 -08002106 m_LineRects.push_back(pdfium::MakeUnique<CFX_Edit_LineRect>(wrLine, rcLine));
weili625ad662016-06-15 11:21:33 -07002107}
2108
2109int32_t CFX_Edit_LineRectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08002110 return pdfium::CollectionSize<int32_t>(m_LineRects);
weili625ad662016-06-15 11:21:33 -07002111}
2112
2113CFX_Edit_LineRect* CFX_Edit_LineRectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002114 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002115 return nullptr;
2116
Tom Sepez3509d162017-01-30 13:22:02 -08002117 return m_LineRects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002118}
2119
2120CFX_Edit_Select::CFX_Edit_Select() {}
2121
weili625ad662016-06-15 11:21:33 -07002122CFX_Edit_Select::CFX_Edit_Select(const CPVT_WordRange& range) {
2123 Set(range.BeginPos, range.EndPos);
2124}
2125
2126CPVT_WordRange CFX_Edit_Select::ConvertToWordRange() const {
2127 return CPVT_WordRange(BeginPos, EndPos);
2128}
2129
Tom Sepez52f69b32017-03-21 13:42:38 -07002130void CFX_Edit_Select::Reset() {
2131 BeginPos.Reset();
2132 EndPos.Reset();
weili625ad662016-06-15 11:21:33 -07002133}
2134
2135void CFX_Edit_Select::Set(const CPVT_WordPlace& begin,
2136 const CPVT_WordPlace& end) {
2137 BeginPos = begin;
2138 EndPos = end;
2139}
2140
weili625ad662016-06-15 11:21:33 -07002141void CFX_Edit_Select::SetEndPos(const CPVT_WordPlace& end) {
2142 EndPos = end;
2143}
2144
Tom Sepez52f69b32017-03-21 13:42:38 -07002145bool CFX_Edit_Select::IsEmpty() const {
2146 return BeginPos == EndPos;
weili625ad662016-06-15 11:21:33 -07002147}
2148
weili625ad662016-06-15 11:21:33 -07002149CFX_Edit_RectArray::CFX_Edit_RectArray() {}
2150
Tom Sepez3509d162017-01-30 13:22:02 -08002151CFX_Edit_RectArray::~CFX_Edit_RectArray() {}
weili625ad662016-06-15 11:21:33 -07002152
Tom Sepez3509d162017-01-30 13:22:02 -08002153void CFX_Edit_RectArray::Clear() {
2154 m_Rects.clear();
weili625ad662016-06-15 11:21:33 -07002155}
2156
2157void CFX_Edit_RectArray::Add(const CFX_FloatRect& rect) {
2158 // check for overlapped area
Tom Sepez3509d162017-01-30 13:22:02 -08002159 for (const auto& pRect : m_Rects) {
weili625ad662016-06-15 11:21:33 -07002160 if (pRect && pRect->Contains(rect))
2161 return;
2162 }
Tom Sepez3509d162017-01-30 13:22:02 -08002163 m_Rects.push_back(pdfium::MakeUnique<CFX_FloatRect>(rect));
weili625ad662016-06-15 11:21:33 -07002164}
2165
2166int32_t CFX_Edit_RectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08002167 return pdfium::CollectionSize<int32_t>(m_Rects);
weili625ad662016-06-15 11:21:33 -07002168}
2169
2170CFX_FloatRect* CFX_Edit_RectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002171 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002172 return nullptr;
2173
Tom Sepez3509d162017-01-30 13:22:02 -08002174 return m_Rects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002175}