Remove core/include/fpdfdoc/fpdf_vt.h

This CL removes the core/include/fpdfdoc/fpdf_vt.h file. The IPDF_VariableText
class was removed in favour of the only concrete class of CPD_VariableText.

CPVT_Provider was moved to CPDF_VariableText::Provider and
CPDF_VariableText_Iterator was moved to CPDF_VariableText::Iterator.

The IFX_Edit_FontMap interface was merged into the IPVT_FontMap interface so
there is only one.

Other classes were split out as needed in order to keep things compiling.

BUG=pdfium:468

Review URL: https://codereview.chromium.org/1860063002
diff --git a/BUILD.gn b/BUILD.gn
index 6e11f18..8e9cc0c 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -192,17 +192,22 @@
 
 static_library("fpdfdoc") {
   sources = [
+    "core/fpdfdoc/cpdf_variabletext.cpp",
     "core/fpdfdoc/cpvt_color.cpp",
     "core/fpdfdoc/cpvt_color.h",
     "core/fpdfdoc/cpvt_dash.h",
+    "core/fpdfdoc/cpvt_floatrect.h",
     "core/fpdfdoc/cpvt_fontmap.cpp",
     "core/fpdfdoc/cpvt_fontmap.h",
     "core/fpdfdoc/cpvt_generateap.cpp",
     "core/fpdfdoc/cpvt_generateap.h",
-    "core/fpdfdoc/cpvt_provider.h",
+    "core/fpdfdoc/cpvt_lineinfo.h",
+    "core/fpdfdoc/cpvt_sectioninfo.h",
+    "core/fpdfdoc/cpvt_wordinfo.h",
+    "core/fpdfdoc/csection.h",
+    "core/fpdfdoc/ctypeset.h",
     "core/fpdfdoc/doc_action.cpp",
     "core/fpdfdoc/doc_annot.cpp",
-    "core/fpdfdoc/doc_ap.cpp",
     "core/fpdfdoc/doc_basic.cpp",
     "core/fpdfdoc/doc_bookmark.cpp",
     "core/fpdfdoc/doc_form.cpp",
@@ -216,13 +221,19 @@
     "core/fpdfdoc/doc_utils.h",
     "core/fpdfdoc/doc_viewerPreferences.cpp",
     "core/fpdfdoc/doc_vt.cpp",
-    "core/fpdfdoc/doc_vtmodule.cpp",
+    "core/fpdfdoc/include/cpdf_variabletext.h",
+    "core/fpdfdoc/include/cpvt_line.h",
+    "core/fpdfdoc/include/cpvt_secprops.h",
+    "core/fpdfdoc/include/cpvt_section.h",
+    "core/fpdfdoc/include/cpvt_word.h",
+    "core/fpdfdoc/include/cpvt_wordplace.h",
+    "core/fpdfdoc/include/cpvt_wordprops.h",
+    "core/fpdfdoc/include/cpvt_wordrange.h",
     "core/fpdfdoc/ipvt_fontmap.h",
     "core/fpdfdoc/pdf_vt.h",
     "core/fpdfdoc/tagged_int.h",
     "core/include/fpdfdoc/fpdf_doc.h",
     "core/include/fpdfdoc/fpdf_tagged.h",
-    "core/include/fpdfdoc/fpdf_vt.h",
   ]
   configs += [ ":pdfium_config" ]
 }
