Cleanup fsdk_define methods

This CL collects the various fsdk_define methods into a fsdk_define.cpp
class. Methods only used in one place are moved into the appropriate
anonymous namespaces.

Change-Id: I75bfc7e8fe20711106fcf9821adeb41d69bf5848
Reviewed-on: https://pdfium-review.googlesource.com/29310
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_customaccess.cpp b/fpdfsdk/cpdfsdk_customaccess.cpp
new file mode 100644
index 0000000..0545ae4
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_customaccess.cpp
@@ -0,0 +1,30 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/cpdfsdk_customaccess.h"
+
+CPDFSDK_CustomAccess::CPDFSDK_CustomAccess(FPDF_FILEACCESS* pFileAccess)
+    : m_FileAccess(*pFileAccess) {}
+
+FX_FILESIZE CPDFSDK_CustomAccess::GetSize() {
+  return m_FileAccess.m_FileLen;
+}
+
+bool CPDFSDK_CustomAccess::ReadBlock(void* buffer,
+                                     FX_FILESIZE offset,
+                                     size_t size) {
+  if (offset < 0)
+    return false;
+
+  FX_SAFE_FILESIZE newPos = pdfium::base::checked_cast<FX_FILESIZE>(size);
+  newPos += offset;
+  if (!newPos.IsValid() ||
+      newPos.ValueOrDie() > static_cast<FX_FILESIZE>(m_FileAccess.m_FileLen)) {
+    return false;
+  }
+  return !!m_FileAccess.m_GetBlock(m_FileAccess.m_Param, offset,
+                                   static_cast<uint8_t*>(buffer), size);
+}
diff --git a/fpdfsdk/cpdfsdk_customaccess.h b/fpdfsdk/cpdfsdk_customaccess.h
new file mode 100644
index 0000000..dabbdf2
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_customaccess.h
@@ -0,0 +1,28 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_CPDFSDK_CUSTOMACCESS_H_
+#define FPDFSDK_CPDFSDK_CUSTOMACCESS_H_
+
+#include "core/fxcrt/fx_stream.h"
+#include "public/fpdfview.h"
+
+class CPDFSDK_CustomAccess final : public IFX_SeekableReadStream {
+ public:
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+  // IFX_SeekableReadStream
+  FX_FILESIZE GetSize() override;
+  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
+
+ private:
+  explicit CPDFSDK_CustomAccess(FPDF_FILEACCESS* pFileAccess);
+
+  FPDF_FILEACCESS m_FileAccess;
+};
+
+#endif  // FPDFSDK_CPDFSDK_CUSTOMACCESS_H_
diff --git a/fpdfsdk/cpdfsdk_memoryaccess.cpp b/fpdfsdk/cpdfsdk_memoryaccess.cpp
new file mode 100644
index 0000000..2a5b7ae
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_memoryaccess.cpp
@@ -0,0 +1,32 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/cpdfsdk_memoryaccess.h"
+
+CPDFSDK_MemoryAccess::CPDFSDK_MemoryAccess(const uint8_t* pBuf,
+                                           FX_FILESIZE size)
+    : m_pBuf(pBuf), m_size(size) {}
+
+CPDFSDK_MemoryAccess::~CPDFSDK_MemoryAccess() = default;
+
+FX_FILESIZE CPDFSDK_MemoryAccess::GetSize() {
+  return m_size;
+}
+
+bool CPDFSDK_MemoryAccess::ReadBlock(void* buffer,
+                                     FX_FILESIZE offset,
+                                     size_t size) {
+  if (offset < 0)
+    return false;
+
+  FX_SAFE_FILESIZE newPos = pdfium::base::checked_cast<FX_FILESIZE>(size);
+  newPos += offset;
+  if (!newPos.IsValid() || newPos.ValueOrDie() > m_size)
+    return false;
+
+  memcpy(buffer, m_pBuf + offset, size);
+  return true;
+}
diff --git a/fpdfsdk/cpdfsdk_memoryaccess.h b/fpdfsdk/cpdfsdk_memoryaccess.h
new file mode 100644
index 0000000..9d5a365
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_memoryaccess.h
@@ -0,0 +1,29 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_CPDFSDK_MEMORYACCESS_H_
+#define FPDFSDK_CPDFSDK_MEMORYACCESS_H_
+
+#include "core/fxcrt/fx_stream.h"
+
+class CPDFSDK_MemoryAccess final : public IFX_SeekableReadStream {
+ public:
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+  ~CPDFSDK_MemoryAccess() override;
+
+  FX_FILESIZE GetSize() override;
+  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
+
+ private:
+  CPDFSDK_MemoryAccess(const uint8_t* pBuf, FX_FILESIZE size);
+
+  const uint8_t* const m_pBuf;
+  const FX_FILESIZE m_size;
+};
+
+#endif  // FPDFSDK_CPDFSDK_MEMORYACCESS_H_
diff --git a/fpdfsdk/fpdf_ext.cpp b/fpdfsdk/fpdf_ext.cpp
index 87605cf..b972141 100644
--- a/fpdfsdk/fpdf_ext.cpp
+++ b/fpdfsdk/fpdf_ext.cpp
@@ -6,36 +6,15 @@
 
 #include "public/fpdf_ext.h"
 
-#include <memory>
-
 #include "core/fpdfapi/cpdf_modulemgr.h"
-#include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
-#include "core/fpdfdoc/cpdf_annot.h"
 #include "core/fpdfdoc/cpdf_interform.h"
-#include "core/fpdfdoc/cpdf_metadata.h"
-#include "core/fxcrt/fx_memory.h"
-#include "core/fxcrt/xml/cxml_content.h"
-#include "core/fxcrt/xml/cxml_element.h"
 #include "fpdfsdk/fsdk_define.h"
-#include "third_party/base/ptr_util.h"
 
 #ifdef PDF_ENABLE_XFA
 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
 #endif  // PDF_ENABLE_XFA
 
-bool FPDF_UnSupportError(int nError) {
-  CFSDK_UnsupportInfo_Adapter* pAdapter =
-      CPDF_ModuleMgr::Get()->GetUnsupportInfoAdapter();
-  if (!pAdapter)
-    return false;
-
-  UNSUPPORT_INFO* info = static_cast<UNSUPPORT_INFO*>(pAdapter->GetUnspInfo());
-  if (info && info->FSDK_UnSupport_Handler)
-    info->FSDK_UnSupport_Handler(info, nError);
-  return true;
-}
-
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
 FSDK_SetUnSpObjProcessHandler(UNSUPPORT_INFO* unsp_info) {
   if (!unsp_info || unsp_info->version != 1)
@@ -46,127 +25,6 @@
   return true;
 }
 
