Create CPWL_AppStream.

This CL creates a CPWL_AppStream and consolidates app stream generation
code from CPDFSDK_Widget, CPDFSDK_BAAnnot and CPWL_Utils. The remaining
app stream code from CPWL_Utils will be cleaned up in a future CL.

Change-Id: I20cfdec09a351bd509241d2c667a182fba84b0c1
Reviewed-on: https://pdfium-review.googlesource.com/8310
Commit-Queue: dsinclair <dsinclair@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Henrique Nakashima <hnakashima@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_baannot.cpp b/fpdfsdk/cpdfsdk_baannot.cpp
index 1f4f279..a426749 100644
--- a/fpdfsdk/cpdfsdk_baannot.cpp
+++ b/fpdfsdk/cpdfsdk_baannot.cpp
@@ -38,6 +38,13 @@
   return m_pAnnot->GetAnnotDict();
 }
 
+CPDF_Dictionary* CPDFSDK_BAAnnot::GetAPDict() const {
+  CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
+  if (!pAPDict)
+    pAPDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("AP");
+  return pAPDict;
+}
+
 void CPDFSDK_BAAnnot::SetRect(const CFX_FloatRect& rect) {
   ASSERT(rect.right - rect.left >= GetMinWidth());
   ASSERT(rect.top - rect.bottom >= GetMinHeight());
@@ -293,50 +300,6 @@
   return false;
 }
 
-void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType,
-                                      const CFX_FloatRect& rcBBox,
-                                      const CFX_Matrix& matrix,
-                                      const CFX_ByteString& sContents,
-                                      const CFX_ByteString& sAPState) {
-  CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
-  if (!pAPDict)
-    pAPDict = m_pAnnot->GetAnnotDict()->SetNewFor<CPDF_Dictionary>("AP");
-
-  CPDF_Stream* pStream = nullptr;
-  CPDF_Dictionary* pParentDict = nullptr;
-  if (sAPState.IsEmpty()) {
-    pParentDict = pAPDict;
-    pStream = pAPDict->GetStreamFor(sAPType);
-  } else {
-    CPDF_Dictionary* pAPTypeDict = pAPDict->GetDictFor(sAPType);
-    if (!pAPTypeDict)
-      pAPTypeDict = pAPDict->SetNewFor<CPDF_Dictionary>(sAPType);
-
-    pParentDict = pAPTypeDict;
-    pStream = pAPTypeDict->GetStreamFor(sAPState);
-  }
-
-  if (!pStream) {
-    CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
-    pStream = pDoc->NewIndirect<CPDF_Stream>();
-    pParentDict->SetNewFor<CPDF_Reference>(sAPType, pDoc, pStream->GetObjNum());
-  }
-
-  CPDF_Dictionary* pStreamDict = pStream->GetDict();
-  if (!pStreamDict) {
-    auto pNewDict = pdfium::MakeUnique<CPDF_Dictionary>(
-        m_pAnnot->GetDocument()->GetByteStringPool());
-    pStreamDict = pNewDict.get();
-    pStreamDict->SetNewFor<CPDF_Name>("Type", "XObject");
-    pStreamDict->SetNewFor<CPDF_Name>("Subtype", "Form");
-    pStreamDict->SetNewFor<CPDF_Number>("FormType", 1);
-    pStream->InitStream(nullptr, 0, std::move(pNewDict));
-  }
-  pStreamDict->SetMatrixFor("Matrix", matrix);
-  pStreamDict->SetRectFor("BBox", rcBBox);
-  pStream->SetData((uint8_t*)sContents.c_str(), sContents.GetLength());
-}
-
 bool CPDFSDK_BAAnnot::IsVisible() const {
   uint32_t nFlags = GetFlags();
   return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) ||
diff --git a/fpdfsdk/cpdfsdk_baannot.h b/fpdfsdk/cpdfsdk_baannot.h
index 6c9ae06..18d25a1 100644
--- a/fpdfsdk/cpdfsdk_baannot.h
+++ b/fpdfsdk/cpdfsdk_baannot.h
@@ -36,6 +36,8 @@
   CPDF_Dictionary* GetAnnotDict() const;
   CPDF_Annot* GetPDFPopupAnnot() const;
 
+  CPDF_Dictionary* GetAPDict() const;
+
   void SetContents(const CFX_WideString& sContents);
   CFX_WideString GetContents() const;
 
@@ -88,12 +90,6 @@
 
   void ClearCachedAP();
 
-  void WriteAppearance(const CFX_ByteString& sAPType,
-                       const CFX_FloatRect& rcBBox,
-                       const CFX_Matrix& matrix,
-                       const CFX_ByteString& sContents,
-                       const CFX_ByteString& sAPState = "");
-
   void SetOpenState(bool bState);
 
  protected:
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp
index 80e7c8a..fed6b95 100644
--- a/fpdfsdk/cpdfsdk_widget.cpp
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -30,6 +30,7 @@
 #include "fpdfsdk/fsdk_actionhandler.h"
 #include "fpdfsdk/fsdk_define.h"
 #include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/cpwl_appstream.h"
 #include "fpdfsdk/pdfwindow/cpwl_edit.h"
 #include "fpdfsdk/pdfwindow/cpwl_utils.h"
 
@@ -764,26 +765,25 @@
   if (bValueChanged)
     m_nValueAge++;
 
-  int nFieldType = GetFieldType();
-
-  switch (nFieldType) {
+  CPWL_AppStream appStream(this, GetAPDict());
+  switch (GetFieldType()) {
     case FIELDTYPE_PUSHBUTTON:
-      ResetAppearance_PushButton();
+      appStream.SetAsPushButton();
       break;
     case FIELDTYPE_CHECKBOX:
-      ResetAppearance_CheckBox();
+      appStream.SetAsCheckBox();
       break;
     case FIELDTYPE_RADIOBUTTON:
-      ResetAppearance_RadioButton();
+      appStream.SetAsRadioButton();
       break;
     case FIELDTYPE_COMBOBOX:
-      ResetAppearance_ComboBox(sValue);
+      appStream.SetAsComboBox(sValue);
       break;
     case FIELDTYPE_LISTBOX:
-      ResetAppearance_ListBox();
+      appStream.SetAsListBox();
       break;
     case FIELDTYPE_TEXTFIELD:
-      ResetAppearance_TextField(sValue);
+      appStream.SetAsTextField(sValue);
       break;
   }
 
@@ -861,777 +861,6 @@
                          m_pInterForm->GetHighlightColor(nFieldType)));
 }
 
