blob: 863486bdea11de0eff3008252d7004244575019e [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
dsinclair0bb385b2016-09-29 17:03:59 -07007#include "fpdfsdk/fxedit/fxet_edit.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -08008
Lei Zhang375a8642016-01-11 11:59:17 -08009#include <algorithm>
thestigd4c34f22016-09-28 17:04:51 -070010#include <memory>
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"
dsinclair0bb385b2016-09-29 17:03:59 -070030#include "fpdfsdk/fxedit/fx_edit.h"
Lei Zhang633a3b72017-06-02 15:27:22 -070031#include "fpdfsdk/pdfwindow/cpwl_edit.h"
32#include "fpdfsdk/pdfwindow/cpwl_edit_ctrl.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 -070040CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) {
41 if (strWords.GetLength() > 0)
Nicolas Pena995a6012017-06-20 17:42:39 -040042 return PDF_EncodeString(strWords, false) + " Tj\n";
dsinclaire35af1e2016-07-13 11:26:20 -070043 return CFX_ByteString();
44}
45
46CFX_ByteString GetFontSetString(IPVT_FontMap* pFontMap,
47 int32_t nFontIndex,
Dan Sinclair05df0752017-03-14 14:43:42 -040048 float fFontSize) {
dsinclaire35af1e2016-07-13 11:26:20 -070049 if (!pFontMap)
50 return CFX_ByteString();
51
52 CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
53 if (sFontAlias.GetLength() <= 0 || fFontSize <= 0)
54 return CFX_ByteString();
55
Henrique Nakashima2e2da132017-06-27 13:43:22 -040056 std::ostringstream sRet;
dsinclaire35af1e2016-07-13 11:26:20 -070057 sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
Henrique Nakashima2e2da132017-06-27 13:43:22 -040058 return CFX_ByteString(sRet);
dsinclaire35af1e2016-07-13 11:26:20 -070059}
60
dsinclaire35af1e2016-07-13 11:26:20 -070061void DrawTextString(CFX_RenderDevice* pDevice,
Dan Sinclairf528eee2017-02-14 11:52:07 -050062 const CFX_PointF& pt,
dsinclaire35af1e2016-07-13 11:26:20 -070063 CPDF_Font* pFont,
Dan Sinclair05df0752017-03-14 14:43:42 -040064 float fFontSize,
dsinclaire35af1e2016-07-13 11:26:20 -070065 CFX_Matrix* pUser2Device,
66 const CFX_ByteString& str,
67 FX_ARGB crTextFill,
dsinclaire35af1e2016-07-13 11:26:20 -070068 int32_t nHorzScale) {
Dan Sinclaira0061af2017-02-23 09:25:17 -050069 CFX_PointF pos = pUser2Device->Transform(pt);
dsinclaire35af1e2016-07-13 11:26:20 -070070
71 if (pFont) {
72 if (nHorzScale != 100) {
73 CFX_Matrix mt(nHorzScale / 100.0f, 0, 0, 1, 0, 0);
74 mt.Concat(*pUser2Device);
75
76 CPDF_RenderOptions ro;
77 ro.m_Flags = RENDER_CLEARTYPE;
78 ro.m_ColorMode = RENDER_COLOR_NORMAL;
79
Dan Sinclaira0061af2017-02-23 09:25:17 -050080 CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize,
81 &mt, str, crTextFill, nullptr, &ro);
dsinclaire35af1e2016-07-13 11:26:20 -070082 } else {
83 CPDF_RenderOptions ro;
84 ro.m_Flags = RENDER_CLEARTYPE;
85 ro.m_ColorMode = RENDER_COLOR_NORMAL;
86
Dan Sinclaira0061af2017-02-23 09:25:17 -050087 CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize,
88 pUser2Device, str, crTextFill, nullptr,
89 &ro);
dsinclaire35af1e2016-07-13 11:26:20 -070090 }
91 }
92}
93
dsinclair8f4bf9a2016-05-04 13:51:51 -070094} // namespace
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070095
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit* pEdit,
dsinclairc7a73492016-04-05 12:01:42 -070097 CPDF_VariableText::Iterator* pVTIterator)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098 : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {}
99
100CFX_Edit_Iterator::~CFX_Edit_Iterator() {}
101
tsepez4cf55152016-11-02 14:37:54 -0700102bool CFX_Edit_Iterator::NextWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700103 return m_pVTIterator->NextWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700104}
105
tsepez4cf55152016-11-02 14:37:54 -0700106bool CFX_Edit_Iterator::PrevWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107 return m_pVTIterator->PrevWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700108}
109
tsepez4cf55152016-11-02 14:37:54 -0700110bool CFX_Edit_Iterator::GetWord(CPVT_Word& word) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700111 ASSERT(m_pEdit);
112
113 if (m_pVTIterator->GetWord(word)) {
114 word.ptWord = m_pEdit->VTToEdit(word.ptWord);
tsepez4cf55152016-11-02 14:37:54 -0700115 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 }
tsepez4cf55152016-11-02 14:37:54 -0700117 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700118}
119
tsepez4cf55152016-11-02 14:37:54 -0700120bool CFX_Edit_Iterator::GetLine(CPVT_Line& line) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 ASSERT(m_pEdit);
122
123 if (m_pVTIterator->GetLine(line)) {
124 line.ptLine = m_pEdit->VTToEdit(line.ptLine);
tsepez4cf55152016-11-02 14:37:54 -0700125 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 }
tsepez4cf55152016-11-02 14:37:54 -0700127 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700128}
129
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130void CFX_Edit_Iterator::SetAt(int32_t nWordIndex) {
131 m_pVTIterator->SetAt(nWordIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700132}
133
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace& place) {
135 m_pVTIterator->SetAt(place);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700136}
137
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138const CPVT_WordPlace& CFX_Edit_Iterator::GetAt() const {
139 return m_pVTIterator->GetAt();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700140}
141
dsinclairc7a73492016-04-05 12:01:42 -0700142CFX_Edit_Provider::CFX_Edit_Provider(IPVT_FontMap* pFontMap)
143 : CPDF_VariableText::Provider(pFontMap), m_pFontMap(pFontMap) {
Lei Zhang96660d62015-12-14 18:27:25 -0800144 ASSERT(m_pFontMap);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700145}
146
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147CFX_Edit_Provider::~CFX_Edit_Provider() {}
148
Tom Sepezd0409af2017-05-25 15:53:57 -0700149IPVT_FontMap* CFX_Edit_Provider::GetFontMap() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700150 return m_pFontMap;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700151}
152
npm41d6bbe2016-09-14 11:54:44 -0700153int32_t CFX_Edit_Provider::GetCharWidth(int32_t nFontIndex, uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700154 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
tsepezc3255f52016-03-25 14:52:27 -0700155 uint32_t charcode = word;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700156
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 if (pPDFFont->IsUnicodeCompatible())
158 charcode = pPDFFont->CharCodeFromUnicode(word);
159 else
160 charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);
161
Wei Li89409932016-03-28 10:33:33 -0700162 if (charcode != CPDF_Font::kInvalidCharCode)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 return pPDFFont->GetCharWidthF(charcode);
164 }
165
166 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700167}
168
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169int32_t CFX_Edit_Provider::GetTypeAscent(int32_t nFontIndex) {
170 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
171 return pPDFFont->GetTypeAscent();
172
173 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174}
175
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176int32_t CFX_Edit_Provider::GetTypeDescent(int32_t nFontIndex) {
177 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
178 return pPDFFont->GetTypeDescent();
179
180 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700181}
182
Tom Sepez62a70f92016-03-21 15:00:20 -0700183int32_t CFX_Edit_Provider::GetWordFontIndex(uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184 int32_t charset,
185 int32_t nFontIndex) {
186 return m_pFontMap->GetWordFontIndex(word, charset, nFontIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700187}
188
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700189int32_t CFX_Edit_Provider::GetDefaultFontIndex() {
190 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700191}
192
tsepez4cf55152016-11-02 14:37:54 -0700193bool CFX_Edit_Provider::IsLatinWord(uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194 return FX_EDIT_ISLATINWORD(word);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700195}
196
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197CFX_Edit_Refresh::CFX_Edit_Refresh() {}
198
199CFX_Edit_Refresh::~CFX_Edit_Refresh() {}
200
201void CFX_Edit_Refresh::BeginRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800202 m_RefreshRects.Clear();
203 m_OldLineRects = std::move(m_NewLineRects);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700204}
205
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206void CFX_Edit_Refresh::Push(const CPVT_WordRange& linerange,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800207 const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208 m_NewLineRects.Add(linerange, rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700209}
210
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211void CFX_Edit_Refresh::NoAnalyse() {
212 {
213 for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
214 if (CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i))
215 m_RefreshRects.Add(pOldRect->m_rcLine);
216 }
217
218 {
219 for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
220 if (CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i))
221 m_RefreshRects.Add(pNewRect->m_rcLine);
222 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700223}
224
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const {
226 return &m_RefreshRects;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700227}
228
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229void CFX_Edit_Refresh::EndRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800230 m_RefreshRects.Clear();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700231}
232
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize)
234 : m_nCurUndoPos(0),
235 m_nBufSize(nBufsize),
tsepez4cf55152016-11-02 14:37:54 -0700236 m_bWorking(false) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237
238CFX_Edit_Undo::~CFX_Edit_Undo() {
239 Reset();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700240}
241
tsepez4cf55152016-11-02 14:37:54 -0700242bool CFX_Edit_Undo::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 return m_nCurUndoPos > 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700244}
245
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246void CFX_Edit_Undo::Undo() {
tsepez4cf55152016-11-02 14:37:54 -0700247 m_bWorking = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700248 if (m_nCurUndoPos > 0) {
Tom Sepez3509d162017-01-30 13:22:02 -0800249 m_UndoItemStack[m_nCurUndoPos - 1]->Undo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 m_nCurUndoPos--;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 }
tsepez4cf55152016-11-02 14:37:54 -0700252 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253}
254
tsepez4cf55152016-11-02 14:37:54 -0700255bool CFX_Edit_Undo::CanRedo() const {
Tom Sepez3509d162017-01-30 13:22:02 -0800256 return m_nCurUndoPos < m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700257}
258
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700259void CFX_Edit_Undo::Redo() {
tsepez4cf55152016-11-02 14:37:54 -0700260 m_bWorking = true;
Tom Sepez3509d162017-01-30 13:22:02 -0800261 if (m_nCurUndoPos < m_UndoItemStack.size()) {
262 m_UndoItemStack[m_nCurUndoPos]->Redo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 m_nCurUndoPos++;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700264 }
tsepez4cf55152016-11-02 14:37:54 -0700265 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700266}
267
Tom Sepez3509d162017-01-30 13:22:02 -0800268void CFX_Edit_Undo::AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269 ASSERT(!m_bWorking);
Lei Zhang96660d62015-12-14 18:27:25 -0800270 ASSERT(pItem);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271 ASSERT(m_nBufSize > 1);
Tom Sepez3509d162017-01-30 13:22:02 -0800272 if (m_nCurUndoPos < m_UndoItemStack.size())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273 RemoveTails();
274
Lei Zhang1a89e362017-03-23 15:27:25 -0700275 if (m_UndoItemStack.size() >= m_nBufSize)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 RemoveHeads();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277
Tom Sepez3509d162017-01-30 13:22:02 -0800278 m_UndoItemStack.push_back(std::move(pItem));
279 m_nCurUndoPos = m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700280}
281
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282void CFX_Edit_Undo::RemoveHeads() {
Tom Sepez3509d162017-01-30 13:22:02 -0800283 ASSERT(m_UndoItemStack.size() > 1);
284 m_UndoItemStack.pop_front();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700285}
286
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287void CFX_Edit_Undo::RemoveTails() {
Tom Sepez3509d162017-01-30 13:22:02 -0800288 while (m_UndoItemStack.size() > m_nCurUndoPos)
289 m_UndoItemStack.pop_back();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290}
291
292void CFX_Edit_Undo::Reset() {
Tom Sepez3509d162017-01-30 13:22:02 -0800293 m_UndoItemStack.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294 m_nCurUndoPos = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700295}
296
tsepez4cf55152016-11-02 14:37:54 -0700297CFX_Edit_UndoItem::CFX_Edit_UndoItem() : m_bFirst(true), m_bLast(true) {}
weili625ad662016-06-15 11:21:33 -0700298
299CFX_Edit_UndoItem::~CFX_Edit_UndoItem() {}
300
Tom Sepez3509d162017-01-30 13:22:02 -0800301CFX_WideString CFX_Edit_UndoItem::GetUndoTitle() const {
302 return CFX_WideString();
weili625ad662016-06-15 11:21:33 -0700303}
304
tsepez4cf55152016-11-02 14:37:54 -0700305void CFX_Edit_UndoItem::SetFirst(bool bFirst) {
weili625ad662016-06-15 11:21:33 -0700306 m_bFirst = bFirst;
307}
308
tsepez4cf55152016-11-02 14:37:54 -0700309void CFX_Edit_UndoItem::SetLast(bool bLast) {
weili625ad662016-06-15 11:21:33 -0700310 m_bLast = bLast;
311}
312
tsepez4cf55152016-11-02 14:37:54 -0700313bool CFX_Edit_UndoItem::IsLast() {
weili625ad662016-06-15 11:21:33 -0700314 return m_bLast;
315}
316
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit* pEdit,
318 const CPVT_WordPlace& wpOldPlace,
319 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700320 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700321 int32_t charset,
322 const CPVT_WordProps* pWordProps)
323 : m_pEdit(pEdit),
324 m_wpOld(wpOldPlace),
325 m_wpNew(wpNewPlace),
326 m_Word(word),
327 m_nCharset(charset),
328 m_WordProps() {
329 if (pWordProps)
330 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700331}
332
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700333CFXEU_InsertWord::~CFXEU_InsertWord() {}
334
335void CFXEU_InsertWord::Redo() {
336 if (m_pEdit) {
337 m_pEdit->SelectNone();
338 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700339 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700341}
342
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700343void CFXEU_InsertWord::Undo() {
344 if (m_pEdit) {
345 m_pEdit->SelectNone();
346 m_pEdit->SetCaret(m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700347 m_pEdit->Backspace(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700348 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700349}
350
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700351CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit* pEdit,
352 const CPVT_WordPlace& wpOldPlace,
353 const CPVT_WordPlace& wpNewPlace,
354 const CPVT_SecProps* pSecProps,
355 const CPVT_WordProps* pWordProps)
356 : m_pEdit(pEdit),
357 m_wpOld(wpOldPlace),
358 m_wpNew(wpNewPlace),
359 m_SecProps(),
360 m_WordProps() {
361 if (pSecProps)
362 m_SecProps = *pSecProps;
363 if (pWordProps)
364 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700365}
366
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700367CFXEU_InsertReturn::~CFXEU_InsertReturn() {}
368
369void CFXEU_InsertReturn::Redo() {
370 if (m_pEdit) {
371 m_pEdit->SelectNone();
372 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700373 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700374 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700375}
376
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700377void CFXEU_InsertReturn::Undo() {
378 if (m_pEdit) {
379 m_pEdit->SelectNone();
380 m_pEdit->SetCaret(m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700381 m_pEdit->Backspace(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700382 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700383}
384
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385CFXEU_Backspace::CFXEU_Backspace(CFX_Edit* pEdit,
386 const CPVT_WordPlace& wpOldPlace,
387 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700388 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700389 int32_t charset,
390 const CPVT_SecProps& SecProps,
391 const CPVT_WordProps& WordProps)
392 : m_pEdit(pEdit),
393 m_wpOld(wpOldPlace),
394 m_wpNew(wpNewPlace),
395 m_Word(word),
396 m_nCharset(charset),
397 m_SecProps(SecProps),
398 m_WordProps(WordProps) {}
399
400CFXEU_Backspace::~CFXEU_Backspace() {}
401
402void CFXEU_Backspace::Redo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700403 if (!m_pEdit)
404 return;
405
406 m_pEdit->SelectNone();
407 m_pEdit->SetCaret(m_wpOld);
408 m_pEdit->Backspace(false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700409}
410
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700411void CFXEU_Backspace::Undo() {
Tom Sepez52f69b32017-03-21 13:42:38 -0700412 if (!m_pEdit)
413 return;
414
415 m_pEdit->SelectNone();
416 m_pEdit->SetCaret(m_wpNew);
417 if (m_wpNew.nSecIndex != m_wpOld.nSecIndex)
418 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
419 else
420 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700421}
422
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700423CFXEU_Delete::CFXEU_Delete(CFX_Edit* pEdit,
424 const CPVT_WordPlace& wpOldPlace,
425 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700426 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700427 int32_t charset,
428 const CPVT_SecProps& SecProps,
429 const CPVT_WordProps& WordProps,
tsepez4cf55152016-11-02 14:37:54 -0700430 bool bSecEnd)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700431 : m_pEdit(pEdit),
432 m_wpOld(wpOldPlace),
433 m_wpNew(wpNewPlace),
434 m_Word(word),
435 m_nCharset(charset),
436 m_SecProps(SecProps),
437 m_WordProps(WordProps),
438 m_bSecEnd(bSecEnd) {}
439
440CFXEU_Delete::~CFXEU_Delete() {}
441
442void CFXEU_Delete::Redo() {
443 if (m_pEdit) {
444 m_pEdit->SelectNone();
445 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700446 m_pEdit->Delete(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700447 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700448}
449
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700450void CFXEU_Delete::Undo() {
451 if (m_pEdit) {
452 m_pEdit->SelectNone();
453 m_pEdit->SetCaret(m_wpNew);
454 if (m_bSecEnd) {
tsepez4cf55152016-11-02 14:37:54 -0700455 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700456 } else {
tsepez4cf55152016-11-02 14:37:54 -0700457 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700458 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700459 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700460}
461
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700462CFXEU_Clear::CFXEU_Clear(CFX_Edit* pEdit,
463 const CPVT_WordRange& wrSel,
464 const CFX_WideString& swText)
465 : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {}
466
467CFXEU_Clear::~CFXEU_Clear() {}
468
469void CFXEU_Clear::Redo() {
470 if (m_pEdit) {
471 m_pEdit->SelectNone();
472 m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
tsepez4cf55152016-11-02 14:37:54 -0700473 m_pEdit->Clear(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700474 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700475}
476
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700477void CFXEU_Clear::Undo() {
478 if (m_pEdit) {
479 m_pEdit->SelectNone();
480 m_pEdit->SetCaret(m_wrSel.BeginPos);
Dan Sinclairf51a02a2017-04-19 12:46:53 -0400481 m_pEdit->InsertText(m_swText, FX_CHARSET_Default, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700482 m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
483 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700484}
485
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700486CFXEU_InsertText::CFXEU_InsertText(CFX_Edit* pEdit,
487 const CPVT_WordPlace& wpOldPlace,
488 const CPVT_WordPlace& wpNewPlace,
489 const CFX_WideString& swText,
dsinclairefd5a992016-07-18 10:04:07 -0700490 int32_t charset)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700491 : m_pEdit(pEdit),
492 m_wpOld(wpOldPlace),
493 m_wpNew(wpNewPlace),
494 m_swText(swText),
dsinclairefd5a992016-07-18 10:04:07 -0700495 m_nCharset(charset) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700496
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700497CFXEU_InsertText::~CFXEU_InsertText() {}
498
499void CFXEU_InsertText::Redo() {
500 if (m_pEdit && IsLast()) {
501 m_pEdit->SelectNone();
502 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700503 m_pEdit->InsertText(m_swText, m_nCharset, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700504 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700505}
506
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700507void CFXEU_InsertText::Undo() {
508 if (m_pEdit) {
509 m_pEdit->SelectNone();
510 m_pEdit->SetSel(m_wpOld, m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700511 m_pEdit->Clear(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700512 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700513}
514
dsinclaire35af1e2016-07-13 11:26:20 -0700515// static
516CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500517 const CFX_PointF& ptOffset,
dsinclaire35af1e2016-07-13 11:26:20 -0700518 const CPVT_WordRange* pRange,
tsepez4cf55152016-11-02 14:37:54 -0700519 bool bContinuous,
dsinclaire35af1e2016-07-13 11:26:20 -0700520 uint16_t SubWord) {
521 CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
522 if (pRange)
523 pIterator->SetAt(pRange->BeginPos);
524 else
525 pIterator->SetAt(0);
526
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400527 std::ostringstream sEditStream;
528 std::ostringstream sWords;
dsinclaire35af1e2016-07-13 11:26:20 -0700529 int32_t nCurFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500530 CFX_PointF ptOld;
531 CFX_PointF ptNew;
dsinclaire35af1e2016-07-13 11:26:20 -0700532 CPVT_WordPlace oldplace;
tsepez63f545c2016-09-13 16:08:49 -0700533
dsinclaire35af1e2016-07-13 11:26:20 -0700534 while (pIterator->NextWord()) {
535 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700536 if (pRange && place > pRange->EndPos)
dsinclaire35af1e2016-07-13 11:26:20 -0700537 break;
538
539 if (bContinuous) {
540 if (place.LineCmp(oldplace) != 0) {
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400541 if (sWords.tellp() > 0) {
542 sEditStream << GetWordRenderString(CFX_ByteString(sWords));
543 sWords.str("");
dsinclaire35af1e2016-07-13 11:26:20 -0700544 }
545
546 CPVT_Word word;
547 if (pIterator->GetWord(word)) {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500548 ptNew = CFX_PointF(word.ptWord.x + ptOffset.x,
549 word.ptWord.y + ptOffset.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700550 } else {
551 CPVT_Line line;
552 pIterator->GetLine(line);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500553 ptNew = CFX_PointF(line.ptLine.x + ptOffset.x,
554 line.ptLine.y + ptOffset.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700555 }
556
557 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
558 sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
559 << " Td\n";
560
561 ptOld = ptNew;
562 }
563 }
564
565 CPVT_Word word;
566 if (pIterator->GetWord(word)) {
567 if (word.nFontIndex != nCurFontIndex) {
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400568 if (sWords.tellp() > 0) {
569 sEditStream << GetWordRenderString(CFX_ByteString(sWords));
570 sWords.str("");
dsinclaire35af1e2016-07-13 11:26:20 -0700571 }
572 sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
573 word.fFontSize);
574 nCurFontIndex = word.nFontIndex;
575 }
576
577 sWords << GetPDFWordString(pEdit->GetFontMap(), nCurFontIndex,
578 word.Word, SubWord);
579 }
580
581 oldplace = place;
582 } else {
583 CPVT_Word word;
584 if (pIterator->GetWord(word)) {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500585 ptNew =
586 CFX_PointF(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700587
588 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
589 sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
590 << " Td\n";
591 ptOld = ptNew;
592 }
593
594 if (word.nFontIndex != nCurFontIndex) {
595 sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
596 word.fFontSize);
597 nCurFontIndex = word.nFontIndex;
598 }
599
600 sEditStream << GetWordRenderString(GetPDFWordString(
601 pEdit->GetFontMap(), nCurFontIndex, word.Word, SubWord));
602 }
603 }
604 }
605
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400606 if (sWords.tellp() > 0) {
607 sEditStream << GetWordRenderString(CFX_ByteString(sWords));
608 sWords.str("");
dsinclaire35af1e2016-07-13 11:26:20 -0700609 }
610
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400611 std::ostringstream sAppStream;
612 if (sEditStream.tellp() > 0) {
dsinclaire35af1e2016-07-13 11:26:20 -0700613 int32_t nHorzScale = pEdit->GetHorzScale();
614 if (nHorzScale != 100) {
615 sAppStream << nHorzScale << " Tz\n";
616 }
617
Dan Sinclair05df0752017-03-14 14:43:42 -0400618 float fCharSpace = pEdit->GetCharSpace();
dsinclair448c4332016-08-02 12:07:35 -0700619 if (!IsFloatZero(fCharSpace)) {
dsinclaire35af1e2016-07-13 11:26:20 -0700620 sAppStream << fCharSpace << " Tc\n";
621 }
622
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400623 sAppStream << sEditStream.str();
dsinclaire35af1e2016-07-13 11:26:20 -0700624 }
625
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400626 return CFX_ByteString(sAppStream);
dsinclaire35af1e2016-07-13 11:26:20 -0700627}
628
629// static
630CFX_ByteString CFX_Edit::GetSelectAppearanceStream(
631 CFX_Edit* pEdit,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500632 const CFX_PointF& ptOffset,
dsinclaire35af1e2016-07-13 11:26:20 -0700633 const CPVT_WordRange* pRange) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700634 if (!pRange || pRange->IsEmpty())
dsinclaire35af1e2016-07-13 11:26:20 -0700635 return CFX_ByteString();
636
637 CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
638 pIterator->SetAt(pRange->BeginPos);
639
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400640 std::ostringstream sRet;
dsinclaire35af1e2016-07-13 11:26:20 -0700641 while (pIterator->NextWord()) {
642 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700643 if (place > pRange->EndPos)
dsinclaire35af1e2016-07-13 11:26:20 -0700644 break;
645
646 CPVT_Word word;
647 CPVT_Line line;
648 if (pIterator->GetWord(word) && pIterator->GetLine(line)) {
649 sRet << word.ptWord.x + ptOffset.x << " "
650 << line.ptLine.y + line.fLineDescent << " " << word.fWidth << " "
651 << line.fLineAscent - line.fLineDescent << " re\nf\n";
652 }
653 }
654
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400655 return CFX_ByteString(sRet);
dsinclaire35af1e2016-07-13 11:26:20 -0700656}
657
658// static
dsinclaire35af1e2016-07-13 11:26:20 -0700659void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice,
660 CFX_Matrix* pUser2Device,
661 CFX_Edit* pEdit,
662 FX_COLORREF crTextFill,
dsinclaire35af1e2016-07-13 11:26:20 -0700663 const CFX_FloatRect& rcClip,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500664 const CFX_PointF& ptOffset,
dsinclaire35af1e2016-07-13 11:26:20 -0700665 const CPVT_WordRange* pRange,
666 CFX_SystemHandler* pSystemHandler,
dsinclair8faac622016-09-15 12:41:50 -0700667 CFFL_FormFiller* pFFLData) {
dsinclaire35af1e2016-07-13 11:26:20 -0700668 const bool bContinuous =
669 pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
670 uint16_t SubWord = pEdit->GetPasswordChar();
Dan Sinclair05df0752017-03-14 14:43:42 -0400671 float fFontSize = pEdit->GetFontSize();
dsinclaire35af1e2016-07-13 11:26:20 -0700672 CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
673 int32_t nHorzScale = pEdit->GetHorzScale();
674
675 FX_COLORREF crCurFill = crTextFill;
676 FX_COLORREF crOldFill = crCurFill;
677
tsepez4cf55152016-11-02 14:37:54 -0700678 bool bSelect = false;
dsinclaire35af1e2016-07-13 11:26:20 -0700679 const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
680 const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
681
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400682 std::ostringstream sTextBuf;
dsinclaire35af1e2016-07-13 11:26:20 -0700683 int32_t nFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500684 CFX_PointF ptBT;
Tom Sepez1629f602017-04-21 14:11:26 -0700685 CFX_RenderDevice::StateRestorer restorer(pDevice);
dsinclaire35af1e2016-07-13 11:26:20 -0700686 if (!rcClip.IsEmpty()) {
687 CFX_FloatRect rcTemp = rcClip;
688 pUser2Device->TransformRect(rcTemp);
689 pDevice->SetClip_Rect(rcTemp.ToFxRect());
690 }
691
692 CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
693 if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
694 if (pRange)
695 pIterator->SetAt(pRange->BeginPos);
696 else
697 pIterator->SetAt(0);
698
699 CPVT_WordPlace oldplace;
700 while (pIterator->NextWord()) {
701 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700702 if (pRange && place > pRange->EndPos)
dsinclaire35af1e2016-07-13 11:26:20 -0700703 break;
704
Tom Sepez52f69b32017-03-21 13:42:38 -0700705 if (!wrSelect.IsEmpty()) {
706 bSelect = place > wrSelect.BeginPos && place <= wrSelect.EndPos;
dsinclaire35af1e2016-07-13 11:26:20 -0700707 crCurFill = bSelect ? crWhite : crTextFill;
708 }
709 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
710 crCurFill = crTextFill;
711 crOldFill = crCurFill;
712 }
713 CPVT_Word word;
714 if (pIterator->GetWord(word)) {
715 if (bSelect) {
716 CPVT_Line line;
717 pIterator->GetLine(line);
718
719 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
720 CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
721 word.ptWord.x + word.fWidth,
722 line.ptLine.y + line.fLineAscent);
723 rc.Intersect(rcClip);
724 pSystemHandler->OutputSelectedRect(pFFLData, rc);
725 } else {
726 CFX_PathData pathSelBK;
727 pathSelBK.AppendRect(
728 word.ptWord.x, line.ptLine.y + line.fLineDescent,
729 word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent);
730
731 pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
732 FXFILL_WINDING);
733 }
734 }
735
736 if (bContinuous) {
737 if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
738 crOldFill != crCurFill) {
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400739 if (sTextBuf.tellp() > 0) {
dsinclaire35af1e2016-07-13 11:26:20 -0700740 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500741 pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700742 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400743 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700744
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400745 sTextBuf.str("");
dsinclaire35af1e2016-07-13 11:26:20 -0700746 }
747 nFontIndex = word.nFontIndex;
748 ptBT = word.ptWord;
749 crOldFill = crCurFill;
750 }
751
752 sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word,
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400753 SubWord);
dsinclaire35af1e2016-07-13 11:26:20 -0700754 } else {
755 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500756 pDevice, CFX_PointF(word.ptWord.x + ptOffset.x,
757 word.ptWord.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700758 pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
759 GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord),
Dan Sinclaira0061af2017-02-23 09:25:17 -0500760 crCurFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700761 }
762 oldplace = place;
763 }
764 }
765
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400766 if (sTextBuf.tellp() > 0) {
Dan Sinclaira0061af2017-02-23 09:25:17 -0500767 DrawTextString(pDevice,
768 CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
769 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
Henrique Nakashima2e2da132017-06-27 13:43:22 -0400770 CFX_ByteString(sTextBuf), crOldFill, nHorzScale);
dsinclaire35af1e2016-07-13 11:26:20 -0700771 }
772 }
dsinclaire35af1e2016-07-13 11:26:20 -0700773}
774
dsinclaire35af1e2016-07-13 11:26:20 -0700775CFX_Edit::CFX_Edit()
776 : m_pVT(new CPDF_VariableText),
thestig821d59e2016-05-11 12:59:22 -0700777 m_pNotify(nullptr),
778 m_pOprNotify(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700779 m_wpCaret(-1, -1, -1),
780 m_wpOldCaret(-1, -1, -1),
781 m_SelState(),
tsepez4cf55152016-11-02 14:37:54 -0700782 m_bEnableScroll(false),
dsinclair8f4bf9a2016-05-04 13:51:51 -0700783 m_Undo(kEditUndoMaxItems),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700784 m_nAlignment(0),
tsepez4cf55152016-11-02 14:37:54 -0700785 m_bNotifyFlag(false),
786 m_bEnableOverflow(false),
787 m_bEnableRefresh(true),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700788 m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f),
tsepez4cf55152016-11-02 14:37:54 -0700789 m_bEnableUndo(true),
Lei Zhang1a89e362017-03-23 15:27:25 -0700790 m_bOprNotify(false) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700791
Lei Zhang1a89e362017-03-23 15:27:25 -0700792CFX_Edit::~CFX_Edit() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700793
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700794void CFX_Edit::Initialize() {
795 m_pVT->Initialize();
796 SetCaret(m_pVT->GetBeginWordPlace());
797 SetCaretOrigin();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700798}
799
dsinclairc7a73492016-04-05 12:01:42 -0700800void CFX_Edit::SetFontMap(IPVT_FontMap* pFontMap) {
tsepez36eb4bd2016-10-03 15:24:27 -0700801 m_pVTProvider = pdfium::MakeUnique<CFX_Edit_Provider>(pFontMap);
thestig821d59e2016-05-11 12:59:22 -0700802 m_pVT->SetProvider(m_pVTProvider.get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700803}
804
dsinclaire35af1e2016-07-13 11:26:20 -0700805void CFX_Edit::SetNotify(CPWL_EditCtrl* pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700806 m_pNotify = pNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700807}
808
dsinclaire35af1e2016-07-13 11:26:20 -0700809void CFX_Edit::SetOprNotify(CPWL_Edit* pOprNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700810 m_pOprNotify = pOprNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700811}
812
dsinclaire35af1e2016-07-13 11:26:20 -0700813CFX_Edit_Iterator* CFX_Edit::GetIterator() {
tsepez36eb4bd2016-10-03 15:24:27 -0700814 if (!m_pIterator) {
815 m_pIterator =
816 pdfium::MakeUnique<CFX_Edit_Iterator>(this, m_pVT->GetIterator());
817 }
thestig821d59e2016-05-11 12:59:22 -0700818 return m_pIterator.get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700819}
820
dsinclairc7a73492016-04-05 12:01:42 -0700821IPVT_FontMap* CFX_Edit::GetFontMap() {
thestig821d59e2016-05-11 12:59:22 -0700822 return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700823}
824
dsinclairefd5a992016-07-18 10:04:07 -0700825void CFX_Edit::SetPlateRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700826 m_pVT->SetPlateRect(rect);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500827 m_ptScrollPos = CFX_PointF(rect.left, rect.top);
dsinclairefd5a992016-07-18 10:04:07 -0700828 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700829}
830
tsepez4cf55152016-11-02 14:37:54 -0700831void CFX_Edit::SetAlignmentH(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700832 m_pVT->SetAlignment(nFormat);
833 if (bPaint)
834 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700835}
836
tsepez4cf55152016-11-02 14:37:54 -0700837void CFX_Edit::SetAlignmentV(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700838 m_nAlignment = nFormat;
839 if (bPaint)
840 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700841}
842
tsepez4cf55152016-11-02 14:37:54 -0700843void CFX_Edit::SetPasswordChar(uint16_t wSubWord, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700844 m_pVT->SetPasswordChar(wSubWord);
845 if (bPaint)
846 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700847}
848
dsinclairefd5a992016-07-18 10:04:07 -0700849void CFX_Edit::SetLimitChar(int32_t nLimitChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700850 m_pVT->SetLimitChar(nLimitChar);
dsinclairefd5a992016-07-18 10:04:07 -0700851 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700852}
853
dsinclairefd5a992016-07-18 10:04:07 -0700854void CFX_Edit::SetCharArray(int32_t nCharArray) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700855 m_pVT->SetCharArray(nCharArray);
dsinclairefd5a992016-07-18 10:04:07 -0700856 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700857}
858
Dan Sinclair05df0752017-03-14 14:43:42 -0400859void CFX_Edit::SetCharSpace(float fCharSpace) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700860 m_pVT->SetCharSpace(fCharSpace);
dsinclairefd5a992016-07-18 10:04:07 -0700861 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700862}
863
tsepez4cf55152016-11-02 14:37:54 -0700864void CFX_Edit::SetMultiLine(bool bMultiLine, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700865 m_pVT->SetMultiLine(bMultiLine);
866 if (bPaint)
867 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700868}
869
tsepez4cf55152016-11-02 14:37:54 -0700870void CFX_Edit::SetAutoReturn(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700871 m_pVT->SetAutoReturn(bAuto);
872 if (bPaint)
873 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700874}
875
tsepez4cf55152016-11-02 14:37:54 -0700876void CFX_Edit::SetAutoFontSize(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700877 m_pVT->SetAutoFontSize(bAuto);
878 if (bPaint)
879 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700880}
881
Dan Sinclair05df0752017-03-14 14:43:42 -0400882void CFX_Edit::SetFontSize(float fFontSize) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700883 m_pVT->SetFontSize(fFontSize);
dsinclairefd5a992016-07-18 10:04:07 -0700884 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700885}
886
tsepez4cf55152016-11-02 14:37:54 -0700887void CFX_Edit::SetAutoScroll(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700888 m_bEnableScroll = bAuto;
889 if (bPaint)
890 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700891}
892
tsepez4cf55152016-11-02 14:37:54 -0700893void CFX_Edit::SetTextOverflow(bool bAllowed, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700894 m_bEnableOverflow = bAllowed;
895 if (bPaint)
896 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700897}
898
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700899void CFX_Edit::SetSel(int32_t nStartChar, int32_t nEndChar) {
900 if (m_pVT->IsValid()) {
901 if (nStartChar == 0 && nEndChar < 0) {
902 SelectAll();
903 } else if (nStartChar < 0) {
904 SelectNone();
905 } else {
906 if (nStartChar < nEndChar) {
907 SetSel(m_pVT->WordIndexToWordPlace(nStartChar),
908 m_pVT->WordIndexToWordPlace(nEndChar));
909 } else {
910 SetSel(m_pVT->WordIndexToWordPlace(nEndChar),
911 m_pVT->WordIndexToWordPlace(nStartChar));
912 }
913 }
914 }
915}
916
917void CFX_Edit::SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
Tom Sepez52f69b32017-03-21 13:42:38 -0700918 if (!m_pVT->IsValid())
919 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700920
Tom Sepez52f69b32017-03-21 13:42:38 -0700921 SelectNone();
922 m_SelState.Set(begin, end);
923 SetCaret(m_SelState.EndPos);
924 ScrollToCaret();
925 if (!m_SelState.IsEmpty())
926 Refresh();
927 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700928}
929
930void CFX_Edit::GetSel(int32_t& nStartChar, int32_t& nEndChar) const {
931 nStartChar = -1;
932 nEndChar = -1;
Tom Sepez52f69b32017-03-21 13:42:38 -0700933 if (!m_pVT->IsValid())
934 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700935
Tom Sepez52f69b32017-03-21 13:42:38 -0700936 if (m_SelState.IsEmpty()) {
937 nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
938 nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
939 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700940 }
Tom Sepez52f69b32017-03-21 13:42:38 -0700941 if (m_SelState.BeginPos < m_SelState.EndPos) {
942 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
943 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
944 return;
945 }
946 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
947 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700948}
949
950int32_t CFX_Edit::GetCaret() const {
951 if (m_pVT->IsValid())
952 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
953
954 return -1;
955}
956
957CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const {
958 return m_wpCaret;
959}
960
961CFX_WideString CFX_Edit::GetText() const {
962 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700963 if (!m_pVT->IsValid())
964 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700965
thestig821d59e2016-05-11 12:59:22 -0700966 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
967 pIterator->SetAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700968
thestig821d59e2016-05-11 12:59:22 -0700969 CPVT_Word wordinfo;
970 CPVT_WordPlace oldplace = pIterator->GetAt();
971 while (pIterator->NextWord()) {
972 CPVT_WordPlace place = pIterator->GetAt();
thestig821d59e2016-05-11 12:59:22 -0700973 if (pIterator->GetWord(wordinfo))
974 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -0700975 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -0700976 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -0700977 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700978 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700979 return swRet;
980}
981
982CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange& range) const {
983 CFX_WideString swRet;
thestig821d59e2016-05-11 12:59:22 -0700984 if (!m_pVT->IsValid())
985 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700986
thestig821d59e2016-05-11 12:59:22 -0700987 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
988 CPVT_WordRange wrTemp = range;
989 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
990 m_pVT->UpdateWordPlace(wrTemp.EndPos);
991 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700992
thestig821d59e2016-05-11 12:59:22 -0700993 CPVT_Word wordinfo;
994 CPVT_WordPlace oldplace = wrTemp.BeginPos;
995 while (pIterator->NextWord()) {
996 CPVT_WordPlace place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -0700997 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -0700998 break;
thestig821d59e2016-05-11 12:59:22 -0700999 if (pIterator->GetWord(wordinfo))
1000 swRet += wordinfo.Word;
Tom Sepez52f69b32017-03-21 13:42:38 -07001001 if (oldplace.nSecIndex != place.nSecIndex)
thestig821d59e2016-05-11 12:59:22 -07001002 swRet += L"\r\n";
thestig821d59e2016-05-11 12:59:22 -07001003 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001004 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001005 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001006}
1007
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001008CFX_WideString CFX_Edit::GetSelText() const {
1009 return GetRangeText(m_SelState.ConvertToWordRange());
1010}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001011
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001012int32_t CFX_Edit::GetTotalLines() const {
thestig821d59e2016-05-11 12:59:22 -07001013 int32_t nLines = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001014
thestig821d59e2016-05-11 12:59:22 -07001015 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1016 pIterator->SetAt(0);
1017 while (pIterator->NextLine())
1018 ++nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001019
thestig821d59e2016-05-11 12:59:22 -07001020 return nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001021}
1022
1023CPVT_WordRange CFX_Edit::GetSelectWordRange() const {
1024 return m_SelState.ConvertToWordRange();
1025}
1026
tsepeza31da742016-09-08 11:28:14 -07001027void CFX_Edit::SetText(const CFX_WideString& sText) {
dsinclairefd5a992016-07-18 10:04:07 -07001028 Empty();
Dan Sinclairf51a02a2017-04-19 12:46:53 -04001029 DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_CHARSET_Default);
dsinclairefd5a992016-07-18 10:04:07 -07001030 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001031}
1032
tsepez4cf55152016-11-02 14:37:54 -07001033bool CFX_Edit::InsertWord(uint16_t word, int32_t charset) {
1034 return InsertWord(word, charset, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001035}
1036
tsepez4cf55152016-11-02 14:37:54 -07001037bool CFX_Edit::InsertReturn() {
1038 return InsertReturn(nullptr, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001039}
1040
tsepez4cf55152016-11-02 14:37:54 -07001041bool CFX_Edit::Backspace() {
1042 return Backspace(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001043}
1044
tsepez4cf55152016-11-02 14:37:54 -07001045bool CFX_Edit::Delete() {
1046 return Delete(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001047}
1048
tsepez4cf55152016-11-02 14:37:54 -07001049bool CFX_Edit::Clear() {
1050 return Clear(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001051}
1052
tsepez4cf55152016-11-02 14:37:54 -07001053bool CFX_Edit::InsertText(const CFX_WideString& sText, int32_t charset) {
1054 return InsertText(sText, charset, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001055}
1056
Dan Sinclair05df0752017-03-14 14:43:42 -04001057float CFX_Edit::GetFontSize() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001058 return m_pVT->GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001059}
1060
Tom Sepez62a70f92016-03-21 15:00:20 -07001061uint16_t CFX_Edit::GetPasswordChar() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001062 return m_pVT->GetPasswordChar();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001063}
1064
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001065int32_t CFX_Edit::GetCharArray() const {
1066 return m_pVT->GetCharArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001067}
1068
Tom Sepez281a9ea2016-02-26 14:24:28 -08001069CFX_FloatRect CFX_Edit::GetContentRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001070 return VTToEdit(m_pVT->GetContentRect());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001071}
1072
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001073int32_t CFX_Edit::GetHorzScale() const {
1074 return m_pVT->GetHorzScale();
1075}
1076
Dan Sinclair05df0752017-03-14 14:43:42 -04001077float CFX_Edit::GetCharSpace() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001078 return m_pVT->GetCharSpace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001079}
1080
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001081CPVT_WordRange CFX_Edit::GetWholeWordRange() const {
1082 if (m_pVT->IsValid())
1083 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001084
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001085 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001086}
1087
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001088CPVT_WordRange CFX_Edit::GetVisibleWordRange() const {
1089 if (m_bEnableOverflow)
1090 return GetWholeWordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001091
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001092 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001093 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001094
Dan Sinclairf528eee2017-02-14 11:52:07 -05001095 CPVT_WordPlace place1 =
1096 m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001097 CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
Dan Sinclairf528eee2017-02-14 11:52:07 -05001098 EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001099
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001100 return CPVT_WordRange(place1, place2);
1101 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001102
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001103 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001104}
1105
Dan Sinclairf528eee2017-02-14 11:52:07 -05001106CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_PointF& point) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001107 if (m_pVT->IsValid()) {
1108 return m_pVT->SearchWordPlace(EditToVT(point));
1109 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001110
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001111 return CPVT_WordPlace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001112}
1113
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001114void CFX_Edit::Paint() {
1115 if (m_pVT->IsValid()) {
1116 RearrangeAll();
1117 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001118 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001119 SetCaretOrigin();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001120 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001121 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001122}
1123
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001124void CFX_Edit::RearrangeAll() {
1125 if (m_pVT->IsValid()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001126 m_pVT->UpdateWordPlace(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001127 m_pVT->RearrangeAll();
1128 m_pVT->UpdateWordPlace(m_wpCaret);
1129 SetScrollInfo();
1130 SetContentChanged();
1131 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001132}
1133
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001134void CFX_Edit::RearrangePart(const CPVT_WordRange& range) {
1135 if (m_pVT->IsValid()) {
1136 m_pVT->UpdateWordPlace(m_wpCaret);
1137 m_pVT->RearrangePart(range);
1138 m_pVT->UpdateWordPlace(m_wpCaret);
1139 SetScrollInfo();
1140 SetContentChanged();
1141 }
1142}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001143
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001144void CFX_Edit::SetContentChanged() {
dsinclaira2919b32016-07-13 10:55:48 -07001145 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001146 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001147 if (rcContent.Width() != m_rcOldContent.Width() ||
1148 rcContent.Height() != m_rcOldContent.Height()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001149 m_rcOldContent = rcContent;
1150 }
1151 }
1152}
1153
1154void CFX_Edit::SelectAll() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001155 if (!m_pVT->IsValid())
1156 return;
1157 m_SelState = CFX_Edit_Select(GetWholeWordRange());
1158 SetCaret(m_SelState.EndPos);
1159 ScrollToCaret();
1160 Refresh();
1161 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001162}
1163
1164void CFX_Edit::SelectNone() {
Tom Sepez52f69b32017-03-21 13:42:38 -07001165 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
1166 return;
1167
1168 m_SelState.Reset();
1169 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001170}
1171
tsepez4cf55152016-11-02 14:37:54 -07001172bool CFX_Edit::IsSelected() const {
Tom Sepez52f69b32017-03-21 13:42:38 -07001173 return !m_SelState.IsEmpty();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001174}
1175
Dan Sinclairf528eee2017-02-14 11:52:07 -05001176CFX_PointF CFX_Edit::VTToEdit(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001177 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1178 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001179
Dan Sinclair05df0752017-03-14 14:43:42 -04001180 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001181
1182 switch (m_nAlignment) {
1183 case 0:
1184 fPadding = 0.0f;
1185 break;
1186 case 1:
1187 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1188 break;
1189 case 2:
1190 fPadding = rcPlate.Height() - rcContent.Height();
1191 break;
1192 }
1193
Dan Sinclairf528eee2017-02-14 11:52:07 -05001194 return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
1195 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001196}
1197
Dan Sinclairf528eee2017-02-14 11:52:07 -05001198CFX_PointF CFX_Edit::EditToVT(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001199 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1200 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001201
Dan Sinclair05df0752017-03-14 14:43:42 -04001202 float fPadding = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001203
1204 switch (m_nAlignment) {
1205 case 0:
1206 fPadding = 0.0f;
1207 break;
1208 case 1:
1209 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1210 break;
1211 case 2:
1212 fPadding = rcPlate.Height() - rcContent.Height();
1213 break;
1214 }
1215
Dan Sinclairf528eee2017-02-14 11:52:07 -05001216 return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
1217 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001218}
1219
Tom Sepez281a9ea2016-02-26 14:24:28 -08001220CFX_FloatRect CFX_Edit::VTToEdit(const CFX_FloatRect& rect) const {
Dan Sinclairf528eee2017-02-14 11:52:07 -05001221 CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
1222 CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001223
Tom Sepez281a9ea2016-02-26 14:24:28 -08001224 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1225 ptRightTop.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001226}
1227
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001228void CFX_Edit::SetScrollInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001229 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001230 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1231 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001232
1233 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001234 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001235 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001236 m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
1237 rcContent.bottom, rcContent.top,
1238 rcPlate.Height() / 3, rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001239 }
1240 }
1241}
1242
Dan Sinclair05df0752017-03-14 14:43:42 -04001243void CFX_Edit::SetScrollPosX(float fx) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001244 if (!m_bEnableScroll)
1245 return;
1246
1247 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001248 if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001249 m_ptScrollPos.x = fx;
dsinclairefd5a992016-07-18 10:04:07 -07001250 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001251 }
1252 }
1253}
1254
Dan Sinclair05df0752017-03-14 14:43:42 -04001255void CFX_Edit::SetScrollPosY(float fy) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001256 if (!m_bEnableScroll)
1257 return;
1258
1259 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001260 if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001261 m_ptScrollPos.y = fy;
dsinclairefd5a992016-07-18 10:04:07 -07001262 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001263
dsinclaira2919b32016-07-13 10:55:48 -07001264 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001265 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001266 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001267 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001268 m_pNotify->IOnSetScrollPosY(fy);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001269 }
1270 }
1271 }
1272 }
1273}
1274
Dan Sinclairf528eee2017-02-14 11:52:07 -05001275void CFX_Edit::SetScrollPos(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001276 SetScrollPosX(point.x);
1277 SetScrollPosY(point.y);
1278 SetScrollLimit();
1279 SetCaretInfo();
1280}
1281
Dan Sinclairf528eee2017-02-14 11:52:07 -05001282CFX_PointF CFX_Edit::GetScrollPos() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001283 return m_ptScrollPos;
1284}
1285
1286void CFX_Edit::SetScrollLimit() {
1287 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001288 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1289 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001290
1291 if (rcPlate.Width() > rcContent.Width()) {
1292 SetScrollPosX(rcPlate.left);
1293 } else {
dsinclair448c4332016-08-02 12:07:35 -07001294 if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001295 SetScrollPosX(rcContent.left);
dsinclair448c4332016-08-02 12:07:35 -07001296 } else if (IsFloatBigger(m_ptScrollPos.x,
1297 rcContent.right - rcPlate.Width())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001298 SetScrollPosX(rcContent.right - rcPlate.Width());
1299 }
1300 }
1301
1302 if (rcPlate.Height() > rcContent.Height()) {
1303 SetScrollPosY(rcPlate.top);
1304 } else {
dsinclair448c4332016-08-02 12:07:35 -07001305 if (IsFloatSmaller(m_ptScrollPos.y,
1306 rcContent.bottom + rcPlate.Height())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001307 SetScrollPosY(rcContent.bottom + rcPlate.Height());
dsinclair448c4332016-08-02 12:07:35 -07001308 } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001309 SetScrollPosY(rcContent.top);
1310 }
1311 }
1312 }
1313}
1314
1315void CFX_Edit::ScrollToCaret() {
1316 SetScrollLimit();
1317
thestig821d59e2016-05-11 12:59:22 -07001318 if (!m_pVT->IsValid())
1319 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001320
thestig821d59e2016-05-11 12:59:22 -07001321 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1322 pIterator->SetAt(m_wpCaret);
1323
Dan Sinclairf528eee2017-02-14 11:52:07 -05001324 CFX_PointF ptHead;
1325 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001326 CPVT_Word word;
1327 CPVT_Line line;
1328 if (pIterator->GetWord(word)) {
1329 ptHead.x = word.ptWord.x + word.fWidth;
1330 ptHead.y = word.ptWord.y + word.fAscent;
1331 ptFoot.x = word.ptWord.x + word.fWidth;
1332 ptFoot.y = word.ptWord.y + word.fDescent;
1333 } else if (pIterator->GetLine(line)) {
1334 ptHead.x = line.ptLine.x;
1335 ptHead.y = line.ptLine.y + line.fLineAscent;
1336 ptFoot.x = line.ptLine.x;
1337 ptFoot.y = line.ptLine.y + line.fLineDescent;
1338 }
1339
Dan Sinclairf528eee2017-02-14 11:52:07 -05001340 CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1341 CFX_PointF ptFootEdit = VTToEdit(ptFoot);
thestig821d59e2016-05-11 12:59:22 -07001342 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
dsinclair448c4332016-08-02 12:07:35 -07001343 if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
1344 if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
1345 IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
thestig821d59e2016-05-11 12:59:22 -07001346 SetScrollPosX(ptHead.x);
dsinclair448c4332016-08-02 12:07:35 -07001347 } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
thestig821d59e2016-05-11 12:59:22 -07001348 SetScrollPosX(ptHead.x - rcPlate.Width());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001349 }
thestig821d59e2016-05-11 12:59:22 -07001350 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001351
dsinclair448c4332016-08-02 12:07:35 -07001352 if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
1353 if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
1354 IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
1355 if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
thestig821d59e2016-05-11 12:59:22 -07001356 SetScrollPosY(ptFoot.y + rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001357 }
dsinclair448c4332016-08-02 12:07:35 -07001358 } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
1359 if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
thestig821d59e2016-05-11 12:59:22 -07001360 SetScrollPosY(ptHead.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001361 }
1362 }
1363 }
1364}
1365
dsinclairefd5a992016-07-18 10:04:07 -07001366void CFX_Edit::Refresh() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001367 if (m_bEnableRefresh && m_pVT->IsValid()) {
1368 m_Refresh.BeginRefresh();
1369 RefreshPushLineRects(GetVisibleWordRange());
1370
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001371 m_Refresh.NoAnalyse();
1372 m_ptRefreshScrollPos = m_ptScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001373
dsinclaira2919b32016-07-13 10:55:48 -07001374 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001375 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001376 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001377 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001378 if (const CFX_Edit_RectArray* pRects = m_Refresh.GetRefreshRects()) {
1379 for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
1380 m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
1381 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001382 }
1383 }
1384
1385 m_Refresh.EndRefresh();
1386 }
1387}
1388
1389void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001390 if (!m_pVT->IsValid())
1391 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001392
thestig821d59e2016-05-11 12:59:22 -07001393 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1394 CPVT_WordPlace wpBegin = wr.BeginPos;
1395 m_pVT->UpdateWordPlace(wpBegin);
1396 CPVT_WordPlace wpEnd = wr.EndPos;
1397 m_pVT->UpdateWordPlace(wpEnd);
1398 pIterator->SetAt(wpBegin);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001399
thestig821d59e2016-05-11 12:59:22 -07001400 CPVT_Line lineinfo;
1401 do {
1402 if (!pIterator->GetLine(lineinfo))
1403 break;
1404 if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
1405 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001406
thestig821d59e2016-05-11 12:59:22 -07001407 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1408 lineinfo.ptLine.y + lineinfo.fLineDescent,
1409 lineinfo.ptLine.x + lineinfo.fLineWidth,
1410 lineinfo.ptLine.y + lineinfo.fLineAscent);
1411
1412 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1413 VTToEdit(rcLine));
1414 } while (pIterator->NextLine());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001415}
1416
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001417void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001418 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1419 CPVT_WordRange wrTemp = wr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001420
thestig821d59e2016-05-11 12:59:22 -07001421 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1422 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1423 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001424
thestig821d59e2016-05-11 12:59:22 -07001425 CPVT_Word wordinfo;
1426 CPVT_Line lineinfo;
1427 CPVT_WordPlace place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001428
thestig821d59e2016-05-11 12:59:22 -07001429 while (pIterator->NextWord()) {
1430 place = pIterator->GetAt();
Tom Sepez52f69b32017-03-21 13:42:38 -07001431 if (place > wrTemp.EndPos)
thestig821d59e2016-05-11 12:59:22 -07001432 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001433
thestig821d59e2016-05-11 12:59:22 -07001434 pIterator->GetWord(wordinfo);
1435 pIterator->GetLine(lineinfo);
thestig821d59e2016-05-11 12:59:22 -07001436 if (place.LineCmp(wrTemp.BeginPos) == 0 ||
1437 place.LineCmp(wrTemp.EndPos) == 0) {
1438 CFX_FloatRect rcWord(wordinfo.ptWord.x,
1439 lineinfo.ptLine.y + lineinfo.fLineDescent,
1440 wordinfo.ptWord.x + wordinfo.fWidth,
1441 lineinfo.ptLine.y + lineinfo.fLineAscent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001442
dsinclaira2919b32016-07-13 10:55:48 -07001443 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001444 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001445 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001446 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001447 CFX_FloatRect rcRefresh = VTToEdit(rcWord);
1448 m_pNotify->IOnInvalidateRect(&rcRefresh);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001449 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001450 }
thestig821d59e2016-05-11 12:59:22 -07001451 } else {
1452 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1453 lineinfo.ptLine.y + lineinfo.fLineDescent,
1454 lineinfo.ptLine.x + lineinfo.fLineWidth,
1455 lineinfo.ptLine.y + lineinfo.fLineAscent);
1456
dsinclaira2919b32016-07-13 10:55:48 -07001457 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001458 if (!m_bNotifyFlag) {
Lei Zhanga8c2b912017-03-22 17:41:02 -07001459 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001460 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001461 CFX_FloatRect rcRefresh = VTToEdit(rcLine);
1462 m_pNotify->IOnInvalidateRect(&rcRefresh);
thestig821d59e2016-05-11 12:59:22 -07001463 }
1464 }
1465
1466 pIterator->NextLine();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001467 }
1468 }
1469}
1470
1471void CFX_Edit::SetCaret(const CPVT_WordPlace& place) {
1472 m_wpOldCaret = m_wpCaret;
1473 m_wpCaret = place;
1474}
1475
1476void CFX_Edit::SetCaretInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001477 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001478 if (!m_bNotifyFlag) {
thestig821d59e2016-05-11 12:59:22 -07001479 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1480 pIterator->SetAt(m_wpCaret);
tsepez63f545c2016-09-13 16:08:49 -07001481
Dan Sinclairf528eee2017-02-14 11:52:07 -05001482 CFX_PointF ptHead;
1483 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001484 CPVT_Word word;
1485 CPVT_Line line;
1486 if (pIterator->GetWord(word)) {
1487 ptHead.x = word.ptWord.x + word.fWidth;
1488 ptHead.y = word.ptWord.y + word.fAscent;
1489 ptFoot.x = word.ptWord.x + word.fWidth;
1490 ptFoot.y = word.ptWord.y + word.fDescent;
1491 } else if (pIterator->GetLine(line)) {
1492 ptHead.x = line.ptLine.x;
1493 ptHead.y = line.ptLine.y + line.fLineAscent;
1494 ptFoot.x = line.ptLine.x;
1495 ptFoot.y = line.ptLine.y + line.fLineDescent;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001496 }
1497
Lei Zhanga8c2b912017-03-22 17:41:02 -07001498 CFX_AutoRestorer<bool> restorer(&m_bNotifyFlag);
tsepez4cf55152016-11-02 14:37:54 -07001499 m_bNotifyFlag = true;
Tom Sepez52f69b32017-03-21 13:42:38 -07001500 m_pNotify->IOnSetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead),
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001501 VTToEdit(ptFoot), m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001502 }
1503 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001504}
1505
Dan Sinclairf528eee2017-02-14 11:52:07 -05001506void CFX_Edit::OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001507 if (!m_pVT->IsValid())
1508 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001509
Tom Sepez52f69b32017-03-21 13:42:38 -07001510 SelectNone();
1511 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1512 m_SelState.Set(m_wpCaret, m_wpCaret);
1513 ScrollToCaret();
1514 SetCaretOrigin();
1515 SetCaretInfo();
1516}
1517
1518void CFX_Edit::OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl) {
1519 if (!m_pVT->IsValid())
1520 return;
1521
1522 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1523 if (m_wpCaret == m_wpOldCaret)
1524 return;
1525
1526 m_SelState.SetEndPos(m_wpCaret);
1527 ScrollToCaret();
1528 Refresh();
1529 SetCaretOrigin();
1530 SetCaretInfo();
1531}
1532
1533void CFX_Edit::OnVK_UP(bool bShift, bool bCtrl) {
1534 if (!m_pVT->IsValid())
1535 return;
1536
1537 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1538 if (bShift) {
1539 if (m_SelState.IsEmpty())
1540 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1541 else
1542 m_SelState.SetEndPos(m_wpCaret);
1543
1544 if (m_wpOldCaret != m_wpCaret) {
1545 ScrollToCaret();
1546 Refresh();
1547 SetCaretInfo();
1548 }
1549 } else {
1550 SelectNone();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001551 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001552 SetCaretInfo();
1553 }
1554}
1555
Tom Sepez52f69b32017-03-21 13:42:38 -07001556void CFX_Edit::OnVK_DOWN(bool bShift, bool bCtrl) {
1557 if (!m_pVT->IsValid())
1558 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001559
Tom Sepez52f69b32017-03-21 13:42:38 -07001560 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1561 if (bShift) {
1562 if (m_SelState.IsEmpty())
1563 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1564 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001565 m_SelState.SetEndPos(m_wpCaret);
1566
Tom Sepez52f69b32017-03-21 13:42:38 -07001567 if (m_wpOldCaret != m_wpCaret) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001568 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001569 Refresh();
Tom Sepez52f69b32017-03-21 13:42:38 -07001570 SetCaretInfo();
1571 }
1572 } else {
1573 SelectNone();
1574 ScrollToCaret();
1575 SetCaretInfo();
1576 }
1577}
1578
1579void CFX_Edit::OnVK_LEFT(bool bShift, bool bCtrl) {
1580 if (!m_pVT->IsValid())
1581 return;
1582
1583 if (bShift) {
1584 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1585 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1586 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1587 }
1588 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1589 if (m_SelState.IsEmpty())
1590 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1591 else
1592 m_SelState.SetEndPos(m_wpCaret);
1593
1594 if (m_wpOldCaret != m_wpCaret) {
1595 ScrollToCaret();
1596 Refresh();
1597 SetCaretInfo();
1598 }
1599 } else {
1600 if (!m_SelState.IsEmpty()) {
1601 if (m_SelState.BeginPos < m_SelState.EndPos)
1602 SetCaret(m_SelState.BeginPos);
1603 else
1604 SetCaret(m_SelState.EndPos);
1605
1606 SelectNone();
1607 ScrollToCaret();
1608 SetCaretInfo();
1609 } else {
1610 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1611 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1612 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1613 }
1614 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1615 ScrollToCaret();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001616 SetCaretOrigin();
1617 SetCaretInfo();
1618 }
1619 }
1620}
1621
tsepez4cf55152016-11-02 14:37:54 -07001622void CFX_Edit::OnVK_RIGHT(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001623 if (!m_pVT->IsValid())
1624 return;
1625
1626 if (bShift) {
1627 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1628 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1629 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001630 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1631
Tom Sepez52f69b32017-03-21 13:42:38 -07001632 if (m_SelState.IsEmpty())
1633 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1634 else
1635 m_SelState.SetEndPos(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001636
Tom Sepez52f69b32017-03-21 13:42:38 -07001637 if (m_wpOldCaret != m_wpCaret) {
1638 ScrollToCaret();
1639 Refresh();
1640 SetCaretInfo();
1641 }
1642 } else {
1643 if (!m_SelState.IsEmpty()) {
1644 if (m_SelState.BeginPos > m_SelState.EndPos)
1645 SetCaret(m_SelState.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001646 else
Tom Sepez52f69b32017-03-21 13:42:38 -07001647 SetCaret(m_SelState.EndPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001648
Tom Sepez52f69b32017-03-21 13:42:38 -07001649 SelectNone();
1650 ScrollToCaret();
1651 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001652 } else {
Tom Sepez52f69b32017-03-21 13:42:38 -07001653 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1654 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1655 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001656 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001657 }
Tom Sepez52f69b32017-03-21 13:42:38 -07001658 ScrollToCaret();
1659 SetCaretOrigin();
1660 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001661 }
1662 }
1663}
1664
tsepez4cf55152016-11-02 14:37:54 -07001665void CFX_Edit::OnVK_HOME(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001666 if (!m_pVT->IsValid())
1667 return;
1668
1669 if (bShift) {
1670 if (bCtrl)
1671 SetCaret(m_pVT->GetBeginWordPlace());
1672 else
1673 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1674
1675 if (m_SelState.IsEmpty())
1676 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1677 else
1678 m_SelState.SetEndPos(m_wpCaret);
1679
1680 ScrollToCaret();
1681 Refresh();
1682 SetCaretInfo();
1683 } else {
1684 if (!m_SelState.IsEmpty()) {
1685 SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos));
1686 SelectNone();
1687 ScrollToCaret();
1688 SetCaretInfo();
1689 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001690 if (bCtrl)
1691 SetCaret(m_pVT->GetBeginWordPlace());
1692 else
1693 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1694
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001695 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001696 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001697 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001698 }
1699 }
1700}
1701
tsepez4cf55152016-11-02 14:37:54 -07001702void CFX_Edit::OnVK_END(bool bShift, bool bCtrl) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001703 if (!m_pVT->IsValid())
1704 return;
1705
1706 if (bShift) {
1707 if (bCtrl)
1708 SetCaret(m_pVT->GetEndWordPlace());
1709 else
1710 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1711
1712 if (m_SelState.IsEmpty())
1713 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1714 else
1715 m_SelState.SetEndPos(m_wpCaret);
1716
1717 ScrollToCaret();
1718 Refresh();
1719 SetCaretInfo();
1720 } else {
1721 if (!m_SelState.IsEmpty()) {
1722 SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos));
1723 SelectNone();
1724 ScrollToCaret();
1725 SetCaretInfo();
1726 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001727 if (bCtrl)
1728 SetCaret(m_pVT->GetEndWordPlace());
1729 else
1730 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1731
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001732 ScrollToCaret();
Tom Sepez52f69b32017-03-21 13:42:38 -07001733 SetCaretOrigin();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001734 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001735 }
1736 }
1737}
1738
tsepez4cf55152016-11-02 14:37:54 -07001739bool CFX_Edit::InsertWord(uint16_t word,
1740 int32_t charset,
1741 const CPVT_WordProps* pWordProps,
1742 bool bAddUndo,
1743 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001744 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001745 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001746
Tom Sepez3509d162017-01-30 13:22:02 -08001747 m_pVT->UpdateWordPlace(m_wpCaret);
1748 SetCaret(m_pVT->InsertWord(m_wpCaret, word,
1749 GetCharSetFromUnicode(word, charset), pWordProps));
1750 m_SelState.Set(m_wpCaret, m_wpCaret);
1751 if (m_wpCaret == m_wpOldCaret)
1752 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001753
Tom Sepez3509d162017-01-30 13:22:02 -08001754 if (bAddUndo && m_bEnableUndo) {
1755 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertWord>(
1756 this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001757 }
Tom Sepez3509d162017-01-30 13:22:02 -08001758 if (bPaint)
1759 PaintInsertText(m_wpOldCaret, m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001760
Tom Sepez3509d162017-01-30 13:22:02 -08001761 if (m_bOprNotify && m_pOprNotify)
1762 m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
1763
1764 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001765}
1766
tsepez4cf55152016-11-02 14:37:54 -07001767bool CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps,
1768 const CPVT_WordProps* pWordProps,
1769 bool bAddUndo,
1770 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001771 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001772 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001773
Tom Sepez3509d162017-01-30 13:22:02 -08001774 m_pVT->UpdateWordPlace(m_wpCaret);
1775 SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
1776 m_SelState.Set(m_wpCaret, m_wpCaret);
1777 if (m_wpCaret == m_wpOldCaret)
1778 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001779
Tom Sepez3509d162017-01-30 13:22:02 -08001780 if (bAddUndo && m_bEnableUndo) {
1781 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertReturn>(
1782 this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001783 }
Tom Sepez3509d162017-01-30 13:22:02 -08001784 if (bPaint) {
1785 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1786 ScrollToCaret();
1787 Refresh();
1788 SetCaretOrigin();
1789 SetCaretInfo();
1790 }
1791 if (m_bOprNotify && m_pOprNotify)
1792 m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001793
Tom Sepez3509d162017-01-30 13:22:02 -08001794 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001795}
1796
tsepez4cf55152016-11-02 14:37:54 -07001797bool CFX_Edit::Backspace(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001798 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1799 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001800
Tom Sepez3509d162017-01-30 13:22:02 -08001801 CPVT_Section section;
1802 CPVT_Word word;
1803 if (bAddUndo) {
1804 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1805 pIterator->SetAt(m_wpCaret);
1806 pIterator->GetSection(section);
1807 pIterator->GetWord(word);
1808 }
1809 m_pVT->UpdateWordPlace(m_wpCaret);
1810 SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1811 m_SelState.Set(m_wpCaret, m_wpCaret);
1812 if (m_wpCaret == m_wpOldCaret)
1813 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001814
Tom Sepez3509d162017-01-30 13:22:02 -08001815 if (bAddUndo && m_bEnableUndo) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001816 if (m_wpCaret.nSecIndex != m_wpOldCaret.nSecIndex) {
Tom Sepez3509d162017-01-30 13:22:02 -08001817 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1818 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1819 section.SecProps, section.WordProps));
1820 } else {
1821 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1822 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1823 section.SecProps, word.WordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001824 }
1825 }
Tom Sepez3509d162017-01-30 13:22:02 -08001826 if (bPaint) {
1827 RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
1828 ScrollToCaret();
1829 Refresh();
1830 SetCaretOrigin();
1831 SetCaretInfo();
1832 }
1833 if (m_bOprNotify && m_pOprNotify)
1834 m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001835
Tom Sepez3509d162017-01-30 13:22:02 -08001836 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001837}
1838
tsepez4cf55152016-11-02 14:37:54 -07001839bool CFX_Edit::Delete(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001840 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1841 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001842
Tom Sepez3509d162017-01-30 13:22:02 -08001843 CPVT_Section section;
1844 CPVT_Word word;
1845 if (bAddUndo) {
1846 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1847 pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1848 pIterator->GetSection(section);
1849 pIterator->GetWord(word);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001850 }
Tom Sepez3509d162017-01-30 13:22:02 -08001851 m_pVT->UpdateWordPlace(m_wpCaret);
1852 bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1853 SetCaret(m_pVT->DeleteWord(m_wpCaret));
1854 m_SelState.Set(m_wpCaret, m_wpCaret);
1855 if (bAddUndo && m_bEnableUndo) {
1856 if (bSecEnd) {
1857 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1858 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1859 section.SecProps, section.WordProps, bSecEnd));
1860 } else {
1861 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
1862 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1863 section.SecProps, word.WordProps, bSecEnd));
1864 }
1865 }
1866 if (bPaint) {
1867 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1868 ScrollToCaret();
1869 Refresh();
1870 SetCaretOrigin();
1871 SetCaretInfo();
1872 }
1873 if (m_bOprNotify && m_pOprNotify)
1874 m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001875
Tom Sepez3509d162017-01-30 13:22:02 -08001876 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001877}
1878
tsepez4cf55152016-11-02 14:37:54 -07001879bool CFX_Edit::Empty() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001880 if (m_pVT->IsValid()) {
1881 m_pVT->DeleteWords(GetWholeWordRange());
1882 SetCaret(m_pVT->GetBeginWordPlace());
1883
tsepez4cf55152016-11-02 14:37:54 -07001884 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001885 }
1886
tsepez4cf55152016-11-02 14:37:54 -07001887 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001888}
1889
tsepez4cf55152016-11-02 14:37:54 -07001890bool CFX_Edit::Clear(bool bAddUndo, bool bPaint) {
Tom Sepez52f69b32017-03-21 13:42:38 -07001891 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
tsepez4cf55152016-11-02 14:37:54 -07001892 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001893
thestig821d59e2016-05-11 12:59:22 -07001894 CPVT_WordRange range = m_SelState.ConvertToWordRange();
dsinclaira2919b32016-07-13 10:55:48 -07001895 if (bAddUndo && m_bEnableUndo)
Tom Sepez3509d162017-01-30 13:22:02 -08001896 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Clear>(this, range, GetSelText()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001897
thestig821d59e2016-05-11 12:59:22 -07001898 SelectNone();
1899 SetCaret(m_pVT->DeleteWords(range));
1900 m_SelState.Set(m_wpCaret, m_wpCaret);
thestig821d59e2016-05-11 12:59:22 -07001901 if (bPaint) {
1902 RearrangePart(range);
1903 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001904 Refresh();
thestig821d59e2016-05-11 12:59:22 -07001905 SetCaretOrigin();
1906 SetCaretInfo();
1907 }
thestig821d59e2016-05-11 12:59:22 -07001908 if (m_bOprNotify && m_pOprNotify)
1909 m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);
1910
tsepez4cf55152016-11-02 14:37:54 -07001911 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001912}
1913
tsepez4cf55152016-11-02 14:37:54 -07001914bool CFX_Edit::InsertText(const CFX_WideString& sText,
1915 int32_t charset,
1916 bool bAddUndo,
1917 bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001918 if (IsTextOverflow())
tsepez4cf55152016-11-02 14:37:54 -07001919 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001920
1921 m_pVT->UpdateWordPlace(m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001922 SetCaret(DoInsertText(m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001923 m_SelState.Set(m_wpCaret, m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07001924 if (m_wpCaret == m_wpOldCaret)
tsepez4cf55152016-11-02 14:37:54 -07001925 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001926
tsepeza31da742016-09-08 11:28:14 -07001927 if (bAddUndo && m_bEnableUndo) {
Tom Sepez3509d162017-01-30 13:22:02 -08001928 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertText>(
1929 this, m_wpOldCaret, m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001930 }
tsepeza31da742016-09-08 11:28:14 -07001931 if (bPaint)
1932 PaintInsertText(m_wpOldCaret, m_wpCaret);
1933
1934 if (m_bOprNotify && m_pOprNotify)
1935 m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
1936
tsepez4cf55152016-11-02 14:37:54 -07001937 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001938}
1939
1940void CFX_Edit::PaintInsertText(const CPVT_WordPlace& wpOld,
1941 const CPVT_WordPlace& wpNew) {
1942 if (m_pVT->IsValid()) {
1943 RearrangePart(CPVT_WordRange(wpOld, wpNew));
1944 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001945 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001946 SetCaretOrigin();
1947 SetCaretInfo();
1948 }
1949}
1950
tsepez4cf55152016-11-02 14:37:54 -07001951bool CFX_Edit::Redo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001952 if (m_bEnableUndo) {
1953 if (m_Undo.CanRedo()) {
1954 m_Undo.Redo();
tsepez4cf55152016-11-02 14:37:54 -07001955 return true;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001956 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001957 }
1958
tsepez4cf55152016-11-02 14:37:54 -07001959 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001960}
1961
tsepez4cf55152016-11-02 14:37:54 -07001962bool CFX_Edit::Undo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001963 if (m_bEnableUndo) {
1964 if (m_Undo.CanUndo()) {
1965 m_Undo.Undo();
tsepez4cf55152016-11-02 14:37:54 -07001966 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001967 }
1968 }
1969
tsepez4cf55152016-11-02 14:37:54 -07001970 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001971}
1972
1973void CFX_Edit::SetCaretOrigin() {
thestig821d59e2016-05-11 12:59:22 -07001974 if (!m_pVT->IsValid())
1975 return;
1976
1977 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1978 pIterator->SetAt(m_wpCaret);
1979 CPVT_Word word;
1980 CPVT_Line line;
1981 if (pIterator->GetWord(word)) {
1982 m_ptCaret.x = word.ptWord.x + word.fWidth;
1983 m_ptCaret.y = word.ptWord.y;
1984 } else if (pIterator->GetLine(line)) {
1985 m_ptCaret.x = line.ptLine.x;
1986 m_ptCaret.y = line.ptLine.y;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001987 }
1988}
1989
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001990CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const {
1991 if (m_pVT->IsValid())
1992 return m_pVT->WordIndexToWordPlace(index);
1993
1994 return CPVT_WordPlace();
1995}
1996
tsepez4cf55152016-11-02 14:37:54 -07001997bool CFX_Edit::IsTextFull() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001998 int32_t nTotalWords = m_pVT->GetTotalWords();
1999 int32_t nLimitChar = m_pVT->GetLimitChar();
2000 int32_t nCharArray = m_pVT->GetCharArray();
2001
2002 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
2003 (nCharArray > 0 && nTotalWords >= nCharArray);
2004}
2005
tsepez4cf55152016-11-02 14:37:54 -07002006bool CFX_Edit::IsTextOverflow() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002007 if (!m_bEnableScroll && !m_bEnableOverflow) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002008 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
2009 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002010
dsinclair448c4332016-08-02 12:07:35 -07002011 if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
2012 IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
tsepez4cf55152016-11-02 14:37:54 -07002013 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002014 }
2015
dsinclair448c4332016-08-02 12:07:35 -07002016 if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
tsepez4cf55152016-11-02 14:37:54 -07002017 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002018 }
2019
tsepez4cf55152016-11-02 14:37:54 -07002020 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002021}
2022
tsepez4cf55152016-11-02 14:37:54 -07002023bool CFX_Edit::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002024 if (m_bEnableUndo) {
2025 return m_Undo.CanUndo();
2026 }
2027
tsepez4cf55152016-11-02 14:37:54 -07002028 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002029}
2030
tsepez4cf55152016-11-02 14:37:54 -07002031bool CFX_Edit::CanRedo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002032 if (m_bEnableUndo) {
2033 return m_Undo.CanRedo();
2034 }
2035
tsepez4cf55152016-11-02 14:37:54 -07002036 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002037}
2038
tsepez4cf55152016-11-02 14:37:54 -07002039void CFX_Edit::EnableRefresh(bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002040 m_bEnableRefresh = bRefresh;
2041}
2042
tsepez4cf55152016-11-02 14:37:54 -07002043void CFX_Edit::EnableUndo(bool bUndo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002044 m_bEnableUndo = bUndo;
2045}
2046
tsepez4cf55152016-11-02 14:37:54 -07002047void CFX_Edit::EnableOprNotify(bool bNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002048 m_bOprNotify = bNotify;
2049}
2050
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002051CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place,
tsepeza31da742016-09-08 11:28:14 -07002052 const CFX_WideString& sText,
dsinclairefd5a992016-07-18 10:04:07 -07002053 int32_t charset) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002054 CPVT_WordPlace wp = place;
2055
2056 if (m_pVT->IsValid()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002057 for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
Tom Sepez62a70f92016-03-21 15:00:20 -07002058 uint16_t word = sText[i];
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002059 switch (word) {
2060 case 0x0D:
dsinclairefd5a992016-07-18 10:04:07 -07002061 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002062 if (sText[i + 1] == 0x0A)
2063 i++;
2064 break;
2065 case 0x0A:
dsinclairefd5a992016-07-18 10:04:07 -07002066 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002067 if (sText[i + 1] == 0x0D)
2068 i++;
2069 break;
2070 case 0x09:
2071 word = 0x20;
2072 default:
2073 wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
dsinclairefd5a992016-07-18 10:04:07 -07002074 nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002075 break;
2076 }
2077 }
2078 }
2079
2080 return wp;
2081}
2082
Tom Sepez62a70f92016-03-21 15:00:20 -07002083int32_t CFX_Edit::GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset) {
dsinclairc7a73492016-04-05 12:01:42 -07002084 if (IPVT_FontMap* pFontMap = GetFontMap())
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002085 return pFontMap->CharSetFromUnicode(word, nOldCharset);
2086 return nOldCharset;
2087}
2088
Tom Sepez3509d162017-01-30 13:22:02 -08002089void CFX_Edit::AddEditUndoItem(
2090 std::unique_ptr<CFX_Edit_UndoItem> pEditUndoItem) {
Lei Zhang1a89e362017-03-23 15:27:25 -07002091 m_Undo.AddItem(std::move(pEditUndoItem));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002092}
2093
weili625ad662016-06-15 11:21:33 -07002094CFX_Edit_LineRectArray::CFX_Edit_LineRectArray() {}
2095
Tom Sepez3509d162017-01-30 13:22:02 -08002096CFX_Edit_LineRectArray::~CFX_Edit_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07002097
Tom Sepez3509d162017-01-30 13:22:02 -08002098void CFX_Edit_LineRectArray::operator=(CFX_Edit_LineRectArray&& that) {
2099 m_LineRects = std::move(that.m_LineRects);
weili625ad662016-06-15 11:21:33 -07002100}
2101
2102void CFX_Edit_LineRectArray::Add(const CPVT_WordRange& wrLine,
2103 const CFX_FloatRect& rcLine) {
Tom Sepez3509d162017-01-30 13:22:02 -08002104 m_LineRects.push_back(pdfium::MakeUnique<CFX_Edit_LineRect>(wrLine, rcLine));
weili625ad662016-06-15 11:21:33 -07002105}
2106
2107int32_t CFX_Edit_LineRectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08002108 return pdfium::CollectionSize<int32_t>(m_LineRects);
weili625ad662016-06-15 11:21:33 -07002109}
2110
2111CFX_Edit_LineRect* CFX_Edit_LineRectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002112 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002113 return nullptr;
2114
Tom Sepez3509d162017-01-30 13:22:02 -08002115 return m_LineRects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002116}
2117
2118CFX_Edit_Select::CFX_Edit_Select() {}
2119
weili625ad662016-06-15 11:21:33 -07002120CFX_Edit_Select::CFX_Edit_Select(const CPVT_WordRange& range) {
2121 Set(range.BeginPos, range.EndPos);
2122}
2123
2124CPVT_WordRange CFX_Edit_Select::ConvertToWordRange() const {
2125 return CPVT_WordRange(BeginPos, EndPos);
2126}
2127
Tom Sepez52f69b32017-03-21 13:42:38 -07002128void CFX_Edit_Select::Reset() {
2129 BeginPos.Reset();
2130 EndPos.Reset();
weili625ad662016-06-15 11:21:33 -07002131}
2132
2133void CFX_Edit_Select::Set(const CPVT_WordPlace& begin,
2134 const CPVT_WordPlace& end) {
2135 BeginPos = begin;
2136 EndPos = end;
2137}
2138
weili625ad662016-06-15 11:21:33 -07002139void CFX_Edit_Select::SetEndPos(const CPVT_WordPlace& end) {
2140 EndPos = end;
2141}
2142
Tom Sepez52f69b32017-03-21 13:42:38 -07002143bool CFX_Edit_Select::IsEmpty() const {
2144 return BeginPos == EndPos;
weili625ad662016-06-15 11:21:33 -07002145}
2146
weili625ad662016-06-15 11:21:33 -07002147CFX_Edit_RectArray::CFX_Edit_RectArray() {}
2148
Tom Sepez3509d162017-01-30 13:22:02 -08002149CFX_Edit_RectArray::~CFX_Edit_RectArray() {}
weili625ad662016-06-15 11:21:33 -07002150
Tom Sepez3509d162017-01-30 13:22:02 -08002151void CFX_Edit_RectArray::Clear() {
2152 m_Rects.clear();
weili625ad662016-06-15 11:21:33 -07002153}
2154
2155void CFX_Edit_RectArray::Add(const CFX_FloatRect& rect) {
2156 // check for overlapped area
Tom Sepez3509d162017-01-30 13:22:02 -08002157 for (const auto& pRect : m_Rects) {
weili625ad662016-06-15 11:21:33 -07002158 if (pRect && pRect->Contains(rect))
2159 return;
2160 }
Tom Sepez3509d162017-01-30 13:22:02 -08002161 m_Rects.push_back(pdfium::MakeUnique<CFX_FloatRect>(rect));
weili625ad662016-06-15 11:21:33 -07002162}
2163
2164int32_t CFX_Edit_RectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08002165 return pdfium::CollectionSize<int32_t>(m_Rects);
weili625ad662016-06-15 11:21:33 -07002166}
2167
2168CFX_FloatRect* CFX_Edit_RectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002169 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002170 return nullptr;
2171
Tom Sepez3509d162017-01-30 13:22:02 -08002172 return m_Rects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002173}