// 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/include/fxet_edit.h"

#include <algorithm>

#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobjectholder.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h"
#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
#include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h"
#include "core/fpdfapi/fpdf_render/include/cpdf_textrenderer.h"
#include "core/fpdfdoc/include/cpvt_section.h"
#include "core/fpdfdoc/include/cpvt_word.h"
#include "core/fpdfdoc/include/ipvt_fontmap.h"
#include "core/fxge/include/cfx_graphstatedata.h"
#include "core/fxge/include/cfx_pathdata.h"
#include "core/fxge/include/cfx_renderdevice.h"
#include "fpdfsdk/cfx_systemhandler.h"
#include "fpdfsdk/fxedit/include/fx_edit.h"
#include "fpdfsdk/fxedit/include/fxet_edit.h"
#include "fpdfsdk/pdfwindow/PWL_Edit.h"
#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"

namespace {

const int kEditUndoMaxItems = 10000;

CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) {
  if (strWords.GetLength() > 0)
    return PDF_EncodeString(strWords) + " Tj\n";
  return CFX_ByteString();
}

CFX_ByteString GetFontSetString(IPVT_FontMap* pFontMap,
                                int32_t nFontIndex,
                                FX_FLOAT fFontSize) {
  if (!pFontMap)
    return CFX_ByteString();

  CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
  if (sFontAlias.GetLength() <= 0 || fFontSize <= 0)
    return CFX_ByteString();

  CFX_ByteTextBuf sRet;
  sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
  return sRet.MakeString();
}

void DrawTextString(CFX_RenderDevice* pDevice,
                    const CFX_FloatPoint& pt,
                    CPDF_Font* pFont,
                    FX_FLOAT fFontSize,
                    CFX_Matrix* pUser2Device,
                    const CFX_ByteString& str,
                    FX_ARGB crTextFill,
                    FX_ARGB crTextStroke,
                    int32_t nHorzScale) {
  FX_FLOAT x = pt.x, y = pt.y;
  pUser2Device->Transform(x, y);

  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 = RENDER_COLOR_NORMAL;

      if (crTextStroke != 0) {
        CFX_FloatPoint pt1;
        CFX_FloatPoint pt2;
        pUser2Device->Transform(pt1.x, pt1.y);
        pUser2Device->Transform(pt2.x, pt2.y);
        CFX_GraphStateData gsd;
        gsd.m_LineWidth =
            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));

        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
                                          str, crTextFill, crTextStroke, &gsd,
                                          &ro);
      } else {
        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
                                          str, crTextFill, 0, nullptr, &ro);
      }
    } else {
      CPDF_RenderOptions ro;
      ro.m_Flags = RENDER_CLEARTYPE;
      ro.m_ColorMode = RENDER_COLOR_NORMAL;

      if (crTextStroke != 0) {
        CFX_FloatPoint pt1;
        CFX_FloatPoint pt2;
        pUser2Device->Transform(pt1.x, pt1.y);
        pUser2Device->Transform(pt2.x, pt2.y);
        CFX_GraphStateData gsd;
        gsd.m_LineWidth =
            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));

        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
                                          pUser2Device, str, crTextFill,
                                          crTextStroke, &gsd, &ro);
      } else {
        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
                                          pUser2Device, str, crTextFill, 0,
                                          nullptr, &ro);
      }
    }
  }
}

CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjectHolder* pObjectHolder,
                                         FX_COLORREF crText,
                                         CPDF_Font* pFont,
                                         FX_FLOAT fFontSize,
                                         FX_FLOAT fCharSpace,
                                         int32_t nHorzScale,
                                         const CFX_FloatPoint& point,
                                         const CFX_ByteString& text) {
  std::unique_ptr<CPDF_TextObject> pTxtObj(new CPDF_TextObject);
  pTxtObj->m_TextState.SetFont(pFont);
  pTxtObj->m_TextState.SetFontSize(fFontSize);
  pTxtObj->m_TextState.SetCharSpace(fCharSpace);
  pTxtObj->m_TextState.SetWordSpace(0);
  pTxtObj->m_TextState.SetTextMode(TextRenderingMode::MODE_FILL);

  FX_FLOAT* matrix = pTxtObj->m_TextState.GetMutableMatrix();
  matrix[0] = nHorzScale / 100.0f;
  matrix[1] = 0;
  matrix[2] = 0;
  matrix[3] = 1;

  FX_FLOAT rgb[3];
  rgb[0] = FXARGB_R(crText) / 255.0f;
  rgb[1] = FXARGB_G(crText) / 255.0f;
  rgb[2] = FXARGB_B(crText) / 255.0f;
  pTxtObj->m_ColorState.SetFillColor(
      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
  pTxtObj->m_ColorState.SetStrokeColor(
      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);

  pTxtObj->SetPosition(point.x, point.y);
  pTxtObj->SetText(text);

  CPDF_TextObject* pRet = pTxtObj.get();
  pObjectHolder->GetPageObjectList()->push_back(std::move(pTxtObj));
  return pRet;
}

}  // 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() {}

FX_BOOL CFX_Edit_Iterator::NextWord() {
  return m_pVTIterator->NextWord();
}

