Remove some IFX_* wrappers.

This CL removes the IFX_* wrappers between fpdfsdk/fxedit and fpdfsdk/pdfwindow
which only have a single implementation.

Review-Url: https://codereview.chromium.org/2142213002
diff --git a/BUILD.gn b/BUILD.gn
index 706ea90..c9a5fdd 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -743,8 +743,6 @@
     "fpdfsdk/fxedit/fxet_ap.cpp",
     "fpdfsdk/fxedit/fxet_edit.cpp",
     "fpdfsdk/fxedit/fxet_list.cpp",
-    "fpdfsdk/fxedit/fxet_module.cpp",
-    "fpdfsdk/fxedit/fxet_pageobjs.cpp",
     "fpdfsdk/fxedit/include/fx_edit.h",
     "fpdfsdk/fxedit/include/fxet_edit.h",
     "fpdfsdk/fxedit/include/fxet_list.h",
diff --git a/fpdfsdk/fsdk_baseform.cpp b/fpdfsdk/fsdk_baseform.cpp
index 90ff144..2994981 100644
--- a/fpdfsdk/fsdk_baseform.cpp
+++ b/fpdfsdk/fsdk_baseform.cpp
@@ -18,6 +18,7 @@
 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
 #include "core/fxge/include/fx_ge.h"
 #include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/fxedit/include/fxet_edit.h"
 #include "fpdfsdk/include/fsdk_actionhandler.h"
 #include "fpdfsdk/include/fsdk_baseannot.h"
 #include "fpdfsdk/include/fsdk_define.h"
@@ -1362,7 +1363,7 @@
   rcButton.left = rcButton.right - 13;
   rcButton.Normalize();
 
-  IFX_Edit* pEdit = IFX_Edit::NewEdit();
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
   pEdit->EnableRefresh(FALSE);
 
   CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
@@ -1399,7 +1400,7 @@
   CFX_FloatRect rcContent = pEdit->GetContentRect();
 
   CFX_ByteString sEdit =
-      CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, 0.0f));
+      CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_FloatPoint(0.0f, 0.0f));
   if (sEdit.GetLength() > 0) {
     sBody << "/Tx BMC\n"
           << "q\n";
@@ -1415,8 +1416,6 @@
           << "Q\nEMC\n";
   }
 
-  IFX_Edit::DelEdit(pEdit);
-
   sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
 
   CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
@@ -1431,7 +1430,7 @@
   CFX_FloatRect rcClient = GetClientRect();
   CFX_ByteTextBuf sBody, sLines;
 
-  IFX_Edit* pEdit = IFX_Edit::NewEdit();
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
   pEdit->EnableRefresh(FALSE);
 
   CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
@@ -1484,13 +1483,15 @@
       sList << "BT\n"
             << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1),
                                              TRUE)
-            << CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, fy))
+            << CPWL_Utils::GetEditAppStream(pEdit.get(),
+                                            CFX_FloatPoint(0.0f, fy))
             << "ET\n";
     } else {
       CPWL_Color crText = GetTextPWLColor();
       sList << "BT\n"
             << CPWL_Utils::GetColorAppStream(crText, TRUE)
-            << CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, fy))
+            << CPWL_Utils::GetEditAppStream(pEdit.get(),
+                                            CFX_FloatPoint(0.0f, fy))
             << "ET\n";
     }
 
@@ -1505,8 +1506,6 @@
     sBody << sList << "Q\nEMC\n";
   }
 
-  IFX_Edit::DelEdit(pEdit);
-
   CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
                        sLines.AsStringC() + sBody.AsStringC();
 
@@ -1518,7 +1517,7 @@
   CPDF_FormField* pField = pControl->GetField();
   CFX_ByteTextBuf sBody, sLines;
 
-  IFX_Edit* pEdit = IFX_Edit::NewEdit();
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
   pEdit->EnableRefresh(FALSE);
 
   CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
@@ -1589,7 +1588,7 @@
   CFX_FloatRect rcContent = pEdit->GetContentRect();
 
   CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
-      pEdit, CFX_FloatPoint(0.0f, 0.0f), nullptr, !bCharArray, subWord);
+      pEdit.get(), CFX_FloatPoint(0.0f, 0.0f), nullptr, !bCharArray, subWord);
 
   if (sEdit.GetLength() > 0) {
     sBody << "/Tx BMC\n"
@@ -1659,8 +1658,6 @@
     }
   }
 
-  IFX_Edit::DelEdit(pEdit);
-
   CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
                        sLines.AsStringC() + sBody.AsStringC();
   WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
diff --git a/fpdfsdk/fxedit/fxet_ap.cpp b/fpdfsdk/fxedit/fxet_ap.cpp
index 863a2d2..8484e5d 100644
--- a/fpdfsdk/fxedit/fxet_ap.cpp
+++ b/fpdfsdk/fxedit/fxet_ap.cpp
@@ -11,31 +11,6 @@
 #include "fpdfsdk/fxedit/include/fx_edit.h"
 #include "fpdfsdk/fxedit/include/fxet_edit.h"
 
-namespace {
-
-CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) {
-  if (strWords.GetLength() > 0)
-    return PDF_EncodeString(strWords) + " Tj\n";
-  return CFX_ByteString();
-}
-
-CFX_ByteString GetFontSetString(IPVT_FontMap* pFontMap,
-                                int32_t nFontIndex,
-                                FX_FLOAT fFontSize) {
-  if (!pFontMap)
-    return CFX_ByteString();
-
-  CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
-  if (sFontAlias.GetLength() <= 0 || fFontSize <= 0)
-    return CFX_ByteString();
-
-  CFX_ByteTextBuf sRet;
-  sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
-  return sRet.MakeString();
-}
-
-}  // namespace
-
 CFX_ByteString GetPDFWordString(IPVT_FontMap* pFontMap,
                                 int32_t nFontIndex,
                                 uint16_t Word,
@@ -61,144 +36,3 @@
   pPDFFont->AppendChar(sWord, Word);
   return sWord;
 }
-
-CFX_ByteString IFX_Edit::GetEditAppearanceStream(IFX_Edit* pEdit,
-                                                 const CFX_FloatPoint& ptOffset,
-                                                 const CPVT_WordRange* pRange,
-                                                 FX_BOOL bContinuous,
-                                                 uint16_t SubWord) {
-  IFX_Edit_Iterator* pIterator = pEdit->GetIterator();
-  if (pRange)
-    pIterator->SetAt(pRange->BeginPos);
-  else
-    pIterator->SetAt(0);
-
-  CFX_ByteTextBuf sEditStream;
-  CFX_ByteTextBuf sWords;
-  int32_t nCurFontIndex = -1;
-  CFX_FloatPoint ptOld(0.0f, 0.0f);
-  CFX_FloatPoint ptNew(0.0f, 0.0f);
-  CPVT_WordPlace oldplace;
-  while (pIterator->NextWord()) {
-    CPVT_WordPlace place = pIterator->GetAt();
-
-    if (pRange && place.WordCmp(pRange->EndPos) > 0)
-      break;
-
-    if (bContinuous) {
-      if (place.LineCmp(oldplace) != 0) {
-        if (sWords.GetSize() > 0) {
-          sEditStream << GetWordRenderString(sWords.MakeString());
-          sWords.Clear();
-        }
-
-        CPVT_Word word;
-        if (pIterator->GetWord(word)) {
-          ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x,
-                                 word.ptWord.y + ptOffset.y);
-        } else {
-          CPVT_Line line;
-          pIterator->GetLine(line);
-          ptNew = CFX_FloatPoint(line.ptLine.x + ptOffset.x,
-                                 line.ptLine.y + ptOffset.y);
-        }
-
-        if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
-          sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
-                      << " Td\n";
-
-          ptOld = ptNew;
-        }
-      }
-
-      CPVT_Word word;
-      if (pIterator->GetWord(word)) {
-        if (word.nFontIndex != nCurFontIndex) {
-          if (sWords.GetSize() > 0) {
-            sEditStream << GetWordRenderString(sWords.MakeString());
-            sWords.Clear();
-          }
-          sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
-                                          word.fFontSize);
-          nCurFontIndex = word.nFontIndex;
-        }
-
-        sWords << GetPDFWordString(pEdit->GetFontMap(), nCurFontIndex,
-                                   word.Word, SubWord);
-      }
-
-      oldplace = place;
-    } else {
-      CPVT_Word word;
-      if (pIterator->GetWord(word)) {
-        ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x,
-                               word.ptWord.y + ptOffset.y);
-
-        if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
-          sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
-                      << " Td\n";
-          ptOld = ptNew;
-        }
-
-        if (word.nFontIndex != nCurFontIndex) {
-          sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
-                                          word.fFontSize);
-          nCurFontIndex = word.nFontIndex;
-        }
-
-        sEditStream << GetWordRenderString(GetPDFWordString(
-            pEdit->GetFontMap(), nCurFontIndex, word.Word, SubWord));
-      }
-    }
-  }
-
-  if (sWords.GetSize() > 0) {
-    sEditStream << GetWordRenderString(sWords.MakeString());
-    sWords.Clear();
-  }
-
-  CFX_ByteTextBuf sAppStream;
-  if (sEditStream.GetSize() > 0) {
-    int32_t nHorzScale = pEdit->GetHorzScale();
-    if (nHorzScale != 100) {
-      sAppStream << nHorzScale << " Tz\n";
-    }
-
-    FX_FLOAT fCharSpace = pEdit->GetCharSpace();
-    if (!FX_EDIT_IsFloatZero(fCharSpace)) {
-      sAppStream << fCharSpace << " Tc\n";
-    }
-
-    sAppStream << sEditStream;
-  }
-
-  return sAppStream.MakeString();
-}
-
-CFX_ByteString IFX_Edit::GetSelectAppearanceStream(
-    IFX_Edit* pEdit,
-    const CFX_FloatPoint& ptOffset,
-    const CPVT_WordRange* pRange) {
-  if (!pRange || !pRange->IsExist())
-    return CFX_ByteString();
-
-  IFX_Edit_Iterator* pIterator = pEdit->GetIterator();
-  pIterator->SetAt(pRange->BeginPos);
-
-  CFX_ByteTextBuf sRet;
-  while (pIterator->NextWord()) {
-    CPVT_WordPlace place = pIterator->GetAt();
-    if (place.WordCmp(pRange->EndPos) > 0)
-      break;
-
-    CPVT_Word word;
-    CPVT_Line line;
-    if (pIterator->GetWord(word) && pIterator->GetLine(line)) {
-      sRet << word.ptWord.x + ptOffset.x << " "
-           << line.ptLine.y + line.fLineDescent << " " << word.fWidth << " "
-           << line.fLineAscent - line.fLineDescent << " re\nf\n";
-    }
-  }
-
-  return sRet.MakeString();
-}
diff --git a/fpdfsdk/fxedit/fxet_edit.cpp b/fpdfsdk/fxedit/fxet_edit.cpp
index 550dd1d..2125eb8 100644
--- a/fpdfsdk/fxedit/fxet_edit.cpp
+++ b/fpdfsdk/fxedit/fxet_edit.cpp
@@ -9,14 +9,183 @@
 #include <algorithm>
 
 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_pageobjectholder.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h"
+#include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h"
+#include "core/fpdfapi/fpdf_render/include/cpdf_textrenderer.h"
 #include "core/fpdfdoc/include/cpvt_section.h"
 #include "core/fpdfdoc/include/cpvt_word.h"
 #include "core/fpdfdoc/include/ipvt_fontmap.h"
+#include "core/fxge/include/fx_ge.h"
+#include "fpdfsdk/cfx_systemhandler.h"
+#include "fpdfsdk/fxedit/include/fx_edit.h"
+#include "fpdfsdk/fxedit/include/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_Edit.h"
+#include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
+
+#define PVTWORD_STYLE_UNDERLINE 0x0002L
+#define PVTWORD_STYLE_CROSSOUT 0x0004L
+#define PVTWORD_STYLE_BOLD 0x0020L
+#define PVTWORD_STYLE_ITALIC 0x0040L
 
 namespace {
 
 const int kEditUndoMaxItems = 10000;
 
+CFX_ByteString GetWordRenderString(const CFX_ByteString& strWords) {
+  if (strWords.GetLength() > 0)
+    return PDF_EncodeString(strWords) + " Tj\n";
+  return CFX_ByteString();
+}
+
+CFX_ByteString GetFontSetString(IPVT_FontMap* pFontMap,
+                                int32_t nFontIndex,
+                                FX_FLOAT fFontSize) {
+  if (!pFontMap)
+    return CFX_ByteString();
+
+  CFX_ByteString sFontAlias = pFontMap->GetPDFFontAlias(nFontIndex);
+  if (sFontAlias.GetLength() <= 0 || fFontSize <= 0)
+    return CFX_ByteString();
+
+  CFX_ByteTextBuf sRet;
+  sRet << "/" << sFontAlias << " " << fFontSize << " Tf\n";
+  return sRet.MakeString();
+}
+
+CFX_FloatRect GetUnderLineRect(const CPVT_Word& word) {
+  return CFX_FloatRect(word.ptWord.x, word.ptWord.y + word.fDescent * 0.5f,
+                       word.ptWord.x + word.fWidth,
+                       word.ptWord.y + word.fDescent * 0.25f);
+}
+
+CFX_FloatRect GetCrossoutRect(const CPVT_Word& word) {
+  return CFX_FloatRect(word.ptWord.x,
+                       word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f +
+                           word.fDescent * 0.25f,
+                       word.ptWord.x + word.fWidth,
+                       word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f);
+}
+
+void DrawTextString(CFX_RenderDevice* pDevice,
+                    const CFX_FloatPoint& pt,
+                    CPDF_Font* pFont,
+                    FX_FLOAT fFontSize,
+                    CFX_Matrix* pUser2Device,
+                    const CFX_ByteString& str,
+                    FX_ARGB crTextFill,
+                    FX_ARGB crTextStroke,
+                    int32_t nHorzScale) {
+  FX_FLOAT x = pt.x, y = pt.y;
+  pUser2Device->Transform(x, y);
+
+  if (pFont) {
+    if (nHorzScale != 100) {
+      CFX_Matrix mt(nHorzScale / 100.0f, 0, 0, 1, 0, 0);
+      mt.Concat(*pUser2Device);
+
+      CPDF_RenderOptions ro;
+      ro.m_Flags = RENDER_CLEARTYPE;
+      ro.m_ColorMode = RENDER_COLOR_NORMAL;
+
+      if (crTextStroke != 0) {
+        CFX_FloatPoint pt1(0, 0), pt2(1, 0);
+        pUser2Device->Transform(pt1.x, pt1.y);
+        pUser2Device->Transform(pt2.x, pt2.y);
+        CFX_GraphStateData gsd;
+        gsd.m_LineWidth =
+            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
+
+        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
+                                          str, crTextFill, crTextStroke, &gsd,
+                                          &ro);
+      } else {
+        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
+                                          str, crTextFill, 0, nullptr, &ro);
+      }
+    } else {
+      CPDF_RenderOptions ro;
+      ro.m_Flags = RENDER_CLEARTYPE;
+      ro.m_ColorMode = RENDER_COLOR_NORMAL;
+
+      if (crTextStroke != 0) {
+        CFX_FloatPoint pt1(0, 0), pt2(1, 0);
+        pUser2Device->Transform(pt1.x, pt1.y);
+        pUser2Device->Transform(pt2.x, pt2.y);
+        CFX_GraphStateData gsd;
+        gsd.m_LineWidth =
+            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
+
+        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
+                                          pUser2Device, str, crTextFill,
+                                          crTextStroke, &gsd, &ro);
+      } else {
+        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
+                                          pUser2Device, str, crTextFill, 0,
+                                          nullptr, &ro);
+      }
+    }
+  }
+}
+
+void AddRectToPageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                          FX_COLORREF crFill,
+                          const CFX_FloatRect& rcFill) {
+  std::unique_ptr<CPDF_PathObject> pPathObj(new CPDF_PathObject);
+  CFX_PathData* pPathData = pPathObj->m_Path.GetModify();
+  pPathData->AppendRect(rcFill.left, rcFill.bottom, rcFill.right, rcFill.top);
+
+  FX_FLOAT rgb[3];
+  rgb[0] = FXARGB_R(crFill) / 255.0f;
+  rgb[1] = FXARGB_G(crFill) / 255.0f;
+  rgb[2] = FXARGB_B(crFill) / 255.0f;
+  pPathObj->m_ColorState.SetFillColor(
+      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
+
+  pPathObj->m_FillType = FXFILL_ALTERNATE;
+  pPathObj->m_bStroke = FALSE;
+  pObjectHolder->GetPageObjectList()->push_back(std::move(pPathObj));
+}
+
+CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                         FX_COLORREF crText,
+                                         CPDF_Font* pFont,
+                                         FX_FLOAT fFontSize,
+                                         FX_FLOAT fCharSpace,
+                                         int32_t nHorzScale,
+                                         const CFX_FloatPoint& point,
+                                         const CFX_ByteString& text) {
+  std::unique_ptr<CPDF_TextObject> pTxtObj(new CPDF_TextObject);
+  CPDF_TextStateData* pTextStateData = pTxtObj->m_TextState.GetModify();
+  pTextStateData->m_pFont = pFont;
+  pTextStateData->m_FontSize = fFontSize;
+  pTextStateData->m_CharSpace = fCharSpace;
+  pTextStateData->m_WordSpace = 0;
+  pTextStateData->m_TextMode = TextRenderingMode::MODE_FILL;
+  pTextStateData->m_Matrix[0] = nHorzScale / 100.0f;
+  pTextStateData->m_Matrix[1] = 0;
+  pTextStateData->m_Matrix[2] = 0;
+  pTextStateData->m_Matrix[3] = 1;
+
+  FX_FLOAT rgb[3];
+  rgb[0] = FXARGB_R(crText) / 255.0f;
+  rgb[1] = FXARGB_G(crText) / 255.0f;
+  rgb[2] = FXARGB_B(crText) / 255.0f;
+  pTxtObj->m_ColorState.SetFillColor(
+      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
+  pTxtObj->m_ColorState.SetStrokeColor(
+      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
+
+  pTxtObj->SetPosition(point.x, point.y);
+  pTxtObj->SetText(text);
+
+  CPDF_TextObject* pRet = pTxtObj.get();
+  pObjectHolder->GetPageObjectList()->push_back(std::move(pTxtObj));
+  return pRet;
+}
+
 }  // namespace
 
 CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit* pEdit,
@@ -91,7 +260,7 @@
   return m_pVTIterator->GetAt();
 }
 