-void CPDFSDK_Widget::ResetAppearance_PushButton() {
-  CPDF_FormControl* pControl = GetFormControl();
-  CFX_FloatRect rcWindow = GetRotatedRect();
-  int32_t nLayout = 0;
-  switch (pControl->GetTextPosition()) {
-    case TEXTPOS_ICON:
-      nLayout = PPBL_ICON;
-      break;
-    case TEXTPOS_BELOW:
-      nLayout = PPBL_ICONTOPLABELBOTTOM;
-      break;
-    case TEXTPOS_ABOVE:
-      nLayout = PPBL_LABELTOPICONBOTTOM;
-      break;
-    case TEXTPOS_RIGHT:
-      nLayout = PPBL_ICONLEFTLABELRIGHT;
-      break;
-    case TEXTPOS_LEFT:
-      nLayout = PPBL_LABELLEFTICONRIGHT;
-      break;
-    case TEXTPOS_OVERLAID:
-      nLayout = PPBL_LABELOVERICON;
-      break;
-    default:
-      nLayout = PPBL_LABEL;
-      break;
-  }
-
-  CFX_Color crBackground;
-  CFX_Color crBorder;
-  int iColorType;
-  float fc[4];
-  pControl->GetOriginalBackgroundColor(iColorType, fc);
-  if (iColorType > 0)
-    crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  pControl->GetOriginalBorderColor(iColorType, fc);
-  if (iColorType > 0)
-    crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  float fBorderWidth = (float)GetBorderWidth();
-  CPWL_Dash dsBorder(3, 0, 0);
-  CFX_Color crLeftTop;
-  CFX_Color crRightBottom;
-
-  BorderStyle nBorderStyle = GetBorderStyle();
-  switch (nBorderStyle) {
-    case BorderStyle::DASH:
-      dsBorder = CPWL_Dash(3, 3, 0);
-      break;
-    case BorderStyle::BEVELED:
-      fBorderWidth *= 2;
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = crBackground / 2.0f;
-      break;
-    case BorderStyle::INSET:
-      fBorderWidth *= 2;
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
-      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
-      break;
-    default:
-      break;
-  }
-
-  CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
-  CFX_Color crText(COLORTYPE_GRAY, 0);
-
-  CFX_ByteString csNameTag;
-  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
-  if (da.HasColor()) {
-    da.GetColor(iColorType, fc);
-    crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-  }
-  float fFontSize = 12.0f;
-  if (da.HasFont())
-    csNameTag = da.GetFont(&fFontSize);
-
-  CFX_WideString csWCaption;
-  CFX_WideString csNormalCaption;
-  CFX_WideString csRolloverCaption;
-  CFX_WideString csDownCaption;
-  if (pControl->HasMKEntry("CA"))
-    csNormalCaption = pControl->GetNormalCaption();
-
-  if (pControl->HasMKEntry("RC"))
-    csRolloverCaption = pControl->GetRolloverCaption();
-
-  if (pControl->HasMKEntry("AC"))
-    csDownCaption = pControl->GetDownCaption();
-
-  CPDF_Stream* pNormalIcon = nullptr;
-  CPDF_Stream* pRolloverIcon = nullptr;
-  CPDF_Stream* pDownIcon = nullptr;
-  if (pControl->HasMKEntry("I"))
-    pNormalIcon = pControl->GetNormalIcon();
-
-  if (pControl->HasMKEntry("RI"))
-    pRolloverIcon = pControl->GetRolloverIcon();
-
-  if (pControl->HasMKEntry("IX"))
-    pDownIcon = pControl->GetDownIcon();
-
-  if (pNormalIcon) {
-    if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
-      if (pImageDict->GetStringFor("Name").IsEmpty())
-        pImageDict->SetNewFor<CPDF_String>("Name", "ImgA", false);
-    }
-  }
-
-  if (pRolloverIcon) {
-    if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
-      if (pImageDict->GetStringFor("Name").IsEmpty())
-        pImageDict->SetNewFor<CPDF_String>("Name", "ImgB", false);
-    }
-  }
-
-  if (pDownIcon) {
-    if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
-      if (pImageDict->GetStringFor("Name").IsEmpty())
-        pImageDict->SetNewFor<CPDF_String>("Name", "ImgC", false);
-    }
-  }
-
-  CPDF_IconFit iconFit = pControl->GetIconFit();
-
-  CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
-  font_map.SetAPType("N");
-
-  CFX_ByteString csAP =
-      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
-      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                     crLeftTop, crRightBottom, nBorderStyle,
-                                     dsBorder) +
-      CPWL_Utils::GetPushButtonAppStream(
-          iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
-          pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
-  if (pNormalIcon)
-    AddImageToAppearance("N", pNormalIcon);
-
-  CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
-  if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
-    if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
-      csRolloverCaption = csNormalCaption;
-      pRolloverIcon = pNormalIcon;
-    }
-
-    font_map.SetAPType("R");
-
-    csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
-           CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                          crLeftTop, crRightBottom,
-                                          nBorderStyle, dsBorder) +
-           CPWL_Utils::GetPushButtonAppStream(
-               iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
-               pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize,
-               nLayout);
-
-    WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
-    if (pRolloverIcon)
-      AddImageToAppearance("R", pRolloverIcon);
-
-    if (csDownCaption.IsEmpty() && !pDownIcon) {
-      csDownCaption = csNormalCaption;
-      pDownIcon = pNormalIcon;
-    }
-
-    switch (nBorderStyle) {
-      case BorderStyle::BEVELED: {
-        CFX_Color crTemp = crLeftTop;
-        crLeftTop = crRightBottom;
-        crRightBottom = crTemp;
-        break;
-      }
-      case BorderStyle::INSET: {
-        crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
-        crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
-        break;
-      }
-      default:
-        break;
-    }
-
-    font_map.SetAPType("D");
-
-    csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
-           CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                          crLeftTop, crRightBottom,
-                                          nBorderStyle, dsBorder) +
-           CPWL_Utils::GetPushButtonAppStream(
-               iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
-               pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
-
-    WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
-    if (pDownIcon)
-      AddImageToAppearance("D", pDownIcon);
-  } else {
-    RemoveAppearance("D");
-    RemoveAppearance("R");
-  }
-}
-
-void CPDFSDK_Widget::ResetAppearance_CheckBox() {
-  CPDF_FormControl* pControl = GetFormControl();
-  CFX_Color crBackground, crBorder, crText;
-  int iColorType;
-  float fc[4];
-
-  pControl->GetOriginalBackgroundColor(iColorType, fc);
-  if (iColorType > 0)
-    crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  pControl->GetOriginalBorderColor(iColorType, fc);
-  if (iColorType > 0)
-    crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  float fBorderWidth = (float)GetBorderWidth();
-  CPWL_Dash dsBorder(3, 0, 0);
-  CFX_Color crLeftTop, crRightBottom;
-
-  BorderStyle nBorderStyle = GetBorderStyle();
-  switch (nBorderStyle) {
-    case BorderStyle::DASH:
-      dsBorder = CPWL_Dash(3, 3, 0);
-      break;
-    case BorderStyle::BEVELED:
-      fBorderWidth *= 2;
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = crBackground / 2.0f;
-      break;
-    case BorderStyle::INSET:
-      fBorderWidth *= 2;
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
-      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
-      break;
-    default:
-      break;
-  }
-
-  CFX_FloatRect rcWindow = GetRotatedRect();
-  CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
-  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
-  if (da.HasColor()) {
-    da.GetColor(iColorType, fc);
-    crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-  }
-
-  int32_t nStyle = 0;
-  CFX_WideString csWCaption = pControl->GetNormalCaption();
-  if (csWCaption.GetLength() > 0) {
-    switch (csWCaption[0]) {
-      case L'l':
-        nStyle = PCS_CIRCLE;
-        break;
-      case L'8':
-        nStyle = PCS_CROSS;
-        break;
-      case L'u':
-        nStyle = PCS_DIAMOND;
-        break;
-      case L'n':
-        nStyle = PCS_SQUARE;
-        break;
-      case L'H':
-        nStyle = PCS_STAR;
-        break;
-      default:  // L'4'
-        nStyle = PCS_CHECK;
-        break;
-    }
-  } else {
-    nStyle = PCS_CHECK;
-  }
-
-  CFX_ByteString csAP_N_ON =
-      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
-      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                     crLeftTop, crRightBottom, nBorderStyle,
-                                     dsBorder);
-
-  CFX_ByteString csAP_N_OFF = csAP_N_ON;
-
-  switch (nBorderStyle) {
-    case BorderStyle::BEVELED: {
-      CFX_Color crTemp = crLeftTop;
-      crLeftTop = crRightBottom;
-      crRightBottom = crTemp;
-      break;
-    }
-    case BorderStyle::INSET: {
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
-      crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
-      break;
-    }
-    default:
-      break;
-  }
-
-  CFX_ByteString csAP_D_ON =
-      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
-      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                     crLeftTop, crRightBottom, nBorderStyle,
-                                     dsBorder);
-
-  CFX_ByteString csAP_D_OFF = csAP_D_ON;
-
-  csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
-  csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
-                  pControl->GetCheckedAPState());
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
-
-  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
-                  pControl->GetCheckedAPState());
-  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
-
-  CFX_ByteString csAS = GetAppState();
-  if (csAS.IsEmpty())
-    SetAppState("Off");
-}
-
-void CPDFSDK_Widget::ResetAppearance_RadioButton() {
-  CPDF_FormControl* pControl = GetFormControl();
-  CFX_Color crBackground, crBorder, crText;
-  int iColorType;
-  float fc[4];
-
-  pControl->GetOriginalBackgroundColor(iColorType, fc);
-  if (iColorType > 0)
-    crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  pControl->GetOriginalBorderColor(iColorType, fc);
-  if (iColorType > 0)
-    crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-
-  float fBorderWidth = (float)GetBorderWidth();
-  CPWL_Dash dsBorder(3, 0, 0);
-  CFX_Color crLeftTop;
-  CFX_Color crRightBottom;
-  BorderStyle nBorderStyle = GetBorderStyle();
-  switch (nBorderStyle) {
-    case BorderStyle::DASH:
-      dsBorder = CPWL_Dash(3, 3, 0);
-      break;
-    case BorderStyle::BEVELED:
-      fBorderWidth *= 2;
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = crBackground / 2.0f;
-      break;
-    case BorderStyle::INSET:
-      fBorderWidth *= 2;
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
-      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
-      break;
-    default:
-      break;
-  }
-
-  CFX_FloatRect rcWindow = GetRotatedRect();
-  CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
-  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
-  if (da.HasColor()) {
-    da.GetColor(iColorType, fc);
-    crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
-  }
-
-  int32_t nStyle = 0;
-  CFX_WideString csWCaption = pControl->GetNormalCaption();
-  if (csWCaption.GetLength() > 0) {
-    switch (csWCaption[0]) {
-      default:  // L'l':
-        nStyle = PCS_CIRCLE;
-        break;
-      case L'8':
-        nStyle = PCS_CROSS;
-        break;
-      case L'u':
-        nStyle = PCS_DIAMOND;
-        break;
-      case L'n':
-        nStyle = PCS_SQUARE;
-        break;
-      case L'H':
-        nStyle = PCS_STAR;
-        break;
-      case L'4':
-        nStyle = PCS_CHECK;
-        break;
-    }
-  } else {
-    nStyle = PCS_CIRCLE;
-  }
-
-  CFX_ByteString csAP_N_ON;
-  CFX_FloatRect rcCenter = rcWindow.GetCenterSquare().GetDeflated(1.0f, 1.0f);
-  if (nStyle == PCS_CIRCLE) {
-    if (nBorderStyle == BorderStyle::BEVELED) {
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = crBackground - 0.25f;
-    } else if (nBorderStyle == BorderStyle::INSET) {
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5f);
-      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75f);
-    }
-
-    csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) +
-                CPWL_Utils::GetCircleBorderAppStream(
-                    rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
-                    nBorderStyle, dsBorder);
-  } else {
-    csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
-                CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                               crLeftTop, crRightBottom,
-                                               nBorderStyle, dsBorder);
-  }
-
-  CFX_ByteString csAP_N_OFF = csAP_N_ON;
-
-  switch (nBorderStyle) {
-    case BorderStyle::BEVELED: {
-      CFX_Color crTemp = crLeftTop;
-      crLeftTop = crRightBottom;
-      crRightBottom = crTemp;
-      break;
-    }
-    case BorderStyle::INSET: {
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
-      crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
-      break;
-    }
-    default:
-      break;
-  }
-
-  CFX_ByteString csAP_D_ON;
-
-  if (nStyle == PCS_CIRCLE) {
-    CFX_Color crBK = crBackground - 0.25f;
-    if (nBorderStyle == BorderStyle::BEVELED) {
-      crLeftTop = crBackground - 0.25f;
-      crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
-      crBK = crBackground;
-    } else if (nBorderStyle == BorderStyle::INSET) {
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
-      crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
-    }
-
-    csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) +
-                CPWL_Utils::GetCircleBorderAppStream(
-                    rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
-                    nBorderStyle, dsBorder);
-  } else {
-    csAP_D_ON =
-        CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
-        CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                       crLeftTop, crRightBottom, nBorderStyle,
-                                       dsBorder);
-  }
-
-  CFX_ByteString csAP_D_OFF = csAP_D_ON;
-
-  csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
-  csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
-                  pControl->GetCheckedAPState());
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
-
-  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
-                  pControl->GetCheckedAPState());
-  WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
-
-  CFX_ByteString csAS = GetAppState();
-  if (csAS.IsEmpty())
-    SetAppState("Off");
-}
-
-void CPDFSDK_Widget::ResetAppearance_ComboBox(const CFX_WideString* sValue) {
-  CPDF_FormControl* pControl = GetFormControl();
-  CPDF_FormField* pField = pControl->GetField();
-  std::ostringstream sBody;
-
-  CFX_FloatRect rcClient = GetClientRect();
-  CFX_FloatRect rcButton = rcClient;
-  rcButton.left = rcButton.right - 13;
-  rcButton.Normalize();
-
-  auto pEdit = pdfium::MakeUnique<CFX_Edit>();
-  pEdit->EnableRefresh(false);
-
-  CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
-  pEdit->SetFontMap(&font_map);
-
-  CFX_FloatRect rcEdit = rcClient;
-  rcEdit.right = rcButton.left;
-  rcEdit.Normalize();
-
-  pEdit->SetPlateRect(rcEdit);
-  pEdit->SetAlignmentV(1, true);
-
-  float fFontSize = GetFontSize();
-  if (IsFloatZero(fFontSize))
-    pEdit->SetAutoFontSize(true, true);
-  else
-    pEdit->SetFontSize(fFontSize);
-
-  pEdit->Initialize();
-
-  if (sValue) {
-    pEdit->SetText(*sValue);
-  } else {
-    int32_t nCurSel = pField->GetSelectedIndex(0);
-    if (nCurSel < 0)
-      pEdit->SetText(pField->GetValue());
-    else
-      pEdit->SetText(pField->GetOptionLabel(nCurSel));
-  }
-
-  CFX_FloatRect rcContent = pEdit->GetContentRect();
-
-  CFX_ByteString sEdit =
-      CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF());
-  if (sEdit.GetLength() > 0) {
-    sBody << "/Tx BMC\n"
-          << "q\n";
-    if (rcContent.Width() > rcEdit.Width() ||
-        rcContent.Height() > rcEdit.Height()) {
-      sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
-            << " " << rcEdit.Height() << " re\nW\nn\n";
-    }
-
-    CFX_Color crText = GetTextPWLColor();
-    sBody << "BT\n"
-          << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
-          << "Q\nEMC\n";
-  }
-
-  sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
-
-  CFX_ByteString sAP =
-      GetBackgroundAppStream() + GetBorderAppStream() + CFX_ByteString(sBody);
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
-}
-
-void CPDFSDK_Widget::ResetAppearance_ListBox() {
-  CPDF_FormControl* pControl = GetFormControl();
-  CPDF_FormField* pField = pControl->GetField();
-  CFX_FloatRect rcClient = GetClientRect();
-  std::ostringstream sBody;
-
-  auto pEdit = pdfium::MakeUnique<CFX_Edit>();
-  pEdit->EnableRefresh(false);
-
-  CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
-  pEdit->SetFontMap(&font_map);
-
-  pEdit->SetPlateRect(CFX_FloatRect(rcClient.left, 0.0f, rcClient.right, 0.0f));
-
-  float fFontSize = GetFontSize();
-
-  pEdit->SetFontSize(IsFloatZero(fFontSize) ? 12.0f : fFontSize);
-
-  pEdit->Initialize();
-
-  std::ostringstream sList;
-  float fy = rcClient.top;
-
-  int32_t nTop = pField->GetTopVisibleIndex();
-  int32_t nCount = pField->CountOptions();
-  int32_t nSelCount = pField->CountSelectedItems();
-
-  for (int32_t i = nTop; i < nCount; ++i) {
-    bool bSelected = false;
-    for (int32_t j = 0; j < nSelCount; ++j) {
-      if (pField->GetSelectedIndex(j) == i) {
-        bSelected = true;
-        break;
-      }
-    }
-
-    pEdit->SetText(pField->GetOptionLabel(i));
-
-    CFX_FloatRect rcContent = pEdit->GetContentRect();
-    float fItemHeight = rcContent.Height();
-
-    if (bSelected) {
-      CFX_FloatRect rcItem =
-          CFX_FloatRect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
-      sList << "q\n"
-            << CPWL_Utils::GetColorAppStream(
-                   CFX_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f, 113.0f / 255.0f),
-                   true)
-            << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
-            << " " << rcItem.Height() << " re f\n"
-            << "Q\n";
-
-      sList << "BT\n"
-            << CPWL_Utils::GetColorAppStream(CFX_Color(COLORTYPE_GRAY, 1), true)
-            << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
-            << "ET\n";
-    } else {
-      CFX_Color crText = GetTextPWLColor();
-      sList << "BT\n"
-            << CPWL_Utils::GetColorAppStream(crText, true)
-            << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
-            << "ET\n";
-    }
-
-    fy -= fItemHeight;
-  }
-
-  if (sList.tellp() > 0) {
-    sBody << "/Tx BMC\n"
-          << "q\n"
-          << rcClient.left << " " << rcClient.bottom << " " << rcClient.Width()
-          << " " << rcClient.Height() << " re\nW\nn\n";
-    sBody << sList.str() << "Q\nEMC\n";
-  }
-
-  CFX_ByteString sAP =
-      GetBackgroundAppStream() + GetBorderAppStream() + CFX_ByteString(sBody);
-
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
-}
-
-void CPDFSDK_Widget::ResetAppearance_TextField(const CFX_WideString* sValue) {
-  CPDF_FormControl* pControl = GetFormControl();
-  CPDF_FormField* pField = pControl->GetField();
-  std::ostringstream sBody;
-  std::ostringstream sLines;
-
-  auto pEdit = pdfium::MakeUnique<CFX_Edit>();
-  pEdit->EnableRefresh(false);
-
-  CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
-  pEdit->SetFontMap(&font_map);
-
-  CFX_FloatRect rcClient = GetClientRect();
-  pEdit->SetPlateRect(rcClient);
-  pEdit->SetAlignmentH(pControl->GetControlAlignment(), true);
-
-  uint32_t dwFieldFlags = pField->GetFieldFlags();
-  bool bMultiLine = (dwFieldFlags >> 12) & 1;
-
-  if (bMultiLine) {
-    pEdit->SetMultiLine(true, true);
-    pEdit->SetAutoReturn(true, true);
-  } else {
-    pEdit->SetAlignmentV(1, true);
-  }
-
-  uint16_t subWord = 0;
-  if ((dwFieldFlags >> 13) & 1) {
-    subWord = '*';
-    pEdit->SetPasswordChar(subWord, true);
-  }
-
-  int nMaxLen = pField->GetMaxLen();
-  bool bCharArray = (dwFieldFlags >> 24) & 1;
-  float fFontSize = GetFontSize();
-
-#ifdef PDF_ENABLE_XFA
-  CFX_WideString sValueTmp;
-  if (!sValue && GetMixXFAWidget()) {
-    sValueTmp = GetValue(true);
-    sValue = &sValueTmp;
-  }
-#endif  // PDF_ENABLE_XFA
-
-  if (nMaxLen > 0) {
-    if (bCharArray) {
-      pEdit->SetCharArray(nMaxLen);
-
-      if (IsFloatZero(fFontSize)) {
-        fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(font_map.GetPDFFont(0),
-                                                        rcClient, nMaxLen);
-      }
-    } else {
-      if (sValue)
-        nMaxLen = sValue->GetLength();
-      pEdit->SetLimitChar(nMaxLen);
-    }
-  }
-
-  if (IsFloatZero(fFontSize))
-    pEdit->SetAutoFontSize(true, true);
-  else
-    pEdit->SetFontSize(fFontSize);
-
-  pEdit->Initialize();
-  pEdit->SetText(sValue ? *sValue : pField->GetValue());
-
-  CFX_FloatRect rcContent = pEdit->GetContentRect();
-  CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
-      pEdit.get(), CFX_PointF(), nullptr, !bCharArray, subWord);
-
-  if (sEdit.GetLength() > 0) {
-    sBody << "/Tx BMC\n"
-          << "q\n";
-    if (rcContent.Width() > rcClient.Width() ||
-        rcContent.Height() > rcClient.Height()) {
-      sBody << rcClient.left << " " << rcClient.bottom << " "
-            << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
-    }
-    CFX_Color crText = GetTextPWLColor();
-    sBody << "BT\n"
-          << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
-          << "Q\nEMC\n";
-  }
-
-  if (bCharArray) {
-    switch (GetBorderStyle()) {
-      case BorderStyle::SOLID: {
-        CFX_ByteString sColor =
-            CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false);
-        if (sColor.GetLength() > 0) {
-          sLines << "q\n"
-                 << GetBorderWidth() << " w\n"
-                 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false)
-                 << " 2 J 0 j\n";
-
-          for (int32_t i = 1; i < nMaxLen; ++i) {
-            sLines << rcClient.left +
-                          ((rcClient.right - rcClient.left) / nMaxLen) * i
-                   << " " << rcClient.bottom << " m\n"
-                   << rcClient.left +
-                          ((rcClient.right - rcClient.left) / nMaxLen) * i
-                   << " " << rcClient.top << " l S\n";
-          }
-
-          sLines << "Q\n";
-        }
-        break;
-      }
-      case BorderStyle::DASH: {
-        CFX_ByteString sColor =
-            CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false);
-        if (sColor.GetLength() > 0) {
-          CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
-
-          sLines << "q\n"
-                 << GetBorderWidth() << " w\n"
-                 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false)
-                 << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
-                 << dsBorder.nPhase << " d\n";
-
-          for (int32_t i = 1; i < nMaxLen; ++i) {
-            sLines << rcClient.left +
-                          ((rcClient.right - rcClient.left) / nMaxLen) * i
-                   << " " << rcClient.bottom << " m\n"
-                   << rcClient.left +
-                          ((rcClient.right - rcClient.left) / nMaxLen) * i
-                   << " " << rcClient.top << " l S\n";
-          }
-
-          sLines << "Q\n";
-        }
-        break;
-      }
-      default:
-        break;
-    }
-  }
-
-  CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
-                       CFX_ByteString(sLines) + CFX_ByteString(sBody);
-  WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
-}
-
 CFX_FloatRect CPDFSDK_Widget::GetClientRect() const {
   CFX_FloatRect rcWindow = GetRotatedRect();
   float fBorderWidth = (float)GetBorderWidth();
@@ -1668,47 +897,6 @@
   return rcPDFWindow;
 }
 
-CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
-  CFX_Color crBackground = GetFillPWLColor();
-  if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
-    return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
-
-  return "";
-}
-
-CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const {
-  CFX_FloatRect rcWindow = GetRotatedRect();
-  CFX_Color crBorder = GetBorderPWLColor();
-  CFX_Color crBackground = GetFillPWLColor();
-  CFX_Color crLeftTop, crRightBottom;
-
-  float fBorderWidth = (float)GetBorderWidth();
-  CPWL_Dash dsBorder(3, 0, 0);
-
-  BorderStyle nBorderStyle = GetBorderStyle();
-  switch (nBorderStyle) {
-    case BorderStyle::DASH:
-      dsBorder = CPWL_Dash(3, 3, 0);
-      break;
-    case BorderStyle::BEVELED:
-      fBorderWidth *= 2;
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
-      crRightBottom = crBackground / 2.0f;
-      break;
-    case BorderStyle::INSET:
-      fBorderWidth *= 2;
-      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
-      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
-      break;
-    default:
-      break;
-  }
-
-  return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
-                                        crLeftTop, crRightBottom, nBorderStyle,
-                                        dsBorder);
-}
-
 CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
   CFX_Matrix mt;
   CPDF_FormControl* pControl = GetFormControl();
@@ -1775,34 +963,6 @@
   return crFill;
 }
 
-void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType,
-                                          CPDF_Stream* pImage) {
-  CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
-  CPDF_Stream* pStream = pAPDict->GetStreamFor(sAPType);
-  CPDF_Dictionary* pStreamDict = pStream->GetDict();
-  CFX_ByteString sImageAlias = "IMG";
-
-  if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
-    sImageAlias = pImageDict->GetStringFor("Name");
-    if (sImageAlias.IsEmpty())
-      sImageAlias = "IMG";
-  }
-
-  CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
-  CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
-  if (!pStreamResList)
-    pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
-
-  CPDF_Dictionary* pXObject =
-      pStreamResList->SetNewFor<CPDF_Dictionary>("XObject");
-  pXObject->SetNewFor<CPDF_Reference>(sImageAlias, pDoc, pImage->GetObjNum());
-}
-
-void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
-  if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP"))
-    pAPDict->RemoveFor(sAPType);
-}
-
 bool CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
                                PDFSDK_FieldAction& data,
                                CPDFSDK_PageView* pPageView) {
diff --git a/fpdfsdk/cpdfsdk_widget.h b/fpdfsdk/cpdfsdk_widget.h
index 8f031cf..954369d 100644
--- a/fpdfsdk/cpdfsdk_widget.h
+++ b/fpdfsdk/cpdfsdk_widget.h
@@ -139,28 +139,14 @@
                       CPDF_Annot::AppearanceMode mode,
                       const CPDF_RenderOptions* pOptions) override;
 
- private:
-  void ResetAppearance_PushButton();
-  void ResetAppearance_CheckBox();
-  void ResetAppearance_RadioButton();
-  void ResetAppearance_ComboBox(const CFX_WideString* sValue);
-  void ResetAppearance_ListBox();
-  void ResetAppearance_TextField(const CFX_WideString* sValue);
-
+  CFX_Matrix GetMatrix() const;
   CFX_FloatRect GetClientRect() const;
   CFX_FloatRect GetRotatedRect() const;
-
-  CFX_ByteString GetBackgroundAppStream() const;
-  CFX_ByteString GetBorderAppStream() const;
-  CFX_Matrix GetMatrix() const;
-
   CFX_Color GetTextPWLColor() const;
   CFX_Color GetBorderPWLColor() const;
   CFX_Color GetFillPWLColor() const;
 
-  void AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Stream* pImage);
-  void RemoveAppearance(const CFX_ByteString& sAPType);
-
+ private:
   CFX_UnownedPtr<CPDFSDK_InterForm> const m_pInterForm;
   bool m_bAppModified;
   int32_t m_nAppAge;
