// 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/pwl/cpwl_edit_impl.h"

#include <algorithm>
#include <memory>
#include <sstream>
#include <utility>

#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fpdfapi/render/cpdf_renderoptions.h"
#include "core/fpdfapi/render/cpdf_textrenderer.h"
#include "core/fpdfdoc/cpvt_word.h"
#include "core/fpdfdoc/ipvt_fontmap.h"
#include "core/fxcrt/autorestorer.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxge/cfx_fillrenderoptions.h"
#include "core/fxge/cfx_graphstatedata.h"
#include "core/fxge/cfx_pathdata.h"
#include "core/fxge/cfx_renderdevice.h"
#include "fpdfsdk/pwl/cpwl_edit.h"
#include "fpdfsdk/pwl/cpwl_edit_ctrl.h"
#include "fpdfsdk/pwl/cpwl_scroll_bar.h"
#include "fpdfsdk/pwl/ipwl_systemhandler.h"
#include "third_party/base/compiler_specific.h"

namespace {

const int kEditUndoMaxItems = 10000;

void DrawTextString(CFX_RenderDevice* pDevice,
                    const CFX_PointF& pt,
                    CPDF_Font* pFont,
                    float fFontSize,
                    const CFX_Matrix& mtUser2Device,
                    const ByteString& str,
                    FX_ARGB crTextFill) {
  if (!pFont)
    return;

  CFX_PointF pos = mtUser2Device.Transform(pt);
  CPDF_RenderOptions ro;
  ASSERT(ro.GetOptions().bClearType);
  ro.SetColorMode(CPDF_RenderOptions::kNormal);
  CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize,
                                    mtUser2Device, str, crTextFill, 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() = default;

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->GetWordPlace();
}

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() = default;

IPVT_FontMap* CPWL_EditImpl_Provider::GetFontMap() const {
  return m_pFontMap;
}

uint32_t CPWL_EditImpl_Provider::GetCharWidth(int32_t nFontIndex,
                                              uint16_t word) {
  RetainPtr<CPDF_Font> pPDFFont = m_pFontMap->GetPDFFont(nFontIndex);
  if (!pPDFFont)
    return 0;

  uint32_t charcode = pPDFFont->IsUnicodeCompatible()
                          ? pPDFFont->CharCodeFromUnicode(word)
                          : m_pFontMap->CharCodeFromUnicode(nFontIndex, word);

  if (charcode == CPDF_Font::kInvalidCharCode)
    return 0;

  return pPDFFont->GetCharWidthF(charcode);
}

int32_t CPWL_EditImpl_Provider::GetTypeAscent(int32_t nFontIndex) {
  RetainPtr<CPDF_Font> pPDFFont = m_pFontMap->GetPDFFont(nFontIndex);
  return pPDFFont ? pPDFFont->GetTypeAscent() : 0;
}

int32_t CPWL_EditImpl_Provider::GetTypeDescent(int32_t nFontIndex) {
  RetainPtr<CPDF_Font> pPDFFont = m_pFontMap->GetPDFFont(nFontIndex);
  return pPDFFont ? pPDFFont->GetTypeDescent() : 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() = default;

void CPWL_EditImpl_Refresh::BeginRefresh() {
  m_OldLineRects = std::move(m_NewLineRects);
  m_NewLineRects.clear();
  m_RefreshRects.clear();
}

void CPWL_EditImpl_Refresh::Push(const CPVT_WordRange& linerange,
                                 const CFX_FloatRect& rect) {
  m_NewLineRects.emplace_back(CPWL_EditImpl_LineRect(linerange, rect));
}

void CPWL_EditImpl_Refresh::NoAnalyse() {
  for (const auto& lineRect : m_OldLineRects)
    Add(lineRect.m_rcLine);

  for (const auto& lineRect : m_NewLineRects)
    Add(lineRect.m_rcLine);
}

std::vector<CFX_FloatRect>* CPWL_EditImpl_Refresh::GetRefreshRects() {
  return &m_RefreshRects;
}

void CPWL_EditImpl_Refresh::EndRefresh() {
  m_RefreshRects.clear();
}

void CPWL_EditImpl_Refresh::Add(const CFX_FloatRect& new_rect) {
  // Check for overlapped area.
  for (const auto& rect : m_RefreshRects) {
    if (rect.Contains(new_rect))
      return;
  }
  m_RefreshRects.emplace_back(CFX_FloatRect(new_rect));
}

CPWL_EditImpl_Undo::CPWL_EditImpl_Undo()
    : m_nCurUndoPos(0), m_bWorking(false) {}

CPWL_EditImpl_Undo::~CPWL_EditImpl_Undo() = default;

bool CPWL_EditImpl_Undo::CanUndo() const {
  return m_nCurUndoPos > 0;
}

void CPWL_EditImpl_Undo::Undo() {
  ASSERT(!m_bWorking);
  m_bWorking = true;
  int nUndoRemain = 1;
  while (CanUndo() && nUndoRemain > 0) {
    nUndoRemain += m_UndoItemStack[m_nCurUndoPos - 1]->Undo();
    m_nCurUndoPos--;
    nUndoRemain--;
  }
  ASSERT(nUndoRemain == 0);
  ASSERT(m_bWorking);
  m_bWorking = false;
}

bool CPWL_EditImpl_Undo::CanRedo() const {
  return m_nCurUndoPos < m_UndoItemStack.size();
}

void CPWL_EditImpl_Undo::Redo() {
  ASSERT(!m_bWorking);
  m_bWorking = true;
  int nRedoRemain = 1;
  while (CanRedo() && nRedoRemain > 0) {
    nRedoRemain += m_UndoItemStack[m_nCurUndoPos]->Redo();
    m_nCurUndoPos++;
    nRedoRemain--;
  }
  ASSERT(nRedoRemain == 0);
  ASSERT(m_bWorking);
  m_bWorking = false;
}

void CPWL_EditImpl_Undo::AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem) {
  ASSERT(!m_bWorking);
  ASSERT(pItem);
  if (CanRedo())
    RemoveTails();

  if (m_UndoItemStack.size() >= kEditUndoMaxItems)
    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 (CanRedo())
    m_UndoItemStack.pop_back();
}

CFXEU_InsertWord::CFXEU_InsertWord(CPWL_EditImpl* pEdit,
                                   const CPVT_WordPlace& wpOldPlace,
                                   const CPVT_WordPlace& wpNewPlace,
                                   uint16_t word,
                                   int32_t charset)
    : m_pEdit(pEdit),
      m_wpOld(wpOldPlace),
      m_wpNew(wpNewPlace),
      m_Word(word),
      m_nCharset(charset) {
  ASSERT(m_pEdit);
}

CFXEU_InsertWord::~CFXEU_InsertWord() = default;

int CFXEU_InsertWord::Redo() {
  m_pEdit->SelectNone();
  m_pEdit->SetCaret(m_wpOld);
  m_pEdit->InsertWord(m_Word, m_nCharset, false, true);
  return 0;
}

int CFXEU_InsertWord::Undo() {
  m_pEdit->SelectNone();
  m_pEdit->SetCaret(m_wpNew);
  m_pEdit->Backspace(false, true);
  return 0;
}

CFXEU_InsertReturn::CFXEU_InsertReturn(CPWL_EditImpl* pEdit,
                                       const CPVT_WordPlace& wpOldPlace,
                                       const CPVT_WordPlace& wpNewPlace)
    : m_pEdit(pEdit), m_wpOld(wpOldPlace), m_wpNew(wpNewPlace) {
  ASSERT(m_pEdit);
}

CFXEU_InsertReturn::~CFXEU_InsertReturn() = default;

int CFXEU_InsertReturn::Redo() {
  m_pEdit->SelectNone();
  m_pEdit->SetCaret(m_wpOld);
  m_pEdit->InsertReturn(false, true);
  return 0;
}

int CFXEU_InsertReturn::Undo() {
  m_pEdit->SelectNone();
  m_pEdit->SetCaret(m_wpNew);
  m_pEdit->Backspace(false, true);
  return 0;
}

CFXEU_ReplaceSelection::CFXEU_ReplaceSelection(CPWL_EditImpl* pEdit,
                                               bool bIsEnd)
    : m_pEdit(pEdit), m_bEnd(bIsEnd) {
  ASSERT(m_pEdit);
}

CFXEU_ReplaceSelection::~CFXEU_ReplaceSelection() = default;

int CFXEU_ReplaceSelection::Redo() {
  m_pEdit->SelectNone();
  if (IsEnd())
    return 0;
  // Redo ClearSelection, InsertText and ReplaceSelection's end marker
  return 3;
}

int CFXEU_ReplaceSelection::Undo() {
  m_pEdit->SelectNone();
  if (!IsEnd())
    return 0;
  // Undo InsertText, ClearSelection and ReplaceSelection's beginning
  // marker
  return 3;
}

CFXEU_Backspace::CFXEU_Backspace(CPWL_EditImpl* pEdit,
                                 const CPVT_WordPlace& wpOldPlace,
                                 const CPVT_WordPlace& wpNewPlace,
                                 uint16_t word,
                                 int32_t charset)
    : m_pEdit(pEdit),
      m_wpOld(wpOldPlace),
      m_wpNew(wpNewPlace),
      m_Word(word),
      m_nCharset(charset) {
  ASSERT(m_pEdit);
}

CFXEU_Backspace::~CFXEU_Backspace() = default;

int CFXEU_Backspace::Redo() {
  m_pEdit->SelectNone();
  m_pEdit->SetCaret(m_wpOld);
  m_pEdit->Backspace(false, true);
  return 0;
}

int CFXEU_Backspace::Undo() {
  m_pEdit->SelectNone();
  m_pEdit->SetCaret(m_wpNew);
  if (m_wpNew.nSecIndex != m_wpOld.nSecIndex)
    m_pEdit->InsertReturn(false, true);
  else
    m_pEdit->InsertWord(m_Word, m_nCharset, false, true);
  return 0;
}

CFXEU_Delete::CFXEU_Delete(CPWL_EditImpl* pEdit,
                           const CPVT_WordPlace& wpOldPlace,
                           const CPVT_WordPlace& wpNewPlace,
                           uint16_t word,
                           int32_t charset,
                           bool bSecEnd)
    : m_pEdit(pEdit),
      m_wpOld(wpOldPlace),
      m_wpNew(wpNewPlace),
      m_Word(word),
      m_nCharset(charset),
      m_bSecEnd(bSecEnd) {
  ASSERT(m_pEdit);
}

CFXEU_Delete::~CFXEU_Delete() = default;

int CFXEU_Delete::Redo() {
  m_pEdit->SelectNone();
  m_pEdit->SetCaret(m_wpOld);
  m_pEdit->Delete(false, true);
  return 0;
}

int CFXEU_Delete::Undo() {
  m_pEdit->SelectNone();
  m_pEdit->SetCaret(m_wpNew);
  if (m_bSecEnd)
    m_pEdit->InsertReturn(false, true);
  else
    m_pEdit->InsertWord(m_Word, m_nCharset, false, true);
  return 0;
}

CFXEU_Clear::CFXEU_Clear(CPWL_EditImpl* pEdit,
                         const CPVT_WordRange& wrSel,
                         const WideString& swText)
    : m_pEdit(pEdit), m_wrSel(wrSel), m_swText(swText) {
  ASSERT(m_pEdit);
}

CFXEU_Clear::~CFXEU_Clear() = default;

int CFXEU_Clear::Redo() {
  m_pEdit->SelectNone();
  m_pEdit->SetSelection(m_wrSel.BeginPos, m_wrSel.EndPos);
  m_pEdit->Clear(false, true);
  return 0;
}

int CFXEU_Clear::Undo() {
  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);
  return 0;
}