-IFX_Edit* CFX_Edit_Iterator::GetEdit() const {
+CFX_Edit* CFX_Edit_Iterator::GetEdit() const {
   return m_pEdit;
 }
 
@@ -645,8 +814,639 @@
   }
 }
 
-CFX_Edit::CFX_Edit(CPDF_VariableText* pVT)
-    : m_pVT(pVT),
+// static
+CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit,
+                                                 const CFX_FloatPoint& ptOffset,
+                                                 const CPVT_WordRange* pRange,
+                                                 FX_BOOL bContinuous,
+                                                 uint16_t SubWord) {
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (pRange)
+    pIterator->SetAt(pRange->BeginPos);
+  else
+    pIterator->SetAt(0);
+
+  CFX_ByteTextBuf sEditStream;
+  CFX_ByteTextBuf sWords;
+  int32_t nCurFontIndex = -1;
+  CFX_FloatPoint ptOld(0.0f, 0.0f);
+  CFX_FloatPoint ptNew(0.0f, 0.0f);
+  CPVT_WordPlace oldplace;
+  while (pIterator->NextWord()) {
+    CPVT_WordPlace place = pIterator->GetAt();
+
+    if (pRange && place.WordCmp(pRange->EndPos) > 0)
+      break;
+
+    if (bContinuous) {
+      if (place.LineCmp(oldplace) != 0) {
+        if (sWords.GetSize() > 0) {
+          sEditStream << GetWordRenderString(sWords.MakeString());
+          sWords.Clear();
+        }
+
+        CPVT_Word word;
+        if (pIterator->GetWord(word)) {
+          ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x,
+                                 word.ptWord.y + ptOffset.y);
+        } else {
+          CPVT_Line line;
+          pIterator->GetLine(line);
+          ptNew = CFX_FloatPoint(line.ptLine.x + ptOffset.x,
+                                 line.ptLine.y + ptOffset.y);
+        }
+
+        if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
+          sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
+                      << " Td\n";
+
+          ptOld = ptNew;
+        }
+      }
+
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        if (word.nFontIndex != nCurFontIndex) {
+          if (sWords.GetSize() > 0) {
+            sEditStream << GetWordRenderString(sWords.MakeString());
+            sWords.Clear();
+          }
+          sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
+                                          word.fFontSize);
+          nCurFontIndex = word.nFontIndex;
+        }
+
+        sWords << GetPDFWordString(pEdit->GetFontMap(), nCurFontIndex,
+                                   word.Word, SubWord);
+      }
+
+      oldplace = place;
+    } else {
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x,
+                               word.ptWord.y + ptOffset.y);
+
+        if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) {
+          sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y
+                      << " Td\n";
+          ptOld = ptNew;
+        }
+
+        if (word.nFontIndex != nCurFontIndex) {
+          sEditStream << GetFontSetString(pEdit->GetFontMap(), word.nFontIndex,
+                                          word.fFontSize);
+          nCurFontIndex = word.nFontIndex;
+        }
+
+        sEditStream << GetWordRenderString(GetPDFWordString(
+            pEdit->GetFontMap(), nCurFontIndex, word.Word, SubWord));
+      }
+    }
+  }
+
+  if (sWords.GetSize() > 0) {
+    sEditStream << GetWordRenderString(sWords.MakeString());
+    sWords.Clear();
+  }
+
+  CFX_ByteTextBuf sAppStream;
+  if (sEditStream.GetSize() > 0) {
+    int32_t nHorzScale = pEdit->GetHorzScale();
+    if (nHorzScale != 100) {
+      sAppStream << nHorzScale << " Tz\n";
+    }
+
+    FX_FLOAT fCharSpace = pEdit->GetCharSpace();
+    if (!FX_EDIT_IsFloatZero(fCharSpace)) {
+      sAppStream << fCharSpace << " Tc\n";
+    }
+
+    sAppStream << sEditStream;
+  }
+
+  return sAppStream.MakeString();
+}
+
+// static
+CFX_ByteString CFX_Edit::GetSelectAppearanceStream(
+    CFX_Edit* pEdit,
+    const CFX_FloatPoint& ptOffset,
+    const CPVT_WordRange* pRange) {
+  if (!pRange || !pRange->IsExist())
+    return CFX_ByteString();
+
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  pIterator->SetAt(pRange->BeginPos);
+
+  CFX_ByteTextBuf sRet;
+  while (pIterator->NextWord()) {
+    CPVT_WordPlace place = pIterator->GetAt();
+    if (place.WordCmp(pRange->EndPos) > 0)
+      break;
+
+    CPVT_Word word;
+    CPVT_Line line;
+    if (pIterator->GetWord(word) && pIterator->GetLine(line)) {
+      sRet << word.ptWord.x + ptOffset.x << " "
+           << line.ptLine.y + line.fLineDescent << " " << word.fWidth << " "
+           << line.fLineAscent - line.fLineDescent << " re\nf\n";
+    }
+  }
+
+  return sRet.MakeString();
+}
+
+// static
+void CFX_Edit::DrawUnderline(CFX_RenderDevice* pDevice,
+                             CFX_Matrix* pUser2Device,
+                             CFX_Edit* pEdit,
+                             FX_COLORREF color,
+                             const CFX_FloatRect& rcClip,
+                             const CFX_FloatPoint& ptOffset,
+                             const CPVT_WordRange* pRange) {
+  pDevice->SaveState();
+
+  if (!rcClip.IsEmpty()) {
+    CFX_FloatRect rcTemp = rcClip;
+    pUser2Device->TransformRect(rcTemp);
+    pDevice->SetClip_Rect(rcTemp.ToFxRect());
+  }
+
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (pEdit->GetFontMap()) {
+    if (pRange)
+      pIterator->SetAt(pRange->BeginPos);
+    else
+      pIterator->SetAt(0);
+
+    while (pIterator->NextWord()) {
+      CPVT_WordPlace place = pIterator->GetAt();
+      if (pRange && place.WordCmp(pRange->EndPos) > 0)
+        break;
+
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        CFX_PathData pathUnderline;
+        CFX_FloatRect rcUnderline = GetUnderLineRect(word);
+        rcUnderline.left += ptOffset.x;
+        rcUnderline.right += ptOffset.x;
+        rcUnderline.top += ptOffset.y;
+        rcUnderline.bottom += ptOffset.y;
+        pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom,
+                                 rcUnderline.right, rcUnderline.top);
+
+        pDevice->DrawPath(&pathUnderline, pUser2Device, nullptr, color, 0,
+                          FXFILL_WINDING);
+      }
+    }
+  }
+
+  pDevice->RestoreState(false);
+}
+
+// static
+void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice,
+                        CFX_Matrix* pUser2Device,
+                        CFX_Edit* pEdit,
+                        FX_COLORREF crTextFill,
+                        FX_COLORREF crTextStroke,
+                        const CFX_FloatRect& rcClip,
+                        const CFX_FloatPoint& ptOffset,
+                        const CPVT_WordRange* pRange,
+                        CFX_SystemHandler* pSystemHandler,
+                        void* pFFLData) {
+  const bool bContinuous =
+      pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
+  uint16_t SubWord = pEdit->GetPasswordChar();
+  FX_FLOAT fFontSize = pEdit->GetFontSize();
+  CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
+  int32_t nHorzScale = pEdit->GetHorzScale();
+
+  FX_COLORREF crCurFill = crTextFill;
+  FX_COLORREF crOldFill = crCurFill;
+
+  FX_BOOL bSelect = FALSE;
+  const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
+  const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
+
+  CFX_ByteTextBuf sTextBuf;
+  int32_t nFontIndex = -1;
+  CFX_FloatPoint ptBT(0.0f, 0.0f);
+
+  pDevice->SaveState();
+
+  if (!rcClip.IsEmpty()) {
+    CFX_FloatRect rcTemp = rcClip;
+    pUser2Device->TransformRect(rcTemp);
+    pDevice->SetClip_Rect(rcTemp.ToFxRect());
+  }
+
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
+    if (pRange)
+      pIterator->SetAt(pRange->BeginPos);
+    else
+      pIterator->SetAt(0);
+
+    CPVT_WordPlace oldplace;
+    while (pIterator->NextWord()) {
+      CPVT_WordPlace place = pIterator->GetAt();
+      if (pRange && place.WordCmp(pRange->EndPos) > 0)
+        break;
+
+      if (wrSelect.IsExist()) {
+        bSelect = place.WordCmp(wrSelect.BeginPos) > 0 &&
+                  place.WordCmp(wrSelect.EndPos) <= 0;
+        crCurFill = bSelect ? crWhite : crTextFill;
+      }
+      if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
+        crCurFill = crTextFill;
+        crOldFill = crCurFill;
+      }
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        if (bSelect) {
+          CPVT_Line line;
+          pIterator->GetLine(line);
+
+          if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
+            CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
+                             word.ptWord.x + word.fWidth,
+                             line.ptLine.y + line.fLineAscent);
+            rc.Intersect(rcClip);
+            pSystemHandler->OutputSelectedRect(pFFLData, rc);
+          } else {
+            CFX_PathData pathSelBK;
+            pathSelBK.AppendRect(
+                word.ptWord.x, line.ptLine.y + line.fLineDescent,
+                word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent);
+
+            pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
+                              FXFILL_WINDING);
+          }
+        }
+
+        if (bContinuous) {
+          if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
+              crOldFill != crCurFill) {
+            if (sTextBuf.GetLength() > 0) {
+              DrawTextString(
+                  pDevice,
+                  CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+                  pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
+                  sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);
+
+              sTextBuf.Clear();
+            }
+            nFontIndex = word.nFontIndex;
+            ptBT = word.ptWord;
+            crOldFill = crCurFill;
+          }
+
+          sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word,
+                                       SubWord)
+                          .AsStringC();
+        } else {
+          DrawTextString(
+              pDevice, CFX_FloatPoint(word.ptWord.x + ptOffset.x,
+                                      word.ptWord.y + ptOffset.y),
+              pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
+              GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord),
+              crCurFill, crTextStroke, nHorzScale);
+        }
+        oldplace = place;
+      }
+    }
+
+    if (sTextBuf.GetLength() > 0) {
+      DrawTextString(
+          pDevice, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+          pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
+          sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);
+    }
+  }
+
+  pDevice->RestoreState(false);
+}
+
+// static
+void CFX_Edit::DrawRichEdit(CFX_RenderDevice* pDevice,
+                            CFX_Matrix* pUser2Device,
+                            CFX_Edit* pEdit,
+                            const CFX_FloatRect& rcClip,
+                            const CFX_FloatPoint& ptOffset,
+                            const CPVT_WordRange* pRange) {
+  CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
+
+  FX_COLORREF crCurText = ArgbEncode(255, 0, 0, 0);
+  FX_COLORREF crOld = crCurText;
+  FX_BOOL bSelect = FALSE;
+  const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
+  const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
+
+  CFX_ByteTextBuf sTextBuf;
+  CPVT_WordProps wp;
+  CFX_FloatPoint ptBT(0.0f, 0.0f);
+
+  pDevice->SaveState();
+
+  if (!rcClip.IsEmpty()) {
+    CFX_FloatRect rcTemp = rcClip;
+    pUser2Device->TransformRect(rcTemp);
+    pDevice->SetClip_Rect(rcTemp.ToFxRect());
+  }
+
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
+    if (pRange)
+      pIterator->SetAt(pRange->BeginPos);
+    else
+      pIterator->SetAt(0);
+
+    CPVT_WordPlace oldplace;
+
+    while (pIterator->NextWord()) {
+      CPVT_WordPlace place = pIterator->GetAt();
+      if (pRange && place.WordCmp(pRange->EndPos) > 0)
+        break;
+
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        word.WordProps.fFontSize = word.fFontSize;
+
+        crCurText = ArgbEncode(255, word.WordProps.dwWordColor);
+
+        if (wrSelect.IsExist()) {
+          bSelect = place.WordCmp(wrSelect.BeginPos) > 0 &&
+                    place.WordCmp(wrSelect.EndPos) <= 0;
+          if (bSelect) {
+            crCurText = crWhite;
+          }
+        }
+
+        if (bSelect) {
+          CPVT_Line line;
+          pIterator->GetLine(line);
+
+          CFX_PathData pathSelBK;
+          pathSelBK.AppendRect(word.ptWord.x + ptOffset.x,
+                               line.ptLine.y + line.fLineDescent + ptOffset.y,
+                               word.ptWord.x + word.fWidth + ptOffset.x,
+                               line.ptLine.y + line.fLineAscent + ptOffset.y);
+
+          pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
+                            FXFILL_WINDING);
+        }
+
+        if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f ||
+            word.WordProps.nHorzScale != 100 ||
+            FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 ||
+            crOld != crCurText) {
+          if (sTextBuf.GetLength() > 0) {
+            DrawTextString(
+                pDevice,
+                CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+                pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, pUser2Device,
+                sTextBuf.MakeString(), crOld, 0, wp.nHorzScale);
+
+            sTextBuf.Clear();
+          }
+          wp = word.WordProps;
+          ptBT = word.ptWord;
+          crOld = crCurText;
+        }
+
+        sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex,
+                                     word.Word, 0)
+                        .AsStringC();
+
+        if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) {
+          CFX_PathData pathUnderline;
+          CFX_FloatRect rcUnderline = GetUnderLineRect(word);
+          pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom,
+                                   rcUnderline.right, rcUnderline.top);
+
+          pDevice->DrawPath(&pathUnderline, pUser2Device, nullptr, crCurText, 0,
+                            FXFILL_WINDING);
+        }
+
+        if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) {
+          CFX_PathData pathCrossout;
+          CFX_FloatRect rcCrossout = GetCrossoutRect(word);
+          pathCrossout.AppendRect(rcCrossout.left, rcCrossout.bottom,
+                                  rcCrossout.right, rcCrossout.top);
+
+          pDevice->DrawPath(&pathCrossout, pUser2Device, nullptr, crCurText, 0,
+                            FXFILL_WINDING);
+        }
+
+        oldplace = place;
+      }
+    }
+
+    if (sTextBuf.GetLength() > 0) {
+      DrawTextString(
+          pDevice, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+          pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, pUser2Device,
+          sTextBuf.MakeString(), crOld, 0, wp.nHorzScale);
+    }
+  }
+
+  pDevice->RestoreState(false);
+}
+
+// static
+void CFX_Edit::GeneratePageObjects(
+    CPDF_PageObjectHolder* pObjectHolder,
+    CFX_Edit* pEdit,
+    const CFX_FloatPoint& ptOffset,
+    const CPVT_WordRange* pRange,
+    FX_COLORREF crText,
+    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
+  FX_FLOAT fFontSize = pEdit->GetFontSize();
+
+  int32_t nOldFontIndex = -1;
+
+  CFX_ByteTextBuf sTextBuf;
+  CFX_FloatPoint ptBT(0.0f, 0.0f);
+
+  ObjArray.RemoveAll();
+
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
+    if (pRange)
+      pIterator->SetAt(pRange->BeginPos);
+    else
+      pIterator->SetAt(0);
+
+    CPVT_WordPlace oldplace;
+
+    while (pIterator->NextWord()) {
+      CPVT_WordPlace place = pIterator->GetAt();
+      if (pRange && place.WordCmp(pRange->EndPos) > 0)
+        break;
+
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex) {
+          if (sTextBuf.GetLength() > 0) {
+            ObjArray.Add(AddTextObjToPageObjects(
+                pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex),
+                fFontSize, 0.0f, 100,
+                CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+                sTextBuf.MakeString()));
+
+            sTextBuf.Clear();
+          }
+
+          ptBT = word.ptWord;
+          nOldFontIndex = word.nFontIndex;
+        }
+
+        sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0)
+                        .AsStringC();
+        oldplace = place;
+      }
+    }
+
+    if (sTextBuf.GetLength() > 0) {
+      ObjArray.Add(AddTextObjToPageObjects(
+          pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize,
+          0.0f, 100, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+          sTextBuf.MakeString()));
+    }
+  }
+}
+
+// static
+void CFX_Edit::GenerateRichPageObjects(
+    CPDF_PageObjectHolder* pObjectHolder,
+    CFX_Edit* pEdit,
+    const CFX_FloatPoint& ptOffset,
+    const CPVT_WordRange* pRange,
+    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
+  FX_COLORREF crCurText = ArgbEncode(255, 0, 0, 0);
+  FX_COLORREF crOld = crCurText;
+
+  CFX_ByteTextBuf sTextBuf;
+  CPVT_WordProps wp;
+  CFX_FloatPoint ptBT(0.0f, 0.0f);
+
+  ObjArray.RemoveAll();
+
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
+    if (pRange)
+      pIterator->SetAt(pRange->BeginPos);
+    else
+      pIterator->SetAt(0);
+
+    CPVT_WordPlace oldplace;
+
+    while (pIterator->NextWord()) {
+      CPVT_WordPlace place = pIterator->GetAt();
+      if (pRange && place.WordCmp(pRange->EndPos) > 0)
+        break;
+
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        word.WordProps.fFontSize = word.fFontSize;
+
+        crCurText = ArgbEncode(255, word.WordProps.dwWordColor);
+
+        if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f ||
+            word.WordProps.nHorzScale != 100 ||
+            FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 ||
+            crOld != crCurText) {
+          if (sTextBuf.GetLength() > 0) {
+            ObjArray.Add(AddTextObjToPageObjects(
+                pObjectHolder, crOld, pFontMap->GetPDFFont(wp.nFontIndex),
+                wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
+                CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+                sTextBuf.MakeString()));
+
+            sTextBuf.Clear();
+          }
+
+          wp = word.WordProps;
+          ptBT = word.ptWord;
+          crOld = crCurText;
+        }
+
+        sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex,
+                                     word.Word, 0)
+                        .AsStringC();
+
+        if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) {
+          CFX_FloatRect rcUnderline = GetUnderLineRect(word);
+          rcUnderline.left += ptOffset.x;
+          rcUnderline.right += ptOffset.x;
+          rcUnderline.top += ptOffset.y;
+          rcUnderline.bottom += ptOffset.y;
+
+          AddRectToPageObjects(pObjectHolder, crCurText, rcUnderline);
+        }
+
+        if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) {
+          CFX_FloatRect rcCrossout = GetCrossoutRect(word);
+          rcCrossout.left += ptOffset.x;
+          rcCrossout.right += ptOffset.x;
+          rcCrossout.top += ptOffset.y;
+          rcCrossout.bottom += ptOffset.y;
+
+          AddRectToPageObjects(pObjectHolder, crCurText, rcCrossout);
+        }
+
+        oldplace = place;
+      }
+    }
+
+    if (sTextBuf.GetLength() > 0) {
+      ObjArray.Add(AddTextObjToPageObjects(
+          pObjectHolder, crOld, pFontMap->GetPDFFont(wp.nFontIndex),
+          wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
+          CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
+          sTextBuf.MakeString()));
+    }
+  }
+}
+
+// static
+void CFX_Edit::GenerateUnderlineObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                        CFX_Edit* pEdit,
+                                        const CFX_FloatPoint& ptOffset,
+                                        const CPVT_WordRange* pRange,
+                                        FX_COLORREF color) {
+  CFX_Edit_Iterator* pIterator = pEdit->GetIterator();
+  if (pEdit->GetFontMap()) {
+    if (pRange)
+      pIterator->SetAt(pRange->BeginPos);
+    else
+      pIterator->SetAt(0);
+
+    CPVT_WordPlace oldplace;
+
+    while (pIterator->NextWord()) {
+      CPVT_WordPlace place = pIterator->GetAt();
+      if (pRange && place.WordCmp(pRange->EndPos) > 0)
+        break;
+
+      CPVT_Word word;
+      if (pIterator->GetWord(word)) {
+        CFX_FloatRect rcUnderline = GetUnderLineRect(word);
+        rcUnderline.left += ptOffset.x;
+        rcUnderline.right += ptOffset.x;
+        rcUnderline.top += ptOffset.y;
+        rcUnderline.bottom += ptOffset.y;
+        AddRectToPageObjects(pObjectHolder, color, rcUnderline);
+      }
+    }
+  }
+}
+
+CFX_Edit::CFX_Edit()
+    : m_pVT(new CPDF_VariableText),
       m_pNotify(nullptr),
       m_pOprNotify(nullptr),
       m_wpCaret(-1, -1, -1),