FX_BOOL CFX_Edit_Iterator::PrevWord() {
  return m_pVTIterator->PrevWord();
}

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

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

FX_BOOL CFX_Edit_Iterator::GetSection(CPVT_Section& section) const {
  ASSERT(m_pEdit);

  if (m_pVTIterator->GetSection(section)) {
    section.rcSection = m_pEdit->VTToEdit(section.rcSection);
    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() {
  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;
}

FX_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.Empty();
  m_OldLineRects = 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);
  }
}

void CFX_Edit_Refresh::AddRefresh(const CFX_FloatRect& rect) {
  m_RefreshRects.Add(rect);
}

const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const {
  return &m_RefreshRects;
}

void CFX_Edit_Refresh::EndRefresh() {
  m_RefreshRects.Empty();
}

CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize)
    : m_nCurUndoPos(0),
      m_nBufSize(nBufsize),
      m_bModified(FALSE),
      m_bVirgin(TRUE),
      m_bWorking(FALSE) {}

CFX_Edit_Undo::~CFX_Edit_Undo() {
  Reset();
}

FX_BOOL CFX_Edit_Undo::CanUndo() const {
  return m_nCurUndoPos > 0;
}

void CFX_Edit_Undo::Undo() {
  m_bWorking = TRUE;

  if (m_nCurUndoPos > 0) {
    IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(m_nCurUndoPos - 1);
    pItem->Undo();

    m_nCurUndoPos--;
    m_bModified = (m_nCurUndoPos != 0);
  }

  m_bWorking = FALSE;
}

FX_BOOL CFX_Edit_Undo::CanRedo() const {
  return m_nCurUndoPos < m_UndoItemStack.GetSize();
}

void CFX_Edit_Undo::Redo() {
  m_bWorking = TRUE;

  int32_t nStackSize = m_UndoItemStack.GetSize();

  if (m_nCurUndoPos < nStackSize) {
    IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(m_nCurUndoPos);
    pItem->Redo();

    m_nCurUndoPos++;
    m_bModified = (m_nCurUndoPos != 0);
  }

  m_bWorking = FALSE;
}

void CFX_Edit_Undo::AddItem(IFX_Edit_UndoItem* pItem) {
  ASSERT(!m_bWorking);
  ASSERT(pItem);
  ASSERT(m_nBufSize > 1);

  if (m_nCurUndoPos < m_UndoItemStack.GetSize())
    RemoveTails();

  if (m_UndoItemStack.GetSize() >= m_nBufSize) {
    RemoveHeads();
    m_bVirgin = FALSE;
  }

  m_UndoItemStack.Add(pItem);
  m_nCurUndoPos = m_UndoItemStack.GetSize();

  m_bModified = (m_nCurUndoPos != 0);
}

FX_BOOL CFX_Edit_Undo::IsModified() const {
  return m_bVirgin ? m_bModified : TRUE;
}

void CFX_Edit_Undo::RemoveHeads() {
  ASSERT(m_UndoItemStack.GetSize() > 1);

  delete m_UndoItemStack.GetAt(0);
  m_UndoItemStack.RemoveAt(0);
}

void CFX_Edit_Undo::RemoveTails() {
  for (int32_t i = m_UndoItemStack.GetSize() - 1; i >= m_nCurUndoPos; i--) {
    delete m_UndoItemStack.GetAt(i);
    m_UndoItemStack.RemoveAt(i);
  }
}

void CFX_Edit_Undo::Reset() {
  for (int32_t i = 0, sz = m_UndoItemStack.GetSize(); i < sz; i++) {
    delete m_UndoItemStack.GetAt(i);
  }
  m_nCurUndoPos = 0;
  m_UndoItemStack.RemoveAll();
}

CFX_Edit_UndoItem::CFX_Edit_UndoItem() : m_bFirst(TRUE), m_bLast(TRUE) {}

CFX_Edit_UndoItem::~CFX_Edit_UndoItem() {}

CFX_WideString CFX_Edit_UndoItem::GetUndoTitle() {
  return L"";
}

void CFX_Edit_UndoItem::SetFirst(FX_BOOL bFirst) {
  m_bFirst = bFirst;
}

void CFX_Edit_UndoItem::SetLast(FX_BOOL bLast) {
  m_bLast = bLast;
}

FX_BOOL CFX_Edit_UndoItem::IsLast() {
  return m_bLast;
}

CFX_Edit_GroupUndoItem::CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle)
    : m_sTitle(sTitle) {}

CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem() {
  for (int i = 0, sz = m_Items.GetSize(); i < sz; i++) {
    delete m_Items[i];
  }

  m_Items.RemoveAll();
}

void CFX_Edit_GroupUndoItem::AddUndoItem(CFX_Edit_UndoItem* pUndoItem) {
  pUndoItem->SetFirst(FALSE);
  pUndoItem->SetLast(FALSE);

  m_Items.Add(pUndoItem);

  if (m_sTitle.IsEmpty())
    m_sTitle = pUndoItem->GetUndoTitle();
}

void CFX_Edit_GroupUndoItem::UpdateItems() {
  if (m_Items.GetSize() > 0) {
    CFX_Edit_UndoItem* pFirstItem = m_Items[0];
    pFirstItem->SetFirst(TRUE);

    CFX_Edit_UndoItem* pLastItem = m_Items[m_Items.GetSize() - 1];
    pLastItem->SetLast(TRUE);
  }
}