CFXEU_InsertText::CFXEU_InsertText(CPWL_EditImpl* pEdit,
                                   const CPVT_WordPlace& wpOldPlace,
                                   const CPVT_WordPlace& wpNewPlace,
                                   const WideString& swText,
                                   int32_t charset)
    : m_pEdit(pEdit),
      m_wpOld(wpOldPlace),
      m_wpNew(wpNewPlace),
      m_swText(swText),
      m_nCharset(charset) {
  ASSERT(m_pEdit);
}

CFXEU_InsertText::~CFXEU_InsertText() = default;

int CFXEU_InsertText::Redo() {
  m_pEdit->SelectNone();
  m_pEdit->SetCaret(m_wpOld);
  m_pEdit->InsertText(m_swText, m_nCharset, false, true);
  return 0;
}

int CFXEU_InsertText::Undo() {
  m_pEdit->SelectNone();
  m_pEdit->SetSelection(m_wpOld, m_wpNew);
  m_pEdit->Clear(false, true);
  return 0;
}

// static
void CPWL_EditImpl::DrawEdit(CFX_RenderDevice* pDevice,
                             const CFX_Matrix& mtUser2Device,
                             CPWL_EditImpl* pEdit,
                             FX_COLORREF crTextFill,
                             const CFX_FloatRect& rcClip,
                             const CFX_PointF& ptOffset,
                             const CPVT_WordRange* pRange,
                             IPWL_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();
  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())
    pDevice->SetClip_Rect(mtUser2Device.TransformRect(rcClip).ToFxRect());

  CPWL_EditImpl_Iterator* pIterator = pEdit->GetIterator();
  IPVT_FontMap* pFontMap = pEdit->GetFontMap();
  if (!pFontMap)
    return;

  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->IsSelectionImplemented()) {
      crCurFill = crTextFill;
      crOldFill = crCurFill;
    }
    CPVT_Word word;
    if (pIterator->GetWord(word)) {
      if (bSelect) {
        CPVT_Line line;
        pIterator->GetLine(line);

        if (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, &mtUser2Device, nullptr, crSelBK, 0,
                            CFX_FillRenderOptions::WindingOptions());
        }
      }

      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).Get(), fFontSize,
                           mtUser2Device, ByteString(sTextBuf), crOldFill);

            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).Get(), fFontSize,
            mtUser2Device,
            pEdit->GetPDFWordString(word.nFontIndex, word.Word, SubWord),
            crCurFill);
      }
      oldplace = place;
    }
  }

  if (sTextBuf.tellp() > 0) {
    DrawTextString(pDevice,
                   CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
                   pFontMap->GetPDFFont(nFontIndex).Get(), fFontSize,
                   mtUser2Device, ByteString(sTextBuf), crOldFill);
  }
}