@@ -664,9 +1464,7 @@
       m_rcOldContent(0.0f, 0.0f, 0.0f, 0.0f),
       m_bEnableUndo(TRUE),
       m_bOprNotify(FALSE),
-      m_pGroupUndoItem(nullptr) {
-  ASSERT(pVT);
-}
+      m_pGroupUndoItem(nullptr) {}
 
 CFX_Edit::~CFX_Edit() {
   ASSERT(!m_pGroupUndoItem);
@@ -683,22 +1481,22 @@
   m_pVT->SetProvider(m_pVTProvider.get());
 }
 
-void CFX_Edit::SetNotify(IFX_Edit_Notify* pNotify) {
+void CFX_Edit::SetNotify(CPWL_EditCtrl* pNotify) {
   m_pNotify = pNotify;
 }
 
-void CFX_Edit::SetOprNotify(IFX_Edit_OprNotify* pOprNotify) {
+void CFX_Edit::SetOprNotify(CPWL_Edit* pOprNotify) {
   m_pOprNotify = pOprNotify;
 }
 
-IFX_Edit_Iterator* CFX_Edit::GetIterator() {
+CFX_Edit_Iterator* CFX_Edit::GetIterator() {
   if (!m_pIterator)
     m_pIterator.reset(new CFX_Edit_Iterator(this, m_pVT->GetIterator()));
   return m_pIterator.get();
 }
 
 CPDF_VariableText* CFX_Edit::GetVariableText() {
-  return m_pVT;
+  return m_pVT.get();
 }
 
 IPVT_FontMap* CFX_Edit::GetFontMap() {
@@ -1202,10 +2000,6 @@
 
     if (!m_bNotifyFlag) {
       m_bNotifyFlag = TRUE;
-      m_pNotify->IOnSetScrollInfoX(rcPlate.left, rcPlate.right, rcContent.left,
-                                   rcContent.right, rcPlate.Width() / 3,
-                                   rcPlate.Width());
-
       m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
                                    rcContent.bottom, rcContent.top,
                                    rcPlate.Height() / 3, rcPlate.Height());
@@ -1222,14 +2016,6 @@
     if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.x, fx)) {
       m_ptScrollPos.x = fx;
       Refresh(RP_NOANALYSE);
-
-      if (m_pNotify) {
-        if (!m_bNotifyFlag) {
-          m_bNotifyFlag = TRUE;
-          m_pNotify->IOnSetScrollPosX(fx);
-          m_bNotifyFlag = FALSE;
-        }
-      }
     }
   }
 }
@@ -1810,8 +2596,6 @@
   DoInsertText(CPVT_WordPlace(0, 0, -1), text, charset, pSecProps, pWordProps);
   if (bPaint)
     Paint();
-  if (m_bOprNotify && m_pOprNotify)
-    m_pOprNotify->OnSetText(m_wpCaret, m_wpOldCaret);
 }
 
 FX_BOOL CFX_Edit::InsertWord(uint16_t word,
diff --git a/fpdfsdk/fxedit/fxet_list.cpp b/fpdfsdk/fxedit/fxet_list.cpp
index 662a64b..b4d5473 100644
--- a/fpdfsdk/fxedit/fxet_list.cpp
+++ b/fpdfsdk/fxedit/fxet_list.cpp
@@ -8,9 +8,10 @@
 
 #include "core/fpdfdoc/include/cpvt_word.h"
 #include "fpdfsdk/fxedit/include/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/PWL_ListBox.h"
 
 CFX_ListItem::CFX_ListItem()
-    : m_pEdit(IFX_Edit::NewEdit()),
+    : m_pEdit(new CFX_Edit),
       m_bSelected(FALSE),
       m_rcListItem(0.0f, 0.0f, 0.0f, 0.0f) {
   m_pEdit->SetAlignmentV(1);
@@ -18,18 +19,17 @@
 }
 
 CFX_ListItem::~CFX_ListItem() {
-  IFX_Edit::DelEdit(m_pEdit);
 }
 
 void CFX_ListItem::SetFontMap(IPVT_FontMap* pFontMap) {
   m_pEdit->SetFontMap(pFontMap);
 }
 
-IFX_Edit* CFX_ListItem::GetEdit() const {
-  return m_pEdit;
+CFX_Edit* CFX_ListItem::GetEdit() const {
+  return m_pEdit.get();
 }
 
-IFX_Edit_Iterator* CFX_ListItem::GetIterator() const {
+CFX_Edit_Iterator* CFX_ListItem::GetIterator() const {
   return m_pEdit->GetIterator();
 }
 
@@ -63,7 +63,7 @@
 
 uint16_t CFX_ListItem::GetFirstChar() const {
   CPVT_Word word;
-  IFX_Edit_Iterator* pIterator = GetIterator();
+  CFX_Edit_Iterator* pIterator = GetIterator();
   pIterator->SetAt(1);
   pIterator->GetWord(word);
   return word.Word;
@@ -81,203 +81,6 @@
   m_rcPlate = rect;
 }
 
-CFX_List::CFX_List()
-    : m_fFontSize(0.0f), m_pFontMap(nullptr), m_bMultiple(FALSE) {}
-
-CFX_List::~CFX_List() {
-  Empty();
-}
-
-void CFX_List::Empty() {
-  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++)
-    delete m_aListItems.GetAt(i);
-
-  m_aListItems.RemoveAll();
-}
-
-void CFX_List::SetFontMap(IPVT_FontMap* pFontMap) {
-  m_pFontMap = pFontMap;
-}
-
-void CFX_List::SetFontSize(FX_FLOAT fFontSize) {
-  m_fFontSize = fFontSize;
-}
-
-void CFX_List::AddItem(const FX_WCHAR* str) {
-  CFX_ListItem* pListItem = new CFX_ListItem();
-  pListItem->SetFontMap(m_pFontMap);
-  pListItem->SetFontSize(m_fFontSize);
-  pListItem->SetText(str);
-  m_aListItems.Add(pListItem);
-}
-
-void CFX_List::ReArrange(int32_t nItemIndex) {
-  FX_FLOAT fPosY = 0.0f;
-
-  if (CFX_ListItem* pPrevItem = m_aListItems.GetAt(nItemIndex - 1))
-    fPosY = pPrevItem->GetRect().bottom;
-
-  for (int32_t i = nItemIndex, sz = m_aListItems.GetSize(); i < sz; i++) {
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
-      FX_FLOAT fListItemHeight = pListItem->GetItemHeight();
-      pListItem->SetRect(CLST_Rect(0.0f, fPosY, 0.0f, fPosY + fListItemHeight));
-      fPosY += fListItemHeight;
-    }
-  }
-
-  SetContentRect(CLST_Rect(0.0f, 0.0f, 0.0f, fPosY));
-}
-
-IFX_Edit* CFX_List::GetItemEdit(int32_t nIndex) const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
-    return pListItem->GetEdit();
-  }
-
-  return nullptr;
-}
-
-int32_t CFX_List::GetCount() const {
-  return m_aListItems.GetSize();
-}
-
-CFX_FloatRect CFX_List::GetPlateRect() const {
-  return CFX_ListContainer::GetPlateRect();
-}
-
-CFX_FloatRect CFX_List::GetContentRect() const {
-  return InnerToOuter(CFX_ListContainer::GetContentRect());
-}
-
-FX_FLOAT CFX_List::GetFontSize() const {
-  return m_fFontSize;
-}
-
-int32_t CFX_List::GetItemIndex(const CFX_FloatPoint& point) const {
-  CFX_FloatPoint pt = OuterToInner(point);
-
-  FX_BOOL bFirst = TRUE;
-  FX_BOOL bLast = TRUE;
-
-  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
-      CLST_Rect rcListItem = pListItem->GetRect();
-
-      if (FX_EDIT_IsFloatBigger(pt.y, rcListItem.top)) {
-        bFirst = FALSE;
-      }
-
-      if (FX_EDIT_IsFloatSmaller(pt.y, rcListItem.bottom)) {
-        bLast = FALSE;
-      }
-
-      if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) {
-        return i;
-      }
-    }
-  }
-
-  if (bFirst)
-    return 0;
-  if (bLast)
-    return m_aListItems.GetSize() - 1;
-
-  return -1;
-}
-
-FX_FLOAT CFX_List::GetFirstHeight() const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(0)) {
-    return pListItem->GetItemHeight();
-  }
-
-  return 1.0f;
-}
-
-int32_t CFX_List::GetFirstSelected() const {
-  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
-      if (pListItem->IsSelected())
-        return i;
-    }
-  }
-  return -1;
-}
-
-int32_t CFX_List::GetLastSelected() const {
-  for (int32_t i = m_aListItems.GetSize() - 1; i >= 0; i--) {
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
-      if (pListItem->IsSelected())
-        return i;
-    }
-  }
-  return -1;
-}
-
-FX_WCHAR CFX_List::Toupper(FX_WCHAR c) const {
-  if ((c >= 'a') && (c <= 'z'))
-    c = c - ('a' - 'A');
-  return c;
-}
-
-int32_t CFX_List::FindNext(int32_t nIndex, FX_WCHAR nChar) const {
-  int32_t nCircleIndex = nIndex;
-
-  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
-    nCircleIndex++;
-    if (nCircleIndex >= sz)
-      nCircleIndex = 0;
-
-    if (CFX_ListItem* pListItem = m_aListItems.GetAt(nCircleIndex)) {
-      if (Toupper(pListItem->GetFirstChar()) == Toupper(nChar))
-        return nCircleIndex;
-    }
-  }
-
-  return nCircleIndex;
-}
-
-CFX_FloatRect CFX_List::GetItemRect(int32_t nIndex) const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
-    CFX_FloatRect rcItem = pListItem->GetRect();
-    rcItem.left = 0.0f;
-    rcItem.right = GetPlateRect().Width();
-    return InnerToOuter(CLST_Rect(rcItem));
-  }
-
-  return CFX_FloatRect();
-}
-
-FX_BOOL CFX_List::IsItemSelected(int32_t nIndex) const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex))
-    return pListItem->IsSelected();
-  return FALSE;
-}
-
-void CFX_List::SetItemSelect(int32_t nItemIndex, FX_BOOL bSelected) {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
-    pListItem->SetSelect(bSelected);
-  }
-}
-
-void CFX_List::SetMultipleSel(FX_BOOL bMultiple) {
-  m_bMultiple = bMultiple;
-}
-
-FX_BOOL CFX_List::IsMultipleSel() const {
-  return m_bMultiple;
-}
-
-FX_BOOL CFX_List::IsValid(int32_t nItemIndex) const {
-  return nItemIndex >= 0 && nItemIndex < m_aListItems.GetSize();
-}
-
-CFX_WideString CFX_List::GetItemText(int32_t nIndex) const {
-  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
-    return pListItem->GetText();
-  }
-
-  return L"";
-}
-
 CPLST_Select::CPLST_Select() {}
 
 CPLST_Select::~CPLST_Select() {
@@ -392,11 +195,16 @@
       m_nSelItem(-1),
       m_nFootIndex(-1),
       m_bCtrlSel(FALSE),
-      m_nCaretIndex(-1) {}
+      m_nCaretIndex(-1),
+      m_fFontSize(0.0f),
+      m_pFontMap(nullptr),
+      m_bMultiple(FALSE) {}
 
-CFX_ListCtrl::~CFX_ListCtrl() {}
+CFX_ListCtrl::~CFX_ListCtrl() {
+  Empty();
+}
 
-void CFX_ListCtrl::SetNotify(IFX_List_Notify* pNotify) {
+void CFX_ListCtrl::SetNotify(CPWL_List_Notify* pNotify) {
   m_pNotify = pNotify;
 }
 
@@ -566,7 +374,18 @@
 }
 
 CFX_FloatRect CFX_ListCtrl::GetItemRect(int32_t nIndex) const {
-  return InToOut(CFX_List::GetItemRect(nIndex));
+  return InToOut(GetItemRectInternal(nIndex));
+}
+
+CFX_FloatRect CFX_ListCtrl::GetItemRectInternal(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    CFX_FloatRect rcItem = pListItem->GetRect();
+    rcItem.left = 0.0f;
+    rcItem.right = GetPlateRect().Width();
+    return InnerToOuter(CLST_Rect(rcItem));
+  }
+
+  return CFX_FloatRect();
 }
 
 int32_t CFX_ListCtrl::GetCaret() const {
@@ -695,7 +514,7 @@
     return;
 
   CFX_FloatRect rcPlate = GetPlateRect();
-  CFX_FloatRect rcItem = CFX_List::GetItemRect(nItemIndex);
+  CFX_FloatRect rcItem = GetItemRectInternal(nItemIndex);
   CFX_FloatRect rcItemCtrl = GetItemRect(nItemIndex);
 
   if (FX_EDIT_IsFloatSmaller(rcItemCtrl.bottom, rcPlate.bottom)) {
@@ -712,7 +531,7 @@
 void CFX_ListCtrl::SetScrollInfo() {
   if (m_pNotify) {
     CFX_FloatRect rcPlate = GetPlateRect();
-    CFX_FloatRect rcContent = CFX_List::GetContentRect();
+    CFX_FloatRect rcContent = GetContentRectInternal();
 
     if (!m_bNotifyFlag) {
       m_bNotifyFlag = TRUE;
@@ -731,7 +550,7 @@
 void CFX_ListCtrl::SetScrollPosY(FX_FLOAT fy) {
   if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y, fy)) {
     CFX_FloatRect rcPlate = GetPlateRect();
-    CFX_FloatRect rcContent = CFX_List::GetContentRect();
+    CFX_FloatRect rcContent = GetContentRectInternal();
 
     if (rcPlate.Height() > rcContent.Height()) {
       fy = rcPlate.top;
@@ -756,19 +575,36 @@
   }
 }
 
+CFX_FloatRect CFX_ListCtrl::GetContentRectInternal() const {
+  return InnerToOuter(CFX_ListContainer::GetContentRect());
+}
+
 CFX_FloatRect CFX_ListCtrl::GetContentRect() const {
-  return InToOut(CFX_List::GetContentRect());
+  return InToOut(GetContentRectInternal());
 }
 
 void CFX_ListCtrl::ReArrange(int32_t nItemIndex) {
-  CFX_List::ReArrange(nItemIndex);
+  FX_FLOAT fPosY = 0.0f;
+
+  if (CFX_ListItem* pPrevItem = m_aListItems.GetAt(nItemIndex - 1))
+    fPosY = pPrevItem->GetRect().bottom;
+
+  for (int32_t i = nItemIndex, sz = m_aListItems.GetSize(); i < sz; i++) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      FX_FLOAT fListItemHeight = pListItem->GetItemHeight();
+      pListItem->SetRect(CLST_Rect(0.0f, fPosY, 0.0f, fPosY + fListItemHeight));
+      fPosY += fListItemHeight;
+    }
+  }
+
+  SetContentRect(CLST_Rect(0.0f, 0.0f, 0.0f, fPosY));
   SetScrollInfo();
 }
 
 void CFX_ListCtrl::SetTopItem(int32_t nIndex) {
   if (IsValid(nIndex)) {
     GetPlateRect();
-    CFX_FloatRect rcItem = CFX_List::GetItemRect(nIndex);
+    CFX_FloatRect rcItem = GetItemRectInternal(nIndex);
     SetScrollPosY(rcItem.top);
   }
 }
@@ -783,7 +619,11 @@
 }
 
 void CFX_ListCtrl::Empty() {
-  CFX_List::Empty();
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++)
+    delete m_aListItems.GetAt(i);
+
+  m_aListItems.RemoveAll();
+
   InvalidateItem(-1);
 }
 
@@ -792,7 +632,35 @@
 }
 
 int32_t CFX_ListCtrl::GetItemIndex(const CFX_FloatPoint& point) const {
-  return CFX_List::GetItemIndex(OutToIn(point));
+  CFX_FloatPoint pt = OuterToInner(OutToIn(point));
+
+  FX_BOOL bFirst = TRUE;
+  FX_BOOL bLast = TRUE;
+
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      CLST_Rect rcListItem = pListItem->GetRect();
+
+      if (FX_EDIT_IsFloatBigger(pt.y, rcListItem.top)) {
+        bFirst = FALSE;
+      }
+
+      if (FX_EDIT_IsFloatSmaller(pt.y, rcListItem.bottom)) {
+        bLast = FALSE;
+      }
+
+      if (pt.y >= rcListItem.top && pt.y < rcListItem.bottom) {
+        return i;
+      }
+    }
+  }
+
+  if (bFirst)
+    return 0;
+  if (bLast)
+    return m_aListItems.GetSize() - 1;
+
+  return -1;
 }
 
 CFX_WideString CFX_ListCtrl::GetText() const {
@@ -800,3 +668,122 @@
     return GetItemText(m_nCaretIndex);
   return GetItemText(m_nSelItem);
 }