-void CheckUnSupportAnnot(CPDF_Document* pDoc, const CPDF_Annot* pPDFAnnot) {
-  CPDF_Annot::Subtype nAnnotSubtype = pPDFAnnot->GetSubtype();
-  if (nAnnotSubtype == CPDF_Annot::Subtype::THREED) {
-    FPDF_UnSupportError(FPDF_UNSP_ANNOT_3DANNOT);
-  } else if (nAnnotSubtype == CPDF_Annot::Subtype::SCREEN) {
-    const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
-    ByteString cbString;
-    if (pAnnotDict->KeyExist("IT"))
-      cbString = pAnnotDict->GetStringFor("IT");
-    if (cbString.Compare("Img") != 0)
-      FPDF_UnSupportError(FPDF_UNSP_ANNOT_SCREEN_MEDIA);
-  } else if (nAnnotSubtype == CPDF_Annot::Subtype::MOVIE) {
-    FPDF_UnSupportError(FPDF_UNSP_ANNOT_MOVIE);
-  } else if (nAnnotSubtype == CPDF_Annot::Subtype::SOUND) {
-    FPDF_UnSupportError(FPDF_UNSP_ANNOT_SOUND);
-  } else if (nAnnotSubtype == CPDF_Annot::Subtype::RICHMEDIA) {
-    FPDF_UnSupportError(FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA);
-  } else if (nAnnotSubtype == CPDF_Annot::Subtype::FILEATTACHMENT) {
-    FPDF_UnSupportError(FPDF_UNSP_ANNOT_ATTACHMENT);
-  } else if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET) {
-    const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
-    ByteString cbString;
-    if (pAnnotDict->KeyExist("FT"))
-      cbString = pAnnotDict->GetStringFor("FT");
-    if (cbString.Compare("Sig") == 0)
-      FPDF_UnSupportError(FPDF_UNSP_ANNOT_SIG);
-  }
-}
-
-bool CheckSharedForm(const CXML_Element* pElement, ByteString cbName) {
-  size_t count = pElement->CountAttrs();
-  for (size_t i = 0; i < count; ++i) {
-    ByteString space;
-    ByteString name;
-    WideString value;
-    pElement->GetAttrByIndex(i, &space, &name, &value);
-    if (space == "xmlns" && name == "adhocwf" &&
-        value == L"http://ns.adobe.com/AcrobatAdhocWorkflow/1.0/") {
-      CXML_Element* pVersion =
-          pElement->GetElement("adhocwf", cbName.AsStringView(), 0);
-      if (!pVersion)
-        continue;
-      CXML_Content* pContent = ToContent(pVersion->GetChild(0));
-      if (!pContent)
-        continue;
-      switch (pContent->m_Content.GetInteger()) {
-        case 1:
-          FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_ACROBAT);
-          break;
-        case 2:
-          FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM);
-          break;
-        case 0:
-          FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_EMAIL);
-          break;
-      }
-    }
-  }
-
-  size_t nCount = pElement->CountChildren();
-  for (size_t i = 0; i < nCount; ++i) {
-    CXML_Element* pChild = ToElement(pElement->GetChild(i));
-    if (pChild && CheckSharedForm(pChild, cbName))
-      return true;
-  }
-  return false;
-}
-
-void CheckUnSupportError(CPDF_Document* pDoc, uint32_t err_code) {
-  // Security
-  if (err_code == FPDF_ERR_SECURITY) {
-    FPDF_UnSupportError(FPDF_UNSP_DOC_SECURITY);
-    return;
-  }
-  if (!pDoc)
-    return;
-
-  // Portfolios and Packages
-  const CPDF_Dictionary* pRootDict = pDoc->GetRoot();
-  if (pRootDict) {
-    ByteString cbString;
-    if (pRootDict->KeyExist("Collection")) {
-      FPDF_UnSupportError(FPDF_UNSP_DOC_PORTABLECOLLECTION);
-      return;
-    }
-    if (pRootDict->KeyExist("Names")) {
-      CPDF_Dictionary* pNameDict = pRootDict->GetDictFor("Names");
-      if (pNameDict && pNameDict->KeyExist("EmbeddedFiles")) {
-        FPDF_UnSupportError(FPDF_UNSP_DOC_ATTACHMENT);
-        return;
-      }
-      if (pNameDict && pNameDict->KeyExist("JavaScript")) {
-        CPDF_Dictionary* pJSDict = pNameDict->GetDictFor("JavaScript");
-        CPDF_Array* pArray = pJSDict ? pJSDict->GetArrayFor("Names") : nullptr;
-        if (pArray) {
-          for (size_t i = 0; i < pArray->GetCount(); i++) {
-            ByteString cbStr = pArray->GetStringAt(i);
-            if (cbStr.Compare("com.adobe.acrobat.SharedReview.Register") == 0) {
-              FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDREVIEW);
-              return;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  // SharedForm
-  CPDF_Metadata metaData(pDoc);
-  const CXML_Element* pElement = metaData.GetRoot();
-  if (pElement)
-    CheckSharedForm(pElement, "workflowType");
-
-#ifndef PDF_ENABLE_XFA
-  // XFA Forms
-  CPDF_InterForm interform(pDoc);
-  if (interform.HasXFAForm())
-    FPDF_UnSupportError(FPDF_UNSP_DOC_XFAFORM);
-#endif  // PDF_ENABLE_XFA
-}
-
 FPDF_EXPORT int FPDF_CALLCONV FPDFDoc_GetPageMode(FPDF_DOCUMENT document) {
   CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
   if (!pDoc)
diff --git a/fpdfsdk/fpdfattachment.cpp b/fpdfsdk/fpdfattachment.cpp
index eb83534..0de01b2 100644
--- a/fpdfsdk/fpdfattachment.cpp
+++ b/fpdfsdk/fpdfattachment.cpp
@@ -25,6 +25,10 @@
 
 constexpr char kChecksumKey[] = "CheckSum";
 
+CPDF_Object* CPDFObjectFromFPDFAttachment(FPDF_ATTACHMENT attachment) {
+  return static_cast<CPDF_Object*>(attachment);
+}
+
 ByteString CFXByteStringHexDecode(const ByteString& bsHex) {
   uint8_t* result = nullptr;
   uint32_t size = 0;
diff --git a/fpdfsdk/fpdfdoc.cpp b/fpdfsdk/fpdfdoc.cpp
index 774dc28..2ba0053 100644
--- a/fpdfsdk/fpdfdoc.cpp
+++ b/fpdfsdk/fpdfdoc.cpp
@@ -60,8 +60,6 @@
   return pHolder->get();
 }
 
-}  // namespace
-
 CPDF_Array* CPDFArrayFromDest(FPDF_DEST dest) {
   return static_cast<CPDF_Array*>(dest);
 }
@@ -78,30 +76,7 @@
   return ToDictionary(static_cast<CPDF_Object*>(link));
 }
 
-const CPDF_Array* GetQuadPointsArrayFromDictionary(CPDF_Dictionary* dict) {
-  return dict ? dict->GetArrayFor("QuadPoints") : nullptr;
-}
-
-bool GetQuadPointsFromDictionary(CPDF_Dictionary* dict,
-                                 size_t quad_index,
-                                 FS_QUADPOINTSF* quad_points) {
-  ASSERT(quad_points);
-
-  const CPDF_Array* pArray = GetQuadPointsArrayFromDictionary(dict);
-  if (!pArray || quad_index >= pArray->GetCount() / 8)
-    return false;
-
-  quad_index *= 8;
-  quad_points->x1 = pArray->GetNumberAt(quad_index);
-  quad_points->y1 = pArray->GetNumberAt(quad_index + 1);
-  quad_points->x2 = pArray->GetNumberAt(quad_index + 2);
-  quad_points->y2 = pArray->GetNumberAt(quad_index + 3);
-  quad_points->x3 = pArray->GetNumberAt(quad_index + 4);
-  quad_points->y3 = pArray->GetNumberAt(quad_index + 5);
-  quad_points->x4 = pArray->GetNumberAt(quad_index + 6);
-  quad_points->y4 = pArray->GetNumberAt(quad_index + 7);
-  return true;
-}
+}  // namespace
 
 FPDF_EXPORT FPDF_BOOKMARK FPDF_CALLCONV
 FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) {
diff --git a/fpdfsdk/fpdfeditimg.cpp b/fpdfsdk/fpdfeditimg.cpp
index 335c152..a98a61f 100644
--- a/fpdfsdk/fpdfeditimg.cpp
+++ b/fpdfsdk/fpdfeditimg.cpp
@@ -14,6 +14,7 @@
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_name.h"
 #include "core/fpdfapi/render/cpdf_dibsource.h"
+#include "fpdfsdk/cpdfsdk_customaccess.h"
 #include "fpdfsdk/fsdk_define.h"
 #include "third_party/base/ptr_util.h"
 
@@ -43,6 +44,11 @@
 static_assert(PDFCS_PATTERN == FPDF_COLORSPACE_PATTERN,
               "PDFCS_PATTERN value mismatch");
 
+RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
+    FPDF_FILEACCESS* pFileAccess) {
+  return pdfium::MakeRetain<CPDFSDK_CustomAccess>(pFileAccess);
+}
+
 bool LoadJpegHelper(FPDF_PAGE* pages,
                     int nCount,
                     FPDF_PAGEOBJECT image_object,
diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp
index d0724d5..92e4357 100644
--- a/fpdfsdk/fpdfeditpage.cpp
+++ b/fpdfsdk/fpdfeditpage.cpp
@@ -53,6 +53,11 @@
 static_assert(FPDF_PAGEOBJ_FORM == CPDF_PageObject::FORM,
               "FPDF_PAGEOBJ_FORM/CPDF_PageObject::FORM mismatch");
 
+const CPDF_ContentMarkItem* CPDFContentMarkItemFromFPDFPageObjectMark(
+    FPDF_PAGEOBJECTMARK mark) {
+  return static_cast<const CPDF_ContentMarkItem*>(mark);
+}
+
 bool IsPageObject(CPDF_Page* pPage) {
   if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type"))
     return false;
diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp
index d0a9406..0b9ac47 100644
--- a/fpdfsdk/fpdfeditpath.cpp
+++ b/fpdfsdk/fpdfeditpath.cpp
@@ -37,6 +37,15 @@
 
 namespace {
 
+CPDF_PathObject* CPDFPathObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
+  auto* obj = CPDFPageObjectFromFPDFPageObject(page_object);
+  return obj ? obj->AsPath() : nullptr;
+}
+
+const FX_PATHPOINT* FXPathPointFromFPDFPathSegment(FPDF_PATHSEGMENT segment) {
+  return static_cast<const FX_PATHPOINT*>(segment);
+}
+
 unsigned int GetAlphaAsUnsignedInt(float alpha) {
   return static_cast<unsigned int>(alpha * 255.f + 0.5f);
 }
diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
index a907810..9a334d5 100644
--- a/fpdfsdk/fpdfview.cpp
+++ b/fpdfsdk/fpdfview.cpp
@@ -6,55 +6,49 @@
 
 #include "public/fpdfview.h"
 
-#include <memory>
 #include <utility>
 #include <vector>
 
 #include "core/fpdfapi/cpdf_modulemgr.h"
 #include "core/fpdfapi/cpdf_pagerendercontext.h"
-#include "core/fpdfapi/page/cpdf_contentmarkitem.h"
-#include "core/fpdfapi/page/cpdf_image.h"
-#include "core/fpdfapi/page/cpdf_imageobject.h"
 #include "core/fpdfapi/page/cpdf_page.h"
-#include "core/fpdfapi/page/cpdf_pageobject.h"
-#include "core/fpdfapi/page/cpdf_pathobject.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
 #include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_parser.h"
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fpdfapi/render/cpdf_progressiverenderer.h"
+#include "core/fpdfapi/render/cpdf_rendercontext.h"
 #include "core/fpdfapi/render/cpdf_renderoptions.h"
 #include "core/fpdfdoc/cpdf_annotlist.h"
 #include "core/fpdfdoc/cpdf_nametree.h"
 #include "core/fpdfdoc/cpdf_occontext.h"
 #include "core/fpdfdoc/cpdf_viewerpreferences.h"
-#include "core/fxcrt/fx_memory.h"
-#include "core/fxcrt/fx_safe_types.h"
 #include "core/fxcrt/fx_stream.h"
+#include "core/fxcrt/fx_system.h"
 #include "core/fxge/cfx_defaultrenderdevice.h"
 #include "core/fxge/cfx_gemodule.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/cpdfsdk_customaccess.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_memoryaccess.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
 #include "fpdfsdk/fsdk_define.h"
 #include "fpdfsdk/fsdk_pauseadapter.h"
 #include "fxjs/ijs_runtime.h"
-#include "public/fpdf_edit.h"
-#include "public/fpdf_ext.h"
 #include "public/fpdf_formfill.h"
-#include "public/fpdf_progressive.h"
-#include "third_party/base/allocator/partition_allocator/partition_alloc.h"
-#include "third_party/base/numerics/safe_conversions_impl.h"
 #include "third_party/base/ptr_util.h"
 
 #ifdef PDF_ENABLE_XFA
 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
-#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
 #include "fxbarcode/BC_Library.h"
 #endif  // PDF_ENABLE_XFA
 
 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
 #include "core/fxge/cfx_windowsrenderdevice.h"
+#include "public/fpdf_edit.h"
 
 // These checks are here because core/ and public/ cannot depend on each other.
 static_assert(WindowsPrintMode::kModeEmf == FPDF_PRINTMODE_EMF,
@@ -132,149 +126,6 @@
     pContext->m_pDevice->RestoreState(false);
 }
 
-class CPDF_CustomAccess final : public IFX_SeekableReadStream {
- public:
-  template <typename T, typename... Args>
-  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
-
-  // IFX_SeekableReadStream
-  FX_FILESIZE GetSize() override;
-  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
-
- private:
-  explicit CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess);
-
-  FPDF_FILEACCESS m_FileAccess;
-};
-
-CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess)
-    : m_FileAccess(*pFileAccess) {}
-
-FX_FILESIZE CPDF_CustomAccess::GetSize() {
-  return m_FileAccess.m_FileLen;
-}
-
-bool CPDF_CustomAccess::ReadBlock(void* buffer,
-                                  FX_FILESIZE offset,
-                                  size_t size) {
-  if (offset < 0)
-    return false;
-
-  FX_SAFE_FILESIZE newPos = pdfium::base::checked_cast<FX_FILESIZE>(size);
-  newPos += offset;
-  if (!newPos.IsValid() ||
-      newPos.ValueOrDie() > static_cast<FX_FILESIZE>(m_FileAccess.m_FileLen)) {
-    return false;
-  }
-  return !!m_FileAccess.m_GetBlock(m_FileAccess.m_Param, offset,
-                                   static_cast<uint8_t*>(buffer), size);
-}
-
-#ifdef PDF_ENABLE_XFA
-class FPDF_FileHandlerContext : public IFX_SeekableStream {
- public:
-  template <typename T, typename... Args>
-  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
-
-  ~FPDF_FileHandlerContext() override;
-
-  // IFX_SeekableStream:
-  FX_FILESIZE GetSize() override;
-  bool IsEOF() override;
-  FX_FILESIZE GetPosition() override;
-  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
-  size_t ReadBlock(void* buffer, size_t size) override;
-  bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override;
-  bool Flush() override;
-
-  void SetPosition(FX_FILESIZE pos) { m_nCurPos = pos; }
-
- protected:
-  explicit FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS);
-
-  FPDF_FILEHANDLER* m_pFS;
-  FX_FILESIZE m_nCurPos;
-};
-
-FPDF_FileHandlerContext::FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS) {
-  m_pFS = pFS;
-  m_nCurPos = 0;
-}
-
-FPDF_FileHandlerContext::~FPDF_FileHandlerContext() {
-  if (m_pFS && m_pFS->Release)
-    m_pFS->Release(m_pFS->clientData);
-}
-
-FX_FILESIZE FPDF_FileHandlerContext::GetSize() {
-  if (m_pFS && m_pFS->GetSize)
-    return (FX_FILESIZE)m_pFS->GetSize(m_pFS->clientData);
-  return 0;
-}
-
-bool FPDF_FileHandlerContext::IsEOF() {
-  return m_nCurPos >= GetSize();
-}
-
-FX_FILESIZE FPDF_FileHandlerContext::GetPosition() {
-  return m_nCurPos;
-}
-
-bool FPDF_FileHandlerContext::ReadBlock(void* buffer,
-                                        FX_FILESIZE offset,
-                                        size_t size) {
-  if (!buffer || !size || !m_pFS->ReadBlock)
-    return false;
-
-  if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
-                       (FPDF_DWORD)size) == 0) {
-    m_nCurPos = offset + size;
-    return true;
-  }
-  return false;
-}
-
-size_t FPDF_FileHandlerContext::ReadBlock(void* buffer, size_t size) {
-  if (!buffer || !size || !m_pFS->ReadBlock)
-    return 0;
-
-  FX_FILESIZE nSize = GetSize();
-  if (m_nCurPos >= nSize)
-    return 0;
-  FX_FILESIZE dwAvail = nSize - m_nCurPos;
-  if (dwAvail < (FX_FILESIZE)size)
-    size = static_cast<size_t>(dwAvail);
-  if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)m_nCurPos, buffer,
-                       (FPDF_DWORD)size) == 0) {
-    m_nCurPos += size;
-    return size;
-  }
-
-  return 0;
-}
-
-bool FPDF_FileHandlerContext::WriteBlock(const void* buffer,
-                                         FX_FILESIZE offset,
-                                         size_t size) {
-  if (!m_pFS || !m_pFS->WriteBlock)
-    return false;
-
-  if (m_pFS->WriteBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
-                        (FPDF_DWORD)size) == 0) {
-    m_nCurPos = offset + size;
-    return true;
-  }
-  return false;
-}
-
-bool FPDF_FileHandlerContext::Flush() {
-  if (!m_pFS || !m_pFS->Flush)
-    return true;
-
-  return m_pFS->Flush(m_pFS->clientData) == 0;
-}
-#endif  // PDF_ENABLE_XFA
-
 FPDF_DOCUMENT LoadDocumentImpl(
     const RetainPtr<IFX_SeekableReadStream>& pFileAccess,
     FPDF_BYTESTRING password) {
@@ -299,172 +150,6 @@
 
 }  // namespace
 
-UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc) {
-  return static_cast<UnderlyingDocumentType*>(doc);
-}
-
-FPDF_DOCUMENT FPDFDocumentFromUnderlying(UnderlyingDocumentType* doc) {
-  return static_cast<FPDF_DOCUMENT>(doc);
-}
-
-UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page) {
-  return static_cast<UnderlyingPageType*>(page);
-}
-
-CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc) {
-#ifdef PDF_ENABLE_XFA
-  return doc ? UnderlyingFromFPDFDocument(doc)->GetPDFDoc() : nullptr;
-#else   // PDF_ENABLE_XFA
-  return UnderlyingFromFPDFDocument(doc);
-#endif  // PDF_ENABLE_XFA
-}
-
-FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc) {
-#ifdef PDF_ENABLE_XFA
-  return doc ? FPDFDocumentFromUnderlying(
-                   new CPDFXFA_Context(pdfium::WrapUnique(doc)))
-             : nullptr;
-#else   // PDF_ENABLE_XFA
-  return FPDFDocumentFromUnderlying(doc);
-#endif  // PDF_ENABLE_XFA
-}
-
-CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
-#ifdef PDF_ENABLE_XFA
-  return page ? UnderlyingFromFPDFPage(page)->GetPDFPage() : nullptr;
-#else   // PDF_ENABLE_XFA
-  return UnderlyingFromFPDFPage(page);
-#endif  // PDF_ENABLE_XFA
-}
-
-CPDF_PathObject* CPDFPathObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
-  auto* obj = CPDFPageObjectFromFPDFPageObject(page_object);
-  return obj ? obj->AsPath() : nullptr;
-}
-
-CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
-  return static_cast<CPDF_PageObject*>(page_object);
-}
-
-const CPDF_ContentMarkItem* CPDFContentMarkItemFromFPDFPageObjectMark(
-    FPDF_PAGEOBJECTMARK mark) {
-  return static_cast<const CPDF_ContentMarkItem*>(mark);
-}
-
-CPDF_Object* CPDFObjectFromFPDFAttachment(FPDF_ATTACHMENT attachment) {
-  return static_cast<CPDF_Object*>(attachment);
-}
-
-ByteString CFXByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string) {
-  return WideString::FromUTF16LE(wide_string,
-                                 WideString::WStringLength(wide_string))
-      .UTF8Encode();
-}
-
-CFX_DIBitmap* CFXBitmapFromFPDFBitmap(FPDF_BITMAP bitmap) {
-  return static_cast<CFX_DIBitmap*>(bitmap);
-}
-
-CFX_FloatRect CFXFloatRectFromFSRECTF(const FS_RECTF& rect) {
-  return CFX_FloatRect(rect.left, rect.bottom, rect.right, rect.top);
-}
-
-void FSRECTFFromCFXFloatRect(const CFX_FloatRect& rect, FS_RECTF* out_rect) {
-  out_rect->left = rect.left;
-  out_rect->top = rect.top;
-  out_rect->right = rect.right;
-  out_rect->bottom = rect.bottom;
-}
-
-const FX_PATHPOINT* FXPathPointFromFPDFPathSegment(FPDF_PATHSEGMENT segment) {
-  return static_cast<const FX_PATHPOINT*>(segment);
-}
-
-unsigned long Utf16EncodeMaybeCopyAndReturnLength(const WideString& text,
-                                                  void* buffer,
-                                                  unsigned long buflen) {
-  ByteString encoded_text = text.UTF16LE_Encode();
-  unsigned long len = encoded_text.GetLength();
-  if (buffer && len <= buflen)
-    memcpy(buffer, encoded_text.c_str(), len);
-  return len;
-}
-
-unsigned long DecodeStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
-                                                   void* buffer,
-                                                   unsigned long buflen) {
-  ASSERT(stream);
-  uint8_t* data = stream->GetRawData();
-  uint32_t len = stream->GetRawSize();
-  CPDF_Dictionary* dict = stream->GetDict();
-  CPDF_Object* decoder = dict ? dict->GetDirectObjectFor("Filter") : nullptr;
-  if (decoder && (decoder->IsArray() || decoder->IsName())) {
-    // Decode the stream if one or more stream filters are specified.
-    uint8_t* decoded_data = nullptr;
-    uint32_t decoded_len = 0;
-    ByteString dummy_last_decoder;
-    CPDF_Dictionary* dummy_last_param;
-    if (PDF_DataDecode(data, len, dict, dict->GetIntegerFor("DL"), false,
-                       &decoded_data, &decoded_len, &dummy_last_decoder,
-                       &dummy_last_param)) {
-      if (buffer && buflen >= decoded_len)
-        memcpy(buffer, decoded_data, decoded_len);
-
-      // Free the buffer for the decoded data if it was allocated by
-      // PDF_DataDecode(). Note that for images with a single image-specific
-      // filter, |decoded_data| is directly assigned to be |data|, so
-      // |decoded_data| does not need to be freed.
-      if (decoded_data != data)
-        FX_Free(decoded_data);
-
-      return decoded_len;
-    }
-  }
-  // Copy the raw data and return its length if there is no valid filter
-  // specified or if decoding failed.
-  if (buffer && buflen >= len)
-    memcpy(buffer, data, len);
-
-  return len;
-}
-
-RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
-    FPDF_FILEACCESS* pFileAccess) {
-  return pdfium::MakeRetain<CPDF_CustomAccess>(pFileAccess);
-}
-
-#ifdef PDF_ENABLE_XFA
-RetainPtr<IFX_SeekableStream> MakeSeekableStream(
-    FPDF_FILEHANDLER* pFilehandler) {
-  return pdfium::MakeRetain<FPDF_FileHandlerContext>(pFilehandler);
-}
-#endif  // PDF_ENABLE_XFA
-
-// 0 bit: FPDF_POLICY_MACHINETIME_ACCESS
-static uint32_t foxit_sandbox_policy = 0xFFFFFFFF;
-
-void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable) {
-  switch (policy) {
-    case FPDF_POLICY_MACHINETIME_ACCESS: {
-      if (enable)
-        foxit_sandbox_policy |= 0x01;
-      else
-        foxit_sandbox_policy &= 0xFFFFFFFE;
-    } break;
-    default:
-      break;
-  }
-}
-
-FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy) {
-  switch (policy) {
-    case FPDF_POLICY_MACHINETIME_ACCESS:
-      return !!(foxit_sandbox_policy & 0x01);
-    default:
-      return false;
-  }
-}
-
 FPDF_EXPORT void FPDF_CALLCONV FPDF_InitLibrary() {
   FPDF_InitLibraryWithConfig(nullptr);
 }