void CFX_Edit_GroupUndoItem::Undo() {
  for (int i = m_Items.GetSize() - 1; i >= 0; i--) {
    CFX_Edit_UndoItem* pUndoItem = m_Items[i];
    pUndoItem->Undo();
  }
}

void CFX_Edit_GroupUndoItem::Redo() {
  for (int i = 0, sz = m_Items.GetSize(); i < sz; i++) {
    CFX_Edit_UndoItem* pUndoItem = m_Items[i];
    pUndoItem->Redo();
  }
}

CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle() {
  return m_sTitle;
}

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) {
    m_pEdit->SelectNone();
    m_pEdit->SetCaret(m_wpOld);
    m_pEdit->Backspace(FALSE, TRUE);
  }
}

void CFXEU_Backspace::Undo() {
  if (m_pEdit) {
    m_pEdit->SelectNone();
    m_pEdit->SetCaret(m_wpNew);
    if (m_wpNew.SecCmp(m_wpOld) != 0) {
      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,
                           FX_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->SetSel(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, DEFAULT_CHARSET, FALSE, TRUE);
    m_pEdit->SetSel(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->SetSel(m_wpOld, m_wpNew);
    m_pEdit->Clear(FALSE, TRUE);
  }
}

// static
CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit,
                                                 const CFX_FloatPoint& ptOffset,
                                                 const CPVT_WordRange* pRange,
                                                 FX_BOOL bContinuous,
                                                 uint16_t SubWord) {
  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
  if (pRange)
    pIterator->SetAt(pRange->BeginPos);
  else
    pIterator->SetAt(0);

  CFX_ByteTextBuf sEditStream;
  CFX_ByteTextBuf sWords;
  int32_t nCurFontIndex = -1;
  CFX_FloatPoint ptOld;
  CFX_FloatPoint ptNew;
  CPVT_WordPlace oldplace;

  while (pIterator->NextWord()) {
    CPVT_WordPlace place = pIterator->GetAt();
    if (pRange && place.WordCmp(pRange->EndPos) > 0)
      break;

    if (bContinuous) {
      if (place.LineCmp(oldplace) != 0) {
        if (sWords.GetSize() > 0) {
          sEditStream << GetWordRenderString(sWords.MakeString());
          sWords.Clear();
        }

        CPVT_Word word;
        if (pIterator->GetWord(word)) {
          ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x,
                                 word.ptWord.y + ptOffset.y);
        } else {
          CPVT_Line line;
          pIterator->GetLine(line);
          ptNew = CFX_FloatPoint(line.ptLine.x + ptOffset.x,
                                 line.ptLine.y + ptOffset.y);
        }

        if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
          sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
                      << " Td\n";

          ptOld = ptNew;
        }
      }

      CPVT_Word word;
      if (pIterator->GetWord(word)) {
        if (word.nFontIndex != nCurFontIndex) {
          if (sWords.GetSize() > 0) {
            sEditStream << GetWordRenderString(sWords.MakeString());
            sWords.Clear();
          }
          sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
                                          word.fFontSize);
          nCurFontIndex = word.nFontIndex;
        }

        sWords << GetPDFWordString(pEdit->GetFontMap(), nCurFontIndex,
                                   word.Word, SubWord);
      }

      oldplace = place;
    } else {
      CPVT_Word word;
      if (pIterator->GetWord(word)) {
        ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x,
                               word.ptWord.y + ptOffset.y);

        if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
          sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
                      << " Td\n";
          ptOld = ptNew;
        }

        if (word.nFontIndex != nCurFontIndex) {
          sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
                                          word.fFontSize);
          nCurFontIndex = word.nFontIndex;
        }

        sEditStream << GetWordRenderString(GetPDFWordString(
            pEdit->GetFontMap(), nCurFontIndex, word.Word, SubWord));
      }
    }
  }

  if (sWords.GetSize() > 0) {
    sEditStream << GetWordRenderString(sWords.MakeString());
    sWords.Clear();
  }

  CFX_ByteTextBuf sAppStream;
  if (sEditStream.GetSize() > 0) {
    int32_t nHorzScale = pEdit->GetHorzScale();
    if (nHorzScale != 100) {
      sAppStream << nHorzScale << " Tz\n";
    }

    FX_FLOAT fCharSpace = pEdit->GetCharSpace();
    if (!IsFloatZero(fCharSpace)) {
      sAppStream << fCharSpace << " Tc\n";
    }

    sAppStream << sEditStream;
  }

  return sAppStream.MakeString();
}

// static
CFX_ByteString CFX_Edit::GetSelectAppearanceStream(
    CFX_Edit* pEdit,
    const CFX_FloatPoint& ptOffset,
    const CPVT_WordRange* pRange) {
  if (!pRange || !pRange->IsExist())
    return CFX_ByteString();

  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
  pIterator->SetAt(pRange->BeginPos);

  CFX_ByteTextBuf sRet;
  while (pIterator->NextWord()) {
    CPVT_WordPlace place = pIterator->GetAt();
    if (place.WordCmp(pRange->EndPos) > 0)
      break;

    CPVT_Word word;
    CPVT_Line line;
    if (pIterator->GetWord(word) && pIterator->GetLine(line)) {
      sRet << word.ptWord.x + ptOffset.x << " "
           << line.ptLine.y + line.fLineDescent << " " << word.fWidth << " "
           << line.fLineAscent - line.fLineDescent << " re\nf\n";
    }
  }

  return sRet.MakeString();
}