diff --git a/core/fpdfdoc/cpdf_variabletext.cpp b/core/fpdfdoc/cpdf_variabletext.cpp
new file mode 100644
index 0000000..6788740
--- /dev/null
+++ b/core/fpdfdoc/cpdf_variabletext.cpp
@@ -0,0 +1,1161 @@
+// Copyright 2016 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 "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+#include "core/fpdfdoc/cpvt_wordinfo.h"
+#include "core/fpdfdoc/csection.h"
+#include "core/fpdfdoc/include/cpdf_variabletext.h"
+#include "core/fpdfdoc/include/cpvt_section.h"
+#include "core/fpdfdoc/include/cpvt_word.h"
+#include "core/fpdfdoc/include/ipvt_fontmap.h"
+
+namespace {
+
+const float kDefaultFontSize = 18.0f;
+const float kFontScale = 0.001f;
+const uint8_t kReturnLength = 1;
+const float kScalePercent = 0.01f;
+
+const uint8_t gFontSizeSteps[] = {4,  6,  8,   9,   10,  12,  14, 18, 20,
+                                  25, 30, 35,  40,  45,  50,  55, 60, 70,
+                                  80, 90, 100, 110, 120, 130, 144};
+
+}  // namespace
+
+CPDF_VariableText::Provider::Provider(IPVT_FontMap* pFontMap)
+    : m_pFontMap(pFontMap) {
+  ASSERT(m_pFontMap);
+}
+
+CPDF_VariableText::Provider::~Provider() {}
+
+int32_t CPDF_VariableText::Provider::GetCharWidth(int32_t nFontIndex,
+                                                  uint16_t word,
+                                                  int32_t nWordStyle) {
+  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
+    uint32_t charcode = pPDFFont->CharCodeFromUnicode(word);
+    if (charcode != CPDF_Font::kInvalidCharCode)
+      return pPDFFont->GetCharWidthF(charcode);
+  }
+  return 0;
+}
+
+int32_t CPDF_VariableText::Provider::GetTypeAscent(int32_t nFontIndex) {
+  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
+    return pPDFFont->GetTypeAscent();
+  return 0;
+}
+
+int32_t CPDF_VariableText::Provider::GetTypeDescent(int32_t nFontIndex) {
+  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
+    return pPDFFont->GetTypeDescent();
+  return 0;
+}
+
+int32_t CPDF_VariableText::Provider::GetWordFontIndex(uint16_t word,
+                                                      int32_t charset,
+                                                      int32_t nFontIndex) {
+  if (CPDF_Font* pDefFont = m_pFontMap->GetPDFFont(0)) {
+    if (pDefFont->CharCodeFromUnicode(word) != CPDF_Font::kInvalidCharCode)
+      return 0;
+  }
+  if (CPDF_Font* pSysFont = m_pFontMap->GetPDFFont(1)) {
+    if (pSysFont->CharCodeFromUnicode(word) != CPDF_Font::kInvalidCharCode)
+      return 1;
+  }
+  return -1;
+}
+
+FX_BOOL CPDF_VariableText::Provider::IsLatinWord(uint16_t word) {
+  if ((word >= 0x61 && word <= 0x7A) || (word >= 0x41 && word <= 0x5A) ||
+      word == 0x2D || word == 0x27) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+int32_t CPDF_VariableText::Provider::GetDefaultFontIndex() {
+  return 0;
+}
+
+CPDF_VariableText::Iterator::Iterator(CPDF_VariableText* pVT)
+    : m_CurPos(-1, -1, -1), m_pVT(pVT) {}
+
+CPDF_VariableText::Iterator::~Iterator() {}
+
+void CPDF_VariableText::Iterator::SetAt(int32_t nWordIndex) {
+  m_CurPos = m_pVT->WordIndexToWordPlace(nWordIndex);
+}
+
+void CPDF_VariableText::Iterator::SetAt(const CPVT_WordPlace& place) {
+  ASSERT(m_pVT);
+  m_CurPos = place;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::NextWord() {
+  if (m_CurPos == m_pVT->GetEndWordPlace())
+    return FALSE;
+
+  m_CurPos = m_pVT->GetNextWordPlace(m_CurPos);
+  return TRUE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::PrevWord() {
+  if (m_CurPos == m_pVT->GetBeginWordPlace())
+    return FALSE;
+
+  m_CurPos = m_pVT->GetPrevWordPlace(m_CurPos);
+  return TRUE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::NextLine() {
+  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
+    if (m_CurPos.nLineIndex < pSection->m_LineArray.GetSize() - 1) {
+      m_CurPos =
+          CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex + 1, -1);
+      return TRUE;
+    }
+    if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
+      m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::PrevLine() {
+  if (m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
+    if (m_CurPos.nLineIndex > 0) {
+      m_CurPos =
+          CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex - 1, -1);
+      return TRUE;
+    }
+    if (m_CurPos.nSecIndex > 0) {
+      if (CSection* pLastSection =
+              m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex - 1)) {
+        m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex - 1,
+                                  pLastSection->m_LineArray.GetSize() - 1, -1);
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::NextSection() {
+  if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
+    m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::PrevSection() {
+  ASSERT(m_pVT);
+  if (m_CurPos.nSecIndex > 0) {
+    m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex - 1, 0, -1);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::GetWord(CPVT_Word& word) const {
+  word.WordPlace = m_CurPos;
+  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
+    if (pSection->m_LineArray.GetAt(m_CurPos.nLineIndex)) {
+      if (CPVT_WordInfo* pWord =
+              pSection->m_WordArray.GetAt(m_CurPos.nWordIndex)) {
+        word.Word = pWord->Word;
+        word.nCharset = pWord->nCharset;
+        word.fWidth = m_pVT->GetWordWidth(*pWord);
+        word.ptWord = m_pVT->InToOut(
+            CFX_FloatPoint(pWord->fWordX + pSection->m_SecInfo.rcSection.left,
+                           pWord->fWordY + pSection->m_SecInfo.rcSection.top));
+        word.fAscent = m_pVT->GetWordAscent(*pWord);
+        word.fDescent = m_pVT->GetWordDescent(*pWord);
+        if (pWord->pWordProps)
+          word.WordProps = *pWord->pWordProps;
+
+        word.nFontIndex = m_pVT->GetWordFontIndex(*pWord);
+        word.fFontSize = m_pVT->GetWordFontSize(*pWord);
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::SetWord(const CPVT_Word& word) {
+  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
+    if (CPVT_WordInfo* pWord =
+            pSection->m_WordArray.GetAt(m_CurPos.nWordIndex)) {
+      if (pWord->pWordProps)
+        *pWord->pWordProps = word.WordProps;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::GetLine(CPVT_Line& line) const {
+  ASSERT(m_pVT);
+  line.lineplace = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex, -1);
+  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
+    if (CLine* pLine = pSection->m_LineArray.GetAt(m_CurPos.nLineIndex)) {
+      line.ptLine = m_pVT->InToOut(CFX_FloatPoint(
+          pLine->m_LineInfo.fLineX + pSection->m_SecInfo.rcSection.left,
+          pLine->m_LineInfo.fLineY + pSection->m_SecInfo.rcSection.top));
+      line.fLineWidth = pLine->m_LineInfo.fLineWidth;
+      line.fLineAscent = pLine->m_LineInfo.fLineAscent;
+      line.fLineDescent = pLine->m_LineInfo.fLineDescent;
+      line.lineEnd = pLine->GetEndWordPlace();
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::GetSection(CPVT_Section& section) const {
+  section.secplace = CPVT_WordPlace(m_CurPos.nSecIndex, 0, -1);
+  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
+    section.rcSection = m_pVT->InToOut(pSection->m_SecInfo.rcSection);
+    if (pSection->m_SecInfo.pSecProps)
+      section.SecProps = *pSection->m_SecInfo.pSecProps;
+    if (pSection->m_SecInfo.pWordProps)
+      section.WordProps = *pSection->m_SecInfo.pWordProps;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::Iterator::SetSection(const CPVT_Section& section) {
+  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
+    if (pSection->m_SecInfo.pSecProps)
+      *pSection->m_SecInfo.pSecProps = section.SecProps;
+    if (pSection->m_SecInfo.pWordProps)
+      *pSection->m_SecInfo.pWordProps = section.WordProps;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+CPDF_VariableText::CPDF_VariableText()
+    : m_nLimitChar(0),
+      m_nCharArray(0),
+      m_bMultiLine(FALSE),
+      m_bLimitWidth(FALSE),
+      m_bAutoFontSize(FALSE),
+      m_nAlignment(0),
+      m_fLineLeading(0.0f),
+      m_fCharSpace(0.0f),
+      m_nHorzScale(100),
+      m_wSubWord(0),
+      m_fFontSize(0.0f),
+      m_bInitial(FALSE),
+      m_bRichText(FALSE),
+      m_pVTProvider(nullptr),
+      m_pVTIterator(nullptr) {}
+
+CPDF_VariableText::~CPDF_VariableText() {
+  delete m_pVTIterator;
+  ResetAll();
+}
+
+void CPDF_VariableText::Initialize() {
+  if (!m_bInitial) {
+    CPVT_SectionInfo secinfo;
+    if (m_bRichText) {
+      secinfo.pSecProps = new CPVT_SecProps(0.0f, 0.0f, 0);
+      secinfo.pWordProps = new CPVT_WordProps(
+          GetDefaultFontIndex(), kDefaultFontSize, 0, ScriptType::Normal, 0);
+    }
+    CPVT_WordPlace place;
+    place.nSecIndex = 0;
+    AddSection(place, secinfo);
+    CPVT_LineInfo lineinfo;
+    lineinfo.fLineAscent = GetFontAscent(GetDefaultFontIndex(), GetFontSize());
+    lineinfo.fLineDescent =
+        GetFontDescent(GetDefaultFontIndex(), GetFontSize());
+    AddLine(place, lineinfo);
+    if (CSection* pSection = m_SectionArray.GetAt(0))
+      pSection->ResetLinePlace();
+
+    m_bInitial = TRUE;
+  }
+}
+
+void CPDF_VariableText::ResetAll() {
+  m_bInitial = FALSE;
+  ResetSectionArray();
+}
+
+CPVT_WordPlace CPDF_VariableText::InsertWord(const CPVT_WordPlace& place,
+                                             uint16_t word,
+                                             int32_t charset,
+                                             const CPVT_WordProps* pWordProps) {
+  int32_t nTotlaWords = GetTotalWords();
+  if (m_nLimitChar > 0 && nTotlaWords >= m_nLimitChar)
+    return place;
+  if (m_nCharArray > 0 && nTotlaWords >= m_nCharArray)
+    return place;
+
+  CPVT_WordPlace newplace = place;
+  newplace.nWordIndex++;
+  if (m_bRichText) {
+    CPVT_WordProps* pNewProps =
+        pWordProps ? new CPVT_WordProps(*pWordProps) : new CPVT_WordProps();
+    pNewProps->nFontIndex =
+        GetWordFontIndex(word, charset, pWordProps->nFontIndex);
+    return AddWord(newplace, CPVT_WordInfo(word, charset, -1, pNewProps));
+  }
+  int32_t nFontIndex =
+      GetSubWord() > 0 ? GetDefaultFontIndex()
+                       : GetWordFontIndex(word, charset, GetDefaultFontIndex());
+  return AddWord(newplace, CPVT_WordInfo(word, charset, nFontIndex, NULL));
+}
+
+CPVT_WordPlace CPDF_VariableText::InsertSection(
+    const CPVT_WordPlace& place,
+    const CPVT_SecProps* pSecProps,
+    const CPVT_WordProps* pWordProps) {
+  int32_t nTotlaWords = GetTotalWords();
+  if (m_nLimitChar > 0 && nTotlaWords >= m_nLimitChar)
+    return place;
+  if (m_nCharArray > 0 && nTotlaWords >= m_nCharArray)
+    return place;
+  if (!m_bMultiLine)
+    return place;
+
+  CPVT_WordPlace wordplace = place;
+  UpdateWordPlace(wordplace);
+  CPVT_WordPlace newplace = place;
+  if (CSection* pSection = m_SectionArray.GetAt(wordplace.nSecIndex)) {
+    CPVT_WordPlace NewPlace(wordplace.nSecIndex + 1, 0, -1);
+    CPVT_SectionInfo secinfo;
+    if (m_bRichText) {
+      if (pSecProps)
+        secinfo.pSecProps = new CPVT_SecProps(*pSecProps);
+      if (pWordProps)
+        secinfo.pWordProps = new CPVT_WordProps(*pWordProps);
+    }
+    AddSection(NewPlace, secinfo);
+    newplace = NewPlace;
+    if (CSection* pNewSection = m_SectionArray.GetAt(NewPlace.nSecIndex)) {
+      for (int32_t w = wordplace.nWordIndex + 1,
+                   sz = pSection->m_WordArray.GetSize();
+           w < sz; w++) {
+        if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(w)) {
+          NewPlace.nWordIndex++;
+          pNewSection->AddWord(NewPlace, *pWord);
+        }
+      }
+    }
+    ClearSectionRightWords(wordplace);
+  }
+  return newplace;
+}
+
+CPVT_WordPlace CPDF_VariableText::InsertText(const CPVT_WordPlace& place,
+                                             const FX_WCHAR* text,
+                                             int32_t charset,
+                                             const CPVT_SecProps* pSecProps,
+                                             const CPVT_WordProps* pProps) {
+  CFX_WideString swText = text;
+  CPVT_WordPlace wp = place;
+  for (int32_t i = 0, sz = swText.GetLength(); i < sz; i++) {
+    CPVT_WordPlace oldwp = wp;
+    uint16_t word = swText.GetAt(i);
+    switch (word) {
+      case 0x0D:
+        if (m_bMultiLine) {
+          if (swText.GetAt(i + 1) == 0x0A)
+            i += 1;
+
+          wp = InsertSection(wp, pSecProps, pProps);
+        }
+        break;
+      case 0x0A:
+        if (m_bMultiLine) {
+          if (swText.GetAt(i + 1) == 0x0D)
+            i += 1;
+
+          wp = InsertSection(wp, pSecProps, pProps);
+        }
+        break;
+      case 0x09:
+        word = 0x20;
+      default:
+        wp = InsertWord(wp, word, charset, pProps);
+        break;
+    }
+    if (wp == oldwp)
+      break;
+  }
+  return wp;
+}
+
+CPVT_WordPlace CPDF_VariableText::DeleteWords(
+    const CPVT_WordRange& PlaceRange) {
+  FX_BOOL bLastSecPos = FALSE;
+  if (CSection* pSection = m_SectionArray.GetAt(PlaceRange.EndPos.nSecIndex))
+    bLastSecPos = (PlaceRange.EndPos == pSection->GetEndWordPlace());
+
+  ClearWords(PlaceRange);
+  if (PlaceRange.BeginPos.nSecIndex != PlaceRange.EndPos.nSecIndex) {
+    ClearEmptySections(PlaceRange);
+    if (!bLastSecPos)
+      LinkLatterSection(PlaceRange.BeginPos);
+  }
+  return PlaceRange.BeginPos;
+}
+
+CPVT_WordPlace CPDF_VariableText::DeleteWord(const CPVT_WordPlace& place) {
+  return ClearRightWord(AdjustLineHeader(place, TRUE));
+}
+
+CPVT_WordPlace CPDF_VariableText::BackSpaceWord(const CPVT_WordPlace& place) {
+  return ClearLeftWord(AdjustLineHeader(place, TRUE));
+}
+
+void CPDF_VariableText::SetText(const FX_WCHAR* text,
+                                int32_t charset,
+                                const CPVT_SecProps* pSecProps,
+                                const CPVT_WordProps* pWordProps) {
+  DeleteWords(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
+  CFX_WideString swText = text;
+  CPVT_WordPlace wp(0, 0, -1);
+  CPVT_SectionInfo secinfo;
+  if (m_bRichText) {
+    if (pSecProps)
+      secinfo.pSecProps = new CPVT_SecProps(*pSecProps);
+    if (pWordProps)
+      secinfo.pWordProps = new CPVT_WordProps(*pWordProps);
+  }
+  if (CSection* pSection = m_SectionArray.GetAt(0))
+    pSection->m_SecInfo = secinfo;
+
+  int32_t nCharCount = 0;
+  for (int32_t i = 0, sz = swText.GetLength(); i < sz; i++) {
+    if (m_nLimitChar > 0 && nCharCount >= m_nLimitChar)
+      break;
+    if (m_nCharArray > 0 && nCharCount >= m_nCharArray)
+      break;
+
+    uint16_t word = swText.GetAt(i);
+    switch (word) {
+      case 0x0D:
+        if (m_bMultiLine) {
+          if (swText.GetAt(i + 1) == 0x0A)
+            i += 1;
+
+          wp.nSecIndex++;
+          wp.nLineIndex = 0;
+          wp.nWordIndex = -1;
+          AddSection(wp, secinfo);
+        }
+        break;
+      case 0x0A:
+        if (m_bMultiLine) {
+          if (swText.GetAt(i + 1) == 0x0D)
+            i += 1;
+
+          wp.nSecIndex++;
+          wp.nLineIndex = 0;
+          wp.nWordIndex = -1;
+          AddSection(wp, secinfo);
+        }
+        break;
+      case 0x09:
+        word = 0x20;
+      default:
+        wp = InsertWord(wp, word, charset, pWordProps);
+        break;
+    }
+    nCharCount++;
+  }
+}
+
+void CPDF_VariableText::UpdateWordPlace(CPVT_WordPlace& place) const {
+  if (place.nSecIndex < 0)
+    place = GetBeginWordPlace();
+  if (place.nSecIndex >= m_SectionArray.GetSize())
+    place = GetEndWordPlace();
+
+  place = AdjustLineHeader(place, TRUE);
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex))
+    pSection->UpdateWordPlace(place);
+}
+
+int32_t CPDF_VariableText::WordPlaceToWordIndex(
+    const CPVT_WordPlace& place) const {
+  CPVT_WordPlace newplace = place;
+  UpdateWordPlace(newplace);
+  int32_t nIndex = 0;
+  int32_t i = 0;
+  int32_t sz = 0;
+  for (i = 0, sz = m_SectionArray.GetSize(); i < sz && i < newplace.nSecIndex;
+       i++) {
+    if (CSection* pSection = m_SectionArray.GetAt(i)) {
+      nIndex += pSection->m_WordArray.GetSize();
+      if (i != m_SectionArray.GetSize() - 1)
+        nIndex += kReturnLength;
+    }
+  }
+  if (i >= 0 && i < m_SectionArray.GetSize())
+    nIndex += newplace.nWordIndex + kReturnLength;
+  return nIndex;
+}
+
+CPVT_WordPlace CPDF_VariableText::WordIndexToWordPlace(int32_t index) const {
+  CPVT_WordPlace place = GetBeginWordPlace();
+  int32_t nOldIndex = 0, nIndex = 0;
+  FX_BOOL bFind = FALSE;
+  for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++) {
+    if (CSection* pSection = m_SectionArray.GetAt(i)) {
+      nIndex += pSection->m_WordArray.GetSize();
+      if (nIndex == index) {
+        place = pSection->GetEndWordPlace();
+        bFind = TRUE;
+        break;
+      } else if (nIndex > index) {
+        place.nSecIndex = i;
+        place.nWordIndex = index - nOldIndex - 1;
+        pSection->UpdateWordPlace(place);
+        bFind = TRUE;
+        break;
+      }
+      if (i != m_SectionArray.GetSize() - 1)
+        nIndex += kReturnLength;
+      nOldIndex = nIndex;
+    }
+  }
+  if (!bFind)
+    place = GetEndWordPlace();
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::GetBeginWordPlace() const {
+  return m_bInitial ? CPVT_WordPlace(0, 0, -1) : CPVT_WordPlace();
+}
+
+CPVT_WordPlace CPDF_VariableText::GetEndWordPlace() const {
+  if (CSection* pSection = m_SectionArray.GetAt(m_SectionArray.GetSize() - 1))
+    return pSection->GetEndWordPlace();
+  return CPVT_WordPlace();
+}
+
+CPVT_WordPlace CPDF_VariableText::GetPrevWordPlace(
+    const CPVT_WordPlace& place) const {
+  if (place.nSecIndex < 0)
+    return GetBeginWordPlace();
+  if (place.nSecIndex >= m_SectionArray.GetSize())
+    return GetEndWordPlace();
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    if (place.WordCmp(pSection->GetBeginWordPlace()) <= 0) {
+      if (CSection* pPrevSection = m_SectionArray.GetAt(place.nSecIndex - 1))
+        return pPrevSection->GetEndWordPlace();
+      return GetBeginWordPlace();
+    }
+    return pSection->GetPrevWordPlace(place);
+  }
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::GetNextWordPlace(
+    const CPVT_WordPlace& place) const {
+  if (place.nSecIndex < 0)
+    return GetBeginWordPlace();
+  if (place.nSecIndex >= m_SectionArray.GetSize())
+    return GetEndWordPlace();
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    if (place.WordCmp(pSection->GetEndWordPlace()) >= 0) {
+      if (CSection* pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1))
+        return pNextSection->GetBeginWordPlace();
+      return GetEndWordPlace();
+    }
+    return pSection->GetNextWordPlace(place);
+  }
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::SearchWordPlace(
+    const CFX_FloatPoint& point) const {
+  CFX_FloatPoint pt = OutToIn(point);
+  CPVT_WordPlace place = GetBeginWordPlace();
+  int32_t nLeft = 0;
+  int32_t nRight = m_SectionArray.GetSize() - 1;
+  int32_t nMid = m_SectionArray.GetSize() / 2;
+  FX_BOOL bUp = TRUE;
+  FX_BOOL bDown = TRUE;
+  while (nLeft <= nRight) {
+    if (CSection* pSection = m_SectionArray.GetAt(nMid)) {
+      if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.top)) {
+        bUp = FALSE;
+      }
+      if (IsFloatBigger(pSection->m_SecInfo.rcSection.bottom, pt.y)) {
+        bDown = FALSE;
+      }
+      if (IsFloatSmaller(pt.y, pSection->m_SecInfo.rcSection.top)) {
+        nRight = nMid - 1;
+        nMid = (nLeft + nRight) / 2;
+        continue;
+      } else if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.bottom)) {
+        nLeft = nMid + 1;
+        nMid = (nLeft + nRight) / 2;
+        continue;
+      } else {
+        place = pSection->SearchWordPlace(
+            CFX_FloatPoint(pt.x - pSection->m_SecInfo.rcSection.left,
+                           pt.y - pSection->m_SecInfo.rcSection.top));
+        place.nSecIndex = nMid;
+        return place;
+      }
+    } else {
+      break;
+    }
+  }
+  if (bUp)
+    place = GetBeginWordPlace();
+  if (bDown)
+    place = GetEndWordPlace();
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::GetUpWordPlace(
+    const CPVT_WordPlace& place,
+    const CFX_FloatPoint& point) const {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    CPVT_WordPlace temp = place;
+    CFX_FloatPoint pt = OutToIn(point);
+    if (temp.nLineIndex-- > 0) {
+      return pSection->SearchWordPlace(
+          pt.x - pSection->m_SecInfo.rcSection.left, temp);
+    }
+    if (temp.nSecIndex-- > 0) {
+      if (CSection* pLastSection = m_SectionArray.GetAt(temp.nSecIndex)) {
+        temp.nLineIndex = pLastSection->m_LineArray.GetSize() - 1;
+        return pLastSection->SearchWordPlace(
+            pt.x - pLastSection->m_SecInfo.rcSection.left, temp);
+      }
+    }
+  }
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::GetDownWordPlace(
+    const CPVT_WordPlace& place,
+    const CFX_FloatPoint& point) const {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    CPVT_WordPlace temp = place;
+    CFX_FloatPoint pt = OutToIn(point);
+    if (temp.nLineIndex++ < pSection->m_LineArray.GetSize() - 1) {
+      return pSection->SearchWordPlace(
+          pt.x - pSection->m_SecInfo.rcSection.left, temp);
+    }
+    if (temp.nSecIndex++ < m_SectionArray.GetSize() - 1) {
+      if (CSection* pNextSection = m_SectionArray.GetAt(temp.nSecIndex)) {
+        temp.nLineIndex = 0;
+        return pNextSection->SearchWordPlace(
+            pt.x - pSection->m_SecInfo.rcSection.left, temp);
+      }
+    }
+  }
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::GetLineBeginPlace(
+    const CPVT_WordPlace& place) const {
+  return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, -1);
+}
+
+CPVT_WordPlace CPDF_VariableText::GetLineEndPlace(
+    const CPVT_WordPlace& place) const {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    if (CLine* pLine = pSection->m_LineArray.GetAt(place.nLineIndex))
+      return pLine->GetEndWordPlace();
+  }
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::GetSectionBeginPlace(
+    const CPVT_WordPlace& place) const {
+  return CPVT_WordPlace(place.nSecIndex, 0, -1);
+}
+
+CPVT_WordPlace CPDF_VariableText::GetSectionEndPlace(
+    const CPVT_WordPlace& place) const {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex))
+    return pSection->GetEndWordPlace();
+  return place;
+}
+
+int32_t CPDF_VariableText::GetTotalWords() const {
+  int32_t nTotal = 0;
+  for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++) {
+    if (CSection* pSection = m_SectionArray.GetAt(i))
+      nTotal += (pSection->m_WordArray.GetSize() + kReturnLength);
+  }
+
+  return nTotal - kReturnLength;
+}
+
+void CPDF_VariableText::ResetSectionArray() {
+  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++)
+    delete m_SectionArray.GetAt(s);
+
+  m_SectionArray.RemoveAll();
+}
+
+CPVT_WordPlace CPDF_VariableText::AddSection(const CPVT_WordPlace& place,
+                                             const CPVT_SectionInfo& secinfo) {
+  if (IsValid() && !m_bMultiLine)
+    return place;
+
+  int32_t nSecIndex =
+      std::max(std::min(place.nSecIndex, m_SectionArray.GetSize()), 0);
+  CSection* pSection = new CSection(this);
+  pSection->m_SecInfo = secinfo;
+  pSection->SecPlace.nSecIndex = nSecIndex;
+  if (nSecIndex == m_SectionArray.GetSize())
+    m_SectionArray.Add(pSection);
+  else
+    m_SectionArray.InsertAt(nSecIndex, pSection);
+
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::AddLine(const CPVT_WordPlace& place,
+                                          const CPVT_LineInfo& lineinfo) {
+  if (m_SectionArray.IsEmpty())
+    return place;
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex))
+    return pSection->AddLine(lineinfo);
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::AddWord(const CPVT_WordPlace& place,
+                                          const CPVT_WordInfo& wordinfo) {
+  if (m_SectionArray.GetSize() <= 0) {
+    return place;
+  }
+  CPVT_WordPlace newplace = place;
+  newplace.nSecIndex =
+      std::max(std::min(newplace.nSecIndex, m_SectionArray.GetSize() - 1), 0);
+  if (CSection* pSection = m_SectionArray.GetAt(newplace.nSecIndex))
+    return pSection->AddWord(newplace, wordinfo);
+  return place;
+}
+
+FX_BOOL CPDF_VariableText::GetWordInfo(const CPVT_WordPlace& place,
+                                       CPVT_WordInfo& wordinfo) {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) {
+      wordinfo = *pWord;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::SetWordInfo(const CPVT_WordPlace& place,
+                                       const CPVT_WordInfo& wordinfo) {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) {
+      *pWord = wordinfo;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::GetLineInfo(const CPVT_WordPlace& place,
+                                       CPVT_LineInfo& lineinfo) {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    if (CLine* pLine = pSection->m_LineArray.GetAt(place.nLineIndex)) {
+      lineinfo = pLine->m_LineInfo;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+FX_BOOL CPDF_VariableText::GetSectionInfo(const CPVT_WordPlace& place,
+                                          CPVT_SectionInfo& secinfo) {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    secinfo = pSection->m_SecInfo;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+CFX_FloatRect CPDF_VariableText::GetContentRect() const {
+  return InToOut(CPVT_FloatRect(CPDF_EditContainer::GetContentRect()));
+}
+
+FX_FLOAT CPDF_VariableText::GetWordFontSize(const CPVT_WordInfo& WordInfo,
+                                            FX_BOOL bFactFontSize) {
+  return m_bRichText && WordInfo.pWordProps
+             ? (WordInfo.pWordProps->nScriptType == ScriptType::Normal ||
+                        bFactFontSize
+                    ? WordInfo.pWordProps->fFontSize
+                    : WordInfo.pWordProps->fFontSize * VARIABLETEXT_HALF)
+             : GetFontSize();
+}
+
+int32_t CPDF_VariableText::GetWordFontIndex(const CPVT_WordInfo& WordInfo) {
+  return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->nFontIndex
+                                            : WordInfo.nFontIndex;
+}
+
+FX_FLOAT CPDF_VariableText::GetWordWidth(int32_t nFontIndex,
+                                         uint16_t Word,
+                                         uint16_t SubWord,
+                                         FX_FLOAT fCharSpace,
+                                         int32_t nHorzScale,
+                                         FX_FLOAT fFontSize,
+                                         FX_FLOAT fWordTail,
+                                         int32_t nWordStyle) {
+  return (GetCharWidth(nFontIndex, Word, SubWord, nWordStyle) * fFontSize *
+              kFontScale +
+          fCharSpace) *
+             nHorzScale * kScalePercent +
+         fWordTail;
+}
+
+FX_FLOAT CPDF_VariableText::GetWordWidth(const CPVT_WordInfo& WordInfo) {
+  return GetWordWidth(
+      GetWordFontIndex(WordInfo), WordInfo.Word, GetSubWord(),
+      GetCharSpace(WordInfo), GetHorzScale(WordInfo), GetWordFontSize(WordInfo),
+      WordInfo.fWordTail,
+      WordInfo.pWordProps ? WordInfo.pWordProps->nWordStyle : 0);
+}
+
+FX_FLOAT CPDF_VariableText::GetLineAscent(const CPVT_SectionInfo& SecInfo) {
+  return m_bRichText && SecInfo.pWordProps
+             ? GetFontAscent(SecInfo.pWordProps->nFontIndex,
+                             SecInfo.pWordProps->fFontSize)
+             : GetFontAscent(GetDefaultFontIndex(), GetFontSize());
+}
+
+FX_FLOAT CPDF_VariableText::GetLineDescent(const CPVT_SectionInfo& SecInfo) {
+  return m_bRichText && SecInfo.pWordProps
+             ? GetFontDescent(SecInfo.pWordProps->nFontIndex,
+                              SecInfo.pWordProps->fFontSize)
+             : GetFontDescent(GetDefaultFontIndex(), GetFontSize());
+}
+
+FX_FLOAT CPDF_VariableText::GetFontAscent(int32_t nFontIndex,
+                                          FX_FLOAT fFontSize) {
+  return (FX_FLOAT)GetTypeAscent(nFontIndex) * fFontSize * kFontScale;
+}
+
+FX_FLOAT CPDF_VariableText::GetFontDescent(int32_t nFontIndex,
+                                           FX_FLOAT fFontSize) {
+  return (FX_FLOAT)GetTypeDescent(nFontIndex) * fFontSize * kFontScale;
+}
+
+FX_FLOAT CPDF_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo,
+                                          FX_FLOAT fFontSize) {
+  return GetFontAscent(GetWordFontIndex(WordInfo), fFontSize);
+}
+
+FX_FLOAT CPDF_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo,
+                                           FX_FLOAT fFontSize) {
+  return GetFontDescent(GetWordFontIndex(WordInfo), fFontSize);
+}
+
+FX_FLOAT CPDF_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo,
+                                          FX_BOOL bFactFontSize) {
+  return GetFontAscent(GetWordFontIndex(WordInfo),
+                       GetWordFontSize(WordInfo, bFactFontSize));
+}
+
+FX_FLOAT CPDF_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo,
+                                           FX_BOOL bFactFontSize) {
+  return GetFontDescent(GetWordFontIndex(WordInfo),
+                        GetWordFontSize(WordInfo, bFactFontSize));
+}
+
+FX_FLOAT CPDF_VariableText::GetLineLeading(const CPVT_SectionInfo& SecInfo) {
+  return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->fLineLeading
+                                          : m_fLineLeading;
+}
+
+FX_FLOAT CPDF_VariableText::GetLineIndent(const CPVT_SectionInfo& SecInfo) {
+  return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->fLineIndent
+                                          : 0.0f;
+}
+
+int32_t CPDF_VariableText::GetAlignment(const CPVT_SectionInfo& SecInfo) {
+  return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->nAlignment
+                                          : m_nAlignment;
+}
+
+FX_FLOAT CPDF_VariableText::GetCharSpace(const CPVT_WordInfo& WordInfo) {
+  return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->fCharSpace
+                                            : m_fCharSpace;
+}
+
+int32_t CPDF_VariableText::GetHorzScale(const CPVT_WordInfo& WordInfo) {
+  return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->nHorzScale
+                                            : m_nHorzScale;
+}
+
+void CPDF_VariableText::ClearSectionRightWords(const CPVT_WordPlace& place) {
+  CPVT_WordPlace wordplace = AdjustLineHeader(place, TRUE);
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    for (int32_t w = pSection->m_WordArray.GetSize() - 1;
+         w > wordplace.nWordIndex; w--) {
+      delete pSection->m_WordArray.GetAt(w);
+      pSection->m_WordArray.RemoveAt(w);
+    }
+  }
+}
+
+CPVT_WordPlace CPDF_VariableText::AdjustLineHeader(const CPVT_WordPlace& place,
+                                                   FX_BOOL bPrevOrNext) const {
+  if (place.nWordIndex < 0 && place.nLineIndex > 0)
+    return bPrevOrNext ? GetPrevWordPlace(place) : GetNextWordPlace(place);
+  return place;
+}
+
+FX_BOOL CPDF_VariableText::ClearEmptySection(const CPVT_WordPlace& place) {
+  if (place.nSecIndex == 0 && m_SectionArray.GetSize() == 1)
+    return FALSE;
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    if (pSection->m_WordArray.GetSize() == 0) {
+      delete pSection;
+      m_SectionArray.RemoveAt(place.nSecIndex);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+void CPDF_VariableText::ClearEmptySections(const CPVT_WordRange& PlaceRange) {
+  CPVT_WordPlace wordplace;
+  for (int32_t s = PlaceRange.EndPos.nSecIndex;
+       s > PlaceRange.BeginPos.nSecIndex; s--) {
+    wordplace.nSecIndex = s;
+    ClearEmptySection(wordplace);
+  }
+}
+
+void CPDF_VariableText::LinkLatterSection(const CPVT_WordPlace& place) {
+  CPVT_WordPlace oldplace = AdjustLineHeader(place, TRUE);
+  if (CSection* pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1)) {
+    if (CSection* pSection = m_SectionArray.GetAt(oldplace.nSecIndex)) {
+      for (int32_t w = 0, sz = pNextSection->m_WordArray.GetSize(); w < sz;
+           w++) {
+        if (CPVT_WordInfo* pWord = pNextSection->m_WordArray.GetAt(w)) {
+          oldplace.nWordIndex++;
+          pSection->AddWord(oldplace, *pWord);
+        }
+      }
+    }
+    delete pNextSection;
+    m_SectionArray.RemoveAt(place.nSecIndex + 1);
+  }
+}
+
+void CPDF_VariableText::ClearWords(const CPVT_WordRange& PlaceRange) {
+  CPVT_WordRange NewRange;
+  NewRange.BeginPos = AdjustLineHeader(PlaceRange.BeginPos, TRUE);
+  NewRange.EndPos = AdjustLineHeader(PlaceRange.EndPos, TRUE);
+  for (int32_t s = NewRange.EndPos.nSecIndex; s >= NewRange.BeginPos.nSecIndex;
+       s--) {
+    if (CSection* pSection = m_SectionArray.GetAt(s))
+      pSection->ClearWords(NewRange);
+  }
+}
+
+CPVT_WordPlace CPDF_VariableText::ClearLeftWord(const CPVT_WordPlace& place) {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    CPVT_WordPlace leftplace = GetPrevWordPlace(place);
+    if (leftplace != place) {
+      if (leftplace.nSecIndex != place.nSecIndex) {
+        if (pSection->m_WordArray.GetSize() == 0)
+          ClearEmptySection(place);
+        else
+          LinkLatterSection(leftplace);
+      } else {
+        pSection->ClearWord(place);
+      }
+    }
+    return leftplace;
+  }
+  return place;
+}
+
+CPVT_WordPlace CPDF_VariableText::ClearRightWord(const CPVT_WordPlace& place) {
+  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
+    CPVT_WordPlace rightplace =
+        AdjustLineHeader(GetNextWordPlace(place), FALSE);
+    if (rightplace != place) {
+      if (rightplace.nSecIndex != place.nSecIndex)
+        LinkLatterSection(place);
+      else
+        pSection->ClearWord(rightplace);
+    }
+  }
+  return place;
+}
+
+void CPDF_VariableText::RearrangeAll() {
+  Rearrange(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
+}
+
+void CPDF_VariableText::RearrangePart(const CPVT_WordRange& PlaceRange) {
+  Rearrange(PlaceRange);
+}
+
+CPVT_FloatRect CPDF_VariableText::Rearrange(const CPVT_WordRange& PlaceRange) {
+  CPVT_FloatRect rcRet;
+  if (IsValid()) {
+    if (m_bAutoFontSize) {
+      SetFontSize(GetAutoFontSize());
+      rcRet = RearrangeSections(
+          CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
+    } else {
+      rcRet = RearrangeSections(PlaceRange);
+    }
+  }
+  SetContentRect(rcRet);
+  return rcRet;
+}
+
+FX_FLOAT CPDF_VariableText::GetAutoFontSize() {
+  int32_t nTotal = sizeof(gFontSizeSteps) / sizeof(uint8_t);
+  if (IsMultiLine())
+    nTotal /= 4;
+  if (nTotal <= 0)
+    return 0;
+  if (GetPlateWidth() <= 0)
+    return 0;
+
+  int32_t nLeft = 0;
+  int32_t nRight = nTotal - 1;
+  int32_t nMid = nTotal / 2;
+  while (nLeft <= nRight) {
+    if (IsBigger(gFontSizeSteps[nMid])) {
+      nRight = nMid - 1;
+      nMid = (nLeft + nRight) / 2;
+      continue;
+    } else {
+      nLeft = nMid + 1;
+      nMid = (nLeft + nRight) / 2;
+      continue;
+    }
+  }
+  return (FX_FLOAT)gFontSizeSteps[nMid];
+}
+
+FX_BOOL CPDF_VariableText::IsBigger(FX_FLOAT fFontSize) {
+  FX_BOOL bBigger = FALSE;
+  CPVT_Size szTotal;
+  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
+    if (CSection* pSection = m_SectionArray.GetAt(s)) {
+      CPVT_Size size = pSection->GetSectionSize(fFontSize);
+      szTotal.x = std::max(size.x, szTotal.x);
+      szTotal.y += size.y;
+      if (IsFloatBigger(szTotal.x, GetPlateWidth()) ||
+          IsFloatBigger(szTotal.y, GetPlateHeight())) {
+        bBigger = TRUE;
+        break;
+      }
+    }
+  }
+  return bBigger;
+}
+
+CPVT_FloatRect CPDF_VariableText::RearrangeSections(
+    const CPVT_WordRange& PlaceRange) {
+  CPVT_WordPlace place;
+  FX_FLOAT fPosY = 0;
+  FX_FLOAT fOldHeight;
+  int32_t nSSecIndex = PlaceRange.BeginPos.nSecIndex;
+  int32_t nESecIndex = PlaceRange.EndPos.nSecIndex;
+  CPVT_FloatRect rcRet;
+  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
+    place.nSecIndex = s;
+    if (CSection* pSection = m_SectionArray.GetAt(s)) {
+      pSection->SecPlace = place;
+      CPVT_FloatRect rcSec = pSection->m_SecInfo.rcSection;
+      if (s >= nSSecIndex) {
+        if (s <= nESecIndex) {
+          rcSec = pSection->Rearrange();
+          rcSec.top += fPosY;
+          rcSec.bottom += fPosY;
+        } else {
+          fOldHeight = pSection->m_SecInfo.rcSection.bottom -
+                       pSection->m_SecInfo.rcSection.top;
+          rcSec.top = fPosY;
+          rcSec.bottom = fPosY + fOldHeight;
+        }
+        pSection->m_SecInfo.rcSection = rcSec;
+        pSection->ResetLinePlace();
+      }
+      if (s == 0) {
+        rcRet = rcSec;
+      } else {
+        rcRet.left = std::min(rcSec.left, rcRet.left);
+        rcRet.top = std::min(rcSec.top, rcRet.top);
+        rcRet.right = std::max(rcSec.right, rcRet.right);
+        rcRet.bottom = std::max(rcSec.bottom, rcRet.bottom);
+      }
+      fPosY += rcSec.Height();
+    }
+  }
+  return rcRet;
+}
+
+int32_t CPDF_VariableText::GetCharWidth(int32_t nFontIndex,
+                                        uint16_t Word,
+                                        uint16_t SubWord,
+                                        int32_t nWordStyle) {
+  if (!m_pVTProvider)
+    return 0;
+  if (SubWord > 0)
+    return m_pVTProvider->GetCharWidth(nFontIndex, SubWord, nWordStyle);
+  return m_pVTProvider->GetCharWidth(nFontIndex, Word, nWordStyle);
+}
+
+int32_t CPDF_VariableText::GetTypeAscent(int32_t nFontIndex) {
+  return m_pVTProvider ? m_pVTProvider->GetTypeAscent(nFontIndex) : 0;
+}
+
+int32_t CPDF_VariableText::GetTypeDescent(int32_t nFontIndex) {
+  return m_pVTProvider ? m_pVTProvider->GetTypeDescent(nFontIndex) : 0;
+}
+
+int32_t CPDF_VariableText::GetWordFontIndex(uint16_t word,
+                                            int32_t charset,
+                                            int32_t nFontIndex) {
+  return m_pVTProvider
+             ? m_pVTProvider->GetWordFontIndex(word, charset, nFontIndex)
+             : -1;
+}
+
+int32_t CPDF_VariableText::GetDefaultFontIndex() {
+  return m_pVTProvider ? m_pVTProvider->GetDefaultFontIndex() : -1;
+}
+
+FX_BOOL CPDF_VariableText::IsLatinWord(uint16_t word) {
+  return m_pVTProvider ? m_pVTProvider->IsLatinWord(word) : FALSE;
+}
+
+CPDF_VariableText::Iterator* CPDF_VariableText::GetIterator() {
+  if (!m_pVTIterator)
+    m_pVTIterator = new CPDF_VariableText::Iterator(this);
+  return m_pVTIterator;
+}
+
+CPDF_VariableText::Provider* CPDF_VariableText::SetProvider(
+    CPDF_VariableText::Provider* pProvider) {
+  CPDF_VariableText::Provider* pOld = m_pVTProvider;
+  m_pVTProvider = pProvider;
+  return pOld;
+}
diff --git a/core/fpdfdoc/cpvt_floatrect.h b/core/fpdfdoc/cpvt_floatrect.h
new file mode 100644
index 0000000..d581610
--- /dev/null
+++ b/core/fpdfdoc/cpvt_floatrect.h
@@ -0,0 +1,42 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_CPVT_FLOATRECT_H_
+#define CORE_FPDFDOC_CPVT_FLOATRECT_H_
+
+#include "core/fxcrt/include/fx_coordinates.h"
+
+class CPVT_FloatRect : public CFX_FloatRect {
+ public:
+  CPVT_FloatRect() { left = top = right = bottom = 0.0f; }
+
+  CPVT_FloatRect(FX_FLOAT other_left,
+                 FX_FLOAT other_top,
+                 FX_FLOAT other_right,
+                 FX_FLOAT other_bottom) {
+    left = other_left;
+    top = other_top;
+    right = other_right;
+    bottom = other_bottom;
+  }
+
+  explicit CPVT_FloatRect(const CFX_FloatRect& rect) {
+    left = rect.left;
+    top = rect.top;
+    right = rect.right;
+    bottom = rect.bottom;
+  }
+
+  void Default() { left = top = right = bottom = 0.0f; }
+
+  FX_FLOAT Height() const {
+    if (top > bottom)
+      return top - bottom;
+    return bottom - top;
+  }
+};
+
+#endif  // CORE_FPDFDOC_CPVT_FLOATRECT_H_
diff --git a/core/fpdfdoc/cpvt_fontmap.cpp b/core/fpdfdoc/cpvt_fontmap.cpp
index 0aa7ac3..eb8869d 100644
--- a/core/fpdfdoc/cpvt_fontmap.cpp
+++ b/core/fpdfdoc/cpvt_fontmap.cpp
@@ -74,3 +74,20 @@
       return "";
   }
 }
+
+int32_t CPVT_FontMap::GetWordFontIndex(uint16_t word,
+                                       int32_t charset,
+                                       int32_t nFontIndex) {
+  ASSERT(false);
+  return 0;
+}
+
+int32_t CPVT_FontMap::CharCodeFromUnicode(int32_t nFontIndex, uint16_t word) {
+  ASSERT(false);
+  return 0;
+}
+
+int32_t CPVT_FontMap::CharSetFromUnicode(uint16_t word, int32_t nOldCharset) {
+  ASSERT(false);
+  return 0;
+}
diff --git a/core/fpdfdoc/cpvt_fontmap.h b/core/fpdfdoc/cpvt_fontmap.h
index d6f931a..5c9b4ab 100644
--- a/core/fpdfdoc/cpvt_fontmap.h
+++ b/core/fpdfdoc/cpvt_fontmap.h
@@ -9,7 +9,7 @@
 
 #include <stdint.h>
 
-#include "core/fpdfdoc/ipvt_fontmap.h"
+#include "core/fpdfdoc/include/ipvt_fontmap.h"
 #include "core/fxcrt/include/fx_string.h"
 
 class CPDF_Document;
@@ -27,6 +27,11 @@
   // IPVT_FontMap:
   CPDF_Font* GetPDFFont(int32_t nFontIndex) override;
   CFX_ByteString GetPDFFontAlias(int32_t nFontIndex) override;
+  int32_t GetWordFontIndex(uint16_t word,
+                           int32_t charset,
+                           int32_t nFontIndex) override;
+  int32_t CharCodeFromUnicode(int32_t nFontIndex, uint16_t word) override;
+  int32_t CharSetFromUnicode(uint16_t word, int32_t nOldCharset) override;
 
   static void GetAnnotSysPDFFont(CPDF_Document* pDoc,
                                  const CPDF_Dictionary* pResDict,
diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp
index c5e2cc7..f323d9a 100644
--- a/core/fpdfdoc/cpvt_generateap.cpp
+++ b/core/fpdfdoc/cpvt_generateap.cpp
@@ -13,7 +13,7 @@
 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
 #include "core/fpdfdoc/cpvt_color.h"
 #include "core/fpdfdoc/cpvt_fontmap.h"
-#include "core/fpdfdoc/cpvt_provider.h"
+#include "core/fpdfdoc/include/cpvt_word.h"
 #include "core/fpdfdoc/pdf_vt.h"
 #include "core/include/fpdfdoc/fpdf_doc.h"
 
@@ -217,7 +217,7 @@
       CPVT_FontMap map(
           pDoc, pStreamDict ? pStreamDict->GetDictBy("Resources") : nullptr,
           pDefFont, sFontName.Right(sFontName.GetLength() - 1));
-      CPVT_Provider prd(&map);
+      CPDF_VariableText::Provider prd(&map);
       CPDF_VariableText vt;
       vt.SetProvider(&prd);
       vt.SetPlateRect(rcBody);
@@ -276,7 +276,7 @@
       CPVT_FontMap map(
           pDoc, pStreamDict ? pStreamDict->GetDictBy("Resources") : nullptr,
           pDefFont, sFontName.Right(sFontName.GetLength() - 1));
-      CPVT_Provider prd(&map);
+      CPDF_VariableText::Provider prd(&map);
       CPDF_VariableText vt;
       vt.SetProvider(&prd);
       CFX_FloatRect rcButton = rcBody;
@@ -344,7 +344,7 @@
       CPVT_FontMap map(
           pDoc, pStreamDict ? pStreamDict->GetDictBy("Resources") : nullptr,
           pDefFont, sFontName.Right(sFontName.GetLength() - 1));
-      CPVT_Provider prd(&map);
+      CPDF_VariableText::Provider prd(&map);
       CPDF_Array* pOpts = FPDF_GetFieldAttr(pAnnotDict, "Opt")
                               ? FPDF_GetFieldAttr(pAnnotDict, "Opt")->GetArray()
                               : nullptr;
@@ -502,7 +502,7 @@
 // Static.
 CFX_ByteString CPVT_GenerateAP::GenerateEditAP(
     IPVT_FontMap* pFontMap,
-    IPDF_VariableText::Iterator* pIterator,
+    CPDF_VariableText::Iterator* pIterator,
     const CFX_FloatPoint& ptOffset,
     FX_BOOL bContinuous,
     uint16_t SubWord,
diff --git a/core/fpdfdoc/cpvt_generateap.h b/core/fpdfdoc/cpvt_generateap.h
index 79062cb..09c0507 100644
--- a/core/fpdfdoc/cpvt_generateap.h
+++ b/core/fpdfdoc/cpvt_generateap.h
@@ -9,10 +9,10 @@
 
 #include "core/fpdfdoc/cpvt_color.h"
 #include "core/fpdfdoc/cpvt_dash.h"
+#include "core/fpdfdoc/include/cpdf_variabletext.h"
 #include "core/fxcrt/include/fx_coordinates.h"
 #include "core/fxcrt/include/fx_string.h"
 #include "core/fxcrt/include/fx_system.h"
-#include "core/include/fpdfdoc/fpdf_vt.h"
 
 // border style
 #define PBS_SOLID 0
@@ -39,7 +39,7 @@
   static FX_BOOL GenerateListBoxAP(CPDF_Document* pDoc,
                                    CPDF_Dictionary* pAnnotDict);
   static CFX_ByteString GenerateEditAP(IPVT_FontMap* pFontMap,
-                                       IPDF_VariableText::Iterator* pIterator,
+                                       CPDF_VariableText::Iterator* pIterator,
                                        const CFX_FloatPoint& ptOffset,
                                        FX_BOOL bContinuous,
                                        uint16_t SubWord = 0,
diff --git a/core/fpdfdoc/cpvt_lineinfo.h b/core/fpdfdoc/cpvt_lineinfo.h
new file mode 100644
index 0000000..ab66d8c
--- /dev/null
+++ b/core/fpdfdoc/cpvt_lineinfo.h
@@ -0,0 +1,33 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_CPVT_LINEINFO_H_
+#define CORE_FPDFDOC_CPVT_LINEINFO_H_
+
+#include "core/fxcrt/include/fx_system.h"
+
+struct CPVT_LineInfo {
+  CPVT_LineInfo()
+      : nTotalWord(0),
+        nBeginWordIndex(-1),
+        nEndWordIndex(-1),
+        fLineX(0.0f),
+        fLineY(0.0f),
+        fLineWidth(0.0f),
+        fLineAscent(0.0f),
+        fLineDescent(0.0f) {}
+
+  int32_t nTotalWord;
+  int32_t nBeginWordIndex;
+  int32_t nEndWordIndex;
+  FX_FLOAT fLineX;
+  FX_FLOAT fLineY;
+  FX_FLOAT fLineWidth;
+  FX_FLOAT fLineAscent;
+  FX_FLOAT fLineDescent;
+};
+
+#endif  // CORE_FPDFDOC_CPVT_LINEINFO_H_
diff --git a/core/fpdfdoc/cpvt_provider.h b/core/fpdfdoc/cpvt_provider.h
deleted file mode 100644
index fb6ff94..0000000
--- a/core/fpdfdoc/cpvt_provider.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFDOC_CPVT_PROVIDER_H_
-#define CORE_FPDFDOC_CPVT_PROVIDER_H_
-
-#include "core/fpdfdoc/ipvt_fontmap.h"
-#include "core/fxcrt/include/fx_system.h"
-#include "core/include/fpdfdoc/fpdf_vt.h"
-
-class CPVT_Provider : public IPDF_VariableText::Provider {
- public:
-  CPVT_Provider(IPVT_FontMap* pFontMap);
-  ~CPVT_Provider() override;
-
-  // IPDF_VariableText::Provider
-  int32_t GetCharWidth(int32_t nFontIndex,
-                       uint16_t word,
-                       int32_t nWordStyle) override;
-  int32_t GetTypeAscent(int32_t nFontIndex) override;
-  int32_t GetTypeDescent(int32_t nFontIndex) override;
-  int32_t GetWordFontIndex(uint16_t word,
-                           int32_t charset,
-                           int32_t nFontIndex) override;
-  FX_BOOL IsLatinWord(uint16_t word) override;
-  int32_t GetDefaultFontIndex() override;
-
- private:
-  IPVT_FontMap* m_pFontMap;
-};
-
-#endif  // CORE_FPDFDOC_CPVT_PROVIDER_H_
diff --git a/core/fpdfdoc/cpvt_sectioninfo.h b/core/fpdfdoc/cpvt_sectioninfo.h
new file mode 100644
index 0000000..e466ae5
--- /dev/null
+++ b/core/fpdfdoc/cpvt_sectioninfo.h
@@ -0,0 +1,54 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_CPVT_SECTIONINFO_H_
+#define CORE_FPDFDOC_CPVT_SECTIONINFO_H_
+
+#include "core/fpdfdoc/cpvt_floatrect.h"
+#include "core/fpdfdoc/include/cpvt_secprops.h"
+#include "core/fpdfdoc/include/cpvt_wordprops.h"
+
+struct CPVT_SectionInfo {
+  CPVT_SectionInfo()
+      : rcSection(), nTotalLine(0), pSecProps(nullptr), pWordProps(nullptr) {}
+
+  ~CPVT_SectionInfo() {
+    delete pSecProps;
+    delete pWordProps;
+  }
+
+  CPVT_SectionInfo(const CPVT_SectionInfo& other)
+      : rcSection(), nTotalLine(0), pSecProps(nullptr), pWordProps(nullptr) {
+    operator=(other);
+  }
+
+  void operator=(const CPVT_SectionInfo& other) {
+    if (this == &other)
+      return;
+
+    rcSection = other.rcSection;
+    nTotalLine = other.nTotalLine;
+    if (other.pSecProps) {
+      if (pSecProps)
+        *pSecProps = *other.pSecProps;
+      else
+        pSecProps = new CPVT_SecProps(*other.pSecProps);
+    }
+    if (other.pWordProps) {
+      if (pWordProps)
+        *pWordProps = *other.pWordProps;
+      else
+        pWordProps = new CPVT_WordProps(*other.pWordProps);
+    }
+  }
+
+  CPVT_FloatRect rcSection;
+  int32_t nTotalLine;
+  CPVT_SecProps* pSecProps;
+  CPVT_WordProps* pWordProps;
+};
+
+#endif  // CORE_FPDFDOC_CPVT_SECTIONINFO_H_
diff --git a/core/fpdfdoc/cpvt_wordinfo.h b/core/fpdfdoc/cpvt_wordinfo.h
new file mode 100644
index 0000000..3eb980f
--- /dev/null
+++ b/core/fpdfdoc/cpvt_wordinfo.h
@@ -0,0 +1,72 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_CPVT_WORDINFO_H_
+#define CORE_FPDFDOC_CPVT_WORDINFO_H_
+
+#include "core/fpdfdoc/include/cpvt_wordprops.h"
+#include "core/fxcrt/include/fx_system.h"
+
+struct CPVT_WordInfo {
+  CPVT_WordInfo()
+      : Word(0),
+        nCharset(0),
+        fWordX(0.0f),
+        fWordY(0.0f),
+        fWordTail(0.0f),
+        nFontIndex(-1),
+        pWordProps(nullptr) {}
+
+  CPVT_WordInfo(uint16_t word,
+                int32_t charset,
+                int32_t fontIndex,
+                CPVT_WordProps* pProps)
+      : Word(word),
+        nCharset(charset),
+        fWordX(0.0f),
+        fWordY(0.0f),
+        fWordTail(0.0f),
+        nFontIndex(fontIndex),
+        pWordProps(pProps) {}
+
+  CPVT_WordInfo(const CPVT_WordInfo& word)
+      : Word(0),
+        nCharset(0),
+        fWordX(0.0f),
+        fWordY(0.0f),
+        fWordTail(0.0f),
+        nFontIndex(-1),
+        pWordProps(nullptr) {
+    operator=(word);
+  }
+
+  ~CPVT_WordInfo() { delete pWordProps; }
+
+  void operator=(const CPVT_WordInfo& word) {
+    if (this == &word)
+      return;
+
+    Word = word.Word;
+    nCharset = word.nCharset;
+    nFontIndex = word.nFontIndex;
+    if (word.pWordProps) {
+      if (pWordProps)
+        *pWordProps = *word.pWordProps;
+      else
+        pWordProps = new CPVT_WordProps(*word.pWordProps);
+    }
+  }
+
+  uint16_t Word;
+  int32_t nCharset;
+  FX_FLOAT fWordX;
+  FX_FLOAT fWordY;
+  FX_FLOAT fWordTail;
+  int32_t nFontIndex;
+  CPVT_WordProps* pWordProps;
+};
+
+#endif  // CORE_FPDFDOC_CPVT_WORDINFO_H_
diff --git a/core/fpdfdoc/csection.h b/core/fpdfdoc/csection.h
new file mode 100644
index 0000000..d8974cb
--- /dev/null
+++ b/core/fpdfdoc/csection.h
@@ -0,0 +1,62 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_CSECTION_H_
+#define CORE_FPDFDOC_CSECTION_H_
+
+#include "core/fpdfdoc/cpvt_sectioninfo.h"
+#include "core/fpdfdoc/ctypeset.h"
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_VariableText;
+
+struct CPVT_LineInfo;
+struct CPVT_WordLine;
+struct CPVT_WordPlace;
+
+class CSection {
+ public:
+  explicit CSection(CPDF_VariableText* pVT);
+  virtual ~CSection();
+  void ResetAll();
+  void ResetLineArray();
+  void ResetWordArray();
+  void ResetLinePlace();
+  CPVT_WordPlace AddWord(const CPVT_WordPlace& place,
+                         const CPVT_WordInfo& wordinfo);
+  CPVT_WordPlace AddLine(const CPVT_LineInfo& lineinfo);
+  void ClearWords(const CPVT_WordRange& PlaceRange);
+  void ClearWord(const CPVT_WordPlace& place);
+  CPVT_FloatRect Rearrange();
+  CPVT_Size GetSectionSize(FX_FLOAT fFontSize);
+  CPVT_WordPlace GetBeginWordPlace() const;
+  CPVT_WordPlace GetEndWordPlace() const;
+  CPVT_WordPlace GetPrevWordPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace GetNextWordPlace(const CPVT_WordPlace& place) const;
+  void UpdateWordPlace(CPVT_WordPlace& place) const;
+  CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const;
+  CPVT_WordPlace SearchWordPlace(FX_FLOAT fx,
+                                 const CPVT_WordPlace& lineplace) const;
+  CPVT_WordPlace SearchWordPlace(FX_FLOAT fx,
+                                 const CPVT_WordRange& range) const;
+
+  CPVT_WordPlace SecPlace;
+  CPVT_SectionInfo m_SecInfo;
+  CLines m_LineArray;
+  CPVT_ArrayTemplate<CPVT_WordInfo*> m_WordArray;
+
+ private:
+  friend class CTypeset;
+
+  void ClearLeftWords(int32_t nWordIndex);
+  void ClearRightWords(int32_t nWordIndex);
+  void ClearMidWords(int32_t nBeginIndex, int32_t nEndIndex);
+
+  CPDF_VariableText* m_pVT;
+};
+
+#endif  // CORE_FPDFDOC_CSECTION_H_
diff --git a/core/fpdfdoc/ctypeset.h b/core/fpdfdoc/ctypeset.h
new file mode 100644
index 0000000..25bb31a
--- /dev/null
+++ b/core/fpdfdoc/ctypeset.h
@@ -0,0 +1,33 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_CTYPESET_H_
+#define CORE_FPDFDOC_CTYPESET_H_
+
+#include "core/fpdfdoc/cpvt_floatrect.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_VariableText;
+class CSection;
+
+class CTypeset {
+ public:
+  explicit CTypeset(CSection* pSection);
+  virtual ~CTypeset();
+  CPVT_Size GetEditSize(FX_FLOAT fFontSize);
+  CPVT_FloatRect Typeset();
+  CPVT_FloatRect CharArray();
+
+ private:
+  void SplitLines(FX_BOOL bTypeset, FX_FLOAT fFontSize);
+  void OutputLines();
+
+  CPVT_FloatRect m_rcRet;
+  CPDF_VariableText* m_pVT;
+  CSection* const m_pSection;
+};
+
+#endif  // CORE_FPDFDOC_CTYPESET_H_
diff --git a/core/fpdfdoc/doc_ap.cpp b/core/fpdfdoc/doc_ap.cpp
deleted file mode 100644
index 440979e..0000000
--- a/core/fpdfdoc/doc_ap.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
-#include "core/fpdfdoc/cpvt_provider.h"
-#include "core/fpdfdoc/doc_utils.h"
-#include "core/fpdfdoc/pdf_vt.h"
-#include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fpdfdoc/fpdf_vt.h"
-
-CPVT_Provider::CPVT_Provider(IPVT_FontMap* pFontMap) : m_pFontMap(pFontMap) {
-  ASSERT(m_pFontMap);
-}
-CPVT_Provider::~CPVT_Provider() {}
-int32_t CPVT_Provider::GetCharWidth(int32_t nFontIndex,
-                                    uint16_t word,
-                                    int32_t nWordStyle) {
-  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
-    uint32_t charcode = pPDFFont->CharCodeFromUnicode(word);
-    if (charcode != CPDF_Font::kInvalidCharCode) {
-      return pPDFFont->GetCharWidthF(charcode);
-    }
-  }
-  return 0;
-}
-int32_t CPVT_Provider::GetTypeAscent(int32_t nFontIndex) {
-  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
-    return pPDFFont->GetTypeAscent();
-  }
-  return 0;
-}
-int32_t CPVT_Provider::GetTypeDescent(int32_t nFontIndex) {
-  if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex)) {
-    return pPDFFont->GetTypeDescent();
-  }
-  return 0;
-}
-int32_t CPVT_Provider::GetWordFontIndex(uint16_t word,
-                                        int32_t charset,
-                                        int32_t nFontIndex) {
-  if (CPDF_Font* pDefFont = m_pFontMap->GetPDFFont(0)) {
-    if (pDefFont->CharCodeFromUnicode(word) != CPDF_Font::kInvalidCharCode) {
-      return 0;
-    }
-  }
-  if (CPDF_Font* pSysFont = m_pFontMap->GetPDFFont(1)) {
-    if (pSysFont->CharCodeFromUnicode(word) != CPDF_Font::kInvalidCharCode) {
-      return 1;
-    }
-  }
-  return -1;
-}
-FX_BOOL CPVT_Provider::IsLatinWord(uint16_t word) {
-  if ((word >= 0x61 && word <= 0x7A) || (word >= 0x41 && word <= 0x5A) ||
-      word == 0x2D || word == 0x27) {
-    return TRUE;
-  }
-  return FALSE;
-}
-int32_t CPVT_Provider::GetDefaultFontIndex() {
-  return 0;
-}
-
diff --git a/core/fpdfdoc/doc_vt.cpp b/core/fpdfdoc/doc_vt.cpp
index e91b945..fa3d3a2 100644
--- a/core/fpdfdoc/doc_vt.cpp
+++ b/core/fpdfdoc/doc_vt.cpp
@@ -6,22 +6,12 @@
 
 #include <algorithm>
 
