Splitting fpdfdoc/doc_* part II.

This splits the doc_ocg, doc_vt and doc_basic files into individual class files.

Review-Url: https://codereview.chromium.org/2187073005
diff --git a/BUILD.gn b/BUILD.gn
index 912c06c..4b6e658 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -200,6 +200,8 @@
 
 static_library("fpdfdoc") {
   sources = [
+    "core/fpdfdoc/cline.cpp",
+    "core/fpdfdoc/cline.h",
     "core/fpdfdoc/clines.cpp",
     "core/fpdfdoc/clines.h",
     "core/fpdfdoc/cpdf_aaction.cpp",
@@ -210,13 +212,19 @@
     "core/fpdfdoc/cpdf_apsettings.h",
     "core/fpdfdoc/cpdf_bookmark.cpp",
     "core/fpdfdoc/cpdf_bookmarktree.cpp",
+    "core/fpdfdoc/cpdf_dest.cpp",
     "core/fpdfdoc/cpdf_docjsactions.cpp",
+    "core/fpdfdoc/cpdf_filespec.cpp",
     "core/fpdfdoc/cpdf_link.cpp",
     "core/fpdfdoc/cpdf_linklist.cpp",
     "core/fpdfdoc/cpdf_metadata.cpp",
+    "core/fpdfdoc/cpdf_nametree.cpp",
+    "core/fpdfdoc/cpdf_occontext.cpp",
+    "core/fpdfdoc/cpdf_pagelabel.cpp",
     "core/fpdfdoc/cpdf_pagelabel.h",
     "core/fpdfdoc/cpdf_variabletext.cpp",
     "core/fpdfdoc/cpdf_viewerpreferences.cpp",
+    "core/fpdfdoc/cpvt_arraytemplate.h",
     "core/fpdfdoc/cpvt_color.cpp",
     "core/fpdfdoc/cpvt_color.h",
     "core/fpdfdoc/cpvt_dash.h",
@@ -234,14 +242,11 @@
     "core/fpdfdoc/csection.h",
     "core/fpdfdoc/ctypeset.cpp",
     "core/fpdfdoc/ctypeset.h",
-    "core/fpdfdoc/doc_basic.cpp",
     "core/fpdfdoc/doc_form.cpp",
     "core/fpdfdoc/doc_formcontrol.cpp",
     "core/fpdfdoc/doc_formfield.cpp",
-    "core/fpdfdoc/doc_ocg.cpp",
     "core/fpdfdoc/doc_utils.cpp",
     "core/fpdfdoc/doc_utils.h",
-    "core/fpdfdoc/doc_vt.cpp",
     "core/fpdfdoc/include/cpdf_aaction.h",
     "core/fpdfdoc/include/cpdf_action.h",
     "core/fpdfdoc/include/cpdf_actionfields.h",
@@ -272,8 +277,8 @@
     "core/fpdfdoc/include/cpvt_wordprops.h",
     "core/fpdfdoc/include/cpvt_wordrange.h",
     "core/fpdfdoc/include/ipdf_formnotify.h",
+    "core/fpdfdoc/ipdf_formnotify.cpp",
     "core/fpdfdoc/ipvt_fontmap.h",
-    "core/fpdfdoc/pdf_vt.h",
   ]
   configs += [ ":pdfium_core_config" ]
 }
@@ -1542,7 +1547,7 @@
     "core/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp",
     "core/fpdfapi/fpdf_parser/cpdf_syntax_parser_unittest.cpp",
     "core/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp",
-    "core/fpdfdoc/doc_basic_unittest.cpp",
+    "core/fpdfdoc/cpdf_filespec_unittest.cpp",
     "core/fpdftext/fpdf_text_int_unittest.cpp",
     "core/fxcodec/codec/fx_codec_jpx_unittest.cpp",
     "core/fxcrt/cfx_retain_ptr_unittest.cpp",
diff --git a/core/fpdfdoc/doc_vt.cpp b/core/fpdfdoc/cline.cpp
similarity index 69%
rename from core/fpdfdoc/doc_vt.cpp
rename to core/fpdfdoc/cline.cpp
index 84d6a1a..2e8477c 100644
--- a/core/fpdfdoc/doc_vt.cpp
+++ b/core/fpdfdoc/cline.cpp
@@ -1,10 +1,10 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// 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/fpdfdoc/pdf_vt.h"
+#include "core/fpdfdoc/cline.h"
 
 CLine::CLine() {}
 
@@ -36,23 +36,3 @@
   return CPVT_WordPlace(place.nSecIndex, place.nLineIndex,
                         place.nWordIndex + 1);
 }
-
-CPDF_EditContainer::CPDF_EditContainer() {}
-
-CPDF_EditContainer::~CPDF_EditContainer() {}
-
-void CPDF_EditContainer::SetPlateRect(const CFX_FloatRect& rect) {
-  m_rcPlate = rect;
-}
-
-const CFX_FloatRect& CPDF_EditContainer::GetPlateRect() const {
-  return m_rcPlate;
-}
-
-void CPDF_EditContainer::SetContentRect(const CPVT_FloatRect& rect) {
-  m_rcContent = rect;
-}
-
-CFX_FloatRect CPDF_EditContainer::GetContentRect() const {
-  return m_rcContent;
-}
diff --git a/core/fpdfdoc/cline.h b/core/fpdfdoc/cline.h
new file mode 100644
index 0000000..a0cdbfd
--- /dev/null
+++ b/core/fpdfdoc/cline.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_CLINE_H_
+#define CORE_FPDFDOC_CLINE_H_
+
+#include "core/fpdfdoc/cpvt_lineinfo.h"
+#include "core/fpdfdoc/include/cpvt_wordplace.h"
+
+class CLine final {
+ public:
+  CLine();
+  ~CLine();
+
+  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 LinePlace;
+  CPVT_LineInfo m_LineInfo;
+};
+
+#endif  // CORE_FPDFDOC_CLINE_H_
diff --git a/core/fpdfdoc/clines.cpp b/core/fpdfdoc/clines.cpp
index b117310..1e425ea 100644
--- a/core/fpdfdoc/clines.cpp
+++ b/core/fpdfdoc/clines.cpp
@@ -6,6 +6,8 @@
 
 #include "core/fpdfdoc/clines.h"
 