+
+void CFX_ListCtrl::SetFontMap(IPVT_FontMap* pFontMap) {
+  m_pFontMap = pFontMap;
+}
+
+void CFX_ListCtrl::SetFontSize(FX_FLOAT fFontSize) {
+  m_fFontSize = fFontSize;
+}
+
+void CFX_ListCtrl::AddItem(const FX_WCHAR* str) {
+  CFX_ListItem* pListItem = new CFX_ListItem();
+  pListItem->SetFontMap(m_pFontMap);
+  pListItem->SetFontSize(m_fFontSize);
+  pListItem->SetText(str);
+  m_aListItems.Add(pListItem);
+}
+
+CFX_Edit* CFX_ListCtrl::GetItemEdit(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    return pListItem->GetEdit();
+  }
+
+  return nullptr;
+}
+
+int32_t CFX_ListCtrl::GetCount() const {
+  return m_aListItems.GetSize();
+}
+
+CFX_FloatRect CFX_ListCtrl::GetPlateRect() const {
+  return CFX_ListContainer::GetPlateRect();
+}
+
+FX_FLOAT CFX_ListCtrl::GetFontSize() const {
+  return m_fFontSize;
+}
+
+FX_FLOAT CFX_ListCtrl::GetFirstHeight() const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(0)) {
+    return pListItem->GetItemHeight();
+  }
+
+  return 1.0f;
+}
+
+int32_t CFX_ListCtrl::GetFirstSelected() const {
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      if (pListItem->IsSelected())
+        return i;
+    }
+  }
+  return -1;
+}
+
+int32_t CFX_ListCtrl::GetLastSelected() const {
+  for (int32_t i = m_aListItems.GetSize() - 1; i >= 0; i--) {
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(i)) {
+      if (pListItem->IsSelected())
+        return i;
+    }
+  }
+  return -1;
+}
+
+FX_WCHAR CFX_ListCtrl::Toupper(FX_WCHAR c) const {
+  if ((c >= 'a') && (c <= 'z'))
+    c = c - ('a' - 'A');
+  return c;
+}
+
+int32_t CFX_ListCtrl::FindNext(int32_t nIndex, FX_WCHAR nChar) const {
+  int32_t nCircleIndex = nIndex;
+
+  for (int32_t i = 0, sz = m_aListItems.GetSize(); i < sz; i++) {
+    nCircleIndex++;
+    if (nCircleIndex >= sz)
+      nCircleIndex = 0;
+
+    if (CFX_ListItem* pListItem = m_aListItems.GetAt(nCircleIndex)) {
+      if (Toupper(pListItem->GetFirstChar()) == Toupper(nChar))
+        return nCircleIndex;
+    }
+  }
+
+  return nCircleIndex;
+}
+
+FX_BOOL CFX_ListCtrl::IsItemSelected(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex))
+    return pListItem->IsSelected();
+  return FALSE;
+}
+
+void CFX_ListCtrl::SetItemSelect(int32_t nItemIndex, FX_BOOL bSelected) {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nItemIndex)) {
+    pListItem->SetSelect(bSelected);
+  }
+}
+
+void CFX_ListCtrl::SetMultipleSel(FX_BOOL bMultiple) {
+  m_bMultiple = bMultiple;
+}
+
+FX_BOOL CFX_ListCtrl::IsMultipleSel() const {
+  return m_bMultiple;
+}
+
+FX_BOOL CFX_ListCtrl::IsValid(int32_t nItemIndex) const {
+  return nItemIndex >= 0 && nItemIndex < m_aListItems.GetSize();
+}
+
+CFX_WideString CFX_ListCtrl::GetItemText(int32_t nIndex) const {
+  if (CFX_ListItem* pListItem = m_aListItems.GetAt(nIndex)) {
+    return pListItem->GetText();
+  }
+
+  return L"";
+}
diff --git a/fpdfsdk/fxedit/fxet_module.cpp b/fpdfsdk/fxedit/fxet_module.cpp
deleted file mode 100644
index 99fd68e..0000000
--- a/fpdfsdk/fxedit/fxet_module.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfdoc/include/cpdf_variabletext.h"
-#include "fpdfsdk/fxedit/include/fxet_edit.h"
-#include "fpdfsdk/fxedit/include/fxet_list.h"
-
-IFX_Edit* IFX_Edit::NewEdit() {
-  return new CFX_Edit(new CPDF_VariableText());
-}
-
-void IFX_Edit::DelEdit(IFX_Edit* pEdit) {
-  delete pEdit->GetVariableText();
-  delete static_cast<CFX_Edit*>(pEdit);
-}
-
-IFX_List* IFX_List::NewList() {
-  return new CFX_ListCtrl();
-}
-
-void IFX_List::DelList(IFX_List* pList) {
-  ASSERT(pList);
-  delete (CFX_ListCtrl*)pList;
-}
diff --git a/fpdfsdk/fxedit/fxet_pageobjs.cpp b/fpdfsdk/fxedit/fxet_pageobjs.cpp
deleted file mode 100644
index 98ec6f5..0000000
--- a/fpdfsdk/fxedit/fxet_pageobjs.cpp
+++ /dev/null
@@ -1,306 +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_page/include/cpdf_pageobject.h"
-#include "core/fpdfapi/fpdf_page/include/cpdf_pageobjectholder.h"
-#include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h"
-#include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h"
-#include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h"
-#include "core/fpdfapi/fpdf_render/include/cpdf_textrenderer.h"
-#include "core/fpdfdoc/include/cpvt_word.h"
-#include "core/fpdfdoc/include/ipvt_fontmap.h"
-#include "core/fxge/include/fx_ge.h"
-#include "fpdfsdk/cfx_systemhandler.h"
-#include "fpdfsdk/fxedit/include/fx_edit.h"
-#include "fpdfsdk/fxedit/include/fxet_edit.h"
-
-namespace {
-
-void DrawTextString(CFX_RenderDevice* pDevice,
-                    const CFX_FloatPoint& pt,
-                    CPDF_Font* pFont,
-                    FX_FLOAT fFontSize,
-                    CFX_Matrix* pUser2Device,
-                    const CFX_ByteString& str,
-                    FX_ARGB crTextFill,
-                    FX_ARGB crTextStroke,
-                    int32_t nHorzScale) {
-  FX_FLOAT x = pt.x, y = pt.y;
-  pUser2Device->Transform(x, y);
-
-  if (pFont) {
-    if (nHorzScale != 100) {
-      CFX_Matrix mt(nHorzScale / 100.0f, 0, 0, 1, 0, 0);
-      mt.Concat(*pUser2Device);
-
-      CPDF_RenderOptions ro;
-      ro.m_Flags = RENDER_CLEARTYPE;
-      ro.m_ColorMode = RENDER_COLOR_NORMAL;
-
-      if (crTextStroke != 0) {
-        CFX_FloatPoint pt1(0, 0), pt2(1, 0);
-        pUser2Device->Transform(pt1.x, pt1.y);
-        pUser2Device->Transform(pt2.x, pt2.y);
-        CFX_GraphStateData gsd;
-        gsd.m_LineWidth =
-            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
-
-        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
-                                          str, crTextFill, crTextStroke, &gsd,
-                                          &ro);
-      } else {
-        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt,
-                                          str, crTextFill, 0, nullptr, &ro);
-      }
-    } else {
-      CPDF_RenderOptions ro;
-      ro.m_Flags = RENDER_CLEARTYPE;
-      ro.m_ColorMode = RENDER_COLOR_NORMAL;
-
-      if (crTextStroke != 0) {
-        CFX_FloatPoint pt1(0, 0), pt2(1, 0);
-        pUser2Device->Transform(pt1.x, pt1.y);
-        pUser2Device->Transform(pt2.x, pt2.y);
-        CFX_GraphStateData gsd;
-        gsd.m_LineWidth =
-            (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
-
-        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
-                                          pUser2Device, str, crTextFill,
-                                          crTextStroke, &gsd, &ro);
-      } else {
-        CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize,
-                                          pUser2Device, str, crTextFill, 0,
-                                          nullptr, &ro);
-      }
-    }
-  }
-}
-
-CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjectHolder* pObjectHolder,
-                                         FX_COLORREF crText,
-                                         CPDF_Font* pFont,
-                                         FX_FLOAT fFontSize,
-                                         FX_FLOAT fCharSpace,
-                                         int32_t nHorzScale,
-                                         const CFX_FloatPoint& point,
-                                         const CFX_ByteString& text) {
-  std::unique_ptr<CPDF_TextObject> pTxtObj(new CPDF_TextObject);
-  CPDF_TextStateData* pTextStateData = pTxtObj->m_TextState.GetModify();
-  pTextStateData->m_pFont = pFont;
-  pTextStateData->m_FontSize = fFontSize;
-  pTextStateData->m_CharSpace = fCharSpace;
-  pTextStateData->m_WordSpace = 0;
-  pTextStateData->m_TextMode = TextRenderingMode::MODE_FILL;
-  pTextStateData->m_Matrix[0] = nHorzScale / 100.0f;
-  pTextStateData->m_Matrix[1] = 0;
-  pTextStateData->m_Matrix[2] = 0;
-  pTextStateData->m_Matrix[3] = 1;
-
-  FX_FLOAT rgb[3];
-  rgb[0] = FXARGB_R(crText) / 255.0f;
-  rgb[1] = FXARGB_G(crText) / 255.0f;
-  rgb[2] = FXARGB_B(crText) / 255.0f;
-  pTxtObj->m_ColorState.SetFillColor(
-      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
-  pTxtObj->m_ColorState.SetStrokeColor(
-      CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
-
-  pTxtObj->SetPosition(point.x, point.y);
-  pTxtObj->SetText(text);
-
-  CPDF_TextObject* pRet = pTxtObj.get();
-  pObjectHolder->GetPageObjectList()->push_back(std::move(pTxtObj));
-  return pRet;
-}
-
-}  // namespace
-
-void IFX_Edit::DrawEdit(CFX_RenderDevice* pDevice,
-                        CFX_Matrix* pUser2Device,
-                        IFX_Edit* pEdit,
-                        FX_COLORREF crTextFill,
-                        FX_COLORREF crTextStroke,
-                        const CFX_FloatRect& rcClip,
-                        const CFX_FloatPoint& ptOffset,
-                        const CPVT_WordRange* pRange,
-                        CFX_SystemHandler* pSystemHandler,
-                        void* pFFLData) {
-  const bool bContinuous =
-      pEdit->GetCharArray() == 0 && pEdit->GetCharSpace() <= 0.0f;
-  uint16_t SubWord = pEdit->GetPasswordChar();
-  FX_FLOAT fFontSize = pEdit->GetFontSize();
-  CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
-  int32_t nHorzScale = pEdit->GetHorzScale();
-
-  FX_COLORREF crCurFill = crTextFill;
-  FX_COLORREF crOldFill = crCurFill;
-
-  FX_BOOL bSelect = FALSE;
-  const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255);
-  const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113);
-
-  CFX_ByteTextBuf sTextBuf;
-  int32_t nFontIndex = -1;
-  CFX_FloatPoint ptBT(0.0f, 0.0f);
-
-  pDevice->SaveState();
-
-  if (!rcClip.IsEmpty()) {
-    CFX_FloatRect rcTemp = rcClip;
-    pUser2Device->TransformRect(rcTemp);
-    pDevice->SetClip_Rect(rcTemp.ToFxRect());
-  }
-
-  IFX_Edit_Iterator* pIterator = pEdit->GetIterator();
-  if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
-    if (pRange)
-      pIterator->SetAt(pRange->BeginPos);
-    else
-      pIterator->SetAt(0);
-
-    CPVT_WordPlace oldplace;
-    while (pIterator->NextWord()) {
-      CPVT_WordPlace place = pIterator->GetAt();
-      if (pRange && place.WordCmp(pRange->EndPos) > 0)
-        break;
-
-      if (wrSelect.IsExist()) {
-        bSelect = place.WordCmp(wrSelect.BeginPos) > 0 &&
-                  place.WordCmp(wrSelect.EndPos) <= 0;
-        crCurFill = bSelect ? crWhite : crTextFill;
-      }
-      if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
-        crCurFill = crTextFill;
-        crOldFill = crCurFill;
-      }
-      CPVT_Word word;
-      if (pIterator->GetWord(word)) {
-        if (bSelect) {
-          CPVT_Line line;
-          pIterator->GetLine(line);
-
-          if (pSystemHandler && pSystemHandler->IsSelectionImplemented()) {
-            CFX_FloatRect rc(word.ptWord.x, line.ptLine.y + line.fLineDescent,
-                             word.ptWord.x + word.fWidth,
-                             line.ptLine.y + line.fLineAscent);
-            rc.Intersect(rcClip);
-            pSystemHandler->OutputSelectedRect(pFFLData, rc);
-          } else {
-            CFX_PathData pathSelBK;
-            pathSelBK.AppendRect(
-                word.ptWord.x, line.ptLine.y + line.fLineDescent,
-                word.ptWord.x + word.fWidth, line.ptLine.y + line.fLineAscent);
-
-            pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0,
-                              FXFILL_WINDING);
-          }
-        }
-
-        if (bContinuous) {
-          if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
-              crOldFill != crCurFill) {
-            if (sTextBuf.GetLength() > 0) {
-              DrawTextString(
-                  pDevice,
-                  CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-                  pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
-                  sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);
-
-              sTextBuf.Clear();
-            }
-            nFontIndex = word.nFontIndex;
-            ptBT = word.ptWord;
-            crOldFill = crCurFill;
-          }
-
-          sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word,
-                                       SubWord)
-                          .AsStringC();
-        } else {
-          DrawTextString(
-              pDevice, CFX_FloatPoint(word.ptWord.x + ptOffset.x,
-                                      word.ptWord.y + ptOffset.y),
-              pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device,
-              GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord),
-              crCurFill, crTextStroke, nHorzScale);
-        }
-        oldplace = place;
-      }
-    }
-
-    if (sTextBuf.GetLength() > 0) {
-      DrawTextString(
-          pDevice, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-          pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device,
-          sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale);
-    }
-  }
-
-  pDevice->RestoreState(false);
-}
-
-void IFX_Edit::GeneratePageObjects(
-    CPDF_PageObjectHolder* pObjectHolder,
-    IFX_Edit* pEdit,
-    const CFX_FloatPoint& ptOffset,
-    const CPVT_WordRange* pRange,
-    FX_COLORREF crText,
-    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
-  FX_FLOAT fFontSize = pEdit->GetFontSize();
-
-  int32_t nOldFontIndex = -1;
-
-  CFX_ByteTextBuf sTextBuf;
-  CFX_FloatPoint ptBT(0.0f, 0.0f);
-
-  ObjArray.RemoveAll();
-
-  IFX_Edit_Iterator* pIterator = pEdit->GetIterator();
-  if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) {
-    if (pRange)
-      pIterator->SetAt(pRange->BeginPos);
-    else
-      pIterator->SetAt(0);
-
-    CPVT_WordPlace oldplace;
-
-    while (pIterator->NextWord()) {
-      CPVT_WordPlace place = pIterator->GetAt();
-      if (pRange && place.WordCmp(pRange->EndPos) > 0)
-        break;
-
-      CPVT_Word word;
-      if (pIterator->GetWord(word)) {
-        if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex) {
-          if (sTextBuf.GetLength() > 0) {
-            ObjArray.Add(AddTextObjToPageObjects(
-                pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex),
-                fFontSize, 0.0f, 100,
-                CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-                sTextBuf.MakeString()));
-
-            sTextBuf.Clear();
-          }
-
-          ptBT = word.ptWord;
-          nOldFontIndex = word.nFontIndex;
-        }
-
-        sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0)
-                        .AsStringC();
-        oldplace = place;
-      }
-    }
-
-    if (sTextBuf.GetLength() > 0) {
-      ObjArray.Add(AddTextObjToPageObjects(
-          pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize,
-          0.0f, 100, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y),
-          sTextBuf.MakeString()));
-    }
-  }
-}
diff --git a/fpdfsdk/fxedit/include/fx_edit.h b/fpdfsdk/fxedit/include/fx_edit.h
index cface7d..4ae6ec2 100644
--- a/fpdfsdk/fxedit/include/fx_edit.h
+++ b/fpdfsdk/fxedit/include/fx_edit.h
@@ -7,41 +7,9 @@
 #ifndef FPDFSDK_FXEDIT_INCLUDE_FX_EDIT_H_
 #define FPDFSDK_FXEDIT_INCLUDE_FX_EDIT_H_
 
-#include "core/fpdfdoc/include/cpdf_variabletext.h"
 #include "core/fxcrt/include/fx_basic.h"
-#include "core/fxge/include/fx_dib.h"
 
-class CPDF_Font;
-class CPDF_PageObjectHolder;
-class CPDF_TextObject;
-class CFX_FloatPoint;
-class CFX_Matrix;
-class CFX_RenderDevice;
-class CFX_SystemHandler;
-class IFX_Edit;
 class IPVT_FontMap;