@@ -507,40 +192,6 @@
   g_bLibraryInitialized = false;
 }
 
-#ifndef _WIN32
-int g_LastError;
-void SetLastError(int err) {
-  g_LastError = err;
-}
-
-int GetLastError() {
-  return g_LastError;
-}
-#endif  // _WIN32
-
-void ProcessParseError(CPDF_Parser::Error err) {
-  uint32_t err_code = FPDF_ERR_SUCCESS;
-  // Translate FPDFAPI error code to FPDFVIEW error code
-  switch (err) {
-    case CPDF_Parser::SUCCESS:
-      err_code = FPDF_ERR_SUCCESS;
-      break;
-    case CPDF_Parser::FILE_ERROR:
-      err_code = FPDF_ERR_FILE;
-      break;
-    case CPDF_Parser::FORMAT_ERROR:
-      err_code = FPDF_ERR_FORMAT;
-      break;
-    case CPDF_Parser::PASSWORD_ERROR:
-      err_code = FPDF_ERR_PASSWORD;
-      break;
-    case CPDF_Parser::HANDLER_ERROR:
-      err_code = FPDF_ERR_SECURITY;
-      break;
-  }
-  SetLastError(err_code);
-}
-
 FPDF_EXPORT void FPDF_CALLCONV FPDF_SetSandBoxPolicy(FPDF_DWORD policy,
                                                      FPDF_BOOL enable) {
   return FSDK_SetSandBoxPolicy(policy, enable);
@@ -606,44 +257,17 @@
 }
 #endif  // PDF_ENABLE_XFA
 