diff --git a/fpdfsdk/pdfwindow/cpwl_appstream.cpp b/fpdfsdk/pdfwindow/cpwl_appstream.cpp
new file mode 100644
index 0000000..2b158cd
--- /dev/null
+++ b/fpdfsdk/pdfwindow/cpwl_appstream.cpp
@@ -0,0 +1,1558 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/pdfwindow/cpwl_appstream.h"
+
+#include <utility>
+
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_document.h"
+#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_number.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfapi/parser/cpdf_string.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_interform.h"
+#include "fpdfsdk/cpdfsdk_pageview.h"
+#include "fpdfsdk/cpdfsdk_widget.h"
+#include "fpdfsdk/formfiller/cba_fontmap.h"
+#include "fpdfsdk/fxedit/fxet_edit.h"
+#include "fpdfsdk/pdfwindow/cpwl_edit.h"
+#include "fpdfsdk/pdfwindow/cpwl_icon.h"
+#include "fpdfsdk/pdfwindow/cpwl_utils.h"
+#include "fpdfsdk/pdfwindow/cpwl_wnd.h"
+
+namespace {
+
+CFX_ByteString GetAP_Check(const CFX_FloatRect& crBBox) {
+  const float fWidth = crBBox.right - crBBox.left;
+  const float fHeight = crBBox.top - crBBox.bottom;
+
+  CFX_PointF pts[8][3] = {{CFX_PointF(0.28f, 0.52f), CFX_PointF(0.27f, 0.48f),
+                           CFX_PointF(0.29f, 0.40f)},
+                          {CFX_PointF(0.30f, 0.33f), CFX_PointF(0.31f, 0.29f),
+                           CFX_PointF(0.31f, 0.28f)},
+                          {CFX_PointF(0.39f, 0.28f), CFX_PointF(0.49f, 0.29f),
+                           CFX_PointF(0.77f, 0.67f)},
+                          {CFX_PointF(0.76f, 0.68f), CFX_PointF(0.78f, 0.69f),
+                           CFX_PointF(0.76f, 0.75f)},
+                          {CFX_PointF(0.76f, 0.75f), CFX_PointF(0.73f, 0.80f),
+                           CFX_PointF(0.68f, 0.75f)},
+                          {CFX_PointF(0.68f, 0.74f), CFX_PointF(0.68f, 0.74f),
+                           CFX_PointF(0.44f, 0.47f)},
+                          {CFX_PointF(0.43f, 0.47f), CFX_PointF(0.40f, 0.47f),
+                           CFX_PointF(0.41f, 0.58f)},
+                          {CFX_PointF(0.40f, 0.60f), CFX_PointF(0.28f, 0.66f),
+                           CFX_PointF(0.30f, 0.56f)}};
+
+  for (size_t i = 0; i < FX_ArraySize(pts); ++i) {
+    for (size_t j = 0; j < FX_ArraySize(pts[0]); ++j) {
+      pts[i][j].x = pts[i][j].x * fWidth + crBBox.left;
+      pts[i][j].y *= pts[i][j].y * fHeight + crBBox.bottom;
+    }
+  }
+
+  std::ostringstream csAP;
+  csAP << pts[0][0].x << " " << pts[0][0].y << " m\n";
+
+  for (size_t i = 0; i < FX_ArraySize(pts); ++i) {
+    size_t nNext = i < FX_ArraySize(pts) - 1 ? i + 1 : 0;
+
+    float px1 = pts[i][1].x - pts[i][0].x;
+    float py1 = pts[i][1].y - pts[i][0].y;
+    float px2 = pts[i][2].x - pts[nNext][0].x;
+    float py2 = pts[i][2].y - pts[nNext][0].y;
+
+    csAP << pts[i][0].x + px1 * FX_BEZIER << " "
+         << pts[i][0].y + py1 * FX_BEZIER << " "
+         << pts[nNext][0].x + px2 * FX_BEZIER << " "
+         << pts[nNext][0].y + py2 * FX_BEZIER << " " << pts[nNext][0].x << " "
+         << pts[nNext][0].y << " c\n";
+  }
+
+  return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Circle(const CFX_FloatRect& crBBox) {
+  std::ostringstream csAP;
+
+  float fWidth = crBBox.right - crBBox.left;
+  float fHeight = crBBox.top - crBBox.bottom;
+
+  CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2);
+  CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top);
+  CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2);
+  CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom);
+
+  csAP << pt1.x << " " << pt1.y << " m\n";
+
+  float px = pt2.x - pt1.x;
+  float py = pt2.y - pt1.y;
+
+  csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
+       << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
+       << " c\n";
+
+  px = pt3.x - pt2.x;
+  py = pt2.y - pt3.y;
+
+  csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
+       << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
+
+  px = pt3.x - pt4.x;
+  py = pt3.y - pt4.y;
+
+  csAP << pt3.x << " " << pt3.y - py * FX_BEZIER << " "
+       << pt4.x + px * FX_BEZIER << " " << pt4.y << " " << pt4.x << " " << pt4.y
+       << " c\n";
+
+  px = pt4.x - pt1.x;
+  py = pt1.y - pt4.y;
+
+  csAP << pt4.x - px * FX_BEZIER << " " << pt4.y << " " << pt1.x << " "
+       << pt1.y - py * FX_BEZIER << " " << pt1.x << " " << pt1.y << " c\n";
+
+  return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Cross(const CFX_FloatRect& crBBox) {
+  std::ostringstream csAP;
+
+  csAP << crBBox.left << " " << crBBox.top << " m\n";
+  csAP << crBBox.right << " " << crBBox.bottom << " l\n";
+  csAP << crBBox.left << " " << crBBox.bottom << " m\n";
+  csAP << crBBox.right << " " << crBBox.top << " l\n";
+
+  return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Diamond(const CFX_FloatRect& crBBox) {
+  std::ostringstream csAP;
+
+  float fWidth = crBBox.right - crBBox.left;
+  float fHeight = crBBox.top - crBBox.bottom;
+
+  CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2);
+  CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top);
+  CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2);
+  CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom);
+
+  csAP << pt1.x << " " << pt1.y << " m\n";
+  csAP << pt2.x << " " << pt2.y << " l\n";
+  csAP << pt3.x << " " << pt3.y << " l\n";
+  csAP << pt4.x << " " << pt4.y << " l\n";
+  csAP << pt1.x << " " << pt1.y << " l\n";
+
+  return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Square(const CFX_FloatRect& crBBox) {
+  std::ostringstream csAP;
+
+  csAP << crBBox.left << " " << crBBox.top << " m\n";
+  csAP << crBBox.right << " " << crBBox.top << " l\n";
+  csAP << crBBox.right << " " << crBBox.bottom << " l\n";
+  csAP << crBBox.left << " " << crBBox.bottom << " l\n";
+  csAP << crBBox.left << " " << crBBox.top << " l\n";
+
+  return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_Star(const CFX_FloatRect& crBBox) {
+  std::ostringstream csAP;
+
+  float fRadius = (crBBox.top - crBBox.bottom) / (1 + (float)cos(FX_PI / 5.0f));
+  CFX_PointF ptCenter = CFX_PointF((crBBox.left + crBBox.right) / 2.0f,
+                                   (crBBox.top + crBBox.bottom) / 2.0f);
+
+  float px[5];
+  float py[5];
+  float fAngel = FX_PI / 10.0f;
+  for (int32_t i = 0; i < 5; i++) {
+    px[i] = ptCenter.x + fRadius * (float)cos(fAngel);
+    py[i] = ptCenter.y + fRadius * (float)sin(fAngel);
+    fAngel += FX_PI * 2 / 5.0f;
+  }
+
+  csAP << px[0] << " " << py[0] << " m\n";
+
+  int32_t nNext = 0;
+  for (int32_t j = 0; j < 5; j++) {
+    nNext += 2;
+    if (nNext >= 5)
+      nNext -= 5;
+    csAP << px[nNext] << " " << py[nNext] << " l\n";
+  }
+
+  return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAP_HalfCircle(const CFX_FloatRect& crBBox, float fRotate) {
+  std::ostringstream csAP;
+
+  float fWidth = crBBox.right - crBBox.left;
+  float fHeight = crBBox.top - crBBox.bottom;
+
+  CFX_PointF pt1(-fWidth / 2, 0);
+  CFX_PointF pt2(0, fHeight / 2);
+  CFX_PointF pt3(fWidth / 2, 0);
+
+  float px;
+  float py;
+
+  csAP << cos(fRotate) << " " << sin(fRotate) << " " << -sin(fRotate) << " "
+       << cos(fRotate) << " " << crBBox.left + fWidth / 2 << " "
+       << crBBox.bottom + fHeight / 2 << " cm\n";
+
+  csAP << pt1.x << " " << pt1.y << " m\n";
+
+  px = pt2.x - pt1.x;
+  py = pt2.y - pt1.y;
+
+  csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
+       << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
+       << " c\n";
+
+  px = pt3.x - pt2.x;
+  py = pt2.y - pt3.y;
+
+  csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
+       << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
+
+  return CFX_ByteString(csAP);
+}
+
+CFX_ByteString GetAppStream_Check(const CFX_FloatRect& rcBBox,
+                                  const CFX_Color& crText) {
+  std::ostringstream sAP;
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Check(rcBBox)
+      << "f\nQ\n";
+  return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Circle(const CFX_FloatRect& rcBBox,
+                                   const CFX_Color& crText) {
+  std::ostringstream sAP;
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Circle(rcBBox)
+      << "f\nQ\n";
+  return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Cross(const CFX_FloatRect& rcBBox,
+                                  const CFX_Color& crText) {
+  std::ostringstream sAP;
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, false) << GetAP_Cross(rcBBox)
+      << "S\nQ\n";
+  return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Diamond(const CFX_FloatRect& rcBBox,
+                                    const CFX_Color& crText) {
+  std::ostringstream sAP;
+  sAP << "q\n1 w\n"
+      << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Diamond(rcBBox)
+      << "f\nQ\n";
+  return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Square(const CFX_FloatRect& rcBBox,
+                                   const CFX_Color& crText) {
+  std::ostringstream sAP;
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Square(rcBBox)
+      << "f\nQ\n";
+  return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetAppStream_Star(const CFX_FloatRect& rcBBox,
+                                 const CFX_Color& crText) {
+  std::ostringstream sAP;
+  sAP << "q\n"
+      << CPWL_Utils::GetColorAppStream(crText, true) << GetAP_Star(rcBBox)
+      << "f\nQ\n";
+  return CFX_ByteString(sAP);
+}
+
+CFX_ByteString GetCircleFillAppStream(const CFX_FloatRect& rect,
+                                      const CFX_Color& color) {
+  std::ostringstream sAppStream;
+  CFX_ByteString sColor = CPWL_Utils::GetColorAppStream(color, true);
+  if (sColor.GetLength() > 0)
+    sAppStream << "q\n" << sColor << GetAP_Circle(rect) << "f\nQ\n";
+  return CFX_ByteString(sAppStream);
+}
+
+CFX_ByteString GetCircleBorderAppStream(const CFX_FloatRect& rect,
+                                        float fWidth,
+                                        const CFX_Color& color,
+                                        const CFX_Color& crLeftTop,
+                                        const CFX_Color& crRightBottom,
+                                        BorderStyle nStyle,
+                                        const CPWL_Dash& dash) {
+  std::ostringstream sAppStream;
+  CFX_ByteString sColor;
+
+  if (fWidth > 0.0f) {
+    sAppStream << "q\n";
+
+    float fHalfWidth = fWidth / 2.0f;
+    CFX_FloatRect rect_by_2 = rect.GetDeflated(fHalfWidth, fHalfWidth);
+
+    float div = fHalfWidth * 0.75f;
+    CFX_FloatRect rect_by_75 = rect.GetDeflated(div, div);
+    switch (nStyle) {
+      default:
+      case BorderStyle::SOLID:
+      case BorderStyle::UNDERLINE: {
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
+        if (sColor.GetLength() > 0) {
+          sAppStream << "q\n"
+                     << fWidth << " w\n"
+                     << sColor << GetAP_Circle(rect_by_2) << " S\nQ\n";
+        }
+      } break;
+      case BorderStyle::DASH: {
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
+        if (sColor.GetLength() > 0) {
+          sAppStream << "q\n"
+                     << fWidth << " w\n"
+                     << "[" << dash.nDash << " " << dash.nGap << "] "
+                     << dash.nPhase << " d\n"
+                     << sColor << GetAP_Circle(rect_by_2) << " S\nQ\n";
+        }
+      } break;
+      case BorderStyle::BEVELED: {
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
+        if (sColor.GetLength() > 0) {
+          sAppStream << "q\n"
+                     << fHalfWidth << " w\n"
+                     << sColor << GetAP_Circle(rect) << " S\nQ\n";
+        }
+
+        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
+        if (sColor.GetLength() > 0) {
+          sAppStream << "q\n"
+                     << fHalfWidth << " w\n"
+                     << sColor << GetAP_HalfCircle(rect_by_75, FX_PI / 4.0f)
+                     << " S\nQ\n";
+        }
+
+        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
+        if (sColor.GetLength() > 0) {
+          sAppStream << "q\n"
+                     << fHalfWidth << " w\n"
+                     << sColor << GetAP_HalfCircle(rect_by_75, FX_PI * 5 / 4.0f)
+                     << " S\nQ\n";
+        }
+      } break;
+      case BorderStyle::INSET: {
+        sColor = CPWL_Utils::GetColorAppStream(color, false);
+        if (sColor.GetLength() > 0) {
+          sAppStream << "q\n"
+                     << fHalfWidth << " w\n"
+                     << sColor << GetAP_Circle(rect) << " S\nQ\n";
+        }
+
+        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
+        if (sColor.GetLength() > 0) {
+          sAppStream << "q\n"
+                     << fHalfWidth << " w\n"
+                     << sColor << GetAP_HalfCircle(rect_by_75, FX_PI / 4.0f)
+                     << " S\nQ\n";
+        }
+
+        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
+        if (sColor.GetLength() > 0) {
+          sAppStream << "q\n"
+                     << fHalfWidth << " w\n"
+                     << sColor << GetAP_HalfCircle(rect_by_75, FX_PI * 5 / 4.0f)
+                     << " S\nQ\n";
+        }
+      } break;
+    }
+
+    sAppStream << "Q\n";
+  }
+  return CFX_ByteString(sAppStream);
+}
+
+CFX_ByteString GetCheckBoxAppStream(const CFX_FloatRect& rcBBox,
+                                    int32_t nStyle,
+                                    const CFX_Color& crText) {
+  CFX_FloatRect rcCenter = rcBBox.GetCenterSquare();
+  switch (nStyle) {
+    default:
+    case PCS_CHECK:
+      return GetAppStream_Check(rcCenter, crText);
+    case PCS_CIRCLE:
+      rcCenter.Scale(2.0f / 3.0f);
+      return GetAppStream_Circle(rcCenter, crText);
+    case PCS_CROSS:
+      return GetAppStream_Cross(rcCenter, crText);
+    case PCS_DIAMOND:
+      rcCenter.Scale(2.0f / 3.0f);
+      return GetAppStream_Diamond(rcCenter, crText);
+    case PCS_SQUARE:
+      rcCenter.Scale(2.0f / 3.0f);
+      return GetAppStream_Square(rcCenter, crText);
+    case PCS_STAR:
+      rcCenter.Scale(2.0f / 3.0f);
+      return GetAppStream_Star(rcCenter, crText);
+  }
+}
+
+CFX_ByteString GetRadioButtonAppStream(const CFX_FloatRect& rcBBox,
+                                       int32_t nStyle,
+                                       const CFX_Color& crText) {
+  CFX_FloatRect rcCenter = rcBBox.GetCenterSquare();
+  switch (nStyle) {
+    default:
+    case PCS_CHECK:
+      return GetAppStream_Check(rcCenter, crText);
+    case PCS_CIRCLE:
+      rcCenter.Scale(1.0f / 2.0f);
+      return GetAppStream_Circle(rcCenter, crText);
+    case PCS_CROSS:
+      return GetAppStream_Cross(rcCenter, crText);
+    case PCS_DIAMOND:
+      rcCenter.Scale(2.0f / 3.0f);
+      return GetAppStream_Diamond(rcCenter, crText);
+    case PCS_SQUARE:
+      rcCenter.Scale(2.0f / 3.0f);
+      return GetAppStream_Square(rcCenter, crText);
+    case PCS_STAR:
+      rcCenter.Scale(2.0f / 3.0f);
+      return GetAppStream_Star(rcCenter, crText);
+  }
+}
+
+CFX_ByteString GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
+                                      IPVT_FontMap* pFontMap,
+                                      CPDF_Stream* pIconStream,
+                                      CPDF_IconFit& IconFit,
+                                      const CFX_WideString& sLabel,
+                                      const CFX_Color& crText,
+                                      float fFontSize,
+                                      int32_t nLayOut) {
+  const float fAutoFontScale = 1.0f / 3.0f;
+
+  auto pEdit = pdfium::MakeUnique<CFX_Edit>();
+  pEdit->SetFontMap(pFontMap);
+  pEdit->SetAlignmentH(1, true);
+  pEdit->SetAlignmentV(1, true);
+  pEdit->SetMultiLine(false, true);
+  pEdit->SetAutoReturn(false, true);
+  if (IsFloatZero(fFontSize))
+    pEdit->SetAutoFontSize(true, true);
+  else
+    pEdit->SetFontSize(fFontSize);
+
+  pEdit->Initialize();
+  pEdit->SetText(sLabel);
+
+  CFX_FloatRect rcLabelContent = pEdit->GetContentRect();
+  CPWL_Icon Icon;
+  PWL_CREATEPARAM cp;
+  cp.dwFlags = PWS_VISIBLE;
+  Icon.Create(cp);
+  Icon.SetIconFit(&IconFit);
+  Icon.SetPDFStream(pIconStream);
+
+  CFX_FloatRect rcLabel;
+  CFX_FloatRect rcIcon;
+  float fWidth = 0.0f;
+  float fHeight = 0.0f;
+
+  switch (nLayOut) {
+    case PPBL_LABEL:
+      rcLabel = rcBBox;
+      break;
+    case PPBL_ICON:
+      rcIcon = rcBBox;
+      break;
+    case PPBL_ICONTOPLABELBOTTOM:
+      if (pIconStream) {
+        if (IsFloatZero(fFontSize)) {
+          fHeight = rcBBox.top - rcBBox.bottom;
+          rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+                                  rcBBox.bottom + fHeight * fAutoFontScale);
+          rcIcon =
+              CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right, rcBBox.top);
+        } else {
+          fHeight = rcLabelContent.Height();
+
+          if (rcBBox.bottom + fHeight > rcBBox.top) {
+            rcLabel = rcBBox;
+          } else {
+            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+                                    rcBBox.bottom + fHeight);
+            rcIcon = CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right,
+                                   rcBBox.top);
+          }
+        }
+      } else {
+        rcLabel = rcBBox;
+      }
+      break;
+    case PPBL_LABELTOPICONBOTTOM:
+      if (pIconStream) {
+        if (IsFloatZero(fFontSize)) {
+          fHeight = rcBBox.top - rcBBox.bottom;
+          rcLabel =
+              CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight * fAutoFontScale,
+                            rcBBox.right, rcBBox.top);
+          rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+                                 rcLabel.bottom);
+        } else {
+          fHeight = rcLabelContent.Height();
+
+          if (rcBBox.bottom + fHeight > rcBBox.top) {
+            rcLabel = rcBBox;
+          } else {
+            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight,
+                                    rcBBox.right, rcBBox.top);
+            rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
+                                   rcLabel.bottom);
+          }
+        }
+      } else {
+        rcLabel = rcBBox;
+      }
+      break;
+    case PPBL_ICONLEFTLABELRIGHT:
+      if (pIconStream) {
+        if (IsFloatZero(fFontSize)) {
+          fWidth = rcBBox.right - rcBBox.left;
+          if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
+            rcLabel = CFX_FloatRect(rcBBox.right - fWidth * fAutoFontScale,
+                                    rcBBox.bottom, rcBBox.right, rcBBox.top);
+            rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+                                   rcBBox.top);
+          } else {
+            if (rcLabelContent.Width() < fWidth) {
+              rcLabel = CFX_FloatRect(rcBBox.right - rcLabelContent.Width(),
+                                      rcBBox.bottom, rcBBox.right, rcBBox.top);
+              rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+                                     rcBBox.top);
+            } else {
+              rcLabel = rcBBox;
+            }
+          }
+        } else {
+          fWidth = rcLabelContent.Width();
+          if (rcBBox.left + fWidth > rcBBox.right) {
+            rcLabel = rcBBox;
+          } else {
+            rcLabel = CFX_FloatRect(rcBBox.right - fWidth, rcBBox.bottom,
+                                    rcBBox.right, rcBBox.top);
+            rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
+                                   rcBBox.top);
+          }
+        }
+      } else {
+        rcLabel = rcBBox;
+      }
+      break;
+    case PPBL_LABELLEFTICONRIGHT:
+      if (pIconStream) {
+        if (IsFloatZero(fFontSize)) {
+          fWidth = rcBBox.right - rcBBox.left;
+          if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
+            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
+                                    rcBBox.left + fWidth * fAutoFontScale,
+                                    rcBBox.top);
+            rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
+                                   rcBBox.top);
+          } else {
+            if (rcLabelContent.Width() < fWidth) {
+              rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
+                                      rcBBox.left + rcLabelContent.Width(),
+                                      rcBBox.top);
+              rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
+                                     rcBBox.top);
+            } else {
+              rcLabel = rcBBox;
+            }
+          }
+        } else {
+          fWidth = rcLabelContent.Width();
+          if (rcBBox.left + fWidth > rcBBox.right) {
+            rcLabel = rcBBox;
+          } else {
+            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
+                                    rcBBox.left + fWidth, rcBBox.top);
+            rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
+                                   rcBBox.top);
+          }
+        }
+      } else {
+        rcLabel = rcBBox;
+      }
+      break;
+    case PPBL_LABELOVERICON:
+      rcLabel = rcBBox;
+      rcIcon = rcBBox;
+      break;
+  }
+
+  std::ostringstream sTemp;
+
+  if (!rcIcon.IsEmpty()) {
+    Icon.Move(rcIcon, false, false);
+    sTemp << Icon.GetImageAppStream();
+  }
+
+  Icon.Destroy();
+
+  if (!rcLabel.IsEmpty()) {
+    pEdit->SetPlateRect(rcLabel);
+    CFX_ByteString sEdit =
+        CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, 0.0f));
+    if (sEdit.GetLength() > 0) {
+      sTemp << "BT\n"
+            << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n";
+    }
+  }
+
+  if (sTemp.tellp() <= 0)
+    return CFX_ByteString();
+
+  std::ostringstream sAppStream;
+  sAppStream << "q\n"
+             << rcBBox.left << " " << rcBBox.bottom << " "
+             << rcBBox.right - rcBBox.left << " " << rcBBox.top - rcBBox.bottom
+             << " re W n\n";
+  sAppStream << sTemp.str().c_str() << "Q\n";
+  return CFX_ByteString(sAppStream);
+}
+
+CFX_ByteString GetDropButtonAppStream(const CFX_FloatRect& rcBBox) {
+  if (rcBBox.IsEmpty())
+    return CFX_ByteString();
+
+  std::ostringstream sAppStream;
+  sAppStream << "q\n"
+             << CPWL_Utils::GetColorAppStream(
+                    CFX_Color(COLORTYPE_RGB, 220.0f / 255.0f, 220.0f / 255.0f,
+                              220.0f / 255.0f),
+                    true)
+             << rcBBox.left << " " << rcBBox.bottom << " "
+             << rcBBox.right - rcBBox.left << " " << rcBBox.top - rcBBox.bottom
+             << " re f\n"
+             << "Q\n";
+
+  sAppStream << "q\n"
+             << CPWL_Utils::GetBorderAppStream(
+                    rcBBox, 2, CFX_Color(COLORTYPE_GRAY, 0),
+                    CFX_Color(COLORTYPE_GRAY, 1),
+                    CFX_Color(COLORTYPE_GRAY, 0.5), BorderStyle::BEVELED,
+                    CPWL_Dash(3, 0, 0))
+             << "Q\n";
+
+  CFX_PointF ptCenter = CFX_PointF((rcBBox.left + rcBBox.right) / 2,
+                                   (rcBBox.top + rcBBox.bottom) / 2);
+  if (IsFloatBigger(rcBBox.right - rcBBox.left, 6) &&
+      IsFloatBigger(rcBBox.top - rcBBox.bottom, 6)) {
+    sAppStream << "q\n"
+               << " 0 g\n"
+               << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " m\n"
+               << ptCenter.x + 3 << " " << ptCenter.y + 1.5f << " l\n"
+               << ptCenter.x << " " << ptCenter.y - 1.5f << " l\n"
+               << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " l f\n"
+               << "Q\n";
+  }
+
+  return CFX_ByteString(sAppStream);
+}
+
+}  // namespace
+
+CPWL_AppStream::CPWL_AppStream(CPDFSDK_Widget* widget, CPDF_Dictionary* dict)
+    : widget_(widget), dict_(dict) {}
+
+CPWL_AppStream::~CPWL_AppStream() {}
+
+void CPWL_AppStream::SetAsPushButton() {
+  CPDF_FormControl* pControl = widget_->GetFormControl();
+  CFX_FloatRect rcWindow = widget_->GetRotatedRect();
+  int32_t nLayout = 0;
+  switch (pControl->GetTextPosition()) {
+    case TEXTPOS_ICON:
+      nLayout = PPBL_ICON;
+      break;
+    case TEXTPOS_BELOW:
+      nLayout = PPBL_ICONTOPLABELBOTTOM;
+      break;
+    case TEXTPOS_ABOVE:
+      nLayout = PPBL_LABELTOPICONBOTTOM;
+      break;
+    case TEXTPOS_RIGHT:
+      nLayout = PPBL_ICONLEFTLABELRIGHT;
+      break;
+    case TEXTPOS_LEFT:
+      nLayout = PPBL_LABELLEFTICONRIGHT;
+      break;
+    case TEXTPOS_OVERLAID:
+      nLayout = PPBL_LABELOVERICON;
+      break;
+    default:
+      nLayout = PPBL_LABEL;
+      break;
+  }
+
+  CFX_Color crBackground;
+  CFX_Color crBorder;
+  int iColorType;
+  float fc[4];
+  pControl->GetOriginalBackgroundColor(iColorType, fc);
+  if (iColorType > 0)
+    crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  pControl->GetOriginalBorderColor(iColorType, fc);
+  if (iColorType > 0)
+    crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  float fBorderWidth = static_cast<float>(widget_->GetBorderWidth());
+  CPWL_Dash dsBorder(3, 0, 0);
+  CFX_Color crLeftTop;
+  CFX_Color crRightBottom;
+
+  BorderStyle nBorderStyle = widget_->GetBorderStyle();
+  switch (nBorderStyle) {
+    case BorderStyle::DASH:
+      dsBorder = CPWL_Dash(3, 3, 0);
+      break;
+    case BorderStyle::BEVELED:
+      fBorderWidth *= 2;
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = crBackground / 2.0f;
+      break;
+    case BorderStyle::INSET:
+      fBorderWidth *= 2;
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
+      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
+      break;
+    default:
+      break;
+  }
+
+  CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
+  CFX_Color crText(COLORTYPE_GRAY, 0);
+  CFX_ByteString csNameTag;
+  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
+  if (da.HasColor()) {
+    da.GetColor(iColorType, fc);
+    crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+  }
+  float fFontSize = 12.0f;
+  if (da.HasFont())
+    csNameTag = da.GetFont(&fFontSize);
+
+  CFX_WideString csWCaption;
+  CFX_WideString csNormalCaption;
+  CFX_WideString csRolloverCaption;
+  CFX_WideString csDownCaption;
+  if (pControl->HasMKEntry("CA"))
+    csNormalCaption = pControl->GetNormalCaption();
+
+  if (pControl->HasMKEntry("RC"))
+    csRolloverCaption = pControl->GetRolloverCaption();
+
+  if (pControl->HasMKEntry("AC"))
+    csDownCaption = pControl->GetDownCaption();
+
+  CPDF_Stream* pNormalIcon = nullptr;
+  CPDF_Stream* pRolloverIcon = nullptr;
+  CPDF_Stream* pDownIcon = nullptr;
+  if (pControl->HasMKEntry("I"))
+    pNormalIcon = pControl->GetNormalIcon();
+
+  if (pControl->HasMKEntry("RI"))
+    pRolloverIcon = pControl->GetRolloverIcon();
+
+  if (pControl->HasMKEntry("IX"))
+    pDownIcon = pControl->GetDownIcon();
+
+  if (pNormalIcon) {
+    if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
+      if (pImageDict->GetStringFor("Name").IsEmpty())
+        pImageDict->SetNewFor<CPDF_String>("Name", "ImgA", false);
+    }
+  }
+
+  if (pRolloverIcon) {
+    if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
+      if (pImageDict->GetStringFor("Name").IsEmpty())
+        pImageDict->SetNewFor<CPDF_String>("Name", "ImgB", false);
+    }
+  }
+
+  if (pDownIcon) {
+    if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
+      if (pImageDict->GetStringFor("Name").IsEmpty())
+        pImageDict->SetNewFor<CPDF_String>("Name", "ImgC", false);
+    }
+  }
+
+  CPDF_IconFit iconFit = pControl->GetIconFit();
+
+  CBA_FontMap font_map(
+      widget_.Get(),
+      widget_->GetInterForm()->GetFormFillEnv()->GetSysHandler());
+  font_map.SetAPType("N");
+
+  CFX_ByteString csAP =
+      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                     crLeftTop, crRightBottom, nBorderStyle,
+                                     dsBorder) +
+      GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient,
+                             &font_map, pNormalIcon, iconFit, csNormalCaption,
+                             crText, fFontSize, nLayout);
+
+  Write("N", csAP, "");
+  if (pNormalIcon)
+    AddImage("N", pNormalIcon);
+
+  CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
+  if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
+    if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
+      csRolloverCaption = csNormalCaption;
+      pRolloverIcon = pNormalIcon;
+    }
+
+    font_map.SetAPType("R");
+
+    csAP =
+        CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+        CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                       crLeftTop, crRightBottom, nBorderStyle,
+                                       dsBorder) +
+        GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient,
+                               &font_map, pRolloverIcon, iconFit,
+                               csRolloverCaption, crText, fFontSize, nLayout);
+
+    Write("R", csAP, "");
+    if (pRolloverIcon)
+      AddImage("R", pRolloverIcon);
+
+    if (csDownCaption.IsEmpty() && !pDownIcon) {
+      csDownCaption = csNormalCaption;
+      pDownIcon = pNormalIcon;
+    }
+
+    switch (nBorderStyle) {
+      case BorderStyle::BEVELED: {
+        CFX_Color crTemp = crLeftTop;
+        crLeftTop = crRightBottom;
+        crRightBottom = crTemp;
+        break;
+      }
+      case BorderStyle::INSET: {
+        crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
+        crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+        break;
+      }
+      default:
+        break;
+    }
+
+    font_map.SetAPType("D");
+
+    csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
+           CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                          crLeftTop, crRightBottom,
+                                          nBorderStyle, dsBorder) +
+           GetPushButtonAppStream(
+               iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
+               pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
+
+    Write("D", csAP, "");
+    if (pDownIcon)
+      AddImage("D", pDownIcon);
+  } else {
+    Remove("D");
+    Remove("R");
+  }
+}
+
+void CPWL_AppStream::SetAsCheckBox() {
+  CPDF_FormControl* pControl = widget_->GetFormControl();
+  CFX_Color crBackground, crBorder, crText;
+  int iColorType;
+  float fc[4];
+
+  pControl->GetOriginalBackgroundColor(iColorType, fc);
+  if (iColorType > 0)
+    crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  pControl->GetOriginalBorderColor(iColorType, fc);
+  if (iColorType > 0)
+    crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  float fBorderWidth = static_cast<float>(widget_->GetBorderWidth());
+  CPWL_Dash dsBorder(3, 0, 0);
+  CFX_Color crLeftTop, crRightBottom;
+
+  BorderStyle nBorderStyle = widget_->GetBorderStyle();
+  switch (nBorderStyle) {
+    case BorderStyle::DASH:
+      dsBorder = CPWL_Dash(3, 3, 0);
+      break;
+    case BorderStyle::BEVELED:
+      fBorderWidth *= 2;
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = crBackground / 2.0f;
+      break;
+    case BorderStyle::INSET:
+      fBorderWidth *= 2;
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
+      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
+      break;
+    default:
+      break;
+  }
+
+  CFX_FloatRect rcWindow = widget_->GetRotatedRect();
+  CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
+  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
+  if (da.HasColor()) {
+    da.GetColor(iColorType, fc);
+    crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+  }
+
+  int32_t nStyle = 0;
+  CFX_WideString csWCaption = pControl->GetNormalCaption();
+  if (csWCaption.GetLength() > 0) {
+    switch (csWCaption[0]) {
+      case L'l':
+        nStyle = PCS_CIRCLE;
+        break;
+      case L'8':
+        nStyle = PCS_CROSS;
+        break;
+      case L'u':
+        nStyle = PCS_DIAMOND;
+        break;
+      case L'n':
+        nStyle = PCS_SQUARE;
+        break;
+      case L'H':
+        nStyle = PCS_STAR;
+        break;
+      default:  // L'4'
+        nStyle = PCS_CHECK;
+        break;
+    }
+  } else {
+    nStyle = PCS_CHECK;
+  }
+
+  CFX_ByteString csAP_N_ON =
+      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                     crLeftTop, crRightBottom, nBorderStyle,
+                                     dsBorder);
+
+  CFX_ByteString csAP_N_OFF = csAP_N_ON;
+
+  switch (nBorderStyle) {
+    case BorderStyle::BEVELED: {
+      CFX_Color crTemp = crLeftTop;
+      crLeftTop = crRightBottom;
+      crRightBottom = crTemp;
+      break;
+    }
+    case BorderStyle::INSET: {
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
+      crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+      break;
+    }
+    default:
+      break;
+  }
+
+  CFX_ByteString csAP_D_ON =
+      CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
+      CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                     crLeftTop, crRightBottom, nBorderStyle,
+                                     dsBorder);
+
+  CFX_ByteString csAP_D_OFF = csAP_D_ON;
+
+  csAP_N_ON += GetCheckBoxAppStream(rcClient, nStyle, crText);
+  csAP_D_ON += GetCheckBoxAppStream(rcClient, nStyle, crText);
+
+  Write("N", csAP_N_ON, pControl->GetCheckedAPState());
+  Write("N", csAP_N_OFF, "Off");
+
+  Write("D", csAP_D_ON, pControl->GetCheckedAPState());
+  Write("D", csAP_D_OFF, "Off");
+
+  CFX_ByteString csAS = widget_->GetAppState();
+  if (csAS.IsEmpty())
+    widget_->SetAppState("Off");
+}
+
+void CPWL_AppStream::SetAsRadioButton() {
+  CPDF_FormControl* pControl = widget_->GetFormControl();
+  CFX_Color crBackground;
+  CFX_Color crBorder;
+  CFX_Color crText;
+  int iColorType;
+  float fc[4];
+
+  pControl->GetOriginalBackgroundColor(iColorType, fc);
+  if (iColorType > 0)
+    crBackground = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  pControl->GetOriginalBorderColor(iColorType, fc);
+  if (iColorType > 0)
+    crBorder = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+
+  float fBorderWidth = static_cast<float>(widget_->GetBorderWidth());
+  CPWL_Dash dsBorder(3, 0, 0);
+  CFX_Color crLeftTop;
+  CFX_Color crRightBottom;
+  BorderStyle nBorderStyle = widget_->GetBorderStyle();
+  switch (nBorderStyle) {
+    case BorderStyle::DASH:
+      dsBorder = CPWL_Dash(3, 3, 0);
+      break;
+    case BorderStyle::BEVELED:
+      fBorderWidth *= 2;
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = crBackground / 2.0f;
+      break;
+    case BorderStyle::INSET:
+      fBorderWidth *= 2;
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
+      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
+      break;
+    default:
+      break;
+  }
+
+  CFX_FloatRect rcWindow = widget_->GetRotatedRect();
+  CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
+  CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
+  if (da.HasColor()) {
+    da.GetColor(iColorType, fc);
+    crText = CFX_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
+  }
+
+  int32_t nStyle = 0;
+  CFX_WideString csWCaption = pControl->GetNormalCaption();
+  if (csWCaption.GetLength() > 0) {
+    switch (csWCaption[0]) {
+      default:  // L'l':
+        nStyle = PCS_CIRCLE;
+        break;
+      case L'8':
+        nStyle = PCS_CROSS;
+        break;
+      case L'u':
+        nStyle = PCS_DIAMOND;
+        break;
+      case L'n':
+        nStyle = PCS_SQUARE;
+        break;
+      case L'H':
+        nStyle = PCS_STAR;
+        break;
+      case L'4':
+        nStyle = PCS_CHECK;
+        break;
+    }
+  } else {
+    nStyle = PCS_CIRCLE;
+  }
+
+  CFX_ByteString csAP_N_ON;
+  CFX_FloatRect rcCenter = rcWindow.GetCenterSquare().GetDeflated(1.0f, 1.0f);
+  if (nStyle == PCS_CIRCLE) {
+    if (nBorderStyle == BorderStyle::BEVELED) {
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = crBackground - 0.25f;
+    } else if (nBorderStyle == BorderStyle::INSET) {
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5f);
+      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75f);
+    }
+
+    csAP_N_ON =
+        GetCircleFillAppStream(rcCenter, crBackground) +
+        GetCircleBorderAppStream(rcCenter, fBorderWidth, crBorder, crLeftTop,
+                                 crRightBottom, nBorderStyle, dsBorder);
+  } else {
+    csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
+                CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                               crLeftTop, crRightBottom,
+                                               nBorderStyle, dsBorder);
+  }
+
+  CFX_ByteString csAP_N_OFF = csAP_N_ON;
+
+  switch (nBorderStyle) {
+    case BorderStyle::BEVELED: {
+      CFX_Color crTemp = crLeftTop;
+      crLeftTop = crRightBottom;
+      crRightBottom = crTemp;
+      break;
+    }
+    case BorderStyle::INSET: {
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
+      crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+      break;
+    }
+    default:
+      break;
+  }
+
+  CFX_ByteString csAP_D_ON;
+
+  if (nStyle == PCS_CIRCLE) {
+    CFX_Color crBK = crBackground - 0.25f;
+    if (nBorderStyle == BorderStyle::BEVELED) {
+      crLeftTop = crBackground - 0.25f;
+      crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+      crBK = crBackground;
+    } else if (nBorderStyle == BorderStyle::INSET) {
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0);
+      crRightBottom = CFX_Color(COLORTYPE_GRAY, 1);
+    }
+
+    csAP_D_ON =
+        GetCircleFillAppStream(rcCenter, crBK) +
+        GetCircleBorderAppStream(rcCenter, fBorderWidth, crBorder, crLeftTop,
+                                 crRightBottom, nBorderStyle, dsBorder);
+  } else {
+    csAP_D_ON =
+        CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
+        CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                       crLeftTop, crRightBottom, nBorderStyle,
+                                       dsBorder);
+  }
+
+  CFX_ByteString csAP_D_OFF = csAP_D_ON;
+
+  csAP_N_ON += GetRadioButtonAppStream(rcClient, nStyle, crText);
+  csAP_D_ON += GetRadioButtonAppStream(rcClient, nStyle, crText);
+
+  Write("N", csAP_N_ON, pControl->GetCheckedAPState());
+  Write("N", csAP_N_OFF, "Off");
+
+  Write("D", csAP_D_ON, pControl->GetCheckedAPState());
+  Write("D", csAP_D_OFF, "Off");
+
+  CFX_ByteString csAS = widget_->GetAppState();
+  if (csAS.IsEmpty())
+    widget_->SetAppState("Off");
+}
+
+void CPWL_AppStream::SetAsComboBox(const CFX_WideString* sValue) {
+  CPDF_FormControl* pControl = widget_->GetFormControl();
+  CPDF_FormField* pField = pControl->GetField();
+  std::ostringstream sBody;
+
+  CFX_FloatRect rcClient = widget_->GetClientRect();
+  CFX_FloatRect rcButton = rcClient;
+  rcButton.left = rcButton.right - 13;
+  rcButton.Normalize();
+
+  auto pEdit = pdfium::MakeUnique<CFX_Edit>();
+  pEdit->EnableRefresh(false);
+
+  CBA_FontMap font_map(
+      widget_.Get(),
+      widget_->GetInterForm()->GetFormFillEnv()->GetSysHandler());
+  pEdit->SetFontMap(&font_map);
+
+  CFX_FloatRect rcEdit = rcClient;
+  rcEdit.right = rcButton.left;
+  rcEdit.Normalize();
+
+  pEdit->SetPlateRect(rcEdit);
+  pEdit->SetAlignmentV(1, true);
+
+  float fFontSize = widget_->GetFontSize();
+  if (IsFloatZero(fFontSize))
+    pEdit->SetAutoFontSize(true, true);
+  else
+    pEdit->SetFontSize(fFontSize);
+
+  pEdit->Initialize();
+
+  if (sValue) {
+    pEdit->SetText(*sValue);
+  } else {
+    int32_t nCurSel = pField->GetSelectedIndex(0);
+    if (nCurSel < 0)
+      pEdit->SetText(pField->GetValue());
+    else
+      pEdit->SetText(pField->GetOptionLabel(nCurSel));
+  }
+
+  CFX_FloatRect rcContent = pEdit->GetContentRect();
+  CFX_ByteString sEdit =
+      CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF());
+  if (sEdit.GetLength() > 0) {
+    sBody << "/Tx BMC\n"
+          << "q\n";
+    if (rcContent.Width() > rcEdit.Width() ||
+        rcContent.Height() > rcEdit.Height()) {
+      sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
+            << " " << rcEdit.Height() << " re\nW\nn\n";
+    }
+
+    CFX_Color crText = widget_->GetTextPWLColor();
+    sBody << "BT\n"
+          << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
+          << "Q\nEMC\n";
+  }
+
+  sBody << GetDropButtonAppStream(rcButton);
+  Write("N",
+        GetBackgroundAppStream() + GetBorderAppStream() + CFX_ByteString(sBody),
+        "");
+}
+
+void CPWL_AppStream::SetAsListBox() {
+  CPDF_FormControl* pControl = widget_->GetFormControl();
+  CPDF_FormField* pField = pControl->GetField();
+  CFX_FloatRect rcClient = widget_->GetClientRect();
+  std::ostringstream sBody;
+
+  auto pEdit = pdfium::MakeUnique<CFX_Edit>();
+  pEdit->EnableRefresh(false);
+
+  CBA_FontMap font_map(
+      widget_.Get(),
+      widget_->GetInterForm()->GetFormFillEnv()->GetSysHandler());
+  pEdit->SetFontMap(&font_map);
+  pEdit->SetPlateRect(CFX_FloatRect(rcClient.left, 0.0f, rcClient.right, 0.0f));
+
+  float fFontSize = widget_->GetFontSize();
+  pEdit->SetFontSize(IsFloatZero(fFontSize) ? 12.0f : fFontSize);
+  pEdit->Initialize();
+
+  std::ostringstream sList;
+  float fy = rcClient.top;
+
+  int32_t nTop = pField->GetTopVisibleIndex();
+  int32_t nCount = pField->CountOptions();
+  int32_t nSelCount = pField->CountSelectedItems();
+
+  for (int32_t i = nTop; i < nCount; ++i) {
+    bool bSelected = false;
+    for (int32_t j = 0; j < nSelCount; ++j) {
+      if (pField->GetSelectedIndex(j) == i) {
+        bSelected = true;
+        break;
+      }
+    }
+
+    pEdit->SetText(pField->GetOptionLabel(i));
+
+    CFX_FloatRect rcContent = pEdit->GetContentRect();
+    float fItemHeight = rcContent.Height();
+
+    if (bSelected) {
+      CFX_FloatRect rcItem =
+          CFX_FloatRect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
+      sList << "q\n"
+            << CPWL_Utils::GetColorAppStream(
+                   CFX_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f, 113.0f / 255.0f),
+                   true)
+            << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
+            << " " << rcItem.Height() << " re f\n"
+            << "Q\n";
+
+      sList << "BT\n"
+            << CPWL_Utils::GetColorAppStream(CFX_Color(COLORTYPE_GRAY, 1), true)
+            << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
+            << "ET\n";
+    } else {
+      CFX_Color crText = widget_->GetTextPWLColor();
+      sList << "BT\n"
+            << CPWL_Utils::GetColorAppStream(crText, true)
+            << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
+            << "ET\n";
+    }
+
+    fy -= fItemHeight;
+  }
+
+  if (sList.tellp() > 0) {
+    sBody << "/Tx BMC\n"
+          << "q\n"
+          << rcClient.left << " " << rcClient.bottom << " " << rcClient.Width()
+          << " " << rcClient.Height() << " re\nW\nn\n";
+    sBody << sList.str() << "Q\nEMC\n";
+  }
+  Write("N",
+        GetBackgroundAppStream() + GetBorderAppStream() + CFX_ByteString(sBody),
+        "");
+}
+
+void CPWL_AppStream::SetAsTextField(const CFX_WideString* sValue) {
+  CPDF_FormControl* pControl = widget_->GetFormControl();
+  CPDF_FormField* pField = pControl->GetField();
+  std::ostringstream sBody;
+  std::ostringstream sLines;
+
+  auto pEdit = pdfium::MakeUnique<CFX_Edit>();
+  pEdit->EnableRefresh(false);
+
+  CBA_FontMap font_map(
+      widget_.Get(),
+      widget_->GetInterForm()->GetFormFillEnv()->GetSysHandler());
+  pEdit->SetFontMap(&font_map);
+
+  CFX_FloatRect rcClient = widget_->GetClientRect();
+  pEdit->SetPlateRect(rcClient);
+  pEdit->SetAlignmentH(pControl->GetControlAlignment(), true);
+
+  uint32_t dwFieldFlags = pField->GetFieldFlags();
+  bool bMultiLine = (dwFieldFlags >> 12) & 1;
+  if (bMultiLine) {
+    pEdit->SetMultiLine(true, true);
+    pEdit->SetAutoReturn(true, true);
+  } else {
+    pEdit->SetAlignmentV(1, true);
+  }
+
+  uint16_t subWord = 0;
+  if ((dwFieldFlags >> 13) & 1) {
+    subWord = '*';
+    pEdit->SetPasswordChar(subWord, true);
+  }
+
+  int nMaxLen = pField->GetMaxLen();
+  bool bCharArray = (dwFieldFlags >> 24) & 1;
+  float fFontSize = widget_->GetFontSize();
+
+#ifdef PDF_ENABLE_XFA
+  CFX_WideString sValueTmp;
+  if (!sValue && widget_->GetMixXFAWidget()) {
+    sValueTmp = widget_->GetValue(true);
+    sValue = &sValueTmp;
+  }
+#endif  // PDF_ENABLE_XFA
+
+  if (nMaxLen > 0) {
+    if (bCharArray) {
+      pEdit->SetCharArray(nMaxLen);
+
+      if (IsFloatZero(fFontSize)) {
+        fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(font_map.GetPDFFont(0),
+                                                        rcClient, nMaxLen);
+      }
+    } else {
+      if (sValue)
+        nMaxLen = sValue->GetLength();
+      pEdit->SetLimitChar(nMaxLen);
+    }
+  }
+
+  if (IsFloatZero(fFontSize))
+    pEdit->SetAutoFontSize(true, true);
+  else
+    pEdit->SetFontSize(fFontSize);
+
+  pEdit->Initialize();
+  pEdit->SetText(sValue ? *sValue : pField->GetValue());
+
+  CFX_FloatRect rcContent = pEdit->GetContentRect();
+  CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
+      pEdit.get(), CFX_PointF(), nullptr, !bCharArray, subWord);
+
+  if (sEdit.GetLength() > 0) {
+    sBody << "/Tx BMC\n"
+          << "q\n";
+    if (rcContent.Width() > rcClient.Width() ||
+        rcContent.Height() > rcClient.Height()) {
+      sBody << rcClient.left << " " << rcClient.bottom << " "
+            << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
+    }
+    CFX_Color crText = widget_->GetTextPWLColor();
+    sBody << "BT\n"
+          << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
+          << "Q\nEMC\n";
+  }
+
+  if (bCharArray) {
+    switch (widget_->GetBorderStyle()) {
+      case BorderStyle::SOLID: {
+        CFX_ByteString sColor =
+            CPWL_Utils::GetColorAppStream(widget_->GetBorderPWLColor(), false);
+        if (sColor.GetLength() > 0) {
+          sLines << "q\n"
+                 << widget_->GetBorderWidth() << " w\n"
+                 << CPWL_Utils::GetColorAppStream(widget_->GetBorderPWLColor(),
+                                                  false)
+                 << " 2 J 0 j\n";
+
+          for (int32_t i = 1; i < nMaxLen; ++i) {
+            sLines << rcClient.left +
+                          ((rcClient.right - rcClient.left) / nMaxLen) * i
+                   << " " << rcClient.bottom << " m\n"
+                   << rcClient.left +
+                          ((rcClient.right - rcClient.left) / nMaxLen) * i
+                   << " " << rcClient.top << " l S\n";
+          }
+
+          sLines << "Q\n";
+        }
+        break;
+      }
+      case BorderStyle::DASH: {
+        CFX_ByteString sColor =
+            CPWL_Utils::GetColorAppStream(widget_->GetBorderPWLColor(), false);
+        if (sColor.GetLength() > 0) {
+          CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
+
+          sLines << "q\n"
+                 << widget_->GetBorderWidth() << " w\n"
+                 << CPWL_Utils::GetColorAppStream(widget_->GetBorderPWLColor(),
+                                                  false)
+                 << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
+                 << dsBorder.nPhase << " d\n";
+
+          for (int32_t i = 1; i < nMaxLen; ++i) {
+            sLines << rcClient.left +
+                          ((rcClient.right - rcClient.left) / nMaxLen) * i
+                   << " " << rcClient.bottom << " m\n"
+                   << rcClient.left +
+                          ((rcClient.right - rcClient.left) / nMaxLen) * i
+                   << " " << rcClient.top << " l S\n";
+          }
+
+          sLines << "Q\n";
+        }
+        break;
+      }
+      default:
+        break;
+    }
+  }
+
+  Write("N",
+        GetBackgroundAppStream() + GetBorderAppStream() +
+            CFX_ByteString(sLines) + CFX_ByteString(sBody),
+        "");
+}
+
+void CPWL_AppStream::AddImage(const CFX_ByteString& sAPType,
+                              CPDF_Stream* pImage) {
+  CPDF_Stream* pStream = dict_->GetStreamFor(sAPType);
+  CPDF_Dictionary* pStreamDict = pStream->GetDict();
+  CFX_ByteString sImageAlias = "IMG";
+
+  if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
+    sImageAlias = pImageDict->GetStringFor("Name");
+    if (sImageAlias.IsEmpty())
+      sImageAlias = "IMG";
+  }
+
+  CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
+  if (!pStreamResList)
+    pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
+
+  CPDF_Dictionary* pXObject =
+      pStreamResList->SetNewFor<CPDF_Dictionary>("XObject");
+  pXObject->SetNewFor<CPDF_Reference>(sImageAlias,
+                                      widget_->GetPageView()->GetPDFDocument(),
+                                      pImage->GetObjNum());
+}
+
+void CPWL_AppStream::Write(const CFX_ByteString& sAPType,
+                           const CFX_ByteString& sContents,
+                           const CFX_ByteString& sAPState) {
+  CPDF_Stream* pStream = nullptr;
+  CPDF_Dictionary* pParentDict = nullptr;
+  if (sAPState.IsEmpty()) {
+    pParentDict = dict_.Get();
+    pStream = dict_->GetStreamFor(sAPType);
+  } else {
+    CPDF_Dictionary* pAPTypeDict = dict_->GetDictFor(sAPType);
+    if (!pAPTypeDict)
+      pAPTypeDict = dict_->SetNewFor<CPDF_Dictionary>(sAPType);
+
+    pParentDict = pAPTypeDict;
+    pStream = pAPTypeDict->GetStreamFor(sAPState);
+  }
+
+  if (!pStream) {
+    CPDF_Document* doc = widget_->GetPageView()->GetPDFDocument();
+    pStream = doc->NewIndirect<CPDF_Stream>();
+    pParentDict->SetNewFor<CPDF_Reference>(sAPType, doc, pStream->GetObjNum());
+  }
+
+  CPDF_Dictionary* pStreamDict = pStream->GetDict();
+  if (!pStreamDict) {
+    auto pNewDict = pdfium::MakeUnique<CPDF_Dictionary>(
+        widget_->GetPDFAnnot()->GetDocument()->GetByteStringPool());
+    pStreamDict = pNewDict.get();
+    pStreamDict->SetNewFor<CPDF_Name>("Type", "XObject");
+    pStreamDict->SetNewFor<CPDF_Name>("Subtype", "Form");
+    pStreamDict->SetNewFor<CPDF_Number>("FormType", 1);
+    pStream->InitStream(nullptr, 0, std::move(pNewDict));
+  }
+  pStreamDict->SetMatrixFor("Matrix", widget_->GetMatrix());
+  pStreamDict->SetRectFor("BBox", widget_->GetRotatedRect());
+  pStream->SetData((uint8_t*)(sContents.c_str()), sContents.GetLength());
+}
+
+void CPWL_AppStream::Remove(const CFX_ByteString& sAPType) {
+  dict_->RemoveFor(sAPType);
+}
+
+CFX_ByteString CPWL_AppStream::GetBackgroundAppStream() const {
+  CFX_Color crBackground = widget_->GetFillPWLColor();
+  if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
+    return CPWL_Utils::GetRectFillAppStream(widget_->GetRotatedRect(),
+                                            crBackground);
+
+  return CFX_ByteString();
+}
+
+CFX_ByteString CPWL_AppStream::GetBorderAppStream() const {
+  CFX_FloatRect rcWindow = widget_->GetRotatedRect();
+  CFX_Color crBorder = widget_->GetBorderPWLColor();
+  CFX_Color crBackground = widget_->GetFillPWLColor();
+  CFX_Color crLeftTop;
+  CFX_Color crRightBottom;
+
+  float fBorderWidth = static_cast<float>(widget_->GetBorderWidth());
+  CPWL_Dash dsBorder(3, 0, 0);
+
+  BorderStyle nBorderStyle = widget_->GetBorderStyle();
+  switch (nBorderStyle) {
+    case BorderStyle::DASH:
+      dsBorder = CPWL_Dash(3, 3, 0);
+      break;
+    case BorderStyle::BEVELED:
+      fBorderWidth *= 2;
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 1);
+      crRightBottom = crBackground / 2.0f;
+      break;
+    case BorderStyle::INSET:
+      fBorderWidth *= 2;
+      crLeftTop = CFX_Color(COLORTYPE_GRAY, 0.5);
+      crRightBottom = CFX_Color(COLORTYPE_GRAY, 0.75);
+      break;
+    default:
+      break;
+  }
+
+  return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
+                                        crLeftTop, crRightBottom, nBorderStyle,
+                                        dsBorder);
+}
diff --git a/fpdfsdk/pdfwindow/cpwl_appstream.h b/fpdfsdk/pdfwindow/cpwl_appstream.h
new file mode 100644
index 0000000..5613786
--- /dev/null
+++ b/fpdfsdk/pdfwindow/cpwl_appstream.h
@@ -0,0 +1,43 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_PDFWINDOW_CPWL_APPSTREAM_H_
+#define FPDFSDK_PDFWINDOW_CPWL_APPSTREAM_H_
+
+#include "core/fxcrt/cfx_unowned_ptr.h"
+#include "core/fxcrt/fx_string.h"
+
+class CPDFSDK_Widget;
+class CPDF_Dictionary;
+class CPDF_Stream;
+
+class CPWL_AppStream {
+ public:
+  CPWL_AppStream(CPDFSDK_Widget* widget, CPDF_Dictionary* dict);
+  ~CPWL_AppStream();
+
+  void SetAsPushButton();
+  void SetAsCheckBox();
+  void SetAsRadioButton();
+  void SetAsComboBox(const CFX_WideString* sValue);
+  void SetAsListBox();
+  void SetAsTextField(const CFX_WideString* sValue);
+
+ private:
+  void AddImage(const CFX_ByteString& sAPType, CPDF_Stream* pImage);
+  void Write(const CFX_ByteString& sAPType,
+             const CFX_ByteString& sContents,
+             const CFX_ByteString& sAPState);
+  void Remove(const CFX_ByteString& sAPType);
+
+  CFX_ByteString GetBackgroundAppStream() const;
+  CFX_ByteString GetBorderAppStream() const;
+
+  CFX_UnownedPtr<CPDFSDK_Widget> widget_;
+  CFX_UnownedPtr<CPDF_Dictionary> dict_;
+};
+
+#endif  // FPDFSDK_PDFWINDOW_CPWL_APPSTREAM_H_
diff --git a/fpdfsdk/pdfwindow/cpwl_utils.cpp b/fpdfsdk/pdfwindow/cpwl_utils.cpp
index b21047b..b628b29 100644
--- a/fpdfsdk/pdfwindow/cpwl_utils.cpp
+++ b/fpdfsdk/pdfwindow/cpwl_utils.cpp
@@ -14,206 +14,6 @@
 #include "fpdfsdk/fxedit/fxet_edit.h"
 #include "fpdfsdk/pdfwindow/cpwl_icon.h"
 