// static
void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice,
                        CFX_Matrix* pUser2Device,
                        CFX_Edit* pEdit,
                        FX_COLORREF crTextFill,
                        FX_COLORREF crTextStroke,
                        const CFX_FloatRect& rcClip,
                        const CFX_FloatPoint& ptOffset,
                        const CPVT_WordRange* pRange,
                        CFX_SystemHandler* pSystemHandler,
                        void* pFFLData) {
  const bool bContinuous =
      pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
  uint16_t SubWord = pEdit->GetPasswordChar();
  FX_FLOAT fFontSize = pEdit->GetFontSize();
  CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
  int32_t nHorzScale = pEdit->GetHorzScale();

  FX_COLORREF crCurFill = crTextFill;
  FX_COLORREF crOldFill = crCurFill;

  FX_BOOL bSelect = FALSE;
  const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
  const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);

  CFX_ByteTextBuf sTextBuf;
  int32_t nFontIndex = -1;
  CFX_FloatPoint ptBT;
  pDevice->SaveState();
  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.WordCmp(pRange->EndPos) > 0)
        break;

      if (wrSelect.IsExist()) {
        bSelect = place.WordCmp(wrSelect.BeginPos) > 0 &&
                  place.WordCmp(wrSelect.EndPos) <= 0;
        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.GetLength() > 0) {
              DrawTextString(
                  pDevice,
                  CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
                  pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
                  sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);

              sTextBuf.Clear();
            }
            nFontIndex = word.nFontIndex;
            ptBT = word.ptWord;
            crOldFill = crCurFill;
          }

          sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word,
                                       SubWord)
                          .AsStringC();
        } else {
          DrawTextString(
              pDevice, CFX_FloatPoint(word.ptWord.x + ptOffset.x,
                                      word.ptWord.y + ptOffset.y),
              pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
              GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord),
              crCurFill, crTextStroke, nHorzScale);
        }
        oldplace = place;
      }
    }

    if (sTextBuf.GetLength() > 0) {
      DrawTextString(
          pDevice, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
          pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
          sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);
    }
  }

  pDevice->RestoreState(false);
}

// static
void CFX_Edit::GeneratePageObjects(
    CPDF_PageObjectHolder* pObjectHolder,
    CFX_Edit* pEdit,
    const CFX_FloatPoint& ptOffset,
    const CPVT_WordRange* pRange,
    FX_COLORREF crText,
    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
  FX_FLOAT fFontSize = pEdit->GetFontSize();

  int32_t nOldFontIndex = -1;

  CFX_ByteTextBuf sTextBuf;
  CFX_FloatPoint ptBT(0.0f, 0.0f);

  ObjArray.RemoveAll();

  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.WordCmp(pRange->EndPos) > 0)
        break;

      CPVT_Word word;
      if (pIterator->GetWord(word)) {
        if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex) {
          if (sTextBuf.GetLength() > 0) {
            ObjArray.Add(AddTextObjToPageObjects(
                pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex),
                fFontSize, 0.0f, 100,
                CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
                sTextBuf.MakeString()));

            sTextBuf.Clear();
          }

          ptBT = word.ptWord;
          nOldFontIndex = word.nFontIndex;
        }

        sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0)
                        .AsStringC();
        oldplace = place;
      }
    }

    if (sTextBuf.GetLength() > 0) {
      ObjArray.Add(AddTextObjToPageObjects(
          pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize,
          0.0f, 100, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
          sTextBuf.MakeString()));
    }
  }
}

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),
      m_pGroupUndoItem(nullptr) {}

CFX_Edit::~CFX_Edit() {
  ASSERT(!m_pGroupUndoItem);
}

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