-class CMemFile final : public IFX_SeekableReadStream {
- public:
-  static RetainPtr<CMemFile> Create(const uint8_t* pBuf, FX_FILESIZE size) {
-    return RetainPtr<CMemFile>(new CMemFile(pBuf, size));
-  }
-
-  FX_FILESIZE GetSize() override { return m_size; }
-  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
-    if (offset < 0)
-      return false;
-
-    FX_SAFE_FILESIZE newPos = pdfium::base::checked_cast<FX_FILESIZE>(size);
-    newPos += offset;
-    if (!newPos.IsValid() || newPos.ValueOrDie() > m_size)
-      return false;
-
-    memcpy(buffer, m_pBuf + offset, size);
-    return true;
-  }
-
- private:
-  CMemFile(const uint8_t* pBuf, FX_FILESIZE size)
-      : m_pBuf(pBuf), m_size(size) {}
-
-  const uint8_t* const m_pBuf;
-  const FX_FILESIZE m_size;
-};
-
 FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV
 FPDF_LoadMemDocument(const void* data_buf, int size, FPDF_BYTESTRING password) {
-  return LoadDocumentImpl(
-      CMemFile::Create(static_cast<const uint8_t*>(data_buf), size), password);
+  return LoadDocumentImpl(pdfium::MakeRetain<CPDFSDK_MemoryAccess>(
+                              static_cast<const uint8_t*>(data_buf), size),
+                          password);
 }
 
 FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV
 FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess,
                         FPDF_BYTESTRING password) {
-  return LoadDocumentImpl(pdfium::MakeRetain<CPDF_CustomAccess>(pFileAccess),
+  return LoadDocumentImpl(pdfium::MakeRetain<CPDFSDK_CustomAccess>(pFileAccess),
                           password);
 }
 
diff --git a/fpdfsdk/fsdk_define.cpp b/fpdfsdk/fsdk_define.cpp
new file mode 100644
index 0000000..917d36d
--- /dev/null
+++ b/fpdfsdk/fsdk_define.cpp
@@ -0,0 +1,462 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/fsdk_define.h"
+
+#include "core/fpdfapi/cpdf_modulemgr.h"
+#include "core/fpdfapi/parser/cpdf_array.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/fpdf_parser_decode.h"
+#include "core/fpdfdoc/cpdf_annot.h"
+#include "core/fpdfdoc/cpdf_interform.h"
+#include "core/fpdfdoc/cpdf_metadata.h"
+#include "core/fxcrt/xml/cxml_content.h"
+#include "core/fxcrt/xml/cxml_element.h"
+#include "public/fpdf_ext.h"
+
+namespace {
+
+FPDF_DOCUMENT FPDFDocumentFromUnderlying(UnderlyingDocumentType* doc) {
+  return static_cast<FPDF_DOCUMENT>(doc);
+}
+
+bool RaiseUnSupportError(int nError) {
+  CFSDK_UnsupportInfo_Adapter* pAdapter =
+      CPDF_ModuleMgr::Get()->GetUnsupportInfoAdapter();
+  if (!pAdapter)
+    return false;
+
+  UNSUPPORT_INFO* info = static_cast<UNSUPPORT_INFO*>(pAdapter->GetUnspInfo());
+  if (info && info->FSDK_UnSupport_Handler)
+    info->FSDK_UnSupport_Handler(info, nError);
+  return true;
+}
+
+bool CheckSharedForm(const CXML_Element* pElement, ByteString cbName) {
+  size_t count = pElement->CountAttrs();
+  for (size_t i = 0; i < count; ++i) {
+    ByteString space;
+    ByteString name;
+    WideString value;
+    pElement->GetAttrByIndex(i, &space, &name, &value);
+    if (space == "xmlns" && name == "adhocwf" &&
+        value == L"http://ns.adobe.com/AcrobatAdhocWorkflow/1.0/") {
+      CXML_Element* pVersion =
+          pElement->GetElement("adhocwf", cbName.AsStringView(), 0);
+      if (!pVersion)
+        continue;
+      CXML_Content* pContent = ToContent(pVersion->GetChild(0));
+      if (!pContent)
+        continue;
+      switch (pContent->m_Content.GetInteger()) {
+        case 1:
+          RaiseUnSupportError(FPDF_UNSP_DOC_SHAREDFORM_ACROBAT);
+          break;
+        case 2:
+          RaiseUnSupportError(FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM);
+          break;
+        case 0:
+          RaiseUnSupportError(FPDF_UNSP_DOC_SHAREDFORM_EMAIL);
+          break;
+      }
+    }
+  }
+
+  size_t nCount = pElement->CountChildren();
+  for (size_t i = 0; i < nCount; ++i) {
+    CXML_Element* pChild = ToElement(pElement->GetChild(i));
+    if (pChild && CheckSharedForm(pChild, cbName))
+      return true;
+  }
+  return false;
+}
+
+#ifdef PDF_ENABLE_XFA
+class FPDF_FileHandlerContext : public IFX_SeekableStream {
+ public:
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+  ~FPDF_FileHandlerContext() override;
+
+  // IFX_SeekableStream:
+  FX_FILESIZE GetSize() override;
+  bool IsEOF() override;
+  FX_FILESIZE GetPosition() override;
+  bool ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override;
+  size_t ReadBlock(void* buffer, size_t size) override;
+  bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override;
+  bool Flush() override;
+
+  void SetPosition(FX_FILESIZE pos) { m_nCurPos = pos; }
+
+ protected:
+  explicit FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS);
+
+  FPDF_FILEHANDLER* m_pFS;
+  FX_FILESIZE m_nCurPos;
+};
+
+FPDF_FileHandlerContext::FPDF_FileHandlerContext(FPDF_FILEHANDLER* pFS) {
+  m_pFS = pFS;
+  m_nCurPos = 0;
+}
+
+FPDF_FileHandlerContext::~FPDF_FileHandlerContext() {
+  if (m_pFS && m_pFS->Release)
+    m_pFS->Release(m_pFS->clientData);
+}
+
+FX_FILESIZE FPDF_FileHandlerContext::GetSize() {
+  if (m_pFS && m_pFS->GetSize)
+    return (FX_FILESIZE)m_pFS->GetSize(m_pFS->clientData);
+  return 0;
+}
+
+bool FPDF_FileHandlerContext::IsEOF() {
+  return m_nCurPos >= GetSize();
+}
+
+FX_FILESIZE FPDF_FileHandlerContext::GetPosition() {
+  return m_nCurPos;
+}
+
+bool FPDF_FileHandlerContext::ReadBlock(void* buffer,
+                                        FX_FILESIZE offset,
+                                        size_t size) {
+  if (!buffer || !size || !m_pFS->ReadBlock)
+    return false;
+
+  if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
+                       (FPDF_DWORD)size) == 0) {
+    m_nCurPos = offset + size;
+    return true;
+  }
+  return false;
+}
+
+size_t FPDF_FileHandlerContext::ReadBlock(void* buffer, size_t size) {
+  if (!buffer || !size || !m_pFS->ReadBlock)
+    return 0;
+
+  FX_FILESIZE nSize = GetSize();
+  if (m_nCurPos >= nSize)
+    return 0;
+  FX_FILESIZE dwAvail = nSize - m_nCurPos;
+  if (dwAvail < (FX_FILESIZE)size)
+    size = static_cast<size_t>(dwAvail);
+  if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)m_nCurPos, buffer,
+                       (FPDF_DWORD)size) == 0) {
+    m_nCurPos += size;
+    return size;
+  }
+
+  return 0;
+}
+
+bool FPDF_FileHandlerContext::WriteBlock(const void* buffer,
+                                         FX_FILESIZE offset,
+                                         size_t size) {
+  if (!m_pFS || !m_pFS->WriteBlock)
+    return false;
+
+  if (m_pFS->WriteBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer,
+                        (FPDF_DWORD)size) == 0) {
+    m_nCurPos = offset + size;
+    return true;
+  }
+  return false;
+}
+
+bool FPDF_FileHandlerContext::Flush() {
+  if (!m_pFS || !m_pFS->Flush)
+    return true;
+
+  return m_pFS->Flush(m_pFS->clientData) == 0;
+}
+#endif  // PDF_ENABLE_XFA
+
+}  // namespace
+
+UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc) {
+  return static_cast<UnderlyingDocumentType*>(doc);
+}
+
+UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page) {
+  return static_cast<UnderlyingPageType*>(page);
+}
+
+CPDF_Document* CPDFDocumentFromFPDFDocument(FPDF_DOCUMENT doc) {
+#ifdef PDF_ENABLE_XFA
+  return doc ? UnderlyingFromFPDFDocument(doc)->GetPDFDoc() : nullptr;
+#else   // PDF_ENABLE_XFA
+  return UnderlyingFromFPDFDocument(doc);
+#endif  // PDF_ENABLE_XFA
+}
+
+FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc) {
+#ifdef PDF_ENABLE_XFA
+  return doc ? FPDFDocumentFromUnderlying(
+                   new CPDFXFA_Context(pdfium::WrapUnique(doc)))
+             : nullptr;
+#else   // PDF_ENABLE_XFA
+  return FPDFDocumentFromUnderlying(doc);
+#endif  // PDF_ENABLE_XFA
+}
+
+CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page) {
+#ifdef PDF_ENABLE_XFA
+  return page ? UnderlyingFromFPDFPage(page)->GetPDFPage() : nullptr;
+#else   // PDF_ENABLE_XFA
+  return UnderlyingFromFPDFPage(page);
+#endif  // PDF_ENABLE_XFA
+}
+
+CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) {
+  return static_cast<CPDF_PageObject*>(page_object);
+}
+
+ByteString CFXByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string) {
+  return WideString::FromUTF16LE(wide_string,
+                                 WideString::WStringLength(wide_string))
+      .UTF8Encode();
+}
+
+CFX_DIBitmap* CFXBitmapFromFPDFBitmap(FPDF_BITMAP bitmap) {
+  return static_cast<CFX_DIBitmap*>(bitmap);
+}
+
+void CheckUnSupportAnnot(CPDF_Document* pDoc, const CPDF_Annot* pPDFAnnot) {
+  CPDF_Annot::Subtype nAnnotSubtype = pPDFAnnot->GetSubtype();
+  if (nAnnotSubtype == CPDF_Annot::Subtype::THREED) {
+    RaiseUnSupportError(FPDF_UNSP_ANNOT_3DANNOT);
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::SCREEN) {
+    const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
+    ByteString cbString;
+    if (pAnnotDict->KeyExist("IT"))
+      cbString = pAnnotDict->GetStringFor("IT");
+    if (cbString.Compare("Img") != 0)
+      RaiseUnSupportError(FPDF_UNSP_ANNOT_SCREEN_MEDIA);
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::MOVIE) {
+    RaiseUnSupportError(FPDF_UNSP_ANNOT_MOVIE);
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::SOUND) {
+    RaiseUnSupportError(FPDF_UNSP_ANNOT_SOUND);
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::RICHMEDIA) {
+    RaiseUnSupportError(FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA);
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::FILEATTACHMENT) {
+    RaiseUnSupportError(FPDF_UNSP_ANNOT_ATTACHMENT);
+  } else if (nAnnotSubtype == CPDF_Annot::Subtype::WIDGET) {
+    const CPDF_Dictionary* pAnnotDict = pPDFAnnot->GetAnnotDict();
+    ByteString cbString;
+    if (pAnnotDict->KeyExist("FT"))
+      cbString = pAnnotDict->GetStringFor("FT");
+    if (cbString.Compare("Sig") == 0)
+      RaiseUnSupportError(FPDF_UNSP_ANNOT_SIG);
+  }
+}
+
+void CheckUnSupportError(CPDF_Document* pDoc, uint32_t err_code) {
+  // Security
+  if (err_code == FPDF_ERR_SECURITY) {
+    RaiseUnSupportError(FPDF_UNSP_DOC_SECURITY);
+    return;
+  }
+  if (!pDoc)
+    return;
+
+  // Portfolios and Packages
+  const CPDF_Dictionary* pRootDict = pDoc->GetRoot();
+  if (pRootDict) {
+    ByteString cbString;
+    if (pRootDict->KeyExist("Collection")) {
+      RaiseUnSupportError(FPDF_UNSP_DOC_PORTABLECOLLECTION);
+      return;
+    }
+    if (pRootDict->KeyExist("Names")) {
+      CPDF_Dictionary* pNameDict = pRootDict->GetDictFor("Names");
+      if (pNameDict && pNameDict->KeyExist("EmbeddedFiles")) {
+        RaiseUnSupportError(FPDF_UNSP_DOC_ATTACHMENT);
+        return;
+      }
+      if (pNameDict && pNameDict->KeyExist("JavaScript")) {
+        CPDF_Dictionary* pJSDict = pNameDict->GetDictFor("JavaScript");
+        CPDF_Array* pArray = pJSDict ? pJSDict->GetArrayFor("Names") : nullptr;
+        if (pArray) {
+          for (size_t i = 0; i < pArray->GetCount(); i++) {
+            ByteString cbStr = pArray->GetStringAt(i);
+            if (cbStr.Compare("com.adobe.acrobat.SharedReview.Register") == 0) {
+              RaiseUnSupportError(FPDF_UNSP_DOC_SHAREDREVIEW);
+              return;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // SharedForm
+  CPDF_Metadata metaData(pDoc);
+  const CXML_Element* pElement = metaData.GetRoot();
+  if (pElement)
+    CheckSharedForm(pElement, "workflowType");
+
+#ifndef PDF_ENABLE_XFA
+  // XFA Forms
+  CPDF_InterForm interform(pDoc);
+  if (interform.HasXFAForm())
+    RaiseUnSupportError(FPDF_UNSP_DOC_XFAFORM);
+#endif  // PDF_ENABLE_XFA
+}
+
+#ifndef _WIN32
+int g_LastError;
+void SetLastError(int err) {
+  g_LastError = err;
+}
+
+int GetLastError() {
+  return g_LastError;
+}
+#endif  // _WIN32
+
+void ProcessParseError(CPDF_Parser::Error err) {
+  uint32_t err_code = FPDF_ERR_SUCCESS;
+  // Translate FPDFAPI error code to FPDFVIEW error code
+  switch (err) {
+    case CPDF_Parser::SUCCESS:
+      err_code = FPDF_ERR_SUCCESS;
+      break;
+    case CPDF_Parser::FILE_ERROR:
+      err_code = FPDF_ERR_FILE;
+      break;
+    case CPDF_Parser::FORMAT_ERROR:
+      err_code = FPDF_ERR_FORMAT;
+      break;
+    case CPDF_Parser::PASSWORD_ERROR:
+      err_code = FPDF_ERR_PASSWORD;
+      break;
+    case CPDF_Parser::HANDLER_ERROR:
+      err_code = FPDF_ERR_SECURITY;
+      break;
+  }
+  SetLastError(err_code);
+}
+
+// 0 bit: FPDF_POLICY_MACHINETIME_ACCESS
+static uint32_t foxit_sandbox_policy = 0xFFFFFFFF;
+
+void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable) {
+  switch (policy) {
+    case FPDF_POLICY_MACHINETIME_ACCESS: {
+      if (enable)
+        foxit_sandbox_policy |= 0x01;
+      else
+        foxit_sandbox_policy &= 0xFFFFFFFE;
+    } break;
+    default:
+      break;
+  }
+}
+
+FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy) {
+  switch (policy) {
+    case FPDF_POLICY_MACHINETIME_ACCESS:
+      return !!(foxit_sandbox_policy & 0x01);
+    default:
+      return false;
+  }
+}
+
+unsigned long DecodeStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
+                                                   void* buffer,
+                                                   unsigned long buflen) {
+  ASSERT(stream);
+  uint8_t* data = stream->GetRawData();
+  uint32_t len = stream->GetRawSize();
+  CPDF_Dictionary* dict = stream->GetDict();
+  CPDF_Object* decoder = dict ? dict->GetDirectObjectFor("Filter") : nullptr;
+  if (decoder && (decoder->IsArray() || decoder->IsName())) {
+    // Decode the stream if one or more stream filters are specified.
+    uint8_t* decoded_data = nullptr;
+    uint32_t decoded_len = 0;
+    ByteString dummy_last_decoder;
+    CPDF_Dictionary* dummy_last_param;
+    if (PDF_DataDecode(data, len, dict, dict->GetIntegerFor("DL"), false,
+                       &decoded_data, &decoded_len, &dummy_last_decoder,
+                       &dummy_last_param)) {
+      if (buffer && buflen >= decoded_len)
+        memcpy(buffer, decoded_data, decoded_len);
+
+      // Free the buffer for the decoded data if it was allocated by
+      // PDF_DataDecode(). Note that for images with a single image-specific
+      // filter, |decoded_data| is directly assigned to be |data|, so
+      // |decoded_data| does not need to be freed.
+      if (decoded_data != data)
+        FX_Free(decoded_data);
+
+      return decoded_len;
+    }
+  }
+  // Copy the raw data and return its length if there is no valid filter
+  // specified or if decoding failed.
+  if (buffer && buflen >= len)
+    memcpy(buffer, data, len);
+
+  return len;
+}
+
+unsigned long Utf16EncodeMaybeCopyAndReturnLength(const WideString& text,
+                                                  void* buffer,
+                                                  unsigned long buflen) {
+  ByteString encoded_text = text.UTF16LE_Encode();
+  unsigned long len = encoded_text.GetLength();
+  if (buffer && len <= buflen)
+    memcpy(buffer, encoded_text.c_str(), len);
+  return len;
+}
+
+void FSRECTFFromCFXFloatRect(const CFX_FloatRect& rect, FS_RECTF* out_rect) {
+  out_rect->left = rect.left;
+  out_rect->top = rect.top;
+  out_rect->right = rect.right;
+  out_rect->bottom = rect.bottom;
+}
+
+CFX_FloatRect CFXFloatRectFromFSRECTF(const FS_RECTF& rect) {
+  return CFX_FloatRect(rect.left, rect.bottom, rect.right, rect.top);
+}
+
+const CPDF_Array* GetQuadPointsArrayFromDictionary(CPDF_Dictionary* dict) {
+  return dict ? dict->GetArrayFor("QuadPoints") : nullptr;
+}
+
+bool GetQuadPointsFromDictionary(CPDF_Dictionary* dict,
+                                 size_t quad_index,
+                                 FS_QUADPOINTSF* quad_points) {
+  ASSERT(quad_points);
+
+  const CPDF_Array* pArray = GetQuadPointsArrayFromDictionary(dict);
+  if (!pArray || quad_index >= pArray->GetCount() / 8)
+    return false;
+
+  quad_index *= 8;
+  quad_points->x1 = pArray->GetNumberAt(quad_index);
+  quad_points->y1 = pArray->GetNumberAt(quad_index + 1);
+  quad_points->x2 = pArray->GetNumberAt(quad_index + 2);
+  quad_points->y2 = pArray->GetNumberAt(quad_index + 3);
+  quad_points->x3 = pArray->GetNumberAt(quad_index + 4);
+  quad_points->y3 = pArray->GetNumberAt(quad_index + 5);
+  quad_points->x4 = pArray->GetNumberAt(quad_index + 6);
+  quad_points->y4 = pArray->GetNumberAt(quad_index + 7);
+  return true;
+}
+
+#ifdef PDF_ENABLE_XFA
+RetainPtr<IFX_SeekableStream> MakeSeekableStream(
+    FPDF_FILEHANDLER* pFilehandler) {
+  return pdfium::MakeRetain<FPDF_FileHandlerContext>(pFilehandler);
+}
+#endif  // PDF_ENABLE_XFA
diff --git a/fpdfsdk/fsdk_define.h b/fpdfsdk/fsdk_define.h
index 94497bb..c864f05 100644
--- a/fpdfsdk/fsdk_define.h
+++ b/fpdfsdk/fsdk_define.h
@@ -23,7 +23,6 @@
 #endif
 
 class CPDF_Annot;
-class CPDF_ContentMarkItem;
 class CPDF_Page;
 class CPDF_PageObject;
 class CPDF_PageRenderContext;
@@ -32,18 +31,6 @@
 class IFSDK_PAUSE_Adapter;
 class FX_PATHPOINT;
 
-// Layering prevents fxcrt from knowing about FPDF_FILEACCESS, so this can't
-// be a static method of IFX_SeekableReadStream.
-RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
-    FPDF_FILEACCESS* pFileAccess);
-
-#ifdef PDF_ENABLE_XFA
-// Layering prevents fxcrt from knowing about FPDF_FILEHANDLER, so this can't
-// be a static method of IFX_SeekableStream.
-RetainPtr<IFX_SeekableStream> MakeSeekableStream(
-    FPDF_FILEHANDLER* pFileHandler);
-#endif  // PDF_ENABLE_XFA
-
 // Object types for public FPDF_ types; these correspond to next layer down
 // from fpdfsdk. For master, these are CPDF_ types, but for XFA, these are
 // CPDFXFA_ types.
@@ -57,7 +44,6 @@
 
 // Conversions to/from underlying types.
 UnderlyingDocumentType* UnderlyingFromFPDFDocument(FPDF_DOCUMENT doc);
-FPDF_DOCUMENT FPDFDocumentFromUnderlying(UnderlyingDocumentType* doc);
 
 UnderlyingPageType* UnderlyingFromFPDFPage(FPDF_PAGE page);
 
@@ -66,27 +52,16 @@
 FPDF_DOCUMENT FPDFDocumentFromCPDFDocument(CPDF_Document* doc);
 
 CPDF_Page* CPDFPageFromFPDFPage(FPDF_PAGE page);
-
-CPDF_PathObject* CPDFPathObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
-
 CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object);
-
-const CPDF_ContentMarkItem* CPDFContentMarkItemFromFPDFPageObjectMark(
-    FPDF_PAGEOBJECTMARK mark);
-
-CPDF_Object* CPDFObjectFromFPDFAttachment(FPDF_ATTACHMENT attachment);
-
 ByteString CFXByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string);
