blob: 808eddb7cbae24fb37e72ed8b2dded095b7cb07e [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
Lei Zhangbff66f12017-08-15 13:26:44 -0700214CPWL_EditImpl_Undo::CPWL_EditImpl_Undo()
215 : m_nCurUndoPos(0), m_bWorking(false) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216
Lei Zhangbff66f12017-08-15 13:26:44 -0700217CPWL_EditImpl_Undo::~CPWL_EditImpl_Undo() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700218
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400219bool CPWL_EditImpl_Undo::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220 return m_nCurUndoPos > 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700221}
222
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400223void CPWL_EditImpl_Undo::Undo() {
tsepez4cf55152016-11-02 14:37:54 -0700224 m_bWorking = true;
Lei Zhangbff66f12017-08-15 13:26:44 -0700225 if (CanUndo()) {
Tom Sepez3509d162017-01-30 13:22:02 -0800226 m_UndoItemStack[m_nCurUndoPos - 1]->Undo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700227 m_nCurUndoPos--;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228 }
tsepez4cf55152016-11-02 14:37:54 -0700229 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700230}
231
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400232bool CPWL_EditImpl_Undo::CanRedo() const {
Tom Sepez3509d162017-01-30 13:22:02 -0800233 return m_nCurUndoPos < m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700234}
235
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400236void CPWL_EditImpl_Undo::Redo() {
tsepez4cf55152016-11-02 14:37:54 -0700237 m_bWorking = true;
Lei Zhangbff66f12017-08-15 13:26:44 -0700238 if (CanRedo()) {
Tom Sepez3509d162017-01-30 13:22:02 -0800239 m_UndoItemStack[m_nCurUndoPos]->Redo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240 m_nCurUndoPos++;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241 }
tsepez4cf55152016-11-02 14:37:54 -0700242 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700243}
244
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400245void CPWL_EditImpl_Undo::AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 ASSERT(!m_bWorking);
Lei Zhang96660d62015-12-14 18:27:25 -0800247 ASSERT(pItem);
Lei Zhangbff66f12017-08-15 13:26:44 -0700248 if (CanRedo())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 RemoveTails();
250
Lei Zhangbff66f12017-08-15 13:26:44 -0700251 if (m_UndoItemStack.size() >= kEditUndoMaxItems)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252 RemoveHeads();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253
Tom Sepez3509d162017-01-30 13:22:02 -0800254 m_UndoItemStack.push_back(std::move(pItem));
255 m_nCurUndoPos = m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256}
257
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400258void CPWL_EditImpl_Undo::RemoveHeads() {
Tom Sepez3509d162017-01-30 13:22:02 -0800259 ASSERT(m_UndoItemStack.size() > 1);
260 m_UndoItemStack.pop_front();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700261}
262
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400263void CPWL_EditImpl_Undo::RemoveTails() {
Lei Zhangbff66f12017-08-15 13:26:44 -0700264 while (CanRedo())
Tom Sepez3509d162017-01-30 13:22:02 -0800265 m_UndoItemStack.pop_back();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266}
267
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400268CFXEU_InsertWord::CFXEU_InsertWord(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269 const CPVT_WordPlace& wpOldPlace,
270 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700271 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272 int32_t charset,
273 const CPVT_WordProps* pWordProps)
274 : m_pEdit(pEdit),
275 m_wpOld(wpOldPlace),
276 m_wpNew(wpNewPlace),
277 m_Word(word),
278 m_nCharset(charset),
279 m_WordProps() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700280 ASSERT(m_pEdit);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281 if (pWordProps)
282 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700283}
284
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285CFXEU_InsertWord::~CFXEU_InsertWord() {}
286
287void CFXEU_InsertWord::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700288 m_pEdit->SelectNone();
289 m_pEdit->SetCaret(m_wpOld);
290 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700291}
292
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293void CFXEU_InsertWord::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700294 m_pEdit->SelectNone();
295 m_pEdit->SetCaret(m_wpNew);
296 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700297}
298
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400299CFXEU_InsertReturn::CFXEU_InsertReturn(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300 const CPVT_WordPlace& wpOldPlace,
301 const CPVT_WordPlace& wpNewPlace,
302 const CPVT_SecProps* pSecProps,
303 const CPVT_WordProps* pWordProps)
304 : m_pEdit(pEdit),
305 m_wpOld(wpOldPlace),
306 m_wpNew(wpNewPlace),
307 m_SecProps(),
308 m_WordProps() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700309 ASSERT(m_pEdit);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310 if (pSecProps)
311 m_SecProps = *pSecProps;
312 if (pWordProps)
313 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700314}
315
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700316CFXEU_InsertReturn::~CFXEU_InsertReturn() {}
317
318void CFXEU_InsertReturn::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700319 m_pEdit->SelectNone();
320 m_pEdit->SetCaret(m_wpOld);
321 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700322}
323
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324void CFXEU_InsertReturn::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700325 m_pEdit->SelectNone();
326 m_pEdit->SetCaret(m_wpNew);
327 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700328}
329
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400330CFXEU_Backspace::CFXEU_Backspace(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700331 const CPVT_WordPlace& wpOldPlace,
332 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700333 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700334 int32_t charset,
335 const CPVT_SecProps& SecProps,
336 const CPVT_WordProps& WordProps)
337 : m_pEdit(pEdit),
338 m_wpOld(wpOldPlace),
339 m_wpNew(wpNewPlace),
340 m_Word(word),
341 m_nCharset(charset),
342 m_SecProps(SecProps),
Lei Zhangf5a06672017-08-12 08:01:37 -0700343 m_WordProps(WordProps) {
344 ASSERT(m_pEdit);
345}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700346
347CFXEU_Backspace::~CFXEU_Backspace() {}
348
349void CFXEU_Backspace::Redo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700350 m_pEdit->SelectNone();
351 m_pEdit->SetCaret(m_wpOld);
352 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700353}
354
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700355void CFXEU_Backspace::Undo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700356 m_pEdit->SelectNone();
357 m_pEdit->SetCaret(m_wpNew);
358 if (m_wpNew.nSecIndex != m_wpOld.nSecIndex)
359 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
360 else
361 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700362}
363
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400364CFXEU_Delete::CFXEU_Delete(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700365 const CPVT_WordPlace& wpOldPlace,
366 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700367 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700368 int32_t charset,
369 const CPVT_SecProps& SecProps,
370 const CPVT_WordProps& WordProps,
tsepez4cf55152016-11-02 14:37:54 -0700371 bool bSecEnd)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372 : m_pEdit(pEdit),
373 m_wpOld(wpOldPlace),
374 m_wpNew(wpNewPlace),
375 m_Word(word),
376 m_nCharset(charset),
377 m_SecProps(SecProps),
378 m_WordProps(WordProps),
Lei Zhangf5a06672017-08-12 08:01:37 -0700379 m_bSecEnd(bSecEnd) {
380 ASSERT(m_pEdit);
381}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700382
383CFXEU_Delete::~CFXEU_Delete() {}
384
385void CFXEU_Delete::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700386 m_pEdit->SelectNone();
387 m_pEdit->SetCaret(m_wpOld);
388 m_pEdit->Delete(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700389}
390
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700391void CFXEU_Delete::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700392 m_pEdit->SelectNone();
393 m_pEdit->SetCaret(m_wpNew);
394 if (m_bSecEnd)
395 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
396 else
397 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700398}
399
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400400CFXEU_Clear::CFXEU_Clear(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700401 const CPVT_WordRange& wrSel,
402 const CFX_WideString& swText)
Lei Zhangf5a06672017-08-12 08:01:37 -0700403 : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {
404 ASSERT(m_pEdit);
405}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700406
407CFXEU_Clear::~CFXEU_Clear() {}
408
409void CFXEU_Clear::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700410 m_pEdit->SelectNone();
411 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
412 m_pEdit->Clear(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700413}
414
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700415void CFXEU_Clear::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700416 m_pEdit->SelectNone();
417 m_pEdit->SetCaret(m_wrSel.BeginPos);
418 m_pEdit->InsertText(m_swText, FX_CHARSET_Default, false, true);
419 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700420}
421
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400422CFXEU_InsertText::CFXEU_InsertText(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700423 const CPVT_WordPlace& wpOldPlace,
424 const CPVT_WordPlace& wpNewPlace,
425 const CFX_WideString& swText,
dsinclairefd5a992016-07-18 10:04:07 -0700426 int32_t charset)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700427 : m_pEdit(pEdit),
428 m_wpOld(wpOldPlace),
429 m_wpNew(wpNewPlace),
430 m_swText(swText),
Lei Zhangf5a06672017-08-12 08:01:37 -0700431 m_nCharset(charset) {
432 ASSERT(m_pEdit);
433}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700434
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700435CFXEU_InsertText::~CFXEU_InsertText() {}
436
437void CFXEU_InsertText::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700438 m_pEdit->SelectNone();
439 m_pEdit->SetCaret(m_wpOld);
440 m_pEdit->InsertText(m_swText, m_nCharset, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700441}
442
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700443void CFXEU_InsertText::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700444 m_pEdit->SelectNone();
445 m_pEdit->SetSelection(m_wpOld, m_wpNew);
446 m_pEdit->Clear(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700447}
448
dsinclaire35af1e2016-07-13 11:26:20 -0700449// static
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400450void CPWL_EditImpl::DrawEdit(CFX_RenderDevice* pDevice,
451 CFX_Matrix* pUser2Device,
452 CPWL_EditImpl* pEdit,
453 FX_COLORREF crTextFill,
454 const CFX_FloatRect& rcClip,
455 const CFX_PointF& ptOffset,
456 const CPVT_WordRange* pRange,
457 CFX_SystemHandler* pSystemHandler,
458 CFFL_FormFiller* pFFLData) {
dsinclaire35af1e2016-07-13 11:26:20 -0700459 const bool bContinuous =
460 pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
461 uint16_t SubWord = pEdit->GetPasswordChar();
Dan Sinclair05df0752017-03-14 14:43:42 -0400462 float fFontSize = pEdit->GetFontSize();
dsinclaire35af1e2016-07-13 11:26:20 -0700463 CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
464 int32_t nHorzScale = pEdit->GetHorzScale();
465
466 FX_COLORREF crCurFill = crTextFill;
467 FX_COLORREF crOldFill = crCurFill;
468
tsepez4cf55152016-11-02 14:37:54 -0700469 bool bSelect = false;
dsinclaire35af1e2016-07-13 11:26:20 -0700470 const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
471 const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
472
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400473 std::ostringstream sTextBuf;
dsinclaire35af1e2016-07-13 11:26:20 -0700474 int32_t nFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500475 CFX_PointF ptBT;
Tom Sepez1629f602017-04-21 14:11:26 -0700476 CFX_RenderDevice::StateRestorer restorer(pDevice);
dsinclaire35af1e2016-07-13 11:26:20 -0700477 if (!rcClip.IsEmpty()) {
478 CFX_FloatRect rcTemp = rcClip;
479 pUser2Device->TransformRect(rcTemp);
480 pDevice->SetClip_Rect(rcTemp.ToFxRect());
481 }
482
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400483 CPWL_EditImpl_Iterator* pIterator = pEdit->GetIterator();
dsinclaire35af1e2016-07-13 11:26:20 -0700484 if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
485 if (pRange)
486 pIterator->SetAt(pRange->BeginPos);
487 else
488 pIterator->SetAt(0);
489
490 CPVT_WordPlace oldplace;
491 while (pIterator->NextWord()) {
492 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700493 if (pRange && place > pRange->EndPos)
dsinclaire35af1e2016-07-13 11:26:20 -0700494 break;
495
Tom Sepez52f69b32017-03-21 13:42:38 -0700496 if (!wrSelect.IsEmpty()) {
497 bSelect = place > wrSelect.BeginPos && place <= wrSelect.EndPos;
dsinclaire35af1e2016-07-13 11:26:20 -0700498 crCurFill = bSelect ? crWhite : crTextFill;
499 }
500 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
501 crCurFill = crTextFill;
502 crOldFill = crCurFill;
503 }
504 CPVT_Word word;
505 if (pIterator->GetWord(word)) {
506 if (bSelect) {
507 CPVT_Line line;
508 pIterator->GetLine(line);
509
510 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
511 CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
512 word.ptWord.x + word.fWidth,
513 line.ptLine.y + line.fLineAscent);
514 rc.Intersect(rcClip);
515 pSystemHandler->OutputSelectedRect(pFFLData, rc);
516 } else {
517 CFX_PathData pathSelBK;
518 pathSelBK.AppendRect(
519 word.ptWord.x, line.ptLine.y + line.fLineDescent,
520 word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent);
521
522 pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
523 FXFILL_WINDING);
524 }
525 }
526
527 if (bContinuous) {
528 if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
529 crOldFill != crCurFill) {
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400530 if (sTextBuf.tellp() > 0) {
dsinclaire35af1e2016-07-13 11:26:20 -0700531 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500532 pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700533 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400534 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700535
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400536 sTextBuf.str("");
dsinclaire35af1e2016-07-13 11:26:20 -0700537 }
538 nFontIndex = word.nFontIndex;
539 ptBT = word.ptWord;
540 crOldFill = crCurFill;
541 }
542
Dan Sinclairc08dc392017-07-24 08:57:35 -0400543 sTextBuf << pEdit->GetPDFWordString(word.nFontIndex, word.Word,
544 SubWord);
dsinclaire35af1e2016-07-13 11:26:20 -0700545 } else {
546 DrawTextString(
Dan Sinclairc08dc392017-07-24 08:57:35 -0400547 pDevice,
548 CFX_PointF(word.ptWord.x + ptOffset.x,
549 word.ptWord.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700550 pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
Dan Sinclairc08dc392017-07-24 08:57:35 -0400551 pEdit->GetPDFWordString(word.nFontIndex, word.Word, SubWord),
Dan Sinclaira0061af2017-02-23 09:25:17 -0500552 crCurFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700553 }
554 oldplace = place;
555 }
556 }
557
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400558 if (sTextBuf.tellp() > 0) {
Dan Sinclaira0061af2017-02-23 09:25:17 -0500559 DrawTextString(pDevice,
560 CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
561 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400562 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700563 }
564 }
dsinclaire35af1e2016-07-13 11:26:20 -0700565}
566
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400567CPWL_EditImpl::CPWL_EditImpl()
Lei Zhang5688d622017-08-12 07:04:19 -0700568 : m_pVT(pdfium::MakeUnique<CPDF_VariableText>()),
tsepez4cf55152016-11-02 14:37:54 -0700569 m_bEnableScroll(false),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700570 m_nAlignment(0),
tsepez4cf55152016-11-02 14:37:54 -0700571 m_bNotifyFlag(false),
572 m_bEnableOverflow(false),
573 m_bEnableRefresh(true),
Lei Zhang5688d622017-08-12 07:04:19 -0700574 m_bEnableUndo(true) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700575
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400576CPWL_EditImpl::~CPWL_EditImpl() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700577
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400578void CPWL_EditImpl::Initialize() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579 m_pVT->Initialize();
580 SetCaret(m_pVT->GetBeginWordPlace());
581 SetCaretOrigin();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700582}
583
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400584void CPWL_EditImpl::SetFontMap(IPVT_FontMap* pFontMap) {
585 m_pVTProvider = pdfium::MakeUnique<CPWL_EditImpl_Provider>(pFontMap);
thestig821d59e2016-05-11 12:59:22 -0700586 m_pVT->SetProvider(m_pVTProvider.get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700587}
588
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400589void CPWL_EditImpl::SetNotify(CPWL_EditCtrl* pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700590 m_pNotify = pNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700591}
592
Lei Zhang5688d622017-08-12 07:04:19 -0700593void CPWL_EditImpl::SetOperationNotify(CPWL_Edit* pOperationNotify) {
594 m_pOperationNotify = pOperationNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700595}
596
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400597CPWL_EditImpl_Iterator* CPWL_EditImpl::GetIterator() {
tsepez36eb4bd2016-10-03 15:24:27 -0700598 if (!m_pIterator) {
599 m_pIterator =
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400600 pdfium::MakeUnique<CPWL_EditImpl_Iterator>(this, m_pVT->GetIterator());
tsepez36eb4bd2016-10-03 15:24:27 -0700601 }
thestig821d59e2016-05-11 12:59:22 -0700602 return m_pIterator.get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700603}
604
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400605IPVT_FontMap* CPWL_EditImpl::GetFontMap() {
thestig821d59e2016-05-11 12:59:22 -0700606 return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700607}
608
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400609void CPWL_EditImpl::SetPlateRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700610 m_pVT->SetPlateRect(rect);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500611 m_ptScrollPos = CFX_PointF(rect.left, rect.top);
dsinclairefd5a992016-07-18 10:04:07 -0700612 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700613}
614
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400615void CPWL_EditImpl::SetAlignmentH(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700616 m_pVT->SetAlignment(nFormat);
617 if (bPaint)
618 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700619}
620
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400621void CPWL_EditImpl::SetAlignmentV(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700622 m_nAlignment = nFormat;
623 if (bPaint)
624 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700625}
626
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400627void CPWL_EditImpl::SetPasswordChar(uint16_t wSubWord, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700628 m_pVT->SetPasswordChar(wSubWord);
629 if (bPaint)
630 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700631}
632
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400633void CPWL_EditImpl::SetLimitChar(int32_t nLimitChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700634 m_pVT->SetLimitChar(nLimitChar);
dsinclairefd5a992016-07-18 10:04:07 -0700635 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700636}
637
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400638void CPWL_EditImpl::SetCharArray(int32_t nCharArray) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700639 m_pVT->SetCharArray(nCharArray);
dsinclairefd5a992016-07-18 10:04:07 -0700640 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700641}
642
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400643void CPWL_EditImpl::SetCharSpace(float fCharSpace) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700644 m_pVT->SetCharSpace(fCharSpace);
dsinclairefd5a992016-07-18 10:04:07 -0700645 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700646}
647
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400648void CPWL_EditImpl::SetMultiLine(bool bMultiLine, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700649 m_pVT->SetMultiLine(bMultiLine);
650 if (bPaint)
651 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700652}
653
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400654void CPWL_EditImpl::SetAutoReturn(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700655 m_pVT->SetAutoReturn(bAuto);
656 if (bPaint)
657 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700658}
659
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400660void CPWL_EditImpl::SetAutoFontSize(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700661 m_pVT->SetAutoFontSize(bAuto);
662 if (bPaint)
663 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700664}
665
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400666void CPWL_EditImpl::SetFontSize(float fFontSize) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700667 m_pVT->SetFontSize(fFontSize);
dsinclairefd5a992016-07-18 10:04:07 -0700668 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700669}
670
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400671void CPWL_EditImpl::SetAutoScroll(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700672 m_bEnableScroll = bAuto;
673 if (bPaint)
674 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700675}
676
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400677void CPWL_EditImpl::SetTextOverflow(bool bAllowed, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700678 m_bEnableOverflow = bAllowed;
679 if (bPaint)
680 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700681}
682
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400683void CPWL_EditImpl::SetSelection(int32_t nStartChar, int32_t nEndChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700684 if (m_pVT->IsValid()) {
685 if (nStartChar == 0 && nEndChar < 0) {
686 SelectAll();
687 } else if (nStartChar < 0) {
688 SelectNone();
689 } else {
690 if (nStartChar < nEndChar) {
Diana Gage4d02e902017-07-20 17:20:31 -0700691 SetSelection(m_pVT->WordIndexToWordPlace(nStartChar),
692 m_pVT->WordIndexToWordPlace(nEndChar));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700693 } else {
Diana Gage4d02e902017-07-20 17:20:31 -0700694 SetSelection(m_pVT->WordIndexToWordPlace(nEndChar),
695 m_pVT->WordIndexToWordPlace(nStartChar));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700696 }
697 }
698 }
699}
700
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400701void CPWL_EditImpl::SetSelection(const CPVT_WordPlace& begin,
702 const CPVT_WordPlace& end) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700703 if (!m_pVT->IsValid())
704 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700705
Tom Sepez52f69b32017-03-21 13:42:38 -0700706 SelectNone();
707 m_SelState.Set(begin, end);
708 SetCaret(m_SelState.EndPos);
709 ScrollToCaret();
710 if (!m_SelState.IsEmpty())
711 Refresh();
712 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700713}
714
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400715void CPWL_EditImpl::GetSelection(int32_t& nStartChar, int32_t& nEndChar) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700716 nStartChar = -1;
717 nEndChar = -1;
Tom Sepez52f69b32017-03-21 13:42:38 -0700718 if (!m_pVT->IsValid())
719 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700720
Tom Sepez52f69b32017-03-21 13:42:38 -0700721 if (m_SelState.IsEmpty()) {
722 nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
723 nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
724 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700725 }
Tom Sepez52f69b32017-03-21 13:42:38 -0700726 if (m_SelState.BeginPos < m_SelState.EndPos) {
727 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
728 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
729 return;
730 }
731 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
732 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700733}
734
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400735int32_t CPWL_EditImpl::GetCaret() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700736 if (m_pVT->IsValid())
737 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
738
739 return -1;
740}
741
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400742CPVT_WordPlace CPWL_EditImpl::GetCaretWordPlace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700743 return m_wpCaret;
744}
745
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400746CFX_WideString CPWL_EditImpl::GetText() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700747 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700748 if (!m_pVT->IsValid())
749 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700750
thestig821d59e2016-05-11 12:59:22 -0700751 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
752 pIterator->SetAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700753
thestig821d59e2016-05-11 12:59:22 -0700754 CPVT_Word wordinfo;
755 CPVT_WordPlace oldplace = pIterator->GetAt();
756 while (pIterator->NextWord()) {
757 CPVT_WordPlace place = pIterator->GetAt();
thestig821d59e2016-05-11 12:59:22 -0700758 if (pIterator->GetWord(wordinfo))
759 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700760 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700761 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700762 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700763 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700764 return swRet;
765}
766
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400767CFX_WideString CPWL_EditImpl::GetRangeText(const CPVT_WordRange& range) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700768 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700769 if (!m_pVT->IsValid())
770 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700771
thestig821d59e2016-05-11 12:59:22 -0700772 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
773 CPVT_WordRange wrTemp = range;
774 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
775 m_pVT->UpdateWordPlace(wrTemp.EndPos);
776 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700777
thestig821d59e2016-05-11 12:59:22 -0700778 CPVT_Word wordinfo;
779 CPVT_WordPlace oldplace = wrTemp.BeginPos;
780 while (pIterator->NextWord()) {
781 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700782 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -0700783 break;
thestig821d59e2016-05-11 12:59:22 -0700784 if (pIterator->GetWord(wordinfo))
785 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700786 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700787 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700788 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700789 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700790 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700791}
792
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400793CFX_WideString CPWL_EditImpl::GetSelectedText() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700794 return GetRangeText(m_SelState.ConvertToWordRange());
795}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700796
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400797int32_t CPWL_EditImpl::GetTotalLines() const {
thestig821d59e2016-05-11 12:59:22 -0700798 int32_t nLines = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700799
thestig821d59e2016-05-11 12:59:22 -0700800 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
801 pIterator->SetAt(0);
802 while (pIterator->NextLine())
803 ++nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700804
thestig821d59e2016-05-11 12:59:22 -0700805 return nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700806}
807
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400808CPVT_WordRange CPWL_EditImpl::GetSelectWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700809 return m_SelState.ConvertToWordRange();
810}
811
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400812void CPWL_EditImpl::SetText(const CFX_WideString& sText) {
dsinclairefd5a992016-07-18 10:04:07 -0700813 Empty();
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400814 DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_CHARSET_Default);
dsinclairefd5a992016-07-18 10:04:07 -0700815 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700816}
817
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400818bool CPWL_EditImpl::InsertWord(uint16_t word, int32_t charset) {
tsepez4cf55152016-11-02 14:37:54 -0700819 return InsertWord(word, charset, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700820}
821
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400822bool CPWL_EditImpl::InsertReturn() {
tsepez4cf55152016-11-02 14:37:54 -0700823 return InsertReturn(nullptr, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700824}
825
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400826bool CPWL_EditImpl::Backspace() {
tsepez4cf55152016-11-02 14:37:54 -0700827 return Backspace(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700828}
829
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400830bool CPWL_EditImpl::Delete() {
tsepez4cf55152016-11-02 14:37:54 -0700831 return Delete(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700832}
833
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400834bool CPWL_EditImpl::ClearSelection() {
tsepez4cf55152016-11-02 14:37:54 -0700835 return Clear(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700836}
837
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400838bool CPWL_EditImpl::InsertText(const CFX_WideString& sText, int32_t charset) {
tsepez4cf55152016-11-02 14:37:54 -0700839 return InsertText(sText, charset, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700840}
841
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400842float CPWL_EditImpl::GetFontSize() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700843 return m_pVT->GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700844}
845
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400846uint16_t CPWL_EditImpl::GetPasswordChar() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700847 return m_pVT->GetPasswordChar();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700848}
849
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400850int32_t CPWL_EditImpl::GetCharArray() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700851 return m_pVT->GetCharArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700852}
853
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400854CFX_FloatRect CPWL_EditImpl::GetContentRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700855 return VTToEdit(m_pVT->GetContentRect());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700856}
857
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400858int32_t CPWL_EditImpl::GetHorzScale() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700859 return m_pVT->GetHorzScale();
860}
861
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400862float CPWL_EditImpl::GetCharSpace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700863 return m_pVT->GetCharSpace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700864}
865
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400866CPVT_WordRange CPWL_EditImpl::GetWholeWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700867 if (m_pVT->IsValid())
868 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700869
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700870 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700871}
872
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400873CPVT_WordRange CPWL_EditImpl::GetVisibleWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700874 if (m_bEnableOverflow)
875 return GetWholeWordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700876
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700877 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800878 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700879
Dan Sinclairf528eee2017-02-14 11:52:07 -0500880 CPVT_WordPlace place1 =
881 m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700882 CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500883 EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700884
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700885 return CPVT_WordRange(place1, place2);
886 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700887
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700888 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700889}
890
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400891CPVT_WordPlace CPWL_EditImpl::SearchWordPlace(const CFX_PointF& point) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700892 if (m_pVT->IsValid()) {
893 return m_pVT->SearchWordPlace(EditToVT(point));
894 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700895
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700896 return CPVT_WordPlace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700897}
898
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400899void CPWL_EditImpl::Paint() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700900 if (m_pVT->IsValid()) {
901 RearrangeAll();
902 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -0700903 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700904 SetCaretOrigin();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700905 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700906 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700907}
908
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400909void CPWL_EditImpl::RearrangeAll() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700910 if (m_pVT->IsValid()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700911 m_pVT->UpdateWordPlace(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700912 m_pVT->RearrangeAll();
913 m_pVT->UpdateWordPlace(m_wpCaret);
914 SetScrollInfo();
915 SetContentChanged();
916 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700917}
918
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400919void CPWL_EditImpl::RearrangePart(const CPVT_WordRange& range) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700920 if (m_pVT->IsValid()) {
921 m_pVT->UpdateWordPlace(m_wpCaret);
922 m_pVT->RearrangePart(range);
923 m_pVT->UpdateWordPlace(m_wpCaret);
924 SetScrollInfo();
925 SetContentChanged();
926 }
927}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700928
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400929void CPWL_EditImpl::SetContentChanged() {
dsinclaira2919b32016-07-13 10:55:48 -0700930 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800931 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700932 if (rcContent.Width() != m_rcOldContent.Width() ||
933 rcContent.Height() != m_rcOldContent.Height()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700934 m_rcOldContent = rcContent;
935 }
936 }
937}
938
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400939void CPWL_EditImpl::SelectAll() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700940 if (!m_pVT->IsValid())
941 return;
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400942 m_SelState = CPWL_EditImpl_Select(GetWholeWordRange());
Tom Sepez52f69b32017-03-21 13:42:38 -0700943 SetCaret(m_SelState.EndPos);
944 ScrollToCaret();
945 Refresh();
946 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700947}
948
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400949void CPWL_EditImpl::SelectNone() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700950 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
951 return;
952
953 m_SelState.Reset();
954 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700955}
956
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400957bool CPWL_EditImpl::IsSelected() const {
Tom Sepez52f69b32017-03-21 13:42:38 -0700958 return !m_SelState.IsEmpty();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700959}
960
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400961CFX_PointF CPWL_EditImpl::VTToEdit(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800962 CFX_FloatRect rcContent = m_pVT->GetContentRect();
963 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700964
Dan Sinclair05df0752017-03-14 14:43:42 -0400965 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700966
967 switch (m_nAlignment) {
968 case 0:
969 fPadding = 0.0f;
970 break;
971 case 1:
972 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
973 break;
974 case 2:
975 fPadding = rcPlate.Height() - rcContent.Height();
976 break;
977 }
978
Dan Sinclairf528eee2017-02-14 11:52:07 -0500979 return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
980 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700981}
982
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400983CFX_PointF CPWL_EditImpl::EditToVT(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800984 CFX_FloatRect rcContent = m_pVT->GetContentRect();
985 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700986
Dan Sinclair05df0752017-03-14 14:43:42 -0400987 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700988
989 switch (m_nAlignment) {
990 case 0:
991 fPadding = 0.0f;
992 break;
993 case 1:
994 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
995 break;
996 case 2:
997 fPadding = rcPlate.Height() - rcContent.Height();
998 break;
999 }
1000
Dan Sinclairf528eee2017-02-14 11:52:07 -05001001 return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
1002 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001003}
1004
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001005CFX_FloatRect CPWL_EditImpl::VTToEdit(const CFX_FloatRect& rect) const {
Dan Sinclairf528eee2017-02-14 11:52:07 -05001006 CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
1007 CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001008
Tom Sepez281a9ea2016-02-26 14:24:28 -08001009 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1010 ptRightTop.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001011}
1012
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001013void CPWL_EditImpl::SetScrollInfo() {
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001014 if (!m_pNotify)
1015 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001016
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001017 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1018 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1019 if (m_bNotifyFlag)
1020 return;
1021
1022 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
1023 m_bNotifyFlag = true;
1024
1025 PWL_SCROLL_INFO Info;
1026 Info.fPlateWidth = rcPlate.top - rcPlate.bottom;
1027 Info.fContentMin = rcContent.bottom;
1028 Info.fContentMax = rcContent.top;
1029 Info.fSmallStep = rcPlate.Height() / 3;
1030 Info.fBigStep = rcPlate.Height();
1031 m_pNotify->SetScrollInfo(Info);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001032}
1033
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001034void CPWL_EditImpl::SetScrollPosX(float fx) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001035 if (!m_bEnableScroll)
1036 return;
1037
1038 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001039 if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001040 m_ptScrollPos.x = fx;
dsinclairefd5a992016-07-18 10:04:07 -07001041 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001042 }
1043 }
1044}
1045
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001046void CPWL_EditImpl::SetScrollPosY(float fy) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001047 if (!m_bEnableScroll)
1048 return;
1049
1050 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001051 if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001052 m_ptScrollPos.y = fy;
dsinclairefd5a992016-07-18 10:04:07 -07001053 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001054
dsinclaira2919b32016-07-13 10:55:48 -07001055 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001056 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001057 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001058 m_bNotifyFlag = true;
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001059 m_pNotify->SetScrollPosition(fy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001060 }
1061 }
1062 }
1063 }
1064}
1065
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001066void CPWL_EditImpl::SetScrollPos(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001067 SetScrollPosX(point.x);
1068 SetScrollPosY(point.y);
1069 SetScrollLimit();
1070 SetCaretInfo();
1071}
1072
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001073CFX_PointF CPWL_EditImpl::GetScrollPos() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001074 return m_ptScrollPos;
1075}
1076
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001077void CPWL_EditImpl::SetScrollLimit() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001078 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001079 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1080 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001081
1082 if (rcPlate.Width() > rcContent.Width()) {
1083 SetScrollPosX(rcPlate.left);
1084 } else {
dsinclair448c4332016-08-02 12:07:35 -07001085 if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001086 SetScrollPosX(rcContent.left);
dsinclair448c4332016-08-02 12:07:35 -07001087 } else if (IsFloatBigger(m_ptScrollPos.x,
1088 rcContent.right - rcPlate.Width())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001089 SetScrollPosX(rcContent.right - rcPlate.Width());
1090 }
1091 }
1092
1093 if (rcPlate.Height() > rcContent.Height()) {
1094 SetScrollPosY(rcPlate.top);
1095 } else {
dsinclair448c4332016-08-02 12:07:35 -07001096 if (IsFloatSmaller(m_ptScrollPos.y,
1097 rcContent.bottom + rcPlate.Height())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001098 SetScrollPosY(rcContent.bottom + rcPlate.Height());
dsinclair448c4332016-08-02 12:07:35 -07001099 } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001100 SetScrollPosY(rcContent.top);
1101 }
1102 }
1103 }
1104}
1105
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001106void CPWL_EditImpl::ScrollToCaret() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001107 SetScrollLimit();
1108
thestig821d59e2016-05-11 12:59:22 -07001109 if (!m_pVT->IsValid())
1110 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001111
thestig821d59e2016-05-11 12:59:22 -07001112 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1113 pIterator->SetAt(m_wpCaret);
1114
Dan Sinclairf528eee2017-02-14 11:52:07 -05001115 CFX_PointF ptHead;
1116 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001117 CPVT_Word word;
1118 CPVT_Line line;
1119 if (pIterator->GetWord(word)) {
1120 ptHead.x = word.ptWord.x + word.fWidth;
1121 ptHead.y = word.ptWord.y + word.fAscent;
1122 ptFoot.x = word.ptWord.x + word.fWidth;
1123 ptFoot.y = word.ptWord.y + word.fDescent;
1124 } else if (pIterator->GetLine(line)) {
1125 ptHead.x = line.ptLine.x;
1126 ptHead.y = line.ptLine.y + line.fLineAscent;
1127 ptFoot.x = line.ptLine.x;
1128 ptFoot.y = line.ptLine.y + line.fLineDescent;
1129 }
1130
Dan Sinclairf528eee2017-02-14 11:52:07 -05001131 CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1132 CFX_PointF ptFootEdit = VTToEdit(ptFoot);
thestig821d59e2016-05-11 12:59:22 -07001133 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
dsinclair448c4332016-08-02 12:07:35 -07001134 if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
1135 if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
1136 IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
thestig821d59e2016-05-11 12:59:22 -07001137 SetScrollPosX(ptHead.x);
dsinclair448c4332016-08-02 12:07:35 -07001138 } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
thestig821d59e2016-05-11 12:59:22 -07001139 SetScrollPosX(ptHead.x - rcPlate.Width());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001140 }
thestig821d59e2016-05-11 12:59:22 -07001141 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001142
dsinclair448c4332016-08-02 12:07:35 -07001143 if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
1144 if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
1145 IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
1146 if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
thestig821d59e2016-05-11 12:59:22 -07001147 SetScrollPosY(ptFoot.y + rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001148 }
dsinclair448c4332016-08-02 12:07:35 -07001149 } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
1150 if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
thestig821d59e2016-05-11 12:59:22 -07001151 SetScrollPosY(ptHead.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001152 }
1153 }
1154 }
1155}
1156
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001157void CPWL_EditImpl::Refresh() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001158 if (m_bEnableRefresh && m_pVT->IsValid()) {
1159 m_Refresh.BeginRefresh();
1160 RefreshPushLineRects(GetVisibleWordRange());
1161
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001162 m_Refresh.NoAnalyse();
1163 m_ptRefreshScrollPos = m_ptScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001164
dsinclaira2919b32016-07-13 10:55:48 -07001165 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001166 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001167 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001168 m_bNotifyFlag = true;
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001169 if (const CPWL_EditImpl_RectArray* pRects =
1170 m_Refresh.GetRefreshRects()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001171 for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001172 m_pNotify->InvalidateRect(pRects->GetAt(i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001173 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001174 }
1175 }
1176
1177 m_Refresh.EndRefresh();
1178 }
1179}
1180
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001181void CPWL_EditImpl::RefreshPushLineRects(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001182 if (!m_pVT->IsValid())
1183 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001184
thestig821d59e2016-05-11 12:59:22 -07001185 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1186 CPVT_WordPlace wpBegin = wr.BeginPos;
1187 m_pVT->UpdateWordPlace(wpBegin);
1188 CPVT_WordPlace wpEnd = wr.EndPos;
1189 m_pVT->UpdateWordPlace(wpEnd);
1190 pIterator->SetAt(wpBegin);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001191
thestig821d59e2016-05-11 12:59:22 -07001192 CPVT_Line lineinfo;
1193 do {
1194 if (!pIterator->GetLine(lineinfo))
1195 break;
1196 if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
1197 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001198
thestig821d59e2016-05-11 12:59:22 -07001199 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1200 lineinfo.ptLine.y + lineinfo.fLineDescent,
1201 lineinfo.ptLine.x + lineinfo.fLineWidth,
1202 lineinfo.ptLine.y + lineinfo.fLineAscent);
1203
1204 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1205 VTToEdit(rcLine));
1206 } while (pIterator->NextLine());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001207}
1208
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001209void CPWL_EditImpl::RefreshWordRange(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001210 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1211 CPVT_WordRange wrTemp = wr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001212
thestig821d59e2016-05-11 12:59:22 -07001213 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1214 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1215 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001216
thestig821d59e2016-05-11 12:59:22 -07001217 CPVT_Word wordinfo;
1218 CPVT_Line lineinfo;
1219 CPVT_WordPlace place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001220
thestig821d59e2016-05-11 12:59:22 -07001221 while (pIterator->NextWord()) {
1222 place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -07001223 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -07001224 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001225
thestig821d59e2016-05-11 12:59:22 -07001226 pIterator->GetWord(wordinfo);
1227 pIterator->GetLine(lineinfo);
thestig821d59e2016-05-11 12:59:22 -07001228 if (place.LineCmp(wrTemp.BeginPos) == 0 ||
1229 place.LineCmp(wrTemp.EndPos) == 0) {
1230 CFX_FloatRect rcWord(wordinfo.ptWord.x,
1231 lineinfo.ptLine.y + lineinfo.fLineDescent,
1232 wordinfo.ptWord.x + wordinfo.fWidth,
1233 lineinfo.ptLine.y + lineinfo.fLineAscent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001234
dsinclaira2919b32016-07-13 10:55:48 -07001235 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001236 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001237 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001238 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001239 CFX_FloatRect rcRefresh = VTToEdit(rcWord);
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001240 m_pNotify->InvalidateRect(&rcRefresh);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001241 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001242 }
thestig821d59e2016-05-11 12:59:22 -07001243 } else {
1244 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1245 lineinfo.ptLine.y + lineinfo.fLineDescent,
1246 lineinfo.ptLine.x + lineinfo.fLineWidth,
1247 lineinfo.ptLine.y + lineinfo.fLineAscent);
1248
dsinclaira2919b32016-07-13 10:55:48 -07001249 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001250 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001251 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001252 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001253 CFX_FloatRect rcRefresh = VTToEdit(rcLine);
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001254 m_pNotify->InvalidateRect(&rcRefresh);
thestig821d59e2016-05-11 12:59:22 -07001255 }
1256 }
1257
1258 pIterator->NextLine();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001259 }
1260 }
1261}
1262
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001263void CPWL_EditImpl::SetCaret(const CPVT_WordPlace& place) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001264 m_wpOldCaret = m_wpCaret;
1265 m_wpCaret = place;
1266}
1267
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001268void CPWL_EditImpl::SetCaretInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001269 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001270 if (!m_bNotifyFlag) {
thestig821d59e2016-05-11 12:59:22 -07001271 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1272 pIterator->SetAt(m_wpCaret);
tsepez63f545c2016-09-13 16:08:49 -07001273
Dan Sinclairf528eee2017-02-14 11:52:07 -05001274 CFX_PointF ptHead;
1275 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001276 CPVT_Word word;
1277 CPVT_Line line;
1278 if (pIterator->GetWord(word)) {
1279 ptHead.x = word.ptWord.x + word.fWidth;
1280 ptHead.y = word.ptWord.y + word.fAscent;
1281 ptFoot.x = word.ptWord.x + word.fWidth;
1282 ptFoot.y = word.ptWord.y + word.fDescent;
1283 } else if (pIterator->GetLine(line)) {
1284 ptHead.x = line.ptLine.x;
1285 ptHead.y = line.ptLine.y + line.fLineAscent;
1286 ptFoot.x = line.ptLine.x;
1287 ptFoot.y = line.ptLine.y + line.fLineDescent;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001288 }
1289
Lei Zhanga8c2b912017-03-22 17:41:02 -07001290 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001291 m_bNotifyFlag = true;
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001292 m_pNotify->SetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead),
1293 VTToEdit(ptFoot));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001294 }
1295 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001296}
1297
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001298void CPWL_EditImpl::OnMouseDown(const CFX_PointF& point,
1299 bool bShift,
1300 bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001301 if (!m_pVT->IsValid())
1302 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001303
Tom Sepez52f69b32017-03-21 13:42:38 -07001304 SelectNone();
1305 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1306 m_SelState.Set(m_wpCaret, m_wpCaret);
1307 ScrollToCaret();
1308 SetCaretOrigin();
1309 SetCaretInfo();
1310}
1311
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001312void CPWL_EditImpl::OnMouseMove(const CFX_PointF& point,
1313 bool bShift,
1314 bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001315 if (!m_pVT->IsValid())
1316 return;
1317
1318 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1319 if (m_wpCaret == m_wpOldCaret)
1320 return;
1321
1322 m_SelState.SetEndPos(m_wpCaret);
1323 ScrollToCaret();
1324 Refresh();
1325 SetCaretOrigin();
1326 SetCaretInfo();
1327}
1328
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001329void CPWL_EditImpl::OnVK_UP(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001330 if (!m_pVT->IsValid())
1331 return;
1332
1333 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1334 if (bShift) {
1335 if (m_SelState.IsEmpty())
1336 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1337 else
1338 m_SelState.SetEndPos(m_wpCaret);
1339
1340 if (m_wpOldCaret != m_wpCaret) {
1341 ScrollToCaret();
1342 Refresh();
1343 SetCaretInfo();
1344 }
1345 } else {
1346 SelectNone();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001347 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001348 SetCaretInfo();
1349 }
1350}
1351
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001352void CPWL_EditImpl::OnVK_DOWN(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001353 if (!m_pVT->IsValid())
1354 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001355
Tom Sepez52f69b32017-03-21 13:42:38 -07001356 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1357 if (bShift) {
1358 if (m_SelState.IsEmpty())
1359 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1360 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001361 m_SelState.SetEndPos(m_wpCaret);
1362
Tom Sepez52f69b32017-03-21 13:42:38 -07001363 if (m_wpOldCaret != m_wpCaret) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001364 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001365 Refresh();
Tom Sepez52f69b32017-03-21 13:42:38 -07001366 SetCaretInfo();
1367 }
1368 } else {
1369 SelectNone();
1370 ScrollToCaret();
1371 SetCaretInfo();
1372 }
1373}
1374
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001375void CPWL_EditImpl::OnVK_LEFT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001376 if (!m_pVT->IsValid())
1377 return;
1378
1379 if (bShift) {
1380 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1381 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1382 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1383 }
1384 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1385 if (m_SelState.IsEmpty())
1386 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1387 else
1388 m_SelState.SetEndPos(m_wpCaret);
1389
1390 if (m_wpOldCaret != m_wpCaret) {
1391 ScrollToCaret();
1392 Refresh();
1393 SetCaretInfo();
1394 }
1395 } else {
1396 if (!m_SelState.IsEmpty()) {
1397 if (m_SelState.BeginPos < m_SelState.EndPos)
1398 SetCaret(m_SelState.BeginPos);
1399 else
1400 SetCaret(m_SelState.EndPos);
1401
1402 SelectNone();
1403 ScrollToCaret();
1404 SetCaretInfo();
1405 } else {
1406 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1407 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1408 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1409 }
1410 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1411 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001412 SetCaretOrigin();
1413 SetCaretInfo();
1414 }
1415 }
1416}
1417
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001418void CPWL_EditImpl::OnVK_RIGHT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001419 if (!m_pVT->IsValid())
1420 return;
1421
1422 if (bShift) {
1423 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1424 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1425 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001426 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1427
Tom Sepez52f69b32017-03-21 13:42:38 -07001428 if (m_SelState.IsEmpty())
1429 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1430 else
1431 m_SelState.SetEndPos(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001432
Tom Sepez52f69b32017-03-21 13:42:38 -07001433 if (m_wpOldCaret != m_wpCaret) {
1434 ScrollToCaret();
1435 Refresh();
1436 SetCaretInfo();
1437 }
1438 } else {
1439 if (!m_SelState.IsEmpty()) {
1440 if (m_SelState.BeginPos > m_SelState.EndPos)
1441 SetCaret(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001442 else
Tom Sepez52f69b32017-03-21 13:42:38 -07001443 SetCaret(m_SelState.EndPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001444
Tom Sepez52f69b32017-03-21 13:42:38 -07001445 SelectNone();
1446 ScrollToCaret();
1447 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001448 } else {
Tom Sepez52f69b32017-03-21 13:42:38 -07001449 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1450 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1451 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001452 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001453 }
Tom Sepez52f69b32017-03-21 13:42:38 -07001454 ScrollToCaret();
1455 SetCaretOrigin();
1456 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001457 }
1458 }
1459}
1460
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001461void CPWL_EditImpl::OnVK_HOME(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001462 if (!m_pVT->IsValid())
1463 return;
1464
1465 if (bShift) {
1466 if (bCtrl)
1467 SetCaret(m_pVT->GetBeginWordPlace());
1468 else
1469 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1470
1471 if (m_SelState.IsEmpty())
1472 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1473 else
1474 m_SelState.SetEndPos(m_wpCaret);
1475
1476 ScrollToCaret();
1477 Refresh();
1478 SetCaretInfo();
1479 } else {
1480 if (!m_SelState.IsEmpty()) {
1481 SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos));
1482 SelectNone();
1483 ScrollToCaret();
1484 SetCaretInfo();
1485 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001486 if (bCtrl)
1487 SetCaret(m_pVT->GetBeginWordPlace());
1488 else
1489 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1490
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001491 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001492 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001493 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001494 }
1495 }
1496}
1497
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001498void CPWL_EditImpl::OnVK_END(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001499 if (!m_pVT->IsValid())
1500 return;
1501
1502 if (bShift) {
1503 if (bCtrl)
1504 SetCaret(m_pVT->GetEndWordPlace());
1505 else
1506 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1507
1508 if (m_SelState.IsEmpty())
1509 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1510 else
1511 m_SelState.SetEndPos(m_wpCaret);
1512
1513 ScrollToCaret();
1514 Refresh();
1515 SetCaretInfo();
1516 } else {
1517 if (!m_SelState.IsEmpty()) {
1518 SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos));
1519 SelectNone();
1520 ScrollToCaret();
1521 SetCaretInfo();
1522 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001523 if (bCtrl)
1524 SetCaret(m_pVT->GetEndWordPlace());
1525 else
1526 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1527
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001528 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001529 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001530 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001531 }
1532 }
1533}
1534
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001535bool CPWL_EditImpl::InsertWord(uint16_t word,
1536 int32_t charset,
1537 const CPVT_WordProps* pWordProps,
1538 bool bAddUndo,
1539 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001540 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001541 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001542
Tom Sepez3509d162017-01-30 13:22:02 -08001543 m_pVT->UpdateWordPlace(m_wpCaret);
1544 SetCaret(m_pVT->InsertWord(m_wpCaret, word,
1545 GetCharSetFromUnicode(word, charset), pWordProps));
1546 m_SelState.Set(m_wpCaret, m_wpCaret);
1547 if (m_wpCaret == m_wpOldCaret)
1548 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001549
Tom Sepez3509d162017-01-30 13:22:02 -08001550 if (bAddUndo && m_bEnableUndo) {
1551 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertWord>(
1552 this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001553 }
Tom Sepez3509d162017-01-30 13:22:02 -08001554 if (bPaint)
1555 PaintInsertText(m_wpOldCaret, m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001556
Lei Zhang5688d622017-08-12 07:04:19 -07001557 if (m_pOperationNotify)
1558 m_pOperationNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
Tom Sepez3509d162017-01-30 13:22:02 -08001559
1560 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001561}
1562
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001563bool CPWL_EditImpl::InsertReturn(const CPVT_SecProps* pSecProps,
1564 const CPVT_WordProps* pWordProps,
1565 bool bAddUndo,
1566 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001567 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001568 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001569
Tom Sepez3509d162017-01-30 13:22:02 -08001570 m_pVT->UpdateWordPlace(m_wpCaret);
1571 SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
1572 m_SelState.Set(m_wpCaret, m_wpCaret);
1573 if (m_wpCaret == m_wpOldCaret)
1574 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001575
Tom Sepez3509d162017-01-30 13:22:02 -08001576 if (bAddUndo && m_bEnableUndo) {
1577 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertReturn>(
1578 this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001579 }
Tom Sepez3509d162017-01-30 13:22:02 -08001580 if (bPaint) {
1581 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1582 ScrollToCaret();
1583 Refresh();
1584 SetCaretOrigin();
1585 SetCaretInfo();
1586 }
Lei Zhang5688d622017-08-12 07:04:19 -07001587 if (m_pOperationNotify)
1588 m_pOperationNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001589
Tom Sepez3509d162017-01-30 13:22:02 -08001590 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001591}
1592
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001593bool CPWL_EditImpl::Backspace(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001594 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1595 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001596
Tom Sepez3509d162017-01-30 13:22:02 -08001597 CPVT_Section section;
1598 CPVT_Word word;
1599 if (bAddUndo) {
1600 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1601 pIterator->SetAt(m_wpCaret);
1602 pIterator->GetSection(section);
1603 pIterator->GetWord(word);
1604 }
1605 m_pVT->UpdateWordPlace(m_wpCaret);
1606 SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1607 m_SelState.Set(m_wpCaret, m_wpCaret);
1608 if (m_wpCaret == m_wpOldCaret)
1609 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001610
Tom Sepez3509d162017-01-30 13:22:02 -08001611 if (bAddUndo && m_bEnableUndo) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001612 if (m_wpCaret.nSecIndex != m_wpOldCaret.nSecIndex) {
Tom Sepez3509d162017-01-30 13:22:02 -08001613 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1614 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1615 section.SecProps, section.WordProps));
1616 } else {
1617 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1618 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1619 section.SecProps, word.WordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001620 }
1621 }
Tom Sepez3509d162017-01-30 13:22:02 -08001622 if (bPaint) {
1623 RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
1624 ScrollToCaret();
1625 Refresh();
1626 SetCaretOrigin();
1627 SetCaretInfo();
1628 }
Lei Zhang5688d622017-08-12 07:04:19 -07001629 if (m_pOperationNotify)
1630 m_pOperationNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001631
Tom Sepez3509d162017-01-30 13:22:02 -08001632 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001633}
1634
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001635bool CPWL_EditImpl::Delete(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001636 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1637 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001638
Tom Sepez3509d162017-01-30 13:22:02 -08001639 CPVT_Section section;
1640 CPVT_Word word;
1641 if (bAddUndo) {
1642 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1643 pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1644 pIterator->GetSection(section);
1645 pIterator->GetWord(word);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001646 }
Tom Sepez3509d162017-01-30 13:22:02 -08001647 m_pVT->UpdateWordPlace(m_wpCaret);
1648 bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1649 SetCaret(m_pVT->DeleteWord(m_wpCaret));
1650 m_SelState.Set(m_wpCaret, m_wpCaret);
1651 if (bAddUndo && m_bEnableUndo) {
1652 if (bSecEnd) {
1653 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1654 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1655 section.SecProps, section.WordProps, bSecEnd));
1656 } else {
1657 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1658 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1659 section.SecProps, word.WordProps, bSecEnd));
1660 }
1661 }
1662 if (bPaint) {
1663 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1664 ScrollToCaret();
1665 Refresh();
1666 SetCaretOrigin();
1667 SetCaretInfo();
1668 }
Lei Zhang5688d622017-08-12 07:04:19 -07001669 if (m_pOperationNotify)
1670 m_pOperationNotify->OnDelete(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001671
Tom Sepez3509d162017-01-30 13:22:02 -08001672 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001673}
1674
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001675bool CPWL_EditImpl::Empty() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001676 if (m_pVT->IsValid()) {
1677 m_pVT->DeleteWords(GetWholeWordRange());
1678 SetCaret(m_pVT->GetBeginWordPlace());
1679
tsepez4cf55152016-11-02 14:37:54 -07001680 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001681 }
1682
tsepez4cf55152016-11-02 14:37:54 -07001683 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001684}
1685
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001686bool CPWL_EditImpl::Clear(bool bAddUndo, bool bPaint) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001687 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
tsepez4cf55152016-11-02 14:37:54 -07001688 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001689
thestig821d59e2016-05-11 12:59:22 -07001690 CPVT_WordRange range = m_SelState.ConvertToWordRange();
Diana Gage22bf7a52017-07-21 11:33:18 -07001691 if (bAddUndo && m_bEnableUndo) {
Diana Gage89e65622017-07-20 18:09:31 -07001692 AddEditUndoItem(
1693 pdfium::MakeUnique<CFXEU_Clear>(this, range, GetSelectedText()));
Diana Gage22bf7a52017-07-21 11:33:18 -07001694 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001695
thestig821d59e2016-05-11 12:59:22 -07001696 SelectNone();
1697 SetCaret(m_pVT->DeleteWords(range));
1698 m_SelState.Set(m_wpCaret, m_wpCaret);
thestig821d59e2016-05-11 12:59:22 -07001699 if (bPaint) {
1700 RearrangePart(range);
1701 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001702 Refresh();
thestig821d59e2016-05-11 12:59:22 -07001703 SetCaretOrigin();
1704 SetCaretInfo();
1705 }
Lei Zhang5688d622017-08-12 07:04:19 -07001706 if (m_pOperationNotify)
1707 m_pOperationNotify->OnClear(m_wpCaret, m_wpOldCaret);
thestig821d59e2016-05-11 12:59:22 -07001708
tsepez4cf55152016-11-02 14:37:54 -07001709 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001710}
1711
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001712bool CPWL_EditImpl::InsertText(const CFX_WideString& sText,
1713 int32_t charset,
1714 bool bAddUndo,
1715 bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001716 if (IsTextOverflow())
tsepez4cf55152016-11-02 14:37:54 -07001717 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001718
1719 m_pVT->UpdateWordPlace(m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001720 SetCaret(DoInsertText(m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001721 m_SelState.Set(m_wpCaret, m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001722 if (m_wpCaret == m_wpOldCaret)
tsepez4cf55152016-11-02 14:37:54 -07001723 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001724
tsepeza31da742016-09-08 11:28:14 -07001725 if (bAddUndo && m_bEnableUndo) {
Tom Sepez3509d162017-01-30 13:22:02 -08001726 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertText>(
1727 this, m_wpOldCaret, m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001728 }
tsepeza31da742016-09-08 11:28:14 -07001729 if (bPaint)
1730 PaintInsertText(m_wpOldCaret, m_wpCaret);
1731
Lei Zhang5688d622017-08-12 07:04:19 -07001732 if (m_pOperationNotify)
1733 m_pOperationNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
tsepeza31da742016-09-08 11:28:14 -07001734
tsepez4cf55152016-11-02 14:37:54 -07001735 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001736}
1737
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001738void CPWL_EditImpl::PaintInsertText(const CPVT_WordPlace& wpOld,
1739 const CPVT_WordPlace& wpNew) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001740 if (m_pVT->IsValid()) {
1741 RearrangePart(CPVT_WordRange(wpOld, wpNew));
1742 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001743 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001744 SetCaretOrigin();
1745 SetCaretInfo();
1746 }
1747}
1748
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001749bool CPWL_EditImpl::Redo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001750 if (m_bEnableUndo) {
1751 if (m_Undo.CanRedo()) {
1752 m_Undo.Redo();
tsepez4cf55152016-11-02 14:37:54 -07001753 return true;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001754 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001755 }
1756
tsepez4cf55152016-11-02 14:37:54 -07001757 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001758}
1759
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001760bool CPWL_EditImpl::Undo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001761 if (m_bEnableUndo) {
1762 if (m_Undo.CanUndo()) {
1763 m_Undo.Undo();
tsepez4cf55152016-11-02 14:37:54 -07001764 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001765 }
1766 }
1767
tsepez4cf55152016-11-02 14:37:54 -07001768 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001769}
1770
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001771void CPWL_EditImpl::SetCaretOrigin() {
thestig821d59e2016-05-11 12:59:22 -07001772 if (!m_pVT->IsValid())
1773 return;
1774
1775 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1776 pIterator->SetAt(m_wpCaret);
1777 CPVT_Word word;
1778 CPVT_Line line;
1779 if (pIterator->GetWord(word)) {
1780 m_ptCaret.x = word.ptWord.x + word.fWidth;
1781 m_ptCaret.y = word.ptWord.y;
1782 } else if (pIterator->GetLine(line)) {
1783 m_ptCaret.x = line.ptLine.x;
1784 m_ptCaret.y = line.ptLine.y;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001785 }
1786}
1787
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001788CPVT_WordPlace CPWL_EditImpl::WordIndexToWordPlace(int32_t index) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001789 if (m_pVT->IsValid())
1790 return m_pVT->WordIndexToWordPlace(index);
1791
1792 return CPVT_WordPlace();
1793}
1794
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001795bool CPWL_EditImpl::IsTextFull() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001796 int32_t nTotalWords = m_pVT->GetTotalWords();
1797 int32_t nLimitChar = m_pVT->GetLimitChar();
1798 int32_t nCharArray = m_pVT->GetCharArray();
1799
1800 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
1801 (nCharArray > 0 && nTotalWords >= nCharArray);
1802}
1803
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001804bool CPWL_EditImpl::IsTextOverflow() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001805 if (!m_bEnableScroll && !m_bEnableOverflow) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001806 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1807 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001808
dsinclair448c4332016-08-02 12:07:35 -07001809 if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
1810 IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
tsepez4cf55152016-11-02 14:37:54 -07001811 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001812 }
1813
dsinclair448c4332016-08-02 12:07:35 -07001814 if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
tsepez4cf55152016-11-02 14:37:54 -07001815 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001816 }
1817
tsepez4cf55152016-11-02 14:37:54 -07001818 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001819}
1820
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001821bool CPWL_EditImpl::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001822 if (m_bEnableUndo) {
1823 return m_Undo.CanUndo();
1824 }
1825
tsepez4cf55152016-11-02 14:37:54 -07001826 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001827}
1828
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001829bool CPWL_EditImpl::CanRedo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001830 if (m_bEnableUndo) {
1831 return m_Undo.CanRedo();
1832 }
1833
tsepez4cf55152016-11-02 14:37:54 -07001834 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001835}
1836
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001837void CPWL_EditImpl::EnableRefresh(bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001838 m_bEnableRefresh = bRefresh;
1839}
1840
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001841void CPWL_EditImpl::EnableUndo(bool bUndo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001842 m_bEnableUndo = bUndo;
1843}
1844
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001845CPVT_WordPlace CPWL_EditImpl::DoInsertText(const CPVT_WordPlace& place,
1846 const CFX_WideString& sText,
1847 int32_t charset) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001848 CPVT_WordPlace wp = place;
1849
1850 if (m_pVT->IsValid()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001851 for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
Tom Sepez62a70f92016-03-21 15:00:20 -07001852 uint16_t word = sText[i];
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001853 switch (word) {
1854 case 0x0D:
dsinclairefd5a992016-07-18 10:04:07 -07001855 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001856 if (sText[i + 1] == 0x0A)
1857 i++;
1858 break;
1859 case 0x0A:
dsinclairefd5a992016-07-18 10:04:07 -07001860 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001861 if (sText[i + 1] == 0x0D)
1862 i++;
1863 break;
1864 case 0x09:
1865 word = 0x20;
1866 default:
1867 wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
dsinclairefd5a992016-07-18 10:04:07 -07001868 nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001869 break;
1870 }
1871 }
1872 }
1873
1874 return wp;
1875}
1876
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001877int32_t CPWL_EditImpl::GetCharSetFromUnicode(uint16_t word,
1878 int32_t nOldCharset) {
dsinclairc7a73492016-04-05 12:01:42 -07001879 if (IPVT_FontMap* pFontMap = GetFontMap())
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001880 return pFontMap->CharSetFromUnicode(word, nOldCharset);
1881 return nOldCharset;
1882}
1883
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001884void CPWL_EditImpl::AddEditUndoItem(
Lei Zhangae9c5ca2017-08-12 07:15:14 -07001885 std::unique_ptr<IFX_Edit_UndoItem> pEditUndoItem) {
Lei Zhang1a89e362017-03-23 15:27:25 -07001886 m_Undo.AddItem(std::move(pEditUndoItem));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001887}
1888
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001889CFX_ByteString CPWL_EditImpl::GetPDFWordString(int32_t nFontIndex,
1890 uint16_t Word,
1891 uint16_t SubWord) {
Dan Sinclairc08dc392017-07-24 08:57:35 -04001892 IPVT_FontMap* pFontMap = GetFontMap();
1893 CPDF_Font* pPDFFont = pFontMap->GetPDFFont(nFontIndex);
1894 if (!pPDFFont)
1895 return CFX_ByteString();
1896
1897 CFX_ByteString sWord;
1898 if (SubWord > 0) {
1899 Word = SubWord;
1900 } else {
1901 uint32_t dwCharCode = pPDFFont->IsUnicodeCompatible()
1902 ? pPDFFont->CharCodeFromUnicode(Word)
1903 : pFontMap->CharCodeFromUnicode(nFontIndex, Word);
1904 if (dwCharCode > 0) {
1905 pPDFFont->AppendChar(&sWord, dwCharCode);
1906 return sWord;
1907 }
1908 }
1909 pPDFFont->AppendChar(&sWord, Word);
1910 return sWord;
1911}
1912
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001913CPWL_EditImpl_LineRectArray::CPWL_EditImpl_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07001914
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001915CPWL_EditImpl_LineRectArray::~CPWL_EditImpl_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07001916
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001917void CPWL_EditImpl_LineRectArray::operator=(
1918 CPWL_EditImpl_LineRectArray&& that) {
Tom Sepez3509d162017-01-30 13:22:02 -08001919 m_LineRects = std::move(that.m_LineRects);
weili625ad662016-06-15 11:21:33 -07001920}
1921
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001922void CPWL_EditImpl_LineRectArray::Add(const CPVT_WordRange& wrLine,
1923 const CFX_FloatRect& rcLine) {
1924 m_LineRects.push_back(
1925 pdfium::MakeUnique<CPWL_EditImpl_LineRect>(wrLine, rcLine));
weili625ad662016-06-15 11:21:33 -07001926}
1927
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001928int32_t CPWL_EditImpl_LineRectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08001929 return pdfium::CollectionSize<int32_t>(m_LineRects);
weili625ad662016-06-15 11:21:33 -07001930}
1931
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001932CPWL_EditImpl_LineRect* CPWL_EditImpl_LineRectArray::GetAt(
1933 int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08001934 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07001935 return nullptr;
1936
Tom Sepez3509d162017-01-30 13:22:02 -08001937 return m_LineRects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07001938}
1939
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001940CPWL_EditImpl_Select::CPWL_EditImpl_Select() {}
weili625ad662016-06-15 11:21:33 -07001941
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001942CPWL_EditImpl_Select::CPWL_EditImpl_Select(const CPVT_WordRange& range) {
weili625ad662016-06-15 11:21:33 -07001943 Set(range.BeginPos, range.EndPos);
1944}
1945
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001946CPVT_WordRange CPWL_EditImpl_Select::ConvertToWordRange() const {
weili625ad662016-06-15 11:21:33 -07001947 return CPVT_WordRange(BeginPos, EndPos);
1948}
1949
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001950void CPWL_EditImpl_Select::Reset() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001951 BeginPos.Reset();
1952 EndPos.Reset();
weili625ad662016-06-15 11:21:33 -07001953}
1954
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001955void CPWL_EditImpl_Select::Set(const CPVT_WordPlace& begin,
1956 const CPVT_WordPlace& end) {
weili625ad662016-06-15 11:21:33 -07001957 BeginPos = begin;
1958 EndPos = end;
1959}
1960
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001961void CPWL_EditImpl_Select::SetEndPos(const CPVT_WordPlace& end) {
weili625ad662016-06-15 11:21:33 -07001962 EndPos = end;
1963}
1964
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001965bool CPWL_EditImpl_Select::IsEmpty() const {
Tom Sepez52f69b32017-03-21 13:42:38 -07001966 return BeginPos == EndPos;
weili625ad662016-06-15 11:21:33 -07001967}
1968
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001969CPWL_EditImpl_RectArray::CPWL_EditImpl_RectArray() {}
weili625ad662016-06-15 11:21:33 -07001970
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001971CPWL_EditImpl_RectArray::~CPWL_EditImpl_RectArray() {}
weili625ad662016-06-15 11:21:33 -07001972
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001973void CPWL_EditImpl_RectArray::Clear() {
Tom Sepez3509d162017-01-30 13:22:02 -08001974 m_Rects.clear();
weili625ad662016-06-15 11:21:33 -07001975}
1976
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001977void CPWL_EditImpl_RectArray::Add(const CFX_FloatRect& rect) {
weili625ad662016-06-15 11:21:33 -07001978 // check for overlapped area
Tom Sepez3509d162017-01-30 13:22:02 -08001979 for (const auto& pRect : m_Rects) {
weili625ad662016-06-15 11:21:33 -07001980 if (pRect && pRect->Contains(rect))
1981 return;
1982 }
Tom Sepez3509d162017-01-30 13:22:02 -08001983 m_Rects.push_back(pdfium::MakeUnique<CFX_FloatRect>(rect));
weili625ad662016-06-15 11:21:33 -07001984}
1985
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001986int32_t CPWL_EditImpl_RectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08001987 return pdfium::CollectionSize<int32_t>(m_Rects);
weili625ad662016-06-15 11:21:33 -07001988}
1989
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001990CFX_FloatRect* CPWL_EditImpl_RectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08001991 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07001992 return nullptr;
1993
Tom Sepez3509d162017-01-30 13:22:02 -08001994 return m_Rects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07001995}