-class IFX_Edit_Iterator;
-class IFX_Edit_Notify;
-class IFX_Edit_UndoItem;
-class IFX_List;
-class IFX_List_Notify;
-
-struct CPVT_Line;
-struct CPVT_SecProps;
-struct CPVT_Section;
-struct CPVT_Word;
-struct CPVT_WordPlace;
-struct CPVT_WordProps;
-struct CPVT_WordRange;
-
-#define PVTWORD_STYLE_NORMAL 0x0000L
-#define PVTWORD_STYLE_HIGHLIGHT 0x0001L
-#define PVTWORD_STYLE_UNDERLINE 0x0002L
-#define PVTWORD_STYLE_CROSSOUT 0x0004L
-#define PVTWORD_STYLE_SQUIGGLY 0x0008L
-#define PVTWORD_STYLE_DUALCROSSOUT 0x0010L
-#define PVTWORD_STYLE_BOLD 0x0020L
-#define PVTWORD_STYLE_ITALIC 0x0040L
 
 #define FX_EDIT_ISLATINWORD(u)                  \
   (u == 0x2D || (u <= 0x005A && u >= 0x0041) || \
@@ -51,493 +19,6 @@
 #define DEFAULT_CHARSET 1
 #endif
 
-class IFX_Edit_Notify {
- public:
-  virtual ~IFX_Edit_Notify() {}
-  // set the horizontal scrollbar information.
-  virtual void IOnSetScrollInfoX(FX_FLOAT fPlateMin,
-                                 FX_FLOAT fPlateMax,
-                                 FX_FLOAT fContentMin,
-                                 FX_FLOAT fContentMax,
-                                 FX_FLOAT fSmallStep,
-                                 FX_FLOAT fBigStep) = 0;
-  // set the vertical scrollbar information.
-  virtual void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
-                                 FX_FLOAT fPlateMax,
-                                 FX_FLOAT fContentMin,
-                                 FX_FLOAT fContentMax,
-                                 FX_FLOAT fSmallStep,
-                                 FX_FLOAT fBigStep) = 0;
-  // set the position of horizontal scrollbar.
-  virtual void IOnSetScrollPosX(FX_FLOAT fx) = 0;
-  // set the position of vertical scrollbar.
-  virtual void IOnSetScrollPosY(FX_FLOAT fy) = 0;
-  // set the caret information.
-  virtual void IOnSetCaret(FX_BOOL bVisible,
-                           const CFX_FloatPoint& ptHead,
-                           const CFX_FloatPoint& ptFoot,
-                           const CPVT_WordPlace& place) = 0;
-  // if the text area is changed, send the information to user.
-  virtual void IOnContentChange(const CFX_FloatRect& rcContent) = 0;
-  // Invalidate the rectangle relative to the bounding box of edit.
-  virtual void IOnInvalidateRect(CFX_FloatRect* pRect) = 0;
-};
-
-class IFX_Edit_OprNotify {
- public:
-  virtual ~IFX_Edit_OprNotify() {}
-
-  // OprType: 0
-  virtual void OnInsertWord(const CPVT_WordPlace& place,
-                            const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 1
-  virtual void OnInsertReturn(const CPVT_WordPlace& place,
-                              const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 2
-  virtual void OnBackSpace(const CPVT_WordPlace& place,
-                           const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 3
-  virtual void OnDelete(const CPVT_WordPlace& place,
-                        const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 4
-  virtual void OnClear(const CPVT_WordPlace& place,
-                       const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 5
-  virtual void OnInsertText(const CPVT_WordPlace& place,
-                            const CPVT_WordPlace& oldplace) = 0;
-  // OprType: 6
-  virtual void OnSetText(const CPVT_WordPlace& place,
-                         const CPVT_WordPlace& oldplace) = 0;
-  //
-  virtual void OnAddUndo(IFX_Edit_UndoItem* pUndoItem) = 0;
-};
-
-class IFX_Edit_Iterator {
- public:
-  virtual ~IFX_Edit_Iterator() {}
-
- public:
-  // move the current position to the next word.
-  virtual FX_BOOL NextWord() = 0;
-  // move the current position to the next line.
-  virtual FX_BOOL NextLine() = 0;
-  // move the current position to the next section.
-  virtual FX_BOOL NextSection() = 0;
-
-  // move the current position to the previous word.
-  virtual FX_BOOL PrevWord() = 0;
-  // move the current position to the previous line.
-  virtual FX_BOOL PrevLine() = 0;
-  // move the current position to the previous section.
-  virtual FX_BOOL PrevSection() = 0;
-
-  // get the information of the current word.
-  virtual FX_BOOL GetWord(CPVT_Word& word) const = 0;
-  // get the information of the current line.
-  virtual FX_BOOL GetLine(CPVT_Line& line) const = 0;
-  // get the information of the current section.
-  virtual FX_BOOL GetSection(CPVT_Section& section) const = 0;
-  // set the current position.
-  virtual void SetAt(int32_t nWordIndex) = 0;
-  // set the current position.
-  virtual void SetAt(const CPVT_WordPlace& place) = 0;
-  // get the current position.
-  virtual const CPVT_WordPlace& GetAt() const = 0;
-
-  // get the edit which this iterator belongs to
-  virtual IFX_Edit* GetEdit() const = 0;
-};
-
-class IFX_Edit_UndoItem {
- public:
-  virtual ~IFX_Edit_UndoItem() {}
-
-  virtual void Undo() = 0;
-  virtual void Redo() = 0;
-  virtual CFX_WideString GetUndoTitle() = 0;
-};
-
-class IFX_Edit {
- public:
-  static IFX_Edit* NewEdit();
-  static void DelEdit(IFX_Edit* pEdit);
-
-  // set a IPVT_FontMap pointer implemented by user.
-  virtual void SetFontMap(IPVT_FontMap* pFontMap) = 0;
-
-  // set a IFX_Edit_Notify pointer implemented by user.
-  virtual void SetNotify(IFX_Edit_Notify* pNotify) = 0;
-  virtual void SetOprNotify(IFX_Edit_OprNotify* pOprNotify) = 0;
-
-  // get a pointer allocated by CPDF_Edit, by this pointer, user can iterate the
-  // contents of edit, but don't need to release.
-  virtual IFX_Edit_Iterator* GetIterator() = 0;
-
-  // get a VT pointer relative to this edit.
-  virtual CPDF_VariableText* GetVariableText() = 0;
-
-  // get the IPVT_FontMap pointer set by user.
-  virtual IPVT_FontMap* GetFontMap() = 0;
-
-  // initialize the edit.
-  virtual void Initialize() = 0;
-
-  // set the bounding box of the text area.
-  virtual void SetPlateRect(const CFX_FloatRect& rect,
-                            FX_BOOL bPaint = TRUE) = 0;
-
-  // set the scroll origin
-  virtual void SetScrollPos(const CFX_FloatPoint& point) = 0;
-
-  // set the horizontal text alignment in text box, nFormat (0:left 1:middle
-  // 2:right).
-  virtual void SetAlignmentH(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) = 0;
-
-  // set the vertical text alignment in text box, nFormat (0:top 1:center
-  // 2:bottom).
-  virtual void SetAlignmentV(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) = 0;
-
-  // if the text is shown in secret , set a character for substitute.
-  virtual void SetPasswordChar(uint16_t wSubWord = '*',
-                               FX_BOOL bPaint = TRUE) = 0;
-
-  // set the maximal count of words of the text.
-  virtual void SetLimitChar(int32_t nLimitChar = 0, FX_BOOL bPaint = TRUE) = 0;
-
-  // if set the count of charArray , then all words is shown in equal space.
-  virtual void SetCharArray(int32_t nCharArray = 0, FX_BOOL bPaint = TRUE) = 0;
-
-  // set the space of two characters.
-  virtual void SetCharSpace(FX_FLOAT fCharSpace = 0.0f,
-                            FX_BOOL bPaint = TRUE) = 0;
-
-  // set the horizontal scale of all characters.
-  virtual void SetHorzScale(int32_t nHorzScale = 100,
-                            FX_BOOL bPaint = TRUE) = 0;
-
-  // set the leading of all lines
-  virtual void SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint = TRUE) = 0;
-
-  // if set, CRLF is allowed.
-  virtual void SetMultiLine(FX_BOOL bMultiLine = TRUE,
-                            FX_BOOL bPaint = TRUE) = 0;
-
-  // if set, all words auto fit the width of the bounding box.
-  virtual void SetAutoReturn(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) = 0;
-
-  // if set, a font size is calculated to full fit the bounding box.
-  virtual void SetAutoFontSize(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) = 0;
-
-  // is set, the text is allowed to scroll.
-  virtual void SetAutoScroll(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) = 0;
-
-  // set the font size of all words.
-  virtual void SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint = TRUE) = 0;
-
-  // the text is allowed to auto-scroll, allow the text overflow?
-  virtual void SetTextOverflow(FX_BOOL bAllowed = FALSE,
-                               FX_BOOL bPaint = TRUE) = 0;
-
-  // set the selected range of text.
-  // if nStartChar == 0 and nEndChar == -1, select all the text.
-  virtual void SetSel(int32_t nStartChar, int32_t nEndChar) = 0;
-
-  // get the selected range of text.
-  virtual void GetSel(int32_t& nStartChar, int32_t& nEndChar) const = 0;
-
-  // select all the text.
-  virtual void SelectAll() = 0;
-
-  // set text is not selected.
-  virtual void SelectNone() = 0;
-
-  // get the caret position.
-  virtual int32_t GetCaret() const = 0;
-  virtual CPVT_WordPlace GetCaretWordPlace() const = 0;
-
-  // get the string of selected text.
-  virtual CFX_WideString GetSelText() const = 0;
-
-  // get the text conent
-  virtual CFX_WideString GetText() const = 0;
-
-  // query if any text is selected.
-  virtual FX_BOOL IsSelected() const = 0;
-
-  // get the scroll origin
-  virtual CFX_FloatPoint GetScrollPos() const = 0;
-
-  // get the bounding box of the text area.
-  virtual CFX_FloatRect GetPlateRect() const = 0;
-
-  // get the fact area of the text.
-  virtual CFX_FloatRect GetContentRect() const = 0;
-
-  // get the visible word range
-  virtual CPVT_WordRange GetVisibleWordRange() const = 0;
-
-  // get the whole word range
-  virtual CPVT_WordRange GetWholeWordRange() const = 0;
-
-  // get the word range of select text
-  virtual CPVT_WordRange GetSelectWordRange() const = 0;
-
-  // send the mousedown message to edit for response.
-  // if Shift key is hold, bShift is TRUE, is Ctrl key is hold, bCtrl is TRUE.
-  virtual void OnMouseDown(const CFX_FloatPoint& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) = 0;
-
-  // send the mousemove message to edit when mouse down is TRUE.
-  virtual void OnMouseMove(const CFX_FloatPoint& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) = 0;
-
-  // send the UP key message to edit.
-  virtual void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-
-  // send the DOWN key message to edit.
-  virtual void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-
-  // send the LEFT key message to edit.
-  virtual void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-
-  // send the RIGHT key message to edit.
-  virtual void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-
-  // send the HOME key message to edit.
-  virtual void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-
-  // send the END key message to edit.
-  virtual void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-
-  // put text into edit.
-  virtual void SetText(const FX_WCHAR* text,
-                       int32_t charset = DEFAULT_CHARSET,
-                       const CPVT_SecProps* pSecProps = nullptr,
-                       const CPVT_WordProps* pWordProps = nullptr) = 0;
-
-  // insert a word into the edit.
-  virtual FX_BOOL InsertWord(uint16_t word,
-                             int32_t charset = DEFAULT_CHARSET,
-                             const CPVT_WordProps* pWordProps = nullptr) = 0;
-
-  // insert a return into the edit.
-  virtual FX_BOOL InsertReturn(const CPVT_SecProps* pSecProps = nullptr,
-                               const CPVT_WordProps* pWordProps = nullptr) = 0;
-
-  // insert text into the edit.
-  virtual FX_BOOL InsertText(const FX_WCHAR* text,
-                             int32_t charset = DEFAULT_CHARSET,
-                             const CPVT_SecProps* pSecProps = nullptr,
-                             const CPVT_WordProps* pWordProps = nullptr) = 0;
-
-  // do backspace operation.
-  virtual FX_BOOL Backspace() = 0;
-
-  // do delete operation.
-  virtual FX_BOOL Delete() = 0;
-
-  // delete the selected text.
-  virtual FX_BOOL Clear() = 0;
-
-  // do Redo operation.
-  virtual FX_BOOL Redo() = 0;
-
-  // do Undo operation.
-  virtual FX_BOOL Undo() = 0;
-
-  // move caret
-  virtual void SetCaret(int32_t nPos) = 0;
-
-  // arrange all words over again
-  virtual void Paint() = 0;
-
-  // allow to refresh screen?
-  virtual void EnableRefresh(FX_BOOL bRefresh) = 0;
-
-  virtual void RefreshWordRange(const CPVT_WordRange& wr) = 0;
-
-  // allow undo/redo?
-  virtual void EnableUndo(FX_BOOL bUndo) = 0;
-
-  // allow opr notify?
-  virtual void EnableOprNotify(FX_BOOL bNotify) = 0;
-
-  // map word place to word index.
-  virtual int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const = 0;
-  // map word index to word place.
-  virtual CPVT_WordPlace WordIndexToWordPlace(int32_t index) const = 0;
-
-  // get the beginning position of a line
-  virtual CPVT_WordPlace GetLineBeginPlace(
-      const CPVT_WordPlace& place) const = 0;
-
-  // get the ending position of a line
-  virtual CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const = 0;
-
-  // get the beginning position of a section
-  virtual CPVT_WordPlace GetSectionBeginPlace(
-      const CPVT_WordPlace& place) const = 0;
-
-  // get the ending position of a section
-  virtual CPVT_WordPlace GetSectionEndPlace(
-      const CPVT_WordPlace& place) const = 0;
-
-  // search a wordplace form point
-  virtual CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const = 0;
-
-  // get the font size of non_rich text or default font size of richtext.
-  virtual FX_FLOAT GetFontSize() const = 0;
-
-  // get the mask character.
-  virtual uint16_t GetPasswordChar() const = 0;
-
-  // get the count of charArray
-  virtual int32_t GetCharArray() const = 0;
-
-  // get the horizontal scale of all characters
-  virtual int32_t GetHorzScale() const = 0;
-
-  // get the space of two characters
-  virtual FX_FLOAT GetCharSpace() const = 0;
-
-  // get the latin words of specified range
-  virtual CFX_WideString GetRangeText(const CPVT_WordRange& range) const = 0;
-
-  // is the text full in bounding box
-  virtual FX_BOOL IsTextFull() const = 0;
-  virtual FX_BOOL CanUndo() const = 0;
-  virtual FX_BOOL CanRedo() const = 0;
-
-  // if the content is changed after settext?
-  virtual FX_BOOL IsModified() const = 0;
-
-  // get the total words in edit
-  virtual int32_t GetTotalWords() const = 0;
-
-  virtual void AddUndoItem(IFX_Edit_UndoItem* pUndoItem) = 0;
-
-  static CFX_ByteString GetEditAppearanceStream(
-      IFX_Edit* pEdit,
-      const CFX_FloatPoint& ptOffset,
-      const CPVT_WordRange* pRange = nullptr,
-      FX_BOOL bContinuous = TRUE,
-      uint16_t SubWord = 0);
-  static CFX_ByteString GetSelectAppearanceStream(
-      IFX_Edit* pEdit,
-      const CFX_FloatPoint& ptOffset,
-      const CPVT_WordRange* pRange = nullptr);
-  static void DrawEdit(CFX_RenderDevice* pDevice,
-                       CFX_Matrix* pUser2Device,
-                       IFX_Edit* pEdit,
-                       FX_COLORREF crTextFill,
-                       FX_COLORREF crTextStroke,
-                       const CFX_FloatRect& rcClip,
-                       const CFX_FloatPoint& ptOffset,
-                       const CPVT_WordRange* pRange,
-                       CFX_SystemHandler* pSystemHandler,
-                       void* pFFLData);
-  static void GeneratePageObjects(
-      CPDF_PageObjectHolder* pObjectHolder,
-      IFX_Edit* pEdit,
-      const CFX_FloatPoint& ptOffset,
-      const CPVT_WordRange* pRange,
-      FX_COLORREF crText,
-      CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
-
- protected:
-  virtual ~IFX_Edit() {}
-};
-
-class IFX_List_Notify {
- public:
-  // set the horizontal scrollbar information.
-  virtual void IOnSetScrollInfoX(FX_FLOAT fPlateMin,
-                                 FX_FLOAT fPlateMax,
-                                 FX_FLOAT fContentMin,
-                                 FX_FLOAT fContentMax,
-                                 FX_FLOAT fSmallStep,
-                                 FX_FLOAT fBigStep) = 0;
-  // set the vertical scrollbar information.
-  virtual void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
-                                 FX_FLOAT fPlateMax,
-                                 FX_FLOAT fContentMin,
-                                 FX_FLOAT fContentMax,
-                                 FX_FLOAT fSmallStep,
-                                 FX_FLOAT fBigStep) = 0;
-  // set the position of horizontal scrollbar.
-  virtual void IOnSetScrollPosX(FX_FLOAT fx) = 0;
-  // set the position of vertical scrollbar.
-  virtual void IOnSetScrollPosY(FX_FLOAT fy) = 0;
-  // Invalidate the rectangle relative to the bounding box of edit.
-  virtual void IOnInvalidateRect(CFX_FloatRect* pRect) = 0;
-
- protected:
-  virtual ~IFX_List_Notify() {}
-};
-
-class IFX_List {
- public:
-  static IFX_List* NewList();
-  static void DelList(IFX_List* pList);
-
-  virtual void SetFontMap(IPVT_FontMap* pFontMap) = 0;
-  virtual void SetNotify(IFX_List_Notify* pNotify) = 0;
-
-  virtual void SetPlateRect(const CFX_FloatRect& rect) = 0;
-  virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
-
-  virtual CFX_FloatRect GetPlateRect() const = 0;
-  virtual CFX_FloatRect GetContentRect() const = 0;
-
-  virtual FX_FLOAT GetFontSize() const = 0;
-  virtual IFX_Edit* GetItemEdit(int32_t nIndex) const = 0;
-  virtual int32_t GetCount() const = 0;
-  virtual FX_BOOL IsItemSelected(int32_t nIndex) const = 0;
-  virtual FX_FLOAT GetFirstHeight() const = 0;
-
-  virtual void SetMultipleSel(FX_BOOL bMultiple) = 0;
-  virtual FX_BOOL IsMultipleSel() const = 0;
-  virtual FX_BOOL IsValid(int32_t nItemIndex) const = 0;
-  virtual int32_t FindNext(int32_t nIndex, FX_WCHAR nChar) const = 0;
-
-  virtual void SetScrollPos(const CFX_FloatPoint& point) = 0;
-  virtual void ScrollToListItem(int32_t nItemIndex) = 0;
-  virtual CFX_FloatRect GetItemRect(int32_t nIndex) const = 0;
-  virtual int32_t GetCaret() const = 0;
-  virtual int32_t GetSelect() const = 0;
-  virtual int32_t GetTopItem() const = 0;
-  virtual int32_t GetItemIndex(const CFX_FloatPoint& point) const = 0;
-  virtual int32_t GetFirstSelected() const = 0;
-
-  virtual void AddString(const FX_WCHAR* str) = 0;
-  virtual void SetTopItem(int32_t nIndex) = 0;
-  virtual void Select(int32_t nItemIndex) = 0;
-  virtual void SetCaret(int32_t nItemIndex) = 0;
-  virtual void Empty() = 0;
-  virtual void Cancel() = 0;
-  virtual CFX_WideString GetText() const = 0;
-
-  virtual void OnMouseDown(const CFX_FloatPoint& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) = 0;
-  virtual void OnMouseMove(const CFX_FloatPoint& point,
-                           FX_BOOL bShift,
-                           FX_BOOL bCtrl) = 0;
-  virtual void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual void OnVK(int32_t nItemIndex, FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-  virtual FX_BOOL OnChar(uint16_t nChar, FX_BOOL bShift, FX_BOOL bCtrl) = 0;
-
- protected:
-  virtual ~IFX_List() {}
-};
-
 CFX_ByteString GetPDFWordString(IPVT_FontMap* pFontMap,
                                 int32_t nFontIndex,
                                 uint16_t Word,
diff --git a/fpdfsdk/fxedit/include/fxet_edit.h b/fpdfsdk/fxedit/include/fxet_edit.h
index 6f1a6d6..3bf5849 100644
--- a/fpdfsdk/fxedit/include/fxet_edit.h
+++ b/fpdfsdk/fxedit/include/fxet_edit.h
@@ -13,9 +13,16 @@
 #include "core/fpdfdoc/include/cpvt_wordprops.h"
 #include "fpdfsdk/fxedit/include/fx_edit.h"
 
+class CPDF_PageObjectHolder;
+class CPDF_TextObject;
+class CPWL_Edit;
+class CPWL_EditCtrl;
 class CFX_Edit;
 class CFX_Edit_Iterator;
 class CFX_Edit_Provider;
+class CFX_RenderDevice;
+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)
@@ -178,6 +185,15 @@
   FX_BOOL m_bWorking;
 };
 
+class IFX_Edit_UndoItem {
+ public:
+  virtual ~IFX_Edit_UndoItem() {}
+
+  virtual void Undo() = 0;
+  virtual void Redo() = 0;
+  virtual CFX_WideString GetUndoTitle() = 0;
+};
+
 class CFX_Edit_UndoItem : public IFX_Edit_UndoItem {
  public:
   CFX_Edit_UndoItem();
@@ -357,116 +373,180 @@
   CPVT_WordProps m_WordProps;
 };
 
-class CFX_Edit : public IFX_Edit {
-  friend class CFX_Edit_Iterator;
-  friend class CFXEU_InsertWord;
-  friend class CFXEU_InsertReturn;
-  friend class CFXEU_Backspace;
-  friend class CFXEU_Delete;
-  friend class CFXEU_Clear;
-  friend class CFXEU_InsertText;
-
+class CFX_Edit {
  public:
-  explicit CFX_Edit(CPDF_VariableText* pVT);
-  ~CFX_Edit() override;
+  static CFX_ByteString GetEditAppearanceStream(
+      CFX_Edit* pEdit,
+      const CFX_FloatPoint& ptOffset,
+      const CPVT_WordRange* pRange = nullptr,
+      FX_BOOL bContinuous = TRUE,
+      uint16_t SubWord = 0);
+  static CFX_ByteString GetSelectAppearanceStream(
+      CFX_Edit* pEdit,
+      const CFX_FloatPoint& ptOffset,
+      const CPVT_WordRange* pRange = nullptr);
+  static void DrawEdit(CFX_RenderDevice* pDevice,
+                       CFX_Matrix* pUser2Device,
+                       CFX_Edit* pEdit,
+                       FX_COLORREF crTextFill,
+                       FX_COLORREF crTextStroke,
+                       const CFX_FloatRect& rcClip,
+                       const CFX_FloatPoint& ptOffset,
+                       const CPVT_WordRange* pRange,
+                       CFX_SystemHandler* pSystemHandler,
+                       void* pFFLData);
+  static void DrawUnderline(CFX_RenderDevice* pDevice,
+                            CFX_Matrix* pUser2Device,
+                            CFX_Edit* pEdit,
+                            FX_COLORREF color,
+                            const CFX_FloatRect& rcClip,
+                            const CFX_FloatPoint& ptOffset,
+                            const CPVT_WordRange* pRange);
+  static void DrawRichEdit(CFX_RenderDevice* pDevice,
+                           CFX_Matrix* pUser2Device,
+                           CFX_Edit* pEdit,
+                           const CFX_FloatRect& rcClip,
+                           const CFX_FloatPoint& ptOffset,
+                           const CPVT_WordRange* pRange);
+  static void GeneratePageObjects(
+      CPDF_PageObjectHolder* pObjectHolder,
+      CFX_Edit* pEdit,
+      const CFX_FloatPoint& ptOffset,
+      const CPVT_WordRange* pRange,
+      FX_COLORREF crText,
+      CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
+  static void GenerateRichPageObjects(
+      CPDF_PageObjectHolder* pObjectHolder,
+      CFX_Edit* pEdit,
+      const CFX_FloatPoint& ptOffset,
+      const CPVT_WordRange* pRange,
+      CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
+  static void GenerateUnderlineObjects(CPDF_PageObjectHolder* pObjectHolder,
+                                       CFX_Edit* pEdit,
+                                       const CFX_FloatPoint& ptOffset,
+                                       const CPVT_WordRange* pRange,
+                                       FX_COLORREF color);
 
-  // IFX_Edit
-  void SetFontMap(IPVT_FontMap* pFontMap) override;
-  void SetNotify(IFX_Edit_Notify* pNotify) override;
-  void SetOprNotify(IFX_Edit_OprNotify* pOprNotify) override;
-  IFX_Edit_Iterator* GetIterator() override;
-  CPDF_VariableText* GetVariableText() override;
-  IPVT_FontMap* GetFontMap() override;
-  void Initialize() override;
-  void SetPlateRect(const CFX_FloatRect& rect, FX_BOOL bPaint = TRUE) override;
-  void SetScrollPos(const CFX_FloatPoint& point) override;
-  void SetAlignmentH(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) override;
-  void SetAlignmentV(int32_t nFormat = 0, FX_BOOL bPaint = TRUE) override;
-  void SetPasswordChar(uint16_t wSubWord = '*', FX_BOOL bPaint = TRUE) override;
-  void SetLimitChar(int32_t nLimitChar = 0, FX_BOOL bPaint = TRUE) override;
-  void SetCharArray(int32_t nCharArray = 0, FX_BOOL bPaint = TRUE) override;
-  void SetCharSpace(FX_FLOAT fCharSpace = 0.0f, FX_BOOL bPaint = TRUE) override;
-  void SetHorzScale(int32_t nHorzScale = 100, FX_BOOL bPaint = TRUE) override;
-  void SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint = TRUE) override;
-  void SetMultiLine(FX_BOOL bMultiLine = TRUE, FX_BOOL bPaint = TRUE) override;
-  void SetAutoReturn(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) override;
-  void SetAutoFontSize(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) override;
-  void SetAutoScroll(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE) override;
-  void SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint = TRUE) override;
-  void SetTextOverflow(FX_BOOL bAllowed = FALSE,
-                       FX_BOOL bPaint = TRUE) override;
-  void OnMouseDown(const CFX_FloatPoint& point,
-                   FX_BOOL bShift,
-                   FX_BOOL bCtrl) override;
-  void OnMouseMove(const CFX_FloatPoint& point,
-                   FX_BOOL bShift,
-                   FX_BOOL bCtrl) override;
-  void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) override;
+  CFX_Edit();
+  ~CFX_Edit();
+
+  void SetFontMap(IPVT_FontMap* pFontMap);
+  void SetNotify(CPWL_EditCtrl* pNotify);
+  void SetOprNotify(CPWL_Edit* pOprNotify);
+
+  // Returns an iterator for the contents. Should not be released.
+  CFX_Edit_Iterator* GetIterator();
+  CPDF_VariableText* GetVariableText();
+  IPVT_FontMap* GetFontMap();
+  void Initialize();
+
+  // Set the bounding box of the text area.
+  void SetPlateRect(const CFX_FloatRect& rect, FX_BOOL bPaint = TRUE);
+  void SetScrollPos(const CFX_FloatPoint& point);
+
+  // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right])
+  void SetAlignmentH(int32_t nFormat = 0, FX_BOOL bPaint = TRUE);
+  // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right])
+  void SetAlignmentV(int32_t nFormat = 0, FX_BOOL bPaint = TRUE);
+
+  // Set the substitution character for hidden text.
+  void SetPasswordChar(uint16_t wSubWord = '*', FX_BOOL bPaint = TRUE);
+
+  // Set the maximum number of words in the text.
+  void SetLimitChar(int32_t nLimitChar = 0, FX_BOOL bPaint = TRUE);
+  void SetCharArray(int32_t nCharArray = 0, FX_BOOL bPaint = TRUE);
+  void SetCharSpace(FX_FLOAT fCharSpace = 0.0f, FX_BOOL bPaint = TRUE);
+  void SetHorzScale(int32_t nHorzScale = 100, FX_BOOL bPaint = TRUE);
+  void SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint = TRUE);
+  void SetMultiLine(FX_BOOL bMultiLine = TRUE, FX_BOOL bPaint = TRUE);
+  void SetAutoReturn(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE);
+  void SetAutoFontSize(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE);
+  void SetAutoScroll(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE);
+  void SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint = TRUE);
+  void SetTextOverflow(FX_BOOL bAllowed = FALSE, FX_BOOL bPaint = TRUE);
+  FX_BOOL IsRichText() const;
+  void SetRichText(FX_BOOL bRichText = TRUE, FX_BOOL bPaint = TRUE);
+  FX_BOOL SetRichFontSize(FX_FLOAT fFontSize);
+  FX_BOOL SetRichFontIndex(int32_t nFontIndex);
+  FX_BOOL SetRichTextColor(FX_COLORREF dwColor);
+  FX_BOOL SetRichTextScript(CPDF_VariableText::ScriptType nScriptType);
+  FX_BOOL SetRichTextBold(FX_BOOL bBold = TRUE);
+  FX_BOOL SetRichTextItalic(FX_BOOL bItalic = TRUE);
+  FX_BOOL SetRichTextUnderline(FX_BOOL bUnderline = TRUE);
+  FX_BOOL SetRichTextCrossout(FX_BOOL bCrossout = TRUE);
+  FX_BOOL SetRichTextCharSpace(FX_FLOAT fCharSpace);
+  FX_BOOL SetRichTextHorzScale(int32_t nHorzScale = 100);
+  FX_BOOL SetRichTextLineLeading(FX_FLOAT fLineLeading);
+  FX_BOOL SetRichTextLineIndent(FX_FLOAT fLineIndent);
+  FX_BOOL SetRichTextAlignment(int32_t nAlignment);
+  void OnMouseDown(const CFX_FloatPoint& point, FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnMouseMove(const CFX_FloatPoint& point, FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl);
   void SetText(const FX_WCHAR* text,
                int32_t charset = DEFAULT_CHARSET,
                const CPVT_SecProps* pSecProps = nullptr,
-               const CPVT_WordProps* pWordProps = nullptr) override;
+               const CPVT_WordProps* pWordProps = nullptr);
   FX_BOOL InsertWord(uint16_t word,
                      int32_t charset = DEFAULT_CHARSET,
-                     const CPVT_WordProps* pWordProps = nullptr) override;
+                     const CPVT_WordProps* pWordProps = nullptr);
   FX_BOOL InsertReturn(const CPVT_SecProps* pSecProps = nullptr,
-                       const CPVT_WordProps* pWordProps = nullptr) override;
-  FX_BOOL Backspace() override;
-  FX_BOOL Delete() override;
-  FX_BOOL Clear() override;
+                       const CPVT_WordProps* pWordProps = nullptr);
+  FX_BOOL Backspace();
+  FX_BOOL Delete();
+  FX_BOOL Clear();
   FX_BOOL InsertText(const FX_WCHAR* text,
                      int32_t charset = DEFAULT_CHARSET,
                      const CPVT_SecProps* pSecProps = nullptr,
-                     const CPVT_WordProps* pWordProps = nullptr) override;
-  FX_BOOL Redo() override;
-  FX_BOOL Undo() override;
-  int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace WordIndexToWordPlace(int32_t index) const override;
-  CPVT_WordPlace GetLineBeginPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetSectionBeginPlace(
-      const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace GetSectionEndPlace(const CPVT_WordPlace& place) const override;
-  CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const override;
-  int32_t GetCaret() const override;
-  CPVT_WordPlace GetCaretWordPlace() const override;
-  CFX_WideString GetSelText() const override;
-  CFX_WideString GetText() const override;
-  FX_FLOAT GetFontSize() const override;
-  uint16_t GetPasswordChar() const override;
-  CFX_FloatPoint GetScrollPos() const override;
-  int32_t GetCharArray() const override;
-  CFX_FloatRect GetPlateRect() const override;
-  CFX_FloatRect GetContentRect() const override;
-  CFX_WideString GetRangeText(const CPVT_WordRange& range) const override;
-  int32_t GetHorzScale() const override;
-  FX_FLOAT GetCharSpace() const override;
-  int32_t GetTotalWords() const override;
-  void SetSel(int32_t nStartChar, int32_t nEndChar) override;
-  void GetSel(int32_t& nStartChar, int32_t& nEndChar) const override;
-  void SelectAll() override;
-  void SelectNone() override;
-  FX_BOOL IsSelected() const override;
-  void Paint() override;
-  void EnableRefresh(FX_BOOL bRefresh) override;
-  void RefreshWordRange(const CPVT_WordRange& wr) override;
-  void SetCaret(int32_t nPos) override;
-  CPVT_WordRange GetWholeWordRange() const override;
-  CPVT_WordRange GetSelectWordRange() const override;
-  void EnableUndo(FX_BOOL bUndo) override;
-  void EnableOprNotify(FX_BOOL bNotify) override;
-  FX_BOOL IsTextFull() const override;
+                     const CPVT_WordProps* pWordProps = nullptr);
+  FX_BOOL Redo();
+  FX_BOOL Undo();
+  int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace WordIndexToWordPlace(int32_t index) const;
+  CPVT_WordPlace GetLineBeginPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace GetSectionBeginPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace GetSectionEndPlace(const CPVT_WordPlace& place) const;
+  CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const;
+  int32_t GetCaret() const;
+  CPVT_WordPlace GetCaretWordPlace() const;
+  CFX_WideString GetSelText() const;
+  CFX_WideString GetText() const;
+  FX_FLOAT GetFontSize() const;
+  uint16_t GetPasswordChar() const;
+  CFX_FloatPoint GetScrollPos() const;
+  int32_t GetCharArray() const;
+  CFX_FloatRect GetPlateRect() const;
+  CFX_FloatRect GetContentRect() const;
+  CFX_WideString GetRangeText(const CPVT_WordRange& range) const;
+  int32_t GetHorzScale() const;
+  FX_FLOAT GetCharSpace() const;
+  int32_t GetTotalWords() const;
+  void SetSel(int32_t nStartChar, int32_t nEndChar);
+  void GetSel(int32_t& nStartChar, int32_t& nEndChar) const;
+  void SelectAll();
+  void SelectNone();
+  FX_BOOL IsSelected() const;
+  void Paint();
+  void EnableNotify(FX_BOOL bNotify);
+  void EnableRefresh(FX_BOOL bRefresh);
+  void RefreshWordRange(const CPVT_WordRange& wr);
+  void SetCaret(int32_t nPos);
+  CPVT_WordRange GetWholeWordRange() const;
+  CPVT_WordRange GetSelectWordRange() const;
+  void EnableUndo(FX_BOOL bUndo);
+  void EnableOprNotify(FX_BOOL bNotify);
+  FX_BOOL IsTextFull() const;
   FX_BOOL IsTextOverflow() const;