CPWL_EditImpl::CPWL_EditImpl()
    : m_pVT(std::make_unique<CPDF_VariableText>()),
      m_bEnableScroll(false),
      m_nAlignment(0),
      m_bNotifyFlag(false),
      m_bEnableOverflow(false),
      m_bEnableRefresh(true),
      m_bEnableUndo(true) {}

CPWL_EditImpl::~CPWL_EditImpl() = default;

void CPWL_EditImpl::Initialize() {
  m_pVT->Initialize();
  SetCaret(m_pVT->GetBeginWordPlace());
  SetCaretOrigin();
}

void CPWL_EditImpl::SetFontMap(IPVT_FontMap* pFontMap) {
  m_pVTProvider = std::make_unique<CPWL_EditImpl_Provider>(pFontMap);
  m_pVT->SetProvider(m_pVTProvider.get());
}

void CPWL_EditImpl::SetNotify(CPWL_EditCtrl* pNotify) {
  m_pNotify = pNotify;
}

void CPWL_EditImpl::SetOperationNotify(CPWL_Edit* pOperationNotify) {
  m_pOperationNotify = pOperationNotify;
}

CPWL_EditImpl_Iterator* CPWL_EditImpl::GetIterator() {
  if (!m_pIterator) {
    m_pIterator =
        std::make_unique<CPWL_EditImpl_Iterator>(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();
}

std::pair<int32_t, int32_t> CPWL_EditImpl::GetSelection() const {
  if (!m_pVT->IsValid())
    return std::make_pair(-1, -1);

  if (m_SelState.IsEmpty()) {
    return std::make_pair(m_pVT->WordPlaceToWordIndex(m_wpCaret),
                          m_pVT->WordPlaceToWordIndex(m_wpCaret));
  }
  if (m_SelState.BeginPos < m_SelState.EndPos) {
    return std::make_pair(m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos),
                          m_pVT->WordPlaceToWordIndex(m_SelState.EndPos));
  }
  return std::make_pair(m_pVT->WordPlaceToWordIndex(m_SelState.EndPos),
                        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;
}

WideString CPWL_EditImpl::GetText() const {
  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->GetWordPlace();
  while (pIterator->NextWord()) {
    CPVT_WordPlace place = pIterator->GetWordPlace();
    if (pIterator->GetWord(wordinfo))
      swRet += wordinfo.Word;
    if (oldplace.nSecIndex != place.nSecIndex)
      swRet += L"\r\n";
    oldplace = place;
  }
  return swRet;
}

WideString CPWL_EditImpl::GetRangeText(const CPVT_WordRange& range) const {
  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->GetWordPlace();
    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;
}

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 WideString& sText) {
  Clear();
  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, true, true);
}