+#include "core/fpdfdoc/cline.h"
+
 CLines::CLines() : m_nTotal(0) {}
 
 CLines::~CLines() {
diff --git a/core/fpdfdoc/clines.h b/core/fpdfdoc/clines.h
index 9d71d3f..b4db0e3 100644
--- a/core/fpdfdoc/clines.h
+++ b/core/fpdfdoc/clines.h
@@ -7,7 +7,12 @@
 #ifndef CORE_FPDFDOC_CLINES_H_
 #define CORE_FPDFDOC_CLINES_H_
 
-#include "core/fpdfdoc/pdf_vt.h"
+#include <stdint.h>
+
+#include "core/fpdfdoc/cpvt_arraytemplate.h"
+#include "core/fpdfdoc/cpvt_lineinfo.h"
+
+class CLine;
 
 class CLines final {
  public:
diff --git a/core/fpdfdoc/cpdf_dest.cpp b/core/fpdfdoc/cpdf_dest.cpp
new file mode 100644
index 0000000..27626a3
--- /dev/null
+++ b/core/fpdfdoc/cpdf_dest.cpp
@@ -0,0 +1,74 @@
+// 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/fpdfdoc/include/cpdf_dest.h"
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+
+namespace {
+
+const FX_CHAR* const g_sZoomModes[] = {"XYZ",  "Fit",   "FitH",  "FitV", "FitR",
+                                       "FitB", "FitBH", "FitBV", nullptr};
+
+}  // namespace
+
+int CPDF_Dest::GetPageIndex(CPDF_Document* pDoc) {
+  CPDF_Array* pArray = ToArray(m_pObj);
+  if (!pArray)
+    return 0;
+
+  CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
+  if (!pPage)
+    return 0;
+  if (pPage->IsNumber())
+    return pPage->GetInteger();
+  if (!pPage->IsDictionary())
+    return 0;
+  return pDoc->GetPageIndex(pPage->GetObjNum());
+}
+
+uint32_t CPDF_Dest::GetPageObjNum() {
+  CPDF_Array* pArray = ToArray(m_pObj);
+  if (!pArray)
+    return 0;
+
+  CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
+  if (!pPage)
+    return 0;
+  if (pPage->IsNumber())
+    return pPage->GetInteger();
+  if (pPage->IsDictionary())
+    return pPage->GetObjNum();
+  return 0;
+}
+
+int CPDF_Dest::GetZoomMode() {
+  CPDF_Array* pArray = ToArray(m_pObj);
+  if (!pArray)
+    return 0;
+
+  CPDF_Object* pObj = pArray->GetDirectObjectAt(1);
+  if (!pObj)
+    return 0;
+
+  CFX_ByteString mode = pObj->GetString();
+  for (int i = 0; g_sZoomModes[i]; ++i) {
+    if (mode == g_sZoomModes[i])
+      return i + 1;
+  }
+
+  return 0;
+}
+
+FX_FLOAT CPDF_Dest::GetParam(int index) {
+  CPDF_Array* pArray = ToArray(m_pObj);
+  return pArray ? pArray->GetNumberAt(2 + index) : 0;
+}
+
+CFX_ByteString CPDF_Dest::GetRemoteName() {
+  return m_pObj ? m_pObj->GetString() : CFX_ByteString();
+}
diff --git a/core/fpdfdoc/cpdf_filespec.cpp b/core/fpdfdoc/cpdf_filespec.cpp
new file mode 100644
index 0000000..2084606
--- /dev/null
+++ b/core/fpdfdoc/cpdf_filespec.cpp
@@ -0,0 +1,167 @@
+// 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/fpdfdoc/include/cpdf_filespec.h"
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_object.h"
+#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
+#include "core/fxcrt/include/fx_system.h"
+
+namespace {
+
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \
+    _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+CFX_WideString ChangeSlashToPlatform(const FX_WCHAR* str) {
+  CFX_WideString result;
+  while (*str) {
+    if (*str == '/') {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+      result += ':';
+#else
+      result += '\\';
+#endif
+    } else {
+      result += *str;
+    }
+    str++;
+  }
+  return result;
+}
+
+CFX_WideString ChangeSlashToPDF(const FX_WCHAR* str) {
+  CFX_WideString result;
+  while (*str) {
+    if (*str == '\\' || *str == ':')
+      result += '/';
+    else
+      result += *str;
+
+    str++;
+  }
+  return result;
+}
+#endif  // _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_WINDOWS_
+
+}  // namespace
+
+CFX_WideString CPDF_FileSpec::DecodeFileName(const CFX_WideStringC& filepath) {
+  if (filepath.GetLength() <= 1)
+    return CFX_WideString();
+
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+  if (filepath.Left(sizeof("/Mac") - 1) == CFX_WideStringC(L"/Mac"))
+    return ChangeSlashToPlatform(filepath.c_str() + 1);
+  return ChangeSlashToPlatform(filepath.c_str());
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+
+  if (filepath.GetAt(0) != '/')
+    return ChangeSlashToPlatform(filepath.c_str());
+  if (filepath.GetAt(1) == '/')
+    return ChangeSlashToPlatform(filepath.c_str() + 1);
+  if (filepath.GetAt(2) == '/') {
+    CFX_WideString result;
+    result += filepath.GetAt(1);
+    result += ':';
+    result += ChangeSlashToPlatform(filepath.c_str() + 2);
+    return result;
+  }
+  CFX_WideString result;
+  result += '\\';
+  result += ChangeSlashToPlatform(filepath.c_str());
+  return result;
+#else
+  return CFX_WideString(filepath);
+#endif
+}
+
+bool CPDF_FileSpec::GetFileName(CFX_WideString* csFileName) const {
+  if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
+    *csFileName = pDict->GetUnicodeTextBy("UF");
+    if (csFileName->IsEmpty()) {
+      *csFileName =
+          CFX_WideString::FromLocal(pDict->GetStringBy("F").AsStringC());
+    }
+    if (pDict->GetStringBy("FS") == "URL")
+      return true;
+    if (csFileName->IsEmpty()) {
+      if (pDict->KeyExist("DOS")) {
+        *csFileName =
+            CFX_WideString::FromLocal(pDict->GetStringBy("DOS").AsStringC());
+      } else if (pDict->KeyExist("Mac")) {
+        *csFileName =
+            CFX_WideString::FromLocal(pDict->GetStringBy("Mac").AsStringC());
+      } else if (pDict->KeyExist("Unix")) {
+        *csFileName =
+            CFX_WideString::FromLocal(pDict->GetStringBy("Unix").AsStringC());
+      } else {
+        return false;
+      }
+    }
+  } else if (m_pObj->IsString()) {
+    *csFileName = CFX_WideString::FromLocal(m_pObj->GetString().AsStringC());
+  } else {
+    return false;
+  }
+  *csFileName = DecodeFileName(csFileName->AsStringC());
+  return true;
+}
+
+CPDF_FileSpec::CPDF_FileSpec() {
+  m_pObj = new CPDF_Dictionary;
+  m_pObj->AsDictionary()->SetAtName("Type", "Filespec");
+}
+
+CFX_WideString CPDF_FileSpec::EncodeFileName(const CFX_WideStringC& filepath) {
+  if (filepath.GetLength() <= 1)
+    return CFX_WideString();
+
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+  if (filepath.GetAt(1) == ':') {
+    CFX_WideString result;
+    result = '/';
+    result += filepath.GetAt(0);
+    if (filepath.GetAt(2) != '\\')
+      result += '/';
+
+    result += ChangeSlashToPDF(filepath.c_str() + 2);
+    return result;
+  }
+  if (filepath.GetAt(0) == '\\' && filepath.GetAt(1) == '\\')
+    return ChangeSlashToPDF(filepath.c_str() + 1);
+
+  if (filepath.GetAt(0) == '\\') {
+    CFX_WideString result;
+    result = '/';
+    result += ChangeSlashToPDF(filepath.c_str());
+    return result;
+  }
+  return ChangeSlashToPDF(filepath.c_str());
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+  if (filepath.Left(sizeof("Mac") - 1) == FX_WSTRC(L"Mac")) {
+    CFX_WideString result;
+    result = '/';
+    result += ChangeSlashToPDF(filepath.c_str());
+    return result;
+  }
+  return ChangeSlashToPDF(filepath.c_str());
+#else
+  return CFX_WideString(filepath);
+#endif
+}
+
+void CPDF_FileSpec::SetFileName(const CFX_WideStringC& wsFileName) {
+  if (!m_pObj)
+    return;
+
+  CFX_WideString wsStr = EncodeFileName(wsFileName);
+  if (m_pObj->IsString()) {
+    m_pObj->SetString(CFX_ByteString::FromUnicode(wsStr));
+  } else if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
+    pDict->SetAtString("F", CFX_ByteString::FromUnicode(wsStr));
+    pDict->SetAtString("UF", PDF_EncodeText(wsStr));
+  }
+}
diff --git a/core/fpdfdoc/doc_basic_unittest.cpp b/core/fpdfdoc/cpdf_filespec_unittest.cpp
similarity index 97%
rename from core/fpdfdoc/doc_basic_unittest.cpp
rename to core/fpdfdoc/cpdf_filespec_unittest.cpp
index 23e8838..0843f30 100644
--- a/core/fpdfdoc/doc_basic_unittest.cpp
+++ b/core/fpdfdoc/cpdf_filespec_unittest.cpp
@@ -19,7 +19,7 @@
     std::unique_ptr<CPDF_Dictionary, ReleaseDeleter<CPDF_Dictionary>>;
 }
 
-TEST(doc_basic_filespec, EncodeDecodeFileName) {
+TEST(cpdf_filespec, EncodeDecodeFileName) {
   std::vector<pdfium::NullTermWstrFuncTestData> test_data = {
     // Empty src string.
     {L"", L""},
@@ -59,7 +59,7 @@
   }
 }
 
-TEST(doc_basic_filespec, GetFileName) {
+TEST(cpdf_filespec, GetFileName) {
   {
     // String object.
     pdfium::NullTermWstrFuncTestData test_data = {
@@ -129,7 +129,7 @@
   }
 }
 
-TEST(doc_basic_filespec, SetFileName) {
+TEST(cpdf_filespec, SetFileName) {
   pdfium::NullTermWstrFuncTestData test_data = {
 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
     L"C:\\docs\\test.pdf",
diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp
new file mode 100644
index 0000000..e046b6b
--- /dev/null
+++ b/core/fpdfdoc/cpdf_nametree.cpp
@@ -0,0 +1,198 @@
+// 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/fpdfdoc/include/cpdf_nametree.h"
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+
+namespace {
+
+const int nMaxRecursion = 32;
+
+CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode,
+                            const CFX_ByteString& csName,
+                            size_t& nIndex,
+                            CPDF_Array** ppFind,
+                            int nLevel = 0) {
+  if (nLevel > nMaxRecursion)
+    return nullptr;
+
+  CPDF_Array* pLimits = pNode->GetArrayBy("Limits");
+  if (pLimits) {
+    CFX_ByteString csLeft = pLimits->GetStringAt(0);
+    CFX_ByteString csRight = pLimits->GetStringAt(1);
+    if (csLeft.Compare(csRight.AsStringC()) > 0) {
+      CFX_ByteString csTmp = csRight;
+      csRight = csLeft;
+      csLeft = csTmp;
+    }
+    if (csName.Compare(csLeft.AsStringC()) < 0 ||
+        csName.Compare(csRight.AsStringC()) > 0) {
+      return nullptr;
+    }
+  }
+
+  CPDF_Array* pNames = pNode->GetArrayBy("Names");
+  if (pNames) {
+    size_t dwCount = pNames->GetCount() / 2;
+    for (size_t i = 0; i < dwCount; i++) {
+      CFX_ByteString csValue = pNames->GetStringAt(i * 2);
+      int32_t iCompare = csValue.Compare(csName.AsStringC());
+      if (iCompare <= 0) {
+        if (ppFind)
+          *ppFind = pNames;
+        if (iCompare < 0)
+          continue;
+      } else {
+        break;
+      }
+      nIndex += i;
+      return pNames->GetDirectObjectAt(i * 2 + 1);
+    }
+    nIndex += dwCount;
+    return nullptr;
+  }
+
+  CPDF_Array* pKids = pNode->GetArrayBy("Kids");
+  if (!pKids)
+    return nullptr;
+
+  for (size_t i = 0; i < pKids->GetCount(); i++) {
+    CPDF_Dictionary* pKid = pKids->GetDictAt(i);
+    if (!pKid)
+      continue;
+
+    CPDF_Object* pFound =
+        SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1);
+    if (pFound)
+      return pFound;
+  }
+  return nullptr;
+}
+
+CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode,
+                            size_t nIndex,
+                            size_t& nCurIndex,
+                            CFX_ByteString& csName,
+                            CPDF_Array** ppFind,
+                            int nLevel = 0) {
+  if (nLevel > nMaxRecursion)
+    return nullptr;
+
+  CPDF_Array* pNames = pNode->GetArrayBy("Names");
+  if (pNames) {
+    size_t nCount = pNames->GetCount() / 2;
+    if (nIndex >= nCurIndex + nCount) {
+      nCurIndex += nCount;
+      return nullptr;
+    }
+    if (ppFind)
+      *ppFind = pNames;
+    csName = pNames->GetStringAt((nIndex - nCurIndex) * 2);
+    return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1);
+  }
+  CPDF_Array* pKids = pNode->GetArrayBy("Kids");
+  if (!pKids)
+    return nullptr;
+  for (size_t i = 0; i < pKids->GetCount(); i++) {
+    CPDF_Dictionary* pKid = pKids->GetDictAt(i);
+    if (!pKid)
+      continue;
+    CPDF_Object* pFound =
+        SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1);
+    if (pFound)
+      return pFound;
+  }
+  return nullptr;
+}
+
+size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) {
+  if (nLevel > nMaxRecursion)
+    return 0;
+
+  CPDF_Array* pNames = pNode->GetArrayBy("Names");
+  if (pNames)
+    return pNames->GetCount() / 2;
+
+  CPDF_Array* pKids = pNode->GetArrayBy("Kids");
+  if (!pKids)
+    return 0;
+
+  size_t nCount = 0;
+  for (size_t i = 0; i < pKids->GetCount(); i++) {
+    CPDF_Dictionary* pKid = pKids->GetDictAt(i);
+    if (!pKid)
+      continue;
+
+    nCount += CountNames(pKid, nLevel + 1);
+  }
+  return nCount;
+}
+
+}  // namespace
+
+CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc,
+                             const CFX_ByteString& category)
+    : m_pRoot(nullptr) {
+  CPDF_Dictionary* pRoot = pDoc->GetRoot();
+  if (!pRoot)
+    return;
+
+  CPDF_Dictionary* pNames = pRoot->GetDictBy("Names");
+  if (!pNames)
+    return;
+
+  m_pRoot = pNames->GetDictBy(category);
+}
+
+size_t CPDF_NameTree::GetCount() const {
+  return m_pRoot ? ::CountNames(m_pRoot) : 0;
+}
+
+int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const {
+  if (!m_pRoot)
+    return -1;
+
+  size_t nIndex = 0;
+  if (!SearchNameNode(m_pRoot, csName, nIndex, nullptr))
+    return -1;
+  return nIndex;
+}
+
+CPDF_Object* CPDF_NameTree::LookupValue(int nIndex,
+                                        CFX_ByteString& csName) const {
+  if (!m_pRoot)
+    return nullptr;
+  size_t nCurIndex = 0;
+  return SearchNameNode(m_pRoot, nIndex, nCurIndex, csName, nullptr);
+}
+
+CPDF_Object* CPDF_NameTree::LookupValue(const CFX_ByteString& csName) const {
+  if (!m_pRoot)
+    return nullptr;
+  size_t nIndex = 0;
+  return SearchNameNode(m_pRoot, csName, nIndex, nullptr);
+}
+
+CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc,
+                                           const CFX_ByteString& sName) {
+  CPDF_Object* pValue = LookupValue(sName);
+  if (!pValue) {
+    CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictBy("Dests");
+    if (!pDests)
+      return nullptr;
+    pValue = pDests->GetDirectObjectBy(sName);
+  }
+  if (!pValue)
+    return nullptr;
+  if (CPDF_Array* pArray = pValue->AsArray())
+    return pArray;
+  if (CPDF_Dictionary* pDict = pValue->AsDictionary())
+    return pDict->GetArrayBy("D");
+  return nullptr;
+}
diff --git a/core/fpdfdoc/doc_ocg.cpp b/core/fpdfdoc/cpdf_occontext.cpp
similarity index 84%
rename from core/fpdfdoc/doc_ocg.cpp
rename to core/fpdfdoc/cpdf_occontext.cpp
index 50bae65..9206b97 100644
--- a/core/fpdfdoc/doc_ocg.cpp
+++ b/core/fpdfdoc/cpdf_occontext.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// 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.
 