void CFX_Edit::SetFontMap(IPVT_FontMap* pFontMap) {
  m_pVTProvider.reset(new CFX_Edit_Provider(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.reset(new CFX_Edit_Iterator(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_FloatPoint(rect.left, rect.top);
  Paint();
}

void CFX_Edit::SetAlignmentH(int32_t nFormat, FX_BOOL bPaint) {
  m_pVT->SetAlignment(nFormat);
  if (bPaint)
    Paint();
}

void CFX_Edit::SetAlignmentV(int32_t nFormat, FX_BOOL bPaint) {
  m_nAlignment = nFormat;
  if (bPaint)
    Paint();
}

void CFX_Edit::SetPasswordChar(uint16_t wSubWord, FX_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(FX_FLOAT fCharSpace) {
  m_pVT->SetCharSpace(fCharSpace);
  Paint();
}

void CFX_Edit::SetMultiLine(FX_BOOL bMultiLine, FX_BOOL bPaint) {
  m_pVT->SetMultiLine(bMultiLine);
  if (bPaint)
    Paint();
}

void CFX_Edit::SetAutoReturn(FX_BOOL bAuto, FX_BOOL bPaint) {
  m_pVT->SetAutoReturn(bAuto);
  if (bPaint)
    Paint();
}

void CFX_Edit::SetAutoFontSize(FX_BOOL bAuto, FX_BOOL bPaint) {
  m_pVT->SetAutoFontSize(bAuto);
  if (bPaint)
    Paint();
}

void CFX_Edit::SetFontSize(FX_FLOAT fFontSize) {
  m_pVT->SetFontSize(fFontSize);
  Paint();
}

void CFX_Edit::SetAutoScroll(FX_BOOL bAuto, FX_BOOL bPaint) {
  m_bEnableScroll = bAuto;
  if (bPaint)
    Paint();
}

void CFX_Edit::SetTextOverflow(FX_BOOL bAllowed, FX_BOOL bPaint) {
  m_bEnableOverflow = bAllowed;
  if (bPaint)
    Paint();
}

void CFX_Edit::SetSel(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) {
        SetSel(m_pVT->WordIndexToWordPlace(nStartChar),
               m_pVT->WordIndexToWordPlace(nEndChar));
      } else {
        SetSel(m_pVT->WordIndexToWordPlace(nEndChar),
               m_pVT->WordIndexToWordPlace(nStartChar));
      }
    }
  }
}

void CFX_Edit::SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
  if (m_pVT->IsValid()) {
    SelectNone();

    m_SelState.Set(begin, end);

    SetCaret(m_SelState.EndPos);

    if (m_SelState.IsExist()) {
      ScrollToCaret();
      Refresh();
      SetCaretInfo();
    } else {
      ScrollToCaret();
      SetCaretInfo();
    }
  }
}

void CFX_Edit::GetSel(int32_t& nStartChar, int32_t& nEndChar) const {
  nStartChar = -1;
  nEndChar = -1;

  if (m_pVT->IsValid()) {
    if (m_SelState.IsExist()) {
      if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0) {
        nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
        nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
      } else {
        nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
        nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
      }
    } else {
      nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
      nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
    }
  }
}

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.SecCmp(place) != 0)
      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.WordCmp(wrTemp.EndPos) > 0)
      break;

    if (pIterator->GetWord(wordinfo))
      swRet += wordinfo.Word;

    if (oldplace.SecCmp(place) != 0)
      swRet += L"\r\n";

    oldplace = place;
  }

  return swRet;
}

CFX_WideString CFX_Edit::GetSelText() const {
  return GetRangeText(m_SelState.ConvertToWordRange());
}

int32_t CFX_Edit::GetTotalWords() const {
  return m_pVT->GetTotalWords();
}

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, DEFAULT_CHARSET);
  Paint();
}

FX_BOOL CFX_Edit::InsertWord(uint16_t word, int32_t charset) {
  return InsertWord(word, charset, nullptr, TRUE, TRUE);
}

FX_BOOL CFX_Edit::InsertReturn() {
  return InsertReturn(nullptr, nullptr, TRUE, TRUE);
}

FX_BOOL CFX_Edit::Backspace() {
  return Backspace(TRUE, TRUE);
}

FX_BOOL CFX_Edit::Delete() {
  return Delete(TRUE, TRUE);
}

FX_BOOL CFX_Edit::Clear() {
  return Clear(TRUE, TRUE);
}

FX_BOOL CFX_Edit::InsertText(const CFX_WideString& sText, int32_t charset) {
  return InsertText(sText, charset, TRUE, TRUE);
}

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

FX_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_FloatPoint(rcPlate.left, rcPlate.top)));
    CPVT_WordPlace place2 = m_pVT->SearchWordPlace(
        EditToVT(CFX_FloatPoint(rcPlate.right, rcPlate.bottom)));

    return CPVT_WordRange(place1, place2);
  }

  return CPVT_WordRange();
}

CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_FloatPoint& 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()) {
      if (!m_bNotifyFlag) {
        m_bNotifyFlag = TRUE;
        m_pNotify->IOnContentChange(rcContent);
        m_bNotifyFlag = FALSE;
      }
      m_rcOldContent = rcContent;
    }
  }
}

void CFX_Edit::SelectAll() {
  if (m_pVT->IsValid()) {
    m_SelState = CFX_Edit_Select(GetWholeWordRange());
    SetCaret(m_SelState.EndPos);

    ScrollToCaret();
    Refresh();
    SetCaretInfo();
  }
}

void CFX_Edit::SelectNone() {
  if (m_pVT->IsValid()) {
    if (m_SelState.IsExist()) {
      m_SelState.Default();
      Refresh();
    }
  }
}

FX_BOOL CFX_Edit::IsSelected() const {
  return m_SelState.IsExist();
}

