blob: cf4fdc3d914997872d9a0ca79300ff0a090bf09d [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;
Tom Sepez1629f602017-04-21 14:11:26 -0700684 CFX_RenderDevice::StateRestorer restorer(pDevice);
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 }
dsinclaire35af1e2016-07-13 11:26:20 -0700773}
774
dsinclaire35af1e2016-07-13 11:26:20 -0700775CFX_Edit::CFX_Edit()
776 : m_pVT(new CPDF_VariableText),
thestig821d59e2016-05-11 12:59:22 -0700777 m_pNotify(nullptr),
778 m_pOprNotify(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700779 m_wpCaret(-1, -1, -1),
780 m_wpOldCaret(-1, -1, -1),
781 m_SelState(),
tsepez4cf55152016-11-02 14:37:54 -0700782 m_bEnableScroll(false),
dsinclair8f4bf9a2016-05-04 13:51:51 -0700783 m_Undo(kEditUndoMaxItems),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700784 m_nAlignment(0),
tsepez4cf55152016-11-02 14:37:54 -0700785 m_bNotifyFlag(false),
786 m_bEnableOverflow(false),
787 m_bEnableRefresh(true),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700788 m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f),
tsepez4cf55152016-11-02 14:37:54 -0700789 m_bEnableUndo(true),
Lei Zhang1a89e362017-03-23 15:27:25 -0700790 m_bOprNotify(false) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700791
Lei Zhang1a89e362017-03-23 15:27:25 -0700792CFX_Edit::~CFX_Edit() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700793
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700794void CFX_Edit::Initialize() {
795 m_pVT->Initialize();
796 SetCaret(m_pVT->GetBeginWordPlace());
797 SetCaretOrigin();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700798}
799
dsinclairc7a73492016-04-05 12:01:42 -0700800void CFX_Edit::SetFontMap(IPVT_FontMap* pFontMap) {
tsepez36eb4bd2016-10-03 15:24:27 -0700801 m_pVTProvider = pdfium::MakeUnique<CFX_Edit_Provider>(pFontMap);
thestig821d59e2016-05-11 12:59:22 -0700802 m_pVT->SetProvider(m_pVTProvider.get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700803}
804
dsinclaire35af1e2016-07-13 11:26:20 -0700805void CFX_Edit::SetNotify(CPWL_EditCtrl* pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700806 m_pNotify = pNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700807}
808
dsinclaire35af1e2016-07-13 11:26:20 -0700809void CFX_Edit::SetOprNotify(CPWL_Edit* pOprNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700810 m_pOprNotify = pOprNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700811}
812
dsinclaire35af1e2016-07-13 11:26:20 -0700813CFX_Edit_Iterator* CFX_Edit::GetIterator() {
tsepez36eb4bd2016-10-03 15:24:27 -0700814 if (!m_pIterator) {
815 m_pIterator =
816 pdfium::MakeUnique<CFX_Edit_Iterator>(this, m_pVT->GetIterator());
817 }
thestig821d59e2016-05-11 12:59:22 -0700818 return m_pIterator.get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700819}
820
dsinclairc7a73492016-04-05 12:01:42 -0700821IPVT_FontMap* CFX_Edit::GetFontMap() {
thestig821d59e2016-05-11 12:59:22 -0700822 return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700823}
824
dsinclairefd5a992016-07-18 10:04:07 -0700825void CFX_Edit::SetPlateRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700826 m_pVT->SetPlateRect(rect);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500827 m_ptScrollPos = CFX_PointF(rect.left, rect.top);
dsinclairefd5a992016-07-18 10:04:07 -0700828 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700829}
830
tsepez4cf55152016-11-02 14:37:54 -0700831void CFX_Edit::SetAlignmentH(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700832 m_pVT->SetAlignment(nFormat);
833 if (bPaint)
834 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700835}
836
tsepez4cf55152016-11-02 14:37:54 -0700837void CFX_Edit::SetAlignmentV(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700838 m_nAlignment = nFormat;
839 if (bPaint)
840 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700841}
842
tsepez4cf55152016-11-02 14:37:54 -0700843void CFX_Edit::SetPasswordChar(uint16_t wSubWord, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700844 m_pVT->SetPasswordChar(wSubWord);
845 if (bPaint)
846 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700847}
848
dsinclairefd5a992016-07-18 10:04:07 -0700849void CFX_Edit::SetLimitChar(int32_t nLimitChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700850 m_pVT->SetLimitChar(nLimitChar);
dsinclairefd5a992016-07-18 10:04:07 -0700851 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700852}
853
dsinclairefd5a992016-07-18 10:04:07 -0700854void CFX_Edit::SetCharArray(int32_t nCharArray) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700855 m_pVT->SetCharArray(nCharArray);
dsinclairefd5a992016-07-18 10:04:07 -0700856 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700857}
858
Dan Sinclair05df0752017-03-14 14:43:42 -0400859void CFX_Edit::SetCharSpace(float fCharSpace) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700860 m_pVT->SetCharSpace(fCharSpace);
dsinclairefd5a992016-07-18 10:04:07 -0700861 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700862}
863
tsepez4cf55152016-11-02 14:37:54 -0700864void CFX_Edit::SetMultiLine(bool bMultiLine, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700865 m_pVT->SetMultiLine(bMultiLine);
866 if (bPaint)
867 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700868}
869
tsepez4cf55152016-11-02 14:37:54 -0700870void CFX_Edit::SetAutoReturn(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700871 m_pVT->SetAutoReturn(bAuto);
872 if (bPaint)
873 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700874}
875
tsepez4cf55152016-11-02 14:37:54 -0700876void CFX_Edit::SetAutoFontSize(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700877 m_pVT->SetAutoFontSize(bAuto);
878 if (bPaint)
879 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700880}
881
Dan Sinclair05df0752017-03-14 14:43:42 -0400882void CFX_Edit::SetFontSize(float fFontSize) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700883 m_pVT->SetFontSize(fFontSize);
dsinclairefd5a992016-07-18 10:04:07 -0700884 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700885}
886
tsepez4cf55152016-11-02 14:37:54 -0700887void CFX_Edit::SetAutoScroll(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700888 m_bEnableScroll = bAuto;
889 if (bPaint)
890 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700891}
892
tsepez4cf55152016-11-02 14:37:54 -0700893void CFX_Edit::SetTextOverflow(bool bAllowed, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700894 m_bEnableOverflow = bAllowed;
895 if (bPaint)
896 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700897}
898
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700899void CFX_Edit::SetSel(int32_t nStartChar, int32_t nEndChar) {
900 if (m_pVT->IsValid()) {
901 if (nStartChar == 0 && nEndChar < 0) {
902 SelectAll();
903 } else if (nStartChar < 0) {
904 SelectNone();
905 } else {
906 if (nStartChar < nEndChar) {
907 SetSel(m_pVT->WordIndexToWordPlace(nStartChar),
908 m_pVT->WordIndexToWordPlace(nEndChar));
909 } else {
910 SetSel(m_pVT->WordIndexToWordPlace(nEndChar),
911 m_pVT->WordIndexToWordPlace(nStartChar));
912 }
913 }
914 }
915}
916
917void CFX_Edit::SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700918 if (!m_pVT->IsValid())
919 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700920
Tom Sepez52f69b32017-03-21 13:42:38 -0700921 SelectNone();
922 m_SelState.Set(begin, end);
923 SetCaret(m_SelState.EndPos);
924 ScrollToCaret();
925 if (!m_SelState.IsEmpty())
926 Refresh();
927 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700928}
929
930void CFX_Edit::GetSel(int32_t& nStartChar, int32_t& nEndChar) const {
931 nStartChar = -1;
932 nEndChar = -1;
Tom Sepez52f69b32017-03-21 13:42:38 -0700933 if (!m_pVT->IsValid())
934 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700935
Tom Sepez52f69b32017-03-21 13:42:38 -0700936 if (m_SelState.IsEmpty()) {
937 nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
938 nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
939 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700940 }
Tom Sepez52f69b32017-03-21 13:42:38 -0700941 if (m_SelState.BeginPos < m_SelState.EndPos) {
942 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
943 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
944 return;
945 }
946 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
947 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700948}
949
950int32_t CFX_Edit::GetCaret() const {
951 if (m_pVT->IsValid())
952 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
953
954 return -1;
955}
956
957CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const {
958 return m_wpCaret;
959}
960
961CFX_WideString CFX_Edit::GetText() const {
962 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700963 if (!m_pVT->IsValid())
964 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700965
thestig821d59e2016-05-11 12:59:22 -0700966 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
967 pIterator->SetAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700968
thestig821d59e2016-05-11 12:59:22 -0700969 CPVT_Word wordinfo;
970 CPVT_WordPlace oldplace = pIterator->GetAt();
971 while (pIterator->NextWord()) {
972 CPVT_WordPlace place = pIterator->GetAt();
thestig821d59e2016-05-11 12:59:22 -0700973 if (pIterator->GetWord(wordinfo))
974 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700975 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700976 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700977 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700978 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700979 return swRet;
980}
981
982CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange& range) const {
983 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700984 if (!m_pVT->IsValid())
985 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700986
thestig821d59e2016-05-11 12:59:22 -0700987 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
988 CPVT_WordRange wrTemp = range;
989 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
990 m_pVT->UpdateWordPlace(wrTemp.EndPos);
991 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700992
thestig821d59e2016-05-11 12:59:22 -0700993 CPVT_Word wordinfo;
994 CPVT_WordPlace oldplace = wrTemp.BeginPos;
995 while (pIterator->NextWord()) {
996 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700997 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -0700998 break;
thestig821d59e2016-05-11 12:59:22 -0700999 if (pIterator->GetWord(wordinfo))
1000 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -07001001 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -07001002 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -07001003 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001004 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001005 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001006}
1007
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001008CFX_WideString CFX_Edit::GetSelText() const {
1009 return GetRangeText(m_SelState.ConvertToWordRange());
1010}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001011
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001012int32_t CFX_Edit::GetTotalLines() const {
thestig821d59e2016-05-11 12:59:22 -07001013 int32_t nLines = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001014
thestig821d59e2016-05-11 12:59:22 -07001015 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1016 pIterator->SetAt(0);
1017 while (pIterator->NextLine())
1018 ++nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001019
thestig821d59e2016-05-11 12:59:22 -07001020 return nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001021}
1022
1023CPVT_WordRange CFX_Edit::GetSelectWordRange() const {
1024 return m_SelState.ConvertToWordRange();
1025}
1026
tsepeza31da742016-09-08 11:28:14 -07001027void CFX_Edit::SetText(const CFX_WideString& sText) {
dsinclairefd5a992016-07-18 10:04:07 -07001028 Empty();
Dan Sinclairf51a02a2017-04-19 12:46:53 -04001029 DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_CHARSET_Default);
dsinclairefd5a992016-07-18 10:04:07 -07001030 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001031}
1032
tsepez4cf55152016-11-02 14:37:54 -07001033bool CFX_Edit::InsertWord(uint16_t word, int32_t charset) {
1034 return InsertWord(word, charset, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001035}
1036
tsepez4cf55152016-11-02 14:37:54 -07001037bool CFX_Edit::InsertReturn() {
1038 return InsertReturn(nullptr, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001039}
1040
tsepez4cf55152016-11-02 14:37:54 -07001041bool CFX_Edit::Backspace() {
1042 return Backspace(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001043}
1044
tsepez4cf55152016-11-02 14:37:54 -07001045bool CFX_Edit::Delete() {
1046 return Delete(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001047}
1048
tsepez4cf55152016-11-02 14:37:54 -07001049bool CFX_Edit::Clear() {
1050 return Clear(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001051}
1052
tsepez4cf55152016-11-02 14:37:54 -07001053bool CFX_Edit::InsertText(const CFX_WideString& sText, int32_t charset) {
1054 return InsertText(sText, charset, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001055}
1056
Dan Sinclair05df0752017-03-14 14:43:42 -04001057float CFX_Edit::GetFontSize() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001058 return m_pVT->GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001059}
1060
Tom Sepez62a70f92016-03-21 15:00:20 -07001061uint16_t CFX_Edit::GetPasswordChar() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001062 return m_pVT->GetPasswordChar();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001063}
1064
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001065int32_t CFX_Edit::GetCharArray() const {
1066 return m_pVT->GetCharArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001067}
1068
Tom Sepez281a9ea2016-02-26 14:24:28 -08001069CFX_FloatRect CFX_Edit::GetContentRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001070 return VTToEdit(m_pVT->GetContentRect());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001071}
1072
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001073int32_t CFX_Edit::GetHorzScale() const {
1074 return m_pVT->GetHorzScale();
1075}
1076
Dan Sinclair05df0752017-03-14 14:43:42 -04001077float CFX_Edit::GetCharSpace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001078 return m_pVT->GetCharSpace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001079}
1080
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001081CPVT_WordRange CFX_Edit::GetWholeWordRange() const {
1082 if (m_pVT->IsValid())
1083 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001084
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001085 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001086}
1087
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001088CPVT_WordRange CFX_Edit::GetVisibleWordRange() const {
1089 if (m_bEnableOverflow)
1090 return GetWholeWordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001091
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001092 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001093 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001094
Dan Sinclairf528eee2017-02-14 11:52:07 -05001095 CPVT_WordPlace place1 =
1096 m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001097 CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
Dan Sinclairf528eee2017-02-14 11:52:07 -05001098 EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001099
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001100 return CPVT_WordRange(place1, place2);
1101 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001102
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001103 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001104}
1105
Dan Sinclairf528eee2017-02-14 11:52:07 -05001106CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_PointF& point) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001107 if (m_pVT->IsValid()) {
1108 return m_pVT->SearchWordPlace(EditToVT(point));
1109 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001110
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001111 return CPVT_WordPlace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001112}
1113
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001114void CFX_Edit::Paint() {
1115 if (m_pVT->IsValid()) {
1116 RearrangeAll();
1117 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001118 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001119 SetCaretOrigin();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001120 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001121 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001122}
1123
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001124void CFX_Edit::RearrangeAll() {
1125 if (m_pVT->IsValid()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001126 m_pVT->UpdateWordPlace(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001127 m_pVT->RearrangeAll();
1128 m_pVT->UpdateWordPlace(m_wpCaret);
1129 SetScrollInfo();
1130 SetContentChanged();
1131 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001132}
1133
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001134void CFX_Edit::RearrangePart(const CPVT_WordRange& range) {
1135 if (m_pVT->IsValid()) {
1136 m_pVT->UpdateWordPlace(m_wpCaret);
1137 m_pVT->RearrangePart(range);
1138 m_pVT->UpdateWordPlace(m_wpCaret);
1139 SetScrollInfo();
1140 SetContentChanged();
1141 }
1142}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001143
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001144void CFX_Edit::SetContentChanged() {
dsinclaira2919b32016-07-13 10:55:48 -07001145 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001146 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001147 if (rcContent.Width() != m_rcOldContent.Width() ||
1148 rcContent.Height() != m_rcOldContent.Height()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001149 m_rcOldContent = rcContent;
1150 }
1151 }
1152}
1153
1154void CFX_Edit::SelectAll() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001155 if (!m_pVT->IsValid())
1156 return;
1157 m_SelState = CFX_Edit_Select(GetWholeWordRange());
1158 SetCaret(m_SelState.EndPos);
1159 ScrollToCaret();
1160 Refresh();
1161 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001162}
1163
1164void CFX_Edit::SelectNone() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001165 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
1166 return;
1167
1168 m_SelState.Reset();
1169 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001170}
1171
tsepez4cf55152016-11-02 14:37:54 -07001172bool CFX_Edit::IsSelected() const {
Tom Sepez52f69b32017-03-21 13:42:38 -07001173 return !m_SelState.IsEmpty();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001174}
1175
Dan Sinclairf528eee2017-02-14 11:52:07 -05001176CFX_PointF CFX_Edit::VTToEdit(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001177 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1178 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001179
Dan Sinclair05df0752017-03-14 14:43:42 -04001180 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001181
1182 switch (m_nAlignment) {
1183 case 0:
1184 fPadding = 0.0f;
1185 break;
1186 case 1:
1187 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1188 break;
1189 case 2:
1190 fPadding = rcPlate.Height() - rcContent.Height();
1191 break;
1192 }
1193
Dan Sinclairf528eee2017-02-14 11:52:07 -05001194 return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
1195 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001196}
1197
Dan Sinclairf528eee2017-02-14 11:52:07 -05001198CFX_PointF CFX_Edit::EditToVT(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001199 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1200 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001201
Dan Sinclair05df0752017-03-14 14:43:42 -04001202 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001203
1204 switch (m_nAlignment) {
1205 case 0:
1206 fPadding = 0.0f;
1207 break;
1208 case 1:
1209 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1210 break;
1211 case 2:
1212 fPadding = rcPlate.Height() - rcContent.Height();
1213 break;
1214 }
1215
Dan Sinclairf528eee2017-02-14 11:52:07 -05001216 return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
1217 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001218}
1219
Tom Sepez281a9ea2016-02-26 14:24:28 -08001220CFX_FloatRect CFX_Edit::VTToEdit(const CFX_FloatRect& rect) const {
Dan Sinclairf528eee2017-02-14 11:52:07 -05001221 CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
1222 CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001223
Tom Sepez281a9ea2016-02-26 14:24:28 -08001224 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1225 ptRightTop.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001226}
1227
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001228void CFX_Edit::SetScrollInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001229 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001230 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1231 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001232
1233 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001234 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001235 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001236 m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
1237 rcContent.bottom, rcContent.top,
1238 rcPlate.Height() / 3, rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001239 }
1240 }
1241}
1242
Dan Sinclair05df0752017-03-14 14:43:42 -04001243void CFX_Edit::SetScrollPosX(float fx) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001244 if (!m_bEnableScroll)
1245 return;
1246
1247 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001248 if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001249 m_ptScrollPos.x = fx;
dsinclairefd5a992016-07-18 10:04:07 -07001250 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001251 }
1252 }
1253}
1254
Dan Sinclair05df0752017-03-14 14:43:42 -04001255void CFX_Edit::SetScrollPosY(float fy) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001256 if (!m_bEnableScroll)
1257 return;
1258
1259 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001260 if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001261 m_ptScrollPos.y = fy;
dsinclairefd5a992016-07-18 10:04:07 -07001262 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001263
dsinclaira2919b32016-07-13 10:55:48 -07001264 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001265 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001266 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001267 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001268 m_pNotify->IOnSetScrollPosY(fy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001269 }
1270 }
1271 }
1272 }
1273}
1274
Dan Sinclairf528eee2017-02-14 11:52:07 -05001275void CFX_Edit::SetScrollPos(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001276 SetScrollPosX(point.x);
1277 SetScrollPosY(point.y);
1278 SetScrollLimit();
1279 SetCaretInfo();
1280}
1281
Dan Sinclairf528eee2017-02-14 11:52:07 -05001282CFX_PointF CFX_Edit::GetScrollPos() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001283 return m_ptScrollPos;
1284}
1285
1286void CFX_Edit::SetScrollLimit() {
1287 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001288 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1289 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001290
1291 if (rcPlate.Width() > rcContent.Width()) {
1292 SetScrollPosX(rcPlate.left);
1293 } else {
dsinclair448c4332016-08-02 12:07:35 -07001294 if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001295 SetScrollPosX(rcContent.left);
dsinclair448c4332016-08-02 12:07:35 -07001296 } else if (IsFloatBigger(m_ptScrollPos.x,
1297 rcContent.right - rcPlate.Width())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001298 SetScrollPosX(rcContent.right - rcPlate.Width());
1299 }
1300 }
1301
1302 if (rcPlate.Height() > rcContent.Height()) {
1303 SetScrollPosY(rcPlate.top);
1304 } else {
dsinclair448c4332016-08-02 12:07:35 -07001305 if (IsFloatSmaller(m_ptScrollPos.y,
1306 rcContent.bottom + rcPlate.Height())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001307 SetScrollPosY(rcContent.bottom + rcPlate.Height());
dsinclair448c4332016-08-02 12:07:35 -07001308 } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001309 SetScrollPosY(rcContent.top);
1310 }
1311 }
1312 }
1313}
1314
1315void CFX_Edit::ScrollToCaret() {
1316 SetScrollLimit();
1317
thestig821d59e2016-05-11 12:59:22 -07001318 if (!m_pVT->IsValid())
1319 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001320
thestig821d59e2016-05-11 12:59:22 -07001321 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1322 pIterator->SetAt(m_wpCaret);
1323
Dan Sinclairf528eee2017-02-14 11:52:07 -05001324 CFX_PointF ptHead;
1325 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001326 CPVT_Word word;
1327 CPVT_Line line;
1328 if (pIterator->GetWord(word)) {
1329 ptHead.x = word.ptWord.x + word.fWidth;
1330 ptHead.y = word.ptWord.y + word.fAscent;
1331 ptFoot.x = word.ptWord.x + word.fWidth;
1332 ptFoot.y = word.ptWord.y + word.fDescent;
1333 } else if (pIterator->GetLine(line)) {
1334 ptHead.x = line.ptLine.x;
1335 ptHead.y = line.ptLine.y + line.fLineAscent;
1336 ptFoot.x = line.ptLine.x;
1337 ptFoot.y = line.ptLine.y + line.fLineDescent;
1338 }
1339
Dan Sinclairf528eee2017-02-14 11:52:07 -05001340 CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1341 CFX_PointF ptFootEdit = VTToEdit(ptFoot);
thestig821d59e2016-05-11 12:59:22 -07001342 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
dsinclair448c4332016-08-02 12:07:35 -07001343 if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
1344 if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
1345 IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
thestig821d59e2016-05-11 12:59:22 -07001346 SetScrollPosX(ptHead.x);
dsinclair448c4332016-08-02 12:07:35 -07001347 } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
thestig821d59e2016-05-11 12:59:22 -07001348 SetScrollPosX(ptHead.x - rcPlate.Width());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001349 }
thestig821d59e2016-05-11 12:59:22 -07001350 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001351
dsinclair448c4332016-08-02 12:07:35 -07001352 if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
1353 if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
1354 IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
1355 if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
thestig821d59e2016-05-11 12:59:22 -07001356 SetScrollPosY(ptFoot.y + rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001357 }
dsinclair448c4332016-08-02 12:07:35 -07001358 } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
1359 if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
thestig821d59e2016-05-11 12:59:22 -07001360 SetScrollPosY(ptHead.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001361 }
1362 }
1363 }
1364}
1365
dsinclairefd5a992016-07-18 10:04:07 -07001366void CFX_Edit::Refresh() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001367 if (m_bEnableRefresh && m_pVT->IsValid()) {
1368 m_Refresh.BeginRefresh();
1369 RefreshPushLineRects(GetVisibleWordRange());
1370
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001371 m_Refresh.NoAnalyse();
1372 m_ptRefreshScrollPos = m_ptScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001373
dsinclaira2919b32016-07-13 10:55:48 -07001374 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001375 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001376 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001377 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001378 if (const CFX_Edit_RectArray* pRects = m_Refresh.GetRefreshRects()) {
1379 for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
1380 m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
1381 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001382 }
1383 }
1384
1385 m_Refresh.EndRefresh();
1386 }
1387}
1388
1389void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001390 if (!m_pVT->IsValid())
1391 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001392
thestig821d59e2016-05-11 12:59:22 -07001393 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1394 CPVT_WordPlace wpBegin = wr.BeginPos;
1395 m_pVT->UpdateWordPlace(wpBegin);
1396 CPVT_WordPlace wpEnd = wr.EndPos;
1397 m_pVT->UpdateWordPlace(wpEnd);
1398 pIterator->SetAt(wpBegin);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001399
thestig821d59e2016-05-11 12:59:22 -07001400 CPVT_Line lineinfo;
1401 do {
1402 if (!pIterator->GetLine(lineinfo))
1403 break;
1404 if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
1405 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001406
thestig821d59e2016-05-11 12:59:22 -07001407 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1408 lineinfo.ptLine.y + lineinfo.fLineDescent,
1409 lineinfo.ptLine.x + lineinfo.fLineWidth,
1410 lineinfo.ptLine.y + lineinfo.fLineAscent);
1411
1412 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1413 VTToEdit(rcLine));
1414 } while (pIterator->NextLine());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001415}
1416
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001417void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001418 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1419 CPVT_WordRange wrTemp = wr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001420
thestig821d59e2016-05-11 12:59:22 -07001421 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1422 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1423 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001424
thestig821d59e2016-05-11 12:59:22 -07001425 CPVT_Word wordinfo;
1426 CPVT_Line lineinfo;
1427 CPVT_WordPlace place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001428
thestig821d59e2016-05-11 12:59:22 -07001429 while (pIterator->NextWord()) {
1430 place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -07001431 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -07001432 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001433
thestig821d59e2016-05-11 12:59:22 -07001434 pIterator->GetWord(wordinfo);
1435 pIterator->GetLine(lineinfo);
thestig821d59e2016-05-11 12:59:22 -07001436 if (place.LineCmp(wrTemp.BeginPos) == 0 ||
1437 place.LineCmp(wrTemp.EndPos) == 0) {
1438 CFX_FloatRect rcWord(wordinfo.ptWord.x,
1439 lineinfo.ptLine.y + lineinfo.fLineDescent,
1440 wordinfo.ptWord.x + wordinfo.fWidth,
1441 lineinfo.ptLine.y + lineinfo.fLineAscent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001442
dsinclaira2919b32016-07-13 10:55:48 -07001443 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001444 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001445 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001446 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001447 CFX_FloatRect rcRefresh = VTToEdit(rcWord);
1448 m_pNotify->IOnInvalidateRect(&rcRefresh);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001449 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001450 }
thestig821d59e2016-05-11 12:59:22 -07001451 } else {
1452 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1453 lineinfo.ptLine.y + lineinfo.fLineDescent,
1454 lineinfo.ptLine.x + lineinfo.fLineWidth,
1455 lineinfo.ptLine.y + lineinfo.fLineAscent);
1456
dsinclaira2919b32016-07-13 10:55:48 -07001457 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001458 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001459 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001460 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001461 CFX_FloatRect rcRefresh = VTToEdit(rcLine);
1462 m_pNotify->IOnInvalidateRect(&rcRefresh);
thestig821d59e2016-05-11 12:59:22 -07001463 }
1464 }
1465
1466 pIterator->NextLine();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001467 }
1468 }
1469}
1470
1471void CFX_Edit::SetCaret(const CPVT_WordPlace& place) {
1472 m_wpOldCaret = m_wpCaret;
1473 m_wpCaret = place;
1474}
1475
1476void CFX_Edit::SetCaretInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001477 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001478 if (!m_bNotifyFlag) {
thestig821d59e2016-05-11 12:59:22 -07001479 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1480 pIterator->SetAt(m_wpCaret);
tsepez63f545c2016-09-13 16:08:49 -07001481
Dan Sinclairf528eee2017-02-14 11:52:07 -05001482 CFX_PointF ptHead;
1483 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001484 CPVT_Word word;
1485 CPVT_Line line;
1486 if (pIterator->GetWord(word)) {
1487 ptHead.x = word.ptWord.x + word.fWidth;
1488 ptHead.y = word.ptWord.y + word.fAscent;
1489 ptFoot.x = word.ptWord.x + word.fWidth;
1490 ptFoot.y = word.ptWord.y + word.fDescent;
1491 } else if (pIterator->GetLine(line)) {
1492 ptHead.x = line.ptLine.x;
1493 ptHead.y = line.ptLine.y + line.fLineAscent;
1494 ptFoot.x = line.ptLine.x;
1495 ptFoot.y = line.ptLine.y + line.fLineDescent;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001496 }
1497
Lei Zhanga8c2b912017-03-22 17:41:02 -07001498 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001499 m_bNotifyFlag = true;
Tom Sepez52f69b32017-03-21 13:42:38 -07001500 m_pNotify->IOnSetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead),
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001501 VTToEdit(ptFoot), m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001502 }
1503 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001504}
1505
Dan Sinclairf528eee2017-02-14 11:52:07 -05001506void CFX_Edit::OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001507 if (!m_pVT->IsValid())
1508 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001509
Tom Sepez52f69b32017-03-21 13:42:38 -07001510 SelectNone();
1511 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1512 m_SelState.Set(m_wpCaret, m_wpCaret);
1513 ScrollToCaret();
1514 SetCaretOrigin();
1515 SetCaretInfo();
1516}
1517
1518void CFX_Edit::OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl) {
1519 if (!m_pVT->IsValid())
1520 return;
1521
1522 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1523 if (m_wpCaret == m_wpOldCaret)
1524 return;
1525
1526 m_SelState.SetEndPos(m_wpCaret);
1527 ScrollToCaret();
1528 Refresh();
1529 SetCaretOrigin();
1530 SetCaretInfo();
1531}
1532
1533void CFX_Edit::OnVK_UP(bool bShift, bool bCtrl) {
1534 if (!m_pVT->IsValid())
1535 return;
1536
1537 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1538 if (bShift) {
1539 if (m_SelState.IsEmpty())
1540 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1541 else
1542 m_SelState.SetEndPos(m_wpCaret);
1543
1544 if (m_wpOldCaret != m_wpCaret) {
1545 ScrollToCaret();
1546 Refresh();
1547 SetCaretInfo();
1548 }
1549 } else {
1550 SelectNone();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001551 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001552 SetCaretInfo();
1553 }
1554}
1555
Tom Sepez52f69b32017-03-21 13:42:38 -07001556void CFX_Edit::OnVK_DOWN(bool bShift, bool bCtrl) {
1557 if (!m_pVT->IsValid())
1558 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001559
Tom Sepez52f69b32017-03-21 13:42:38 -07001560 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1561 if (bShift) {
1562 if (m_SelState.IsEmpty())
1563 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1564 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001565 m_SelState.SetEndPos(m_wpCaret);
1566
Tom Sepez52f69b32017-03-21 13:42:38 -07001567 if (m_wpOldCaret != m_wpCaret) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001568 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001569 Refresh();
Tom Sepez52f69b32017-03-21 13:42:38 -07001570 SetCaretInfo();
1571 }
1572 } else {
1573 SelectNone();
1574 ScrollToCaret();
1575 SetCaretInfo();
1576 }
1577}
1578
1579void CFX_Edit::OnVK_LEFT(bool bShift, bool bCtrl) {
1580 if (!m_pVT->IsValid())
1581 return;
1582
1583 if (bShift) {
1584 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1585 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1586 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1587 }
1588 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1589 if (m_SelState.IsEmpty())
1590 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1591 else
1592 m_SelState.SetEndPos(m_wpCaret);
1593
1594 if (m_wpOldCaret != m_wpCaret) {
1595 ScrollToCaret();
1596 Refresh();
1597 SetCaretInfo();
1598 }
1599 } else {
1600 if (!m_SelState.IsEmpty()) {
1601 if (m_SelState.BeginPos < m_SelState.EndPos)
1602 SetCaret(m_SelState.BeginPos);
1603 else
1604 SetCaret(m_SelState.EndPos);
1605
1606 SelectNone();
1607 ScrollToCaret();
1608 SetCaretInfo();
1609 } else {
1610 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1611 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1612 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1613 }
1614 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1615 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001616 SetCaretOrigin();
1617 SetCaretInfo();
1618 }
1619 }
1620}
1621
tsepez4cf55152016-11-02 14:37:54 -07001622void CFX_Edit::OnVK_RIGHT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001623 if (!m_pVT->IsValid())
1624 return;
1625
1626 if (bShift) {
1627 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1628 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1629 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001630 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1631
Tom Sepez52f69b32017-03-21 13:42:38 -07001632 if (m_SelState.IsEmpty())
1633 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1634 else
1635 m_SelState.SetEndPos(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001636
Tom Sepez52f69b32017-03-21 13:42:38 -07001637 if (m_wpOldCaret != m_wpCaret) {
1638 ScrollToCaret();
1639 Refresh();
1640 SetCaretInfo();
1641 }
1642 } else {
1643 if (!m_SelState.IsEmpty()) {
1644 if (m_SelState.BeginPos > m_SelState.EndPos)
1645 SetCaret(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001646 else
Tom Sepez52f69b32017-03-21 13:42:38 -07001647 SetCaret(m_SelState.EndPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001648
Tom Sepez52f69b32017-03-21 13:42:38 -07001649 SelectNone();
1650 ScrollToCaret();
1651 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001652 } else {
Tom Sepez52f69b32017-03-21 13:42:38 -07001653 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1654 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1655 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001656 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001657 }
Tom Sepez52f69b32017-03-21 13:42:38 -07001658 ScrollToCaret();
1659 SetCaretOrigin();
1660 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001661 }
1662 }
1663}
1664
tsepez4cf55152016-11-02 14:37:54 -07001665void CFX_Edit::OnVK_HOME(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001666 if (!m_pVT->IsValid())
1667 return;
1668
1669 if (bShift) {
1670 if (bCtrl)
1671 SetCaret(m_pVT->GetBeginWordPlace());
1672 else
1673 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1674
1675 if (m_SelState.IsEmpty())
1676 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1677 else
1678 m_SelState.SetEndPos(m_wpCaret);
1679
1680 ScrollToCaret();
1681 Refresh();
1682 SetCaretInfo();
1683 } else {
1684 if (!m_SelState.IsEmpty()) {
1685 SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos));
1686 SelectNone();
1687 ScrollToCaret();
1688 SetCaretInfo();
1689 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001690 if (bCtrl)
1691 SetCaret(m_pVT->GetBeginWordPlace());
1692 else
1693 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1694
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001695 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001696 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001697 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001698 }
1699 }
1700}
1701
tsepez4cf55152016-11-02 14:37:54 -07001702void CFX_Edit::OnVK_END(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001703 if (!m_pVT->IsValid())
1704 return;
1705
1706 if (bShift) {
1707 if (bCtrl)
1708 SetCaret(m_pVT->GetEndWordPlace());
1709 else
1710 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1711
1712 if (m_SelState.IsEmpty())
1713 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1714 else
1715 m_SelState.SetEndPos(m_wpCaret);
1716
1717 ScrollToCaret();
1718 Refresh();
1719 SetCaretInfo();
1720 } else {
1721 if (!m_SelState.IsEmpty()) {
1722 SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos));
1723 SelectNone();
1724 ScrollToCaret();
1725 SetCaretInfo();
1726 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001727 if (bCtrl)
1728 SetCaret(m_pVT->GetEndWordPlace());
1729 else
1730 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1731
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001732 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001733 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001734 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001735 }
1736 }
1737}
1738
tsepez4cf55152016-11-02 14:37:54 -07001739bool CFX_Edit::InsertWord(uint16_t word,
1740 int32_t charset,
1741 const CPVT_WordProps* pWordProps,
1742 bool bAddUndo,
1743 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001744 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001745 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001746
Tom Sepez3509d162017-01-30 13:22:02 -08001747 m_pVT->UpdateWordPlace(m_wpCaret);
1748 SetCaret(m_pVT->InsertWord(m_wpCaret, word,
1749 GetCharSetFromUnicode(word, charset), pWordProps));
1750 m_SelState.Set(m_wpCaret, m_wpCaret);
1751 if (m_wpCaret == m_wpOldCaret)
1752 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001753
Tom Sepez3509d162017-01-30 13:22:02 -08001754 if (bAddUndo && m_bEnableUndo) {
1755 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertWord>(
1756 this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001757 }
Tom Sepez3509d162017-01-30 13:22:02 -08001758 if (bPaint)
1759 PaintInsertText(m_wpOldCaret, m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001760
Tom Sepez3509d162017-01-30 13:22:02 -08001761 if (m_bOprNotify && m_pOprNotify)
1762 m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
1763
1764 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001765}
1766
tsepez4cf55152016-11-02 14:37:54 -07001767bool CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps,
1768 const CPVT_WordProps* pWordProps,
1769 bool bAddUndo,
1770 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001771 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001772 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001773
Tom Sepez3509d162017-01-30 13:22:02 -08001774 m_pVT->UpdateWordPlace(m_wpCaret);
1775 SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
1776 m_SelState.Set(m_wpCaret, m_wpCaret);
1777 if (m_wpCaret == m_wpOldCaret)
1778 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001779
Tom Sepez3509d162017-01-30 13:22:02 -08001780 if (bAddUndo && m_bEnableUndo) {
1781 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertReturn>(
1782 this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001783 }
Tom Sepez3509d162017-01-30 13:22:02 -08001784 if (bPaint) {
1785 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1786 ScrollToCaret();
1787 Refresh();
1788 SetCaretOrigin();
1789 SetCaretInfo();
1790 }
1791 if (m_bOprNotify && m_pOprNotify)
1792 m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001793
Tom Sepez3509d162017-01-30 13:22:02 -08001794 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001795}
1796
tsepez4cf55152016-11-02 14:37:54 -07001797bool CFX_Edit::Backspace(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001798 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1799 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001800
Tom Sepez3509d162017-01-30 13:22:02 -08001801 CPVT_Section section;
1802 CPVT_Word word;
1803 if (bAddUndo) {
1804 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1805 pIterator->SetAt(m_wpCaret);
1806 pIterator->GetSection(section);
1807 pIterator->GetWord(word);
1808 }
1809 m_pVT->UpdateWordPlace(m_wpCaret);
1810 SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1811 m_SelState.Set(m_wpCaret, m_wpCaret);
1812 if (m_wpCaret == m_wpOldCaret)
1813 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001814
Tom Sepez3509d162017-01-30 13:22:02 -08001815 if (bAddUndo && m_bEnableUndo) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001816 if (m_wpCaret.nSecIndex != m_wpOldCaret.nSecIndex) {
Tom Sepez3509d162017-01-30 13:22:02 -08001817 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1818 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1819 section.SecProps, section.WordProps));
1820 } else {
1821 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1822 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1823 section.SecProps, word.WordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001824 }
1825 }
Tom Sepez3509d162017-01-30 13:22:02 -08001826 if (bPaint) {
1827 RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
1828 ScrollToCaret();
1829 Refresh();
1830 SetCaretOrigin();
1831 SetCaretInfo();
1832 }
1833 if (m_bOprNotify && m_pOprNotify)
1834 m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001835
Tom Sepez3509d162017-01-30 13:22:02 -08001836 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001837}
1838
tsepez4cf55152016-11-02 14:37:54 -07001839bool CFX_Edit::Delete(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001840 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1841 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001842
Tom Sepez3509d162017-01-30 13:22:02 -08001843 CPVT_Section section;
1844 CPVT_Word word;
1845 if (bAddUndo) {
1846 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1847 pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1848 pIterator->GetSection(section);
1849 pIterator->GetWord(word);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001850 }
Tom Sepez3509d162017-01-30 13:22:02 -08001851 m_pVT->UpdateWordPlace(m_wpCaret);
1852 bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1853 SetCaret(m_pVT->DeleteWord(m_wpCaret));
1854 m_SelState.Set(m_wpCaret, m_wpCaret);
1855 if (bAddUndo && m_bEnableUndo) {
1856 if (bSecEnd) {
1857 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1858 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1859 section.SecProps, section.WordProps, bSecEnd));
1860 } else {
1861 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1862 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1863 section.SecProps, word.WordProps, bSecEnd));
1864 }
1865 }
1866 if (bPaint) {
1867 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1868 ScrollToCaret();
1869 Refresh();
1870 SetCaretOrigin();
1871 SetCaretInfo();
1872 }
1873 if (m_bOprNotify && m_pOprNotify)
1874 m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001875
Tom Sepez3509d162017-01-30 13:22:02 -08001876 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001877}
1878
tsepez4cf55152016-11-02 14:37:54 -07001879bool CFX_Edit::Empty() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001880 if (m_pVT->IsValid()) {
1881 m_pVT->DeleteWords(GetWholeWordRange());
1882 SetCaret(m_pVT->GetBeginWordPlace());
1883
tsepez4cf55152016-11-02 14:37:54 -07001884 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001885 }
1886
tsepez4cf55152016-11-02 14:37:54 -07001887 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001888}
1889
tsepez4cf55152016-11-02 14:37:54 -07001890bool CFX_Edit::Clear(bool bAddUndo, bool bPaint) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001891 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
tsepez4cf55152016-11-02 14:37:54 -07001892 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001893
thestig821d59e2016-05-11 12:59:22 -07001894 CPVT_WordRange range = m_SelState.ConvertToWordRange();
dsinclaira2919b32016-07-13 10:55:48 -07001895 if (bAddUndo && m_bEnableUndo)
Tom Sepez3509d162017-01-30 13:22:02 -08001896 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Clear>(this, range, GetSelText()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001897
thestig821d59e2016-05-11 12:59:22 -07001898 SelectNone();
1899 SetCaret(m_pVT->DeleteWords(range));
1900 m_SelState.Set(m_wpCaret, m_wpCaret);
thestig821d59e2016-05-11 12:59:22 -07001901 if (bPaint) {
1902 RearrangePart(range);
1903 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001904 Refresh();
thestig821d59e2016-05-11 12:59:22 -07001905 SetCaretOrigin();
1906 SetCaretInfo();
1907 }
thestig821d59e2016-05-11 12:59:22 -07001908 if (m_bOprNotify && m_pOprNotify)
1909 m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);
1910
tsepez4cf55152016-11-02 14:37:54 -07001911 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001912}
1913
tsepez4cf55152016-11-02 14:37:54 -07001914bool CFX_Edit::InsertText(const CFX_WideString& sText,
1915 int32_t charset,
1916 bool bAddUndo,
1917 bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001918 if (IsTextOverflow())
tsepez4cf55152016-11-02 14:37:54 -07001919 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001920
1921 m_pVT->UpdateWordPlace(m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001922 SetCaret(DoInsertText(m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001923 m_SelState.Set(m_wpCaret, m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001924 if (m_wpCaret == m_wpOldCaret)
tsepez4cf55152016-11-02 14:37:54 -07001925 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001926
tsepeza31da742016-09-08 11:28:14 -07001927 if (bAddUndo && m_bEnableUndo) {
Tom Sepez3509d162017-01-30 13:22:02 -08001928 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertText>(
1929 this, m_wpOldCaret, m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001930 }
tsepeza31da742016-09-08 11:28:14 -07001931 if (bPaint)
1932 PaintInsertText(m_wpOldCaret, m_wpCaret);
1933
1934 if (m_bOprNotify && m_pOprNotify)
1935 m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
1936
tsepez4cf55152016-11-02 14:37:54 -07001937 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001938}
1939
1940void CFX_Edit::PaintInsertText(const CPVT_WordPlace& wpOld,
1941 const CPVT_WordPlace& wpNew) {
1942 if (m_pVT->IsValid()) {
1943 RearrangePart(CPVT_WordRange(wpOld, wpNew));
1944 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001945 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001946 SetCaretOrigin();
1947 SetCaretInfo();
1948 }
1949}
1950
tsepez4cf55152016-11-02 14:37:54 -07001951bool CFX_Edit::Redo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001952 if (m_bEnableUndo) {
1953 if (m_Undo.CanRedo()) {
1954 m_Undo.Redo();
tsepez4cf55152016-11-02 14:37:54 -07001955 return true;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001956 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001957 }
1958
tsepez4cf55152016-11-02 14:37:54 -07001959 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001960}
1961
tsepez4cf55152016-11-02 14:37:54 -07001962bool CFX_Edit::Undo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001963 if (m_bEnableUndo) {
1964 if (m_Undo.CanUndo()) {
1965 m_Undo.Undo();
tsepez4cf55152016-11-02 14:37:54 -07001966 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001967 }
1968 }
1969
tsepez4cf55152016-11-02 14:37:54 -07001970 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001971}
1972
1973void CFX_Edit::SetCaretOrigin() {
thestig821d59e2016-05-11 12:59:22 -07001974 if (!m_pVT->IsValid())
1975 return;
1976
1977 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1978 pIterator->SetAt(m_wpCaret);
1979 CPVT_Word word;
1980 CPVT_Line line;
1981 if (pIterator->GetWord(word)) {
1982 m_ptCaret.x = word.ptWord.x + word.fWidth;
1983 m_ptCaret.y = word.ptWord.y;
1984 } else if (pIterator->GetLine(line)) {
1985 m_ptCaret.x = line.ptLine.x;
1986 m_ptCaret.y = line.ptLine.y;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001987 }
1988}
1989
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001990CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const {
1991 if (m_pVT->IsValid())
1992 return m_pVT->WordIndexToWordPlace(index);
1993
1994 return CPVT_WordPlace();
1995}
1996
tsepez4cf55152016-11-02 14:37:54 -07001997bool CFX_Edit::IsTextFull() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001998 int32_t nTotalWords = m_pVT->GetTotalWords();
1999 int32_t nLimitChar = m_pVT->GetLimitChar();
2000 int32_t nCharArray = m_pVT->GetCharArray();
2001
2002 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
2003 (nCharArray > 0 && nTotalWords >= nCharArray);
2004}
2005
tsepez4cf55152016-11-02 14:37:54 -07002006bool CFX_Edit::IsTextOverflow() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002007 if (!m_bEnableScroll && !m_bEnableOverflow) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002008 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
2009 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002010
dsinclair448c4332016-08-02 12:07:35 -07002011 if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
2012 IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
tsepez4cf55152016-11-02 14:37:54 -07002013 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002014 }
2015
dsinclair448c4332016-08-02 12:07:35 -07002016 if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
tsepez4cf55152016-11-02 14:37:54 -07002017 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002018 }
2019
tsepez4cf55152016-11-02 14:37:54 -07002020 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002021}
2022
tsepez4cf55152016-11-02 14:37:54 -07002023bool CFX_Edit::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002024 if (m_bEnableUndo) {
2025 return m_Undo.CanUndo();
2026 }
2027
tsepez4cf55152016-11-02 14:37:54 -07002028 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002029}
2030
tsepez4cf55152016-11-02 14:37:54 -07002031bool CFX_Edit::CanRedo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002032 if (m_bEnableUndo) {
2033 return m_Undo.CanRedo();
2034 }
2035
tsepez4cf55152016-11-02 14:37:54 -07002036 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002037}
2038
tsepez4cf55152016-11-02 14:37:54 -07002039void CFX_Edit::EnableRefresh(bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002040 m_bEnableRefresh = bRefresh;
2041}
2042
tsepez4cf55152016-11-02 14:37:54 -07002043void CFX_Edit::EnableUndo(bool bUndo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002044 m_bEnableUndo = bUndo;
2045}
2046
tsepez4cf55152016-11-02 14:37:54 -07002047void CFX_Edit::EnableOprNotify(bool bNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002048 m_bOprNotify = bNotify;
2049}
2050
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002051CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place,
tsepeza31da742016-09-08 11:28:14 -07002052 const CFX_WideString& sText,
dsinclairefd5a992016-07-18 10:04:07 -07002053 int32_t charset) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002054 CPVT_WordPlace wp = place;
2055
2056 if (m_pVT->IsValid()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002057 for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
Tom Sepez62a70f92016-03-21 15:00:20 -07002058 uint16_t word = sText[i];
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002059 switch (word) {
2060 case 0x0D:
dsinclairefd5a992016-07-18 10:04:07 -07002061 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002062 if (sText[i + 1] == 0x0A)
2063 i++;
2064 break;
2065 case 0x0A:
dsinclairefd5a992016-07-18 10:04:07 -07002066 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002067 if (sText[i + 1] == 0x0D)
2068 i++;
2069 break;
2070 case 0x09:
2071 word = 0x20;
2072 default:
2073 wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
dsinclairefd5a992016-07-18 10:04:07 -07002074 nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002075 break;
2076 }
2077 }
2078 }
2079
2080 return wp;
2081}
2082
Tom Sepez62a70f92016-03-21 15:00:20 -07002083int32_t CFX_Edit::GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset) {
dsinclairc7a73492016-04-05 12:01:42 -07002084 if (IPVT_FontMap* pFontMap = GetFontMap())
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002085 return pFontMap->CharSetFromUnicode(word, nOldCharset);
2086 return nOldCharset;
2087}
2088
Tom Sepez3509d162017-01-30 13:22:02 -08002089void CFX_Edit::AddEditUndoItem(
2090 std::unique_ptr<CFX_Edit_UndoItem> pEditUndoItem) {
Lei Zhang1a89e362017-03-23 15:27:25 -07002091 m_Undo.AddItem(std::move(pEditUndoItem));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002092}
2093
weili625ad662016-06-15 11:21:33 -07002094CFX_Edit_LineRectArray::CFX_Edit_LineRectArray() {}
2095
Tom Sepez3509d162017-01-30 13:22:02 -08002096CFX_Edit_LineRectArray::~CFX_Edit_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07002097
Tom Sepez3509d162017-01-30 13:22:02 -08002098void CFX_Edit_LineRectArray::operator=(CFX_Edit_LineRectArray&& that) {
2099 m_LineRects = std::move(that.m_LineRects);
weili625ad662016-06-15 11:21:33 -07002100}
2101
2102void CFX_Edit_LineRectArray::Add(const CPVT_WordRange& wrLine,
2103 const CFX_FloatRect& rcLine) {
Tom Sepez3509d162017-01-30 13:22:02 -08002104 m_LineRects.push_back(pdfium::MakeUnique<CFX_Edit_LineRect>(wrLine, rcLine));
weili625ad662016-06-15 11:21:33 -07002105}
2106
2107int32_t CFX_Edit_LineRectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08002108 return pdfium::CollectionSize<int32_t>(m_LineRects);
weili625ad662016-06-15 11:21:33 -07002109}
2110
2111CFX_Edit_LineRect* CFX_Edit_LineRectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002112 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002113 return nullptr;
2114
Tom Sepez3509d162017-01-30 13:22:02 -08002115 return m_LineRects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002116}
2117
2118CFX_Edit_Select::CFX_Edit_Select() {}
2119
weili625ad662016-06-15 11:21:33 -07002120CFX_Edit_Select::CFX_Edit_Select(const CPVT_WordRange& range) {
2121 Set(range.BeginPos, range.EndPos);
2122}
2123
2124CPVT_WordRange CFX_Edit_Select::ConvertToWordRange() const {
2125 return CPVT_WordRange(BeginPos, EndPos);
2126}
2127
Tom Sepez52f69b32017-03-21 13:42:38 -07002128void CFX_Edit_Select::Reset() {
2129 BeginPos.Reset();
2130 EndPos.Reset();
weili625ad662016-06-15 11:21:33 -07002131}
2132
2133void CFX_Edit_Select::Set(const CPVT_WordPlace& begin,
2134 const CPVT_WordPlace& end) {
2135 BeginPos = begin;
2136 EndPos = end;
2137}
2138
weili625ad662016-06-15 11:21:33 -07002139void CFX_Edit_Select::SetEndPos(const CPVT_WordPlace& end) {
2140 EndPos = end;
2141}
2142
Tom Sepez52f69b32017-03-21 13:42:38 -07002143bool CFX_Edit_Select::IsEmpty() const {
2144 return BeginPos == EndPos;
weili625ad662016-06-15 11:21:33 -07002145}
2146
weili625ad662016-06-15 11:21:33 -07002147CFX_Edit_RectArray::CFX_Edit_RectArray() {}
2148
Tom Sepez3509d162017-01-30 13:22:02 -08002149CFX_Edit_RectArray::~CFX_Edit_RectArray() {}
weili625ad662016-06-15 11:21:33 -07002150
Tom Sepez3509d162017-01-30 13:22:02 -08002151void CFX_Edit_RectArray::Clear() {
2152 m_Rects.clear();
weili625ad662016-06-15 11:21:33 -07002153}
2154
2155void CFX_Edit_RectArray::Add(const CFX_FloatRect& rect) {
2156 // check for overlapped area
Tom Sepez3509d162017-01-30 13:22:02 -08002157 for (const auto& pRect : m_Rects) {
weili625ad662016-06-15 11:21:33 -07002158 if (pRect && pRect->Contains(rect))
2159 return;
2160 }
Tom Sepez3509d162017-01-30 13:22:02 -08002161 m_Rects.push_back(pdfium::MakeUnique<CFX_FloatRect>(rect));
weili625ad662016-06-15 11:21:33 -07002162}
2163
2164int32_t CFX_Edit_RectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08002165 return pdfium::CollectionSize<int32_t>(m_Rects);
weili625ad662016-06-15 11:21:33 -07002166}
2167
2168CFX_FloatRect* CFX_Edit_RectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002169 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002170 return nullptr;
2171
Tom Sepez3509d162017-01-30 13:22:02 -08002172 return m_Rects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002173}