blob: 5b6fd556850338398f86482b8f60f68ea7e458c8 [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>
11#include <utility>
Lei Zhang375a8642016-01-11 11:59:17 -080012
dsinclairbc5e6d22016-10-04 11:08:49 -070013#include "core/fpdfapi/font/cpdf_font.h"
dsinclair41872fa2016-10-04 11:29:35 -070014#include "core/fpdfapi/page/cpdf_pageobject.h"
15#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
16#include "core/fpdfapi/page/cpdf_pathobject.h"
17#include "core/fpdfapi/page/cpdf_textobject.h"
dsinclair488b7ad2016-10-04 11:55:50 -070018#include "core/fpdfapi/parser/fpdf_parser_decode.h"
dsinclair69d9c682016-10-04 12:18:35 -070019#include "core/fpdfapi/render/cpdf_renderoptions.h"
20#include "core/fpdfapi/render/cpdf_textrenderer.h"
dsinclair1727aee2016-09-29 13:12:56 -070021#include "core/fpdfdoc/cpvt_section.h"
22#include "core/fpdfdoc/cpvt_word.h"
23#include "core/fpdfdoc/ipvt_fontmap.h"
dsinclair74a34fc2016-09-29 16:41:42 -070024#include "core/fxge/cfx_graphstatedata.h"
25#include "core/fxge/cfx_pathdata.h"
26#include "core/fxge/cfx_renderdevice.h"
dsinclaire35af1e2016-07-13 11:26:20 -070027#include "fpdfsdk/cfx_systemhandler.h"
dsinclair0bb385b2016-09-29 17:03:59 -070028#include "fpdfsdk/fxedit/fx_edit.h"
dsinclaire35af1e2016-07-13 11:26:20 -070029#include "fpdfsdk/pdfwindow/PWL_Edit.h"
30#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
tsepez36eb4bd2016-10-03 15:24:27 -070031#include "third_party/base/ptr_util.h"
Tom Sepez3509d162017-01-30 13:22:02 -080032#include "third_party/base/stl_util.h"
dsinclaire35af1e2016-07-13 11:26:20 -070033
dsinclair8f4bf9a2016-05-04 13:51:51 -070034namespace {
35
36const int kEditUndoMaxItems = 10000;
37
dsinclaire35af1e2016-07-13 11:26:20 -070038CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) {
39 if (strWords.GetLength() > 0)
40 return PDF_EncodeString(strWords) + " Tj\n";
41 return CFX_ByteString();
42}
43
44CFX_ByteString GetFontSetString(IPVT_FontMap* pFontMap,
45 int32_t nFontIndex,
46 FX_FLOAT fFontSize) {
47 if (!pFontMap)
48 return CFX_ByteString();
49
50 CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
51 if (sFontAlias.GetLength() <= 0 || fFontSize <= 0)
52 return CFX_ByteString();
53
54 CFX_ByteTextBuf sRet;
55 sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
56 return sRet.MakeString();
57}
58
dsinclaire35af1e2016-07-13 11:26:20 -070059void DrawTextString(CFX_RenderDevice* pDevice,
Dan Sinclairf528eee2017-02-14 11:52:07 -050060 const CFX_PointF& pt,
dsinclaire35af1e2016-07-13 11:26:20 -070061 CPDF_Font* pFont,
62 FX_FLOAT fFontSize,
63 CFX_Matrix* pUser2Device,
64 const CFX_ByteString& str,
65 FX_ARGB crTextFill,
66 FX_ARGB crTextStroke,
67 int32_t nHorzScale) {
68 FX_FLOAT x = pt.x, y = pt.y;
Dan Sinclairafb44562017-02-09 13:07:43 -050069 pUser2Device->TransformPoint(x, y);
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
80 if (crTextStroke != 0) {
Dan Sinclairf528eee2017-02-14 11:52:07 -050081 CFX_PointF pt1;
82 CFX_PointF pt2;
Dan Sinclairafb44562017-02-09 13:07:43 -050083 pUser2Device->TransformPoint(pt1.x, pt1.y);
84 pUser2Device->TransformPoint(pt2.x, pt2.y);
dsinclaire35af1e2016-07-13 11:26:20 -070085 CFX_GraphStateData gsd;
86 gsd.m_LineWidth =
87 (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
88
89 CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
90 str, crTextFill, crTextStroke, &gsd,
91 &ro);
92 } else {
93 CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
94 str, crTextFill, 0, nullptr, &ro);
95 }
96 } else {
97 CPDF_RenderOptions ro;
98 ro.m_Flags = RENDER_CLEARTYPE;
99 ro.m_ColorMode = RENDER_COLOR_NORMAL;
100
101 if (crTextStroke != 0) {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500102 CFX_PointF pt1;
103 CFX_PointF pt2;
Dan Sinclairafb44562017-02-09 13:07:43 -0500104 pUser2Device->TransformPoint(pt1.x, pt1.y);
105 pUser2Device->TransformPoint(pt2.x, pt2.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700106 CFX_GraphStateData gsd;
107 gsd.m_LineWidth =
108 (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
109
110 CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
111 pUser2Device, str, crTextFill,
112 crTextStroke, &gsd, &ro);
113 } else {
114 CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
115 pUser2Device, str, crTextFill, 0,
116 nullptr, &ro);
117 }
118 }
119 }
120}
121
dsinclair8f4bf9a2016-05-04 13:51:51 -0700122} // namespace
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700123
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit* pEdit,
dsinclairc7a73492016-04-05 12:01:42 -0700125 CPDF_VariableText::Iterator* pVTIterator)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {}
127
128CFX_Edit_Iterator::~CFX_Edit_Iterator() {}
129
tsepez4cf55152016-11-02 14:37:54 -0700130bool CFX_Edit_Iterator::NextWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 return m_pVTIterator->NextWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700132}
133
tsepez4cf55152016-11-02 14:37:54 -0700134bool CFX_Edit_Iterator::PrevWord() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 return m_pVTIterator->PrevWord();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700136}
137
tsepez4cf55152016-11-02 14:37:54 -0700138bool CFX_Edit_Iterator::GetWord(CPVT_Word& word) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700139 ASSERT(m_pEdit);
140
141 if (m_pVTIterator->GetWord(word)) {
142 word.ptWord = m_pEdit->VTToEdit(word.ptWord);
tsepez4cf55152016-11-02 14:37:54 -0700143 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 }
tsepez4cf55152016-11-02 14:37:54 -0700145 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700146}
147
tsepez4cf55152016-11-02 14:37:54 -0700148bool CFX_Edit_Iterator::GetLine(CPVT_Line& line) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149 ASSERT(m_pEdit);
150
151 if (m_pVTIterator->GetLine(line)) {
152 line.ptLine = m_pEdit->VTToEdit(line.ptLine);
tsepez4cf55152016-11-02 14:37:54 -0700153 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700154 }
tsepez4cf55152016-11-02 14:37:54 -0700155 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700156}
157
tsepez4cf55152016-11-02 14:37:54 -0700158bool CFX_Edit_Iterator::GetSection(CPVT_Section& section) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 ASSERT(m_pEdit);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700160
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 if (m_pVTIterator->GetSection(section)) {
162 section.rcSection = m_pEdit->VTToEdit(section.rcSection);
tsepez4cf55152016-11-02 14:37:54 -0700163 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164 }
tsepez4cf55152016-11-02 14:37:54 -0700165 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700166}
167
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168void CFX_Edit_Iterator::SetAt(int32_t nWordIndex) {
169 m_pVTIterator->SetAt(nWordIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700170}
171
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace& place) {
173 m_pVTIterator->SetAt(place);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174}
175
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176const CPVT_WordPlace& CFX_Edit_Iterator::GetAt() const {
177 return m_pVTIterator->GetAt();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700178}
179
dsinclairc7a73492016-04-05 12:01:42 -0700180CFX_Edit_Provider::CFX_Edit_Provider(IPVT_FontMap* pFontMap)
181 : CPDF_VariableText::Provider(pFontMap), m_pFontMap(pFontMap) {
Lei Zhang96660d62015-12-14 18:27:25 -0800182 ASSERT(m_pFontMap);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700183}
184
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185CFX_Edit_Provider::~CFX_Edit_Provider() {}
186
dsinclairc7a73492016-04-05 12:01:42 -0700187IPVT_FontMap* CFX_Edit_Provider::GetFontMap() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188 return m_pFontMap;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700189}
190
npm41d6bbe2016-09-14 11:54:44 -0700191int32_t CFX_Edit_Provider::GetCharWidth(int32_t nFontIndex, uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700192 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
tsepezc3255f52016-03-25 14:52:27 -0700193 uint32_t charcode = word;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700194
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700195 if (pPDFFont->IsUnicodeCompatible())
196 charcode = pPDFFont->CharCodeFromUnicode(word);
197 else
198 charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);
199
Wei Li89409932016-03-28 10:33:33 -0700200 if (charcode != CPDF_Font::kInvalidCharCode)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201 return pPDFFont->GetCharWidthF(charcode);
202 }
203
204 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700205}
206
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207int32_t CFX_Edit_Provider::GetTypeAscent(int32_t nFontIndex) {
208 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
209 return pPDFFont->GetTypeAscent();
210
211 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700212}
213
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700214int32_t CFX_Edit_Provider::GetTypeDescent(int32_t nFontIndex) {
215 if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
216 return pPDFFont->GetTypeDescent();
217
218 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700219}
220
Tom Sepez62a70f92016-03-21 15:00:20 -0700221int32_t CFX_Edit_Provider::GetWordFontIndex(uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222 int32_t charset,
223 int32_t nFontIndex) {
224 return m_pFontMap->GetWordFontIndex(word, charset, nFontIndex);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700225}
226
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700227int32_t CFX_Edit_Provider::GetDefaultFontIndex() {
228 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700229}
230
tsepez4cf55152016-11-02 14:37:54 -0700231bool CFX_Edit_Provider::IsLatinWord(uint16_t word) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232 return FX_EDIT_ISLATINWORD(word);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700233}
234
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235CFX_Edit_Refresh::CFX_Edit_Refresh() {}
236
237CFX_Edit_Refresh::~CFX_Edit_Refresh() {}
238
239void CFX_Edit_Refresh::BeginRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800240 m_RefreshRects.Clear();
241 m_OldLineRects = std::move(m_NewLineRects);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700242}
243
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244void CFX_Edit_Refresh::Push(const CPVT_WordRange& linerange,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800245 const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 m_NewLineRects.Add(linerange, rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700247}
248
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249void CFX_Edit_Refresh::NoAnalyse() {
250 {
251 for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
252 if (CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i))
253 m_RefreshRects.Add(pOldRect->m_rcLine);
254 }
255
256 {
257 for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
258 if (CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i))
259 m_RefreshRects.Add(pNewRect->m_rcLine);
260 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700261}
262
Tom Sepez281a9ea2016-02-26 14:24:28 -0800263void CFX_Edit_Refresh::AddRefresh(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700264 m_RefreshRects.Add(rect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700265}
266
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const {
268 return &m_RefreshRects;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700269}
270
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271void CFX_Edit_Refresh::EndRefresh() {
Tom Sepez3509d162017-01-30 13:22:02 -0800272 m_RefreshRects.Clear();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700273}
274
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize)
276 : m_nCurUndoPos(0),
277 m_nBufSize(nBufsize),
tsepez4cf55152016-11-02 14:37:54 -0700278 m_bModified(false),
279 m_bVirgin(true),
280 m_bWorking(false) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281
282CFX_Edit_Undo::~CFX_Edit_Undo() {
283 Reset();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700284}
285
tsepez4cf55152016-11-02 14:37:54 -0700286bool CFX_Edit_Undo::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287 return m_nCurUndoPos > 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700288}
289
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290void CFX_Edit_Undo::Undo() {
tsepez4cf55152016-11-02 14:37:54 -0700291 m_bWorking = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700292 if (m_nCurUndoPos > 0) {
Tom Sepez3509d162017-01-30 13:22:02 -0800293 m_UndoItemStack[m_nCurUndoPos - 1]->Undo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294 m_nCurUndoPos--;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700295 m_bModified = (m_nCurUndoPos != 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 }
tsepez4cf55152016-11-02 14:37:54 -0700297 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700298}
299
tsepez4cf55152016-11-02 14:37:54 -0700300bool CFX_Edit_Undo::CanRedo() const {
Tom Sepez3509d162017-01-30 13:22:02 -0800301 return m_nCurUndoPos < m_UndoItemStack.size();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700302}
303
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304void CFX_Edit_Undo::Redo() {
tsepez4cf55152016-11-02 14:37:54 -0700305 m_bWorking = true;
Tom Sepez3509d162017-01-30 13:22:02 -0800306 if (m_nCurUndoPos < m_UndoItemStack.size()) {
307 m_UndoItemStack[m_nCurUndoPos]->Redo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308 m_nCurUndoPos++;
Tom Sepez3509d162017-01-30 13:22:02 -0800309 m_bModified = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310 }
tsepez4cf55152016-11-02 14:37:54 -0700311 m_bWorking = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700312}
313
Tom Sepez3509d162017-01-30 13:22:02 -0800314void CFX_Edit_Undo::AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700315 ASSERT(!m_bWorking);
Lei Zhang96660d62015-12-14 18:27:25 -0800316 ASSERT(pItem);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317 ASSERT(m_nBufSize > 1);
Tom Sepez3509d162017-01-30 13:22:02 -0800318 if (m_nCurUndoPos < m_UndoItemStack.size())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700319 RemoveTails();
320
Tom Sepez3509d162017-01-30 13:22:02 -0800321 if (m_UndoItemStack.size() >= m_nBufSize) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700322 RemoveHeads();
tsepez4cf55152016-11-02 14:37:54 -0700323 m_bVirgin = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324 }
325
Tom Sepez3509d162017-01-30 13:22:02 -0800326 m_UndoItemStack.push_back(std::move(pItem));
327 m_nCurUndoPos = m_UndoItemStack.size();
328 m_bModified = true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700329}
330
tsepez4cf55152016-11-02 14:37:54 -0700331bool CFX_Edit_Undo::IsModified() const {
332 return m_bVirgin ? m_bModified : true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700333}
334
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700335void CFX_Edit_Undo::RemoveHeads() {
Tom Sepez3509d162017-01-30 13:22:02 -0800336 ASSERT(m_UndoItemStack.size() > 1);
337 m_UndoItemStack.pop_front();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700338}
339
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340void CFX_Edit_Undo::RemoveTails() {
Tom Sepez3509d162017-01-30 13:22:02 -0800341 while (m_UndoItemStack.size() > m_nCurUndoPos)
342 m_UndoItemStack.pop_back();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700343}
344
345void CFX_Edit_Undo::Reset() {
Tom Sepez3509d162017-01-30 13:22:02 -0800346 m_UndoItemStack.clear();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700347 m_nCurUndoPos = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700348}
349
tsepez4cf55152016-11-02 14:37:54 -0700350CFX_Edit_UndoItem::CFX_Edit_UndoItem() : m_bFirst(true), m_bLast(true) {}
weili625ad662016-06-15 11:21:33 -0700351
352CFX_Edit_UndoItem::~CFX_Edit_UndoItem() {}
353
Tom Sepez3509d162017-01-30 13:22:02 -0800354CFX_WideString CFX_Edit_UndoItem::GetUndoTitle() const {
355 return CFX_WideString();
weili625ad662016-06-15 11:21:33 -0700356}
357
tsepez4cf55152016-11-02 14:37:54 -0700358void CFX_Edit_UndoItem::SetFirst(bool bFirst) {
weili625ad662016-06-15 11:21:33 -0700359 m_bFirst = bFirst;
360}
361
tsepez4cf55152016-11-02 14:37:54 -0700362void CFX_Edit_UndoItem::SetLast(bool bLast) {
weili625ad662016-06-15 11:21:33 -0700363 m_bLast = bLast;
364}
365
tsepez4cf55152016-11-02 14:37:54 -0700366bool CFX_Edit_UndoItem::IsLast() {
weili625ad662016-06-15 11:21:33 -0700367 return m_bLast;
368}
369
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700370CFX_Edit_GroupUndoItem::CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle)
371 : m_sTitle(sTitle) {}
372
Tom Sepez3509d162017-01-30 13:22:02 -0800373CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700374
Tom Sepez3509d162017-01-30 13:22:02 -0800375void CFX_Edit_GroupUndoItem::AddUndoItem(
376 std::unique_ptr<CFX_Edit_UndoItem> pUndoItem) {
tsepez4cf55152016-11-02 14:37:54 -0700377 pUndoItem->SetFirst(false);
378 pUndoItem->SetLast(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700379 if (m_sTitle.IsEmpty())
380 m_sTitle = pUndoItem->GetUndoTitle();
Tom Sepez3509d162017-01-30 13:22:02 -0800381
382 m_Items.push_back(std::move(pUndoItem));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700383}
384
385void CFX_Edit_GroupUndoItem::UpdateItems() {
Tom Sepez3509d162017-01-30 13:22:02 -0800386 if (!m_Items.empty()) {
387 m_Items.front()->SetFirst(true);
388 m_Items.back()->SetLast(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700389 }
390}
391
392void CFX_Edit_GroupUndoItem::Undo() {
Tom Sepez3509d162017-01-30 13:22:02 -0800393 for (auto iter = m_Items.rbegin(); iter != m_Items.rend(); ++iter)
394 (*iter)->Undo();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700395}
396
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700397void CFX_Edit_GroupUndoItem::Redo() {
Tom Sepez3509d162017-01-30 13:22:02 -0800398 for (auto iter = m_Items.begin(); iter != m_Items.end(); ++iter)
399 (*iter)->Redo();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700400}
401
Tom Sepez3509d162017-01-30 13:22:02 -0800402CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700403 return m_sTitle;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700404}
405
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700406CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit* pEdit,
407 const CPVT_WordPlace& wpOldPlace,
408 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700409 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700410 int32_t charset,
411 const CPVT_WordProps* pWordProps)
412 : m_pEdit(pEdit),
413 m_wpOld(wpOldPlace),
414 m_wpNew(wpNewPlace),
415 m_Word(word),
416 m_nCharset(charset),
417 m_WordProps() {
418 if (pWordProps)
419 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700420}
421
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700422CFXEU_InsertWord::~CFXEU_InsertWord() {}
423
424void CFXEU_InsertWord::Redo() {
425 if (m_pEdit) {
426 m_pEdit->SelectNone();
427 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700428 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700429 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700430}
431
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700432void CFXEU_InsertWord::Undo() {
433 if (m_pEdit) {
434 m_pEdit->SelectNone();
435 m_pEdit->SetCaret(m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700436 m_pEdit->Backspace(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700437 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700438}
439
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700440CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit* pEdit,
441 const CPVT_WordPlace& wpOldPlace,
442 const CPVT_WordPlace& wpNewPlace,
443 const CPVT_SecProps* pSecProps,
444 const CPVT_WordProps* pWordProps)
445 : m_pEdit(pEdit),
446 m_wpOld(wpOldPlace),
447 m_wpNew(wpNewPlace),
448 m_SecProps(),
449 m_WordProps() {
450 if (pSecProps)
451 m_SecProps = *pSecProps;
452 if (pWordProps)
453 m_WordProps = *pWordProps;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700454}
455
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700456CFXEU_InsertReturn::~CFXEU_InsertReturn() {}
457
458void CFXEU_InsertReturn::Redo() {
459 if (m_pEdit) {
460 m_pEdit->SelectNone();
461 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700462 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700463 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700464}
465
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700466void CFXEU_InsertReturn::Undo() {
467 if (m_pEdit) {
468 m_pEdit->SelectNone();
469 m_pEdit->SetCaret(m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700470 m_pEdit->Backspace(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700471 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700472}
473
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700474CFXEU_Backspace::CFXEU_Backspace(CFX_Edit* pEdit,
475 const CPVT_WordPlace& wpOldPlace,
476 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700477 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700478 int32_t charset,
479 const CPVT_SecProps& SecProps,
480 const CPVT_WordProps& WordProps)
481 : m_pEdit(pEdit),
482 m_wpOld(wpOldPlace),
483 m_wpNew(wpNewPlace),
484 m_Word(word),
485 m_nCharset(charset),
486 m_SecProps(SecProps),
487 m_WordProps(WordProps) {}
488
489CFXEU_Backspace::~CFXEU_Backspace() {}
490
491void CFXEU_Backspace::Redo() {
492 if (m_pEdit) {
493 m_pEdit->SelectNone();
494 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700495 m_pEdit->Backspace(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700496 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700497}
498
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700499void CFXEU_Backspace::Undo() {
500 if (m_pEdit) {
501 m_pEdit->SelectNone();
502 m_pEdit->SetCaret(m_wpNew);
503 if (m_wpNew.SecCmp(m_wpOld) != 0) {
tsepez4cf55152016-11-02 14:37:54 -0700504 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700505 } else {
tsepez4cf55152016-11-02 14:37:54 -0700506 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700507 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700508 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700509}
510
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700511CFXEU_Delete::CFXEU_Delete(CFX_Edit* pEdit,
512 const CPVT_WordPlace& wpOldPlace,
513 const CPVT_WordPlace& wpNewPlace,
Tom Sepez62a70f92016-03-21 15:00:20 -0700514 uint16_t word,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700515 int32_t charset,
516 const CPVT_SecProps& SecProps,
517 const CPVT_WordProps& WordProps,
tsepez4cf55152016-11-02 14:37:54 -0700518 bool bSecEnd)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700519 : m_pEdit(pEdit),
520 m_wpOld(wpOldPlace),
521 m_wpNew(wpNewPlace),
522 m_Word(word),
523 m_nCharset(charset),
524 m_SecProps(SecProps),
525 m_WordProps(WordProps),
526 m_bSecEnd(bSecEnd) {}
527
528CFXEU_Delete::~CFXEU_Delete() {}
529
530void CFXEU_Delete::Redo() {
531 if (m_pEdit) {
532 m_pEdit->SelectNone();
533 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700534 m_pEdit->Delete(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700535 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700536}
537
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700538void CFXEU_Delete::Undo() {
539 if (m_pEdit) {
540 m_pEdit->SelectNone();
541 m_pEdit->SetCaret(m_wpNew);
542 if (m_bSecEnd) {
tsepez4cf55152016-11-02 14:37:54 -0700543 m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700544 } else {
tsepez4cf55152016-11-02 14:37:54 -0700545 m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700546 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700547 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700548}
549
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700550CFXEU_Clear::CFXEU_Clear(CFX_Edit* pEdit,
551 const CPVT_WordRange& wrSel,
552 const CFX_WideString& swText)
553 : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {}
554
555CFXEU_Clear::~CFXEU_Clear() {}
556
557void CFXEU_Clear::Redo() {
558 if (m_pEdit) {
559 m_pEdit->SelectNone();
560 m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
tsepez4cf55152016-11-02 14:37:54 -0700561 m_pEdit->Clear(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700562 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700563}
564
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700565void CFXEU_Clear::Undo() {
566 if (m_pEdit) {
567 m_pEdit->SelectNone();
568 m_pEdit->SetCaret(m_wrSel.BeginPos);
tsepez4cf55152016-11-02 14:37:54 -0700569 m_pEdit->InsertText(m_swText, FXFONT_DEFAULT_CHARSET, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700570 m_pEdit->SetSel(m_wrSel.BeginPos, m_wrSel.EndPos);
571 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700572}
573
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700574CFXEU_InsertText::CFXEU_InsertText(CFX_Edit* pEdit,
575 const CPVT_WordPlace& wpOldPlace,
576 const CPVT_WordPlace& wpNewPlace,
577 const CFX_WideString& swText,
dsinclairefd5a992016-07-18 10:04:07 -0700578 int32_t charset)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579 : m_pEdit(pEdit),
580 m_wpOld(wpOldPlace),
581 m_wpNew(wpNewPlace),
582 m_swText(swText),
dsinclairefd5a992016-07-18 10:04:07 -0700583 m_nCharset(charset) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700584
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700585CFXEU_InsertText::~CFXEU_InsertText() {}
586
587void CFXEU_InsertText::Redo() {
588 if (m_pEdit && IsLast()) {
589 m_pEdit->SelectNone();
590 m_pEdit->SetCaret(m_wpOld);
tsepez4cf55152016-11-02 14:37:54 -0700591 m_pEdit->InsertText(m_swText, m_nCharset, false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700592 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700593}
594
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700595void CFXEU_InsertText::Undo() {
596 if (m_pEdit) {
597 m_pEdit->SelectNone();
598 m_pEdit->SetSel(m_wpOld, m_wpNew);
tsepez4cf55152016-11-02 14:37:54 -0700599 m_pEdit->Clear(false, true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700600 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700601}
602
dsinclaire35af1e2016-07-13 11:26:20 -0700603// static
604CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500605 const CFX_PointF& ptOffset,
dsinclaire35af1e2016-07-13 11:26:20 -0700606 const CPVT_WordRange* pRange,
tsepez4cf55152016-11-02 14:37:54 -0700607 bool bContinuous,
dsinclaire35af1e2016-07-13 11:26:20 -0700608 uint16_t SubWord) {
609 CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
610 if (pRange)
611 pIterator->SetAt(pRange->BeginPos);
612 else
613 pIterator->SetAt(0);
614
615 CFX_ByteTextBuf sEditStream;
616 CFX_ByteTextBuf sWords;
617 int32_t nCurFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500618 CFX_PointF ptOld;
619 CFX_PointF ptNew;
dsinclaire35af1e2016-07-13 11:26:20 -0700620 CPVT_WordPlace oldplace;
tsepez63f545c2016-09-13 16:08:49 -0700621
dsinclaire35af1e2016-07-13 11:26:20 -0700622 while (pIterator->NextWord()) {
623 CPVT_WordPlace place = pIterator->GetAt();
dsinclaire35af1e2016-07-13 11:26:20 -0700624 if (pRange && place.WordCmp(pRange->EndPos) > 0)
625 break;
626
627 if (bContinuous) {
628 if (place.LineCmp(oldplace) != 0) {
629 if (sWords.GetSize() > 0) {
630 sEditStream << GetWordRenderString(sWords.MakeString());
631 sWords.Clear();
632 }
633
634 CPVT_Word word;
635 if (pIterator->GetWord(word)) {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500636 ptNew = CFX_PointF(word.ptWord.x + ptOffset.x,
637 word.ptWord.y + ptOffset.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700638 } else {
639 CPVT_Line line;
640 pIterator->GetLine(line);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500641 ptNew = CFX_PointF(line.ptLine.x + ptOffset.x,
642 line.ptLine.y + ptOffset.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700643 }
644
645 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
646 sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
647 << " Td\n";
648
649 ptOld = ptNew;
650 }
651 }
652
653 CPVT_Word word;
654 if (pIterator->GetWord(word)) {
655 if (word.nFontIndex != nCurFontIndex) {
656 if (sWords.GetSize() > 0) {
657 sEditStream << GetWordRenderString(sWords.MakeString());
658 sWords.Clear();
659 }
660 sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
661 word.fFontSize);
662 nCurFontIndex = word.nFontIndex;
663 }
664
665 sWords << GetPDFWordString(pEdit->GetFontMap(), nCurFontIndex,
666 word.Word, SubWord);
667 }
668
669 oldplace = place;
670 } else {
671 CPVT_Word word;
672 if (pIterator->GetWord(word)) {
Dan Sinclairf528eee2017-02-14 11:52:07 -0500673 ptNew =
674 CFX_PointF(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y);
dsinclaire35af1e2016-07-13 11:26:20 -0700675
676 if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
677 sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
678 << " Td\n";
679 ptOld = ptNew;
680 }
681
682 if (word.nFontIndex != nCurFontIndex) {
683 sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
684 word.fFontSize);
685 nCurFontIndex = word.nFontIndex;
686 }
687
688 sEditStream << GetWordRenderString(GetPDFWordString(
689 pEdit->GetFontMap(), nCurFontIndex, word.Word, SubWord));
690 }
691 }
692 }
693
694 if (sWords.GetSize() > 0) {
695 sEditStream << GetWordRenderString(sWords.MakeString());
696 sWords.Clear();
697 }
698
699 CFX_ByteTextBuf sAppStream;
700 if (sEditStream.GetSize() > 0) {
701 int32_t nHorzScale = pEdit->GetHorzScale();
702 if (nHorzScale != 100) {
703 sAppStream << nHorzScale << " Tz\n";
704 }
705
706 FX_FLOAT fCharSpace = pEdit->GetCharSpace();
dsinclair448c4332016-08-02 12:07:35 -0700707 if (!IsFloatZero(fCharSpace)) {
dsinclaire35af1e2016-07-13 11:26:20 -0700708 sAppStream << fCharSpace << " Tc\n";
709 }
710
711 sAppStream << sEditStream;
712 }
713
714 return sAppStream.MakeString();
715}
716
717// static
718CFX_ByteString CFX_Edit::GetSelectAppearanceStream(
719 CFX_Edit* pEdit,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500720 const CFX_PointF& ptOffset,
dsinclaire35af1e2016-07-13 11:26:20 -0700721 const CPVT_WordRange* pRange) {
722 if (!pRange || !pRange->IsExist())
723 return CFX_ByteString();
724
725 CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
726 pIterator->SetAt(pRange->BeginPos);
727
728 CFX_ByteTextBuf sRet;
729 while (pIterator->NextWord()) {
730 CPVT_WordPlace place = pIterator->GetAt();
731 if (place.WordCmp(pRange->EndPos) > 0)
732 break;
733
734 CPVT_Word word;
735 CPVT_Line line;
736 if (pIterator->GetWord(word) && pIterator->GetLine(line)) {
737 sRet << word.ptWord.x + ptOffset.x << " "
738 << line.ptLine.y + line.fLineDescent << " " << word.fWidth << " "
739 << line.fLineAscent - line.fLineDescent << " re\nf\n";
740 }
741 }
742
743 return sRet.MakeString();
744}
745
746// static
dsinclaire35af1e2016-07-13 11:26:20 -0700747void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice,
748 CFX_Matrix* pUser2Device,
749 CFX_Edit* pEdit,
750 FX_COLORREF crTextFill,
751 FX_COLORREF crTextStroke,
752 const CFX_FloatRect& rcClip,
Dan Sinclairf528eee2017-02-14 11:52:07 -0500753 const CFX_PointF& ptOffset,
dsinclaire35af1e2016-07-13 11:26:20 -0700754 const CPVT_WordRange* pRange,
755 CFX_SystemHandler* pSystemHandler,
dsinclair8faac622016-09-15 12:41:50 -0700756 CFFL_FormFiller* pFFLData) {
dsinclaire35af1e2016-07-13 11:26:20 -0700757 const bool bContinuous =
758 pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
759 uint16_t SubWord = pEdit->GetPasswordChar();
760 FX_FLOAT fFontSize = pEdit->GetFontSize();
761 CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
762 int32_t nHorzScale = pEdit->GetHorzScale();
763
764 FX_COLORREF crCurFill = crTextFill;
765 FX_COLORREF crOldFill = crCurFill;
766
tsepez4cf55152016-11-02 14:37:54 -0700767 bool bSelect = false;
dsinclaire35af1e2016-07-13 11:26:20 -0700768 const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
769 const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
770
771 CFX_ByteTextBuf sTextBuf;
772 int32_t nFontIndex = -1;
Dan Sinclairf528eee2017-02-14 11:52:07 -0500773 CFX_PointF ptBT;
dsinclaire35af1e2016-07-13 11:26:20 -0700774 pDevice->SaveState();
dsinclaire35af1e2016-07-13 11:26:20 -0700775 if (!rcClip.IsEmpty()) {
776 CFX_FloatRect rcTemp = rcClip;
777 pUser2Device->TransformRect(rcTemp);
778 pDevice->SetClip_Rect(rcTemp.ToFxRect());
779 }
780
781 CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
782 if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
783 if (pRange)
784 pIterator->SetAt(pRange->BeginPos);
785 else
786 pIterator->SetAt(0);
787
788 CPVT_WordPlace oldplace;
789 while (pIterator->NextWord()) {
790 CPVT_WordPlace place = pIterator->GetAt();
791 if (pRange && place.WordCmp(pRange->EndPos) > 0)
792 break;
793
794 if (wrSelect.IsExist()) {
795 bSelect = place.WordCmp(wrSelect.BeginPos) > 0 &&
796 place.WordCmp(wrSelect.EndPos) <= 0;
797 crCurFill = bSelect ? crWhite : crTextFill;
798 }
799 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
800 crCurFill = crTextFill;
801 crOldFill = crCurFill;
802 }
803 CPVT_Word word;
804 if (pIterator->GetWord(word)) {
805 if (bSelect) {
806 CPVT_Line line;
807 pIterator->GetLine(line);
808
809 if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
810 CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
811 word.ptWord.x + word.fWidth,
812 line.ptLine.y + line.fLineAscent);
813 rc.Intersect(rcClip);
814 pSystemHandler->OutputSelectedRect(pFFLData, rc);
815 } else {
816 CFX_PathData pathSelBK;
817 pathSelBK.AppendRect(
818 word.ptWord.x, line.ptLine.y + line.fLineDescent,
819 word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent);
820
821 pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
822 FXFILL_WINDING);
823 }
824 }
825
826 if (bContinuous) {
827 if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
828 crOldFill != crCurFill) {
829 if (sTextBuf.GetLength() > 0) {
830 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500831 pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700832 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
833 sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);
834
835 sTextBuf.Clear();
836 }
837 nFontIndex = word.nFontIndex;
838 ptBT = word.ptWord;
839 crOldFill = crCurFill;
840 }
841
842 sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word,
843 SubWord)
844 .AsStringC();
845 } else {
846 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500847 pDevice, CFX_PointF(word.ptWord.x + ptOffset.x,
848 word.ptWord.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700849 pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
850 GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord),
851 crCurFill, crTextStroke, nHorzScale);
852 }
853 oldplace = place;
854 }
855 }
856
857 if (sTextBuf.GetLength() > 0) {
858 DrawTextString(
Dan Sinclairf528eee2017-02-14 11:52:07 -0500859 pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
dsinclaire35af1e2016-07-13 11:26:20 -0700860 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
861 sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);
862 }
863 }
864
865 pDevice->RestoreState(false);
866}
867
dsinclaire35af1e2016-07-13 11:26:20 -0700868CFX_Edit::CFX_Edit()
869 : m_pVT(new CPDF_VariableText),
thestig821d59e2016-05-11 12:59:22 -0700870 m_pNotify(nullptr),
871 m_pOprNotify(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700872 m_wpCaret(-1, -1, -1),
873 m_wpOldCaret(-1, -1, -1),
874 m_SelState(),
tsepez4cf55152016-11-02 14:37:54 -0700875 m_bEnableScroll(false),
dsinclair8f4bf9a2016-05-04 13:51:51 -0700876 m_Undo(kEditUndoMaxItems),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700877 m_nAlignment(0),
tsepez4cf55152016-11-02 14:37:54 -0700878 m_bNotifyFlag(false),
879 m_bEnableOverflow(false),
880 m_bEnableRefresh(true),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700881 m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f),
tsepez4cf55152016-11-02 14:37:54 -0700882 m_bEnableUndo(true),
883 m_bOprNotify(false),
dsinclaire35af1e2016-07-13 11:26:20 -0700884 m_pGroupUndoItem(nullptr) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700885
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700886CFX_Edit::~CFX_Edit() {
Lei Zhang412e9082015-12-14 18:34:00 -0800887 ASSERT(!m_pGroupUndoItem);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700888}
889
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700890void CFX_Edit::Initialize() {
891 m_pVT->Initialize();
892 SetCaret(m_pVT->GetBeginWordPlace());
893 SetCaretOrigin();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700894}
895
dsinclairc7a73492016-04-05 12:01:42 -0700896void CFX_Edit::SetFontMap(IPVT_FontMap* pFontMap) {
tsepez36eb4bd2016-10-03 15:24:27 -0700897 m_pVTProvider = pdfium::MakeUnique<CFX_Edit_Provider>(pFontMap);
thestig821d59e2016-05-11 12:59:22 -0700898 m_pVT->SetProvider(m_pVTProvider.get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700899}
900
dsinclaire35af1e2016-07-13 11:26:20 -0700901void CFX_Edit::SetNotify(CPWL_EditCtrl* pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700902 m_pNotify = pNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700903}
904
dsinclaire35af1e2016-07-13 11:26:20 -0700905void CFX_Edit::SetOprNotify(CPWL_Edit* pOprNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700906 m_pOprNotify = pOprNotify;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700907}
908
dsinclaire35af1e2016-07-13 11:26:20 -0700909CFX_Edit_Iterator* CFX_Edit::GetIterator() {
tsepez36eb4bd2016-10-03 15:24:27 -0700910 if (!m_pIterator) {
911 m_pIterator =
912 pdfium::MakeUnique<CFX_Edit_Iterator>(this, m_pVT->GetIterator());
913 }
thestig821d59e2016-05-11 12:59:22 -0700914 return m_pIterator.get();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700915}
916
dsinclairc7a73492016-04-05 12:01:42 -0700917IPVT_FontMap* CFX_Edit::GetFontMap() {
thestig821d59e2016-05-11 12:59:22 -0700918 return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700919}
920
dsinclairefd5a992016-07-18 10:04:07 -0700921void CFX_Edit::SetPlateRect(const CFX_FloatRect& rect) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700922 m_pVT->SetPlateRect(rect);
Dan Sinclairf528eee2017-02-14 11:52:07 -0500923 m_ptScrollPos = CFX_PointF(rect.left, rect.top);
dsinclairefd5a992016-07-18 10:04:07 -0700924 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700925}
926
tsepez4cf55152016-11-02 14:37:54 -0700927void CFX_Edit::SetAlignmentH(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700928 m_pVT->SetAlignment(nFormat);
929 if (bPaint)
930 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700931}
932
tsepez4cf55152016-11-02 14:37:54 -0700933void CFX_Edit::SetAlignmentV(int32_t nFormat, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700934 m_nAlignment = nFormat;
935 if (bPaint)
936 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700937}
938
tsepez4cf55152016-11-02 14:37:54 -0700939void CFX_Edit::SetPasswordChar(uint16_t wSubWord, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700940 m_pVT->SetPasswordChar(wSubWord);
941 if (bPaint)
942 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700943}
944
dsinclairefd5a992016-07-18 10:04:07 -0700945void CFX_Edit::SetLimitChar(int32_t nLimitChar) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700946 m_pVT->SetLimitChar(nLimitChar);
dsinclairefd5a992016-07-18 10:04:07 -0700947 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700948}
949
dsinclairefd5a992016-07-18 10:04:07 -0700950void CFX_Edit::SetCharArray(int32_t nCharArray) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700951 m_pVT->SetCharArray(nCharArray);
dsinclairefd5a992016-07-18 10:04:07 -0700952 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700953}
954
dsinclairefd5a992016-07-18 10:04:07 -0700955void CFX_Edit::SetCharSpace(FX_FLOAT fCharSpace) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700956 m_pVT->SetCharSpace(fCharSpace);
dsinclairefd5a992016-07-18 10:04:07 -0700957 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700958}
959
tsepez4cf55152016-11-02 14:37:54 -0700960void CFX_Edit::SetMultiLine(bool bMultiLine, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700961 m_pVT->SetMultiLine(bMultiLine);
962 if (bPaint)
963 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700964}
965
tsepez4cf55152016-11-02 14:37:54 -0700966void CFX_Edit::SetAutoReturn(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700967 m_pVT->SetAutoReturn(bAuto);
968 if (bPaint)
969 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700970}
971
tsepez4cf55152016-11-02 14:37:54 -0700972void CFX_Edit::SetAutoFontSize(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700973 m_pVT->SetAutoFontSize(bAuto);
974 if (bPaint)
975 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700976}
977
dsinclairefd5a992016-07-18 10:04:07 -0700978void CFX_Edit::SetFontSize(FX_FLOAT fFontSize) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700979 m_pVT->SetFontSize(fFontSize);
dsinclairefd5a992016-07-18 10:04:07 -0700980 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700981}
982
tsepez4cf55152016-11-02 14:37:54 -0700983void CFX_Edit::SetAutoScroll(bool bAuto, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700984 m_bEnableScroll = bAuto;
985 if (bPaint)
986 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700987}
988
tsepez4cf55152016-11-02 14:37:54 -0700989void CFX_Edit::SetTextOverflow(bool bAllowed, bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700990 m_bEnableOverflow = bAllowed;
991 if (bPaint)
992 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700993}
994
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700995void CFX_Edit::SetSel(int32_t nStartChar, int32_t nEndChar) {
996 if (m_pVT->IsValid()) {
997 if (nStartChar == 0 && nEndChar < 0) {
998 SelectAll();
999 } else if (nStartChar < 0) {
1000 SelectNone();
1001 } else {
1002 if (nStartChar < nEndChar) {
1003 SetSel(m_pVT->WordIndexToWordPlace(nStartChar),
1004 m_pVT->WordIndexToWordPlace(nEndChar));
1005 } else {
1006 SetSel(m_pVT->WordIndexToWordPlace(nEndChar),
1007 m_pVT->WordIndexToWordPlace(nStartChar));
1008 }
1009 }
1010 }
1011}
1012
1013void CFX_Edit::SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
1014 if (m_pVT->IsValid()) {
1015 SelectNone();
1016
1017 m_SelState.Set(begin, end);
1018
1019 SetCaret(m_SelState.EndPos);
1020
1021 if (m_SelState.IsExist()) {
1022 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001023 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001024 SetCaretInfo();
1025 } else {
1026 ScrollToCaret();
1027 SetCaretInfo();
1028 }
1029 }
1030}
1031
1032void CFX_Edit::GetSel(int32_t& nStartChar, int32_t& nEndChar) const {
1033 nStartChar = -1;
1034 nEndChar = -1;
1035
1036 if (m_pVT->IsValid()) {
1037 if (m_SelState.IsExist()) {
1038 if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0) {
1039 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
1040 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
1041 } else {
1042 nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
1043 nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
1044 }
1045 } else {
1046 nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
1047 nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
1048 }
1049 }
1050}
1051
1052int32_t CFX_Edit::GetCaret() const {
1053 if (m_pVT->IsValid())
1054 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
1055
1056 return -1;
1057}
1058
1059CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const {
1060 return m_wpCaret;
1061}
1062
1063CFX_WideString CFX_Edit::GetText() const {
1064 CFX_WideString swRet;
1065
thestig821d59e2016-05-11 12:59:22 -07001066 if (!m_pVT->IsValid())
1067 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001068
thestig821d59e2016-05-11 12:59:22 -07001069 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1070 pIterator->SetAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001071
thestig821d59e2016-05-11 12:59:22 -07001072 CPVT_Word wordinfo;
1073 CPVT_WordPlace oldplace = pIterator->GetAt();
1074 while (pIterator->NextWord()) {
1075 CPVT_WordPlace place = pIterator->GetAt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001076
thestig821d59e2016-05-11 12:59:22 -07001077 if (pIterator->GetWord(wordinfo))
1078 swRet += wordinfo.Word;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001079
thestig821d59e2016-05-11 12:59:22 -07001080 if (oldplace.SecCmp(place) != 0)
1081 swRet += L"\r\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001082
thestig821d59e2016-05-11 12:59:22 -07001083 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001084 }
1085
1086 return swRet;
1087}
1088
1089CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange& range) const {
1090 CFX_WideString swRet;
1091
thestig821d59e2016-05-11 12:59:22 -07001092 if (!m_pVT->IsValid())
1093 return swRet;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001094
thestig821d59e2016-05-11 12:59:22 -07001095 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1096 CPVT_WordRange wrTemp = range;
1097 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1098 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1099 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001100
thestig821d59e2016-05-11 12:59:22 -07001101 CPVT_Word wordinfo;
1102 CPVT_WordPlace oldplace = wrTemp.BeginPos;
1103 while (pIterator->NextWord()) {
1104 CPVT_WordPlace place = pIterator->GetAt();
1105 if (place.WordCmp(wrTemp.EndPos) > 0)
1106 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001107
thestig821d59e2016-05-11 12:59:22 -07001108 if (pIterator->GetWord(wordinfo))
1109 swRet += wordinfo.Word;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001110
thestig821d59e2016-05-11 12:59:22 -07001111 if (oldplace.SecCmp(place) != 0)
1112 swRet += L"\r\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001113
thestig821d59e2016-05-11 12:59:22 -07001114 oldplace = place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001115 }
1116
1117 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001118}
1119
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001120CFX_WideString CFX_Edit::GetSelText() const {
1121 return GetRangeText(m_SelState.ConvertToWordRange());
1122}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001123
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001124int32_t CFX_Edit::GetTotalWords() const {
1125 return m_pVT->GetTotalWords();
1126}
1127
1128int32_t CFX_Edit::GetTotalLines() const {
thestig821d59e2016-05-11 12:59:22 -07001129 int32_t nLines = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001130
thestig821d59e2016-05-11 12:59:22 -07001131 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1132 pIterator->SetAt(0);
1133 while (pIterator->NextLine())
1134 ++nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001135
thestig821d59e2016-05-11 12:59:22 -07001136 return nLines;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001137}
1138
1139CPVT_WordRange CFX_Edit::GetSelectWordRange() const {
1140 return m_SelState.ConvertToWordRange();
1141}
1142
tsepeza31da742016-09-08 11:28:14 -07001143void CFX_Edit::SetText(const CFX_WideString& sText) {
dsinclairefd5a992016-07-18 10:04:07 -07001144 Empty();
npmea3c3be2016-09-19 07:24:33 -07001145 DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FXFONT_DEFAULT_CHARSET);
dsinclairefd5a992016-07-18 10:04:07 -07001146 Paint();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001147}
1148
tsepez4cf55152016-11-02 14:37:54 -07001149bool CFX_Edit::InsertWord(uint16_t word, int32_t charset) {
1150 return InsertWord(word, charset, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001151}
1152
tsepez4cf55152016-11-02 14:37:54 -07001153bool CFX_Edit::InsertReturn() {
1154 return InsertReturn(nullptr, nullptr, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001155}
1156
tsepez4cf55152016-11-02 14:37:54 -07001157bool CFX_Edit::Backspace() {
1158 return Backspace(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001159}
1160
tsepez4cf55152016-11-02 14:37:54 -07001161bool CFX_Edit::Delete() {
1162 return Delete(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001163}
1164
tsepez4cf55152016-11-02 14:37:54 -07001165bool CFX_Edit::Clear() {
1166 return Clear(true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001167}
1168
tsepez4cf55152016-11-02 14:37:54 -07001169bool CFX_Edit::InsertText(const CFX_WideString& sText, int32_t charset) {
1170 return InsertText(sText, charset, true, true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001171}
1172
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001173FX_FLOAT CFX_Edit::GetFontSize() const {
1174 return m_pVT->GetFontSize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001175}
1176
Tom Sepez62a70f92016-03-21 15:00:20 -07001177uint16_t CFX_Edit::GetPasswordChar() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001178 return m_pVT->GetPasswordChar();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001179}
1180
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001181int32_t CFX_Edit::GetCharArray() const {
1182 return m_pVT->GetCharArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001183}
1184
Tom Sepez281a9ea2016-02-26 14:24:28 -08001185CFX_FloatRect CFX_Edit::GetContentRect() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001186 return VTToEdit(m_pVT->GetContentRect());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001187}
1188
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001189int32_t CFX_Edit::GetHorzScale() const {
1190 return m_pVT->GetHorzScale();
1191}
1192
1193FX_FLOAT CFX_Edit::GetCharSpace() const {
1194 return m_pVT->GetCharSpace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001195}
1196
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001197CPVT_WordRange CFX_Edit::GetWholeWordRange() const {
1198 if (m_pVT->IsValid())
1199 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001200
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001201 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001202}
1203
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001204CPVT_WordRange CFX_Edit::GetVisibleWordRange() const {
1205 if (m_bEnableOverflow)
1206 return GetWholeWordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001207
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001208 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001209 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001210
Dan Sinclairf528eee2017-02-14 11:52:07 -05001211 CPVT_WordPlace place1 =
1212 m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001213 CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
Dan Sinclairf528eee2017-02-14 11:52:07 -05001214 EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001215
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001216 return CPVT_WordRange(place1, place2);
1217 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001218
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001219 return CPVT_WordRange();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001220}
1221
Dan Sinclairf528eee2017-02-14 11:52:07 -05001222CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_PointF& point) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001223 if (m_pVT->IsValid()) {
1224 return m_pVT->SearchWordPlace(EditToVT(point));
1225 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001226
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001227 return CPVT_WordPlace();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001228}
1229
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001230void CFX_Edit::Paint() {
1231 if (m_pVT->IsValid()) {
1232 RearrangeAll();
1233 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001234 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001235 SetCaretOrigin();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001236 SetCaretInfo();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001237 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001238}
1239
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001240void CFX_Edit::RearrangeAll() {
1241 if (m_pVT->IsValid()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001242 m_pVT->UpdateWordPlace(m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001243 m_pVT->RearrangeAll();
1244 m_pVT->UpdateWordPlace(m_wpCaret);
1245 SetScrollInfo();
1246 SetContentChanged();
1247 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001248}
1249
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001250void CFX_Edit::RearrangePart(const CPVT_WordRange& range) {
1251 if (m_pVT->IsValid()) {
1252 m_pVT->UpdateWordPlace(m_wpCaret);
1253 m_pVT->RearrangePart(range);
1254 m_pVT->UpdateWordPlace(m_wpCaret);
1255 SetScrollInfo();
1256 SetContentChanged();
1257 }
1258}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001259
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001260void CFX_Edit::SetContentChanged() {
dsinclaira2919b32016-07-13 10:55:48 -07001261 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001262 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001263 if (rcContent.Width() != m_rcOldContent.Width() ||
1264 rcContent.Height() != m_rcOldContent.Height()) {
1265 if (!m_bNotifyFlag) {
tsepez4cf55152016-11-02 14:37:54 -07001266 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001267 m_pNotify->IOnContentChange(rcContent);
tsepez4cf55152016-11-02 14:37:54 -07001268 m_bNotifyFlag = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001269 }
1270 m_rcOldContent = rcContent;
1271 }
1272 }
1273}
1274
1275void CFX_Edit::SelectAll() {
1276 if (m_pVT->IsValid()) {
Lei Zhang375a8642016-01-11 11:59:17 -08001277 m_SelState = CFX_Edit_Select(GetWholeWordRange());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001278 SetCaret(m_SelState.EndPos);
1279
1280 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001281 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001282 SetCaretInfo();
1283 }
1284}
1285
1286void CFX_Edit::SelectNone() {
1287 if (m_pVT->IsValid()) {
1288 if (m_SelState.IsExist()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001289 m_SelState.Default();
dsinclairefd5a992016-07-18 10:04:07 -07001290 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001291 }
1292 }
1293}
1294
tsepez4cf55152016-11-02 14:37:54 -07001295bool CFX_Edit::IsSelected() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001296 return m_SelState.IsExist();
1297}
1298
Dan Sinclairf528eee2017-02-14 11:52:07 -05001299CFX_PointF CFX_Edit::VTToEdit(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001300 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1301 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001302
1303 FX_FLOAT fPadding = 0.0f;
1304
1305 switch (m_nAlignment) {
1306 case 0:
1307 fPadding = 0.0f;
1308 break;
1309 case 1:
1310 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1311 break;
1312 case 2:
1313 fPadding = rcPlate.Height() - rcContent.Height();
1314 break;
1315 }
1316
Dan Sinclairf528eee2017-02-14 11:52:07 -05001317 return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
1318 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001319}
1320
Dan Sinclairf528eee2017-02-14 11:52:07 -05001321CFX_PointF CFX_Edit::EditToVT(const CFX_PointF& point) const {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001322 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1323 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001324
1325 FX_FLOAT fPadding = 0.0f;
1326
1327 switch (m_nAlignment) {
1328 case 0:
1329 fPadding = 0.0f;
1330 break;
1331 case 1:
1332 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
1333 break;
1334 case 2:
1335 fPadding = rcPlate.Height() - rcContent.Height();
1336 break;
1337 }
1338
Dan Sinclairf528eee2017-02-14 11:52:07 -05001339 return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
1340 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001341}
1342
Tom Sepez281a9ea2016-02-26 14:24:28 -08001343CFX_FloatRect CFX_Edit::VTToEdit(const CFX_FloatRect& rect) const {
Dan Sinclairf528eee2017-02-14 11:52:07 -05001344 CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
1345 CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001346
Tom Sepez281a9ea2016-02-26 14:24:28 -08001347 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1348 ptRightTop.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001349}
1350
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001351void CFX_Edit::SetScrollInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001352 if (m_pNotify) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001353 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
1354 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001355
1356 if (!m_bNotifyFlag) {
tsepez4cf55152016-11-02 14:37:54 -07001357 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001358 m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
1359 rcContent.bottom, rcContent.top,
1360 rcPlate.Height() / 3, rcPlate.Height());
tsepez4cf55152016-11-02 14:37:54 -07001361 m_bNotifyFlag = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001362 }
1363 }
1364}
1365
1366void CFX_Edit::SetScrollPosX(FX_FLOAT fx) {
1367 if (!m_bEnableScroll)
1368 return;
1369
1370 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001371 if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001372 m_ptScrollPos.x = fx;
dsinclairefd5a992016-07-18 10:04:07 -07001373 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001374 }
1375 }
1376}
1377
1378void CFX_Edit::SetScrollPosY(FX_FLOAT fy) {
1379 if (!m_bEnableScroll)
1380 return;
1381
1382 if (m_pVT->IsValid()) {
dsinclair448c4332016-08-02 12:07:35 -07001383 if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001384 m_ptScrollPos.y = fy;
dsinclairefd5a992016-07-18 10:04:07 -07001385 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001386
dsinclaira2919b32016-07-13 10:55:48 -07001387 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001388 if (!m_bNotifyFlag) {
tsepez4cf55152016-11-02 14:37:54 -07001389 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001390 m_pNotify->IOnSetScrollPosY(fy);
tsepez4cf55152016-11-02 14:37:54 -07001391 m_bNotifyFlag = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001392 }
1393 }
1394 }
1395 }
1396}
1397
Dan Sinclairf528eee2017-02-14 11:52:07 -05001398void CFX_Edit::SetScrollPos(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001399 SetScrollPosX(point.x);
1400 SetScrollPosY(point.y);
1401 SetScrollLimit();
1402 SetCaretInfo();
1403}
1404
Dan Sinclairf528eee2017-02-14 11:52:07 -05001405CFX_PointF CFX_Edit::GetScrollPos() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001406 return m_ptScrollPos;
1407}
1408
1409void CFX_Edit::SetScrollLimit() {
1410 if (m_pVT->IsValid()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08001411 CFX_FloatRect rcContent = m_pVT->GetContentRect();
1412 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001413
1414 if (rcPlate.Width() > rcContent.Width()) {
1415 SetScrollPosX(rcPlate.left);
1416 } else {
dsinclair448c4332016-08-02 12:07:35 -07001417 if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001418 SetScrollPosX(rcContent.left);
dsinclair448c4332016-08-02 12:07:35 -07001419 } else if (IsFloatBigger(m_ptScrollPos.x,
1420 rcContent.right - rcPlate.Width())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001421 SetScrollPosX(rcContent.right - rcPlate.Width());
1422 }
1423 }
1424
1425 if (rcPlate.Height() > rcContent.Height()) {
1426 SetScrollPosY(rcPlate.top);
1427 } else {
dsinclair448c4332016-08-02 12:07:35 -07001428 if (IsFloatSmaller(m_ptScrollPos.y,
1429 rcContent.bottom + rcPlate.Height())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001430 SetScrollPosY(rcContent.bottom + rcPlate.Height());
dsinclair448c4332016-08-02 12:07:35 -07001431 } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001432 SetScrollPosY(rcContent.top);
1433 }
1434 }
1435 }
1436}
1437
1438void CFX_Edit::ScrollToCaret() {
1439 SetScrollLimit();
1440
thestig821d59e2016-05-11 12:59:22 -07001441 if (!m_pVT->IsValid())
1442 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001443
thestig821d59e2016-05-11 12:59:22 -07001444 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1445 pIterator->SetAt(m_wpCaret);
1446
Dan Sinclairf528eee2017-02-14 11:52:07 -05001447 CFX_PointF ptHead;
1448 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001449 CPVT_Word word;
1450 CPVT_Line line;
1451 if (pIterator->GetWord(word)) {
1452 ptHead.x = word.ptWord.x + word.fWidth;
1453 ptHead.y = word.ptWord.y + word.fAscent;
1454 ptFoot.x = word.ptWord.x + word.fWidth;
1455 ptFoot.y = word.ptWord.y + word.fDescent;
1456 } else if (pIterator->GetLine(line)) {
1457 ptHead.x = line.ptLine.x;
1458 ptHead.y = line.ptLine.y + line.fLineAscent;
1459 ptFoot.x = line.ptLine.x;
1460 ptFoot.y = line.ptLine.y + line.fLineDescent;
1461 }
1462
Dan Sinclairf528eee2017-02-14 11:52:07 -05001463 CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1464 CFX_PointF ptFootEdit = VTToEdit(ptFoot);
thestig821d59e2016-05-11 12:59:22 -07001465 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
dsinclair448c4332016-08-02 12:07:35 -07001466 if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
1467 if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
1468 IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
thestig821d59e2016-05-11 12:59:22 -07001469 SetScrollPosX(ptHead.x);
dsinclair448c4332016-08-02 12:07:35 -07001470 } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
thestig821d59e2016-05-11 12:59:22 -07001471 SetScrollPosX(ptHead.x - rcPlate.Width());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001472 }
thestig821d59e2016-05-11 12:59:22 -07001473 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001474
dsinclair448c4332016-08-02 12:07:35 -07001475 if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
1476 if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
1477 IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
1478 if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
thestig821d59e2016-05-11 12:59:22 -07001479 SetScrollPosY(ptFoot.y + rcPlate.Height());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001480 }
dsinclair448c4332016-08-02 12:07:35 -07001481 } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
1482 if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
thestig821d59e2016-05-11 12:59:22 -07001483 SetScrollPosY(ptHead.y);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001484 }
1485 }
1486 }
1487}
1488
dsinclairefd5a992016-07-18 10:04:07 -07001489void CFX_Edit::Refresh() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001490 if (m_bEnableRefresh && m_pVT->IsValid()) {
1491 m_Refresh.BeginRefresh();
1492 RefreshPushLineRects(GetVisibleWordRange());
1493
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001494 m_Refresh.NoAnalyse();
1495 m_ptRefreshScrollPos = m_ptScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001496
dsinclaira2919b32016-07-13 10:55:48 -07001497 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001498 if (!m_bNotifyFlag) {
tsepez4cf55152016-11-02 14:37:54 -07001499 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001500 if (const CFX_Edit_RectArray* pRects = m_Refresh.GetRefreshRects()) {
1501 for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
1502 m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
1503 }
tsepez4cf55152016-11-02 14:37:54 -07001504 m_bNotifyFlag = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001505 }
1506 }
1507
1508 m_Refresh.EndRefresh();
1509 }
1510}
1511
1512void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001513 if (!m_pVT->IsValid())
1514 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001515
thestig821d59e2016-05-11 12:59:22 -07001516 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1517 CPVT_WordPlace wpBegin = wr.BeginPos;
1518 m_pVT->UpdateWordPlace(wpBegin);
1519 CPVT_WordPlace wpEnd = wr.EndPos;
1520 m_pVT->UpdateWordPlace(wpEnd);
1521 pIterator->SetAt(wpBegin);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001522
thestig821d59e2016-05-11 12:59:22 -07001523 CPVT_Line lineinfo;
1524 do {
1525 if (!pIterator->GetLine(lineinfo))
1526 break;
1527 if (lineinfo.lineplace.LineCmp(wpEnd) > 0)
1528 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001529
thestig821d59e2016-05-11 12:59:22 -07001530 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1531 lineinfo.ptLine.y + lineinfo.fLineDescent,
1532 lineinfo.ptLine.x + lineinfo.fLineWidth,
1533 lineinfo.ptLine.y + lineinfo.fLineAscent);
1534
1535 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1536 VTToEdit(rcLine));
1537 } while (pIterator->NextLine());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001538}
1539
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001540void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr) {
thestig821d59e2016-05-11 12:59:22 -07001541 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1542 CPVT_WordRange wrTemp = wr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001543
thestig821d59e2016-05-11 12:59:22 -07001544 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1545 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1546 pIterator->SetAt(wrTemp.BeginPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001547
thestig821d59e2016-05-11 12:59:22 -07001548 CPVT_Word wordinfo;
1549 CPVT_Line lineinfo;
1550 CPVT_WordPlace place;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001551
thestig821d59e2016-05-11 12:59:22 -07001552 while (pIterator->NextWord()) {
1553 place = pIterator->GetAt();
1554 if (place.WordCmp(wrTemp.EndPos) > 0)
1555 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001556
thestig821d59e2016-05-11 12:59:22 -07001557 pIterator->GetWord(wordinfo);
1558 pIterator->GetLine(lineinfo);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001559
thestig821d59e2016-05-11 12:59:22 -07001560 if (place.LineCmp(wrTemp.BeginPos) == 0 ||
1561 place.LineCmp(wrTemp.EndPos) == 0) {
1562 CFX_FloatRect rcWord(wordinfo.ptWord.x,
1563 lineinfo.ptLine.y + lineinfo.fLineDescent,
1564 wordinfo.ptWord.x + wordinfo.fWidth,
1565 lineinfo.ptLine.y + lineinfo.fLineAscent);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001566
dsinclaira2919b32016-07-13 10:55:48 -07001567 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001568 if (!m_bNotifyFlag) {
tsepez4cf55152016-11-02 14:37:54 -07001569 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001570 CFX_FloatRect rcRefresh = VTToEdit(rcWord);
1571 m_pNotify->IOnInvalidateRect(&rcRefresh);
tsepez4cf55152016-11-02 14:37:54 -07001572 m_bNotifyFlag = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001573 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001574 }
thestig821d59e2016-05-11 12:59:22 -07001575 } else {
1576 CFX_FloatRect rcLine(lineinfo.ptLine.x,
1577 lineinfo.ptLine.y + lineinfo.fLineDescent,
1578 lineinfo.ptLine.x + lineinfo.fLineWidth,
1579 lineinfo.ptLine.y + lineinfo.fLineAscent);
1580
dsinclaira2919b32016-07-13 10:55:48 -07001581 if (m_pNotify) {
thestig821d59e2016-05-11 12:59:22 -07001582 if (!m_bNotifyFlag) {
tsepez4cf55152016-11-02 14:37:54 -07001583 m_bNotifyFlag = true;
thestig821d59e2016-05-11 12:59:22 -07001584 CFX_FloatRect rcRefresh = VTToEdit(rcLine);
1585 m_pNotify->IOnInvalidateRect(&rcRefresh);
tsepez4cf55152016-11-02 14:37:54 -07001586 m_bNotifyFlag = false;
thestig821d59e2016-05-11 12:59:22 -07001587 }
1588 }
1589
1590 pIterator->NextLine();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001591 }
1592 }
1593}
1594
1595void CFX_Edit::SetCaret(const CPVT_WordPlace& place) {
1596 m_wpOldCaret = m_wpCaret;
1597 m_wpCaret = place;
1598}
1599
1600void CFX_Edit::SetCaretInfo() {
dsinclaira2919b32016-07-13 10:55:48 -07001601 if (m_pNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001602 if (!m_bNotifyFlag) {
thestig821d59e2016-05-11 12:59:22 -07001603 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1604 pIterator->SetAt(m_wpCaret);
tsepez63f545c2016-09-13 16:08:49 -07001605
Dan Sinclairf528eee2017-02-14 11:52:07 -05001606 CFX_PointF ptHead;
1607 CFX_PointF ptFoot;
thestig821d59e2016-05-11 12:59:22 -07001608 CPVT_Word word;
1609 CPVT_Line line;
1610 if (pIterator->GetWord(word)) {
1611 ptHead.x = word.ptWord.x + word.fWidth;
1612 ptHead.y = word.ptWord.y + word.fAscent;
1613 ptFoot.x = word.ptWord.x + word.fWidth;
1614 ptFoot.y = word.ptWord.y + word.fDescent;
1615 } else if (pIterator->GetLine(line)) {
1616 ptHead.x = line.ptLine.x;
1617 ptHead.y = line.ptLine.y + line.fLineAscent;
1618 ptFoot.x = line.ptLine.x;
1619 ptFoot.y = line.ptLine.y + line.fLineDescent;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001620 }
1621
tsepez4cf55152016-11-02 14:37:54 -07001622 m_bNotifyFlag = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001623 m_pNotify->IOnSetCaret(!m_SelState.IsExist(), VTToEdit(ptHead),
1624 VTToEdit(ptFoot), m_wpCaret);
tsepez4cf55152016-11-02 14:37:54 -07001625 m_bNotifyFlag = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001626 }
1627 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001628}
1629
1630void CFX_Edit::SetCaret(int32_t nPos) {
1631 if (m_pVT->IsValid()) {
1632 SelectNone();
1633 SetCaret(m_pVT->WordIndexToWordPlace(nPos));
1634 m_SelState.Set(m_wpCaret, m_wpCaret);
1635
1636 ScrollToCaret();
1637 SetCaretOrigin();
1638 SetCaretInfo();
1639 }
1640}
1641
Dan Sinclairf528eee2017-02-14 11:52:07 -05001642void CFX_Edit::OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001643 if (m_pVT->IsValid()) {
1644 SelectNone();
1645 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1646 m_SelState.Set(m_wpCaret, m_wpCaret);
1647
1648 ScrollToCaret();
1649 SetCaretOrigin();
1650 SetCaretInfo();
1651 }
1652}
1653
Dan Sinclairf528eee2017-02-14 11:52:07 -05001654void CFX_Edit::OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001655 if (m_pVT->IsValid()) {
1656 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1657
1658 if (m_wpCaret != m_wpOldCaret) {
1659 m_SelState.SetEndPos(m_wpCaret);
1660
1661 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001662 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001663 SetCaretOrigin();
1664 SetCaretInfo();
1665 }
1666 }
1667}
1668
tsepez4cf55152016-11-02 14:37:54 -07001669void CFX_Edit::OnVK_UP(bool bShift, bool bCtrl) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001670 if (m_pVT->IsValid()) {
1671 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1672
1673 if (bShift) {
1674 if (m_SelState.IsExist())
1675 m_SelState.SetEndPos(m_wpCaret);
1676 else
1677 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1678
1679 if (m_wpOldCaret != m_wpCaret) {
1680 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001681 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001682 SetCaretInfo();
1683 }
1684 } else {
1685 SelectNone();
1686
1687 ScrollToCaret();
1688 SetCaretInfo();
1689 }
1690 }
1691}
1692
tsepez4cf55152016-11-02 14:37:54 -07001693void CFX_Edit::OnVK_DOWN(bool bShift, bool bCtrl) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001694 if (m_pVT->IsValid()) {
1695 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1696
1697 if (bShift) {
1698 if (m_SelState.IsExist())
1699 m_SelState.SetEndPos(m_wpCaret);
1700 else
1701 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1702
1703 if (m_wpOldCaret != m_wpCaret) {
1704 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001705 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001706 SetCaretInfo();
1707 }
1708 } else {
1709 SelectNone();
1710
1711 ScrollToCaret();
1712 SetCaretInfo();
1713 }
1714 }
1715}
1716
tsepez4cf55152016-11-02 14:37:54 -07001717void CFX_Edit::OnVK_LEFT(bool bShift, bool bCtrl) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001718 if (m_pVT->IsValid()) {
1719 if (bShift) {
1720 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1721 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
1722 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1723
1724 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1725
1726 if (m_SelState.IsExist())
1727 m_SelState.SetEndPos(m_wpCaret);
1728 else
1729 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1730
1731 if (m_wpOldCaret != m_wpCaret) {
1732 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001733 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001734 SetCaretInfo();
1735 }
1736 } else {
1737 if (m_SelState.IsExist()) {
1738 if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0)
1739 SetCaret(m_SelState.BeginPos);
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001740 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001741 SetCaret(m_SelState.EndPos);
1742
1743 SelectNone();
1744 ScrollToCaret();
1745 SetCaretInfo();
1746 } else {
1747 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1748 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
1749 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1750
1751 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1752
1753 ScrollToCaret();
1754 SetCaretOrigin();
1755 SetCaretInfo();
1756 }
1757 }
1758 }
1759}
1760
tsepez4cf55152016-11-02 14:37:54 -07001761void CFX_Edit::OnVK_RIGHT(bool bShift, bool bCtrl) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001762 if (m_pVT->IsValid()) {
1763 if (bShift) {
1764 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1765
1766 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1767 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
1768 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1769
1770 if (m_SelState.IsExist())
1771 m_SelState.SetEndPos(m_wpCaret);
1772 else
1773 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1774
1775 if (m_wpOldCaret != m_wpCaret) {
1776 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001777 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001778 SetCaretInfo();
1779 }
1780 } else {
1781 if (m_SelState.IsExist()) {
1782 if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) > 0)
1783 SetCaret(m_SelState.BeginPos);
1784 else
1785 SetCaret(m_SelState.EndPos);
1786
1787 SelectNone();
1788 ScrollToCaret();
1789 SetCaretInfo();
1790 } else {
1791 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1792
1793 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1794 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
1795 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1796
1797 ScrollToCaret();
1798 SetCaretOrigin();
1799 SetCaretInfo();
1800 }
1801 }
1802 }
1803}
1804
tsepez4cf55152016-11-02 14:37:54 -07001805void CFX_Edit::OnVK_HOME(bool bShift, bool bCtrl) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001806 if (m_pVT->IsValid()) {
1807 if (bShift) {
1808 if (bCtrl)
1809 SetCaret(m_pVT->GetBeginWordPlace());
1810 else
1811 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1812
1813 if (m_SelState.IsExist())
1814 m_SelState.SetEndPos(m_wpCaret);
1815 else
1816 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1817
1818 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001819 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001820 SetCaretInfo();
1821 } else {
1822 if (m_SelState.IsExist()) {
1823 if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0)
1824 SetCaret(m_SelState.BeginPos);
1825 else
1826 SetCaret(m_SelState.EndPos);
1827
1828 SelectNone();
1829 ScrollToCaret();
1830 SetCaretInfo();
1831 } else {
1832 if (bCtrl)
1833 SetCaret(m_pVT->GetBeginWordPlace());
1834 else
1835 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1836
1837 ScrollToCaret();
1838 SetCaretOrigin();
1839 SetCaretInfo();
1840 }
1841 }
1842 }
1843}
1844
tsepez4cf55152016-11-02 14:37:54 -07001845void CFX_Edit::OnVK_END(bool bShift, bool bCtrl) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001846 if (m_pVT->IsValid()) {
1847 if (bShift) {
1848 if (bCtrl)
1849 SetCaret(m_pVT->GetEndWordPlace());
1850 else
1851 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1852
1853 if (m_SelState.IsExist())
1854 m_SelState.SetEndPos(m_wpCaret);
1855 else
1856 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1857
1858 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07001859 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001860 SetCaretInfo();
1861 } else {
1862 if (m_SelState.IsExist()) {
1863 if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) > 0)
1864 SetCaret(m_SelState.BeginPos);
1865 else
1866 SetCaret(m_SelState.EndPos);
1867
1868 SelectNone();
1869 ScrollToCaret();
1870 SetCaretInfo();
1871 } else {
1872 if (bCtrl)
1873 SetCaret(m_pVT->GetEndWordPlace());
1874 else
1875 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1876
1877 ScrollToCaret();
1878 SetCaretOrigin();
1879 SetCaretInfo();
1880 }
1881 }
1882 }
1883}
1884
tsepez4cf55152016-11-02 14:37:54 -07001885bool CFX_Edit::InsertWord(uint16_t word,
1886 int32_t charset,
1887 const CPVT_WordProps* pWordProps,
1888 bool bAddUndo,
1889 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001890 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001891 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001892
Tom Sepez3509d162017-01-30 13:22:02 -08001893 m_pVT->UpdateWordPlace(m_wpCaret);
1894 SetCaret(m_pVT->InsertWord(m_wpCaret, word,
1895 GetCharSetFromUnicode(word, charset), pWordProps));
1896 m_SelState.Set(m_wpCaret, m_wpCaret);
1897 if (m_wpCaret == m_wpOldCaret)
1898 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001899
Tom Sepez3509d162017-01-30 13:22:02 -08001900 if (bAddUndo && m_bEnableUndo) {
1901 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertWord>(
1902 this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001903 }
Tom Sepez3509d162017-01-30 13:22:02 -08001904 if (bPaint)
1905 PaintInsertText(m_wpOldCaret, m_wpCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001906
Tom Sepez3509d162017-01-30 13:22:02 -08001907 if (m_bOprNotify && m_pOprNotify)
1908 m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
1909
1910 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001911}
1912
tsepez4cf55152016-11-02 14:37:54 -07001913bool CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps,
1914 const CPVT_WordProps* pWordProps,
1915 bool bAddUndo,
1916 bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001917 if (IsTextOverflow() || !m_pVT->IsValid())
tsepez4cf55152016-11-02 14:37:54 -07001918 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001919
Tom Sepez3509d162017-01-30 13:22:02 -08001920 m_pVT->UpdateWordPlace(m_wpCaret);
1921 SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps));
1922 m_SelState.Set(m_wpCaret, m_wpCaret);
1923 if (m_wpCaret == m_wpOldCaret)
1924 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001925
Tom Sepez3509d162017-01-30 13:22:02 -08001926 if (bAddUndo && m_bEnableUndo) {
1927 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertReturn>(
1928 this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001929 }
Tom Sepez3509d162017-01-30 13:22:02 -08001930 if (bPaint) {
1931 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
1932 ScrollToCaret();
1933 Refresh();
1934 SetCaretOrigin();
1935 SetCaretInfo();
1936 }
1937 if (m_bOprNotify && m_pOprNotify)
1938 m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001939
Tom Sepez3509d162017-01-30 13:22:02 -08001940 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001941}
1942
tsepez4cf55152016-11-02 14:37:54 -07001943bool CFX_Edit::Backspace(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001944 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1945 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001946
Tom Sepez3509d162017-01-30 13:22:02 -08001947 CPVT_Section section;
1948 CPVT_Word word;
1949 if (bAddUndo) {
1950 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1951 pIterator->SetAt(m_wpCaret);
1952 pIterator->GetSection(section);
1953 pIterator->GetWord(word);
1954 }
1955 m_pVT->UpdateWordPlace(m_wpCaret);
1956 SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1957 m_SelState.Set(m_wpCaret, m_wpCaret);
1958 if (m_wpCaret == m_wpOldCaret)
1959 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001960
Tom Sepez3509d162017-01-30 13:22:02 -08001961 if (bAddUndo && m_bEnableUndo) {
1962 if (m_wpCaret.SecCmp(m_wpOldCaret) != 0) {
1963 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1964 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1965 section.SecProps, section.WordProps));
1966 } else {
1967 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>(
1968 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
1969 section.SecProps, word.WordProps));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001970 }
1971 }
Tom Sepez3509d162017-01-30 13:22:02 -08001972 if (bPaint) {
1973 RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
1974 ScrollToCaret();
1975 Refresh();
1976 SetCaretOrigin();
1977 SetCaretInfo();
1978 }
1979 if (m_bOprNotify && m_pOprNotify)
1980 m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001981
Tom Sepez3509d162017-01-30 13:22:02 -08001982 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001983}
1984
tsepez4cf55152016-11-02 14:37:54 -07001985bool CFX_Edit::Delete(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08001986 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1987 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001988
Tom Sepez3509d162017-01-30 13:22:02 -08001989 CPVT_Section section;
1990 CPVT_Word word;
1991 if (bAddUndo) {
1992 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
1993 pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1994 pIterator->GetSection(section);
1995 pIterator->GetWord(word);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001996 }
Tom Sepez3509d162017-01-30 13:22:02 -08001997 m_pVT->UpdateWordPlace(m_wpCaret);
1998 bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1999 SetCaret(m_pVT->DeleteWord(m_wpCaret));
2000 m_SelState.Set(m_wpCaret, m_wpCaret);
2001 if (bAddUndo && m_bEnableUndo) {
2002 if (bSecEnd) {
2003 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
2004 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
2005 section.SecProps, section.WordProps, bSecEnd));
2006 } else {
2007 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>(
2008 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
2009 section.SecProps, word.WordProps, bSecEnd));
2010 }
2011 }
2012 if (bPaint) {
2013 RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
2014 ScrollToCaret();
2015 Refresh();
2016 SetCaretOrigin();
2017 SetCaretInfo();
2018 }
2019 if (m_bOprNotify && m_pOprNotify)
2020 m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002021
Tom Sepez3509d162017-01-30 13:22:02 -08002022 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002023}
2024
tsepez4cf55152016-11-02 14:37:54 -07002025bool CFX_Edit::Empty() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002026 if (m_pVT->IsValid()) {
2027 m_pVT->DeleteWords(GetWholeWordRange());
2028 SetCaret(m_pVT->GetBeginWordPlace());
2029
tsepez4cf55152016-11-02 14:37:54 -07002030 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002031 }
2032
tsepez4cf55152016-11-02 14:37:54 -07002033 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002034}
2035
tsepez4cf55152016-11-02 14:37:54 -07002036bool CFX_Edit::Clear(bool bAddUndo, bool bPaint) {
Tom Sepez3509d162017-01-30 13:22:02 -08002037 if (!m_pVT->IsValid() || !m_SelState.IsExist())
tsepez4cf55152016-11-02 14:37:54 -07002038 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002039
thestig821d59e2016-05-11 12:59:22 -07002040 CPVT_WordRange range = m_SelState.ConvertToWordRange();
dsinclaira2919b32016-07-13 10:55:48 -07002041 if (bAddUndo && m_bEnableUndo)
Tom Sepez3509d162017-01-30 13:22:02 -08002042 AddEditUndoItem(pdfium::MakeUnique<CFXEU_Clear>(this, range, GetSelText()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002043
thestig821d59e2016-05-11 12:59:22 -07002044 SelectNone();
2045 SetCaret(m_pVT->DeleteWords(range));
2046 m_SelState.Set(m_wpCaret, m_wpCaret);
thestig821d59e2016-05-11 12:59:22 -07002047 if (bPaint) {
2048 RearrangePart(range);
2049 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07002050 Refresh();
thestig821d59e2016-05-11 12:59:22 -07002051 SetCaretOrigin();
2052 SetCaretInfo();
2053 }
thestig821d59e2016-05-11 12:59:22 -07002054 if (m_bOprNotify && m_pOprNotify)
2055 m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);
2056
tsepez4cf55152016-11-02 14:37:54 -07002057 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002058}
2059
tsepez4cf55152016-11-02 14:37:54 -07002060bool CFX_Edit::InsertText(const CFX_WideString& sText,
2061 int32_t charset,
2062 bool bAddUndo,
2063 bool bPaint) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002064 if (IsTextOverflow())
tsepez4cf55152016-11-02 14:37:54 -07002065 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002066
2067 m_pVT->UpdateWordPlace(m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07002068 SetCaret(DoInsertText(m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002069 m_SelState.Set(m_wpCaret, m_wpCaret);
tsepeza31da742016-09-08 11:28:14 -07002070 if (m_wpCaret == m_wpOldCaret)
tsepez4cf55152016-11-02 14:37:54 -07002071 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002072
tsepeza31da742016-09-08 11:28:14 -07002073 if (bAddUndo && m_bEnableUndo) {
Tom Sepez3509d162017-01-30 13:22:02 -08002074 AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertText>(
2075 this, m_wpOldCaret, m_wpCaret, sText, charset));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002076 }
tsepeza31da742016-09-08 11:28:14 -07002077 if (bPaint)
2078 PaintInsertText(m_wpOldCaret, m_wpCaret);
2079
2080 if (m_bOprNotify && m_pOprNotify)
2081 m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
2082
tsepez4cf55152016-11-02 14:37:54 -07002083 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002084}
2085
2086void CFX_Edit::PaintInsertText(const CPVT_WordPlace& wpOld,
2087 const CPVT_WordPlace& wpNew) {
2088 if (m_pVT->IsValid()) {
2089 RearrangePart(CPVT_WordRange(wpOld, wpNew));
2090 ScrollToCaret();
dsinclairefd5a992016-07-18 10:04:07 -07002091 Refresh();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002092 SetCaretOrigin();
2093 SetCaretInfo();
2094 }
2095}
2096
tsepez4cf55152016-11-02 14:37:54 -07002097bool CFX_Edit::Redo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002098 if (m_bEnableUndo) {
2099 if (m_Undo.CanRedo()) {
2100 m_Undo.Redo();
tsepez4cf55152016-11-02 14:37:54 -07002101 return true;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002102 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002103 }
2104
tsepez4cf55152016-11-02 14:37:54 -07002105 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002106}
2107
tsepez4cf55152016-11-02 14:37:54 -07002108bool CFX_Edit::Undo() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002109 if (m_bEnableUndo) {
2110 if (m_Undo.CanUndo()) {
2111 m_Undo.Undo();
tsepez4cf55152016-11-02 14:37:54 -07002112 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002113 }
2114 }
2115
tsepez4cf55152016-11-02 14:37:54 -07002116 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002117}
2118
2119void CFX_Edit::SetCaretOrigin() {
thestig821d59e2016-05-11 12:59:22 -07002120 if (!m_pVT->IsValid())
2121 return;
2122
2123 CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
2124 pIterator->SetAt(m_wpCaret);
2125 CPVT_Word word;
2126 CPVT_Line line;
2127 if (pIterator->GetWord(word)) {
2128 m_ptCaret.x = word.ptWord.x + word.fWidth;
2129 m_ptCaret.y = word.ptWord.y;
2130 } else if (pIterator->GetLine(line)) {
2131 m_ptCaret.x = line.ptLine.x;
2132 m_ptCaret.y = line.ptLine.y;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002133 }
2134}
2135
2136int32_t CFX_Edit::WordPlaceToWordIndex(const CPVT_WordPlace& place) const {
2137 if (m_pVT->IsValid())
2138 return m_pVT->WordPlaceToWordIndex(place);
2139
2140 return -1;
2141}
2142
2143CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const {
2144 if (m_pVT->IsValid())
2145 return m_pVT->WordIndexToWordPlace(index);
2146
2147 return CPVT_WordPlace();
2148}
2149
tsepez4cf55152016-11-02 14:37:54 -07002150bool CFX_Edit::IsTextFull() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002151 int32_t nTotalWords = m_pVT->GetTotalWords();
2152 int32_t nLimitChar = m_pVT->GetLimitChar();
2153 int32_t nCharArray = m_pVT->GetCharArray();
2154
2155 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
2156 (nCharArray > 0 && nTotalWords >= nCharArray);
2157}
2158
tsepez4cf55152016-11-02 14:37:54 -07002159bool CFX_Edit::IsTextOverflow() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002160 if (!m_bEnableScroll && !m_bEnableOverflow) {
Tom Sepez281a9ea2016-02-26 14:24:28 -08002161 CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
2162 CFX_FloatRect rcContent = m_pVT->GetContentRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002163
dsinclair448c4332016-08-02 12:07:35 -07002164 if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
2165 IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
tsepez4cf55152016-11-02 14:37:54 -07002166 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002167 }
2168
dsinclair448c4332016-08-02 12:07:35 -07002169 if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
tsepez4cf55152016-11-02 14:37:54 -07002170 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002171 }
2172
tsepez4cf55152016-11-02 14:37:54 -07002173 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002174}
2175
tsepez4cf55152016-11-02 14:37:54 -07002176bool CFX_Edit::CanUndo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002177 if (m_bEnableUndo) {
2178 return m_Undo.CanUndo();
2179 }
2180
tsepez4cf55152016-11-02 14:37:54 -07002181 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002182}
2183
tsepez4cf55152016-11-02 14:37:54 -07002184bool CFX_Edit::CanRedo() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002185 if (m_bEnableUndo) {
2186 return m_Undo.CanRedo();
2187 }
2188
tsepez4cf55152016-11-02 14:37:54 -07002189 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002190}
2191
tsepez4cf55152016-11-02 14:37:54 -07002192void CFX_Edit::EnableRefresh(bool bRefresh) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002193 m_bEnableRefresh = bRefresh;
2194}
2195
tsepez4cf55152016-11-02 14:37:54 -07002196void CFX_Edit::EnableUndo(bool bUndo) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002197 m_bEnableUndo = bUndo;
2198}
2199
tsepez4cf55152016-11-02 14:37:54 -07002200void CFX_Edit::EnableOprNotify(bool bNotify) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002201 m_bOprNotify = bNotify;
2202}
2203
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002204CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place,
tsepeza31da742016-09-08 11:28:14 -07002205 const CFX_WideString& sText,
dsinclairefd5a992016-07-18 10:04:07 -07002206 int32_t charset) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002207 CPVT_WordPlace wp = place;
2208
2209 if (m_pVT->IsValid()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002210 for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) {
Tom Sepez62a70f92016-03-21 15:00:20 -07002211 uint16_t word = sText[i];
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002212 switch (word) {
2213 case 0x0D:
dsinclairefd5a992016-07-18 10:04:07 -07002214 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002215 if (sText[i + 1] == 0x0A)
2216 i++;
2217 break;
2218 case 0x0A:
dsinclairefd5a992016-07-18 10:04:07 -07002219 wp = m_pVT->InsertSection(wp, nullptr, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002220 if (sText[i + 1] == 0x0D)
2221 i++;
2222 break;
2223 case 0x09:
2224 word = 0x20;
2225 default:
2226 wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset),
dsinclairefd5a992016-07-18 10:04:07 -07002227 nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002228 break;
2229 }
2230 }
2231 }
2232
2233 return wp;
2234}
2235
Tom Sepez62a70f92016-03-21 15:00:20 -07002236int32_t CFX_Edit::GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset) {
dsinclairc7a73492016-04-05 12:01:42 -07002237 if (IPVT_FontMap* pFontMap = GetFontMap())
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002238 return pFontMap->CharSetFromUnicode(word, nOldCharset);
2239 return nOldCharset;
2240}
2241
Tom Sepez3509d162017-01-30 13:22:02 -08002242void CFX_Edit::AddEditUndoItem(
2243 std::unique_ptr<CFX_Edit_UndoItem> pEditUndoItem) {
2244 if (m_pGroupUndoItem)
2245 m_pGroupUndoItem->AddUndoItem(std::move(pEditUndoItem));
2246 else
2247 m_Undo.AddItem(std::move(pEditUndoItem));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002248}
2249
weili625ad662016-06-15 11:21:33 -07002250CFX_Edit_LineRectArray::CFX_Edit_LineRectArray() {}
2251
Tom Sepez3509d162017-01-30 13:22:02 -08002252CFX_Edit_LineRectArray::~CFX_Edit_LineRectArray() {}
weili625ad662016-06-15 11:21:33 -07002253
Tom Sepez3509d162017-01-30 13:22:02 -08002254void CFX_Edit_LineRectArray::operator=(CFX_Edit_LineRectArray&& that) {
2255 m_LineRects = std::move(that.m_LineRects);
weili625ad662016-06-15 11:21:33 -07002256}
2257
2258void CFX_Edit_LineRectArray::Add(const CPVT_WordRange& wrLine,
2259 const CFX_FloatRect& rcLine) {
Tom Sepez3509d162017-01-30 13:22:02 -08002260 m_LineRects.push_back(pdfium::MakeUnique<CFX_Edit_LineRect>(wrLine, rcLine));
weili625ad662016-06-15 11:21:33 -07002261}
2262
2263int32_t CFX_Edit_LineRectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08002264 return pdfium::CollectionSize<int32_t>(m_LineRects);
weili625ad662016-06-15 11:21:33 -07002265}
2266
2267CFX_Edit_LineRect* CFX_Edit_LineRectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002268 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002269 return nullptr;
2270
Tom Sepez3509d162017-01-30 13:22:02 -08002271 return m_LineRects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002272}
2273
2274CFX_Edit_Select::CFX_Edit_Select() {}
2275
2276CFX_Edit_Select::CFX_Edit_Select(const CPVT_WordPlace& begin,
2277 const CPVT_WordPlace& end) {
2278 Set(begin, end);
2279}
2280
2281CFX_Edit_Select::CFX_Edit_Select(const CPVT_WordRange& range) {
2282 Set(range.BeginPos, range.EndPos);
2283}
2284
2285CPVT_WordRange CFX_Edit_Select::ConvertToWordRange() const {
2286 return CPVT_WordRange(BeginPos, EndPos);
2287}
2288
2289void CFX_Edit_Select::Default() {
2290 BeginPos.Default();
2291 EndPos.Default();
2292}
2293
2294void CFX_Edit_Select::Set(const CPVT_WordPlace& begin,
2295 const CPVT_WordPlace& end) {
2296 BeginPos = begin;
2297 EndPos = end;
2298}
2299
2300void CFX_Edit_Select::SetBeginPos(const CPVT_WordPlace& begin) {
2301 BeginPos = begin;
2302}
2303
2304void CFX_Edit_Select::SetEndPos(const CPVT_WordPlace& end) {
2305 EndPos = end;
2306}
2307
tsepez4cf55152016-11-02 14:37:54 -07002308bool CFX_Edit_Select::IsExist() const {
weili625ad662016-06-15 11:21:33 -07002309 return BeginPos != EndPos;
2310}
2311
weili625ad662016-06-15 11:21:33 -07002312CFX_Edit_RectArray::CFX_Edit_RectArray() {}
2313
Tom Sepez3509d162017-01-30 13:22:02 -08002314CFX_Edit_RectArray::~CFX_Edit_RectArray() {}
weili625ad662016-06-15 11:21:33 -07002315
Tom Sepez3509d162017-01-30 13:22:02 -08002316void CFX_Edit_RectArray::Clear() {
2317 m_Rects.clear();
weili625ad662016-06-15 11:21:33 -07002318}
2319
2320void CFX_Edit_RectArray::Add(const CFX_FloatRect& rect) {
2321 // check for overlapped area
Tom Sepez3509d162017-01-30 13:22:02 -08002322 for (const auto& pRect : m_Rects) {
weili625ad662016-06-15 11:21:33 -07002323 if (pRect && pRect->Contains(rect))
2324 return;
2325 }
Tom Sepez3509d162017-01-30 13:22:02 -08002326 m_Rects.push_back(pdfium::MakeUnique<CFX_FloatRect>(rect));
weili625ad662016-06-15 11:21:33 -07002327}
2328
2329int32_t CFX_Edit_RectArray::GetSize() const {
Tom Sepez3509d162017-01-30 13:22:02 -08002330 return pdfium::CollectionSize<int32_t>(m_Rects);
weili625ad662016-06-15 11:21:33 -07002331}
2332
2333CFX_FloatRect* CFX_Edit_RectArray::GetAt(int32_t nIndex) const {
Tom Sepez3509d162017-01-30 13:22:02 -08002334 if (nIndex < 0 || nIndex >= GetSize())
weili625ad662016-06-15 11:21:33 -07002335 return nullptr;
2336
Tom Sepez3509d162017-01-30 13:22:02 -08002337 return m_Rects[nIndex].get();
weili625ad662016-06-15 11:21:33 -07002338}