CFX_FloatPoint CFX_Edit::VTToEdit(const CFX_FloatPoint& point) const {
  CFX_FloatRect rcContent = m_pVT->GetContentRect();
  CFX_FloatRect rcPlate = m_pVT->GetPlateRect();

  FX_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_FloatPoint(point.x - (m_ptScrollPos.x - rcPlate.left),
                        point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
}

CFX_FloatPoint CFX_Edit::EditToVT(const CFX_FloatPoint& point) const {
  CFX_FloatRect rcContent = m_pVT->GetContentRect();
  CFX_FloatRect rcPlate = m_pVT->GetPlateRect();

  FX_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_FloatPoint(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_FloatPoint ptLeftBottom =
      VTToEdit(CFX_FloatPoint(rect.left, rect.bottom));
  CFX_FloatPoint ptRightTop = VTToEdit(CFX_FloatPoint(rect.right, rect.top));

  return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x,
                       ptRightTop.y);
}

void CFX_Edit::SetScrollInfo() {
  if (m_pNotify) {
    CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
    CFX_FloatRect rcContent = m_pVT->GetContentRect();

    if (!m_bNotifyFlag) {
      m_bNotifyFlag = TRUE;
      m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
                                   rcContent.bottom, rcContent.top,
                                   rcPlate.Height() / 3, rcPlate.Height());
      m_bNotifyFlag = FALSE;
    }
  }
}

void CFX_Edit::SetScrollPosX(FX_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(FX_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) {
          m_bNotifyFlag = TRUE;
          m_pNotify->IOnSetScrollPosY(fy);
          m_bNotifyFlag = FALSE;
        }
      }
    }
  }
}

void CFX_Edit::SetScrollPos(const CFX_FloatPoint& point) {
  SetScrollPosX(point.x);
  SetScrollPosY(point.y);
  SetScrollLimit();
  SetCaretInfo();
}

CFX_FloatPoint 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_FloatPoint ptHead;
  CFX_FloatPoint 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_FloatPoint ptHeadEdit = VTToEdit(ptHead);
  CFX_FloatPoint 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) {
        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->IOnInvalidateRect(pRects->GetAt(i));
        }
        m_bNotifyFlag = FALSE;
      }
    }

    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.WordCmp(wrTemp.EndPos) > 0)
      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) {
          m_bNotifyFlag = TRUE;
          CFX_FloatRect rcRefresh = VTToEdit(rcWord);
          m_pNotify->IOnInvalidateRect(&rcRefresh);
          m_bNotifyFlag = FALSE;
        }
      }
    } 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) {
          m_bNotifyFlag = TRUE;
          CFX_FloatRect rcRefresh = VTToEdit(rcLine);
          m_pNotify->IOnInvalidateRect(&rcRefresh);
          m_bNotifyFlag = FALSE;
        }
      }

      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_FloatPoint ptHead;
      CFX_FloatPoint 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;
      }

      m_bNotifyFlag = TRUE;
      m_pNotify->IOnSetCaret(!m_SelState.IsExist(), VTToEdit(ptHead),
                             VTToEdit(ptFoot), m_wpCaret);
      m_bNotifyFlag = FALSE;
    }
  }
}

void CFX_Edit::SetCaret(int32_t nPos) {
  if (m_pVT->IsValid()) {
    SelectNone();
    SetCaret(m_pVT->WordIndexToWordPlace(nPos));
    m_SelState.Set(m_wpCaret, m_wpCaret);

    ScrollToCaret();
    SetCaretOrigin();
    SetCaretInfo();
  }
}

void CFX_Edit::OnMouseDown(const CFX_FloatPoint& point,
                           FX_BOOL bShift,
                           FX_BOOL bCtrl) {
  if (m_pVT->IsValid()) {
    SelectNone();
    SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
    m_SelState.Set(m_wpCaret, m_wpCaret);

    ScrollToCaret();
    SetCaretOrigin();
    SetCaretInfo();
  }
}

void CFX_Edit::OnMouseMove(const CFX_FloatPoint& point,
                           FX_BOOL bShift,
                           FX_BOOL bCtrl) {
  if (m_pVT->IsValid()) {
    SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));

    if (m_wpCaret != m_wpOldCaret) {
      m_SelState.SetEndPos(m_wpCaret);

      ScrollToCaret();
      Refresh();
      SetCaretOrigin();
      SetCaretInfo();
    }
  }
}

void CFX_Edit::OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) {
  if (m_pVT->IsValid()) {
    SetCaret(m_pVT->GetUpWordPlace(m_wpCaret, m_ptCaret));

    if (bShift) {
      if (m_SelState.IsExist())
        m_SelState.SetEndPos(m_wpCaret);
      else
        m_SelState.Set(m_wpOldCaret, m_wpCaret);

      if (m_wpOldCaret != m_wpCaret) {
        ScrollToCaret();
        Refresh();
        SetCaretInfo();
      }
    } else {
      SelectNone();

      ScrollToCaret();
      SetCaretInfo();
    }
  }
}

void CFX_Edit::OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) {
  if (m_pVT->IsValid()) {
    SetCaret(m_pVT->GetDownWordPlace(m_wpCaret, m_ptCaret));

    if (bShift) {
      if (m_SelState.IsExist())
        m_SelState.SetEndPos(m_wpCaret);
      else
        m_SelState.Set(m_wpOldCaret, m_wpCaret);

      if (m_wpOldCaret != m_wpCaret) {
        ScrollToCaret();
        Refresh();
        SetCaretInfo();
      }
    } else {
      SelectNone();

      ScrollToCaret();
      SetCaretInfo();
    }
  }
}

