7#include "fpdfsdk/pwl/cpwl_edit_impl.h"
13#include "core/fpdfapi/font/cpdf_font.h"
14#include "core/fpdfapi/render/cpdf_renderoptions.h"
15#include "core/fpdfapi/render/cpdf_textrenderer.h"
16#include "core/fpdfdoc/cpvt_word.h"
17#include "core/fpdfdoc/ipvt_fontmap.h"
18#include "core/fxcrt/autorestorer.h"
19#include "core/fxcrt/fx_codepage.h"
20#include "core/fxge/cfx_fillrenderoptions.h"
21#include "core/fxge/cfx_graphstatedata.h"
22#include "core/fxge/cfx_path.h"
23#include "core/fxge/cfx_renderdevice.h"
24#include "fpdfsdk/pwl/cpwl_edit.h"
25#include "fpdfsdk/pwl/cpwl_scroll_bar.h"
26#include "fpdfsdk/pwl/ipwl_fillernotify.h"
27#include "third_party/base/check.h"
28#include "third_party/base/check_op.h"
32const int kEditUndoMaxItems = 10000;
39 const ByteString& str,
44 CFX_PointF pos = mtUser2Device.Transform(pt);
46 DCHECK(ro.GetOptions().bClearType);
49 mtUser2Device
, str
, crTextFill
, ro
);
61 return m_pVTIterator->NextWord();
67 if (m_pVTIterator->GetWord(word)) {
68 word.ptWord = m_pEdit->VTToEdit(word.ptWord);
77 if (m_pVTIterator->GetLine(line)) {
78 line.ptLine = m_pEdit->VTToEdit(line.ptLine);
85 m_pVTIterator->SetAt(nWordIndex);
89 m_pVTIterator->SetAt(place);
93 return m_pVTIterator->GetWordPlace();
105 int32_t nFontIndex)
override;
118 uint32_t charcode = pPDFFont->IsUnicodeCompatible()
119 ? pPDFFont->CharCodeFromUnicode(word)
120 :
GetFontMap()->CharCodeFromUnicode(nFontIndex, word);
124 return pPDFFont->GetCharWidthF(charcode);
129 int32_t nFontIndex) {
130 return GetFontMap()->GetWordFontIndex(word, charset, nFontIndex);
138 m_OldLineRects = std::move(m_NewLineRects);
139 m_NewLineRects.clear();
140 m_RefreshRects.clear();
145 m_NewLineRects.emplace_back(linerange, rect);
149 for (
const auto& lineRect : m_OldLineRects)
150 Add(lineRect.m_rcLine);
152 for (
const auto& lineRect : m_NewLineRects)
153 Add(lineRect.m_rcLine);
156std::vector<CFX_FloatRect>*
CPWL_EditImpl::RefreshState::GetRefreshRects() {
157 return &m_RefreshRects;
161 m_RefreshRects.clear();
166 for (
const auto& rect : m_RefreshRects) {
167 if (rect.Contains(new_rect))
170 m_RefreshRects.push_back(new_rect);
178 return m_nCurUndoPos > 0;
184 int undo_remaining = 1;
185 while (CanUndo() && undo_remaining > 0) {
186 undo_remaining += m_UndoItemStack[m_nCurUndoPos - 1]->Undo();
190 DCHECK_EQ(undo_remaining, 0);
196 return m_nCurUndoPos < m_UndoItemStack.size();
200 CHECK(!m_UndoItemStack.empty());
201 return m_UndoItemStack.back().get();
208 while (CanRedo() && nRedoRemain > 0) {
209 nRedoRemain += m_UndoItemStack[m_nCurUndoPos]->Redo();
213 DCHECK_EQ(nRedoRemain, 0);
218void CPWL_EditImpl::UndoStack::AddItem(std::unique_ptr<UndoItemIface> pItem) {
224 if (m_UndoItemStack.size() >= kEditUndoMaxItems)
227 m_UndoItemStack.push_back(std::move(pItem));
228 m_nCurUndoPos = m_UndoItemStack.size();
232 DCHECK(m_UndoItemStack.size() > 1);
233 m_UndoItemStack.pop_front();
238 m_UndoItemStack.pop_back();
273 m_nCharset(charset) {
280 m_pEdit->SelectNone();
281 m_pEdit->SetCaret(m_wpOld);
282 m_pEdit->InsertWord(m_Word, m_nCharset,
false);
287 m_pEdit->SelectNone();
288 m_pEdit->SetCaret(m_wpNew);
289 m_pEdit->Backspace(
false);
316 :
m_pEdit(
pEdit), m_wpOld(wpOldPlace), m_wpNew(wpNewPlace) {
323 m_pEdit->SelectNone();
324 m_pEdit->SetCaret(m_wpOld);
325 m_pEdit->InsertReturn(
false);
330 m_pEdit->SelectNone();
331 m_pEdit->SetCaret(m_wpNew);
332 m_pEdit->Backspace(
false);
347 bool IsEnd()
const {
return m_bEnd; }
360 set_undo_remaining(3);
366 m_pEdit->SelectNone();
372 return undo_remaining();
376 m_pEdit->SelectNone();
382 return undo_remaining();
416 m_nCharset(charset) {
423 m_pEdit->SelectNone();
424 m_pEdit->SetCaret(m_wpOld);
425 m_pEdit->Backspace(
false);
430 m_pEdit->SelectNone();
431 m_pEdit->SetCaret(m_wpNew);
432 if (m_wpNew.nSecIndex != m_wpOld.nSecIndex)
433 m_pEdit->InsertReturn(
false);
435 m_pEdit->InsertWord(m_Word, m_nCharset,
false);
481 m_pEdit->SelectNone();
482 m_pEdit->SetCaret(m_wpOld);
483 m_pEdit->Delete(
false);
488 m_pEdit->SelectNone();
489 m_pEdit->SetCaret(m_wpNew);
491 m_pEdit->InsertReturn(
false);
493 m_pEdit->InsertWord(m_Word, m_nCharset,
false);
501 const WideString& swText);
517 const WideString& swText)
525 m_pEdit->SelectNone();
526 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
527 m_pEdit->Clear(
false);
532 m_pEdit->SelectNone();
533 m_pEdit->SetCaret(m_wrSel.BeginPos);
534 m_pEdit->InsertText(m_swText, FX_Charset::kDefault,
false);
535 m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
545 const WideString& swText,
565 const WideString& swText,
571 m_nCharset(charset) {
578 m_pEdit->SelectNone();
579 m_pEdit->SetCaret(m_wpOld);
580 m_pEdit->InsertText(m_swText, m_nCharset,
false);
585 m_pEdit->SelectNone();
586 m_pEdit->SetSelection(m_wpOld, m_wpNew);
587 m_pEdit->Clear(
false);
593 FX_COLORREF crTextFill,
595 const CFX_PointF& ptOffset,
603 FX_COLORREF crCurFill = crTextFill;
604 FX_COLORREF crOldFill = crCurFill;
605 bool bSelect =
false;
609 int32_t nFontIndex = -1;
634 crCurFill = bSelect ? crWhite : crTextFill;
637 crCurFill = crTextFill;
638 crOldFill = crCurFill;
663 crOldFill != crCurFill) {
665 DrawTextString(pDevice,
666 CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
668 mtUser2Device, sTextBuf, crOldFill);
673 crOldFill = crCurFill;
679 CFX_PointF(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y),
688 DrawTextString(pDevice,
689 CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
691 mtUser2Device, sTextBuf, crOldFill);
702 SetCaret(m_pVT->GetBeginWordPlace());
707 m_pVTProvider = std::make_unique<Provider>(pFontMap);
708 m_pVT->SetProvider(m_pVTProvider.get());
717 m_pIterator = std::make_unique<Iterator>(
this, m_pVT->GetIterator());
718 return m_pIterator.get();
722 return m_pVTProvider ? m_pVTProvider->GetFontMap() :
nullptr;
726 m_pVT->SetPlateRect(rect);
727 m_ptScrollPos = CFX_PointF(rect.left, rect.top);
731 m_pVT->SetAlignment(nFormat);
735 m_nAlignment = nFormat;
739 m_pVT->SetPasswordChar(wSubWord);
743 m_pVT->SetLimitChar(nLimitChar);
747 m_pVT->SetCharArray(nCharArray);
751 m_pVT->SetMultiLine(bMultiLine);
755 m_pVT->SetAutoReturn(bAuto);
759 m_pVT->SetAutoFontSize(bAuto);
763 m_pVT->SetFontSize(fFontSize);
767 m_bEnableScroll = bAuto;
771 m_bEnableOverflow = bAllowed;
775 if (m_pVT->IsValid()) {
776 if (nStartChar == 0 && nEndChar < 0) {
778 }
else if (nStartChar < 0) {
781 if (nStartChar < nEndChar) {
782 SetSelection(m_pVT->WordIndexToWordPlace(nStartChar),
783 m_pVT->WordIndexToWordPlace(nEndChar));
785 SetSelection(m_pVT->WordIndexToWordPlace(nEndChar),
786 m_pVT->WordIndexToWordPlace(nStartChar));
794 if (!m_pVT->IsValid())
798 m_SelState.Set(begin, end);
799 SetCaret(m_SelState.EndPos);
801 if (!m_SelState.IsEmpty())
807 if (!m_pVT->IsValid())
808 return std::make_pair(-1, -1);
810 if (m_SelState.IsEmpty()) {
811 return std::make_pair(m_pVT->WordPlaceToWordIndex(m_wpCaret),
812 m_pVT->WordPlaceToWordIndex(m_wpCaret));
814 if (m_SelState.BeginPos
< m_SelState.EndPos) {
815 return std::make_pair(m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos),
816 m_pVT->WordPlaceToWordIndex(m_SelState.EndPos));
818 return std::make_pair(m_pVT->WordPlaceToWordIndex(m_SelState.EndPos),
819 m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos));
823 if (m_pVT->IsValid())
824 return m_pVT->WordPlaceToWordIndex(m_wpCaret);
835 if (!m_pVT->IsValid())
856 if (!m_pVT->IsValid())
861 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
862 m_pVT->UpdateWordPlace(wrTemp.EndPos);
896 return m_SelState.ConvertToWordRange();
905 return InsertWord(word, charset,
true);
909 return InsertReturn(
true);
913 return Backspace(
true);
925 return InsertText(sText, charset,
true);
929 return m_pVT->GetFontSize();
933 return m_pVT->GetPasswordChar();
937 return m_pVT->GetCharArray();
941 return VTToEdit(m_pVT->GetContentRect());
945 if (m_pVT->IsValid())
946 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace());
952 if (m_bEnableOverflow)
955 if (m_pVT->IsValid()) {
959 m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top)));
961 EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom)));
970 if (m_pVT->IsValid()) {
971 return m_pVT->SearchWordPlace(EditToVT(point));
978 if (m_pVT->IsValid()) {
988 if (m_pVT->IsValid()) {
989 m_pVT->UpdateWordPlace(m_wpCaret);
990 m_pVT->RearrangeAll();
991 m_pVT->UpdateWordPlace(m_wpCaret);
998 if (m_pVT->IsValid()) {
999 m_pVT->UpdateWordPlace(m_wpCaret);
1000 m_pVT->RearrangePart(range);
1001 m_pVT->UpdateWordPlace(m_wpCaret);
1003 SetContentChanged();
1012 m_rcOldContent
= rcContent;
1018 if (!m_pVT->IsValid())
1021 SetCaret(m_SelState.EndPos);
1028 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
1036 return !m_SelState.IsEmpty();
1039CFX_PointF
CPWL_EditImpl::VTToEdit(
const CFX_PointF& point)
const {
1043 float fPadding = 0.0f;
1045 switch (m_nAlignment) {
1057 return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left),
1058 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
1061CFX_PointF
CPWL_EditImpl::EditToVT(
const CFX_PointF& point)
const {
1065 float fPadding = 0.0f;
1067 switch (m_nAlignment) {
1079 return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left),
1080 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
1084 CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom));
1085 CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top));
1087 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
1101 m_bNotifyFlag =
true;
1109 m_pNotify->SetScrollInfo(Info);
1113 if (!m_bEnableScroll)
1116 if (m_pVT->IsValid()) {
1118 m_ptScrollPos.x = fx;
1125 if (!m_bEnableScroll)
1128 if (m_pVT->IsValid()) {
1130 m_ptScrollPos.y = fy;
1134 if (!m_bNotifyFlag) {
1136 m_bNotifyFlag =
true;
1137 m_pNotify->SetScrollPosition(fy);
1145 SetScrollPosX(point.x);
1146 SetScrollPosY(point.y);
1152 return m_ptScrollPos;
1156 if (m_pVT->IsValid()) {
1161 SetScrollPosX(rcPlate
.left);
1164 SetScrollPosX(rcContent
.left);
1166 rcContent.right - rcPlate.Width())) {
1172 SetScrollPosY(rcPlate
.top);
1175 rcContent.bottom + rcPlate.Height())) {
1178 SetScrollPosY(rcContent
.top);
1187 if (!m_pVT->IsValid())
1198 ptHead.x = word.ptWord.x + word
.fWidth;
1199 ptHead.y = word.ptWord.y + word
.fAscent;
1200 ptFoot.x = word.ptWord.x + word
.fWidth;
1201 ptFoot.y = word.ptWord.y + word
.fDescent;
1203 ptHead.x = line.ptLine.x;
1205 ptFoot.x = line.ptLine.x;
1209 CFX_PointF ptHeadEdit = VTToEdit(ptHead);
1210 CFX_PointF ptFootEdit = VTToEdit(ptFoot);
1215 SetScrollPosX(ptHead.x);
1217 SetScrollPosX(ptHead.x - rcPlate
.Width());
1225 SetScrollPosY(ptFoot.y + rcPlate
.Height());
1229 SetScrollPosY(ptHead.y);
1236 if (m_bEnableRefresh && m_pVT->IsValid()) {
1237 m_Refresh.BeginRefresh();
1240 m_Refresh.NoAnalyse();
1241 m_ptRefreshScrollPos = m_ptScrollPos;
1244 if (!m_bNotifyFlag) {
1246 m_bNotifyFlag =
true;
1247 std::vector<CFX_FloatRect>* pRects = m_Refresh.GetRefreshRects();
1248 for (
auto& rect : *pRects) {
1249 if (!m_pNotify->InvalidateRect(&rect)) {
1250 m_pNotify =
nullptr;
1257 m_Refresh.EndRefresh();
1262 if (!m_pVT->IsValid())
1267 m_pVT->UpdateWordPlace(wpBegin);
1269 m_pVT->UpdateWordPlace(wpEnd);
1284 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd),
1293 m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1294 m_pVT->UpdateWordPlace(wrTemp.EndPos);
1312 wordinfo.ptWord.x + wordinfo
.fWidth,
1316 if (!m_bNotifyFlag) {
1318 m_bNotifyFlag =
true;
1320 if (!m_pNotify->InvalidateRect(&rcRefresh)) {
1321 m_pNotify =
nullptr;
1332 if (!m_bNotifyFlag) {
1334 m_bNotifyFlag =
true;
1336 if (!m_pNotify->InvalidateRect(&rcRefresh)) {
1337 m_pNotify =
nullptr;
1348 m_wpOldCaret = m_wpCaret;
1354 if (!m_bNotifyFlag) {
1363 ptHead.x = word.ptWord.x + word
.fWidth;
1364 ptHead.y = word.ptWord.y + word
.fAscent;
1365 ptFoot.x = word.ptWord.x + word
.fWidth;
1366 ptFoot.y = word.ptWord.y + word
.fDescent;
1368 ptHead.x = line.ptLine.x;
1370 ptFoot.x = line.ptLine.x;
1375 m_bNotifyFlag =
true;
1376 m_pNotify->SetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead),
1385 if (!m_pVT->IsValid())
1389 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1390 m_SelState.Set(m_wpCaret, m_wpCaret);
1399 if (!m_pVT->IsValid())
1402 SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
1403 if (m_wpCaret
== m_wpOldCaret)
1406 m_SelState.SetEndPos(m_wpCaret);
1414 if (!m_pVT->IsValid())
1417 SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));
1419 if (m_SelState.IsEmpty())
1420 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1422 m_SelState.SetEndPos(m_wpCaret);
1424 if (m_wpOldCaret
!= m_wpCaret) {
1437 if (!m_pVT->IsValid())
1440 SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));
1442 if (m_SelState.IsEmpty())
1443 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1445 m_SelState.SetEndPos(m_wpCaret);
1447 if (m_wpOldCaret
!= m_wpCaret) {
1460 if (!m_pVT->IsValid())
1464 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1465 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1466 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1468 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1469 if (m_SelState.IsEmpty())
1470 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1472 m_SelState.SetEndPos(m_wpCaret);
1474 if (m_wpOldCaret
!= m_wpCaret) {
1480 if (!m_SelState.IsEmpty()) {
1481 if (m_SelState.BeginPos
< m_SelState.EndPos)
1482 SetCaret(m_SelState.BeginPos);
1484 SetCaret(m_SelState.EndPos);
1490 if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
1491 m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) {
1492 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1494 SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
1503 if (!m_pVT->IsValid())
1507 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1508 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1509 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
1510 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1512 if (m_SelState.IsEmpty())
1513 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1515 m_SelState.SetEndPos(m_wpCaret);
1517 if (m_wpOldCaret
!= m_wpCaret) {
1523 if (!m_SelState.IsEmpty()) {
1524 if (m_SelState.BeginPos
> m_SelState.EndPos)
1525 SetCaret(m_SelState.BeginPos);
1527 SetCaret(m_SelState.EndPos);
1533 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1534 if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
1535 m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) {
1536 SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
1546 if (!m_pVT->IsValid())
1551 SetCaret(m_pVT->GetBeginWordPlace());
1553 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1555 if (m_SelState.IsEmpty())
1556 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1558 m_SelState.SetEndPos(m_wpCaret);
1564 if (!m_SelState.IsEmpty()) {
1565 SetCaret(
std::min(m_SelState.BeginPos, m_SelState.EndPos));
1571 SetCaret(m_pVT->GetBeginWordPlace());
1573 SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
1583 if (!m_pVT->IsValid())
1588 SetCaret(m_pVT->GetEndWordPlace());
1590 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1592 if (m_SelState.IsEmpty())
1593 m_SelState.Set(m_wpOldCaret, m_wpCaret);
1595 m_SelState.SetEndPos(m_wpCaret);
1601 if (!m_SelState.IsEmpty()) {
1602 SetCaret(
std::max(m_SelState.BeginPos, m_SelState.EndPos));
1608 SetCaret(m_pVT->GetEndWordPlace());
1610 SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
1622 if (IsTextOverflow() || !m_pVT->IsValid())
1625 m_pVT->UpdateWordPlace(m_wpCaret);
1627 m_pVT->InsertWord(m_wpCaret, word, GetCharSetFromUnicode(word, charset)));
1628 m_SelState.Set(m_wpCaret, m_wpCaret);
1629 if (m_wpCaret
== m_wpOldCaret)
1632 if (bAddUndo && m_bEnableUndo) {
1633 AddEditUndoItem(std::make_unique<UndoInsertWord>(
this, m_wpOldCaret,
1634 m_wpCaret, word, charset));
1636 PaintInsertText(m_wpOldCaret, m_wpCaret);
1641 if (IsTextOverflow() || !m_pVT->IsValid())
1644 m_pVT->UpdateWordPlace(m_wpCaret);
1645 SetCaret(m_pVT->InsertSection(m_wpCaret));
1646 m_SelState.Set(m_wpCaret, m_wpCaret);
1647 if (m_wpCaret
== m_wpOldCaret)
1650 if (bAddUndo && m_bEnableUndo) {
1652 std::make_unique<UndoInsertReturn>(
this, m_wpOldCaret, m_wpCaret));
1663 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace())
1672 m_pVT->UpdateWordPlace(m_wpCaret);
1673 SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
1674 m_SelState.Set(m_wpCaret, m_wpCaret);
1675 if (m_wpCaret
== m_wpOldCaret)
1678 if (bAddUndo && m_bEnableUndo) {
1679 AddEditUndoItem(std::make_unique<UndoBackspace>(
1680 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset));
1691 if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace())
1697 pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
1700 m_pVT->UpdateWordPlace(m_wpCaret);
1701 bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
1702 SetCaret(m_pVT->DeleteWord(m_wpCaret));
1703 m_SelState.Set(m_wpCaret, m_wpCaret);
1704 if (bAddUndo && m_bEnableUndo) {
1706 AddEditUndoItem(std::make_unique<UndoDelete>(
1707 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, bSecEnd));
1709 AddEditUndoItem(std::make_unique<UndoDelete>(
1710 this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, bSecEnd));
1722 if (m_pVT->IsValid()) {
1723 m_pVT->DeleteWords(GetWholeWordRange());
1724 SetCaret(m_pVT->GetBeginWordPlace());
1733 if (!m_pVT->IsValid() || m_SelState.IsEmpty())
1737 if (bAddUndo && m_bEnableUndo) {
1739 std::make_unique<UndoClear>(
this, range, GetSelectedText()));
1742 SetCaret(m_pVT->DeleteWords(range));
1743 m_SelState.Set(m_wpCaret, m_wpCaret);
1744 RearrangePart(range);
1755 if (IsTextOverflow())
1758 m_pVT->UpdateWordPlace(m_wpCaret);
1759 SetCaret(DoInsertText(m_wpCaret, sText, charset));
1760 m_SelState.Set(m_wpCaret, m_wpCaret);
1761 if (m_wpCaret
== m_wpOldCaret)
1764 if (bAddUndo && m_bEnableUndo) {
1765 AddEditUndoItem(std::make_unique<UndoInsertText>(
1766 this, m_wpOldCaret, m_wpCaret, sText, charset));
1768 PaintInsertText(m_wpOldCaret, m_wpCaret);
1774 if (m_pVT->IsValid()) {
1784 AddEditUndoItem(std::make_unique<UndoReplaceSelection>(
this,
false));
1788 if (!is_insert_undo_clear) {
1789 m_Undo.GetLastAddItem()->set_undo_remaining(2);
1795 m_SelState.Set(caret_before_insert, caret_after_insert);
1797 AddEditUndoItem(std::make_unique<UndoReplaceSelection>(
this,
true));
1798 if (!is_insert_undo_clear) {
1799 m_Undo.GetLastAddItem()->set_undo_remaining(2);
1804 AddEditUndoItem(std::make_unique<UndoReplaceSelection>(
this,
false));
1808 if (!is_insert_undo_clear) {
1809 m_Undo.GetLastAddItem()->set_undo_remaining(2);
1812 AddEditUndoItem(std::make_unique<UndoReplaceSelection>(
this,
true));
1813 if (!is_insert_undo_clear) {
1814 m_Undo.GetLastAddItem()->set_undo_remaining(2);
1819 if (m_bEnableUndo) {
1820 if (m_Undo.CanRedo()) {
1830 if (m_bEnableUndo) {
1831 if (m_Undo.CanUndo()) {
1841 if (!m_pVT->IsValid())
1849 m_ptCaret.x = word.ptWord.x + word.fWidth;
1850 m_ptCaret.y = word.ptWord.y;
1852 m_ptCaret.x = line.ptLine.x;
1853 m_ptCaret.y = line.ptLine.y;
1858 if (m_pVT->IsValid())
1859 return m_pVT->WordIndexToWordPlace(index);
1865 int32_t nTotalWords = m_pVT->GetTotalWords();
1866 int32_t nLimitChar = m_pVT->GetLimitChar();
1867 int32_t nCharArray = m_pVT->GetCharArray();
1869 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) ||
1870 (nCharArray > 0 && nTotalWords >= nCharArray);
1874 if (!m_bEnableScroll && !m_bEnableOverflow) {
1878 if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
1891 if (m_bEnableUndo) {
1892 return m_Undo.CanUndo();
1899 if (m_bEnableUndo) {
1900 return m_Undo.CanRedo();
1907 m_bEnableRefresh = bRefresh;
1911 m_bEnableUndo = bUndo;
1915 const WideString& sText,
1917 if (!m_pVT->IsValid())
1921 for (size_t i = 0; i < sText.GetLength(); ++i) {
1922 uint16_t word = sText[i];
1925 wp = m_pVT->InsertSection(wp);
1926 if (i + 1 < sText.GetLength() && sText[i + 1] ==
'\n')
1930 wp = m_pVT->InsertSection(wp);
1936 wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset));
1951 std::unique_ptr<UndoItemIface> pEditUndoItem) {
1952 m_Undo.AddItem(std::move(pEditUndoItem));
1961 return ByteString
();
1967 uint32_t dwCharCode = pPDFFont->IsUnicodeCompatible()
1968 ? pPDFFont->CharCodeFromUnicode(Word)
1970 if (dwCharCode > 0) {
1971 pPDFFont->AppendChar(&sWord, dwCharCode);
1975 pPDFFont->AppendChar(&sWord, Word);
2005 return BeginPos
== EndPos;
void Intersect(const CFX_FloatRect &other_rect)
CFX_FloatRect & operator=(const CFX_FloatRect &that)=default
CFX_FloatRect TransformRect(const CFX_FloatRect &rect) const
void AppendRect(float left, float bottom, float right, float top)
StateRestorer(CFX_RenderDevice *pDevice)
bool SetClip_Rect(const FX_RECT &pRect)
bool DrawPath(const CFX_Path &path, const CFX_Matrix *pObject2Device, const CFX_GraphStateData *pGraphState, uint32_t fill_color, uint32_t stroke_color, const CFX_FillRenderOptions &fill_options)
static constexpr uint32_t kInvalidCharCode
void SetColorMode(Type mode)
static void DrawTextString(CFX_RenderDevice *pDevice, float origin_x, float origin_y, CPDF_Font *pFont, float font_size, const CFX_Matrix &matrix, const ByteString &str, FX_ARGB fill_argb, const CPDF_RenderOptions &options)
void SetAt(int32_t nWordIndex)
bool GetWord(CPVT_Word &word) const
bool GetLine(CPVT_Line &line) const
const CPVT_WordPlace & GetWordPlace() const
void SetAt(const CPVT_WordPlace &place)
Provider(IPVT_FontMap *pFontMap)
IPVT_FontMap * GetFontMap()
void SetAt(int32_t nWordIndex)
Iterator(CPWL_EditImpl *pEdit, CPVT_VariableText::Iterator *pVTIterator)
bool GetWord(CPVT_Word &word) const
bool GetLine(CPVT_Line &line) const
const CPVT_WordPlace & GetAt() const
void SetAt(const CPVT_WordPlace &place)
Provider(IPVT_FontMap *pFontMap)
int32_t GetWordFontIndex(uint16_t word, FX_Charset charset, int32_t nFontIndex) override
int GetCharWidth(int32_t nFontIndex, uint16_t word) override
UndoBackspace(CPWL_EditImpl *pEdit, const CPVT_WordPlace &wpOldPlace, const CPVT_WordPlace &wpNewPlace, uint16_t word, FX_Charset charset)
~UndoBackspace() override
UndoClear(CPWL_EditImpl *pEdit, const CPVT_WordRange &wrSel, const WideString &swText)
UndoDelete(CPWL_EditImpl *pEdit, const CPVT_WordPlace &wpOldPlace, const CPVT_WordPlace &wpNewPlace, uint16_t word, FX_Charset charset, bool bSecEnd)
~UndoInsertReturn() override
UndoInsertReturn(CPWL_EditImpl *pEdit, const CPVT_WordPlace &wpOldPlace, const CPVT_WordPlace &wpNewPlace)
UndoInsertText(CPWL_EditImpl *pEdit, const CPVT_WordPlace &wpOldPlace, const CPVT_WordPlace &wpNewPlace, const WideString &swText, FX_Charset charset)
~UndoInsertText() override
~UndoInsertWord() override
UndoInsertWord(CPWL_EditImpl *pEdit, const CPVT_WordPlace &wpOldPlace, const CPVT_WordPlace &wpNewPlace, uint16_t word, FX_Charset charset)
~UndoReplaceSelection() override
UndoReplaceSelection(CPWL_EditImpl *pEdit, bool bIsEnd)
WideString GetRangeText(const CPVT_WordRange &range) const
void OnVK_DOWN(bool bShift)
WideString GetText() const
uint16_t GetPasswordChar() const
void EnableUndo(bool bUndo)
CFX_FloatRect GetContentRect() const
void SetText(const WideString &sText)
int32_t GetCharArray() const
std::pair< int32_t, int32_t > GetSelection() const
void OnMouseMove(const CFX_PointF &point, bool bShift, bool bCtrl)
void SetFontMap(IPVT_FontMap *pFontMap)
CPVT_WordPlace GetCaretWordPlace() const
CPVT_WordRange GetSelectWordRange() const
void OnMouseDown(const CFX_PointF &point, bool bShift, bool bCtrl)
void DrawEdit(CFX_RenderDevice *pDevice, const CFX_Matrix &mtUser2Device, FX_COLORREF crTextFill, const CFX_FloatRect &rcClip, const CFX_PointF &ptOffset, const CPVT_WordRange *pRange, IPWL_FillerNotify *pFillerNotify, IPWL_FillerNotify::PerWindowData *pSystemData)
void SetAutoScroll(bool bAuto)
void SetAutoReturn(bool bAuto)
void SetTextOverflow(bool bAllowed)
void OnVK_RIGHT(bool bShift)
void OnVK_END(bool bShift, bool bCtrl)
void SetFontSize(float fFontSize)
void SetAlignmentH(int32_t nFormat)
void RefreshWordRange(const CPVT_WordRange &wr)
void EnableRefresh(bool bRefresh)
bool InsertWord(uint16_t word, FX_Charset charset)
ByteString GetPDFWordString(int32_t nFontIndex, uint16_t Word, uint16_t SubWord)
void OnVK_HOME(bool bShift, bool bCtrl)
void OnVK_UP(bool bShift)
IPVT_FontMap * GetFontMap()
void SetLimitChar(int32_t nLimitChar)
void SetSelection(int32_t nStartChar, int32_t nEndChar)
void SetCharArray(int32_t nCharArray)
void SetAlignmentV(int32_t nFormat)
CPVT_WordPlace WordIndexToWordPlace(int32_t index) const
CPVT_WordRange GetWholeWordRange() const
CPVT_WordPlace SearchWordPlace(const CFX_PointF &point) const
WideString GetSelectedText() const
void SetNotify(CPWL_Edit *pNotify)
CPVT_WordRange GetVisibleWordRange() const
void ReplaceSelection(const WideString &text)
bool InsertText(const WideString &sText, FX_Charset charset)
float GetFontSize() const
void SetScrollPos(const CFX_PointF &point)
void ReplaceAndKeepSelection(const WideString &text)
void SetMultiLine(bool bMultiLine)
void OnVK_LEFT(bool bShift)
CFX_PointF GetScrollPos() const
void SetAutoFontSize(bool bAuto)
void SetPlateRect(const CFX_FloatRect &rect)
void SetPasswordChar(uint16_t wSubWord)
virtual RetainPtr< CPDF_Font > GetPDFFont(int32_t nFontIndex)=0
virtual int32_t CharCodeFromUnicode(int32_t nFontIndex, uint16_t word)=0
virtual FX_Charset CharSetFromUnicode(uint16_t word, FX_Charset nOldCharset)=0
virtual bool IsSelectionImplemented() const =0
virtual void OutputSelectedRect(PerWindowData *pWidgetData, const CFX_FloatRect &rect)=0
ByteString & operator+=(const ByteString &str)
WideString & operator+=(const wchar_t *str)
WideString & operator+=(wchar_t ch)
constexpr FX_ARGB ArgbEncode(uint32_t a, uint32_t r, uint32_t g, uint32_t b)
#define FXSYS_IsFloatBigger(fa, fb)
#define FXSYS_IsFloatEqual(fa, fb)
#define FXSYS_IsFloatSmaller(fa, fb)
static constexpr CFX_FillRenderOptions WindingOptions()
int32_t LineCmp(const CPVT_WordPlace &wp) const
bool operator<=(const CPVT_WordPlace &wp) const
bool operator!=(const CPVT_WordPlace &wp) const
bool operator>(const CPVT_WordPlace &wp) const
CPVT_WordPlace(int32_t other_nSecIndex, int32_t other_nLineIndex, int32_t other_nWordIndex)
bool operator<(const CPVT_WordPlace &wp) const
bool operator==(const CPVT_WordPlace &wp) const
CPVT_WordRange(const CPVT_WordPlace &begin, const CPVT_WordPlace &end)