blob: 0f5cf05b10474060cfe15494b950231d4b10cc05 [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
Dan Sinclair6b0158f2017-07-24 09:42:55 -04007#include "fpdfsdk/pdfwindow/cpwl_edit_impl.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>
Henrique Nakashima2e2da132017-06-27 13:43:22 -040011#include <sstream>
thestigd4c34f22016-09-28 17:04:51 -070012#include <utility>
Lei Zhang375a8642016-01-11 11:59:17 -080013
dsinclairbc5e6d22016-10-04 11:08:49 -070014#include "core/fpdfapi/font/cpdf_font.h"
dsinclair41872fa2016-10-04 11:29:35 -070015#include "core/fpdfapi/page/cpdf_pageobject.h"
16#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
17#include "core/fpdfapi/page/cpdf_pathobject.h"
18#include "core/fpdfapi/page/cpdf_textobject.h"
dsinclair488b7ad2016-10-04 11:55:50 -070019#include "core/fpdfapi/parser/fpdf_parser_decode.h"
dsinclair69d9c682016-10-04 12:18:35 -070020#include "core/fpdfapi/render/cpdf_renderoptions.h"
21#include "core/fpdfapi/render/cpdf_textrenderer.h"
dsinclair1727aee2016-09-29 13:12:56 -070022#include "core/fpdfdoc/cpvt_section.h"
23#include "core/fpdfdoc/cpvt_word.h"
24#include "core/fpdfdoc/ipvt_fontmap.h"
Dan Sinclairf51a02a2017-04-19 12:46:53 -040025#include "core/fxcrt/fx_codepage.h"
dsinclair74a34fc2016-09-29 16:41:42 -070026#include "core/fxge/cfx_graphstatedata.h"
27#include "core/fxge/cfx_pathdata.h"
28#include "core/fxge/cfx_renderdevice.h"
dsinclaire35af1e2016-07-13 11:26:20 -070029#include "fpdfsdk/cfx_systemhandler.h"
Lei Zhang633a3b72017-06-02 15:27:22 -070030#include "fpdfsdk/pdfwindow/cpwl_edit.h"
31#include "fpdfsdk/pdfwindow/cpwl_edit_ctrl.h"
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -040032#include "fpdfsdk/pdfwindow/cpwl_scroll_bar.h"
tsepez36eb4bd2016-10-03 15:24:27 -070033#include "third_party/base/ptr_util.h"
Tom Sepez3509d162017-01-30 13:22:02 -080034#include "third_party/base/stl_util.h"
dsinclaire35af1e2016-07-13 11:26:20 -070035
dsinclair8f4bf9a2016-05-04 13:51:51 -070036namespace {
37
38const int kEditUndoMaxItems = 10000;
39
dsinclaire35af1e2016-07-13 11:26:20 -070040void DrawTextString(CFX_RenderDevice* pDevice,
Dan Sinclairf528eee2017-02-14 11:52:07 -050041 const CFX_PointF& pt,
dsinclaire35af1e2016-07-13 11:26:20 -070042 CPDF_Font* pFont,
Dan Sinclair05df0752017-03-14 14:43:42 -040043 float fFontSize,
dsinclaire35af1e2016-07-13 11:26:20 -070044 CFX_Matrix* pUser2Device,
45 const CFX_ByteString& str,
46 FX_ARGB crTextFill,
dsinclaire35af1e2016-07-13 11:26:20 -070047 int32_t nHorzScale) {
Dan Sinclaira0061af2017-02-23 09:25:17 -050048 CFX_PointF pos = pUser2Device->Transform(pt);
dsinclaire35af1e2016-07-13 11:26:20 -070049
50 if (pFont) {
51 if (nHorzScale != 100) {
52 CFX_Matrix mt(nHorzScale / 100.0f, 0, 0, 1, 0, 0);
53 mt.Concat(*pUser2Device);
54
55 CPDF_RenderOptions ro;
56 ro.m_Flags = RENDER_CLEARTYPE;
Dan Sinclairf55e72e2017-07-13 14:53:28 -040057 ro.m_ColorMode = CPDF_RenderOptions::kNormal;
dsinclaire35af1e2016-07-13 11:26:20 -070058
Dan Sinclaira0061af2017-02-23 09:25:17 -050059 CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize,
60 &mt, str, crTextFill, nullptr, &ro);
dsinclaire35af1e2016-07-13 11:26:20 -070061 } else {
62 CPDF_RenderOptions ro;
63 ro.m_Flags = RENDER_CLEARTYPE;
Dan Sinclairf55e72e2017-07-13 14:53:28 -040064 ro.m_ColorMode = CPDF_RenderOptions::kNormal;
dsinclaire35af1e2016-07-13 11:26:20 -070065
Dan Sinclaira0061af2017-02-23 09:25:17 -050066 CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize,
67 pUser2Device, str, crTextFill, nullptr,
68 &ro);
dsinclaire35af1e2016-07-13 11:26:20 -070069 }
70 }
71}
72
dsinclair8f4bf9a2016-05-04 13:51:51 -070073} // namespace
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074
Dan Sinclair6b0158f2017-07-24 09:42:55 -040075CPWL_EditImpl_Iterator::CPWL_EditImpl_Iterator(
76 CPWL_EditImpl* pEdit,
77 CPDF_VariableText::Iterator* pVTIterator)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078 : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {}
79
Dan Sinclair6b0158f2017-07-24 09:42:55 -040080CPWL_EditImpl_Iterator::~CPWL_EditImpl_Iterator() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081
Dan Sinclair6b0158f2017-07-24 09:42:55 -040082bool CPWL_EditImpl_Iterator::NextWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083 return m_pVTIterator->NextWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070084}
85
Dan Sinclair6b0158f2017-07-24 09:42:55 -040086bool CPWL_EditImpl_Iterator::PrevWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070087 return m_pVTIterator->PrevWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070088}
89
Dan Sinclair6b0158f2017-07-24 09:42:55 -040090bool CPWL_EditImpl_Iterator::GetWord(CPVT_Word& word) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091 ASSERT(m_pEdit);
92
93 if (m_pVTIterator->GetWord(word)) {
94 word.ptWord = m_pEdit->VTToEdit(word.ptWord);
tsepez4cf55152016-11-02 14:37:54 -070095 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096 }
tsepez4cf55152016-11-02 14:37:54 -070097 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098}
99
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400100bool CPWL_EditImpl_Iterator::GetLine(CPVT_Line& line) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700101 ASSERT(m_pEdit);
102
103 if (m_pVTIterator->GetLine(line)) {
104 line.ptLine = m_pEdit->VTToEdit(line.ptLine);
tsepez4cf55152016-11-02 14:37:54 -0700105 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700106 }
tsepez4cf55152016-11-02 14:37:54 -0700107 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700108}
109
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400110void CPWL_EditImpl_Iterator::SetAt(int32_t nWordIndex) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700111 m_pVTIterator->SetAt(nWordIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700112}
113
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400114void CPWL_EditImpl_Iterator::SetAt(const CPVT_WordPlace& place) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700115 m_pVTIterator->SetAt(place);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700116}
117
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400118const CPVT_WordPlace& CPWL_EditImpl_Iterator::GetAt() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119 return m_pVTIterator->GetAt();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700120}
121
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400122CPWL_EditImpl_Provider::CPWL_EditImpl_Provider(IPVT_FontMap* pFontMap)
dsinclairc7a73492016-04-05 12:01:42 -0700123 : CPDF_VariableText::Provider(pFontMap), m_pFontMap(pFontMap) {
Lei Zhang96660d62015-12-14 18:27:25 -0800124 ASSERT(m_pFontMap);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700125}
126
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400127CPWL_EditImpl_Provider::~CPWL_EditImpl_Provider() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400129IPVT_FontMap* CPWL_EditImpl_Provider::GetFontMap() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130 return m_pFontMap;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700131}
132
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400133int32_t CPWL_EditImpl_Provider::GetCharWidth(int32_t nFontIndex,
134 uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
tsepezc3255f52016-03-25 14:52:27 -0700136 uint32_t charcode = word;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700137
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138 if (pPDFFont->IsUnicodeCompatible())
139 charcode = pPDFFont->CharCodeFromUnicode(word);
140 else
141 charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);
142
Wei Li89409932016-03-28 10:33:33 -0700143 if (charcode != CPDF_Font::kInvalidCharCode)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 return pPDFFont->GetCharWidthF(charcode);
145 }
146
147 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700148}
149
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400150int32_t CPWL_EditImpl_Provider::GetTypeAscent(int32_t nFontIndex) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
152 return pPDFFont->GetTypeAscent();
153
154 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700155}
156
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400157int32_t CPWL_EditImpl_Provider::GetTypeDescent(int32_t nFontIndex) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
159 return pPDFFont->GetTypeDescent();
160
161 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700162}
163
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400164int32_t CPWL_EditImpl_Provider::GetWordFontIndex(uint16_t word,
165 int32_t charset,
166 int32_t nFontIndex) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 return m_pFontMap->GetWordFontIndex(word, charset, nFontIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700168}
169
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400170int32_t CPWL_EditImpl_Provider::GetDefaultFontIndex() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700172}
173
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400174bool CPWL_EditImpl_Provider::IsLatinWord(uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 return FX_EDIT_ISLATINWORD(word);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700176}
177
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400178CPWL_EditImpl_Refresh::CPWL_EditImpl_Refresh() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400180CPWL_EditImpl_Refresh::~CPWL_EditImpl_Refresh() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400182void CPWL_EditImpl_Refresh::BeginRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800183 m_RefreshRects.Clear();
184 m_OldLineRects = std::move(m_NewLineRects);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700185}
186
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400187void CPWL_EditImpl_Refresh::Push(const CPVT_WordRange& linerange,
188 const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700189 m_NewLineRects.Add(linerange, rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700190}
191
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400192void CPWL_EditImpl_Refresh::NoAnalyse() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193 {
194 for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400195 if (CPWL_EditImpl_LineRect* pOldRect = m_OldLineRects.GetAt(i))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196 m_RefreshRects.Add(pOldRect->m_rcLine);
197 }
198
199 {
200 for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400201 if (CPWL_EditImpl_LineRect* pNewRect = m_NewLineRects.GetAt(i))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202 m_RefreshRects.Add(pNewRect->m_rcLine);
203 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700204}
205
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400206const CPWL_EditImpl_RectArray* CPWL_EditImpl_Refresh::GetRefreshRects() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207 return &m_RefreshRects;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700208}
209
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400210void CPWL_EditImpl_Refresh::EndRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800211 m_RefreshRects.Clear();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700212}
213
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400214CPWL_EditImpl_Undo::CPWL_EditImpl_Undo(int32_t nBufsize)
215 : m_nCurUndoPos(0), m_nBufSize(nBufsize), m_bWorking(false) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400217CPWL_EditImpl_Undo::~CPWL_EditImpl_Undo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 Reset();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700219}
220
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400221bool CPWL_EditImpl_Undo::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222 return m_nCurUndoPos > 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700223}
224
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400225void CPWL_EditImpl_Undo::Undo() {
tsepez4cf55152016-11-02 14:37:54 -0700226 m_bWorking = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700227 if (m_nCurUndoPos > 0) {
Tom Sepez3509d162017-01-30 13:22:02 -0800228 m_UndoItemStack[m_nCurUndoPos - 1]->Undo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229 m_nCurUndoPos--;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230 }
tsepez4cf55152016-11-02 14:37:54 -0700231 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700232}
233
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400234bool CPWL_EditImpl_Undo::CanRedo() const {
Tom Sepez3509d162017-01-30 13:22:02 -0800235 return m_nCurUndoPos < m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700236}
237
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400238void CPWL_EditImpl_Undo::Redo() {
tsepez4cf55152016-11-02 14:37:54 -0700239 m_bWorking = true;
Tom Sepez3509d162017-01-30 13:22:02 -0800240 if (m_nCurUndoPos < m_UndoItemStack.size()) {
241 m_UndoItemStack[m_nCurUndoPos]->Redo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 m_nCurUndoPos++;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 }
tsepez4cf55152016-11-02 14:37:54 -0700244 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700245}
246
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400247void CPWL_EditImpl_Undo::AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700248 ASSERT(!m_bWorking);
Lei Zhang96660d62015-12-14 18:27:25 -0800249 ASSERT(pItem);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 ASSERT(m_nBufSize > 1);
Tom Sepez3509d162017-01-30 13:22:02 -0800251 if (m_nCurUndoPos < m_UndoItemStack.size())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252 RemoveTails();
253
Lei Zhang1a89e362017-03-23 15:27:25 -0700254 if (m_UndoItemStack.size() >= m_nBufSize)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255 RemoveHeads();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256
Tom Sepez3509d162017-01-30 13:22:02 -0800257 m_UndoItemStack.push_back(std::move(pItem));
258 m_nCurUndoPos = m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700259}
260
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400261void CPWL_EditImpl_Undo::RemoveHeads() {
Tom Sepez3509d162017-01-30 13:22:02 -0800262 ASSERT(m_UndoItemStack.size() > 1);
263 m_UndoItemStack.pop_front();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700264}
265
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400266void CPWL_EditImpl_Undo::RemoveTails() {
Tom Sepez3509d162017-01-30 13:22:02 -0800267 while (m_UndoItemStack.size() > m_nCurUndoPos)
268 m_UndoItemStack.pop_back();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269}
270
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400271void CPWL_EditImpl_Undo::Reset() {
Tom Sepez3509d162017-01-30 13:22:02 -0800272 m_UndoItemStack.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273 m_nCurUndoPos = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274}
275
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400276CPWL_EditImpl_UndoItem::CPWL_EditImpl_UndoItem()
277 : m_bFirst(true), m_bLast(true) {}
weili625ad662016-06-15 11:21:33 -0700278
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400279CPWL_EditImpl_UndoItem::~CPWL_EditImpl_UndoItem() {}
weili625ad662016-06-15 11:21:33 -0700280
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400281CFX_WideString CPWL_EditImpl_UndoItem::GetUndoTitle() const {
Tom Sepez3509d162017-01-30 13:22:02 -0800282 return CFX_WideString();
weili625ad662016-06-15 11:21:33 -0700283}
284
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400285void CPWL_EditImpl_UndoItem::SetFirst(bool bFirst) {
weili625ad662016-06-15 11:21:33 -0700286 m_bFirst = bFirst;
287}
288
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400289void CPWL_EditImpl_UndoItem::SetLast(bool bLast) {
weili625ad662016-06-15 11:21:33 -0700290 m_bLast = bLast;
291}
292
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400293bool CPWL_EditImpl_UndoItem::IsLast() {
weili625ad662016-06-15 11:21:33 -0700294 return m_bLast;
295}
296
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400297CFXEU_InsertWord::CFXEU_InsertWord(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700298 const CPVT_WordPlace& wpOldPlace,
299 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700300 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700301 int32_t charset,
302 const CPVT_WordProps* pWordProps)
303 : m_pEdit(pEdit),
304 m_wpOld(wpOldPlace),
305 m_wpNew(wpNewPlace),
306 m_Word(word),
307 m_nCharset(charset),
308 m_WordProps() {
309 if (pWordProps)
310 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700311}
312
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700313CFXEU_InsertWord::~CFXEU_InsertWord() {}
314
315void CFXEU_InsertWord::Redo() {
316 if (m_pEdit) {
317 m_pEdit->SelectNone();
318 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700319 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700320 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700321}
322
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700323void CFXEU_InsertWord::Undo() {
324 if (m_pEdit) {
325 m_pEdit->SelectNone();
326 m_pEdit->SetCaret(m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700327 m_pEdit->Backspace(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700328 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700329}
330
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400331CFXEU_InsertReturn::CFXEU_InsertReturn(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700332 const CPVT_WordPlace& wpOldPlace,
333 const CPVT_WordPlace& wpNewPlace,
334 const CPVT_SecProps* pSecProps,
335 const CPVT_WordProps* pWordProps)
336 : m_pEdit(pEdit),
337 m_wpOld(wpOldPlace),
338 m_wpNew(wpNewPlace),
339 m_SecProps(),
340 m_WordProps() {
341 if (pSecProps)
342 m_SecProps = *pSecProps;
343 if (pWordProps)
344 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700345}
346
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700347CFXEU_InsertReturn::~CFXEU_InsertReturn() {}
348
349void CFXEU_InsertReturn::Redo() {
350 if (m_pEdit) {
351 m_pEdit->SelectNone();
352 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700353 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700354 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700355}
356
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700357void CFXEU_InsertReturn::Undo() {
358 if (m_pEdit) {
359 m_pEdit->SelectNone();
360 m_pEdit->SetCaret(m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700361 m_pEdit->Backspace(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700362 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700363}
364
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400365CFXEU_Backspace::CFXEU_Backspace(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366 const CPVT_WordPlace& wpOldPlace,
367 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700368 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700369 int32_t charset,
370 const CPVT_SecProps& SecProps,
371 const CPVT_WordProps& WordProps)
372 : m_pEdit(pEdit),
373 m_wpOld(wpOldPlace),
374 m_wpNew(wpNewPlace),
375 m_Word(word),
376 m_nCharset(charset),
377 m_SecProps(SecProps),
378 m_WordProps(WordProps) {}
379
380CFXEU_Backspace::~CFXEU_Backspace() {}
381
382void CFXEU_Backspace::Redo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700383 if (!m_pEdit)
384 return;
385
386 m_pEdit->SelectNone();
387 m_pEdit->SetCaret(m_wpOld);
388 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700389}
390
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700391void CFXEU_Backspace::Undo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700392 if (!m_pEdit)
393 return;
394
395 m_pEdit->SelectNone();
396 m_pEdit->SetCaret(m_wpNew);
397 if (m_wpNew.nSecIndex != m_wpOld.nSecIndex)
398 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
399 else
400 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700401}
402
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400403CFXEU_Delete::CFXEU_Delete(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700404 const CPVT_WordPlace& wpOldPlace,
405 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700406 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700407 int32_t charset,
408 const CPVT_SecProps& SecProps,
409 const CPVT_WordProps& WordProps,
tsepez4cf55152016-11-02 14:37:54 -0700410 bool bSecEnd)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700411 : m_pEdit(pEdit),
412 m_wpOld(wpOldPlace),
413 m_wpNew(wpNewPlace),
414 m_Word(word),
415 m_nCharset(charset),
416 m_SecProps(SecProps),
417 m_WordProps(WordProps),
418 m_bSecEnd(bSecEnd) {}
419
420CFXEU_Delete::~CFXEU_Delete() {}
421
422void CFXEU_Delete::Redo() {
423 if (m_pEdit) {
424 m_pEdit->SelectNone();
425 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700426 m_pEdit->Delete(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700427 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700428}
429
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700430void CFXEU_Delete::Undo() {
431 if (m_pEdit) {
432 m_pEdit->SelectNone();
433 m_pEdit->SetCaret(m_wpNew);
434 if (m_bSecEnd) {
tsepez4cf55152016-11-02 14:37:54 -0700435 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700436 } else {
tsepez4cf55152016-11-02 14:37:54 -0700437 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700438 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700439 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700440}
441
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400442CFXEU_Clear::CFXEU_Clear(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700443 const CPVT_WordRange& wrSel,
444 const CFX_WideString& swText)
445 : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {}
446
447CFXEU_Clear::~CFXEU_Clear() {}
448
449void CFXEU_Clear::Redo() {
450 if (m_pEdit) {
451 m_pEdit->SelectNone();
Diana Gage4d02e902017-07-20 17:20:31 -0700452 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
tsepez4cf55152016-11-02 14:37:54 -0700453 m_pEdit->Clear(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700454 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700455}
456
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700457void CFXEU_Clear::Undo() {
458 if (m_pEdit) {
459 m_pEdit->SelectNone();
460 m_pEdit->SetCaret(m_wrSel.BeginPos);
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400461 m_pEdit->InsertText(m_swText, FX_CHARSET_Default, false, true);
Diana Gage4d02e902017-07-20 17:20:31 -0700462 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700463 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700464}
465
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400466CFXEU_InsertText::CFXEU_InsertText(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700467 const CPVT_WordPlace& wpOldPlace,
468 const CPVT_WordPlace& wpNewPlace,
469 const CFX_WideString& swText,
dsinclairefd5a992016-07-18 10:04:07 -0700470 int32_t charset)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700471 : m_pEdit(pEdit),
472 m_wpOld(wpOldPlace),
473 m_wpNew(wpNewPlace),
474 m_swText(swText),
dsinclairefd5a992016-07-18 10:04:07 -0700475 m_nCharset(charset) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700476
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700477CFXEU_InsertText::~CFXEU_InsertText() {}
478
479void CFXEU_InsertText::Redo() {
480 if (m_pEdit && IsLast()) {
481 m_pEdit->SelectNone();
482 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700483 m_pEdit->InsertText(m_swText, m_nCharset, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700484 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700485}
486
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700487void CFXEU_InsertText::Undo() {
488 if (m_pEdit) {
489 m_pEdit->SelectNone();
Diana Gage4d02e902017-07-20 17:20:31 -0700490 m_pEdit->SetSelection(m_wpOld, m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700491 m_pEdit->Clear(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700492 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700493}
494
dsinclaire35af1e2016-07-13 11:26:20 -0700495// static
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400496void CPWL_EditImpl::DrawEdit(CFX_RenderDevice* pDevice,
497 CFX_Matrix* pUser2Device,
498 CPWL_EditImpl* pEdit,
499 FX_COLORREF crTextFill,
500 const CFX_FloatRect& rcClip,
501 const CFX_PointF& ptOffset,
502 const CPVT_WordRange* pRange,
503 CFX_SystemHandler* pSystemHandler,
504 CFFL_FormFiller* pFFLData) {
dsinclaire35af1e2016-07-13 11:26:20 -0700505 const bool bContinuous =
506 pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
507 uint16_t SubWord = pEdit->GetPasswordChar();
Dan Sinclair05df0752017-03-14 14:43:42 -0400508 float fFontSize = pEdit->GetFontSize();
dsinclaire35af1e2016-07-13 11:26:20 -0700509 CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
510 int32_t nHorzScale = pEdit->GetHorzScale();
511
512 FX_COLORREF crCurFill = crTextFill;
513 FX_COLORREF crOldFill = crCurFill;
514
tsepez4cf55152016-11-02 14:37:54 -0700515 bool bSelect = false;
dsinclaire35af1e2016-07-13 11:26:20 -0700516 const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
517 const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
518
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400519 std::ostringstream sTextBuf;
dsinclaire35af1e2016-07-13 11:26:20 -0700520 int32_t nFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500521 CFX_PointF ptBT;
Tom Sepez1629f602017-04-21 14:11:26 -0700522 CFX_RenderDevice::StateRestorer restorer(pDevice);
dsinclaire35af1e2016-07-13 11:26:20 -0700523 if (!rcClip.IsEmpty()) {
524 CFX_FloatRect rcTemp = rcClip;
525 pUser2Device->TransformRect(rcTemp);
526 pDevice->SetClip_Rect(rcTemp.ToFxRect());
527 }
528
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400529 CPWL_EditImpl_Iterator* pIterator = pEdit->GetIterator();
dsinclaire35af1e2016-07-13 11:26:20 -0700530 if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
531 if (pRange)
532 pIterator->SetAt(pRange->BeginPos);
533 else
534 pIterator->SetAt(0);
535
536 CPVT_WordPlace oldplace;
537 while (pIterator->NextWord()) {
538 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700539 if (pRange && place > pRange->EndPos)
dsinclaire35af1e2016-07-13 11:26:20 -0700540 break;
541
Tom Sepez52f69b32017-03-21 13:42:38 -0700542 if (!wrSelect.IsEmpty()) {
543 bSelect = place > wrSelect.BeginPos && place <= wrSelect.EndPos;
dsinclaire35af1e2016-07-13 11:26:20 -0700544 crCurFill = bSelect ? crWhite : crTextFill;
545 }
546 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
547 crCurFill = crTextFill;
548 crOldFill = crCurFill;
549 }
550 CPVT_Word word;
551 if (pIterator->GetWord(word)) {
552 if (bSelect) {
553 CPVT_Line line;
554 pIterator->GetLine(line);
555
556 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
557 CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
558 word.ptWord.x + word.fWidth,
559 line.ptLine.y + line.fLineAscent);
560 rc.Intersect(rcClip);
561 pSystemHandler->OutputSelectedRect(pFFLData, rc);
562 } else {
563 CFX_PathData pathSelBK;
564 pathSelBK.AppendRect(
565 word.ptWord.x, line.ptLine.y + line.fLineDescent,
566 word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent);
567
568 pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
569 FXFILL_WINDING);
570 }
571 }
572
573 if (bContinuous) {
574 if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
575 crOldFill != crCurFill) {
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400576 if (sTextBuf.tellp() > 0) {
dsinclaire35af1e2016-07-13 11:26:20 -0700577 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500578 pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700579 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400580 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700581
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400582 sTextBuf.str("");
dsinclaire35af1e2016-07-13 11:26:20 -0700583 }
584 nFontIndex = word.nFontIndex;
585 ptBT = word.ptWord;
586 crOldFill = crCurFill;
587 }
588
Dan Sinclairc08dc392017-07-24 08:57:35 -0400589 sTextBuf << pEdit->GetPDFWordString(word.nFontIndex, word.Word,
590 SubWord);
dsinclaire35af1e2016-07-13 11:26:20 -0700591 } else {
592 DrawTextString(
Dan Sinclairc08dc392017-07-24 08:57:35 -0400593 pDevice,
594 CFX_PointF(word.ptWord.x + ptOffset.x,
595 word.ptWord.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700596 pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
Dan Sinclairc08dc392017-07-24 08:57:35 -0400597 pEdit->GetPDFWordString(word.nFontIndex, word.Word, SubWord),
Dan Sinclaira0061af2017-02-23 09:25:17 -0500598 crCurFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700599 }
600 oldplace = place;
601 }
602 }
603
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400604 if (sTextBuf.tellp() > 0) {
Dan Sinclaira0061af2017-02-23 09:25:17 -0500605 DrawTextString(pDevice,
606 CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
607 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400608 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700609 }
610 }
dsinclaire35af1e2016-07-13 11:26:20 -0700611}
612
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400613CPWL_EditImpl::CPWL_EditImpl()
dsinclaire35af1e2016-07-13 11:26:20 -0700614 : m_pVT(new CPDF_VariableText),
thestig821d59e2016-05-11 12:59:22 -0700615 m_pNotify(nullptr),
616 m_pOprNotify(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700617 m_wpCaret(-1, -1, -1),
618 m_wpOldCaret(-1, -1, -1),
619 m_SelState(),
tsepez4cf55152016-11-02 14:37:54 -0700620 m_bEnableScroll(false),
dsinclair8f4bf9a2016-05-04 13:51:51 -0700621 m_Undo(kEditUndoMaxItems),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700622 m_nAlignment(0),
tsepez4cf55152016-11-02 14:37:54 -0700623 m_bNotifyFlag(false),
624 m_bEnableOverflow(false),
625 m_bEnableRefresh(true),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700626 m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f),
tsepez4cf55152016-11-02 14:37:54 -0700627 m_bEnableUndo(true),
Lei Zhang1a89e362017-03-23 15:27:25 -0700628 m_bOprNotify(false) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700629
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400630CPWL_EditImpl::~CPWL_EditImpl() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700631
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400632void CPWL_EditImpl::Initialize() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700633 m_pVT->Initialize();
634 SetCaret(m_pVT->GetBeginWordPlace());
635 SetCaretOrigin();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700636}
637
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400638void CPWL_EditImpl::SetFontMap(IPVT_FontMap* pFontMap) {
639 m_pVTProvider = pdfium::MakeUnique<CPWL_EditImpl_Provider>(pFontMap);
thestig821d59e2016-05-11 12:59:22 -0700640 m_pVT->SetProvider(m_pVTProvider.get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700641}
642
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400643void CPWL_EditImpl::SetNotify(CPWL_EditCtrl* pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700644 m_pNotify = pNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700645}
646
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400647void CPWL_EditImpl::SetOprNotify(CPWL_Edit* pOprNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700648 m_pOprNotify = pOprNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700649}
650
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400651CPWL_EditImpl_Iterator* CPWL_EditImpl::GetIterator() {
tsepez36eb4bd2016-10-03 15:24:27 -0700652 if (!m_pIterator) {
653 m_pIterator =
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400654 pdfium::MakeUnique<CPWL_EditImpl_Iterator>(this, m_pVT->GetIterator());
tsepez36eb4bd2016-10-03 15:24:27 -0700655 }
thestig821d59e2016-05-11 12:59:22 -0700656 return m_pIterator.get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700657}
658
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400659IPVT_FontMap* CPWL_EditImpl::GetFontMap() {
thestig821d59e2016-05-11 12:59:22 -0700660 return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700661}
662
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400663void CPWL_EditImpl::SetPlateRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700664 m_pVT->SetPlateRect(rect);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500665 m_ptScrollPos = CFX_PointF(rect.left, rect.top);
dsinclairefd5a992016-07-18 10:04:07 -0700666 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700667}
668
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400669void CPWL_EditImpl::SetAlignmentH(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700670 m_pVT->SetAlignment(nFormat);
671 if (bPaint)
672 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700673}
674
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400675void CPWL_EditImpl::SetAlignmentV(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700676 m_nAlignment = nFormat;
677 if (bPaint)
678 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700679}
680
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400681void CPWL_EditImpl::SetPasswordChar(uint16_t wSubWord, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700682 m_pVT->SetPasswordChar(wSubWord);
683 if (bPaint)
684 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700685}
686
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400687void CPWL_EditImpl::SetLimitChar(int32_t nLimitChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700688 m_pVT->SetLimitChar(nLimitChar);
dsinclairefd5a992016-07-18 10:04:07 -0700689 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700690}
691
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400692void CPWL_EditImpl::SetCharArray(int32_t nCharArray) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700693 m_pVT->SetCharArray(nCharArray);
dsinclairefd5a992016-07-18 10:04:07 -0700694 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700695}
696
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400697void CPWL_EditImpl::SetCharSpace(float fCharSpace) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700698 m_pVT->SetCharSpace(fCharSpace);
dsinclairefd5a992016-07-18 10:04:07 -0700699 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700700}
701
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400702void CPWL_EditImpl::SetMultiLine(bool bMultiLine, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700703 m_pVT->SetMultiLine(bMultiLine);
704 if (bPaint)
705 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700706}
707
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400708void CPWL_EditImpl::SetAutoReturn(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700709 m_pVT->SetAutoReturn(bAuto);
710 if (bPaint)
711 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700712}
713
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400714void CPWL_EditImpl::SetAutoFontSize(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700715 m_pVT->SetAutoFontSize(bAuto);
716 if (bPaint)
717 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700718}
719
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400720void CPWL_EditImpl::SetFontSize(float fFontSize) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700721 m_pVT->SetFontSize(fFontSize);
dsinclairefd5a992016-07-18 10:04:07 -0700722 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700723}
724
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400725void CPWL_EditImpl::SetAutoScroll(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700726 m_bEnableScroll = bAuto;
727 if (bPaint)
728 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700729}
730
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400731void CPWL_EditImpl::SetTextOverflow(bool bAllowed, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700732 m_bEnableOverflow = bAllowed;
733 if (bPaint)
734 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700735}
736
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400737void CPWL_EditImpl::SetSelection(int32_t nStartChar, int32_t nEndChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700738 if (m_pVT->IsValid()) {
739 if (nStartChar == 0 && nEndChar < 0) {
740 SelectAll();
741 } else if (nStartChar < 0) {
742 SelectNone();
743 } else {
744 if (nStartChar < nEndChar) {
Diana Gage4d02e902017-07-20 17:20:31 -0700745 SetSelection(m_pVT->WordIndexToWordPlace(nStartChar),
746 m_pVT->WordIndexToWordPlace(nEndChar));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700747 } else {
Diana Gage4d02e902017-07-20 17:20:31 -0700748 SetSelection(m_pVT->WordIndexToWordPlace(nEndChar),
749 m_pVT->WordIndexToWordPlace(nStartChar));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700750 }
751 }
752 }
753}
754
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400755void CPWL_EditImpl::SetSelection(const CPVT_WordPlace& begin,
756 const CPVT_WordPlace& end) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700757 if (!m_pVT->IsValid())
758 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700759
Tom Sepez52f69b32017-03-21 13:42:38 -0700760 SelectNone();
761 m_SelState.Set(begin, end);
762 SetCaret(m_SelState.EndPos);
763 ScrollToCaret();
764 if (!m_SelState.IsEmpty())
765 Refresh();
766 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700767}
768
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400769void CPWL_EditImpl::GetSelection(int32_t& nStartChar, int32_t& nEndChar) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700770 nStartChar = -1;
771 nEndChar = -1;
Tom Sepez52f69b32017-03-21 13:42:38 -0700772 if (!m_pVT->IsValid())
773 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700774
Tom Sepez52f69b32017-03-21 13:42:38 -0700775 if (m_SelState.IsEmpty()) {
776 nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
777 nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
778 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700779 }
Tom Sepez52f69b32017-03-21 13:42:38 -0700780 if (m_SelState.BeginPos < m_SelState.EndPos) {
781 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
782 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
783 return;
784 }
785 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
786 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700787}
788
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400789int32_t CPWL_EditImpl::GetCaret() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700790 if (m_pVT->IsValid())
791 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
792
793 return -1;
794}
795
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400796CPVT_WordPlace CPWL_EditImpl::GetCaretWordPlace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700797 return m_wpCaret;
798}
799
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400800CFX_WideString CPWL_EditImpl::GetText() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700801 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700802 if (!m_pVT->IsValid())
803 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700804
thestig821d59e2016-05-11 12:59:22 -0700805 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
806 pIterator->SetAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700807
thestig821d59e2016-05-11 12:59:22 -0700808 CPVT_Word wordinfo;
809 CPVT_WordPlace oldplace = pIterator->GetAt();
810 while (pIterator->NextWord()) {
811 CPVT_WordPlace place = pIterator->GetAt();
thestig821d59e2016-05-11 12:59:22 -0700812 if (pIterator->GetWord(wordinfo))
813 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700814 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700815 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700816 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700817 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700818 return swRet;
819}
820
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400821CFX_WideString CPWL_EditImpl::GetRangeText(const CPVT_WordRange& range) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700822 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700823 if (!m_pVT->IsValid())
824 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700825
thestig821d59e2016-05-11 12:59:22 -0700826 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
827 CPVT_WordRange wrTemp = range;
828 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
829 m_pVT->UpdateWordPlace(wrTemp.EndPos);
830 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700831
thestig821d59e2016-05-11 12:59:22 -0700832 CPVT_Word wordinfo;
833 CPVT_WordPlace oldplace = wrTemp.BeginPos;
834 while (pIterator->NextWord()) {
835 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700836 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -0700837 break;
thestig821d59e2016-05-11 12:59:22 -0700838 if (pIterator->GetWord(wordinfo))
839 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700840 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700841 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700842 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700843 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700844 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700845}
846
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400847CFX_WideString CPWL_EditImpl::GetSelectedText() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700848 return GetRangeText(m_SelState.ConvertToWordRange());
849}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700850
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400851int32_t CPWL_EditImpl::GetTotalLines() const {
thestig821d59e2016-05-11 12:59:22 -0700852 int32_t nLines = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700853
thestig821d59e2016-05-11 12:59:22 -0700854 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
855 pIterator->SetAt(0);
856 while (pIterator->NextLine())
857 ++nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700858
thestig821d59e2016-05-11 12:59:22 -0700859 return nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700860}
861
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400862CPVT_WordRange CPWL_EditImpl::GetSelectWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700863 return m_SelState.ConvertToWordRange();
864}
865
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400866void CPWL_EditImpl::SetText(const CFX_WideString& sText) {
dsinclairefd5a992016-07-18 10:04:07 -0700867 Empty();
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400868 DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_CHARSET_Default);
dsinclairefd5a992016-07-18 10:04:07 -0700869 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700870}
871
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400872bool CPWL_EditImpl::InsertWord(uint16_t word, int32_t charset) {
tsepez4cf55152016-11-02 14:37:54 -0700873 return InsertWord(word, charset, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700874}
875
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400876bool CPWL_EditImpl::InsertReturn() {
tsepez4cf55152016-11-02 14:37:54 -0700877 return InsertReturn(nullptr, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700878}
879
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400880bool CPWL_EditImpl::Backspace() {
tsepez4cf55152016-11-02 14:37:54 -0700881 return Backspace(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700882}
883
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400884bool CPWL_EditImpl::Delete() {
tsepez4cf55152016-11-02 14:37:54 -0700885 return Delete(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700886}
887
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400888bool CPWL_EditImpl::ClearSelection() {
tsepez4cf55152016-11-02 14:37:54 -0700889 return Clear(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700890}
891
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400892bool CPWL_EditImpl::InsertText(const CFX_WideString& sText, int32_t charset) {
tsepez4cf55152016-11-02 14:37:54 -0700893 return InsertText(sText, charset, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700894}
895
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400896float CPWL_EditImpl::GetFontSize() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700897 return m_pVT->GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700898}
899
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400900uint16_t CPWL_EditImpl::GetPasswordChar() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700901 return m_pVT->GetPasswordChar();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700902}
903
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400904int32_t CPWL_EditImpl::GetCharArray() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700905 return m_pVT->GetCharArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700906}
907
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400908CFX_FloatRect CPWL_EditImpl::GetContentRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700909 return VTToEdit(m_pVT->GetContentRect());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700910}
911
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400912int32_t CPWL_EditImpl::GetHorzScale() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700913 return m_pVT->GetHorzScale();
914}
915
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400916float CPWL_EditImpl::GetCharSpace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700917 return m_pVT->GetCharSpace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700918}
919
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400920CPVT_WordRange CPWL_EditImpl::GetWholeWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700921 if (m_pVT->IsValid())
922 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700923
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700924 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700925}
926
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400927CPVT_WordRange CPWL_EditImpl::GetVisibleWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700928 if (m_bEnableOverflow)
929 return GetWholeWordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700930
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700931 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800932 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700933
Dan Sinclairf528eee2017-02-14 11:52:07 -0500934 CPVT_WordPlace place1 =
935 m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700936 CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500937 EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700938
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700939 return CPVT_WordRange(place1, place2);
940 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700941
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700942 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700943}
944
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400945CPVT_WordPlace CPWL_EditImpl::SearchWordPlace(const CFX_PointF& point) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700946 if (m_pVT->IsValid()) {
947 return m_pVT->SearchWordPlace(EditToVT(point));
948 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700949
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700950 return CPVT_WordPlace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700951}
952
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400953void CPWL_EditImpl::Paint() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700954 if (m_pVT->IsValid()) {
955 RearrangeAll();
956 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -0700957 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700958 SetCaretOrigin();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700959 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700960 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700961}
962
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400963void CPWL_EditImpl::RearrangeAll() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700964 if (m_pVT->IsValid()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700965 m_pVT->UpdateWordPlace(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700966 m_pVT->RearrangeAll();
967 m_pVT->UpdateWordPlace(m_wpCaret);
968 SetScrollInfo();
969 SetContentChanged();
970 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700971}
972
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400973void CPWL_EditImpl::RearrangePart(const CPVT_WordRange& range) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700974 if (m_pVT->IsValid()) {
975 m_pVT->UpdateWordPlace(m_wpCaret);
976 m_pVT->RearrangePart(range);
977 m_pVT->UpdateWordPlace(m_wpCaret);
978 SetScrollInfo();
979 SetContentChanged();
980 }
981}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700982
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400983void CPWL_EditImpl::SetContentChanged() {
dsinclaira2919b32016-07-13 10:55:48 -0700984 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800985 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700986 if (rcContent.Width() != m_rcOldContent.Width() ||
987 rcContent.Height() != m_rcOldContent.Height()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700988 m_rcOldContent = rcContent;
989 }
990 }
991}
992
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400993void CPWL_EditImpl::SelectAll() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700994 if (!m_pVT->IsValid())
995 return;
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400996 m_SelState = CPWL_EditImpl_Select(GetWholeWordRange());
Tom Sepez52f69b32017-03-21 13:42:38 -0700997 SetCaret(m_SelState.EndPos);
998 ScrollToCaret();
999 Refresh();
1000 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001001}
1002
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001003void CPWL_EditImpl::SelectNone() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001004 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
1005 return;
1006
1007 m_SelState.Reset();
1008 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001009}
1010
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001011bool CPWL_EditImpl::IsSelected() const {
Tom Sepez52f69b32017-03-21 13:42:38 -07001012 return !m_SelState.IsEmpty();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001013}
1014
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001015CFX_PointF CPWL_EditImpl::VTToEdit(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001016 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1017 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001018
Dan Sinclair05df0752017-03-14 14:43:42 -04001019 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001020
1021 switch (m_nAlignment) {
1022 case 0:
1023 fPadding = 0.0f;
1024 break;
1025 case 1:
1026 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1027 break;
1028 case 2:
1029 fPadding = rcPlate.Height() - rcContent.Height();
1030 break;
1031 }
1032
Dan Sinclairf528eee2017-02-14 11:52:07 -05001033 return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
1034 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001035}
1036
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001037CFX_PointF CPWL_EditImpl::EditToVT(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001038 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1039 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001040
Dan Sinclair05df0752017-03-14 14:43:42 -04001041 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001042
1043 switch (m_nAlignment) {
1044 case 0:
1045 fPadding = 0.0f;
1046 break;
1047 case 1:
1048 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1049 break;
1050 case 2:
1051 fPadding = rcPlate.Height() - rcContent.Height();
1052 break;
1053 }
1054
Dan Sinclairf528eee2017-02-14 11:52:07 -05001055 return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
1056 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001057}
1058
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001059CFX_FloatRect CPWL_EditImpl::VTToEdit(const CFX_FloatRect& rect) const {
Dan Sinclairf528eee2017-02-14 11:52:07 -05001060 CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
1061 CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001062
Tom Sepez281a9ea2016-02-26 14:24:28 -08001063 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1064 ptRightTop.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001065}
1066
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001067void CPWL_EditImpl::SetScrollInfo() {
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001068 if (!m_pNotify)
1069 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001070
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001071 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1072 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1073 if (m_bNotifyFlag)
1074 return;
1075
1076 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
1077 m_bNotifyFlag = true;
1078
1079 PWL_SCROLL_INFO Info;
1080 Info.fPlateWidth = rcPlate.top - rcPlate.bottom;
1081 Info.fContentMin = rcContent.bottom;
1082 Info.fContentMax = rcContent.top;
1083 Info.fSmallStep = rcPlate.Height() / 3;
1084 Info.fBigStep = rcPlate.Height();
1085 m_pNotify->SetScrollInfo(Info);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001086}
1087
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001088void CPWL_EditImpl::SetScrollPosX(float fx) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001089 if (!m_bEnableScroll)
1090 return;
1091
1092 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001093 if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001094 m_ptScrollPos.x = fx;
dsinclairefd5a992016-07-18 10:04:07 -07001095 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001096 }
1097 }
1098}
1099
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001100void CPWL_EditImpl::SetScrollPosY(float fy) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001101 if (!m_bEnableScroll)
1102 return;
1103
1104 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001105 if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001106 m_ptScrollPos.y = fy;
dsinclairefd5a992016-07-18 10:04:07 -07001107 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001108
dsinclaira2919b32016-07-13 10:55:48 -07001109 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001110 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001111 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001112 m_bNotifyFlag = true;
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001113 m_pNotify->SetScrollPosition(fy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001114 }
1115 }
1116 }
1117 }
1118}
1119
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001120void CPWL_EditImpl::SetScrollPos(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001121 SetScrollPosX(point.x);
1122 SetScrollPosY(point.y);
1123 SetScrollLimit();
1124 SetCaretInfo();
1125}
1126
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001127CFX_PointF CPWL_EditImpl::GetScrollPos() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001128 return m_ptScrollPos;
1129}
1130
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001131void CPWL_EditImpl::SetScrollLimit() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001132 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001133 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1134 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001135
1136 if (rcPlate.Width() > rcContent.Width()) {
1137 SetScrollPosX(rcPlate.left);
1138 } else {
dsinclair448c4332016-08-02 12:07:35 -07001139 if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001140 SetScrollPosX(rcContent.left);
dsinclair448c4332016-08-02 12:07:35 -07001141 } else if (IsFloatBigger(m_ptScrollPos.x,
1142 rcContent.right - rcPlate.Width())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001143 SetScrollPosX(rcContent.right - rcPlate.Width());
1144 }
1145 }
1146
1147 if (rcPlate.Height() > rcContent.Height()) {
1148 SetScrollPosY(rcPlate.top);
1149 } else {
dsinclair448c4332016-08-02 12:07:35 -07001150 if (IsFloatSmaller(m_ptScrollPos.y,
1151 rcContent.bottom + rcPlate.Height())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001152 SetScrollPosY(rcContent.bottom + rcPlate.Height());
dsinclair448c4332016-08-02 12:07:35 -07001153 } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001154 SetScrollPosY(rcContent.top);
1155 }
1156 }
1157 }
1158}
1159
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001160void CPWL_EditImpl::ScrollToCaret() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001161 SetScrollLimit();
1162
thestig821d59e2016-05-11 12:59:22 -07001163 if (!m_pVT->IsValid())
1164 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001165
thestig821d59e2016-05-11 12:59:22 -07001166 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1167 pIterator->SetAt(m_wpCaret);
1168
Dan Sinclairf528eee2017-02-14 11:52:07 -05001169 CFX_PointF ptHead;
1170 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001171 CPVT_Word word;
1172 CPVT_Line line;
1173 if (pIterator->GetWord(word)) {
1174 ptHead.x = word.ptWord.x + word.fWidth;
1175 ptHead.y = word.ptWord.y + word.fAscent;
1176 ptFoot.x = word.ptWord.x + word.fWidth;
1177 ptFoot.y = word.ptWord.y + word.fDescent;
1178 } else if (pIterator->GetLine(line)) {
1179 ptHead.x = line.ptLine.x;
1180 ptHead.y = line.ptLine.y + line.fLineAscent;
1181 ptFoot.x = line.ptLine.x;
1182 ptFoot.y = line.ptLine.y + line.fLineDescent;
1183 }
1184
Dan Sinclairf528eee2017-02-14 11:52:07 -05001185 CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1186 CFX_PointF ptFootEdit = VTToEdit(ptFoot);
thestig821d59e2016-05-11 12:59:22 -07001187 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
dsinclair448c4332016-08-02 12:07:35 -07001188 if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
1189 if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
1190 IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
thestig821d59e2016-05-11 12:59:22 -07001191 SetScrollPosX(ptHead.x);
dsinclair448c4332016-08-02 12:07:35 -07001192 } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
thestig821d59e2016-05-11 12:59:22 -07001193 SetScrollPosX(ptHead.x - rcPlate.Width());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001194 }
thestig821d59e2016-05-11 12:59:22 -07001195 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001196
dsinclair448c4332016-08-02 12:07:35 -07001197 if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
1198 if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
1199 IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
1200 if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
thestig821d59e2016-05-11 12:59:22 -07001201 SetScrollPosY(ptFoot.y + rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001202 }
dsinclair448c4332016-08-02 12:07:35 -07001203 } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
1204 if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
thestig821d59e2016-05-11 12:59:22 -07001205 SetScrollPosY(ptHead.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001206 }
1207 }
1208 }
1209}
1210
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001211void CPWL_EditImpl::Refresh() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001212 if (m_bEnableRefresh && m_pVT->IsValid()) {
1213 m_Refresh.BeginRefresh();
1214 RefreshPushLineRects(GetVisibleWordRange());
1215
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001216 m_Refresh.NoAnalyse();
1217 m_ptRefreshScrollPos = m_ptScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001218
dsinclaira2919b32016-07-13 10:55:48 -07001219 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001220 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001221 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001222 m_bNotifyFlag = true;
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001223 if (const CPWL_EditImpl_RectArray* pRects =
1224 m_Refresh.GetRefreshRects()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001225 for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001226 m_pNotify->InvalidateRect(pRects->GetAt(i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001227 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001228 }
1229 }
1230
1231 m_Refresh.EndRefresh();
1232 }
1233}
1234
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001235void CPWL_EditImpl::RefreshPushLineRects(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001236 if (!m_pVT->IsValid())
1237 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001238
thestig821d59e2016-05-11 12:59:22 -07001239 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1240 CPVT_WordPlace wpBegin = wr.BeginPos;
1241 m_pVT->UpdateWordPlace(wpBegin);
1242 CPVT_WordPlace wpEnd = wr.EndPos;
1243 m_pVT->UpdateWordPlace(wpEnd);
1244 pIterator->SetAt(wpBegin);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001245
thestig821d59e2016-05-11 12:59:22 -07001246 CPVT_Line lineinfo;
1247 do {
1248 if (!pIterator->GetLine(lineinfo))
1249 break;
1250 if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
1251 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001252
thestig821d59e2016-05-11 12:59:22 -07001253 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1254 lineinfo.ptLine.y + lineinfo.fLineDescent,
1255 lineinfo.ptLine.x + lineinfo.fLineWidth,
1256 lineinfo.ptLine.y + lineinfo.fLineAscent);
1257
1258 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1259 VTToEdit(rcLine));
1260 } while (pIterator->NextLine());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001261}
1262
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001263void CPWL_EditImpl::RefreshWordRange(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001264 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1265 CPVT_WordRange wrTemp = wr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001266
thestig821d59e2016-05-11 12:59:22 -07001267 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1268 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1269 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001270
thestig821d59e2016-05-11 12:59:22 -07001271 CPVT_Word wordinfo;
1272 CPVT_Line lineinfo;
1273 CPVT_WordPlace place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001274
thestig821d59e2016-05-11 12:59:22 -07001275 while (pIterator->NextWord()) {
1276 place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -07001277 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -07001278 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001279
thestig821d59e2016-05-11 12:59:22 -07001280 pIterator->GetWord(wordinfo);
1281 pIterator->GetLine(lineinfo);
thestig821d59e2016-05-11 12:59:22 -07001282 if (place.LineCmp(wrTemp.BeginPos) == 0 ||
1283 place.LineCmp(wrTemp.EndPos) == 0) {
1284 CFX_FloatRect rcWord(wordinfo.ptWord.x,
1285 lineinfo.ptLine.y + lineinfo.fLineDescent,
1286 wordinfo.ptWord.x + wordinfo.fWidth,
1287 lineinfo.ptLine.y + lineinfo.fLineAscent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001288
dsinclaira2919b32016-07-13 10:55:48 -07001289 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001290 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001291 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001292 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001293 CFX_FloatRect rcRefresh = VTToEdit(rcWord);
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001294 m_pNotify->InvalidateRect(&rcRefresh);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001295 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001296 }
thestig821d59e2016-05-11 12:59:22 -07001297 } else {
1298 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1299 lineinfo.ptLine.y + lineinfo.fLineDescent,
1300 lineinfo.ptLine.x + lineinfo.fLineWidth,
1301 lineinfo.ptLine.y + lineinfo.fLineAscent);
1302
dsinclaira2919b32016-07-13 10:55:48 -07001303 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001304 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001305 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001306 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001307 CFX_FloatRect rcRefresh = VTToEdit(rcLine);
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001308 m_pNotify->InvalidateRect(&rcRefresh);
thestig821d59e2016-05-11 12:59:22 -07001309 }
1310 }
1311
1312 pIterator->NextLine();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001313 }
1314 }
1315}
1316
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001317void CPWL_EditImpl::SetCaret(const CPVT_WordPlace& place) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001318 m_wpOldCaret = m_wpCaret;
1319 m_wpCaret = place;
1320}
1321
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001322void CPWL_EditImpl::SetCaretInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001323 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001324 if (!m_bNotifyFlag) {
thestig821d59e2016-05-11 12:59:22 -07001325 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1326 pIterator->SetAt(m_wpCaret);
tsepez63f545c2016-09-13 16:08:49 -07001327
Dan Sinclairf528eee2017-02-14 11:52:07 -05001328 CFX_PointF ptHead;
1329 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001330 CPVT_Word word;
1331 CPVT_Line line;
1332 if (pIterator->GetWord(word)) {
1333 ptHead.x = word.ptWord.x + word.fWidth;
1334 ptHead.y = word.ptWord.y + word.fAscent;
1335 ptFoot.x = word.ptWord.x + word.fWidth;
1336 ptFoot.y = word.ptWord.y + word.fDescent;
1337 } else if (pIterator->GetLine(line)) {
1338 ptHead.x = line.ptLine.x;
1339 ptHead.y = line.ptLine.y + line.fLineAscent;
1340 ptFoot.x = line.ptLine.x;
1341 ptFoot.y = line.ptLine.y + line.fLineDescent;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001342 }
1343
Lei Zhanga8c2b912017-03-22 17:41:02 -07001344 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001345 m_bNotifyFlag = true;
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001346 m_pNotify->SetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead),
1347 VTToEdit(ptFoot));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001348 }
1349 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001350}
1351
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001352void CPWL_EditImpl::OnMouseDown(const CFX_PointF& point,
1353 bool bShift,
1354 bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001355 if (!m_pVT->IsValid())
1356 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001357
Tom Sepez52f69b32017-03-21 13:42:38 -07001358 SelectNone();
1359 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1360 m_SelState.Set(m_wpCaret, m_wpCaret);
1361 ScrollToCaret();
1362 SetCaretOrigin();
1363 SetCaretInfo();
1364}
1365
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001366void CPWL_EditImpl::OnMouseMove(const CFX_PointF& point,
1367 bool bShift,
1368 bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001369 if (!m_pVT->IsValid())
1370 return;
1371
1372 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1373 if (m_wpCaret == m_wpOldCaret)
1374 return;
1375
1376 m_SelState.SetEndPos(m_wpCaret);
1377 ScrollToCaret();
1378 Refresh();
1379 SetCaretOrigin();
1380 SetCaretInfo();
1381}
1382
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001383void CPWL_EditImpl::OnVK_UP(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001384 if (!m_pVT->IsValid())
1385 return;
1386
1387 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1388 if (bShift) {
1389 if (m_SelState.IsEmpty())
1390 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1391 else
1392 m_SelState.SetEndPos(m_wpCaret);
1393
1394 if (m_wpOldCaret != m_wpCaret) {
1395 ScrollToCaret();
1396 Refresh();
1397 SetCaretInfo();
1398 }
1399 } else {
1400 SelectNone();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001401 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001402 SetCaretInfo();
1403 }
1404}
1405
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001406void CPWL_EditImpl::OnVK_DOWN(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001407 if (!m_pVT->IsValid())
1408 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001409
Tom Sepez52f69b32017-03-21 13:42:38 -07001410 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1411 if (bShift) {
1412 if (m_SelState.IsEmpty())
1413 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1414 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001415 m_SelState.SetEndPos(m_wpCaret);
1416
Tom Sepez52f69b32017-03-21 13:42:38 -07001417 if (m_wpOldCaret != m_wpCaret) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001418 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001419 Refresh();
Tom Sepez52f69b32017-03-21 13:42:38 -07001420 SetCaretInfo();
1421 }
1422 } else {
1423 SelectNone();
1424 ScrollToCaret();
1425 SetCaretInfo();
1426 }
1427}
1428
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001429void CPWL_EditImpl::OnVK_LEFT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001430 if (!m_pVT->IsValid())
1431 return;
1432
1433 if (bShift) {
1434 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1435 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1436 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1437 }
1438 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1439 if (m_SelState.IsEmpty())
1440 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1441 else
1442 m_SelState.SetEndPos(m_wpCaret);
1443
1444 if (m_wpOldCaret != m_wpCaret) {
1445 ScrollToCaret();
1446 Refresh();
1447 SetCaretInfo();
1448 }
1449 } else {
1450 if (!m_SelState.IsEmpty()) {
1451 if (m_SelState.BeginPos < m_SelState.EndPos)
1452 SetCaret(m_SelState.BeginPos);
1453 else
1454 SetCaret(m_SelState.EndPos);
1455
1456 SelectNone();
1457 ScrollToCaret();
1458 SetCaretInfo();
1459 } else {
1460 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1461 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1462 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1463 }
1464 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1465 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001466 SetCaretOrigin();
1467 SetCaretInfo();
1468 }
1469 }
1470}
1471
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001472void CPWL_EditImpl::OnVK_RIGHT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001473 if (!m_pVT->IsValid())
1474 return;
1475
1476 if (bShift) {
1477 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1478 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1479 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001480 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1481
Tom Sepez52f69b32017-03-21 13:42:38 -07001482 if (m_SelState.IsEmpty())
1483 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1484 else
1485 m_SelState.SetEndPos(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001486
Tom Sepez52f69b32017-03-21 13:42:38 -07001487 if (m_wpOldCaret != m_wpCaret) {
1488 ScrollToCaret();
1489 Refresh();
1490 SetCaretInfo();
1491 }
1492 } else {
1493 if (!m_SelState.IsEmpty()) {
1494 if (m_SelState.BeginPos > m_SelState.EndPos)
1495 SetCaret(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001496 else
Tom Sepez52f69b32017-03-21 13:42:38 -07001497 SetCaret(m_SelState.EndPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001498
Tom Sepez52f69b32017-03-21 13:42:38 -07001499 SelectNone();
1500 ScrollToCaret();
1501 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001502 } else {
Tom Sepez52f69b32017-03-21 13:42:38 -07001503 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1504 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1505 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001506 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001507 }
Tom Sepez52f69b32017-03-21 13:42:38 -07001508 ScrollToCaret();
1509 SetCaretOrigin();
1510 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001511 }
1512 }
1513}
1514
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001515void CPWL_EditImpl::OnVK_HOME(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001516 if (!m_pVT->IsValid())
1517 return;
1518
1519 if (bShift) {
1520 if (bCtrl)
1521 SetCaret(m_pVT->GetBeginWordPlace());
1522 else
1523 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1524
1525 if (m_SelState.IsEmpty())
1526 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1527 else
1528 m_SelState.SetEndPos(m_wpCaret);
1529
1530 ScrollToCaret();
1531 Refresh();
1532 SetCaretInfo();
1533 } else {
1534 if (!m_SelState.IsEmpty()) {
1535 SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos));
1536 SelectNone();
1537 ScrollToCaret();
1538 SetCaretInfo();
1539 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001540 if (bCtrl)
1541 SetCaret(m_pVT->GetBeginWordPlace());
1542 else
1543 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1544
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001545 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001546 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001547 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001548 }
1549 }
1550}
1551
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001552void CPWL_EditImpl::OnVK_END(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001553 if (!m_pVT->IsValid())
1554 return;
1555
1556 if (bShift) {
1557 if (bCtrl)
1558 SetCaret(m_pVT->GetEndWordPlace());
1559 else
1560 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1561
1562 if (m_SelState.IsEmpty())
1563 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1564 else
1565 m_SelState.SetEndPos(m_wpCaret);
1566
1567 ScrollToCaret();
1568 Refresh();
1569 SetCaretInfo();
1570 } else {
1571 if (!m_SelState.IsEmpty()) {
1572 SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos));
1573 SelectNone();
1574 ScrollToCaret();
1575 SetCaretInfo();
1576 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001577 if (bCtrl)
1578 SetCaret(m_pVT->GetEndWordPlace());
1579 else
1580 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1581
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001582 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001583 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001584 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001585 }
1586 }
1587}
1588
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001589bool CPWL_EditImpl::InsertWord(uint16_t word,
1590 int32_t charset,
1591 const CPVT_WordProps* pWordProps,
1592 bool bAddUndo,
1593 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001594 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001595 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001596
Tom Sepez3509d162017-01-30 13:22:02 -08001597 m_pVT->UpdateWordPlace(m_wpCaret);
1598 SetCaret(m_pVT->InsertWord(m_wpCaret, word,
1599 GetCharSetFromUnicode(word, charset), pWordProps));
1600 m_SelState.Set(m_wpCaret, m_wpCaret);
1601 if (m_wpCaret == m_wpOldCaret)
1602 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001603
Tom Sepez3509d162017-01-30 13:22:02 -08001604 if (bAddUndo && m_bEnableUndo) {
1605 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertWord>(
1606 this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001607 }
Tom Sepez3509d162017-01-30 13:22:02 -08001608 if (bPaint)
1609 PaintInsertText(m_wpOldCaret, m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001610
Tom Sepez3509d162017-01-30 13:22:02 -08001611 if (m_bOprNotify && m_pOprNotify)
1612 m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
1613
1614 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001615}
1616
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001617bool CPWL_EditImpl::InsertReturn(const CPVT_SecProps* pSecProps,
1618 const CPVT_WordProps* pWordProps,
1619 bool bAddUndo,
1620 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001621 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001622 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001623
Tom Sepez3509d162017-01-30 13:22:02 -08001624 m_pVT->UpdateWordPlace(m_wpCaret);
1625 SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
1626 m_SelState.Set(m_wpCaret, m_wpCaret);
1627 if (m_wpCaret == m_wpOldCaret)
1628 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001629
Tom Sepez3509d162017-01-30 13:22:02 -08001630 if (bAddUndo && m_bEnableUndo) {
1631 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertReturn>(
1632 this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001633 }
Tom Sepez3509d162017-01-30 13:22:02 -08001634 if (bPaint) {
1635 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1636 ScrollToCaret();
1637 Refresh();
1638 SetCaretOrigin();
1639 SetCaretInfo();
1640 }
1641 if (m_bOprNotify && m_pOprNotify)
1642 m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001643
Tom Sepez3509d162017-01-30 13:22:02 -08001644 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001645}
1646
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001647bool CPWL_EditImpl::Backspace(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001648 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1649 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001650
Tom Sepez3509d162017-01-30 13:22:02 -08001651 CPVT_Section section;
1652 CPVT_Word word;
1653 if (bAddUndo) {
1654 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1655 pIterator->SetAt(m_wpCaret);
1656 pIterator->GetSection(section);
1657 pIterator->GetWord(word);
1658 }
1659 m_pVT->UpdateWordPlace(m_wpCaret);
1660 SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1661 m_SelState.Set(m_wpCaret, m_wpCaret);
1662 if (m_wpCaret == m_wpOldCaret)
1663 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001664
Tom Sepez3509d162017-01-30 13:22:02 -08001665 if (bAddUndo && m_bEnableUndo) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001666 if (m_wpCaret.nSecIndex != m_wpOldCaret.nSecIndex) {
Tom Sepez3509d162017-01-30 13:22:02 -08001667 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1668 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1669 section.SecProps, section.WordProps));
1670 } else {
1671 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1672 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1673 section.SecProps, word.WordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001674 }
1675 }
Tom Sepez3509d162017-01-30 13:22:02 -08001676 if (bPaint) {
1677 RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
1678 ScrollToCaret();
1679 Refresh();
1680 SetCaretOrigin();
1681 SetCaretInfo();
1682 }
1683 if (m_bOprNotify && m_pOprNotify)
1684 m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001685
Tom Sepez3509d162017-01-30 13:22:02 -08001686 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001687}
1688
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001689bool CPWL_EditImpl::Delete(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001690 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1691 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001692
Tom Sepez3509d162017-01-30 13:22:02 -08001693 CPVT_Section section;
1694 CPVT_Word word;
1695 if (bAddUndo) {
1696 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1697 pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1698 pIterator->GetSection(section);
1699 pIterator->GetWord(word);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001700 }
Tom Sepez3509d162017-01-30 13:22:02 -08001701 m_pVT->UpdateWordPlace(m_wpCaret);
1702 bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1703 SetCaret(m_pVT->DeleteWord(m_wpCaret));
1704 m_SelState.Set(m_wpCaret, m_wpCaret);
1705 if (bAddUndo && m_bEnableUndo) {
1706 if (bSecEnd) {
1707 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1708 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1709 section.SecProps, section.WordProps, bSecEnd));
1710 } else {
1711 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1712 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1713 section.SecProps, word.WordProps, bSecEnd));
1714 }
1715 }
1716 if (bPaint) {
1717 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1718 ScrollToCaret();
1719 Refresh();
1720 SetCaretOrigin();
1721 SetCaretInfo();
1722 }
1723 if (m_bOprNotify && m_pOprNotify)
1724 m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001725
Tom Sepez3509d162017-01-30 13:22:02 -08001726 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001727}
1728
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001729bool CPWL_EditImpl::Empty() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001730 if (m_pVT->IsValid()) {
1731 m_pVT->DeleteWords(GetWholeWordRange());
1732 SetCaret(m_pVT->GetBeginWordPlace());
1733
tsepez4cf55152016-11-02 14:37:54 -07001734 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001735 }
1736
tsepez4cf55152016-11-02 14:37:54 -07001737 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001738}
1739
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001740bool CPWL_EditImpl::Clear(bool bAddUndo, bool bPaint) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001741 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
tsepez4cf55152016-11-02 14:37:54 -07001742 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001743
thestig821d59e2016-05-11 12:59:22 -07001744 CPVT_WordRange range = m_SelState.ConvertToWordRange();
Diana Gage22bf7a52017-07-21 11:33:18 -07001745 if (bAddUndo && m_bEnableUndo) {
Diana Gage89e65622017-07-20 18:09:31 -07001746 AddEditUndoItem(
1747 pdfium::MakeUnique<CFXEU_Clear>(this, range, GetSelectedText()));
Diana Gage22bf7a52017-07-21 11:33:18 -07001748 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001749
thestig821d59e2016-05-11 12:59:22 -07001750 SelectNone();
1751 SetCaret(m_pVT->DeleteWords(range));
1752 m_SelState.Set(m_wpCaret, m_wpCaret);
thestig821d59e2016-05-11 12:59:22 -07001753 if (bPaint) {
1754 RearrangePart(range);
1755 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001756 Refresh();
thestig821d59e2016-05-11 12:59:22 -07001757 SetCaretOrigin();
1758 SetCaretInfo();
1759 }
thestig821d59e2016-05-11 12:59:22 -07001760 if (m_bOprNotify && m_pOprNotify)
1761 m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);
1762
tsepez4cf55152016-11-02 14:37:54 -07001763 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001764}
1765
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001766bool CPWL_EditImpl::InsertText(const CFX_WideString& sText,
1767 int32_t charset,
1768 bool bAddUndo,
1769 bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001770 if (IsTextOverflow())
tsepez4cf55152016-11-02 14:37:54 -07001771 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001772
1773 m_pVT->UpdateWordPlace(m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001774 SetCaret(DoInsertText(m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001775 m_SelState.Set(m_wpCaret, m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001776 if (m_wpCaret == m_wpOldCaret)
tsepez4cf55152016-11-02 14:37:54 -07001777 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001778
tsepeza31da742016-09-08 11:28:14 -07001779 if (bAddUndo && m_bEnableUndo) {
Tom Sepez3509d162017-01-30 13:22:02 -08001780 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertText>(
1781 this, m_wpOldCaret, m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001782 }
tsepeza31da742016-09-08 11:28:14 -07001783 if (bPaint)
1784 PaintInsertText(m_wpOldCaret, m_wpCaret);
1785
1786 if (m_bOprNotify && m_pOprNotify)
1787 m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
1788
tsepez4cf55152016-11-02 14:37:54 -07001789 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001790}
1791
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001792void CPWL_EditImpl::PaintInsertText(const CPVT_WordPlace& wpOld,
1793 const CPVT_WordPlace& wpNew) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001794 if (m_pVT->IsValid()) {
1795 RearrangePart(CPVT_WordRange(wpOld, wpNew));
1796 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001797 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001798 SetCaretOrigin();
1799 SetCaretInfo();
1800 }
1801}
1802
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001803bool CPWL_EditImpl::Redo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001804 if (m_bEnableUndo) {
1805 if (m_Undo.CanRedo()) {
1806 m_Undo.Redo();
tsepez4cf55152016-11-02 14:37:54 -07001807 return true;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001808 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001809 }
1810
tsepez4cf55152016-11-02 14:37:54 -07001811 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001812}
1813
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001814bool CPWL_EditImpl::Undo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001815 if (m_bEnableUndo) {
1816 if (m_Undo.CanUndo()) {
1817 m_Undo.Undo();
tsepez4cf55152016-11-02 14:37:54 -07001818 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001819 }
1820 }
1821
tsepez4cf55152016-11-02 14:37:54 -07001822 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001823}
1824
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001825void CPWL_EditImpl::SetCaretOrigin() {
thestig821d59e2016-05-11 12:59:22 -07001826 if (!m_pVT->IsValid())
1827 return;
1828
1829 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1830 pIterator->SetAt(m_wpCaret);
1831 CPVT_Word word;
1832 CPVT_Line line;
1833 if (pIterator->GetWord(word)) {
1834 m_ptCaret.x = word.ptWord.x + word.fWidth;
1835 m_ptCaret.y = word.ptWord.y;
1836 } else if (pIterator->GetLine(line)) {
1837 m_ptCaret.x = line.ptLine.x;
1838 m_ptCaret.y = line.ptLine.y;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001839 }
1840}
1841
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001842CPVT_WordPlace CPWL_EditImpl::WordIndexToWordPlace(int32_t index) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001843 if (m_pVT->IsValid())
1844 return m_pVT->WordIndexToWordPlace(index);
1845
1846 return CPVT_WordPlace();
1847}
1848
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001849bool CPWL_EditImpl::IsTextFull() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001850 int32_t nTotalWords = m_pVT->GetTotalWords();
1851 int32_t nLimitChar = m_pVT->GetLimitChar();
1852 int32_t nCharArray = m_pVT->GetCharArray();
1853
1854 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
1855 (nCharArray > 0 && nTotalWords >= nCharArray);
1856}
1857
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001858bool CPWL_EditImpl::IsTextOverflow() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001859 if (!m_bEnableScroll && !m_bEnableOverflow) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001860 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1861 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001862
dsinclair448c4332016-08-02 12:07:35 -07001863 if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
1864 IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
tsepez4cf55152016-11-02 14:37:54 -07001865 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001866 }
1867
dsinclair448c4332016-08-02 12:07:35 -07001868 if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
tsepez4cf55152016-11-02 14:37:54 -07001869 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001870 }
1871
tsepez4cf55152016-11-02 14:37:54 -07001872 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001873}
1874
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001875bool CPWL_EditImpl::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001876 if (m_bEnableUndo) {
1877 return m_Undo.CanUndo();
1878 }
1879
tsepez4cf55152016-11-02 14:37:54 -07001880 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001881}
1882
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001883bool CPWL_EditImpl::CanRedo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001884 if (m_bEnableUndo) {
1885 return m_Undo.CanRedo();
1886 }
1887
tsepez4cf55152016-11-02 14:37:54 -07001888 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001889}
1890
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001891void CPWL_EditImpl::EnableRefresh(bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001892 m_bEnableRefresh = bRefresh;
1893}
1894
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001895void CPWL_EditImpl::EnableUndo(bool bUndo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001896 m_bEnableUndo = bUndo;
1897}
1898
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001899void CPWL_EditImpl::EnableOprNotify(bool bNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001900 m_bOprNotify = bNotify;
1901}
1902
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001903CPVT_WordPlace CPWL_EditImpl::DoInsertText(const CPVT_WordPlace& place,
1904 const CFX_WideString& sText,
1905 int32_t charset) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001906 CPVT_WordPlace wp = place;
1907
1908 if (m_pVT->IsValid()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001909 for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
Tom Sepez62a70f92016-03-21 15:00:20 -07001910 uint16_t word = sText[i];
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001911 switch (word) {
1912 case 0x0D:
dsinclairefd5a992016-07-18 10:04:07 -07001913 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001914 if (sText[i + 1] == 0x0A)
1915 i++;
1916 break;
1917 case 0x0A:
dsinclairefd5a992016-07-18 10:04:07 -07001918 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001919 if (sText[i + 1] == 0x0D)
1920 i++;
1921 break;
1922 case 0x09:
1923 word = 0x20;
1924 default:
1925 wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
dsinclairefd5a992016-07-18 10:04:07 -07001926 nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001927 break;
1928 }
1929 }
1930 }
1931
1932 return wp;
1933}
1934
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001935int32_t CPWL_EditImpl::GetCharSetFromUnicode(uint16_t word,
1936 int32_t nOldCharset) {
dsinclairc7a73492016-04-05 12:01:42 -07001937 if (IPVT_FontMap* pFontMap = GetFontMap())
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001938 return pFontMap->CharSetFromUnicode(word, nOldCharset);
1939 return nOldCharset;
1940}
1941
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001942void CPWL_EditImpl::AddEditUndoItem(
1943 std::unique_ptr<CPWL_EditImpl_UndoItem> pEditUndoItem) {
Lei Zhang1a89e362017-03-23 15:27:25 -07001944 m_Undo.AddItem(std::move(pEditUndoItem));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001945}
1946
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001947CFX_ByteString CPWL_EditImpl::GetPDFWordString(int32_t nFontIndex,
1948 uint16_t Word,
1949 uint16_t SubWord) {
Dan Sinclairc08dc392017-07-24 08:57:35 -04001950 IPVT_FontMap* pFontMap = GetFontMap();
1951 CPDF_Font* pPDFFont = pFontMap->GetPDFFont(nFontIndex);
1952 if (!pPDFFont)
1953 return CFX_ByteString();
1954
1955 CFX_ByteString sWord;
1956 if (SubWord > 0) {
1957 Word = SubWord;
1958 } else {
1959 uint32_t dwCharCode = pPDFFont->IsUnicodeCompatible()
1960 ? pPDFFont->CharCodeFromUnicode(Word)
1961 : pFontMap->CharCodeFromUnicode(nFontIndex, Word);
1962 if (dwCharCode > 0) {
1963 pPDFFont->AppendChar(&sWord, dwCharCode);
1964 return sWord;
1965 }
1966 }
1967 pPDFFont->AppendChar(&sWord, Word);
1968 return sWord;
1969}
1970
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001971CPWL_EditImpl_LineRectArray::CPWL_EditImpl_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07001972
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001973CPWL_EditImpl_LineRectArray::~CPWL_EditImpl_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07001974
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001975void CPWL_EditImpl_LineRectArray::operator=(
1976 CPWL_EditImpl_LineRectArray&& that) {
Tom Sepez3509d162017-01-30 13:22:02 -08001977 m_LineRects = std::move(that.m_LineRects);
weili625ad662016-06-15 11:21:33 -07001978}
1979
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001980void CPWL_EditImpl_LineRectArray::Add(const CPVT_WordRange& wrLine,
1981 const CFX_FloatRect& rcLine) {
1982 m_LineRects.push_back(
1983 pdfium::MakeUnique<CPWL_EditImpl_LineRect>(wrLine, rcLine));
weili625ad662016-06-15 11:21:33 -07001984}
1985
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001986int32_t CPWL_EditImpl_LineRectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08001987 return pdfium::CollectionSize<int32_t>(m_LineRects);
weili625ad662016-06-15 11:21:33 -07001988}
1989
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001990CPWL_EditImpl_LineRect* CPWL_EditImpl_LineRectArray::GetAt(
1991 int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08001992 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07001993 return nullptr;
1994
Tom Sepez3509d162017-01-30 13:22:02 -08001995 return m_LineRects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07001996}
1997
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001998CPWL_EditImpl_Select::CPWL_EditImpl_Select() {}
weili625ad662016-06-15 11:21:33 -07001999
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002000CPWL_EditImpl_Select::CPWL_EditImpl_Select(const CPVT_WordRange& range) {
weili625ad662016-06-15 11:21:33 -07002001 Set(range.BeginPos, range.EndPos);
2002}
2003
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002004CPVT_WordRange CPWL_EditImpl_Select::ConvertToWordRange() const {
weili625ad662016-06-15 11:21:33 -07002005 return CPVT_WordRange(BeginPos, EndPos);
2006}
2007
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002008void CPWL_EditImpl_Select::Reset() {
Tom Sepez52f69b32017-03-21 13:42:38 -07002009 BeginPos.Reset();
2010 EndPos.Reset();
weili625ad662016-06-15 11:21:33 -07002011}
2012
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002013void CPWL_EditImpl_Select::Set(const CPVT_WordPlace& begin,
2014 const CPVT_WordPlace& end) {
weili625ad662016-06-15 11:21:33 -07002015 BeginPos = begin;
2016 EndPos = end;
2017}
2018
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002019void CPWL_EditImpl_Select::SetEndPos(const CPVT_WordPlace& end) {
weili625ad662016-06-15 11:21:33 -07002020 EndPos = end;
2021}
2022
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002023bool CPWL_EditImpl_Select::IsEmpty() const {
Tom Sepez52f69b32017-03-21 13:42:38 -07002024 return BeginPos == EndPos;
weili625ad662016-06-15 11:21:33 -07002025}
2026
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002027CPWL_EditImpl_RectArray::CPWL_EditImpl_RectArray() {}
weili625ad662016-06-15 11:21:33 -07002028
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002029CPWL_EditImpl_RectArray::~CPWL_EditImpl_RectArray() {}
weili625ad662016-06-15 11:21:33 -07002030
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002031void CPWL_EditImpl_RectArray::Clear() {
Tom Sepez3509d162017-01-30 13:22:02 -08002032 m_Rects.clear();
weili625ad662016-06-15 11:21:33 -07002033}
2034
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002035void CPWL_EditImpl_RectArray::Add(const CFX_FloatRect& rect) {
weili625ad662016-06-15 11:21:33 -07002036 // check for overlapped area
Tom Sepez3509d162017-01-30 13:22:02 -08002037 for (const auto& pRect : m_Rects) {
weili625ad662016-06-15 11:21:33 -07002038 if (pRect && pRect->Contains(rect))
2039 return;
2040 }
Tom Sepez3509d162017-01-30 13:22:02 -08002041 m_Rects.push_back(pdfium::MakeUnique<CFX_FloatRect>(rect));
weili625ad662016-06-15 11:21:33 -07002042}
2043
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002044int32_t CPWL_EditImpl_RectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08002045 return pdfium::CollectionSize<int32_t>(m_Rects);
weili625ad662016-06-15 11:21:33 -07002046}
2047
Dan Sinclair6b0158f2017-07-24 09:42:55 -04002048CFX_FloatRect* CPWL_EditImpl_RectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002049 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002050 return nullptr;
2051
Tom Sepez3509d162017-01-30 13:22:02 -08002052 return m_Rects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002053}