void CFX_Edit::OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) {
  if (m_pVT->IsValid()) {
    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.IsExist())
        m_SelState.SetEndPos(m_wpCaret);
      else
        m_SelState.Set(m_wpOldCaret, m_wpCaret);

      if (m_wpOldCaret != m_wpCaret) {
        ScrollToCaret();
        Refresh();
        SetCaretInfo();
      }
    } else {
      if (m_SelState.IsExist()) {
        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0)
          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(FX_BOOL bShift, FX_BOOL bCtrl) {
  if (m_pVT->IsValid()) {
    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.IsExist())
        m_SelState.SetEndPos(m_wpCaret);
      else
        m_SelState.Set(m_wpOldCaret, m_wpCaret);

      if (m_wpOldCaret != m_wpCaret) {
        ScrollToCaret();
        Refresh();
        SetCaretInfo();
      }
    } else {
      if (m_SelState.IsExist()) {
        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) > 0)
          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(FX_BOOL bShift, FX_BOOL bCtrl) {
  if (m_pVT->IsValid()) {
    if (bShift) {
      if (bCtrl)
        SetCaret(m_pVT->GetBeginWordPlace());
      else
        SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));

      if (m_SelState.IsExist())
        m_SelState.SetEndPos(m_wpCaret);
      else
        m_SelState.Set(m_wpOldCaret, m_wpCaret);

      ScrollToCaret();
      Refresh();
      SetCaretInfo();
    } else {
      if (m_SelState.IsExist()) {
        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) < 0)
          SetCaret(m_SelState.BeginPos);
        else
          SetCaret(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(FX_BOOL bShift, FX_BOOL bCtrl) {
  if (m_pVT->IsValid()) {
    if (bShift) {
      if (bCtrl)
        SetCaret(m_pVT->GetEndWordPlace());
      else
        SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));

      if (m_SelState.IsExist())
        m_SelState.SetEndPos(m_wpCaret);
      else
        m_SelState.Set(m_wpOldCaret, m_wpCaret);

      ScrollToCaret();
      Refresh();
      SetCaretInfo();
    } else {
      if (m_SelState.IsExist()) {
        if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos) > 0)
          SetCaret(m_SelState.BeginPos);
        else
          SetCaret(m_SelState.EndPos);

        SelectNone();
        ScrollToCaret();
        SetCaretInfo();
      } else {
        if (bCtrl)
          SetCaret(m_pVT->GetEndWordPlace());
        else
          SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));

        ScrollToCaret();
        SetCaretOrigin();
        SetCaretInfo();
      }
    }
  }
}