@@ -13,8 +13,7 @@
 
 namespace {
 
-int32_t FPDFDOC_OCG_FindGroup(const CPDF_Array* pArray,
-                              const CPDF_Dictionary* pGroupDict) {
+int32_t FindGroup(const CPDF_Array* pArray, const CPDF_Dictionary* pGroupDict) {
   if (!pArray || !pGroupDict)
     return -1;
 
@@ -25,9 +24,9 @@
   return -1;
 }
 
-bool FPDFDOC_OCG_HasIntent(const CPDF_Dictionary* pDict,
-                           const CFX_ByteStringC& csElement,
-                           const CFX_ByteStringC& csDef) {
+bool HasIntent(const CPDF_Dictionary* pDict,
+               const CFX_ByteStringC& csElement,
+               const CFX_ByteStringC& csDef) {
   CPDF_Object* pIntent = pDict->GetDirectObjectBy("Intent");
   if (!pIntent)
     return csElement == csDef;
@@ -45,8 +44,8 @@
   return bsIntent == "All" || bsIntent == csElement;
 }
 
-CPDF_Dictionary* FPDFDOC_OCG_GetConfig(CPDF_Document* pDoc,
-                                       const CPDF_Dictionary* pOCGDict) {
+CPDF_Dictionary* GetConfig(CPDF_Document* pDoc,
+                           const CPDF_Dictionary* pOCGDict) {
   ASSERT(pOCGDict);
   CPDF_Dictionary* pOCProperties = pDoc->GetRoot()->GetDictBy("OCProperties");
   if (!pOCProperties)
@@ -56,7 +55,7 @@
   if (!pOCGs)
     return nullptr;
 
-  if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0)
+  if (FindGroup(pOCGs, pOCGDict) < 0)
     return nullptr;
 
   CPDF_Dictionary* pConfig = pOCProperties->GetDictBy("D");
@@ -66,13 +65,13 @@
 
   for (size_t i = 0; i < pConfigs->GetCount(); i++) {
     CPDF_Dictionary* pFind = pConfigs->GetDictAt(i);
-    if (pFind && FPDFDOC_OCG_HasIntent(pFind, "View", "View"))
+    if (pFind && HasIntent(pFind, "View", "View"))
       return pFind;
   }
   return pConfig;
 }
 
-CFX_ByteString FPDFDOC_OCG_GetUsageTypeString(CPDF_OCContext::UsageType eType) {
+CFX_ByteString GetUsageTypeString(CPDF_OCContext::UsageType eType) {
   CFX_ByteString csState;
   switch (eType) {
     case CPDF_OCContext::Design:
@@ -98,25 +97,24 @@
   ASSERT(pDoc);
 }
 
-CPDF_OCContext::~CPDF_OCContext() {
-}
+CPDF_OCContext::~CPDF_OCContext() {}
 
 bool CPDF_OCContext::LoadOCGStateFromConfig(
     const CFX_ByteString& csConfig,
     const CPDF_Dictionary* pOCGDict) const {
-  CPDF_Dictionary* pConfig = FPDFDOC_OCG_GetConfig(m_pDocument, pOCGDict);
+  CPDF_Dictionary* pConfig = GetConfig(m_pDocument, pOCGDict);
   if (!pConfig)
     return true;
 
   bool bState = pConfig->GetStringBy("BaseState", "ON") != "OFF";
   CPDF_Array* pArray = pConfig->GetArrayBy("ON");
   if (pArray) {
-    if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0)
+    if (FindGroup(pArray, pOCGDict) >= 0)
       bState = true;
   }
   pArray = pConfig->GetArrayBy("OFF");
   if (pArray) {
-    if (FPDFDOC_OCG_FindGroup(pArray, pOCGDict) >= 0)
+    if (FindGroup(pArray, pOCGDict) >= 0)
       bState = false;
   }
   pArray = pConfig->GetArrayBy("AS");
@@ -136,7 +134,7 @@
     if (!pOCGs)
       continue;
 
-    if (FPDFDOC_OCG_FindGroup(pOCGs, pOCGDict) < 0)
+    if (FindGroup(pOCGs, pOCGDict) < 0)
       continue;
 
     CPDF_Dictionary* pState = pUsage->GetDictBy(csConfig);
@@ -149,24 +147,22 @@
 }
 
 bool CPDF_OCContext::LoadOCGState(const CPDF_Dictionary* pOCGDict) const {
-  if (!FPDFDOC_OCG_HasIntent(pOCGDict, "View", "View"))
+  if (!HasIntent(pOCGDict, "View", "View"))
     return true;
 
-  CFX_ByteString csState = FPDFDOC_OCG_GetUsageTypeString(m_eUsageType);
+  CFX_ByteString csState = GetUsageTypeString(m_eUsageType);
   CPDF_Dictionary* pUsage = pOCGDict->GetDictBy("Usage");
   if (pUsage) {
     CPDF_Dictionary* pState = pUsage->GetDictBy(csState);
     if (pState) {
       CFX_ByteString csFind = csState + "State";
-      if (pState->KeyExist(csFind)) {
+      if (pState->KeyExist(csFind))
         return pState->GetStringBy(csFind) != "OFF";
-      }
     }
     if (csState != "View") {
       pState = pUsage->GetDictBy("View");
-      if (pState && pState->KeyExist("ViewState")) {
+      if (pState && pState->KeyExist("ViewState"))
         return pState->GetStringBy("ViewState") != "OFF";
-      }
     }
   }
   return LoadOCGStateFromConfig(csState, pOCGDict);
diff --git a/core/fpdfdoc/cpdf_pagelabel.cpp b/core/fpdfdoc/cpdf_pagelabel.cpp
new file mode 100644
index 0000000..886e844
--- /dev/null
+++ b/core/fpdfdoc/cpdf_pagelabel.cpp
@@ -0,0 +1,136 @@
+// 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/fpdfdoc/cpdf_pagelabel.h"
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
+#include "core/fpdfdoc/doc_utils.h"
+
+namespace {
+
+CFX_WideString MakeRoman(int num) {
+  const int kArabic[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
+  const CFX_WideString kRoman[] = {L"m",  L"cm", L"d",  L"cd", L"c",
+                                   L"xc", L"l",  L"xl", L"x",  L"ix",
+                                   L"v",  L"iv", L"i"};
+  const int kMaxNum = 1000000;
+
+  num %= kMaxNum;
+  int i = 0;
+  CFX_WideString wsRomanNumber;
+  while (num > 0) {
+    while (num >= kArabic[i]) {
+      num = num - kArabic[i];
+      wsRomanNumber += kRoman[i];
+    }
+    i = i + 1;
+  }
+  return wsRomanNumber;
+}
+
+CFX_WideString MakeLetters(int num) {
+  if (num == 0)
+    return CFX_WideString();
+
+  CFX_WideString wsLetters;
+  const int nMaxCount = 1000;
+  const int nLetterCount = 26;
+  --num;
+
+  int count = num / nLetterCount + 1;
+  count %= nMaxCount;
+  FX_WCHAR ch = L'a' + num % nLetterCount;
+  for (int i = 0; i < count; i++)
+    wsLetters += ch;
+  return wsLetters;
+}
+
+CFX_WideString GetLabelNumPortion(int num, const CFX_ByteString& bsStyle) {
+  CFX_WideString wsNumPortion;
+  if (bsStyle.IsEmpty())
+    return wsNumPortion;
+  if (bsStyle == "D") {
+    wsNumPortion.Format(L"%d", num);
+  } else if (bsStyle == "R") {
+    wsNumPortion = MakeRoman(num);
+    wsNumPortion.MakeUpper();
+  } else if (bsStyle == "r") {
+    wsNumPortion = MakeRoman(num);
+  } else if (bsStyle == "A") {
+    wsNumPortion = MakeLetters(num);
+    wsNumPortion.MakeUpper();
+  } else if (bsStyle == "a") {
+    wsNumPortion = MakeLetters(num);
+  }
+  return wsNumPortion;
+}
+
+}  // namespace
+
+CPDF_PageLabel::CPDF_PageLabel(CPDF_Document* pDocument)
+    : m_pDocument(pDocument) {}
+
+CFX_WideString CPDF_PageLabel::GetLabel(int nPage) const {
+  CFX_WideString wsLabel;
+  if (!m_pDocument)
+    return wsLabel;
+
+  CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
+  if (!pPDFRoot)
+    return wsLabel;
+
+  CPDF_Dictionary* pLabels = pPDFRoot->GetDictBy("PageLabels");
+  CPDF_NumberTree numberTree(pLabels);
+  CPDF_Object* pValue = nullptr;
+  int n = nPage;
+  while (n >= 0) {
+    pValue = numberTree.LookupValue(n);
+    if (pValue)
+      break;
+    n--;
+  }
+
+  if (pValue) {
+    pValue = pValue->GetDirect();
+    if (CPDF_Dictionary* pLabel = pValue->AsDictionary()) {
+      if (pLabel->KeyExist("P"))
+        wsLabel += pLabel->GetUnicodeTextBy("P");
+
+      CFX_ByteString bsNumberingStyle = pLabel->GetStringBy("S", "");
+      int nLabelNum = nPage - n + pLabel->GetIntegerBy("St", 1);
+      CFX_WideString wsNumPortion =
+          GetLabelNumPortion(nLabelNum, bsNumberingStyle);
+      wsLabel += wsNumPortion;
+      return wsLabel;
+    }
+  }
+  wsLabel.Format(L"%d", nPage + 1);
+  return wsLabel;
+}
+
+int32_t CPDF_PageLabel::GetPageByLabel(const CFX_ByteStringC& bsLabel) const {
+  if (!m_pDocument)
+    return -1;
+
+  CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
+  if (!pPDFRoot)
+    return -1;
+
+  int nPages = m_pDocument->GetPageCount();
+  for (int i = 0; i < nPages; i++) {
+    if (PDF_EncodeText(GetLabel(i)).Compare(bsLabel))
+      return i;
+  }
+
+  int nPage = FXSYS_atoi(CFX_ByteString(bsLabel).c_str());  // NUL terminate.
+  return nPage > 0 && nPage <= nPages ? nPage : -1;
+}
+
+int32_t CPDF_PageLabel::GetPageByLabel(const CFX_WideStringC& wsLabel) const {
+  return GetPageByLabel(PDF_EncodeText(wsLabel.c_str()).AsStringC());
+}
diff --git a/core/fpdfdoc/cpdf_variabletext.cpp b/core/fpdfdoc/cpdf_variabletext.cpp
index a4f9d89..040b7e6 100644
--- a/core/fpdfdoc/cpdf_variabletext.cpp
+++ b/core/fpdfdoc/cpdf_variabletext.cpp
@@ -8,6 +8,7 @@
 
 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
 #include "core/fpdfdoc/cpvt_wordinfo.h"
+#include "core/fpdfdoc/cline.h"
 #include "core/fpdfdoc/csection.h"
 #include "core/fpdfdoc/include/cpvt_section.h"
 #include "core/fpdfdoc/include/cpvt_word.h"
@@ -756,15 +757,19 @@
 }
 
 void CPDF_VariableText::SetPlateRect(const CFX_FloatRect& rect) {
-  CPDF_EditContainer::SetPlateRect(rect);
+  m_rcPlate = rect;
+}
+
+void CPDF_VariableText::SetContentRect(const CPVT_FloatRect& rect) {
+  m_rcContent = rect;
 }
 
 CFX_FloatRect CPDF_VariableText::GetContentRect() const {
-  return InToOut(CPVT_FloatRect(CPDF_EditContainer::GetContentRect()));
+  return InToOut(CPVT_FloatRect(m_rcContent));
 }
 
 const CFX_FloatRect& CPDF_VariableText::GetPlateRect() const {
-  return CPDF_EditContainer::GetPlateRect();
+  return m_rcPlate;
 }
 
 FX_FLOAT CPDF_VariableText::GetWordFontSize(const CPVT_WordInfo& WordInfo) {
@@ -1103,3 +1108,39 @@
 void CPDF_VariableText::SetProvider(CPDF_VariableText::Provider* pProvider) {
   m_pVTProvider = pProvider;
 }
+
+CFX_SizeF CPDF_VariableText::GetPlateSize() const {
+  return CFX_SizeF(GetPlateWidth(), GetPlateHeight());
+}
+
+CFX_FloatPoint CPDF_VariableText::GetBTPoint() const {
+  return CFX_FloatPoint(m_rcPlate.left, m_rcPlate.top);
+}
+
+CFX_FloatPoint CPDF_VariableText::GetETPoint() const {
+  return CFX_FloatPoint(m_rcPlate.right, m_rcPlate.bottom);
+}
+
+CFX_FloatPoint CPDF_VariableText::InToOut(const CFX_FloatPoint& point) const {
+  return CFX_FloatPoint(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
+}
+
+CFX_FloatPoint CPDF_VariableText::OutToIn(const CFX_FloatPoint& point) const {
+  return CFX_FloatPoint(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
+}
+
+CFX_FloatRect CPDF_VariableText::InToOut(const CPVT_FloatRect& rect) const {
+  CFX_FloatPoint ptLeftTop = InToOut(CFX_FloatPoint(rect.left, rect.top));
+  CFX_FloatPoint ptRightBottom =
+      InToOut(CFX_FloatPoint(rect.right, rect.bottom));
+  return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x,
+                       ptLeftTop.y);
+}
+
+CPVT_FloatRect CPDF_VariableText::OutToIn(const CFX_FloatRect& rect) const {
+  CFX_FloatPoint ptLeftTop = OutToIn(CFX_FloatPoint(rect.left, rect.top));
+  CFX_FloatPoint ptRightBottom =
+      OutToIn(CFX_FloatPoint(rect.right, rect.bottom));
+  return CPVT_FloatRect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x,
+                        ptRightBottom.y);
+}
diff --git a/core/fpdfdoc/cpvt_arraytemplate.h b/core/fpdfdoc/cpvt_arraytemplate.h
new file mode 100644
index 0000000..a0f129d
--- /dev/null
+++ b/core/fpdfdoc/cpvt_arraytemplate.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_CPVT_ARRAYTEMPLATE_H_
+#define CORE_FPDFDOC_CPVT_ARRAYTEMPLATE_H_
+
+#include "core/fxcrt/include/fx_basic.h"
+#include "core/fxcrt/include/fx_system.h"
+
+template <class TYPE>
+class CPVT_ArrayTemplate : public CFX_ArrayTemplate<TYPE> {
+ public:
+  bool IsEmpty() { return CFX_ArrayTemplate<TYPE>::GetSize() <= 0; }
+
+  TYPE GetAt(int nIndex) const {
+    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize())
+      return CFX_ArrayTemplate<TYPE>::GetAt(nIndex);
+    return nullptr;
+  }
+
+  void RemoveAt(int nIndex) {
+    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize())
+      CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);
+  }
+};
+
+#endif  // CORE_FPDFDOC_CPVT_ARRAYTEMPLATE_H_
diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp
index 13ef506..78bd780 100644
--- a/core/fpdfdoc/cpvt_generateap.cpp
+++ b/core/fpdfdoc/cpvt_generateap.cpp
@@ -16,7 +16,6 @@
 #include "core/fpdfdoc/cpvt_fontmap.h"
 #include "core/fpdfdoc/include/cpdf_formfield.h"
 #include "core/fpdfdoc/include/cpvt_word.h"
-#include "core/fpdfdoc/pdf_vt.h"
 
 namespace {
 
diff --git a/core/fpdfdoc/csection.cpp b/core/fpdfdoc/csection.cpp
index 0cf08fd..6686c0c 100644
--- a/core/fpdfdoc/csection.cpp
+++ b/core/fpdfdoc/csection.cpp
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 
+#include "core/fpdfdoc/cline.h"
 #include "core/fpdfdoc/cpvt_wordinfo.h"
 
 CSection::CSection(CPDF_VariableText* pVT) : m_pVT(pVT) {}
diff --git a/core/fpdfdoc/ctypeset.cpp b/core/fpdfdoc/ctypeset.cpp
index 57d3733..082cef8 100644
--- a/core/fpdfdoc/ctypeset.cpp
+++ b/core/fpdfdoc/ctypeset.cpp
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 
+#include "core/fpdfdoc/cline.h"
 #include "core/fpdfdoc/csection.h"
 #include "core/fpdfdoc/cpvt_wordinfo.h"
 
diff --git a/core/fpdfdoc/doc_basic.cpp b/core/fpdfdoc/doc_basic.cpp
deleted file mode 100644
index 97acf23..0000000
--- a/core/fpdfdoc/doc_basic.cpp
+++ /dev/null
@@ -1,568 +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_parser/include/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
-#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
-#include "core/fpdfdoc/doc_utils.h"
-#include "core/fpdfdoc/cpdf_pagelabel.h"
-#include "core/fpdfdoc/include/cpdf_filespec.h"
-#include "core/fpdfdoc/include/cpdf_nametree.h"
-#include "core/fpdfdoc/include/ipdf_formnotify.h"
-
-namespace {
-
-const int nMaxRecursion = 32;
-const FX_CHAR* const g_sZoomModes[] = {"XYZ",  "Fit",   "FitH",  "FitV", "FitR",
-                                       "FitB", "FitBH", "FitBV", nullptr};
-
-}  // namespace
-
-int CPDF_Dest::GetPageIndex(CPDF_Document* pDoc) {
-  CPDF_Array* pArray = ToArray(m_pObj);
-  if (!pArray)
-    return 0;
-
-  CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
-  if (!pPage)
-    return 0;
-  if (pPage->IsNumber())
-    return pPage->GetInteger();
-  if (!pPage->IsDictionary())
-    return 0;
-  return pDoc->GetPageIndex(pPage->GetObjNum());
-}
-
-uint32_t CPDF_Dest::GetPageObjNum() {
-  CPDF_Array* pArray = ToArray(m_pObj);
-  if (!pArray)
-    return 0;
-
-  CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
-  if (!pPage)
-    return 0;
-  if (pPage->IsNumber())
-    return pPage->GetInteger();
-  if (pPage->IsDictionary())
-    return pPage->GetObjNum();
-  return 0;
-}
-
-int CPDF_Dest::GetZoomMode() {
-  CPDF_Array* pArray = ToArray(m_pObj);
-  if (!pArray)
-    return 0;
-
-  CPDF_Object* pObj = pArray->GetDirectObjectAt(1);
-  if (!pObj)
-    return 0;
-
-  CFX_ByteString mode = pObj->GetString();
-  for (int i = 0; g_sZoomModes[i]; ++i) {
-    if (mode == g_sZoomModes[i])
-      return i + 1;
-  }
-
-  return 0;
-}
-
-FX_FLOAT CPDF_Dest::GetParam(int index) {
-  CPDF_Array* pArray = ToArray(m_pObj);
-  return pArray ? pArray->GetNumberAt(2 + index) : 0;
-}
-
-CFX_ByteString CPDF_Dest::GetRemoteName() {
-  return m_pObj ? m_pObj->GetString() : CFX_ByteString();
-}
-
-CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc,
-                             const CFX_ByteString& category)
-    : m_pRoot(nullptr) {
-  CPDF_Dictionary* pRoot = pDoc->GetRoot();
-  if (!pRoot)
-    return;
-
-  CPDF_Dictionary* pNames = pRoot->GetDictBy("Names");
-  if (!pNames)
-    return;
-
-  m_pRoot = pNames->GetDictBy(category);
-}
-
-static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode,
-                                   const CFX_ByteString& csName,
-                                   size_t& nIndex,
-                                   CPDF_Array** ppFind,
-                                   int nLevel = 0) {
-  if (nLevel > nMaxRecursion) {
-    return nullptr;
-  }
-  CPDF_Array* pLimits = pNode->GetArrayBy("Limits");
-  if (pLimits) {
-    CFX_ByteString csLeft = pLimits->GetStringAt(0);
-    CFX_ByteString csRight = pLimits->GetStringAt(1);
-    if (csLeft.Compare(csRight.AsStringC()) > 0) {
-      CFX_ByteString csTmp = csRight;
-      csRight = csLeft;
-      csLeft = csTmp;
-    }
-    if (csName.Compare(csLeft.AsStringC()) < 0 ||
-        csName.Compare(csRight.AsStringC()) > 0) {
-      return nullptr;
-    }
-  }
-  CPDF_Array* pNames = pNode->GetArrayBy("Names");
-  if (pNames) {
-    size_t dwCount = pNames->GetCount() / 2;
-    for (size_t i = 0; i < dwCount; i++) {
-      CFX_ByteString csValue = pNames->GetStringAt(i * 2);
-      int32_t iCompare = csValue.Compare(csName.AsStringC());
-      if (iCompare <= 0) {
-        if (ppFind) {
-          *ppFind = pNames;
-        }
-        if (iCompare < 0) {
-          continue;
-        }
-      } else {
-        break;
-      }
-      nIndex += i;
-      return pNames->GetDirectObjectAt(i * 2 + 1);
-    }
-    nIndex += dwCount;
-    return nullptr;
-  }
-  CPDF_Array* pKids = pNode->GetArrayBy("Kids");
-  if (!pKids) {
-    return nullptr;
-  }
-  for (size_t i = 0; i < pKids->GetCount(); i++) {
-    CPDF_Dictionary* pKid = pKids->GetDictAt(i);
-    if (!pKid) {
-      continue;
-    }
-    CPDF_Object* pFound =
-        SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1);
-    if (pFound) {
-      return pFound;
-    }
-  }
-  return nullptr;
-}
-
-static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode,
-                                   size_t nIndex,
-                                   size_t& nCurIndex,
-                                   CFX_ByteString& csName,
-                                   CPDF_Array** ppFind,
-                                   int nLevel = 0) {
-  if (nLevel > nMaxRecursion)
-    return nullptr;
-
-  CPDF_Array* pNames = pNode->GetArrayBy("Names");
-  if (pNames) {
-    size_t nCount = pNames->GetCount() / 2;
-    if (nIndex >= nCurIndex + nCount) {
-      nCurIndex += nCount;
-      return nullptr;
-    }
-    if (ppFind)
-      *ppFind = pNames;
-    csName = pNames->GetStringAt((nIndex - nCurIndex) * 2);
-    return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1);
-  }
-  CPDF_Array* pKids = pNode->GetArrayBy("Kids");
-  if (!pKids)
-    return nullptr;
-  for (size_t i = 0; i < pKids->GetCount(); i++) {
-    CPDF_Dictionary* pKid = pKids->GetDictAt(i);
-    if (!pKid)
-      continue;
-    CPDF_Object* pFound =
-        SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1);
-    if (pFound)
-      return pFound;
-  }
-  return nullptr;
-}
-
-static size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) {
-  if (nLevel > nMaxRecursion) {
-    return 0;
-  }
-  CPDF_Array* pNames = pNode->GetArrayBy("Names");
-  if (pNames) {
-    return pNames->GetCount() / 2;
-  }
-  CPDF_Array* pKids = pNode->GetArrayBy("Kids");
-  if (!pKids) {
-    return 0;
-  }
-  size_t nCount = 0;
-  for (size_t i = 0; i < pKids->GetCount(); i++) {
-    CPDF_Dictionary* pKid = pKids->GetDictAt(i);
-    if (!pKid) {
-      continue;
-    }
-    nCount += CountNames(pKid, nLevel + 1);
-  }
-  return nCount;
-}
-
-size_t CPDF_NameTree::GetCount() const {
-  if (!m_pRoot) {
-    return 0;
-  }
-  return ::CountNames(m_pRoot);
-}
-
-int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const {
-  if (!m_pRoot) {
-    return -1;
-  }
-  size_t nIndex = 0;
-  if (!SearchNameNode(m_pRoot, csName, nIndex, nullptr)) {
-    return -1;
-  }
-  return nIndex;
-}
-
-CPDF_Object* CPDF_NameTree::LookupValue(int nIndex,
-                                        CFX_ByteString& csName) const {
-  if (!m_pRoot) {
-    return nullptr;
-  }
-  size_t nCurIndex = 0;
-  return SearchNameNode(m_pRoot, nIndex, nCurIndex, csName, nullptr);
-}
-
-CPDF_Object* CPDF_NameTree::LookupValue(const CFX_ByteString& csName) const {
-  if (!m_pRoot) {
-    return nullptr;
-  }
-  size_t nIndex = 0;
-  return SearchNameNode(m_pRoot, csName, nIndex, nullptr);
-}
-
-CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc,
-                                           const CFX_ByteString& sName) {
-  CPDF_Object* pValue = LookupValue(sName);
-  if (!pValue) {
-    CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictBy("Dests");
-    if (!pDests)
-      return nullptr;
-    pValue = pDests->GetDirectObjectBy(sName);
-  }
-  if (!pValue)
-    return nullptr;
-  if (CPDF_Array* pArray = pValue->AsArray())
-    return pArray;
-  if (CPDF_Dictionary* pDict = pValue->AsDictionary())
-    return pDict->GetArrayBy("D");
-  return nullptr;
-}
-
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \
-    _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
-static CFX_WideString ChangeSlashToPlatform(const FX_WCHAR* str) {
-  CFX_WideString result;
-  while (*str) {
-    if (*str == '/') {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-      result += ':';
-#else
-      result += '\\';
-#endif
-    } else {
-      result += *str;
-    }
-    str++;
-  }
-  return result;
-}
-
-static CFX_WideString ChangeSlashToPDF(const FX_WCHAR* str) {
-  CFX_WideString result;
-  while (*str) {
-    if (*str == '\\' || *str == ':') {
-      result += '/';
-    } else {
-      result += *str;
-    }
-    str++;
-  }
-  return result;
-}
-#endif  // _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_WINDOWS_
-
-CFX_WideString CPDF_FileSpec::DecodeFileName(const CFX_WideStringC& filepath) {
-  if (filepath.GetLength() <= 1)
-    return CFX_WideString();
-
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-  if (filepath.Left(sizeof("/Mac") - 1) == CFX_WideStringC(L"/Mac"))
-    return ChangeSlashToPlatform(filepath.c_str() + 1);
-  return ChangeSlashToPlatform(filepath.c_str());
-#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
-  if (filepath.GetAt(0) != '/')
-    return ChangeSlashToPlatform(filepath.c_str());
-  if (filepath.GetAt(1) == '/')
-    return ChangeSlashToPlatform(filepath.c_str() + 1);
-  if (filepath.GetAt(2) == '/') {
-    CFX_WideString result;
-    result += filepath.GetAt(1);
-    result += ':';
-    result += ChangeSlashToPlatform(filepath.c_str() + 2);
-    return result;
-  }
-  CFX_WideString result;
-  result += '\\';
-  result += ChangeSlashToPlatform(filepath.c_str());
-  return result;
-#else
-  return CFX_WideString(filepath);
-#endif
-}
-
-bool CPDF_FileSpec::GetFileName(CFX_WideString* csFileName) const {
-  if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
-    *csFileName = pDict->GetUnicodeTextBy("UF");
-    if (csFileName->IsEmpty()) {
-      *csFileName =
-          CFX_WideString::FromLocal(pDict->GetStringBy("F").AsStringC());
-    }
-    if (pDict->GetStringBy("FS") == "URL")
-      return true;
-    if (csFileName->IsEmpty()) {
-      if (pDict->KeyExist("DOS")) {
-        *csFileName =
-            CFX_WideString::FromLocal(pDict->GetStringBy("DOS").AsStringC());
-      } else if (pDict->KeyExist("Mac")) {
-        *csFileName =
-            CFX_WideString::FromLocal(pDict->GetStringBy("Mac").AsStringC());
-      } else if (pDict->KeyExist("Unix")) {
-        *csFileName =
-            CFX_WideString::FromLocal(pDict->GetStringBy("Unix").AsStringC());
-      } else {
-        return false;
-      }
-    }
-  } else if (m_pObj->IsString()) {
-    *csFileName = CFX_WideString::FromLocal(m_pObj->GetString().AsStringC());
-  } else {
-    return false;
-  }
-  *csFileName = DecodeFileName(csFileName->AsStringC());
-  return true;
-}
-
-CPDF_FileSpec::CPDF_FileSpec() {
-  m_pObj = new CPDF_Dictionary;
-  m_pObj->AsDictionary()->SetAtName("Type", "Filespec");
-}
-
-CFX_WideString CPDF_FileSpec::EncodeFileName(const CFX_WideStringC& filepath) {
-  if (filepath.GetLength() <= 1) {
-    return CFX_WideString();
-  }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
-  if (filepath.GetAt(1) == ':') {
-    CFX_WideString result;
-    result = '/';
-    result += filepath.GetAt(0);
-    if (filepath.GetAt(2) != '\\') {
-      result += '/';
-    }
-    result += ChangeSlashToPDF(filepath.c_str() + 2);
-    return result;
-  }
-  if (filepath.GetAt(0) == '\\' && filepath.GetAt(1) == '\\') {
-    return ChangeSlashToPDF(filepath.c_str() + 1);
-  }
-  if (filepath.GetAt(0) == '\\') {
-    CFX_WideString result;
-    result = '/';
-    result += ChangeSlashToPDF(filepath.c_str());
-    return result;
-  }
-  return ChangeSlashToPDF(filepath.c_str());
-#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-  if (filepath.Left(sizeof("Mac") - 1) == FX_WSTRC(L"Mac")) {
-    CFX_WideString result;
-    result = '/';
-    result += ChangeSlashToPDF(filepath.c_str());
-    return result;
-  }
-  return ChangeSlashToPDF(filepath.c_str());
-#else
-  return CFX_WideString(filepath);
-#endif
-}
-
-void CPDF_FileSpec::SetFileName(const CFX_WideStringC& wsFileName) {
-  if (!m_pObj)
-    return;
-
-  CFX_WideString wsStr = EncodeFileName(wsFileName);
-  if (m_pObj->IsString()) {
-    m_pObj->SetString(CFX_ByteString::FromUnicode(wsStr));
-  } else if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
-    pDict->SetAtString("F", CFX_ByteString::FromUnicode(wsStr));
-    pDict->SetAtString("UF", PDF_EncodeText(wsStr));
-  }
-}
-
-static CFX_WideString _MakeRoman(int num) {
-  const int arabic[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
-  const CFX_WideString roman[] = {L"m",  L"cm", L"d",  L"cd", L"c",
-                                  L"xc", L"l",  L"xl", L"x",  L"ix",
-                                  L"v",  L"iv", L"i"};
-  const int nMaxNum = 1000000;
-  num %= nMaxNum;
-  int i = 0;
-  CFX_WideString wsRomanNumber;
-  while (num > 0) {
-    while (num >= arabic[i]) {
-      num = num - arabic[i];
-      wsRomanNumber += roman[i];
-    }
-    i = i + 1;
-  }
-  return wsRomanNumber;
-}
-
-static CFX_WideString _MakeLetters(int num) {
-  if (num == 0) {
-    return CFX_WideString();
-  }
-  CFX_WideString wsLetters;
-  const int nMaxCount = 1000;
-  const int nLetterCount = 26;
-  num -= 1;
-  int count = num / nLetterCount + 1;
-  count %= nMaxCount;
-  FX_WCHAR ch = L'a' + num % nLetterCount;
-  for (int i = 0; i < count; i++) {
-    wsLetters += ch;
-  }
-  return wsLetters;
-}
-
-static CFX_WideString _GetLabelNumPortion(int num,
-                                          const CFX_ByteString& bsStyle) {
-  CFX_WideString wsNumPortion;
-  if (bsStyle.IsEmpty()) {
-    return wsNumPortion;
-  }
-  if (bsStyle == "D") {
-    wsNumPortion.Format(L"%d", num);
-  } else if (bsStyle == "R") {
-    wsNumPortion = _MakeRoman(num);
-    wsNumPortion.MakeUpper();
-  } else if (bsStyle == "r") {
-    wsNumPortion = _MakeRoman(num);
-  } else if (bsStyle == "A") {
-    wsNumPortion = _MakeLetters(num);
-    wsNumPortion.MakeUpper();
-  } else if (bsStyle == "a") {
-    wsNumPortion = _MakeLetters(num);
-  }
-  return wsNumPortion;
-}
-
-IPDF_FormNotify::~IPDF_FormNotify() {}
-
-int IPDF_FormNotify::BeforeValueChange(CPDF_FormField* pField,
-                                       const CFX_WideString& csValue) {
-  return 0;
-}
-
-void IPDF_FormNotify::AfterValueChange(CPDF_FormField* pField) {}
-
-int IPDF_FormNotify::BeforeSelectionChange(CPDF_FormField* pField,
-                                           const CFX_WideString& csValue) {
-  return 0;
-}
-
-void IPDF_FormNotify::AfterSelectionChange(CPDF_FormField* pField) {}
-
-void IPDF_FormNotify::AfterCheckedStatusChange(CPDF_FormField* pField) {}
-
-int IPDF_FormNotify::BeforeFormReset(CPDF_InterForm* pForm) {
-  return 0;
-}
-
-void IPDF_FormNotify::AfterFormReset(CPDF_InterForm* pForm) {}
-
-int IPDF_FormNotify::BeforeFormImportData(CPDF_InterForm* pForm) {
-  return 0;
-}
-
-void IPDF_FormNotify::AfterFormImportData(CPDF_InterForm* pForm) {}
-
-CPDF_PageLabel::CPDF_PageLabel(CPDF_Document* pDocument)
-    : m_pDocument(pDocument) {}
-
-CFX_WideString CPDF_PageLabel::GetLabel(int nPage) const {
-  CFX_WideString wsLabel;
-  if (!m_pDocument) {
-    return wsLabel;
-  }
-  CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
-  if (!pPDFRoot) {
-    return wsLabel;
-  }
-  CPDF_Dictionary* pLabels = pPDFRoot->GetDictBy("PageLabels");
-  CPDF_NumberTree numberTree(pLabels);
-  CPDF_Object* pValue = nullptr;
-  int n = nPage;
-  while (n >= 0) {
-    pValue = numberTree.LookupValue(n);
-    if (pValue) {
-      break;
-    }
-    n--;
-  }
-  if (pValue) {
-    pValue = pValue->GetDirect();
-    if (CPDF_Dictionary* pLabel = pValue->AsDictionary()) {
-      if (pLabel->KeyExist("P")) {
-        wsLabel += pLabel->GetUnicodeTextBy("P");
-      }
-      CFX_ByteString bsNumberingStyle = pLabel->GetStringBy("S", "");
-      int nLabelNum = nPage - n + pLabel->GetIntegerBy("St", 1);
-      CFX_WideString wsNumPortion =
-          _GetLabelNumPortion(nLabelNum, bsNumberingStyle);
-      wsLabel += wsNumPortion;
-      return wsLabel;
-    }
-  }
-  wsLabel.Format(L"%d", nPage + 1);
-  return wsLabel;
-}
-
-int32_t CPDF_PageLabel::GetPageByLabel(const CFX_ByteStringC& bsLabel) const {
-  if (!m_pDocument)
-    return -1;
-
-  CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
-  if (!pPDFRoot)
-    return -1;
-
-  int nPages = m_pDocument->GetPageCount();
-  for (int i = 0; i < nPages; i++) {
-    if (PDF_EncodeText(GetLabel(i)).Compare(bsLabel))
-      return i;
-  }
-
-  int nPage = FXSYS_atoi(CFX_ByteString(bsLabel).c_str());  // NUL terminate.
-  return nPage > 0 && nPage <= nPages ? nPage : -1;
-}
-
-int32_t CPDF_PageLabel::GetPageByLabel(const CFX_WideStringC& wsLabel) const {
-  return GetPageByLabel(PDF_EncodeText(wsLabel.c_str()).AsStringC());
-}
diff --git a/core/fpdfdoc/include/cpdf_variabletext.h b/core/fpdfdoc/include/cpdf_variabletext.h
index c898b18..fa5fe07 100644
--- a/core/fpdfdoc/include/cpdf_variabletext.h
+++ b/core/fpdfdoc/include/cpdf_variabletext.h
@@ -9,12 +9,12 @@
 
 #include <memory>
 
+#include "core/fpdfdoc/cpvt_arraytemplate.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"
@@ -32,7 +32,7 @@
 
 #define VARIABLETEXT_HALF 0.5f
 
-class CPDF_VariableText : private CPDF_EditContainer {
+class CPDF_VariableText {
  public:
   enum class ScriptType { Normal, Super, Sub };
 
@@ -82,15 +82,15 @@
   };
 
   CPDF_VariableText();
-  ~CPDF_VariableText() override;
+  ~CPDF_VariableText();
 
   void SetProvider(CPDF_VariableText::Provider* pProvider);
   CPDF_VariableText::Iterator* GetIterator();
 
-  // CPDF_EditContainer.
-  void SetPlateRect(const CFX_FloatRect& rect) override;
-  CFX_FloatRect GetContentRect() const override;
-  const CFX_FloatRect& GetPlateRect() const override;
+  void SetContentRect(const CPVT_FloatRect& rect);
+  CFX_FloatRect GetContentRect() const;
+  void SetPlateRect(const CFX_FloatRect& rect);
+  const CFX_FloatRect& GetPlateRect() const;
 
   void SetAlignment(int32_t nFormat) { m_nAlignment = nFormat; }
   void SetPasswordChar(uint16_t wSubWord) { m_wSubWord = wSubWord; }
@@ -151,6 +151,17 @@
 
   uint16_t GetSubWord() const { return m_wSubWord; }
 
+  FX_FLOAT GetPlateWidth() const { return m_rcPlate.right - m_rcPlate.left; }
+  FX_FLOAT GetPlateHeight() const { return m_rcPlate.top - m_rcPlate.bottom; }
+  CFX_SizeF GetPlateSize() const;
+  CFX_FloatPoint GetBTPoint() const;
+  CFX_FloatPoint GetETPoint() const;
+
+  CFX_FloatPoint InToOut(const CFX_FloatPoint& point) const;
+  CFX_FloatPoint OutToIn(const CFX_FloatPoint& point) const;
+  CFX_FloatRect InToOut(const CPVT_FloatRect& rect) const;
+  CPVT_FloatRect OutToIn(const CFX_FloatRect& rect) const;
+
  private:
   friend class CTypeset;
   friend class CSection;
@@ -233,6 +244,8 @@
   FX_BOOL m_bInitial;
   CPDF_VariableText::Provider* m_pVTProvider;
   std::unique_ptr<CPDF_VariableText::Iterator> m_pVTIterator;
+  CFX_FloatRect m_rcPlate;
+  CPVT_FloatRect m_rcContent;
 };
 
 #endif  // CORE_FPDFDOC_INCLUDE_CPDF_VARIABLETEXT_H_
diff --git a/core/fpdfdoc/ipdf_formnotify.cpp b/core/fpdfdoc/ipdf_formnotify.cpp
new file mode 100644
index 0000000..b36419d
--- /dev/null
+++ b/core/fpdfdoc/ipdf_formnotify.cpp
@@ -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
+
+#include "core/fpdfdoc/include/ipdf_formnotify.h"
+
+IPDF_FormNotify::~IPDF_FormNotify() {}
+
+int IPDF_FormNotify::BeforeValueChange(CPDF_FormField* pField,
+                                       const CFX_WideString& csValue) {
+  return 0;
+}
+
+void IPDF_FormNotify::AfterValueChange(CPDF_FormField* pField) {}
+
+int IPDF_FormNotify::BeforeSelectionChange(CPDF_FormField* pField,
+                                           const CFX_WideString& csValue) {
+  return 0;
+}
+
+void IPDF_FormNotify::AfterSelectionChange(CPDF_FormField* pField) {}
+
+void IPDF_FormNotify::AfterCheckedStatusChange(CPDF_FormField* pField) {}
+
+int IPDF_FormNotify::BeforeFormReset(CPDF_InterForm* pForm) {
+  return 0;
+}
+
+void IPDF_FormNotify::AfterFormReset(CPDF_InterForm* pForm) {}
+
+int IPDF_FormNotify::BeforeFormImportData(CPDF_InterForm* pForm) {
+  return 0;
+}
+
+void IPDF_FormNotify::AfterFormImportData(CPDF_InterForm* pForm) {}
diff --git a/core/fpdfdoc/pdf_vt.h b/core/fpdfdoc/pdf_vt.h
deleted file mode 100644
index 71e28da..0000000
--- a/core/fpdfdoc/pdf_vt.h
+++ /dev/null
@@ -1,99 +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_FPDFDOC_PDF_VT_H_
-#define CORE_FPDFDOC_PDF_VT_H_
-
-#include "core/fpdfdoc/cpvt_floatrect.h"
-#include "core/fpdfdoc/cpvt_lineinfo.h"
-#include "core/fpdfdoc/include/cpvt_wordrange.h"
-
-class CPDF_VariableText;
-
-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))
-
-template <class TYPE>
-class CPVT_ArrayTemplate : public CFX_ArrayTemplate<TYPE> {
- public:
-  FX_BOOL IsEmpty() { return CFX_ArrayTemplate<TYPE>::GetSize() <= 0; }
-  TYPE GetAt(int nIndex) const {
-    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) {
-      return CFX_ArrayTemplate<TYPE>::GetAt(nIndex);
-    }
-    return nullptr;
-  }
-  void RemoveAt(int nIndex) {
-    if (nIndex >= 0 && nIndex < CFX_ArrayTemplate<TYPE>::GetSize()) {
-      CFX_ArrayTemplate<TYPE>::RemoveAt(nIndex);
-    }
-  }
-};
-class CLine final {
- public:
-  CLine();
-  ~CLine();
-
-  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 LinePlace;
-  CPVT_LineInfo m_LineInfo;
-};
-
-class CPDF_EditContainer {
- public:
-  CPDF_EditContainer();
-  virtual ~CPDF_EditContainer();
-
-  virtual void SetPlateRect(const CFX_FloatRect& rect);
-  virtual const CFX_FloatRect& GetPlateRect() const;
-  virtual void SetContentRect(const CPVT_FloatRect& rect);
-  virtual CFX_FloatRect GetContentRect() const;
-
-  FX_FLOAT GetPlateWidth() const { return m_rcPlate.right - m_rcPlate.left; }
-  FX_FLOAT GetPlateHeight() const { return m_rcPlate.top - m_rcPlate.bottom; }
-  CFX_SizeF GetPlateSize() const {
-    return CFX_SizeF(GetPlateWidth(), GetPlateHeight());
-  }
-  CFX_FloatPoint GetBTPoint() const {
-    return CFX_FloatPoint(m_rcPlate.left, m_rcPlate.top);
-  }
-  CFX_FloatPoint GetETPoint() const {
-    return CFX_FloatPoint(m_rcPlate.right, m_rcPlate.bottom);
-  }
-  CFX_FloatPoint InToOut(const CFX_FloatPoint& point) const {
-    return CFX_FloatPoint(point.x + GetBTPoint().x, GetBTPoint().y - point.y);
-  }
-  CFX_FloatPoint OutToIn(const CFX_FloatPoint& point) const {
-    return CFX_FloatPoint(point.x - GetBTPoint().x, GetBTPoint().y - point.y);
-  }
-  CFX_FloatRect InToOut(const CPVT_FloatRect& rect) const {
-    CFX_FloatPoint ptLeftTop = InToOut(CFX_FloatPoint(rect.left, rect.top));
-    CFX_FloatPoint ptRightBottom =
-        InToOut(CFX_FloatPoint(rect.right, rect.bottom));
-    return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x,
-                         ptLeftTop.y);
-  }
-  CPVT_FloatRect OutToIn(const CFX_FloatRect& rect) const {
-    CFX_FloatPoint ptLeftTop = OutToIn(CFX_FloatPoint(rect.left, rect.top));
-    CFX_FloatPoint ptRightBottom =
-        OutToIn(CFX_FloatPoint(rect.right, rect.bottom));
-    return CPVT_FloatRect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x,
-                          ptRightBottom.y);
-  }
-
- private:
-  CFX_FloatRect m_rcPlate;
-  CPVT_FloatRect m_rcContent;
-};
-
-#endif  // CORE_FPDFDOC_PDF_VT_H_
diff --git a/core/fxcrt/include/fx_system.h b/core/fxcrt/include/fx_system.h
index f4fc2e8..0542f33 100644
--- a/core/fxcrt/include/fx_system.h
+++ b/core/fxcrt/include/fx_system.h
@@ -73,6 +73,11 @@
 typedef char FX_CHAR;       // Keep, questionable signedness.
 typedef wchar_t FX_WCHAR;   // Keep, maybe bad platform wchars.
 