-
 CFX_DIBitmap* CFXBitmapFromFPDFBitmap(FPDF_BITMAP bitmap);
 
-CPDF_Array* CPDFArrayFromDest(FPDF_DEST dest);
-
-CPDF_Dictionary* CPDFDictionaryFromFPDFAction(FPDF_ACTION action);
-
-CPDF_Dictionary* CPDFDictionaryFromFPDFBookmark(FPDF_BOOKMARK bookmark);
-
-CPDF_Dictionary* CPDFDictionaryFromFPDFLink(FPDF_LINK link);
+#ifdef PDF_ENABLE_XFA
+// Layering prevents fxcrt from knowing about FPDF_FILEHANDLER, so this can't
+// be a static method of IFX_SeekableStream.
+RetainPtr<IFX_SeekableStream> MakeSeekableStream(
+    FPDF_FILEHANDLER* pFileHandler);
+#endif  // PDF_ENABLE_XFA
 
 const CPDF_Array* GetQuadPointsArrayFromDictionary(CPDF_Dictionary* dict);
 bool GetQuadPointsFromDictionary(CPDF_Dictionary* dict,
@@ -96,18 +71,17 @@
 CFX_FloatRect CFXFloatRectFromFSRECTF(const FS_RECTF& rect);
 void FSRECTFFromCFXFloatRect(const CFX_FloatRect& rect, FS_RECTF* out_rect);
 
-const FX_PATHPOINT* FXPathPointFromFPDFPathSegment(FPDF_PATHSEGMENT segment);
-
 unsigned long Utf16EncodeMaybeCopyAndReturnLength(const WideString& text,
                                                   void* buffer,
                                                   unsigned long buflen);
-
 unsigned long DecodeStreamMaybeCopyAndReturnLength(const CPDF_Stream* stream,
                                                    void* buffer,
                                                    unsigned long buflen);
 
 void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable);
 FPDF_BOOL FSDK_IsSandBoxPolicyEnabled(FPDF_DWORD policy);
+
+// TODO(dsinclair): Where should this live?
 void FPDF_RenderPage_Retail(CPDF_PageRenderContext* pContext,
                             FPDF_PAGE page,
                             int start_x,
@@ -121,7 +95,15 @@
 
 void CheckUnSupportError(CPDF_Document* pDoc, uint32_t err_code);
 void CheckUnSupportAnnot(CPDF_Document* pDoc, const CPDF_Annot* pPDFAnnot);
+
+#ifndef _WIN32
+void SetLastError(int err);
+int GetLastError();
+#endif  // _WIN32
+
 void ProcessParseError(CPDF_Parser::Error err);
+
+// TODO(dsinclair): This seems like it should be a public API?
 FPDF_BOOL FPDFPageObj_SetFillColor(FPDF_PAGEOBJECT page_object,
                                    unsigned int R,
                                    unsigned int G,