-  FX_BOOL CanUndo() const override;
-  FX_BOOL CanRedo() const override;
-  FX_BOOL IsModified() const override;
-  CPVT_WordRange GetVisibleWordRange() const override;
-  void AddUndoItem(IFX_Edit_UndoItem* pUndoItem) override;
+  FX_BOOL CanUndo() const;
+  FX_BOOL CanRedo() const;
+  FX_BOOL IsModified() const;
+  CPVT_WordRange GetVisibleWordRange() const;
+  void AddUndoItem(IFX_Edit_UndoItem* pUndoItem);
 
   FX_BOOL Empty();
 
@@ -480,6 +560,15 @@
   int32_t GetTotalLines() const;
 
  private:
+  friend class CFX_Edit_Iterator;
+  friend class CFXEU_InsertWord;
+  friend class CFXEU_InsertReturn;
+  friend class CFXEU_Backspace;
+  friend class CFXEU_Delete;
+  friend class CFXEU_Clear;
+  friend class CFXEU_ClearRich;
+  friend class CFXEU_InsertText;
+
   void SetSel(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
 
   void RearrangeAll();
@@ -548,9 +637,9 @@
   FX_FLOAT GetLineBottom(const CPVT_WordPlace& place) const;
 
  private:
-  CPDF_VariableText* m_pVT;
-  IFX_Edit_Notify* m_pNotify;
-  IFX_Edit_OprNotify* m_pOprNotify;
+  std::unique_ptr<CPDF_VariableText> m_pVT;
+  CPWL_EditCtrl* m_pNotify;
+  CPWL_Edit* m_pOprNotify;
   std::unique_ptr<CFX_Edit_Provider> m_pVTProvider;
 
   CPVT_WordPlace m_wpCaret;
@@ -560,7 +649,7 @@
   CFX_FloatPoint m_ptScrollPos;
   CFX_FloatPoint m_ptRefreshScrollPos;
   FX_BOOL m_bEnableScroll;
-  std::unique_ptr<IFX_Edit_Iterator> m_pIterator;
+  std::unique_ptr<CFX_Edit_Iterator> m_pIterator;
   CFX_Edit_Refresh m_Refresh;
   CFX_FloatPoint m_ptCaret;
   CFX_Edit_Undo m_Undo;
@@ -574,25 +663,24 @@
   CFX_Edit_GroupUndoItem* m_pGroupUndoItem;
 };
 