+#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)
+
 // PDFium string sizes are limited to 2^31-1, and the value is signed to
 // allow -1 as a placeholder for "unknown".
 // TODO(palmer): it should be a |size_t|, or at least unsigned.
diff --git a/fpdfsdk/fxedit/fxet_edit.cpp b/fpdfsdk/fxedit/fxet_edit.cpp
index bafe3d0d..f31c60a 100644
--- a/fpdfsdk/fxedit/fxet_edit.cpp
+++ b/fpdfsdk/fxedit/fxet_edit.cpp
@@ -841,7 +841,7 @@
     }
 
     FX_FLOAT fCharSpace = pEdit->GetCharSpace();
-    if (!FX_EDIT_IsFloatZero(fCharSpace)) {
+    if (!IsFloatZero(fCharSpace)) {
       sAppStream << fCharSpace << " Tc\n";
     }
 
@@ -1909,7 +1909,7 @@
     return;
 
   if (m_pVT->IsValid()) {
-    if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.x, fx)) {
+    if (!IsFloatEqual(m_ptScrollPos.x, fx)) {
       m_ptScrollPos.x = fx;
       Refresh();
     }
@@ -1921,7 +1921,7 @@
     return;
 
   if (m_pVT->IsValid()) {
-    if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y, fy)) {
+    if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
       m_ptScrollPos.y = fy;
       Refresh();
 
@@ -1955,10 +1955,10 @@
     if (rcPlate.Width() > rcContent.Width()) {
       SetScrollPosX(rcPlate.left);
     } else {
-      if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
+      if (IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) {
         SetScrollPosX(rcContent.left);
-      } else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.x,
-                                       rcContent.right - rcPlate.Width())) {
+      } else if (IsFloatBigger(m_ptScrollPos.x,
+                               rcContent.right - rcPlate.Width())) {
         SetScrollPosX(rcContent.right - rcPlate.Width());
       }
     }
