blob: 1f3aa211300d4845c689c092fa380ad9f83ed783 [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 Sinclairc411eb92017-07-25 09:39:30 -04007#include "fpdfsdk/pwl/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"
Dan Sinclairc411eb92017-07-25 09:39:30 -040030#include "fpdfsdk/pwl/cpwl_edit.h"
31#include "fpdfsdk/pwl/cpwl_edit_ctrl.h"
32#include "fpdfsdk/pwl/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 -0400276CFXEU_InsertWord::CFXEU_InsertWord(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 const CPVT_WordPlace& wpOldPlace,
278 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700279 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280 int32_t charset,
281 const CPVT_WordProps* pWordProps)
282 : m_pEdit(pEdit),
283 m_wpOld(wpOldPlace),
284 m_wpNew(wpNewPlace),
285 m_Word(word),
286 m_nCharset(charset),
287 m_WordProps() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700288 ASSERT(m_pEdit);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700289 if (pWordProps)
290 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700291}
292
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293CFXEU_InsertWord::~CFXEU_InsertWord() {}
294
295void CFXEU_InsertWord::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700296 m_pEdit->SelectNone();
297 m_pEdit->SetCaret(m_wpOld);
298 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700299}
300
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700301void CFXEU_InsertWord::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700302 m_pEdit->SelectNone();
303 m_pEdit->SetCaret(m_wpNew);
304 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700305}
306
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400307CFXEU_InsertReturn::CFXEU_InsertReturn(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308 const CPVT_WordPlace& wpOldPlace,
309 const CPVT_WordPlace& wpNewPlace,
310 const CPVT_SecProps* pSecProps,
311 const CPVT_WordProps* pWordProps)
312 : m_pEdit(pEdit),
313 m_wpOld(wpOldPlace),
314 m_wpNew(wpNewPlace),
315 m_SecProps(),
316 m_WordProps() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700317 ASSERT(m_pEdit);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700318 if (pSecProps)
319 m_SecProps = *pSecProps;
320 if (pWordProps)
321 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700322}
323
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324CFXEU_InsertReturn::~CFXEU_InsertReturn() {}
325
326void CFXEU_InsertReturn::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700327 m_pEdit->SelectNone();
328 m_pEdit->SetCaret(m_wpOld);
329 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700330}
331
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700332void CFXEU_InsertReturn::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700333 m_pEdit->SelectNone();
334 m_pEdit->SetCaret(m_wpNew);
335 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700336}
337
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400338CFXEU_Backspace::CFXEU_Backspace(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339 const CPVT_WordPlace& wpOldPlace,
340 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700341 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700342 int32_t charset,
343 const CPVT_SecProps& SecProps,
344 const CPVT_WordProps& WordProps)
345 : m_pEdit(pEdit),
346 m_wpOld(wpOldPlace),
347 m_wpNew(wpNewPlace),
348 m_Word(word),
349 m_nCharset(charset),
350 m_SecProps(SecProps),
Lei Zhangf5a06672017-08-12 08:01:37 -0700351 m_WordProps(WordProps) {
352 ASSERT(m_pEdit);
353}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700354
355CFXEU_Backspace::~CFXEU_Backspace() {}
356
357void CFXEU_Backspace::Redo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700358 m_pEdit->SelectNone();
359 m_pEdit->SetCaret(m_wpOld);
360 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700361}
362
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363void CFXEU_Backspace::Undo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700364 m_pEdit->SelectNone();
365 m_pEdit->SetCaret(m_wpNew);
366 if (m_wpNew.nSecIndex != m_wpOld.nSecIndex)
367 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
368 else
369 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700370}
371
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400372CFXEU_Delete::CFXEU_Delete(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700373 const CPVT_WordPlace& wpOldPlace,
374 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700375 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376 int32_t charset,
377 const CPVT_SecProps& SecProps,
378 const CPVT_WordProps& WordProps,
tsepez4cf55152016-11-02 14:37:54 -0700379 bool bSecEnd)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700380 : m_pEdit(pEdit),
381 m_wpOld(wpOldPlace),
382 m_wpNew(wpNewPlace),
383 m_Word(word),
384 m_nCharset(charset),
385 m_SecProps(SecProps),
386 m_WordProps(WordProps),
Lei Zhangf5a06672017-08-12 08:01:37 -0700387 m_bSecEnd(bSecEnd) {
388 ASSERT(m_pEdit);
389}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390
391CFXEU_Delete::~CFXEU_Delete() {}
392
393void CFXEU_Delete::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700394 m_pEdit->SelectNone();
395 m_pEdit->SetCaret(m_wpOld);
396 m_pEdit->Delete(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700397}
398
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700399void CFXEU_Delete::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700400 m_pEdit->SelectNone();
401 m_pEdit->SetCaret(m_wpNew);
402 if (m_bSecEnd)
403 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
404 else
405 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700406}
407
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400408CFXEU_Clear::CFXEU_Clear(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700409 const CPVT_WordRange& wrSel,
410 const CFX_WideString& swText)
Lei Zhangf5a06672017-08-12 08:01:37 -0700411 : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {
412 ASSERT(m_pEdit);
413}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700414
415CFXEU_Clear::~CFXEU_Clear() {}
416
417void CFXEU_Clear::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700418 m_pEdit->SelectNone();
419 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
420 m_pEdit->Clear(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700421}
422
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700423void CFXEU_Clear::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700424 m_pEdit->SelectNone();
425 m_pEdit->SetCaret(m_wrSel.BeginPos);
426 m_pEdit->InsertText(m_swText, FX_CHARSET_Default, false, true);
427 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700428}
429
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400430CFXEU_InsertText::CFXEU_InsertText(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700431 const CPVT_WordPlace& wpOldPlace,
432 const CPVT_WordPlace& wpNewPlace,
433 const CFX_WideString& swText,
dsinclairefd5a992016-07-18 10:04:07 -0700434 int32_t charset)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700435 : m_pEdit(pEdit),
436 m_wpOld(wpOldPlace),
437 m_wpNew(wpNewPlace),
438 m_swText(swText),
Lei Zhangf5a06672017-08-12 08:01:37 -0700439 m_nCharset(charset) {
440 ASSERT(m_pEdit);
441}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700442
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700443CFXEU_InsertText::~CFXEU_InsertText() {}
444
445void CFXEU_InsertText::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700446 m_pEdit->SelectNone();
447 m_pEdit->SetCaret(m_wpOld);
448 m_pEdit->InsertText(m_swText, m_nCharset, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700449}
450
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700451void CFXEU_InsertText::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700452 m_pEdit->SelectNone();
453 m_pEdit->SetSelection(m_wpOld, m_wpNew);
454 m_pEdit->Clear(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700455}
456
dsinclaire35af1e2016-07-13 11:26:20 -0700457// static
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400458void CPWL_EditImpl::DrawEdit(CFX_RenderDevice* pDevice,
459 CFX_Matrix* pUser2Device,
460 CPWL_EditImpl* pEdit,
461 FX_COLORREF crTextFill,
462 const CFX_FloatRect& rcClip,
463 const CFX_PointF& ptOffset,
464 const CPVT_WordRange* pRange,
465 CFX_SystemHandler* pSystemHandler,
466 CFFL_FormFiller* pFFLData) {
dsinclaire35af1e2016-07-13 11:26:20 -0700467 const bool bContinuous =
468 pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
469 uint16_t SubWord = pEdit->GetPasswordChar();
Dan Sinclair05df0752017-03-14 14:43:42 -0400470 float fFontSize = pEdit->GetFontSize();
dsinclaire35af1e2016-07-13 11:26:20 -0700471 CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
472 int32_t nHorzScale = pEdit->GetHorzScale();
473
474 FX_COLORREF crCurFill = crTextFill;
475 FX_COLORREF crOldFill = crCurFill;
476
tsepez4cf55152016-11-02 14:37:54 -0700477 bool bSelect = false;
dsinclaire35af1e2016-07-13 11:26:20 -0700478 const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
479 const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
480
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400481 std::ostringstream sTextBuf;
dsinclaire35af1e2016-07-13 11:26:20 -0700482 int32_t nFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500483 CFX_PointF ptBT;
Tom Sepez1629f602017-04-21 14:11:26 -0700484 CFX_RenderDevice::StateRestorer restorer(pDevice);
dsinclaire35af1e2016-07-13 11:26:20 -0700485 if (!rcClip.IsEmpty()) {
486 CFX_FloatRect rcTemp = rcClip;
487 pUser2Device->TransformRect(rcTemp);
488 pDevice->SetClip_Rect(rcTemp.ToFxRect());
489 }
490
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400491 CPWL_EditImpl_Iterator* pIterator = pEdit->GetIterator();
dsinclaire35af1e2016-07-13 11:26:20 -0700492 if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
493 if (pRange)
494 pIterator->SetAt(pRange->BeginPos);
495 else
496 pIterator->SetAt(0);
497
498 CPVT_WordPlace oldplace;
499 while (pIterator->NextWord()) {
500 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700501 if (pRange && place > pRange->EndPos)
dsinclaire35af1e2016-07-13 11:26:20 -0700502 break;
503
Tom Sepez52f69b32017-03-21 13:42:38 -0700504 if (!wrSelect.IsEmpty()) {
505 bSelect = place > wrSelect.BeginPos && place <= wrSelect.EndPos;
dsinclaire35af1e2016-07-13 11:26:20 -0700506 crCurFill = bSelect ? crWhite : crTextFill;
507 }
508 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
509 crCurFill = crTextFill;
510 crOldFill = crCurFill;
511 }
512 CPVT_Word word;
513 if (pIterator->GetWord(word)) {
514 if (bSelect) {
515 CPVT_Line line;
516 pIterator->GetLine(line);
517
518 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
519 CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
520 word.ptWord.x + word.fWidth,
521 line.ptLine.y + line.fLineAscent);
522 rc.Intersect(rcClip);
523 pSystemHandler->OutputSelectedRect(pFFLData, rc);
524 } else {
525 CFX_PathData pathSelBK;
526 pathSelBK.AppendRect(
527 word.ptWord.x, line.ptLine.y + line.fLineDescent,
528 word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent);
529
530 pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
531 FXFILL_WINDING);
532 }
533 }
534
535 if (bContinuous) {
536 if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
537 crOldFill != crCurFill) {
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400538 if (sTextBuf.tellp() > 0) {
dsinclaire35af1e2016-07-13 11:26:20 -0700539 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500540 pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700541 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400542 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700543
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400544 sTextBuf.str("");
dsinclaire35af1e2016-07-13 11:26:20 -0700545 }
546 nFontIndex = word.nFontIndex;
547 ptBT = word.ptWord;
548 crOldFill = crCurFill;
549 }
550
Dan Sinclairc08dc392017-07-24 08:57:35 -0400551 sTextBuf << pEdit->GetPDFWordString(word.nFontIndex, word.Word,
552 SubWord);
dsinclaire35af1e2016-07-13 11:26:20 -0700553 } else {
554 DrawTextString(
Dan Sinclairc08dc392017-07-24 08:57:35 -0400555 pDevice,
556 CFX_PointF(word.ptWord.x + ptOffset.x,
557 word.ptWord.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700558 pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
Dan Sinclairc08dc392017-07-24 08:57:35 -0400559 pEdit->GetPDFWordString(word.nFontIndex, word.Word, SubWord),
Dan Sinclaira0061af2017-02-23 09:25:17 -0500560 crCurFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700561 }
562 oldplace = place;
563 }
564 }
565
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400566 if (sTextBuf.tellp() > 0) {
Dan Sinclaira0061af2017-02-23 09:25:17 -0500567 DrawTextString(pDevice,
568 CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
569 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400570 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700571 }
572 }
dsinclaire35af1e2016-07-13 11:26:20 -0700573}
574
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400575CPWL_EditImpl::CPWL_EditImpl()
Lei Zhang5688d622017-08-12 07:04:19 -0700576 : m_pVT(pdfium::MakeUnique<CPDF_VariableText>()),
tsepez4cf55152016-11-02 14:37:54 -0700577 m_bEnableScroll(false),
dsinclair8f4bf9a2016-05-04 13:51:51 -0700578 m_Undo(kEditUndoMaxItems),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579 m_nAlignment(0),
tsepez4cf55152016-11-02 14:37:54 -0700580 m_bNotifyFlag(false),
581 m_bEnableOverflow(false),
582 m_bEnableRefresh(true),
Lei Zhang5688d622017-08-12 07:04:19 -0700583 m_bEnableUndo(true) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700584
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400585CPWL_EditImpl::~CPWL_EditImpl() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700586
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400587void CPWL_EditImpl::Initialize() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700588 m_pVT->Initialize();
589 SetCaret(m_pVT->GetBeginWordPlace());
590 SetCaretOrigin();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700591}
592
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400593void CPWL_EditImpl::SetFontMap(IPVT_FontMap* pFontMap) {
594 m_pVTProvider = pdfium::MakeUnique<CPWL_EditImpl_Provider>(pFontMap);
thestig821d59e2016-05-11 12:59:22 -0700595 m_pVT->SetProvider(m_pVTProvider.get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700596}
597
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400598void CPWL_EditImpl::SetNotify(CPWL_EditCtrl* pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700599 m_pNotify = pNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700600}
601
Lei Zhang5688d622017-08-12 07:04:19 -0700602void CPWL_EditImpl::SetOperationNotify(CPWL_Edit* pOperationNotify) {
603 m_pOperationNotify = pOperationNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700604}
605
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400606CPWL_EditImpl_Iterator* CPWL_EditImpl::GetIterator() {
tsepez36eb4bd2016-10-03 15:24:27 -0700607 if (!m_pIterator) {
608 m_pIterator =
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400609 pdfium::MakeUnique<CPWL_EditImpl_Iterator>(this, m_pVT->GetIterator());
tsepez36eb4bd2016-10-03 15:24:27 -0700610 }
thestig821d59e2016-05-11 12:59:22 -0700611 return m_pIterator.get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700612}
613
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400614IPVT_FontMap* CPWL_EditImpl::GetFontMap() {
thestig821d59e2016-05-11 12:59:22 -0700615 return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700616}
617
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400618void CPWL_EditImpl::SetPlateRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700619 m_pVT->SetPlateRect(rect);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500620 m_ptScrollPos = CFX_PointF(rect.left, rect.top);
dsinclairefd5a992016-07-18 10:04:07 -0700621 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700622}
623
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400624void CPWL_EditImpl::SetAlignmentH(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700625 m_pVT->SetAlignment(nFormat);
626 if (bPaint)
627 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700628}
629
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400630void CPWL_EditImpl::SetAlignmentV(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700631 m_nAlignment = nFormat;
632 if (bPaint)
633 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700634}
635
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400636void CPWL_EditImpl::SetPasswordChar(uint16_t wSubWord, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700637 m_pVT->SetPasswordChar(wSubWord);
638 if (bPaint)
639 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700640}
641
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400642void CPWL_EditImpl::SetLimitChar(int32_t nLimitChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700643 m_pVT->SetLimitChar(nLimitChar);
dsinclairefd5a992016-07-18 10:04:07 -0700644 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700645}
646
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400647void CPWL_EditImpl::SetCharArray(int32_t nCharArray) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700648 m_pVT->SetCharArray(nCharArray);
dsinclairefd5a992016-07-18 10:04:07 -0700649 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700650}
651
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400652void CPWL_EditImpl::SetCharSpace(float fCharSpace) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700653 m_pVT->SetCharSpace(fCharSpace);
dsinclairefd5a992016-07-18 10:04:07 -0700654 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700655}
656
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400657void CPWL_EditImpl::SetMultiLine(bool bMultiLine, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700658 m_pVT->SetMultiLine(bMultiLine);
659 if (bPaint)
660 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700661}
662
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400663void CPWL_EditImpl::SetAutoReturn(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700664 m_pVT->SetAutoReturn(bAuto);
665 if (bPaint)
666 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700667}
668
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400669void CPWL_EditImpl::SetAutoFontSize(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700670 m_pVT->SetAutoFontSize(bAuto);
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::SetFontSize(float fFontSize) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700676 m_pVT->SetFontSize(fFontSize);
dsinclairefd5a992016-07-18 10:04:07 -0700677 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700678}
679
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400680void CPWL_EditImpl::SetAutoScroll(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700681 m_bEnableScroll = bAuto;
682 if (bPaint)
683 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700684}
685
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400686void CPWL_EditImpl::SetTextOverflow(bool bAllowed, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700687 m_bEnableOverflow = bAllowed;
688 if (bPaint)
689 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700690}
691
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400692void CPWL_EditImpl::SetSelection(int32_t nStartChar, int32_t nEndChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700693 if (m_pVT->IsValid()) {
694 if (nStartChar == 0 && nEndChar < 0) {
695 SelectAll();
696 } else if (nStartChar < 0) {
697 SelectNone();
698 } else {
699 if (nStartChar < nEndChar) {
Diana Gage4d02e902017-07-20 17:20:31 -0700700 SetSelection(m_pVT->WordIndexToWordPlace(nStartChar),
701 m_pVT->WordIndexToWordPlace(nEndChar));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700702 } else {
Diana Gage4d02e902017-07-20 17:20:31 -0700703 SetSelection(m_pVT->WordIndexToWordPlace(nEndChar),
704 m_pVT->WordIndexToWordPlace(nStartChar));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700705 }
706 }
707 }
708}
709
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400710void CPWL_EditImpl::SetSelection(const CPVT_WordPlace& begin,
711 const CPVT_WordPlace& end) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700712 if (!m_pVT->IsValid())
713 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700714
Tom Sepez52f69b32017-03-21 13:42:38 -0700715 SelectNone();
716 m_SelState.Set(begin, end);
717 SetCaret(m_SelState.EndPos);
718 ScrollToCaret();
719 if (!m_SelState.IsEmpty())
720 Refresh();
721 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700722}
723
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400724void CPWL_EditImpl::GetSelection(int32_t& nStartChar, int32_t& nEndChar) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700725 nStartChar = -1;
726 nEndChar = -1;
Tom Sepez52f69b32017-03-21 13:42:38 -0700727 if (!m_pVT->IsValid())
728 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700729
Tom Sepez52f69b32017-03-21 13:42:38 -0700730 if (m_SelState.IsEmpty()) {
731 nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
732 nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
733 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700734 }
Tom Sepez52f69b32017-03-21 13:42:38 -0700735 if (m_SelState.BeginPos < m_SelState.EndPos) {
736 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
737 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
738 return;
739 }
740 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
741 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700742}
743
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400744int32_t CPWL_EditImpl::GetCaret() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700745 if (m_pVT->IsValid())
746 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
747
748 return -1;
749}
750
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400751CPVT_WordPlace CPWL_EditImpl::GetCaretWordPlace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700752 return m_wpCaret;
753}
754
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400755CFX_WideString CPWL_EditImpl::GetText() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700756 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700757 if (!m_pVT->IsValid())
758 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700759
thestig821d59e2016-05-11 12:59:22 -0700760 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
761 pIterator->SetAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700762
thestig821d59e2016-05-11 12:59:22 -0700763 CPVT_Word wordinfo;
764 CPVT_WordPlace oldplace = pIterator->GetAt();
765 while (pIterator->NextWord()) {
766 CPVT_WordPlace place = pIterator->GetAt();
thestig821d59e2016-05-11 12:59:22 -0700767 if (pIterator->GetWord(wordinfo))
768 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700769 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700770 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700771 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700772 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700773 return swRet;
774}
775
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400776CFX_WideString CPWL_EditImpl::GetRangeText(const CPVT_WordRange& range) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700777 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700778 if (!m_pVT->IsValid())
779 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700780
thestig821d59e2016-05-11 12:59:22 -0700781 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
782 CPVT_WordRange wrTemp = range;
783 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
784 m_pVT->UpdateWordPlace(wrTemp.EndPos);
785 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700786
thestig821d59e2016-05-11 12:59:22 -0700787 CPVT_Word wordinfo;
788 CPVT_WordPlace oldplace = wrTemp.BeginPos;
789 while (pIterator->NextWord()) {
790 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700791 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -0700792 break;
thestig821d59e2016-05-11 12:59:22 -0700793 if (pIterator->GetWord(wordinfo))
794 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700795 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700796 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700797 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700798 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700799 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700800}
801
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400802CFX_WideString CPWL_EditImpl::GetSelectedText() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700803 return GetRangeText(m_SelState.ConvertToWordRange());
804}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700805
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400806int32_t CPWL_EditImpl::GetTotalLines() const {
thestig821d59e2016-05-11 12:59:22 -0700807 int32_t nLines = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700808
thestig821d59e2016-05-11 12:59:22 -0700809 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
810 pIterator->SetAt(0);
811 while (pIterator->NextLine())
812 ++nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700813
thestig821d59e2016-05-11 12:59:22 -0700814 return nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700815}
816
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400817CPVT_WordRange CPWL_EditImpl::GetSelectWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700818 return m_SelState.ConvertToWordRange();
819}
820
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400821void CPWL_EditImpl::SetText(const CFX_WideString& sText) {
dsinclairefd5a992016-07-18 10:04:07 -0700822 Empty();
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400823 DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_CHARSET_Default);
dsinclairefd5a992016-07-18 10:04:07 -0700824 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700825}
826
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400827bool CPWL_EditImpl::InsertWord(uint16_t word, int32_t charset) {
tsepez4cf55152016-11-02 14:37:54 -0700828 return InsertWord(word, charset, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700829}
830
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400831bool CPWL_EditImpl::InsertReturn() {
tsepez4cf55152016-11-02 14:37:54 -0700832 return InsertReturn(nullptr, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700833}
834
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400835bool CPWL_EditImpl::Backspace() {
tsepez4cf55152016-11-02 14:37:54 -0700836 return Backspace(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700837}
838
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400839bool CPWL_EditImpl::Delete() {
tsepez4cf55152016-11-02 14:37:54 -0700840 return Delete(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700841}
842
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400843bool CPWL_EditImpl::ClearSelection() {
tsepez4cf55152016-11-02 14:37:54 -0700844 return Clear(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700845}
846
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400847bool CPWL_EditImpl::InsertText(const CFX_WideString& sText, int32_t charset) {
tsepez4cf55152016-11-02 14:37:54 -0700848 return InsertText(sText, charset, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700849}
850
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400851float CPWL_EditImpl::GetFontSize() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700852 return m_pVT->GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700853}
854
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400855uint16_t CPWL_EditImpl::GetPasswordChar() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700856 return m_pVT->GetPasswordChar();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700857}
858
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400859int32_t CPWL_EditImpl::GetCharArray() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700860 return m_pVT->GetCharArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700861}
862
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400863CFX_FloatRect CPWL_EditImpl::GetContentRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700864 return VTToEdit(m_pVT->GetContentRect());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700865}
866
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400867int32_t CPWL_EditImpl::GetHorzScale() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700868 return m_pVT->GetHorzScale();
869}
870
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400871float CPWL_EditImpl::GetCharSpace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700872 return m_pVT->GetCharSpace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700873}
874
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400875CPVT_WordRange CPWL_EditImpl::GetWholeWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700876 if (m_pVT->IsValid())
877 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700878
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700879 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700880}
881
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400882CPVT_WordRange CPWL_EditImpl::GetVisibleWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700883 if (m_bEnableOverflow)
884 return GetWholeWordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700885
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700886 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800887 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700888
Dan Sinclairf528eee2017-02-14 11:52:07 -0500889 CPVT_WordPlace place1 =
890 m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700891 CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500892 EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700893
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700894 return CPVT_WordRange(place1, place2);
895 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700896
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700897 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700898}
899
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400900CPVT_WordPlace CPWL_EditImpl::SearchWordPlace(const CFX_PointF& point) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700901 if (m_pVT->IsValid()) {
902 return m_pVT->SearchWordPlace(EditToVT(point));
903 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700904
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700905 return CPVT_WordPlace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700906}
907
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400908void CPWL_EditImpl::Paint() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700909 if (m_pVT->IsValid()) {
910 RearrangeAll();
911 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -0700912 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700913 SetCaretOrigin();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700914 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700915 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700916}
917
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400918void CPWL_EditImpl::RearrangeAll() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700919 if (m_pVT->IsValid()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700920 m_pVT->UpdateWordPlace(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700921 m_pVT->RearrangeAll();
922 m_pVT->UpdateWordPlace(m_wpCaret);
923 SetScrollInfo();
924 SetContentChanged();
925 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700926}
927
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400928void CPWL_EditImpl::RearrangePart(const CPVT_WordRange& range) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700929 if (m_pVT->IsValid()) {
930 m_pVT->UpdateWordPlace(m_wpCaret);
931 m_pVT->RearrangePart(range);
932 m_pVT->UpdateWordPlace(m_wpCaret);
933 SetScrollInfo();
934 SetContentChanged();
935 }
936}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700937
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400938void CPWL_EditImpl::SetContentChanged() {
dsinclaira2919b32016-07-13 10:55:48 -0700939 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800940 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700941 if (rcContent.Width() != m_rcOldContent.Width() ||
942 rcContent.Height() != m_rcOldContent.Height()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700943 m_rcOldContent = rcContent;
944 }
945 }
946}
947
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400948void CPWL_EditImpl::SelectAll() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700949 if (!m_pVT->IsValid())
950 return;
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400951 m_SelState = CPWL_EditImpl_Select(GetWholeWordRange());
Tom Sepez52f69b32017-03-21 13:42:38 -0700952 SetCaret(m_SelState.EndPos);
953 ScrollToCaret();
954 Refresh();
955 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700956}
957
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400958void CPWL_EditImpl::SelectNone() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700959 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
960 return;
961
962 m_SelState.Reset();
963 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700964}
965
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400966bool CPWL_EditImpl::IsSelected() const {
Tom Sepez52f69b32017-03-21 13:42:38 -0700967 return !m_SelState.IsEmpty();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700968}
969
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400970CFX_PointF CPWL_EditImpl::VTToEdit(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800971 CFX_FloatRect rcContent = m_pVT->GetContentRect();
972 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700973
Dan Sinclair05df0752017-03-14 14:43:42 -0400974 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700975
976 switch (m_nAlignment) {
977 case 0:
978 fPadding = 0.0f;
979 break;
980 case 1:
981 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
982 break;
983 case 2:
984 fPadding = rcPlate.Height() - rcContent.Height();
985 break;
986 }
987
Dan Sinclairf528eee2017-02-14 11:52:07 -0500988 return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
989 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700990}
991
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400992CFX_PointF CPWL_EditImpl::EditToVT(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800993 CFX_FloatRect rcContent = m_pVT->GetContentRect();
994 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700995
Dan Sinclair05df0752017-03-14 14:43:42 -0400996 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700997
998 switch (m_nAlignment) {
999 case 0:
1000 fPadding = 0.0f;
1001 break;
1002 case 1:
1003 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1004 break;
1005 case 2:
1006 fPadding = rcPlate.Height() - rcContent.Height();
1007 break;
1008 }
1009
Dan Sinclairf528eee2017-02-14 11:52:07 -05001010 return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
1011 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001012}
1013
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001014CFX_FloatRect CPWL_EditImpl::VTToEdit(const CFX_FloatRect& rect) const {
Dan Sinclairf528eee2017-02-14 11:52:07 -05001015 CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
1016 CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001017
Tom Sepez281a9ea2016-02-26 14:24:28 -08001018 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1019 ptRightTop.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001020}
1021
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001022void CPWL_EditImpl::SetScrollInfo() {
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001023 if (!m_pNotify)
1024 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001025
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001026 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1027 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1028 if (m_bNotifyFlag)
1029 return;
1030
1031 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
1032 m_bNotifyFlag = true;
1033
1034 PWL_SCROLL_INFO Info;
1035 Info.fPlateWidth = rcPlate.top - rcPlate.bottom;
1036 Info.fContentMin = rcContent.bottom;
1037 Info.fContentMax = rcContent.top;
1038 Info.fSmallStep = rcPlate.Height() / 3;
1039 Info.fBigStep = rcPlate.Height();
1040 m_pNotify->SetScrollInfo(Info);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001041}
1042
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001043void CPWL_EditImpl::SetScrollPosX(float fx) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001044 if (!m_bEnableScroll)
1045 return;
1046
1047 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001048 if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001049 m_ptScrollPos.x = fx;
dsinclairefd5a992016-07-18 10:04:07 -07001050 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001051 }
1052 }
1053}
1054
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001055void CPWL_EditImpl::SetScrollPosY(float fy) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001056 if (!m_bEnableScroll)
1057 return;
1058
1059 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001060 if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001061 m_ptScrollPos.y = fy;
dsinclairefd5a992016-07-18 10:04:07 -07001062 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001063
dsinclaira2919b32016-07-13 10:55:48 -07001064 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001065 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001066 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001067 m_bNotifyFlag = true;
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001068 m_pNotify->SetScrollPosition(fy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001069 }
1070 }
1071 }
1072 }
1073}
1074
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001075void CPWL_EditImpl::SetScrollPos(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001076 SetScrollPosX(point.x);
1077 SetScrollPosY(point.y);
1078 SetScrollLimit();
1079 SetCaretInfo();
1080}
1081
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001082CFX_PointF CPWL_EditImpl::GetScrollPos() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001083 return m_ptScrollPos;
1084}
1085
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001086void CPWL_EditImpl::SetScrollLimit() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001087 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001088 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1089 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001090
1091 if (rcPlate.Width() > rcContent.Width()) {
1092 SetScrollPosX(rcPlate.left);
1093 } else {
dsinclair448c4332016-08-02 12:07:35 -07001094 if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001095 SetScrollPosX(rcContent.left);
dsinclair448c4332016-08-02 12:07:35 -07001096 } else if (IsFloatBigger(m_ptScrollPos.x,
1097 rcContent.right - rcPlate.Width())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001098 SetScrollPosX(rcContent.right - rcPlate.Width());
1099 }
1100 }
1101
1102 if (rcPlate.Height() > rcContent.Height()) {
1103 SetScrollPosY(rcPlate.top);
1104 } else {
dsinclair448c4332016-08-02 12:07:35 -07001105 if (IsFloatSmaller(m_ptScrollPos.y,
1106 rcContent.bottom + rcPlate.Height())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001107 SetScrollPosY(rcContent.bottom + rcPlate.Height());
dsinclair448c4332016-08-02 12:07:35 -07001108 } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001109 SetScrollPosY(rcContent.top);
1110 }
1111 }
1112 }
1113}
1114
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001115void CPWL_EditImpl::ScrollToCaret() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001116 SetScrollLimit();
1117
thestig821d59e2016-05-11 12:59:22 -07001118 if (!m_pVT->IsValid())
1119 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001120
thestig821d59e2016-05-11 12:59:22 -07001121 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1122 pIterator->SetAt(m_wpCaret);
1123
Dan Sinclairf528eee2017-02-14 11:52:07 -05001124 CFX_PointF ptHead;
1125 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001126 CPVT_Word word;
1127 CPVT_Line line;
1128 if (pIterator->GetWord(word)) {
1129 ptHead.x = word.ptWord.x + word.fWidth;
1130 ptHead.y = word.ptWord.y + word.fAscent;
1131 ptFoot.x = word.ptWord.x + word.fWidth;
1132 ptFoot.y = word.ptWord.y + word.fDescent;
1133 } else if (pIterator->GetLine(line)) {
1134 ptHead.x = line.ptLine.x;
1135 ptHead.y = line.ptLine.y + line.fLineAscent;
1136 ptFoot.x = line.ptLine.x;
1137 ptFoot.y = line.ptLine.y + line.fLineDescent;
1138 }
1139
Dan Sinclairf528eee2017-02-14 11:52:07 -05001140 CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1141 CFX_PointF ptFootEdit = VTToEdit(ptFoot);
thestig821d59e2016-05-11 12:59:22 -07001142 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
dsinclair448c4332016-08-02 12:07:35 -07001143 if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
1144 if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
1145 IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
thestig821d59e2016-05-11 12:59:22 -07001146 SetScrollPosX(ptHead.x);
dsinclair448c4332016-08-02 12:07:35 -07001147 } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
thestig821d59e2016-05-11 12:59:22 -07001148 SetScrollPosX(ptHead.x - rcPlate.Width());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001149 }
thestig821d59e2016-05-11 12:59:22 -07001150 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001151
dsinclair448c4332016-08-02 12:07:35 -07001152 if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
1153 if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
1154 IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
1155 if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
thestig821d59e2016-05-11 12:59:22 -07001156 SetScrollPosY(ptFoot.y + rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001157 }
dsinclair448c4332016-08-02 12:07:35 -07001158 } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
1159 if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
thestig821d59e2016-05-11 12:59:22 -07001160 SetScrollPosY(ptHead.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001161 }
1162 }
1163 }
1164}
1165
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001166void CPWL_EditImpl::Refresh() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001167 if (m_bEnableRefresh && m_pVT->IsValid()) {
1168 m_Refresh.BeginRefresh();
1169 RefreshPushLineRects(GetVisibleWordRange());
1170
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001171 m_Refresh.NoAnalyse();
1172 m_ptRefreshScrollPos = m_ptScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001173
dsinclaira2919b32016-07-13 10:55:48 -07001174 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001175 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001176 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001177 m_bNotifyFlag = true;
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001178 if (const CPWL_EditImpl_RectArray* pRects =
1179 m_Refresh.GetRefreshRects()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001180 for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001181 m_pNotify->InvalidateRect(pRects->GetAt(i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001182 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001183 }
1184 }
1185
1186 m_Refresh.EndRefresh();
1187 }
1188}
1189
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001190void CPWL_EditImpl::RefreshPushLineRects(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001191 if (!m_pVT->IsValid())
1192 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001193
thestig821d59e2016-05-11 12:59:22 -07001194 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1195 CPVT_WordPlace wpBegin = wr.BeginPos;
1196 m_pVT->UpdateWordPlace(wpBegin);
1197 CPVT_WordPlace wpEnd = wr.EndPos;
1198 m_pVT->UpdateWordPlace(wpEnd);
1199 pIterator->SetAt(wpBegin);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001200
thestig821d59e2016-05-11 12:59:22 -07001201 CPVT_Line lineinfo;
1202 do {
1203 if (!pIterator->GetLine(lineinfo))
1204 break;
1205 if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
1206 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001207
thestig821d59e2016-05-11 12:59:22 -07001208 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1209 lineinfo.ptLine.y + lineinfo.fLineDescent,
1210 lineinfo.ptLine.x + lineinfo.fLineWidth,
1211 lineinfo.ptLine.y + lineinfo.fLineAscent);
1212
1213 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1214 VTToEdit(rcLine));
1215 } while (pIterator->NextLine());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001216}
1217
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001218void CPWL_EditImpl::RefreshWordRange(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001219 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1220 CPVT_WordRange wrTemp = wr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001221
thestig821d59e2016-05-11 12:59:22 -07001222 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1223 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1224 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001225
thestig821d59e2016-05-11 12:59:22 -07001226 CPVT_Word wordinfo;
1227 CPVT_Line lineinfo;
1228 CPVT_WordPlace place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001229
thestig821d59e2016-05-11 12:59:22 -07001230 while (pIterator->NextWord()) {
1231 place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -07001232 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -07001233 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001234
thestig821d59e2016-05-11 12:59:22 -07001235 pIterator->GetWord(wordinfo);
1236 pIterator->GetLine(lineinfo);
thestig821d59e2016-05-11 12:59:22 -07001237 if (place.LineCmp(wrTemp.BeginPos) == 0 ||
1238 place.LineCmp(wrTemp.EndPos) == 0) {
1239 CFX_FloatRect rcWord(wordinfo.ptWord.x,
1240 lineinfo.ptLine.y + lineinfo.fLineDescent,
1241 wordinfo.ptWord.x + wordinfo.fWidth,
1242 lineinfo.ptLine.y + lineinfo.fLineAscent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001243
dsinclaira2919b32016-07-13 10:55:48 -07001244 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001245 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001246 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001247 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001248 CFX_FloatRect rcRefresh = VTToEdit(rcWord);
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001249 m_pNotify->InvalidateRect(&rcRefresh);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001250 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001251 }
thestig821d59e2016-05-11 12:59:22 -07001252 } else {
1253 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
dsinclaira2919b32016-07-13 10:55:48 -07001258 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001259 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001260 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001261 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001262 CFX_FloatRect rcRefresh = VTToEdit(rcLine);
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001263 m_pNotify->InvalidateRect(&rcRefresh);
thestig821d59e2016-05-11 12:59:22 -07001264 }
1265 }
1266
1267 pIterator->NextLine();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001268 }
1269 }
1270}
1271
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001272void CPWL_EditImpl::SetCaret(const CPVT_WordPlace& place) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001273 m_wpOldCaret = m_wpCaret;
1274 m_wpCaret = place;
1275}
1276
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001277void CPWL_EditImpl::SetCaretInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001278 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001279 if (!m_bNotifyFlag) {
thestig821d59e2016-05-11 12:59:22 -07001280 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1281 pIterator->SetAt(m_wpCaret);
tsepez63f545c2016-09-13 16:08:49 -07001282
Dan Sinclairf528eee2017-02-14 11:52:07 -05001283 CFX_PointF ptHead;
1284 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001285 CPVT_Word word;
1286 CPVT_Line line;
1287 if (pIterator->GetWord(word)) {
1288 ptHead.x = word.ptWord.x + word.fWidth;
1289 ptHead.y = word.ptWord.y + word.fAscent;
1290 ptFoot.x = word.ptWord.x + word.fWidth;
1291 ptFoot.y = word.ptWord.y + word.fDescent;
1292 } else if (pIterator->GetLine(line)) {
1293 ptHead.x = line.ptLine.x;
1294 ptHead.y = line.ptLine.y + line.fLineAscent;
1295 ptFoot.x = line.ptLine.x;
1296 ptFoot.y = line.ptLine.y + line.fLineDescent;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001297 }
1298
Lei Zhanga8c2b912017-03-22 17:41:02 -07001299 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001300 m_bNotifyFlag = true;
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001301 m_pNotify->SetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead),
1302 VTToEdit(ptFoot));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001303 }
1304 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001305}
1306
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001307void CPWL_EditImpl::OnMouseDown(const CFX_PointF& point,
1308 bool bShift,
1309 bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001310 if (!m_pVT->IsValid())
1311 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001312
Tom Sepez52f69b32017-03-21 13:42:38 -07001313 SelectNone();
1314 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1315 m_SelState.Set(m_wpCaret, m_wpCaret);
1316 ScrollToCaret();
1317 SetCaretOrigin();
1318 SetCaretInfo();
1319}
1320
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001321void CPWL_EditImpl::OnMouseMove(const CFX_PointF& point,
1322 bool bShift,
1323 bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001324 if (!m_pVT->IsValid())
1325 return;
1326
1327 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1328 if (m_wpCaret == m_wpOldCaret)
1329 return;
1330
1331 m_SelState.SetEndPos(m_wpCaret);
1332 ScrollToCaret();
1333 Refresh();
1334 SetCaretOrigin();
1335 SetCaretInfo();
1336}
1337
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001338void CPWL_EditImpl::OnVK_UP(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001339 if (!m_pVT->IsValid())
1340 return;
1341
1342 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1343 if (bShift) {
1344 if (m_SelState.IsEmpty())
1345 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1346 else
1347 m_SelState.SetEndPos(m_wpCaret);
1348
1349 if (m_wpOldCaret != m_wpCaret) {
1350 ScrollToCaret();
1351 Refresh();
1352 SetCaretInfo();
1353 }
1354 } else {
1355 SelectNone();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001356 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001357 SetCaretInfo();
1358 }
1359}
1360
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001361void CPWL_EditImpl::OnVK_DOWN(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001362 if (!m_pVT->IsValid())
1363 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001364
Tom Sepez52f69b32017-03-21 13:42:38 -07001365 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1366 if (bShift) {
1367 if (m_SelState.IsEmpty())
1368 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1369 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001370 m_SelState.SetEndPos(m_wpCaret);
1371
Tom Sepez52f69b32017-03-21 13:42:38 -07001372 if (m_wpOldCaret != m_wpCaret) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001373 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001374 Refresh();
Tom Sepez52f69b32017-03-21 13:42:38 -07001375 SetCaretInfo();
1376 }
1377 } else {
1378 SelectNone();
1379 ScrollToCaret();
1380 SetCaretInfo();
1381 }
1382}
1383
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001384void CPWL_EditImpl::OnVK_LEFT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001385 if (!m_pVT->IsValid())
1386 return;
1387
1388 if (bShift) {
1389 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1390 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1391 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1392 }
1393 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1394 if (m_SelState.IsEmpty())
1395 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1396 else
1397 m_SelState.SetEndPos(m_wpCaret);
1398
1399 if (m_wpOldCaret != m_wpCaret) {
1400 ScrollToCaret();
1401 Refresh();
1402 SetCaretInfo();
1403 }
1404 } else {
1405 if (!m_SelState.IsEmpty()) {
1406 if (m_SelState.BeginPos < m_SelState.EndPos)
1407 SetCaret(m_SelState.BeginPos);
1408 else
1409 SetCaret(m_SelState.EndPos);
1410
1411 SelectNone();
1412 ScrollToCaret();
1413 SetCaretInfo();
1414 } else {
1415 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1416 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1417 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1418 }
1419 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1420 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001421 SetCaretOrigin();
1422 SetCaretInfo();
1423 }
1424 }
1425}
1426
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001427void CPWL_EditImpl::OnVK_RIGHT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001428 if (!m_pVT->IsValid())
1429 return;
1430
1431 if (bShift) {
1432 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1433 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1434 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001435 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1436
Tom Sepez52f69b32017-03-21 13:42:38 -07001437 if (m_SelState.IsEmpty())
1438 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1439 else
1440 m_SelState.SetEndPos(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001441
Tom Sepez52f69b32017-03-21 13:42:38 -07001442 if (m_wpOldCaret != m_wpCaret) {
1443 ScrollToCaret();
1444 Refresh();
1445 SetCaretInfo();
1446 }
1447 } else {
1448 if (!m_SelState.IsEmpty()) {
1449 if (m_SelState.BeginPos > m_SelState.EndPos)
1450 SetCaret(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001451 else
Tom Sepez52f69b32017-03-21 13:42:38 -07001452 SetCaret(m_SelState.EndPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001453
Tom Sepez52f69b32017-03-21 13:42:38 -07001454 SelectNone();
1455 ScrollToCaret();
1456 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001457 } else {
Tom Sepez52f69b32017-03-21 13:42:38 -07001458 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1459 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1460 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001461 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001462 }
Tom Sepez52f69b32017-03-21 13:42:38 -07001463 ScrollToCaret();
1464 SetCaretOrigin();
1465 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001466 }
1467 }
1468}
1469
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001470void CPWL_EditImpl::OnVK_HOME(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001471 if (!m_pVT->IsValid())
1472 return;
1473
1474 if (bShift) {
1475 if (bCtrl)
1476 SetCaret(m_pVT->GetBeginWordPlace());
1477 else
1478 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1479
1480 if (m_SelState.IsEmpty())
1481 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1482 else
1483 m_SelState.SetEndPos(m_wpCaret);
1484
1485 ScrollToCaret();
1486 Refresh();
1487 SetCaretInfo();
1488 } else {
1489 if (!m_SelState.IsEmpty()) {
1490 SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos));
1491 SelectNone();
1492 ScrollToCaret();
1493 SetCaretInfo();
1494 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001495 if (bCtrl)
1496 SetCaret(m_pVT->GetBeginWordPlace());
1497 else
1498 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1499
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001500 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001501 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001502 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001503 }
1504 }
1505}
1506
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001507void CPWL_EditImpl::OnVK_END(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001508 if (!m_pVT->IsValid())
1509 return;
1510
1511 if (bShift) {
1512 if (bCtrl)
1513 SetCaret(m_pVT->GetEndWordPlace());
1514 else
1515 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1516
1517 if (m_SelState.IsEmpty())
1518 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1519 else
1520 m_SelState.SetEndPos(m_wpCaret);
1521
1522 ScrollToCaret();
1523 Refresh();
1524 SetCaretInfo();
1525 } else {
1526 if (!m_SelState.IsEmpty()) {
1527 SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos));
1528 SelectNone();
1529 ScrollToCaret();
1530 SetCaretInfo();
1531 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001532 if (bCtrl)
1533 SetCaret(m_pVT->GetEndWordPlace());
1534 else
1535 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1536
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001537 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001538 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001539 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001540 }
1541 }
1542}
1543
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001544bool CPWL_EditImpl::InsertWord(uint16_t word,
1545 int32_t charset,
1546 const CPVT_WordProps* pWordProps,
1547 bool bAddUndo,
1548 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001549 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001550 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001551
Tom Sepez3509d162017-01-30 13:22:02 -08001552 m_pVT->UpdateWordPlace(m_wpCaret);
1553 SetCaret(m_pVT->InsertWord(m_wpCaret, word,
1554 GetCharSetFromUnicode(word, charset), pWordProps));
1555 m_SelState.Set(m_wpCaret, m_wpCaret);
1556 if (m_wpCaret == m_wpOldCaret)
1557 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001558
Tom Sepez3509d162017-01-30 13:22:02 -08001559 if (bAddUndo && m_bEnableUndo) {
1560 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertWord>(
1561 this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001562 }
Tom Sepez3509d162017-01-30 13:22:02 -08001563 if (bPaint)
1564 PaintInsertText(m_wpOldCaret, m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001565
Lei Zhang5688d622017-08-12 07:04:19 -07001566 if (m_pOperationNotify)
1567 m_pOperationNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
Tom Sepez3509d162017-01-30 13:22:02 -08001568
1569 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001570}
1571
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001572bool CPWL_EditImpl::InsertReturn(const CPVT_SecProps* pSecProps,
1573 const CPVT_WordProps* pWordProps,
1574 bool bAddUndo,
1575 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001576 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001577 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001578
Tom Sepez3509d162017-01-30 13:22:02 -08001579 m_pVT->UpdateWordPlace(m_wpCaret);
1580 SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
1581 m_SelState.Set(m_wpCaret, m_wpCaret);
1582 if (m_wpCaret == m_wpOldCaret)
1583 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001584
Tom Sepez3509d162017-01-30 13:22:02 -08001585 if (bAddUndo && m_bEnableUndo) {
1586 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertReturn>(
1587 this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001588 }
Tom Sepez3509d162017-01-30 13:22:02 -08001589 if (bPaint) {
1590 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1591 ScrollToCaret();
1592 Refresh();
1593 SetCaretOrigin();
1594 SetCaretInfo();
1595 }
Lei Zhang5688d622017-08-12 07:04:19 -07001596 if (m_pOperationNotify)
1597 m_pOperationNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001598
Tom Sepez3509d162017-01-30 13:22:02 -08001599 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001600}
1601
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001602bool CPWL_EditImpl::Backspace(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001603 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1604 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001605
Tom Sepez3509d162017-01-30 13:22:02 -08001606 CPVT_Section section;
1607 CPVT_Word word;
1608 if (bAddUndo) {
1609 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1610 pIterator->SetAt(m_wpCaret);
1611 pIterator->GetSection(section);
1612 pIterator->GetWord(word);
1613 }
1614 m_pVT->UpdateWordPlace(m_wpCaret);
1615 SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1616 m_SelState.Set(m_wpCaret, m_wpCaret);
1617 if (m_wpCaret == m_wpOldCaret)
1618 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001619
Tom Sepez3509d162017-01-30 13:22:02 -08001620 if (bAddUndo && m_bEnableUndo) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001621 if (m_wpCaret.nSecIndex != m_wpOldCaret.nSecIndex) {
Tom Sepez3509d162017-01-30 13:22:02 -08001622 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1623 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1624 section.SecProps, section.WordProps));
1625 } else {
1626 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1627 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1628 section.SecProps, word.WordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001629 }
1630 }
Tom Sepez3509d162017-01-30 13:22:02 -08001631 if (bPaint) {
1632 RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
1633 ScrollToCaret();
1634 Refresh();
1635 SetCaretOrigin();
1636 SetCaretInfo();
1637 }
Lei Zhang5688d622017-08-12 07:04:19 -07001638 if (m_pOperationNotify)
1639 m_pOperationNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001640
Tom Sepez3509d162017-01-30 13:22:02 -08001641 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001642}
1643
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001644bool CPWL_EditImpl::Delete(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001645 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1646 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001647
Tom Sepez3509d162017-01-30 13:22:02 -08001648 CPVT_Section section;
1649 CPVT_Word word;
1650 if (bAddUndo) {
1651 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1652 pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1653 pIterator->GetSection(section);
1654 pIterator->GetWord(word);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001655 }
Tom Sepez3509d162017-01-30 13:22:02 -08001656 m_pVT->UpdateWordPlace(m_wpCaret);
1657 bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1658 SetCaret(m_pVT->DeleteWord(m_wpCaret));
1659 m_SelState.Set(m_wpCaret, m_wpCaret);
1660 if (bAddUndo && m_bEnableUndo) {
1661 if (bSecEnd) {
1662 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1663 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1664 section.SecProps, section.WordProps, bSecEnd));
1665 } else {
1666 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1667 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1668 section.SecProps, word.WordProps, bSecEnd));
1669 }
1670 }
1671 if (bPaint) {
1672 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1673 ScrollToCaret();
1674 Refresh();
1675 SetCaretOrigin();
1676 SetCaretInfo();
1677 }
Lei Zhang5688d622017-08-12 07:04:19 -07001678 if (m_pOperationNotify)
1679 m_pOperationNotify->OnDelete(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001680
Tom Sepez3509d162017-01-30 13:22:02 -08001681 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001682}
1683
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001684bool CPWL_EditImpl::Empty() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001685 if (m_pVT->IsValid()) {
1686 m_pVT->DeleteWords(GetWholeWordRange());
1687 SetCaret(m_pVT->GetBeginWordPlace());
1688
tsepez4cf55152016-11-02 14:37:54 -07001689 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001690 }
1691
tsepez4cf55152016-11-02 14:37:54 -07001692 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001693}
1694
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001695bool CPWL_EditImpl::Clear(bool bAddUndo, bool bPaint) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001696 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
tsepez4cf55152016-11-02 14:37:54 -07001697 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001698
thestig821d59e2016-05-11 12:59:22 -07001699 CPVT_WordRange range = m_SelState.ConvertToWordRange();
Diana Gage22bf7a52017-07-21 11:33:18 -07001700 if (bAddUndo && m_bEnableUndo) {
Diana Gage89e65622017-07-20 18:09:31 -07001701 AddEditUndoItem(
1702 pdfium::MakeUnique<CFXEU_Clear>(this, range, GetSelectedText()));
Diana Gage22bf7a52017-07-21 11:33:18 -07001703 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001704
thestig821d59e2016-05-11 12:59:22 -07001705 SelectNone();
1706 SetCaret(m_pVT->DeleteWords(range));
1707 m_SelState.Set(m_wpCaret, m_wpCaret);
thestig821d59e2016-05-11 12:59:22 -07001708 if (bPaint) {
1709 RearrangePart(range);
1710 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001711 Refresh();
thestig821d59e2016-05-11 12:59:22 -07001712 SetCaretOrigin();
1713 SetCaretInfo();
1714 }
Lei Zhang5688d622017-08-12 07:04:19 -07001715 if (m_pOperationNotify)
1716 m_pOperationNotify->OnClear(m_wpCaret, m_wpOldCaret);
thestig821d59e2016-05-11 12:59:22 -07001717
tsepez4cf55152016-11-02 14:37:54 -07001718 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001719}
1720
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001721bool CPWL_EditImpl::InsertText(const CFX_WideString& sText,
1722 int32_t charset,
1723 bool bAddUndo,
1724 bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001725 if (IsTextOverflow())
tsepez4cf55152016-11-02 14:37:54 -07001726 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001727
1728 m_pVT->UpdateWordPlace(m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001729 SetCaret(DoInsertText(m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001730 m_SelState.Set(m_wpCaret, m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001731 if (m_wpCaret == m_wpOldCaret)
tsepez4cf55152016-11-02 14:37:54 -07001732 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001733
tsepeza31da742016-09-08 11:28:14 -07001734 if (bAddUndo && m_bEnableUndo) {
Tom Sepez3509d162017-01-30 13:22:02 -08001735 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertText>(
1736 this, m_wpOldCaret, m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001737 }
tsepeza31da742016-09-08 11:28:14 -07001738 if (bPaint)
1739 PaintInsertText(m_wpOldCaret, m_wpCaret);
1740
Lei Zhang5688d622017-08-12 07:04:19 -07001741 if (m_pOperationNotify)
1742 m_pOperationNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
tsepeza31da742016-09-08 11:28:14 -07001743
tsepez4cf55152016-11-02 14:37:54 -07001744 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001745}
1746
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001747void CPWL_EditImpl::PaintInsertText(const CPVT_WordPlace& wpOld,
1748 const CPVT_WordPlace& wpNew) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001749 if (m_pVT->IsValid()) {
1750 RearrangePart(CPVT_WordRange(wpOld, wpNew));
1751 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001752 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001753 SetCaretOrigin();
1754 SetCaretInfo();
1755 }
1756}
1757
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001758bool CPWL_EditImpl::Redo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001759 if (m_bEnableUndo) {
1760 if (m_Undo.CanRedo()) {
1761 m_Undo.Redo();
tsepez4cf55152016-11-02 14:37:54 -07001762 return true;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001763 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001764 }
1765
tsepez4cf55152016-11-02 14:37:54 -07001766 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001767}
1768
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001769bool CPWL_EditImpl::Undo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001770 if (m_bEnableUndo) {
1771 if (m_Undo.CanUndo()) {
1772 m_Undo.Undo();
tsepez4cf55152016-11-02 14:37:54 -07001773 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001774 }
1775 }
1776
tsepez4cf55152016-11-02 14:37:54 -07001777 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001778}
1779
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001780void CPWL_EditImpl::SetCaretOrigin() {
thestig821d59e2016-05-11 12:59:22 -07001781 if (!m_pVT->IsValid())
1782 return;
1783
1784 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1785 pIterator->SetAt(m_wpCaret);
1786 CPVT_Word word;
1787 CPVT_Line line;
1788 if (pIterator->GetWord(word)) {
1789 m_ptCaret.x = word.ptWord.x + word.fWidth;
1790 m_ptCaret.y = word.ptWord.y;
1791 } else if (pIterator->GetLine(line)) {
1792 m_ptCaret.x = line.ptLine.x;
1793 m_ptCaret.y = line.ptLine.y;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001794 }
1795}
1796
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001797CPVT_WordPlace CPWL_EditImpl::WordIndexToWordPlace(int32_t index) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001798 if (m_pVT->IsValid())
1799 return m_pVT->WordIndexToWordPlace(index);
1800
1801 return CPVT_WordPlace();
1802}
1803
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001804bool CPWL_EditImpl::IsTextFull() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001805 int32_t nTotalWords = m_pVT->GetTotalWords();
1806 int32_t nLimitChar = m_pVT->GetLimitChar();
1807 int32_t nCharArray = m_pVT->GetCharArray();
1808
1809 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
1810 (nCharArray > 0 && nTotalWords >= nCharArray);
1811}
1812
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001813bool CPWL_EditImpl::IsTextOverflow() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001814 if (!m_bEnableScroll && !m_bEnableOverflow) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001815 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1816 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001817
dsinclair448c4332016-08-02 12:07:35 -07001818 if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
1819 IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
tsepez4cf55152016-11-02 14:37:54 -07001820 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001821 }
1822
dsinclair448c4332016-08-02 12:07:35 -07001823 if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
tsepez4cf55152016-11-02 14:37:54 -07001824 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001825 }
1826
tsepez4cf55152016-11-02 14:37:54 -07001827 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001828}
1829
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001830bool CPWL_EditImpl::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001831 if (m_bEnableUndo) {
1832 return m_Undo.CanUndo();
1833 }
1834
tsepez4cf55152016-11-02 14:37:54 -07001835 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001836}
1837
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001838bool CPWL_EditImpl::CanRedo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001839 if (m_bEnableUndo) {
1840 return m_Undo.CanRedo();
1841 }
1842
tsepez4cf55152016-11-02 14:37:54 -07001843 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001844}
1845
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001846void CPWL_EditImpl::EnableRefresh(bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001847 m_bEnableRefresh = bRefresh;
1848}
1849
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001850void CPWL_EditImpl::EnableUndo(bool bUndo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001851 m_bEnableUndo = bUndo;
1852}
1853
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001854CPVT_WordPlace CPWL_EditImpl::DoInsertText(const CPVT_WordPlace& place,
1855 const CFX_WideString& sText,
1856 int32_t charset) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001857 CPVT_WordPlace wp = place;
1858
1859 if (m_pVT->IsValid()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001860 for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
Tom Sepez62a70f92016-03-21 15:00:20 -07001861 uint16_t word = sText[i];
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001862 switch (word) {
1863 case 0x0D:
dsinclairefd5a992016-07-18 10:04:07 -07001864 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001865 if (sText[i + 1] == 0x0A)
1866 i++;
1867 break;
1868 case 0x0A:
dsinclairefd5a992016-07-18 10:04:07 -07001869 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001870 if (sText[i + 1] == 0x0D)
1871 i++;
1872 break;
1873 case 0x09:
1874 word = 0x20;
1875 default:
1876 wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
dsinclairefd5a992016-07-18 10:04:07 -07001877 nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001878 break;
1879 }
1880 }
1881 }
1882
1883 return wp;
1884}
1885
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001886int32_t CPWL_EditImpl::GetCharSetFromUnicode(uint16_t word,
1887 int32_t nOldCharset) {
dsinclairc7a73492016-04-05 12:01:42 -07001888 if (IPVT_FontMap* pFontMap = GetFontMap())
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001889 return pFontMap->CharSetFromUnicode(word, nOldCharset);
1890 return nOldCharset;
1891}
1892
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001893void CPWL_EditImpl::AddEditUndoItem(
Lei Zhangae9c5ca2017-08-12 07:15:14 -07001894 std::unique_ptr<IFX_Edit_UndoItem> pEditUndoItem) {
Lei Zhang1a89e362017-03-23 15:27:25 -07001895 m_Undo.AddItem(std::move(pEditUndoItem));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001896}
1897
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001898CFX_ByteString CPWL_EditImpl::GetPDFWordString(int32_t nFontIndex,
1899 uint16_t Word,
1900 uint16_t SubWord) {
Dan Sinclairc08dc392017-07-24 08:57:35 -04001901 IPVT_FontMap* pFontMap = GetFontMap();
1902 CPDF_Font* pPDFFont = pFontMap->GetPDFFont(nFontIndex);
1903 if (!pPDFFont)
1904 return CFX_ByteString();
1905
1906 CFX_ByteString sWord;
1907 if (SubWord > 0) {
1908 Word = SubWord;
1909 } else {
1910 uint32_t dwCharCode = pPDFFont->IsUnicodeCompatible()
1911 ? pPDFFont->CharCodeFromUnicode(Word)
1912 : pFontMap->CharCodeFromUnicode(nFontIndex, Word);
1913 if (dwCharCode > 0) {
1914 pPDFFont->AppendChar(&sWord, dwCharCode);
1915 return sWord;
1916 }
1917 }
1918 pPDFFont->AppendChar(&sWord, Word);
1919 return sWord;
1920}
1921
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001922CPWL_EditImpl_LineRectArray::CPWL_EditImpl_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07001923
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001924CPWL_EditImpl_LineRectArray::~CPWL_EditImpl_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07001925
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001926void CPWL_EditImpl_LineRectArray::operator=(
1927 CPWL_EditImpl_LineRectArray&& that) {
Tom Sepez3509d162017-01-30 13:22:02 -08001928 m_LineRects = std::move(that.m_LineRects);
weili625ad662016-06-15 11:21:33 -07001929}
1930
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001931void CPWL_EditImpl_LineRectArray::Add(const CPVT_WordRange& wrLine,
1932 const CFX_FloatRect& rcLine) {
1933 m_LineRects.push_back(
1934 pdfium::MakeUnique<CPWL_EditImpl_LineRect>(wrLine, rcLine));
weili625ad662016-06-15 11:21:33 -07001935}
1936
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001937int32_t CPWL_EditImpl_LineRectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08001938 return pdfium::CollectionSize<int32_t>(m_LineRects);
weili625ad662016-06-15 11:21:33 -07001939}
1940
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001941CPWL_EditImpl_LineRect* CPWL_EditImpl_LineRectArray::GetAt(
1942 int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08001943 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07001944 return nullptr;
1945
Tom Sepez3509d162017-01-30 13:22:02 -08001946 return m_LineRects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07001947}
1948
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001949CPWL_EditImpl_Select::CPWL_EditImpl_Select() {}
weili625ad662016-06-15 11:21:33 -07001950
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001951CPWL_EditImpl_Select::CPWL_EditImpl_Select(const CPVT_WordRange& range) {
weili625ad662016-06-15 11:21:33 -07001952 Set(range.BeginPos, range.EndPos);
1953}
1954
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001955CPVT_WordRange CPWL_EditImpl_Select::ConvertToWordRange() const {
weili625ad662016-06-15 11:21:33 -07001956 return CPVT_WordRange(BeginPos, EndPos);
1957}
1958
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001959void CPWL_EditImpl_Select::Reset() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001960 BeginPos.Reset();
1961 EndPos.Reset();
weili625ad662016-06-15 11:21:33 -07001962}
1963
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001964void CPWL_EditImpl_Select::Set(const CPVT_WordPlace& begin,
1965 const CPVT_WordPlace& end) {
weili625ad662016-06-15 11:21:33 -07001966 BeginPos = begin;
1967 EndPos = end;
1968}
1969
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001970void CPWL_EditImpl_Select::SetEndPos(const CPVT_WordPlace& end) {
weili625ad662016-06-15 11:21:33 -07001971 EndPos = end;
1972}
1973
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001974bool CPWL_EditImpl_Select::IsEmpty() const {
Tom Sepez52f69b32017-03-21 13:42:38 -07001975 return BeginPos == EndPos;
weili625ad662016-06-15 11:21:33 -07001976}
1977
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001978CPWL_EditImpl_RectArray::CPWL_EditImpl_RectArray() {}
weili625ad662016-06-15 11:21:33 -07001979
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001980CPWL_EditImpl_RectArray::~CPWL_EditImpl_RectArray() {}
weili625ad662016-06-15 11:21:33 -07001981
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001982void CPWL_EditImpl_RectArray::Clear() {
Tom Sepez3509d162017-01-30 13:22:02 -08001983 m_Rects.clear();
weili625ad662016-06-15 11:21:33 -07001984}
1985
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001986void CPWL_EditImpl_RectArray::Add(const CFX_FloatRect& rect) {
weili625ad662016-06-15 11:21:33 -07001987 // check for overlapped area
Tom Sepez3509d162017-01-30 13:22:02 -08001988 for (const auto& pRect : m_Rects) {
weili625ad662016-06-15 11:21:33 -07001989 if (pRect && pRect->Contains(rect))
1990 return;
1991 }
Tom Sepez3509d162017-01-30 13:22:02 -08001992 m_Rects.push_back(pdfium::MakeUnique<CFX_FloatRect>(rect));
weili625ad662016-06-15 11:21:33 -07001993}
1994
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001995int32_t CPWL_EditImpl_RectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08001996 return pdfium::CollectionSize<int32_t>(m_Rects);
weili625ad662016-06-15 11:21:33 -07001997}
1998
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001999CFX_FloatRect* CPWL_EditImpl_RectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002000 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002001 return nullptr;
2002
Tom Sepez3509d162017-01-30 13:22:02 -08002003 return m_Rects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002004}