+#include "core/fpdfdoc/cpvt_wordinfo.h"
+#include "core/fpdfdoc/csection.h"
+#include "core/fpdfdoc/include/cpdf_variabletext.h"
 #include "core/fpdfdoc/pdf_vt.h"
 #include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fpdfdoc/fpdf_vt.h"
-#include "core/include/fpdfdoc/fpdf_vt.h"
 
-const uint8_t gFontSizeSteps[] = {4,  6,  8,   9,   10,  12,  14, 18, 20,
-                                  25, 30, 35,  40,  45,  50,  55, 60, 70,
-                                  80, 90, 100, 110, 120, 130, 144};
-#define PVT_RETURN_LENGTH 1
-#define PVT_DEFAULT_FONTSIZE 18.0f
-#define PVTWORD_SCRIPT_NORMAL 0
-#define PVTWORD_SCRIPT_SUPER 1
-#define PVTWORD_SCRIPT_SUB 2
-#define PVT_FONTSCALE 0.001f
-#define PVT_PERCENT 0.01f
-#define PVT_HALF 0.5f
 CLine::CLine() {}
 CLine::~CLine() {}
 CPVT_WordPlace CLine::GetBeginWordPlace() const {
@@ -244,7 +234,8 @@
       break;
     }
     if (CPVT_WordInfo* pWord = m_WordArray.GetAt(nMid)) {
-      if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * PVT_HALF) {
+      if (fx >
+          pWord->fWordX + m_pVT->GetWordWidth(*pWord) * VARIABLETEXT_HALF) {
         nLeft = nMid;
         nMid = (nLeft + nRight) / 2;
         continue;
@@ -258,7 +249,7 @@
     }
   }
   if (CPVT_WordInfo* pWord = m_WordArray.GetAt(nMid)) {
-    if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * PVT_HALF) {
+    if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * VARIABLETEXT_HALF) {
       wordplace.nWordIndex = nMid;
     }
   }