-CFX_ByteString CPWL_Utils::GetAP_Check(const CFX_FloatRect& crBBox) {
-  const float fWidth = crBBox.right - crBBox.left;
-  const float fHeight = crBBox.top - crBBox.bottom;
-
-  CFX_PointF pts[8][3] = {{CFX_PointF(0.28f, 0.52f), CFX_PointF(0.27f, 0.48f),
-                           CFX_PointF(0.29f, 0.40f)},
-                          {CFX_PointF(0.30f, 0.33f), CFX_PointF(0.31f, 0.29f),
-                           CFX_PointF(0.31f, 0.28f)},
-                          {CFX_PointF(0.39f, 0.28f), CFX_PointF(0.49f, 0.29f),
-                           CFX_PointF(0.77f, 0.67f)},
-                          {CFX_PointF(0.76f, 0.68f), CFX_PointF(0.78f, 0.69f),
-                           CFX_PointF(0.76f, 0.75f)},
-                          {CFX_PointF(0.76f, 0.75f), CFX_PointF(0.73f, 0.80f),
-                           CFX_PointF(0.68f, 0.75f)},
-                          {CFX_PointF(0.68f, 0.74f), CFX_PointF(0.68f, 0.74f),
-                           CFX_PointF(0.44f, 0.47f)},
-                          {CFX_PointF(0.43f, 0.47f), CFX_PointF(0.40f, 0.47f),
-                           CFX_PointF(0.41f, 0.58f)},
-                          {CFX_PointF(0.40f, 0.60f), CFX_PointF(0.28f, 0.66f),
-                           CFX_PointF(0.30f, 0.56f)}};
-
-  for (size_t i = 0; i < FX_ArraySize(pts); ++i) {
-    for (size_t j = 0; j < FX_ArraySize(pts[0]); ++j) {
-      pts[i][j].x = pts[i][j].x * fWidth + crBBox.left;
-      pts[i][j].y *= pts[i][j].y * fHeight + crBBox.bottom;
-    }
-  }
-
-  std::ostringstream csAP;
-  csAP << pts[0][0].x << " " << pts[0][0].y << " m\n";
-
-  for (size_t i = 0; i < FX_ArraySize(pts); ++i) {
-    size_t nNext = i < FX_ArraySize(pts) - 1 ? i + 1 : 0;
-
-    float px1 = pts[i][1].x - pts[i][0].x;
-    float py1 = pts[i][1].y - pts[i][0].y;
-    float px2 = pts[i][2].x - pts[nNext][0].x;
-    float py2 = pts[i][2].y - pts[nNext][0].y;
-
-    csAP << pts[i][0].x + px1 * FX_BEZIER << " "
-         << pts[i][0].y + py1 * FX_BEZIER << " "
-         << pts[nNext][0].x + px2 * FX_BEZIER << " "
-         << pts[nNext][0].y + py2 * FX_BEZIER << " " << pts[nNext][0].x << " "
-         << pts[nNext][0].y << " c\n";
-  }
-
-  return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Circle(const CFX_FloatRect& crBBox) {
-  std::ostringstream csAP;
-
-  float fWidth = crBBox.right - crBBox.left;
-  float fHeight = crBBox.top - crBBox.bottom;
-
-  CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2);
-  CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top);
-  CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2);
-  CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom);
-
-  csAP << pt1.x << " " << pt1.y << " m\n";
-
-  float px = pt2.x - pt1.x;
-  float py = pt2.y - pt1.y;
-
-  csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
-       << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
-       << " c\n";
-
-  px = pt3.x - pt2.x;
-  py = pt2.y - pt3.y;
-
-  csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
-       << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
-
-  px = pt3.x - pt4.x;
-  py = pt3.y - pt4.y;
-
-  csAP << pt3.x << " " << pt3.y - py * FX_BEZIER << " "
-       << pt4.x + px * FX_BEZIER << " " << pt4.y << " " << pt4.x << " " << pt4.y
-       << " c\n";
-
-  px = pt4.x - pt1.x;
-  py = pt1.y - pt4.y;
-
-  csAP << pt4.x - px * FX_BEZIER << " " << pt4.y << " " << pt1.x << " "
-       << pt1.y - py * FX_BEZIER << " " << pt1.x << " " << pt1.y << " c\n";
-
-  return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Cross(const CFX_FloatRect& crBBox) {
-  std::ostringstream csAP;
-
-  csAP << crBBox.left << " " << crBBox.top << " m\n";
-  csAP << crBBox.right << " " << crBBox.bottom << " l\n";
-  csAP << crBBox.left << " " << crBBox.bottom << " m\n";
-  csAP << crBBox.right << " " << crBBox.top << " l\n";
-
-  return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Diamond(const CFX_FloatRect& crBBox) {
-  std::ostringstream csAP;
-
-  float fWidth = crBBox.right - crBBox.left;
-  float fHeight = crBBox.top - crBBox.bottom;
-
-  CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2);
-  CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top);
-  CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2);
-  CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom);
-
-  csAP << pt1.x << " " << pt1.y << " m\n";
-  csAP << pt2.x << " " << pt2.y << " l\n";
-  csAP << pt3.x << " " << pt3.y << " l\n";
-  csAP << pt4.x << " " << pt4.y << " l\n";
-  csAP << pt1.x << " " << pt1.y << " l\n";
-
-  return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Square(const CFX_FloatRect& crBBox) {
-  std::ostringstream csAP;
-
-  csAP << crBBox.left << " " << crBBox.top << " m\n";
-  csAP << crBBox.right << " " << crBBox.top << " l\n";
-  csAP << crBBox.right << " " << crBBox.bottom << " l\n";
-  csAP << crBBox.left << " " << crBBox.bottom << " l\n";
-  csAP << crBBox.left << " " << crBBox.top << " l\n";
-
-  return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_Star(const CFX_FloatRect& crBBox) {
-  std::ostringstream csAP;
-
-  float fRadius = (crBBox.top - crBBox.bottom) / (1 + (float)cos(FX_PI / 5.0f));
-  CFX_PointF ptCenter = CFX_PointF((crBBox.left + crBBox.right) / 2.0f,
-                                   (crBBox.top + crBBox.bottom) / 2.0f);
-
-  float px[5], py[5];
-
-  float fAngel = FX_PI / 10.0f;
-
-  for (int32_t i = 0; i < 5; i++) {
-    px[i] = ptCenter.x + fRadius * (float)cos(fAngel);
-    py[i] = ptCenter.y + fRadius * (float)sin(fAngel);
-
-    fAngel += FX_PI * 2 / 5.0f;
-  }
-
-  csAP << px[0] << " " << py[0] << " m\n";
-
-  int32_t nNext = 0;
-  for (int32_t j = 0; j < 5; j++) {
-    nNext += 2;
-    if (nNext >= 5)
-      nNext -= 5;
-    csAP << px[nNext] << " " << py[nNext] << " l\n";
-  }
-
-  return CFX_ByteString(csAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAP_HalfCircle(const CFX_FloatRect& crBBox,
-                                            float fRotate) {
-  std::ostringstream csAP;
-
-  float fWidth = crBBox.right - crBBox.left;
-  float fHeight = crBBox.top - crBBox.bottom;
-
-  CFX_PointF pt1(-fWidth / 2, 0);
-  CFX_PointF pt2(0, fHeight / 2);
-  CFX_PointF pt3(fWidth / 2, 0);
-
-  float px, py;
-
-  csAP << cos(fRotate) << " " << sin(fRotate) << " " << -sin(fRotate) << " "
-       << cos(fRotate) << " " << crBBox.left + fWidth / 2 << " "
-       << crBBox.bottom + fHeight / 2 << " cm\n";
-
-  csAP << pt1.x << " " << pt1.y << " m\n";
-
-  px = pt2.x - pt1.x;
-  py = pt2.y - pt1.y;
-
-  csAP << pt1.x << " " << pt1.y + py * FX_BEZIER << " "
-       << pt2.x - px * FX_BEZIER << " " << pt2.y << " " << pt2.x << " " << pt2.y
-       << " c\n";
-
-  px = pt3.x - pt2.x;
-  py = pt2.y - pt3.y;
-
-  csAP << pt2.x + px * FX_BEZIER << " " << pt2.y << " " << pt3.x << " "
-       << pt3.y + py * FX_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
-
-  return CFX_ByteString(csAP);
-}
-
 CFX_ByteString CPWL_Utils::GetRectFillAppStream(const CFX_FloatRect& rect,
                                                 const CFX_Color& color) {
   std::ostringstream sAppStream;
@@ -228,15 +28,6 @@
   return CFX_ByteString(sAppStream);
 }
 
-CFX_ByteString CPWL_Utils::GetCircleFillAppStream(const CFX_FloatRect& rect,
-                                                  const CFX_Color& color) {
-  std::ostringstream sAppStream;
-  CFX_ByteString sColor = GetColorAppStream(color, true);
-  if (sColor.GetLength() > 0)
-    sAppStream << "q\n" << sColor << CPWL_Utils::GetAP_Circle(rect) << "f\nQ\n";
-  return CFX_ByteString(sAppStream);
-}
-
 CFX_ByteString CPWL_Utils::GetEditAppStream(CFX_Edit* pEdit,
                                             const CFX_PointF& ptOffset,
                                             const CPVT_WordRange* pRange,
@@ -252,206 +43,6 @@
   return CFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange);
 }
 
-CFX_ByteString CPWL_Utils::GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
-                                                  IPVT_FontMap* pFontMap,
-                                                  CPDF_Stream* pIconStream,
-                                                  CPDF_IconFit& IconFit,
-                                                  const CFX_WideString& sLabel,
-                                                  const CFX_Color& crText,
-                                                  float fFontSize,
-                                                  int32_t nLayOut) {
-  const float fAutoFontScale = 1.0f / 3.0f;
-
-  auto pEdit = pdfium::MakeUnique<CFX_Edit>();
-  pEdit->SetFontMap(pFontMap);
-  pEdit->SetAlignmentH(1, true);
-  pEdit->SetAlignmentV(1, true);
-  pEdit->SetMultiLine(false, true);
-  pEdit->SetAutoReturn(false, true);
-  if (IsFloatZero(fFontSize))
-    pEdit->SetAutoFontSize(true, true);
-  else
-    pEdit->SetFontSize(fFontSize);
-
-  pEdit->Initialize();
-  pEdit->SetText(sLabel);
-
-  CFX_FloatRect rcLabelContent = pEdit->GetContentRect();
-  CPWL_Icon Icon;
-  PWL_CREATEPARAM cp;
-  cp.dwFlags = PWS_VISIBLE;
-  Icon.Create(cp);
-  Icon.SetIconFit(&IconFit);
-  Icon.SetPDFStream(pIconStream);
-
-  CFX_FloatRect rcLabel;
-  CFX_FloatRect rcIcon;
-  float fWidth = 0.0f;
-  float fHeight = 0.0f;
-
-  switch (nLayOut) {
-    case PPBL_LABEL:
-      rcLabel = rcBBox;
-      break;
-    case PPBL_ICON:
-      rcIcon = rcBBox;
-      break;
-    case PPBL_ICONTOPLABELBOTTOM:
-      if (pIconStream) {
-        if (IsFloatZero(fFontSize)) {
-          fHeight = rcBBox.top - rcBBox.bottom;
-          rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
-                                  rcBBox.bottom + fHeight * fAutoFontScale);
-          rcIcon =
-              CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right, rcBBox.top);
-        } else {
-          fHeight = rcLabelContent.Height();
-
-          if (rcBBox.bottom + fHeight > rcBBox.top) {
-            rcLabel = rcBBox;
-          } else {
-            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
-                                    rcBBox.bottom + fHeight);
-            rcIcon = CFX_FloatRect(rcBBox.left, rcLabel.top, rcBBox.right,
-                                   rcBBox.top);
-          }
-        }
-      } else {
-        rcLabel = rcBBox;
-      }
-      break;
-    case PPBL_LABELTOPICONBOTTOM:
-      if (pIconStream) {
-        if (IsFloatZero(fFontSize)) {
-          fHeight = rcBBox.top - rcBBox.bottom;
-          rcLabel =
-              CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight * fAutoFontScale,
-                            rcBBox.right, rcBBox.top);
-          rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
-                                 rcLabel.bottom);
-        } else {
-          fHeight = rcLabelContent.Height();
-
-          if (rcBBox.bottom + fHeight > rcBBox.top) {
-            rcLabel = rcBBox;
-          } else {
-            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.top - fHeight,
-                                    rcBBox.right, rcBBox.top);
-            rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcBBox.right,
-                                   rcLabel.bottom);
-          }
-        }
-      } else {
-        rcLabel = rcBBox;
-      }
-      break;
-    case PPBL_ICONLEFTLABELRIGHT:
-      if (pIconStream) {
-        if (IsFloatZero(fFontSize)) {
-          fWidth = rcBBox.right - rcBBox.left;
-          if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
-            rcLabel = CFX_FloatRect(rcBBox.right - fWidth * fAutoFontScale,
-                                    rcBBox.bottom, rcBBox.right, rcBBox.top);
-            rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
-                                   rcBBox.top);
-          } else {
-            if (rcLabelContent.Width() < fWidth) {
-              rcLabel = CFX_FloatRect(rcBBox.right - rcLabelContent.Width(),
-                                      rcBBox.bottom, rcBBox.right, rcBBox.top);
-              rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
-                                     rcBBox.top);
-            } else {
-              rcLabel = rcBBox;
-            }
-          }
-        } else {
-          fWidth = rcLabelContent.Width();
-          if (rcBBox.left + fWidth > rcBBox.right) {
-            rcLabel = rcBBox;
-          } else {
-            rcLabel = CFX_FloatRect(rcBBox.right - fWidth, rcBBox.bottom,
-                                    rcBBox.right, rcBBox.top);
-            rcIcon = CFX_FloatRect(rcBBox.left, rcBBox.bottom, rcLabel.left,
-                                   rcBBox.top);
-          }
-        }
-      } else {
-        rcLabel = rcBBox;
-      }
-      break;
-    case PPBL_LABELLEFTICONRIGHT:
-      if (pIconStream) {
-        if (IsFloatZero(fFontSize)) {
-          fWidth = rcBBox.right - rcBBox.left;
-          if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
-            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
-                                    rcBBox.left + fWidth * fAutoFontScale,
-                                    rcBBox.top);
-            rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
-                                   rcBBox.top);
-          } else {
-            if (rcLabelContent.Width() < fWidth) {
-              rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
-                                      rcBBox.left + rcLabelContent.Width(),
-                                      rcBBox.top);
-              rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
-                                     rcBBox.top);
-            } else {
-              rcLabel = rcBBox;
-            }
-          }
-        } else {
-          fWidth = rcLabelContent.Width();
-          if (rcBBox.left + fWidth > rcBBox.right) {
-            rcLabel = rcBBox;
-          } else {
-            rcLabel = CFX_FloatRect(rcBBox.left, rcBBox.bottom,
-                                    rcBBox.left + fWidth, rcBBox.top);
-            rcIcon = CFX_FloatRect(rcLabel.right, rcBBox.bottom, rcBBox.right,
-                                   rcBBox.top);
-          }
-        }
-      } else {
-        rcLabel = rcBBox;
-      }
-      break;
-    case PPBL_LABELOVERICON:
-      rcLabel = rcBBox;
-      rcIcon = rcBBox;
-      break;
-  }
-
-  std::ostringstream sTemp;
-
-  if (!rcIcon.IsEmpty()) {
-    Icon.Move(rcIcon, false, false);
-    sTemp << Icon.GetImageAppStream();
-  }
-
-  Icon.Destroy();
-
-  if (!rcLabel.IsEmpty()) {
-    pEdit->SetPlateRect(rcLabel);
-    CFX_ByteString sEdit =
-        CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, 0.0f));
-    if (sEdit.GetLength() > 0) {
-      sTemp << "BT\n"
-            << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n";
-    }
-  }
-
-  if (sTemp.tellp() <= 0)
-    return CFX_ByteString();
-
-  std::ostringstream sAppStream;
-  sAppStream << "q\n"
-             << rcBBox.left << " " << rcBBox.bottom << " "
-             << rcBBox.right - rcBBox.left << " " << rcBBox.top - rcBBox.bottom
-             << " re W n\n";
-  sAppStream << sTemp.str().c_str() << "Q\n";
-  return CFX_ByteString(sAppStream);
-}
-
 CFX_ByteString CPWL_Utils::GetColorAppStream(const CFX_Color& color,
                                              const bool& bFillOrStroke) {
   std::ostringstream sColorStream;
@@ -591,250 +182,3 @@
 
   return CFX_ByteString(sAppStream);
 }