bool CPWL_EditImpl::InsertReturn() {
  return InsertReturn(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 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());
}

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;

  AutoRestorer<bool> 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) {
          AutoRestorer<bool> 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) {
        AutoRestorer<bool> restorer(&m_bNotifyFlag);
        m_bNotifyFlag = true;
        if (std::vector<CFX_FloatRect>* pRects = m_Refresh.GetRefreshRects()) {
          for (auto& rect : *pRects)
            m_pNotify->InvalidateRect(&rect);
        }
      }
    }

    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->GetWordPlace();
    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) {
          AutoRestorer<bool> 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) {
          AutoRestorer<bool> 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;
      }

      AutoRestorer<bool> 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,
                               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)));
  m_SelState.Set(m_wpCaret, m_wpCaret);
  if (m_wpCaret == m_wpOldCaret)
    return false;

  if (bAddUndo && m_bEnableUndo) {
    AddEditUndoItem(std::make_unique<CFXEU_InsertWord>(
        this, m_wpOldCaret, m_wpCaret, word, charset));
  }
  if (bPaint)
    PaintInsertText(m_wpOldCaret, m_wpCaret);

  if (m_pOperationNotify)
    m_pOperationNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);

  return true;
}

bool CPWL_EditImpl::InsertReturn(bool bAddUndo, bool bPaint) {
  if (IsTextOverflow() || !m_pVT->IsValid())
    return false;

  m_pVT->UpdateWordPlace(m_wpCaret);
  SetCaret(m_pVT->InsertSection(m_wpCaret));
  m_SelState.Set(m_wpCaret, m_wpCaret);
  if (m_wpCaret == m_wpOldCaret)
    return false;

  if (bAddUndo && m_bEnableUndo) {
    AddEditUndoItem(
        std::make_unique<CFXEU_InsertReturn>(this, m_wpOldCaret, m_wpCaret));
  }
  if (bPaint) {
    RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
    ScrollToCaret();
    Refresh();
    SetCaretOrigin();
    SetCaretInfo();
  }
  if (m_pOperationNotify)
    m_pOperationNotify->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_Word word;
  if (bAddUndo) {
    CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
    pIterator->SetAt(m_wpCaret);
    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) {
    AddEditUndoItem(std::make_unique<CFXEU_Backspace>(
        this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset));
  }
  if (bPaint) {
    RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret));
    ScrollToCaret();
    Refresh();
    SetCaretOrigin();
    SetCaretInfo();
  }
  if (m_pOperationNotify)
    m_pOperationNotify->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_Word word;
  if (bAddUndo) {
    CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator();
    pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
    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(std::make_unique<CFXEU_Delete>(
          this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, bSecEnd));
    } else {
      AddEditUndoItem(std::make_unique<CFXEU_Delete>(
          this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, bSecEnd));
    }
  }
  if (bPaint) {
    RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
    ScrollToCaret();
    Refresh();
    SetCaretOrigin();
    SetCaretInfo();
  }
  if (m_pOperationNotify)
    m_pOperationNotify->OnDelete(m_wpCaret, m_wpOldCaret);

  return true;
}