-class CFX_Edit_Iterator : public IFX_Edit_Iterator {
+class CFX_Edit_Iterator {
  public:
   CFX_Edit_Iterator(CFX_Edit* pEdit, CPDF_VariableText::Iterator* pVTIterator);
-  ~CFX_Edit_Iterator() override;
+  ~CFX_Edit_Iterator();
 
-  // IFX_Edit_Iterator
-  FX_BOOL NextWord() override;
-  FX_BOOL NextLine() override;
-  FX_BOOL NextSection() override;
-  FX_BOOL PrevWord() override;
-  FX_BOOL PrevLine() override;
-  FX_BOOL PrevSection() override;
-  FX_BOOL GetWord(CPVT_Word& word) const override;
-  FX_BOOL GetLine(CPVT_Line& line) const override;
-  FX_BOOL GetSection(CPVT_Section& section) const override;
-  void SetAt(int32_t nWordIndex) override;
-  void SetAt(const CPVT_WordPlace& place) override;
-  const CPVT_WordPlace& GetAt() const override;
-  IFX_Edit* GetEdit() const override;
+  FX_BOOL NextWord();
+  FX_BOOL NextLine();
+  FX_BOOL NextSection();
+  FX_BOOL PrevWord();
+  FX_BOOL PrevLine();
+  FX_BOOL PrevSection();
+  FX_BOOL GetWord(CPVT_Word& word) const;
+  FX_BOOL GetLine(CPVT_Line& line) const;
+  FX_BOOL GetSection(CPVT_Section& section) const;
+  void SetAt(int32_t nWordIndex);
+  void SetAt(const CPVT_WordPlace& place);
+  const CPVT_WordPlace& GetAt() const;
+  CFX_Edit* GetEdit() const;
 
  private:
   CFX_Edit* m_pEdit;
diff --git a/fpdfsdk/fxedit/include/fxet_list.h b/fpdfsdk/fxedit/include/fxet_list.h
index a763db5..2377e1d 100644
--- a/fpdfsdk/fxedit/include/fxet_list.h
+++ b/fpdfsdk/fxedit/include/fxet_list.h
@@ -7,30 +7,12 @@
 #ifndef FPDFSDK_FXEDIT_INCLUDE_FXET_LIST_H_
 #define FPDFSDK_FXEDIT_INCLUDE_FXET_LIST_H_
 
+#include "core/fxcrt/include/fx_coordinates.h"
 #include "fpdfsdk/fxedit/include/fx_edit.h"
 
-class IFX_Edit;
-
-class CLST_Size {
- public:
-  CLST_Size() : x(0.0f), y(0.0f) {}
-
-  CLST_Size(FX_FLOAT other_x, FX_FLOAT other_y) {
-    x = other_x;
-    y = other_y;
-  }
-
-  void Default() {
-    x = 0.0f;
-    y = 0.0f;
-  }
-
-  FX_BOOL operator!=(const CLST_Size& size) const {
-    return FXSYS_memcmp(this, &size, sizeof(CLST_Size)) != 0;
-  }
-
-  FX_FLOAT x, y;
-};
+class CFX_Edit;
+class CFX_Edit_Iterator;
+class CPWL_List_Notify;
 
 class CLST_Rect : public CFX_FloatRect {
  public:
@@ -119,7 +101,7 @@
   ~CFX_ListItem();
 
   void SetFontMap(IPVT_FontMap* pFontMap);
-  IFX_Edit* GetEdit() const;
+  CFX_Edit* GetEdit() const;
 
   void SetRect(const CLST_Rect& rect);
   void SetSelect(FX_BOOL bSelected);
@@ -133,9 +115,9 @@
   uint16_t GetFirstChar() const;
 
  private:
-  IFX_Edit_Iterator* GetIterator() const;
+  CFX_Edit_Iterator* GetIterator() const;
 
-  IFX_Edit* m_pEdit;
+  std::unique_ptr<CFX_Edit> m_pEdit;
   FX_BOOL m_bSelected;
   CLST_Rect m_rcListItem;
 };
@@ -144,6 +126,7 @@
  public:
   CFX_ListContainer();
   virtual ~CFX_ListContainer();
+
   virtual void SetPlateRect(const CFX_FloatRect& rect);
 
   CFX_FloatRect GetPlateRect() const { return m_rcPlate; }
@@ -200,45 +183,6 @@
   }
 };
 
-class CFX_List : protected CFX_ListContainer, public IFX_List {
- public:
-  CFX_List();
-  ~CFX_List() override;
-
-  // IFX_List:
-  void SetFontMap(IPVT_FontMap* pFontMap) override;
-  void SetFontSize(FX_FLOAT fFontSize) override;
-  CFX_FloatRect GetPlateRect() const override;
-  CFX_FloatRect GetContentRect() const override;
-  FX_FLOAT GetFontSize() const override;
-  IFX_Edit* GetItemEdit(int32_t nIndex) const override;
-  int32_t GetCount() const override;
-  FX_BOOL IsItemSelected(int32_t nIndex) const override;
-  FX_FLOAT GetFirstHeight() const override;
-  void SetMultipleSel(FX_BOOL bMultiple) override;
-  FX_BOOL IsMultipleSel() const override;
-  FX_BOOL IsValid(int32_t nItemIndex) const override;
-  int32_t FindNext(int32_t nIndex, FX_WCHAR nChar) const override;
-  void Empty() override;
-  CFX_FloatRect GetItemRect(int32_t nIndex) const override;
-  int32_t GetItemIndex(const CFX_FloatPoint& point) const override;
-  int32_t GetFirstSelected() const override;
-
- protected:
-  void AddItem(const FX_WCHAR* str);
-  virtual void ReArrange(int32_t nItemIndex);
-  CFX_WideString GetItemText(int32_t nIndex) const;
-  void SetItemSelect(int32_t nItemIndex, FX_BOOL bSelected);
-  int32_t GetLastSelected() const;
-  FX_WCHAR Toupper(FX_WCHAR c) const;
-
- private:
-  CLST_ArrayTemplate<CFX_ListItem*> m_aListItems;
-  FX_FLOAT m_fFontSize;
-  IPVT_FontMap* m_pFontMap;
-  FX_BOOL m_bMultiple;
-};
-
 struct CPLST_Select_Item {
   CPLST_Select_Item(int32_t other_nItemIndex, int32_t other_nState) {
     nItemIndex = other_nItemIndex;
@@ -271,51 +215,65 @@
   CFX_ArrayTemplate<CPLST_Select_Item*> m_aItems;
 };
 
-class CFX_ListCtrl : public CFX_List {
+class CFX_ListCtrl : protected CFX_ListContainer {
  public:
   CFX_ListCtrl();
   ~CFX_ListCtrl() override;
 
-  // CFX_List
-  void SetNotify(IFX_List_Notify* pNotify) override;
-  void OnMouseDown(const CFX_FloatPoint& point,
-                   FX_BOOL bShift,
-                   FX_BOOL bCtrl) override;
-  void OnMouseMove(const CFX_FloatPoint& point,
-                   FX_BOOL bShift,
-                   FX_BOOL bCtrl) override;
-  void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl) override;
-  void OnVK(int32_t nItemIndex, FX_BOOL bShift, FX_BOOL bCtrl) override;
-  FX_BOOL OnChar(uint16_t nChar, FX_BOOL bShift, FX_BOOL bCtrl) override;
+  // CFX_ListContainer
   void SetPlateRect(const CFX_FloatRect& rect) override;
-  void SetScrollPos(const CFX_FloatPoint& point) override;
-  void ScrollToListItem(int32_t nItemIndex) override;
-  CFX_FloatRect GetItemRect(int32_t nIndex) const override;
-  int32_t GetCaret() const override;
-  int32_t GetSelect() const override;
-  int32_t GetTopItem() const override;
-  CFX_FloatRect GetContentRect() const override;
-  int32_t GetItemIndex(const CFX_FloatPoint& point) const override;
-  void AddString(const FX_WCHAR* str) override;
-  void SetTopItem(int32_t nIndex) override;
-  void Select(int32_t nItemIndex) override;
-  void SetCaret(int32_t nItemIndex) override;
-  void Empty() override;
-  void Cancel() override;
-  CFX_WideString GetText() const override;
-  void ReArrange(int32_t nItemIndex) override;
 
-  virtual CFX_FloatPoint InToOut(const CFX_FloatPoint& point) const;
-  virtual CFX_FloatPoint OutToIn(const CFX_FloatPoint& point) const;
-  virtual CFX_FloatRect InToOut(const CFX_FloatRect& rect) const;
-  virtual CFX_FloatRect OutToIn(const CFX_FloatRect& rect) const;
+  void SetNotify(CPWL_List_Notify* pNotify);
+  void OnMouseDown(const CFX_FloatPoint& point, FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnMouseMove(const CFX_FloatPoint& point, FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_UP(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_DOWN(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_LEFT(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_RIGHT(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_HOME(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK_END(FX_BOOL bShift, FX_BOOL bCtrl);
+  void OnVK(int32_t nItemIndex, FX_BOOL bShift, FX_BOOL bCtrl);
+  FX_BOOL OnChar(uint16_t nChar, FX_BOOL bShift, FX_BOOL bCtrl);
+
+  void SetScrollPos(const CFX_FloatPoint& point);
+  void ScrollToListItem(int32_t nItemIndex);
+  CFX_FloatRect GetItemRect(int32_t nIndex) const;
+  int32_t GetCaret() const;
+  int32_t GetSelect() const;
+  int32_t GetTopItem() const;
+  CFX_FloatRect GetContentRect() const;
+  int32_t GetItemIndex(const CFX_FloatPoint& point) const;
+  void AddString(const FX_WCHAR* str);
+  void SetTopItem(int32_t nIndex);
+  void Select(int32_t nItemIndex);
+  void SetCaret(int32_t nItemIndex);
+  void Empty();
+  void Cancel();
+  CFX_WideString GetText() const;
+
+  void SetFontMap(IPVT_FontMap* pFontMap);
+  void SetFontSize(FX_FLOAT fFontSize);
+  CFX_FloatRect GetPlateRect() const;
+  FX_FLOAT GetFontSize() const;
+  CFX_Edit* GetItemEdit(int32_t nIndex) const;
+  int32_t GetCount() const;
+  FX_BOOL IsItemSelected(int32_t nIndex) const;
+  FX_FLOAT GetFirstHeight() const;
+  void SetMultipleSel(FX_BOOL bMultiple);
+  FX_BOOL IsMultipleSel() const;
+  FX_BOOL IsValid(int32_t nItemIndex) const;
+  int32_t FindNext(int32_t nIndex, FX_WCHAR nChar) const;
+  int32_t GetFirstSelected() const;
+
+  CFX_FloatPoint InToOut(const CFX_FloatPoint& point) const;
+  CFX_FloatPoint OutToIn(const CFX_FloatPoint& point) const;
+  CFX_FloatRect InToOut(const CFX_FloatRect& rect) const;
+  CFX_FloatRect OutToIn(const CFX_FloatRect& rect) const;
 
  private:
+  void ReArrange(int32_t nItemIndex);
+  CFX_FloatRect GetItemRectInternal(int32_t nIndex) const;
+  CFX_FloatRect GetContentRectInternal() const;
   void SetMultipleSelect(int32_t nItemIndex, FX_BOOL bSelected);
   void SetSingleSelect(int32_t nItemIndex);
   void InvalidateItem(int32_t nItemIndex);
@@ -323,9 +281,13 @@
   FX_BOOL IsItemVisible(int32_t nItemIndex) const;
   void SetScrollInfo();
   void SetScrollPosY(FX_FLOAT fy);
+  void AddItem(const FX_WCHAR* str);
+  CFX_WideString GetItemText(int32_t nIndex) const;
+  void SetItemSelect(int32_t nItemIndex, FX_BOOL bSelected);
+  int32_t GetLastSelected() const;
+  FX_WCHAR Toupper(FX_WCHAR c) const;
 
- private:
-  IFX_List_Notify* m_pNotify;
+  CPWL_List_Notify* m_pNotify;
   FX_BOOL m_bNotifyFlag;
   CFX_FloatPoint m_ptScrollPos;
   CPLST_Select m_aSelItems;  // for multiple
@@ -333,6 +295,10 @@
   int32_t m_nFootIndex;      // for multiple
   FX_BOOL m_bCtrlSel;        // for multiple
   int32_t m_nCaretIndex;     // for multiple
+  CLST_ArrayTemplate<CFX_ListItem*> m_aListItems;
+  FX_FLOAT m_fFontSize;
+  IPVT_FontMap* m_pFontMap;
+  FX_BOOL m_bMultiple;
 };
 
 #endif  // FPDFSDK_FXEDIT_INCLUDE_FXET_LIST_H_
diff --git a/fpdfsdk/pdfwindow/PWL_ComboBox.cpp b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
index c556022..5184cfe 100644
--- a/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
+++ b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
@@ -7,6 +7,7 @@
 #include "fpdfsdk/pdfwindow/PWL_ComboBox.h"
 
 #include "core/fxge/include/fx_ge.h"
+#include "fpdfsdk/fxedit/include/fxet_list.h"
 #include "fpdfsdk/pdfwindow/PWL_Edit.h"
 #include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
 #include "fpdfsdk/pdfwindow/PWL_ListBox.h"
diff --git a/fpdfsdk/pdfwindow/PWL_Edit.cpp b/fpdfsdk/pdfwindow/PWL_Edit.cpp
index e7a4ac9..d729945 100644
--- a/fpdfsdk/pdfwindow/PWL_Edit.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Edit.cpp
@@ -13,6 +13,7 @@
 #include "core/fxcrt/include/fx_safe_types.h"
 #include "core/fxcrt/include/fx_xml.h"
 #include "core/fxge/include/fx_ge.h"
+#include "fpdfsdk/fxedit/include/fxet_edit.h"
 #include "fpdfsdk/pdfwindow/PWL_Caret.h"
 #include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
 #include "fpdfsdk/pdfwindow/PWL_FontMap.h"
@@ -258,7 +259,7 @@
   CPVT_WordRange wrTemp =
       CPWL_Utils::OverlapWordRange(GetSelectWordRange(), wrVisible);
   CFX_ByteString sEditSel =
-      CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, &wrTemp);
+      CPWL_Utils::GetEditSelAppStream(m_pEdit.get(), ptOffset, &wrTemp);
 
   if (sEditSel.GetLength() > 0)
     sText << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELBACKCOLOR).AsStringC()
@@ -266,7 +267,7 @@
 
   wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelBefore);
   CFX_ByteString sEditBefore = CPWL_Utils::GetEditAppStream(
-      m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
+      m_pEdit.get(), ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
       m_pEdit->GetPasswordChar());
 
   if (sEditBefore.GetLength() > 0)
@@ -275,7 +276,7 @@
 
   wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelect);
   CFX_ByteString sEditMid = CPWL_Utils::GetEditAppStream(
-      m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
+      m_pEdit.get(), ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
       m_pEdit->GetPasswordChar());
 
   if (sEditMid.GetLength() > 0)
@@ -286,7 +287,7 @@
 
   wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelAfter);
   CFX_ByteString sEditAfter = CPWL_Utils::GetEditAppStream(
-      m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
+      m_pEdit.get(), ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
       m_pEdit->GetPasswordChar());
 
   if (sEditAfter.GetLength() > 0)
@@ -395,8 +396,8 @@
     pRange = &wrRange;
   }
   CFX_SystemHandler* pSysHandler = GetSystemHandler();
-  IFX_Edit::DrawEdit(
-      pDevice, pUser2Device, m_pEdit,
+  CFX_Edit::DrawEdit(
+      pDevice, pUser2Device, m_pEdit.get(),
       CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
       CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), GetTransparency()),
       rcClip, CFX_FloatPoint(0.0f, 0.0f), pRange, pSysHandler, m_pFormFiller);
@@ -490,7 +491,7 @@
 CFX_ByteString CPWL_Edit::GetSelectAppearanceStream(
     const CFX_FloatPoint& ptOffset) const {
   CPVT_WordRange wr = GetSelectWordRange();
-  return CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, &wr);
+  return CPWL_Utils::GetEditSelAppStream(m_pEdit.get(), ptOffset, &wr);
 }
 
 CPVT_WordRange CPWL_Edit::GetSelectWordRange() const {
@@ -512,7 +513,7 @@
 CFX_ByteString CPWL_Edit::GetTextAppearanceStream(
     const CFX_FloatPoint& ptOffset) const {
   CFX_ByteTextBuf sRet;
-  CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset);
+  CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit.get(), ptOffset);
   if (sEdit.GetLength() > 0) {
     sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC()
          << sEdit.AsStringC() << "ET\n";
@@ -532,7 +533,7 @@
     const CPVT_WordPlace& wpWord) {
   CFX_FloatPoint pt(0.0f, 0.0f);
 
-  IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
   CPVT_WordPlace wpOld = pIterator->GetAt();
   pIterator->SetAt(wpWord);
   CPVT_Word word;
@@ -823,9 +824,6 @@
   }
 }
 
