From 6b0158fdc229e7fc45fdb61c700b709bd82b2309 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Mon, 24 Jul 2017 09:42:55 -0400 Subject: Remove fxedit place classes in pdfwindow/ This CL removes the fpdfsdk/fxedit folder and moves the code to fpdfsdk/pdfwindow which is the primary consumer. The classes were renamed from CFX_* to CPWL_*. Change-Id: I6c6178adccf978193bbb9685204657ebd3f438bb Reviewed-on: https://pdfium-review.googlesource.com/8552 Commit-Queue: dsinclair Reviewed-by: Tom Sepez --- BUILD.gn | 18 +- fpdfsdk/cpdfsdk_interform.cpp | 1 - fpdfsdk/cpdfsdk_widget.cpp | 1 - fpdfsdk/fxedit/fxet_edit.cpp | 2043 --------------------------------- fpdfsdk/fxedit/fxet_edit.h | 513 --------- fpdfsdk/fxedit/fxet_list.cpp | 637 ----------- fpdfsdk/fxedit/fxet_list.h | 168 --- fpdfsdk/pdfwindow/cpwl_appstream.cpp | 14 +- fpdfsdk/pdfwindow/cpwl_combo_box.cpp | 2 +- fpdfsdk/pdfwindow/cpwl_edit.cpp | 13 +- fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp | 6 +- fpdfsdk/pdfwindow/cpwl_edit_ctrl.h | 4 +- fpdfsdk/pdfwindow/cpwl_edit_impl.cpp | 2053 ++++++++++++++++++++++++++++++++++ fpdfsdk/pdfwindow/cpwl_edit_impl.h | 515 +++++++++ fpdfsdk/pdfwindow/cpwl_list_box.cpp | 27 +- fpdfsdk/pdfwindow/cpwl_list_box.h | 4 +- fpdfsdk/pdfwindow/cpwl_list_impl.cpp | 637 +++++++++++ fpdfsdk/pdfwindow/cpwl_list_impl.h | 168 +++ 18 files changed, 3413 insertions(+), 3411 deletions(-) delete mode 100644 fpdfsdk/fxedit/fxet_edit.cpp delete mode 100644 fpdfsdk/fxedit/fxet_edit.h delete mode 100644 fpdfsdk/fxedit/fxet_list.cpp delete mode 100644 fpdfsdk/fxedit/fxet_list.h create mode 100644 fpdfsdk/pdfwindow/cpwl_edit_impl.cpp create mode 100644 fpdfsdk/pdfwindow/cpwl_edit_impl.h create mode 100644 fpdfsdk/pdfwindow/cpwl_list_impl.cpp create mode 100644 fpdfsdk/pdfwindow/cpwl_list_impl.h diff --git a/BUILD.gn b/BUILD.gn index 313714d668..7d5232ceb0 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -187,7 +187,6 @@ static_library("pdfium") { ":fpdftext", ":fxcodec", ":fxcrt", - ":fxedit", ":fxge", ":javascript", ":pdfwindow", @@ -1077,19 +1076,6 @@ static_library("fxge") { } } -static_library("fxedit") { - sources = [ - "fpdfsdk/fxedit/fxet_edit.cpp", - "fpdfsdk/fxedit/fxet_edit.h", - "fpdfsdk/fxedit/fxet_list.cpp", - "fpdfsdk/fxedit/fxet_list.h", - ] - configs += [ ":pdfium_core_config" ] - deps = [ - ":fxcrt", - ] -} - static_library("pdfwindow") { sources = [ "fpdfsdk/pdfwindow/cpwl_appstream.cpp", @@ -1104,12 +1090,16 @@ static_library("pdfwindow") { "fpdfsdk/pdfwindow/cpwl_edit.h", "fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp", "fpdfsdk/pdfwindow/cpwl_edit_ctrl.h", + "fpdfsdk/pdfwindow/cpwl_edit_impl.cpp", + "fpdfsdk/pdfwindow/cpwl_edit_impl.h", "fpdfsdk/pdfwindow/cpwl_font_map.cpp", "fpdfsdk/pdfwindow/cpwl_font_map.h", "fpdfsdk/pdfwindow/cpwl_icon.cpp", "fpdfsdk/pdfwindow/cpwl_icon.h", "fpdfsdk/pdfwindow/cpwl_list_box.cpp", "fpdfsdk/pdfwindow/cpwl_list_box.h", + "fpdfsdk/pdfwindow/cpwl_list_impl.cpp", + "fpdfsdk/pdfwindow/cpwl_list_impl.h", "fpdfsdk/pdfwindow/cpwl_scroll_bar.cpp", "fpdfsdk/pdfwindow/cpwl_scroll_bar.h", "fpdfsdk/pdfwindow/cpwl_special_button.cpp", diff --git a/fpdfsdk/cpdfsdk_interform.cpp b/fpdfsdk/cpdfsdk_interform.cpp index 9ae2aa44f4..c9736126d3 100644 --- a/fpdfsdk/cpdfsdk_interform.cpp +++ b/fpdfsdk/cpdfsdk_interform.cpp @@ -28,7 +28,6 @@ #include "fpdfsdk/formfiller/cffl_formfiller.h" #include "fpdfsdk/fsdk_actionhandler.h" #include "fpdfsdk/fsdk_define.h" -#include "fpdfsdk/fxedit/fxet_edit.h" #include "fpdfsdk/ipdfsdk_annothandler.h" #include "fpdfsdk/javascript/ijs_event_context.h" #include "fpdfsdk/javascript/ijs_runtime.h" diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp index afc83edb07..4b85333a2a 100644 --- a/fpdfsdk/cpdfsdk_widget.cpp +++ b/fpdfsdk/cpdfsdk_widget.cpp @@ -29,7 +29,6 @@ #include "fpdfsdk/formfiller/cba_fontmap.h" #include "fpdfsdk/fsdk_actionhandler.h" #include "fpdfsdk/fsdk_define.h" -#include "fpdfsdk/fxedit/fxet_edit.h" #include "fpdfsdk/pdfwindow/cpwl_appstream.h" #include "fpdfsdk/pdfwindow/cpwl_edit.h" diff --git a/fpdfsdk/fxedit/fxet_edit.cpp b/fpdfsdk/fxedit/fxet_edit.cpp deleted file mode 100644 index 6c4595408f..0000000000 --- a/fpdfsdk/fxedit/fxet_edit.cpp +++ /dev/null @@ -1,2043 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "fpdfsdk/fxedit/fxet_edit.h" - -#include -#include -#include -#include - -#include "core/fpdfapi/font/cpdf_font.h" -#include "core/fpdfapi/page/cpdf_pageobject.h" -#include "core/fpdfapi/page/cpdf_pageobjectholder.h" -#include "core/fpdfapi/page/cpdf_pathobject.h" -#include "core/fpdfapi/page/cpdf_textobject.h" -#include "core/fpdfapi/parser/fpdf_parser_decode.h" -#include "core/fpdfapi/render/cpdf_renderoptions.h" -#include "core/fpdfapi/render/cpdf_textrenderer.h" -#include "core/fpdfdoc/cpvt_section.h" -#include "core/fpdfdoc/cpvt_word.h" -#include "core/fpdfdoc/ipvt_fontmap.h" -#include "core/fxcrt/fx_codepage.h" -#include "core/fxge/cfx_graphstatedata.h" -#include "core/fxge/cfx_pathdata.h" -#include "core/fxge/cfx_renderdevice.h" -#include "fpdfsdk/cfx_systemhandler.h" -#include "fpdfsdk/pdfwindow/cpwl_edit.h" -#include "fpdfsdk/pdfwindow/cpwl_edit_ctrl.h" -#include "fpdfsdk/pdfwindow/cpwl_scroll_bar.h" -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" - -namespace { - -const int kEditUndoMaxItems = 10000; - -void DrawTextString(CFX_RenderDevice* pDevice, - const CFX_PointF& pt, - CPDF_Font* pFont, - float fFontSize, - CFX_Matrix* pUser2Device, - const CFX_ByteString& str, - FX_ARGB crTextFill, - int32_t nHorzScale) { - CFX_PointF pos = pUser2Device->Transform(pt); - - if (pFont) { - if (nHorzScale != 100) { - CFX_Matrix mt(nHorzScale / 100.0f, 0, 0, 1, 0, 0); - mt.Concat(*pUser2Device); - - CPDF_RenderOptions ro; - ro.m_Flags = RENDER_CLEARTYPE; - ro.m_ColorMode = CPDF_RenderOptions::kNormal; - - CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize, - &mt, str, crTextFill, nullptr, &ro); - } else { - CPDF_RenderOptions ro; - ro.m_Flags = RENDER_CLEARTYPE; - ro.m_ColorMode = CPDF_RenderOptions::kNormal; - - CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize, - pUser2Device, str, crTextFill, nullptr, - &ro); - } - } -} - -} // namespace - -CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit* pEdit, - CPDF_VariableText::Iterator* pVTIterator) - : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {} - -CFX_Edit_Iterator::~CFX_Edit_Iterator() {} - -bool CFX_Edit_Iterator::NextWord() { - return m_pVTIterator->NextWord(); -} - -bool CFX_Edit_Iterator::PrevWord() { - return m_pVTIterator->PrevWord(); -} - -bool CFX_Edit_Iterator::GetWord(CPVT_Word& word) const { - ASSERT(m_pEdit); - - if (m_pVTIterator->GetWord(word)) { - word.ptWord = m_pEdit->VTToEdit(word.ptWord); - return true; - } - return false; -} - -bool CFX_Edit_Iterator::GetLine(CPVT_Line& line) const { - ASSERT(m_pEdit); - - if (m_pVTIterator->GetLine(line)) { - line.ptLine = m_pEdit->VTToEdit(line.ptLine); - return true; - } - return false; -} - -void CFX_Edit_Iterator::SetAt(int32_t nWordIndex) { - m_pVTIterator->SetAt(nWordIndex); -} - -void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace& place) { - m_pVTIterator->SetAt(place); -} - -const CPVT_WordPlace& CFX_Edit_Iterator::GetAt() const { - return m_pVTIterator->GetAt(); -} - -CFX_Edit_Provider::CFX_Edit_Provider(IPVT_FontMap* pFontMap) - : CPDF_VariableText::Provider(pFontMap), m_pFontMap(pFontMap) { - ASSERT(m_pFontMap); -} - -CFX_Edit_Provider::~CFX_Edit_Provider() {} - -IPVT_FontMap* CFX_Edit_Provider::GetFontMap() const { - return m_pFontMap; -} - -int32_t CFX_Edit_Provider::GetCharWidth(int32_t nFontIndex, uint16_t word) { - if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) { - uint32_t charcode = word; - - if (pPDFFont->IsUnicodeCompatible()) - charcode = pPDFFont->CharCodeFromUnicode(word); - else - charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word); - - if (charcode != CPDF_Font::kInvalidCharCode) - return pPDFFont->GetCharWidthF(charcode); - } - - return 0; -} - -int32_t CFX_Edit_Provider::GetTypeAscent(int32_t nFontIndex) { - if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) - return pPDFFont->GetTypeAscent(); - - return 0; -} - -int32_t CFX_Edit_Provider::GetTypeDescent(int32_t nFontIndex) { - if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) - return pPDFFont->GetTypeDescent(); - - return 0; -} - -int32_t CFX_Edit_Provider::GetWordFontIndex(uint16_t word, - int32_t charset, - int32_t nFontIndex) { - return m_pFontMap->GetWordFontIndex(word, charset, nFontIndex); -} - -int32_t CFX_Edit_Provider::GetDefaultFontIndex() { - return 0; -} - -bool CFX_Edit_Provider::IsLatinWord(uint16_t word) { - return FX_EDIT_ISLATINWORD(word); -} - -CFX_Edit_Refresh::CFX_Edit_Refresh() {} - -CFX_Edit_Refresh::~CFX_Edit_Refresh() {} - -void CFX_Edit_Refresh::BeginRefresh() { - m_RefreshRects.Clear(); - m_OldLineRects = std::move(m_NewLineRects); -} - -void CFX_Edit_Refresh::Push(const CPVT_WordRange& linerange, - const CFX_FloatRect& rect) { - m_NewLineRects.Add(linerange, rect); -} - -void CFX_Edit_Refresh::NoAnalyse() { - { - for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++) - if (CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i)) - m_RefreshRects.Add(pOldRect->m_rcLine); - } - - { - for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++) - if (CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i)) - m_RefreshRects.Add(pNewRect->m_rcLine); - } -} - -const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const { - return &m_RefreshRects; -} - -void CFX_Edit_Refresh::EndRefresh() { - m_RefreshRects.Clear(); -} - -CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize) - : m_nCurUndoPos(0), - m_nBufSize(nBufsize), - m_bWorking(false) {} - -CFX_Edit_Undo::~CFX_Edit_Undo() { - Reset(); -} - -bool CFX_Edit_Undo::CanUndo() const { - return m_nCurUndoPos > 0; -} - -void CFX_Edit_Undo::Undo() { - m_bWorking = true; - if (m_nCurUndoPos > 0) { - m_UndoItemStack[m_nCurUndoPos - 1]->Undo(); - m_nCurUndoPos--; - } - m_bWorking = false; -} - -bool CFX_Edit_Undo::CanRedo() const { - return m_nCurUndoPos < m_UndoItemStack.size(); -} - -void CFX_Edit_Undo::Redo() { - m_bWorking = true; - if (m_nCurUndoPos < m_UndoItemStack.size()) { - m_UndoItemStack[m_nCurUndoPos]->Redo(); - m_nCurUndoPos++; - } - m_bWorking = false; -} - -void CFX_Edit_Undo::AddItem(std::unique_ptr pItem) { - ASSERT(!m_bWorking); - ASSERT(pItem); - ASSERT(m_nBufSize > 1); - if (m_nCurUndoPos < m_UndoItemStack.size()) - RemoveTails(); - - if (m_UndoItemStack.size() >= m_nBufSize) - RemoveHeads(); - - m_UndoItemStack.push_back(std::move(pItem)); - m_nCurUndoPos = m_UndoItemStack.size(); -} - -void CFX_Edit_Undo::RemoveHeads() { - ASSERT(m_UndoItemStack.size() > 1); - m_UndoItemStack.pop_front(); -} - -void CFX_Edit_Undo::RemoveTails() { - while (m_UndoItemStack.size() > m_nCurUndoPos) - m_UndoItemStack.pop_back(); -} - -void CFX_Edit_Undo::Reset() { - m_UndoItemStack.clear(); - m_nCurUndoPos = 0; -} - -CFX_Edit_UndoItem::CFX_Edit_UndoItem() : m_bFirst(true), m_bLast(true) {} - -CFX_Edit_UndoItem::~CFX_Edit_UndoItem() {} - -CFX_WideString CFX_Edit_UndoItem::GetUndoTitle() const { - return CFX_WideString(); -} - -void CFX_Edit_UndoItem::SetFirst(bool bFirst) { - m_bFirst = bFirst; -} - -void CFX_Edit_UndoItem::SetLast(bool bLast) { - m_bLast = bLast; -} - -bool CFX_Edit_UndoItem::IsLast() { - return m_bLast; -} - -CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - uint16_t word, - int32_t charset, - const CPVT_WordProps* pWordProps) - : m_pEdit(pEdit), - m_wpOld(wpOldPlace), - m_wpNew(wpNewPlace), - m_Word(word), - m_nCharset(charset), - m_WordProps() { - if (pWordProps) - m_WordProps = *pWordProps; -} - -CFXEU_InsertWord::~CFXEU_InsertWord() {} - -void CFXEU_InsertWord::Redo() { - if (m_pEdit) { - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wpOld); - m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true); - } -} - -void CFXEU_InsertWord::Undo() { - if (m_pEdit) { - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wpNew); - m_pEdit->Backspace(false, true); - } -} - -CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - const CPVT_SecProps* pSecProps, - const CPVT_WordProps* pWordProps) - : m_pEdit(pEdit), - m_wpOld(wpOldPlace), - m_wpNew(wpNewPlace), - m_SecProps(), - m_WordProps() { - if (pSecProps) - m_SecProps = *pSecProps; - if (pWordProps) - m_WordProps = *pWordProps; -} - -CFXEU_InsertReturn::~CFXEU_InsertReturn() {} - -void CFXEU_InsertReturn::Redo() { - if (m_pEdit) { - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wpOld); - m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true); - } -} - -void CFXEU_InsertReturn::Undo() { - if (m_pEdit) { - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wpNew); - m_pEdit->Backspace(false, true); - } -} - -CFXEU_Backspace::CFXEU_Backspace(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - uint16_t word, - int32_t charset, - const CPVT_SecProps& SecProps, - const CPVT_WordProps& WordProps) - : m_pEdit(pEdit), - m_wpOld(wpOldPlace), - m_wpNew(wpNewPlace), - m_Word(word), - m_nCharset(charset), - m_SecProps(SecProps), - m_WordProps(WordProps) {} - -CFXEU_Backspace::~CFXEU_Backspace() {} - -void CFXEU_Backspace::Redo() { - if (!m_pEdit) - return; - - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wpOld); - m_pEdit->Backspace(false, true); -} - -void CFXEU_Backspace::Undo() { - if (!m_pEdit) - return; - - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wpNew); - if (m_wpNew.nSecIndex != m_wpOld.nSecIndex) - m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true); - else - m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true); -} - -CFXEU_Delete::CFXEU_Delete(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - uint16_t word, - int32_t charset, - const CPVT_SecProps& SecProps, - const CPVT_WordProps& WordProps, - bool bSecEnd) - : m_pEdit(pEdit), - m_wpOld(wpOldPlace), - m_wpNew(wpNewPlace), - m_Word(word), - m_nCharset(charset), - m_SecProps(SecProps), - m_WordProps(WordProps), - m_bSecEnd(bSecEnd) {} - -CFXEU_Delete::~CFXEU_Delete() {} - -void CFXEU_Delete::Redo() { - if (m_pEdit) { - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wpOld); - m_pEdit->Delete(false, true); - } -} - -void CFXEU_Delete::Undo() { - if (m_pEdit) { - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wpNew); - if (m_bSecEnd) { - m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true); - } else { - m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true); - } - } -} - -CFXEU_Clear::CFXEU_Clear(CFX_Edit* pEdit, - const CPVT_WordRange& wrSel, - const CFX_WideString& swText) - : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {} - -CFXEU_Clear::~CFXEU_Clear() {} - -void CFXEU_Clear::Redo() { - if (m_pEdit) { - m_pEdit->SelectNone(); - m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos); - m_pEdit->Clear(false, true); - } -} - -void CFXEU_Clear::Undo() { - if (m_pEdit) { - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wrSel.BeginPos); - m_pEdit->InsertText(m_swText, FX_CHARSET_Default, false, true); - m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos); - } -} - -CFXEU_InsertText::CFXEU_InsertText(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - const CFX_WideString& swText, - int32_t charset) - : m_pEdit(pEdit), - m_wpOld(wpOldPlace), - m_wpNew(wpNewPlace), - m_swText(swText), - m_nCharset(charset) {} - -CFXEU_InsertText::~CFXEU_InsertText() {} - -void CFXEU_InsertText::Redo() { - if (m_pEdit && IsLast()) { - m_pEdit->SelectNone(); - m_pEdit->SetCaret(m_wpOld); - m_pEdit->InsertText(m_swText, m_nCharset, false, true); - } -} - -void CFXEU_InsertText::Undo() { - if (m_pEdit) { - m_pEdit->SelectNone(); - m_pEdit->SetSelection(m_wpOld, m_wpNew); - m_pEdit->Clear(false, true); - } -} - -// static -void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, - CFX_Matrix* pUser2Device, - CFX_Edit* pEdit, - FX_COLORREF crTextFill, - const CFX_FloatRect& rcClip, - const CFX_PointF& ptOffset, - const CPVT_WordRange* pRange, - CFX_SystemHandler* pSystemHandler, - CFFL_FormFiller* pFFLData) { - const bool bContinuous = - pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f; - uint16_t SubWord = pEdit->GetPasswordChar(); - float fFontSize = pEdit->GetFontSize(); - CPVT_WordRange wrSelect = pEdit->GetSelectWordRange(); - int32_t nHorzScale = pEdit->GetHorzScale(); - - FX_COLORREF crCurFill = crTextFill; - FX_COLORREF crOldFill = crCurFill; - - bool bSelect = false; - const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255); - const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113); - - std::ostringstream sTextBuf; - int32_t nFontIndex = -1; - CFX_PointF ptBT; - CFX_RenderDevice::StateRestorer restorer(pDevice); - if (!rcClip.IsEmpty()) { - CFX_FloatRect rcTemp = rcClip; - pUser2Device->TransformRect(rcTemp); - pDevice->SetClip_Rect(rcTemp.ToFxRect()); - } - - CFX_Edit_Iterator* pIterator = pEdit->GetIterator(); - if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) { - if (pRange) - pIterator->SetAt(pRange->BeginPos); - else - pIterator->SetAt(0); - - CPVT_WordPlace oldplace; - while (pIterator->NextWord()) { - CPVT_WordPlace place = pIterator->GetAt(); - if (pRange && place > pRange->EndPos) - break; - - if (!wrSelect.IsEmpty()) { - bSelect = place > wrSelect.BeginPos && place <= wrSelect.EndPos; - crCurFill = bSelect ? crWhite : crTextFill; - } - if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) { - crCurFill = crTextFill; - crOldFill = crCurFill; - } - CPVT_Word word; - if (pIterator->GetWord(word)) { - if (bSelect) { - CPVT_Line line; - pIterator->GetLine(line); - - if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) { - CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent, - word.ptWord.x + word.fWidth, - line.ptLine.y + line.fLineAscent); - rc.Intersect(rcClip); - pSystemHandler->OutputSelectedRect(pFFLData, rc); - } else { - CFX_PathData pathSelBK; - pathSelBK.AppendRect( - word.ptWord.x, line.ptLine.y + line.fLineDescent, - word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent); - - pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0, - FXFILL_WINDING); - } - } - - if (bContinuous) { - if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex || - crOldFill != crCurFill) { - if (sTextBuf.tellp() > 0) { - DrawTextString( - pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), - pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device, - CFX_ByteString(sTextBuf), crOldFill, nHorzScale); - - sTextBuf.str(""); - } - nFontIndex = word.nFontIndex; - ptBT = word.ptWord; - crOldFill = crCurFill; - } - - sTextBuf << pEdit->GetPDFWordString(word.nFontIndex, word.Word, - SubWord); - } else { - DrawTextString( - pDevice, - CFX_PointF(word.ptWord.x + ptOffset.x, - word.ptWord.y + ptOffset.y), - pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device, - pEdit->GetPDFWordString(word.nFontIndex, word.Word, SubWord), - crCurFill, nHorzScale); - } - oldplace = place; - } - } - - if (sTextBuf.tellp() > 0) { - DrawTextString(pDevice, - CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), - pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device, - CFX_ByteString(sTextBuf), crOldFill, nHorzScale); - } - } -} - -CFX_Edit::CFX_Edit() - : m_pVT(new CPDF_VariableText), - m_pNotify(nullptr), - m_pOprNotify(nullptr), - m_wpCaret(-1, -1, -1), - m_wpOldCaret(-1, -1, -1), - m_SelState(), - m_bEnableScroll(false), - m_Undo(kEditUndoMaxItems), - m_nAlignment(0), - m_bNotifyFlag(false), - m_bEnableOverflow(false), - m_bEnableRefresh(true), - m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f), - m_bEnableUndo(true), - m_bOprNotify(false) {} - -CFX_Edit::~CFX_Edit() {} - -void CFX_Edit::Initialize() { - m_pVT->Initialize(); - SetCaret(m_pVT->GetBeginWordPlace()); - SetCaretOrigin(); -} - -void CFX_Edit::SetFontMap(IPVT_FontMap* pFontMap) { - m_pVTProvider = pdfium::MakeUnique(pFontMap); - m_pVT->SetProvider(m_pVTProvider.get()); -} - -void CFX_Edit::SetNotify(CPWL_EditCtrl* pNotify) { - m_pNotify = pNotify; -} - -void CFX_Edit::SetOprNotify(CPWL_Edit* pOprNotify) { - m_pOprNotify = pOprNotify; -} - -CFX_Edit_Iterator* CFX_Edit::GetIterator() { - if (!m_pIterator) { - m_pIterator = - pdfium::MakeUnique(this, m_pVT->GetIterator()); - } - return m_pIterator.get(); -} - -IPVT_FontMap* CFX_Edit::GetFontMap() { - return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr; -} - -void CFX_Edit::SetPlateRect(const CFX_FloatRect& rect) { - m_pVT->SetPlateRect(rect); - m_ptScrollPos = CFX_PointF(rect.left, rect.top); - Paint(); -} - -void CFX_Edit::SetAlignmentH(int32_t nFormat, bool bPaint) { - m_pVT->SetAlignment(nFormat); - if (bPaint) - Paint(); -} - -void CFX_Edit::SetAlignmentV(int32_t nFormat, bool bPaint) { - m_nAlignment = nFormat; - if (bPaint) - Paint(); -} - -void CFX_Edit::SetPasswordChar(uint16_t wSubWord, bool bPaint) { - m_pVT->SetPasswordChar(wSubWord); - if (bPaint) - Paint(); -} - -void CFX_Edit::SetLimitChar(int32_t nLimitChar) { - m_pVT->SetLimitChar(nLimitChar); - Paint(); -} - -void CFX_Edit::SetCharArray(int32_t nCharArray) { - m_pVT->SetCharArray(nCharArray); - Paint(); -} - -void CFX_Edit::SetCharSpace(float fCharSpace) { - m_pVT->SetCharSpace(fCharSpace); - Paint(); -} - -void CFX_Edit::SetMultiLine(bool bMultiLine, bool bPaint) { - m_pVT->SetMultiLine(bMultiLine); - if (bPaint) - Paint(); -} - -void CFX_Edit::SetAutoReturn(bool bAuto, bool bPaint) { - m_pVT->SetAutoReturn(bAuto); - if (bPaint) - Paint(); -} - -void CFX_Edit::SetAutoFontSize(bool bAuto, bool bPaint) { - m_pVT->SetAutoFontSize(bAuto); - if (bPaint) - Paint(); -} - -void CFX_Edit::SetFontSize(float fFontSize) { - m_pVT->SetFontSize(fFontSize); - Paint(); -} - -void CFX_Edit::SetAutoScroll(bool bAuto, bool bPaint) { - m_bEnableScroll = bAuto; - if (bPaint) - Paint(); -} - -void CFX_Edit::SetTextOverflow(bool bAllowed, bool bPaint) { - m_bEnableOverflow = bAllowed; - if (bPaint) - Paint(); -} - -void CFX_Edit::SetSelection(int32_t nStartChar, int32_t nEndChar) { - if (m_pVT->IsValid()) { - if (nStartChar == 0 && nEndChar < 0) { - SelectAll(); - } else if (nStartChar < 0) { - SelectNone(); - } else { - if (nStartChar < nEndChar) { - SetSelection(m_pVT->WordIndexToWordPlace(nStartChar), - m_pVT->WordIndexToWordPlace(nEndChar)); - } else { - SetSelection(m_pVT->WordIndexToWordPlace(nEndChar), - m_pVT->WordIndexToWordPlace(nStartChar)); - } - } - } -} - -void CFX_Edit::SetSelection(const CPVT_WordPlace& begin, - const CPVT_WordPlace& end) { - if (!m_pVT->IsValid()) - return; - - SelectNone(); - m_SelState.Set(begin, end); - SetCaret(m_SelState.EndPos); - ScrollToCaret(); - if (!m_SelState.IsEmpty()) - Refresh(); - SetCaretInfo(); -} - -void CFX_Edit::GetSelection(int32_t& nStartChar, int32_t& nEndChar) const { - nStartChar = -1; - nEndChar = -1; - if (!m_pVT->IsValid()) - return; - - if (m_SelState.IsEmpty()) { - nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret); - nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret); - return; - } - if (m_SelState.BeginPos < m_SelState.EndPos) { - nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos); - nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos); - return; - } - nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos); - nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos); -} - -int32_t CFX_Edit::GetCaret() const { - if (m_pVT->IsValid()) - return m_pVT->WordPlaceToWordIndex(m_wpCaret); - - return -1; -} - -CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const { - return m_wpCaret; -} - -CFX_WideString CFX_Edit::GetText() const { - CFX_WideString swRet; - if (!m_pVT->IsValid()) - return swRet; - - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - pIterator->SetAt(0); - - CPVT_Word wordinfo; - CPVT_WordPlace oldplace = pIterator->GetAt(); - while (pIterator->NextWord()) { - CPVT_WordPlace place = pIterator->GetAt(); - if (pIterator->GetWord(wordinfo)) - swRet += wordinfo.Word; - if (oldplace.nSecIndex != place.nSecIndex) - swRet += L"\r\n"; - oldplace = place; - } - return swRet; -} - -CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange& range) const { - CFX_WideString swRet; - if (!m_pVT->IsValid()) - return swRet; - - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - CPVT_WordRange wrTemp = range; - m_pVT->UpdateWordPlace(wrTemp.BeginPos); - m_pVT->UpdateWordPlace(wrTemp.EndPos); - pIterator->SetAt(wrTemp.BeginPos); - - CPVT_Word wordinfo; - CPVT_WordPlace oldplace = wrTemp.BeginPos; - while (pIterator->NextWord()) { - CPVT_WordPlace place = pIterator->GetAt(); - if (place > wrTemp.EndPos) - break; - if (pIterator->GetWord(wordinfo)) - swRet += wordinfo.Word; - if (oldplace.nSecIndex != place.nSecIndex) - swRet += L"\r\n"; - oldplace = place; - } - return swRet; -} - -CFX_WideString CFX_Edit::GetSelectedText() const { - return GetRangeText(m_SelState.ConvertToWordRange()); -} - -int32_t CFX_Edit::GetTotalLines() const { - int32_t nLines = 1; - - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - pIterator->SetAt(0); - while (pIterator->NextLine()) - ++nLines; - - return nLines; -} - -CPVT_WordRange CFX_Edit::GetSelectWordRange() const { - return m_SelState.ConvertToWordRange(); -} - -void CFX_Edit::SetText(const CFX_WideString& sText) { - Empty(); - DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_CHARSET_Default); - Paint(); -} - -bool CFX_Edit::InsertWord(uint16_t word, int32_t charset) { - return InsertWord(word, charset, nullptr, true, true); -} - -bool CFX_Edit::InsertReturn() { - return InsertReturn(nullptr, nullptr, true, true); -} - -bool CFX_Edit::Backspace() { - return Backspace(true, true); -} - -bool CFX_Edit::Delete() { - return Delete(true, true); -} - -bool CFX_Edit::ClearSelection() { - return Clear(true, true); -} - -bool CFX_Edit::InsertText(const CFX_WideString& sText, int32_t charset) { - return InsertText(sText, charset, true, true); -} - -float CFX_Edit::GetFontSize() const { - return m_pVT->GetFontSize(); -} - -uint16_t CFX_Edit::GetPasswordChar() const { - return m_pVT->GetPasswordChar(); -} - -int32_t CFX_Edit::GetCharArray() const { - return m_pVT->GetCharArray(); -} - -CFX_FloatRect CFX_Edit::GetContentRect() const { - return VTToEdit(m_pVT->GetContentRect()); -} - -int32_t CFX_Edit::GetHorzScale() const { - return m_pVT->GetHorzScale(); -} - -float CFX_Edit::GetCharSpace() const { - return m_pVT->GetCharSpace(); -} - -CPVT_WordRange CFX_Edit::GetWholeWordRange() const { - if (m_pVT->IsValid()) - return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace()); - - return CPVT_WordRange(); -} - -CPVT_WordRange CFX_Edit::GetVisibleWordRange() const { - if (m_bEnableOverflow) - return GetWholeWordRange(); - - if (m_pVT->IsValid()) { - CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); - - CPVT_WordPlace place1 = - m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top))); - CPVT_WordPlace place2 = m_pVT->SearchWordPlace( - EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom))); - - return CPVT_WordRange(place1, place2); - } - - return CPVT_WordRange(); -} - -CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_PointF& point) const { - if (m_pVT->IsValid()) { - return m_pVT->SearchWordPlace(EditToVT(point)); - } - - return CPVT_WordPlace(); -} - -void CFX_Edit::Paint() { - if (m_pVT->IsValid()) { - RearrangeAll(); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); - } -} - -void CFX_Edit::RearrangeAll() { - if (m_pVT->IsValid()) { - m_pVT->UpdateWordPlace(m_wpCaret); - m_pVT->RearrangeAll(); - m_pVT->UpdateWordPlace(m_wpCaret); - SetScrollInfo(); - SetContentChanged(); - } -} - -void CFX_Edit::RearrangePart(const CPVT_WordRange& range) { - if (m_pVT->IsValid()) { - m_pVT->UpdateWordPlace(m_wpCaret); - m_pVT->RearrangePart(range); - m_pVT->UpdateWordPlace(m_wpCaret); - SetScrollInfo(); - SetContentChanged(); - } -} - -void CFX_Edit::SetContentChanged() { - if (m_pNotify) { - CFX_FloatRect rcContent = m_pVT->GetContentRect(); - if (rcContent.Width() != m_rcOldContent.Width() || - rcContent.Height() != m_rcOldContent.Height()) { - m_rcOldContent = rcContent; - } - } -} - -void CFX_Edit::SelectAll() { - if (!m_pVT->IsValid()) - return; - m_SelState = CFX_Edit_Select(GetWholeWordRange()); - SetCaret(m_SelState.EndPos); - ScrollToCaret(); - Refresh(); - SetCaretInfo(); -} - -void CFX_Edit::SelectNone() { - if (!m_pVT->IsValid() || m_SelState.IsEmpty()) - return; - - m_SelState.Reset(); - Refresh(); -} - -bool CFX_Edit::IsSelected() const { - return !m_SelState.IsEmpty(); -} - -CFX_PointF CFX_Edit::VTToEdit(const CFX_PointF& point) const { - CFX_FloatRect rcContent = m_pVT->GetContentRect(); - CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); - - float fPadding = 0.0f; - - switch (m_nAlignment) { - case 0: - fPadding = 0.0f; - break; - case 1: - fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f; - break; - case 2: - fPadding = rcPlate.Height() - rcContent.Height(); - break; - } - - return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left), - point.y - (m_ptScrollPos.y + fPadding - rcPlate.top)); -} - -CFX_PointF CFX_Edit::EditToVT(const CFX_PointF& point) const { - CFX_FloatRect rcContent = m_pVT->GetContentRect(); - CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); - - float fPadding = 0.0f; - - switch (m_nAlignment) { - case 0: - fPadding = 0.0f; - break; - case 1: - fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f; - break; - case 2: - fPadding = rcPlate.Height() - rcContent.Height(); - break; - } - - return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left), - point.y + (m_ptScrollPos.y + fPadding - rcPlate.top)); -} - -CFX_FloatRect CFX_Edit::VTToEdit(const CFX_FloatRect& rect) const { - CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom)); - CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top)); - - return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, - ptRightTop.y); -} - -void CFX_Edit::SetScrollInfo() { - if (!m_pNotify) - return; - - CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); - CFX_FloatRect rcContent = m_pVT->GetContentRect(); - if (m_bNotifyFlag) - return; - - CFX_AutoRestorer restorer(&m_bNotifyFlag); - m_bNotifyFlag = true; - - PWL_SCROLL_INFO Info; - Info.fPlateWidth = rcPlate.top - rcPlate.bottom; - Info.fContentMin = rcContent.bottom; - Info.fContentMax = rcContent.top; - Info.fSmallStep = rcPlate.Height() / 3; - Info.fBigStep = rcPlate.Height(); - m_pNotify->SetScrollInfo(Info); -} - -void CFX_Edit::SetScrollPosX(float fx) { - if (!m_bEnableScroll) - return; - - if (m_pVT->IsValid()) { - if (!IsFloatEqual(m_ptScrollPos.x, fx)) { - m_ptScrollPos.x = fx; - Refresh(); - } - } -} - -void CFX_Edit::SetScrollPosY(float fy) { - if (!m_bEnableScroll) - return; - - if (m_pVT->IsValid()) { - if (!IsFloatEqual(m_ptScrollPos.y, fy)) { - m_ptScrollPos.y = fy; - Refresh(); - - if (m_pNotify) { - if (!m_bNotifyFlag) { - CFX_AutoRestorer restorer(&m_bNotifyFlag); - m_bNotifyFlag = true; - m_pNotify->SetScrollPosition(fy); - } - } - } - } -} - -void CFX_Edit::SetScrollPos(const CFX_PointF& point) { - SetScrollPosX(point.x); - SetScrollPosY(point.y); - SetScrollLimit(); - SetCaretInfo(); -} - -CFX_PointF CFX_Edit::GetScrollPos() const { - return m_ptScrollPos; -} - -void CFX_Edit::SetScrollLimit() { - if (m_pVT->IsValid()) { - CFX_FloatRect rcContent = m_pVT->GetContentRect(); - CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); - - if (rcPlate.Width() > rcContent.Width()) { - SetScrollPosX(rcPlate.left); - } else { - if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) { - SetScrollPosX(rcContent.left); - } else if (IsFloatBigger(m_ptScrollPos.x, - rcContent.right - rcPlate.Width())) { - SetScrollPosX(rcContent.right - rcPlate.Width()); - } - } - - if (rcPlate.Height() > rcContent.Height()) { - SetScrollPosY(rcPlate.top); - } else { - if (IsFloatSmaller(m_ptScrollPos.y, - rcContent.bottom + rcPlate.Height())) { - SetScrollPosY(rcContent.bottom + rcPlate.Height()); - } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) { - SetScrollPosY(rcContent.top); - } - } - } -} - -void CFX_Edit::ScrollToCaret() { - SetScrollLimit(); - - if (!m_pVT->IsValid()) - return; - - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - pIterator->SetAt(m_wpCaret); - - CFX_PointF ptHead; - CFX_PointF ptFoot; - CPVT_Word word; - CPVT_Line line; - if (pIterator->GetWord(word)) { - ptHead.x = word.ptWord.x + word.fWidth; - ptHead.y = word.ptWord.y + word.fAscent; - ptFoot.x = word.ptWord.x + word.fWidth; - ptFoot.y = word.ptWord.y + word.fDescent; - } else if (pIterator->GetLine(line)) { - ptHead.x = line.ptLine.x; - ptHead.y = line.ptLine.y + line.fLineAscent; - ptFoot.x = line.ptLine.x; - ptFoot.y = line.ptLine.y + line.fLineDescent; - } - - CFX_PointF ptHeadEdit = VTToEdit(ptHead); - CFX_PointF ptFootEdit = VTToEdit(ptFoot); - CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); - if (!IsFloatEqual(rcPlate.left, rcPlate.right)) { - if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) || - IsFloatEqual(ptHeadEdit.x, rcPlate.left)) { - SetScrollPosX(ptHead.x); - } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) { - SetScrollPosX(ptHead.x - rcPlate.Width()); - } - } - - if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) { - if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) || - IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) { - if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) { - SetScrollPosY(ptFoot.y + rcPlate.Height()); - } - } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) { - if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) { - SetScrollPosY(ptHead.y); - } - } - } -} - -void CFX_Edit::Refresh() { - if (m_bEnableRefresh && m_pVT->IsValid()) { - m_Refresh.BeginRefresh(); - RefreshPushLineRects(GetVisibleWordRange()); - - m_Refresh.NoAnalyse(); - m_ptRefreshScrollPos = m_ptScrollPos; - - if (m_pNotify) { - if (!m_bNotifyFlag) { - CFX_AutoRestorer restorer(&m_bNotifyFlag); - m_bNotifyFlag = true; - if (const CFX_Edit_RectArray* pRects = m_Refresh.GetRefreshRects()) { - for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++) - m_pNotify->InvalidateRect(pRects->GetAt(i)); - } - } - } - - m_Refresh.EndRefresh(); - } -} - -void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange& wr) { - if (!m_pVT->IsValid()) - return; - - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - CPVT_WordPlace wpBegin = wr.BeginPos; - m_pVT->UpdateWordPlace(wpBegin); - CPVT_WordPlace wpEnd = wr.EndPos; - m_pVT->UpdateWordPlace(wpEnd); - pIterator->SetAt(wpBegin); - - CPVT_Line lineinfo; - do { - if (!pIterator->GetLine(lineinfo)) - break; - if (lineinfo.lineplace.LineCmp(wpEnd) > 0) - break; - - CFX_FloatRect rcLine(lineinfo.ptLine.x, - lineinfo.ptLine.y + lineinfo.fLineDescent, - lineinfo.ptLine.x + lineinfo.fLineWidth, - lineinfo.ptLine.y + lineinfo.fLineAscent); - - m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd), - VTToEdit(rcLine)); - } while (pIterator->NextLine()); -} - -void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr) { - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - CPVT_WordRange wrTemp = wr; - - m_pVT->UpdateWordPlace(wrTemp.BeginPos); - m_pVT->UpdateWordPlace(wrTemp.EndPos); - pIterator->SetAt(wrTemp.BeginPos); - - CPVT_Word wordinfo; - CPVT_Line lineinfo; - CPVT_WordPlace place; - - while (pIterator->NextWord()) { - place = pIterator->GetAt(); - if (place > wrTemp.EndPos) - break; - - pIterator->GetWord(wordinfo); - pIterator->GetLine(lineinfo); - if (place.LineCmp(wrTemp.BeginPos) == 0 || - place.LineCmp(wrTemp.EndPos) == 0) { - CFX_FloatRect rcWord(wordinfo.ptWord.x, - lineinfo.ptLine.y + lineinfo.fLineDescent, - wordinfo.ptWord.x + wordinfo.fWidth, - lineinfo.ptLine.y + lineinfo.fLineAscent); - - if (m_pNotify) { - if (!m_bNotifyFlag) { - CFX_AutoRestorer restorer(&m_bNotifyFlag); - m_bNotifyFlag = true; - CFX_FloatRect rcRefresh = VTToEdit(rcWord); - m_pNotify->InvalidateRect(&rcRefresh); - } - } - } else { - CFX_FloatRect rcLine(lineinfo.ptLine.x, - lineinfo.ptLine.y + lineinfo.fLineDescent, - lineinfo.ptLine.x + lineinfo.fLineWidth, - lineinfo.ptLine.y + lineinfo.fLineAscent); - - if (m_pNotify) { - if (!m_bNotifyFlag) { - CFX_AutoRestorer restorer(&m_bNotifyFlag); - m_bNotifyFlag = true; - CFX_FloatRect rcRefresh = VTToEdit(rcLine); - m_pNotify->InvalidateRect(&rcRefresh); - } - } - - pIterator->NextLine(); - } - } -} - -void CFX_Edit::SetCaret(const CPVT_WordPlace& place) { - m_wpOldCaret = m_wpCaret; - m_wpCaret = place; -} - -void CFX_Edit::SetCaretInfo() { - if (m_pNotify) { - if (!m_bNotifyFlag) { - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - pIterator->SetAt(m_wpCaret); - - CFX_PointF ptHead; - CFX_PointF ptFoot; - CPVT_Word word; - CPVT_Line line; - if (pIterator->GetWord(word)) { - ptHead.x = word.ptWord.x + word.fWidth; - ptHead.y = word.ptWord.y + word.fAscent; - ptFoot.x = word.ptWord.x + word.fWidth; - ptFoot.y = word.ptWord.y + word.fDescent; - } else if (pIterator->GetLine(line)) { - ptHead.x = line.ptLine.x; - ptHead.y = line.ptLine.y + line.fLineAscent; - ptFoot.x = line.ptLine.x; - ptFoot.y = line.ptLine.y + line.fLineDescent; - } - - CFX_AutoRestorer restorer(&m_bNotifyFlag); - m_bNotifyFlag = true; - m_pNotify->SetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead), - VTToEdit(ptFoot)); - } - } -} - -void CFX_Edit::OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl) { - if (!m_pVT->IsValid()) - return; - - SelectNone(); - SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); - m_SelState.Set(m_wpCaret, m_wpCaret); - ScrollToCaret(); - SetCaretOrigin(); - SetCaretInfo(); -} - -void CFX_Edit::OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl) { - if (!m_pVT->IsValid()) - return; - - SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); - if (m_wpCaret == m_wpOldCaret) - return; - - m_SelState.SetEndPos(m_wpCaret); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); -} - -void CFX_Edit::OnVK_UP(bool bShift, bool bCtrl) { - if (!m_pVT->IsValid()) - return; - - SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret)); - if (bShift) { - if (m_SelState.IsEmpty()) - m_SelState.Set(m_wpOldCaret, m_wpCaret); - else - m_SelState.SetEndPos(m_wpCaret); - - if (m_wpOldCaret != m_wpCaret) { - ScrollToCaret(); - Refresh(); - SetCaretInfo(); - } - } else { - SelectNone(); - ScrollToCaret(); - SetCaretInfo(); - } -} - -void CFX_Edit::OnVK_DOWN(bool bShift, bool bCtrl) { - if (!m_pVT->IsValid()) - return; - - SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret)); - if (bShift) { - if (m_SelState.IsEmpty()) - m_SelState.Set(m_wpOldCaret, m_wpCaret); - else - m_SelState.SetEndPos(m_wpCaret); - - if (m_wpOldCaret != m_wpCaret) { - ScrollToCaret(); - Refresh(); - SetCaretInfo(); - } - } else { - SelectNone(); - ScrollToCaret(); - SetCaretInfo(); - } -} - -void CFX_Edit::OnVK_LEFT(bool bShift, bool bCtrl) { - if (!m_pVT->IsValid()) - return; - - if (bShift) { - if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) && - m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) { - SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret)); - } - SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret)); - if (m_SelState.IsEmpty()) - m_SelState.Set(m_wpOldCaret, m_wpCaret); - else - m_SelState.SetEndPos(m_wpCaret); - - if (m_wpOldCaret != m_wpCaret) { - ScrollToCaret(); - Refresh(); - SetCaretInfo(); - } - } else { - if (!m_SelState.IsEmpty()) { - if (m_SelState.BeginPos < m_SelState.EndPos) - SetCaret(m_SelState.BeginPos); - else - SetCaret(m_SelState.EndPos); - - SelectNone(); - ScrollToCaret(); - SetCaretInfo(); - } else { - if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) && - m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) { - SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret)); - } - SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret)); - ScrollToCaret(); - SetCaretOrigin(); - SetCaretInfo(); - } - } -} - -void CFX_Edit::OnVK_RIGHT(bool bShift, bool bCtrl) { - if (!m_pVT->IsValid()) - return; - - if (bShift) { - SetCaret(m_pVT->GetNextWordPlace(m_wpCaret)); - if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) && - m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) - SetCaret(m_pVT->GetNextWordPlace(m_wpCaret)); - - if (m_SelState.IsEmpty()) - m_SelState.Set(m_wpOldCaret, m_wpCaret); - else - m_SelState.SetEndPos(m_wpCaret); - - if (m_wpOldCaret != m_wpCaret) { - ScrollToCaret(); - Refresh(); - SetCaretInfo(); - } - } else { - if (!m_SelState.IsEmpty()) { - if (m_SelState.BeginPos > m_SelState.EndPos) - SetCaret(m_SelState.BeginPos); - else - SetCaret(m_SelState.EndPos); - - SelectNone(); - ScrollToCaret(); - SetCaretInfo(); - } else { - SetCaret(m_pVT->GetNextWordPlace(m_wpCaret)); - if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) && - m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) { - SetCaret(m_pVT->GetNextWordPlace(m_wpCaret)); - } - ScrollToCaret(); - SetCaretOrigin(); - SetCaretInfo(); - } - } -} - -void CFX_Edit::OnVK_HOME(bool bShift, bool bCtrl) { - if (!m_pVT->IsValid()) - return; - - if (bShift) { - if (bCtrl) - SetCaret(m_pVT->GetBeginWordPlace()); - else - SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret)); - - if (m_SelState.IsEmpty()) - m_SelState.Set(m_wpOldCaret, m_wpCaret); - else - m_SelState.SetEndPos(m_wpCaret); - - ScrollToCaret(); - Refresh(); - SetCaretInfo(); - } else { - if (!m_SelState.IsEmpty()) { - SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos)); - SelectNone(); - ScrollToCaret(); - SetCaretInfo(); - } else { - if (bCtrl) - SetCaret(m_pVT->GetBeginWordPlace()); - else - SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret)); - - ScrollToCaret(); - SetCaretOrigin(); - SetCaretInfo(); - } - } -} - -void CFX_Edit::OnVK_END(bool bShift, bool bCtrl) { - if (!m_pVT->IsValid()) - return; - - if (bShift) { - if (bCtrl) - SetCaret(m_pVT->GetEndWordPlace()); - else - SetCaret(m_pVT->GetLineEndPlace(m_wpCaret)); - - if (m_SelState.IsEmpty()) - m_SelState.Set(m_wpOldCaret, m_wpCaret); - else - m_SelState.SetEndPos(m_wpCaret); - - ScrollToCaret(); - Refresh(); - SetCaretInfo(); - } else { - if (!m_SelState.IsEmpty()) { - SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos)); - SelectNone(); - ScrollToCaret(); - SetCaretInfo(); - } else { - if (bCtrl) - SetCaret(m_pVT->GetEndWordPlace()); - else - SetCaret(m_pVT->GetLineEndPlace(m_wpCaret)); - - ScrollToCaret(); - SetCaretOrigin(); - SetCaretInfo(); - } - } -} - -bool CFX_Edit::InsertWord(uint16_t word, - int32_t charset, - const CPVT_WordProps* pWordProps, - bool bAddUndo, - bool bPaint) { - if (IsTextOverflow() || !m_pVT->IsValid()) - return false; - - m_pVT->UpdateWordPlace(m_wpCaret); - SetCaret(m_pVT->InsertWord(m_wpCaret, word, - GetCharSetFromUnicode(word, charset), pWordProps)); - m_SelState.Set(m_wpCaret, m_wpCaret); - if (m_wpCaret == m_wpOldCaret) - return false; - - if (bAddUndo && m_bEnableUndo) { - AddEditUndoItem(pdfium::MakeUnique( - this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps)); - } - if (bPaint) - PaintInsertText(m_wpOldCaret, m_wpCaret); - - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret); - - return true; -} - -bool CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps, - const CPVT_WordProps* pWordProps, - bool bAddUndo, - bool bPaint) { - if (IsTextOverflow() || !m_pVT->IsValid()) - return false; - - m_pVT->UpdateWordPlace(m_wpCaret); - SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps)); - m_SelState.Set(m_wpCaret, m_wpCaret); - if (m_wpCaret == m_wpOldCaret) - return false; - - if (bAddUndo && m_bEnableUndo) { - AddEditUndoItem(pdfium::MakeUnique( - this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps)); - } - if (bPaint) { - RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret)); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); - } - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret); - - return true; -} - -bool CFX_Edit::Backspace(bool bAddUndo, bool bPaint) { - if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace()) - return false; - - CPVT_Section section; - CPVT_Word word; - if (bAddUndo) { - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - pIterator->SetAt(m_wpCaret); - pIterator->GetSection(section); - pIterator->GetWord(word); - } - m_pVT->UpdateWordPlace(m_wpCaret); - SetCaret(m_pVT->BackSpaceWord(m_wpCaret)); - m_SelState.Set(m_wpCaret, m_wpCaret); - if (m_wpCaret == m_wpOldCaret) - return false; - - if (bAddUndo && m_bEnableUndo) { - if (m_wpCaret.nSecIndex != m_wpOldCaret.nSecIndex) { - AddEditUndoItem(pdfium::MakeUnique( - this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, - section.SecProps, section.WordProps)); - } else { - AddEditUndoItem(pdfium::MakeUnique( - this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, - section.SecProps, word.WordProps)); - } - } - if (bPaint) { - RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret)); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); - } - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret); - - return true; -} - -bool CFX_Edit::Delete(bool bAddUndo, bool bPaint) { - if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace()) - return false; - - CPVT_Section section; - CPVT_Word word; - if (bAddUndo) { - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret)); - pIterator->GetSection(section); - pIterator->GetWord(word); - } - m_pVT->UpdateWordPlace(m_wpCaret); - bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret)); - SetCaret(m_pVT->DeleteWord(m_wpCaret)); - m_SelState.Set(m_wpCaret, m_wpCaret); - if (bAddUndo && m_bEnableUndo) { - if (bSecEnd) { - AddEditUndoItem(pdfium::MakeUnique( - this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, - section.SecProps, section.WordProps, bSecEnd)); - } else { - AddEditUndoItem(pdfium::MakeUnique( - this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, - section.SecProps, word.WordProps, bSecEnd)); - } - } - if (bPaint) { - RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret)); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); - } - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret); - - return true; -} - -bool CFX_Edit::Empty() { - if (m_pVT->IsValid()) { - m_pVT->DeleteWords(GetWholeWordRange()); - SetCaret(m_pVT->GetBeginWordPlace()); - - return true; - } - - return false; -} - -bool CFX_Edit::Clear(bool bAddUndo, bool bPaint) { - if (!m_pVT->IsValid() || m_SelState.IsEmpty()) - return false; - - CPVT_WordRange range = m_SelState.ConvertToWordRange(); - if (bAddUndo && m_bEnableUndo) { - AddEditUndoItem( - pdfium::MakeUnique(this, range, GetSelectedText())); - } - - SelectNone(); - SetCaret(m_pVT->DeleteWords(range)); - m_SelState.Set(m_wpCaret, m_wpCaret); - if (bPaint) { - RearrangePart(range); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); - } - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret); - - return true; -} - -bool CFX_Edit::InsertText(const CFX_WideString& sText, - int32_t charset, - bool bAddUndo, - bool bPaint) { - if (IsTextOverflow()) - return false; - - m_pVT->UpdateWordPlace(m_wpCaret); - SetCaret(DoInsertText(m_wpCaret, sText, charset)); - m_SelState.Set(m_wpCaret, m_wpCaret); - if (m_wpCaret == m_wpOldCaret) - return false; - - if (bAddUndo && m_bEnableUndo) { - AddEditUndoItem(pdfium::MakeUnique( - this, m_wpOldCaret, m_wpCaret, sText, charset)); - } - if (bPaint) - PaintInsertText(m_wpOldCaret, m_wpCaret); - - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret); - - return true; -} - -void CFX_Edit::PaintInsertText(const CPVT_WordPlace& wpOld, - const CPVT_WordPlace& wpNew) { - if (m_pVT->IsValid()) { - RearrangePart(CPVT_WordRange(wpOld, wpNew)); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); - } -} - -bool CFX_Edit::Redo() { - if (m_bEnableUndo) { - if (m_Undo.CanRedo()) { - m_Undo.Redo(); - return true; - } - } - - return false; -} - -bool CFX_Edit::Undo() { - if (m_bEnableUndo) { - if (m_Undo.CanUndo()) { - m_Undo.Undo(); - return true; - } - } - - return false; -} - -void CFX_Edit::SetCaretOrigin() { - if (!m_pVT->IsValid()) - return; - - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - pIterator->SetAt(m_wpCaret); - CPVT_Word word; - CPVT_Line line; - if (pIterator->GetWord(word)) { - m_ptCaret.x = word.ptWord.x + word.fWidth; - m_ptCaret.y = word.ptWord.y; - } else if (pIterator->GetLine(line)) { - m_ptCaret.x = line.ptLine.x; - m_ptCaret.y = line.ptLine.y; - } -} - -CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const { - if (m_pVT->IsValid()) - return m_pVT->WordIndexToWordPlace(index); - - return CPVT_WordPlace(); -} - -bool CFX_Edit::IsTextFull() const { - int32_t nTotalWords = m_pVT->GetTotalWords(); - int32_t nLimitChar = m_pVT->GetLimitChar(); - int32_t nCharArray = m_pVT->GetCharArray(); - - return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) || - (nCharArray > 0 && nTotalWords >= nCharArray); -} - -bool CFX_Edit::IsTextOverflow() const { - if (!m_bEnableScroll && !m_bEnableOverflow) { - CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); - CFX_FloatRect rcContent = m_pVT->GetContentRect(); - - if (m_pVT->IsMultiLine() && GetTotalLines() > 1 && - IsFloatBigger(rcContent.Height(), rcPlate.Height())) { - return true; - } - - if (IsFloatBigger(rcContent.Width(), rcPlate.Width())) - return true; - } - - return false; -} - -bool CFX_Edit::CanUndo() const { - if (m_bEnableUndo) { - return m_Undo.CanUndo(); - } - - return false; -} - -bool CFX_Edit::CanRedo() const { - if (m_bEnableUndo) { - return m_Undo.CanRedo(); - } - - return false; -} - -void CFX_Edit::EnableRefresh(bool bRefresh) { - m_bEnableRefresh = bRefresh; -} - -void CFX_Edit::EnableUndo(bool bUndo) { - m_bEnableUndo = bUndo; -} - -void CFX_Edit::EnableOprNotify(bool bNotify) { - m_bOprNotify = bNotify; -} - -CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place, - const CFX_WideString& sText, - int32_t charset) { - CPVT_WordPlace wp = place; - - if (m_pVT->IsValid()) { - for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) { - uint16_t word = sText[i]; - switch (word) { - case 0x0D: - wp = m_pVT->InsertSection(wp, nullptr, nullptr); - if (sText[i + 1] == 0x0A) - i++; - break; - case 0x0A: - wp = m_pVT->InsertSection(wp, nullptr, nullptr); - if (sText[i + 1] == 0x0D) - i++; - break; - case 0x09: - word = 0x20; - default: - wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset), - nullptr); - break; - } - } - } - - return wp; -} - -int32_t CFX_Edit::GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset) { - if (IPVT_FontMap* pFontMap = GetFontMap()) - return pFontMap->CharSetFromUnicode(word, nOldCharset); - return nOldCharset; -} - -void CFX_Edit::AddEditUndoItem( - std::unique_ptr pEditUndoItem) { - m_Undo.AddItem(std::move(pEditUndoItem)); -} - -CFX_ByteString CFX_Edit::GetPDFWordString(int32_t nFontIndex, - uint16_t Word, - uint16_t SubWord) { - IPVT_FontMap* pFontMap = GetFontMap(); - CPDF_Font* pPDFFont = pFontMap->GetPDFFont(nFontIndex); - if (!pPDFFont) - return CFX_ByteString(); - - CFX_ByteString sWord; - if (SubWord > 0) { - Word = SubWord; - } else { - uint32_t dwCharCode = pPDFFont->IsUnicodeCompatible() - ? pPDFFont->CharCodeFromUnicode(Word) - : pFontMap->CharCodeFromUnicode(nFontIndex, Word); - if (dwCharCode > 0) { - pPDFFont->AppendChar(&sWord, dwCharCode); - return sWord; - } - } - pPDFFont->AppendChar(&sWord, Word); - return sWord; -} - -CFX_Edit_LineRectArray::CFX_Edit_LineRectArray() {} - -CFX_Edit_LineRectArray::~CFX_Edit_LineRectArray() {} - -void CFX_Edit_LineRectArray::operator=(CFX_Edit_LineRectArray&& that) { - m_LineRects = std::move(that.m_LineRects); -} - -void CFX_Edit_LineRectArray::Add(const CPVT_WordRange& wrLine, - const CFX_FloatRect& rcLine) { - m_LineRects.push_back(pdfium::MakeUnique(wrLine, rcLine)); -} - -int32_t CFX_Edit_LineRectArray::GetSize() const { - return pdfium::CollectionSize(m_LineRects); -} - -CFX_Edit_LineRect* CFX_Edit_LineRectArray::GetAt(int32_t nIndex) const { - if (nIndex < 0 || nIndex >= GetSize()) - return nullptr; - - return m_LineRects[nIndex].get(); -} - -CFX_Edit_Select::CFX_Edit_Select() {} - -CFX_Edit_Select::CFX_Edit_Select(const CPVT_WordRange& range) { - Set(range.BeginPos, range.EndPos); -} - -CPVT_WordRange CFX_Edit_Select::ConvertToWordRange() const { - return CPVT_WordRange(BeginPos, EndPos); -} - -void CFX_Edit_Select::Reset() { - BeginPos.Reset(); - EndPos.Reset(); -} - -void CFX_Edit_Select::Set(const CPVT_WordPlace& begin, - const CPVT_WordPlace& end) { - BeginPos = begin; - EndPos = end; -} - -void CFX_Edit_Select::SetEndPos(const CPVT_WordPlace& end) { - EndPos = end; -} - -bool CFX_Edit_Select::IsEmpty() const { - return BeginPos == EndPos; -} - -CFX_Edit_RectArray::CFX_Edit_RectArray() {} - -CFX_Edit_RectArray::~CFX_Edit_RectArray() {} - -void CFX_Edit_RectArray::Clear() { - m_Rects.clear(); -} - -void CFX_Edit_RectArray::Add(const CFX_FloatRect& rect) { - // check for overlapped area - for (const auto& pRect : m_Rects) { - if (pRect && pRect->Contains(rect)) - return; - } - m_Rects.push_back(pdfium::MakeUnique(rect)); -} - -int32_t CFX_Edit_RectArray::GetSize() const { - return pdfium::CollectionSize(m_Rects); -} - -CFX_FloatRect* CFX_Edit_RectArray::GetAt(int32_t nIndex) const { - if (nIndex < 0 || nIndex >= GetSize()) - return nullptr; - - return m_Rects[nIndex].get(); -} diff --git a/fpdfsdk/fxedit/fxet_edit.h b/fpdfsdk/fxedit/fxet_edit.h deleted file mode 100644 index 4aaee69f96..0000000000 --- a/fpdfsdk/fxedit/fxet_edit.h +++ /dev/null @@ -1,513 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FPDFSDK_FXEDIT_FXET_EDIT_H_ -#define FPDFSDK_FXEDIT_FXET_EDIT_H_ - -#include -#include -#include - -#include "core/fpdfdoc/cpvt_secprops.h" -#include "core/fpdfdoc/cpvt_wordprops.h" -#include "core/fxcrt/cfx_unowned_ptr.h" - -#define FX_EDIT_ISLATINWORD(u) \ - (u == 0x2D || (u <= 0x005A && u >= 0x0041) || \ - (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0)) - -class CFFL_FormFiller; -class CFX_Edit; -class CFX_Edit_Iterator; -class CFX_Edit_Provider; -class CFX_RenderDevice; -class CFX_SystemHandler; -class CPWL_Edit; -class CPWL_EditCtrl; -class IFX_Edit_UndoItem; - -struct CFX_Edit_LineRect { - CFX_Edit_LineRect(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine) - : m_wrLine(wrLine), m_rcLine(rcLine) {} - - CPVT_WordRange m_wrLine; - CFX_FloatRect m_rcLine; -}; - -class CFX_Edit_LineRectArray { - public: - CFX_Edit_LineRectArray(); - ~CFX_Edit_LineRectArray(); - - void operator=(CFX_Edit_LineRectArray&& rects); - void Add(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine); - - int32_t GetSize() const; - CFX_Edit_LineRect* GetAt(int32_t nIndex) const; - - private: - std::vector> m_LineRects; -}; - -class CFX_Edit_RectArray { - public: - CFX_Edit_RectArray(); - ~CFX_Edit_RectArray(); - - void Clear(); - void Add(const CFX_FloatRect& rect); - - int32_t GetSize() const; - CFX_FloatRect* GetAt(int32_t nIndex) const; - - private: - std::vector> m_Rects; -}; - -class CFX_Edit_Refresh { - public: - CFX_Edit_Refresh(); - ~CFX_Edit_Refresh(); - - void BeginRefresh(); - void Push(const CPVT_WordRange& linerange, const CFX_FloatRect& rect); - void NoAnalyse(); - const CFX_Edit_RectArray* GetRefreshRects() const; - void EndRefresh(); - - private: - CFX_Edit_LineRectArray m_NewLineRects; - CFX_Edit_LineRectArray m_OldLineRects; - CFX_Edit_RectArray m_RefreshRects; -}; - -class CFX_Edit_Select { - public: - CFX_Edit_Select(); - explicit CFX_Edit_Select(const CPVT_WordRange& range); - - void Reset(); - void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end); - void SetEndPos(const CPVT_WordPlace& end); - - CPVT_WordRange ConvertToWordRange() const; - bool IsEmpty() const; - - CPVT_WordPlace BeginPos; - CPVT_WordPlace EndPos; -}; - -class CFX_Edit_Undo { - public: - explicit CFX_Edit_Undo(int32_t nBufsize); - ~CFX_Edit_Undo(); - - void AddItem(std::unique_ptr pItem); - void Undo(); - void Redo(); - bool CanUndo() const; - bool CanRedo() const; - void Reset(); - - private: - void RemoveHeads(); - void RemoveTails(); - - std::deque> m_UndoItemStack; - size_t m_nCurUndoPos; - size_t m_nBufSize; - bool m_bWorking; -}; - -class IFX_Edit_UndoItem { - public: - virtual ~IFX_Edit_UndoItem() {} - - virtual void Undo() = 0; - virtual void Redo() = 0; - virtual CFX_WideString GetUndoTitle() const = 0; -}; - -class CFX_Edit_UndoItem : public IFX_Edit_UndoItem { - public: - CFX_Edit_UndoItem(); - ~CFX_Edit_UndoItem() override; - - CFX_WideString GetUndoTitle() const override; - - void SetFirst(bool bFirst); - void SetLast(bool bLast); - bool IsLast(); - - private: - bool m_bFirst; - bool m_bLast; -}; - -class CFXEU_InsertWord : public CFX_Edit_UndoItem { - public: - CFXEU_InsertWord(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - uint16_t word, - int32_t charset, - const CPVT_WordProps* pWordProps); - ~CFXEU_InsertWord() override; - - // CFX_Edit_UndoItem - void Redo() override; - void Undo() override; - - private: - CFX_UnownedPtr m_pEdit; - - CPVT_WordPlace m_wpOld; - CPVT_WordPlace m_wpNew; - uint16_t m_Word; - int32_t m_nCharset; - CPVT_WordProps m_WordProps; -}; - -class CFXEU_InsertReturn : public CFX_Edit_UndoItem { - public: - CFXEU_InsertReturn(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - const CPVT_SecProps* pSecProps, - const CPVT_WordProps* pWordProps); - ~CFXEU_InsertReturn() override; - - // CFX_Edit_UndoItem - void Redo() override; - void Undo() override; - - private: - CFX_UnownedPtr m_pEdit; - - CPVT_WordPlace m_wpOld; - CPVT_WordPlace m_wpNew; - CPVT_SecProps m_SecProps; - CPVT_WordProps m_WordProps; -}; - -class CFXEU_Backspace : public CFX_Edit_UndoItem { - public: - CFXEU_Backspace(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - uint16_t word, - int32_t charset, - const CPVT_SecProps& SecProps, - const CPVT_WordProps& WordProps); - ~CFXEU_Backspace() override; - - // CFX_Edit_UndoItem - void Redo() override; - void Undo() override; - - private: - CFX_UnownedPtr m_pEdit; - - CPVT_WordPlace m_wpOld; - CPVT_WordPlace m_wpNew; - uint16_t m_Word; - int32_t m_nCharset; - CPVT_SecProps m_SecProps; - CPVT_WordProps m_WordProps; -}; - -class CFXEU_Delete : public CFX_Edit_UndoItem { - public: - CFXEU_Delete(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - uint16_t word, - int32_t charset, - const CPVT_SecProps& SecProps, - const CPVT_WordProps& WordProps, - bool bSecEnd); - ~CFXEU_Delete() override; - - // CFX_Edit_UndoItem - void Redo() override; - void Undo() override; - - private: - CFX_UnownedPtr m_pEdit; - - CPVT_WordPlace m_wpOld; - CPVT_WordPlace m_wpNew; - uint16_t m_Word; - int32_t m_nCharset; - CPVT_SecProps m_SecProps; - CPVT_WordProps m_WordProps; - bool m_bSecEnd; -}; - -class CFXEU_Clear : public CFX_Edit_UndoItem { - public: - CFXEU_Clear(CFX_Edit* pEdit, - const CPVT_WordRange& wrSel, - const CFX_WideString& swText); - ~CFXEU_Clear() override; - - // CFX_Edit_UndoItem - void Redo() override; - void Undo() override; - - private: - CFX_UnownedPtr m_pEdit; - - CPVT_WordRange m_wrSel; - CFX_WideString m_swText; -}; - -class CFXEU_InsertText : public CFX_Edit_UndoItem { - public: - CFXEU_InsertText(CFX_Edit* pEdit, - const CPVT_WordPlace& wpOldPlace, - const CPVT_WordPlace& wpNewPlace, - const CFX_WideString& swText, - int32_t charset); - ~CFXEU_InsertText() override; - - // CFX_Edit_UndoItem - void Redo() override; - void Undo() override; - - private: - CFX_UnownedPtr m_pEdit; - - CPVT_WordPlace m_wpOld; - CPVT_WordPlace m_wpNew; - CFX_WideString m_swText; - int32_t m_nCharset; -}; - -class CFX_Edit { - public: - static void DrawEdit(CFX_RenderDevice* pDevice, - CFX_Matrix* pUser2Device, - CFX_Edit* pEdit, - FX_COLORREF crTextFill, - const CFX_FloatRect& rcClip, - const CFX_PointF& ptOffset, - const CPVT_WordRange* pRange, - CFX_SystemHandler* pSystemHandler, - CFFL_FormFiller* pFFLData); - - CFX_Edit(); - ~CFX_Edit(); - - void SetFontMap(IPVT_FontMap* pFontMap); - void SetNotify(CPWL_EditCtrl* pNotify); - void SetOprNotify(CPWL_Edit* pOprNotify); - - // Returns an iterator for the contents. Should not be released. - CFX_Edit_Iterator* GetIterator(); - IPVT_FontMap* GetFontMap(); - void Initialize(); - - // Set the bounding box of the text area. - void SetPlateRect(const CFX_FloatRect& rect); - void SetScrollPos(const CFX_PointF& point); - - // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right]) - void SetAlignmentH(int32_t nFormat, bool bPaint); - // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right]) - void SetAlignmentV(int32_t nFormat, bool bPaint); - - // Set the substitution character for hidden text. - void SetPasswordChar(uint16_t wSubWord, bool bPaint); - - // Set the maximum number of words in the text. - void SetLimitChar(int32_t nLimitChar); - void SetCharArray(int32_t nCharArray); - void SetCharSpace(float fCharSpace); - void SetMultiLine(bool bMultiLine, bool bPaint); - void SetAutoReturn(bool bAuto, bool bPaint); - void SetAutoFontSize(bool bAuto, bool bPaint); - void SetAutoScroll(bool bAuto, bool bPaint); - void SetFontSize(float fFontSize); - void SetTextOverflow(bool bAllowed, bool bPaint); - void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl); - void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl); - void OnVK_UP(bool bShift, bool bCtrl); - void OnVK_DOWN(bool bShift, bool bCtrl); - void OnVK_LEFT(bool bShift, bool bCtrl); - void OnVK_RIGHT(bool bShift, bool bCtrl); - void OnVK_HOME(bool bShift, bool bCtrl); - void OnVK_END(bool bShift, bool bCtrl); - void SetText(const CFX_WideString& sText); - bool InsertWord(uint16_t word, int32_t charset); - bool InsertReturn(); - bool Backspace(); - bool Delete(); - bool ClearSelection(); - bool InsertText(const CFX_WideString& sText, int32_t charset); - bool Redo(); - bool Undo(); - CPVT_WordPlace WordIndexToWordPlace(int32_t index) const; - CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const; - int32_t GetCaret() const; - CPVT_WordPlace GetCaretWordPlace() const; - CFX_WideString GetSelectedText() const; - CFX_WideString GetText() const; - float GetFontSize() const; - uint16_t GetPasswordChar() const; - CFX_PointF GetScrollPos() const; - int32_t GetCharArray() const; - CFX_FloatRect GetContentRect() const; - CFX_WideString GetRangeText(const CPVT_WordRange& range) const; - int32_t GetHorzScale() const; - float GetCharSpace() const; - void SetSelection(int32_t nStartChar, int32_t nEndChar); - void GetSelection(int32_t& nStartChar, int32_t& nEndChar) const; - void SelectAll(); - void SelectNone(); - bool IsSelected() const; - void Paint(); - void EnableRefresh(bool bRefresh); - void RefreshWordRange(const CPVT_WordRange& wr); - CPVT_WordRange GetWholeWordRange() const; - CPVT_WordRange GetSelectWordRange() const; - void EnableUndo(bool bUndo); - void EnableOprNotify(bool bNotify); - bool IsTextFull() const; - bool IsTextOverflow() const; - bool CanUndo() const; - bool CanRedo() const; - CPVT_WordRange GetVisibleWordRange() const; - - bool Empty(); - - CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place, - const CFX_WideString& sText, - int32_t charset); - int32_t GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset); - - int32_t GetTotalLines() const; - - CFX_ByteString GetPDFWordString(int32_t nFontIndex, - uint16_t Word, - uint16_t SubWord); - - private: - friend class CFX_Edit_Iterator; - friend class CFXEU_InsertWord; - friend class CFXEU_InsertReturn; - friend class CFXEU_Backspace; - friend class CFXEU_Delete; - friend class CFXEU_Clear; - friend class CFXEU_InsertText; - - void SetSelection(const CPVT_WordPlace& begin, const CPVT_WordPlace& end); - - void RearrangeAll(); - void RearrangePart(const CPVT_WordRange& range); - void ScrollToCaret(); - void SetScrollInfo(); - void SetScrollPosX(float fx); - void SetScrollPosY(float fy); - void SetScrollLimit(); - void SetContentChanged(); - - bool InsertWord(uint16_t word, - int32_t charset, - const CPVT_WordProps* pWordProps, - bool bAddUndo, - bool bPaint); - bool InsertReturn(const CPVT_SecProps* pSecProps, - const CPVT_WordProps* pWordProps, - bool bAddUndo, - bool bPaint); - bool Backspace(bool bAddUndo, bool bPaint); - bool Delete(bool bAddUndo, bool bPaint); - bool Clear(bool bAddUndo, bool bPaint); - bool InsertText(const CFX_WideString& sText, - int32_t charset, - bool bAddUndo, - bool bPaint); - void PaintInsertText(const CPVT_WordPlace& wpOld, - const CPVT_WordPlace& wpNew); - - inline CFX_PointF VTToEdit(const CFX_PointF& point) const; - inline CFX_PointF EditToVT(const CFX_PointF& point) const; - inline CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const; - - void Refresh(); - void RefreshPushLineRects(const CPVT_WordRange& wr); - - void SetCaret(const CPVT_WordPlace& place); - void SetCaretInfo(); - void SetCaretOrigin(); - - void AddEditUndoItem(std::unique_ptr pEditUndoItem); - - private: - std::unique_ptr m_pVT; - CFX_UnownedPtr m_pNotify; - CFX_UnownedPtr m_pOprNotify; - std::unique_ptr m_pVTProvider; - CPVT_WordPlace m_wpCaret; - CPVT_WordPlace m_wpOldCaret; - CFX_Edit_Select m_SelState; - CFX_PointF m_ptScrollPos; - CFX_PointF m_ptRefreshScrollPos; - bool m_bEnableScroll; - std::unique_ptr m_pIterator; - CFX_Edit_Refresh m_Refresh; - CFX_PointF m_ptCaret; - CFX_Edit_Undo m_Undo; - int32_t m_nAlignment; - bool m_bNotifyFlag; - bool m_bEnableOverflow; - bool m_bEnableRefresh; - CFX_FloatRect m_rcOldContent; - bool m_bEnableUndo; - bool m_bOprNotify; -}; - -class CFX_Edit_Iterator { - public: - CFX_Edit_Iterator(CFX_Edit* pEdit, CPDF_VariableText::Iterator* pVTIterator); - ~CFX_Edit_Iterator(); - - bool NextWord(); - bool PrevWord(); - bool GetWord(CPVT_Word& word) const; - bool GetLine(CPVT_Line& line) const; - void SetAt(int32_t nWordIndex); - void SetAt(const CPVT_WordPlace& place); - const CPVT_WordPlace& GetAt() const; - - private: - CFX_UnownedPtr m_pEdit; - CPDF_VariableText::Iterator* m_pVTIterator; -}; - -class CFX_Edit_Provider : public CPDF_VariableText::Provider { - public: - explicit CFX_Edit_Provider(IPVT_FontMap* pFontMap); - ~CFX_Edit_Provider() override; - - IPVT_FontMap* GetFontMap() const; - - // CPDF_VariableText::Provider: - int32_t GetCharWidth(int32_t nFontIndex, uint16_t word) override; - int32_t GetTypeAscent(int32_t nFontIndex) override; - int32_t GetTypeDescent(int32_t nFontIndex) override; - int32_t GetWordFontIndex(uint16_t word, - int32_t charset, - int32_t nFontIndex) override; - int32_t GetDefaultFontIndex() override; - bool IsLatinWord(uint16_t word) override; - - private: - IPVT_FontMap* m_pFontMap; -}; - -#endif // FPDFSDK_FXEDIT_FXET_EDIT_H_ diff --git a/fpdfsdk/fxedit/fxet_list.cpp b/fpdfsdk/fxedit/fxet_list.cpp deleted file mode 100644 index fa085f237f..0000000000 --- a/fpdfsdk/fxedit/fxet_list.cpp +++ /dev/null @@ -1,637 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "fpdfsdk/fxedit/fxet_list.h" - -#include -#include - -#include "core/fpdfdoc/cpvt_word.h" -#include "core/fxcrt/fx_extension.h" -#include "fpdfsdk/fxedit/fxet_edit.h" -#include "fpdfsdk/pdfwindow/cpwl_list_box.h" -#include "third_party/base/stl_util.h" - -CFX_ListCtrl::Item::Item() - : m_pEdit(new CFX_Edit), - m_bSelected(false), - m_rcListItem(0.0f, 0.0f, 0.0f, 0.0f) { - m_pEdit->SetAlignmentV(1, true); - m_pEdit->Initialize(); -} - -CFX_ListCtrl::Item::~Item() {} - -void CFX_ListCtrl::Item::SetFontMap(IPVT_FontMap* pFontMap) { - m_pEdit->SetFontMap(pFontMap); -} - -void CFX_ListCtrl::Item::SetText(const CFX_WideString& text) { - m_pEdit->SetText(text); -} - -void CFX_ListCtrl::Item::SetFontSize(float fFontSize) { - m_pEdit->SetFontSize(fFontSize); -} - -float CFX_ListCtrl::Item::GetItemHeight() const { - return m_pEdit->GetContentRect().Height(); -} - -uint16_t CFX_ListCtrl::Item::GetFirstChar() const { - CPVT_Word word; - CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator(); - pIterator->SetAt(1); - pIterator->GetWord(word); - return word.Word; -} - -CFX_WideString CFX_ListCtrl::Item::GetText() const { - return m_pEdit->GetText(); -} - -CPLST_Select::CPLST_Select() {} - -CPLST_Select::~CPLST_Select() {} - -void CPLST_Select::Add(int32_t nItemIndex) { - m_Items[nItemIndex] = SELECTING; -} - -void CPLST_Select::Add(int32_t nBeginIndex, int32_t nEndIndex) { - if (nBeginIndex > nEndIndex) - std::swap(nBeginIndex, nEndIndex); - - for (int32_t i = nBeginIndex; i <= nEndIndex; ++i) - Add(i); -} - -void CPLST_Select::Sub(int32_t nItemIndex) { - auto it = m_Items.find(nItemIndex); - if (it != m_Items.end()) - it->second = DESELECTING; -} - -void CPLST_Select::Sub(int32_t nBeginIndex, int32_t nEndIndex) { - if (nBeginIndex > nEndIndex) - std::swap(nBeginIndex, nEndIndex); - - for (int32_t i = nBeginIndex; i <= nEndIndex; ++i) - Sub(i); -} - -void CPLST_Select::DeselectAll() { - for (auto& item : m_Items) - item.second = DESELECTING; -} - -void CPLST_Select::Done() { - auto it = m_Items.begin(); - while (it != m_Items.end()) { - if (it->second == DESELECTING) - it = m_Items.erase(it); - else - (it++)->second = NORMAL; - } -} - -CFX_ListCtrl::CFX_ListCtrl() - : m_pNotify(nullptr), - m_bNotifyFlag(false), - m_nSelItem(-1), - m_nFootIndex(-1), - m_bCtrlSel(false), - m_nCaretIndex(-1), - m_fFontSize(0.0f), - m_pFontMap(nullptr), - m_bMultiple(false) {} - -CFX_ListCtrl::~CFX_ListCtrl() { - Empty(); -} - -CFX_PointF CFX_ListCtrl::InToOut(const CFX_PointF& point) const { - CFX_FloatRect rcPlate = m_rcPlate; - return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left), - point.y - (m_ptScrollPos.y - rcPlate.top)); -} - -CFX_PointF CFX_ListCtrl::OutToIn(const CFX_PointF& point) const { - CFX_FloatRect rcPlate = m_rcPlate; - return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left), - point.y + (m_ptScrollPos.y - rcPlate.top)); -} - -CFX_FloatRect CFX_ListCtrl::InToOut(const CFX_FloatRect& rect) const { - CFX_PointF ptLeftBottom = InToOut(CFX_PointF(rect.left, rect.bottom)); - CFX_PointF ptRightTop = InToOut(CFX_PointF(rect.right, rect.top)); - return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, - ptRightTop.y); -} - -CFX_FloatRect CFX_ListCtrl::OutToIn(const CFX_FloatRect& rect) const { - CFX_PointF ptLeftBottom = OutToIn(CFX_PointF(rect.left, rect.bottom)); - CFX_PointF ptRightTop = OutToIn(CFX_PointF(rect.right, rect.top)); - return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, - ptRightTop.y); -} - -CFX_PointF CFX_ListCtrl::InnerToOuter(const CFX_PointF& point) const { - return CFX_PointF(point.x + GetBTPoint().x, GetBTPoint().y - point.y); -} - -CFX_PointF CFX_ListCtrl::OuterToInner(const CFX_PointF& point) const { - return CFX_PointF(point.x - GetBTPoint().x, GetBTPoint().y - point.y); -} - -CFX_FloatRect CFX_ListCtrl::InnerToOuter(const CFX_FloatRect& rect) const { - CFX_PointF ptLeftTop = InnerToOuter(CFX_PointF(rect.left, rect.top)); - CFX_PointF ptRightBottom = InnerToOuter(CFX_PointF(rect.right, rect.bottom)); - return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, - ptLeftTop.y); -} - -CFX_FloatRect CFX_ListCtrl::OuterToInner(const CFX_FloatRect& rect) const { - CFX_PointF ptLeftTop = OuterToInner(CFX_PointF(rect.left, rect.top)); - CFX_PointF ptRightBottom = OuterToInner(CFX_PointF(rect.right, rect.bottom)); - return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, - ptLeftTop.y); -} - -void CFX_ListCtrl::OnMouseDown(const CFX_PointF& point, - bool bShift, - bool bCtrl) { - int32_t nHitIndex = GetItemIndex(point); - - if (IsMultipleSel()) { - if (bCtrl) { - if (IsItemSelected(nHitIndex)) { - m_aSelItems.Sub(nHitIndex); - SelectItems(); - m_bCtrlSel = false; - } else { - m_aSelItems.Add(nHitIndex); - SelectItems(); - m_bCtrlSel = true; - } - - m_nFootIndex = nHitIndex; - } else if (bShift) { - m_aSelItems.DeselectAll(); - m_aSelItems.Add(m_nFootIndex, nHitIndex); - SelectItems(); - } else { - m_aSelItems.DeselectAll(); - m_aSelItems.Add(nHitIndex); - SelectItems(); - - m_nFootIndex = nHitIndex; - } - - SetCaret(nHitIndex); - } else { - SetSingleSelect(nHitIndex); - } - - if (!IsItemVisible(nHitIndex)) - ScrollToListItem(nHitIndex); -} - -void CFX_ListCtrl::OnMouseMove(const CFX_PointF& point, - bool bShift, - bool bCtrl) { - int32_t nHitIndex = GetItemIndex(point); - - if (IsMultipleSel()) { - if (bCtrl) { - if (m_bCtrlSel) - m_aSelItems.Add(m_nFootIndex, nHitIndex); - else - m_aSelItems.Sub(m_nFootIndex, nHitIndex); - - SelectItems(); - } else { - m_aSelItems.DeselectAll(); - m_aSelItems.Add(m_nFootIndex, nHitIndex); - SelectItems(); - } - - SetCaret(nHitIndex); - } else { - SetSingleSelect(nHitIndex); - } - - if (!IsItemVisible(nHitIndex)) - ScrollToListItem(nHitIndex); -} - -void CFX_ListCtrl::OnVK(int32_t nItemIndex, bool bShift, bool bCtrl) { - if (IsMultipleSel()) { - if (nItemIndex >= 0 && nItemIndex < GetCount()) { - if (bCtrl) { - } else if (bShift) { - m_aSelItems.DeselectAll(); - m_aSelItems.Add(m_nFootIndex, nItemIndex); - SelectItems(); - } else { - m_aSelItems.DeselectAll(); - m_aSelItems.Add(nItemIndex); - SelectItems(); - m_nFootIndex = nItemIndex; - } - - SetCaret(nItemIndex); - } - } else { - SetSingleSelect(nItemIndex); - } - - if (!IsItemVisible(nItemIndex)) - ScrollToListItem(nItemIndex); -} - -void CFX_ListCtrl::OnVK_UP(bool bShift, bool bCtrl) { - OnVK(IsMultipleSel() ? GetCaret() - 1 : GetSelect() - 1, bShift, bCtrl); -} - -void CFX_ListCtrl::OnVK_DOWN(bool bShift, bool bCtrl) { - OnVK(IsMultipleSel() ? GetCaret() + 1 : GetSelect() + 1, bShift, bCtrl); -} - -void CFX_ListCtrl::OnVK_LEFT(bool bShift, bool bCtrl) { - OnVK(0, bShift, bCtrl); -} - -void CFX_ListCtrl::OnVK_RIGHT(bool bShift, bool bCtrl) { - OnVK(GetCount() - 1, bShift, bCtrl); -} - -void CFX_ListCtrl::OnVK_HOME(bool bShift, bool bCtrl) { - OnVK(0, bShift, bCtrl); -} - -void CFX_ListCtrl::OnVK_END(bool bShift, bool bCtrl) { - OnVK(GetCount() - 1, bShift, bCtrl); -} - -bool CFX_ListCtrl::OnChar(uint16_t nChar, bool bShift, bool bCtrl) { - int32_t nIndex = GetLastSelected(); - int32_t nFindIndex = FindNext(nIndex, nChar); - - if (nFindIndex != nIndex) { - OnVK(nFindIndex, bShift, bCtrl); - return true; - } - return false; -} - -void CFX_ListCtrl::SetPlateRect(const CFX_FloatRect& rect) { - m_rcPlate = rect; - m_ptScrollPos.x = rect.left; - SetScrollPos(CFX_PointF(rect.left, rect.top)); - ReArrange(0); - InvalidateItem(-1); -} - -CFX_FloatRect CFX_ListCtrl::GetItemRect(int32_t nIndex) const { - return InToOut(GetItemRectInternal(nIndex)); -} - -CFX_FloatRect CFX_ListCtrl::GetItemRectInternal(int32_t nIndex) const { - if (!pdfium::IndexInBounds(m_ListItems, nIndex) || !m_ListItems[nIndex]) - return CFX_FloatRect(); - - CFX_FloatRect rcItem = m_ListItems[nIndex]->GetRect(); - rcItem.left = 0.0f; - rcItem.right = m_rcPlate.Width(); - return InnerToOuter(rcItem); -} - -void CFX_ListCtrl::AddString(const CFX_WideString& str) { - AddItem(str); - ReArrange(GetCount() - 1); -} - -void CFX_ListCtrl::SetMultipleSelect(int32_t nItemIndex, bool bSelected) { - if (!IsValid(nItemIndex)) - return; - - if (bSelected != IsItemSelected(nItemIndex)) { - if (bSelected) { - SetItemSelect(nItemIndex, true); - InvalidateItem(nItemIndex); - } else { - SetItemSelect(nItemIndex, false); - InvalidateItem(nItemIndex); - } - } -} - -void CFX_ListCtrl::SetSingleSelect(int32_t nItemIndex) { - if (!IsValid(nItemIndex)) - return; - - if (m_nSelItem != nItemIndex) { - if (m_nSelItem >= 0) { - SetItemSelect(m_nSelItem, false); - InvalidateItem(m_nSelItem); - } - - SetItemSelect(nItemIndex, true); - InvalidateItem(nItemIndex); - m_nSelItem = nItemIndex; - } -} - -void CFX_ListCtrl::SetCaret(int32_t nItemIndex) { - if (!IsValid(nItemIndex)) - return; - - if (IsMultipleSel()) { - int32_t nOldIndex = m_nCaretIndex; - - if (nOldIndex != nItemIndex) { - m_nCaretIndex = nItemIndex; - InvalidateItem(nOldIndex); - InvalidateItem(nItemIndex); - } - } -} - -void CFX_ListCtrl::InvalidateItem(int32_t nItemIndex) { - if (m_pNotify) { - if (nItemIndex == -1) { - if (!m_bNotifyFlag) { - m_bNotifyFlag = true; - CFX_FloatRect rcRefresh = m_rcPlate; - m_pNotify->IOnInvalidateRect(&rcRefresh); - m_bNotifyFlag = false; - } - } else { - if (!m_bNotifyFlag) { - m_bNotifyFlag = true; - CFX_FloatRect rcRefresh = GetItemRect(nItemIndex); - rcRefresh.left -= 1.0f; - rcRefresh.right += 1.0f; - rcRefresh.bottom -= 1.0f; - rcRefresh.top += 1.0f; - - m_pNotify->IOnInvalidateRect(&rcRefresh); - m_bNotifyFlag = false; - } - } - } -} - -void CFX_ListCtrl::SelectItems() { - for (const auto& item : m_aSelItems) { - if (item.second != CPLST_Select::NORMAL) - SetMultipleSelect(item.first, item.second == CPLST_Select::SELECTING); - } - m_aSelItems.Done(); -} - -void CFX_ListCtrl::Select(int32_t nItemIndex) { - if (!IsValid(nItemIndex)) - return; - - if (IsMultipleSel()) { - m_aSelItems.Add(nItemIndex); - SelectItems(); - } else { - SetSingleSelect(nItemIndex); - } -} - -bool CFX_ListCtrl::IsItemVisible(int32_t nItemIndex) const { - CFX_FloatRect rcPlate = m_rcPlate; - CFX_FloatRect rcItem = GetItemRect(nItemIndex); - - return rcItem.bottom >= rcPlate.bottom && rcItem.top <= rcPlate.top; -} - -void CFX_ListCtrl::ScrollToListItem(int32_t nItemIndex) { - if (!IsValid(nItemIndex)) - return; - - CFX_FloatRect rcPlate = m_rcPlate; - CFX_FloatRect rcItem = GetItemRectInternal(nItemIndex); - CFX_FloatRect rcItemCtrl = GetItemRect(nItemIndex); - - if (IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) { - if (IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) { - SetScrollPosY(rcItem.bottom + rcPlate.Height()); - } - } else if (IsFloatBigger(rcItemCtrl.top, rcPlate.top)) { - if (IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) { - SetScrollPosY(rcItem.top); - } - } -} - -void CFX_ListCtrl::SetScrollInfo() { - if (m_pNotify) { - CFX_FloatRect rcPlate = m_rcPlate; - CFX_FloatRect rcContent = GetContentRectInternal(); - - if (!m_bNotifyFlag) { - m_bNotifyFlag = true; - m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top, - rcContent.bottom, rcContent.top, - GetFirstHeight(), rcPlate.Height()); - m_bNotifyFlag = false; - } - } -} - -void CFX_ListCtrl::SetScrollPos(const CFX_PointF& point) { - SetScrollPosY(point.y); -} - -void CFX_ListCtrl::SetScrollPosY(float fy) { - if (!IsFloatEqual(m_ptScrollPos.y, fy)) { - CFX_FloatRect rcPlate = m_rcPlate; - CFX_FloatRect rcContent = GetContentRectInternal(); - - if (rcPlate.Height() > rcContent.Height()) { - fy = rcPlate.top; - } else { - if (IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) { - fy = rcContent.bottom + rcPlate.Height(); - } else if (IsFloatBigger(fy, rcContent.top)) { - fy = rcContent.top; - } - } - - m_ptScrollPos.y = fy; - InvalidateItem(-1); - - if (m_pNotify) { - if (!m_bNotifyFlag) { - m_bNotifyFlag = true; - m_pNotify->IOnSetScrollPosY(fy); - m_bNotifyFlag = false; - } - } - } -} - -CFX_FloatRect CFX_ListCtrl::GetContentRectInternal() const { - return InnerToOuter(m_rcContent); -} - -CFX_FloatRect CFX_ListCtrl::GetContentRect() const { - return InToOut(GetContentRectInternal()); -} - -void CFX_ListCtrl::ReArrange(int32_t nItemIndex) { - float fPosY = 0.0f; - if (pdfium::IndexInBounds(m_ListItems, nItemIndex - 1) && - m_ListItems[nItemIndex - 1]) { - fPosY = m_ListItems[nItemIndex - 1]->GetRect().bottom; - } - for (const auto& pListItem : m_ListItems) { - if (pListItem) { - float fListItemHeight = pListItem->GetItemHeight(); - pListItem->SetRect( - CFX_FloatRect(0.0f, fPosY + fListItemHeight, 0.0f, fPosY)); - fPosY += fListItemHeight; - } - } - SetContentRect(CFX_FloatRect(0.0f, fPosY, 0.0f, 0.0f)); - SetScrollInfo(); -} - -void CFX_ListCtrl::SetTopItem(int32_t nIndex) { - if (IsValid(nIndex)) { - CFX_FloatRect rcItem = GetItemRectInternal(nIndex); - SetScrollPosY(rcItem.top); - } -} - -int32_t CFX_ListCtrl::GetTopItem() const { - int32_t nItemIndex = GetItemIndex(GetBTPoint()); - if (!IsItemVisible(nItemIndex) && IsItemVisible(nItemIndex + 1)) - nItemIndex += 1; - - return nItemIndex; -} - -void CFX_ListCtrl::Empty() { - m_ListItems.clear(); - InvalidateItem(-1); -} - -void CFX_ListCtrl::Cancel() { - m_aSelItems.DeselectAll(); -} - -int32_t CFX_ListCtrl::GetItemIndex(const CFX_PointF& point) const { - CFX_PointF pt = OuterToInner(OutToIn(point)); - bool bFirst = true; - bool bLast = true; - for (const auto& pListItem : m_ListItems) { - if (!pListItem) - continue; - CFX_FloatRect rcListItem = pListItem->GetRect(); - if (IsFloatBigger(pt.y, rcListItem.top)) - bFirst = false; - if (IsFloatSmaller(pt.y, rcListItem.bottom)) - bLast = false; - if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) - return &pListItem - &m_ListItems.front(); - } - if (bFirst) - return 0; - if (bLast) - return pdfium::CollectionSize(m_ListItems) - 1; - return -1; -} - -CFX_WideString CFX_ListCtrl::GetText() const { - if (IsMultipleSel()) - return GetItemText(m_nCaretIndex); - return GetItemText(m_nSelItem); -} - -void CFX_ListCtrl::AddItem(const CFX_WideString& str) { - auto pListItem = pdfium::MakeUnique(); - pListItem->SetFontMap(m_pFontMap.Get()); - pListItem->SetFontSize(m_fFontSize); - pListItem->SetText(str); - m_ListItems.push_back(std::move(pListItem)); -} - -CFX_Edit* CFX_ListCtrl::GetItemEdit(int32_t nIndex) const { - if (!pdfium::IndexInBounds(m_ListItems, nIndex) || !m_ListItems[nIndex]) - return nullptr; - return m_ListItems[nIndex]->GetEdit(); -} - -int32_t CFX_ListCtrl::GetCount() const { - return pdfium::CollectionSize(m_ListItems); -} - -float CFX_ListCtrl::GetFirstHeight() const { - if (m_ListItems.empty() || !m_ListItems.front()) - return 1.0f; - return m_ListItems.front()->GetItemHeight(); -} - -int32_t CFX_ListCtrl::GetFirstSelected() const { - int32_t i = 0; - for (const auto& pListItem : m_ListItems) { - if (pListItem && pListItem->IsSelected()) - return i; - ++i; - } - return -1; -} - -int32_t CFX_ListCtrl::GetLastSelected() const { - for (auto iter = m_ListItems.rbegin(); iter != m_ListItems.rend(); ++iter) { - if (*iter && (*iter)->IsSelected()) - return &*iter - &m_ListItems.front(); - } - return -1; -} - -int32_t CFX_ListCtrl::FindNext(int32_t nIndex, wchar_t nChar) const { - int32_t nCircleIndex = nIndex; - int32_t sz = pdfium::CollectionSize(m_ListItems); - for (int32_t i = 0; i < sz; i++) { - nCircleIndex++; - if (nCircleIndex >= sz) - nCircleIndex = 0; - - if (Item* pListItem = m_ListItems[nCircleIndex].get()) { - if (FXSYS_toupper(pListItem->GetFirstChar()) == FXSYS_toupper(nChar)) - return nCircleIndex; - } - } - - return nCircleIndex; -} - -bool CFX_ListCtrl::IsItemSelected(int32_t nIndex) const { - return pdfium::IndexInBounds(m_ListItems, nIndex) && m_ListItems[nIndex] && - m_ListItems[nIndex]->IsSelected(); -} - -void CFX_ListCtrl::SetItemSelect(int32_t nIndex, bool bSelected) { - if (pdfium::IndexInBounds(m_ListItems, nIndex) && m_ListItems[nIndex]) - m_ListItems[nIndex]->SetSelect(bSelected); -} - -bool CFX_ListCtrl::IsValid(int32_t nItemIndex) const { - return pdfium::IndexInBounds(m_ListItems, nItemIndex); -} - -CFX_WideString CFX_ListCtrl::GetItemText(int32_t nIndex) const { - if (pdfium::IndexInBounds(m_ListItems, nIndex) && m_ListItems[nIndex]) - return m_ListItems[nIndex]->GetText(); - return L""; -} diff --git a/fpdfsdk/fxedit/fxet_list.h b/fpdfsdk/fxedit/fxet_list.h deleted file mode 100644 index 83b8d9e865..0000000000 --- a/fpdfsdk/fxedit/fxet_list.h +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FPDFSDK_FXEDIT_FXET_LIST_H_ -#define FPDFSDK_FXEDIT_FXET_LIST_H_ - -#include -#include -#include - -#include "core/fxcrt/cfx_unowned_ptr.h" -#include "core/fxcrt/fx_coordinates.h" - -class CFX_Edit; -class CFX_Edit_Iterator; -class CPWL_List_Notify; -class IPVT_FontMap; - -class CPLST_Select { - public: - enum State { DESELECTING = -1, NORMAL = 0, SELECTING = 1 }; - using const_iterator = std::map::const_iterator; - - CPLST_Select(); - virtual ~CPLST_Select(); - - void Add(int32_t nItemIndex); - void Add(int32_t nBeginIndex, int32_t nEndIndex); - void Sub(int32_t nItemIndex); - void Sub(int32_t nBeginIndex, int32_t nEndIndex); - void DeselectAll(); - void Done(); - - const_iterator begin() const { return m_Items.begin(); } - const_iterator end() const { return m_Items.end(); } - - private: - std::map m_Items; -}; - -class CFX_ListCtrl { - public: - CFX_ListCtrl(); - ~CFX_ListCtrl(); - - void SetNotify(CPWL_List_Notify* pNotify) { m_pNotify = pNotify; } - void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl); - void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl); - void OnVK_UP(bool bShift, bool bCtrl); - void OnVK_DOWN(bool bShift, bool bCtrl); - void OnVK_LEFT(bool bShift, bool bCtrl); - void OnVK_RIGHT(bool bShift, bool bCtrl); - void OnVK_HOME(bool bShift, bool bCtrl); - void OnVK_END(bool bShift, bool bCtrl); - bool OnChar(uint16_t nChar, bool bShift, bool bCtrl); - - void SetScrollPos(const CFX_PointF& point); - void ScrollToListItem(int32_t nItemIndex); - CFX_FloatRect GetItemRect(int32_t nIndex) const; - int32_t GetCaret() const { return m_nCaretIndex; } - int32_t GetSelect() const { return m_nSelItem; } - int32_t GetTopItem() const; - void SetContentRect(const CFX_FloatRect& rect) { m_rcContent = rect; } - CFX_FloatRect GetContentRect() const; - - int32_t GetItemIndex(const CFX_PointF& point) const; - void AddString(const CFX_WideString& str); - void SetTopItem(int32_t nIndex); - void Select(int32_t nItemIndex); - void SetCaret(int32_t nItemIndex); - void Empty(); - void Cancel(); - CFX_WideString GetText() const; - - void SetFontMap(IPVT_FontMap* pFontMap) { m_pFontMap = pFontMap; } - void SetFontSize(float fFontSize) { m_fFontSize = fFontSize; } - CFX_FloatRect GetPlateRect() const { return m_rcPlate; } - void SetPlateRect(const CFX_FloatRect& rect); - - float GetFontSize() const { return m_fFontSize; } - CFX_Edit* GetItemEdit(int32_t nIndex) const; - int32_t GetCount() const; - bool IsItemSelected(int32_t nIndex) const; - float GetFirstHeight() const; - void SetMultipleSel(bool bMultiple) { m_bMultiple = bMultiple; } - bool IsMultipleSel() const { return m_bMultiple; } - int32_t FindNext(int32_t nIndex, wchar_t nChar) const; - int32_t GetFirstSelected() const; - - private: - class Item { - public: - Item(); - ~Item(); - - void SetFontMap(IPVT_FontMap* pFontMap); - CFX_Edit* GetEdit() const { return m_pEdit.get(); } - - void SetRect(const CFX_FloatRect& rect) { m_rcListItem = rect; } - void SetSelect(bool bSelected) { m_bSelected = bSelected; } - void SetText(const CFX_WideString& text); - void SetFontSize(float fFontSize); - CFX_WideString GetText() const; - - CFX_FloatRect GetRect() const { return m_rcListItem; } - bool IsSelected() const { return m_bSelected; } - float GetItemHeight() const; - uint16_t GetFirstChar() const; - - private: - CFX_Edit_Iterator* GetIterator() const; - - std::unique_ptr m_pEdit; - bool m_bSelected; - CFX_FloatRect m_rcListItem; - }; - - CFX_PointF InToOut(const CFX_PointF& point) const; - CFX_PointF OutToIn(const CFX_PointF& point) const; - CFX_FloatRect InToOut(const CFX_FloatRect& rect) const; - CFX_FloatRect OutToIn(const CFX_FloatRect& rect) const; - - CFX_PointF InnerToOuter(const CFX_PointF& point) const; - CFX_PointF OuterToInner(const CFX_PointF& point) const; - CFX_FloatRect InnerToOuter(const CFX_FloatRect& rect) const; - CFX_FloatRect OuterToInner(const CFX_FloatRect& rect) const; - - void OnVK(int32_t nItemIndex, bool bShift, bool bCtrl); - bool IsValid(int32_t nItemIndex) const; - - void ReArrange(int32_t nItemIndex); - CFX_FloatRect GetItemRectInternal(int32_t nIndex) const; - CFX_FloatRect GetContentRectInternal() const; - void SetMultipleSelect(int32_t nItemIndex, bool bSelected); - void SetSingleSelect(int32_t nItemIndex); - void InvalidateItem(int32_t nItemIndex); - void SelectItems(); - bool IsItemVisible(int32_t nItemIndex) const; - void SetScrollInfo(); - void SetScrollPosY(float fy); - void AddItem(const CFX_WideString& str); - CFX_WideString GetItemText(int32_t nIndex) const; - void SetItemSelect(int32_t nItemIndex, bool bSelected); - int32_t GetLastSelected() const; - CFX_PointF GetBTPoint() const { - return CFX_PointF(m_rcPlate.left, m_rcPlate.top); - } - - CFX_FloatRect m_rcPlate; - CFX_FloatRect m_rcContent; - CFX_UnownedPtr m_pNotify; - bool m_bNotifyFlag; - CFX_PointF m_ptScrollPos; - CPLST_Select m_aSelItems; // for multiple - int32_t m_nSelItem; // for single - int32_t m_nFootIndex; // for multiple - bool m_bCtrlSel; // for multiple - int32_t m_nCaretIndex; // for multiple - std::vector> m_ListItems; - float m_fFontSize; - CFX_UnownedPtr m_pFontMap; - bool m_bMultiple; -}; - -#endif // FPDFSDK_FXEDIT_FXET_LIST_H_ diff --git a/fpdfsdk/pdfwindow/cpwl_appstream.cpp b/fpdfsdk/pdfwindow/cpwl_appstream.cpp index f7ba4c465c..9ac08fa078 100644 --- a/fpdfsdk/pdfwindow/cpwl_appstream.cpp +++ b/fpdfsdk/pdfwindow/cpwl_appstream.cpp @@ -22,8 +22,8 @@ #include "fpdfsdk/cpdfsdk_pageview.h" #include "fpdfsdk/cpdfsdk_widget.h" #include "fpdfsdk/formfiller/cba_fontmap.h" -#include "fpdfsdk/fxedit/fxet_edit.h" #include "fpdfsdk/pdfwindow/cpwl_edit.h" +#include "fpdfsdk/pdfwindow/cpwl_edit_impl.h" #include "fpdfsdk/pdfwindow/cpwl_icon.h" #include "fpdfsdk/pdfwindow/cpwl_wnd.h" @@ -523,11 +523,11 @@ CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) { return CFX_ByteString(); } -CFX_ByteString GetEditAppStream(CFX_Edit* pEdit, +CFX_ByteString GetEditAppStream(CPWL_EditImpl* pEdit, const CFX_PointF& ptOffset, bool bContinuous, uint16_t SubWord) { - CFX_Edit_Iterator* pIterator = pEdit->GetIterator(); + CPWL_EditImpl_Iterator* pIterator = pEdit->GetIterator(); pIterator->SetAt(0); std::ostringstream sEditStream; @@ -686,7 +686,7 @@ CFX_ByteString GetPushButtonAppStream(const CFX_FloatRect& rcBBox, ButtonStyle nLayOut) { const float fAutoFontScale = 1.0f / 3.0f; - auto pEdit = pdfium::MakeUnique(); + auto pEdit = pdfium::MakeUnique(); pEdit->SetFontMap(pFontMap); pEdit->SetAlignmentH(1, true); pEdit->SetAlignmentV(1, true); @@ -1515,7 +1515,7 @@ void CPWL_AppStream::SetAsComboBox(const CFX_WideString* sValue) { rcButton.left = rcButton.right - 13; rcButton.Normalize(); - auto pEdit = pdfium::MakeUnique(); + auto pEdit = pdfium::MakeUnique(); pEdit->EnableRefresh(false); CBA_FontMap font_map( @@ -1578,7 +1578,7 @@ void CPWL_AppStream::SetAsListBox() { CFX_FloatRect rcClient = widget_->GetClientRect(); std::ostringstream sBody; - auto pEdit = pdfium::MakeUnique(); + auto pEdit = pdfium::MakeUnique(); pEdit->EnableRefresh(false); CBA_FontMap font_map( @@ -1658,7 +1658,7 @@ void CPWL_AppStream::SetAsTextField(const CFX_WideString* sValue) { std::ostringstream sBody; std::ostringstream sLines; - auto pEdit = pdfium::MakeUnique(); + auto pEdit = pdfium::MakeUnique(); pEdit->EnableRefresh(false); CBA_FontMap font_map( diff --git a/fpdfsdk/pdfwindow/cpwl_combo_box.cpp b/fpdfsdk/pdfwindow/cpwl_combo_box.cpp index 484027eba2..8de2f1e733 100644 --- a/fpdfsdk/pdfwindow/cpwl_combo_box.cpp +++ b/fpdfsdk/pdfwindow/cpwl_combo_box.cpp @@ -11,10 +11,10 @@ #include "core/fxge/cfx_pathdata.h" #include "core/fxge/cfx_renderdevice.h" -#include "fpdfsdk/fxedit/fxet_list.h" #include "fpdfsdk/pdfwindow/cpwl_edit.h" #include "fpdfsdk/pdfwindow/cpwl_edit_ctrl.h" #include "fpdfsdk/pdfwindow/cpwl_list_box.h" +#include "fpdfsdk/pdfwindow/cpwl_list_impl.h" #include "fpdfsdk/pdfwindow/cpwl_wnd.h" #include "public/fpdf_fwlevent.h" diff --git a/fpdfsdk/pdfwindow/cpwl_edit.cpp b/fpdfsdk/pdfwindow/cpwl_edit.cpp index 89361b5835..8588de73c6 100644 --- a/fpdfsdk/pdfwindow/cpwl_edit.cpp +++ b/fpdfsdk/pdfwindow/cpwl_edit.cpp @@ -20,9 +20,9 @@ #include "core/fxge/cfx_pathdata.h" #include "core/fxge/cfx_renderdevice.h" #include "core/fxge/fx_font.h" -#include "fpdfsdk/fxedit/fxet_edit.h" #include "fpdfsdk/pdfwindow/cpwl_caret.h" #include "fpdfsdk/pdfwindow/cpwl_edit_ctrl.h" +#include "fpdfsdk/pdfwindow/cpwl_edit_impl.h" #include "fpdfsdk/pdfwindow/cpwl_font_map.h" #include "fpdfsdk/pdfwindow/cpwl_scroll_bar.h" #include "fpdfsdk/pdfwindow/cpwl_wnd.h" @@ -281,9 +281,10 @@ void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice, } CFX_SystemHandler* pSysHandler = GetSystemHandler(); - CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pEdit.get(), - GetTextColor().ToFXColor(GetTransparency()), rcClip, - CFX_PointF(), pRange, pSysHandler, m_pFormFiller.Get()); + CPWL_EditImpl::DrawEdit(pDevice, pUser2Device, m_pEdit.get(), + GetTextColor().ToFXColor(GetTransparency()), rcClip, + CFX_PointF(), pRange, pSysHandler, + m_pFormFiller.Get()); } bool CPWL_Edit::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) { @@ -373,7 +374,7 @@ CPVT_WordRange CPWL_Edit::GetSelectWordRange() const { } CFX_PointF CPWL_Edit::GetWordRightBottomPoint(const CPVT_WordPlace& wpWord) { - CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator(); + CPWL_EditImpl_Iterator* pIterator = m_pEdit->GetIterator(); CPVT_WordPlace wpOld = pIterator->GetAt(); pIterator->SetAt(wpWord); @@ -660,7 +661,7 @@ CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace& place, bool bArabic) const { CPVT_WordRange range; - CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator(); + CPWL_EditImpl_Iterator* pIterator = m_pEdit->GetIterator(); CPVT_Word wordinfo; CPVT_WordPlace wpStart(place), wpEnd(place); pIterator->SetAt(place); diff --git a/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp b/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp index 7b90579a5f..c7e1f14499 100644 --- a/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp +++ b/fpdfsdk/pdfwindow/cpwl_edit_ctrl.cpp @@ -9,15 +9,15 @@ #include "core/fpdfdoc/cpvt_section.h" #include "core/fpdfdoc/cpvt_word.h" #include "core/fxge/fx_font.h" -#include "fpdfsdk/fxedit/fxet_edit.h" #include "fpdfsdk/pdfwindow/cpwl_caret.h" +#include "fpdfsdk/pdfwindow/cpwl_edit_impl.h" #include "fpdfsdk/pdfwindow/cpwl_font_map.h" #include "fpdfsdk/pdfwindow/cpwl_scroll_bar.h" #include "fpdfsdk/pdfwindow/cpwl_wnd.h" #include "public/fpdf_fwlevent.h" CPWL_EditCtrl::CPWL_EditCtrl() - : m_pEdit(new CFX_Edit), + : m_pEdit(new CPWL_EditImpl), m_pEditCaret(nullptr), m_bMouseDown(false), m_nCharSet(FX_CHARSET_Default) {} @@ -302,7 +302,7 @@ void CPWL_EditCtrl::SetEditCaret(bool bVisible) { } void CPWL_EditCtrl::GetCaretInfo(CFX_PointF* ptHead, CFX_PointF* ptFoot) const { - CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator(); + CPWL_EditImpl_Iterator* pIterator = m_pEdit->GetIterator(); pIterator->SetAt(m_pEdit->GetCaret()); CPVT_Word word; CPVT_Line line; diff --git a/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h b/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h index fca3bd8fe4..ef6989e637 100644 --- a/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h +++ b/fpdfsdk/pdfwindow/cpwl_edit_ctrl.h @@ -12,7 +12,7 @@ #include "core/fxcrt/fx_string.h" #include "fpdfsdk/pdfwindow/cpwl_wnd.h" -class CFX_Edit; +class CPWL_EditImpl; class CPWL_Caret; struct CPVT_WordPlace; @@ -82,7 +82,7 @@ class CPWL_EditCtrl : public CPWL_Wnd { void SetEditCaret(bool bVisible); - std::unique_ptr m_pEdit; + std::unique_ptr m_pEdit; CPWL_Caret* m_pEditCaret; bool m_bMouseDown; diff --git a/fpdfsdk/pdfwindow/cpwl_edit_impl.cpp b/fpdfsdk/pdfwindow/cpwl_edit_impl.cpp new file mode 100644 index 0000000000..0f5cf05b10 --- /dev/null +++ b/fpdfsdk/pdfwindow/cpwl_edit_impl.cpp @@ -0,0 +1,2053 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "fpdfsdk/pdfwindow/cpwl_edit_impl.h" + +#include +#include +#include +#include + +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/cpdf_pageobjectholder.h" +#include "core/fpdfapi/page/cpdf_pathobject.h" +#include "core/fpdfapi/page/cpdf_textobject.h" +#include "core/fpdfapi/parser/fpdf_parser_decode.h" +#include "core/fpdfapi/render/cpdf_renderoptions.h" +#include "core/fpdfapi/render/cpdf_textrenderer.h" +#include "core/fpdfdoc/cpvt_section.h" +#include "core/fpdfdoc/cpvt_word.h" +#include "core/fpdfdoc/ipvt_fontmap.h" +#include "core/fxcrt/fx_codepage.h" +#include "core/fxge/cfx_graphstatedata.h" +#include "core/fxge/cfx_pathdata.h" +#include "core/fxge/cfx_renderdevice.h" +#include "fpdfsdk/cfx_systemhandler.h" +#include "fpdfsdk/pdfwindow/cpwl_edit.h" +#include "fpdfsdk/pdfwindow/cpwl_edit_ctrl.h" +#include "fpdfsdk/pdfwindow/cpwl_scroll_bar.h" +#include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" + +namespace { + +const int kEditUndoMaxItems = 10000; + +void DrawTextString(CFX_RenderDevice* pDevice, + const CFX_PointF& pt, + CPDF_Font* pFont, + float fFontSize, + CFX_Matrix* pUser2Device, + const CFX_ByteString& str, + FX_ARGB crTextFill, + int32_t nHorzScale) { + CFX_PointF pos = pUser2Device->Transform(pt); + + if (pFont) { + if (nHorzScale != 100) { + CFX_Matrix mt(nHorzScale / 100.0f, 0, 0, 1, 0, 0); + mt.Concat(*pUser2Device); + + CPDF_RenderOptions ro; + ro.m_Flags = RENDER_CLEARTYPE; + ro.m_ColorMode = CPDF_RenderOptions::kNormal; + + CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize, + &mt, str, crTextFill, nullptr, &ro); + } else { + CPDF_RenderOptions ro; + ro.m_Flags = RENDER_CLEARTYPE; + ro.m_ColorMode = CPDF_RenderOptions::kNormal; + + CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize, + pUser2Device, str, crTextFill, nullptr, + &ro); + } + } +} + +} // namespace + +CPWL_EditImpl_Iterator::CPWL_EditImpl_Iterator( + CPWL_EditImpl* pEdit, + CPDF_VariableText::Iterator* pVTIterator) + : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {} + +CPWL_EditImpl_Iterator::~CPWL_EditImpl_Iterator() {} + +bool CPWL_EditImpl_Iterator::NextWord() { + return m_pVTIterator->NextWord(); +} + +bool CPWL_EditImpl_Iterator::PrevWord() { + return m_pVTIterator->PrevWord(); +} + +bool CPWL_EditImpl_Iterator::GetWord(CPVT_Word& word) const { + ASSERT(m_pEdit); + + if (m_pVTIterator->GetWord(word)) { + word.ptWord = m_pEdit->VTToEdit(word.ptWord); + return true; + } + return false; +} + +bool CPWL_EditImpl_Iterator::GetLine(CPVT_Line& line) const { + ASSERT(m_pEdit); + + if (m_pVTIterator->GetLine(line)) { + line.ptLine = m_pEdit->VTToEdit(line.ptLine); + return true; + } + return false; +} + +void CPWL_EditImpl_Iterator::SetAt(int32_t nWordIndex) { + m_pVTIterator->SetAt(nWordIndex); +} + +void CPWL_EditImpl_Iterator::SetAt(const CPVT_WordPlace& place) { + m_pVTIterator->SetAt(place); +} + +const CPVT_WordPlace& CPWL_EditImpl_Iterator::GetAt() const { + return m_pVTIterator->GetAt(); +} + +CPWL_EditImpl_Provider::CPWL_EditImpl_Provider(IPVT_FontMap* pFontMap) + : CPDF_VariableText::Provider(pFontMap), m_pFontMap(pFontMap) { + ASSERT(m_pFontMap); +} + +CPWL_EditImpl_Provider::~CPWL_EditImpl_Provider() {} + +IPVT_FontMap* CPWL_EditImpl_Provider::GetFontMap() const { + return m_pFontMap; +} + +int32_t CPWL_EditImpl_Provider::GetCharWidth(int32_t nFontIndex, + uint16_t word) { + if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) { + uint32_t charcode = word; + + if (pPDFFont->IsUnicodeCompatible()) + charcode = pPDFFont->CharCodeFromUnicode(word); + else + charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word); + + if (charcode != CPDF_Font::kInvalidCharCode) + return pPDFFont->GetCharWidthF(charcode); + } + + return 0; +} + +int32_t CPWL_EditImpl_Provider::GetTypeAscent(int32_t nFontIndex) { + if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) + return pPDFFont->GetTypeAscent(); + + return 0; +} + +int32_t CPWL_EditImpl_Provider::GetTypeDescent(int32_t nFontIndex) { + if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) + return pPDFFont->GetTypeDescent(); + + return 0; +} + +int32_t CPWL_EditImpl_Provider::GetWordFontIndex(uint16_t word, + int32_t charset, + int32_t nFontIndex) { + return m_pFontMap->GetWordFontIndex(word, charset, nFontIndex); +} + +int32_t CPWL_EditImpl_Provider::GetDefaultFontIndex() { + return 0; +} + +bool CPWL_EditImpl_Provider::IsLatinWord(uint16_t word) { + return FX_EDIT_ISLATINWORD(word); +} + +CPWL_EditImpl_Refresh::CPWL_EditImpl_Refresh() {} + +CPWL_EditImpl_Refresh::~CPWL_EditImpl_Refresh() {} + +void CPWL_EditImpl_Refresh::BeginRefresh() { + m_RefreshRects.Clear(); + m_OldLineRects = std::move(m_NewLineRects); +} + +void CPWL_EditImpl_Refresh::Push(const CPVT_WordRange& linerange, + const CFX_FloatRect& rect) { + m_NewLineRects.Add(linerange, rect); +} + +void CPWL_EditImpl_Refresh::NoAnalyse() { + { + for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++) + if (CPWL_EditImpl_LineRect* pOldRect = m_OldLineRects.GetAt(i)) + m_RefreshRects.Add(pOldRect->m_rcLine); + } + + { + for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++) + if (CPWL_EditImpl_LineRect* pNewRect = m_NewLineRects.GetAt(i)) + m_RefreshRects.Add(pNewRect->m_rcLine); + } +} + +const CPWL_EditImpl_RectArray* CPWL_EditImpl_Refresh::GetRefreshRects() const { + return &m_RefreshRects; +} + +void CPWL_EditImpl_Refresh::EndRefresh() { + m_RefreshRects.Clear(); +} + +CPWL_EditImpl_Undo::CPWL_EditImpl_Undo(int32_t nBufsize) + : m_nCurUndoPos(0), m_nBufSize(nBufsize), m_bWorking(false) {} + +CPWL_EditImpl_Undo::~CPWL_EditImpl_Undo() { + Reset(); +} + +bool CPWL_EditImpl_Undo::CanUndo() const { + return m_nCurUndoPos > 0; +} + +void CPWL_EditImpl_Undo::Undo() { + m_bWorking = true; + if (m_nCurUndoPos > 0) { + m_UndoItemStack[m_nCurUndoPos - 1]->Undo(); + m_nCurUndoPos--; + } + m_bWorking = false; +} + +bool CPWL_EditImpl_Undo::CanRedo() const { + return m_nCurUndoPos < m_UndoItemStack.size(); +} + +void CPWL_EditImpl_Undo::Redo() { + m_bWorking = true; + if (m_nCurUndoPos < m_UndoItemStack.size()) { + m_UndoItemStack[m_nCurUndoPos]->Redo(); + m_nCurUndoPos++; + } + m_bWorking = false; +} + +void CPWL_EditImpl_Undo::AddItem(std::unique_ptr pItem) { + ASSERT(!m_bWorking); + ASSERT(pItem); + ASSERT(m_nBufSize > 1); + if (m_nCurUndoPos < m_UndoItemStack.size()) + RemoveTails(); + + if (m_UndoItemStack.size() >= m_nBufSize) + RemoveHeads(); + + m_UndoItemStack.push_back(std::move(pItem)); + m_nCurUndoPos = m_UndoItemStack.size(); +} + +void CPWL_EditImpl_Undo::RemoveHeads() { + ASSERT(m_UndoItemStack.size() > 1); + m_UndoItemStack.pop_front(); +} + +void CPWL_EditImpl_Undo::RemoveTails() { + while (m_UndoItemStack.size() > m_nCurUndoPos) + m_UndoItemStack.pop_back(); +} + +void CPWL_EditImpl_Undo::Reset() { + m_UndoItemStack.clear(); + m_nCurUndoPos = 0; +} + +CPWL_EditImpl_UndoItem::CPWL_EditImpl_UndoItem() + : m_bFirst(true), m_bLast(true) {} + +CPWL_EditImpl_UndoItem::~CPWL_EditImpl_UndoItem() {} + +CFX_WideString CPWL_EditImpl_UndoItem::GetUndoTitle() const { + return CFX_WideString(); +} + +void CPWL_EditImpl_UndoItem::SetFirst(bool bFirst) { + m_bFirst = bFirst; +} + +void CPWL_EditImpl_UndoItem::SetLast(bool bLast) { + m_bLast = bLast; +} + +bool CPWL_EditImpl_UndoItem::IsLast() { + return m_bLast; +} + +CFXEU_InsertWord::CFXEU_InsertWord(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + uint16_t word, + int32_t charset, + const CPVT_WordProps* pWordProps) + : m_pEdit(pEdit), + m_wpOld(wpOldPlace), + m_wpNew(wpNewPlace), + m_Word(word), + m_nCharset(charset), + m_WordProps() { + if (pWordProps) + m_WordProps = *pWordProps; +} + +CFXEU_InsertWord::~CFXEU_InsertWord() {} + +void CFXEU_InsertWord::Redo() { + if (m_pEdit) { + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wpOld); + m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true); + } +} + +void CFXEU_InsertWord::Undo() { + if (m_pEdit) { + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wpNew); + m_pEdit->Backspace(false, true); + } +} + +CFXEU_InsertReturn::CFXEU_InsertReturn(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + const CPVT_SecProps* pSecProps, + const CPVT_WordProps* pWordProps) + : m_pEdit(pEdit), + m_wpOld(wpOldPlace), + m_wpNew(wpNewPlace), + m_SecProps(), + m_WordProps() { + if (pSecProps) + m_SecProps = *pSecProps; + if (pWordProps) + m_WordProps = *pWordProps; +} + +CFXEU_InsertReturn::~CFXEU_InsertReturn() {} + +void CFXEU_InsertReturn::Redo() { + if (m_pEdit) { + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wpOld); + m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true); + } +} + +void CFXEU_InsertReturn::Undo() { + if (m_pEdit) { + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wpNew); + m_pEdit->Backspace(false, true); + } +} + +CFXEU_Backspace::CFXEU_Backspace(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + uint16_t word, + int32_t charset, + const CPVT_SecProps& SecProps, + const CPVT_WordProps& WordProps) + : m_pEdit(pEdit), + m_wpOld(wpOldPlace), + m_wpNew(wpNewPlace), + m_Word(word), + m_nCharset(charset), + m_SecProps(SecProps), + m_WordProps(WordProps) {} + +CFXEU_Backspace::~CFXEU_Backspace() {} + +void CFXEU_Backspace::Redo() { + if (!m_pEdit) + return; + + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wpOld); + m_pEdit->Backspace(false, true); +} + +void CFXEU_Backspace::Undo() { + if (!m_pEdit) + return; + + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wpNew); + if (m_wpNew.nSecIndex != m_wpOld.nSecIndex) + m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true); + else + m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true); +} + +CFXEU_Delete::CFXEU_Delete(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + uint16_t word, + int32_t charset, + const CPVT_SecProps& SecProps, + const CPVT_WordProps& WordProps, + bool bSecEnd) + : m_pEdit(pEdit), + m_wpOld(wpOldPlace), + m_wpNew(wpNewPlace), + m_Word(word), + m_nCharset(charset), + m_SecProps(SecProps), + m_WordProps(WordProps), + m_bSecEnd(bSecEnd) {} + +CFXEU_Delete::~CFXEU_Delete() {} + +void CFXEU_Delete::Redo() { + if (m_pEdit) { + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wpOld); + m_pEdit->Delete(false, true); + } +} + +void CFXEU_Delete::Undo() { + if (m_pEdit) { + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wpNew); + if (m_bSecEnd) { + m_pEdit->InsertReturn(&m_SecProps, &m_WordProps, false, true); + } else { + m_pEdit->InsertWord(m_Word, m_nCharset, &m_WordProps, false, true); + } + } +} + +CFXEU_Clear::CFXEU_Clear(CPWL_EditImpl* pEdit, + const CPVT_WordRange& wrSel, + const CFX_WideString& swText) + : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {} + +CFXEU_Clear::~CFXEU_Clear() {} + +void CFXEU_Clear::Redo() { + if (m_pEdit) { + m_pEdit->SelectNone(); + m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos); + m_pEdit->Clear(false, true); + } +} + +void CFXEU_Clear::Undo() { + if (m_pEdit) { + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wrSel.BeginPos); + m_pEdit->InsertText(m_swText, FX_CHARSET_Default, false, true); + m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos); + } +} + +CFXEU_InsertText::CFXEU_InsertText(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + const CFX_WideString& swText, + int32_t charset) + : m_pEdit(pEdit), + m_wpOld(wpOldPlace), + m_wpNew(wpNewPlace), + m_swText(swText), + m_nCharset(charset) {} + +CFXEU_InsertText::~CFXEU_InsertText() {} + +void CFXEU_InsertText::Redo() { + if (m_pEdit && IsLast()) { + m_pEdit->SelectNone(); + m_pEdit->SetCaret(m_wpOld); + m_pEdit->InsertText(m_swText, m_nCharset, false, true); + } +} + +void CFXEU_InsertText::Undo() { + if (m_pEdit) { + m_pEdit->SelectNone(); + m_pEdit->SetSelection(m_wpOld, m_wpNew); + m_pEdit->Clear(false, true); + } +} + +// static +void CPWL_EditImpl::DrawEdit(CFX_RenderDevice* pDevice, + CFX_Matrix* pUser2Device, + CPWL_EditImpl* pEdit, + FX_COLORREF crTextFill, + const CFX_FloatRect& rcClip, + const CFX_PointF& ptOffset, + const CPVT_WordRange* pRange, + CFX_SystemHandler* pSystemHandler, + CFFL_FormFiller* pFFLData) { + const bool bContinuous = + pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f; + uint16_t SubWord = pEdit->GetPasswordChar(); + float fFontSize = pEdit->GetFontSize(); + CPVT_WordRange wrSelect = pEdit->GetSelectWordRange(); + int32_t nHorzScale = pEdit->GetHorzScale(); + + FX_COLORREF crCurFill = crTextFill; + FX_COLORREF crOldFill = crCurFill; + + bool bSelect = false; + const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255); + const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113); + + std::ostringstream sTextBuf; + int32_t nFontIndex = -1; + CFX_PointF ptBT; + CFX_RenderDevice::StateRestorer restorer(pDevice); + if (!rcClip.IsEmpty()) { + CFX_FloatRect rcTemp = rcClip; + pUser2Device->TransformRect(rcTemp); + pDevice->SetClip_Rect(rcTemp.ToFxRect()); + } + + CPWL_EditImpl_Iterator* pIterator = pEdit->GetIterator(); + if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) { + if (pRange) + pIterator->SetAt(pRange->BeginPos); + else + pIterator->SetAt(0); + + CPVT_WordPlace oldplace; + while (pIterator->NextWord()) { + CPVT_WordPlace place = pIterator->GetAt(); + if (pRange && place > pRange->EndPos) + break; + + if (!wrSelect.IsEmpty()) { + bSelect = place > wrSelect.BeginPos && place <= wrSelect.EndPos; + crCurFill = bSelect ? crWhite : crTextFill; + } + if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) { + crCurFill = crTextFill; + crOldFill = crCurFill; + } + CPVT_Word word; + if (pIterator->GetWord(word)) { + if (bSelect) { + CPVT_Line line; + pIterator->GetLine(line); + + if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) { + CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent, + word.ptWord.x + word.fWidth, + line.ptLine.y + line.fLineAscent); + rc.Intersect(rcClip); + pSystemHandler->OutputSelectedRect(pFFLData, rc); + } else { + CFX_PathData pathSelBK; + pathSelBK.AppendRect( + word.ptWord.x, line.ptLine.y + line.fLineDescent, + word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent); + + pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0, + FXFILL_WINDING); + } + } + + if (bContinuous) { + if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex || + crOldFill != crCurFill) { + if (sTextBuf.tellp() > 0) { + DrawTextString( + pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), + pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device, + CFX_ByteString(sTextBuf), crOldFill, nHorzScale); + + sTextBuf.str(""); + } + nFontIndex = word.nFontIndex; + ptBT = word.ptWord; + crOldFill = crCurFill; + } + + sTextBuf << pEdit->GetPDFWordString(word.nFontIndex, word.Word, + SubWord); + } else { + DrawTextString( + pDevice, + CFX_PointF(word.ptWord.x + ptOffset.x, + word.ptWord.y + ptOffset.y), + pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device, + pEdit->GetPDFWordString(word.nFontIndex, word.Word, SubWord), + crCurFill, nHorzScale); + } + oldplace = place; + } + } + + if (sTextBuf.tellp() > 0) { + DrawTextString(pDevice, + CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), + pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device, + CFX_ByteString(sTextBuf), crOldFill, nHorzScale); + } + } +} + +CPWL_EditImpl::CPWL_EditImpl() + : m_pVT(new CPDF_VariableText), + m_pNotify(nullptr), + m_pOprNotify(nullptr), + m_wpCaret(-1, -1, -1), + m_wpOldCaret(-1, -1, -1), + m_SelState(), + m_bEnableScroll(false), + m_Undo(kEditUndoMaxItems), + m_nAlignment(0), + m_bNotifyFlag(false), + m_bEnableOverflow(false), + m_bEnableRefresh(true), + m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f), + m_bEnableUndo(true), + m_bOprNotify(false) {} + +CPWL_EditImpl::~CPWL_EditImpl() {} + +void CPWL_EditImpl::Initialize() { + m_pVT->Initialize(); + SetCaret(m_pVT->GetBeginWordPlace()); + SetCaretOrigin(); +} + +void CPWL_EditImpl::SetFontMap(IPVT_FontMap* pFontMap) { + m_pVTProvider = pdfium::MakeUnique(pFontMap); + m_pVT->SetProvider(m_pVTProvider.get()); +} + +void CPWL_EditImpl::SetNotify(CPWL_EditCtrl* pNotify) { + m_pNotify = pNotify; +} + +void CPWL_EditImpl::SetOprNotify(CPWL_Edit* pOprNotify) { + m_pOprNotify = pOprNotify; +} + +CPWL_EditImpl_Iterator* CPWL_EditImpl::GetIterator() { + if (!m_pIterator) { + m_pIterator = + pdfium::MakeUnique(this, m_pVT->GetIterator()); + } + return m_pIterator.get(); +} + +IPVT_FontMap* CPWL_EditImpl::GetFontMap() { + return m_pVTProvider ? m_pVTProvider->GetFontMap() : nullptr; +} + +void CPWL_EditImpl::SetPlateRect(const CFX_FloatRect& rect) { + m_pVT->SetPlateRect(rect); + m_ptScrollPos = CFX_PointF(rect.left, rect.top); + Paint(); +} + +void CPWL_EditImpl::SetAlignmentH(int32_t nFormat, bool bPaint) { + m_pVT->SetAlignment(nFormat); + if (bPaint) + Paint(); +} + +void CPWL_EditImpl::SetAlignmentV(int32_t nFormat, bool bPaint) { + m_nAlignment = nFormat; + if (bPaint) + Paint(); +} + +void CPWL_EditImpl::SetPasswordChar(uint16_t wSubWord, bool bPaint) { + m_pVT->SetPasswordChar(wSubWord); + if (bPaint) + Paint(); +} + +void CPWL_EditImpl::SetLimitChar(int32_t nLimitChar) { + m_pVT->SetLimitChar(nLimitChar); + Paint(); +} + +void CPWL_EditImpl::SetCharArray(int32_t nCharArray) { + m_pVT->SetCharArray(nCharArray); + Paint(); +} + +void CPWL_EditImpl::SetCharSpace(float fCharSpace) { + m_pVT->SetCharSpace(fCharSpace); + Paint(); +} + +void CPWL_EditImpl::SetMultiLine(bool bMultiLine, bool bPaint) { + m_pVT->SetMultiLine(bMultiLine); + if (bPaint) + Paint(); +} + +void CPWL_EditImpl::SetAutoReturn(bool bAuto, bool bPaint) { + m_pVT->SetAutoReturn(bAuto); + if (bPaint) + Paint(); +} + +void CPWL_EditImpl::SetAutoFontSize(bool bAuto, bool bPaint) { + m_pVT->SetAutoFontSize(bAuto); + if (bPaint) + Paint(); +} + +void CPWL_EditImpl::SetFontSize(float fFontSize) { + m_pVT->SetFontSize(fFontSize); + Paint(); +} + +void CPWL_EditImpl::SetAutoScroll(bool bAuto, bool bPaint) { + m_bEnableScroll = bAuto; + if (bPaint) + Paint(); +} + +void CPWL_EditImpl::SetTextOverflow(bool bAllowed, bool bPaint) { + m_bEnableOverflow = bAllowed; + if (bPaint) + Paint(); +} + +void CPWL_EditImpl::SetSelection(int32_t nStartChar, int32_t nEndChar) { + if (m_pVT->IsValid()) { + if (nStartChar == 0 && nEndChar < 0) { + SelectAll(); + } else if (nStartChar < 0) { + SelectNone(); + } else { + if (nStartChar < nEndChar) { + SetSelection(m_pVT->WordIndexToWordPlace(nStartChar), + m_pVT->WordIndexToWordPlace(nEndChar)); + } else { + SetSelection(m_pVT->WordIndexToWordPlace(nEndChar), + m_pVT->WordIndexToWordPlace(nStartChar)); + } + } + } +} + +void CPWL_EditImpl::SetSelection(const CPVT_WordPlace& begin, + const CPVT_WordPlace& end) { + if (!m_pVT->IsValid()) + return; + + SelectNone(); + m_SelState.Set(begin, end); + SetCaret(m_SelState.EndPos); + ScrollToCaret(); + if (!m_SelState.IsEmpty()) + Refresh(); + SetCaretInfo(); +} + +void CPWL_EditImpl::GetSelection(int32_t& nStartChar, int32_t& nEndChar) const { + nStartChar = -1; + nEndChar = -1; + if (!m_pVT->IsValid()) + return; + + if (m_SelState.IsEmpty()) { + nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret); + nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret); + return; + } + if (m_SelState.BeginPos < m_SelState.EndPos) { + nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos); + nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos); + return; + } + nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos); + nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos); +} + +int32_t CPWL_EditImpl::GetCaret() const { + if (m_pVT->IsValid()) + return m_pVT->WordPlaceToWordIndex(m_wpCaret); + + return -1; +} + +CPVT_WordPlace CPWL_EditImpl::GetCaretWordPlace() const { + return m_wpCaret; +} + +CFX_WideString CPWL_EditImpl::GetText() const { + CFX_WideString swRet; + if (!m_pVT->IsValid()) + return swRet; + + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + pIterator->SetAt(0); + + CPVT_Word wordinfo; + CPVT_WordPlace oldplace = pIterator->GetAt(); + while (pIterator->NextWord()) { + CPVT_WordPlace place = pIterator->GetAt(); + if (pIterator->GetWord(wordinfo)) + swRet += wordinfo.Word; + if (oldplace.nSecIndex != place.nSecIndex) + swRet += L"\r\n"; + oldplace = place; + } + return swRet; +} + +CFX_WideString CPWL_EditImpl::GetRangeText(const CPVT_WordRange& range) const { + CFX_WideString swRet; + if (!m_pVT->IsValid()) + return swRet; + + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + CPVT_WordRange wrTemp = range; + m_pVT->UpdateWordPlace(wrTemp.BeginPos); + m_pVT->UpdateWordPlace(wrTemp.EndPos); + pIterator->SetAt(wrTemp.BeginPos); + + CPVT_Word wordinfo; + CPVT_WordPlace oldplace = wrTemp.BeginPos; + while (pIterator->NextWord()) { + CPVT_WordPlace place = pIterator->GetAt(); + if (place > wrTemp.EndPos) + break; + if (pIterator->GetWord(wordinfo)) + swRet += wordinfo.Word; + if (oldplace.nSecIndex != place.nSecIndex) + swRet += L"\r\n"; + oldplace = place; + } + return swRet; +} + +CFX_WideString CPWL_EditImpl::GetSelectedText() const { + return GetRangeText(m_SelState.ConvertToWordRange()); +} + +int32_t CPWL_EditImpl::GetTotalLines() const { + int32_t nLines = 1; + + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + pIterator->SetAt(0); + while (pIterator->NextLine()) + ++nLines; + + return nLines; +} + +CPVT_WordRange CPWL_EditImpl::GetSelectWordRange() const { + return m_SelState.ConvertToWordRange(); +} + +void CPWL_EditImpl::SetText(const CFX_WideString& sText) { + Empty(); + DoInsertText(CPVT_WordPlace(0, 0, -1), sText, FX_CHARSET_Default); + Paint(); +} + +bool CPWL_EditImpl::InsertWord(uint16_t word, int32_t charset) { + return InsertWord(word, charset, nullptr, true, true); +} + +bool CPWL_EditImpl::InsertReturn() { + return InsertReturn(nullptr, nullptr, true, true); +} + +bool CPWL_EditImpl::Backspace() { + return Backspace(true, true); +} + +bool CPWL_EditImpl::Delete() { + return Delete(true, true); +} + +bool CPWL_EditImpl::ClearSelection() { + return Clear(true, true); +} + +bool CPWL_EditImpl::InsertText(const CFX_WideString& sText, int32_t charset) { + return InsertText(sText, charset, true, true); +} + +float CPWL_EditImpl::GetFontSize() const { + return m_pVT->GetFontSize(); +} + +uint16_t CPWL_EditImpl::GetPasswordChar() const { + return m_pVT->GetPasswordChar(); +} + +int32_t CPWL_EditImpl::GetCharArray() const { + return m_pVT->GetCharArray(); +} + +CFX_FloatRect CPWL_EditImpl::GetContentRect() const { + return VTToEdit(m_pVT->GetContentRect()); +} + +int32_t CPWL_EditImpl::GetHorzScale() const { + return m_pVT->GetHorzScale(); +} + +float CPWL_EditImpl::GetCharSpace() const { + return m_pVT->GetCharSpace(); +} + +CPVT_WordRange CPWL_EditImpl::GetWholeWordRange() const { + if (m_pVT->IsValid()) + return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace()); + + return CPVT_WordRange(); +} + +CPVT_WordRange CPWL_EditImpl::GetVisibleWordRange() const { + if (m_bEnableOverflow) + return GetWholeWordRange(); + + if (m_pVT->IsValid()) { + CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); + + CPVT_WordPlace place1 = + m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top))); + CPVT_WordPlace place2 = m_pVT->SearchWordPlace( + EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom))); + + return CPVT_WordRange(place1, place2); + } + + return CPVT_WordRange(); +} + +CPVT_WordPlace CPWL_EditImpl::SearchWordPlace(const CFX_PointF& point) const { + if (m_pVT->IsValid()) { + return m_pVT->SearchWordPlace(EditToVT(point)); + } + + return CPVT_WordPlace(); +} + +void CPWL_EditImpl::Paint() { + if (m_pVT->IsValid()) { + RearrangeAll(); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); + } +} + +void CPWL_EditImpl::RearrangeAll() { + if (m_pVT->IsValid()) { + m_pVT->UpdateWordPlace(m_wpCaret); + m_pVT->RearrangeAll(); + m_pVT->UpdateWordPlace(m_wpCaret); + SetScrollInfo(); + SetContentChanged(); + } +} + +void CPWL_EditImpl::RearrangePart(const CPVT_WordRange& range) { + if (m_pVT->IsValid()) { + m_pVT->UpdateWordPlace(m_wpCaret); + m_pVT->RearrangePart(range); + m_pVT->UpdateWordPlace(m_wpCaret); + SetScrollInfo(); + SetContentChanged(); + } +} + +void CPWL_EditImpl::SetContentChanged() { + if (m_pNotify) { + CFX_FloatRect rcContent = m_pVT->GetContentRect(); + if (rcContent.Width() != m_rcOldContent.Width() || + rcContent.Height() != m_rcOldContent.Height()) { + m_rcOldContent = rcContent; + } + } +} + +void CPWL_EditImpl::SelectAll() { + if (!m_pVT->IsValid()) + return; + m_SelState = CPWL_EditImpl_Select(GetWholeWordRange()); + SetCaret(m_SelState.EndPos); + ScrollToCaret(); + Refresh(); + SetCaretInfo(); +} + +void CPWL_EditImpl::SelectNone() { + if (!m_pVT->IsValid() || m_SelState.IsEmpty()) + return; + + m_SelState.Reset(); + Refresh(); +} + +bool CPWL_EditImpl::IsSelected() const { + return !m_SelState.IsEmpty(); +} + +CFX_PointF CPWL_EditImpl::VTToEdit(const CFX_PointF& point) const { + CFX_FloatRect rcContent = m_pVT->GetContentRect(); + CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); + + float fPadding = 0.0f; + + switch (m_nAlignment) { + case 0: + fPadding = 0.0f; + break; + case 1: + fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f; + break; + case 2: + fPadding = rcPlate.Height() - rcContent.Height(); + break; + } + + return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left), + point.y - (m_ptScrollPos.y + fPadding - rcPlate.top)); +} + +CFX_PointF CPWL_EditImpl::EditToVT(const CFX_PointF& point) const { + CFX_FloatRect rcContent = m_pVT->GetContentRect(); + CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); + + float fPadding = 0.0f; + + switch (m_nAlignment) { + case 0: + fPadding = 0.0f; + break; + case 1: + fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f; + break; + case 2: + fPadding = rcPlate.Height() - rcContent.Height(); + break; + } + + return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left), + point.y + (m_ptScrollPos.y + fPadding - rcPlate.top)); +} + +CFX_FloatRect CPWL_EditImpl::VTToEdit(const CFX_FloatRect& rect) const { + CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom)); + CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top)); + + return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, + ptRightTop.y); +} + +void CPWL_EditImpl::SetScrollInfo() { + if (!m_pNotify) + return; + + CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); + CFX_FloatRect rcContent = m_pVT->GetContentRect(); + if (m_bNotifyFlag) + return; + + CFX_AutoRestorer restorer(&m_bNotifyFlag); + m_bNotifyFlag = true; + + PWL_SCROLL_INFO Info; + Info.fPlateWidth = rcPlate.top - rcPlate.bottom; + Info.fContentMin = rcContent.bottom; + Info.fContentMax = rcContent.top; + Info.fSmallStep = rcPlate.Height() / 3; + Info.fBigStep = rcPlate.Height(); + m_pNotify->SetScrollInfo(Info); +} + +void CPWL_EditImpl::SetScrollPosX(float fx) { + if (!m_bEnableScroll) + return; + + if (m_pVT->IsValid()) { + if (!IsFloatEqual(m_ptScrollPos.x, fx)) { + m_ptScrollPos.x = fx; + Refresh(); + } + } +} + +void CPWL_EditImpl::SetScrollPosY(float fy) { + if (!m_bEnableScroll) + return; + + if (m_pVT->IsValid()) { + if (!IsFloatEqual(m_ptScrollPos.y, fy)) { + m_ptScrollPos.y = fy; + Refresh(); + + if (m_pNotify) { + if (!m_bNotifyFlag) { + CFX_AutoRestorer restorer(&m_bNotifyFlag); + m_bNotifyFlag = true; + m_pNotify->SetScrollPosition(fy); + } + } + } + } +} + +void CPWL_EditImpl::SetScrollPos(const CFX_PointF& point) { + SetScrollPosX(point.x); + SetScrollPosY(point.y); + SetScrollLimit(); + SetCaretInfo(); +} + +CFX_PointF CPWL_EditImpl::GetScrollPos() const { + return m_ptScrollPos; +} + +void CPWL_EditImpl::SetScrollLimit() { + if (m_pVT->IsValid()) { + CFX_FloatRect rcContent = m_pVT->GetContentRect(); + CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); + + if (rcPlate.Width() > rcContent.Width()) { + SetScrollPosX(rcPlate.left); + } else { + if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) { + SetScrollPosX(rcContent.left); + } else if (IsFloatBigger(m_ptScrollPos.x, + rcContent.right - rcPlate.Width())) { + SetScrollPosX(rcContent.right - rcPlate.Width()); + } + } + + if (rcPlate.Height() > rcContent.Height()) { + SetScrollPosY(rcPlate.top); + } else { + if (IsFloatSmaller(m_ptScrollPos.y, + rcContent.bottom + rcPlate.Height())) { + SetScrollPosY(rcContent.bottom + rcPlate.Height()); + } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) { + SetScrollPosY(rcContent.top); + } + } + } +} + +void CPWL_EditImpl::ScrollToCaret() { + SetScrollLimit(); + + if (!m_pVT->IsValid()) + return; + + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + pIterator->SetAt(m_wpCaret); + + CFX_PointF ptHead; + CFX_PointF ptFoot; + CPVT_Word word; + CPVT_Line line; + if (pIterator->GetWord(word)) { + ptHead.x = word.ptWord.x + word.fWidth; + ptHead.y = word.ptWord.y + word.fAscent; + ptFoot.x = word.ptWord.x + word.fWidth; + ptFoot.y = word.ptWord.y + word.fDescent; + } else if (pIterator->GetLine(line)) { + ptHead.x = line.ptLine.x; + ptHead.y = line.ptLine.y + line.fLineAscent; + ptFoot.x = line.ptLine.x; + ptFoot.y = line.ptLine.y + line.fLineDescent; + } + + CFX_PointF ptHeadEdit = VTToEdit(ptHead); + CFX_PointF ptFootEdit = VTToEdit(ptFoot); + CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); + if (!IsFloatEqual(rcPlate.left, rcPlate.right)) { + if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) || + IsFloatEqual(ptHeadEdit.x, rcPlate.left)) { + SetScrollPosX(ptHead.x); + } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) { + SetScrollPosX(ptHead.x - rcPlate.Width()); + } + } + + if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) { + if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) || + IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) { + if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) { + SetScrollPosY(ptFoot.y + rcPlate.Height()); + } + } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) { + if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) { + SetScrollPosY(ptHead.y); + } + } + } +} + +void CPWL_EditImpl::Refresh() { + if (m_bEnableRefresh && m_pVT->IsValid()) { + m_Refresh.BeginRefresh(); + RefreshPushLineRects(GetVisibleWordRange()); + + m_Refresh.NoAnalyse(); + m_ptRefreshScrollPos = m_ptScrollPos; + + if (m_pNotify) { + if (!m_bNotifyFlag) { + CFX_AutoRestorer restorer(&m_bNotifyFlag); + m_bNotifyFlag = true; + if (const CPWL_EditImpl_RectArray* pRects = + m_Refresh.GetRefreshRects()) { + for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++) + m_pNotify->InvalidateRect(pRects->GetAt(i)); + } + } + } + + m_Refresh.EndRefresh(); + } +} + +void CPWL_EditImpl::RefreshPushLineRects(const CPVT_WordRange& wr) { + if (!m_pVT->IsValid()) + return; + + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + CPVT_WordPlace wpBegin = wr.BeginPos; + m_pVT->UpdateWordPlace(wpBegin); + CPVT_WordPlace wpEnd = wr.EndPos; + m_pVT->UpdateWordPlace(wpEnd); + pIterator->SetAt(wpBegin); + + CPVT_Line lineinfo; + do { + if (!pIterator->GetLine(lineinfo)) + break; + if (lineinfo.lineplace.LineCmp(wpEnd) > 0) + break; + + CFX_FloatRect rcLine(lineinfo.ptLine.x, + lineinfo.ptLine.y + lineinfo.fLineDescent, + lineinfo.ptLine.x + lineinfo.fLineWidth, + lineinfo.ptLine.y + lineinfo.fLineAscent); + + m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd), + VTToEdit(rcLine)); + } while (pIterator->NextLine()); +} + +void CPWL_EditImpl::RefreshWordRange(const CPVT_WordRange& wr) { + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + CPVT_WordRange wrTemp = wr; + + m_pVT->UpdateWordPlace(wrTemp.BeginPos); + m_pVT->UpdateWordPlace(wrTemp.EndPos); + pIterator->SetAt(wrTemp.BeginPos); + + CPVT_Word wordinfo; + CPVT_Line lineinfo; + CPVT_WordPlace place; + + while (pIterator->NextWord()) { + place = pIterator->GetAt(); + if (place > wrTemp.EndPos) + break; + + pIterator->GetWord(wordinfo); + pIterator->GetLine(lineinfo); + if (place.LineCmp(wrTemp.BeginPos) == 0 || + place.LineCmp(wrTemp.EndPos) == 0) { + CFX_FloatRect rcWord(wordinfo.ptWord.x, + lineinfo.ptLine.y + lineinfo.fLineDescent, + wordinfo.ptWord.x + wordinfo.fWidth, + lineinfo.ptLine.y + lineinfo.fLineAscent); + + if (m_pNotify) { + if (!m_bNotifyFlag) { + CFX_AutoRestorer restorer(&m_bNotifyFlag); + m_bNotifyFlag = true; + CFX_FloatRect rcRefresh = VTToEdit(rcWord); + m_pNotify->InvalidateRect(&rcRefresh); + } + } + } else { + CFX_FloatRect rcLine(lineinfo.ptLine.x, + lineinfo.ptLine.y + lineinfo.fLineDescent, + lineinfo.ptLine.x + lineinfo.fLineWidth, + lineinfo.ptLine.y + lineinfo.fLineAscent); + + if (m_pNotify) { + if (!m_bNotifyFlag) { + CFX_AutoRestorer restorer(&m_bNotifyFlag); + m_bNotifyFlag = true; + CFX_FloatRect rcRefresh = VTToEdit(rcLine); + m_pNotify->InvalidateRect(&rcRefresh); + } + } + + pIterator->NextLine(); + } + } +} + +void CPWL_EditImpl::SetCaret(const CPVT_WordPlace& place) { + m_wpOldCaret = m_wpCaret; + m_wpCaret = place; +} + +void CPWL_EditImpl::SetCaretInfo() { + if (m_pNotify) { + if (!m_bNotifyFlag) { + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + pIterator->SetAt(m_wpCaret); + + CFX_PointF ptHead; + CFX_PointF ptFoot; + CPVT_Word word; + CPVT_Line line; + if (pIterator->GetWord(word)) { + ptHead.x = word.ptWord.x + word.fWidth; + ptHead.y = word.ptWord.y + word.fAscent; + ptFoot.x = word.ptWord.x + word.fWidth; + ptFoot.y = word.ptWord.y + word.fDescent; + } else if (pIterator->GetLine(line)) { + ptHead.x = line.ptLine.x; + ptHead.y = line.ptLine.y + line.fLineAscent; + ptFoot.x = line.ptLine.x; + ptFoot.y = line.ptLine.y + line.fLineDescent; + } + + CFX_AutoRestorer restorer(&m_bNotifyFlag); + m_bNotifyFlag = true; + m_pNotify->SetCaret(m_SelState.IsEmpty(), VTToEdit(ptHead), + VTToEdit(ptFoot)); + } + } +} + +void CPWL_EditImpl::OnMouseDown(const CFX_PointF& point, + bool bShift, + bool bCtrl) { + if (!m_pVT->IsValid()) + return; + + SelectNone(); + SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); + m_SelState.Set(m_wpCaret, m_wpCaret); + ScrollToCaret(); + SetCaretOrigin(); + SetCaretInfo(); +} + +void CPWL_EditImpl::OnMouseMove(const CFX_PointF& point, + bool bShift, + bool bCtrl) { + if (!m_pVT->IsValid()) + return; + + SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); + if (m_wpCaret == m_wpOldCaret) + return; + + m_SelState.SetEndPos(m_wpCaret); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); +} + +void CPWL_EditImpl::OnVK_UP(bool bShift, bool bCtrl) { + if (!m_pVT->IsValid()) + return; + + SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret)); + if (bShift) { + if (m_SelState.IsEmpty()) + m_SelState.Set(m_wpOldCaret, m_wpCaret); + else + m_SelState.SetEndPos(m_wpCaret); + + if (m_wpOldCaret != m_wpCaret) { + ScrollToCaret(); + Refresh(); + SetCaretInfo(); + } + } else { + SelectNone(); + ScrollToCaret(); + SetCaretInfo(); + } +} + +void CPWL_EditImpl::OnVK_DOWN(bool bShift, bool bCtrl) { + if (!m_pVT->IsValid()) + return; + + SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret)); + if (bShift) { + if (m_SelState.IsEmpty()) + m_SelState.Set(m_wpOldCaret, m_wpCaret); + else + m_SelState.SetEndPos(m_wpCaret); + + if (m_wpOldCaret != m_wpCaret) { + ScrollToCaret(); + Refresh(); + SetCaretInfo(); + } + } else { + SelectNone(); + ScrollToCaret(); + SetCaretInfo(); + } +} + +void CPWL_EditImpl::OnVK_LEFT(bool bShift, bool bCtrl) { + if (!m_pVT->IsValid()) + return; + + if (bShift) { + if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) && + m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) { + SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret)); + } + SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret)); + if (m_SelState.IsEmpty()) + m_SelState.Set(m_wpOldCaret, m_wpCaret); + else + m_SelState.SetEndPos(m_wpCaret); + + if (m_wpOldCaret != m_wpCaret) { + ScrollToCaret(); + Refresh(); + SetCaretInfo(); + } + } else { + if (!m_SelState.IsEmpty()) { + if (m_SelState.BeginPos < m_SelState.EndPos) + SetCaret(m_SelState.BeginPos); + else + SetCaret(m_SelState.EndPos); + + SelectNone(); + ScrollToCaret(); + SetCaretInfo(); + } else { + if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) && + m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret)) { + SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret)); + } + SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret)); + ScrollToCaret(); + SetCaretOrigin(); + SetCaretInfo(); + } + } +} + +void CPWL_EditImpl::OnVK_RIGHT(bool bShift, bool bCtrl) { + if (!m_pVT->IsValid()) + return; + + if (bShift) { + SetCaret(m_pVT->GetNextWordPlace(m_wpCaret)); + if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) && + m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) + SetCaret(m_pVT->GetNextWordPlace(m_wpCaret)); + + if (m_SelState.IsEmpty()) + m_SelState.Set(m_wpOldCaret, m_wpCaret); + else + m_SelState.SetEndPos(m_wpCaret); + + if (m_wpOldCaret != m_wpCaret) { + ScrollToCaret(); + Refresh(); + SetCaretInfo(); + } + } else { + if (!m_SelState.IsEmpty()) { + if (m_SelState.BeginPos > m_SelState.EndPos) + SetCaret(m_SelState.BeginPos); + else + SetCaret(m_SelState.EndPos); + + SelectNone(); + ScrollToCaret(); + SetCaretInfo(); + } else { + SetCaret(m_pVT->GetNextWordPlace(m_wpCaret)); + if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) && + m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret)) { + SetCaret(m_pVT->GetNextWordPlace(m_wpCaret)); + } + ScrollToCaret(); + SetCaretOrigin(); + SetCaretInfo(); + } + } +} + +void CPWL_EditImpl::OnVK_HOME(bool bShift, bool bCtrl) { + if (!m_pVT->IsValid()) + return; + + if (bShift) { + if (bCtrl) + SetCaret(m_pVT->GetBeginWordPlace()); + else + SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret)); + + if (m_SelState.IsEmpty()) + m_SelState.Set(m_wpOldCaret, m_wpCaret); + else + m_SelState.SetEndPos(m_wpCaret); + + ScrollToCaret(); + Refresh(); + SetCaretInfo(); + } else { + if (!m_SelState.IsEmpty()) { + SetCaret(std::min(m_SelState.BeginPos, m_SelState.EndPos)); + SelectNone(); + ScrollToCaret(); + SetCaretInfo(); + } else { + if (bCtrl) + SetCaret(m_pVT->GetBeginWordPlace()); + else + SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret)); + + ScrollToCaret(); + SetCaretOrigin(); + SetCaretInfo(); + } + } +} + +void CPWL_EditImpl::OnVK_END(bool bShift, bool bCtrl) { + if (!m_pVT->IsValid()) + return; + + if (bShift) { + if (bCtrl) + SetCaret(m_pVT->GetEndWordPlace()); + else + SetCaret(m_pVT->GetLineEndPlace(m_wpCaret)); + + if (m_SelState.IsEmpty()) + m_SelState.Set(m_wpOldCaret, m_wpCaret); + else + m_SelState.SetEndPos(m_wpCaret); + + ScrollToCaret(); + Refresh(); + SetCaretInfo(); + } else { + if (!m_SelState.IsEmpty()) { + SetCaret(std::max(m_SelState.BeginPos, m_SelState.EndPos)); + SelectNone(); + ScrollToCaret(); + SetCaretInfo(); + } else { + if (bCtrl) + SetCaret(m_pVT->GetEndWordPlace()); + else + SetCaret(m_pVT->GetLineEndPlace(m_wpCaret)); + + ScrollToCaret(); + SetCaretOrigin(); + SetCaretInfo(); + } + } +} + +bool CPWL_EditImpl::InsertWord(uint16_t word, + int32_t charset, + const CPVT_WordProps* pWordProps, + bool bAddUndo, + bool bPaint) { + if (IsTextOverflow() || !m_pVT->IsValid()) + return false; + + m_pVT->UpdateWordPlace(m_wpCaret); + SetCaret(m_pVT->InsertWord(m_wpCaret, word, + GetCharSetFromUnicode(word, charset), pWordProps)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (m_wpCaret == m_wpOldCaret) + return false; + + if (bAddUndo && m_bEnableUndo) { + AddEditUndoItem(pdfium::MakeUnique( + this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps)); + } + if (bPaint) + PaintInsertText(m_wpOldCaret, m_wpCaret); + + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret); + + return true; +} + +bool CPWL_EditImpl::InsertReturn(const CPVT_SecProps* pSecProps, + const CPVT_WordProps* pWordProps, + bool bAddUndo, + bool bPaint) { + if (IsTextOverflow() || !m_pVT->IsValid()) + return false; + + m_pVT->UpdateWordPlace(m_wpCaret); + SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (m_wpCaret == m_wpOldCaret) + return false; + + if (bAddUndo && m_bEnableUndo) { + AddEditUndoItem(pdfium::MakeUnique( + this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps)); + } + if (bPaint) { + RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret)); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); + } + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret); + + return true; +} + +bool CPWL_EditImpl::Backspace(bool bAddUndo, bool bPaint) { + if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace()) + return false; + + CPVT_Section section; + CPVT_Word word; + if (bAddUndo) { + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + pIterator->SetAt(m_wpCaret); + pIterator->GetSection(section); + pIterator->GetWord(word); + } + m_pVT->UpdateWordPlace(m_wpCaret); + SetCaret(m_pVT->BackSpaceWord(m_wpCaret)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (m_wpCaret == m_wpOldCaret) + return false; + + if (bAddUndo && m_bEnableUndo) { + if (m_wpCaret.nSecIndex != m_wpOldCaret.nSecIndex) { + AddEditUndoItem(pdfium::MakeUnique( + this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, + section.SecProps, section.WordProps)); + } else { + AddEditUndoItem(pdfium::MakeUnique( + this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, + section.SecProps, word.WordProps)); + } + } + if (bPaint) { + RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret)); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); + } + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret); + + return true; +} + +bool CPWL_EditImpl::Delete(bool bAddUndo, bool bPaint) { + if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace()) + return false; + + CPVT_Section section; + CPVT_Word word; + if (bAddUndo) { + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret)); + pIterator->GetSection(section); + pIterator->GetWord(word); + } + m_pVT->UpdateWordPlace(m_wpCaret); + bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret)); + SetCaret(m_pVT->DeleteWord(m_wpCaret)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (bAddUndo && m_bEnableUndo) { + if (bSecEnd) { + AddEditUndoItem(pdfium::MakeUnique( + this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, + section.SecProps, section.WordProps, bSecEnd)); + } else { + AddEditUndoItem(pdfium::MakeUnique( + this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, + section.SecProps, word.WordProps, bSecEnd)); + } + } + if (bPaint) { + RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret)); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); + } + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret); + + return true; +} + +bool CPWL_EditImpl::Empty() { + if (m_pVT->IsValid()) { + m_pVT->DeleteWords(GetWholeWordRange()); + SetCaret(m_pVT->GetBeginWordPlace()); + + return true; + } + + return false; +} + +bool CPWL_EditImpl::Clear(bool bAddUndo, bool bPaint) { + if (!m_pVT->IsValid() || m_SelState.IsEmpty()) + return false; + + CPVT_WordRange range = m_SelState.ConvertToWordRange(); + if (bAddUndo && m_bEnableUndo) { + AddEditUndoItem( + pdfium::MakeUnique(this, range, GetSelectedText())); + } + + SelectNone(); + SetCaret(m_pVT->DeleteWords(range)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (bPaint) { + RearrangePart(range); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); + } + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret); + + return true; +} + +bool CPWL_EditImpl::InsertText(const CFX_WideString& sText, + int32_t charset, + bool bAddUndo, + bool bPaint) { + if (IsTextOverflow()) + return false; + + m_pVT->UpdateWordPlace(m_wpCaret); + SetCaret(DoInsertText(m_wpCaret, sText, charset)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (m_wpCaret == m_wpOldCaret) + return false; + + if (bAddUndo && m_bEnableUndo) { + AddEditUndoItem(pdfium::MakeUnique( + this, m_wpOldCaret, m_wpCaret, sText, charset)); + } + if (bPaint) + PaintInsertText(m_wpOldCaret, m_wpCaret); + + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret); + + return true; +} + +void CPWL_EditImpl::PaintInsertText(const CPVT_WordPlace& wpOld, + const CPVT_WordPlace& wpNew) { + if (m_pVT->IsValid()) { + RearrangePart(CPVT_WordRange(wpOld, wpNew)); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); + } +} + +bool CPWL_EditImpl::Redo() { + if (m_bEnableUndo) { + if (m_Undo.CanRedo()) { + m_Undo.Redo(); + return true; + } + } + + return false; +} + +bool CPWL_EditImpl::Undo() { + if (m_bEnableUndo) { + if (m_Undo.CanUndo()) { + m_Undo.Undo(); + return true; + } + } + + return false; +} + +void CPWL_EditImpl::SetCaretOrigin() { + if (!m_pVT->IsValid()) + return; + + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + pIterator->SetAt(m_wpCaret); + CPVT_Word word; + CPVT_Line line; + if (pIterator->GetWord(word)) { + m_ptCaret.x = word.ptWord.x + word.fWidth; + m_ptCaret.y = word.ptWord.y; + } else if (pIterator->GetLine(line)) { + m_ptCaret.x = line.ptLine.x; + m_ptCaret.y = line.ptLine.y; + } +} + +CPVT_WordPlace CPWL_EditImpl::WordIndexToWordPlace(int32_t index) const { + if (m_pVT->IsValid()) + return m_pVT->WordIndexToWordPlace(index); + + return CPVT_WordPlace(); +} + +bool CPWL_EditImpl::IsTextFull() const { + int32_t nTotalWords = m_pVT->GetTotalWords(); + int32_t nLimitChar = m_pVT->GetLimitChar(); + int32_t nCharArray = m_pVT->GetCharArray(); + + return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) || + (nCharArray > 0 && nTotalWords >= nCharArray); +} + +bool CPWL_EditImpl::IsTextOverflow() const { + if (!m_bEnableScroll && !m_bEnableOverflow) { + CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); + CFX_FloatRect rcContent = m_pVT->GetContentRect(); + + if (m_pVT->IsMultiLine() && GetTotalLines() > 1 && + IsFloatBigger(rcContent.Height(), rcPlate.Height())) { + return true; + } + + if (IsFloatBigger(rcContent.Width(), rcPlate.Width())) + return true; + } + + return false; +} + +bool CPWL_EditImpl::CanUndo() const { + if (m_bEnableUndo) { + return m_Undo.CanUndo(); + } + + return false; +} + +bool CPWL_EditImpl::CanRedo() const { + if (m_bEnableUndo) { + return m_Undo.CanRedo(); + } + + return false; +} + +void CPWL_EditImpl::EnableRefresh(bool bRefresh) { + m_bEnableRefresh = bRefresh; +} + +void CPWL_EditImpl::EnableUndo(bool bUndo) { + m_bEnableUndo = bUndo; +} + +void CPWL_EditImpl::EnableOprNotify(bool bNotify) { + m_bOprNotify = bNotify; +} + +CPVT_WordPlace CPWL_EditImpl::DoInsertText(const CPVT_WordPlace& place, + const CFX_WideString& sText, + int32_t charset) { + CPVT_WordPlace wp = place; + + if (m_pVT->IsValid()) { + for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++) { + uint16_t word = sText[i]; + switch (word) { + case 0x0D: + wp = m_pVT->InsertSection(wp, nullptr, nullptr); + if (sText[i + 1] == 0x0A) + i++; + break; + case 0x0A: + wp = m_pVT->InsertSection(wp, nullptr, nullptr); + if (sText[i + 1] == 0x0D) + i++; + break; + case 0x09: + word = 0x20; + default: + wp = m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset), + nullptr); + break; + } + } + } + + return wp; +} + +int32_t CPWL_EditImpl::GetCharSetFromUnicode(uint16_t word, + int32_t nOldCharset) { + if (IPVT_FontMap* pFontMap = GetFontMap()) + return pFontMap->CharSetFromUnicode(word, nOldCharset); + return nOldCharset; +} + +void CPWL_EditImpl::AddEditUndoItem( + std::unique_ptr pEditUndoItem) { + m_Undo.AddItem(std::move(pEditUndoItem)); +} + +CFX_ByteString CPWL_EditImpl::GetPDFWordString(int32_t nFontIndex, + uint16_t Word, + uint16_t SubWord) { + IPVT_FontMap* pFontMap = GetFontMap(); + CPDF_Font* pPDFFont = pFontMap->GetPDFFont(nFontIndex); + if (!pPDFFont) + return CFX_ByteString(); + + CFX_ByteString sWord; + if (SubWord > 0) { + Word = SubWord; + } else { + uint32_t dwCharCode = pPDFFont->IsUnicodeCompatible() + ? pPDFFont->CharCodeFromUnicode(Word) + : pFontMap->CharCodeFromUnicode(nFontIndex, Word); + if (dwCharCode > 0) { + pPDFFont->AppendChar(&sWord, dwCharCode); + return sWord; + } + } + pPDFFont->AppendChar(&sWord, Word); + return sWord; +} + +CPWL_EditImpl_LineRectArray::CPWL_EditImpl_LineRectArray() {} + +CPWL_EditImpl_LineRectArray::~CPWL_EditImpl_LineRectArray() {} + +void CPWL_EditImpl_LineRectArray::operator=( + CPWL_EditImpl_LineRectArray&& that) { + m_LineRects = std::move(that.m_LineRects); +} + +void CPWL_EditImpl_LineRectArray::Add(const CPVT_WordRange& wrLine, + const CFX_FloatRect& rcLine) { + m_LineRects.push_back( + pdfium::MakeUnique(wrLine, rcLine)); +} + +int32_t CPWL_EditImpl_LineRectArray::GetSize() const { + return pdfium::CollectionSize(m_LineRects); +} + +CPWL_EditImpl_LineRect* CPWL_EditImpl_LineRectArray::GetAt( + int32_t nIndex) const { + if (nIndex < 0 || nIndex >= GetSize()) + return nullptr; + + return m_LineRects[nIndex].get(); +} + +CPWL_EditImpl_Select::CPWL_EditImpl_Select() {} + +CPWL_EditImpl_Select::CPWL_EditImpl_Select(const CPVT_WordRange& range) { + Set(range.BeginPos, range.EndPos); +} + +CPVT_WordRange CPWL_EditImpl_Select::ConvertToWordRange() const { + return CPVT_WordRange(BeginPos, EndPos); +} + +void CPWL_EditImpl_Select::Reset() { + BeginPos.Reset(); + EndPos.Reset(); +} + +void CPWL_EditImpl_Select::Set(const CPVT_WordPlace& begin, + const CPVT_WordPlace& end) { + BeginPos = begin; + EndPos = end; +} + +void CPWL_EditImpl_Select::SetEndPos(const CPVT_WordPlace& end) { + EndPos = end; +} + +bool CPWL_EditImpl_Select::IsEmpty() const { + return BeginPos == EndPos; +} + +CPWL_EditImpl_RectArray::CPWL_EditImpl_RectArray() {} + +CPWL_EditImpl_RectArray::~CPWL_EditImpl_RectArray() {} + +void CPWL_EditImpl_RectArray::Clear() { + m_Rects.clear(); +} + +void CPWL_EditImpl_RectArray::Add(const CFX_FloatRect& rect) { + // check for overlapped area + for (const auto& pRect : m_Rects) { + if (pRect && pRect->Contains(rect)) + return; + } + m_Rects.push_back(pdfium::MakeUnique(rect)); +} + +int32_t CPWL_EditImpl_RectArray::GetSize() const { + return pdfium::CollectionSize(m_Rects); +} + +CFX_FloatRect* CPWL_EditImpl_RectArray::GetAt(int32_t nIndex) const { + if (nIndex < 0 || nIndex >= GetSize()) + return nullptr; + + return m_Rects[nIndex].get(); +} diff --git a/fpdfsdk/pdfwindow/cpwl_edit_impl.h b/fpdfsdk/pdfwindow/cpwl_edit_impl.h new file mode 100644 index 0000000000..53ed8da0c2 --- /dev/null +++ b/fpdfsdk/pdfwindow/cpwl_edit_impl.h @@ -0,0 +1,515 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef FPDFSDK_PDFWINDOW_CPWL_EDIT_IMPL_H_ +#define FPDFSDK_PDFWINDOW_CPWL_EDIT_IMPL_H_ + +#include +#include +#include + +#include "core/fpdfdoc/cpvt_secprops.h" +#include "core/fpdfdoc/cpvt_wordprops.h" +#include "core/fxcrt/cfx_unowned_ptr.h" + +#define FX_EDIT_ISLATINWORD(u) \ + (u == 0x2D || (u <= 0x005A && u >= 0x0041) || \ + (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0)) + +class CFFL_FormFiller; +class CPWL_EditImpl; +class CPWL_EditImpl_Iterator; +class CPWL_EditImpl_Provider; +class CFX_RenderDevice; +class CFX_SystemHandler; +class CPWL_Edit; +class CPWL_EditCtrl; +class IFX_Edit_UndoItem; + +struct CPWL_EditImpl_LineRect { + CPWL_EditImpl_LineRect(const CPVT_WordRange& wrLine, + const CFX_FloatRect& rcLine) + : m_wrLine(wrLine), m_rcLine(rcLine) {} + + CPVT_WordRange m_wrLine; + CFX_FloatRect m_rcLine; +}; + +class CPWL_EditImpl_LineRectArray { + public: + CPWL_EditImpl_LineRectArray(); + ~CPWL_EditImpl_LineRectArray(); + + void operator=(CPWL_EditImpl_LineRectArray&& rects); + void Add(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine); + + int32_t GetSize() const; + CPWL_EditImpl_LineRect* GetAt(int32_t nIndex) const; + + private: + std::vector> m_LineRects; +}; + +class CPWL_EditImpl_RectArray { + public: + CPWL_EditImpl_RectArray(); + ~CPWL_EditImpl_RectArray(); + + void Clear(); + void Add(const CFX_FloatRect& rect); + + int32_t GetSize() const; + CFX_FloatRect* GetAt(int32_t nIndex) const; + + private: + std::vector> m_Rects; +}; + +class CPWL_EditImpl_Refresh { + public: + CPWL_EditImpl_Refresh(); + ~CPWL_EditImpl_Refresh(); + + void BeginRefresh(); + void Push(const CPVT_WordRange& linerange, const CFX_FloatRect& rect); + void NoAnalyse(); + const CPWL_EditImpl_RectArray* GetRefreshRects() const; + void EndRefresh(); + + private: + CPWL_EditImpl_LineRectArray m_NewLineRects; + CPWL_EditImpl_LineRectArray m_OldLineRects; + CPWL_EditImpl_RectArray m_RefreshRects; +}; + +class CPWL_EditImpl_Select { + public: + CPWL_EditImpl_Select(); + explicit CPWL_EditImpl_Select(const CPVT_WordRange& range); + + void Reset(); + void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end); + void SetEndPos(const CPVT_WordPlace& end); + + CPVT_WordRange ConvertToWordRange() const; + bool IsEmpty() const; + + CPVT_WordPlace BeginPos; + CPVT_WordPlace EndPos; +}; + +class CPWL_EditImpl_Undo { + public: + explicit CPWL_EditImpl_Undo(int32_t nBufsize); + ~CPWL_EditImpl_Undo(); + + void AddItem(std::unique_ptr pItem); + void Undo(); + void Redo(); + bool CanUndo() const; + bool CanRedo() const; + void Reset(); + + private: + void RemoveHeads(); + void RemoveTails(); + + std::deque> m_UndoItemStack; + size_t m_nCurUndoPos; + size_t m_nBufSize; + bool m_bWorking; +}; + +class IFX_Edit_UndoItem { + public: + virtual ~IFX_Edit_UndoItem() {} + + virtual void Undo() = 0; + virtual void Redo() = 0; + virtual CFX_WideString GetUndoTitle() const = 0; +}; + +class CPWL_EditImpl_UndoItem : public IFX_Edit_UndoItem { + public: + CPWL_EditImpl_UndoItem(); + ~CPWL_EditImpl_UndoItem() override; + + CFX_WideString GetUndoTitle() const override; + + void SetFirst(bool bFirst); + void SetLast(bool bLast); + bool IsLast(); + + private: + bool m_bFirst; + bool m_bLast; +}; + +class CFXEU_InsertWord : public CPWL_EditImpl_UndoItem { + public: + CFXEU_InsertWord(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + uint16_t word, + int32_t charset, + const CPVT_WordProps* pWordProps); + ~CFXEU_InsertWord() override; + + // CPWL_EditImpl_UndoItem + void Redo() override; + void Undo() override; + + private: + CFX_UnownedPtr m_pEdit; + + CPVT_WordPlace m_wpOld; + CPVT_WordPlace m_wpNew; + uint16_t m_Word; + int32_t m_nCharset; + CPVT_WordProps m_WordProps; +}; + +class CFXEU_InsertReturn : public CPWL_EditImpl_UndoItem { + public: + CFXEU_InsertReturn(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + const CPVT_SecProps* pSecProps, + const CPVT_WordProps* pWordProps); + ~CFXEU_InsertReturn() override; + + // CPWL_EditImpl_UndoItem + void Redo() override; + void Undo() override; + + private: + CFX_UnownedPtr m_pEdit; + + CPVT_WordPlace m_wpOld; + CPVT_WordPlace m_wpNew; + CPVT_SecProps m_SecProps; + CPVT_WordProps m_WordProps; +}; + +class CFXEU_Backspace : public CPWL_EditImpl_UndoItem { + public: + CFXEU_Backspace(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + uint16_t word, + int32_t charset, + const CPVT_SecProps& SecProps, + const CPVT_WordProps& WordProps); + ~CFXEU_Backspace() override; + + // CPWL_EditImpl_UndoItem + void Redo() override; + void Undo() override; + + private: + CFX_UnownedPtr m_pEdit; + + CPVT_WordPlace m_wpOld; + CPVT_WordPlace m_wpNew; + uint16_t m_Word; + int32_t m_nCharset; + CPVT_SecProps m_SecProps; + CPVT_WordProps m_WordProps; +}; + +class CFXEU_Delete : public CPWL_EditImpl_UndoItem { + public: + CFXEU_Delete(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + uint16_t word, + int32_t charset, + const CPVT_SecProps& SecProps, + const CPVT_WordProps& WordProps, + bool bSecEnd); + ~CFXEU_Delete() override; + + // CPWL_EditImpl_UndoItem + void Redo() override; + void Undo() override; + + private: + CFX_UnownedPtr m_pEdit; + + CPVT_WordPlace m_wpOld; + CPVT_WordPlace m_wpNew; + uint16_t m_Word; + int32_t m_nCharset; + CPVT_SecProps m_SecProps; + CPVT_WordProps m_WordProps; + bool m_bSecEnd; +}; + +class CFXEU_Clear : public CPWL_EditImpl_UndoItem { + public: + CFXEU_Clear(CPWL_EditImpl* pEdit, + const CPVT_WordRange& wrSel, + const CFX_WideString& swText); + ~CFXEU_Clear() override; + + // CPWL_EditImpl_UndoItem + void Redo() override; + void Undo() override; + + private: + CFX_UnownedPtr m_pEdit; + + CPVT_WordRange m_wrSel; + CFX_WideString m_swText; +}; + +class CFXEU_InsertText : public CPWL_EditImpl_UndoItem { + public: + CFXEU_InsertText(CPWL_EditImpl* pEdit, + const CPVT_WordPlace& wpOldPlace, + const CPVT_WordPlace& wpNewPlace, + const CFX_WideString& swText, + int32_t charset); + ~CFXEU_InsertText() override; + + // CPWL_EditImpl_UndoItem + void Redo() override; + void Undo() override; + + private: + CFX_UnownedPtr m_pEdit; + + CPVT_WordPlace m_wpOld; + CPVT_WordPlace m_wpNew; + CFX_WideString m_swText; + int32_t m_nCharset; +}; + +class CPWL_EditImpl { + public: + static void DrawEdit(CFX_RenderDevice* pDevice, + CFX_Matrix* pUser2Device, + CPWL_EditImpl* pEdit, + FX_COLORREF crTextFill, + const CFX_FloatRect& rcClip, + const CFX_PointF& ptOffset, + const CPVT_WordRange* pRange, + CFX_SystemHandler* pSystemHandler, + CFFL_FormFiller* pFFLData); + + CPWL_EditImpl(); + ~CPWL_EditImpl(); + + void SetFontMap(IPVT_FontMap* pFontMap); + void SetNotify(CPWL_EditCtrl* pNotify); + void SetOprNotify(CPWL_Edit* pOprNotify); + + // Returns an iterator for the contents. Should not be released. + CPWL_EditImpl_Iterator* GetIterator(); + IPVT_FontMap* GetFontMap(); + void Initialize(); + + // Set the bounding box of the text area. + void SetPlateRect(const CFX_FloatRect& rect); + void SetScrollPos(const CFX_PointF& point); + + // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right]) + void SetAlignmentH(int32_t nFormat, bool bPaint); + // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right]) + void SetAlignmentV(int32_t nFormat, bool bPaint); + + // Set the substitution character for hidden text. + void SetPasswordChar(uint16_t wSubWord, bool bPaint); + + // Set the maximum number of words in the text. + void SetLimitChar(int32_t nLimitChar); + void SetCharArray(int32_t nCharArray); + void SetCharSpace(float fCharSpace); + void SetMultiLine(bool bMultiLine, bool bPaint); + void SetAutoReturn(bool bAuto, bool bPaint); + void SetAutoFontSize(bool bAuto, bool bPaint); + void SetAutoScroll(bool bAuto, bool bPaint); + void SetFontSize(float fFontSize); + void SetTextOverflow(bool bAllowed, bool bPaint); + void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl); + void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl); + void OnVK_UP(bool bShift, bool bCtrl); + void OnVK_DOWN(bool bShift, bool bCtrl); + void OnVK_LEFT(bool bShift, bool bCtrl); + void OnVK_RIGHT(bool bShift, bool bCtrl); + void OnVK_HOME(bool bShift, bool bCtrl); + void OnVK_END(bool bShift, bool bCtrl); + void SetText(const CFX_WideString& sText); + bool InsertWord(uint16_t word, int32_t charset); + bool InsertReturn(); + bool Backspace(); + bool Delete(); + bool ClearSelection(); + bool InsertText(const CFX_WideString& sText, int32_t charset); + bool Redo(); + bool Undo(); + CPVT_WordPlace WordIndexToWordPlace(int32_t index) const; + CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const; + int32_t GetCaret() const; + CPVT_WordPlace GetCaretWordPlace() const; + CFX_WideString GetSelectedText() const; + CFX_WideString GetText() const; + float GetFontSize() const; + uint16_t GetPasswordChar() const; + CFX_PointF GetScrollPos() const; + int32_t GetCharArray() const; + CFX_FloatRect GetContentRect() const; + CFX_WideString GetRangeText(const CPVT_WordRange& range) const; + int32_t GetHorzScale() const; + float GetCharSpace() const; + void SetSelection(int32_t nStartChar, int32_t nEndChar); + void GetSelection(int32_t& nStartChar, int32_t& nEndChar) const; + void SelectAll(); + void SelectNone(); + bool IsSelected() const; + void Paint(); + void EnableRefresh(bool bRefresh); + void RefreshWordRange(const CPVT_WordRange& wr); + CPVT_WordRange GetWholeWordRange() const; + CPVT_WordRange GetSelectWordRange() const; + void EnableUndo(bool bUndo); + void EnableOprNotify(bool bNotify); + bool IsTextFull() const; + bool IsTextOverflow() const; + bool CanUndo() const; + bool CanRedo() const; + CPVT_WordRange GetVisibleWordRange() const; + + bool Empty(); + + CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place, + const CFX_WideString& sText, + int32_t charset); + int32_t GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset); + + int32_t GetTotalLines() const; + + CFX_ByteString GetPDFWordString(int32_t nFontIndex, + uint16_t Word, + uint16_t SubWord); + + private: + friend class CPWL_EditImpl_Iterator; + friend class CFXEU_InsertWord; + friend class CFXEU_InsertReturn; + friend class CFXEU_Backspace; + friend class CFXEU_Delete; + friend class CFXEU_Clear; + friend class CFXEU_InsertText; + + void SetSelection(const CPVT_WordPlace& begin, const CPVT_WordPlace& end); + + void RearrangeAll(); + void RearrangePart(const CPVT_WordRange& range); + void ScrollToCaret(); + void SetScrollInfo(); + void SetScrollPosX(float fx); + void SetScrollPosY(float fy); + void SetScrollLimit(); + void SetContentChanged(); + + bool InsertWord(uint16_t word, + int32_t charset, + const CPVT_WordProps* pWordProps, + bool bAddUndo, + bool bPaint); + bool InsertReturn(const CPVT_SecProps* pSecProps, + const CPVT_WordProps* pWordProps, + bool bAddUndo, + bool bPaint); + bool Backspace(bool bAddUndo, bool bPaint); + bool Delete(bool bAddUndo, bool bPaint); + bool Clear(bool bAddUndo, bool bPaint); + bool InsertText(const CFX_WideString& sText, + int32_t charset, + bool bAddUndo, + bool bPaint); + void PaintInsertText(const CPVT_WordPlace& wpOld, + const CPVT_WordPlace& wpNew); + + inline CFX_PointF VTToEdit(const CFX_PointF& point) const; + inline CFX_PointF EditToVT(const CFX_PointF& point) const; + inline CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const; + + void Refresh(); + void RefreshPushLineRects(const CPVT_WordRange& wr); + + void SetCaret(const CPVT_WordPlace& place); + void SetCaretInfo(); + void SetCaretOrigin(); + + void AddEditUndoItem(std::unique_ptr pEditUndoItem); + + private: + std::unique_ptr m_pVT; + CFX_UnownedPtr m_pNotify; + CFX_UnownedPtr m_pOprNotify; + std::unique_ptr m_pVTProvider; + CPVT_WordPlace m_wpCaret; + CPVT_WordPlace m_wpOldCaret; + CPWL_EditImpl_Select m_SelState; + CFX_PointF m_ptScrollPos; + CFX_PointF m_ptRefreshScrollPos; + bool m_bEnableScroll; + std::unique_ptr m_pIterator; + CPWL_EditImpl_Refresh m_Refresh; + CFX_PointF m_ptCaret; + CPWL_EditImpl_Undo m_Undo; + int32_t m_nAlignment; + bool m_bNotifyFlag; + bool m_bEnableOverflow; + bool m_bEnableRefresh; + CFX_FloatRect m_rcOldContent; + bool m_bEnableUndo; + bool m_bOprNotify; +}; + +class CPWL_EditImpl_Iterator { + public: + CPWL_EditImpl_Iterator(CPWL_EditImpl* pEdit, + CPDF_VariableText::Iterator* pVTIterator); + ~CPWL_EditImpl_Iterator(); + + bool NextWord(); + bool PrevWord(); + bool GetWord(CPVT_Word& word) const; + bool GetLine(CPVT_Line& line) const; + void SetAt(int32_t nWordIndex); + void SetAt(const CPVT_WordPlace& place); + const CPVT_WordPlace& GetAt() const; + + private: + CFX_UnownedPtr m_pEdit; + CPDF_VariableText::Iterator* m_pVTIterator; +}; + +class CPWL_EditImpl_Provider : public CPDF_VariableText::Provider { + public: + explicit CPWL_EditImpl_Provider(IPVT_FontMap* pFontMap); + ~CPWL_EditImpl_Provider() override; + + IPVT_FontMap* GetFontMap() const; + + // CPDF_VariableText::Provider: + int32_t GetCharWidth(int32_t nFontIndex, uint16_t word) override; + int32_t GetTypeAscent(int32_t nFontIndex) override; + int32_t GetTypeDescent(int32_t nFontIndex) override; + int32_t GetWordFontIndex(uint16_t word, + int32_t charset, + int32_t nFontIndex) override; + int32_t GetDefaultFontIndex() override; + bool IsLatinWord(uint16_t word) override; + + private: + IPVT_FontMap* m_pFontMap; +}; + +#endif // FPDFSDK_PDFWINDOW_CPWL_EDIT_IMPL_H_ diff --git a/fpdfsdk/pdfwindow/cpwl_list_box.cpp b/fpdfsdk/pdfwindow/cpwl_list_box.cpp index ffa5b4780f..7e820bfbfa 100644 --- a/fpdfsdk/pdfwindow/cpwl_list_box.cpp +++ b/fpdfsdk/pdfwindow/cpwl_list_box.cpp @@ -9,10 +9,10 @@ #include #include "core/fxge/cfx_renderdevice.h" -#include "fpdfsdk/fxedit/fxet_edit.h" -#include "fpdfsdk/fxedit/fxet_list.h" #include "fpdfsdk/pdfwindow/cpwl_edit.h" #include "fpdfsdk/pdfwindow/cpwl_edit_ctrl.h" +#include "fpdfsdk/pdfwindow/cpwl_edit_impl.h" +#include "fpdfsdk/pdfwindow/cpwl_list_impl.h" #include "fpdfsdk/pdfwindow/cpwl_scroll_bar.h" #include "fpdfsdk/pdfwindow/cpwl_wnd.h" #include "public/fpdf_fwlevent.h" @@ -63,7 +63,7 @@ void CPWL_List_Notify::IOnInvalidateRect(CFX_FloatRect* pRect) { } CPWL_ListBox::CPWL_ListBox() - : m_pList(new CFX_ListCtrl), + : m_pList(new CPWL_ListCtrl), m_bMouseDown(false), m_bHoverSel(false), m_pFillerNotify(nullptr) {} @@ -107,7 +107,7 @@ void CPWL_ListBox::DrawThisAppearance(CFX_RenderDevice* pDevice, continue; CFX_PointF ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f); - if (CFX_Edit* pEdit = m_pList->GetItemEdit(i)) { + if (CPWL_EditImpl* pEdit = m_pList->GetItemEdit(i)) { CFX_FloatRect rcContent = pEdit->GetContentRect(); if (rcContent.Width() > rcClient.Width()) rcItem.Intersect(rcList); @@ -118,22 +118,23 @@ void CPWL_ListBox::DrawThisAppearance(CFX_RenderDevice* pDevice, if (m_pList->IsItemSelected(i)) { CFX_SystemHandler* pSysHandler = GetSystemHandler(); if (pSysHandler && pSysHandler->IsSelectionImplemented()) { - CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), - GetTextColor().ToFXColor(255), rcList, ptOffset, - nullptr, pSysHandler, m_pFormFiller.Get()); + CPWL_EditImpl::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), + GetTextColor().ToFXColor(255), rcList, ptOffset, + nullptr, pSysHandler, m_pFormFiller.Get()); pSysHandler->OutputSelectedRect(m_pFormFiller.Get(), rcItem); } else { pDevice->DrawFillRect(pUser2Device, rcItem, ArgbEncode(255, 0, 51, 113)); - CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), - ArgbEncode(255, 255, 255, 255), rcList, ptOffset, - nullptr, pSysHandler, m_pFormFiller.Get()); + CPWL_EditImpl::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), + ArgbEncode(255, 255, 255, 255), rcList, + ptOffset, nullptr, pSysHandler, + m_pFormFiller.Get()); } } else { CFX_SystemHandler* pSysHandler = GetSystemHandler(); - CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), - GetTextColor().ToFXColor(255), rcList, ptOffset, - nullptr, pSysHandler, nullptr); + CPWL_EditImpl::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), + GetTextColor().ToFXColor(255), rcList, ptOffset, + nullptr, pSysHandler, nullptr); } } } diff --git a/fpdfsdk/pdfwindow/cpwl_list_box.h b/fpdfsdk/pdfwindow/cpwl_list_box.h index f41a6dd87f..d76c7a5c5a 100644 --- a/fpdfsdk/pdfwindow/cpwl_list_box.h +++ b/fpdfsdk/pdfwindow/cpwl_list_box.h @@ -12,7 +12,7 @@ #include "core/fxcrt/cfx_unowned_ptr.h" #include "fpdfsdk/pdfwindow/cpwl_wnd.h" -class CFX_ListCtrl; +class CPWL_ListCtrl; class CPWL_List_Notify; class CPWL_ListBox; class IPWL_Filler_Notify; @@ -97,7 +97,7 @@ class CPWL_ListBox : public CPWL_Wnd { void AttachFFLData(CFFL_FormFiller* pData) { m_pFormFiller = pData; } protected: - std::unique_ptr m_pList; + std::unique_ptr m_pList; std::unique_ptr m_pListNotify; bool m_bMouseDown; bool m_bHoverSel; diff --git a/fpdfsdk/pdfwindow/cpwl_list_impl.cpp b/fpdfsdk/pdfwindow/cpwl_list_impl.cpp new file mode 100644 index 0000000000..66b2e77747 --- /dev/null +++ b/fpdfsdk/pdfwindow/cpwl_list_impl.cpp @@ -0,0 +1,637 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "fpdfsdk/pdfwindow/cpwl_list_impl.h" + +#include +#include + +#include "core/fpdfdoc/cpvt_word.h" +#include "core/fxcrt/fx_extension.h" +#include "fpdfsdk/pdfwindow/cpwl_edit_impl.h" +#include "fpdfsdk/pdfwindow/cpwl_list_box.h" +#include "third_party/base/stl_util.h" + +CPWL_ListCtrl::Item::Item() + : m_pEdit(new CPWL_EditImpl), + m_bSelected(false), + m_rcListItem(0.0f, 0.0f, 0.0f, 0.0f) { + m_pEdit->SetAlignmentV(1, true); + m_pEdit->Initialize(); +} + +CPWL_ListCtrl::Item::~Item() {} + +void CPWL_ListCtrl::Item::SetFontMap(IPVT_FontMap* pFontMap) { + m_pEdit->SetFontMap(pFontMap); +} + +void CPWL_ListCtrl::Item::SetText(const CFX_WideString& text) { + m_pEdit->SetText(text); +} + +void CPWL_ListCtrl::Item::SetFontSize(float fFontSize) { + m_pEdit->SetFontSize(fFontSize); +} + +float CPWL_ListCtrl::Item::GetItemHeight() const { + return m_pEdit->GetContentRect().Height(); +} + +uint16_t CPWL_ListCtrl::Item::GetFirstChar() const { + CPVT_Word word; + CPWL_EditImpl_Iterator* pIterator = m_pEdit->GetIterator(); + pIterator->SetAt(1); + pIterator->GetWord(word); + return word.Word; +} + +CFX_WideString CPWL_ListCtrl::Item::GetText() const { + return m_pEdit->GetText(); +} + +CPLST_Select::CPLST_Select() {} + +CPLST_Select::~CPLST_Select() {} + +void CPLST_Select::Add(int32_t nItemIndex) { + m_Items[nItemIndex] = SELECTING; +} + +void CPLST_Select::Add(int32_t nBeginIndex, int32_t nEndIndex) { + if (nBeginIndex > nEndIndex) + std::swap(nBeginIndex, nEndIndex); + + for (int32_t i = nBeginIndex; i <= nEndIndex; ++i) + Add(i); +} + +void CPLST_Select::Sub(int32_t nItemIndex) { + auto it = m_Items.find(nItemIndex); + if (it != m_Items.end()) + it->second = DESELECTING; +} + +void CPLST_Select::Sub(int32_t nBeginIndex, int32_t nEndIndex) { + if (nBeginIndex > nEndIndex) + std::swap(nBeginIndex, nEndIndex); + + for (int32_t i = nBeginIndex; i <= nEndIndex; ++i) + Sub(i); +} + +void CPLST_Select::DeselectAll() { + for (auto& item : m_Items) + item.second = DESELECTING; +} + +void CPLST_Select::Done() { + auto it = m_Items.begin(); + while (it != m_Items.end()) { + if (it->second == DESELECTING) + it = m_Items.erase(it); + else + (it++)->second = NORMAL; + } +} + +CPWL_ListCtrl::CPWL_ListCtrl() + : m_pNotify(nullptr), + m_bNotifyFlag(false), + m_nSelItem(-1), + m_nFootIndex(-1), + m_bCtrlSel(false), + m_nCaretIndex(-1), + m_fFontSize(0.0f), + m_pFontMap(nullptr), + m_bMultiple(false) {} + +CPWL_ListCtrl::~CPWL_ListCtrl() { + Empty(); +} + +CFX_PointF CPWL_ListCtrl::InToOut(const CFX_PointF& point) const { + CFX_FloatRect rcPlate = m_rcPlate; + return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left), + point.y - (m_ptScrollPos.y - rcPlate.top)); +} + +CFX_PointF CPWL_ListCtrl::OutToIn(const CFX_PointF& point) const { + CFX_FloatRect rcPlate = m_rcPlate; + return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left), + point.y + (m_ptScrollPos.y - rcPlate.top)); +} + +CFX_FloatRect CPWL_ListCtrl::InToOut(const CFX_FloatRect& rect) const { + CFX_PointF ptLeftBottom = InToOut(CFX_PointF(rect.left, rect.bottom)); + CFX_PointF ptRightTop = InToOut(CFX_PointF(rect.right, rect.top)); + return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, + ptRightTop.y); +} + +CFX_FloatRect CPWL_ListCtrl::OutToIn(const CFX_FloatRect& rect) const { + CFX_PointF ptLeftBottom = OutToIn(CFX_PointF(rect.left, rect.bottom)); + CFX_PointF ptRightTop = OutToIn(CFX_PointF(rect.right, rect.top)); + return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, + ptRightTop.y); +} + +CFX_PointF CPWL_ListCtrl::InnerToOuter(const CFX_PointF& point) const { + return CFX_PointF(point.x + GetBTPoint().x, GetBTPoint().y - point.y); +} + +CFX_PointF CPWL_ListCtrl::OuterToInner(const CFX_PointF& point) const { + return CFX_PointF(point.x - GetBTPoint().x, GetBTPoint().y - point.y); +} + +CFX_FloatRect CPWL_ListCtrl::InnerToOuter(const CFX_FloatRect& rect) const { + CFX_PointF ptLeftTop = InnerToOuter(CFX_PointF(rect.left, rect.top)); + CFX_PointF ptRightBottom = InnerToOuter(CFX_PointF(rect.right, rect.bottom)); + return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, + ptLeftTop.y); +} + +CFX_FloatRect CPWL_ListCtrl::OuterToInner(const CFX_FloatRect& rect) const { + CFX_PointF ptLeftTop = OuterToInner(CFX_PointF(rect.left, rect.top)); + CFX_PointF ptRightBottom = OuterToInner(CFX_PointF(rect.right, rect.bottom)); + return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, + ptLeftTop.y); +} + +void CPWL_ListCtrl::OnMouseDown(const CFX_PointF& point, + bool bShift, + bool bCtrl) { + int32_t nHitIndex = GetItemIndex(point); + + if (IsMultipleSel()) { + if (bCtrl) { + if (IsItemSelected(nHitIndex)) { + m_aSelItems.Sub(nHitIndex); + SelectItems(); + m_bCtrlSel = false; + } else { + m_aSelItems.Add(nHitIndex); + SelectItems(); + m_bCtrlSel = true; + } + + m_nFootIndex = nHitIndex; + } else if (bShift) { + m_aSelItems.DeselectAll(); + m_aSelItems.Add(m_nFootIndex, nHitIndex); + SelectItems(); + } else { + m_aSelItems.DeselectAll(); + m_aSelItems.Add(nHitIndex); + SelectItems(); + + m_nFootIndex = nHitIndex; + } + + SetCaret(nHitIndex); + } else { + SetSingleSelect(nHitIndex); + } + + if (!IsItemVisible(nHitIndex)) + ScrollToListItem(nHitIndex); +} + +void CPWL_ListCtrl::OnMouseMove(const CFX_PointF& point, + bool bShift, + bool bCtrl) { + int32_t nHitIndex = GetItemIndex(point); + + if (IsMultipleSel()) { + if (bCtrl) { + if (m_bCtrlSel) + m_aSelItems.Add(m_nFootIndex, nHitIndex); + else + m_aSelItems.Sub(m_nFootIndex, nHitIndex); + + SelectItems(); + } else { + m_aSelItems.DeselectAll(); + m_aSelItems.Add(m_nFootIndex, nHitIndex); + SelectItems(); + } + + SetCaret(nHitIndex); + } else { + SetSingleSelect(nHitIndex); + } + + if (!IsItemVisible(nHitIndex)) + ScrollToListItem(nHitIndex); +} + +void CPWL_ListCtrl::OnVK(int32_t nItemIndex, bool bShift, bool bCtrl) { + if (IsMultipleSel()) { + if (nItemIndex >= 0 && nItemIndex < GetCount()) { + if (bCtrl) { + } else if (bShift) { + m_aSelItems.DeselectAll(); + m_aSelItems.Add(m_nFootIndex, nItemIndex); + SelectItems(); + } else { + m_aSelItems.DeselectAll(); + m_aSelItems.Add(nItemIndex); + SelectItems(); + m_nFootIndex = nItemIndex; + } + + SetCaret(nItemIndex); + } + } else { + SetSingleSelect(nItemIndex); + } + + if (!IsItemVisible(nItemIndex)) + ScrollToListItem(nItemIndex); +} + +void CPWL_ListCtrl::OnVK_UP(bool bShift, bool bCtrl) { + OnVK(IsMultipleSel() ? GetCaret() - 1 : GetSelect() - 1, bShift, bCtrl); +} + +void CPWL_ListCtrl::OnVK_DOWN(bool bShift, bool bCtrl) { + OnVK(IsMultipleSel() ? GetCaret() + 1 : GetSelect() + 1, bShift, bCtrl); +} + +void CPWL_ListCtrl::OnVK_LEFT(bool bShift, bool bCtrl) { + OnVK(0, bShift, bCtrl); +} + +void CPWL_ListCtrl::OnVK_RIGHT(bool bShift, bool bCtrl) { + OnVK(GetCount() - 1, bShift, bCtrl); +} + +void CPWL_ListCtrl::OnVK_HOME(bool bShift, bool bCtrl) { + OnVK(0, bShift, bCtrl); +} + +void CPWL_ListCtrl::OnVK_END(bool bShift, bool bCtrl) { + OnVK(GetCount() - 1, bShift, bCtrl); +} + +bool CPWL_ListCtrl::OnChar(uint16_t nChar, bool bShift, bool bCtrl) { + int32_t nIndex = GetLastSelected(); + int32_t nFindIndex = FindNext(nIndex, nChar); + + if (nFindIndex != nIndex) { + OnVK(nFindIndex, bShift, bCtrl); + return true; + } + return false; +} + +void CPWL_ListCtrl::SetPlateRect(const CFX_FloatRect& rect) { + m_rcPlate = rect; + m_ptScrollPos.x = rect.left; + SetScrollPos(CFX_PointF(rect.left, rect.top)); + ReArrange(0); + InvalidateItem(-1); +} + +CFX_FloatRect CPWL_ListCtrl::GetItemRect(int32_t nIndex) const { + return InToOut(GetItemRectInternal(nIndex)); +} + +CFX_FloatRect CPWL_ListCtrl::GetItemRectInternal(int32_t nIndex) const { + if (!pdfium::IndexInBounds(m_ListItems, nIndex) || !m_ListItems[nIndex]) + return CFX_FloatRect(); + + CFX_FloatRect rcItem = m_ListItems[nIndex]->GetRect(); + rcItem.left = 0.0f; + rcItem.right = m_rcPlate.Width(); + return InnerToOuter(rcItem); +} + +void CPWL_ListCtrl::AddString(const CFX_WideString& str) { + AddItem(str); + ReArrange(GetCount() - 1); +} + +void CPWL_ListCtrl::SetMultipleSelect(int32_t nItemIndex, bool bSelected) { + if (!IsValid(nItemIndex)) + return; + + if (bSelected != IsItemSelected(nItemIndex)) { + if (bSelected) { + SetItemSelect(nItemIndex, true); + InvalidateItem(nItemIndex); + } else { + SetItemSelect(nItemIndex, false); + InvalidateItem(nItemIndex); + } + } +} + +void CPWL_ListCtrl::SetSingleSelect(int32_t nItemIndex) { + if (!IsValid(nItemIndex)) + return; + + if (m_nSelItem != nItemIndex) { + if (m_nSelItem >= 0) { + SetItemSelect(m_nSelItem, false); + InvalidateItem(m_nSelItem); + } + + SetItemSelect(nItemIndex, true); + InvalidateItem(nItemIndex); + m_nSelItem = nItemIndex; + } +} + +void CPWL_ListCtrl::SetCaret(int32_t nItemIndex) { + if (!IsValid(nItemIndex)) + return; + + if (IsMultipleSel()) { + int32_t nOldIndex = m_nCaretIndex; + + if (nOldIndex != nItemIndex) { + m_nCaretIndex = nItemIndex; + InvalidateItem(nOldIndex); + InvalidateItem(nItemIndex); + } + } +} + +void CPWL_ListCtrl::InvalidateItem(int32_t nItemIndex) { + if (m_pNotify) { + if (nItemIndex == -1) { + if (!m_bNotifyFlag) { + m_bNotifyFlag = true; + CFX_FloatRect rcRefresh = m_rcPlate; + m_pNotify->IOnInvalidateRect(&rcRefresh); + m_bNotifyFlag = false; + } + } else { + if (!m_bNotifyFlag) { + m_bNotifyFlag = true; + CFX_FloatRect rcRefresh = GetItemRect(nItemIndex); + rcRefresh.left -= 1.0f; + rcRefresh.right += 1.0f; + rcRefresh.bottom -= 1.0f; + rcRefresh.top += 1.0f; + + m_pNotify->IOnInvalidateRect(&rcRefresh); + m_bNotifyFlag = false; + } + } + } +} + +void CPWL_ListCtrl::SelectItems() { + for (const auto& item : m_aSelItems) { + if (item.second != CPLST_Select::NORMAL) + SetMultipleSelect(item.first, item.second == CPLST_Select::SELECTING); + } + m_aSelItems.Done(); +} + +void CPWL_ListCtrl::Select(int32_t nItemIndex) { + if (!IsValid(nItemIndex)) + return; + + if (IsMultipleSel()) { + m_aSelItems.Add(nItemIndex); + SelectItems(); + } else { + SetSingleSelect(nItemIndex); + } +} + +bool CPWL_ListCtrl::IsItemVisible(int32_t nItemIndex) const { + CFX_FloatRect rcPlate = m_rcPlate; + CFX_FloatRect rcItem = GetItemRect(nItemIndex); + + return rcItem.bottom >= rcPlate.bottom && rcItem.top <= rcPlate.top; +} + +void CPWL_ListCtrl::ScrollToListItem(int32_t nItemIndex) { + if (!IsValid(nItemIndex)) + return; + + CFX_FloatRect rcPlate = m_rcPlate; + CFX_FloatRect rcItem = GetItemRectInternal(nItemIndex); + CFX_FloatRect rcItemCtrl = GetItemRect(nItemIndex); + + if (IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) { + if (IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) { + SetScrollPosY(rcItem.bottom + rcPlate.Height()); + } + } else if (IsFloatBigger(rcItemCtrl.top, rcPlate.top)) { + if (IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) { + SetScrollPosY(rcItem.top); + } + } +} + +void CPWL_ListCtrl::SetScrollInfo() { + if (m_pNotify) { + CFX_FloatRect rcPlate = m_rcPlate; + CFX_FloatRect rcContent = GetContentRectInternal(); + + if (!m_bNotifyFlag) { + m_bNotifyFlag = true; + m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top, + rcContent.bottom, rcContent.top, + GetFirstHeight(), rcPlate.Height()); + m_bNotifyFlag = false; + } + } +} + +void CPWL_ListCtrl::SetScrollPos(const CFX_PointF& point) { + SetScrollPosY(point.y); +} + +void CPWL_ListCtrl::SetScrollPosY(float fy) { + if (!IsFloatEqual(m_ptScrollPos.y, fy)) { + CFX_FloatRect rcPlate = m_rcPlate; + CFX_FloatRect rcContent = GetContentRectInternal(); + + if (rcPlate.Height() > rcContent.Height()) { + fy = rcPlate.top; + } else { + if (IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) { + fy = rcContent.bottom + rcPlate.Height(); + } else if (IsFloatBigger(fy, rcContent.top)) { + fy = rcContent.top; + } + } + + m_ptScrollPos.y = fy; + InvalidateItem(-1); + + if (m_pNotify) { + if (!m_bNotifyFlag) { + m_bNotifyFlag = true; + m_pNotify->IOnSetScrollPosY(fy); + m_bNotifyFlag = false; + } + } + } +} + +CFX_FloatRect CPWL_ListCtrl::GetContentRectInternal() const { + return InnerToOuter(m_rcContent); +} + +CFX_FloatRect CPWL_ListCtrl::GetContentRect() const { + return InToOut(GetContentRectInternal()); +} + +void CPWL_ListCtrl::ReArrange(int32_t nItemIndex) { + float fPosY = 0.0f; + if (pdfium::IndexInBounds(m_ListItems, nItemIndex - 1) && + m_ListItems[nItemIndex - 1]) { + fPosY = m_ListItems[nItemIndex - 1]->GetRect().bottom; + } + for (const auto& pListItem : m_ListItems) { + if (pListItem) { + float fListItemHeight = pListItem->GetItemHeight(); + pListItem->SetRect( + CFX_FloatRect(0.0f, fPosY + fListItemHeight, 0.0f, fPosY)); + fPosY += fListItemHeight; + } + } + SetContentRect(CFX_FloatRect(0.0f, fPosY, 0.0f, 0.0f)); + SetScrollInfo(); +} + +void CPWL_ListCtrl::SetTopItem(int32_t nIndex) { + if (IsValid(nIndex)) { + CFX_FloatRect rcItem = GetItemRectInternal(nIndex); + SetScrollPosY(rcItem.top); + } +} + +int32_t CPWL_ListCtrl::GetTopItem() const { + int32_t nItemIndex = GetItemIndex(GetBTPoint()); + if (!IsItemVisible(nItemIndex) && IsItemVisible(nItemIndex + 1)) + nItemIndex += 1; + + return nItemIndex; +} + +void CPWL_ListCtrl::Empty() { + m_ListItems.clear(); + InvalidateItem(-1); +} + +void CPWL_ListCtrl::Cancel() { + m_aSelItems.DeselectAll(); +} + +int32_t CPWL_ListCtrl::GetItemIndex(const CFX_PointF& point) const { + CFX_PointF pt = OuterToInner(OutToIn(point)); + bool bFirst = true; + bool bLast = true; + for (const auto& pListItem : m_ListItems) { + if (!pListItem) + continue; + CFX_FloatRect rcListItem = pListItem->GetRect(); + if (IsFloatBigger(pt.y, rcListItem.top)) + bFirst = false; + if (IsFloatSmaller(pt.y, rcListItem.bottom)) + bLast = false; + if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) + return &pListItem - &m_ListItems.front(); + } + if (bFirst) + return 0; + if (bLast) + return pdfium::CollectionSize(m_ListItems) - 1; + return -1; +} + +CFX_WideString CPWL_ListCtrl::GetText() const { + if (IsMultipleSel()) + return GetItemText(m_nCaretIndex); + return GetItemText(m_nSelItem); +} + +void CPWL_ListCtrl::AddItem(const CFX_WideString& str) { + auto pListItem = pdfium::MakeUnique(); + pListItem->SetFontMap(m_pFontMap.Get()); + pListItem->SetFontSize(m_fFontSize); + pListItem->SetText(str); + m_ListItems.push_back(std::move(pListItem)); +} + +CPWL_EditImpl* CPWL_ListCtrl::GetItemEdit(int32_t nIndex) const { + if (!pdfium::IndexInBounds(m_ListItems, nIndex) || !m_ListItems[nIndex]) + return nullptr; + return m_ListItems[nIndex]->GetEdit(); +} + +int32_t CPWL_ListCtrl::GetCount() const { + return pdfium::CollectionSize(m_ListItems); +} + +float CPWL_ListCtrl::GetFirstHeight() const { + if (m_ListItems.empty() || !m_ListItems.front()) + return 1.0f; + return m_ListItems.front()->GetItemHeight(); +} + +int32_t CPWL_ListCtrl::GetFirstSelected() const { + int32_t i = 0; + for (const auto& pListItem : m_ListItems) { + if (pListItem && pListItem->IsSelected()) + return i; + ++i; + } + return -1; +} + +int32_t CPWL_ListCtrl::GetLastSelected() const { + for (auto iter = m_ListItems.rbegin(); iter != m_ListItems.rend(); ++iter) { + if (*iter && (*iter)->IsSelected()) + return &*iter - &m_ListItems.front(); + } + return -1; +} + +int32_t CPWL_ListCtrl::FindNext(int32_t nIndex, wchar_t nChar) const { + int32_t nCircleIndex = nIndex; + int32_t sz = pdfium::CollectionSize(m_ListItems); + for (int32_t i = 0; i < sz; i++) { + nCircleIndex++; + if (nCircleIndex >= sz) + nCircleIndex = 0; + + if (Item* pListItem = m_ListItems[nCircleIndex].get()) { + if (FXSYS_toupper(pListItem->GetFirstChar()) == FXSYS_toupper(nChar)) + return nCircleIndex; + } + } + + return nCircleIndex; +} + +bool CPWL_ListCtrl::IsItemSelected(int32_t nIndex) const { + return pdfium::IndexInBounds(m_ListItems, nIndex) && m_ListItems[nIndex] && + m_ListItems[nIndex]->IsSelected(); +} + +void CPWL_ListCtrl::SetItemSelect(int32_t nIndex, bool bSelected) { + if (pdfium::IndexInBounds(m_ListItems, nIndex) && m_ListItems[nIndex]) + m_ListItems[nIndex]->SetSelect(bSelected); +} + +bool CPWL_ListCtrl::IsValid(int32_t nItemIndex) const { + return pdfium::IndexInBounds(m_ListItems, nItemIndex); +} + +CFX_WideString CPWL_ListCtrl::GetItemText(int32_t nIndex) const { + if (pdfium::IndexInBounds(m_ListItems, nIndex) && m_ListItems[nIndex]) + return m_ListItems[nIndex]->GetText(); + return L""; +} diff --git a/fpdfsdk/pdfwindow/cpwl_list_impl.h b/fpdfsdk/pdfwindow/cpwl_list_impl.h new file mode 100644 index 0000000000..167def057e --- /dev/null +++ b/fpdfsdk/pdfwindow/cpwl_list_impl.h @@ -0,0 +1,168 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef FPDFSDK_PDFWINDOW_CPWL_LIST_IMPL_H_ +#define FPDFSDK_PDFWINDOW_CPWL_LIST_IMPL_H_ + +#include +#include +#include + +#include "core/fxcrt/cfx_unowned_ptr.h" +#include "core/fxcrt/fx_coordinates.h" + +class CPWL_EditImpl; +class CPWL_EditImpl_Iterator; +class CPWL_List_Notify; +class IPVT_FontMap; + +class CPLST_Select { + public: + enum State { DESELECTING = -1, NORMAL = 0, SELECTING = 1 }; + using const_iterator = std::map::const_iterator; + + CPLST_Select(); + virtual ~CPLST_Select(); + + void Add(int32_t nItemIndex); + void Add(int32_t nBeginIndex, int32_t nEndIndex); + void Sub(int32_t nItemIndex); + void Sub(int32_t nBeginIndex, int32_t nEndIndex); + void DeselectAll(); + void Done(); + + const_iterator begin() const { return m_Items.begin(); } + const_iterator end() const { return m_Items.end(); } + + private: + std::map m_Items; +}; + +class CPWL_ListCtrl { + public: + CPWL_ListCtrl(); + ~CPWL_ListCtrl(); + + void SetNotify(CPWL_List_Notify* pNotify) { m_pNotify = pNotify; } + void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl); + void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl); + void OnVK_UP(bool bShift, bool bCtrl); + void OnVK_DOWN(bool bShift, bool bCtrl); + void OnVK_LEFT(bool bShift, bool bCtrl); + void OnVK_RIGHT(bool bShift, bool bCtrl); + void OnVK_HOME(bool bShift, bool bCtrl); + void OnVK_END(bool bShift, bool bCtrl); + bool OnChar(uint16_t nChar, bool bShift, bool bCtrl); + + void SetScrollPos(const CFX_PointF& point); + void ScrollToListItem(int32_t nItemIndex); + CFX_FloatRect GetItemRect(int32_t nIndex) const; + int32_t GetCaret() const { return m_nCaretIndex; } + int32_t GetSelect() const { return m_nSelItem; } + int32_t GetTopItem() const; + void SetContentRect(const CFX_FloatRect& rect) { m_rcContent = rect; } + CFX_FloatRect GetContentRect() const; + + int32_t GetItemIndex(const CFX_PointF& point) const; + void AddString(const CFX_WideString& str); + void SetTopItem(int32_t nIndex); + void Select(int32_t nItemIndex); + void SetCaret(int32_t nItemIndex); + void Empty(); + void Cancel(); + CFX_WideString GetText() const; + + void SetFontMap(IPVT_FontMap* pFontMap) { m_pFontMap = pFontMap; } + void SetFontSize(float fFontSize) { m_fFontSize = fFontSize; } + CFX_FloatRect GetPlateRect() const { return m_rcPlate; } + void SetPlateRect(const CFX_FloatRect& rect); + + float GetFontSize() const { return m_fFontSize; } + CPWL_EditImpl* GetItemEdit(int32_t nIndex) const; + int32_t GetCount() const; + bool IsItemSelected(int32_t nIndex) const; + float GetFirstHeight() const; + void SetMultipleSel(bool bMultiple) { m_bMultiple = bMultiple; } + bool IsMultipleSel() const { return m_bMultiple; } + int32_t FindNext(int32_t nIndex, wchar_t nChar) const; + int32_t GetFirstSelected() const; + + private: + class Item { + public: + Item(); + ~Item(); + + void SetFontMap(IPVT_FontMap* pFontMap); + CPWL_EditImpl* GetEdit() const { return m_pEdit.get(); } + + void SetRect(const CFX_FloatRect& rect) { m_rcListItem = rect; } + void SetSelect(bool bSelected) { m_bSelected = bSelected; } + void SetText(const CFX_WideString& text); + void SetFontSize(float fFontSize); + CFX_WideString GetText() const; + + CFX_FloatRect GetRect() const { return m_rcListItem; } + bool IsSelected() const { return m_bSelected; } + float GetItemHeight() const; + uint16_t GetFirstChar() const; + + private: + CPWL_EditImpl_Iterator* GetIterator() const; + + std::unique_ptr m_pEdit; + bool m_bSelected; + CFX_FloatRect m_rcListItem; + }; + + CFX_PointF InToOut(const CFX_PointF& point) const; + CFX_PointF OutToIn(const CFX_PointF& point) const; + CFX_FloatRect InToOut(const CFX_FloatRect& rect) const; + CFX_FloatRect OutToIn(const CFX_FloatRect& rect) const; + + CFX_PointF InnerToOuter(const CFX_PointF& point) const; + CFX_PointF OuterToInner(const CFX_PointF& point) const; + CFX_FloatRect InnerToOuter(const CFX_FloatRect& rect) const; + CFX_FloatRect OuterToInner(const CFX_FloatRect& rect) const; + + void OnVK(int32_t nItemIndex, bool bShift, bool bCtrl); + bool IsValid(int32_t nItemIndex) const; + + void ReArrange(int32_t nItemIndex); + CFX_FloatRect GetItemRectInternal(int32_t nIndex) const; + CFX_FloatRect GetContentRectInternal() const; + void SetMultipleSelect(int32_t nItemIndex, bool bSelected); + void SetSingleSelect(int32_t nItemIndex); + void InvalidateItem(int32_t nItemIndex); + void SelectItems(); + bool IsItemVisible(int32_t nItemIndex) const; + void SetScrollInfo(); + void SetScrollPosY(float fy); + void AddItem(const CFX_WideString& str); + CFX_WideString GetItemText(int32_t nIndex) const; + void SetItemSelect(int32_t nItemIndex, bool bSelected); + int32_t GetLastSelected() const; + CFX_PointF GetBTPoint() const { + return CFX_PointF(m_rcPlate.left, m_rcPlate.top); + } + + CFX_FloatRect m_rcPlate; + CFX_FloatRect m_rcContent; + CFX_UnownedPtr m_pNotify; + bool m_bNotifyFlag; + CFX_PointF m_ptScrollPos; + CPLST_Select m_aSelItems; // for multiple + int32_t m_nSelItem; // for single + int32_t m_nFootIndex; // for multiple + bool m_bCtrlSel; // for multiple + int32_t m_nCaretIndex; // for multiple + std::vector> m_ListItems; + float m_fFontSize; + CFX_UnownedPtr m_pFontMap; + bool m_bMultiple; +}; + +#endif // FPDFSDK_PDFWINDOW_CPWL_LIST_IMPL_H_ -- cgit v1.2.3