bool CPWL_EditImpl::Clear() {
  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(
        std::make_unique<CFXEU_Clear>(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_pOperationNotify)
    m_pOperationNotify->OnClear(m_wpCaret, m_wpOldCaret);

  return true;
}

bool CPWL_EditImpl::InsertText(const 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(std::make_unique<CFXEU_InsertText>(
        this, m_wpOldCaret, m_wpCaret, sText, charset));
  }
  if (bPaint)
    PaintInsertText(m_wpOldCaret, m_wpCaret);

  if (m_pOperationNotify)
    m_pOperationNotify->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();
  }
}

void CPWL_EditImpl::ReplaceSelection(const WideString& text) {
  AddEditUndoItem(std::make_unique<CFXEU_ReplaceSelection>(this, false));
  ClearSelection();
  InsertText(text, FX_CHARSET_Default);
  AddEditUndoItem(std::make_unique<CFXEU_ReplaceSelection>(this, true));
}

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;
}

CPVT_WordPlace CPWL_EditImpl::DoInsertText(const CPVT_WordPlace& place,
                                           const 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 '\r':
          wp = m_pVT->InsertSection(wp);
          if (i + 1 < sz && sText[i + 1] == '\n')
            i++;
          break;
        case '\n':
          wp = m_pVT->InsertSection(wp);
          break;
        case '\t':
          word = ' ';
          FALLTHROUGH;
        default:
          wp =
              m_pVT->InsertWord(wp, word, GetCharSetFromUnicode(word, charset));
          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<IFX_Edit_UndoItem> pEditUndoItem) {
  m_Undo.AddItem(std::move(pEditUndoItem));
}

ByteString CPWL_EditImpl::GetPDFWordString(int32_t nFontIndex,
                                           uint16_t Word,
                                           uint16_t SubWord) {
  IPVT_FontMap* pFontMap = GetFontMap();
  RetainPtr<CPDF_Font> pPDFFont = pFontMap->GetPDFFont(nFontIndex);
  if (!pPDFFont)
    return ByteString();

  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_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;
}