-void CPWL_Edit::OnSetText(const CPVT_WordPlace& place,
-                          const CPVT_WordPlace& oldplace) {}
-
 void CPWL_Edit::OnInsertText(const CPVT_WordPlace& place,
                              const CPVT_WordPlace& oldplace) {
   if (HasFlag(PES_SPELLCHECK)) {
@@ -886,7 +884,7 @@
                                             FX_BOOL bArabic) const {
   CPVT_WordRange range;
 
-  IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
   CPVT_Word wordinfo;
   CPVT_WordPlace wpStart(place), wpEnd(place);
   pIterator->SetAt(place);
@@ -937,8 +935,8 @@
     CPDF_PageObjectHolder* pObjectHolder,
     const CFX_FloatPoint& ptOffset,
     CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
-  IFX_Edit::GeneratePageObjects(
-      pObjectHolder, m_pEdit, ptOffset, nullptr,
+  CFX_Edit::GeneratePageObjects(
+      pObjectHolder, m_pEdit.get(), ptOffset, nullptr,
       CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
       ObjArray);
 }
@@ -946,8 +944,8 @@
 void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder,
                                     const CFX_FloatPoint& ptOffset) {
   CFX_ArrayTemplate<CPDF_TextObject*> ObjArray;
-  IFX_Edit::GeneratePageObjects(
-      pObjectHolder, m_pEdit, ptOffset, nullptr,
+  CFX_Edit::GeneratePageObjects(
+      pObjectHolder, m_pEdit.get(), ptOffset, nullptr,
       CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
       ObjArray);
 }
diff --git a/fpdfsdk/pdfwindow/PWL_Edit.h b/fpdfsdk/pdfwindow/PWL_Edit.h
index 8a9d371..e1518ef 100644
--- a/fpdfsdk/pdfwindow/PWL_Edit.h
+++ b/fpdfsdk/pdfwindow/PWL_Edit.h
@@ -12,6 +12,10 @@
 #include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
+class CPDF_PageObjectHolder;
+class CPDF_TextObject;
+class IFX_Edit_UndoItem;
+
 class IPWL_Filler_Notify {
  public:
   virtual ~IPWL_Filler_Notify() {}
@@ -40,7 +44,7 @@
 #endif  // PDF_ENABLE_XFA
 };
 
-class CPWL_Edit : public CPWL_EditCtrl, public IFX_Edit_OprNotify {
+class CPWL_Edit : public CPWL_EditCtrl {
  public:
   CPWL_Edit();
   ~CPWL_Edit() override;
@@ -113,23 +117,16 @@
   FX_BOOL IsProceedtoOnChar(uint16_t nKeyCode, uint32_t nFlag);
   void AttachFFLData(void* pData) { m_pFormFiller = pData; }
 
- protected:
-  // IFX_Edit_OprNotify
   void OnInsertWord(const CPVT_WordPlace& place,
-                    const CPVT_WordPlace& oldplace) override;
+                    const CPVT_WordPlace& oldplace);
   void OnInsertReturn(const CPVT_WordPlace& place,
-                      const CPVT_WordPlace& oldplace) override;
-  void OnBackSpace(const CPVT_WordPlace& place,
-                   const CPVT_WordPlace& oldplace) override;
-  void OnDelete(const CPVT_WordPlace& place,
-                const CPVT_WordPlace& oldplace) override;
-  void OnClear(const CPVT_WordPlace& place,
-               const CPVT_WordPlace& oldplace) override;
-  void OnSetText(const CPVT_WordPlace& place,
-                 const CPVT_WordPlace& oldplace) override;
+                      const CPVT_WordPlace& oldplace);
+  void OnBackSpace(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace);
+  void OnDelete(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace);
+  void OnClear(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace);
   void OnInsertText(const CPVT_WordPlace& place,
-                    const CPVT_WordPlace& oldplace) override;
-  void OnAddUndo(IFX_Edit_UndoItem* pUndoItem) override;
+                    const CPVT_WordPlace& oldplace);
+  void OnAddUndo(IFX_Edit_UndoItem* pUndoItem);
 
  private:
   CPVT_WordRange GetSelectWordRange() const;
diff --git a/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
index 4802c78..dd1094a 100644
--- a/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
+++ b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp
@@ -8,6 +8,7 @@
 
 #include "core/fpdfdoc/include/cpvt_section.h"
 #include "core/fpdfdoc/include/cpvt_word.h"
+#include "fpdfsdk/fxedit/include/fxet_edit.h"
 #include "fpdfsdk/pdfwindow/PWL_Caret.h"
 #include "fpdfsdk/pdfwindow/PWL_FontMap.h"
 #include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
@@ -21,7 +22,7 @@
 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
 
 CPWL_EditCtrl::CPWL_EditCtrl()
-    : m_pEdit(IFX_Edit::NewEdit()),
+    : m_pEdit(new CFX_Edit),
       m_pEditCaret(nullptr),
       m_bMouseDown(FALSE),
       m_pEditNotify(nullptr),
@@ -29,7 +30,6 @@
       m_nCodePage(0) {}
 
 CPWL_EditCtrl::~CPWL_EditCtrl() {
-  IFX_Edit::DelEdit(m_pEdit);
 }
 
 void CPWL_EditCtrl::OnCreate(PWL_CREATEPARAM& cp) {
@@ -347,7 +347,7 @@
 
 void CPWL_EditCtrl::GetCaretInfo(CFX_FloatPoint& ptHead,
                                  CFX_FloatPoint& ptFoot) const {
-  IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
   pIterator->SetAt(m_pEdit->GetCaret());
   CPVT_Word word;
   CPVT_Line line;
@@ -435,7 +435,7 @@
 CPDF_Font* CPWL_EditCtrl::GetCaretFont() const {
   int32_t nFontIndex = 0;
 
-  IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
   pIterator->SetAt(m_pEdit->GetCaret());
   CPVT_Word word;
   CPVT_Section section;
@@ -456,7 +456,7 @@
 FX_FLOAT CPWL_EditCtrl::GetCaretFontSize() const {
   FX_FLOAT fFontSize = GetFontSize();
 
-  IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
+  CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator();
   pIterator->SetAt(m_pEdit->GetCaret());
   CPVT_Word word;
   CPVT_Section section;
diff --git a/fpdfsdk/pdfwindow/PWL_EditCtrl.h b/fpdfsdk/pdfwindow/PWL_EditCtrl.h
index b21c480..028c41b 100644
--- a/fpdfsdk/pdfwindow/PWL_EditCtrl.h
+++ b/fpdfsdk/pdfwindow/PWL_EditCtrl.h
@@ -11,12 +11,15 @@
 #include "fpdfsdk/fxedit/include/fx_edit.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
+class CFX_Edit;
 class CPWL_Caret;
 class CPWL_Edit;
 class CPWL_EditCtrl;
-class IFX_Edit;
 class IPWL_Edit_Notify;
+struct CPVT_SecProps;
 struct CPVT_WordPlace;
+struct CPVT_WordProps;
+struct CPVT_WordRange;
 
 enum PWL_EDIT_ALIGNFORMAT_H { PEAH_LEFT = 0, PEAH_MIDDLE, PEAH_RIGHT };
 
@@ -52,7 +55,7 @@
   virtual void OnAddUndo(CPWL_Edit* pEdit) {}
 };
 
-class CPWL_EditCtrl : public CPWL_Wnd, public IFX_Edit_Notify {
+class CPWL_EditCtrl : public CPWL_Wnd {
   friend class CPWL_Edit_Notify;
 
  public:
@@ -118,29 +121,23 @@
   FX_FLOAT GetFontSize() const override;
   void SetCursor() override;
 
- protected:
-  // IFX_Edit_Notify
-  void IOnSetScrollInfoX(FX_FLOAT fPlateMin,
-                         FX_FLOAT fPlateMax,
-                         FX_FLOAT fContentMin,
-                         FX_FLOAT fContentMax,
-                         FX_FLOAT fSmallStep,
-                         FX_FLOAT fBigStep) override {}
   void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
                          FX_FLOAT fPlateMax,
                          FX_FLOAT fContentMin,
                          FX_FLOAT fContentMax,
                          FX_FLOAT fSmallStep,
-                         FX_FLOAT fBigStep) override;
-  void IOnSetScrollPosX(FX_FLOAT fx) override {}
-  void IOnSetScrollPosY(FX_FLOAT fy) override;
+                         FX_FLOAT fBigStep);
+  void IOnSetScrollPosY(FX_FLOAT fy);
   void IOnSetCaret(FX_BOOL bVisible,
                    const CFX_FloatPoint& ptHead,
                    const CFX_FloatPoint& ptFoot,
-                   const CPVT_WordPlace& place) override;
-  void IOnContentChange(const CFX_FloatRect& rcContent) override;
-  void IOnInvalidateRect(CFX_FloatRect* pRect) override;
+                   const CPVT_WordPlace& place);
+  void IOnCaretChange(const CPVT_SecProps& secProps,
+                      const CPVT_WordProps& wordProps);
+  void IOnContentChange(const CFX_FloatRect& rcContent);
+  void IOnInvalidateRect(CFX_FloatRect* pRect);
 
+ protected:
   void InsertText(const FX_WCHAR* csText);
   void SetText(const FX_WCHAR* csText);
   void CopyText();
@@ -162,16 +159,14 @@
 
   void SetEditCaret(FX_BOOL bVisible);
 
- private:
-  void CreateEditCaret(const PWL_CREATEPARAM& cp);
-
- protected:
-  IFX_Edit* m_pEdit;
+  std::unique_ptr<CFX_Edit> m_pEdit;
   CPWL_Caret* m_pEditCaret;
   FX_BOOL m_bMouseDown;
   IPWL_Edit_Notify* m_pEditNotify;
 
  private:
+  void CreateEditCaret(const PWL_CREATEPARAM& cp);
+
   int32_t m_nCharSet;
   int32_t m_nCodePage;
 };
diff --git a/fpdfsdk/pdfwindow/PWL_ListBox.cpp b/fpdfsdk/pdfwindow/PWL_ListBox.cpp
index 84d2614..e8c1f82 100644
--- a/fpdfsdk/pdfwindow/PWL_ListBox.cpp
+++ b/fpdfsdk/pdfwindow/PWL_ListBox.cpp
@@ -6,6 +6,8 @@
 
 #include "fpdfsdk/pdfwindow/PWL_ListBox.h"
 
+#include "fpdfsdk/fxedit/include/fxet_edit.h"
+#include "fpdfsdk/fxedit/include/fxet_list.h"
 #include "fpdfsdk/pdfwindow/PWL_Edit.h"
 #include "fpdfsdk/pdfwindow/PWL_EditCtrl.h"
 #include "fpdfsdk/pdfwindow/PWL_ScrollBar.h"
@@ -65,18 +67,12 @@
 }
 
 CPWL_ListBox::CPWL_ListBox()
-    : m_pList(nullptr),
-      m_pListNotify(nullptr),
+    : m_pList(new CFX_ListCtrl),
       m_bMouseDown(FALSE),
       m_bHoverSel(FALSE),
-      m_pFillerNotify(nullptr) {
-  m_pList = IFX_List::NewList();
-}
+      m_pFillerNotify(nullptr) {}
 
 CPWL_ListBox::~CPWL_ListBox() {
-  IFX_List::DelList(m_pList);
-  delete m_pListNotify;
-  m_pListNotify = nullptr;
 }
 
 CFX_ByteString CPWL_ListBox::GetClassName() const {
@@ -85,10 +81,9 @@
 
 void CPWL_ListBox::OnCreated() {
   if (m_pList) {
-    delete m_pListNotify;
-
     m_pList->SetFontMap(GetFontMap());
-    m_pList->SetNotify(m_pListNotify = new CPWL_List_Notify(this));
+    m_pListNotify.reset(new CPWL_List_Notify(this));
+    m_pList->SetNotify(m_pListNotify.get());
 
     SetHoverSel(HasFlag(PLBS_HOVERSEL));
     m_pList->SetMultipleSel(HasFlag(PLBS_MULTIPLESEL));
@@ -99,8 +94,7 @@
 }
 
 void CPWL_ListBox::OnDestroy() {
-  delete m_pListNotify;
-  m_pListNotify = nullptr;
+  m_pListNotify.reset();
 }
 
 void CPWL_ListBox::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
@@ -172,7 +166,7 @@
         continue;
 
       CFX_FloatPoint ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f);
-      if (IFX_Edit* pEdit = m_pList->GetItemEdit(i)) {
+      if (CFX_Edit* pEdit = m_pList->GetItemEdit(i)) {
         CFX_FloatRect rcContent = pEdit->GetContentRect();
         if (rcContent.Width() > rcClient.Width())
           rcItem.Intersect(rcList);
@@ -183,7 +177,7 @@
       if (m_pList->IsItemSelected(i)) {
         CFX_SystemHandler* pSysHandler = GetSystemHandler();
         if (pSysHandler && pSysHandler->IsSelectionImplemented()) {
-          IFX_Edit::DrawEdit(
+          CFX_Edit::DrawEdit(
               pDevice, pUser2Device, m_pList->GetItemEdit(i),
               CPWL_Utils::PWLColorToFXColor(GetTextColor()),
               CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()), rcList,
@@ -192,13 +186,13 @@
         } else {
           CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcItem,
                                    ArgbEncode(255, 0, 51, 113));
-          IFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i),
+          CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i),
                              ArgbEncode(255, 255, 255, 255), 0, rcList,
                              ptOffset, nullptr, pSysHandler, m_pFormFiller);
         }
       } else {
         CFX_SystemHandler* pSysHandler = GetSystemHandler();
-        IFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i),
+        CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i),
                            CPWL_Utils::PWLColorToFXColor(GetTextColor()),
                            CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()),
                            rcList, ptOffset, nullptr, pSysHandler, nullptr);
diff --git a/fpdfsdk/pdfwindow/PWL_ListBox.h b/fpdfsdk/pdfwindow/PWL_ListBox.h
index eea0862..91ab7f7 100644
--- a/fpdfsdk/pdfwindow/PWL_ListBox.h
+++ b/fpdfsdk/pdfwindow/PWL_ListBox.h
@@ -10,31 +10,27 @@
 #include "fpdfsdk/fxedit/include/fx_edit.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
+class CFX_ListCtrl;
 class CPWL_List_Notify;
 class CPWL_ListBox;
 class IPWL_Filler_Notify;
+struct CPVT_SecProps;
+struct CPVT_WordPlace;
+struct CPVT_WordProps;
 
-class CPWL_List_Notify : public IFX_List_Notify {
+class CPWL_List_Notify {
  public:
   CPWL_List_Notify(CPWL_ListBox* pList);
-  ~CPWL_List_Notify() override;
+  ~CPWL_List_Notify();
 
-  // IFX_List_Notify
-  void IOnSetScrollInfoX(FX_FLOAT fPlateMin,
-                         FX_FLOAT fPlateMax,
-                         FX_FLOAT fContentMin,
-                         FX_FLOAT fContentMax,
-                         FX_FLOAT fSmallStep,
-                         FX_FLOAT fBigStep) override {}
   void IOnSetScrollInfoY(FX_FLOAT fPlateMin,
                          FX_FLOAT fPlateMax,
                          FX_FLOAT fContentMin,
                          FX_FLOAT fContentMax,
                          FX_FLOAT fSmallStep,
-                         FX_FLOAT fBigStep) override;
-  void IOnSetScrollPosX(FX_FLOAT fx) override {}
-  void IOnSetScrollPosY(FX_FLOAT fy) override;
-  void IOnInvalidateRect(CFX_FloatRect* pRect) override;
+                         FX_FLOAT fBigStep);
+  void IOnSetScrollPosY(FX_FLOAT fy);
+  void IOnInvalidateRect(CFX_FloatRect* pRect);
 
   void IOnSetCaret(FX_BOOL bVisible,
                    const CFX_FloatPoint& ptHead,
@@ -104,8 +100,8 @@
   }
 
  protected:
-  IFX_List* m_pList;
-  CPWL_List_Notify* m_pListNotify;
+  std::unique_ptr<CFX_ListCtrl> m_pList;
+  std::unique_ptr<CPWL_List_Notify> m_pListNotify;
   FX_BOOL m_bMouseDown;
   FX_BOOL m_bHoverSel;
   IPWL_Filler_Notify* m_pFillerNotify;
diff --git a/fpdfsdk/pdfwindow/PWL_Utils.cpp b/fpdfsdk/pdfwindow/PWL_Utils.cpp
index f5d30b2..c8b2239 100644
--- a/fpdfsdk/pdfwindow/PWL_Utils.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Utils.cpp
@@ -10,7 +10,7 @@
 
 #include "core/fpdfdoc/include/cpvt_word.h"
 #include "core/fxge/include/fx_ge.h"
-#include "fpdfsdk/fxedit/include/fx_edit.h"
+#include "fpdfsdk/fxedit/include/fxet_edit.h"
 #include "fpdfsdk/pdfwindow/PWL_Icon.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
@@ -412,19 +412,19 @@
                        fCenterX + fRadius, fCenterY + fRadius);
 }
 
-CFX_ByteString CPWL_Utils::GetEditAppStream(IFX_Edit* pEdit,
+CFX_ByteString CPWL_Utils::GetEditAppStream(CFX_Edit* pEdit,
                                             const CFX_FloatPoint& ptOffset,
                                             const CPVT_WordRange* pRange,
                                             FX_BOOL bContinuous,
                                             uint16_t SubWord) {
-  return IFX_Edit::GetEditAppearanceStream(pEdit, ptOffset, pRange, bContinuous,
+  return CFX_Edit::GetEditAppearanceStream(pEdit, ptOffset, pRange, bContinuous,
                                            SubWord);
 }
 
-CFX_ByteString CPWL_Utils::GetEditSelAppStream(IFX_Edit* pEdit,
+CFX_ByteString CPWL_Utils::GetEditSelAppStream(CFX_Edit* pEdit,
                                                const CFX_FloatPoint& ptOffset,
                                                const CPVT_WordRange* pRange) {
-  return IFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange);
+  return CFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange);
 }
 
 CFX_ByteString CPWL_Utils::GetTextAppStream(const CFX_FloatRect& rcBBox,
@@ -438,7 +438,7 @@
                                             const CPWL_Color& crText) {
   CFX_ByteTextBuf sRet;
 
-  IFX_Edit* pEdit = IFX_Edit::NewEdit();
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
   pEdit->SetFontMap(pFontMap);
   pEdit->SetPlateRect(rcBBox);
   pEdit->SetAlignmentH(nAlignmentH);
@@ -454,10 +454,9 @@
   pEdit->SetText(sText.c_str());
 
   CFX_ByteString sEdit =
-      CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, 0.0f));
+      CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_FloatPoint(0.0f, 0.0f));
   if (sEdit.GetLength() > 0)
     sRet << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n";
-  IFX_Edit::DelEdit(pEdit);
 
   return sRet.MakeString();
 }
@@ -472,7 +471,7 @@
                                                   int32_t nLayOut) {
   const FX_FLOAT fAutoFontScale = 1.0f / 3.0f;
 
-  IFX_Edit* pEdit = IFX_Edit::NewEdit();
+  std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
   pEdit->SetFontMap(pFontMap);
   pEdit->SetAlignmentH(1);
   pEdit->SetAlignmentV(1);
@@ -667,14 +666,13 @@
   if (!rcLabel.IsEmpty()) {
     pEdit->SetPlateRect(rcLabel);
     CFX_ByteString sEdit =
-        CPWL_Utils::GetEditAppStream(pEdit, CFX_FloatPoint(0.0f, 0.0f));
+        CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_FloatPoint(0.0f, 0.0f));
     if (sEdit.GetLength() > 0) {
       sTemp << "BT\n"
             << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n";
     }
   }
 
-  IFX_Edit::DelEdit(pEdit);
   if (sTemp.GetSize() > 0) {
     sAppStream << "q\n"
                << rcBBox.left << " " << rcBBox.bottom << " "
diff --git a/fpdfsdk/pdfwindow/PWL_Utils.h b/fpdfsdk/pdfwindow/PWL_Utils.h
index db79cf7..c3acc59 100644
--- a/fpdfsdk/pdfwindow/PWL_Utils.h
+++ b/fpdfsdk/pdfwindow/PWL_Utils.h
@@ -10,8 +10,8 @@
 #include "core/fpdfdoc/include/cpvt_wordrange.h"
 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
 
+class CFX_Edit;
 class CFX_PathData;
-class IFX_Edit;
 
 struct CPWL_Color;
 
@@ -166,13 +166,13 @@
                                                 int32_t nStyle,
                                                 const CPWL_Color& crText);
 
-  static CFX_ByteString GetEditAppStream(IFX_Edit* pEdit,
+  static CFX_ByteString GetEditAppStream(CFX_Edit* pEdit,
                                          const CFX_FloatPoint& ptOffset,
                                          const CPVT_WordRange* pRange = nullptr,
                                          FX_BOOL bContinuous = TRUE,
                                          uint16_t SubWord = 0);
   static CFX_ByteString GetEditSelAppStream(
-      IFX_Edit* pEdit,
+      CFX_Edit* pEdit,
       const CFX_FloatPoint& ptOffset,
       const CPVT_WordRange* pRange = nullptr);
   static CFX_ByteString GetTextAppStream(const CFX_FloatRect& rcBBox,
diff --git a/pdfium.gyp b/pdfium.gyp
index 79ff088..04bc006 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -735,8 +735,6 @@
         'fpdfsdk/fxedit/fxet_ap.cpp',
         'fpdfsdk/fxedit/fxet_edit.cpp',
         'fpdfsdk/fxedit/fxet_list.cpp',
-        'fpdfsdk/fxedit/fxet_module.cpp',
-        'fpdfsdk/fxedit/fxet_pageobjs.cpp',
       ],
     },
     {