@@ -1966,10 +1966,10 @@
     if (rcPlate.Height() > rcContent.Height()) {
       SetScrollPosY(rcPlate.top);
     } else {
-      if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.y,
-                                 rcContent.bottom + rcPlate.Height())) {
+      if (IsFloatSmaller(m_ptScrollPos.y,
+                         rcContent.bottom + rcPlate.Height())) {
         SetScrollPosY(rcContent.bottom + rcPlate.Height());
-      } else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
+      } else if (IsFloatBigger(m_ptScrollPos.y, rcContent.top)) {
         SetScrollPosY(rcContent.top);
       }
     }
@@ -2007,23 +2007,23 @@
 
   CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
 
-  if (!FX_EDIT_IsFloatEqual(rcPlate.left, rcPlate.right)) {
-    if (FX_EDIT_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
-        FX_EDIT_IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
+  if (!IsFloatEqual(rcPlate.left, rcPlate.right)) {
+    if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
+        IsFloatEqual(ptHeadEdit.x, rcPlate.left)) {
       SetScrollPosX(ptHead.x);
-    } else if (FX_EDIT_IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
+    } else if (IsFloatBigger(ptHeadEdit.x, rcPlate.right)) {
       SetScrollPosX(ptHead.x - rcPlate.Width());
     }
   }
 
-  if (!FX_EDIT_IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
-    if (FX_EDIT_IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
-        FX_EDIT_IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
-      if (FX_EDIT_IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
+  if (!IsFloatEqual(rcPlate.top, rcPlate.bottom)) {
+    if (IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
+        IsFloatEqual(ptFootEdit.y, rcPlate.bottom)) {
+      if (IsFloatSmaller(ptHeadEdit.y, rcPlate.top)) {
         SetScrollPosY(ptFoot.y + rcPlate.Height());
       }
-    } else if (FX_EDIT_IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
-      if (FX_EDIT_IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
+    } else if (IsFloatBigger(ptHeadEdit.y, rcPlate.top)) {
+      if (IsFloatBigger(ptFootEdit.y, rcPlate.bottom)) {
         SetScrollPosY(ptHead.y);
       }
     }
@@ -2788,12 +2788,12 @@
     CFX_FloatRect rcPlate = m_pVT->GetPlateRect();
     CFX_FloatRect rcContent = m_pVT->GetContentRect();
 
-    if (m_pVT->IsMultiLine() && GetTotalLines() > 1) {
-      if (FX_EDIT_IsFloatBigger(rcContent.Height(), rcPlate.Height()))
-        return TRUE;
+    if (m_pVT->IsMultiLine() && GetTotalLines() > 1 &&
+        IsFloatBigger(rcContent.Height(), rcPlate.Height())) {
+      return TRUE;
     }
 
-    if (FX_EDIT_IsFloatBigger(rcContent.Width(), rcPlate.Width()))
+    if (IsFloatBigger(rcContent.Width(), rcPlate.Width()))
       return TRUE;
   }
 
diff --git a/fpdfsdk/fxedit/fxet_list.cpp b/fpdfsdk/fxedit/fxet_list.cpp
index 77484e6..96fb60d 100644
--- a/fpdfsdk/fxedit/fxet_list.cpp
+++ b/fpdfsdk/fxedit/fxet_list.cpp
@@ -517,12 +517,12 @@
   CFX_FloatRect rcItem = GetItemRectInternal(nItemIndex);
   CFX_FloatRect rcItemCtrl = GetItemRect(nItemIndex);
 
-  if (FX_EDIT_IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
-    if (FX_EDIT_IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) {
+  if (IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
+    if (IsFloatSmaller(rcItemCtrl.top, rcPlate.top)) {
       SetScrollPosY(rcItem.bottom + rcPlate.Height());
     }
-  } else if (FX_EDIT_IsFloatBigger(rcItemCtrl.top, rcPlate.top)) {
-    if (FX_EDIT_IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) {
+  } else if (IsFloatBigger(rcItemCtrl.top, rcPlate.top)) {
+    if (IsFloatBigger(rcItemCtrl.bottom, rcPlate.bottom)) {
       SetScrollPosY(rcItem.top);
     }
   }
@@ -548,16 +548,16 @@
 }
 
 void CFX_ListCtrl::SetScrollPosY(FX_FLOAT fy) {
-  if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y, fy)) {
+  if (!IsFloatEqual(m_ptScrollPos.y, fy)) {
     CFX_FloatRect rcPlate = GetPlateRect();
     CFX_FloatRect rcContent = GetContentRectInternal();
 
     if (rcPlate.Height() > rcContent.Height()) {
       fy = rcPlate.top;
     } else {
-      if (FX_EDIT_IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) {
+      if (IsFloatSmaller(fy - rcPlate.Height(), rcContent.bottom)) {
         fy = rcContent.bottom + rcPlate.Height();
-      } else if (FX_EDIT_IsFloatBigger(fy, rcContent.top)) {
+      } else if (IsFloatBigger(fy, rcContent.top)) {
         fy = rcContent.top;
       }
     }
@@ -641,11 +641,11 @@
     if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
       CLST_Rect rcListItem = pListItem->GetRect();
 
-      if (FX_EDIT_IsFloatBigger(pt.y, rcListItem.top)) {
+      if (IsFloatBigger(pt.y, rcListItem.top)) {
         bFirst = FALSE;
       }
 
-      if (FX_EDIT_IsFloatSmaller(pt.y, rcListItem.bottom)) {
+      if (IsFloatSmaller(pt.y, rcListItem.bottom)) {
         bLast = FALSE;
       }
 
diff --git a/fpdfsdk/fxedit/include/fxet_edit.h b/fpdfsdk/fxedit/include/fxet_edit.h
index bf88286..9adf172 100644
--- a/fpdfsdk/fxedit/include/fxet_edit.h
+++ b/fpdfsdk/fxedit/include/fxet_edit.h
@@ -24,12 +24,6 @@
 class CFX_SystemHandler;
 class IFX_Edit_UndoItem;
 
-#define FX_EDIT_IsFloatZero(f) (f < 0.0001 && f > -0.0001)
-#define FX_EDIT_IsFloatEqual(fa, fb) FX_EDIT_IsFloatZero(fa - fb)
-#define FX_EDIT_IsFloatBigger(fa, fb) (fa > fb && !FX_EDIT_IsFloatEqual(fa, fb))
-#define FX_EDIT_IsFloatSmaller(fa, fb) \
-  (fa < fb && !FX_EDIT_IsFloatEqual(fa, fb))
-
 enum EDIT_PROPS_E {
   EP_LINELEADING,
   EP_LINEINDENT,
@@ -55,21 +49,20 @@
   }
 
   FX_BOOL IsSameHeight(const CFX_Edit_LineRect& linerect) const {
-    return FX_EDIT_IsFloatZero(
-        (m_rcLine.top - m_rcLine.bottom) -
-        (linerect.m_rcLine.top - linerect.m_rcLine.bottom));
+    return IsFloatZero((m_rcLine.top - m_rcLine.bottom) -
+                       (linerect.m_rcLine.top - linerect.m_rcLine.bottom));
   }
 
   FX_BOOL IsSameTop(const CFX_Edit_LineRect& linerect) const {
-    return FX_EDIT_IsFloatZero(m_rcLine.top - linerect.m_rcLine.top);
+    return IsFloatZero(m_rcLine.top - linerect.m_rcLine.top);
   }
 
   FX_BOOL IsSameLeft(const CFX_Edit_LineRect& linerect) const {
-    return FX_EDIT_IsFloatZero(m_rcLine.left - linerect.m_rcLine.left);
+    return IsFloatZero(m_rcLine.left - linerect.m_rcLine.left);
   }
 
   FX_BOOL IsSameRight(const CFX_Edit_LineRect& linerect) const {
-    return FX_EDIT_IsFloatZero(m_rcLine.right - linerect.m_rcLine.right);
+    return IsFloatZero(m_rcLine.right - linerect.m_rcLine.right);
   }
 
   CPVT_WordRange m_wrLine;
diff --git a/fpdfsdk/pdfwindow/PWL_ComboBox.cpp b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
index dd899be..7349ed0 100644
--- a/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
+++ b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
@@ -17,11 +17,6 @@
 
 #define PWLCB_DEFAULTFONTSIZE 12.0f
 
-#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))
-
 FX_BOOL CPWL_CBListBox::OnLButtonUp(const CFX_FloatPoint& point,
                                     uint32_t nFlag) {
   CPWL_Wnd::OnLButtonUp(point, nFlag);
diff --git a/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
index ee3df36..febf69e 100644
--- a/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
+++ b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
@@ -16,11 +16,6 @@
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 #include "public/fpdf_fwlevent.h"
 
-#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))
-
 CPWL_EditCtrl::CPWL_EditCtrl()
     : m_pEdit(new CFX_Edit),
       m_pEditCaret(nullptr),
diff --git a/fpdfsdk/pdfwindow/PWL_ListBox.cpp b/fpdfsdk/pdfwindow/PWL_ListBox.cpp
index 730b319..1265a8d 100644
--- a/fpdfsdk/pdfwindow/PWL_ListBox.cpp
+++ b/fpdfsdk/pdfwindow/PWL_ListBox.cpp
@@ -15,11 +15,6 @@
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 #include "public/fpdf_fwlevent.h"
 
-#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))
-
 CPWL_List_Notify::CPWL_List_Notify(CPWL_ListBox* pList) : m_pList(pList) {
   ASSERT(m_pList);
 }
diff --git a/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp b/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp
index 7cec290..410be18 100644
--- a/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp
+++ b/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp
@@ -10,11 +10,6 @@
 #include "fpdfsdk/pdfwindow/PWL_Utils.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
-#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))
-
 PWL_FLOATRANGE::PWL_FLOATRANGE() {
   Default();
 }
diff --git a/fpdfsdk/pdfwindow/PWL_Utils.cpp b/fpdfsdk/pdfwindow/PWL_Utils.cpp
index a969886..7e961a4 100644
--- a/fpdfsdk/pdfwindow/PWL_Utils.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Utils.cpp
@@ -14,11 +14,6 @@
 #include "fpdfsdk/pdfwindow/PWL_Icon.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
-#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))
-
 CFX_ByteString CPWL_Utils::GetAppStreamFromArray(const CPWL_PathData* pPathData,
                                                  int32_t nCount) {
   CFX_ByteTextBuf csAP;
diff --git a/pdfium.gyp b/pdfium.gyp
index f83ec3a..501ed9e 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -182,6 +182,8 @@
       'target_name': 'fpdfdoc',
       'type': 'static_library',
       'sources': [
+        'core/fpdfdoc/cline.cpp',
+        'core/fpdfdoc/cline.h',
         'core/fpdfdoc/clines.cpp',
         'core/fpdfdoc/clines.h',
         'core/fpdfdoc/cpdf_aaction.cpp',
@@ -192,13 +194,19 @@
         'core/fpdfdoc/cpdf_annotlist.cpp',
         'core/fpdfdoc/cpdf_bookmark.cpp',
         'core/fpdfdoc/cpdf_bookmarktree.cpp',
+        'core/fpdfdoc/cpdf_dest.cpp',
         'core/fpdfdoc/cpdf_docjsactions.cpp',
+        'core/fpdfdoc/cpdf_filespec.cpp',
         'core/fpdfdoc/cpdf_link.cpp',
         'core/fpdfdoc/cpdf_linklist.cpp',
         'core/fpdfdoc/cpdf_metadata.cpp',
+        'core/fpdfdoc/cpdf_nametree.cpp',
+        'core/fpdfdoc/cpdf_occontext.cpp',
+        'core/fpdfdoc/cpdf_pagelabel.cpp',
         'core/fpdfdoc/cpdf_pagelabel.h',
         'core/fpdfdoc/cpdf_variabletext.cpp',
         'core/fpdfdoc/cpdf_viewerpreferences.cpp',
+        'core/fpdfdoc/cpvt_arraytemplate.h',
         'core/fpdfdoc/cpvt_color.cpp',
         'core/fpdfdoc/cpvt_color.h',
         'core/fpdfdoc/cpvt_dash.h',
@@ -216,14 +224,11 @@
         'core/fpdfdoc/csection.h',
         'core/fpdfdoc/ctypeset.cpp',
         'core/fpdfdoc/ctypeset.h',
-        'core/fpdfdoc/doc_basic.cpp',
         'core/fpdfdoc/doc_form.cpp',
         'core/fpdfdoc/doc_formcontrol.cpp',
         'core/fpdfdoc/doc_formfield.cpp',
-        'core/fpdfdoc/doc_ocg.cpp',
         'core/fpdfdoc/doc_utils.cpp',
         'core/fpdfdoc/doc_utils.h',
-        'core/fpdfdoc/doc_vt.cpp',
         'core/fpdfdoc/include/cpdf_aaction.h',
         'core/fpdfdoc/include/cpdf_action.h',
         'core/fpdfdoc/include/cpdf_actionfields.h',
@@ -255,7 +260,7 @@
         'core/fpdfdoc/include/cpvt_wordrange.h',
         'core/fpdfdoc/include/ipvt_fontmap.h',
         'core/fpdfdoc/include/ipdf_formnotify.h',
-        'core/fpdfdoc/pdf_vt.h',
+        'core/fpdfdoc/ipdf_formnotify.cpp',
       ],
     },
     {
@@ -919,7 +924,7 @@
         'core/fpdfapi/fpdf_parser/cpdf_simple_parser_unittest.cpp',
         'core/fpdfapi/fpdf_parser/cpdf_syntax_parser_unittest.cpp',
         'core/fpdfapi/fpdf_parser/fpdf_parser_decode_unittest.cpp',
-        'core/fpdfdoc/doc_basic_unittest.cpp',
+        'core/fpdfdoc/cpdf_filespec_unittest.cpp',
         'core/fpdftext/fpdf_text_int_unittest.cpp',
         'core/fxcodec/codec/fx_codec_jpx_unittest.cpp',
         'core/fxcrt/fx_basic_bstring_unittest.cpp',