@@ -326,15 +317,17 @@
     nStart = 0;
     switch (m_pVT->GetAlignment(m_pSection->m_SecInfo)) {
       case 0:
-        pLine->m_LineInfo.fLineX = fNodeWidth * PVT_HALF;
+        pLine->m_LineInfo.fLineX = fNodeWidth * VARIABLETEXT_HALF;
         break;
       case 1:
         nStart = (m_pVT->m_nCharArray - m_pSection->m_WordArray.GetSize()) / 2;
-        pLine->m_LineInfo.fLineX = fNodeWidth * nStart - fNodeWidth * PVT_HALF;
+        pLine->m_LineInfo.fLineX =
+            fNodeWidth * nStart - fNodeWidth * VARIABLETEXT_HALF;
         break;
       case 2:
         nStart = m_pVT->m_nCharArray - m_pSection->m_WordArray.GetSize();
-        pLine->m_LineInfo.fLineX = fNodeWidth * nStart - fNodeWidth * PVT_HALF;
+        pLine->m_LineInfo.fLineX =
+            fNodeWidth * nStart - fNodeWidth * VARIABLETEXT_HALF;
         break;
     }
     for (int32_t w = 0, sz = m_pSection->m_WordArray.GetSize(); w < sz; w++) {
@@ -353,7 +346,8 @@
         FX_FLOAT fWordWidth = m_pVT->GetWordWidth(*pWord);
         FX_FLOAT fWordAscent = m_pVT->GetWordAscent(*pWord);
         FX_FLOAT fWordDescent = m_pVT->GetWordDescent(*pWord);
-        x = (FX_FLOAT)(fNodeWidth * (w + nStart + 0.5) - fWordWidth * PVT_HALF);
+        x = (FX_FLOAT)(fNodeWidth * (w + nStart + 0.5) -
+                       fWordWidth * VARIABLETEXT_HALF);
         pWord->fWordX = x;
         pWord->fWordY = y;
         if (w == 0) {
@@ -361,8 +355,8 @@
         }
         if (w != m_pSection->m_WordArray.GetSize() - 1) {
           pWord->fWordTail =
-              (fNodeWidth - (fWordWidth + fNextWidth) * PVT_HALF > 0
-                   ? fNodeWidth - (fWordWidth + fNextWidth) * PVT_HALF
+              (fNodeWidth - (fWordWidth + fNextWidth) * VARIABLETEXT_HALF > 0
+                   ? fNodeWidth - (fWordWidth + fNextWidth) * VARIABLETEXT_HALF
                    : 0);
         } else {
           pWord->fWordTail = 0;
@@ -712,7 +706,7 @@
       fMinX = 0.0f;
       break;
     case 1:
-      fMinX = (fTypesetWidth - m_rcRet.Width()) * PVT_HALF;
+      fMinX = (fTypesetWidth - m_rcRet.Width()) * VARIABLETEXT_HALF;
       break;
     case 2:
       fMinX = fTypesetWidth - m_rcRet.Width();
@@ -732,7 +726,8 @@
             fPosX = 0;
             break;
           case 1:
-            fPosX = (fTypesetWidth - pLine->m_LineInfo.fLineWidth) * PVT_HALF;
+            fPosX = (fTypesetWidth - pLine->m_LineInfo.fLineWidth) *
+                    VARIABLETEXT_HALF;
             break;
           case 2:
             fPosX = fTypesetWidth - pLine->m_LineInfo.fLineWidth;
@@ -750,13 +745,13 @@
             if (pWord->pWordProps) {
               switch (pWord->pWordProps->nScriptType) {
                 default:
-                case PVTWORD_SCRIPT_NORMAL:
+                case CPDF_VariableText::ScriptType::Normal:
                   pWord->fWordY = fPosY - fMinY;
                   break;
-                case PVTWORD_SCRIPT_SUPER:
+                case CPDF_VariableText::ScriptType::Super:
                   pWord->fWordY = fPosY - m_pVT->GetWordAscent(*pWord) - fMinY;
                   break;
-                case PVTWORD_SCRIPT_SUB:
+                case CPDF_VariableText::ScriptType::Sub:
                   pWord->fWordY = fPosY - m_pVT->GetWordDescent(*pWord) - fMinY;
                   break;
               }
@@ -772,1037 +767,3 @@
   }
   m_rcRet = CPVT_FloatRect(fMinX, fMinY, fMaxX, fMaxY);
 }
-CPDF_VariableText::CPDF_VariableText()
-    : m_nLimitChar(0),
-      m_nCharArray(0),
-      m_bMultiLine(FALSE),
-      m_bLimitWidth(FALSE),
-      m_bAutoFontSize(FALSE),
-      m_nAlignment(0),
-      m_fLineLeading(0.0f),
-      m_fCharSpace(0.0f),
-      m_nHorzScale(100),
-      m_wSubWord(0),
-      m_fFontSize(0.0f),
-      m_bInitial(FALSE),
-      m_bRichText(FALSE),
-      m_pVTProvider(NULL),
-      m_pVTIterator(NULL) {}
-CPDF_VariableText::~CPDF_VariableText() {
-  delete m_pVTIterator;
-  m_pVTIterator = NULL;
-  ResetAll();
-}
-void CPDF_VariableText::Initialize() {
-  if (!m_bInitial) {
-    CPVT_SectionInfo secinfo;
-    if (m_bRichText) {
-      secinfo.pSecProps = new CPVT_SecProps(0.0f, 0.0f, 0);
-      secinfo.pWordProps = new CPVT_WordProps(GetDefaultFontIndex(),
-                                              PVT_DEFAULT_FONTSIZE, 0, 0, 0);
-    }
-    CPVT_WordPlace place;
-    place.nSecIndex = 0;
-    AddSection(place, secinfo);
-    CPVT_LineInfo lineinfo;
-    lineinfo.fLineAscent = GetFontAscent(GetDefaultFontIndex(), GetFontSize());
-    lineinfo.fLineDescent =
-        GetFontDescent(GetDefaultFontIndex(), GetFontSize());
-    AddLine(place, lineinfo);
-    if (CSection* pSection = m_SectionArray.GetAt(0)) {
-      pSection->ResetLinePlace();
-    }
-    m_bInitial = TRUE;
-  }
-}
-void CPDF_VariableText::ResetAll() {
-  m_bInitial = FALSE;
-  ResetSectionArray();
-}
-CPVT_WordPlace CPDF_VariableText::InsertWord(const CPVT_WordPlace& place,
-                                             uint16_t word,
-                                             int32_t charset,
-                                             const CPVT_WordProps* pWordProps) {
-  int32_t nTotlaWords = GetTotalWords();
-  if (m_nLimitChar > 0 && nTotlaWords >= m_nLimitChar) {
-    return place;
-  }
-  if (m_nCharArray > 0 && nTotlaWords >= m_nCharArray) {
-    return place;
-  }
-  CPVT_WordPlace newplace = place;
-  newplace.nWordIndex++;
-  if (m_bRichText) {
-    CPVT_WordProps* pNewProps =
-        pWordProps ? new CPVT_WordProps(*pWordProps) : new CPVT_WordProps();
-    pNewProps->nFontIndex =
-        GetWordFontIndex(word, charset, pWordProps->nFontIndex);
-    return AddWord(newplace, CPVT_WordInfo(word, charset, -1, pNewProps));
-  }
-  int32_t nFontIndex =
-      GetSubWord() > 0 ? GetDefaultFontIndex()
-                       : GetWordFontIndex(word, charset, GetDefaultFontIndex());
-  return AddWord(newplace, CPVT_WordInfo(word, charset, nFontIndex, NULL));
-}
-CPVT_WordPlace CPDF_VariableText::InsertSection(
-    const CPVT_WordPlace& place,
-    const CPVT_SecProps* pSecProps,
-    const CPVT_WordProps* pWordProps) {
-  int32_t nTotlaWords = GetTotalWords();
-  if (m_nLimitChar > 0 && nTotlaWords >= m_nLimitChar) {
-    return place;
-  }
-  if (m_nCharArray > 0 && nTotlaWords >= m_nCharArray) {
-    return place;
-  }
-  if (!m_bMultiLine) {
-    return place;
-  }
-  CPVT_WordPlace wordplace = place;
-  UpdateWordPlace(wordplace);
-  CPVT_WordPlace newplace = place;
-  if (CSection* pSection = m_SectionArray.GetAt(wordplace.nSecIndex)) {
-    CPVT_WordPlace NewPlace(wordplace.nSecIndex + 1, 0, -1);
-    CPVT_SectionInfo secinfo;
-    if (m_bRichText) {
-      if (pSecProps) {
-        secinfo.pSecProps = new CPVT_SecProps(*pSecProps);
-      }
-      if (pWordProps) {
-        secinfo.pWordProps = new CPVT_WordProps(*pWordProps);
-      }
-    }
-    AddSection(NewPlace, secinfo);
-    newplace = NewPlace;
-    if (CSection* pNewSection = m_SectionArray.GetAt(NewPlace.nSecIndex)) {
-      for (int32_t w = wordplace.nWordIndex + 1,
-                   sz = pSection->m_WordArray.GetSize();
-           w < sz; w++) {
-        if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(w)) {
-          NewPlace.nWordIndex++;
-          pNewSection->AddWord(NewPlace, *pWord);
-        }
-      }
-    }
-    ClearSectionRightWords(wordplace);
-  }
-  return newplace;
-}
-CPVT_WordPlace CPDF_VariableText::InsertText(const CPVT_WordPlace& place,
-                                             const FX_WCHAR* text,
-                                             int32_t charset,
-                                             const CPVT_SecProps* pSecProps,
-                                             const CPVT_WordProps* pProps) {
-  CFX_WideString swText = text;
-  CPVT_WordPlace wp = place;
-  for (int32_t i = 0, sz = swText.GetLength(); i < sz; i++) {
-    CPVT_WordPlace oldwp = wp;
-    uint16_t word = swText.GetAt(i);
-    switch (word) {
-      case 0x0D:
-        if (m_bMultiLine) {
-          if (swText.GetAt(i + 1) == 0x0A) {
-            i += 1;
-          }
-          wp = InsertSection(wp, pSecProps, pProps);
-        }
-        break;
-      case 0x0A:
-        if (m_bMultiLine) {
-          if (swText.GetAt(i + 1) == 0x0D) {
-            i += 1;
-          }
-          wp = InsertSection(wp, pSecProps, pProps);
-        }
-        break;
-      case 0x09:
-        word = 0x20;
-      default:
-        wp = InsertWord(wp, word, charset, pProps);
-        break;
-    }
-    if (wp == oldwp) {
-      break;
-    }
-  }
-  return wp;
-}
-CPVT_WordPlace CPDF_VariableText::DeleteWords(
-    const CPVT_WordRange& PlaceRange) {
-  FX_BOOL bLastSecPos = FALSE;
-  if (CSection* pSection = m_SectionArray.GetAt(PlaceRange.EndPos.nSecIndex)) {
-    bLastSecPos = (PlaceRange.EndPos == pSection->GetEndWordPlace());
-  }
-  ClearWords(PlaceRange);
-  if (PlaceRange.BeginPos.nSecIndex != PlaceRange.EndPos.nSecIndex) {
-    ClearEmptySections(PlaceRange);
-    if (!bLastSecPos) {
-      LinkLatterSection(PlaceRange.BeginPos);
-    }
-  }
-  return PlaceRange.BeginPos;
-}
-CPVT_WordPlace CPDF_VariableText::DeleteWord(const CPVT_WordPlace& place) {
-  return ClearRightWord(AdjustLineHeader(place, TRUE));
-}
-CPVT_WordPlace CPDF_VariableText::BackSpaceWord(const CPVT_WordPlace& place) {
-  return ClearLeftWord(AdjustLineHeader(place, TRUE));
-}
-void CPDF_VariableText::SetText(const FX_WCHAR* text,
-                                int32_t charset,
-                                const CPVT_SecProps* pSecProps,
-                                const CPVT_WordProps* pWordProps) {
-  DeleteWords(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
-  CFX_WideString swText = text;
-  CPVT_WordPlace wp(0, 0, -1);
-  CPVT_SectionInfo secinfo;
-  if (m_bRichText) {
-    if (pSecProps) {
-      secinfo.pSecProps = new CPVT_SecProps(*pSecProps);
-    }
-    if (pWordProps) {
-      secinfo.pWordProps = new CPVT_WordProps(*pWordProps);
-    }
-  }
-  if (CSection* pSection = m_SectionArray.GetAt(0)) {
-    pSection->m_SecInfo = secinfo;
-  }
-  int32_t nCharCount = 0;
-  for (int32_t i = 0, sz = swText.GetLength(); i < sz; i++) {
-    if (m_nLimitChar > 0 && nCharCount >= m_nLimitChar) {
-      break;
-    }
-    if (m_nCharArray > 0 && nCharCount >= m_nCharArray) {
-      break;
-    }
-    uint16_t word = swText.GetAt(i);
-    switch (word) {
-      case 0x0D:
-        if (m_bMultiLine) {
-          if (swText.GetAt(i + 1) == 0x0A) {
-            i += 1;
-          }
-          wp.nSecIndex++;
-          wp.nLineIndex = 0;
-          wp.nWordIndex = -1;
-          AddSection(wp, secinfo);
-        }
-        break;
-      case 0x0A:
-        if (m_bMultiLine) {
-          if (swText.GetAt(i + 1) == 0x0D) {
-            i += 1;
-          }
-          wp.nSecIndex++;
-          wp.nLineIndex = 0;
-          wp.nWordIndex = -1;
-          AddSection(wp, secinfo);
-        }
-        break;
-      case 0x09:
-        word = 0x20;
-      default:
-        wp = InsertWord(wp, word, charset, pWordProps);
-        break;
-    }
-    nCharCount++;
-  }
-}
-void CPDF_VariableText::UpdateWordPlace(CPVT_WordPlace& place) const {
-  if (place.nSecIndex < 0) {
-    place = GetBeginWordPlace();
-  }
-  if (place.nSecIndex >= m_SectionArray.GetSize()) {
-    place = GetEndWordPlace();
-  }
-  place = AdjustLineHeader(place, TRUE);
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    pSection->UpdateWordPlace(place);
-  }
-}
-int32_t CPDF_VariableText::WordPlaceToWordIndex(
-    const CPVT_WordPlace& place) const {
-  CPVT_WordPlace newplace = place;
-  UpdateWordPlace(newplace);
-  int32_t nIndex = 0;
-  int32_t i = 0;
-  int32_t sz = 0;
-  for (i = 0, sz = m_SectionArray.GetSize(); i < sz && i < newplace.nSecIndex;
-       i++) {
-    if (CSection* pSection = m_SectionArray.GetAt(i)) {
-      nIndex += pSection->m_WordArray.GetSize();
-      if (i != m_SectionArray.GetSize() - 1) {
-        nIndex += PVT_RETURN_LENGTH;
-      }
-    }
-  }
-  if (i >= 0 && i < m_SectionArray.GetSize()) {
-    nIndex += newplace.nWordIndex + PVT_RETURN_LENGTH;
-  }
-  return nIndex;
-}
-CPVT_WordPlace CPDF_VariableText::WordIndexToWordPlace(int32_t index) const {
-  CPVT_WordPlace place = GetBeginWordPlace();
-  int32_t nOldIndex = 0, nIndex = 0;
-  FX_BOOL bFind = FALSE;
-  for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++) {
-    if (CSection* pSection = m_SectionArray.GetAt(i)) {
-      nIndex += pSection->m_WordArray.GetSize();
-      if (nIndex == index) {
-        place = pSection->GetEndWordPlace();
-        bFind = TRUE;
-        break;
-      } else if (nIndex > index) {
-        place.nSecIndex = i;
-        place.nWordIndex = index - nOldIndex - 1;
-        pSection->UpdateWordPlace(place);
-        bFind = TRUE;
-        break;
-      }
-      if (i != m_SectionArray.GetSize() - 1) {
-        nIndex += PVT_RETURN_LENGTH;
-      }
-      nOldIndex = nIndex;
-    }
-  }
-  if (!bFind) {
-    place = GetEndWordPlace();
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::GetBeginWordPlace() const {
-  return m_bInitial ? CPVT_WordPlace(0, 0, -1) : CPVT_WordPlace();
-}
-CPVT_WordPlace CPDF_VariableText::GetEndWordPlace() const {
-  if (CSection* pSection = m_SectionArray.GetAt(m_SectionArray.GetSize() - 1)) {
-    return pSection->GetEndWordPlace();
-  }
-  return CPVT_WordPlace();
-}
-CPVT_WordPlace CPDF_VariableText::GetPrevWordPlace(
-    const CPVT_WordPlace& place) const {
-  if (place.nSecIndex < 0) {
-    return GetBeginWordPlace();
-  }
-  if (place.nSecIndex >= m_SectionArray.GetSize()) {
-    return GetEndWordPlace();
-  }
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    if (place.WordCmp(pSection->GetBeginWordPlace()) <= 0) {
-      if (CSection* pPrevSection = m_SectionArray.GetAt(place.nSecIndex - 1)) {
-        return pPrevSection->GetEndWordPlace();
-      }
-      return GetBeginWordPlace();
-    }
-    return pSection->GetPrevWordPlace(place);
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::GetNextWordPlace(
-    const CPVT_WordPlace& place) const {
-  if (place.nSecIndex < 0) {
-    return GetBeginWordPlace();
-  }
-  if (place.nSecIndex >= m_SectionArray.GetSize()) {
-    return GetEndWordPlace();
-  }
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    if (place.WordCmp(pSection->GetEndWordPlace()) >= 0) {
-      if (CSection* pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1)) {
-        return pNextSection->GetBeginWordPlace();
-      }
-      return GetEndWordPlace();
-    }
-    return pSection->GetNextWordPlace(place);
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::SearchWordPlace(
-    const CFX_FloatPoint& point) const {
-  CFX_FloatPoint pt = OutToIn(point);
-  CPVT_WordPlace place = GetBeginWordPlace();
-  int32_t nLeft = 0;
-  int32_t nRight = m_SectionArray.GetSize() - 1;
-  int32_t nMid = m_SectionArray.GetSize() / 2;
-  FX_BOOL bUp = TRUE;
-  FX_BOOL bDown = TRUE;
-  while (nLeft <= nRight) {
-    if (CSection* pSection = m_SectionArray.GetAt(nMid)) {
-      if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.top)) {
-        bUp = FALSE;
-      }
-      if (IsFloatBigger(pSection->m_SecInfo.rcSection.bottom, pt.y)) {
-        bDown = FALSE;
-      }
-      if (IsFloatSmaller(pt.y, pSection->m_SecInfo.rcSection.top)) {
-        nRight = nMid - 1;
-        nMid = (nLeft + nRight) / 2;
-        continue;
-      } else if (IsFloatBigger(pt.y, pSection->m_SecInfo.rcSection.bottom)) {
-        nLeft = nMid + 1;
-        nMid = (nLeft + nRight) / 2;
-        continue;
-      } else {
-        place = pSection->SearchWordPlace(
-            CFX_FloatPoint(pt.x - pSection->m_SecInfo.rcSection.left,
-                           pt.y - pSection->m_SecInfo.rcSection.top));
-        place.nSecIndex = nMid;
-        return place;
-      }
-    } else {
-      break;
-    }
-  }
-  if (bUp) {
-    place = GetBeginWordPlace();
-  }
-  if (bDown) {
-    place = GetEndWordPlace();
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::GetUpWordPlace(
-    const CPVT_WordPlace& place,
-    const CFX_FloatPoint& point) const {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    CPVT_WordPlace temp = place;
-    CFX_FloatPoint pt = OutToIn(point);
-    if (temp.nLineIndex-- > 0) {
-      return pSection->SearchWordPlace(
-          pt.x - pSection->m_SecInfo.rcSection.left, temp);
-    }
-    if (temp.nSecIndex-- > 0) {
-      if (CSection* pLastSection = m_SectionArray.GetAt(temp.nSecIndex)) {
-        temp.nLineIndex = pLastSection->m_LineArray.GetSize() - 1;
-        return pLastSection->SearchWordPlace(
-            pt.x - pLastSection->m_SecInfo.rcSection.left, temp);
-      }
-    }
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::GetDownWordPlace(
-    const CPVT_WordPlace& place,
-    const CFX_FloatPoint& point) const {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    CPVT_WordPlace temp = place;
-    CFX_FloatPoint pt = OutToIn(point);
-    if (temp.nLineIndex++ < pSection->m_LineArray.GetSize() - 1) {
-      return pSection->SearchWordPlace(
-          pt.x - pSection->m_SecInfo.rcSection.left, temp);
-    }
-    if (temp.nSecIndex++ < m_SectionArray.GetSize() - 1) {
-      if (CSection* pNextSection = m_SectionArray.GetAt(temp.nSecIndex)) {
-        temp.nLineIndex = 0;
-        return pNextSection->SearchWordPlace(
-            pt.x - pSection->m_SecInfo.rcSection.left, temp);
-      }
-    }
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::GetLineBeginPlace(
-    const CPVT_WordPlace& place) const {
-  return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, -1);
-}
-CPVT_WordPlace CPDF_VariableText::GetLineEndPlace(
-    const CPVT_WordPlace& place) const {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    if (CLine* pLine = pSection->m_LineArray.GetAt(place.nLineIndex))
-      return pLine->GetEndWordPlace();
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::GetSectionBeginPlace(
-    const CPVT_WordPlace& place) const {
-  return CPVT_WordPlace(place.nSecIndex, 0, -1);
-}
-CPVT_WordPlace CPDF_VariableText::GetSectionEndPlace(
-    const CPVT_WordPlace& place) const {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    return pSection->GetEndWordPlace();
-  }
-  return place;
-}
-int32_t CPDF_VariableText::GetTotalWords() const {
-  int32_t nTotal = 0;
-  for (int32_t i = 0, sz = m_SectionArray.GetSize(); i < sz; i++)
-    if (CSection* pSection = m_SectionArray.GetAt(i)) {
-      nTotal += (pSection->m_WordArray.GetSize() + PVT_RETURN_LENGTH);
-    }
-  return nTotal - PVT_RETURN_LENGTH;
-}
-void CPDF_VariableText::ResetSectionArray() {
-  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
-    delete m_SectionArray.GetAt(s);
-  }
-  m_SectionArray.RemoveAll();
-}
-CPVT_WordPlace CPDF_VariableText::AddSection(const CPVT_WordPlace& place,
-                                             const CPVT_SectionInfo& secinfo) {
-  if (IsValid() && !m_bMultiLine) {
-    return place;
-  }
-  int32_t nSecIndex =
-      std::max(std::min(place.nSecIndex, m_SectionArray.GetSize()), 0);
-  CSection* pSection = new CSection(this);
-  pSection->m_SecInfo = secinfo;
-  pSection->SecPlace.nSecIndex = nSecIndex;
-  if (nSecIndex == m_SectionArray.GetSize()) {
-    m_SectionArray.Add(pSection);
-  } else {
-    m_SectionArray.InsertAt(nSecIndex, pSection);
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::AddLine(const CPVT_WordPlace& place,
-                                          const CPVT_LineInfo& lineinfo) {
-  if (m_SectionArray.IsEmpty()) {
-    return place;
-  }
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    return pSection->AddLine(lineinfo);
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::AddWord(const CPVT_WordPlace& place,
-                                          const CPVT_WordInfo& wordinfo) {
-  if (m_SectionArray.GetSize() <= 0) {
-    return place;
-  }
-  CPVT_WordPlace newplace = place;
-  newplace.nSecIndex =
-      std::max(std::min(newplace.nSecIndex, m_SectionArray.GetSize() - 1), 0);
-  if (CSection* pSection = m_SectionArray.GetAt(newplace.nSecIndex)) {
-    return pSection->AddWord(newplace, wordinfo);
-  }
-  return place;
-}
-FX_BOOL CPDF_VariableText::GetWordInfo(const CPVT_WordPlace& place,
-                                       CPVT_WordInfo& wordinfo) {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) {
-      wordinfo = *pWord;
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText::SetWordInfo(const CPVT_WordPlace& place,
-                                       const CPVT_WordInfo& wordinfo) {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    if (CPVT_WordInfo* pWord = pSection->m_WordArray.GetAt(place.nWordIndex)) {
-      *pWord = wordinfo;
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText::GetLineInfo(const CPVT_WordPlace& place,
-                                       CPVT_LineInfo& lineinfo) {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    if (CLine* pLine = pSection->m_LineArray.GetAt(place.nLineIndex)) {
-      lineinfo = pLine->m_LineInfo;
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText::GetSectionInfo(const CPVT_WordPlace& place,
-                                          CPVT_SectionInfo& secinfo) {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    secinfo = pSection->m_SecInfo;
-    return TRUE;
-  }
-  return FALSE;
-}
-CFX_FloatRect CPDF_VariableText::GetContentRect() const {
-  return InToOut(CPVT_FloatRect(CPDF_EditContainer::GetContentRect()));
-}
-FX_FLOAT CPDF_VariableText::GetWordFontSize(const CPVT_WordInfo& WordInfo,
-                                            FX_BOOL bFactFontSize) {
-  return m_bRichText && WordInfo.pWordProps
-             ? (WordInfo.pWordProps->nScriptType == PVTWORD_SCRIPT_NORMAL ||
-                        bFactFontSize
-                    ? WordInfo.pWordProps->fFontSize
-                    : WordInfo.pWordProps->fFontSize * PVT_HALF)
-             : GetFontSize();
-}
-int32_t CPDF_VariableText::GetWordFontIndex(const CPVT_WordInfo& WordInfo) {
-  return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->nFontIndex
-                                            : WordInfo.nFontIndex;
-}
-FX_FLOAT CPDF_VariableText::GetWordWidth(int32_t nFontIndex,
-                                         uint16_t Word,
-                                         uint16_t SubWord,
-                                         FX_FLOAT fCharSpace,
-                                         int32_t nHorzScale,
-                                         FX_FLOAT fFontSize,
-                                         FX_FLOAT fWordTail,
-                                         int32_t nWordStyle) {
-  return (GetCharWidth(nFontIndex, Word, SubWord, nWordStyle) * fFontSize *
-              PVT_FONTSCALE +
-          fCharSpace) *
-             nHorzScale * PVT_PERCENT +
-         fWordTail;
-}
-FX_FLOAT CPDF_VariableText::GetWordWidth(const CPVT_WordInfo& WordInfo) {
-  return GetWordWidth(
-      GetWordFontIndex(WordInfo), WordInfo.Word, GetSubWord(),
-      GetCharSpace(WordInfo), GetHorzScale(WordInfo), GetWordFontSize(WordInfo),
-      WordInfo.fWordTail,
-      WordInfo.pWordProps ? WordInfo.pWordProps->nWordStyle : 0);
-}
-FX_FLOAT CPDF_VariableText::GetLineAscent(const CPVT_SectionInfo& SecInfo) {
-  return m_bRichText && SecInfo.pWordProps
-             ? GetFontAscent(SecInfo.pWordProps->nFontIndex,
-                             SecInfo.pWordProps->fFontSize)
-             : GetFontAscent(GetDefaultFontIndex(), GetFontSize());
-}
-FX_FLOAT CPDF_VariableText::GetLineDescent(const CPVT_SectionInfo& SecInfo) {
-  return m_bRichText && SecInfo.pWordProps
-             ? GetFontDescent(SecInfo.pWordProps->nFontIndex,
-                              SecInfo.pWordProps->fFontSize)
-             : GetFontDescent(GetDefaultFontIndex(), GetFontSize());
-}
-FX_FLOAT CPDF_VariableText::GetFontAscent(int32_t nFontIndex,
-                                          FX_FLOAT fFontSize) {
-  return (FX_FLOAT)GetTypeAscent(nFontIndex) * fFontSize * PVT_FONTSCALE;
-}
-FX_FLOAT CPDF_VariableText::GetFontDescent(int32_t nFontIndex,
-                                           FX_FLOAT fFontSize) {
-  return (FX_FLOAT)GetTypeDescent(nFontIndex) * fFontSize * PVT_FONTSCALE;
-}
-FX_FLOAT CPDF_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo,
-                                          FX_FLOAT fFontSize) {
-  return GetFontAscent(GetWordFontIndex(WordInfo), fFontSize);
-}
-FX_FLOAT CPDF_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo,
-                                           FX_FLOAT fFontSize) {
-  return GetFontDescent(GetWordFontIndex(WordInfo), fFontSize);
-}
-FX_FLOAT CPDF_VariableText::GetWordAscent(const CPVT_WordInfo& WordInfo,
-                                          FX_BOOL bFactFontSize) {
-  return GetFontAscent(GetWordFontIndex(WordInfo),
-                       GetWordFontSize(WordInfo, bFactFontSize));
-}
-FX_FLOAT CPDF_VariableText::GetWordDescent(const CPVT_WordInfo& WordInfo,
-                                           FX_BOOL bFactFontSize) {
-  return GetFontDescent(GetWordFontIndex(WordInfo),
-                        GetWordFontSize(WordInfo, bFactFontSize));
-}
-FX_FLOAT CPDF_VariableText::GetLineLeading(const CPVT_SectionInfo& SecInfo) {
-  return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->fLineLeading
-                                          : m_fLineLeading;
-}
-FX_FLOAT CPDF_VariableText::GetLineIndent(const CPVT_SectionInfo& SecInfo) {
-  return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->fLineIndent
-                                          : 0.0f;
-}
-int32_t CPDF_VariableText::GetAlignment(const CPVT_SectionInfo& SecInfo) {
-  return m_bRichText && SecInfo.pSecProps ? SecInfo.pSecProps->nAlignment
-                                          : m_nAlignment;
-}
-FX_FLOAT CPDF_VariableText::GetCharSpace(const CPVT_WordInfo& WordInfo) {
-  return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->fCharSpace
-                                            : m_fCharSpace;
-}
-int32_t CPDF_VariableText::GetHorzScale(const CPVT_WordInfo& WordInfo) {
-  return m_bRichText && WordInfo.pWordProps ? WordInfo.pWordProps->nHorzScale
-                                            : m_nHorzScale;
-}
-void CPDF_VariableText::ClearSectionRightWords(const CPVT_WordPlace& place) {
-  CPVT_WordPlace wordplace = AdjustLineHeader(place, TRUE);
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    for (int32_t w = pSection->m_WordArray.GetSize() - 1;
-         w > wordplace.nWordIndex; w--) {
-      delete pSection->m_WordArray.GetAt(w);
-      pSection->m_WordArray.RemoveAt(w);
-    }
-  }
-}
-CPVT_WordPlace CPDF_VariableText::AdjustLineHeader(const CPVT_WordPlace& place,
-                                                   FX_BOOL bPrevOrNext) const {
-  if (place.nWordIndex < 0 && place.nLineIndex > 0) {
-    return bPrevOrNext ? GetPrevWordPlace(place) : GetNextWordPlace(place);
-  }
-  return place;
-}
-FX_BOOL CPDF_VariableText::ClearEmptySection(const CPVT_WordPlace& place) {
-  if (place.nSecIndex == 0 && m_SectionArray.GetSize() == 1) {
-    return FALSE;
-  }
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    if (pSection->m_WordArray.GetSize() == 0) {
-      delete pSection;
-      m_SectionArray.RemoveAt(place.nSecIndex);
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-void CPDF_VariableText::ClearEmptySections(const CPVT_WordRange& PlaceRange) {
-  CPVT_WordPlace wordplace;
-  for (int32_t s = PlaceRange.EndPos.nSecIndex;
-       s > PlaceRange.BeginPos.nSecIndex; s--) {
-    wordplace.nSecIndex = s;
-    ClearEmptySection(wordplace);
-  }
-}
-void CPDF_VariableText::LinkLatterSection(const CPVT_WordPlace& place) {
-  CPVT_WordPlace oldplace = AdjustLineHeader(place, TRUE);
-  if (CSection* pNextSection = m_SectionArray.GetAt(place.nSecIndex + 1)) {
-    if (CSection* pSection = m_SectionArray.GetAt(oldplace.nSecIndex)) {
-      for (int32_t w = 0, sz = pNextSection->m_WordArray.GetSize(); w < sz;
-           w++) {
-        if (CPVT_WordInfo* pWord = pNextSection->m_WordArray.GetAt(w)) {
-          oldplace.nWordIndex++;
-          pSection->AddWord(oldplace, *pWord);
-        }
-      }
-    }
-    delete pNextSection;
-    m_SectionArray.RemoveAt(place.nSecIndex + 1);
-  }
-}
-void CPDF_VariableText::ClearWords(const CPVT_WordRange& PlaceRange) {
-  CPVT_WordRange NewRange;
-  NewRange.BeginPos = AdjustLineHeader(PlaceRange.BeginPos, TRUE);
-  NewRange.EndPos = AdjustLineHeader(PlaceRange.EndPos, TRUE);
-  for (int32_t s = NewRange.EndPos.nSecIndex; s >= NewRange.BeginPos.nSecIndex;
-       s--) {
-    if (CSection* pSection = m_SectionArray.GetAt(s)) {
-      pSection->ClearWords(NewRange);
-    }
-  }
-}
-CPVT_WordPlace CPDF_VariableText::ClearLeftWord(const CPVT_WordPlace& place) {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    CPVT_WordPlace leftplace = GetPrevWordPlace(place);
-    if (leftplace != place) {
-      if (leftplace.nSecIndex != place.nSecIndex) {
-        if (pSection->m_WordArray.GetSize() == 0) {
-          ClearEmptySection(place);
-        } else {
-          LinkLatterSection(leftplace);
-        }
-      } else {
-        pSection->ClearWord(place);
-      }
-    }
-    return leftplace;
-  }
-  return place;
-}
-CPVT_WordPlace CPDF_VariableText::ClearRightWord(const CPVT_WordPlace& place) {
-  if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) {
-    CPVT_WordPlace rightplace =
-        AdjustLineHeader(GetNextWordPlace(place), FALSE);
-    if (rightplace != place) {
-      if (rightplace.nSecIndex != place.nSecIndex) {
-        LinkLatterSection(place);
-      } else {
-        pSection->ClearWord(rightplace);
-      }
-    }
-  }
-  return place;
-}
-void CPDF_VariableText::RearrangeAll() {
-  Rearrange(CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
-}
-void CPDF_VariableText::RearrangePart(const CPVT_WordRange& PlaceRange) {
-  Rearrange(PlaceRange);
-}
-CPVT_FloatRect CPDF_VariableText::Rearrange(const CPVT_WordRange& PlaceRange) {
-  CPVT_FloatRect rcRet;
-  if (IsValid()) {
-    if (m_bAutoFontSize) {
-      SetFontSize(GetAutoFontSize());
-      rcRet = RearrangeSections(
-          CPVT_WordRange(GetBeginWordPlace(), GetEndWordPlace()));
-    } else {
-      rcRet = RearrangeSections(PlaceRange);
-    }
-  }
-  SetContentRect(rcRet);
-  return rcRet;
-}
-FX_FLOAT CPDF_VariableText::GetAutoFontSize() {
-  int32_t nTotal = sizeof(gFontSizeSteps) / sizeof(uint8_t);
-  if (IsMultiLine()) {
-    nTotal /= 4;
-  }
-  if (nTotal <= 0) {
-    return 0;
-  }
-  if (GetPlateWidth() <= 0) {
-    return 0;
-  }
-  int32_t nLeft = 0;
-  int32_t nRight = nTotal - 1;
-  int32_t nMid = nTotal / 2;
-  while (nLeft <= nRight) {
-    if (IsBigger(gFontSizeSteps[nMid])) {
-      nRight = nMid - 1;
-      nMid = (nLeft + nRight) / 2;
-      continue;
-    } else {
-      nLeft = nMid + 1;
-      nMid = (nLeft + nRight) / 2;
-      continue;
-    }
-  }
-  return (FX_FLOAT)gFontSizeSteps[nMid];
-}
-FX_BOOL CPDF_VariableText::IsBigger(FX_FLOAT fFontSize) {
-  FX_BOOL bBigger = FALSE;
-  CPVT_Size szTotal;
-  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
-    if (CSection* pSection = m_SectionArray.GetAt(s)) {
-      CPVT_Size size = pSection->GetSectionSize(fFontSize);
-      szTotal.x = std::max(size.x, szTotal.x);
-      szTotal.y += size.y;
-      if (IsFloatBigger(szTotal.x, GetPlateWidth()) ||
-          IsFloatBigger(szTotal.y, GetPlateHeight())) {
-        bBigger = TRUE;
-        break;
-      }
-    }
-  }
-  return bBigger;
-}
-CPVT_FloatRect CPDF_VariableText::RearrangeSections(
-    const CPVT_WordRange& PlaceRange) {
-  CPVT_WordPlace place;
-  FX_FLOAT fPosY = 0;
-  FX_FLOAT fOldHeight;
-  int32_t nSSecIndex = PlaceRange.BeginPos.nSecIndex;
-  int32_t nESecIndex = PlaceRange.EndPos.nSecIndex;
-  CPVT_FloatRect rcRet;
-  for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) {
-    place.nSecIndex = s;
-    if (CSection* pSection = m_SectionArray.GetAt(s)) {
-      pSection->SecPlace = place;
-      CPVT_FloatRect rcSec = pSection->m_SecInfo.rcSection;
-      if (s >= nSSecIndex) {
-        if (s <= nESecIndex) {
-          rcSec = pSection->Rearrange();
-          rcSec.top += fPosY;
-          rcSec.bottom += fPosY;
-        } else {
-          fOldHeight = pSection->m_SecInfo.rcSection.bottom -
-                       pSection->m_SecInfo.rcSection.top;
-          rcSec.top = fPosY;
-          rcSec.bottom = fPosY + fOldHeight;
-        }
-        pSection->m_SecInfo.rcSection = rcSec;
-        pSection->ResetLinePlace();
-      }
-      if (s == 0) {
-        rcRet = rcSec;
-      } else {
-        rcRet.left = std::min(rcSec.left, rcRet.left);
-        rcRet.top = std::min(rcSec.top, rcRet.top);
-        rcRet.right = std::max(rcSec.right, rcRet.right);
-        rcRet.bottom = std::max(rcSec.bottom, rcRet.bottom);
-      }
-      fPosY += rcSec.Height();
-    }
-  }
-  return rcRet;
-}
-int32_t CPDF_VariableText::GetCharWidth(int32_t nFontIndex,
-                                        uint16_t Word,
-                                        uint16_t SubWord,
-                                        int32_t nWordStyle) {
-  if (!m_pVTProvider) {
-    return 0;
-  }
-  if (SubWord > 0) {
-    return m_pVTProvider->GetCharWidth(nFontIndex, SubWord, nWordStyle);
-  }
-  return m_pVTProvider->GetCharWidth(nFontIndex, Word, nWordStyle);
-}
-int32_t CPDF_VariableText::GetTypeAscent(int32_t nFontIndex) {
-  return m_pVTProvider ? m_pVTProvider->GetTypeAscent(nFontIndex) : 0;
-}
-int32_t CPDF_VariableText::GetTypeDescent(int32_t nFontIndex) {
-  return m_pVTProvider ? m_pVTProvider->GetTypeDescent(nFontIndex) : 0;
-}
-int32_t CPDF_VariableText::GetWordFontIndex(uint16_t word,
-                                            int32_t charset,
-                                            int32_t nFontIndex) {
-  return m_pVTProvider
-             ? m_pVTProvider->GetWordFontIndex(word, charset, nFontIndex)
-             : -1;
-}
-int32_t CPDF_VariableText::GetDefaultFontIndex() {
-  return m_pVTProvider ? m_pVTProvider->GetDefaultFontIndex() : -1;
-}
-FX_BOOL CPDF_VariableText::IsLatinWord(uint16_t word) {
-  return m_pVTProvider ? m_pVTProvider->IsLatinWord(word) : FALSE;
-}
-IPDF_VariableText::Iterator* CPDF_VariableText::GetIterator() {
-  if (!m_pVTIterator) {
-    m_pVTIterator = new CPDF_VariableText_Iterator(this);
-  }
-  return m_pVTIterator;
-}
-IPDF_VariableText::Provider* CPDF_VariableText::SetProvider(
-    IPDF_VariableText::Provider* pProvider) {
-  IPDF_VariableText::Provider* pOld = m_pVTProvider;
-  m_pVTProvider = pProvider;
-  return pOld;
-}
-CPDF_VariableText_Iterator::CPDF_VariableText_Iterator(CPDF_VariableText* pVT)
-    : m_CurPos(-1, -1, -1), m_pVT(pVT) {}
-CPDF_VariableText_Iterator::~CPDF_VariableText_Iterator() {}
-void CPDF_VariableText_Iterator::SetAt(int32_t nWordIndex) {
-  m_CurPos = m_pVT->WordIndexToWordPlace(nWordIndex);
-}
-void CPDF_VariableText_Iterator::SetAt(const CPVT_WordPlace& place) {
-  ASSERT(m_pVT);
-  m_CurPos = place;
-}
-FX_BOOL CPDF_VariableText_Iterator::NextWord() {
-  if (m_CurPos == m_pVT->GetEndWordPlace()) {
-    return FALSE;
-  }
-  m_CurPos = m_pVT->GetNextWordPlace(m_CurPos);
-  return TRUE;
-}
-FX_BOOL CPDF_VariableText_Iterator::PrevWord() {
-  if (m_CurPos == m_pVT->GetBeginWordPlace()) {
-    return FALSE;
-  }
-  m_CurPos = m_pVT->GetPrevWordPlace(m_CurPos);
-  return TRUE;
-}
-FX_BOOL CPDF_VariableText_Iterator::NextLine() {
-  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
-    if (m_CurPos.nLineIndex < pSection->m_LineArray.GetSize() - 1) {
-      m_CurPos =
-          CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex + 1, -1);
-      return TRUE;
-    }
-    if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
-      m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText_Iterator::PrevLine() {
-  if (m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
-    if (m_CurPos.nLineIndex > 0) {
-      m_CurPos =
-          CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex - 1, -1);
-      return TRUE;
-    }
-    if (m_CurPos.nSecIndex > 0) {
-      if (CSection* pLastSection =
-              m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex - 1)) {
-        m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex - 1,
-                                  pLastSection->m_LineArray.GetSize() - 1, -1);
-        return TRUE;
-      }
-    }
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText_Iterator::NextSection() {
-  if (m_CurPos.nSecIndex < m_pVT->m_SectionArray.GetSize() - 1) {
-    m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex + 1, 0, -1);
-    return TRUE;
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText_Iterator::PrevSection() {
-  ASSERT(m_pVT);
-  if (m_CurPos.nSecIndex > 0) {
-    m_CurPos = CPVT_WordPlace(m_CurPos.nSecIndex - 1, 0, -1);
-    return TRUE;
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText_Iterator::GetWord(CPVT_Word& word) const {
-  word.WordPlace = m_CurPos;
-  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
-    if (pSection->m_LineArray.GetAt(m_CurPos.nLineIndex)) {
-      if (CPVT_WordInfo* pWord =
-              pSection->m_WordArray.GetAt(m_CurPos.nWordIndex)) {
-        word.Word = pWord->Word;
-        word.nCharset = pWord->nCharset;
-        word.fWidth = m_pVT->GetWordWidth(*pWord);
-        word.ptWord = m_pVT->InToOut(
-            CFX_FloatPoint(pWord->fWordX + pSection->m_SecInfo.rcSection.left,
-                           pWord->fWordY + pSection->m_SecInfo.rcSection.top));
-        word.fAscent = m_pVT->GetWordAscent(*pWord);
-        word.fDescent = m_pVT->GetWordDescent(*pWord);
-        if (pWord->pWordProps) {
-          word.WordProps = *pWord->pWordProps;
-        }
-        word.nFontIndex = m_pVT->GetWordFontIndex(*pWord);
-        word.fFontSize = m_pVT->GetWordFontSize(*pWord);
-        return TRUE;
-      }
-    }
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText_Iterator::SetWord(const CPVT_Word& word) {
-  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
-    if (CPVT_WordInfo* pWord =
-            pSection->m_WordArray.GetAt(m_CurPos.nWordIndex)) {
-      if (pWord->pWordProps) {
-        *pWord->pWordProps = word.WordProps;
-      }
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText_Iterator::GetLine(CPVT_Line& line) const {
-  ASSERT(m_pVT);
-  line.lineplace = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex, -1);
-  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
-    if (CLine* pLine = pSection->m_LineArray.GetAt(m_CurPos.nLineIndex)) {
-      line.ptLine = m_pVT->InToOut(CFX_FloatPoint(
-          pLine->m_LineInfo.fLineX + pSection->m_SecInfo.rcSection.left,
-          pLine->m_LineInfo.fLineY + pSection->m_SecInfo.rcSection.top));
-      line.fLineWidth = pLine->m_LineInfo.fLineWidth;
-      line.fLineAscent = pLine->m_LineInfo.fLineAscent;
-      line.fLineDescent = pLine->m_LineInfo.fLineDescent;
-      line.lineEnd = pLine->GetEndWordPlace();
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText_Iterator::GetSection(CPVT_Section& section) const {
-  section.secplace = CPVT_WordPlace(m_CurPos.nSecIndex, 0, -1);
-  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
-    section.rcSection = m_pVT->InToOut(pSection->m_SecInfo.rcSection);
-    if (pSection->m_SecInfo.pSecProps) {
-      section.SecProps = *pSection->m_SecInfo.pSecProps;
-    }
-    if (pSection->m_SecInfo.pWordProps) {
-      section.WordProps = *pSection->m_SecInfo.pWordProps;
-    }
-    return TRUE;
-  }
-  return FALSE;
-}
-FX_BOOL CPDF_VariableText_Iterator::SetSection(const CPVT_Section& section) {
-  if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) {
-    if (pSection->m_SecInfo.pSecProps) {
-      *pSection->m_SecInfo.pSecProps = section.SecProps;
-    }
-    if (pSection->m_SecInfo.pWordProps) {
-      *pSection->m_SecInfo.pWordProps = section.WordProps;
-    }
-    return TRUE;
-  }
-  return FALSE;
-}
diff --git a/core/fpdfdoc/doc_vtmodule.cpp b/core/fpdfdoc/doc_vtmodule.cpp
deleted file mode 100644
index 85e19ff..0000000
--- a/core/fpdfdoc/doc_vtmodule.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfdoc/pdf_vt.h"
-#include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fpdfdoc/fpdf_vt.h"
-
-IPDF_VariableText* IPDF_VariableText::NewVariableText() {
-  return new CPDF_VariableText();
-}
-void IPDF_VariableText::DelVariableText(IPDF_VariableText* pVT) {
-  delete (CPDF_VariableText*)pVT;
-}
diff --git a/core/fpdfdoc/include/cpdf_variabletext.h b/core/fpdfdoc/include/cpdf_variabletext.h
new file mode 100644
index 0000000..b73d3df
--- /dev/null
+++ b/core/fpdfdoc/include/cpdf_variabletext.h
@@ -0,0 +1,253 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_INCLUDE_CPDF_VARIABLETEXT_H_
+#define CORE_FPDFDOC_INCLUDE_CPDF_VARIABLETEXT_H_
+
+#include "core/fpdfdoc/cpvt_floatrect.h"
+#include "core/fpdfdoc/cpvt_lineinfo.h"
+#include "core/fpdfdoc/include/cpvt_line.h"
+#include "core/fpdfdoc/include/cpvt_wordplace.h"
+#include "core/fpdfdoc/include/cpvt_wordrange.h"
+#include "core/fpdfdoc/pdf_vt.h"
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_string.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CSection;
+class IPVT_FontMap;
+
+struct CPVT_SecProps;
+struct CPVT_Section;
+struct CPVT_SectionInfo;
+struct CPVT_Word;
+struct CPVT_WordProps;
+struct CPVT_WordInfo;
+
+#define VARIABLETEXT_HALF 0.5f
+
+class CPDF_VariableText : private CPDF_EditContainer {
+ public:
+  enum class ScriptType { Normal, Super, Sub };
+
+  class Iterator {
+   public:
+    explicit Iterator(CPDF_VariableText* pVT);
+    ~Iterator();
+
+    FX_BOOL NextWord();
+    FX_BOOL PrevWord();
+    FX_BOOL NextLine();
+    FX_BOOL PrevLine();
+    FX_BOOL NextSection();
+    FX_BOOL PrevSection();
+    FX_BOOL SetWord(const CPVT_Word& word);
+    FX_BOOL GetWord(CPVT_Word& word) const;
+    FX_BOOL GetLine(CPVT_Line& line) const;
+    FX_BOOL GetSection(CPVT_Section& section) const;
+    FX_BOOL SetSection(const CPVT_Section& section);
+    void SetAt(int32_t nWordIndex);
+    void SetAt(const CPVT_WordPlace& place);
+    const CPVT_WordPlace& GetAt() const { return m_CurPos; }
+
+   private:
+    CPVT_WordPlace m_CurPos;
+    CPDF_VariableText* const m_pVT;
+  };
+
+  class Provider {
+   public:
+    Provider(IPVT_FontMap* pFontMap);
+    virtual ~Provider();
+
+    virtual int32_t GetCharWidth(int32_t nFontIndex,
+                                 uint16_t word,
+                                 int32_t nWordStyle);
+    virtual int32_t GetTypeAscent(int32_t nFontIndex);
+    virtual int32_t GetTypeDescent(int32_t nFontIndex);
+    virtual int32_t GetWordFontIndex(uint16_t word,
+                                     int32_t charset,
+                                     int32_t nFontIndex);
+    virtual FX_BOOL IsLatinWord(uint16_t word);
+    virtual int32_t GetDefaultFontIndex();
+
+   private:
+    IPVT_FontMap* m_pFontMap;
+  };
+
+  CPDF_VariableText();
+  virtual ~CPDF_VariableText();
+
+  CPDF_VariableText::Provider* SetProvider(
+      CPDF_VariableText::Provider* pProvider);
+  CPDF_VariableText::Iterator* GetIterator();
+
+  // CPDF_EditContainer.
+  void SetPlateRect(const CFX_FloatRect& rect) override {
+    CPDF_EditContainer::SetPlateRect(rect);
+  }
+  CFX_FloatRect GetContentRect() const override;
+  const CFX_FloatRect& GetPlateRect() const override {
+    return CPDF_EditContainer::GetPlateRect();
+  }
+
+  void SetAlignment(int32_t nFormat = 0) { m_nAlignment = nFormat; }
+  void SetPasswordChar(uint16_t wSubWord = '*') { m_wSubWord = wSubWord; }
+  void SetLimitChar(int32_t nLimitChar = 0) { m_nLimitChar = nLimitChar; }
+  void SetCharSpace(FX_FLOAT fCharSpace = 0.0f) { m_fCharSpace = fCharSpace; }
+  void SetHorzScale(int32_t nHorzScale = 100) { m_nHorzScale = nHorzScale; }
+  void SetMultiLine(FX_BOOL bMultiLine = TRUE) { m_bMultiLine = bMultiLine; }
+  void SetAutoReturn(FX_BOOL bAuto = TRUE) { m_bLimitWidth = bAuto; }
+  void SetFontSize(FX_FLOAT fFontSize) { m_fFontSize = fFontSize; }
+  void SetCharArray(int32_t nCharArray = 0) { m_nCharArray = nCharArray; }
+  void SetAutoFontSize(FX_BOOL bAuto = TRUE) { m_bAutoFontSize = bAuto; }
+  void SetRichText(FX_BOOL bRichText) { m_bRichText = bRichText; }
+  void SetLineLeading(FX_FLOAT fLineLeading) { m_fLineLeading = fLineLeading; }
+  void Initialize();
+  FX_BOOL IsValid() const { return m_bInitial; }
+  FX_BOOL IsRichText() const { return m_bRichText; }
+  void RearrangeAll();
+  void RearrangePart(const CPVT_WordRange& PlaceRange);
+  void ResetAll();
+  void SetText(const FX_WCHAR* text,
+               int32_t charset = 1,
+               const CPVT_SecProps* pSecProps = NULL,
+               const CPVT_WordProps* pWordProps = NULL);
+  CPVT_WordPlace InsertWord(const CPVT_WordPlace& place,
+                            uint16_t word,
+                            int32_t charset = 1,
+                            const CPVT_WordProps* pWordProps = NULL);
+  CPVT_WordPlace InsertSection(const CPVT_WordPlace& place,
+                               const CPVT_SecProps* pSecProps = NULL,
+                               const CPVT_WordProps* pWordProps = NULL);
+  CPVT_WordPlace InsertText(const CPVT_WordPlace& place,
+                            const FX_WCHAR* text,
+                            int32_t charset = 1,
+                            const CPVT_SecProps* pSecProps = NULL,
+                            const CPVT_WordProps* pWordProps = NULL);
+  CPVT_WordPlace DeleteWords(const CPVT_WordRange& PlaceRange);
+  CPVT_WordPlace DeleteWord(const CPVT_WordPlace& place);
+  CPVT_WordPlace BackSpaceWord(const CPVT_WordPlace& place);
+
+  int32_t GetTotalWords() const;
+  FX_FLOAT GetFontSize() const { return m_fFontSize; }
+  int32_t GetAlignment() const { return m_nAlignment; }
+  uint16_t GetPasswordChar() const { return GetSubWord(); }
+  int32_t GetCharArray() const { return m_nCharArray; }
+  int32_t GetLimitChar() const { return m_nLimitChar; }
+  FX_BOOL IsMultiLine() const { return m_bMultiLine; }
+  int32_t GetHorzScale() const { return m_nHorzScale; }
+  FX_FLOAT GetCharSpace() const { return m_fCharSpace; }
+  CPVT_WordPlace GetBeginWordPlace() const;
+  CPVT_WordPlace GetEndWordPlace() const;
+  CPVT_WordPlace GetPrevWordPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace GetNextWordPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const;
+  CPVT_WordPlace GetUpWordPlace(const CPVT_WordPlace& place,
+                                const CFX_FloatPoint& point) const;
+  CPVT_WordPlace GetDownWordPlace(const CPVT_WordPlace& place,
+                                  const CFX_FloatPoint& point) const;
+  CPVT_WordPlace GetLineBeginPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace GetSectionBeginPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace GetSectionEndPlace(const CPVT_WordPlace& place) const;
+  void UpdateWordPlace(CPVT_WordPlace& place) const;
+  CPVT_WordPlace AdjustLineHeader(const CPVT_WordPlace& place,
+                                  FX_BOOL bPrevOrNext) const;
+  int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace WordIndexToWordPlace(int32_t index) const;
+
+  uint16_t GetSubWord() const { return m_wSubWord; }
+
+ private:
+  friend class CTypeset;
+  friend class CSection;
+
+  int32_t GetCharWidth(int32_t nFontIndex,
+                       uint16_t Word,
+                       uint16_t SubWord,
+                       int32_t nWordStyle);
+  int32_t GetTypeAscent(int32_t nFontIndex);
+  int32_t GetTypeDescent(int32_t nFontIndex);
+  int32_t GetWordFontIndex(uint16_t word, int32_t charset, int32_t nFontIndex);
+  int32_t GetDefaultFontIndex();
+  FX_BOOL IsLatinWord(uint16_t word);
+
+  CPVT_WordPlace AddSection(const CPVT_WordPlace& place,
+                            const CPVT_SectionInfo& secinfo);
+  CPVT_WordPlace AddLine(const CPVT_WordPlace& place,
+                         const CPVT_LineInfo& lineinfo);
+  CPVT_WordPlace AddWord(const CPVT_WordPlace& place,
+                         const CPVT_WordInfo& wordinfo);
+  FX_BOOL GetWordInfo(const CPVT_WordPlace& place, CPVT_WordInfo& wordinfo);
+  FX_BOOL SetWordInfo(const CPVT_WordPlace& place,
+                      const CPVT_WordInfo& wordinfo);
+  FX_BOOL GetLineInfo(const CPVT_WordPlace& place, CPVT_LineInfo& lineinfo);
+  FX_BOOL GetSectionInfo(const CPVT_WordPlace& place,
+                         CPVT_SectionInfo& secinfo);
+  FX_FLOAT GetWordFontSize(const CPVT_WordInfo& WordInfo,
+                           FX_BOOL bFactFontSize = FALSE);
+  FX_FLOAT GetWordWidth(int32_t nFontIndex,
+                        uint16_t Word,
+                        uint16_t SubWord,
+                        FX_FLOAT fCharSpace,
+                        int32_t nHorzScale,
+                        FX_FLOAT fFontSize,
+                        FX_FLOAT fWordTail,
+                        int32_t nWordStyle);
+  FX_FLOAT GetWordWidth(const CPVT_WordInfo& WordInfo);
+  FX_FLOAT GetWordAscent(const CPVT_WordInfo& WordInfo, FX_FLOAT fFontSize);
+  FX_FLOAT GetWordDescent(const CPVT_WordInfo& WordInfo, FX_FLOAT fFontSize);
+  FX_FLOAT GetWordAscent(const CPVT_WordInfo& WordInfo,
+                         FX_BOOL bFactFontSize = FALSE);
+  FX_FLOAT GetWordDescent(const CPVT_WordInfo& WordInfo,
+                          FX_BOOL bFactFontSize = FALSE);
+  FX_FLOAT GetLineAscent(const CPVT_SectionInfo& SecInfo);
+  FX_FLOAT GetLineDescent(const CPVT_SectionInfo& SecInfo);
+  FX_FLOAT GetFontAscent(int32_t nFontIndex, FX_FLOAT fFontSize);
+  FX_FLOAT GetFontDescent(int32_t nFontIndex, FX_FLOAT fFontSize);
+  int32_t GetWordFontIndex(const CPVT_WordInfo& WordInfo);
+  FX_FLOAT GetCharSpace(const CPVT_WordInfo& WordInfo);
+  int32_t GetHorzScale(const CPVT_WordInfo& WordInfo);
+  FX_FLOAT GetLineLeading(const CPVT_SectionInfo& SecInfo);
+  FX_FLOAT GetLineIndent(const CPVT_SectionInfo& SecInfo);
+  int32_t GetAlignment(const CPVT_SectionInfo& SecInfo);
+
+  void ClearSectionRightWords(const CPVT_WordPlace& place);
+
+  FX_BOOL ClearEmptySection(const CPVT_WordPlace& place);
+  void ClearEmptySections(const CPVT_WordRange& PlaceRange);
+  void LinkLatterSection(const CPVT_WordPlace& place);
+  void ClearWords(const CPVT_WordRange& PlaceRange);
+  CPVT_WordPlace ClearLeftWord(const CPVT_WordPlace& place);
+  CPVT_WordPlace ClearRightWord(const CPVT_WordPlace& place);
+
+  CPVT_FloatRect Rearrange(const CPVT_WordRange& PlaceRange);
+  FX_FLOAT GetAutoFontSize();
+  FX_BOOL IsBigger(FX_FLOAT fFontSize);
+  CPVT_FloatRect RearrangeSections(const CPVT_WordRange& PlaceRange);
+
+  void ResetSectionArray();
+
+  CPVT_ArrayTemplate<CSection*> m_SectionArray;
+  int32_t m_nLimitChar;
+  int32_t m_nCharArray;
+  FX_BOOL m_bMultiLine;
+  FX_BOOL m_bLimitWidth;
+  FX_BOOL m_bAutoFontSize;
+  int32_t m_nAlignment;
+  FX_FLOAT m_fLineLeading;
+  FX_FLOAT m_fCharSpace;
+  int32_t m_nHorzScale;
+  uint16_t m_wSubWord;
+  FX_FLOAT m_fFontSize;
+  FX_BOOL m_bInitial;
+  FX_BOOL m_bRichText;
+  CPDF_VariableText::Provider* m_pVTProvider;
+  CPDF_VariableText::Iterator* m_pVTIterator;
+};
+
+#endif  // CORE_FPDFDOC_INCLUDE_CPDF_VARIABLETEXT_H_
diff --git a/core/fpdfdoc/include/cpvt_line.h b/core/fpdfdoc/include/cpvt_line.h
new file mode 100644
index 0000000..ea0f899
--- /dev/null
+++ b/core/fpdfdoc/include/cpvt_line.h
@@ -0,0 +1,26 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_INCLUDE_CPVT_LINE_H_
+#define CORE_FPDFDOC_INCLUDE_CPVT_LINE_H_
+
+#include "core/fpdfdoc/include/cpvt_wordplace.h"
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_system.h"
+
+struct CPVT_Line {
+  CPVT_Line()
+      : ptLine(0, 0), fLineWidth(0.0f), fLineAscent(0.0f), fLineDescent(0.0f) {}
+
+  CPVT_WordPlace lineplace;
+  CPVT_WordPlace lineEnd;
+  CFX_FloatPoint ptLine;
+  FX_FLOAT fLineWidth;
+  FX_FLOAT fLineAscent;
+  FX_FLOAT fLineDescent;
+};
+
+#endif  // CORE_FPDFDOC_INCLUDE_CPVT_LINE_H_
diff --git a/core/fpdfdoc/include/cpvt_secprops.h b/core/fpdfdoc/include/cpvt_secprops.h
new file mode 100644
index 0000000..67878f8
--- /dev/null
+++ b/core/fpdfdoc/include/cpvt_secprops.h
@@ -0,0 +1,30 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_INCLUDE_CPVT_SECPROPS_H_
+#define CORE_FPDFDOC_INCLUDE_CPVT_SECPROPS_H_
+
+#include "core/fxcrt/include/fx_system.h"
+
+struct CPVT_SecProps {
+  CPVT_SecProps() : fLineLeading(0.0f), fLineIndent(0.0f), nAlignment(0) {}
+
+  CPVT_SecProps(FX_FLOAT lineLeading, FX_FLOAT lineIndent, int32_t alignment)
+      : fLineLeading(lineLeading),
+        fLineIndent(lineIndent),
+        nAlignment(alignment) {}
+
+  CPVT_SecProps(const CPVT_SecProps& other)
+      : fLineLeading(other.fLineLeading),
+        fLineIndent(other.fLineIndent),
+        nAlignment(other.nAlignment) {}
+
+  FX_FLOAT fLineLeading;
+  FX_FLOAT fLineIndent;
+  int32_t nAlignment;
+};
+
+#endif  // CORE_FPDFDOC_INCLUDE_CPVT_SECPROPS_H_
diff --git a/core/fpdfdoc/include/cpvt_section.h b/core/fpdfdoc/include/cpvt_section.h
new file mode 100644
index 0000000..a9820bd
--- /dev/null
+++ b/core/fpdfdoc/include/cpvt_section.h
@@ -0,0 +1,22 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_INCLUDE_CPVT_SECTION_H_
+#define CORE_FPDFDOC_INCLUDE_CPVT_SECTION_H_
+
+#include "core/fpdfdoc/include/cpvt_secprops.h"
+#include "core/fpdfdoc/include/cpvt_wordplace.h"
+#include "core/fpdfdoc/include/cpvt_wordprops.h"
+#include "core/fxcrt/include/fx_coordinates.h"
+
+struct CPVT_Section {
+  CPVT_WordPlace secplace;
+  CFX_FloatRect rcSection;
+  CPVT_SecProps SecProps;
+  CPVT_WordProps WordProps;
+};
+
+#endif  // CORE_FPDFDOC_INCLUDE_CPVT_SECTION_H_
diff --git a/core/fpdfdoc/include/cpvt_word.h b/core/fpdfdoc/include/cpvt_word.h
new file mode 100644
index 0000000..7d022dd
--- /dev/null
+++ b/core/fpdfdoc/include/cpvt_word.h
@@ -0,0 +1,37 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_INCLUDE_CPVT_WORD_H_
+#define CORE_FPDFDOC_INCLUDE_CPVT_WORD_H_
+
+#include "core/fpdfdoc/include/cpvt_wordplace.h"
+#include "core/fpdfdoc/include/cpvt_wordprops.h"
+#include "core/fxcrt/include/fx_system.h"
+
+struct CPVT_Word {
+  CPVT_Word()
+      : Word(0),
+        nCharset(0),
+        ptWord(0, 0),
+        fAscent(0.0f),
+        fDescent(0.0f),
+        fWidth(0.0f),
+        fFontSize(0),
+        WordProps() {}
+
+  uint16_t Word;
+  int32_t nCharset;
+  CPVT_WordPlace WordPlace;
+  CFX_FloatPoint ptWord;
+  FX_FLOAT fAscent;
+  FX_FLOAT fDescent;
+  FX_FLOAT fWidth;
+  int32_t nFontIndex;
+  FX_FLOAT fFontSize;
+  CPVT_WordProps WordProps;
+};
+
+#endif  // CORE_FPDFDOC_INCLUDE_CPVT_WORD_H_
diff --git a/core/fpdfdoc/include/cpvt_wordplace.h b/core/fpdfdoc/include/cpvt_wordplace.h
new file mode 100644
index 0000000..ef79077
--- /dev/null
+++ b/core/fpdfdoc/include/cpvt_wordplace.h
@@ -0,0 +1,73 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_INCLUDE_CPVT_WORDPLACE_H_
+#define CORE_FPDFDOC_INCLUDE_CPVT_WORDPLACE_H_
+
+#include "core/fxcrt/include/fx_system.h"
+
+struct CPVT_WordPlace {
+  CPVT_WordPlace() : nSecIndex(-1), nLineIndex(-1), nWordIndex(-1) {}
+
+  CPVT_WordPlace(int32_t other_nSecIndex,
+                 int32_t other_nLineIndex,
+                 int32_t other_nWordIndex) {
+    nSecIndex = other_nSecIndex;
+    nLineIndex = other_nLineIndex;
+    nWordIndex = other_nWordIndex;
+  }
+
+  void Default() { nSecIndex = nLineIndex = nWordIndex = -1; }
+
+  bool operator==(const CPVT_WordPlace& wp) const {
+    return wp.nSecIndex == nSecIndex && wp.nLineIndex == nLineIndex &&
+           wp.nWordIndex == nWordIndex;
+  }
+
+  FX_BOOL operator!=(const CPVT_WordPlace& wp) const { return !(*this == wp); }
+
+  inline int32_t WordCmp(const CPVT_WordPlace& wp) const {
+    if (nSecIndex > wp.nSecIndex)
+      return 1;
+    if (nSecIndex < wp.nSecIndex)
+      return -1;
+    if (nLineIndex > wp.nLineIndex)
+      return 1;
+    if (nLineIndex < wp.nLineIndex)
+      return -1;
+    if (nWordIndex > wp.nWordIndex)
+      return 1;
+    if (nWordIndex < wp.nWordIndex)
+      return -1;
+    return 0;
+  }
+
+  inline int32_t LineCmp(const CPVT_WordPlace& wp) const {
+    if (nSecIndex > wp.nSecIndex)
+      return 1;
+    if (nSecIndex < wp.nSecIndex)
+      return -1;
+    if (nLineIndex > wp.nLineIndex)
+      return 1;
+    if (nLineIndex < wp.nLineIndex)
+      return -1;
+    return 0;
+  }
+
+  inline int32_t SecCmp(const CPVT_WordPlace& wp) const {
+    if (nSecIndex > wp.nSecIndex)
+      return 1;
+    if (nSecIndex < wp.nSecIndex)
+      return -1;
+    return 0;
+  }
+
+  int32_t nSecIndex;
+  int32_t nLineIndex;
+  int32_t nWordIndex;
+};
+
+#endif  // CORE_FPDFDOC_INCLUDE_CPVT_WORDPLACE_H_
diff --git a/core/fpdfdoc/include/cpvt_wordprops.h b/core/fpdfdoc/include/cpvt_wordprops.h
new file mode 100644
index 0000000..e091579
--- /dev/null
+++ b/core/fpdfdoc/include/cpvt_wordprops.h
@@ -0,0 +1,58 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_INCLUDE_CPVT_WORDPROPS_H_
+#define CORE_FPDFDOC_INCLUDE_CPVT_WORDPROPS_H_
+
+#include "core/fpdfdoc/include/cpdf_variabletext.h"
+#include "core/fxcrt/include/fx_system.h"
+#include "core/include/fxge/fx_dib.h"
+
+struct CPVT_WordProps {
+  CPVT_WordProps()
+      : nFontIndex(-1),
+        fFontSize(0.0f),
+        dwWordColor(0),
+        nScriptType(CPDF_VariableText::ScriptType::Normal),
+        nWordStyle(0),
+        fCharSpace(0.0f),
+        nHorzScale(0) {}
+
+  CPVT_WordProps(int32_t fontIndex,
+                 FX_FLOAT fontSize,
+                 FX_COLORREF wordColor = 0,
+                 CPDF_VariableText::ScriptType scriptType =
+                     CPDF_VariableText::ScriptType::Normal,
+                 int32_t wordStyle = 0,
+                 FX_FLOAT charSpace = 0,
+                 int32_t horzScale = 100)
+      : nFontIndex(fontIndex),
+        fFontSize(fontSize),
+        dwWordColor(wordColor),
+        nScriptType(scriptType),
+        nWordStyle(wordStyle),
+        fCharSpace(charSpace),
+        nHorzScale(horzScale) {}
+
+  CPVT_WordProps(const CPVT_WordProps& other)
+      : nFontIndex(other.nFontIndex),
+        fFontSize(other.fFontSize),
+        dwWordColor(other.dwWordColor),
+        nScriptType(other.nScriptType),
+        nWordStyle(other.nWordStyle),
+        fCharSpace(other.fCharSpace),
+        nHorzScale(other.nHorzScale) {}
+
+  int32_t nFontIndex;
+  FX_FLOAT fFontSize;
+  FX_COLORREF dwWordColor;
+  CPDF_VariableText::ScriptType nScriptType;
+  int32_t nWordStyle;
+  FX_FLOAT fCharSpace;
+  int32_t nHorzScale;
+};
+
+#endif  // CORE_FPDFDOC_INCLUDE_CPVT_WORDPROPS_H_
diff --git a/core/fpdfdoc/include/cpvt_wordrange.h b/core/fpdfdoc/include/cpvt_wordrange.h
new file mode 100644
index 0000000..3c6f05b
--- /dev/null
+++ b/core/fpdfdoc/include/cpvt_wordrange.h
@@ -0,0 +1,59 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_INCLUDE_CPVT_WORDRANGE_H_
+#define CORE_FPDFDOC_INCLUDE_CPVT_WORDRANGE_H_
+
+#include "core/fpdfdoc/include/cpvt_wordplace.h"
+#include "core/fxcrt/include/fx_system.h"
+
+struct CPVT_WordRange {
+  CPVT_WordRange() {}
+
+  CPVT_WordRange(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
+    Set(begin, end);
+  }
+
+  void Default() {
+    BeginPos.Default();
+    EndPos.Default();
+  }
+
+  void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
+    BeginPos = begin;
+    EndPos = end;
+    SwapWordPlace();
+  }
+
+  void SetBeginPos(const CPVT_WordPlace& begin) {
+    BeginPos = begin;
+    SwapWordPlace();
+  }
+
+  void SetEndPos(const CPVT_WordPlace& end) {
+    EndPos = end;
+    SwapWordPlace();
+  }
+
+  FX_BOOL IsExist() const { return BeginPos != EndPos; }
+
+  FX_BOOL operator!=(const CPVT_WordRange& wr) const {
+    return wr.BeginPos != BeginPos || wr.EndPos != EndPos;
+  }
+
+  void SwapWordPlace() {
+    if (BeginPos.WordCmp(EndPos) > 0) {
+      CPVT_WordPlace place = EndPos;
+      EndPos = BeginPos;
+      BeginPos = place;
+    }
+  }
+
+  CPVT_WordPlace BeginPos;
+  CPVT_WordPlace EndPos;
+};
+
+#endif  // CORE_FPDFDOC_INCLUDE_CPVT_WORDRANGE_H_
diff --git a/core/fpdfdoc/include/ipvt_fontmap.h b/core/fpdfdoc/include/ipvt_fontmap.h
new file mode 100644
index 0000000..9835d5e
--- /dev/null
+++ b/core/fpdfdoc/include/ipvt_fontmap.h
@@ -0,0 +1,29 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFDOC_INCLUDE_IPVT_FONTMAP_H_
+#define CORE_FPDFDOC_INCLUDE_IPVT_FONTMAP_H_
+
+#include <stdint.h>
+
+#include "core/fxcrt/include/fx_string.h"
+
+class CPDF_Font;
+
+class IPVT_FontMap {
+ public:
+  virtual ~IPVT_FontMap() {}
+
+  virtual CPDF_Font* GetPDFFont(int32_t nFontIndex) = 0;
+  virtual CFX_ByteString GetPDFFontAlias(int32_t nFontIndex) = 0;
+  virtual int32_t GetWordFontIndex(uint16_t word,
+                                   int32_t charset,
+                                   int32_t nFontIndex) = 0;
+  virtual int32_t CharCodeFromUnicode(int32_t nFontIndex, uint16_t word) = 0;
+  virtual int32_t CharSetFromUnicode(uint16_t word, int32_t nOldCharset) = 0;
+};
+
+#endif  // CORE_FPDFDOC_INCLUDE_IPVT_FONTMAP_H_
diff --git a/core/fpdfdoc/ipvt_fontmap.h b/core/fpdfdoc/ipvt_fontmap.h
deleted file mode 100644
index eec414d..0000000
--- a/core/fpdfdoc/ipvt_fontmap.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_FPDFDOC_IPVT_FONTMAP_H_
-#define CORE_FPDFDOC_IPVT_FONTMAP_H_
-
-#include <stdint.h>
-
-#include "core/fxcrt/include/fx_string.h"
-
-class CPDF_Font;
-
-class IPVT_FontMap {
- public:
-  virtual ~IPVT_FontMap() {}
-
-  virtual CPDF_Font* GetPDFFont(int32_t nFontIndex) = 0;
-  virtual CFX_ByteString GetPDFFontAlias(int32_t nFontIndex) = 0;
-};
-
-#endif  // CORE_FPDFDOC_IPVT_FONTMAP_H_
diff --git a/core/fpdfdoc/pdf_vt.h b/core/fpdfdoc/pdf_vt.h
index 73913f7..a3b7883 100644
--- a/core/fpdfdoc/pdf_vt.h
+++ b/core/fpdfdoc/pdf_vt.h
@@ -7,14 +7,18 @@
 #ifndef CORE_FPDFDOC_PDF_VT_H_
 #define CORE_FPDFDOC_PDF_VT_H_
 
-#include "core/include/fpdfdoc/fpdf_vt.h"
+#include "core/fpdfdoc/cpvt_floatrect.h"
+#include "core/fpdfdoc/cpvt_lineinfo.h"
+#include "core/fpdfdoc/include/cpvt_wordrange.h"
 
 class CPDF_VariableText;
-class CPDF_VariableText_Iterator;
+
+struct CPVT_WordInfo;
 
 #define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
+#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
 
 class CPVT_Size {
  public:
@@ -25,141 +29,7 @@
   }
   FX_FLOAT x, y;
 };
-class CPVT_FloatRect : public CFX_FloatRect {
- public:
-  CPVT_FloatRect() { left = top = right = bottom = 0.0f; }
-  CPVT_FloatRect(FX_FLOAT other_left,
-                 FX_FLOAT other_top,
-                 FX_FLOAT other_right,
-                 FX_FLOAT other_bottom) {
-    left = other_left;
-    top = other_top;
-    right = other_right;
-    bottom = other_bottom;
-  }
-  explicit CPVT_FloatRect(const CFX_FloatRect& rect) {
-    left = rect.left;
-    top = rect.top;
-    right = rect.right;
-    bottom = rect.bottom;
-  }
-  void Default() { left = top = right = bottom = 0.0f; }
-  FX_FLOAT Height() const {
-    if (top > bottom)
-      return top - bottom;
-    return bottom - top;
-  }
-};
-struct CPVT_SectionInfo {
-  CPVT_SectionInfo()
-      : rcSection(), nTotalLine(0), pSecProps(NULL), pWordProps(NULL) {}
-  virtual ~CPVT_SectionInfo() {
-    delete pSecProps;
-    delete pWordProps;
-  }
-  CPVT_SectionInfo(const CPVT_SectionInfo& other)
-      : rcSection(), nTotalLine(0), pSecProps(NULL), pWordProps(NULL) {
-    operator=(other);
-  }
-  void operator=(const CPVT_SectionInfo& other) {
-    if (this == &other) {
-      return;
-    }
-    rcSection = other.rcSection;
-    nTotalLine = other.nTotalLine;
-    if (other.pSecProps) {
-      if (pSecProps) {
-        *pSecProps = *other.pSecProps;
-      } else {
-        pSecProps = new CPVT_SecProps(*other.pSecProps);
-      }
-    }
-    if (other.pWordProps) {
-      if (pWordProps) {
-        *pWordProps = *other.pWordProps;
-      } else {
-        pWordProps = new CPVT_WordProps(*other.pWordProps);
-      }
-    }
-  }
-  CPVT_FloatRect rcSection;
-  int32_t nTotalLine;
-  CPVT_SecProps* pSecProps;
-  CPVT_WordProps* pWordProps;
-};
-struct CPVT_LineInfo {
-  CPVT_LineInfo()
-      : nTotalWord(0),
-        nBeginWordIndex(-1),
-        nEndWordIndex(-1),
-        fLineX(0.0f),
-        fLineY(0.0f),
-        fLineWidth(0.0f),
-        fLineAscent(0.0f),
-        fLineDescent(0.0f) {}
-  int32_t nTotalWord;
-  int32_t nBeginWordIndex;
-  int32_t nEndWordIndex;
-  FX_FLOAT fLineX;
-  FX_FLOAT fLineY;
-  FX_FLOAT fLineWidth;
-  FX_FLOAT fLineAscent;
-  FX_FLOAT fLineDescent;
-};
-struct CPVT_WordInfo {
-  CPVT_WordInfo()
-      : Word(0),
-        nCharset(0),
-        fWordX(0.0f),
-        fWordY(0.0f),
-        fWordTail(0.0f),
-        nFontIndex(-1),
-        pWordProps(NULL) {}
-  CPVT_WordInfo(uint16_t word,
-                int32_t charset,
-                int32_t fontIndex,
-                CPVT_WordProps* pProps)
-      : Word(word),
-        nCharset(charset),
-        fWordX(0.0f),
-        fWordY(0.0f),
-        fWordTail(0.0f),
-        nFontIndex(fontIndex),
-        pWordProps(pProps) {}
-  virtual ~CPVT_WordInfo() { delete pWordProps; }
-  CPVT_WordInfo(const CPVT_WordInfo& word)
-      : Word(0),
-        nCharset(0),
-        fWordX(0.0f),
-        fWordY(0.0f),
-        fWordTail(0.0f),
-        nFontIndex(-1),
-        pWordProps(NULL) {
-    operator=(word);
-  }
-  void operator=(const CPVT_WordInfo& word) {
-    if (this == &word) {
-      return;
-    }
-    Word = word.Word;
-    nCharset = word.nCharset;
-    nFontIndex = word.nFontIndex;
-    if (word.pWordProps) {
-      if (pWordProps) {
-        *pWordProps = *word.pWordProps;
-      } else {
-        pWordProps = new CPVT_WordProps(*word.pWordProps);
-      }
-    }
-  }
-  uint16_t Word;
-  int32_t nCharset;
-  FX_FLOAT fWordX;
-  FX_FLOAT fWordY;
-  FX_FLOAT fWordTail;
-  int32_t nFontIndex;
-  CPVT_WordProps* pWordProps;
-};
+
 struct CPVT_FloatRange {
   CPVT_FloatRange() : fMin(0.0f), fMax(0.0f) {}
   CPVT_FloatRange(FX_FLOAT min, FX_FLOAT max) : fMin(min), fMax(max) {}
@@ -228,63 +98,7 @@
   CPVT_ArrayTemplate<CLine*> m_Lines;
   int32_t m_nTotal;
 };
-class CSection {
-  friend class CTypeset;
 
- public:
-  explicit CSection(CPDF_VariableText* pVT);
-  virtual ~CSection();
-  void ResetAll();
-  void ResetLineArray();
-  void ResetWordArray();
-  void ResetLinePlace();
-  CPVT_WordPlace AddWord(const CPVT_WordPlace& place,
-                         const CPVT_WordInfo& wordinfo);
-  CPVT_WordPlace AddLine(const CPVT_LineInfo& lineinfo);
-  void ClearWords(const CPVT_WordRange& PlaceRange);
-  void ClearWord(const CPVT_WordPlace& place);
-  CPVT_FloatRect Rearrange();
-  CPVT_Size GetSectionSize(FX_FLOAT fFontSize);
-  CPVT_WordPlace GetBeginWordPlace() const;
-  CPVT_WordPlace GetEndWordPlace() const;
-  CPVT_WordPlace GetPrevWordPlace(const CPVT_WordPlace& place) const;
-  CPVT_WordPlace GetNextWordPlace(const CPVT_WordPlace& place) const;
-  void UpdateWordPlace(CPVT_WordPlace& place) const;
-  CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const;
-  CPVT_WordPlace SearchWordPlace(FX_FLOAT fx,
-                                 const CPVT_WordPlace& lineplace) const;
-  CPVT_WordPlace SearchWordPlace(FX_FLOAT fx,
-                                 const CPVT_WordRange& range) const;
-
- public:
-  CPVT_WordPlace SecPlace;
-  CPVT_SectionInfo m_SecInfo;
-  CLines m_LineArray;
-  CPVT_ArrayTemplate<CPVT_WordInfo*> m_WordArray;
-
- private:
-  void ClearLeftWords(int32_t nWordIndex);
-  void ClearRightWords(int32_t nWordIndex);
-  void ClearMidWords(int32_t nBeginIndex, int32_t nEndIndex);
-
-  CPDF_VariableText* m_pVT;
-};
-class CTypeset {
- public:
-  explicit CTypeset(CSection* pSection);
-  virtual ~CTypeset();
-  CPVT_Size GetEditSize(FX_FLOAT fFontSize);
-  CPVT_FloatRect Typeset();
-  CPVT_FloatRect CharArray();
-
- private:
-  void SplitLines(FX_BOOL bTypeset, FX_FLOAT fFontSize);
-  void OutputLines();
-
-  CPVT_FloatRect m_rcRet;
-  CPDF_VariableText* m_pVT;
-  CSection* m_pSection;
-};
 class CPDF_EditContainer {
  public:
   CPDF_EditContainer() : m_rcPlate(0, 0, 0, 0), m_rcContent(0, 0, 0, 0) {}
@@ -332,223 +146,4 @@
   CPVT_FloatRect m_rcContent;
 };
 
-class CPDF_VariableText : public IPDF_VariableText, private CPDF_EditContainer {
-  friend class CTypeset;
-  friend class CSection;
-  friend class CPDF_VariableText_Iterator;
-
- public:
-  CPDF_VariableText();
-  ~CPDF_VariableText() override;
-
-  // IPDF_VariableText
-  IPDF_VariableText::Provider* SetProvider(
-      IPDF_VariableText::Provider* pProvider) override;
-  IPDF_VariableText::Iterator* GetIterator() override;
-  void SetPlateRect(const CFX_FloatRect& rect) override {
-    CPDF_EditContainer::SetPlateRect(rect);
-  }
-  void SetAlignment(int32_t nFormat = 0) override { m_nAlignment = nFormat; }
-  void SetPasswordChar(uint16_t wSubWord = '*') override {
-    m_wSubWord = wSubWord;
-  }
-  void SetLimitChar(int32_t nLimitChar = 0) override {
-    m_nLimitChar = nLimitChar;
-  }
-  void SetCharSpace(FX_FLOAT fCharSpace = 0.0f) override {
-    m_fCharSpace = fCharSpace;
-  }
-  void SetHorzScale(int32_t nHorzScale = 100) override {
-    m_nHorzScale = nHorzScale;
-  }
-  void SetMultiLine(FX_BOOL bMultiLine = TRUE) override {
-    m_bMultiLine = bMultiLine;
-  }
-  void SetAutoReturn(FX_BOOL bAuto = TRUE) override { m_bLimitWidth = bAuto; }
-  void SetFontSize(FX_FLOAT fFontSize) override { m_fFontSize = fFontSize; }
-  void SetCharArray(int32_t nCharArray = 0) override {
-    m_nCharArray = nCharArray;
-  }
-  void SetAutoFontSize(FX_BOOL bAuto = TRUE) override {
-    m_bAutoFontSize = bAuto;
-  }
-  void SetRichText(FX_BOOL bRichText) override { m_bRichText = bRichText; }
-  void SetLineLeading(FX_FLOAT fLineLeading) override {
-    m_fLineLeading = fLineLeading;
-  }
-  void Initialize() override;
-  FX_BOOL IsValid() const override { return m_bInitial; }
-  FX_BOOL IsRichText() const override { return m_bRichText; }
-  void RearrangeAll() override;
-  void RearrangePart(const CPVT_WordRange& PlaceRange) override;
-  void ResetAll() override;
-  void SetText(const FX_WCHAR* text,
-               int32_t charset = 1,
-               const CPVT_SecProps* pSecProps = NULL,
-               const CPVT_WordProps* pWordProps = NULL) override;
-  CPVT_WordPlace InsertWord(const CPVT_WordPlace& place,
-                            uint16_t word,
-                            int32_t charset = 1,
-                            const CPVT_WordProps* pWordProps = NULL) override;
-  CPVT_WordPlace InsertSection(
-      const CPVT_WordPlace& place,
-      const CPVT_SecProps* pSecProps = NULL,
-      const CPVT_WordProps* pWordProps = NULL) override;
-  CPVT_WordPlace InsertText(const CPVT_WordPlace& place,
-                            const FX_WCHAR* text,
-                            int32_t charset = 1,
-                            const CPVT_SecProps* pSecProps = NULL,
-                            const CPVT_WordProps* pWordProps = NULL) override;
-  CPVT_WordPlace DeleteWords(const CPVT_WordRange& PlaceRange) override;
-  CPVT_WordPlace DeleteWord(const CPVT_WordPlace& place) override;
-  CPVT_WordPlace BackSpaceWord(const CPVT_WordPlace& place) override;
-  const CFX_FloatRect& GetPlateRect() const override {
-    return CPDF_EditContainer::GetPlateRect();
-  }
-  CFX_FloatRect GetContentRect() const override;
-  int32_t GetTotalWords() const override;
-  FX_FLOAT GetFontSize() const override { return m_fFontSize; }
-  int32_t GetAlignment() const override { return m_nAlignment; }
-  uint16_t GetPasswordChar() const override { return GetSubWord(); }
-  int32_t GetCharArray() const override { return m_nCharArray; }
-  int32_t GetLimitChar() const override { return m_nLimitChar; }
-  FX_BOOL IsMultiLine() const override { return m_bMultiLine; }
-  int32_t GetHorzScale() const override { return m_nHorzScale; }
-  FX_FLOAT GetCharSpace() const override { return m_fCharSpace; }
-  CPVT_WordPlace GetBeginWordPlace() const override;
-  CPVT_WordPlace GetEndWordPlace() const override;
-  CPVT_WordPlace GetPrevWordPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetNextWordPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const override;
-  CPVT_WordPlace GetUpWordPlace(const CPVT_WordPlace& place,
-                                const CFX_FloatPoint& point) const override;
-  CPVT_WordPlace GetDownWordPlace(const CPVT_WordPlace& place,
-                                  const CFX_FloatPoint& point) const override;
-  CPVT_WordPlace GetLineBeginPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetSectionBeginPlace(
-      const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetSectionEndPlace(const CPVT_WordPlace& place) const override;
-  void UpdateWordPlace(CPVT_WordPlace& place) const override;
-  CPVT_WordPlace AdjustLineHeader(const CPVT_WordPlace& place,
-                                  FX_BOOL bPrevOrNext) const override;
-  int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace WordIndexToWordPlace(int32_t index) const override;
-
-  uint16_t GetSubWord() const { return m_wSubWord; }
-
- private:
-  int32_t GetCharWidth(int32_t nFontIndex,
-                       uint16_t Word,
-                       uint16_t SubWord,
-                       int32_t nWordStyle);
-  int32_t GetTypeAscent(int32_t nFontIndex);
-  int32_t GetTypeDescent(int32_t nFontIndex);
-  int32_t GetWordFontIndex(uint16_t word, int32_t charset, int32_t nFontIndex);
-  int32_t GetDefaultFontIndex();
-  FX_BOOL IsLatinWord(uint16_t word);
-
-  CPVT_WordPlace AddSection(const CPVT_WordPlace& place,
-                            const CPVT_SectionInfo& secinfo);
-  CPVT_WordPlace AddLine(const CPVT_WordPlace& place,
-                         const CPVT_LineInfo& lineinfo);
-  CPVT_WordPlace AddWord(const CPVT_WordPlace& place,
-                         const CPVT_WordInfo& wordinfo);
-  FX_BOOL GetWordInfo(const CPVT_WordPlace& place, CPVT_WordInfo& wordinfo);
-  FX_BOOL SetWordInfo(const CPVT_WordPlace& place,
-                      const CPVT_WordInfo& wordinfo);
-  FX_BOOL GetLineInfo(const CPVT_WordPlace& place, CPVT_LineInfo& lineinfo);
-  FX_BOOL GetSectionInfo(const CPVT_WordPlace& place,
-                         CPVT_SectionInfo& secinfo);
-  FX_FLOAT GetWordFontSize(const CPVT_WordInfo& WordInfo,
-                           FX_BOOL bFactFontSize = FALSE);
-  FX_FLOAT GetWordWidth(int32_t nFontIndex,
-                        uint16_t Word,
-                        uint16_t SubWord,
-                        FX_FLOAT fCharSpace,
-                        int32_t nHorzScale,
-                        FX_FLOAT fFontSize,
-                        FX_FLOAT fWordTail,
-                        int32_t nWordStyle);
-  FX_FLOAT GetWordWidth(const CPVT_WordInfo& WordInfo);
-  FX_FLOAT GetWordAscent(const CPVT_WordInfo& WordInfo, FX_FLOAT fFontSize);
-  FX_FLOAT GetWordDescent(const CPVT_WordInfo& WordInfo, FX_FLOAT fFontSize);
-  FX_FLOAT GetWordAscent(const CPVT_WordInfo& WordInfo,
-                         FX_BOOL bFactFontSize = FALSE);
-  FX_FLOAT GetWordDescent(const CPVT_WordInfo& WordInfo,
-                          FX_BOOL bFactFontSize = FALSE);
-  FX_FLOAT GetLineAscent(const CPVT_SectionInfo& SecInfo);
-  FX_FLOAT GetLineDescent(const CPVT_SectionInfo& SecInfo);
-  FX_FLOAT GetFontAscent(int32_t nFontIndex, FX_FLOAT fFontSize);
-  FX_FLOAT GetFontDescent(int32_t nFontIndex, FX_FLOAT fFontSize);
-  int32_t GetWordFontIndex(const CPVT_WordInfo& WordInfo);
-  FX_FLOAT GetCharSpace(const CPVT_WordInfo& WordInfo);
-  int32_t GetHorzScale(const CPVT_WordInfo& WordInfo);
-  FX_FLOAT GetLineLeading(const CPVT_SectionInfo& SecInfo);
-  FX_FLOAT GetLineIndent(const CPVT_SectionInfo& SecInfo);
-  int32_t GetAlignment(const CPVT_SectionInfo& SecInfo);
-
-  void ClearSectionRightWords(const CPVT_WordPlace& place);
-
-  FX_BOOL ClearEmptySection(const CPVT_WordPlace& place);
-  void ClearEmptySections(const CPVT_WordRange& PlaceRange);
-  void LinkLatterSection(const CPVT_WordPlace& place);
-  void ClearWords(const CPVT_WordRange& PlaceRange);
-  CPVT_WordPlace ClearLeftWord(const CPVT_WordPlace& place);
-  CPVT_WordPlace ClearRightWord(const CPVT_WordPlace& place);
-
- private:
-  CPVT_FloatRect Rearrange(const CPVT_WordRange& PlaceRange);
-  FX_FLOAT GetAutoFontSize();
-  FX_BOOL IsBigger(FX_FLOAT fFontSize);
-  CPVT_FloatRect RearrangeSections(const CPVT_WordRange& PlaceRange);
-
-  void ResetSectionArray();
-
-  CPVT_ArrayTemplate<CSection*> m_SectionArray;
-  int32_t m_nLimitChar;
-  int32_t m_nCharArray;
-  FX_BOOL m_bMultiLine;
-  FX_BOOL m_bLimitWidth;
-  FX_BOOL m_bAutoFontSize;
-  int32_t m_nAlignment;
-  FX_FLOAT m_fLineLeading;
-  FX_FLOAT m_fCharSpace;
-  int32_t m_nHorzScale;
-  uint16_t m_wSubWord;
-  FX_FLOAT m_fFontSize;
-
- private:
-  FX_BOOL m_bInitial;
-  FX_BOOL m_bRichText;
-  IPDF_VariableText::Provider* m_pVTProvider;
-  CPDF_VariableText::Iterator* m_pVTIterator;
-};
-
-class CPDF_VariableText_Iterator : public IPDF_VariableText::Iterator {
- public:
-  explicit CPDF_VariableText_Iterator(CPDF_VariableText* pVT);
-  ~CPDF_VariableText_Iterator() override;
-
-  // IPDF_VariableText::Iterator
-  FX_BOOL NextWord() override;
-  FX_BOOL PrevWord() override;
-  FX_BOOL NextLine() override;
-  FX_BOOL PrevLine() override;
-  FX_BOOL NextSection() override;
-  FX_BOOL PrevSection() override;
-  FX_BOOL SetWord(const CPVT_Word& word) override;
-  FX_BOOL GetWord(CPVT_Word& word) const override;
-  FX_BOOL GetLine(CPVT_Line& line) const override;
-  FX_BOOL GetSection(CPVT_Section& section) const override;
-  FX_BOOL SetSection(const CPVT_Section& section) override;
-  void SetAt(int32_t nWordIndex) override;
-  void SetAt(const CPVT_WordPlace& place) override;
-  const CPVT_WordPlace& GetAt() const override { return m_CurPos; }
-
- private:
-  CPVT_WordPlace m_CurPos;
-  CPDF_VariableText* m_pVT;
-};
-
 #endif  // CORE_FPDFDOC_PDF_VT_H_
diff --git a/core/include/fpdfdoc/fpdf_vt.h b/core/include/fpdfdoc/fpdf_vt.h
deleted file mode 100644
index d8a904c..0000000
--- a/core/include/fpdfdoc/fpdf_vt.h
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef CORE_INCLUDE_FPDFDOC_FPDF_VT_H_
-#define CORE_INCLUDE_FPDFDOC_FPDF_VT_H_
-
-#include "core/include/fxge/fx_dib.h"
-
-class IPDF_VariableText;
-struct CPVT_Line;
-struct CPVT_Section;
-struct CPVT_Word;
-struct CPVT_WordPlace;
-struct CPVT_WordRange;
-
-struct CPVT_WordPlace {
-  CPVT_WordPlace() : nSecIndex(-1), nLineIndex(-1), nWordIndex(-1) {}
-
-  CPVT_WordPlace(int32_t other_nSecIndex,
-                 int32_t other_nLineIndex,
-                 int32_t other_nWordIndex) {
-    nSecIndex = other_nSecIndex;
-    nLineIndex = other_nLineIndex;
-    nWordIndex = other_nWordIndex;
-  }
-
-  void Default() { nSecIndex = nLineIndex = nWordIndex = -1; }
-
-  bool operator==(const CPVT_WordPlace& wp) const {
-    return wp.nSecIndex == nSecIndex && wp.nLineIndex == nLineIndex &&
-           wp.nWordIndex == nWordIndex;
-  }
-
-  FX_BOOL operator!=(const CPVT_WordPlace& wp) const { return !(*this == wp); }
-
-  inline int32_t WordCmp(const CPVT_WordPlace& wp) const {
-    if (nSecIndex > wp.nSecIndex)
-      return 1;
-    if (nSecIndex < wp.nSecIndex)
-      return -1;
-    if (nLineIndex > wp.nLineIndex)
-      return 1;
-    if (nLineIndex < wp.nLineIndex)
-      return -1;
-    if (nWordIndex > wp.nWordIndex)
-      return 1;
-    if (nWordIndex < wp.nWordIndex)
-      return -1;
-    return 0;
-  }
-
-  inline int32_t LineCmp(const CPVT_WordPlace& wp) const {
-    if (nSecIndex > wp.nSecIndex)
-      return 1;
-    if (nSecIndex < wp.nSecIndex)
-      return -1;
-    if (nLineIndex > wp.nLineIndex)
-      return 1;
-    if (nLineIndex < wp.nLineIndex)
-      return -1;
-    return 0;
-  }
-
-  inline int32_t SecCmp(const CPVT_WordPlace& wp) const {
-    if (nSecIndex > wp.nSecIndex)
-      return 1;
-    if (nSecIndex < wp.nSecIndex)
-      return -1;
-    return 0;
-  }
-
-  int32_t nSecIndex;
-  int32_t nLineIndex;
-  int32_t nWordIndex;
-};
-struct CPVT_WordRange {
-  CPVT_WordRange() {}
-
-  CPVT_WordRange(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
-    Set(begin, end);
-  }
-
-  void Default() {
-    BeginPos.Default();
-    EndPos.Default();
-  }
-
-  void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end) {
-    BeginPos = begin;
-    EndPos = end;
-    SwapWordPlace();
-  }
-
-  void SetBeginPos(const CPVT_WordPlace& begin) {
-    BeginPos = begin;
-    SwapWordPlace();
-  }
-
-  void SetEndPos(const CPVT_WordPlace& end) {
-    EndPos = end;
-    SwapWordPlace();
-  }
-
-  FX_BOOL IsExist() const { return BeginPos != EndPos; }
-
-  FX_BOOL operator!=(const CPVT_WordRange& wr) const {
-    return wr.BeginPos != BeginPos || wr.EndPos != EndPos;
-  }
-
-  void SwapWordPlace() {
-    if (BeginPos.WordCmp(EndPos) > 0) {
-      CPVT_WordPlace place = EndPos;
-      EndPos = BeginPos;
-      BeginPos = place;
-    }
-  }
-
-  CPVT_WordPlace BeginPos;
-  CPVT_WordPlace EndPos;
-};
-struct CPVT_SecProps {
-  CPVT_SecProps() : fLineLeading(0.0f), fLineIndent(0.0f), nAlignment(0) {}
-
-  CPVT_SecProps(FX_FLOAT lineLeading, FX_FLOAT lineIndent, int32_t alignment)
-      : fLineLeading(lineLeading),
-        fLineIndent(lineIndent),
-        nAlignment(alignment) {}
-
-  CPVT_SecProps(const CPVT_SecProps& other)
-      : fLineLeading(other.fLineLeading),
-        fLineIndent(other.fLineIndent),
-        nAlignment(other.nAlignment) {}
-
-  FX_FLOAT fLineLeading;
-  FX_FLOAT fLineIndent;
-  int32_t nAlignment;
-};
-struct CPVT_WordProps {
-  CPVT_WordProps()
-      : nFontIndex(-1),
-        fFontSize(0.0f),
-        dwWordColor(0),
-        nScriptType(0),
-        nWordStyle(0),
-        fCharSpace(0.0f),
-        nHorzScale(0) {}
-
-  CPVT_WordProps(int32_t fontIndex,
-                 FX_FLOAT fontSize,
-                 FX_COLORREF wordColor = 0,
-                 int32_t scriptType = 0,
-                 int32_t wordStyle = 0,
-                 FX_FLOAT charSpace = 0,
-                 int32_t horzScale = 100)
-      : nFontIndex(fontIndex),
-        fFontSize(fontSize),
-        dwWordColor(wordColor),
-        nScriptType(scriptType),
-        nWordStyle(wordStyle),
-        fCharSpace(charSpace),
-        nHorzScale(horzScale) {}
-
-  CPVT_WordProps(const CPVT_WordProps& other)
-      : nFontIndex(other.nFontIndex),
-        fFontSize(other.fFontSize),
-        dwWordColor(other.dwWordColor),
-        nScriptType(other.nScriptType),
-        nWordStyle(other.nWordStyle),
-        fCharSpace(other.fCharSpace),
-        nHorzScale(other.nHorzScale) {}
-
-  int32_t nFontIndex;
-  FX_FLOAT fFontSize;
-  FX_COLORREF dwWordColor;
-  int32_t nScriptType;
-  int32_t nWordStyle;
-  FX_FLOAT fCharSpace;
-  int32_t nHorzScale;
-};
-struct CPVT_Word {
-  CPVT_Word()
-      : Word(0),
-        nCharset(0),
-        ptWord(0, 0),
-        fAscent(0.0f),
-        fDescent(0.0f),
-        fWidth(0.0f),
-        fFontSize(0),
-        WordProps() {}
-
-  uint16_t Word;
-  int32_t nCharset;
-  CPVT_WordPlace WordPlace;
-  CFX_FloatPoint ptWord;
-  FX_FLOAT fAscent;
-  FX_FLOAT fDescent;
-  FX_FLOAT fWidth;
-  int32_t nFontIndex;
-  FX_FLOAT fFontSize;
-  CPVT_WordProps WordProps;
-};
-struct CPVT_Line {
-  CPVT_Line()
-      : ptLine(0, 0), fLineWidth(0.0f), fLineAscent(0.0f), fLineDescent(0.0f) {}
-
-  CPVT_WordPlace lineplace;
-  CPVT_WordPlace lineEnd;
-  CFX_FloatPoint ptLine;
-  FX_FLOAT fLineWidth;
-  FX_FLOAT fLineAscent;
-  FX_FLOAT fLineDescent;
-};
-struct CPVT_Section {
-  CPVT_WordPlace secplace;
-  CFX_FloatRect rcSection;
-  CPVT_SecProps SecProps;
-  CPVT_WordProps WordProps;
-};
-
-class IPDF_VariableText {
- public:
-  class Provider {
-   public:
-    virtual ~Provider() {}
-
-    virtual int32_t GetCharWidth(int32_t nFontIndex,
-                                 uint16_t word,
-                                 int32_t nWordStyle) = 0;
-    virtual int32_t GetTypeAscent(int32_t nFontIndex) = 0;
-    virtual int32_t GetTypeDescent(int32_t nFontIndex) = 0;
-    virtual int32_t GetWordFontIndex(uint16_t word,
-                                     int32_t charset,
-                                     int32_t nFontIndex) = 0;
-    virtual int32_t GetDefaultFontIndex() = 0;
-    virtual FX_BOOL IsLatinWord(uint16_t word) = 0;
-  };
-
-  class Iterator {
-   public:
-    virtual ~Iterator() {}
-
-    virtual FX_BOOL NextWord() = 0;
-    virtual FX_BOOL PrevWord() = 0;
-    virtual FX_BOOL NextLine() = 0;
-    virtual FX_BOOL PrevLine() = 0;
-    virtual FX_BOOL NextSection() = 0;
-    virtual FX_BOOL PrevSection() = 0;
-    virtual FX_BOOL GetWord(CPVT_Word& word) const = 0;
-    virtual FX_BOOL SetWord(const CPVT_Word& word) = 0;
-    virtual FX_BOOL GetLine(CPVT_Line& line) const = 0;
-    virtual FX_BOOL GetSection(CPVT_Section& section) const = 0;
-    virtual FX_BOOL SetSection(const CPVT_Section& section) = 0;
-    virtual void SetAt(int32_t nWordIndex) = 0;
-    virtual void SetAt(const CPVT_WordPlace& place) = 0;
-    virtual const CPVT_WordPlace& GetAt() const = 0;
-  };
-
-  static IPDF_VariableText* NewVariableText();
-  static void DelVariableText(IPDF_VariableText* pVT);
-
-  virtual void Initialize() = 0;
-
-  virtual Provider* SetProvider(Provider* pProvider) = 0;
-  virtual Iterator* GetIterator() = 0;
-
-  virtual void SetPlateRect(const CFX_FloatRect& rect) = 0;
-  virtual void SetAlignment(int32_t nFormat = 0) = 0;
-  virtual void SetPasswordChar(uint16_t wSubWord = '*') = 0;
-  virtual void SetLimitChar(int32_t nLimitChar = 0) = 0;
-  virtual void SetCharArray(int32_t nCharArray = 0) = 0;
-  virtual void SetCharSpace(FX_FLOAT fCharSpace = 0.0f) = 0;
-  virtual void SetHorzScale(int32_t nHorzScale = 100) = 0;
-  virtual void SetMultiLine(FX_BOOL bMultiLine = TRUE) = 0;
-  virtual void SetAutoReturn(FX_BOOL bAuto = TRUE) = 0;
-  virtual void SetAutoFontSize(FX_BOOL bAuto = TRUE) = 0;
-  virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
-  virtual void SetLineLeading(FX_FLOAT fLineLeading) = 0;
-  virtual void SetRichText(FX_BOOL bRichText) = 0;
-
-  virtual FX_BOOL IsValid() const = 0;
-  virtual FX_BOOL IsRichText() const = 0;
-  virtual FX_BOOL IsMultiLine() const = 0;
-
-  virtual void RearrangeAll() = 0;
-  virtual void RearrangePart(const CPVT_WordRange& PlaceRange) = 0;
-
-  virtual void ResetAll() = 0;
-
-  virtual void SetText(const FX_WCHAR* text,
-                       int32_t charset = 1,
-                       const CPVT_SecProps* pSecProps = NULL,
-                       const CPVT_WordProps* pWordProps = NULL) = 0;
-  virtual CPVT_WordPlace InsertWord(
-      const CPVT_WordPlace& place,
-      uint16_t word,
-      int32_t charset = 1,
-      const CPVT_WordProps* pWordProps = NULL) = 0;
-  virtual CPVT_WordPlace InsertSection(
-      const CPVT_WordPlace& place,
-      const CPVT_SecProps* pSecProps = NULL,
-      const CPVT_WordProps* pWordProps = NULL) = 0;
-  virtual CPVT_WordPlace InsertText(
-      const CPVT_WordPlace& place,
-      const FX_WCHAR* text,
-      int32_t charset = 1,
-      const CPVT_SecProps* pSecProps = NULL,
-      const CPVT_WordProps* pWordProps = NULL) = 0;
-
-  virtual CPVT_WordPlace DeleteWords(const CPVT_WordRange& PlaceRange) = 0;
-  virtual CPVT_WordPlace DeleteWord(const CPVT_WordPlace& place) = 0;
-  virtual CPVT_WordPlace BackSpaceWord(const CPVT_WordPlace& place) = 0;
-
-  virtual const CFX_FloatRect& GetPlateRect() const = 0;
-  virtual CFX_FloatRect GetContentRect() const = 0;
-  virtual int32_t GetTotalWords() const = 0;
-  virtual FX_FLOAT GetFontSize() const = 0;
-  virtual int32_t GetAlignment() const = 0;
-  virtual uint16_t GetPasswordChar() const = 0;
-  virtual int32_t GetCharArray() const = 0;
-  virtual int32_t GetLimitChar() const = 0;
-  virtual int32_t GetHorzScale() const = 0;
-  virtual FX_FLOAT GetCharSpace() const = 0;
-  virtual CPVT_WordPlace GetBeginWordPlace() const = 0;
-  virtual CPVT_WordPlace GetEndWordPlace() const = 0;
-  virtual CPVT_WordPlace GetPrevWordPlace(
-      const CPVT_WordPlace& place) const = 0;
-  virtual CPVT_WordPlace GetNextWordPlace(
-      const CPVT_WordPlace& place) const = 0;
-
-  virtual CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const = 0;
-  virtual CPVT_WordPlace GetUpWordPlace(const CPVT_WordPlace& place,
-                                        const CFX_FloatPoint& point) const = 0;
-  virtual CPVT_WordPlace GetDownWordPlace(
-      const CPVT_WordPlace& place,
-      const CFX_FloatPoint& point) const = 0;
-  virtual CPVT_WordPlace GetLineBeginPlace(
-      const CPVT_WordPlace& place) const = 0;
-  virtual CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const = 0;
-  virtual CPVT_WordPlace GetSectionBeginPlace(
-      const CPVT_WordPlace& place) const = 0;
-  virtual CPVT_WordPlace GetSectionEndPlace(
-      const CPVT_WordPlace& place) const = 0;
-
-  virtual void UpdateWordPlace(CPVT_WordPlace& place) const = 0;
-  virtual CPVT_WordPlace AdjustLineHeader(const CPVT_WordPlace& place,
-                                          FX_BOOL bPrevOrNext) const = 0;
-
-  virtual int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const = 0;
-  virtual CPVT_WordPlace WordIndexToWordPlace(int32_t index) const = 0;
-
- protected:
-  ~IPDF_VariableText() {}
-};
-
-#endif  // CORE_INCLUDE_FPDFDOC_FPDF_VT_H_
diff --git a/fpdfsdk/fsdk_baseform.cpp b/fpdfsdk/fsdk_baseform.cpp
index d195d87..fe7c2393 100644
--- a/fpdfsdk/fsdk_baseform.cpp
+++ b/fpdfsdk/fsdk_baseform.cpp
@@ -30,11 +30,6 @@
 #include "xfa/include/fxfa/xfa_ffwidget.h"
 #endif  // PDF_ENABLE_XFA
 
-#define IsFloatZero(f) ((f) < 0.01 && (f) > -0.01)
-#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
-#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
-
 CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot,
                                CPDFSDK_PageView* pPageView,
                                CPDFSDK_InterForm* pInterForm)
diff --git a/fpdfsdk/fxedit/DEPS b/fpdfsdk/fxedit/DEPS
index 8e0928c..cf99b35 100644
--- a/fpdfsdk/fxedit/DEPS
+++ b/fpdfsdk/fxedit/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   '+core/fpdfapi/fpdf_font/include',
+  '+core/fpdfdoc/include',
 ]
diff --git a/fpdfsdk/fxedit/fxet_ap.cpp b/fpdfsdk/fxedit/fxet_ap.cpp
index c17a2ca..48c6876 100644
--- a/fpdfsdk/fxedit/fxet_ap.cpp
+++ b/fpdfsdk/fxedit/fxet_ap.cpp
@@ -6,10 +6,12 @@
 
 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
 #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
+#include "core/fpdfdoc/include/cpvt_word.h"
+#include "core/fpdfdoc/include/ipvt_fontmap.h"
 #include "fpdfsdk/include/fxedit/fx_edit.h"
 #include "fpdfsdk/include/fxedit/fxet_edit.h"
 
-CFX_ByteString GetPDFWordString(IFX_Edit_FontMap* pFontMap,
+CFX_ByteString GetPDFWordString(IPVT_FontMap* pFontMap,
                                 int32_t nFontIndex,
                                 uint16_t Word,
                                 uint16_t SubWord) {
@@ -42,7 +44,7 @@
   return "";
 }
 
-static CFX_ByteString GetFontSetString(IFX_Edit_FontMap* pFontMap,
+static CFX_ByteString GetFontSetString(IPVT_FontMap* pFontMap,
                                        int32_t nFontIndex,
                                        FX_FLOAT fFontSize) {
   CFX_ByteTextBuf sRet;
diff --git a/fpdfsdk/fxedit/fxet_edit.cpp b/fpdfsdk/fxedit/fxet_edit.cpp
index 0cb5a28..f275248 100644
--- a/fpdfsdk/fxedit/fxet_edit.cpp
+++ b/fpdfsdk/fxedit/fxet_edit.cpp
@@ -9,11 +9,14 @@
 #include <algorithm>
 
 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+#include "core/fpdfdoc/include/cpvt_section.h"
+#include "core/fpdfdoc/include/cpvt_word.h"
+#include "core/fpdfdoc/include/ipvt_fontmap.h"
 
 #define FX_EDIT_UNDO_MAXITEM 10000
 
 CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit* pEdit,
-                                     IPDF_VariableText::Iterator* pVTIterator)
+                                     CPDF_VariableText::Iterator* pVTIterator)
     : m_pEdit(pEdit), m_pVTIterator(pVTIterator) {}
 
 CFX_Edit_Iterator::~CFX_Edit_Iterator() {}
@@ -88,14 +91,14 @@
   return m_pEdit;
 }
 
-CFX_Edit_Provider::CFX_Edit_Provider(IFX_Edit_FontMap* pFontMap)
-    : m_pFontMap(pFontMap) {
+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() {}
 
-IFX_Edit_FontMap* CFX_Edit_Provider::GetFontMap() {
+IPVT_FontMap* CFX_Edit_Provider::GetFontMap() {
   return m_pFontMap;
 }
 
@@ -739,7 +742,7 @@
   }
 }
 
-CFX_Edit::CFX_Edit(IPDF_VariableText* pVT)
+CFX_Edit::CFX_Edit(CPDF_VariableText* pVT)
     : m_pVT(pVT),
       m_pNotify(NULL),
       m_pOprNotify(NULL),
@@ -779,12 +782,12 @@
   SetCaretOrigin();
 }
 
-void CFX_Edit::SetFontMap(IFX_Edit_FontMap* pFontMap) {
+void CFX_Edit::SetFontMap(IPVT_FontMap* pFontMap) {
   delete m_pVTProvide;
   m_pVT->SetProvider(m_pVTProvide = new CFX_Edit_Provider(pFontMap));
 }
 
-void CFX_Edit::SetVTProvider(IPDF_VariableText::Provider* pProvider) {
+void CFX_Edit::SetVTProvider(CPDF_VariableText::Provider* pProvider) {
   m_pVT->SetProvider(pProvider);
 }
 
@@ -803,11 +806,11 @@
   return m_pIterator;
 }
 
-IPDF_VariableText* CFX_Edit::GetVariableText() {
+CPDF_VariableText* CFX_Edit::GetVariableText() {
   return m_pVT;
 }
 
-IFX_Edit_FontMap* CFX_Edit::GetFontMap() {
+IPVT_FontMap* CFX_Edit::GetFontMap() {
   if (m_pVTProvide)
     return m_pVTProvide->GetFontMap();
 
@@ -978,7 +981,7 @@
   CFX_WideString swRet;
 
   if (m_pVT->IsValid()) {
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       FX_BOOL bRich = m_pVT->IsRichText();
 
       pIterator->SetAt(0);
@@ -1015,7 +1018,7 @@
   if (m_pVT->IsValid()) {
     FX_BOOL bRich = m_pVT->IsRichText();
 
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       CPVT_WordRange wrTemp = range;
       m_pVT->UpdateWordPlace(wrTemp.BeginPos);
       m_pVT->UpdateWordPlace(wrTemp.EndPos);
@@ -1060,7 +1063,7 @@
 int32_t CFX_Edit::GetTotalLines() const {
   int32_t nLines = 0;
 
-  if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+  if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
     pIterator->SetAt(0);
     while (pIterator->NextLine())
       nLines++;
@@ -1120,7 +1123,7 @@
   return SetRichTextProps(EP_WORDCOLOR, NULL, &WordProps);
 }
 
-FX_BOOL CFX_Edit::SetRichTextScript(int32_t nScriptType) {
+FX_BOOL CFX_Edit::SetRichTextScript(CPDF_VariableText::ScriptType nScriptType) {
   CPVT_WordProps WordProps;
   WordProps.nScriptType = nScriptType;
   return SetRichTextProps(EP_SCRIPTTYPE, NULL, &WordProps);
@@ -1190,7 +1193,7 @@
   FX_BOOL bSet = FALSE;
   FX_BOOL bSet1, bSet2;
   if (m_pVT->IsValid() && m_pVT->IsRichText()) {
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
 
       m_pVT->UpdateWordPlace(wrTemp.BeginPos);
@@ -1266,7 +1269,7 @@
                               const CPVT_WordRange& wr,
                               FX_BOOL bAddUndo) {
   if (m_pVT->IsValid() && m_pVT->IsRichText()) {
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       FX_BOOL bSet = FALSE;
       CPVT_Section secinfo;
       CPVT_Section OldSecinfo;
@@ -1445,7 +1448,7 @@
                                const CPVT_WordRange& wr,
                                FX_BOOL bAddUndo) {
   if (m_pVT->IsValid() && m_pVT->IsRichText()) {
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       FX_BOOL bSet = FALSE;
       CPVT_Word wordinfo;
       CPVT_Word OldWordinfo;
@@ -1461,7 +1464,7 @@
           switch (eProps) {
             case EP_FONTINDEX:
               if (wordinfo.WordProps.nFontIndex != pWordProps->nFontIndex) {
-                if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
+                if (IPVT_FontMap* pFontMap = GetFontMap()) {
                   wordinfo.WordProps.nFontIndex = pFontMap->GetWordFontIndex(
                       wordinfo.Word, wordinfo.nCharset, pWordProps->nFontIndex);
                 }
@@ -1919,7 +1922,7 @@
     CFX_FloatPoint ptHead(0, 0);
     CFX_FloatPoint ptFoot(0, 0);
 
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       pIterator->SetAt(m_wpCaret);
 
       CPVT_Word word;
@@ -1993,7 +1996,7 @@
 
 void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange& wr) {
   if (m_pVT->IsValid()) {
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       CPVT_WordPlace wpBegin = wr.BeginPos;
       m_pVT->UpdateWordPlace(wpBegin);
       CPVT_WordPlace wpEnd = wr.EndPos;
@@ -2021,7 +2024,7 @@
 
 void CFX_Edit::RefreshPushRandomRects(const CPVT_WordRange& wr) {
   if (m_pVT->IsValid()) {
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       CPVT_WordRange wrTemp = wr;
 
       m_pVT->UpdateWordPlace(wrTemp.BeginPos);
@@ -2064,7 +2067,7 @@
 }
 
 void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr) {
-  if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+  if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
     CPVT_WordRange wrTemp = wr;
 
     m_pVT->UpdateWordPlace(wrTemp.BeginPos);
@@ -2129,7 +2132,7 @@
     if (!m_bNotifyFlag) {
       CFX_FloatPoint ptHead(0.0f, 0.0f), ptFoot(0.0f, 0.0f);
 
-      if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+      if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
         pIterator->SetAt(m_wpCaret);
         CPVT_Word word;
         CPVT_Line line;
@@ -2164,7 +2167,7 @@
     CPVT_SecProps SecProps;
     CPVT_WordProps WordProps;
 
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       pIterator->SetAt(m_wpCaret);
       CPVT_Word word;
       CPVT_Section section;
@@ -2547,7 +2550,7 @@
     CPVT_Word word;
 
     if (bAddUndo) {
-      if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+      if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
         pIterator->SetAt(m_wpCaret);
         pIterator->GetSection(section);
         pIterator->GetWord(word);
@@ -2610,7 +2613,7 @@
     CPVT_Word word;
 
     if (bAddUndo) {
-      if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+      if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
         pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
         pIterator->GetSection(section);
         pIterator->GetWord(word);
@@ -2684,7 +2687,7 @@
         if (m_pVT->IsRichText()) {
           BeginGroupUndo(L"");
 
-          if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+          if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
             pIterator->SetAt(range.EndPos);
 
             CPVT_Word wordinfo;
@@ -2817,7 +2820,7 @@
 
 void CFX_Edit::SetCaretOrigin() {
   if (m_pVT->IsValid()) {
-    if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+    if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
       pIterator->SetAt(m_wpCaret);
       CPVT_Word word;
       CPVT_Line line;
@@ -2930,7 +2933,7 @@
 }
 
 FX_FLOAT CFX_Edit::GetLineTop(const CPVT_WordPlace& place) const {
-  if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+  if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
     CPVT_WordPlace wpOld = pIterator->GetAt();
 
     pIterator->SetAt(place);
@@ -2946,7 +2949,7 @@
 }
 
 FX_FLOAT CFX_Edit::GetLineBottom(const CPVT_WordPlace& place) const {
-  if (IPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
+  if (CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator()) {
     CPVT_WordPlace wpOld = pIterator->GetAt();
 
     pIterator->SetAt(place);
@@ -2998,7 +3001,7 @@
 }
 
 int32_t CFX_Edit::GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset) {
-  if (IFX_Edit_FontMap* pFontMap = GetFontMap())
+  if (IPVT_FontMap* pFontMap = GetFontMap())
     return pFontMap->CharSetFromUnicode(word, nOldCharset);
   return nOldCharset;
 }
diff --git a/fpdfsdk/fxedit/fxet_list.cpp b/fpdfsdk/fxedit/fxet_list.cpp
index f060d93..f3db386 100644
--- a/fpdfsdk/fxedit/fxet_list.cpp
+++ b/fpdfsdk/fxedit/fxet_list.cpp
@@ -6,6 +6,7 @@
 
 #include "fpdfsdk/include/fxedit/fxet_list.h"
 
+#include "core/fpdfdoc/include/cpvt_word.h"
 #include "fpdfsdk/include/fxedit/fxet_edit.h"
 
 CFX_ListItem::CFX_ListItem()
@@ -22,7 +23,7 @@
   IFX_Edit::DelEdit(m_pEdit);
 }
 
-void CFX_ListItem::SetFontMap(IFX_Edit_FontMap* pFontMap) {
+void CFX_ListItem::SetFontMap(IPVT_FontMap* pFontMap) {
   if (m_pEdit)
     m_pEdit->SetFontMap(pFontMap);
 }
@@ -111,7 +112,7 @@
   m_aListItems.RemoveAll();
 }
 
-void CFX_List::SetFontMap(IFX_Edit_FontMap* pFontMap) {
+void CFX_List::SetFontMap(IPVT_FontMap* pFontMap) {
   m_pFontMap = pFontMap;
 }
 
diff --git a/fpdfsdk/fxedit/fxet_module.cpp b/fpdfsdk/fxedit/fxet_module.cpp
index 889b0f8..330b72b 100644
--- a/fpdfsdk/fxedit/fxet_module.cpp
+++ b/fpdfsdk/fxedit/fxet_module.cpp
@@ -4,21 +4,17 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "core/fpdfdoc/include/cpdf_variabletext.h"
 #include "fpdfsdk/include/fxedit/fxet_edit.h"
 #include "fpdfsdk/include/fxedit/fxet_list.h"
 
 IFX_Edit* IFX_Edit::NewEdit() {
-  if (IPDF_VariableText* pVT = IPDF_VariableText::NewVariableText()) {
-    return new CFX_Edit(pVT);
-  }
-
-  return NULL;
+  return new CFX_Edit(new CPDF_VariableText());
 }
 
 void IFX_Edit::DelEdit(IFX_Edit* pEdit) {
-  IPDF_VariableText::DelVariableText(pEdit->GetVariableText());
-
-  delete (CFX_Edit*)pEdit;
+  delete pEdit->GetVariableText();
+  delete static_cast<CFX_Edit*>(pEdit);
 }
 
 IFX_List* IFX_List::NewList() {
diff --git a/fpdfsdk/fxedit/fxet_pageobjs.cpp b/fpdfsdk/fxedit/fxet_pageobjs.cpp
index 1133cab..1fe40d9 100644
--- a/fpdfsdk/fxedit/fxet_pageobjs.cpp
+++ b/fpdfsdk/fxedit/fxet_pageobjs.cpp
@@ -10,6 +10,8 @@
 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h"
 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h"
 #include "core/fpdfapi/fpdf_render/include/cpdf_textrenderer.h"
+#include "core/fpdfdoc/include/cpvt_word.h"
+#include "core/fpdfdoc/include/ipvt_fontmap.h"
 #include "core/include/fxge/fx_ge.h"
 #include "fpdfsdk/include/fx_systemhandler.h"
 #include "fpdfsdk/include/fxedit/fx_edit.h"
@@ -178,7 +180,7 @@
   }
 
   if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap()) {
+    if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
       if (pRange)
         pIterator->SetAt(pRange->BeginPos);
       else
@@ -299,7 +301,7 @@
   }
 
   if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap()) {
+    if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
       if (pRange)
         pIterator->SetAt(pRange->BeginPos);
       else
@@ -473,7 +475,7 @@
   ObjArray.RemoveAll();
 
   if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap()) {
+    if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
       if (pRange)
         pIterator->SetAt(pRange->BeginPos);
       else
@@ -537,7 +539,7 @@
   ObjArray.RemoveAll();
 
   if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
-    if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap()) {
+    if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
       if (pRange)
         pIterator->SetAt(pRange->BeginPos);
       else
diff --git a/fpdfsdk/include/fsdk_define.h b/fpdfsdk/include/fsdk_define.h
index 706880a..9d81737 100644
--- a/fpdfsdk/include/fsdk_define.h
+++ b/fpdfsdk/include/fsdk_define.h
@@ -9,7 +9,6 @@
 
 #include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h"
 #include "core/include/fpdfdoc/fpdf_doc.h"
-#include "core/include/fpdfdoc/fpdf_vt.h"
 #include "core/include/fxge/fx_ge.h"
 #include "core/include/fxge/fx_ge_win32.h"
 #include "public/fpdfview.h"
diff --git a/fpdfsdk/include/fxedit/fx_edit.h b/fpdfsdk/include/fxedit/fx_edit.h
index 2adf97b..532e96d 100644
--- a/fpdfsdk/include/fxedit/fx_edit.h
+++ b/fpdfsdk/include/fxedit/fx_edit.h
@@ -7,18 +7,18 @@
 #ifndef FPDFSDK_INCLUDE_FXEDIT_FX_EDIT_H_
 #define FPDFSDK_INCLUDE_FXEDIT_FX_EDIT_H_
 
+#include "core/fpdfdoc/include/cpdf_variabletext.h"
 #include "core/fxcrt/include/fx_basic.h"
-#include "core/include/fpdfdoc/fpdf_vt.h"
 #include "core/include/fxge/fx_dib.h"
 
-class CFX_RenderDevice;
 class CPDF_Font;
-class CFX_Matrix;
 class CPDF_PageObjectHolder;
-class CFX_FloatPoint;
 class CPDF_TextObject;
+class CFX_FloatPoint;
+class CFX_Matrix;
+class CFX_RenderDevice;
 class IFX_Edit;
-class IFX_Edit_FontMap;
+class IPVT_FontMap;
 class IFX_Edit_Iterator;
 class IFX_Edit_Notify;
 class IFX_Edit_UndoItem;
@@ -51,23 +51,6 @@
 #define DEFAULT_CHARSET 1
 #endif
 
-class IFX_Edit_FontMap {
- public:
-  virtual ~IFX_Edit_FontMap() {}
-  // map a fontindex to pdf font.
-  virtual CPDF_Font* GetPDFFont(int32_t nFontIndex) = 0;
-  // get the alias of a pdf font.
-  virtual CFX_ByteString GetPDFFontAlias(int32_t nFontIndex) = 0;
-  // get the index of a font that can show a word.
-  virtual int32_t GetWordFontIndex(uint16_t word,
-                                   int32_t charset,
-                                   int32_t nFontIndex) = 0;
-  // get the charcode of word from unicode
-  virtual int32_t CharCodeFromUnicode(int32_t nFontIndex, uint16_t word) = 0;
-  // get the charset of unicode
-  virtual int32_t CharSetFromUnicode(uint16_t word, int32_t nOldCharset) = 0;
-};
-
 class IFX_Edit_Notify {
  public:
   virtual ~IFX_Edit_Notify() {}
@@ -183,21 +166,26 @@
   static IFX_Edit* NewEdit();
   static void DelEdit(IFX_Edit* pEdit);
 
-  // set a IFX_Edit_FontMap pointer implemented by user.
-  virtual void SetFontMap(IFX_Edit_FontMap* pFontMap) = 0;
+  // set a IPVT_FontMap pointer implemented by user.
+  virtual void SetFontMap(IPVT_FontMap* pFontMap) = 0;
+
   // if user don't like to use FontMap, implement VTProvider and set it
   // directly.
-  virtual void SetVTProvider(IPDF_VariableText::Provider* pProvider) = 0;
+  virtual void SetVTProvider(CPDF_VariableText::Provider* pProvider) = 0;
+
   // set a IFX_Edit_Notify pointer implemented by user.
   virtual void SetNotify(IFX_Edit_Notify* pNotify) = 0;
   virtual void SetOprNotify(IFX_Edit_OprNotify* pOprNotify) = 0;
+
   // get a pointer allocated by CPDF_Edit, by this pointer, user can iterate the
   // contents of edit, but don't need to release.
   virtual IFX_Edit_Iterator* GetIterator() = 0;
+
   // get a VT pointer relative to this edit.
-  virtual IPDF_VariableText* GetVariableText() = 0;
-  // get the IFX_Edit_FontMap pointer set by user.
-  virtual IFX_Edit_FontMap* GetFontMap() = 0;
+  virtual CPDF_VariableText* GetVariableText() = 0;
+
+  // get the IPVT_FontMap pointer set by user.
+  virtual IPVT_FontMap* GetFontMap() = 0;
 
   // initialize the edit.
   virtual void Initialize() = 0;
@@ -205,106 +193,148 @@
   // set the bounding box of the text area.
   virtual void SetPlateRect(const CFX_FloatRect& rect,
                             FX_BOOL bPaint = TRUE) = 0;
+
   // set the scroll origin
   virtual void SetScrollPos(const CFX_FloatPoint& point) = 0;
 
   // set the horizontal text alignment in text box, nFormat (0:left 1:middle
   // 2:right).
   virtual void SetAlignmentH(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) = 0;
+
   // set the vertical text alignment in text box, nFormat (0:top 1:center
   // 2:bottom).
   virtual void SetAlignmentV(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) = 0;
+
   // if the text is shown in secret , set a character for substitute.
   virtual void SetPasswordChar(uint16_t wSubWord = '*',
                                FX_BOOL bPaint = TRUE) = 0;
+
   // set the maximal count of words of the text.
   virtual void SetLimitChar(int32_t nLimitChar = 0, FX_BOOL bPaint = TRUE) = 0;
+
   // if set the count of charArray , then all words is shown in equal space.
   virtual void SetCharArray(int32_t nCharArray = 0, FX_BOOL bPaint = TRUE) = 0;
+
   // set the space of two characters.
   virtual void SetCharSpace(FX_FLOAT fCharSpace = 0.0f,
                             FX_BOOL bPaint = TRUE) = 0;
+
   // set the horizontal scale of all characters.
   virtual void SetHorzScale(int32_t nHorzScale = 100,
                             FX_BOOL bPaint = TRUE) = 0;
+
   // set the leading of all lines
   virtual void SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint = TRUE) = 0;
+
   // if set, CRLF is allowed.
   virtual void SetMultiLine(FX_BOOL bMultiLine = TRUE,
                             FX_BOOL bPaint = TRUE) = 0;
+
   // if set, all words auto fit the width of the bounding box.
   virtual void SetAutoReturn(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) = 0;
+
   // if set, a font size is calculated to full fit the bounding box.
   virtual void SetAutoFontSize(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) = 0;
+
   // is set, the text is allowed to scroll.
   virtual void SetAutoScroll(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) = 0;
+
   // set the font size of all words.
   virtual void SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint = TRUE) = 0;
+
   // the text is allowed to auto-scroll, allow the text overflow?
   virtual void SetTextOverflow(FX_BOOL bAllowed = FALSE,
                                FX_BOOL bPaint = TRUE) = 0;
 
   // query if the edit is richedit.
   virtual FX_BOOL IsRichText() const = 0;
+
   // set the edit is richedit.
   virtual void SetRichText(FX_BOOL bRichText = TRUE, FX_BOOL bPaint = TRUE) = 0;
+
   // set the fontsize of selected text.
   virtual FX_BOOL SetRichFontSize(FX_FLOAT fFontSize) = 0;
+
   // set the fontindex of selected text, user can change the font of selected
   // text.
   virtual FX_BOOL SetRichFontIndex(int32_t nFontIndex) = 0;
+
   // set the textcolor of selected text.
   virtual FX_BOOL SetRichTextColor(FX_COLORREF dwColor) = 0;
+
   // set the text script type of selected text. (0:normal 1:superscript
   // 2:subscript)
-  virtual FX_BOOL SetRichTextScript(int32_t nScriptType) = 0;
+  virtual FX_BOOL SetRichTextScript(
+      CPDF_VariableText::ScriptType nScriptType) = 0;
+
   // set the bold font style of selected text.
   virtual FX_BOOL SetRichTextBold(FX_BOOL bBold = TRUE) = 0;
+
   // set the italic font style of selected text.
   virtual FX_BOOL SetRichTextItalic(FX_BOOL bItalic = TRUE) = 0;
+
   // set the underline style of selected text.
   virtual FX_BOOL SetRichTextUnderline(FX_BOOL bUnderline = TRUE) = 0;
+
   // set the crossout style of selected text.
   virtual FX_BOOL SetRichTextCrossout(FX_BOOL bCrossout = TRUE) = 0;
+
   // set the charspace of selected text, in user coordinate.
   virtual FX_BOOL SetRichTextCharSpace(FX_FLOAT fCharSpace) = 0;
+
   // set the horizontal scale of selected text, default value is 100.
   virtual FX_BOOL SetRichTextHorzScale(int32_t nHorzScale = 100) = 0;
+
   // set the leading of selected section, in user coordinate.
   virtual FX_BOOL SetRichTextLineLeading(FX_FLOAT fLineLeading) = 0;
+
   // set the indent of selected section, in user coordinate.
   virtual FX_BOOL SetRichTextLineIndent(FX_FLOAT fLineIndent) = 0;
+
   // set the alignment of selected section, nAlignment(0:left 1:middle 2:right)
   virtual FX_BOOL SetRichTextAlignment(int32_t nAlignment) = 0;
 
   // set the selected range of text.
   // if nStartChar == 0 and nEndChar == -1, select all the text.
   virtual void SetSel(int32_t nStartChar, int32_t nEndChar) = 0;
+
   // get the selected range of text.
   virtual void GetSel(int32_t& nStartChar, int32_t& nEndChar) const = 0;
+
   // select all the text.
   virtual void SelectAll() = 0;
+
   // set text is not selected.
   virtual void SelectNone() = 0;
+
   // get the caret position.
   virtual int32_t GetCaret() const = 0;
   virtual CPVT_WordPlace GetCaretWordPlace() const = 0;
+
   // get the string of selected text.
   virtual CFX_WideString GetSelText() const = 0;
+
   // get the text conent
   virtual CFX_WideString GetText() const = 0;
+
   // query if any text is selected.
   virtual FX_BOOL IsSelected() const = 0;
+
   // get the scroll origin
   virtual CFX_FloatPoint GetScrollPos() const = 0;
+
   // get the bounding box of the text area.
   virtual CFX_FloatRect GetPlateRect() const = 0;
+
   // get the fact area of the text.
   virtual CFX_FloatRect GetContentRect() const = 0;
+
   // get the visible word range
   virtual CPVT_WordRange GetVisibleWordRange() const = 0;
+
   // get the whole word range
   virtual CPVT_WordRange GetWholeWordRange() const = 0;
+
   // get the word range of select text
   virtual CPVT_WordRange GetSelectWordRange() const = 0;
 
@@ -313,20 +343,27 @@
   virtual void OnMouseDown(const CFX_FloatPoint& point,
                            FX_BOOL bShift,
                            FX_BOOL bCtrl) = 0;
+
   // send the mousemove message to edit when mouse down is TRUE.
   virtual void OnMouseMove(const CFX_FloatPoint& point,
                            FX_BOOL bShift,
                            FX_BOOL bCtrl) = 0;
+
   // send the UP key message to edit.
   virtual void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
+
   // send the DOWN key message to edit.
   virtual void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
+
   // send the LEFT key message to edit.
   virtual void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
+
   // send the RIGHT key message to edit.
   virtual void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
+
   // send the HOME key message to edit.
   virtual void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
+
   // send the END key message to edit.
   virtual void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
 
@@ -335,29 +372,37 @@
                        int32_t charset = DEFAULT_CHARSET,
                        const CPVT_SecProps* pSecProps = NULL,
                        const CPVT_WordProps* pWordProps = NULL) = 0;
+
   // insert a word into the edit.
   virtual FX_BOOL InsertWord(uint16_t word,
                              int32_t charset = DEFAULT_CHARSET,
                              const CPVT_WordProps* pWordProps = NULL) = 0;
+
   // insert a return into the edit.
   virtual FX_BOOL InsertReturn(const CPVT_SecProps* pSecProps = NULL,
                                const CPVT_WordProps* pWordProps = NULL) = 0;
+
   // insert text into the edit.
   virtual FX_BOOL InsertText(const FX_WCHAR* text,
                              int32_t charset = DEFAULT_CHARSET,
                              const CPVT_SecProps* pSecProps = NULL,
                              const CPVT_WordProps* pWordProps = NULL) = 0;
+
   // do backspace operation.
   virtual FX_BOOL Backspace() = 0;
+
   // do delete operation.
   virtual FX_BOOL Delete() = 0;
+
   // delete the selected text.
   virtual FX_BOOL Clear() = 0;
 
   // do Redo operation.
   virtual FX_BOOL Redo() = 0;
+
   // do Undo operation.
   virtual FX_BOOL Undo() = 0;
+
   // move caret
   virtual void SetCaret(int32_t nPos) = 0;
 
@@ -403,22 +448,30 @@
 
   // get the font size of non_rich text or default font size of richtext.
   virtual FX_FLOAT GetFontSize() const = 0;
+
   // get the mask character.
   virtual uint16_t GetPasswordChar() const = 0;
+
   // get the count of charArray
   virtual int32_t GetCharArray() const = 0;
+
   // get the horizontal scale of all characters
   virtual int32_t GetHorzScale() const = 0;
+
   // get the space of two characters
   virtual FX_FLOAT GetCharSpace() const = 0;
+
   // get the latin words of specified range
   virtual CFX_WideString GetRangeText(const CPVT_WordRange& range) const = 0;
+
   // is the text full in bounding box
   virtual FX_BOOL IsTextFull() const = 0;
   virtual FX_BOOL CanUndo() const = 0;
   virtual FX_BOOL CanRedo() const = 0;
+
   // if the content is changed after settext?
   virtual FX_BOOL IsModified() const = 0;
+
   // get the total words in edit
   virtual int32_t GetTotalWords() const = 0;
 
@@ -512,7 +565,7 @@
   static IFX_List* NewList();
   static void DelList(IFX_List* pList);
 
-  virtual void SetFontMap(IFX_Edit_FontMap* pFontMap) = 0;
+  virtual void SetFontMap(IPVT_FontMap* pFontMap) = 0;
   virtual void SetNotify(IFX_List_Notify* pNotify) = 0;
 
   virtual void SetPlateRect(const CFX_FloatRect& rect) = 0;
@@ -568,7 +621,7 @@
   virtual ~IFX_List() {}
 };
 
-CFX_ByteString GetPDFWordString(IFX_Edit_FontMap* pFontMap,
+CFX_ByteString GetPDFWordString(IPVT_FontMap* pFontMap,
                                 int32_t nFontIndex,
                                 uint16_t Word,
                                 uint16_t SubWord);
diff --git a/fpdfsdk/include/fxedit/fxet_edit.h b/fpdfsdk/include/fxedit/fxet_edit.h
index a9df992..fb6c917 100644
--- a/fpdfsdk/include/fxedit/fxet_edit.h
+++ b/fpdfsdk/include/fxedit/fxet_edit.h
@@ -7,7 +7,8 @@
 #ifndef FPDFSDK_INCLUDE_FXEDIT_FXET_EDIT_H_
 #define FPDFSDK_INCLUDE_FXEDIT_FXET_EDIT_H_
 
-#include "core/include/fpdfdoc/fpdf_vt.h"
+#include "core/fpdfdoc/include/cpvt_secprops.h"
+#include "core/fpdfdoc/include/cpvt_wordprops.h"
 #include "fpdfsdk/include/fxedit/fx_edit.h"
 
 class CFX_Edit;
@@ -510,17 +511,17 @@
   friend class CFXEU_InsertText;
 
  public:
-  explicit CFX_Edit(IPDF_VariableText* pVT);
+  explicit CFX_Edit(CPDF_VariableText* pVT);
   ~CFX_Edit() override;
 
   // IFX_Edit
-  void SetFontMap(IFX_Edit_FontMap* pFontMap) override;
-  void SetVTProvider(IPDF_VariableText::Provider* pProvider) override;
+  void SetFontMap(IPVT_FontMap* pFontMap) override;
+  void SetVTProvider(CPDF_VariableText::Provider* pProvider) override;
   void SetNotify(IFX_Edit_Notify* pNotify) override;
   void SetOprNotify(IFX_Edit_OprNotify* pOprNotify) override;
   IFX_Edit_Iterator* GetIterator() override;
-  IPDF_VariableText* GetVariableText() override;
-  IFX_Edit_FontMap* GetFontMap() override;
+  CPDF_VariableText* GetVariableText() override;
+  IPVT_FontMap* GetFontMap() override;
   void Initialize() override;
   void SetPlateRect(const CFX_FloatRect& rect, FX_BOOL bPaint = TRUE) override;
   void SetScrollPos(const CFX_FloatPoint& point) override;
@@ -544,7 +545,7 @@
   FX_BOOL SetRichFontSize(FX_FLOAT fFontSize) override;
   FX_BOOL SetRichFontIndex(int32_t nFontIndex) override;
   FX_BOOL SetRichTextColor(FX_COLORREF dwColor) override;
-  FX_BOOL SetRichTextScript(int32_t nScriptType) override;
+  FX_BOOL SetRichTextScript(CPDF_VariableText::ScriptType nScriptType) override;
   FX_BOOL SetRichTextBold(FX_BOOL bBold = TRUE) override;
   FX_BOOL SetRichTextItalic(FX_BOOL bItalic = TRUE) override;
   FX_BOOL SetRichTextUnderline(FX_BOOL bUnderline = TRUE) override;
@@ -725,7 +726,7 @@
   FX_FLOAT GetLineBottom(const CPVT_WordPlace& place) const;
 
  private:
-  IPDF_VariableText* m_pVT;
+  CPDF_VariableText* m_pVT;
   IFX_Edit_Notify* m_pNotify;
   IFX_Edit_OprNotify* m_pOprNotify;
   CFX_Edit_Provider* m_pVTProvide;
@@ -754,7 +755,7 @@
 
 class CFX_Edit_Iterator : public IFX_Edit_Iterator {
  public:
-  CFX_Edit_Iterator(CFX_Edit* pEdit, IPDF_VariableText::Iterator* pVTIterator);
+  CFX_Edit_Iterator(CFX_Edit* pEdit, CPDF_VariableText::Iterator* pVTIterator);
   ~CFX_Edit_Iterator() override;
 
   // IFX_Edit_Iterator
@@ -774,17 +775,17 @@
 
  private:
   CFX_Edit* m_pEdit;
-  IPDF_VariableText::Iterator* m_pVTIterator;
+  CPDF_VariableText::Iterator* m_pVTIterator;
 };
 
-class CFX_Edit_Provider : public IPDF_VariableText::Provider {
+class CFX_Edit_Provider : public CPDF_VariableText::Provider {
  public:
-  explicit CFX_Edit_Provider(IFX_Edit_FontMap* pFontMap);
+  explicit CFX_Edit_Provider(IPVT_FontMap* pFontMap);
   ~CFX_Edit_Provider() override;
 
-  IFX_Edit_FontMap* GetFontMap();
+  IPVT_FontMap* GetFontMap();
 
-  // IPDF_VariableText::Provider:
+  // CPDF_VariableText::Provider:
   int32_t GetCharWidth(int32_t nFontIndex,
                        uint16_t word,
                        int32_t nWordStyle) override;
@@ -797,7 +798,7 @@
   FX_BOOL IsLatinWord(uint16_t word) override;
 
  private:
-  IFX_Edit_FontMap* m_pFontMap;
+  IPVT_FontMap* m_pFontMap;
 };
 
 #endif  // FPDFSDK_INCLUDE_FXEDIT_FXET_EDIT_H_
diff --git a/fpdfsdk/include/fxedit/fxet_list.h b/fpdfsdk/include/fxedit/fxet_list.h
index d86e6ff..0018f13 100644
--- a/fpdfsdk/include/fxedit/fxet_list.h
+++ b/fpdfsdk/include/fxedit/fxet_list.h
@@ -118,7 +118,7 @@
   CFX_ListItem();
   virtual ~CFX_ListItem();
 
-  void SetFontMap(IFX_Edit_FontMap* pFontMap);
+  void SetFontMap(IPVT_FontMap* pFontMap);
   IFX_Edit_Iterator* GetIterator() const;
   IFX_Edit* GetEdit() const;
 
@@ -210,7 +210,7 @@
   ~CFX_List() override;
 
   // IFX_List:
-  void SetFontMap(IFX_Edit_FontMap* pFontMap) override;
+  void SetFontMap(IPVT_FontMap* pFontMap) override;
   void SetFontSize(FX_FLOAT fFontSize) override;
   CFX_FloatRect GetPlateRect() const override;
   CFX_FloatRect GetContentRect() const override;
@@ -240,7 +240,7 @@
  private:
   CLST_ArrayTemplate<CFX_ListItem*> m_aListItems;
   FX_FLOAT m_fFontSize;
-  IFX_Edit_FontMap* m_pFontMap;
+  IPVT_FontMap* m_pFontMap;
   FX_BOOL m_bMultiple;
 };
 
diff --git a/fpdfsdk/pdfwindow/DEPS b/fpdfsdk/pdfwindow/DEPS
index 8e0928c..cf99b35 100644
--- a/fpdfsdk/pdfwindow/DEPS
+++ b/fpdfsdk/pdfwindow/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   '+core/fpdfapi/fpdf_font/include',
+  '+core/fpdfdoc/include',
 ]
diff --git a/fpdfsdk/pdfwindow/PWL_Edit.cpp b/fpdfsdk/pdfwindow/PWL_Edit.cpp
index 64588f2..b5e2093 100644
--- a/fpdfsdk/pdfwindow/PWL_Edit.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Edit.cpp
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+#include "core/fpdfdoc/include/cpvt_word.h"
 #include "core/fxcrt/include/fx_safe_types.h"
 #include "core/fxcrt/include/fx_xml.h"
 #include "core/include/fxge/fx_ge.h"
@@ -811,7 +812,7 @@
     m_pEdit->SetTextOverflow(TRUE);
 
     if (HasFlag(PWS_AUTOFONTSIZE)) {
-      if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
+      if (IPVT_FontMap* pFontMap = GetFontMap()) {
         FX_FLOAT fFontSize = GetCharArrayAutoFontSize(
             pFontMap->GetPDFFont(0), GetClientRect(), nCharArray);
         if (fFontSize > 0.0f) {
@@ -978,7 +979,7 @@
   if (bExit)
     return FALSE;
 
-  if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
+  if (IPVT_FontMap* pFontMap = GetFontMap()) {
     int32_t nOldCharSet = GetCharSet();
     int32_t nNewCharSet = pFontMap->CharSetFromUnicode(nChar, DEFAULT_CHARSET);
     if (nOldCharSet != nNewCharSet) {
diff --git a/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
index fe9dab9..af7e583 100644
--- a/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
+++ b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
@@ -6,6 +6,8 @@
 
 #include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
 
+#include "core/fpdfdoc/include/cpvt_section.h"
+#include "core/fpdfdoc/include/cpvt_word.h"
 #include "fpdfsdk/pdfwindow/PWL_Caret.h"
 #include "fpdfsdk/pdfwindow/PWL_FontMap.h"
 #include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
@@ -466,7 +468,7 @@
     }
   }
 
-  if (IFX_Edit_FontMap* pFontMap = GetFontMap())
+  if (IPVT_FontMap* pFontMap = GetFontMap())
     return pFontMap->GetPDFFont(nFontIndex);
 
   return NULL;
diff --git a/fpdfsdk/pdfwindow/PWL_FontMap.cpp b/fpdfsdk/pdfwindow/PWL_FontMap.cpp
index 3f149e7..42beab7 100644
--- a/fpdfsdk/pdfwindow/PWL_FontMap.cpp
+++ b/fpdfsdk/pdfwindow/PWL_FontMap.cpp
@@ -10,6 +10,7 @@
 #include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
 #include "core/fpdfapi/include/cpdf_modulemgr.h"
+#include "core/fpdfdoc/include/ipvt_fontmap.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
 namespace {
diff --git a/fpdfsdk/pdfwindow/PWL_FontMap.h b/fpdfsdk/pdfwindow/PWL_FontMap.h
index b344e4f..70806eb 100644
--- a/fpdfsdk/pdfwindow/PWL_FontMap.h
+++ b/fpdfsdk/pdfwindow/PWL_FontMap.h
@@ -7,6 +7,7 @@
 #ifndef FPDFSDK_PDFWINDOW_PWL_FONTMAP_H_
 #define FPDFSDK_PDFWINDOW_PWL_FONTMAP_H_
 
+#include "core/fpdfdoc/include/ipvt_fontmap.h"
 #include "fpdfsdk/include/fxedit/fx_edit.h"
 #include "public/fpdf_sysfontinfo.h"
 
@@ -48,12 +49,12 @@
 
 #endif
 
-class CPWL_FontMap : public IFX_Edit_FontMap {
+class CPWL_FontMap : public IPVT_FontMap {
  public:
   CPWL_FontMap(IFX_SystemHandler* pSystemHandler);
   ~CPWL_FontMap() override;
 
-  // IFX_Edit_FontMap
+  // IPVT_FontMap
   CPDF_Font* GetPDFFont(int32_t nFontIndex) override;
   CFX_ByteString GetPDFFontAlias(int32_t nFontIndex) override;
   int32_t GetWordFontIndex(uint16_t word,
diff --git a/fpdfsdk/pdfwindow/PWL_Label.cpp b/fpdfsdk/pdfwindow/PWL_Label.cpp
index 8c5b067..0e9a9f6 100644
--- a/fpdfsdk/pdfwindow/PWL_Label.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Label.cpp
@@ -4,6 +4,7 @@
 
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
+#include "fpdfsdk/include/fxedit/fx_edit.h"
 #include "fpdfsdk/pdfwindow/PWL_Label.h"
 #include "fpdfsdk/pdfwindow/PWL_Utils.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
diff --git a/fpdfsdk/pdfwindow/PWL_Utils.cpp b/fpdfsdk/pdfwindow/PWL_Utils.cpp
index 3622a84..acd362a 100644
--- a/fpdfsdk/pdfwindow/PWL_Utils.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Utils.cpp
@@ -8,7 +8,9 @@
 
 #include <algorithm>
 
+#include "core/fpdfdoc/include/cpvt_word.h"
 #include "core/include/fxge/fx_ge.h"
+#include "fpdfsdk/include/fxedit/fx_edit.h"
 #include "fpdfsdk/pdfwindow/PWL_Icon.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
@@ -575,7 +577,7 @@
 }
 
 CFX_ByteString CPWL_Utils::GetTextAppStream(const CFX_FloatRect& rcBBox,
-                                            IFX_Edit_FontMap* pFontMap,
+                                            IPVT_FontMap* pFontMap,
                                             const CFX_WideString& sText,
                                             int32_t nAlignmentH,
                                             int32_t nAlignmentV,
@@ -613,7 +615,7 @@
 }
 
 CFX_ByteString CPWL_Utils::GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
-                                                  IFX_Edit_FontMap* pFontMap,
+                                                  IPVT_FontMap* pFontMap,
                                                   CPDF_Stream* pIconStream,
                                                   CPDF_IconFit& IconFit,
                                                   const CFX_WideString& sLabel,
diff --git a/fpdfsdk/pdfwindow/PWL_Utils.h b/fpdfsdk/pdfwindow/PWL_Utils.h
index 6917083..76c3c47 100644
--- a/fpdfsdk/pdfwindow/PWL_Utils.h
+++ b/fpdfsdk/pdfwindow/PWL_Utils.h
@@ -7,11 +7,12 @@
 #ifndef FPDFSDK_PDFWINDOW_PWL_UTILS_H_
 #define FPDFSDK_PDFWINDOW_PWL_UTILS_H_
 
-#include "core/include/fpdfdoc/fpdf_vt.h"
-#include "fpdfsdk/include/fxedit/fx_edit.h"
+#include "core/fpdfdoc/include/cpvt_wordrange.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
 class CFX_PathData;
+class IFX_Edit;
+
 struct CPWL_Color;
 
 template <class T>
@@ -153,7 +154,7 @@
                                                const CPWL_Color& color);
 
   static CFX_ByteString GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
-                                               IFX_Edit_FontMap* pFontMap,
+                                               IPVT_FontMap* pFontMap,
                                                CPDF_Stream* pIconStream,
                                                CPDF_IconFit& IconFit,
                                                const CFX_WideString& sLabel,
@@ -182,7 +183,7 @@
       const CFX_FloatPoint& ptOffset,
       const CPVT_WordRange* pRange = NULL);
   static CFX_ByteString GetTextAppStream(const CFX_FloatRect& rcBBox,
-                                         IFX_Edit_FontMap* pFontMap,
+                                         IPVT_FontMap* pFontMap,
                                          const CFX_WideString& sText,
                                          int32_t nAlignmentH,
                                          int32_t nAlignmentV,
diff --git a/fpdfsdk/pdfwindow/PWL_Wnd.cpp b/fpdfsdk/pdfwindow/PWL_Wnd.cpp
index cb0955c..5386517 100644
--- a/fpdfsdk/pdfwindow/PWL_Wnd.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Wnd.cpp
@@ -815,7 +815,7 @@
   return m_sPrivateParam.pProvider;
 }
 
-IFX_Edit_FontMap* CPWL_Wnd::GetFontMap() const {
+IPVT_FontMap* CPWL_Wnd::GetFontMap() const {
   return m_sPrivateParam.pFontMap;
 }
 
diff --git a/fpdfsdk/pdfwindow/PWL_Wnd.h b/fpdfsdk/pdfwindow/PWL_Wnd.h
index d07adba..f05b1e6 100644
--- a/fpdfsdk/pdfwindow/PWL_Wnd.h
+++ b/fpdfsdk/pdfwindow/PWL_Wnd.h
@@ -18,7 +18,7 @@
 class CPWL_Timer;
 class CPWL_TimerHandler;
 class CPWL_Wnd;
-class IFX_Edit_FontMap;
+class IPVT_FontMap;
 class IFX_SystemHandler;
 class IPWL_Provider;
 class IPWL_SpellCheck;
@@ -230,7 +230,7 @@
 
   CFX_FloatRect rcRectWnd;            // required
   IFX_SystemHandler* pSystemHandler;  // required
-  IFX_Edit_FontMap* pFontMap;         // required for text window
+  IPVT_FontMap* pFontMap;             // required for text window
   IPWL_Provider* pProvider;           // required for self coordinate
   IPWL_FocusHandler* pFocusHandler;   // optional
   uint32_t dwFlags;                   // optional
@@ -366,7 +366,7 @@
   FX_BOOL IsReadOnly() const;
   CPWL_ScrollBar* GetVScrollBar() const;
 
-  IFX_Edit_FontMap* GetFontMap() const;
+  IPVT_FontMap* GetFontMap() const;
   IPWL_Provider* GetProvider() const;
   IPWL_FocusHandler* GetFocusHandler() const;
 
diff --git a/pdfium.gyp b/pdfium.gyp
index 281cec3..69aab07 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -221,18 +221,22 @@
       'sources': [
         'core/include/fpdfdoc/fpdf_doc.h',
         'core/include/fpdfdoc/fpdf_tagged.h',
-        'core/include/fpdfdoc/fpdf_vt.h',
+        'core/fpdfdoc/cpdf_variabletext.cpp',
         'core/fpdfdoc/cpvt_color.cpp',
         'core/fpdfdoc/cpvt_color.h',
         'core/fpdfdoc/cpvt_dash.h',
+        'core/fpdfdoc/cpvt_floatrect.h',
         'core/fpdfdoc/cpvt_fontmap.cpp',
         'core/fpdfdoc/cpvt_fontmap.h',
         'core/fpdfdoc/cpvt_generateap.cpp',
         'core/fpdfdoc/cpvt_generateap.h',
-        'core/fpdfdoc/cpvt_provider.h',
+        'core/fpdfdoc/cpvt_lineinfo.h',
+        'core/fpdfdoc/cpvt_sectioninfo.h',
+        'core/fpdfdoc/cpvt_wordinfo.h',
+        'core/fpdfdoc/csection.h',
+        'core/fpdfdoc/ctypeset.h',
         'core/fpdfdoc/doc_action.cpp',
         'core/fpdfdoc/doc_annot.cpp',
-        'core/fpdfdoc/doc_ap.cpp',
         'core/fpdfdoc/doc_basic.cpp',
         'core/fpdfdoc/doc_bookmark.cpp',
         'core/fpdfdoc/doc_form.cpp',
@@ -246,7 +250,14 @@
         'core/fpdfdoc/doc_utils.h',
         'core/fpdfdoc/doc_viewerPreferences.cpp',
         'core/fpdfdoc/doc_vt.cpp',
-        'core/fpdfdoc/doc_vtmodule.cpp',
+        'core/fpdfdoc/include/cpdf_variabletext.h',
+        'core/fpdfdoc/include/cpvt_line.h',
+        'core/fpdfdoc/include/cpvt_secprops.h',
+        'core/fpdfdoc/include/cpvt_section.h',
+        'core/fpdfdoc/include/cpvt_word.h',
+        'core/fpdfdoc/include/cpvt_wordplace.h',
+        'core/fpdfdoc/include/cpvt_wordprops.h',
+        'core/fpdfdoc/include/cpvt_wordrange.h',
         'core/fpdfdoc/ipvt_fontmap.h',
         'core/fpdfdoc/pdf_vt.h',
         'core/fpdfdoc/tagged_int.h',