-
-CFX_ByteString CPWL_Utils::GetCircleBorderAppStream(
-    const CFX_FloatRect& rect,
-    float fWidth,
-    const CFX_Color& color,
-    const CFX_Color& crLeftTop,
-    const CFX_Color& crRightBottom,
-    BorderStyle nStyle,
-    const CPWL_Dash& dash) {
-  std::ostringstream sAppStream;
-  CFX_ByteString sColor;
-
-  if (fWidth > 0.0f) {
-    sAppStream << "q\n";
-
-    float fHalfWidth = fWidth / 2.0f;
-    CFX_FloatRect rect_by_2 = rect.GetDeflated(fHalfWidth, fHalfWidth);
-
-    float div = fHalfWidth * 0.75f;
-    CFX_FloatRect rect_by_75 = rect.GetDeflated(div, div);
-    switch (nStyle) {
-      default:
-      case BorderStyle::SOLID:
-      case BorderStyle::UNDERLINE: {
-        sColor = CPWL_Utils::GetColorAppStream(color, false);
-        if (sColor.GetLength() > 0) {
-          sAppStream << "q\n"
-                     << fWidth << " w\n"
-                     << sColor << CPWL_Utils::GetAP_Circle(rect_by_2)
-                     << " S\nQ\n";
-        }
-      } break;
-      case BorderStyle::DASH: {
-        sColor = CPWL_Utils::GetColorAppStream(color, false);
-        if (sColor.GetLength() > 0) {
-          sAppStream << "q\n"
-                     << fWidth << " w\n"
-                     << "[" << dash.nDash << " " << dash.nGap << "] "
-                     << dash.nPhase << " d\n"
-                     << sColor << CPWL_Utils::GetAP_Circle(rect_by_2)
-                     << " S\nQ\n";
-        }
-      } break;
-      case BorderStyle::BEVELED: {
-        sColor = CPWL_Utils::GetColorAppStream(color, false);
-        if (sColor.GetLength() > 0) {
-          sAppStream << "q\n"
-                     << fHalfWidth << " w\n"
-                     << sColor << CPWL_Utils::GetAP_Circle(rect) << " S\nQ\n";
-        }
-
-        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
-        if (sColor.GetLength() > 0) {
-          sAppStream << "q\n"
-                     << fHalfWidth << " w\n"
-                     << sColor
-                     << CPWL_Utils::GetAP_HalfCircle(rect_by_75, FX_PI / 4.0f)
-                     << " S\nQ\n";
-        }
-
-        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
-        if (sColor.GetLength() > 0) {
-          sAppStream << "q\n"
-                     << fHalfWidth << " w\n"
-                     << sColor
-                     << CPWL_Utils::GetAP_HalfCircle(rect_by_75,
-                                                     FX_PI * 5 / 4.0f)
-                     << " S\nQ\n";
-        }
-      } break;
-      case BorderStyle::INSET: {
-        sColor = CPWL_Utils::GetColorAppStream(color, false);
-        if (sColor.GetLength() > 0) {
-          sAppStream << "q\n"
-                     << fHalfWidth << " w\n"
-                     << sColor << CPWL_Utils::GetAP_Circle(rect) << " S\nQ\n";
-        }
-
-        sColor = CPWL_Utils::GetColorAppStream(crLeftTop, false);
-        if (sColor.GetLength() > 0) {
-          sAppStream << "q\n"
-                     << fHalfWidth << " w\n"
-                     << sColor
-                     << CPWL_Utils::GetAP_HalfCircle(rect_by_75, FX_PI / 4.0f)
-                     << " S\nQ\n";
-        }
-
-        sColor = CPWL_Utils::GetColorAppStream(crRightBottom, false);
-        if (sColor.GetLength() > 0) {
-          sAppStream << "q\n"
-                     << fHalfWidth << " w\n"
-                     << sColor
-                     << CPWL_Utils::GetAP_HalfCircle(rect_by_75,
-                                                     FX_PI * 5 / 4.0f)
-                     << " S\nQ\n";
-        }
-      } break;
-    }
-
-    sAppStream << "Q\n";
-  }
-
-  return CFX_ByteString(sAppStream);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Check(const CFX_FloatRect& rcBBox,
-                                              const CFX_Color& crText) {
-  std::ostringstream sAP;
-  sAP << "q\n"
-      << CPWL_Utils::GetColorAppStream(crText, true)
-      << CPWL_Utils::GetAP_Check(rcBBox) << "f\nQ\n";
-  return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Circle(const CFX_FloatRect& rcBBox,
-                                               const CFX_Color& crText) {
-  std::ostringstream sAP;
-  sAP << "q\n"
-      << CPWL_Utils::GetColorAppStream(crText, true)
-      << CPWL_Utils::GetAP_Circle(rcBBox) << "f\nQ\n";
-  return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Cross(const CFX_FloatRect& rcBBox,
-                                              const CFX_Color& crText) {
-  std::ostringstream sAP;
-  sAP << "q\n"
-      << CPWL_Utils::GetColorAppStream(crText, false)
-      << CPWL_Utils::GetAP_Cross(rcBBox) << "S\nQ\n";
-  return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Diamond(const CFX_FloatRect& rcBBox,
-                                                const CFX_Color& crText) {
-  std::ostringstream sAP;
-  sAP << "q\n1 w\n"
-      << CPWL_Utils::GetColorAppStream(crText, true)
-      << CPWL_Utils::GetAP_Diamond(rcBBox) << "f\nQ\n";
-  return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Square(const CFX_FloatRect& rcBBox,
-                                               const CFX_Color& crText) {
-  std::ostringstream sAP;
-  sAP << "q\n"
-      << CPWL_Utils::GetColorAppStream(crText, true)
-      << CPWL_Utils::GetAP_Square(rcBBox) << "f\nQ\n";
-  return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetAppStream_Star(const CFX_FloatRect& rcBBox,
-                                             const CFX_Color& crText) {
-  std::ostringstream sAP;
-  sAP << "q\n"
-      << CPWL_Utils::GetColorAppStream(crText, true)
-      << CPWL_Utils::GetAP_Star(rcBBox) << "f\nQ\n";
-  return CFX_ByteString(sAP);
-}
-
-CFX_ByteString CPWL_Utils::GetCheckBoxAppStream(const CFX_FloatRect& rcBBox,
-                                                int32_t nStyle,
-                                                const CFX_Color& crText) {
-  CFX_FloatRect rcCenter = rcBBox.GetCenterSquare();
-  switch (nStyle) {
-    default:
-    case PCS_CHECK:
-      return GetAppStream_Check(rcCenter, crText);
-    case PCS_CIRCLE:
-      rcCenter.Scale(2.0f / 3.0f);
-      return GetAppStream_Circle(rcCenter, crText);
-    case PCS_CROSS:
-      return GetAppStream_Cross(rcCenter, crText);
-    case PCS_DIAMOND:
-      rcCenter.Scale(2.0f / 3.0f);
-      return GetAppStream_Diamond(rcCenter, crText);
-    case PCS_SQUARE:
-      rcCenter.Scale(2.0f / 3.0f);
-      return GetAppStream_Square(rcCenter, crText);
-    case PCS_STAR:
-      rcCenter.Scale(2.0f / 3.0f);
-      return GetAppStream_Star(rcCenter, crText);
-  }
-}
-
-CFX_ByteString CPWL_Utils::GetRadioButtonAppStream(const CFX_FloatRect& rcBBox,
-                                                   int32_t nStyle,
-                                                   const CFX_Color& crText) {
-  CFX_FloatRect rcCenter = rcBBox.GetCenterSquare();
-  switch (nStyle) {
-    default:
-    case PCS_CHECK:
-      return GetAppStream_Check(rcCenter, crText);
-    case PCS_CIRCLE:
-      rcCenter.Scale(1.0f / 2.0f);
-      return GetAppStream_Circle(rcCenter, crText);
-    case PCS_CROSS:
-      return GetAppStream_Cross(rcCenter, crText);
-    case PCS_DIAMOND:
-      rcCenter.Scale(2.0f / 3.0f);
-      return GetAppStream_Diamond(rcCenter, crText);
-    case PCS_SQUARE:
-      rcCenter.Scale(2.0f / 3.0f);
-      return GetAppStream_Square(rcCenter, crText);
-    case PCS_STAR:
-      rcCenter.Scale(2.0f / 3.0f);
-      return GetAppStream_Star(rcCenter, crText);
-  }
-}
-
-CFX_ByteString CPWL_Utils::GetDropButtonAppStream(const CFX_FloatRect& rcBBox) {
-  if (rcBBox.IsEmpty())
-    return CFX_ByteString();
-
-  std::ostringstream sAppStream;
-  sAppStream << "q\n"
-             << CPWL_Utils::GetColorAppStream(
-                    CFX_Color(COLORTYPE_RGB, 220.0f / 255.0f, 220.0f / 255.0f,
-                              220.0f / 255.0f),
-                    true)
-             << rcBBox.left << " " << rcBBox.bottom << " "
-             << rcBBox.right - rcBBox.left << " " << rcBBox.top - rcBBox.bottom
-             << " re f\n"
-             << "Q\n";
-
-  sAppStream << "q\n"
-             << CPWL_Utils::GetBorderAppStream(
-                    rcBBox, 2, CFX_Color(COLORTYPE_GRAY, 0),
-                    CFX_Color(COLORTYPE_GRAY, 1),
-                    CFX_Color(COLORTYPE_GRAY, 0.5), BorderStyle::BEVELED,
-                    CPWL_Dash(3, 0, 0))
-             << "Q\n";
-
-  CFX_PointF ptCenter = CFX_PointF((rcBBox.left + rcBBox.right) / 2,
-                                   (rcBBox.top + rcBBox.bottom) / 2);
-  if (IsFloatBigger(rcBBox.right - rcBBox.left, 6) &&
-      IsFloatBigger(rcBBox.top - rcBBox.bottom, 6)) {
-    sAppStream << "q\n"
-               << " 0 g\n"
-               << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " m\n"
-               << ptCenter.x + 3 << " " << ptCenter.y + 1.5f << " l\n"
-               << ptCenter.x << " " << ptCenter.y - 1.5f << " l\n"
-               << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " l f\n"
-               << "Q\n";
-  }
-
-  return CFX_ByteString(sAppStream);
-}
diff --git a/fpdfsdk/pdfwindow/cpwl_utils.h b/fpdfsdk/pdfwindow/cpwl_utils.h
index 67876ed..9445de3 100644
--- a/fpdfsdk/pdfwindow/cpwl_utils.h
+++ b/fpdfsdk/pdfwindow/cpwl_utils.h
@@ -41,31 +41,8 @@
                                            const CFX_Color& crRightBottom,
                                            BorderStyle nStyle,
                                            const CPWL_Dash& dash);
-  static CFX_ByteString GetCircleBorderAppStream(const CFX_FloatRect& rect,
-                                                 float fWidth,
-                                                 const CFX_Color& color,
-                                                 const CFX_Color& crLeftTop,
-                                                 const CFX_Color& crRightBottom,
-                                                 BorderStyle nStyle,
-                                                 const CPWL_Dash& dash);
   static CFX_ByteString GetRectFillAppStream(const CFX_FloatRect& rect,
                                              const CFX_Color& color);
-  static CFX_ByteString GetCircleFillAppStream(const CFX_FloatRect& rect,
-                                               const CFX_Color& color);
-  static CFX_ByteString GetPushButtonAppStream(const CFX_FloatRect& rcBBox,
-                                               IPVT_FontMap* pFontMap,
-                                               CPDF_Stream* pIconStream,
-                                               CPDF_IconFit& IconFit,
-                                               const CFX_WideString& sLabel,
-                                               const CFX_Color& crText,
-                                               float fFontSize,
-                                               int32_t nLayOut);
-  static CFX_ByteString GetCheckBoxAppStream(const CFX_FloatRect& rcBBox,
-                                             int32_t nStyle,
-                                             const CFX_Color& crText);
-  static CFX_ByteString GetRadioButtonAppStream(const CFX_FloatRect& rcBBox,
-                                                int32_t nStyle,
-                                                const CFX_Color& crText);
   static CFX_ByteString GetEditAppStream(CFX_Edit* pEdit,
                                          const CFX_PointF& ptOffset,
                                          const CPVT_WordRange* pRange = nullptr,
@@ -75,30 +52,6 @@
       CFX_Edit* pEdit,
       const CFX_PointF& ptOffset,
       const CPVT_WordRange* pRange = nullptr);
-  static CFX_ByteString GetDropButtonAppStream(const CFX_FloatRect& rcBBox);
-
- private:
-  static CFX_ByteString GetAppStream_Check(const CFX_FloatRect& rcBBox,
-                                           const CFX_Color& crText);
-  static CFX_ByteString GetAppStream_Circle(const CFX_FloatRect& rcBBox,
-                                            const CFX_Color& crText);
-  static CFX_ByteString GetAppStream_Cross(const CFX_FloatRect& rcBBox,
-                                           const CFX_Color& crText);
-  static CFX_ByteString GetAppStream_Diamond(const CFX_FloatRect& rcBBox,
-                                             const CFX_Color& crText);
-  static CFX_ByteString GetAppStream_Square(const CFX_FloatRect& rcBBox,
-                                            const CFX_Color& crText);
-  static CFX_ByteString GetAppStream_Star(const CFX_FloatRect& rcBBox,
-                                          const CFX_Color& crText);
-
-  static CFX_ByteString GetAP_Check(const CFX_FloatRect& crBBox);
-  static CFX_ByteString GetAP_Circle(const CFX_FloatRect& crBBox);
-  static CFX_ByteString GetAP_Cross(const CFX_FloatRect& crBBox);
-  static CFX_ByteString GetAP_Diamond(const CFX_FloatRect& crBBox);
-  static CFX_ByteString GetAP_Square(const CFX_FloatRect& crBBox);
-  static CFX_ByteString GetAP_Star(const CFX_FloatRect& crBBox);
-  static CFX_ByteString GetAP_HalfCircle(const CFX_FloatRect& crBBox,
-                                         float fRotate);
 };
 
 #endif  // FPDFSDK_PDFWINDOW_CPWL_UTILS_H_