blob: 5d7a44c62387eb68db49a7992fcceb5136d11235 [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,
Lei Zhangeb14e042017-08-15 13:56:43 -070044 const CFX_Matrix& mtUser2Device,
dsinclaire35af1e2016-07-13 11:26:20 -070045 const CFX_ByteString& str,
46 FX_ARGB crTextFill,
dsinclaire35af1e2016-07-13 11:26:20 -070047 int32_t nHorzScale) {
Lei Zhangeb14e042017-08-15 13:56:43 -070048 if (!pFont)
49 return;
dsinclaire35af1e2016-07-13 11:26:20 -070050
Lei Zhangeb14e042017-08-15 13:56:43 -070051 CFX_PointF pos = mtUser2Device.Transform(pt);
52 CFX_Matrix mt;
53 if (nHorzScale == 100) {
54 mt = mtUser2Device;
55 } else {
56 mt = CFX_Matrix(nHorzScale / 100.0f, 0, 0, 1, 0, 0);
57 mt.Concat(mtUser2Device);
dsinclaire35af1e2016-07-13 11:26:20 -070058 }
Lei Zhangeb14e042017-08-15 13:56:43 -070059
60 CPDF_RenderOptions ro;
61 ro.m_Flags = RENDER_CLEARTYPE;
62 ro.m_ColorMode = CPDF_RenderOptions::kNormal;
63 CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize,
64 &mt, str, crTextFill, nullptr, &ro);
dsinclaire35af1e2016-07-13 11:26:20 -070065}
66
dsinclair8f4bf9a2016-05-04 13:51:51 -070067} // namespace
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070068
Dan Sinclair6b0158f2017-07-24 09:42:55 -040069CPWL_EditImpl_Iterator::CPWL_EditImpl_Iterator(
70 CPWL_EditImpl* pEdit,
71 CPDF_VariableText::Iterator* pVTIterator)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070072 : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {}
73
Dan Sinclair6b0158f2017-07-24 09:42:55 -040074CPWL_EditImpl_Iterator::~CPWL_EditImpl_Iterator() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075
Dan Sinclair6b0158f2017-07-24 09:42:55 -040076bool CPWL_EditImpl_Iterator::NextWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070077 return m_pVTIterator->NextWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070078}
79
Dan Sinclair6b0158f2017-07-24 09:42:55 -040080bool CPWL_EditImpl_Iterator::PrevWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 return m_pVTIterator->PrevWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070082}
83
Dan Sinclair6b0158f2017-07-24 09:42:55 -040084bool CPWL_EditImpl_Iterator::GetWord(CPVT_Word& word) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 ASSERT(m_pEdit);
86
87 if (m_pVTIterator->GetWord(word)) {
88 word.ptWord = m_pEdit->VTToEdit(word.ptWord);
tsepez4cf55152016-11-02 14:37:54 -070089 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090 }
tsepez4cf55152016-11-02 14:37:54 -070091 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070092}
93
Dan Sinclair6b0158f2017-07-24 09:42:55 -040094bool CPWL_EditImpl_Iterator::GetLine(CPVT_Line& line) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095 ASSERT(m_pEdit);
96
97 if (m_pVTIterator->GetLine(line)) {
98 line.ptLine = m_pEdit->VTToEdit(line.ptLine);
tsepez4cf55152016-11-02 14:37:54 -070099 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100 }
tsepez4cf55152016-11-02 14:37:54 -0700101 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700102}
103
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400104void CPWL_EditImpl_Iterator::SetAt(int32_t nWordIndex) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700105 m_pVTIterator->SetAt(nWordIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700106}
107
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400108void CPWL_EditImpl_Iterator::SetAt(const CPVT_WordPlace& place) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700109 m_pVTIterator->SetAt(place);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700110}
111
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400112const CPVT_WordPlace& CPWL_EditImpl_Iterator::GetAt() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113 return m_pVTIterator->GetAt();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700114}
115
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400116CPWL_EditImpl_Provider::CPWL_EditImpl_Provider(IPVT_FontMap* pFontMap)
dsinclairc7a73492016-04-05 12:01:42 -0700117 : CPDF_VariableText::Provider(pFontMap), m_pFontMap(pFontMap) {
Lei Zhang96660d62015-12-14 18:27:25 -0800118 ASSERT(m_pFontMap);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700119}
120
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400121CPWL_EditImpl_Provider::~CPWL_EditImpl_Provider() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400123IPVT_FontMap* CPWL_EditImpl_Provider::GetFontMap() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124 return m_pFontMap;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700125}
126
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400127int32_t CPWL_EditImpl_Provider::GetCharWidth(int32_t nFontIndex,
128 uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
tsepezc3255f52016-03-25 14:52:27 -0700130 uint32_t charcode = word;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700131
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 if (pPDFFont->IsUnicodeCompatible())
133 charcode = pPDFFont->CharCodeFromUnicode(word);
134 else
135 charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);
136
Wei Li89409932016-03-28 10:33:33 -0700137 if (charcode != CPDF_Font::kInvalidCharCode)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138 return pPDFFont->GetCharWidthF(charcode);
139 }
140
141 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700142}
143
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400144int32_t CPWL_EditImpl_Provider::GetTypeAscent(int32_t nFontIndex) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700145 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
146 return pPDFFont->GetTypeAscent();
147
148 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700149}
150
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400151int32_t CPWL_EditImpl_Provider::GetTypeDescent(int32_t nFontIndex) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
153 return pPDFFont->GetTypeDescent();
154
155 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700156}
157
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400158int32_t CPWL_EditImpl_Provider::GetWordFontIndex(uint16_t word,
159 int32_t charset,
160 int32_t nFontIndex) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 return m_pFontMap->GetWordFontIndex(word, charset, nFontIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700162}
163
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400164int32_t CPWL_EditImpl_Provider::GetDefaultFontIndex() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700166}
167
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400168bool CPWL_EditImpl_Provider::IsLatinWord(uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169 return FX_EDIT_ISLATINWORD(word);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700170}
171
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400172CPWL_EditImpl_Refresh::CPWL_EditImpl_Refresh() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400174CPWL_EditImpl_Refresh::~CPWL_EditImpl_Refresh() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400176void CPWL_EditImpl_Refresh::BeginRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800177 m_RefreshRects.Clear();
178 m_OldLineRects = std::move(m_NewLineRects);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700179}
180
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400181void CPWL_EditImpl_Refresh::Push(const CPVT_WordRange& linerange,
182 const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 m_NewLineRects.Add(linerange, rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184}
185
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400186void CPWL_EditImpl_Refresh::NoAnalyse() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187 {
188 for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400189 if (CPWL_EditImpl_LineRect* pOldRect = m_OldLineRects.GetAt(i))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 m_RefreshRects.Add(pOldRect->m_rcLine);
191 }
192
193 {
194 for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400195 if (CPWL_EditImpl_LineRect* pNewRect = m_NewLineRects.GetAt(i))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196 m_RefreshRects.Add(pNewRect->m_rcLine);
197 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700198}
199
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400200const CPWL_EditImpl_RectArray* CPWL_EditImpl_Refresh::GetRefreshRects() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201 return &m_RefreshRects;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700202}
203
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400204void CPWL_EditImpl_Refresh::EndRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800205 m_RefreshRects.Clear();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700206}
207
Lei Zhangbff66f12017-08-15 13:26:44 -0700208CPWL_EditImpl_Undo::CPWL_EditImpl_Undo()
209 : m_nCurUndoPos(0), m_bWorking(false) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210
Lei Zhangbff66f12017-08-15 13:26:44 -0700211CPWL_EditImpl_Undo::~CPWL_EditImpl_Undo() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700212
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400213bool CPWL_EditImpl_Undo::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700214 return m_nCurUndoPos > 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700215}
216
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400217void CPWL_EditImpl_Undo::Undo() {
tsepez4cf55152016-11-02 14:37:54 -0700218 m_bWorking = true;
Lei Zhangbff66f12017-08-15 13:26:44 -0700219 if (CanUndo()) {
Tom Sepez3509d162017-01-30 13:22:02 -0800220 m_UndoItemStack[m_nCurUndoPos - 1]->Undo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 m_nCurUndoPos--;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222 }
tsepez4cf55152016-11-02 14:37:54 -0700223 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700224}
225
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400226bool CPWL_EditImpl_Undo::CanRedo() const {
Tom Sepez3509d162017-01-30 13:22:02 -0800227 return m_nCurUndoPos < m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228}
229
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400230void CPWL_EditImpl_Undo::Redo() {
tsepez4cf55152016-11-02 14:37:54 -0700231 m_bWorking = true;
Lei Zhangbff66f12017-08-15 13:26:44 -0700232 if (CanRedo()) {
Tom Sepez3509d162017-01-30 13:22:02 -0800233 m_UndoItemStack[m_nCurUndoPos]->Redo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234 m_nCurUndoPos++;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235 }
tsepez4cf55152016-11-02 14:37:54 -0700236 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700237}
238
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400239void CPWL_EditImpl_Undo::AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240 ASSERT(!m_bWorking);
Lei Zhang96660d62015-12-14 18:27:25 -0800241 ASSERT(pItem);
Lei Zhangbff66f12017-08-15 13:26:44 -0700242 if (CanRedo())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 RemoveTails();
244
Lei Zhangbff66f12017-08-15 13:26:44 -0700245 if (m_UndoItemStack.size() >= kEditUndoMaxItems)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 RemoveHeads();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247
Tom Sepez3509d162017-01-30 13:22:02 -0800248 m_UndoItemStack.push_back(std::move(pItem));
249 m_nCurUndoPos = m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700250}
251
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400252void CPWL_EditImpl_Undo::RemoveHeads() {
Tom Sepez3509d162017-01-30 13:22:02 -0800253 ASSERT(m_UndoItemStack.size() > 1);
254 m_UndoItemStack.pop_front();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700255}
256
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400257void CPWL_EditImpl_Undo::RemoveTails() {
Lei Zhangbff66f12017-08-15 13:26:44 -0700258 while (CanRedo())
Tom Sepez3509d162017-01-30 13:22:02 -0800259 m_UndoItemStack.pop_back();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260}
261
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400262CFXEU_InsertWord::CFXEU_InsertWord(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 const CPVT_WordPlace& wpOldPlace,
264 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700265 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 int32_t charset,
267 const CPVT_WordProps* pWordProps)
268 : m_pEdit(pEdit),
269 m_wpOld(wpOldPlace),
270 m_wpNew(wpNewPlace),
271 m_Word(word),
272 m_nCharset(charset),
273 m_WordProps() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700274 ASSERT(m_pEdit);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275 if (pWordProps)
276 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700277}
278
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700279CFXEU_InsertWord::~CFXEU_InsertWord() {}
280
281void CFXEU_InsertWord::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700282 m_pEdit->SelectNone();
283 m_pEdit->SetCaret(m_wpOld);
284 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700285}
286
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287void CFXEU_InsertWord::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700288 m_pEdit->SelectNone();
289 m_pEdit->SetCaret(m_wpNew);
290 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700291}
292
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400293CFXEU_InsertReturn::CFXEU_InsertReturn(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294 const CPVT_WordPlace& wpOldPlace,
295 const CPVT_WordPlace& wpNewPlace,
296 const CPVT_SecProps* pSecProps,
297 const CPVT_WordProps* pWordProps)
298 : m_pEdit(pEdit),
299 m_wpOld(wpOldPlace),
300 m_wpNew(wpNewPlace),
301 m_SecProps(),
302 m_WordProps() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700303 ASSERT(m_pEdit);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304 if (pSecProps)
305 m_SecProps = *pSecProps;
306 if (pWordProps)
307 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700308}
309
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310CFXEU_InsertReturn::~CFXEU_InsertReturn() {}
311
312void CFXEU_InsertReturn::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700313 m_pEdit->SelectNone();
314 m_pEdit->SetCaret(m_wpOld);
315 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700316}
317
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700318void CFXEU_InsertReturn::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700319 m_pEdit->SelectNone();
320 m_pEdit->SetCaret(m_wpNew);
321 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700322}
323
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400324CFXEU_Backspace::CFXEU_Backspace(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700325 const CPVT_WordPlace& wpOldPlace,
326 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700327 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700328 int32_t charset,
329 const CPVT_SecProps& SecProps,
330 const CPVT_WordProps& WordProps)
331 : m_pEdit(pEdit),
332 m_wpOld(wpOldPlace),
333 m_wpNew(wpNewPlace),
334 m_Word(word),
335 m_nCharset(charset),
336 m_SecProps(SecProps),
Lei Zhangf5a06672017-08-12 08:01:37 -0700337 m_WordProps(WordProps) {
338 ASSERT(m_pEdit);
339}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340
341CFXEU_Backspace::~CFXEU_Backspace() {}
342
343void CFXEU_Backspace::Redo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700344 m_pEdit->SelectNone();
345 m_pEdit->SetCaret(m_wpOld);
346 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700347}
348
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700349void CFXEU_Backspace::Undo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700350 m_pEdit->SelectNone();
351 m_pEdit->SetCaret(m_wpNew);
352 if (m_wpNew.nSecIndex != m_wpOld.nSecIndex)
353 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
354 else
355 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700356}
357
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400358CFXEU_Delete::CFXEU_Delete(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700359 const CPVT_WordPlace& wpOldPlace,
360 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700361 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700362 int32_t charset,
363 const CPVT_SecProps& SecProps,
364 const CPVT_WordProps& WordProps,
tsepez4cf55152016-11-02 14:37:54 -0700365 bool bSecEnd)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366 : m_pEdit(pEdit),
367 m_wpOld(wpOldPlace),
368 m_wpNew(wpNewPlace),
369 m_Word(word),
370 m_nCharset(charset),
371 m_SecProps(SecProps),
372 m_WordProps(WordProps),
Lei Zhangf5a06672017-08-12 08:01:37 -0700373 m_bSecEnd(bSecEnd) {
374 ASSERT(m_pEdit);
375}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376
377CFXEU_Delete::~CFXEU_Delete() {}
378
379void CFXEU_Delete::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700380 m_pEdit->SelectNone();
381 m_pEdit->SetCaret(m_wpOld);
382 m_pEdit->Delete(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700383}
384
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385void CFXEU_Delete::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700386 m_pEdit->SelectNone();
387 m_pEdit->SetCaret(m_wpNew);
388 if (m_bSecEnd)
389 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
390 else
391 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700392}
393
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400394CFXEU_Clear::CFXEU_Clear(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700395 const CPVT_WordRange& wrSel,
396 const CFX_WideString& swText)
Lei Zhangf5a06672017-08-12 08:01:37 -0700397 : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {
398 ASSERT(m_pEdit);
399}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700400
401CFXEU_Clear::~CFXEU_Clear() {}
402
403void CFXEU_Clear::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700404 m_pEdit->SelectNone();
405 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
406 m_pEdit->Clear(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407}
408
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700409void CFXEU_Clear::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700410 m_pEdit->SelectNone();
411 m_pEdit->SetCaret(m_wrSel.BeginPos);
412 m_pEdit->InsertText(m_swText, FX_CHARSET_Default, false, true);
413 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700414}
415
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400416CFXEU_InsertText::CFXEU_InsertText(CPWL_EditImpl* pEdit,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700417 const CPVT_WordPlace& wpOldPlace,
418 const CPVT_WordPlace& wpNewPlace,
419 const CFX_WideString& swText,
dsinclairefd5a992016-07-18 10:04:07 -0700420 int32_t charset)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700421 : m_pEdit(pEdit),
422 m_wpOld(wpOldPlace),
423 m_wpNew(wpNewPlace),
424 m_swText(swText),
Lei Zhangf5a06672017-08-12 08:01:37 -0700425 m_nCharset(charset) {
426 ASSERT(m_pEdit);
427}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700428
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700429CFXEU_InsertText::~CFXEU_InsertText() {}
430
431void CFXEU_InsertText::Redo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700432 m_pEdit->SelectNone();
433 m_pEdit->SetCaret(m_wpOld);
434 m_pEdit->InsertText(m_swText, m_nCharset, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700435}
436
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700437void CFXEU_InsertText::Undo() {
Lei Zhangf5a06672017-08-12 08:01:37 -0700438 m_pEdit->SelectNone();
439 m_pEdit->SetSelection(m_wpOld, m_wpNew);
440 m_pEdit->Clear(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700441}
442
dsinclaire35af1e2016-07-13 11:26:20 -0700443// static
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400444void CPWL_EditImpl::DrawEdit(CFX_RenderDevice* pDevice,
Lei Zhangeb14e042017-08-15 13:56:43 -0700445 const CFX_Matrix& mtUser2Device,
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400446 CPWL_EditImpl* pEdit,
447 FX_COLORREF crTextFill,
448 const CFX_FloatRect& rcClip,
449 const CFX_PointF& ptOffset,
450 const CPVT_WordRange* pRange,
451 CFX_SystemHandler* pSystemHandler,
452 CFFL_FormFiller* pFFLData) {
dsinclaire35af1e2016-07-13 11:26:20 -0700453 const bool bContinuous =
454 pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
455 uint16_t SubWord = pEdit->GetPasswordChar();
Dan Sinclair05df0752017-03-14 14:43:42 -0400456 float fFontSize = pEdit->GetFontSize();
dsinclaire35af1e2016-07-13 11:26:20 -0700457 CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
458 int32_t nHorzScale = pEdit->GetHorzScale();
459
460 FX_COLORREF crCurFill = crTextFill;
461 FX_COLORREF crOldFill = crCurFill;
462
tsepez4cf55152016-11-02 14:37:54 -0700463 bool bSelect = false;
Lei Zhangeb14e042017-08-15 13:56:43 -0700464 static const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
465 static const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
dsinclaire35af1e2016-07-13 11:26:20 -0700466
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400467 std::ostringstream sTextBuf;
dsinclaire35af1e2016-07-13 11:26:20 -0700468 int32_t nFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500469 CFX_PointF ptBT;
Tom Sepez1629f602017-04-21 14:11:26 -0700470 CFX_RenderDevice::StateRestorer restorer(pDevice);
Jane Liu878b27d2017-08-22 10:50:06 -0400471 if (!rcClip.IsEmpty())
472 pDevice->SetClip_Rect(mtUser2Device.TransformRect(rcClip).ToFxRect());
dsinclaire35af1e2016-07-13 11:26:20 -0700473
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400474 CPWL_EditImpl_Iterator* pIterator = pEdit->GetIterator();
Lei Zhangeb14e042017-08-15 13:56:43 -0700475 IPVT_FontMap* pFontMap = pEdit->GetFontMap();
476 if (!pFontMap)
477 return;
dsinclaire35af1e2016-07-13 11:26:20 -0700478
Lei Zhangeb14e042017-08-15 13:56:43 -0700479 if (pRange)
480 pIterator->SetAt(pRange->BeginPos);
481 else
482 pIterator->SetAt(0);
dsinclaire35af1e2016-07-13 11:26:20 -0700483
Lei Zhangeb14e042017-08-15 13:56:43 -0700484 CPVT_WordPlace oldplace;
485 while (pIterator->NextWord()) {
486 CPVT_WordPlace place = pIterator->GetAt();
487 if (pRange && place > pRange->EndPos)
488 break;
dsinclaire35af1e2016-07-13 11:26:20 -0700489
Lei Zhangeb14e042017-08-15 13:56:43 -0700490 if (!wrSelect.IsEmpty()) {
491 bSelect = place > wrSelect.BeginPos && place <= wrSelect.EndPos;
492 crCurFill = bSelect ? crWhite : crTextFill;
493 }
494 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
495 crCurFill = crTextFill;
496 crOldFill = crCurFill;
497 }
498 CPVT_Word word;
499 if (pIterator->GetWord(word)) {
500 if (bSelect) {
501 CPVT_Line line;
502 pIterator->GetLine(line);
dsinclaire35af1e2016-07-13 11:26:20 -0700503
Lei Zhangeb14e042017-08-15 13:56:43 -0700504 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
505 CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
506 word.ptWord.x + word.fWidth,
507 line.ptLine.y + line.fLineAscent);
508 rc.Intersect(rcClip);
509 pSystemHandler->OutputSelectedRect(pFFLData, rc);
dsinclaire35af1e2016-07-13 11:26:20 -0700510 } else {
Lei Zhangeb14e042017-08-15 13:56:43 -0700511 CFX_PathData pathSelBK;
512 pathSelBK.AppendRect(word.ptWord.x, line.ptLine.y + line.fLineDescent,
513 word.ptWord.x + word.fWidth,
514 line.ptLine.y + line.fLineAscent);
dsinclaire35af1e2016-07-13 11:26:20 -0700515
Lei Zhangeb14e042017-08-15 13:56:43 -0700516 pDevice->DrawPath(&pathSelBK, &mtUser2Device, nullptr, crSelBK, 0,
517 FXFILL_WINDING);
518 }
519 }
520
521 if (bContinuous) {
522 if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
523 crOldFill != crCurFill) {
524 if (sTextBuf.tellp() > 0) {
525 DrawTextString(
526 pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
527 pFontMap->GetPDFFont(nFontIndex), fFontSize, mtUser2Device,
528 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
529
530 sTextBuf.str("");
531 }
532 nFontIndex = word.nFontIndex;
533 ptBT = word.ptWord;
534 crOldFill = crCurFill;
535 }
536
537 sTextBuf << pEdit->GetPDFWordString(word.nFontIndex, word.Word,
538 SubWord);
539 } else {
540 DrawTextString(
541 pDevice,
542 CFX_PointF(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y),
543 pFontMap->GetPDFFont(word.nFontIndex), fFontSize, mtUser2Device,
544 pEdit->GetPDFWordString(word.nFontIndex, word.Word, SubWord),
545 crCurFill, nHorzScale);
546 }
547 oldplace = place;
dsinclaire35af1e2016-07-13 11:26:20 -0700548 }
549 }
Lei Zhangeb14e042017-08-15 13:56:43 -0700550
551 if (sTextBuf.tellp() > 0) {
552 DrawTextString(pDevice,
553 CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
554 pFontMap->GetPDFFont(nFontIndex), fFontSize, mtUser2Device,
555 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
556 }
dsinclaire35af1e2016-07-13 11:26:20 -0700557}
558
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400559CPWL_EditImpl::CPWL_EditImpl()
Lei Zhang5688d622017-08-12 07:04:19 -0700560 : m_pVT(pdfium::MakeUnique<CPDF_VariableText>()),
tsepez4cf55152016-11-02 14:37:54 -0700561 m_bEnableScroll(false),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700562 m_nAlignment(0),
tsepez4cf55152016-11-02 14:37:54 -0700563 m_bNotifyFlag(false),
564 m_bEnableOverflow(false),
565 m_bEnableRefresh(true),
Lei Zhang5688d622017-08-12 07:04:19 -0700566 m_bEnableUndo(true) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700567
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400568CPWL_EditImpl::~CPWL_EditImpl() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700569
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400570void CPWL_EditImpl::Initialize() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700571 m_pVT->Initialize();
572 SetCaret(m_pVT->GetBeginWordPlace());
573 SetCaretOrigin();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700574}
575
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400576void CPWL_EditImpl::SetFontMap(IPVT_FontMap* pFontMap) {
577 m_pVTProvider = pdfium::MakeUnique<CPWL_EditImpl_Provider>(pFontMap);
thestig821d59e2016-05-11 12:59:22 -0700578 m_pVT->SetProvider(m_pVTProvider.get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700579}
580
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400581void CPWL_EditImpl::SetNotify(CPWL_EditCtrl* pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700582 m_pNotify = pNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700583}
584
Lei Zhang5688d622017-08-12 07:04:19 -0700585void CPWL_EditImpl::SetOperationNotify(CPWL_Edit* pOperationNotify) {
586 m_pOperationNotify = pOperationNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700587}
588
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400589CPWL_EditImpl_Iterator* CPWL_EditImpl::GetIterator() {
tsepez36eb4bd2016-10-03 15:24:27 -0700590 if (!m_pIterator) {
591 m_pIterator =
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400592 pdfium::MakeUnique<CPWL_EditImpl_Iterator>(this, m_pVT->GetIterator());
tsepez36eb4bd2016-10-03 15:24:27 -0700593 }
thestig821d59e2016-05-11 12:59:22 -0700594 return m_pIterator.get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700595}
596
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400597IPVT_FontMap* CPWL_EditImpl::GetFontMap() {
thestig821d59e2016-05-11 12:59:22 -0700598 return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700599}
600
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400601void CPWL_EditImpl::SetPlateRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700602 m_pVT->SetPlateRect(rect);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500603 m_ptScrollPos = CFX_PointF(rect.left, rect.top);
dsinclairefd5a992016-07-18 10:04:07 -0700604 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700605}
606
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400607void CPWL_EditImpl::SetAlignmentH(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700608 m_pVT->SetAlignment(nFormat);
609 if (bPaint)
610 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700611}
612
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400613void CPWL_EditImpl::SetAlignmentV(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700614 m_nAlignment = nFormat;
615 if (bPaint)
616 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700617}
618
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400619void CPWL_EditImpl::SetPasswordChar(uint16_t wSubWord, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700620 m_pVT->SetPasswordChar(wSubWord);
621 if (bPaint)
622 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700623}
624
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400625void CPWL_EditImpl::SetLimitChar(int32_t nLimitChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700626 m_pVT->SetLimitChar(nLimitChar);
dsinclairefd5a992016-07-18 10:04:07 -0700627 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700628}
629
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400630void CPWL_EditImpl::SetCharArray(int32_t nCharArray) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700631 m_pVT->SetCharArray(nCharArray);
dsinclairefd5a992016-07-18 10:04:07 -0700632 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700633}
634
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400635void CPWL_EditImpl::SetCharSpace(float fCharSpace) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700636 m_pVT->SetCharSpace(fCharSpace);
dsinclairefd5a992016-07-18 10:04:07 -0700637 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700638}
639
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400640void CPWL_EditImpl::SetMultiLine(bool bMultiLine, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700641 m_pVT->SetMultiLine(bMultiLine);
642 if (bPaint)
643 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700644}
645
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400646void CPWL_EditImpl::SetAutoReturn(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700647 m_pVT->SetAutoReturn(bAuto);
648 if (bPaint)
649 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700650}
651
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400652void CPWL_EditImpl::SetAutoFontSize(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700653 m_pVT->SetAutoFontSize(bAuto);
654 if (bPaint)
655 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700656}
657
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400658void CPWL_EditImpl::SetFontSize(float fFontSize) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700659 m_pVT->SetFontSize(fFontSize);
dsinclairefd5a992016-07-18 10:04:07 -0700660 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700661}
662
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400663void CPWL_EditImpl::SetAutoScroll(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700664 m_bEnableScroll = bAuto;
665 if (bPaint)
666 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700667}
668
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400669void CPWL_EditImpl::SetTextOverflow(bool bAllowed, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700670 m_bEnableOverflow = bAllowed;
671 if (bPaint)
672 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700673}
674
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400675void CPWL_EditImpl::SetSelection(int32_t nStartChar, int32_t nEndChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700676 if (m_pVT->IsValid()) {
677 if (nStartChar == 0 && nEndChar < 0) {
678 SelectAll();
679 } else if (nStartChar < 0) {
680 SelectNone();
681 } else {
682 if (nStartChar < nEndChar) {
Diana Gage4d02e902017-07-20 17:20:31 -0700683 SetSelection(m_pVT->WordIndexToWordPlace(nStartChar),
684 m_pVT->WordIndexToWordPlace(nEndChar));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700685 } else {
Diana Gage4d02e902017-07-20 17:20:31 -0700686 SetSelection(m_pVT->WordIndexToWordPlace(nEndChar),
687 m_pVT->WordIndexToWordPlace(nStartChar));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700688 }
689 }
690 }
691}
692
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400693void CPWL_EditImpl::SetSelection(const CPVT_WordPlace& begin,
694 const CPVT_WordPlace& end) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700695 if (!m_pVT->IsValid())
696 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700697
Tom Sepez52f69b32017-03-21 13:42:38 -0700698 SelectNone();
699 m_SelState.Set(begin, end);
700 SetCaret(m_SelState.EndPos);
701 ScrollToCaret();
702 if (!m_SelState.IsEmpty())
703 Refresh();
704 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700705}
706
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400707void CPWL_EditImpl::GetSelection(int32_t& nStartChar, int32_t& nEndChar) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700708 nStartChar = -1;
709 nEndChar = -1;
Tom Sepez52f69b32017-03-21 13:42:38 -0700710 if (!m_pVT->IsValid())
711 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700712
Tom Sepez52f69b32017-03-21 13:42:38 -0700713 if (m_SelState.IsEmpty()) {
714 nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
715 nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
716 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700717 }
Tom Sepez52f69b32017-03-21 13:42:38 -0700718 if (m_SelState.BeginPos < m_SelState.EndPos) {
719 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
720 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
721 return;
722 }
723 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
724 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700725}
726
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400727int32_t CPWL_EditImpl::GetCaret() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700728 if (m_pVT->IsValid())
729 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
730
731 return -1;
732}
733
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400734CPVT_WordPlace CPWL_EditImpl::GetCaretWordPlace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700735 return m_wpCaret;
736}
737
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400738CFX_WideString CPWL_EditImpl::GetText() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700739 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700740 if (!m_pVT->IsValid())
741 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700742
thestig821d59e2016-05-11 12:59:22 -0700743 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
744 pIterator->SetAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700745
thestig821d59e2016-05-11 12:59:22 -0700746 CPVT_Word wordinfo;
747 CPVT_WordPlace oldplace = pIterator->GetAt();
748 while (pIterator->NextWord()) {
749 CPVT_WordPlace place = pIterator->GetAt();
thestig821d59e2016-05-11 12:59:22 -0700750 if (pIterator->GetWord(wordinfo))
751 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700752 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700753 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700754 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700755 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700756 return swRet;
757}
758
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400759CFX_WideString CPWL_EditImpl::GetRangeText(const CPVT_WordRange& range) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700760 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700761 if (!m_pVT->IsValid())
762 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700763
thestig821d59e2016-05-11 12:59:22 -0700764 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
765 CPVT_WordRange wrTemp = range;
766 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
767 m_pVT->UpdateWordPlace(wrTemp.EndPos);
768 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700769
thestig821d59e2016-05-11 12:59:22 -0700770 CPVT_Word wordinfo;
771 CPVT_WordPlace oldplace = wrTemp.BeginPos;
772 while (pIterator->NextWord()) {
773 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700774 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -0700775 break;
thestig821d59e2016-05-11 12:59:22 -0700776 if (pIterator->GetWord(wordinfo))
777 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700778 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700779 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700780 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700781 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700782 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700783}
784
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400785CFX_WideString CPWL_EditImpl::GetSelectedText() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700786 return GetRangeText(m_SelState.ConvertToWordRange());
787}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700788
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400789int32_t CPWL_EditImpl::GetTotalLines() const {
thestig821d59e2016-05-11 12:59:22 -0700790 int32_t nLines = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700791
thestig821d59e2016-05-11 12:59:22 -0700792 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
793 pIterator->SetAt(0);
794 while (pIterator->NextLine())
795 ++nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700796
thestig821d59e2016-05-11 12:59:22 -0700797 return nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700798}
799
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400800CPVT_WordRange CPWL_EditImpl::GetSelectWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700801 return m_SelState.ConvertToWordRange();
802}
803
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400804void CPWL_EditImpl::SetText(const CFX_WideString& sText) {
dsinclairefd5a992016-07-18 10:04:07 -0700805 Empty();
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400806 DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_CHARSET_Default);
dsinclairefd5a992016-07-18 10:04:07 -0700807 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700808}
809
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400810bool CPWL_EditImpl::InsertWord(uint16_t word, int32_t charset) {
tsepez4cf55152016-11-02 14:37:54 -0700811 return InsertWord(word, charset, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700812}
813
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400814bool CPWL_EditImpl::InsertReturn() {
tsepez4cf55152016-11-02 14:37:54 -0700815 return InsertReturn(nullptr, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700816}
817
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400818bool CPWL_EditImpl::Backspace() {
tsepez4cf55152016-11-02 14:37:54 -0700819 return Backspace(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700820}
821
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400822bool CPWL_EditImpl::Delete() {
tsepez4cf55152016-11-02 14:37:54 -0700823 return Delete(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700824}
825
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400826bool CPWL_EditImpl::ClearSelection() {
tsepez4cf55152016-11-02 14:37:54 -0700827 return Clear(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700828}
829
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400830bool CPWL_EditImpl::InsertText(const CFX_WideString& sText, int32_t charset) {
tsepez4cf55152016-11-02 14:37:54 -0700831 return InsertText(sText, charset, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700832}
833
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400834float CPWL_EditImpl::GetFontSize() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700835 return m_pVT->GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700836}
837
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400838uint16_t CPWL_EditImpl::GetPasswordChar() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700839 return m_pVT->GetPasswordChar();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700840}
841
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400842int32_t CPWL_EditImpl::GetCharArray() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700843 return m_pVT->GetCharArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700844}
845
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400846CFX_FloatRect CPWL_EditImpl::GetContentRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700847 return VTToEdit(m_pVT->GetContentRect());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700848}
849
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400850int32_t CPWL_EditImpl::GetHorzScale() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700851 return m_pVT->GetHorzScale();
852}
853
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400854float CPWL_EditImpl::GetCharSpace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700855 return m_pVT->GetCharSpace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700856}
857
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400858CPVT_WordRange CPWL_EditImpl::GetWholeWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700859 if (m_pVT->IsValid())
860 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700861
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700862 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700863}
864
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400865CPVT_WordRange CPWL_EditImpl::GetVisibleWordRange() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700866 if (m_bEnableOverflow)
867 return GetWholeWordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700868
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700869 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800870 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700871
Dan Sinclairf528eee2017-02-14 11:52:07 -0500872 CPVT_WordPlace place1 =
873 m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700874 CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500875 EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700876
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700877 return CPVT_WordRange(place1, place2);
878 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700879
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700880 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700881}
882
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400883CPVT_WordPlace CPWL_EditImpl::SearchWordPlace(const CFX_PointF& point) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700884 if (m_pVT->IsValid()) {
885 return m_pVT->SearchWordPlace(EditToVT(point));
886 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700887
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700888 return CPVT_WordPlace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700889}
890
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400891void CPWL_EditImpl::Paint() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700892 if (m_pVT->IsValid()) {
893 RearrangeAll();
894 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -0700895 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700896 SetCaretOrigin();
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700897 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700898 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700899}
900
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400901void CPWL_EditImpl::RearrangeAll() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700902 if (m_pVT->IsValid()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700903 m_pVT->UpdateWordPlace(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700904 m_pVT->RearrangeAll();
905 m_pVT->UpdateWordPlace(m_wpCaret);
906 SetScrollInfo();
907 SetContentChanged();
908 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700909}
910
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400911void CPWL_EditImpl::RearrangePart(const CPVT_WordRange& range) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700912 if (m_pVT->IsValid()) {
913 m_pVT->UpdateWordPlace(m_wpCaret);
914 m_pVT->RearrangePart(range);
915 m_pVT->UpdateWordPlace(m_wpCaret);
916 SetScrollInfo();
917 SetContentChanged();
918 }
919}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700920
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400921void CPWL_EditImpl::SetContentChanged() {
dsinclaira2919b32016-07-13 10:55:48 -0700922 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800923 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700924 if (rcContent.Width() != m_rcOldContent.Width() ||
925 rcContent.Height() != m_rcOldContent.Height()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700926 m_rcOldContent = rcContent;
927 }
928 }
929}
930
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400931void CPWL_EditImpl::SelectAll() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700932 if (!m_pVT->IsValid())
933 return;
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400934 m_SelState = CPWL_EditImpl_Select(GetWholeWordRange());
Tom Sepez52f69b32017-03-21 13:42:38 -0700935 SetCaret(m_SelState.EndPos);
936 ScrollToCaret();
937 Refresh();
938 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700939}
940
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400941void CPWL_EditImpl::SelectNone() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700942 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
943 return;
944
945 m_SelState.Reset();
946 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700947}
948
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400949bool CPWL_EditImpl::IsSelected() const {
Tom Sepez52f69b32017-03-21 13:42:38 -0700950 return !m_SelState.IsEmpty();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700951}
952
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400953CFX_PointF CPWL_EditImpl::VTToEdit(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800954 CFX_FloatRect rcContent = m_pVT->GetContentRect();
955 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700956
Dan Sinclair05df0752017-03-14 14:43:42 -0400957 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700958
959 switch (m_nAlignment) {
960 case 0:
961 fPadding = 0.0f;
962 break;
963 case 1:
964 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
965 break;
966 case 2:
967 fPadding = rcPlate.Height() - rcContent.Height();
968 break;
969 }
970
Dan Sinclairf528eee2017-02-14 11:52:07 -0500971 return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
972 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700973}
974
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400975CFX_PointF CPWL_EditImpl::EditToVT(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800976 CFX_FloatRect rcContent = m_pVT->GetContentRect();
977 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700978
Dan Sinclair05df0752017-03-14 14:43:42 -0400979 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700980
981 switch (m_nAlignment) {
982 case 0:
983 fPadding = 0.0f;
984 break;
985 case 1:
986 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
987 break;
988 case 2:
989 fPadding = rcPlate.Height() - rcContent.Height();
990 break;
991 }
992
Dan Sinclairf528eee2017-02-14 11:52:07 -0500993 return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
994 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700995}
996
Dan Sinclair6b0158f2017-07-24 09:42:55 -0400997CFX_FloatRect CPWL_EditImpl::VTToEdit(const CFX_FloatRect& rect) const {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500998 CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
999 CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001000
Tom Sepez281a9ea2016-02-26 14:24:28 -08001001 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1002 ptRightTop.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001003}
1004
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001005void CPWL_EditImpl::SetScrollInfo() {
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001006 if (!m_pNotify)
1007 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001008
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001009 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1010 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1011 if (m_bNotifyFlag)
1012 return;
1013
1014 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
1015 m_bNotifyFlag = true;
1016
1017 PWL_SCROLL_INFO Info;
1018 Info.fPlateWidth = rcPlate.top - rcPlate.bottom;
1019 Info.fContentMin = rcContent.bottom;
1020 Info.fContentMax = rcContent.top;
1021 Info.fSmallStep = rcPlate.Height() / 3;
1022 Info.fBigStep = rcPlate.Height();
1023 m_pNotify->SetScrollInfo(Info);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001024}
1025
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001026void CPWL_EditImpl::SetScrollPosX(float fx) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001027 if (!m_bEnableScroll)
1028 return;
1029
1030 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001031 if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001032 m_ptScrollPos.x = fx;
dsinclairefd5a992016-07-18 10:04:07 -07001033 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001034 }
1035 }
1036}
1037
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001038void CPWL_EditImpl::SetScrollPosY(float fy) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001039 if (!m_bEnableScroll)
1040 return;
1041
1042 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001043 if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001044 m_ptScrollPos.y = fy;
dsinclairefd5a992016-07-18 10:04:07 -07001045 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001046
dsinclaira2919b32016-07-13 10:55:48 -07001047 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001048 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001049 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001050 m_bNotifyFlag = true;
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001051 m_pNotify->SetScrollPosition(fy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001052 }
1053 }
1054 }
1055 }
1056}
1057
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001058void CPWL_EditImpl::SetScrollPos(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001059 SetScrollPosX(point.x);
1060 SetScrollPosY(point.y);
1061 SetScrollLimit();
1062 SetCaretInfo();
1063}
1064
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001065CFX_PointF CPWL_EditImpl::GetScrollPos() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001066 return m_ptScrollPos;
1067}
1068
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001069void CPWL_EditImpl::SetScrollLimit() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001070 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001071 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1072 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001073
1074 if (rcPlate.Width() > rcContent.Width()) {
1075 SetScrollPosX(rcPlate.left);
1076 } else {
dsinclair448c4332016-08-02 12:07:35 -07001077 if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001078 SetScrollPosX(rcContent.left);
dsinclair448c4332016-08-02 12:07:35 -07001079 } else if (IsFloatBigger(m_ptScrollPos.x,
1080 rcContent.right - rcPlate.Width())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001081 SetScrollPosX(rcContent.right - rcPlate.Width());
1082 }
1083 }
1084
1085 if (rcPlate.Height() > rcContent.Height()) {
1086 SetScrollPosY(rcPlate.top);
1087 } else {
dsinclair448c4332016-08-02 12:07:35 -07001088 if (IsFloatSmaller(m_ptScrollPos.y,
1089 rcContent.bottom + rcPlate.Height())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001090 SetScrollPosY(rcContent.bottom + rcPlate.Height());
dsinclair448c4332016-08-02 12:07:35 -07001091 } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001092 SetScrollPosY(rcContent.top);
1093 }
1094 }
1095 }
1096}
1097
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001098void CPWL_EditImpl::ScrollToCaret() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001099 SetScrollLimit();
1100
thestig821d59e2016-05-11 12:59:22 -07001101 if (!m_pVT->IsValid())
1102 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001103
thestig821d59e2016-05-11 12:59:22 -07001104 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1105 pIterator->SetAt(m_wpCaret);
1106
Dan Sinclairf528eee2017-02-14 11:52:07 -05001107 CFX_PointF ptHead;
1108 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001109 CPVT_Word word;
1110 CPVT_Line line;
1111 if (pIterator->GetWord(word)) {
1112 ptHead.x = word.ptWord.x + word.fWidth;
1113 ptHead.y = word.ptWord.y + word.fAscent;
1114 ptFoot.x = word.ptWord.x + word.fWidth;
1115 ptFoot.y = word.ptWord.y + word.fDescent;
1116 } else if (pIterator->GetLine(line)) {
1117 ptHead.x = line.ptLine.x;
1118 ptHead.y = line.ptLine.y + line.fLineAscent;
1119 ptFoot.x = line.ptLine.x;
1120 ptFoot.y = line.ptLine.y + line.fLineDescent;
1121 }
1122
Dan Sinclairf528eee2017-02-14 11:52:07 -05001123 CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1124 CFX_PointF ptFootEdit = VTToEdit(ptFoot);
thestig821d59e2016-05-11 12:59:22 -07001125 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
dsinclair448c4332016-08-02 12:07:35 -07001126 if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
1127 if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
1128 IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
thestig821d59e2016-05-11 12:59:22 -07001129 SetScrollPosX(ptHead.x);
dsinclair448c4332016-08-02 12:07:35 -07001130 } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
thestig821d59e2016-05-11 12:59:22 -07001131 SetScrollPosX(ptHead.x - rcPlate.Width());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001132 }
thestig821d59e2016-05-11 12:59:22 -07001133 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001134
dsinclair448c4332016-08-02 12:07:35 -07001135 if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
1136 if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
1137 IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
1138 if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
thestig821d59e2016-05-11 12:59:22 -07001139 SetScrollPosY(ptFoot.y + rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001140 }
dsinclair448c4332016-08-02 12:07:35 -07001141 } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
1142 if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
thestig821d59e2016-05-11 12:59:22 -07001143 SetScrollPosY(ptHead.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001144 }
1145 }
1146 }
1147}
1148
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001149void CPWL_EditImpl::Refresh() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001150 if (m_bEnableRefresh && m_pVT->IsValid()) {
1151 m_Refresh.BeginRefresh();
1152 RefreshPushLineRects(GetVisibleWordRange());
1153
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001154 m_Refresh.NoAnalyse();
1155 m_ptRefreshScrollPos = m_ptScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001156
dsinclaira2919b32016-07-13 10:55:48 -07001157 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001158 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001159 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001160 m_bNotifyFlag = true;
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001161 if (const CPWL_EditImpl_RectArray* pRects =
1162 m_Refresh.GetRefreshRects()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001163 for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001164 m_pNotify->InvalidateRect(pRects->GetAt(i));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001165 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001166 }
1167 }
1168
1169 m_Refresh.EndRefresh();
1170 }
1171}
1172
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001173void CPWL_EditImpl::RefreshPushLineRects(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001174 if (!m_pVT->IsValid())
1175 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001176
thestig821d59e2016-05-11 12:59:22 -07001177 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1178 CPVT_WordPlace wpBegin = wr.BeginPos;
1179 m_pVT->UpdateWordPlace(wpBegin);
1180 CPVT_WordPlace wpEnd = wr.EndPos;
1181 m_pVT->UpdateWordPlace(wpEnd);
1182 pIterator->SetAt(wpBegin);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001183
thestig821d59e2016-05-11 12:59:22 -07001184 CPVT_Line lineinfo;
1185 do {
1186 if (!pIterator->GetLine(lineinfo))
1187 break;
1188 if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
1189 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001190
thestig821d59e2016-05-11 12:59:22 -07001191 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1192 lineinfo.ptLine.y + lineinfo.fLineDescent,
1193 lineinfo.ptLine.x + lineinfo.fLineWidth,
1194 lineinfo.ptLine.y + lineinfo.fLineAscent);
1195
1196 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1197 VTToEdit(rcLine));
1198 } while (pIterator->NextLine());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001199}
1200
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001201void CPWL_EditImpl::RefreshWordRange(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001202 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1203 CPVT_WordRange wrTemp = wr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001204
thestig821d59e2016-05-11 12:59:22 -07001205 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1206 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1207 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001208
thestig821d59e2016-05-11 12:59:22 -07001209 CPVT_Word wordinfo;
1210 CPVT_Line lineinfo;
1211 CPVT_WordPlace place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001212
thestig821d59e2016-05-11 12:59:22 -07001213 while (pIterator->NextWord()) {
1214 place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -07001215 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -07001216 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001217
thestig821d59e2016-05-11 12:59:22 -07001218 pIterator->GetWord(wordinfo);
1219 pIterator->GetLine(lineinfo);
thestig821d59e2016-05-11 12:59:22 -07001220 if (place.LineCmp(wrTemp.BeginPos) == 0 ||
1221 place.LineCmp(wrTemp.EndPos) == 0) {
1222 CFX_FloatRect rcWord(wordinfo.ptWord.x,
1223 lineinfo.ptLine.y + lineinfo.fLineDescent,
1224 wordinfo.ptWord.x + wordinfo.fWidth,
1225 lineinfo.ptLine.y + lineinfo.fLineAscent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001226
dsinclaira2919b32016-07-13 10:55:48 -07001227 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001228 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001229 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001230 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001231 CFX_FloatRect rcRefresh = VTToEdit(rcWord);
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001232 m_pNotify->InvalidateRect(&rcRefresh);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001233 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001234 }
thestig821d59e2016-05-11 12:59:22 -07001235 } else {
1236 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1237 lineinfo.ptLine.y + lineinfo.fLineDescent,
1238 lineinfo.ptLine.x + lineinfo.fLineWidth,
1239 lineinfo.ptLine.y + lineinfo.fLineAscent);
1240
dsinclaira2919b32016-07-13 10:55:48 -07001241 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001242 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001243 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001244 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001245 CFX_FloatRect rcRefresh = VTToEdit(rcLine);
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001246 m_pNotify->InvalidateRect(&rcRefresh);
thestig821d59e2016-05-11 12:59:22 -07001247 }
1248 }
1249
1250 pIterator->NextLine();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001251 }
1252 }
1253}
1254
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001255void CPWL_EditImpl::SetCaret(const CPVT_WordPlace& place) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001256 m_wpOldCaret = m_wpCaret;
1257 m_wpCaret = place;
1258}
1259
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001260void CPWL_EditImpl::SetCaretInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001261 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001262 if (!m_bNotifyFlag) {
thestig821d59e2016-05-11 12:59:22 -07001263 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1264 pIterator->SetAt(m_wpCaret);
tsepez63f545c2016-09-13 16:08:49 -07001265
Dan Sinclairf528eee2017-02-14 11:52:07 -05001266 CFX_PointF ptHead;
1267 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001268 CPVT_Word word;
1269 CPVT_Line line;
1270 if (pIterator->GetWord(word)) {
1271 ptHead.x = word.ptWord.x + word.fWidth;
1272 ptHead.y = word.ptWord.y + word.fAscent;
1273 ptFoot.x = word.ptWord.x + word.fWidth;
1274 ptFoot.y = word.ptWord.y + word.fDescent;
1275 } else if (pIterator->GetLine(line)) {
1276 ptHead.x = line.ptLine.x;
1277 ptHead.y = line.ptLine.y + line.fLineAscent;
1278 ptFoot.x = line.ptLine.x;
1279 ptFoot.y = line.ptLine.y + line.fLineDescent;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001280 }
1281
Lei Zhanga8c2b912017-03-22 17:41:02 -07001282 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001283 m_bNotifyFlag = true;
Dan Sinclair0fdd1ae2017-07-05 16:00:48 -04001284 m_pNotify->SetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead),
1285 VTToEdit(ptFoot));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001286 }
1287 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001288}
1289
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001290void CPWL_EditImpl::OnMouseDown(const CFX_PointF& point,
1291 bool bShift,
1292 bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001293 if (!m_pVT->IsValid())
1294 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001295
Tom Sepez52f69b32017-03-21 13:42:38 -07001296 SelectNone();
1297 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1298 m_SelState.Set(m_wpCaret, m_wpCaret);
1299 ScrollToCaret();
1300 SetCaretOrigin();
1301 SetCaretInfo();
1302}
1303
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001304void CPWL_EditImpl::OnMouseMove(const CFX_PointF& point,
1305 bool bShift,
1306 bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001307 if (!m_pVT->IsValid())
1308 return;
1309
1310 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1311 if (m_wpCaret == m_wpOldCaret)
1312 return;
1313
1314 m_SelState.SetEndPos(m_wpCaret);
1315 ScrollToCaret();
1316 Refresh();
1317 SetCaretOrigin();
1318 SetCaretInfo();
1319}
1320
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001321void CPWL_EditImpl::OnVK_UP(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001322 if (!m_pVT->IsValid())
1323 return;
1324
1325 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1326 if (bShift) {
1327 if (m_SelState.IsEmpty())
1328 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1329 else
1330 m_SelState.SetEndPos(m_wpCaret);
1331
1332 if (m_wpOldCaret != m_wpCaret) {
1333 ScrollToCaret();
1334 Refresh();
1335 SetCaretInfo();
1336 }
1337 } else {
1338 SelectNone();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001339 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001340 SetCaretInfo();
1341 }
1342}
1343
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001344void CPWL_EditImpl::OnVK_DOWN(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001345 if (!m_pVT->IsValid())
1346 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001347
Tom Sepez52f69b32017-03-21 13:42:38 -07001348 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1349 if (bShift) {
1350 if (m_SelState.IsEmpty())
1351 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1352 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001353 m_SelState.SetEndPos(m_wpCaret);
1354
Tom Sepez52f69b32017-03-21 13:42:38 -07001355 if (m_wpOldCaret != m_wpCaret) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001356 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001357 Refresh();
Tom Sepez52f69b32017-03-21 13:42:38 -07001358 SetCaretInfo();
1359 }
1360 } else {
1361 SelectNone();
1362 ScrollToCaret();
1363 SetCaretInfo();
1364 }
1365}
1366
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001367void CPWL_EditImpl::OnVK_LEFT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001368 if (!m_pVT->IsValid())
1369 return;
1370
1371 if (bShift) {
1372 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1373 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1374 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1375 }
1376 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1377 if (m_SelState.IsEmpty())
1378 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1379 else
1380 m_SelState.SetEndPos(m_wpCaret);
1381
1382 if (m_wpOldCaret != m_wpCaret) {
1383 ScrollToCaret();
1384 Refresh();
1385 SetCaretInfo();
1386 }
1387 } else {
1388 if (!m_SelState.IsEmpty()) {
1389 if (m_SelState.BeginPos < m_SelState.EndPos)
1390 SetCaret(m_SelState.BeginPos);
1391 else
1392 SetCaret(m_SelState.EndPos);
1393
1394 SelectNone();
1395 ScrollToCaret();
1396 SetCaretInfo();
1397 } else {
1398 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1399 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1400 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1401 }
1402 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1403 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001404 SetCaretOrigin();
1405 SetCaretInfo();
1406 }
1407 }
1408}
1409
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001410void CPWL_EditImpl::OnVK_RIGHT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001411 if (!m_pVT->IsValid())
1412 return;
1413
1414 if (bShift) {
1415 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1416 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1417 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001418 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1419
Tom Sepez52f69b32017-03-21 13:42:38 -07001420 if (m_SelState.IsEmpty())
1421 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1422 else
1423 m_SelState.SetEndPos(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001424
Tom Sepez52f69b32017-03-21 13:42:38 -07001425 if (m_wpOldCaret != m_wpCaret) {
1426 ScrollToCaret();
1427 Refresh();
1428 SetCaretInfo();
1429 }
1430 } else {
1431 if (!m_SelState.IsEmpty()) {
1432 if (m_SelState.BeginPos > m_SelState.EndPos)
1433 SetCaret(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001434 else
Tom Sepez52f69b32017-03-21 13:42:38 -07001435 SetCaret(m_SelState.EndPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001436
Tom Sepez52f69b32017-03-21 13:42:38 -07001437 SelectNone();
1438 ScrollToCaret();
1439 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001440 } else {
Tom Sepez52f69b32017-03-21 13:42:38 -07001441 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1442 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1443 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001444 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001445 }
Tom Sepez52f69b32017-03-21 13:42:38 -07001446 ScrollToCaret();
1447 SetCaretOrigin();
1448 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001449 }
1450 }
1451}
1452
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001453void CPWL_EditImpl::OnVK_HOME(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001454 if (!m_pVT->IsValid())
1455 return;
1456
1457 if (bShift) {
1458 if (bCtrl)
1459 SetCaret(m_pVT->GetBeginWordPlace());
1460 else
1461 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1462
1463 if (m_SelState.IsEmpty())
1464 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1465 else
1466 m_SelState.SetEndPos(m_wpCaret);
1467
1468 ScrollToCaret();
1469 Refresh();
1470 SetCaretInfo();
1471 } else {
1472 if (!m_SelState.IsEmpty()) {
1473 SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos));
1474 SelectNone();
1475 ScrollToCaret();
1476 SetCaretInfo();
1477 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001478 if (bCtrl)
1479 SetCaret(m_pVT->GetBeginWordPlace());
1480 else
1481 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1482
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001483 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001484 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001485 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001486 }
1487 }
1488}
1489
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001490void CPWL_EditImpl::OnVK_END(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001491 if (!m_pVT->IsValid())
1492 return;
1493
1494 if (bShift) {
1495 if (bCtrl)
1496 SetCaret(m_pVT->GetEndWordPlace());
1497 else
1498 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1499
1500 if (m_SelState.IsEmpty())
1501 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1502 else
1503 m_SelState.SetEndPos(m_wpCaret);
1504
1505 ScrollToCaret();
1506 Refresh();
1507 SetCaretInfo();
1508 } else {
1509 if (!m_SelState.IsEmpty()) {
1510 SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos));
1511 SelectNone();
1512 ScrollToCaret();
1513 SetCaretInfo();
1514 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001515 if (bCtrl)
1516 SetCaret(m_pVT->GetEndWordPlace());
1517 else
1518 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1519
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001520 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001521 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001522 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001523 }
1524 }
1525}
1526
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001527bool CPWL_EditImpl::InsertWord(uint16_t word,
1528 int32_t charset,
1529 const CPVT_WordProps* pWordProps,
1530 bool bAddUndo,
1531 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001532 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001533 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001534
Tom Sepez3509d162017-01-30 13:22:02 -08001535 m_pVT->UpdateWordPlace(m_wpCaret);
1536 SetCaret(m_pVT->InsertWord(m_wpCaret, word,
1537 GetCharSetFromUnicode(word, charset), pWordProps));
1538 m_SelState.Set(m_wpCaret, m_wpCaret);
1539 if (m_wpCaret == m_wpOldCaret)
1540 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001541
Tom Sepez3509d162017-01-30 13:22:02 -08001542 if (bAddUndo && m_bEnableUndo) {
1543 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertWord>(
1544 this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001545 }
Tom Sepez3509d162017-01-30 13:22:02 -08001546 if (bPaint)
1547 PaintInsertText(m_wpOldCaret, m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001548
Lei Zhang5688d622017-08-12 07:04:19 -07001549 if (m_pOperationNotify)
1550 m_pOperationNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
Tom Sepez3509d162017-01-30 13:22:02 -08001551
1552 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001553}
1554
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001555bool CPWL_EditImpl::InsertReturn(const CPVT_SecProps* pSecProps,
1556 const CPVT_WordProps* pWordProps,
1557 bool bAddUndo,
1558 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001559 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001560 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001561
Tom Sepez3509d162017-01-30 13:22:02 -08001562 m_pVT->UpdateWordPlace(m_wpCaret);
1563 SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
1564 m_SelState.Set(m_wpCaret, m_wpCaret);
1565 if (m_wpCaret == m_wpOldCaret)
1566 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001567
Tom Sepez3509d162017-01-30 13:22:02 -08001568 if (bAddUndo && m_bEnableUndo) {
1569 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertReturn>(
1570 this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001571 }
Tom Sepez3509d162017-01-30 13:22:02 -08001572 if (bPaint) {
1573 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1574 ScrollToCaret();
1575 Refresh();
1576 SetCaretOrigin();
1577 SetCaretInfo();
1578 }
Lei Zhang5688d622017-08-12 07:04:19 -07001579 if (m_pOperationNotify)
1580 m_pOperationNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001581
Tom Sepez3509d162017-01-30 13:22:02 -08001582 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001583}
1584
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001585bool CPWL_EditImpl::Backspace(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001586 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1587 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001588
Tom Sepez3509d162017-01-30 13:22:02 -08001589 CPVT_Section section;
1590 CPVT_Word word;
1591 if (bAddUndo) {
1592 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1593 pIterator->SetAt(m_wpCaret);
1594 pIterator->GetSection(section);
1595 pIterator->GetWord(word);
1596 }
1597 m_pVT->UpdateWordPlace(m_wpCaret);
1598 SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1599 m_SelState.Set(m_wpCaret, m_wpCaret);
1600 if (m_wpCaret == m_wpOldCaret)
1601 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001602
Tom Sepez3509d162017-01-30 13:22:02 -08001603 if (bAddUndo && m_bEnableUndo) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001604 if (m_wpCaret.nSecIndex != m_wpOldCaret.nSecIndex) {
Tom Sepez3509d162017-01-30 13:22:02 -08001605 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1606 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1607 section.SecProps, section.WordProps));
1608 } else {
1609 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1610 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1611 section.SecProps, word.WordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001612 }
1613 }
Tom Sepez3509d162017-01-30 13:22:02 -08001614 if (bPaint) {
1615 RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
1616 ScrollToCaret();
1617 Refresh();
1618 SetCaretOrigin();
1619 SetCaretInfo();
1620 }
Lei Zhang5688d622017-08-12 07:04:19 -07001621 if (m_pOperationNotify)
1622 m_pOperationNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001623
Tom Sepez3509d162017-01-30 13:22:02 -08001624 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001625}
1626
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001627bool CPWL_EditImpl::Delete(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001628 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1629 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001630
Tom Sepez3509d162017-01-30 13:22:02 -08001631 CPVT_Section section;
1632 CPVT_Word word;
1633 if (bAddUndo) {
1634 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1635 pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1636 pIterator->GetSection(section);
1637 pIterator->GetWord(word);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001638 }
Tom Sepez3509d162017-01-30 13:22:02 -08001639 m_pVT->UpdateWordPlace(m_wpCaret);
1640 bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1641 SetCaret(m_pVT->DeleteWord(m_wpCaret));
1642 m_SelState.Set(m_wpCaret, m_wpCaret);
1643 if (bAddUndo && m_bEnableUndo) {
1644 if (bSecEnd) {
1645 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1646 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1647 section.SecProps, section.WordProps, bSecEnd));
1648 } else {
1649 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1650 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1651 section.SecProps, word.WordProps, bSecEnd));
1652 }
1653 }
1654 if (bPaint) {
1655 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1656 ScrollToCaret();
1657 Refresh();
1658 SetCaretOrigin();
1659 SetCaretInfo();
1660 }
Lei Zhang5688d622017-08-12 07:04:19 -07001661 if (m_pOperationNotify)
1662 m_pOperationNotify->OnDelete(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001663
Tom Sepez3509d162017-01-30 13:22:02 -08001664 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001665}
1666
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001667bool CPWL_EditImpl::Empty() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001668 if (m_pVT->IsValid()) {
1669 m_pVT->DeleteWords(GetWholeWordRange());
1670 SetCaret(m_pVT->GetBeginWordPlace());
1671
tsepez4cf55152016-11-02 14:37:54 -07001672 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001673 }
1674
tsepez4cf55152016-11-02 14:37:54 -07001675 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001676}
1677
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001678bool CPWL_EditImpl::Clear(bool bAddUndo, bool bPaint) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001679 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
tsepez4cf55152016-11-02 14:37:54 -07001680 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001681
thestig821d59e2016-05-11 12:59:22 -07001682 CPVT_WordRange range = m_SelState.ConvertToWordRange();
Diana Gage22bf7a52017-07-21 11:33:18 -07001683 if (bAddUndo && m_bEnableUndo) {
Diana Gage89e65622017-07-20 18:09:31 -07001684 AddEditUndoItem(
1685 pdfium::MakeUnique<CFXEU_Clear>(this, range, GetSelectedText()));
Diana Gage22bf7a52017-07-21 11:33:18 -07001686 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001687
thestig821d59e2016-05-11 12:59:22 -07001688 SelectNone();
1689 SetCaret(m_pVT->DeleteWords(range));
1690 m_SelState.Set(m_wpCaret, m_wpCaret);
thestig821d59e2016-05-11 12:59:22 -07001691 if (bPaint) {
1692 RearrangePart(range);
1693 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001694 Refresh();
thestig821d59e2016-05-11 12:59:22 -07001695 SetCaretOrigin();
1696 SetCaretInfo();
1697 }
Lei Zhang5688d622017-08-12 07:04:19 -07001698 if (m_pOperationNotify)
1699 m_pOperationNotify->OnClear(m_wpCaret, m_wpOldCaret);
thestig821d59e2016-05-11 12:59:22 -07001700
tsepez4cf55152016-11-02 14:37:54 -07001701 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001702}
1703
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001704bool CPWL_EditImpl::InsertText(const CFX_WideString& sText,
1705 int32_t charset,
1706 bool bAddUndo,
1707 bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001708 if (IsTextOverflow())
tsepez4cf55152016-11-02 14:37:54 -07001709 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001710
1711 m_pVT->UpdateWordPlace(m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001712 SetCaret(DoInsertText(m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001713 m_SelState.Set(m_wpCaret, m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001714 if (m_wpCaret == m_wpOldCaret)
tsepez4cf55152016-11-02 14:37:54 -07001715 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001716
tsepeza31da742016-09-08 11:28:14 -07001717 if (bAddUndo && m_bEnableUndo) {
Tom Sepez3509d162017-01-30 13:22:02 -08001718 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertText>(
1719 this, m_wpOldCaret, m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001720 }
tsepeza31da742016-09-08 11:28:14 -07001721 if (bPaint)
1722 PaintInsertText(m_wpOldCaret, m_wpCaret);
1723
Lei Zhang5688d622017-08-12 07:04:19 -07001724 if (m_pOperationNotify)
1725 m_pOperationNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
tsepeza31da742016-09-08 11:28:14 -07001726
tsepez4cf55152016-11-02 14:37:54 -07001727 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001728}
1729
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001730void CPWL_EditImpl::PaintInsertText(const CPVT_WordPlace& wpOld,
1731 const CPVT_WordPlace& wpNew) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001732 if (m_pVT->IsValid()) {
1733 RearrangePart(CPVT_WordRange(wpOld, wpNew));
1734 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001735 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001736 SetCaretOrigin();
1737 SetCaretInfo();
1738 }
1739}
1740
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001741bool CPWL_EditImpl::Redo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001742 if (m_bEnableUndo) {
1743 if (m_Undo.CanRedo()) {
1744 m_Undo.Redo();
tsepez4cf55152016-11-02 14:37:54 -07001745 return true;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001746 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001747 }
1748
tsepez4cf55152016-11-02 14:37:54 -07001749 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001750}
1751
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001752bool CPWL_EditImpl::Undo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001753 if (m_bEnableUndo) {
1754 if (m_Undo.CanUndo()) {
1755 m_Undo.Undo();
tsepez4cf55152016-11-02 14:37:54 -07001756 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001757 }
1758 }
1759
tsepez4cf55152016-11-02 14:37:54 -07001760 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001761}
1762
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001763void CPWL_EditImpl::SetCaretOrigin() {
thestig821d59e2016-05-11 12:59:22 -07001764 if (!m_pVT->IsValid())
1765 return;
1766
1767 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1768 pIterator->SetAt(m_wpCaret);
1769 CPVT_Word word;
1770 CPVT_Line line;
1771 if (pIterator->GetWord(word)) {
1772 m_ptCaret.x = word.ptWord.x + word.fWidth;
1773 m_ptCaret.y = word.ptWord.y;
1774 } else if (pIterator->GetLine(line)) {
1775 m_ptCaret.x = line.ptLine.x;
1776 m_ptCaret.y = line.ptLine.y;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001777 }
1778}
1779
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001780CPVT_WordPlace CPWL_EditImpl::WordIndexToWordPlace(int32_t index) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001781 if (m_pVT->IsValid())
1782 return m_pVT->WordIndexToWordPlace(index);
1783
1784 return CPVT_WordPlace();
1785}
1786
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001787bool CPWL_EditImpl::IsTextFull() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001788 int32_t nTotalWords = m_pVT->GetTotalWords();
1789 int32_t nLimitChar = m_pVT->GetLimitChar();
1790 int32_t nCharArray = m_pVT->GetCharArray();
1791
1792 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
1793 (nCharArray > 0 && nTotalWords >= nCharArray);
1794}
1795
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001796bool CPWL_EditImpl::IsTextOverflow() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001797 if (!m_bEnableScroll && !m_bEnableOverflow) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001798 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1799 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001800
dsinclair448c4332016-08-02 12:07:35 -07001801 if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
1802 IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
tsepez4cf55152016-11-02 14:37:54 -07001803 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001804 }
1805
dsinclair448c4332016-08-02 12:07:35 -07001806 if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
tsepez4cf55152016-11-02 14:37:54 -07001807 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001808 }
1809
tsepez4cf55152016-11-02 14:37:54 -07001810 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001811}
1812
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001813bool CPWL_EditImpl::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001814 if (m_bEnableUndo) {
1815 return m_Undo.CanUndo();
1816 }
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::CanRedo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001822 if (m_bEnableUndo) {
1823 return m_Undo.CanRedo();
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 -04001829void CPWL_EditImpl::EnableRefresh(bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001830 m_bEnableRefresh = bRefresh;
1831}
1832
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001833void CPWL_EditImpl::EnableUndo(bool bUndo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001834 m_bEnableUndo = bUndo;
1835}
1836
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001837CPVT_WordPlace CPWL_EditImpl::DoInsertText(const CPVT_WordPlace& place,
1838 const CFX_WideString& sText,
1839 int32_t charset) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001840 CPVT_WordPlace wp = place;
1841
1842 if (m_pVT->IsValid()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001843 for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
Tom Sepez62a70f92016-03-21 15:00:20 -07001844 uint16_t word = sText[i];
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001845 switch (word) {
1846 case 0x0D:
dsinclairefd5a992016-07-18 10:04:07 -07001847 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001848 if (sText[i + 1] == 0x0A)
1849 i++;
1850 break;
1851 case 0x0A:
dsinclairefd5a992016-07-18 10:04:07 -07001852 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001853 if (sText[i + 1] == 0x0D)
1854 i++;
1855 break;
1856 case 0x09:
1857 word = 0x20;
1858 default:
1859 wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
dsinclairefd5a992016-07-18 10:04:07 -07001860 nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001861 break;
1862 }
1863 }
1864 }
1865
1866 return wp;
1867}
1868
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001869int32_t CPWL_EditImpl::GetCharSetFromUnicode(uint16_t word,
1870 int32_t nOldCharset) {
dsinclairc7a73492016-04-05 12:01:42 -07001871 if (IPVT_FontMap* pFontMap = GetFontMap())
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001872 return pFontMap->CharSetFromUnicode(word, nOldCharset);
1873 return nOldCharset;
1874}
1875
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001876void CPWL_EditImpl::AddEditUndoItem(
Lei Zhangae9c5ca2017-08-12 07:15:14 -07001877 std::unique_ptr<IFX_Edit_UndoItem> pEditUndoItem) {
Lei Zhang1a89e362017-03-23 15:27:25 -07001878 m_Undo.AddItem(std::move(pEditUndoItem));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001879}
1880
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001881CFX_ByteString CPWL_EditImpl::GetPDFWordString(int32_t nFontIndex,
1882 uint16_t Word,
1883 uint16_t SubWord) {
Dan Sinclairc08dc392017-07-24 08:57:35 -04001884 IPVT_FontMap* pFontMap = GetFontMap();
1885 CPDF_Font* pPDFFont = pFontMap->GetPDFFont(nFontIndex);
1886 if (!pPDFFont)
1887 return CFX_ByteString();
1888
1889 CFX_ByteString sWord;
1890 if (SubWord > 0) {
1891 Word = SubWord;
1892 } else {
1893 uint32_t dwCharCode = pPDFFont->IsUnicodeCompatible()
1894 ? pPDFFont->CharCodeFromUnicode(Word)
1895 : pFontMap->CharCodeFromUnicode(nFontIndex, Word);
1896 if (dwCharCode > 0) {
1897 pPDFFont->AppendChar(&sWord, dwCharCode);
1898 return sWord;
1899 }
1900 }
1901 pPDFFont->AppendChar(&sWord, Word);
1902 return sWord;
1903}
1904
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001905CPWL_EditImpl_LineRectArray::CPWL_EditImpl_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07001906
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001907CPWL_EditImpl_LineRectArray::~CPWL_EditImpl_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07001908
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001909void CPWL_EditImpl_LineRectArray::operator=(
1910 CPWL_EditImpl_LineRectArray&& that) {
Tom Sepez3509d162017-01-30 13:22:02 -08001911 m_LineRects = std::move(that.m_LineRects);
weili625ad662016-06-15 11:21:33 -07001912}
1913
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001914void CPWL_EditImpl_LineRectArray::Add(const CPVT_WordRange& wrLine,
1915 const CFX_FloatRect& rcLine) {
1916 m_LineRects.push_back(
1917 pdfium::MakeUnique<CPWL_EditImpl_LineRect>(wrLine, rcLine));
weili625ad662016-06-15 11:21:33 -07001918}
1919
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001920int32_t CPWL_EditImpl_LineRectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08001921 return pdfium::CollectionSize<int32_t>(m_LineRects);
weili625ad662016-06-15 11:21:33 -07001922}
1923
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001924CPWL_EditImpl_LineRect* CPWL_EditImpl_LineRectArray::GetAt(
1925 int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08001926 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07001927 return nullptr;
1928
Tom Sepez3509d162017-01-30 13:22:02 -08001929 return m_LineRects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07001930}
1931
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001932CPWL_EditImpl_Select::CPWL_EditImpl_Select() {}
weili625ad662016-06-15 11:21:33 -07001933
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001934CPWL_EditImpl_Select::CPWL_EditImpl_Select(const CPVT_WordRange& range) {
weili625ad662016-06-15 11:21:33 -07001935 Set(range.BeginPos, range.EndPos);
1936}
1937
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001938CPVT_WordRange CPWL_EditImpl_Select::ConvertToWordRange() const {
weili625ad662016-06-15 11:21:33 -07001939 return CPVT_WordRange(BeginPos, EndPos);
1940}
1941
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001942void CPWL_EditImpl_Select::Reset() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001943 BeginPos.Reset();
1944 EndPos.Reset();
weili625ad662016-06-15 11:21:33 -07001945}
1946
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001947void CPWL_EditImpl_Select::Set(const CPVT_WordPlace& begin,
1948 const CPVT_WordPlace& end) {
weili625ad662016-06-15 11:21:33 -07001949 BeginPos = begin;
1950 EndPos = end;
1951}
1952
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001953void CPWL_EditImpl_Select::SetEndPos(const CPVT_WordPlace& end) {
weili625ad662016-06-15 11:21:33 -07001954 EndPos = end;
1955}
1956
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001957bool CPWL_EditImpl_Select::IsEmpty() const {
Tom Sepez52f69b32017-03-21 13:42:38 -07001958 return BeginPos == EndPos;
weili625ad662016-06-15 11:21:33 -07001959}
1960
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001961CPWL_EditImpl_RectArray::CPWL_EditImpl_RectArray() {}
weili625ad662016-06-15 11:21:33 -07001962
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001963CPWL_EditImpl_RectArray::~CPWL_EditImpl_RectArray() {}
weili625ad662016-06-15 11:21:33 -07001964
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001965void CPWL_EditImpl_RectArray::Clear() {
Tom Sepez3509d162017-01-30 13:22:02 -08001966 m_Rects.clear();
weili625ad662016-06-15 11:21:33 -07001967}
1968
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001969void CPWL_EditImpl_RectArray::Add(const CFX_FloatRect& rect) {
weili625ad662016-06-15 11:21:33 -07001970 // check for overlapped area
Tom Sepez3509d162017-01-30 13:22:02 -08001971 for (const auto& pRect : m_Rects) {
weili625ad662016-06-15 11:21:33 -07001972 if (pRect && pRect->Contains(rect))
1973 return;
1974 }
Tom Sepez3509d162017-01-30 13:22:02 -08001975 m_Rects.push_back(pdfium::MakeUnique<CFX_FloatRect>(rect));
weili625ad662016-06-15 11:21:33 -07001976}
1977
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001978int32_t CPWL_EditImpl_RectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08001979 return pdfium::CollectionSize<int32_t>(m_Rects);
weili625ad662016-06-15 11:21:33 -07001980}
1981
Dan Sinclair6b0158f2017-07-24 09:42:55 -04001982CFX_FloatRect* CPWL_EditImpl_RectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08001983 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07001984 return nullptr;
1985
Tom Sepez3509d162017-01-30 13:22:02 -08001986 return m_Rects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07001987}