FX_BOOL CFX_Edit::InsertWord(uint16_t word,
                             int32_t charset,
                             const CPVT_WordProps* pWordProps,
                             FX_BOOL bAddUndo,
                             FX_BOOL bPaint) {
  if (IsTextOverflow())
    return FALSE;

  if (m_pVT->IsValid()) {
    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) {
      if (bAddUndo && m_bEnableUndo) {
        AddEditUndoItem(new CFXEU_InsertWord(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;
    }
  }

  return FALSE;
}

FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps,
                               const CPVT_WordProps* pWordProps,
                               FX_BOOL bAddUndo,
                               FX_BOOL bPaint) {
  if (IsTextOverflow())
    return FALSE;

  if (m_pVT->IsValid()) {
    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) {
      if (bAddUndo && m_bEnableUndo) {
        AddEditUndoItem(new CFXEU_InsertReturn(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;
    }
  }

  return FALSE;
}

FX_BOOL CFX_Edit::Backspace(FX_BOOL bAddUndo, FX_BOOL bPaint) {
  if (m_pVT->IsValid()) {
    if (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) {
      if (bAddUndo && m_bEnableUndo) {
        if (m_wpCaret.SecCmp(m_wpOldCaret) != 0)
          AddEditUndoItem(new CFXEU_Backspace(
              this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
              section.SecProps, section.WordProps));
        else
          AddEditUndoItem(new CFXEU_Backspace(
              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;
    }
  }

  return FALSE;
}

FX_BOOL CFX_Edit::Delete(FX_BOOL bAddUndo, FX_BOOL bPaint) {
  if (m_pVT->IsValid()) {
    if (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);
    FX_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(new CFXEU_Delete(
            this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset,
            section.SecProps, section.WordProps, bSecEnd));
      else
        AddEditUndoItem(new CFXEU_Delete(
            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;
  }

  return FALSE;
}

FX_BOOL CFX_Edit::Empty() {
  if (m_pVT->IsValid()) {
    m_pVT->DeleteWords(GetWholeWordRange());
    SetCaret(m_pVT->GetBeginWordPlace());

    return TRUE;
  }

  return FALSE;
}

FX_BOOL CFX_Edit::Clear(FX_BOOL bAddUndo, FX_BOOL bPaint) {
  if (!m_pVT->IsValid())
    return FALSE;

  if (!m_SelState.IsExist())
    return FALSE;

  CPVT_WordRange range = m_SelState.ConvertToWordRange();

  if (bAddUndo && m_bEnableUndo)
    AddEditUndoItem(new CFXEU_Clear(this, range, GetSelText()));

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

FX_BOOL CFX_Edit::InsertText(const CFX_WideString& sText,
                             int32_t charset,
                             FX_BOOL bAddUndo,
                             FX_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(
        new CFXEU_InsertText(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();
  }
}

FX_BOOL CFX_Edit::Redo() {
  if (m_bEnableUndo) {
    if (m_Undo.CanRedo()) {
      m_Undo.Redo();
      return TRUE;
    }
  }

  return FALSE;
}

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

int32_t CFX_Edit::WordPlaceToWordIndex(const CPVT_WordPlace& place) const {
  if (m_pVT->IsValid())
    return m_pVT->WordPlaceToWordIndex(place);

  return -1;
}

CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const {
  if (m_pVT->IsValid())
    return m_pVT->WordIndexToWordPlace(index);

  return CPVT_WordPlace();
}

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

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

FX_BOOL CFX_Edit::CanUndo() const {
  if (m_bEnableUndo) {
    return m_Undo.CanUndo();
  }

  return FALSE;
}

FX_BOOL CFX_Edit::CanRedo() const {
  if (m_bEnableUndo) {
    return m_Undo.CanRedo();
  }

  return FALSE;
}

void CFX_Edit::EnableRefresh(FX_BOOL bRefresh) {
  m_bEnableRefresh = bRefresh;
}

void CFX_Edit::EnableUndo(FX_BOOL bUndo) {
  m_bEnableUndo = bUndo;
}

void CFX_Edit::EnableOprNotify(FX_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(CFX_Edit_UndoItem* pEditUndoItem) {
  if (m_pGroupUndoItem) {
    m_pGroupUndoItem->AddUndoItem(pEditUndoItem);
  } else {
    m_Undo.AddItem(pEditUndoItem);
  }
}

CFX_Edit_LineRectArray::CFX_Edit_LineRectArray() {}

CFX_Edit_LineRectArray::~CFX_Edit_LineRectArray() {
  Empty();
}

void CFX_Edit_LineRectArray::Empty() {
  for (int32_t i = 0, sz = m_LineRects.GetSize(); i < sz; i++)
    delete m_LineRects.GetAt(i);

  m_LineRects.RemoveAll();
}

void CFX_Edit_LineRectArray::RemoveAll() {
  m_LineRects.RemoveAll();
}

void CFX_Edit_LineRectArray::operator=(CFX_Edit_LineRectArray& rects) {
  Empty();
  for (int32_t i = 0, sz = rects.GetSize(); i < sz; i++)
    m_LineRects.Add(rects.GetAt(i));

  rects.RemoveAll();
}

void CFX_Edit_LineRectArray::Add(const CPVT_WordRange& wrLine,
                                 const CFX_FloatRect& rcLine) {
  m_LineRects.Add(new CFX_Edit_LineRect(wrLine, rcLine));
}

int32_t CFX_Edit_LineRectArray::GetSize() const {
  return m_LineRects.GetSize();
}

CFX_Edit_LineRect* CFX_Edit_LineRectArray::GetAt(int32_t nIndex) const {
  if (nIndex < 0 || nIndex >= m_LineRects.GetSize())
    return nullptr;

  return m_LineRects.GetAt(nIndex);
}

CFX_Edit_Select::CFX_Edit_Select() {}

CFX_Edit_Select::CFX_Edit_Select(const CPVT_WordPlace& begin,
                                 const CPVT_WordPlace& end) {
  Set(begin, end);
}

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::Default() {
  BeginPos.Default();
  EndPos.Default();
}

void CFX_Edit_Select::Set(const CPVT_WordPlace& begin,
                          const CPVT_WordPlace& end) {
  BeginPos = begin;
  EndPos = end;
}

void CFX_Edit_Select::SetBeginPos(const CPVT_WordPlace& begin) {
  BeginPos = begin;
}

void CFX_Edit_Select::SetEndPos(const CPVT_WordPlace& end) {
  EndPos = end;
}

FX_BOOL CFX_Edit_Select::IsExist() const {
  return BeginPos != EndPos;
}

CFX_Edit_RectArray::CFX_Edit_RectArray() {}

CFX_Edit_RectArray::~CFX_Edit_RectArray() {
  Empty();
}

void CFX_Edit_RectArray::Empty() {
  for (int32_t i = 0, sz = m_Rects.GetSize(); i < sz; i++)
    delete m_Rects.GetAt(i);

  m_Rects.RemoveAll();
}

void CFX_Edit_RectArray::Add(const CFX_FloatRect& rect) {
  // check for overlapped area
  for (int32_t i = 0, sz = m_Rects.GetSize(); i < sz; i++) {
    CFX_FloatRect* pRect = m_Rects.GetAt(i);
    if (pRect && pRect->Contains(rect))
      return;
  }

  m_Rects.Add(new CFX_FloatRect(rect));
}

int32_t CFX_Edit_RectArray::GetSize() const {
  return m_Rects.GetSize();
}

CFX_FloatRect* CFX_Edit_RectArray::GetAt(int32_t nIndex) const {
  if (nIndex < 0 || nIndex >= m_Rects.GetSize())
    return nullptr;

  return m_Rects.GetAt(nIndex);
}
