Switch from absl::optional to std::optional

Since absl::optional is using std::optional underneath, just switch to
using std::optional directly.

Change-Id: Ide39da5ac9c7551a710e653a60e15f022046df7b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/116290
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index c39493d..aa16328 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -591,7 +591,7 @@
   }
 
   ByteString name;
-  absl::optional<ByteString> maybe_name =
+  std::optional<ByteString> maybe_name =
       m_pObjHolder->GraphicsMapSearch(graphD);
   if (maybe_name.has_value()) {
     name = std::move(maybe_name.value());
@@ -630,7 +630,7 @@
   defaultGraphics.strokeAlpha = 1.0f;
   defaultGraphics.blendType = BlendMode::kNormal;
 
-  absl::optional<ByteString> maybe_name =
+  std::optional<ByteString> maybe_name =
       m_pObjHolder->GraphicsMapSearch(defaultGraphics);
   if (maybe_name.has_value())
     return maybe_name.value();
@@ -675,7 +675,7 @@
   data.baseFont = pFont->GetBaseFontName();
 
   ByteString dict_name;
-  absl::optional<ByteString> maybe_name = m_pObjHolder->FontsMapSearch(data);
+  std::optional<ByteString> maybe_name = m_pObjHolder->FontsMapSearch(data);
   if (maybe_name.has_value()) {
     dict_name = std::move(maybe_name.value());
   } else {
diff --git a/core/fpdfapi/font/cfx_cttgsubtable.cpp b/core/fpdfapi/font/cfx_cttgsubtable.cpp
index c19649e..bf9566c 100644
--- a/core/fpdfapi/font/cfx_cttgsubtable.cpp
+++ b/core/fpdfapi/font/cfx_cttgsubtable.cpp
@@ -72,7 +72,7 @@
 
 uint32_t CFX_CTTGSUBTable::GetVerticalGlyph(uint32_t glyphnum) const {
   for (uint32_t item : feature_set_) {
-    absl::optional<uint32_t> result =
+    std::optional<uint32_t> result =
         GetVerticalGlyphSub(feature_list_[item], glyphnum);
     if (result.has_value())
       return result.value();
@@ -80,7 +80,7 @@
   return 0;
 }
 
-absl::optional<uint32_t> CFX_CTTGSUBTable::GetVerticalGlyphSub(
+std::optional<uint32_t> CFX_CTTGSUBTable::GetVerticalGlyphSub(
     const FeatureRecord& feature,
     uint32_t glyphnum) const {
   for (int index : feature.lookup_list_indices) {
@@ -90,15 +90,15 @@
     if (lookup_list_[index].lookup_type != 1) {
       continue;
     }
-    absl::optional<uint32_t> result =
+    std::optional<uint32_t> result =
         GetVerticalGlyphSub2(lookup_list_[index], glyphnum);
     if (result.has_value())
       return result.value();
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<uint32_t> CFX_CTTGSUBTable::GetVerticalGlyphSub2(
+std::optional<uint32_t> CFX_CTTGSUBTable::GetVerticalGlyphSub2(
     const Lookup& lookup,
     uint32_t glyphnum) const {
   for (const auto& sub_table : lookup.sub_tables) {
@@ -118,7 +118,7 @@
       }
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 int CFX_CTTGSUBTable::GetCoverageIndex(const CoverageFormat& coverage,
diff --git a/core/fpdfapi/font/cfx_cttgsubtable.h b/core/fpdfapi/font/cfx_cttgsubtable.h
index e6b797a..30bc353 100644
--- a/core/fpdfapi/font/cfx_cttgsubtable.h
+++ b/core/fpdfapi/font/cfx_cttgsubtable.h
@@ -9,11 +9,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <set>
 #include <vector>
 
 #include "core/fxcrt/data_vector.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 #include "third_party/base/containers/span.h"
 
@@ -91,10 +91,10 @@
   CoverageFormat ParseCoverage(const uint8_t* raw);
   SubTable ParseSingleSubst(const uint8_t* raw);
 
-  absl::optional<uint32_t> GetVerticalGlyphSub(const FeatureRecord& feature,
+  std::optional<uint32_t> GetVerticalGlyphSub(const FeatureRecord& feature,
+                                              uint32_t glyphnum) const;
+  std::optional<uint32_t> GetVerticalGlyphSub2(const Lookup& lookup,
                                                uint32_t glyphnum) const;
-  absl::optional<uint32_t> GetVerticalGlyphSub2(const Lookup& lookup,
-                                                uint32_t glyphnum) const;
   int GetCoverageIndex(const CoverageFormat& coverage, uint32_t g) const;
 
   uint8_t GetUInt8(const uint8_t*& p) const;
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index b0bcfd5..709517a 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -763,7 +763,7 @@
       return cid;
     }
 
-    absl::optional<fxge::FontEncoding> charmap =
+    std::optional<fxge::FontEncoding> charmap =
         face->GetCurrentCharMapEncoding();
     if (!charmap.has_value()) {
       return cid;
diff --git a/core/fpdfapi/font/cpdf_cmapparser.cpp b/core/fpdfapi/font/cpdf_cmapparser.cpp
index e026cb1..97d72ed 100644
--- a/core/fpdfapi/font/cpdf_cmapparser.cpp
+++ b/core/fpdfapi/font/cpdf_cmapparser.cpp
@@ -112,7 +112,7 @@
       return;
 
     if (m_CodeSeq % 2) {
-      absl::optional<CPDF_CMap::CodeRange> range =
+      std::optional<CPDF_CMap::CodeRange> range =
           GetCodeRange(m_LastWord.AsStringView(), word);
       if (range.has_value())
         m_PendingRanges.push_back(range.value());
@@ -161,11 +161,11 @@
 }
 
 // static
-absl::optional<CPDF_CMap::CodeRange> CPDF_CMapParser::GetCodeRange(
+std::optional<CPDF_CMap::CodeRange> CPDF_CMapParser::GetCodeRange(
     ByteStringView first,
     ByteStringView second) {
   if (first.IsEmpty() || first[0] != '<')
-    return absl::nullopt;
+    return std::nullopt;
 
   size_t i;
   for (i = 1; i < first.GetLength(); ++i) {
@@ -174,7 +174,7 @@
   }
   size_t char_size = (i - 1) / 2;
   if (char_size > 4)
-    return absl::nullopt;
+    return std::nullopt;
 
   CPDF_CMap::CodeRange range;
   range.m_CharSize = char_size;
diff --git a/core/fpdfapi/font/cpdf_cmapparser.h b/core/fpdfapi/font/cpdf_cmapparser.h
index 9219814..25d1e18 100644
--- a/core/fpdfapi/font/cpdf_cmapparser.h
+++ b/core/fpdfapi/font/cpdf_cmapparser.h
@@ -7,13 +7,13 @@
 #ifndef CORE_FPDFAPI_FONT_CPDF_CMAPPARSER_H_
 #define CORE_FPDFAPI_FONT_CPDF_CMAPPARSER_H_
 
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "core/fpdfapi/font/cpdf_cidfont.h"
 #include "core/fpdfapi/font/cpdf_cmap.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_CMapParser {
  public:
@@ -43,7 +43,7 @@
   void HandleCodeSpaceRange(ByteStringView word);
 
   static uint32_t GetCode(ByteStringView word);
-  static absl::optional<CPDF_CMap::CodeRange> GetCodeRange(
+  static std::optional<CPDF_CMap::CodeRange> GetCodeRange(
       ByteStringView first,
       ByteStringView second);
 
diff --git a/core/fpdfapi/font/cpdf_cmapparser_unittest.cpp b/core/fpdfapi/font/cpdf_cmapparser_unittest.cpp
index a9cdc71..d62c1b9 100644
--- a/core/fpdfapi/font/cpdf_cmapparser_unittest.cpp
+++ b/core/fpdfapi/font/cpdf_cmapparser_unittest.cpp
@@ -37,7 +37,7 @@
 }
 
 TEST(cpdf_cmapparser, GetCodeRange) {
-  absl::optional<CPDF_CMap::CodeRange> range;
+  std::optional<CPDF_CMap::CodeRange> range;
 
   // Must start with a <
   range = CPDF_CMapParser::GetCodeRange("", "");
diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp
index 66e385d..52695d4 100644
--- a/core/fpdfapi/font/cpdf_font.cpp
+++ b/core/fpdfapi/font/cpdf_font.cpp
@@ -274,7 +274,7 @@
 RetainPtr<CPDF_Font> CPDF_Font::GetStockFont(CPDF_Document* pDoc,
                                              ByteStringView name) {
   ByteString fontname(name);
-  absl::optional<CFX_FontMapper::StandardFont> font_id =
+  std::optional<CFX_FontMapper::StandardFont> font_id =
       CFX_FontMapper::GetStandardFontName(&fontname);
   if (!font_id.has_value())
     return nullptr;
@@ -344,10 +344,10 @@
   return AsType1Font()->IsBase14Font();
 }
 
-absl::optional<FX_Charset> CPDF_Font::GetSubstFontCharset() const {
+std::optional<FX_Charset> CPDF_Font::GetSubstFontCharset() const {
   CFX_SubstFont* pFont = m_Font.GetSubstFont();
   if (!pFont)
-    return absl::nullopt;
+    return std::nullopt;
   return pFont->m_Charset;
 }
 
diff --git a/core/fpdfapi/font/cpdf_font.h b/core/fpdfapi/font/cpdf_font.h
index af0a82b..edfbc9f 100644
--- a/core/fpdfapi/font/cpdf_font.h
+++ b/core/fpdfapi/font/cpdf_font.h
@@ -10,6 +10,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -22,7 +23,6 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_font.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_DIBitmap;
 class CPDF_CIDFont;
@@ -44,7 +44,7 @@
     virtual void ParseContentForType3Char(CPDF_Type3Char* pChar) = 0;
     virtual bool HasPageObjects() const = 0;
     virtual CFX_FloatRect CalcBoundingBox() const = 0;
-    virtual absl::optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
+    virtual std::optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
     GetBitmapAndMatrixFromSoleImageOfForm() const = 0;
   };
 
@@ -96,7 +96,7 @@
   virtual bool HasFontWidths() const;
 
   ByteString GetBaseFontName() const { return m_BaseFontName; }
-  absl::optional<FX_Charset> GetSubstFontCharset() const;
+  std::optional<FX_Charset> GetSubstFontCharset() const;
   bool IsEmbedded() const { return IsType3Font() || m_pFontFile != nullptr; }
   RetainPtr<CPDF_Dictionary> GetMutableFontDict() { return m_pFontDict; }
   RetainPtr<const CPDF_Dictionary> GetFontDict() const { return m_pFontDict; }
diff --git a/core/fpdfapi/font/cpdf_fontencoding.cpp b/core/fpdfapi/font/cpdf_fontencoding.cpp
index 7ed59c0..481487a 100644
--- a/core/fpdfapi/font/cpdf_fontencoding.cpp
+++ b/core/fpdfapi/font/cpdf_fontencoding.cpp
@@ -7,6 +7,7 @@
 #include "core/fpdfapi/font/cpdf_fontencoding.h"
 
 #include <iterator>
+#include <optional>
 
 #include "constants/font_encodings.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
@@ -16,7 +17,6 @@
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fxge/fx_font.h"
 #include "core/fxge/fx_fontencoding.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
@@ -1688,7 +1688,7 @@
       FontEncoding::kAdobeSymbol,
   };
 
-  absl::optional<FontEncoding> predefined;
+  std::optional<FontEncoding> predefined;
   for (FontEncoding cs : kEncodings) {
     pdfium::span<const uint16_t> src = UnicodesForPredefinedCharSet(cs);
     bool match = true;
diff --git a/core/fpdfapi/font/cpdf_tounicodemap.cpp b/core/fpdfapi/font/cpdf_tounicodemap.cpp
index 9cb77ba..2e4dbe5 100644
--- a/core/fpdfapi/font/cpdf_tounicodemap.cpp
+++ b/core/fpdfapi/font/cpdf_tounicodemap.cpp
@@ -79,7 +79,7 @@
 }
 
 // static
-absl::optional<uint32_t> CPDF_ToUnicodeMap::StringToCode(ByteStringView input) {
+std::optional<uint32_t> CPDF_ToUnicodeMap::StringToCode(ByteStringView input) {
   // Ignore whitespaces within `input`. See https://crbug.com/pdfium/2065.
   std::set<char> seen_whitespace_chars;
   for (char c : input) {
@@ -103,18 +103,18 @@
 
   size_t len = str.GetLength();
   if (len <= 2 || str[0] != '<' || str[len - 1] != '>')
-    return absl::nullopt;
+    return std::nullopt;
 
   FX_SAFE_UINT32 code = 0;
   for (char c : str.Substr(1, len - 2)) {
     if (!FXSYS_IsHexDigit(c))
-      return absl::nullopt;
+      return std::nullopt;
 
     code = code * 16 + FXSYS_HexCharToInt(c);
     if (!code.IsValid())
-      return absl::nullopt;
+      return std::nullopt;
   }
-  return absl::optional<uint32_t>(code.ValueOrDie());
+  return std::optional<uint32_t>(code.ValueOrDie());
 }
 
 // static
@@ -175,7 +175,7 @@
     if (word.IsEmpty() || word == "endbfchar")
       return;
 
-    absl::optional<uint32_t> code = StringToCode(word);
+    std::optional<uint32_t> code = StringToCode(word);
     if (!code.has_value())
       return;
 
@@ -189,12 +189,12 @@
     if (lowcode_str.IsEmpty() || lowcode_str == "endbfrange")
       return;
 
-    absl::optional<uint32_t> lowcode_opt = StringToCode(lowcode_str);
+    std::optional<uint32_t> lowcode_opt = StringToCode(lowcode_str);
     if (!lowcode_opt.has_value())
       return;
 
     ByteStringView highcode_str = pParser->GetWord();
-    absl::optional<uint32_t> highcode_opt = StringToCode(highcode_str);
+    std::optional<uint32_t> highcode_opt = StringToCode(highcode_str);
     if (!highcode_opt.has_value())
       return;
 
@@ -215,7 +215,7 @@
 
     WideString destcode = StringToWideString(start);
     if (destcode.GetLength() == 1) {
-      absl::optional<uint32_t> value_or_error = StringToCode(start);
+      std::optional<uint32_t> value_or_error = StringToCode(start);
       if (!value_or_error.has_value())
         return;
 
diff --git a/core/fpdfapi/font/cpdf_tounicodemap.h b/core/fpdfapi/font/cpdf_tounicodemap.h
index 7f4ba03..d464ca4 100644
--- a/core/fpdfapi/font/cpdf_tounicodemap.h
+++ b/core/fpdfapi/font/cpdf_tounicodemap.h
@@ -8,13 +8,13 @@
 #define CORE_FPDFAPI_FONT_CPDF_TOUNICODEMAP_H_
 
 #include <map>
+#include <optional>
 #include <set>
 #include <vector>
 
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_CID2UnicodeMap;
 class CPDF_SimpleParser;
@@ -34,7 +34,7 @@
   friend class cpdf_tounicodemap_StringToCode_Test;
   friend class cpdf_tounicodemap_StringToWideString_Test;
 
-  static absl::optional<uint32_t> StringToCode(ByteStringView input);
+  static std::optional<uint32_t> StringToCode(ByteStringView input);
   static WideString StringToWideString(ByteStringView str);
 
   void Load(RetainPtr<const CPDF_Stream> pStream);
diff --git a/core/fpdfapi/font/cpdf_type1font.h b/core/fpdfapi/font/cpdf_type1font.h
index 55f542f..60e1ffa 100644
--- a/core/fpdfapi/font/cpdf_type1font.h
+++ b/core/fpdfapi/font/cpdf_type1font.h
@@ -49,7 +49,7 @@
   uint16_t m_ExtGID[kInternalTableSize];
 #endif
 
-  absl::optional<CFX_FontMapper::StandardFont> m_Base14Font;
+  std::optional<CFX_FontMapper::StandardFont> m_Base14Font;
 };
 
 #endif  // CORE_FPDFAPI_FONT_CPDF_TYPE1FONT_H_
diff --git a/core/fpdfapi/font/cpdf_type3char.h b/core/fpdfapi/font/cpdf_type3char.h
index 990fb77..555873c 100644
--- a/core/fpdfapi/font/cpdf_type3char.h
+++ b/core/fpdfapi/font/cpdf_type3char.h
@@ -8,12 +8,12 @@
 #define CORE_FPDFAPI_FONT_CPDF_TYPE3CHAR_H_
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "core/fpdfapi/font/cpdf_font.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 class CFX_DIBitmap;
diff --git a/core/fpdfapi/page/cpdf_dib.cpp b/core/fpdfapi/page/cpdf_dib.cpp
index c538e43..50bcef7 100644
--- a/core/fpdfapi/page/cpdf_dib.cpp
+++ b/core/fpdfapi/page/cpdf_dib.cpp
@@ -248,7 +248,7 @@
     m_Format = MakeRGBFormat(CalculateBitsPerPixel(m_bpc, m_nComponents));
   }
 
-  absl::optional<uint32_t> pitch =
+  std::optional<uint32_t> pitch =
       fxge::CalculatePitch32(GetBppFromFormat(m_Format), m_Width);
   if (!pitch.has_value())
     return false;
@@ -384,7 +384,7 @@
 
 bool CPDF_DIB::LoadColorInfo(const CPDF_Dictionary* pFormResources,
                              const CPDF_Dictionary* pPageResources) {
-  absl::optional<DecoderArray> decoder_array = GetDecoderArray(m_pDict);
+  std::optional<DecoderArray> decoder_array = GetDecoderArray(m_pDict);
   if (!decoder_array.has_value())
     return false;
 
@@ -543,11 +543,11 @@
   if (!m_pDecoder)
     return LoadState::kFail;
 
-  const absl::optional<uint32_t> requested_pitch =
+  const std::optional<uint32_t> requested_pitch =
       fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
   if (!requested_pitch.has_value())
     return LoadState::kFail;
-  const absl::optional<uint32_t> provided_pitch = fxge::CalculatePitch8(
+  const std::optional<uint32_t> provided_pitch = fxge::CalculatePitch8(
       m_pDecoder->GetBPC(), m_pDecoder->CountComps(), m_pDecoder->GetWidth());
   if (!provided_pitch.has_value())
     return LoadState::kFail;
@@ -564,7 +564,7 @@
   if (m_pDecoder)
     return true;
 
-  absl::optional<JpegModule::ImageInfo> info_opt =
+  std::optional<JpegModule::ImageInfo> info_opt =
       JpegModule::LoadInfo(src_span);
   if (!info_opt.has_value())
     return false;
@@ -802,7 +802,7 @@
   if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0))
     return false;
 
-  const absl::optional<uint32_t> maybe_size =
+  const std::optional<uint32_t> maybe_size =
       fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
   if (!maybe_size.has_value())
     return false;
@@ -1133,7 +1133,7 @@
   if (m_bpc == 0)
     return pdfium::span<const uint8_t>();
 
-  const absl::optional<uint32_t> src_pitch =
+  const std::optional<uint32_t> src_pitch =
       fxge::CalculatePitch8(m_bpc, m_nComponents, m_Width);
   if (!src_pitch.has_value())
     return pdfium::span<const uint8_t>();
diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp
index 01ea481..ca45164 100644
--- a/core/fpdfapi/page/cpdf_docpagedata.cpp
+++ b/core/fpdfapi/page/cpdf_docpagedata.cpp
@@ -488,7 +488,7 @@
     const ByteString& fontName,
     const CPDF_FontEncoding* pEncoding) {
   ByteString mutable_name(fontName);
-  absl::optional<CFX_FontMapper::StandardFont> font_id =
+  std::optional<CFX_FontMapper::StandardFont> font_id =
       CFX_FontMapper::GetStandardFontName(&mutable_name);
   if (!font_id.has_value())
     return nullptr;
diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp
index e66ff0b..eae6bd1 100644
--- a/core/fpdfapi/page/cpdf_form.cpp
+++ b/core/fpdfapi/page/cpdf_form.cpp
@@ -115,14 +115,14 @@
   return m_pFormStream;
 }
 
-absl::optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
+std::optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
 CPDF_Form::GetBitmapAndMatrixFromSoleImageOfForm() const {
   if (GetPageObjectCount() != 1)
-    return absl::nullopt;
+    return std::nullopt;
 
   CPDF_ImageObject* pImageObject = (*begin())->AsImage();
   if (!pImageObject)
-    return absl::nullopt;
+    return std::nullopt;
 
   return {{pImageObject->GetIndependentBitmap(), pImageObject->matrix()}};
 }
diff --git a/core/fpdfapi/page/cpdf_form.h b/core/fpdfapi/page/cpdf_form.h
index 3ced731..aa9f540 100644
--- a/core/fpdfapi/page/cpdf_form.h
+++ b/core/fpdfapi/page/cpdf_form.h
@@ -49,7 +49,7 @@
   void ParseContentForType3Char(CPDF_Type3Char* pType3Char) override;
   bool HasPageObjects() const override;
   CFX_FloatRect CalcBoundingBox() const override;
-  absl::optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
+  std::optional<std::pair<RetainPtr<CFX_DIBitmap>, CFX_Matrix>>
   GetBitmapAndMatrixFromSoleImageOfForm() const override;
 
   void ParseContent();
diff --git a/core/fpdfapi/page/cpdf_function.cpp b/core/fpdfapi/page/cpdf_function.cpp
index 2cd2bc1..be9ddaf 100644
--- a/core/fpdfapi/page/cpdf_function.cpp
+++ b/core/fpdfapi/page/cpdf_function.cpp
@@ -128,23 +128,22 @@
   return true;
 }
 
-absl::optional<uint32_t> CPDF_Function::Call(
-    pdfium::span<const float> inputs,
-    pdfium::span<float> results) const {
+std::optional<uint32_t> CPDF_Function::Call(pdfium::span<const float> inputs,
+                                            pdfium::span<float> results) const {
   if (m_nInputs != inputs.size())
-    return absl::nullopt;
+    return std::nullopt;
 
   std::vector<float> clamped_inputs(m_nInputs);
   for (uint32_t i = 0; i < m_nInputs; i++) {
     float domain1 = m_Domains[i * 2];
     float domain2 = m_Domains[i * 2 + 1];
     if (domain1 > domain2)
-      return absl::nullopt;
+      return std::nullopt;
 
     clamped_inputs[i] = std::clamp(inputs[i], domain1, domain2);
   }
   if (!v_Call(clamped_inputs, results))
-    return absl::nullopt;
+    return std::nullopt;
 
   if (m_Ranges.empty())
     return m_nOutputs;
@@ -153,7 +152,7 @@
     float range1 = m_Ranges[i * 2];
     float range2 = m_Ranges[i * 2 + 1];
     if (range1 > range2)
-      return absl::nullopt;
+      return std::nullopt;
 
     results[i] = std::clamp(results[i], range1, range2);
   }
diff --git a/core/fpdfapi/page/cpdf_function.h b/core/fpdfapi/page/cpdf_function.h
index 8fc4e72..0aee6bd 100644
--- a/core/fpdfapi/page/cpdf_function.h
+++ b/core/fpdfapi/page/cpdf_function.h
@@ -8,11 +8,11 @@
 #define CORE_FPDFAPI_PAGE_CPDF_FUNCTION_H_
 
 #include <memory>
+#include <optional>
 #include <set>
 #include <vector>
 
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 class CPDF_ExpIntFunc;
@@ -36,8 +36,8 @@
 
   virtual ~CPDF_Function();
 
-  absl::optional<uint32_t> Call(pdfium::span<const float> inputs,
-                                pdfium::span<float> results) const;
+  std::optional<uint32_t> Call(pdfium::span<const float> inputs,
+                               pdfium::span<float> results) const;
   uint32_t CountInputs() const { return m_nInputs; }
   uint32_t CountOutputs() const { return m_nOutputs; }
   float GetDomain(int i) const { return m_Domains[i]; }
diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp
index 663bde0..aa0b120 100644
--- a/core/fpdfapi/page/cpdf_image.cpp
+++ b/core/fpdfapi/page/cpdf_image.cpp
@@ -96,7 +96,7 @@
 
 RetainPtr<CPDF_Dictionary> CPDF_Image::InitJPEG(
     pdfium::span<uint8_t> src_span) {
-  absl::optional<JpegModule::ImageInfo> info_opt =
+  std::optional<JpegModule::ImageInfo> info_opt =
       JpegModule::LoadInfo(src_span);
   if (!info_opt.has_value())
     return nullptr;
diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
index d3493de..7c7a603 100644
--- a/core/fpdfapi/page/cpdf_page.cpp
+++ b/core/fpdfapi/page/cpdf_page.cpp
@@ -104,7 +104,7 @@
   return box;
 }
 
-absl::optional<CFX_PointF> CPDF_Page::DeviceToPage(
+std::optional<CFX_PointF> CPDF_Page::DeviceToPage(
     const FX_RECT& rect,
     int rotate,
     const CFX_PointF& device_point) const {
@@ -112,7 +112,7 @@
   return page2device.GetInverse().Transform(device_point);
 }
 
-absl::optional<CFX_PointF> CPDF_Page::PageToDevice(
+std::optional<CFX_PointF> CPDF_Page::PageToDevice(
     const FX_RECT& rect,
     int rotate,
     const CFX_PointF& page_point) const {
diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h
index 2b659e6..70d50d6 100644
--- a/core/fpdfapi/page/cpdf_page.h
+++ b/core/fpdfapi/page/cpdf_page.h
@@ -8,6 +8,7 @@
 #define CORE_FPDFAPI_PAGE_CPDF_PAGE_H_
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "core/fpdfapi/page/cpdf_pageobjectholder.h"
@@ -17,7 +18,6 @@
 #include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_Array;
 class CPDF_Dictionary;
@@ -58,11 +58,11 @@
   float GetPageWidth() const override;
   float GetPageHeight() const override;
   CFX_Matrix GetDisplayMatrix(const FX_RECT& rect, int iRotate) const override;
-  absl::optional<CFX_PointF> DeviceToPage(
+  std::optional<CFX_PointF> DeviceToPage(
       const FX_RECT& rect,
       int rotate,
       const CFX_PointF& device_point) const override;
-  absl::optional<CFX_PointF> PageToDevice(
+  std::optional<CFX_PointF> PageToDevice(
       const FX_RECT& rect,
       int rotate,
       const CFX_PointF& page_point) const override;
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.cpp b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
index d52f129..3b4e071 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.cpp
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
@@ -86,11 +86,11 @@
   return dirty_streams;
 }
 
-absl::optional<ByteString> CPDF_PageObjectHolder::GraphicsMapSearch(
+std::optional<ByteString> CPDF_PageObjectHolder::GraphicsMapSearch(
     const GraphicsData& gd) {
   auto it = m_GraphicsMap.find(gd);
   if (it == m_GraphicsMap.end())
-    return absl::nullopt;
+    return std::nullopt;
 
   return it->second;
 }
@@ -100,11 +100,11 @@
   m_GraphicsMap[gd] = str;
 }
 
-absl::optional<ByteString> CPDF_PageObjectHolder::FontsMapSearch(
+std::optional<ByteString> CPDF_PageObjectHolder::FontsMapSearch(
     const FontData& fd) {
   auto it = m_FontsMap.find(fd);
   if (it == m_FontsMap.end())
-    return absl::nullopt;
+    return std::nullopt;
 
   return it->second;
 }
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.h b/core/fpdfapi/page/cpdf_pageobjectholder.h
index 629c028..6afe13b 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.h
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.h
@@ -13,6 +13,7 @@
 #include <deque>
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <utility>
 #include <vector>
@@ -24,7 +25,6 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/dib/fx_dib.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_ContentParser;
 class CPDF_Document;
@@ -113,10 +113,10 @@
   bool HasDirtyStreams() const { return !m_DirtyStreams.empty(); }
   std::set<int32_t> TakeDirtyStreams();
 
-  absl::optional<ByteString> GraphicsMapSearch(const GraphicsData& gd);
+  std::optional<ByteString> GraphicsMapSearch(const GraphicsData& gd);
   void GraphicsMapInsert(const GraphicsData& gd, const ByteString& str);
 
-  absl::optional<ByteString> FontsMapSearch(const FontData& fd);
+  std::optional<ByteString> FontsMapSearch(const FontData& fd);
   void FontsMapInsert(const FontData& fd, const ByteString& str);
 
  protected:
diff --git a/core/fpdfapi/page/cpdf_stitchfunc.cpp b/core/fpdfapi/page/cpdf_stitchfunc.cpp
index 21e5c80..61e04bb 100644
--- a/core/fpdfapi/page/cpdf_stitchfunc.cpp
+++ b/core/fpdfapi/page/cpdf_stitchfunc.cpp
@@ -63,7 +63,7 @@
 
   // Check sub-functions.
   {
-    absl::optional<uint32_t> nOutputs;
+    std::optional<uint32_t> nOutputs;
     for (uint32_t i = 0; i < nSubs; ++i) {
       RetainPtr<const CPDF_Object> pSub = pFunctionsArray->GetDirectObjectAt(i);
       if (pSub == pObj)
diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp
index dd0a76d..a842f98 100644
--- a/core/fpdfapi/page/cpdf_streamparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamparser.cpp
@@ -54,7 +54,7 @@
   if (width <= 0 || height <= 0)
     return FX_INVALID_OFFSET;
 
-  absl::optional<uint32_t> maybe_size =
+  std::optional<uint32_t> maybe_size =
       fxge::CalculatePitch8(bpc, ncomps, width);
   if (!maybe_size.has_value())
     return FX_INVALID_OFFSET;
@@ -165,7 +165,7 @@
     nComponents = pCS ? pCS->CountComponents() : 3;
     bpc = pDict->GetIntegerFor("BitsPerComponent");
   }
-  absl::optional<uint32_t> maybe_size =
+  std::optional<uint32_t> maybe_size =
       fxge::CalculatePitch8(bpc, nComponents, width);
   if (!maybe_size.has_value())
     return nullptr;
diff --git a/core/fpdfapi/page/ipdf_page.h b/core/fpdfapi/page/ipdf_page.h
index a71106b..a37155f 100644
--- a/core/fpdfapi/page/ipdf_page.h
+++ b/core/fpdfapi/page/ipdf_page.h
@@ -7,9 +7,10 @@
 #ifndef CORE_FPDFAPI_PAGE_IPDF_PAGE_H_
 #define CORE_FPDFAPI_PAGE_IPDF_PAGE_H_
 
+#include <optional>
+
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_Document;
 class CPDF_Page;
@@ -35,12 +36,12 @@
   virtual CFX_Matrix GetDisplayMatrix(const FX_RECT& rect,
                                       int iRotate) const = 0;
 
-  virtual absl::optional<CFX_PointF> DeviceToPage(
+  virtual std::optional<CFX_PointF> DeviceToPage(
       const FX_RECT& rect,
       int rotate,
       const CFX_PointF& device_point) const = 0;
 
-  virtual absl::optional<CFX_PointF> PageToDevice(
+  virtual std::optional<CFX_PointF> PageToDevice(
       const FX_RECT& rect,
       int rotate,
       const CFX_PointF& page_point) const = 0;
diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp
index 3d51a9f..9a6ee88 100644
--- a/core/fpdfapi/parser/cpdf_array.cpp
+++ b/core/fpdfapi/parser/cpdf_array.cpp
@@ -81,12 +81,12 @@
                     GetFloatAt(4), GetFloatAt(5));
 }
 
-absl::optional<size_t> CPDF_Array::Find(const CPDF_Object* pThat) const {
+std::optional<size_t> CPDF_Array::Find(const CPDF_Object* pThat) const {
   for (size_t i = 0; i < size(); ++i) {
     if (GetDirectObjectAt(i) == pThat)
       return i;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool CPDF_Array::Contains(const CPDF_Object* pThat) const {
diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h
index 2554809..a103133 100644
--- a/core/fpdfapi/parser/cpdf_array.h
+++ b/core/fpdfapi/parser/cpdf_array.h
@@ -9,6 +9,7 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <set>
 #include <type_traits>
 #include <utility>
@@ -18,7 +19,6 @@
 #include "core/fpdfapi/parser/cpdf_object.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 
 // Arrays never contain nullptrs for objects within bounds, but some of the
@@ -72,7 +72,7 @@
   CFX_FloatRect GetRect() const;
   CFX_Matrix GetMatrix() const;
 
-  absl::optional<size_t> Find(const CPDF_Object* pThat) const;
+  std::optional<size_t> Find(const CPDF_Object* pThat) const;
   bool Contains(const CPDF_Object* pThat) const;
 
   // Creates object owned by the array, and returns a retained pointer to it.
diff --git a/core/fpdfapi/parser/cpdf_array_unittest.cpp b/core/fpdfapi/parser/cpdf_array_unittest.cpp
index 9b3e841..c3c9ef0 100644
--- a/core/fpdfapi/parser/cpdf_array_unittest.cpp
+++ b/core/fpdfapi/parser/cpdf_array_unittest.cpp
@@ -197,7 +197,7 @@
   arr->Append(dict0);
   arr->Append(dict1);
 
-  absl::optional<size_t> maybe_found = arr->Find(nullptr);
+  std::optional<size_t> maybe_found = arr->Find(nullptr);
   EXPECT_FALSE(maybe_found.has_value());
 
   maybe_found = arr->Find(dict0.Get());
diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp
index bc3ff33..1605a1a 100644
--- a/core/fpdfapi/parser/cpdf_data_avail.cpp
+++ b/core/fpdfapi/parser/cpdf_data_avail.cpp
@@ -490,7 +490,7 @@
     return kDataAvailable;
 
   CPDF_ReadValidator::ScopedSession read_session(GetValidator());
-  const absl::optional<FX_FILESIZE> header_offset =
+  const std::optional<FX_FILESIZE> header_offset =
       GetHeaderOffset(GetValidator());
   if (GetValidator()->has_read_problems())
     return kDataNotAvailable;
diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp
index fa336ab..373b8bd 100644
--- a/core/fpdfapi/parser/cpdf_document.cpp
+++ b/core/fpdfapi/parser/cpdf_document.cpp
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <functional>
+#include <optional>
 #include <utility>
 
 #include "core/fpdfapi/parser/cpdf_array.h"
@@ -25,7 +26,6 @@
 #include "core/fxcrt/fx_codepage.h"
 #include "core/fxcrt/scoped_set_insertion.h"
 #include "core/fxcrt/stl_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/check_op.h"
 #include "third_party/base/containers/contains.h"
@@ -64,7 +64,7 @@
 // violations. By normalizing the in-memory representation, other code that
 // reads the object do not have to deal with the same spec violations again.
 // If the PDF gets saved, the saved copy will also be more spec-compliant.
-absl::optional<int> CountPages(
+std::optional<int> CountPages(
     RetainPtr<CPDF_Dictionary> pages_dict,
     std::set<RetainPtr<CPDF_Dictionary>>* visited_pages) {
   // Required. See ISO 32000-1:2008 spec, table 29, but tolerate page tree nodes
@@ -91,10 +91,10 @@
       // Use |visited_pages| to help detect circular references of pages.
       ScopedSetInsertion<RetainPtr<CPDF_Dictionary>> local_add(visited_pages,
                                                                kid_dict);
-      absl::optional<int> local_count =
+      std::optional<int> local_count =
           CountPages(std::move(kid_dict), visited_pages);
       if (!local_count.has_value()) {
-        return absl::nullopt;  // Propagate error.
+        return std::nullopt;  // Propagate error.
       }
       count += local_count.value();
     } else {
@@ -103,7 +103,7 @@
     }
 
     if (count >= CPDF_Document::kPageMaxNum) {
-      return absl::nullopt;  // Error: too many pages.
+      return std::nullopt;  // Error: too many pages.
     }
   }
   // Fix the in-memory representation for page tree nodes that violate the spec.
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index d502c42..b28deeb 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -203,7 +203,7 @@
 }
 
 bool CPDF_Parser::InitSyntaxParser(RetainPtr<CPDF_ReadValidator> validator) {
-  const absl::optional<FX_FILESIZE> header_offset = GetHeaderOffset(validator);
+  const std::optional<FX_FILESIZE> header_offset = GetHeaderOffset(validator);
   if (!header_offset.has_value())
     return false;
   if (validator->GetSize() < header_offset.value() + kPDFHeaderSize)
diff --git a/core/fpdfapi/parser/cpdf_stream_acc.cpp b/core/fpdfapi/parser/cpdf_stream_acc.cpp
index e3c14af..02e3450 100644
--- a/core/fpdfapi/parser/cpdf_stream_acc.cpp
+++ b/core/fpdfapi/parser/cpdf_stream_acc.cpp
@@ -138,7 +138,7 @@
   std::unique_ptr<uint8_t, FxFreeDeleter> pDecodedData;
   uint32_t dwDecodedSize = 0;
 
-  absl::optional<DecoderArray> decoder_array =
+  std::optional<DecoderArray> decoder_array =
       GetDecoderArray(m_pStream->GetDict());
   if (!decoder_array.has_value() || decoder_array.value().empty() ||
       !PDF_DataDecode(src_span, estimated_size, bImageAcc,
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index 79fcb1f..181a2ff 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -360,14 +360,14 @@
                                        estimated_size, dest_buf, dest_size);
 }
 
-absl::optional<DecoderArray> GetDecoderArray(
+std::optional<DecoderArray> GetDecoderArray(
     RetainPtr<const CPDF_Dictionary> pDict) {
   RetainPtr<const CPDF_Object> pFilter = pDict->GetDirectObjectFor("Filter");
   if (!pFilter)
     return DecoderArray();
 
   if (!pFilter->IsArray() && !pFilter->IsName())
-    return absl::nullopt;
+    return std::nullopt;
 
   RetainPtr<const CPDF_Object> pParams =
       pDict->GetDirectObjectFor(pdfium::stream::kDecodeParms);
@@ -375,7 +375,7 @@
   DecoderArray decoder_array;
   if (const CPDF_Array* pDecoders = pFilter->AsArray()) {
     if (!ValidateDecoderPipeline(pDecoders))
-      return absl::nullopt;
+      return std::nullopt;
 
     RetainPtr<const CPDF_Array> pParamsArray = ToArray(pParams);
     for (size_t i = 0; i < pDecoders->size(); ++i) {
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.h b/core/fpdfapi/parser/fpdf_parser_decode.h
index 757f4cf..b84da06 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.h
+++ b/core/fpdfapi/parser/fpdf_parser_decode.h
@@ -10,6 +10,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -17,7 +18,6 @@
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 class CPDF_Array;
@@ -71,14 +71,14 @@
                           std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
                           uint32_t* dest_size);
 
-// Returns absl::nullopt if the filter in |pDict| is the wrong type or an
+// Returns std::nullopt if the filter in |pDict| is the wrong type or an
 // invalid decoder pipeline.
 // Returns an empty vector if there is no filter, or if the filter is an empty
 // array.
 // Otherwise, returns a vector of decoders.
 using DecoderArray =
     std::vector<std::pair<ByteString, RetainPtr<const CPDF_Object>>>;
-absl::optional<DecoderArray> GetDecoderArray(
+std::optional<DecoderArray> GetDecoderArray(
     RetainPtr<const CPDF_Dictionary> pDict);
 
 bool PDF_DataDecode(pdfium::span<const uint8_t> src_span,
diff --git a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
index 6b3bc1e..cc9b6d9 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
@@ -201,7 +201,7 @@
   {
     // Treat no filter as an empty filter array.
     auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
-    absl::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
+    std::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
     ASSERT_TRUE(decoder_array.has_value());
     EXPECT_TRUE(decoder_array.value().empty());
   }
@@ -209,14 +209,14 @@
     // Wrong filter type.
     auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
     dict->SetNewFor<CPDF_String>("Filter", "RL", false);
-    absl::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
+    std::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
     EXPECT_FALSE(decoder_array.has_value());
   }
   {
     // Filter name.
     auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
     dict->SetNewFor<CPDF_Name>("Filter", "RL");
-    absl::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
+    std::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
     ASSERT_TRUE(decoder_array.has_value());
     ASSERT_EQ(1u, decoder_array.value().size());
     EXPECT_EQ("RL", decoder_array.value()[0].first);
@@ -225,7 +225,7 @@
     // Empty filter array.
     auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
     dict->SetNewFor<CPDF_Array>("Filter");
-    absl::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
+    std::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
     ASSERT_TRUE(decoder_array.has_value());
     EXPECT_TRUE(decoder_array.value().empty());
   }
@@ -234,7 +234,7 @@
     auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
     auto filter_array = dict->SetNewFor<CPDF_Array>("Filter");
     filter_array->AppendNew<CPDF_Name>("FooBar");
-    absl::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
+    std::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
     ASSERT_TRUE(decoder_array.has_value());
     ASSERT_EQ(1u, decoder_array.value().size());
     EXPECT_EQ("FooBar", decoder_array.value()[0].first);
@@ -245,7 +245,7 @@
     auto filter_array = dict->SetNewFor<CPDF_Array>("Filter");
     filter_array->AppendNew<CPDF_Name>("AHx");
     filter_array->AppendNew<CPDF_Name>("LZWDecode");
-    absl::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
+    std::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
     ASSERT_TRUE(decoder_array.has_value());
     ASSERT_EQ(2u, decoder_array.value().size());
     EXPECT_EQ("AHx", decoder_array.value()[0].first);
@@ -257,7 +257,7 @@
     auto invalid_filter_array = dict->SetNewFor<CPDF_Array>("Filter");
     invalid_filter_array->AppendNew<CPDF_Name>("DCTDecode");
     invalid_filter_array->AppendNew<CPDF_Name>("CCITTFaxDecode");
-    absl::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
+    std::optional<DecoderArray> decoder_array = GetDecoderArray(dict);
     EXPECT_FALSE(decoder_array.has_value());
   }
 }
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.cpp b/core/fpdfapi/parser/fpdf_parser_utility.cpp
index e31131e..ac5df9d 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_utility.cpp
@@ -75,18 +75,18 @@
     'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R',
     'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W'};
 
-absl::optional<FX_FILESIZE> GetHeaderOffset(
+std::optional<FX_FILESIZE> GetHeaderOffset(
     const RetainPtr<IFX_SeekableReadStream>& pFile) {
   static constexpr size_t kBufSize = 4;
   uint8_t buf[kBufSize];
   for (FX_FILESIZE offset = 0; offset <= 1024; ++offset) {
     if (!pFile->ReadBlockAtOffset(buf, offset))
-      return absl::nullopt;
+      return std::nullopt;
 
     if (memcmp(buf, "%PDF", 4) == 0)
       return offset;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 ByteString PDF_NameDecode(ByteStringView orig) {
diff --git a/core/fpdfapi/parser/fpdf_parser_utility.h b/core/fpdfapi/parser/fpdf_parser_utility.h
index 521e20a..509661a 100644
--- a/core/fpdfapi/parser/fpdf_parser_utility.h
+++ b/core/fpdfapi/parser/fpdf_parser_utility.h
@@ -8,11 +8,11 @@
 #define CORE_FPDFAPI_PARSER_FPDF_PARSER_UTILITY_H_
 
 #include <iosfwd>
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/bytestring.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_Array;
 class CPDF_Dictionary;
@@ -42,7 +42,7 @@
 // On success, return a positive offset value to the PDF header. If the header
 // cannot be found, or if there is an error reading from |pFile|, then return
 // nullopt.
-absl::optional<FX_FILESIZE> GetHeaderOffset(
+std::optional<FX_FILESIZE> GetHeaderOffset(
     const RetainPtr<IFX_SeekableReadStream>& pFile);
 
 ByteString PDF_NameDecode(ByteStringView orig);
diff --git a/core/fpdfapi/render/charposlist.cpp b/core/fpdfapi/render/charposlist.cpp
index aba0ada..83d363f 100644
--- a/core/fpdfapi/render/charposlist.cpp
+++ b/core/fpdfapi/render/charposlist.cpp
@@ -55,7 +55,7 @@
   subst_font_name.Remove(' ');
   subst_font_name.MakeLower();
 
-  absl::optional<size_t> find =
+  std::optional<size_t> find =
       base_font_name.Find(subst_font_name.AsStringView());
   return find.has_value() && find.value() == 0;
 }
diff --git a/core/fpdfapi/render/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp
index 7f37161..faa2896 100644
--- a/core/fpdfapi/render/cpdf_imagerenderer.cpp
+++ b/core/fpdfapi/render/cpdf_imagerenderer.cpp
@@ -409,7 +409,7 @@
       return false;
     }
 
-    absl::optional<FX_RECT> image_rect = GetUnitRect();
+    std::optional<FX_RECT> image_rect = GetUnitRect();
     if (!image_rect.has_value())
       return false;
 
@@ -421,7 +421,7 @@
     return true;
   }
 
-  absl::optional<FX_RECT> image_rect = GetUnitRect();
+  std::optional<FX_RECT> image_rect = GetUnitRect();
   if (!image_rect.has_value())
     return false;
 
@@ -503,7 +503,7 @@
     return false;
   }
 
-  absl::optional<FX_RECT> image_rect = GetUnitRect();
+  std::optional<FX_RECT> image_rect = GetUnitRect();
   if (!image_rect.has_value())
     return false;
 
@@ -579,7 +579,7 @@
 }
 
 void CPDF_ImageRenderer::HandleFilters() {
-  absl::optional<DecoderArray> decoder_array =
+  std::optional<DecoderArray> decoder_array =
       GetDecoderArray(m_pImageObject->GetImage()->GetStream()->GetDict());
   if (!decoder_array.has_value())
     return;
@@ -592,11 +592,11 @@
   }
 }
 
-absl::optional<FX_RECT> CPDF_ImageRenderer::GetUnitRect() const {
+std::optional<FX_RECT> CPDF_ImageRenderer::GetUnitRect() const {
   CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
   FX_RECT image_rect = image_rect_f.GetOuterRect();
   if (!image_rect.Valid())
-    return absl::nullopt;
+    return std::nullopt;
   return image_rect;
 }
 
diff --git a/core/fpdfapi/render/cpdf_imagerenderer.h b/core/fpdfapi/render/cpdf_imagerenderer.h
index 0bab169..eea78b7 100644
--- a/core/fpdfapi/render/cpdf_imagerenderer.h
+++ b/core/fpdfapi/render/cpdf_imagerenderer.h
@@ -8,13 +8,13 @@
 #define CORE_FPDFAPI_RENDER_CPDF_IMAGERENDERER_H_
 
 #include <memory>
+#include <optional>
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/dib/cfx_imagerenderer.h"
 #include "core/fxge/dib/fx_dib.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_DIBBase;
 class CFX_DefaultRenderDevice;
@@ -72,7 +72,7 @@
       const FX_RECT& rect) const;
   const CPDF_RenderOptions& GetRenderOptions() const;
   void HandleFilters();
-  absl::optional<FX_RECT> GetUnitRect() const;
+  std::optional<FX_RECT> GetUnitRect() const;
   bool GetDimensionsFromUnitRect(const FX_RECT& rect,
                                  int* left,
                                  int* top,
diff --git a/core/fpdfapi/render/cpdf_rendershading.cpp b/core/fpdfapi/render/cpdf_rendershading.cpp
index 99cdf50..5575205 100644
--- a/core/fpdfapi/render/cpdf_rendershading.cpp
+++ b/core/fpdfapi/render/cpdf_rendershading.cpp
@@ -76,7 +76,7 @@
     for (const auto& func : funcs) {
       if (!func)
         continue;
-      absl::optional<uint32_t> nresults =
+      std::optional<uint32_t> nresults =
           func->Call(pdfium::span_from_ref(input), result_span);
       if (nresults.has_value())
         result_span = result_span.subspan(nresults.value());
@@ -303,7 +303,7 @@
       for (const auto& func : funcs) {
         if (!func)
           continue;
-        absl::optional<uint32_t> nresults = func->Call(input, result_span);
+        std::optional<uint32_t> nresults = func->Call(input, result_span);
         if (nresults.has_value())
           result_span = result_span.subspan(nresults.value());
       }
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index db4ae7f..a80676d 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -911,7 +911,7 @@
           if (!glyph.m_pGlyph)
             continue;
 
-          absl::optional<CFX_Point> point = glyph.GetOrigin({0, 0});
+          std::optional<CFX_Point> point = glyph.GetOrigin({0, 0});
           if (!point.has_value())
             continue;
 
@@ -1025,7 +1025,7 @@
     if (!glyph.m_pGlyph || !glyph.m_pGlyph->GetBitmap()->IsMaskFormat())
       continue;
 
-    absl::optional<CFX_Point> point = glyph.GetOrigin({rect.left, rect.top});
+    std::optional<CFX_Point> point = glyph.GetOrigin({rect.left, rect.top});
     if (!point.has_value())
       continue;
 
diff --git a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
index 534511a..bcfb6e7 100644
--- a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
+++ b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
@@ -46,7 +46,7 @@
     int32_t height = bitmap_rect.Height();
     // Set to 0 to make CalculatePitchAndSize() calculate it.
     constexpr uint32_t kNoPitch = 0;
-    absl::optional<CFX_DIBitmap::PitchAndSize> pitch_size =
+    std::optional<CFX_DIBitmap::PitchAndSize> pitch_size =
         CFX_DIBitmap::CalculatePitchAndSize(width, height, dibFormat, kNoPitch);
     if (!pitch_size.has_value())
       return false;
diff --git a/core/fpdfdoc/cpdf_action.cpp b/core/fpdfdoc/cpdf_action.cpp
index 1370c7f..2463c36 100644
--- a/core/fpdfdoc/cpdf_action.cpp
+++ b/core/fpdfdoc/cpdf_action.cpp
@@ -146,10 +146,10 @@
   return result;
 }
 
-absl::optional<WideString> CPDF_Action::MaybeGetJavaScript() const {
+std::optional<WideString> CPDF_Action::MaybeGetJavaScript() const {
   RetainPtr<const CPDF_Object> pObject = GetJavaScriptObject();
   if (!pObject)
-    return absl::nullopt;
+    return std::nullopt;
   return pObject->GetUnicodeText();
 }
 
diff --git a/core/fpdfdoc/cpdf_action.h b/core/fpdfdoc/cpdf_action.h
index cb9e930..624a413 100644
--- a/core/fpdfdoc/cpdf_action.h
+++ b/core/fpdfdoc/cpdf_action.h
@@ -7,12 +7,12 @@
 #ifndef CORE_FPDFDOC_CPDF_ACTION_H_
 #define CORE_FPDFDOC_CPDF_ACTION_H_
 
+#include <optional>
 #include <vector>
 
 #include "core/fpdfdoc/cpdf_dest.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_Dictionary;
 class CPDF_Document;
@@ -62,7 +62,7 @@
   std::vector<RetainPtr<const CPDF_Object>> GetAllFields() const;
 
   // Differentiates between empty JS entry and no JS entry.
-  absl::optional<WideString> MaybeGetJavaScript() const;
+  std::optional<WideString> MaybeGetJavaScript() const;
 
   // Returns empty string for empty JS entry and no JS entry.
   WideString GetJavaScript() const;
diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp
index e0ecd88..375889e 100644
--- a/core/fpdfdoc/cpdf_annot.cpp
+++ b/core/fpdfdoc/cpdf_annot.cpp
@@ -225,9 +225,9 @@
     m_pPopupAnnot->SetOpenState(bOpenState);
 }
 
-absl::optional<CFX_FloatRect> CPDF_Annot::GetPopupAnnotRect() const {
+std::optional<CFX_FloatRect> CPDF_Annot::GetPopupAnnotRect() const {
   if (!m_pPopupAnnot)
-    return absl::nullopt;
+    return std::nullopt;
   return m_pPopupAnnot->GetRect();
 }
 
diff --git a/core/fpdfdoc/cpdf_annot.h b/core/fpdfdoc/cpdf_annot.h
index 4f8b2f8..5db98fd 100644
--- a/core/fpdfdoc/cpdf_annot.h
+++ b/core/fpdfdoc/cpdf_annot.h
@@ -12,6 +12,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fxcrt/bytestring.h"
@@ -19,7 +20,6 @@
 #include "core/fxcrt/maybe_owned.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_RenderDevice;
 class CPDF_Array;
@@ -99,7 +99,7 @@
   CPDF_Form* GetAPForm(CPDF_Page* pPage, AppearanceMode mode);
   void SetOpenState(bool bOpenState) { m_bOpenState = bOpenState; }
   void SetPopupAnnotOpenState(bool bOpenState);
-  absl::optional<CFX_FloatRect> GetPopupAnnotRect() const;
+  std::optional<CFX_FloatRect> GetPopupAnnotRect() const;
   void SetPopupAnnot(CPDF_Annot* pAnnot) { m_pPopupAnnot = pAnnot; }
 
  private:
diff --git a/core/fpdfdoc/cpdf_bafontmap.cpp b/core/fpdfdoc/cpdf_bafontmap.cpp
index f60e832..694778c 100644
--- a/core/fpdfdoc/cpdf_bafontmap.cpp
+++ b/core/fpdfdoc/cpdf_bafontmap.cpp
@@ -253,7 +253,7 @@
 
   CPDF_DefaultAppearance appearance(sDA);
   float font_size;
-  absl::optional<ByteString> font = appearance.GetFont(&font_size);
+  std::optional<ByteString> font = appearance.GetFont(&font_size);
   *sAlias = font.value_or(ByteString());
 
   RetainPtr<CPDF_Dictionary> pFontDict;
diff --git a/core/fpdfdoc/cpdf_defaultappearance.cpp b/core/fpdfdoc/cpdf_defaultappearance.cpp
index e3b91a9..0d8f85c 100644
--- a/core/fpdfdoc/cpdf_defaultappearance.cpp
+++ b/core/fpdfdoc/cpdf_defaultappearance.cpp
@@ -64,11 +64,11 @@
 
 CPDF_DefaultAppearance::~CPDF_DefaultAppearance() = default;
 
-absl::optional<ByteString> CPDF_DefaultAppearance::GetFont(
+std::optional<ByteString> CPDF_DefaultAppearance::GetFont(
     float* fFontSize) const {
   *fFontSize = 0.0f;
   if (m_csDA.IsEmpty())
-    return absl::nullopt;
+    return std::nullopt;
 
   ByteString csFontNameTag;
   CPDF_SimpleParser syntax(m_csDA.AsStringView().raw_span());
@@ -80,9 +80,9 @@
   return PDF_NameDecode(csFontNameTag.AsStringView());
 }
 
-absl::optional<CFX_Color> CPDF_DefaultAppearance::GetColor() const {
+std::optional<CFX_Color> CPDF_DefaultAppearance::GetColor() const {
   if (m_csDA.IsEmpty())
-    return absl::nullopt;
+    return std::nullopt;
 
   CPDF_SimpleParser syntax(m_csDA.AsStringView().raw_span());
   if (FindTagParamFromStart(&syntax, "g", 1)) {
@@ -102,14 +102,14 @@
     float k = StringToFloat(syntax.GetWord());
     return CFX_Color(CFX_Color::Type::kCMYK, c, m, y, k);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<CFX_Color::TypeAndARGB> CPDF_DefaultAppearance::GetColorARGB()
+std::optional<CFX_Color::TypeAndARGB> CPDF_DefaultAppearance::GetColorARGB()
     const {
-  absl::optional<CFX_Color> maybe_color = GetColor();
+  std::optional<CFX_Color> maybe_color = GetColor();
   if (!maybe_color.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   const CFX_Color& color = maybe_color.value();
   if (color.nColorType == CFX_Color::Type::kGray) {
diff --git a/core/fpdfdoc/cpdf_defaultappearance.h b/core/fpdfdoc/cpdf_defaultappearance.h
index 42389ec..2ec725c 100644
--- a/core/fpdfdoc/cpdf_defaultappearance.h
+++ b/core/fpdfdoc/cpdf_defaultappearance.h
@@ -7,9 +7,10 @@
 #ifndef CORE_FPDFDOC_CPDF_DEFAULTAPPEARANCE_H_
 #define CORE_FPDFDOC_CPDF_DEFAULTAPPEARANCE_H_
 
+#include <optional>
+
 #include "core/fxcrt/bytestring.h"
 #include "core/fxge/cfx_color.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_SimpleParser;
 
@@ -20,10 +21,10 @@
   CPDF_DefaultAppearance(const CPDF_DefaultAppearance& cDA);
   ~CPDF_DefaultAppearance();
 
-  absl::optional<ByteString> GetFont(float* fFontSize) const;
+  std::optional<ByteString> GetFont(float* fFontSize) const;
 
-  absl::optional<CFX_Color> GetColor() const;
-  absl::optional<CFX_Color::TypeAndARGB> GetColorARGB() const;
+  std::optional<CFX_Color> GetColor() const;
+  std::optional<CFX_Color::TypeAndARGB> GetColorARGB() const;
 
   static bool FindTagParamFromStartForTesting(CPDF_SimpleParser* parser,
                                               ByteStringView token,
diff --git a/core/fpdfdoc/cpdf_formcontrol.cpp b/core/fpdfdoc/cpdf_formcontrol.cpp
index 31bbdf3..929f3a9 100644
--- a/core/fpdfdoc/cpdf_formcontrol.cpp
+++ b/core/fpdfdoc/cpdf_formcontrol.cpp
@@ -192,10 +192,10 @@
   return m_pForm->GetDefaultAppearance();
 }
 
-absl::optional<WideString> CPDF_FormControl::GetDefaultControlFontName() const {
+std::optional<WideString> CPDF_FormControl::GetDefaultControlFontName() const {
   RetainPtr<CPDF_Font> pFont = GetDefaultControlFont();
   if (!pFont)
-    return absl::nullopt;
+    return std::nullopt;
 
   return WideString::FromDefANSI(pFont->GetBaseFontName().AsStringView());
 }
@@ -203,7 +203,7 @@
 RetainPtr<CPDF_Font> CPDF_FormControl::GetDefaultControlFont() const {
   float fFontSize;
   CPDF_DefaultAppearance cDA = GetDefaultAppearance();
-  absl::optional<ByteString> csFontNameTag = cDA.GetFont(&fFontSize);
+  std::optional<ByteString> csFontNameTag = cDA.GetFont(&fFontSize);
   if (!csFontNameTag.has_value() || csFontNameTag->IsEmpty())
     return nullptr;
 
diff --git a/core/fpdfdoc/cpdf_formcontrol.h b/core/fpdfdoc/cpdf_formcontrol.h
index 59eec21..0f11653 100644
--- a/core/fpdfdoc/cpdf_formcontrol.h
+++ b/core/fpdfdoc/cpdf_formcontrol.h
@@ -7,6 +7,8 @@
 #ifndef CORE_FPDFDOC_CPDF_FORMCONTROL_H_
 #define CORE_FPDFDOC_CPDF_FORMCONTROL_H_
 
+#include <optional>
+
 #include "constants/appearance.h"
 #include "core/fpdfdoc/cpdf_aaction.h"
 #include "core/fpdfdoc/cpdf_action.h"
@@ -22,7 +24,6 @@
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_color.h"
 #include "core/fxge/dib/fx_dib.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_RenderDevice;
 class CPDF_Dictionary;
@@ -92,7 +93,7 @@
   int GetTextPosition() const;
   CPDF_DefaultAppearance GetDefaultAppearance() const;
 
-  absl::optional<WideString> GetDefaultControlFontName() const;
+  std::optional<WideString> GetDefaultControlFontName() const;
   int GetControlAlignment() const;
 
   ByteString GetOnStateName() const;
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index bfcb797..83dd665 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -75,12 +75,12 @@
 }  // namespace
 
 // static
-absl::optional<FormFieldType> CPDF_FormField::IntToFormFieldType(int value) {
+std::optional<FormFieldType> CPDF_FormField::IntToFormFieldType(int value) {
   if (value >= static_cast<int>(FormFieldType::kUnknown) &&
       value < static_cast<int>(kFormFieldTypeCount)) {
     return static_cast<FormFieldType>(value);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // static
diff --git a/core/fpdfdoc/cpdf_formfield.h b/core/fpdfdoc/cpdf_formfield.h
index 118cdd9..fa7bf33 100644
--- a/core/fpdfdoc/cpdf_formfield.h
+++ b/core/fpdfdoc/cpdf_formfield.h
@@ -72,7 +72,7 @@
   CPDF_FormField(CPDF_InteractiveForm* pForm, RetainPtr<CPDF_Dictionary> pDict);
   ~CPDF_FormField();
 
-  static absl::optional<FormFieldType> IntToFormFieldType(int value);
+  static std::optional<FormFieldType> IntToFormFieldType(int value);
   static WideString GetFullNameForDict(const CPDF_Dictionary* pFieldDict);
   static RetainPtr<const CPDF_Object> GetFieldAttrForDict(
       const CPDF_Dictionary* pFieldDict,
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp
index abb58db..bff3182 100644
--- a/core/fpdfdoc/cpdf_generateap.cpp
+++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -931,7 +931,7 @@
   CPDF_DefaultAppearance appearance(DA);
 
   float fFontSize = 0;
-  absl::optional<ByteString> font = appearance.GetFont(&fFontSize);
+  std::optional<ByteString> font = appearance.GetFont(&fFontSize);
   if (!font.has_value())
     return;
 
diff --git a/core/fpdfdoc/cpdf_interactiveform.cpp b/core/fpdfdoc/cpdf_interactiveform.cpp
index de7fd71..f8b19db 100644
--- a/core/fpdfdoc/cpdf_interactiveform.cpp
+++ b/core/fpdfdoc/cpdf_interactiveform.cpp
@@ -6,6 +6,7 @@
 
 #include "core/fpdfdoc/cpdf_interactiveform.h"
 
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -31,7 +32,6 @@
 #include "core/fxcrt/fx_codepage.h"
 #include "core/fxcrt/stl_util.h"
 #include "core/fxge/fx_font.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/containers/contains.h"
 #include "third_party/base/numerics/safe_conversions.h"
@@ -688,7 +688,7 @@
   if (!pArray)
     return -1;
 
-  absl::optional<size_t> maybe_found = pArray->Find(pField->GetFieldDict());
+  std::optional<size_t> maybe_found = pArray->Find(pField->GetFieldDict());
   if (!maybe_found.has_value())
     return -1;
 
diff --git a/core/fpdfdoc/cpdf_nametree.cpp b/core/fpdfdoc/cpdf_nametree.cpp
index 95d540f..a745953 100644
--- a/core/fpdfdoc/cpdf_nametree.cpp
+++ b/core/fpdfdoc/cpdf_nametree.cpp
@@ -299,26 +299,26 @@
 // Find the `nTargetPairIndex` node in the tree with root `pNode`. `nLevel`
 // tracks the recursion level and `nCurPairIndex` tracks the progress towards
 // `nTargetPairIndex`.
-absl::optional<IndexSearchResult> SearchNameNodeByIndexInternal(
+std::optional<IndexSearchResult> SearchNameNodeByIndexInternal(
     CPDF_Dictionary* pNode,
     size_t nTargetPairIndex,
     int nLevel,
     size_t* nCurPairIndex) {
   if (nLevel > kNameTreeMaxRecursion)
-    return absl::nullopt;
+    return std::nullopt;
 
   RetainPtr<CPDF_Array> pNames = pNode->GetMutableArrayFor("Names");
   if (pNames) {
     size_t nCount = pNames->size() / 2;
     if (nTargetPairIndex >= *nCurPairIndex + nCount) {
       *nCurPairIndex += nCount;
-      return absl::nullopt;
+      return std::nullopt;
     }
 
     size_t index = 2 * (nTargetPairIndex - *nCurPairIndex);
     RetainPtr<CPDF_Object> value = pNames->GetMutableDirectObjectAt(index + 1);
     if (!value)
-      return absl::nullopt;
+      return std::nullopt;
 
     IndexSearchResult result;
     result.key = pNames->GetUnicodeTextAt(index);
@@ -330,23 +330,23 @@
 
   RetainPtr<CPDF_Array> pKids = pNode->GetMutableArrayFor("Kids");
   if (!pKids)
-    return absl::nullopt;
+    return std::nullopt;
 
   for (size_t i = 0; i < pKids->size(); i++) {
     RetainPtr<CPDF_Dictionary> pKid = pKids->GetMutableDictAt(i);
     if (!pKid)
       continue;
-    absl::optional<IndexSearchResult> result = SearchNameNodeByIndexInternal(
+    std::optional<IndexSearchResult> result = SearchNameNodeByIndexInternal(
         pKid.Get(), nTargetPairIndex, nLevel + 1, nCurPairIndex);
     if (result.has_value())
       return result;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 // Wrapper for SearchNameNodeByIndexInternal() so callers do not need to know
 // about the details.
-absl::optional<IndexSearchResult> SearchNameNodeByIndex(
+std::optional<IndexSearchResult> SearchNameNodeByIndex(
     CPDF_Dictionary* pNode,
     size_t nTargetPairIndex) {
   size_t nCurPairIndex = 0;
@@ -505,7 +505,7 @@
   // |name| into. We instead will find the leftmost leaf array in which to place
   // |name| and |pObj|.
   if (!pFind) {
-    absl::optional<IndexSearchResult> result =
+    std::optional<IndexSearchResult> result =
         SearchNameNodeByIndex(m_pRoot.Get(), 0);
     if (!result.has_value()) {
       // Give up if that fails too.
@@ -541,7 +541,7 @@
 }
 
 bool CPDF_NameTree::DeleteValueAndName(size_t nIndex) {
-  absl::optional<IndexSearchResult> result =
+  std::optional<IndexSearchResult> result =
       SearchNameNodeByIndex(m_pRoot.Get(), nIndex);
   if (!result) {
     // Fail if the tree does not contain |nIndex|.
@@ -562,7 +562,7 @@
 RetainPtr<CPDF_Object> CPDF_NameTree::LookupValueAndName(
     size_t nIndex,
     WideString* csName) const {
-  absl::optional<IndexSearchResult> result =
+  std::optional<IndexSearchResult> result =
       SearchNameNodeByIndex(m_pRoot.Get(), nIndex);
   if (!result) {
     csName->clear();
diff --git a/core/fpdfdoc/cpdf_pagelabel.cpp b/core/fpdfdoc/cpdf_pagelabel.cpp
index 2611936..73b2f56 100644
--- a/core/fpdfdoc/cpdf_pagelabel.cpp
+++ b/core/fpdfdoc/cpdf_pagelabel.cpp
@@ -81,20 +81,20 @@
 
 CPDF_PageLabel::~CPDF_PageLabel() = default;
 
-absl::optional<WideString> CPDF_PageLabel::GetLabel(int nPage) const {
+std::optional<WideString> CPDF_PageLabel::GetLabel(int nPage) const {
   if (!m_pDocument)
-    return absl::nullopt;
+    return std::nullopt;
 
   if (nPage < 0 || nPage >= m_pDocument->GetPageCount())
-    return absl::nullopt;
+    return std::nullopt;
 
   const CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
   if (!pPDFRoot)
-    return absl::nullopt;
+    return std::nullopt;
 
   RetainPtr<const CPDF_Dictionary> pLabels = pPDFRoot->GetDictFor("PageLabels");
   if (!pLabels)
-    return absl::nullopt;
+    return std::nullopt;
 
   CPDF_NumberTree numberTree(std::move(pLabels));
   RetainPtr<const CPDF_Object> pValue;
diff --git a/core/fpdfdoc/cpdf_pagelabel.h b/core/fpdfdoc/cpdf_pagelabel.h
index 05ec237..a428065 100644
--- a/core/fpdfdoc/cpdf_pagelabel.h
+++ b/core/fpdfdoc/cpdf_pagelabel.h
@@ -7,9 +7,10 @@
 #ifndef CORE_FPDFDOC_CPDF_PAGELABEL_H_
 #define CORE_FPDFDOC_CPDF_PAGELABEL_H_
 
+#include <optional>
+
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxcrt/widestring.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_Document;
 
@@ -18,7 +19,7 @@
   explicit CPDF_PageLabel(CPDF_Document* pDocument);
   ~CPDF_PageLabel();
 
-  absl::optional<WideString> GetLabel(int nPage) const;
+  std::optional<WideString> GetLabel(int nPage) const;
 
  private:
   UnownedPtr<CPDF_Document> const m_pDocument;
diff --git a/core/fpdfdoc/cpdf_structelement.cpp b/core/fpdfdoc/cpdf_structelement.cpp
index 18ca39e..1e5399f 100644
--- a/core/fpdfdoc/cpdf_structelement.cpp
+++ b/core/fpdfdoc/cpdf_structelement.cpp
@@ -56,17 +56,17 @@
   return m_pDict->GetUnicodeTextFor("T");
 }
 
-absl::optional<WideString> CPDF_StructElement::GetID() const {
+std::optional<WideString> CPDF_StructElement::GetID() const {
   RetainPtr<const CPDF_Object> obj = m_pDict->GetObjectFor("ID");
   if (!obj || !obj->IsString())
-    return absl::nullopt;
+    return std::nullopt;
   return obj->GetUnicodeText();
 }
 
-absl::optional<WideString> CPDF_StructElement::GetLang() const {
+std::optional<WideString> CPDF_StructElement::GetLang() const {
   RetainPtr<const CPDF_Object> obj = m_pDict->GetObjectFor("Lang");
   if (!obj || !obj->IsString())
-    return absl::nullopt;
+    return std::nullopt;
   return obj->GetUnicodeText();
 }
 
diff --git a/core/fpdfdoc/cpdf_structelement.h b/core/fpdfdoc/cpdf_structelement.h
index 95c3f9e..fe714db 100644
--- a/core/fpdfdoc/cpdf_structelement.h
+++ b/core/fpdfdoc/cpdf_structelement.h
@@ -7,12 +7,12 @@
 #ifndef CORE_FPDFDOC_CPDF_STRUCTELEMENT_H_
 #define CORE_FPDFDOC_CPDF_STRUCTELEMENT_H_
 
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_Dictionary;
 class CPDF_Object;
@@ -27,8 +27,8 @@
   WideString GetAltText() const;
   WideString GetActualText() const;
   WideString GetTitle() const;
-  absl::optional<WideString> GetID() const;
-  absl::optional<WideString> GetLang() const;
+  std::optional<WideString> GetID() const;
+  std::optional<WideString> GetLang() const;
   RetainPtr<const CPDF_Object> GetA() const;
   RetainPtr<const CPDF_Object> GetK() const;
 
diff --git a/core/fpdfdoc/cpdf_viewerpreferences.cpp b/core/fpdfdoc/cpdf_viewerpreferences.cpp
index e3f15f0..436f670 100644
--- a/core/fpdfdoc/cpdf_viewerpreferences.cpp
+++ b/core/fpdfdoc/cpdf_viewerpreferences.cpp
@@ -41,15 +41,15 @@
   return pDict ? pDict->GetByteStringFor("Duplex") : ByteString("None");
 }
 
-absl::optional<ByteString> CPDF_ViewerPreferences::GenericName(
+std::optional<ByteString> CPDF_ViewerPreferences::GenericName(
     const ByteString& bsKey) const {
   RetainPtr<const CPDF_Dictionary> pDict = GetViewerPreferences();
   if (!pDict)
-    return absl::nullopt;
+    return std::nullopt;
 
   RetainPtr<const CPDF_Name> pName = ToName(pDict->GetObjectFor(bsKey));
   if (!pName)
-    return absl::nullopt;
+    return std::nullopt;
 
   return pName->GetString();
 }
diff --git a/core/fpdfdoc/cpdf_viewerpreferences.h b/core/fpdfdoc/cpdf_viewerpreferences.h
index 3e17048..4fb86ce 100644
--- a/core/fpdfdoc/cpdf_viewerpreferences.h
+++ b/core/fpdfdoc/cpdf_viewerpreferences.h
@@ -9,10 +9,11 @@
 
 #include <stdint.h>
 
+#include <optional>
+
 #include "core/fxcrt/bytestring.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_Array;
 class CPDF_Dictionary;
@@ -30,7 +31,7 @@
   ByteString Duplex() const;
 
   // Gets the entry for |bsKey|.
-  absl::optional<ByteString> GenericName(const ByteString& bsKey) const;
+  std::optional<ByteString> GenericName(const ByteString& bsKey) const;
 
  private:
   RetainPtr<const CPDF_Dictionary> GetViewerPreferences() const;
diff --git a/core/fpdftext/cpdf_linkextract.cpp b/core/fpdftext/cpdf_linkextract.cpp
index 66a3dda..4f4c5a6 100644
--- a/core/fpdftext/cpdf_linkextract.cpp
+++ b/core/fpdftext/cpdf_linkextract.cpp
@@ -176,7 +176,7 @@
   }
 }
 
-absl::optional<CPDF_LinkExtract::Link> CPDF_LinkExtract::CheckWebLink(
+std::optional<CPDF_LinkExtract::Link> CPDF_LinkExtract::CheckWebLink(
     const WideString& strBeCheck) {
   static const wchar_t kHttpScheme[] = L"http";
   static const wchar_t kWWWAddrStart[] = L"www.";
@@ -227,7 +227,7 @@
     }
   }
 
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool CPDF_LinkExtract::CheckMailLink(WideString* str) {
@@ -311,9 +311,9 @@
                                    m_LinkArray[index].m_Count);
 }
 
-absl::optional<CPDF_LinkExtract::Range> CPDF_LinkExtract::GetTextRange(
+std::optional<CPDF_LinkExtract::Range> CPDF_LinkExtract::GetTextRange(
     size_t index) const {
   if (index >= m_LinkArray.size())
-    return absl::nullopt;
+    return std::nullopt;
   return m_LinkArray[index];
 }
diff --git a/core/fpdftext/cpdf_linkextract.h b/core/fpdftext/cpdf_linkextract.h
index 3f0fa61..87f1c18 100644
--- a/core/fpdftext/cpdf_linkextract.h
+++ b/core/fpdftext/cpdf_linkextract.h
@@ -10,12 +10,12 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxcrt/widestring.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_TextPage;
 
@@ -33,14 +33,14 @@
   size_t CountLinks() const { return m_LinkArray.size(); }
   WideString GetURL(size_t index) const;
   std::vector<CFX_FloatRect> GetRects(size_t index) const;
-  absl::optional<Range> GetTextRange(size_t index) const;
+  std::optional<Range> GetTextRange(size_t index) const;
 
  protected:
   struct Link : public Range {
     WideString m_strUrl;
   };
 
-  absl::optional<Link> CheckWebLink(const WideString& str);
+  std::optional<Link> CheckWebLink(const WideString& str);
   bool CheckMailLink(WideString* str);
 
   UnownedPtr<const CPDF_TextPage> const m_pTextPage;
diff --git a/core/fpdftext/cpdf_textpage.cpp b/core/fpdftext/cpdf_textpage.cpp
index 86bae9c..1d6aa77 100644
--- a/core/fpdftext/cpdf_textpage.cpp
+++ b/core/fpdftext/cpdf_textpage.cpp
@@ -606,7 +606,7 @@
 
 void CPDF_TextPage::AppendGeneratedCharacter(wchar_t unicode,
                                              const CFX_Matrix& formMatrix) {
-  absl::optional<CharInfo> pGenerateChar = GenerateCharInfo(unicode);
+  std::optional<CharInfo> pGenerateChar = GenerateCharInfo(unicode);
   if (!pGenerateChar.has_value())
     return;
 
@@ -976,7 +976,7 @@
       case GenerateCharacter::kNone:
         break;
       case GenerateCharacter::kSpace: {
-        absl::optional<CharInfo> pGenerateChar = GenerateCharInfo(L' ');
+        std::optional<CharInfo> pGenerateChar = GenerateCharInfo(L' ');
         if (pGenerateChar.has_value()) {
           if (!form_matrix.IsIdentity())
             pGenerateChar->m_Matrix = form_matrix;
@@ -1417,11 +1417,11 @@
   return false;
 }
 
-absl::optional<CPDF_TextPage::CharInfo> CPDF_TextPage::GenerateCharInfo(
+std::optional<CPDF_TextPage::CharInfo> CPDF_TextPage::GenerateCharInfo(
     wchar_t unicode) {
   const CharInfo* pPrevCharInfo = GetPrevCharInfo();
   if (!pPrevCharInfo)
-    return absl::nullopt;
+    return std::nullopt;
 
   CharInfo info;
   info.m_Index = m_TextBuf.GetLength();
diff --git a/core/fpdftext/cpdf_textpage.h b/core/fpdftext/cpdf_textpage.h
index 325e2a4..93c4080 100644
--- a/core/fpdftext/cpdf_textpage.h
+++ b/core/fpdftext/cpdf_textpage.h
@@ -11,6 +11,7 @@
 
 #include <deque>
 #include <functional>
+#include <optional>
 #include <vector>
 
 #include "core/fpdfapi/page/cpdf_pageobjectholder.h"
@@ -20,7 +21,6 @@
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxcrt/widestring.h"
 #include "core/fxcrt/widetext_buffer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_FormObject;
 class CPDF_Page;
@@ -124,7 +124,7 @@
   GenerateCharacter ProcessInsertObject(const CPDF_TextObject* pObj,
                                         const CFX_Matrix& formMatrix);
   const CharInfo* GetPrevCharInfo() const;
-  absl::optional<CharInfo> GenerateCharInfo(wchar_t unicode);
+  std::optional<CharInfo> GenerateCharInfo(wchar_t unicode);
   bool IsSameAsPreTextObject(CPDF_TextObject* pTextObj,
                              const CPDF_PageObjectHolder* pObjList,
                              CPDF_PageObjectHolder::const_iterator iter) const;
diff --git a/core/fpdftext/cpdf_textpagefind.cpp b/core/fpdftext/cpdf_textpagefind.cpp
index 92810ca..a26692c 100644
--- a/core/fpdftext/cpdf_textpagefind.cpp
+++ b/core/fpdftext/cpdf_textpagefind.cpp
@@ -91,14 +91,14 @@
   return wsLower;
 }
 
-absl::optional<WideString> ExtractSubString(const wchar_t* lpszFullString,
-                                            int iSubString) {
+std::optional<WideString> ExtractSubString(const wchar_t* lpszFullString,
+                                           int iSubString) {
   DCHECK(lpszFullString);
 
   while (iSubString--) {
     lpszFullString = wcschr(lpszFullString, L' ');
     if (!lpszFullString)
-      return absl::nullopt;
+      return std::nullopt;
 
     lpszFullString++;
     while (*lpszFullString == L' ')
@@ -109,7 +109,7 @@
   int nLen = lpchEnd ? static_cast<int>(lpchEnd - lpszFullString)
                      : static_cast<int>(wcslen(lpszFullString));
   if (nLen < 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   return WideString(lpszFullString, static_cast<size_t>(nLen));
 }
@@ -129,7 +129,7 @@
 
   int index = 0;
   while (true) {
-    absl::optional<WideString> word = ExtractSubString(findwhat.c_str(), index);
+    std::optional<WideString> word = ExtractSubString(findwhat.c_str(), index);
     if (!word.has_value())
       break;
 
@@ -176,7 +176,7 @@
     const CPDF_TextPage* pTextPage,
     const WideString& findwhat,
     const Options& options,
-    absl::optional<size_t> startPos) {
+    std::optional<size_t> startPos) {
   std::vector<WideString> findwhat_array =
       ExtractFindWhat(GetStringCase(findwhat, options.bMatchCase));
   auto find = pdfium::WrapUnique(
@@ -189,7 +189,7 @@
     const CPDF_TextPage* pTextPage,
     const std::vector<WideString>& findwhat_array,
     const Options& options,
-    absl::optional<size_t> startPos)
+    std::optional<size_t> startPos)
     : m_pTextPage(pTextPage),
       m_strText(GetStringCase(pTextPage->GetAllPageText(), options.bMatchCase)),
       m_csFindWhatArray(findwhat_array),
@@ -221,7 +221,7 @@
   }
 
   int nCount = fxcrt::CollectionSize<int>(m_csFindWhatArray);
-  absl::optional<size_t> nResultPos = 0;
+  std::optional<size_t> nResultPos = 0;
   bool bSpaceStart = false;
   for (int iWord = 0; iWord < nCount; iWord++) {
     WideString csWord = m_csFindWhatArray[iWord];
diff --git a/core/fpdftext/cpdf_textpagefind.h b/core/fpdftext/cpdf_textpagefind.h
index ee5c46e..fa0653d 100644
--- a/core/fpdftext/cpdf_textpagefind.h
+++ b/core/fpdftext/cpdf_textpagefind.h
@@ -10,12 +10,12 @@
 #include <stddef.h>
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxcrt/widestring.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_TextPage;
 
@@ -31,7 +31,7 @@
       const CPDF_TextPage* pTextPage,
       const WideString& findwhat,
       const Options& options,
-      absl::optional<size_t> startPos);
+      std::optional<size_t> startPos);
 
   ~CPDF_TextPageFind();
 
@@ -44,7 +44,7 @@
   CPDF_TextPageFind(const CPDF_TextPage* pTextPage,
                     const std::vector<WideString>& findwhat_array,
                     const Options& options,
-                    absl::optional<size_t> startPos);
+                    std::optional<size_t> startPos);
 
   // Should be called immediately after construction.
   bool FindFirst();
@@ -54,8 +54,8 @@
   UnownedPtr<const CPDF_TextPage> const m_pTextPage;
   const WideString m_strText;
   const std::vector<WideString> m_csFindWhatArray;
-  absl::optional<size_t> m_findNextStart;
-  absl::optional<size_t> m_findPreStart;
+  std::optional<size_t> m_findNextStart;
+  std::optional<size_t> m_findPreStart;
   int m_resStart = 0;
   int m_resEnd = -1;
   const Options m_options;
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
index 40a8163..1566038 100644
--- a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
+++ b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
@@ -229,7 +229,7 @@
     default:
       return BmpDecoder::Status::kFail;
   }
-  absl::optional<uint32_t> stride = fxge::CalculatePitch32(bit_counts_, width_);
+  std::optional<uint32_t> stride = fxge::CalculatePitch32(bit_counts_, width_);
   if (!stride.has_value())
     return BmpDecoder::Status::kFail;
 
diff --git a/core/fxcodec/jbig2/JBig2_TrdProc.cpp b/core/fxcodec/jbig2/JBig2_TrdProc.cpp
index 0ea171b..99865ef 100644
--- a/core/fxcodec/jbig2/JBig2_TrdProc.cpp
+++ b/core/fxcodec/jbig2/JBig2_TrdProc.cpp
@@ -7,6 +7,7 @@
 #include "core/fxcodec/jbig2/JBig2_TrdProc.h"
 
 #include <memory>
+#include <optional>
 
 #include "core/fxcodec/jbig2/JBig2_ArithDecoder.h"
 #include "core/fxcodec/jbig2/JBig2_ArithIntDecoder.h"
@@ -14,25 +15,24 @@
 #include "core/fxcodec/jbig2/JBig2_HuffmanDecoder.h"
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxcrt/maybe_owned.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
-absl::optional<uint32_t> CheckTRDDimension(uint32_t dimension, int32_t delta) {
+std::optional<uint32_t> CheckTRDDimension(uint32_t dimension, int32_t delta) {
   FX_SAFE_UINT32 result = dimension;
   result += delta;
   if (!result.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
   return result.ValueOrDie();
 }
 
-absl::optional<int32_t> CheckTRDReferenceDimension(int32_t dimension,
-                                                   uint32_t shift,
-                                                   int32_t offset) {
+std::optional<int32_t> CheckTRDReferenceDimension(int32_t dimension,
+                                                  uint32_t shift,
+                                                  int32_t offset) {
   FX_SAFE_INT32 result = offset;
   result += dimension >> shift;
   if (!result.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
   return result.ValueOrDie();
 }
 
@@ -159,14 +159,14 @@
         if (!IBOI)
           return nullptr;
 
-        absl::optional<uint32_t> WOI = CheckTRDDimension(IBOI->width(), RDWI);
-        absl::optional<uint32_t> HOI = CheckTRDDimension(IBOI->height(), RDHI);
+        std::optional<uint32_t> WOI = CheckTRDDimension(IBOI->width(), RDWI);
+        std::optional<uint32_t> HOI = CheckTRDDimension(IBOI->height(), RDHI);
         if (!WOI.has_value() || !HOI.has_value())
           return nullptr;
 
-        absl::optional<int32_t> GRREFERENCEDX =
+        std::optional<int32_t> GRREFERENCEDX =
             CheckTRDReferenceDimension(RDWI, 2, RDXI);
-        absl::optional<int32_t> GRREFERENCEDY =
+        std::optional<int32_t> GRREFERENCEDY =
             CheckTRDReferenceDimension(RDHI, 2, RDYI);
         if (!GRREFERENCEDX.has_value() || !GRREFERENCEDY.has_value())
           return nullptr;
@@ -339,14 +339,14 @@
         if (!IBOI)
           return nullptr;
 
-        absl::optional<uint32_t> WOI = CheckTRDDimension(IBOI->width(), RDWI);
-        absl::optional<uint32_t> HOI = CheckTRDDimension(IBOI->height(), RDHI);
+        std::optional<uint32_t> WOI = CheckTRDDimension(IBOI->width(), RDWI);
+        std::optional<uint32_t> HOI = CheckTRDDimension(IBOI->height(), RDHI);
         if (!WOI.has_value() || !HOI.has_value())
           return nullptr;
 
-        absl::optional<int32_t> GRREFERENCEDX =
+        std::optional<int32_t> GRREFERENCEDX =
             CheckTRDReferenceDimension(RDWI, 1, RDXI);
-        absl::optional<int32_t> GRREFERENCEDY =
+        std::optional<int32_t> GRREFERENCEDY =
             CheckTRDReferenceDimension(RDHI, 1, RDYI);
         if (!GRREFERENCEDX.has_value() || !GRREFERENCEDY.has_value())
           return nullptr;
diff --git a/core/fxcodec/jpeg/jpeg_progressive_decoder.cpp b/core/fxcodec/jpeg/jpeg_progressive_decoder.cpp
index d4d8839..ad09cc1 100644
--- a/core/fxcodec/jpeg/jpeg_progressive_decoder.cpp
+++ b/core/fxcodec/jpeg/jpeg_progressive_decoder.cpp
@@ -6,6 +6,7 @@
 
 #include "core/fxcodec/jpeg/jpeg_progressive_decoder.h"
 
+#include <optional>
 #include <utility>
 
 #include "core/fxcodec/cfx_codec_memory.h"
@@ -15,7 +16,6 @@
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/dib/fx_dib.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/memory/ptr_util.h"
 
diff --git a/core/fxcodec/jpeg/jpegmodule.cpp b/core/fxcodec/jpeg/jpegmodule.cpp
index 7daefac..3ac906d 100644
--- a/core/fxcodec/jpeg/jpegmodule.cpp
+++ b/core/fxcodec/jpeg/jpegmodule.cpp
@@ -11,6 +11,7 @@
 #include <string.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "build/build_config.h"
@@ -21,7 +22,6 @@
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/dib/fx_dib.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/check_op.h"
 
@@ -190,7 +190,7 @@
   m_bInited = true;
 
   if (setjmp(m_JmpBuf) == -1) {
-    absl::optional<size_t> known_bad_header_offset;
+    std::optional<size_t> known_bad_header_offset;
     if (bAcceptKnownBadHeader) {
       for (size_t offset : kKnownBadHeaderWithInvalidHeightByteOffsetStarts) {
         if (HasKnownBadHeaderWithInvalidHeight(offset)) {
@@ -393,11 +393,11 @@
 }
 
 // static
-absl::optional<JpegModule::ImageInfo> JpegModule::LoadInfo(
+std::optional<JpegModule::ImageInfo> JpegModule::LoadInfo(
     pdfium::span<const uint8_t> src_span) {
   ImageInfo info;
   if (!JpegLoadInfo(src_span, &info))
-    return absl::nullopt;
+    return std::nullopt;
 
   return info;
 }
diff --git a/core/fxcodec/jpeg/jpegmodule.h b/core/fxcodec/jpeg/jpegmodule.h
index ac54fa8..80dd406 100644
--- a/core/fxcodec/jpeg/jpegmodule.h
+++ b/core/fxcodec/jpeg/jpegmodule.h
@@ -10,9 +10,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
 #include "build/build_config.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 #if BUILDFLAG(IS_WIN)
@@ -42,7 +42,7 @@
       int nComps,
       bool ColorTransform);
 
-  static absl::optional<ImageInfo> LoadInfo(
+  static std::optional<ImageInfo> LoadInfo(
       pdfium::span<const uint8_t> src_span);
 
 #if BUILDFLAG(IS_WIN)
diff --git a/core/fxcodec/jpx/cjpx_decoder.cpp b/core/fxcodec/jpx/cjpx_decoder.cpp
index 2e7a72a..9fb1b4b 100644
--- a/core/fxcodec/jpx/cjpx_decoder.cpp
+++ b/core/fxcodec/jpx/cjpx_decoder.cpp
@@ -10,6 +10,7 @@
 
 #include <algorithm>
 #include <limits>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -17,7 +18,6 @@
 #include "core/fxcrt/fx_safe_types.h"
 #include "core/fxcrt/span_util.h"
 #include "core/fxge/calculate_pitch.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/memory/ptr_util.h"
 
 #if !defined(USE_SYSTEM_LIBOPENJPEG2)
@@ -60,19 +60,19 @@
   return stream;
 }
 
-absl::optional<OpjImageRgbData> alloc_rgb(size_t size) {
+std::optional<OpjImageRgbData> alloc_rgb(size_t size) {
   OpjImageRgbData data;
   data.r.reset(static_cast<int*>(opj_image_data_alloc(size)));
   if (!data.r)
-    return absl::nullopt;
+    return std::nullopt;
 
   data.g.reset(static_cast<int*>(opj_image_data_alloc(size)));
   if (!data.g)
-    return absl::nullopt;
+    return std::nullopt;
 
   data.b.reset(static_cast<int*>(opj_image_data_alloc(size)));
   if (!data.b)
-    return absl::nullopt;
+    return std::nullopt;
 
   return data;
 }
@@ -115,7 +115,7 @@
   if (!y || !cb || !cr)
     return;
 
-  absl::optional<OpjImageRgbData> data = alloc_rgb(max_size.ValueOrDie());
+  std::optional<OpjImageRgbData> data = alloc_rgb(max_size.ValueOrDie());
   if (!data.has_value())
     return;
 
@@ -180,7 +180,7 @@
   if (!y || !cb || !cr)
     return;
 
-  absl::optional<OpjImageRgbData> data = alloc_rgb(safe_size.ValueOrDie());
+  std::optional<OpjImageRgbData> data = alloc_rgb(safe_size.ValueOrDie());
   if (!data.has_value())
     return;
 
@@ -317,7 +317,7 @@
   if (!y || !cb || !cr)
     return;
 
-  absl::optional<OpjImageRgbData> data = alloc_rgb(max_size.ValueOrDie());
+  std::optional<OpjImageRgbData> data = alloc_rgb(max_size.ValueOrDie());
   if (!data.has_value())
     return;
 
@@ -524,7 +524,7 @@
     channel_count = 4;
   }
 
-  absl::optional<uint32_t> calculated_pitch =
+  std::optional<uint32_t> calculated_pitch =
       fxge::CalculatePitch32(8 * channel_count, m_Image->comps[0].w);
   if (!calculated_pitch.has_value() || pitch < calculated_pitch.value()) {
     return false;
diff --git a/core/fxcodec/progressive_decoder.cpp b/core/fxcodec/progressive_decoder.cpp
index feb6abb..669949e 100644
--- a/core/fxcodec/progressive_decoder.cpp
+++ b/core/fxcodec/progressive_decoder.cpp
@@ -684,7 +684,7 @@
 
   // Set to 0 to make CalculatePitchAndSize() calculate it.
   constexpr uint32_t kNoPitch = 0;
-  absl::optional<CFX_DIBitmap::PitchAndSize> needed_data =
+  std::optional<CFX_DIBitmap::PitchAndSize> needed_data =
       CFX_DIBitmap::CalculatePitchAndSize(m_SrcWidth, m_SrcHeight, format,
                                           kNoPitch);
   if (!needed_data.has_value()) {
diff --git a/core/fxcrt/bytestring.cpp b/core/fxcrt/bytestring.cpp
index 41d46e2..40b41b0 100644
--- a/core/fxcrt/bytestring.cpp
+++ b/core/fxcrt/bytestring.cpp
@@ -34,10 +34,10 @@
 
 constexpr char kTrimChars[] = "\x09\x0a\x0b\x0c\x0d\x20";
 
-absl::optional<size_t> FX_strpos(pdfium::span<const char> haystack,
-                                 pdfium::span<const char> needle) {
+std::optional<size_t> FX_strpos(pdfium::span<const char> haystack,
+                                pdfium::span<const char> needle) {
   if (needle.empty() || needle.size() > haystack.size()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // After `end_pos`, not enough characters remain in `haystack` for
   // a full match to occur.
@@ -48,7 +48,7 @@
       return haystack_pos;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
@@ -537,46 +537,46 @@
   return new_length;
 }
 
-absl::optional<size_t> ByteString::Find(char ch, size_t start) const {
+std::optional<size_t> ByteString::Find(char ch, size_t start) const {
   if (!m_pData)
-    return absl::nullopt;
+    return std::nullopt;
 
   if (!IsValidIndex(start))
-    return absl::nullopt;
+    return std::nullopt;
 
   const char* pStr = static_cast<const char*>(FXSYS_memchr(
       m_pData->m_String + start, ch, m_pData->m_nDataLength - start));
-  return pStr ? absl::optional<size_t>(
+  return pStr ? std::optional<size_t>(
                     static_cast<size_t>(pStr - m_pData->m_String))
-              : absl::nullopt;
+              : std::nullopt;
 }
 
-absl::optional<size_t> ByteString::Find(ByteStringView subStr,
-                                        size_t start) const {
+std::optional<size_t> ByteString::Find(ByteStringView subStr,
+                                       size_t start) const {
   if (!m_pData) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (!IsValidIndex(start)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<size_t> result =
+  std::optional<size_t> result =
       FX_strpos(m_pData->span().subspan(start), subStr.span());
   if (!result.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return start + result.value();
 }
 
-absl::optional<size_t> ByteString::ReverseFind(char ch) const {
+std::optional<size_t> ByteString::ReverseFind(char ch) const {
   if (!m_pData)
-    return absl::nullopt;
+    return std::nullopt;
 
   size_t nLength = m_pData->m_nDataLength;
   while (nLength--) {
     if (m_pData->m_String[nLength] == ch)
       return nLength;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void ByteString::MakeLower() {
@@ -638,7 +638,7 @@
     // Limit span lifetime.
     pdfium::span<char> search_span = m_pData->span();
     while (true) {
-      absl::optional<size_t> found = FX_strpos(search_span, pOld.span());
+      std::optional<size_t> found = FX_strpos(search_span, pOld.span());
       if (!found.has_value()) {
         break;
       }
diff --git a/core/fxcrt/bytestring.h b/core/fxcrt/bytestring.h
index f863087..6986674 100644
--- a/core/fxcrt/bytestring.h
+++ b/core/fxcrt/bytestring.h
@@ -15,13 +15,13 @@
 #include <functional>
 #include <iosfwd>
 #include <iterator>
+#include <optional>
 #include <utility>
 
 #include "core/fxcrt/fx_string_wrappers.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/string_data_template.h"
 #include "core/fxcrt/string_view_template.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/containers/span.h"
 
@@ -180,9 +180,9 @@
   ByteString First(size_t count) const;
   ByteString Last(size_t count) const;
 
-  absl::optional<size_t> Find(ByteStringView subStr, size_t start = 0) const;
-  absl::optional<size_t> Find(char ch, size_t start = 0) const;
-  absl::optional<size_t> ReverseFind(char ch) const;
+  std::optional<size_t> Find(ByteStringView subStr, size_t start = 0) const;
+  std::optional<size_t> Find(char ch, size_t start = 0) const;
+  std::optional<size_t> ReverseFind(char ch) const;
 
   bool Contains(ByteStringView lpszSub, size_t start = 0) const {
     return Find(lpszSub, start).has_value();
diff --git a/core/fxcrt/bytestring_unittest.cpp b/core/fxcrt/bytestring_unittest.cpp
index a66959e..ae6a02c 100644
--- a/core/fxcrt/bytestring_unittest.cpp
+++ b/core/fxcrt/bytestring_unittest.cpp
@@ -735,7 +735,7 @@
   EXPECT_FALSE(empty_string.Find('\0').has_value());
 
   ByteString single_string("a");
-  absl::optional<size_t> result = single_string.Find('a');
+  std::optional<size_t> result = single_string.Find('a');
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(0u, result.value());
   EXPECT_FALSE(single_string.Find('b').has_value());
@@ -783,7 +783,7 @@
   EXPECT_FALSE(empty_string.ReverseFind('\0').has_value());
 
   ByteString single_string("a");
-  absl::optional<size_t> result = single_string.ReverseFind('a');
+  std::optional<size_t> result = single_string.ReverseFind('a');
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(0u, result.value());
   EXPECT_FALSE(single_string.ReverseFind('b').has_value());
@@ -1313,7 +1313,7 @@
   EXPECT_FALSE(empty_string.Find('\0').has_value());
 
   ByteStringView single_string("a");
-  absl::optional<size_t> result = single_string.Find('a');
+  std::optional<size_t> result = single_string.Find('a');
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(0u, result.value());
   EXPECT_FALSE(single_string.Find('b').has_value());
diff --git a/core/fxcrt/css/cfx_csscomputedstyle.cpp b/core/fxcrt/css/cfx_csscomputedstyle.cpp
index 489eed1..cff50db 100644
--- a/core/fxcrt/css/cfx_csscomputedstyle.cpp
+++ b/core/fxcrt/css/cfx_csscomputedstyle.cpp
@@ -25,10 +25,10 @@
   return false;
 }
 
-absl::optional<WideString> CFX_CSSComputedStyle::GetLastFontFamily() const {
+std::optional<WideString> CFX_CSSComputedStyle::GetLastFontFamily() const {
   if (!m_InheritedData.m_pFontFamily ||
       m_InheritedData.m_pFontFamily->values().empty()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return m_InheritedData.m_pFontFamily->values()
diff --git a/core/fxcrt/css/cfx_csscomputedstyle.h b/core/fxcrt/css/cfx_csscomputedstyle.h
index 9e685c4..76b2430 100644
--- a/core/fxcrt/css/cfx_csscomputedstyle.h
+++ b/core/fxcrt/css/cfx_csscomputedstyle.h
@@ -7,6 +7,7 @@
 #ifndef CORE_FXCRT_CSS_CFX_CSSCOMPUTEDSTYLE_H_
 #define CORE_FXCRT_CSS_CFX_CSSCOMPUTEDSTYLE_H_
 
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/css/cfx_css.h"
@@ -15,7 +16,6 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/widestring.h"
 #include "core/fxge/dib/fx_dib.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_CSSValueList;
 
@@ -61,7 +61,7 @@
 
   CONSTRUCT_VIA_MAKE_RETAIN;
 
-  absl::optional<WideString> GetLastFontFamily() const;
+  std::optional<WideString> GetLastFontFamily() const;
   uint16_t GetFontWeight() const;
   CFX_CSSFontVariant GetFontVariant() const;
   CFX_CSSFontStyle GetFontStyle() const;
diff --git a/core/fxcrt/fx_string.h b/core/fxcrt/fx_string.h
index a73d587..c714eb3 100644
--- a/core/fxcrt/fx_string.h
+++ b/core/fxcrt/fx_string.h
@@ -39,7 +39,7 @@
   std::vector<StrType> result;
   StringViewTemplate<typename StrType::CharType> remaining(that.span());
   while (true) {
-    absl::optional<size_t> index = remaining.Find(ch);
+    std::optional<size_t> index = remaining.Find(ch);
     if (!index.has_value())
       break;
     result.emplace_back(remaining.First(index.value()));
diff --git a/core/fxcrt/string_view_template.h b/core/fxcrt/string_view_template.h
index 069b803..58b04e1 100644
--- a/core/fxcrt/string_view_template.h
+++ b/core/fxcrt/string_view_template.h
@@ -11,11 +11,11 @@
 
 #include <algorithm>
 #include <iterator>
+#include <optional>
 #include <type_traits>
 
 #include "core/fxcrt/fx_memcpy_wrappers.h"
 #include "core/fxcrt/fx_system.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 namespace fxcrt {
@@ -187,12 +187,11 @@
     return static_cast<CharType>(m_Span[index]);
   }
 
-  absl::optional<size_t> Find(CharType ch) const {
+  std::optional<size_t> Find(CharType ch) const {
     const auto* found = reinterpret_cast<const UnsignedType*>(FXSYS_chr(
         reinterpret_cast<const CharType*>(m_Span.data()), ch, m_Span.size()));
 
-    return found ? absl::optional<size_t>(found - m_Span.data())
-                 : absl::nullopt;
+    return found ? std::optional<size_t>(found - m_Span.data()) : std::nullopt;
   }
 
   bool Contains(CharType ch) const { return Find(ch).has_value(); }
diff --git a/core/fxcrt/widestring.cpp b/core/fxcrt/widestring.cpp
index 82358ef..132393f 100644
--- a/core/fxcrt/widestring.cpp
+++ b/core/fxcrt/widestring.cpp
@@ -54,10 +54,10 @@
 
 constexpr wchar_t kWideTrimChars[] = L"\x09\x0a\x0b\x0c\x0d\x20";
 
-absl::optional<size_t> FX_wcspos(pdfium::span<const wchar_t> haystack,
-                                 pdfium::span<const wchar_t> needle) {
+std::optional<size_t> FX_wcspos(pdfium::span<const wchar_t> haystack,
+                                pdfium::span<const wchar_t> needle) {
   if (needle.empty() || needle.size() > haystack.size()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   // After this `end_pos`, not enough characters remain in `haystack` for
   // a full match to occur.
@@ -68,11 +68,11 @@
       return haystack_pos;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<size_t> GuessSizeForVSWPrintf(const wchar_t* pFormat,
-                                             va_list argList) {
+std::optional<size_t> GuessSizeForVSWPrintf(const wchar_t* pFormat,
+                                            va_list argList) {
   size_t nMaxLen = 0;
   for (const wchar_t* pStr = pFormat; *pStr != 0; pStr++) {
     if (*pStr != '%' || *(pStr = pStr + 1) == '%') {
@@ -95,7 +95,7 @@
         ++pStr;
     }
     if (iWidth < 0 || iWidth > 128 * 1024)
-      return absl::nullopt;
+      return std::nullopt;
     uint32_t nWidth = static_cast<uint32_t>(iWidth);
     int iPrecision = 0;
     if (*pStr == '.') {
@@ -110,7 +110,7 @@
       }
     }
     if (iPrecision < 0 || iPrecision > 128 * 1024)
-      return absl::nullopt;
+      return std::nullopt;
     uint32_t nPrecision = static_cast<uint32_t>(iPrecision);
     int nModifier = 0;
     if (*pStr == L'I' && *(pStr + 1) == L'6' && *(pStr + 2) == L'4') {
@@ -265,11 +265,11 @@
 }
 
 // Returns string unless we ran out of space.
-absl::optional<WideString> TryVSWPrintf(size_t size,
-                                        const wchar_t* pFormat,
-                                        va_list argList) {
+std::optional<WideString> TryVSWPrintf(size_t size,
+                                       const wchar_t* pFormat,
+                                       va_list argList) {
   if (!size)
-    return absl::nullopt;
+    return std::nullopt;
 
   WideString str;
   {
@@ -287,7 +287,7 @@
 
     bool bSufficientBuffer = ret >= 0 || buffer[size - 1] == 0;
     if (!bSufficientBuffer)
-      return absl::nullopt;
+      return std::nullopt;
   }
   str.ReleaseBuffer(str.GetStringLength());
   return str;
@@ -381,7 +381,7 @@
 
   while (maxLen < 32 * 1024) {
     va_copy(argListCopy, argList);
-    absl::optional<WideString> ret =
+    std::optional<WideString> ret =
         TryVSWPrintf(static_cast<size_t>(maxLen), format, argListCopy);
     va_end(argListCopy);
     if (ret.has_value())
@@ -850,46 +850,46 @@
   return new_length;
 }
 
-absl::optional<size_t> WideString::Find(wchar_t ch, size_t start) const {
+std::optional<size_t> WideString::Find(wchar_t ch, size_t start) const {
   if (!m_pData)
-    return absl::nullopt;
+    return std::nullopt;
 
   if (!IsValidIndex(start))
-    return absl::nullopt;
+    return std::nullopt;
 
   const wchar_t* pStr = FXSYS_wmemchr(m_pData->m_String + start, ch,
                                       m_pData->m_nDataLength - start);
-  return pStr ? absl::optional<size_t>(
+  return pStr ? std::optional<size_t>(
                     static_cast<size_t>(pStr - m_pData->m_String))
-              : absl::nullopt;
+              : std::nullopt;
 }
 
-absl::optional<size_t> WideString::Find(WideStringView subStr,
-                                        size_t start) const {
+std::optional<size_t> WideString::Find(WideStringView subStr,
+                                       size_t start) const {
   if (!m_pData) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (!IsValidIndex(start)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
-  absl::optional<size_t> result =
+  std::optional<size_t> result =
       FX_wcspos(m_pData->span().subspan(start), subStr.span());
   if (!result.has_value()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return start + result.value();
 }
 
-absl::optional<size_t> WideString::ReverseFind(wchar_t ch) const {
+std::optional<size_t> WideString::ReverseFind(wchar_t ch) const {
   if (!m_pData)
-    return absl::nullopt;
+    return std::nullopt;
 
   size_t nLength = m_pData->m_nDataLength;
   while (nLength--) {
     if (m_pData->m_String[nLength] == ch)
       return nLength;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void WideString::MakeLower() {
@@ -951,7 +951,7 @@
     // Limit span lifetime.
     pdfium::span<const wchar_t> search_span = m_pData->span();
     while (true) {
-      absl::optional<size_t> found = FX_wcspos(search_span, pOld.span());
+      std::optional<size_t> found = FX_wcspos(search_span, pOld.span());
       if (!found.has_value()) {
         break;
       }
diff --git a/core/fxcrt/widestring.h b/core/fxcrt/widestring.h
index 543b195..5ae355c 100644
--- a/core/fxcrt/widestring.h
+++ b/core/fxcrt/widestring.h
@@ -15,12 +15,12 @@
 #include <functional>
 #include <iosfwd>
 #include <iterator>
+#include <optional>
 #include <utility>
 
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/string_data_template.h"
 #include "core/fxcrt/string_view_template.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/containers/span.h"
 
@@ -197,9 +197,9 @@
 
   int GetInteger() const;
 
-  absl::optional<size_t> Find(WideStringView subStr, size_t start = 0) const;
-  absl::optional<size_t> Find(wchar_t ch, size_t start = 0) const;
-  absl::optional<size_t> ReverseFind(wchar_t ch) const;
+  std::optional<size_t> Find(WideStringView subStr, size_t start = 0) const;
+  std::optional<size_t> Find(wchar_t ch, size_t start = 0) const;
+  std::optional<size_t> ReverseFind(wchar_t ch) const;
 
   bool Contains(WideStringView lpszSub, size_t start = 0) const {
     return Find(lpszSub, start).has_value();
diff --git a/core/fxcrt/widestring_unittest.cpp b/core/fxcrt/widestring_unittest.cpp
index f8e3b9a..90161c2 100644
--- a/core/fxcrt/widestring_unittest.cpp
+++ b/core/fxcrt/widestring_unittest.cpp
@@ -727,7 +727,7 @@
   EXPECT_FALSE(empty_string.Find(L'\0').has_value());
 
   WideString single_string(L"a");
-  absl::optional<size_t> result = single_string.Find(L'a');
+  std::optional<size_t> result = single_string.Find(L'a');
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(0u, result.value());
   EXPECT_FALSE(single_string.Find(L'b').has_value());
@@ -774,7 +774,7 @@
   EXPECT_FALSE(empty_string.ReverseFind(L'\0').has_value());
 
   WideString single_string(L"a");
-  absl::optional<size_t> result = single_string.ReverseFind(L'a');
+  std::optional<size_t> result = single_string.ReverseFind(L'a');
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(0u, result.value());
   EXPECT_FALSE(single_string.ReverseFind(L'b').has_value());
@@ -1630,7 +1630,7 @@
   EXPECT_FALSE(empty_string.Find(L'\0').has_value());
 
   WideStringView single_string(L"a");
-  absl::optional<size_t> result = single_string.Find(L'a');
+  std::optional<size_t> result = single_string.Find(L'a');
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(0u, result.value());
   EXPECT_FALSE(single_string.Find(L'b').has_value());
diff --git a/core/fxcrt/xml/cfx_xmlparser.cpp b/core/fxcrt/xml/cfx_xmlparser.cpp
index 3daa96d..7a69e49 100644
--- a/core/fxcrt/xml/cfx_xmlparser.cpp
+++ b/core/fxcrt/xml/cfx_xmlparser.cpp
@@ -515,7 +515,7 @@
         }
       }
     }
-    entity_start_ = absl::nullopt;
+    entity_start_ = std::nullopt;
   } else if (!entity_start_.has_value() && character == L'&') {
     entity_start_ = current_text_.size() - 1;
   }
@@ -533,7 +533,7 @@
 
 WideString CFX_XMLParser::GetTextData() {
   WideString ret(current_text_.data(), current_text_.size());
-  entity_start_ = absl::nullopt;
+  entity_start_ = std::nullopt;
   current_text_.clear();
   current_text_.reserve(kCurrentTextReserve);
   return ret;
diff --git a/core/fxcrt/xml/cfx_xmlparser.h b/core/fxcrt/xml/cfx_xmlparser.h
index 268c9f2..34f743b 100644
--- a/core/fxcrt/xml/cfx_xmlparser.h
+++ b/core/fxcrt/xml/cfx_xmlparser.h
@@ -8,12 +8,12 @@
 #define CORE_FXCRT_XML_CFX_XMLPARSER_H_
 
 #include <memory>
+#include <optional>
 
 #include "core/fxcrt/data_vector.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxcrt/widestring.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_SeekableStreamProxy;
 class CFX_XMLDocument;
@@ -58,7 +58,7 @@
   RetainPtr<CFX_SeekableStreamProxy> stream_;
   DataVector<wchar_t> current_text_;
   size_t xml_plane_size_ = 1024;
-  absl::optional<size_t> entity_start_;
+  std::optional<size_t> entity_start_;
 };
 
 #endif  // CORE_FXCRT_XML_CFX_XMLPARSER_H_
diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp
index cab97f0..3a2a627 100644
--- a/core/fxge/agg/fx_agg_driver.cpp
+++ b/core/fxge/agg/fx_agg_driver.cpp
@@ -1084,7 +1084,7 @@
     m_pClipRgn = std::make_unique<CFX_ClipRgn>(
         GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT));
   }
-  absl::optional<CFX_FloatRect> maybe_rectf = path.GetRect(pObject2Device);
+  std::optional<CFX_FloatRect> maybe_rectf = path.GetRect(pObject2Device);
   if (maybe_rectf.has_value()) {
     CFX_FloatRect& rectf = maybe_rectf.value();
     rectf.Intersect(
diff --git a/core/fxge/android/cfpf_skiafontmgr.cpp b/core/fxge/android/cfpf_skiafontmgr.cpp
index 13089d6..baa4e38 100644
--- a/core/fxge/android/cfpf_skiafontmgr.cpp
+++ b/core/fxge/android/cfpf_skiafontmgr.cpp
@@ -389,7 +389,7 @@
   }
 
   uint32_t charset = FPF_SKIACHARSET_Default;
-  absl::optional<std::array<uint32_t, 2>> code_page_range =
+  std::optional<std::array<uint32_t, 2>> code_page_range =
       face->GetOs2CodePageRange();
   if (code_page_range.has_value()) {
     if (code_page_range.value()[0] & (1 << 31)) {
@@ -398,7 +398,7 @@
     charset |= FPF_SkiaGetFaceCharset(code_page_range.value()[0]);
   }
 
-  absl::optional<std::array<uint8_t, 2>> panose = face->GetOs2Panose();
+  std::optional<std::array<uint8_t, 2>> panose = face->GetOs2Panose();
   if (panose.has_value() && panose.value()[0] == 2) {
     uint8_t serif = panose.value()[1];
     if ((serif > 1 && serif < 10) || serif > 13) {
diff --git a/core/fxge/calculate_pitch.cpp b/core/fxge/calculate_pitch.cpp
index 799e10e..14390b1 100644
--- a/core/fxge/calculate_pitch.cpp
+++ b/core/fxge/calculate_pitch.cpp
@@ -40,19 +40,19 @@
   return CalculatePitch32Safely(bpp, width).ValueOrDie();
 }
 
-absl::optional<uint32_t> CalculatePitch8(uint32_t bpc,
-                                         uint32_t components,
-                                         int width) {
+std::optional<uint32_t> CalculatePitch8(uint32_t bpc,
+                                        uint32_t components,
+                                        int width) {
   FX_SAFE_UINT32 pitch = CalculatePitch8Safely(bpc, components, width);
   if (!pitch.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
   return pitch.ValueOrDie();
 }
 
-absl::optional<uint32_t> CalculatePitch32(int bpp, int width) {
+std::optional<uint32_t> CalculatePitch32(int bpp, int width) {
   FX_SAFE_UINT32 pitch = CalculatePitch32Safely(bpp, width);
   if (!pitch.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
   return pitch.ValueOrDie();
 }
 
diff --git a/core/fxge/calculate_pitch.h b/core/fxge/calculate_pitch.h
index 1de7fdd..5aefc92 100644
--- a/core/fxge/calculate_pitch.h
+++ b/core/fxge/calculate_pitch.h
@@ -7,16 +7,16 @@
 
 #include <stdint.h>
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 namespace fxge {
 
 uint32_t CalculatePitch8OrDie(uint32_t bpc, uint32_t components, int width);
 uint32_t CalculatePitch32OrDie(int bpp, int width);
-absl::optional<uint32_t> CalculatePitch8(uint32_t bpc,
-                                         uint32_t components,
-                                         int width);
-absl::optional<uint32_t> CalculatePitch32(int bpp, int width);
+std::optional<uint32_t> CalculatePitch8(uint32_t bpc,
+                                        uint32_t components,
+                                        int width);
+std::optional<uint32_t> CalculatePitch32(int bpp, int width);
 
 }  // namespace fxge
 
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index c2ed0af..7d9cd0f 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -399,10 +399,10 @@
   return pdfium::base::checked_cast<size_t>(length);
 }
 
-absl::optional<std::array<uint32_t, 4>> CFX_Face::GetOs2UnicodeRange() {
+std::optional<std::array<uint32_t, 4>> CFX_Face::GetOs2UnicodeRange() {
   auto* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
   if (!os2) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return std::array<uint32_t, 4>{static_cast<uint32_t>(os2->ulUnicodeRange1),
                                  static_cast<uint32_t>(os2->ulUnicodeRange2),
@@ -410,19 +410,19 @@
                                  static_cast<uint32_t>(os2->ulUnicodeRange4)};
 }
 
-absl::optional<std::array<uint32_t, 2>> CFX_Face::GetOs2CodePageRange() {
+std::optional<std::array<uint32_t, 2>> CFX_Face::GetOs2CodePageRange() {
   auto* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
   if (!os2) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return std::array<uint32_t, 2>{static_cast<uint32_t>(os2->ulCodePageRange1),
                                  static_cast<uint32_t>(os2->ulCodePageRange2)};
 }
 
-absl::optional<std::array<uint8_t, 2>> CFX_Face::GetOs2Panose() {
+std::optional<std::array<uint8_t, 2>> CFX_Face::GetOs2Panose() {
   auto* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(GetRec(), FT_SFNT_OS2));
   if (!os2) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return std::array<uint8_t, 2>{os2->panose[0], os2->panose[1]};
 }
@@ -736,9 +736,9 @@
   return GetRec()->charmap;
 }
 
-absl::optional<fxge::FontEncoding> CFX_Face::GetCurrentCharMapEncoding() const {
+std::optional<fxge::FontEncoding> CFX_Face::GetCurrentCharMapEncoding() const {
   if (!GetRec()->charmap) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return ToFontEncoding(GetRec()->charmap->encoding);
 }
diff --git a/core/fxge/cfx_face.h b/core/fxge/cfx_face.h
index aa0bb93..ce8d693 100644
--- a/core/fxge/cfx_face.h
+++ b/core/fxge/cfx_face.h
@@ -9,6 +9,7 @@
 
 #include <array>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "build/build_config.h"
@@ -17,7 +18,6 @@
 #include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/freetype/fx_freetype.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 namespace fxge {
@@ -77,9 +77,9 @@
   // it is large enough to hold the data.
   size_t GetSfntTable(uint32_t table, pdfium::span<uint8_t> buffer);
 
-  absl::optional<std::array<uint32_t, 4>> GetOs2UnicodeRange();
-  absl::optional<std::array<uint32_t, 2>> GetOs2CodePageRange();
-  absl::optional<std::array<uint8_t, 2>> GetOs2Panose();
+  std::optional<std::array<uint32_t, 4>> GetOs2UnicodeRange();
+  std::optional<std::array<uint32_t, 2>> GetOs2CodePageRange();
+  std::optional<std::array<uint8_t, 2>> GetOs2Panose();
 
   int GetGlyphCount() const;
   // TODO(crbug.com/pdfium/2037): Can this method be private?
@@ -108,7 +108,7 @@
   std::vector<CharCodeAndIndex> GetCharCodesAndIndices(char32_t max_char);
 
   CharMap GetCurrentCharMap() const;
-  absl::optional<fxge::FontEncoding> GetCurrentCharMapEncoding() const;
+  std::optional<fxge::FontEncoding> GetCurrentCharMapEncoding() const;
   int GetCharMapPlatformIdByIndex(size_t index) const;
   int GetCharMapEncodingIdByIndex(size_t index) const;
   fxge::FontEncoding GetCharMapEncodingByIndex(size_t index) const;
diff --git a/core/fxge/cfx_folderfontinfo.cpp b/core/fxge/cfx_folderfontinfo.cpp
index af8691a..3a4f41b 100644
--- a/core/fxge/cfx_folderfontinfo.cpp
+++ b/core/fxge/cfx_folderfontinfo.cpp
@@ -51,7 +51,7 @@
 
 bool FindFamilyNameMatch(ByteStringView family_name,
                          const ByteString& installed_font_name) {
-  absl::optional<size_t> result = installed_font_name.Find(family_name, 0);
+  std::optional<size_t> result = installed_font_name.Find(family_name, 0);
   if (!result.has_value())
     return false;
 
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index 8a8ce47..ff97860 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -288,24 +288,24 @@
   return NormalizeFontMetric(m_Face->GetDescender(), m_Face->GetUnitsPerEm());
 }
 
-absl::optional<FX_RECT> CFX_Font::GetGlyphBBox(uint32_t glyph_index) {
+std::optional<FX_RECT> CFX_Font::GetGlyphBBox(uint32_t glyph_index) {
   if (!m_Face)
-    return absl::nullopt;
+    return std::nullopt;
 
   if (m_Face->IsTricky()) {
     int error = FT_Set_Char_Size(m_Face->GetRec(), 0, 1000 * 64, 72, 72);
     if (error)
-      return absl::nullopt;
+      return std::nullopt;
 
     error = FT_Load_Glyph(m_Face->GetRec(), glyph_index,
                           FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
     if (error)
-      return absl::nullopt;
+      return std::nullopt;
 
     FT_Glyph glyph;
     error = FT_Get_Glyph(m_Face->GetRec()->glyph, &glyph);
     if (error)
-      return absl::nullopt;
+      return std::nullopt;
 
     FT_BBox cbox;
     FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &cbox);
@@ -318,12 +318,12 @@
         std::max(result.bottom, static_cast<int>(m_Face->GetDescender()));
     FT_Done_Glyph(glyph);
     if (FT_Set_Pixel_Sizes(m_Face->GetRec(), 0, 64) != 0)
-      return absl::nullopt;
+      return std::nullopt;
     return result;
   }
   constexpr int kFlag = FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
   if (FT_Load_Glyph(m_Face->GetRec(), glyph_index, kFlag) != 0)
-    return absl::nullopt;
+    return std::nullopt;
   int em = m_Face->GetUnitsPerEm();
   return ScaledFXRectFromFTPos(FXFT_Get_Glyph_HoriBearingX(m_Face->GetRec()),
                                FXFT_Get_Glyph_HoriBearingY(m_Face->GetRec()) -
@@ -415,14 +415,14 @@
   return ByteString();
 }
 
-absl::optional<FX_RECT> CFX_Font::GetRawBBox() const {
+std::optional<FX_RECT> CFX_Font::GetRawBBox() const {
   if (!m_Face)
-    return absl::nullopt;
+    return std::nullopt;
   return m_Face->GetBBox();
 }
 
-absl::optional<FX_RECT> CFX_Font::GetBBox() const {
-  absl::optional<FX_RECT> result = GetRawBBox();
+std::optional<FX_RECT> CFX_Font::GetBBox() const {
+  std::optional<FX_RECT> result = GetRawBBox();
   if (!result.has_value())
     return result;
 
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h
index e78114a..6db9a1f 100644
--- a/core/fxge/cfx_font.h
+++ b/core/fxge/cfx_font.h
@@ -10,6 +10,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
 #include "build/build_config.h"
 #include "core/fxcrt/bytestring.h"
@@ -20,7 +21,6 @@
 #include "core/fxcrt/unowned_ptr_exclusion.h"
 #include "core/fxge/cfx_face.h"
 #include "core/fxge/freetype/fx_freetype.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 #if defined(PDF_USE_SKIA)
@@ -104,7 +104,7 @@
   int GetGlyphWidth(uint32_t glyph_index, int dest_width, int weight) const;
   int GetAscent() const;
   int GetDescent() const;
-  absl::optional<FX_RECT> GetGlyphBBox(uint32_t glyph_index);
+  std::optional<FX_RECT> GetGlyphBBox(uint32_t glyph_index);
   bool IsItalic() const;
   bool IsBold() const;
   bool IsFixedWidth() const;
@@ -116,10 +116,10 @@
   bool IsTTFont() const;
 
   // Raw bounding box.
-  absl::optional<FX_RECT> GetRawBBox() const;
+  std::optional<FX_RECT> GetRawBBox() const;
 
   // Bounding box adjusted for font units.
-  absl::optional<FX_RECT> GetBBox() const;
+  std::optional<FX_RECT> GetBBox() const;
 
   bool IsEmbedded() const { return m_bEmbedded; }
   FontType GetFontType() const { return m_FontType; }
diff --git a/core/fxge/cfx_fontmapper.cpp b/core/fxge/cfx_fontmapper.cpp
index 6640360..91197ea 100644
--- a/core/fxge/cfx_fontmapper.cpp
+++ b/core/fxge/cfx_fontmapper.cpp
@@ -373,7 +373,7 @@
 bool IsNarrowFontName(const ByteString& name) {
   static const char kNarrowFonts[][10] = {"Narrow", "Condensed"};
   for (const char* font : kNarrowFonts) {
-    absl::optional<size_t> pos = name.Find(font);
+    std::optional<size_t> pos = name.Find(font);
     if (pos.has_value() && pos.value() != 0)
       return true;
   }
@@ -595,7 +595,7 @@
   bool has_comma = false;
   bool has_hyphen = false;
   {
-    absl::optional<size_t> pos = subst_name.Find(",");
+    std::optional<size_t> pos = subst_name.Find(",");
     if (pos.has_value()) {
       family = subst_name.First(pos.value());
       GetStandardFontName(&family);
@@ -619,7 +619,7 @@
     base_font = kNumStandardFonts;
     nStyle = FXFONT_NORMAL;
     if (!has_comma) {
-      absl::optional<size_t> pos = family.ReverseFind('-');
+      std::optional<size_t> pos = family.ReverseFind('-');
       if (pos.has_value()) {
         style = family.Last(family.GetLength() - (pos.value() + 1));
         family = family.First(pos.value());
@@ -773,22 +773,22 @@
 }
 
 #if BUILDFLAG(IS_WIN)
-absl::optional<ByteString> CFX_FontMapper::InstalledFontNameStartingWith(
+std::optional<ByteString> CFX_FontMapper::InstalledFontNameStartingWith(
     const ByteString& name) const {
   for (const auto& thisname : m_InstalledTTFonts) {
     if (thisname.First(name.GetLength()) == name)
       return thisname;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<ByteString> CFX_FontMapper::LocalizedFontNameStartingWith(
+std::optional<ByteString> CFX_FontMapper::LocalizedFontNameStartingWith(
     const ByteString& name) const {
   for (const auto& thispair : m_LocalizedTTFonts) {
     if (thispair.first.First(name.GetLength()) == name)
       return thispair.second;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 #endif  // BUILDFLAG(IS_WIN)
 
@@ -878,8 +878,8 @@
 }
 
 // static
-absl::optional<CFX_FontMapper::StandardFont>
-CFX_FontMapper::GetStandardFontName(ByteString* name) {
+std::optional<CFX_FontMapper::StandardFont> CFX_FontMapper::GetStandardFontName(
+    ByteString* name) {
   const auto* end = std::end(kAltFontNames);
   const auto* found =
       std::lower_bound(std::begin(kAltFontNames), end, name->c_str(),
@@ -887,7 +887,7 @@
                          return FXSYS_stricmp(element.m_pName, name) < 0;
                        });
   if (found == end || FXSYS_stricmp(found->m_pName, name->c_str()))
-    return absl::nullopt;
+    return std::nullopt;
 
   *name = kBase14FontNames[static_cast<size_t>(found->m_Index)];
   return found->m_Index;
diff --git a/core/fxge/cfx_fontmapper.h b/core/fxge/cfx_fontmapper.h
index ecbec60..9c73ef6 100644
--- a/core/fxge/cfx_fontmapper.h
+++ b/core/fxge/cfx_fontmapper.h
@@ -8,6 +8,7 @@
 #define CORE_FXGE_CFX_FONTMAPPER_H_
 
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -17,7 +18,6 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_face.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #ifdef PDF_ENABLE_XFA
 #include "core/fxcrt/fixed_size_data_vector.h"
@@ -51,7 +51,7 @@
   explicit CFX_FontMapper(CFX_FontMgr* mgr);
   ~CFX_FontMapper();
 
-  static absl::optional<StandardFont> GetStandardFontName(ByteString* name);
+  static std::optional<StandardFont> GetStandardFontName(ByteString* name);
   static bool IsStandardFontName(const ByteString& name);
   static bool IsSymbolicFont(StandardFont font);
   static bool IsFixedFont(StandardFont font);
@@ -80,9 +80,9 @@
   bool HasLocalizedFont(ByteStringView name) const;
 
 #if BUILDFLAG(IS_WIN)
-  absl::optional<ByteString> InstalledFontNameStartingWith(
+  std::optional<ByteString> InstalledFontNameStartingWith(
       const ByteString& name) const;
-  absl::optional<ByteString> LocalizedFontNameStartingWith(
+  std::optional<ByteString> LocalizedFontNameStartingWith(
       const ByteString& name) const;
 #endif  // BUILDFLAG(IS_WIN)
 
diff --git a/core/fxge/cfx_path.cpp b/core/fxge/cfx_path.cpp
index 525409e..5412ae1 100644
--- a/core/fxge/cfx_path.cpp
+++ b/core/fxge/cfx_path.cpp
@@ -400,8 +400,7 @@
   return IsRectImpl(m_Points);
 }
 
-absl::optional<CFX_FloatRect> CFX_Path::GetRect(
-    const CFX_Matrix* matrix) const {
+std::optional<CFX_FloatRect> CFX_Path::GetRect(const CFX_Matrix* matrix) const {
   bool do_normalize = PathPointsNeedNormalization(m_Points);
   std::vector<Point> normalized;
   if (do_normalize)
@@ -410,13 +409,13 @@
 
   if (!matrix) {
     if (!IsRectImpl(path_points))
-      return absl::nullopt;
+      return std::nullopt;
 
     return CreateRectFromPoints(path_points[0].m_Point, path_points[2].m_Point);
   }
 
   if (!IsRectPreTransform(path_points))
-    return absl::nullopt;
+    return std::nullopt;
 
   CFX_PointF points[5];
   for (size_t i = 0; i < path_points.size(); ++i) {
@@ -425,11 +424,11 @@
     if (i == 0)
       continue;
     if (XYBothNotEqual(points[i], points[i - 1]))
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   if (XYBothNotEqual(points[0], points[3]))
-    return absl::nullopt;
+    return std::nullopt;
 
   return CreateRectFromPoints(points[0], points[2]);
 }
diff --git a/core/fxge/cfx_path.h b/core/fxge/cfx_path.h
index 5c6199c..d107bb3 100644
--- a/core/fxge/cfx_path.h
+++ b/core/fxge/cfx_path.h
@@ -9,11 +9,11 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_Path {
  public:
@@ -56,7 +56,7 @@
 
   void Transform(const CFX_Matrix& matrix);
   bool IsRect() const;
-  absl::optional<CFX_FloatRect> GetRect(const CFX_Matrix* matrix) const;
+  std::optional<CFX_FloatRect> GetRect(const CFX_Matrix* matrix) const;
 
   void Append(const CFX_Path& src, const CFX_Matrix* matrix);
   void AppendFloatRect(const CFX_FloatRect& rect);
diff --git a/core/fxge/cfx_path_unittest.cpp b/core/fxge/cfx_path_unittest.cpp
index 4ccb1c2..bae99ad 100644
--- a/core/fxge/cfx_path_unittest.cpp
+++ b/core/fxge/cfx_path_unittest.cpp
@@ -12,7 +12,7 @@
   path.AppendRect(/*left=*/1, /*bottom=*/2, /*right=*/3, /*top=*/5);
   EXPECT_EQ(5u, path.GetPoints().size());
   EXPECT_TRUE(path.IsRect());
-  absl::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
+  std::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
   ASSERT_TRUE(rect.has_value());
   EXPECT_EQ(CFX_FloatRect(1, 2, 3, 5), rect.value());
   EXPECT_EQ(CFX_FloatRect(1, 2, 3, 5), path.GetBoundingBox());
@@ -71,7 +71,7 @@
 
   const CFX_Matrix kShearMatrix(1, 2, 0, 1, 0, 0);
   EXPECT_TRUE(path.IsRect());
-  absl::optional<CFX_FloatRect> rect = path.GetRect(&kShearMatrix);
+  std::optional<CFX_FloatRect> rect = path.GetRect(&kShearMatrix);
   EXPECT_FALSE(rect.has_value());
   EXPECT_EQ(CFX_FloatRect(1, 2, 3, 5), path.GetBoundingBox());
 
@@ -148,7 +148,7 @@
   EXPECT_EQ(CFX_Path::Point::Type::kLine, path.GetType(3));
   EXPECT_FALSE(path.IsClosingFigure(3));
   EXPECT_TRUE(path.IsRect());
-  absl::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
+  std::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
   ASSERT_TRUE(rect.has_value());
   EXPECT_EQ(CFX_FloatRect(0, 0, 1, 1), rect.value());
 
@@ -200,7 +200,7 @@
   EXPECT_EQ(CFX_Path::Point::Type::kLine, path.GetType(4));
   EXPECT_FALSE(path.IsClosingFigure(4));
   EXPECT_TRUE(path.IsRect());
-  absl::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
+  std::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
   ASSERT_TRUE(rect.has_value());
   EXPECT_EQ(CFX_FloatRect(0, 0, 2, 1), rect.value());
 
@@ -223,7 +223,7 @@
   path.AppendPoint({0, 1}, CFX_Path::Point::Type::kLine);
   path.AppendPoint({0, 0}, CFX_Path::Point::Type::kLine);
   EXPECT_TRUE(path.IsRect());
-  absl::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
+  std::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
   ASSERT_TRUE(rect.has_value());
   EXPECT_EQ(CFX_FloatRect(0, 0, 2, 1), rect.value());
   EXPECT_EQ(CFX_FloatRect(0, 0, 2, 1), path.GetBoundingBox());
@@ -257,7 +257,7 @@
   path.AppendPoint({0, 1}, CFX_Path::Point::Type::kLine);
   path.AppendPoint({0, 0.1f}, CFX_Path::Point::Type::kLine);
   EXPECT_FALSE(path.IsRect());
-  absl::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
+  std::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
   EXPECT_FALSE(rect.has_value());
   EXPECT_EQ(CFX_FloatRect(0, 0, 2, 1), path.GetBoundingBox());
 
@@ -342,7 +342,7 @@
   path.AppendPoint({0, 1}, CFX_Path::Point::Type::kLine);
   path.AppendPoint({0, 0}, CFX_Path::Point::Type::kLine);
   EXPECT_TRUE(path.IsRect());
-  absl::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
+  std::optional<CFX_FloatRect> rect = path.GetRect(nullptr);
   ASSERT_TRUE(rect.has_value());
   EXPECT_EQ(CFX_FloatRect(0, 0, 0, 1), rect.value());
   EXPECT_EQ(CFX_FloatRect(0, 0, 0, 1), path.GetBoundingBox());
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index 3d8f428..1776461 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -635,7 +635,7 @@
   }
 
   if (stroke_alpha == 0 && !fill_options.rect_aa) {
-    absl::optional<CFX_FloatRect> maybe_rect_f = path.GetRect(pObject2Device);
+    std::optional<CFX_FloatRect> maybe_rect_f = path.GetRect(pObject2Device);
     if (maybe_rect_f.has_value()) {
       const CFX_FloatRect& rect_f = maybe_rect_f.value();
       FX_RECT rect_i = rect_f.GetOuterRect();
@@ -1150,8 +1150,7 @@
       if (!glyph.m_pGlyph)
         continue;
 
-      absl::optional<CFX_Point> point =
-          glyph.GetOrigin({pixel_left, pixel_top});
+      std::optional<CFX_Point> point = glyph.GetOrigin({pixel_left, pixel_top});
       if (!point.has_value())
         continue;
 
@@ -1187,7 +1186,7 @@
     if (!glyph.m_pGlyph)
       continue;
 
-    absl::optional<CFX_Point> point = glyph.GetOrigin({pixel_left, pixel_top});
+    std::optional<CFX_Point> point = glyph.GetOrigin({pixel_left, pixel_top});
     if (!point.has_value())
       continue;
 
diff --git a/core/fxge/dib/cfx_dibbase.cpp b/core/fxge/dib/cfx_dibbase.cpp
index cd00ede..8601275 100644
--- a/core/fxge/dib/cfx_dibbase.cpp
+++ b/core/fxge/dib/cfx_dibbase.cpp
@@ -672,7 +672,7 @@
       }
     }
   } else {
-    absl::optional<uint32_t> copy_len = fxge::CalculatePitch8(
+    std::optional<uint32_t> copy_len = fxge::CalculatePitch8(
         pNewBitmap->GetBPP(), /*components=*/1, pNewBitmap->GetWidth());
     if (!copy_len.has_value()) {
       return nullptr;
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index 01a3351..ec91d70 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -44,7 +44,7 @@
   m_Height = 0;
   m_Pitch = 0;
 
-  absl::optional<PitchAndSize> pitch_size =
+  std::optional<PitchAndSize> pitch_size =
       CalculatePitchAndSize(width, height, format, pitch);
   if (!pitch_size.has_value())
     return false;
@@ -499,35 +499,35 @@
 }
 
 // static
-absl::optional<CFX_DIBitmap::PitchAndSize> CFX_DIBitmap::CalculatePitchAndSize(
+std::optional<CFX_DIBitmap::PitchAndSize> CFX_DIBitmap::CalculatePitchAndSize(
     int width,
     int height,
     FXDIB_Format format,
     uint32_t pitch) {
   if (width <= 0 || height <= 0) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   int bpp = GetBppFromFormat(format);
   if (!bpp) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   if (pitch == 0) {
-    absl::optional<uint32_t> pitch32 = fxge::CalculatePitch32(bpp, width);
+    std::optional<uint32_t> pitch32 = fxge::CalculatePitch32(bpp, width);
     if (!pitch32.has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     pitch = pitch32.value();
   } else {
-    absl::optional<uint32_t> actual_pitch =
+    std::optional<uint32_t> actual_pitch =
         fxge::CalculatePitch8(bpp, /*components=*/1, width);
     if (!actual_pitch.has_value() || pitch < actual_pitch.value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
   FX_SAFE_UINT32 safe_size = pitch;
   safe_size *= height;
   if (!safe_size.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
 
   return PitchAndSize{pitch, safe_size.ValueOrDie()};
 }
diff --git a/core/fxge/dib/cfx_dibitmap.h b/core/fxge/dib/cfx_dibitmap.h
index 3651432..c1444d1 100644
--- a/core/fxge/dib/cfx_dibitmap.h
+++ b/core/fxge/dib/cfx_dibitmap.h
@@ -7,12 +7,13 @@
 #ifndef CORE_FXGE_DIB_CFX_DIBITMAP_H_
 #define CORE_FXGE_DIB_CFX_DIBITMAP_H_
 
+#include <optional>
+
 #include "core/fxcrt/fx_memory_wrappers.h"
 #include "core/fxcrt/maybe_owned.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/dib/cfx_dibbase.h"
 #include "core/fxge/dib/fx_dib.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 class CFX_DIBitmap final : public CFX_DIBBase {
@@ -123,10 +124,10 @@
   // If |pitch| is non-zero, then that be used as the actual pitch.
   // The actual pitch will be used to calculate the size.
   // Returns the calculated pitch and size on success, or nullopt on failure.
-  static absl::optional<PitchAndSize> CalculatePitchAndSize(int width,
-                                                            int height,
-                                                            FXDIB_Format format,
-                                                            uint32_t pitch);
+  static std::optional<PitchAndSize> CalculatePitchAndSize(int width,
+                                                           int height,
+                                                           FXDIB_Format format,
+                                                           uint32_t pitch);
 
 #if defined(PDF_USE_SKIA)
   // Converts to un-pre-multiplied alpha if necessary.
diff --git a/core/fxge/dib/cfx_dibitmap_unittest.cpp b/core/fxge/dib/cfx_dibitmap_unittest.cpp
index 2b5f549..5473ce0 100644
--- a/core/fxge/dib/cfx_dibitmap_unittest.cpp
+++ b/core/fxge/dib/cfx_dibitmap_unittest.cpp
@@ -28,7 +28,7 @@
 
 TEST(CFX_DIBitmap, CalculatePitchAndSizeGood) {
   // Simple case with no provided pitch.
-  absl::optional<CFX_DIBitmap::PitchAndSize> result =
+  std::optional<CFX_DIBitmap::PitchAndSize> result =
       CFX_DIBitmap::CalculatePitchAndSize(100, 200, FXDIB_Format::kArgb, 0);
   ASSERT_TRUE(result.has_value());
   EXPECT_EQ(400u, result.value().pitch);
@@ -98,7 +98,7 @@
 
 TEST(CFX_DIBitmap, CalculatePitchAndSizeBoundary) {
   // Test boundary condition for pitch overflow.
-  absl::optional<CFX_DIBitmap::PitchAndSize> result =
+  std::optional<CFX_DIBitmap::PitchAndSize> result =
       CFX_DIBitmap::CalculatePitchAndSize(536870908, 4, FXDIB_Format::k8bppRgb,
                                           0);
   ASSERT_TRUE(result);
diff --git a/core/fxge/dib/cstretchengine.cpp b/core/fxge/dib/cstretchengine.cpp
index 5590612..ff64646 100644
--- a/core/fxge/dib/cstretchengine.cpp
+++ b/core/fxge/dib/cstretchengine.cpp
@@ -203,7 +203,7 @@
     DCHECK_EQ(m_SrcBpp, GetBppFromFormat(FXDIB_Format::kArgb));
   }
 
-  absl::optional<uint32_t> maybe_size =
+  std::optional<uint32_t> maybe_size =
       fxge::CalculatePitch32(m_DestBpp, clip_rect.Width());
   if (!maybe_size.has_value())
     return;
diff --git a/core/fxge/fx_font.cpp b/core/fxge/fx_font.cpp
index 887629b..c5d7076 100644
--- a/core/fxge/fx_font.cpp
+++ b/core/fxge/fx_font.cpp
@@ -42,7 +42,7 @@
     if (!glyph.m_pGlyph)
       continue;
 
-    absl::optional<CFX_Point> point = glyph.GetOrigin({0, 0});
+    std::optional<CFX_Point> point = glyph.GetOrigin({0, 0});
     if (!point.has_value())
       continue;
 
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index 1e6e71b..73e18ca 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -1028,7 +1028,7 @@
 
   SkPath skClipPath;
   if (path.GetPoints().size() == 5 || path.GetPoints().size() == 4) {
-    absl::optional<CFX_FloatRect> maybe_rectf = path.GetRect(&deviceMatrix);
+    std::optional<CFX_FloatRect> maybe_rectf = path.GetRect(&deviceMatrix);
     if (maybe_rectf.has_value()) {
       CFX_FloatRect& rectf = maybe_rectf.value();
       rectf.Intersect(CFX_FloatRect(0, 0,
diff --git a/core/fxge/text_glyph_pos.cpp b/core/fxge/text_glyph_pos.cpp
index d887d08..b821f91 100644
--- a/core/fxge/text_glyph_pos.cpp
+++ b/core/fxge/text_glyph_pos.cpp
@@ -15,19 +15,19 @@
 
 TextGlyphPos::~TextGlyphPos() = default;
 
-absl::optional<CFX_Point> TextGlyphPos::GetOrigin(
+std::optional<CFX_Point> TextGlyphPos::GetOrigin(
     const CFX_Point& offset) const {
   FX_SAFE_INT32 left = m_Origin.x;
   left += m_pGlyph->left();
   left -= offset.x;
   if (!left.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
 
   FX_SAFE_INT32 top = m_Origin.y;
   top -= m_pGlyph->top();
   top -= offset.y;
   if (!top.IsValid())
-    return absl::nullopt;
+    return std::nullopt;
 
   return CFX_Point(left.ValueOrDie(), top.ValueOrDie());
 }
diff --git a/core/fxge/text_glyph_pos.h b/core/fxge/text_glyph_pos.h
index 36935d8..97ba35c 100644
--- a/core/fxge/text_glyph_pos.h
+++ b/core/fxge/text_glyph_pos.h
@@ -7,10 +7,10 @@
 #ifndef CORE_FXGE_TEXT_GLYPH_POS_H_
 #define CORE_FXGE_TEXT_GLYPH_POS_H_
 
-#include "core/fxcrt/fx_coordinates.h"
+#include <optional>
 
+#include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_GlyphBitmap;
 
@@ -20,7 +20,7 @@
   TextGlyphPos(const TextGlyphPos&);
   ~TextGlyphPos();
 
-  absl::optional<CFX_Point> GetOrigin(const CFX_Point& offset) const;
+  std::optional<CFX_Point> GetOrigin(const CFX_Point& offset) const;
 
   UnownedPtr<const CFX_GlyphBitmap> m_pGlyph;
   CFX_Point m_Origin;
diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp
index cb9e069..b536730 100644
--- a/core/fxge/win32/cfx_psrenderer.cpp
+++ b/core/fxge/win32/cfx_psrenderer.cpp
@@ -39,17 +39,17 @@
 
 namespace {
 
-absl::optional<ByteString> GenerateType42SfntData(
+std::optional<ByteString> GenerateType42SfntData(
     const ByteString& psname,
     pdfium::span<const uint8_t> font_data) {
   if (font_data.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   // Per Type 42 font spec.
   constexpr size_t kMaxSfntStringSize = 65535;
   if (font_data.size() > kMaxSfntStringSize) {
     // TODO(thestig): Fonts that are too big need to be written out in sections.
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Each byte is written as 2 ASCIIHex characters, so really 64 chars per line.
@@ -170,7 +170,7 @@
   const ByteString psname = font->GetPsName();
   DCHECK(!psname.IsEmpty());
 
-  absl::optional<ByteString> sfnt_data =
+  std::optional<ByteString> sfnt_data =
       GenerateType42SfntData(psname, font->GetFontSpan());
   if (!sfnt_data.has_value())
     return ByteString();
@@ -195,7 +195,7 @@
 
   UnownedPtr<CFX_Font> const font;
   const uint32_t glyph_index;
-  absl::optional<std::array<float, 4>> adjust_matrix;
+  std::optional<std::array<float, 4>> adjust_matrix;
 };
 
 CFX_PSRenderer::FaxCompressResult::FaxCompressResult() = default;
@@ -578,7 +578,7 @@
     uint8_t* output_buf = nullptr;
     size_t output_size = 0;
     bool output_buf_is_owned = true;
-    absl::optional<PSCompressResult> compress_result;
+    std::optional<PSCompressResult> compress_result;
     ByteString filter;
     if ((m_Level.value() == RenderingLevel::kLevel2 || options.bLossy) &&
         m_pEncoderIface->pJpegEncodeFunc(bitmap, &output_buf, &output_size)) {
@@ -870,10 +870,10 @@
   return result;
 }
 
-absl::optional<CFX_PSRenderer::PSCompressResult> CFX_PSRenderer::PSCompressData(
+std::optional<CFX_PSRenderer::PSCompressResult> CFX_PSRenderer::PSCompressData(
     pdfium::span<const uint8_t> src_span) const {
   if (src_span.size() < 1024)
-    return absl::nullopt;
+    return std::nullopt;
 
   DataVector<uint8_t> (*encode_func)(pdfium::span<const uint8_t> src_span);
   ByteString filter;
@@ -888,7 +888,7 @@
 
   DataVector<uint8_t> decode_result = encode_func(src_span);
   if (decode_result.size() == 0 || decode_result.size() >= src_span.size())
-    return absl::nullopt;
+    return std::nullopt;
 
   PSCompressResult result;
   result.data = std::move(decode_result);
@@ -921,7 +921,7 @@
 }
 
 // static
-absl::optional<ByteString> CFX_PSRenderer::GenerateType42SfntDataForTesting(
+std::optional<ByteString> CFX_PSRenderer::GenerateType42SfntDataForTesting(
     const ByteString& psname,
     pdfium::span<const uint8_t> font_data) {
   return GenerateType42SfntData(psname, font_data);
diff --git a/core/fxge/win32/cfx_psrenderer.h b/core/fxge/win32/cfx_psrenderer.h
index c79802e..87ce8c4 100644
--- a/core/fxge/win32/cfx_psrenderer.h
+++ b/core/fxge/win32/cfx_psrenderer.h
@@ -11,6 +11,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <sstream>
 #include <vector>
 
@@ -23,7 +24,6 @@
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_graphstatedata.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 class CFX_DIBBase;
@@ -99,7 +99,7 @@
                 float font_size,
                 uint32_t color);
 
-  static absl::optional<ByteString> GenerateType42SfntDataForTesting(
+  static std::optional<ByteString> GenerateType42SfntDataForTesting(
       const ByteString& psname,
       pdfium::span<const uint8_t> font_data);
 
@@ -157,7 +157,7 @@
                             float font_size,
                             fxcrt::ostringstream& buf);
   FaxCompressResult FaxCompressData(RetainPtr<const CFX_DIBBase> src) const;
-  absl::optional<PSCompressResult> PSCompressData(
+  std::optional<PSCompressResult> PSCompressData(
       pdfium::span<const uint8_t> src_span) const;
   void WritePreambleString(ByteStringView str);
   void WritePSBinary(pdfium::span<const uint8_t> data);
@@ -167,7 +167,7 @@
   bool m_bInited = false;
   bool m_bGraphStateSet = false;
   bool m_bColorSet = false;
-  absl::optional<RenderingLevel> m_Level;
+  std::optional<RenderingLevel> m_Level;
   uint32_t m_LastColor = 0;
   FX_RECT m_ClipBox;
   CFX_GraphStateData m_CurGraphState;
diff --git a/core/fxge/win32/cfx_psrenderer_unittest.cpp b/core/fxge/win32/cfx_psrenderer_unittest.cpp
index 2112a26..44674e7 100644
--- a/core/fxge/win32/cfx_psrenderer_unittest.cpp
+++ b/core/fxge/win32/cfx_psrenderer_unittest.cpp
@@ -4,6 +4,7 @@
 
 #include "core/fxge/win32/cfx_psrenderer.h"
 
+#include <optional>
 #include <utility>
 
 #include "core/fxcrt/bytestring.h"
@@ -15,7 +16,6 @@
 #include "core/fxge/dib/fx_dib.h"
 #include "core/fxge/win32/cfx_psfonttracker.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 namespace {
@@ -43,7 +43,7 @@
 }  // namespace
 
 TEST(PSRendererTest, GenerateType42SfntData) {
-  absl::optional<ByteString> result;
+  std::optional<ByteString> result;
 
   result = CFX_PSRenderer::GenerateType42SfntDataForTesting("empty", {});
   EXPECT_FALSE(result.has_value());
diff --git a/core/fxge/win32/cgdi_device_driver.cpp b/core/fxge/win32/cgdi_device_driver.cpp
index b959be4..6c0433b 100644
--- a/core/fxge/win32/cgdi_device_driver.cpp
+++ b/core/fxge/win32/cgdi_device_driver.cpp
@@ -713,7 +713,7 @@
     const CFX_Path& path,
     const CFX_Matrix* pMatrix,
     const CFX_FillRenderOptions& fill_options) {
-  absl::optional<CFX_FloatRect> maybe_rectf = path.GetRect(pMatrix);
+  std::optional<CFX_FloatRect> maybe_rectf = path.GetRect(pMatrix);
   if (maybe_rectf.has_value()) {
     FX_RECT rect = maybe_rectf.value().GetOuterRect();
     // Can easily apply base clip to protect against wildly large rectangular
diff --git a/core/fxge/win32/cgdi_device_driver.h b/core/fxge/win32/cgdi_device_driver.h
index 644a2a4..fe6415f 100644
--- a/core/fxge/win32/cgdi_device_driver.h
+++ b/core/fxge/win32/cgdi_device_driver.h
@@ -9,9 +9,10 @@
 
 #include <windows.h>
 
+#include <optional>
+
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/renderdevicedriver_iface.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_DIBBase;
 
@@ -76,7 +77,7 @@
   int m_nBitsPerPixel;
   const DeviceType m_DeviceType;
   int m_RenderCaps;
-  absl::optional<FX_RECT> m_BaseClipBox;
+  std::optional<FX_RECT> m_BaseClipBox;
 };
 
 #endif  // CORE_FXGE_WIN32_CGDI_DEVICE_DRIVER_H_
diff --git a/core/fxge/win32/cgdi_plus_ext.cpp b/core/fxge/win32/cgdi_plus_ext.cpp
index 1ea1836..e8bc88d 100644
--- a/core/fxge/win32/cgdi_plus_ext.cpp
+++ b/core/fxge/win32/cgdi_plus_ext.cpp
@@ -394,7 +394,7 @@
   return pPen;
 }
 
-absl::optional<std::pair<size_t, size_t>> IsSmallTriangle(
+std::optional<std::pair<size_t, size_t>> IsSmallTriangle(
     pdfium::span<const Gdiplus::PointF> points,
     const CFX_Matrix* pMatrix) {
   static constexpr size_t kPairs[3][2] = {{1, 2}, {0, 2}, {0, 1}};
@@ -414,7 +414,7 @@
     if (distance_square < 2.25f)
       return std::make_pair(i, pair1);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 class GpStream final : public IStream {
diff --git a/core/fxge/win32/cwin32_platform.cpp b/core/fxge/win32/cwin32_platform.cpp
index 50d1d75..50aae40 100644
--- a/core/fxge/win32/cwin32_platform.cpp
+++ b/core/fxge/win32/cwin32_platform.cpp
@@ -208,12 +208,12 @@
   if (!m_pMapper)
     return name;
 
-  absl::optional<ByteString> maybe_installed =
+  std::optional<ByteString> maybe_installed =
       m_pMapper->InstalledFontNameStartingWith(name);
   if (maybe_installed.has_value())
     return maybe_installed.value();
 
-  absl::optional<ByteString> maybe_localized =
+  std::optional<ByteString> maybe_localized =
       m_pMapper->LocalizedFontNameStartingWith(name);
   if (maybe_localized.has_value())
     return maybe_localized.value();
diff --git a/fpdfsdk/cpdfsdk_appstream.cpp b/fpdfsdk/cpdfsdk_appstream.cpp
index d89fb80..c9d7758 100644
--- a/fpdfsdk/cpdfsdk_appstream.cpp
+++ b/fpdfsdk/cpdfsdk_appstream.cpp
@@ -1098,9 +1098,9 @@
   pImageDict->SetNewFor<CPDF_String>("Name", name, false);
 }
 
-absl::optional<CheckStyle> CheckStyleFromCaption(const WideString& caption) {
+std::optional<CheckStyle> CheckStyleFromCaption(const WideString& caption) {
   if (caption.IsEmpty())
-    return absl::nullopt;
+    return std::nullopt;
 
   // Character values are ZapfDingbats encodings of named glyphs.
   switch (caption[0]) {
@@ -1117,7 +1117,7 @@
     case L'u':
       return CheckStyle::kDiamond;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
@@ -1186,12 +1186,12 @@
 
   CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
   CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
-  absl::optional<CFX_Color> color = da.GetColor();
+  std::optional<CFX_Color> color = da.GetColor();
   CFX_Color crText = color.value_or(CFX_Color(CFX_Color::Type::kGray, 0));
 
   float fFontSize;
   ByteString csNameTag;
-  absl::optional<ByteString> font = da.GetFont(&fFontSize);
+  std::optional<ByteString> font = da.GetFont(&fFontSize);
   if (font.has_value())
     csNameTag = font.value();
   else
@@ -1337,7 +1337,7 @@
 
   CFX_FloatRect rcWindow = widget_->GetRotatedRect();
   CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
-  absl::optional<CFX_Color> color = pControl->GetDefaultAppearance().GetColor();
+  std::optional<CFX_Color> color = pControl->GetDefaultAppearance().GetColor();
   CFX_Color crText = color.value_or(CFX_Color());
 
   CheckStyle nStyle = CheckStyleFromCaption(pControl->GetNormalCaption())
@@ -1416,7 +1416,7 @@
 
   CFX_FloatRect rcWindow = widget_->GetRotatedRect();
   CFX_FloatRect rcClient = rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
-  absl::optional<CFX_Color> color = pControl->GetDefaultAppearance().GetColor();
+  std::optional<CFX_Color> color = pControl->GetDefaultAppearance().GetColor();
   CFX_Color crText = color.value_or(CFX_Color());
   CheckStyle nStyle = CheckStyleFromCaption(pControl->GetNormalCaption())
                           .value_or(CheckStyle::kCircle);
@@ -1502,7 +1502,7 @@
     widget_->SetAppStateOff();
 }
 
-void CPDFSDK_AppStream::SetAsComboBox(absl::optional<WideString> sValue) {
+void CPDFSDK_AppStream::SetAsComboBox(std::optional<WideString> sValue) {
   CPDF_FormControl* pControl = widget_->GetFormControl();
   CPDF_FormField* pField = pControl->GetField();
   fxcrt::ostringstream sBody;
@@ -1654,7 +1654,7 @@
         ByteString());
 }
 
-void CPDFSDK_AppStream::SetAsTextField(absl::optional<WideString> sValue) {
+void CPDFSDK_AppStream::SetAsTextField(std::optional<WideString> sValue) {
   CPDF_FormControl* pControl = widget_->GetFormControl();
   CPDF_FormField* pField = pControl->GetField();
   fxcrt::ostringstream sBody;
diff --git a/fpdfsdk/cpdfsdk_appstream.h b/fpdfsdk/cpdfsdk_appstream.h
index d3cc07c..e0a5277 100644
--- a/fpdfsdk/cpdfsdk_appstream.h
+++ b/fpdfsdk/cpdfsdk_appstream.h
@@ -7,10 +7,11 @@
 #ifndef FPDFSDK_CPDFSDK_APPSTREAM_H_
 #define FPDFSDK_CPDFSDK_APPSTREAM_H_
 
+#include <optional>
+
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDFSDK_Widget;
 class CPDF_Dictionary;
@@ -24,9 +25,9 @@
   void SetAsPushButton();
   void SetAsCheckBox();
   void SetAsRadioButton();
-  void SetAsComboBox(absl::optional<WideString> sValue);
+  void SetAsComboBox(std::optional<WideString> sValue);
   void SetAsListBox();
-  void SetAsTextField(absl::optional<WideString> sValue);
+  void SetAsTextField(std::optional<WideString> sValue);
 
  private:
   void AddImage(const ByteString& sAPType, const CPDF_Stream* pImage);
diff --git a/fpdfsdk/cpdfsdk_baannot.cpp b/fpdfsdk/cpdfsdk_baannot.cpp
index c5d33d6..54e5f9c 100644
--- a/fpdfsdk/cpdfsdk_baannot.cpp
+++ b/fpdfsdk/cpdfsdk_baannot.cpp
@@ -6,6 +6,7 @@
 
 #include "fpdfsdk/cpdfsdk_baannot.h"
 
+#include <optional>
 #include <vector>
 
 #include "constants/annotation_common.h"
@@ -23,7 +24,6 @@
 #include "core/fxge/cfx_drawutils.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/containers/contains.h"
 
@@ -228,7 +228,7 @@
   std::vector<CFX_FloatRect> rects;
   rects.push_back(GetRect());
 
-  absl::optional<CFX_FloatRect> annot_rect = m_pAnnot->GetPopupAnnotRect();
+  std::optional<CFX_FloatRect> annot_rect = m_pAnnot->GetPopupAnnotRect();
   if (annot_rect.has_value())
     rects.push_back(annot_rect.value());
 
diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.cpp b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
index a063f16..e3798fc 100644
--- a/fpdfsdk/cpdfsdk_formfillenvironment.cpp
+++ b/fpdfsdk/cpdfsdk_formfillenvironment.cpp
@@ -408,7 +408,7 @@
   CPDFSDK_Widget* pWidget = ToCPDFSDKWidget(pAnnot.Get());
   DCHECK(pWidget);
 
-  absl::optional<WideString> sValue =
+  std::optional<WideString> sValue =
       m_pInteractiveForm->OnFormat(pWidget->GetFormField());
   if (!pAnnot)
     return;
diff --git a/fpdfsdk/cpdfsdk_interactiveform.cpp b/fpdfsdk/cpdfsdk_interactiveform.cpp
index 021124f..37c088c 100644
--- a/fpdfsdk/cpdfsdk_interactiveform.cpp
+++ b/fpdfsdk/cpdfsdk_interactiveform.cpp
@@ -281,16 +281,16 @@
     IJS_Runtime::ScopedEventContext pContext(pRuntime);
     pContext->OnField_Calculate(pFormField, pField, &sValue, &bRC);
 
-    absl::optional<IJS_Runtime::JS_Error> err = pContext->RunScript(csJS);
+    std::optional<IJS_Runtime::JS_Error> err = pContext->RunScript(csJS);
     if (!err.has_value() && bRC && sValue != sOldValue)
       pField->SetValue(sValue, NotificationOption::kNotify);
   }
 }
 
-absl::optional<WideString> CPDFSDK_InteractiveForm::OnFormat(
+std::optional<WideString> CPDFSDK_InteractiveForm::OnFormat(
     CPDF_FormField* pFormField) {
   if (!m_pFormFillEnv->IsJSPlatformPresent())
-    return absl::nullopt;
+    return std::nullopt;
 
   WideString sValue = pFormField->GetValue();
   IJS_Runtime* pRuntime = m_pFormFillEnv->GetIJSRuntime();
@@ -309,18 +309,18 @@
       if (!script.IsEmpty()) {
         IJS_Runtime::ScopedEventContext pContext(pRuntime);
         pContext->OnField_Format(pFormField, &sValue);
-        absl::optional<IJS_Runtime::JS_Error> err = pContext->RunScript(script);
+        std::optional<IJS_Runtime::JS_Error> err = pContext->RunScript(script);
         if (!err.has_value())
           return sValue;
       }
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void CPDFSDK_InteractiveForm::ResetFieldAppearance(
     CPDF_FormField* pFormField,
-    absl::optional<WideString> sValue) {
+    std::optional<WideString> sValue) {
   for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
     CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
     DCHECK(pFormCtrl);
@@ -554,7 +554,7 @@
     return;
 
   OnCalculate(pField);
-  ResetFieldAppearance(pField, absl::nullopt);
+  ResetFieldAppearance(pField, std::nullopt);
   UpdateField(pField);
 }
 
diff --git a/fpdfsdk/cpdfsdk_interactiveform.h b/fpdfsdk/cpdfsdk_interactiveform.h
index 223e3d4..d2f54e1 100644
--- a/fpdfsdk/cpdfsdk_interactiveform.h
+++ b/fpdfsdk/cpdfsdk_interactiveform.h
@@ -10,6 +10,7 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "core/fpdfdoc/cpdf_action.h"
@@ -17,7 +18,6 @@
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/dib/fx_dib.h"
 #include "fpdfsdk/cpdfsdk_widget.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_Dictionary;
 class CPDF_FormControl;
@@ -58,10 +58,10 @@
   bool OnKeyStrokeCommit(CPDF_FormField* pFormField, const WideString& csValue);
   bool OnValidate(CPDF_FormField* pFormField, const WideString& csValue);
   void OnCalculate(CPDF_FormField* pFormField);
-  absl::optional<WideString> OnFormat(CPDF_FormField* pFormField);
+  std::optional<WideString> OnFormat(CPDF_FormField* pFormField);
 
   void ResetFieldAppearance(CPDF_FormField* pFormField,
-                            absl::optional<WideString> sValue);
+                            std::optional<WideString> sValue);
   void UpdateField(CPDF_FormField* pFormField);
 
   bool DoAction_Hide(const CPDF_Action& action);
diff --git a/fpdfsdk/cpdfsdk_pageview.cpp b/fpdfsdk/cpdfsdk_pageview.cpp
index 1bbaeeb..41d62c5 100644
--- a/fpdfsdk/cpdfsdk_pageview.cpp
+++ b/fpdfsdk/cpdfsdk_pageview.cpp
@@ -105,7 +105,7 @@
     auto ret = std::make_unique<CPDFSDK_Widget>(annot, this, form);
     form->AddMap(form_control, ret.get());
     if (pdf_form->NeedConstructAP())
-      ret->ResetAppearance(absl::nullopt, CPDFSDK_Widget::kValueUnchanged);
+      ret->ResetAppearance(std::nullopt, CPDFSDK_Widget::kValueUnchanged);
     return ret;
   }
 
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp
index 12a9b56..c217aaa 100644
--- a/fpdfsdk/cpdfsdk_widget.cpp
+++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -437,35 +437,35 @@
 }
 #endif  // PDF_ENABLE_XFA
 
-absl::optional<FX_COLORREF> CPDFSDK_Widget::GetFillColor() const {
+std::optional<FX_COLORREF> CPDFSDK_Widget::GetFillColor() const {
   CFX_Color::TypeAndARGB type_argb_pair =
       GetFormControl()->GetColorARGB(pdfium::appearance::kBG);
 
   if (type_argb_pair.color_type == CFX_Color::Type::kTransparent)
-    return absl::nullopt;
+    return std::nullopt;
 
   return ArgbToColorRef(type_argb_pair.argb);
 }
 
-absl::optional<FX_COLORREF> CPDFSDK_Widget::GetBorderColor() const {
+std::optional<FX_COLORREF> CPDFSDK_Widget::GetBorderColor() const {
   CFX_Color::TypeAndARGB type_argb_pair =
       GetFormControl()->GetColorARGB(pdfium::appearance::kBC);
   if (type_argb_pair.color_type == CFX_Color::Type::kTransparent)
-    return absl::nullopt;
+    return std::nullopt;
 
   return ArgbToColorRef(type_argb_pair.argb);
 }
 
-absl::optional<FX_COLORREF> CPDFSDK_Widget::GetTextColor() const {
+std::optional<FX_COLORREF> CPDFSDK_Widget::GetTextColor() const {
   CPDF_DefaultAppearance da = GetFormControl()->GetDefaultAppearance();
-  absl::optional<CFX_Color::TypeAndARGB> maybe_type_argb_pair =
+  std::optional<CFX_Color::TypeAndARGB> maybe_type_argb_pair =
       da.GetColorARGB();
 
   if (!maybe_type_argb_pair.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (maybe_type_argb_pair.value().color_type == CFX_Color::Type::kTransparent)
-    return absl::nullopt;
+    return std::nullopt;
 
   return ArgbToColorRef(maybe_type_argb_pair.value().argb);
 }
@@ -637,13 +637,13 @@
       break;
     }
     default:
-      ResetAppearance(absl::nullopt, kValueUnchanged);
+      ResetAppearance(std::nullopt, kValueUnchanged);
       break;
   }
 }
 #endif  // PDF_ENABLE_XFA
 
-void CPDFSDK_Widget::ResetAppearance(absl::optional<WideString> sValue,
+void CPDFSDK_Widget::ResetAppearance(std::optional<WideString> sValue,
                                      ValueChanged bValueChanged) {
   SetAppModified();
 
@@ -678,7 +678,7 @@
   ClearCachedAnnotAP();
 }
 
-absl::optional<WideString> CPDFSDK_Widget::OnFormat() {
+std::optional<WideString> CPDFSDK_Widget::OnFormat() {
   CPDF_FormField* pFormField = GetFormField();
   DCHECK(pFormField);
   return m_pInteractiveForm->OnFormat(pFormField);
@@ -687,7 +687,7 @@
 void CPDFSDK_Widget::ResetFieldAppearance() {
   CPDF_FormField* pFormField = GetFormField();
   DCHECK(pFormField);
-  m_pInteractiveForm->ResetFieldAppearance(pFormField, absl::nullopt);
+  m_pInteractiveForm->ResetFieldAppearance(pFormField, std::nullopt);
 }
 
 void CPDFSDK_Widget::OnDraw(CFX_RenderDevice* pDevice,
@@ -1021,7 +1021,7 @@
 
 CFX_Color CPDFSDK_Widget::GetTextPWLColor() const {
   CPDF_FormControl* pFormCtrl = GetFormControl();
-  absl::optional<CFX_Color> crText =
+  std::optional<CFX_Color> crText =
       pFormCtrl->GetDefaultAppearance().GetColor();
   return crText.value_or(CFX_Color(CFX_Color::Type::kGray, 0));
 }
@@ -1058,13 +1058,13 @@
     return;
 
   if (!IsAppearanceValid())
-    ResetAppearance(absl::nullopt, CPDFSDK_Widget::kValueUnchanged);
+    ResetAppearance(std::nullopt, CPDFSDK_Widget::kValueUnchanged);
 
   FormFieldType field_type = GetFieldType();
   if (field_type == FormFieldType::kTextField ||
       field_type == FormFieldType::kComboBox) {
     ObservedPtr<CPDFSDK_Annot> pObserved(this);
-    absl::optional<WideString> sValue = OnFormat();
+    std::optional<WideString> sValue = OnFormat();
     if (!pObserved)
       return;
 
diff --git a/fpdfsdk/cpdfsdk_widget.h b/fpdfsdk/cpdfsdk_widget.h
index ce68cfb..31f2ff8 100644
--- a/fpdfsdk/cpdfsdk_widget.h
+++ b/fpdfsdk/cpdfsdk_widget.h
@@ -7,6 +7,8 @@
 #ifndef FPDFSDK_CPDFSDK_WIDGET_H_
 #define FPDFSDK_CPDFSDK_WIDGET_H_
 
+#include <optional>
+
 #include "core/fpdfdoc/cpdf_aaction.h"
 #include "core/fpdfdoc/cpdf_action.h"
 #include "core/fpdfdoc/cpdf_annot.h"
@@ -16,7 +18,6 @@
 #include "core/fxcrt/widestring.h"
 #include "core/fxge/cfx_color.h"
 #include "fpdfsdk/cpdfsdk_baannot.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFFL_InteractiveFormFiller;
 class CFX_RenderDevice;
@@ -80,9 +81,9 @@
   int GetFieldFlags() const;
   int GetRotate() const;
 
-  absl::optional<FX_COLORREF> GetFillColor() const;
-  absl::optional<FX_COLORREF> GetBorderColor() const;
-  absl::optional<FX_COLORREF> GetTextColor() const;
+  std::optional<FX_COLORREF> GetFillColor() const;
+  std::optional<FX_COLORREF> GetBorderColor() const;
+  std::optional<FX_COLORREF> GetTextColor() const;
   float GetFontSize() const;
 
   int GetSelectedIndex(int nIndex) const;
@@ -115,11 +116,11 @@
   void ResetXFAAppearance(ValueChanged bValueChanged);
 #endif  // PDF_ENABLE_XFA
 
-  void ResetAppearance(absl::optional<WideString> sValue,
+  void ResetAppearance(std::optional<WideString> sValue,
                        ValueChanged bValueChanged);
   void ResetFieldAppearance();
   void UpdateField();
-  absl::optional<WideString> OnFormat();
+  std::optional<WideString> OnFormat();
 
   bool OnAAction(CPDF_AAction::AActionType type,
                  CFFL_FieldAction* data,
diff --git a/fpdfsdk/formfiller/cffl_formfield.cpp b/fpdfsdk/formfiller/cffl_formfield.cpp
index 88fb16a..50855c1 100644
--- a/fpdfsdk/formfiller/cffl_formfield.cpp
+++ b/fpdfsdk/formfiller/cffl_formfield.cpp
@@ -317,7 +317,7 @@
   if (dwFieldFlag & pdfium::form_flags::kReadOnly)
     dwCreateFlags |= PWS_READONLY;
 
-  absl::optional<FX_COLORREF> color = m_pWidget->GetFillColor();
+  std::optional<FX_COLORREF> color = m_pWidget->GetFillColor();
   if (color.has_value())
     cp.sBackgroundColor = CFX_Color(color.value());
   color = m_pWidget->GetBorderColor();
diff --git a/fpdfsdk/fpdf_dataavail_embeddertest.cpp b/fpdfsdk/fpdf_dataavail_embeddertest.cpp
index 9718bb5..b205074 100644
--- a/fpdfsdk/fpdf_dataavail_embeddertest.cpp
+++ b/fpdfsdk/fpdf_dataavail_embeddertest.cpp
@@ -309,7 +309,7 @@
   // Map "Info" to an object within the first section without breaking
   // linearization.
   ByteString data(ByteStringView(loader.file_contents()));
-  absl::optional<size_t> index = data.Find("/Info 27 0 R");
+  std::optional<size_t> index = data.Find("/Info 27 0 R");
   ASSERT_TRUE(index.has_value());
   auto span = loader.mutable_file_contents().subspan(index.value()).subspan(7);
   ASSERT_FALSE(span.empty());
@@ -337,7 +337,7 @@
   TestAsyncLoader loader("linearized.pdf");
   // Map "Info" to an invalid object without breaking linearization.
   ByteString data(ByteStringView(loader.file_contents()));
-  absl::optional<size_t> index = data.Find("/Info 27 0 R");
+  std::optional<size_t> index = data.Find("/Info 27 0 R");
   ASSERT_TRUE(index.has_value());
   auto span = loader.mutable_file_contents().subspan(index.value()).subspan(6);
   ASSERT_GE(span.size(), 2u);
@@ -368,7 +368,7 @@
   TestAsyncLoader loader("linearized.pdf");
   // Break the "Info" parameter without breaking linearization.
   ByteString data(ByteStringView(loader.file_contents()));
-  absl::optional<size_t> index = data.Find("/Info 27 0 R");
+  std::optional<size_t> index = data.Find("/Info 27 0 R");
   ASSERT_TRUE(index.has_value());
   auto span = loader.mutable_file_contents().subspan(index.value()).subspan(2);
   ASSERT_FALSE(span.empty());
diff --git a/fpdfsdk/fpdf_doc.cpp b/fpdfsdk/fpdf_doc.cpp
index 4f57144..e23103a 100644
--- a/fpdfsdk/fpdf_doc.cpp
+++ b/fpdfsdk/fpdf_doc.cpp
@@ -512,7 +512,7 @@
 
   // CPDF_PageLabel can deal with NULL |document|.
   CPDF_PageLabel label(CPDFDocumentFromFPDFDocument(document));
-  absl::optional<WideString> str = label.GetLabel(page_index);
+  std::optional<WideString> str = label.GetLabel(page_index);
   return str.has_value()
              ? Utf16EncodeMaybeCopyAndReturnLength(str.value(), buffer, buflen)
              : 0;
diff --git a/fpdfsdk/fpdf_formfill.cpp b/fpdfsdk/fpdf_formfill.cpp
index ebb030b..bc07d93 100644
--- a/fpdfsdk/fpdf_formfill.cpp
+++ b/fpdfsdk/fpdf_formfill.cpp
@@ -712,7 +712,7 @@
   if (!pForm)
     return;
 
-  absl::optional<FormFieldType> cast_input =
+  std::optional<FormFieldType> cast_input =
       CPDF_FormField::IntToFormFieldType(fieldType);
   if (!cast_input.has_value())
     return;
diff --git a/fpdfsdk/fpdf_javascript.cpp b/fpdfsdk/fpdf_javascript.cpp
index ed91ac6..f6a9180 100644
--- a/fpdfsdk/fpdf_javascript.cpp
+++ b/fpdfsdk/fpdf_javascript.cpp
@@ -50,7 +50,7 @@
   if (action.GetType() != CPDF_Action::Type::kJavaScript)
     return nullptr;
 
-  absl::optional<WideString> script = action.MaybeGetJavaScript();
+  std::optional<WideString> script = action.MaybeGetJavaScript();
   if (!script.has_value())
     return nullptr;
 
diff --git a/fpdfsdk/fpdf_save.cpp b/fpdfsdk/fpdf_save.cpp
index b7b7ddf9..d3e03a1 100644
--- a/fpdfsdk/fpdf_save.cpp
+++ b/fpdfsdk/fpdf_save.cpp
@@ -6,6 +6,7 @@
 
 #include "public/fpdf_save.h"
 
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -22,7 +23,6 @@
 #include "fpdfsdk/cpdfsdk_filewriteadapter.h"
 #include "fpdfsdk/cpdfsdk_helpers.h"
 #include "public/fpdf_edit.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #ifdef PDF_ENABLE_XFA
 #include "core/fpdfapi/parser/cpdf_stream.h"
@@ -153,7 +153,7 @@
 bool DoDocSave(FPDF_DOCUMENT document,
                FPDF_FILEWRITE* pFileWrite,
                FPDF_DWORD flags,
-               absl::optional<int> version) {
+               std::optional<int> version) {
   CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document);
   if (!pPDFDoc)
     return false;
diff --git a/fpdfsdk/fpdf_structtree.cpp b/fpdfsdk/fpdf_structtree.cpp
index 28312fc..e0cfb3f 100644
--- a/fpdfsdk/fpdf_structtree.cpp
+++ b/fpdfsdk/fpdf_structtree.cpp
@@ -103,7 +103,7 @@
       CPDFStructElementFromFPDFStructElement(struct_element);
   if (!elem)
     return 0;
-  absl::optional<WideString> id = elem->GetID();
+  std::optional<WideString> id = elem->GetID();
   if (!id.has_value())
     return 0;
   return Utf16EncodeMaybeCopyAndReturnLength(id.value(), buffer, buflen);
@@ -117,7 +117,7 @@
       CPDFStructElementFromFPDFStructElement(struct_element);
   if (!elem)
     return 0;
-  absl::optional<WideString> lang = elem->GetLang();
+  std::optional<WideString> lang = elem->GetLang();
   if (!lang.has_value())
     return 0;
   return Utf16EncodeMaybeCopyAndReturnLength(lang.value(), buffer, buflen);
diff --git a/fpdfsdk/fpdf_structtree_embeddertest.cpp b/fpdfsdk/fpdf_structtree_embeddertest.cpp
index 78a3b87..f47d10b 100644
--- a/fpdfsdk/fpdf_structtree_embeddertest.cpp
+++ b/fpdfsdk/fpdf_structtree_embeddertest.cpp
@@ -3,11 +3,11 @@
 // found in the LICENSE file.
 
 #include <iterator>
+#include <optional>
 
 #include "public/fpdf_structtree.h"
 #include "testing/embedder_test.h"
 #include "testing/fx_string_testhelpers.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class FPDFStructTreeEmbedderTest : public EmbedderTest {};
 
diff --git a/fpdfsdk/fpdf_text.cpp b/fpdfsdk/fpdf_text.cpp
index 194a602..32e6f8f 100644
--- a/fpdfsdk/fpdf_text.cpp
+++ b/fpdfsdk/fpdf_text.cpp
@@ -417,7 +417,7 @@
   options.bConsecutive = !!(flags & FPDF_CONSECUTIVE);
   auto find = CPDF_TextPageFind::Create(
       textpage, WideStringFromFPDFWideString(findwhat), options,
-      start_index >= 0 ? absl::optional<size_t>(start_index) : absl::nullopt);
+      start_index >= 0 ? std::optional<size_t>(start_index) : std::nullopt);
 
   // Caller takes ownership.
   return FPDFSchHandleFromCPDFTextPageFind(find.release());
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 17c53ba..3cba971 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -839,7 +839,7 @@
 
   IPDF_Page* pPage = IPDFPageFromFPDFPage(page);
   const FX_RECT rect(start_x, start_y, start_x + size_x, start_y + size_y);
-  absl::optional<CFX_PointF> pos =
+  std::optional<CFX_PointF> pos =
       pPage->DeviceToPage(rect, rotate, CFX_PointF(device_x, device_y));
   if (!pos.has_value())
     return false;
@@ -865,8 +865,7 @@
   IPDF_Page* pPage = IPDFPageFromFPDFPage(page);
   const FX_RECT rect(start_x, start_y, start_x + size_x, start_y + size_y);
   CFX_PointF page_point(static_cast<float>(page_x), static_cast<float>(page_y));
-  absl::optional<CFX_PointF> pos =
-      pPage->PageToDevice(rect, rotate, page_point);
+  std::optional<CFX_PointF> pos = pPage->PageToDevice(rect, rotate, page_point);
   if (!pos.has_value())
     return false;
 
@@ -1102,7 +1101,7 @@
     return 0;
 
   CPDF_ViewerPreferences viewRef(pDoc);
-  absl::optional<ByteString> bsVal = viewRef.GenericName(key);
+  std::optional<ByteString> bsVal = viewRef.GenericName(key);
   if (!bsVal.has_value())
     return 0;
 
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
index 6f4f2b7..4d883d3 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
@@ -172,25 +172,25 @@
   return 0.0f;
 }
 
-absl::optional<CFX_PointF> CPDFXFA_Page::DeviceToPage(
+std::optional<CFX_PointF> CPDFXFA_Page::DeviceToPage(
     const FX_RECT& rect,
     int rotate,
     const CFX_PointF& device_point) const {
   CXFA_FFPageView* pPageView = GetXFAPageView();
   if (!m_pPDFPage && !pPageView)
-    return absl::nullopt;
+    return std::nullopt;
 
   CFX_Matrix page2device = GetDisplayMatrix(rect, rotate);
   return page2device.GetInverse().Transform(device_point);
 }
 
-absl::optional<CFX_PointF> CPDFXFA_Page::PageToDevice(
+std::optional<CFX_PointF> CPDFXFA_Page::PageToDevice(
     const FX_RECT& rect,
     int rotate,
     const CFX_PointF& page_point) const {
   CXFA_FFPageView* pPageView = GetXFAPageView();
   if (!m_pPDFPage && !pPageView)
-    return absl::nullopt;
+    return std::nullopt;
 
   CFX_Matrix page2device = GetDisplayMatrix(rect, rotate);
   return page2device.Transform(page_point);
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_page.h b/fpdfsdk/fpdfxfa/cpdfxfa_page.h
index 1b05562..10865d7 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_page.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.h
@@ -7,12 +7,13 @@
 #ifndef FPDFSDK_FPDFXFA_CPDFXFA_PAGE_H_
 #define FPDFSDK_FPDFXFA_CPDFXFA_PAGE_H_
 
+#include <optional>
+
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/page/ipdf_page.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_RenderDevice;
 class CPDF_Dictionary;
@@ -32,11 +33,11 @@
   float GetPageWidth() const override;
   float GetPageHeight() const override;
   CFX_Matrix GetDisplayMatrix(const FX_RECT& rect, int iRotate) const override;
-  absl::optional<CFX_PointF> DeviceToPage(
+  std::optional<CFX_PointF> DeviceToPage(
       const FX_RECT& rect,
       int rotate,
       const CFX_PointF& device_point) const override;
-  absl::optional<CFX_PointF> PageToDevice(
+  std::optional<CFX_PointF> PageToDevice(
       const FX_RECT& rect,
       int rotate,
       const CFX_PointF& page_point) const override;
diff --git a/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp b/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp
index 31e6c89..75898fe 100644
--- a/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp
+++ b/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp
@@ -73,9 +73,9 @@
   return m_expTable[a];
 }
 
-absl::optional<int32_t> CBC_ReedSolomonGF256::Inverse(int32_t a) {
+std::optional<int32_t> CBC_ReedSolomonGF256::Inverse(int32_t a) {
   if (a == 0)
-    return absl::nullopt;
+    return std::nullopt;
   return m_expTable[255 - m_logTable[a]];
 }
 
diff --git a/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h b/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h
index b4b4da8..f75af9b0 100644
--- a/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h
+++ b/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h
@@ -8,8 +8,7 @@
 #define FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONGF256_H_
 
 #include <memory>
-
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 class CBC_ReedSolomonGF256Poly;
 
@@ -25,7 +24,7 @@
                                                           int32_t coefficient);
   static int32_t AddOrSubtract(int32_t a, int32_t b);
   int32_t Exp(int32_t a);
-  absl::optional<int32_t> Inverse(int32_t a);
+  std::optional<int32_t> Inverse(int32_t a);
   int32_t Multiply(int32_t a, int32_t b);
   void Init();
 
diff --git a/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp b/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp
index 449d0a3..463db48 100644
--- a/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp
+++ b/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp
@@ -151,7 +151,7 @@
     return nullptr;
 
   int32_t denominatorLeadingTerm = other->GetCoefficients(other->GetDegree());
-  absl::optional<int32_t> inverseDenominatorLeadingTeam =
+  std::optional<int32_t> inverseDenominatorLeadingTeam =
       m_field->Inverse(denominatorLeadingTerm);
   if (!inverseDenominatorLeadingTeam.has_value())
     return nullptr;
diff --git a/fxbarcode/datamatrix/BC_ASCIIEncoder.cpp b/fxbarcode/datamatrix/BC_ASCIIEncoder.cpp
index 333fffe..215ffae 100644
--- a/fxbarcode/datamatrix/BC_ASCIIEncoder.cpp
+++ b/fxbarcode/datamatrix/BC_ASCIIEncoder.cpp
@@ -22,20 +22,21 @@
 
 #include "fxbarcode/datamatrix/BC_ASCIIEncoder.h"
 
+#include <optional>
+
 #include "core/fxcrt/fx_extension.h"
 #include "fxbarcode/datamatrix/BC_Encoder.h"
 #include "fxbarcode/datamatrix/BC_EncoderContext.h"
 #include "fxbarcode/datamatrix/BC_HighLevelEncoder.h"
 #include "fxbarcode/datamatrix/BC_SymbolInfo.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace {
 
-absl::optional<wchar_t> EncodeASCIIDigits(wchar_t digit1, wchar_t digit2) {
+std::optional<wchar_t> EncodeASCIIDigits(wchar_t digit1, wchar_t digit2) {
   if (!FXSYS_IsDecimalDigit(digit1) || !FXSYS_IsDecimalDigit(digit2)) {
     // This could potentially return 0 as a sentinel value. Then this function
-    // can just return wchar_t instead of absl::optional<wchar_t>.
-    return absl::nullopt;
+    // can just return wchar_t instead of std::optional<wchar_t>.
+    return std::nullopt;
   }
   return static_cast<wchar_t>((digit1 - 48) * 10 + (digit2 - 48) + 130);
 }
@@ -67,7 +68,7 @@
 bool CBC_ASCIIEncoder::Encode(CBC_EncoderContext* context) {
   size_t n = DetermineConsecutiveDigitCount(context->m_msg, context->m_pos);
   if (n >= 2) {
-    absl::optional<wchar_t> code = EncodeASCIIDigits(
+    std::optional<wchar_t> code = EncodeASCIIDigits(
         context->m_msg[context->m_pos], context->m_msg[context->m_pos + 1]);
     if (!code.has_value())
       return false;
diff --git a/fxbarcode/pdf417/BC_PDF417.cpp b/fxbarcode/pdf417/BC_PDF417.cpp
index d48b98a..0d0ae68 100644
--- a/fxbarcode/pdf417/BC_PDF417.cpp
+++ b/fxbarcode/pdf417/BC_PDF417.cpp
@@ -366,7 +366,7 @@
   if (errorCorrectionCodeWords < 0)
     return false;
 
-  absl::optional<WideString> high_level =
+  std::optional<WideString> high_level =
       CBC_PDF417HighLevelEncoder::EncodeHighLevel(msg);
   if (!high_level.has_value())
     return false;
@@ -391,7 +391,7 @@
     sb += (wchar_t)900;
 
   WideString dataCodewords(sb);
-  absl::optional<WideString> ec =
+  std::optional<WideString> ec =
       CBC_PDF417ErrorCorrection::GenerateErrorCorrection(dataCodewords,
                                                          errorCorrectionLevel);
   if (!ec.has_value())
diff --git a/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp b/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp
index 509f8aa..b0fe2b8 100644
--- a/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp
+++ b/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp
@@ -133,12 +133,12 @@
 }
 
 // static
-absl::optional<WideString> CBC_PDF417ErrorCorrection::GenerateErrorCorrection(
+std::optional<WideString> CBC_PDF417ErrorCorrection::GenerateErrorCorrection(
     const WideString& dataCodewords,
     int32_t errorCorrectionLevel) {
   int32_t k = GetErrorCorrectionCodewordCount(errorCorrectionLevel);
   if (k < 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   DataVector<wchar_t> ech(k);
   size_t sld = dataCodewords.GetLength();
diff --git a/fxbarcode/pdf417/BC_PDF417ErrorCorrection.h b/fxbarcode/pdf417/BC_PDF417ErrorCorrection.h
index ccb2fa0..4e0085f 100644
--- a/fxbarcode/pdf417/BC_PDF417ErrorCorrection.h
+++ b/fxbarcode/pdf417/BC_PDF417ErrorCorrection.h
@@ -9,8 +9,9 @@
 
 #include <stdint.h>
 
+#include <optional>
+
 #include "core/fxcrt/widestring.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CBC_PDF417ErrorCorrection {
  public:
@@ -18,7 +19,7 @@
   ~CBC_PDF417ErrorCorrection() = delete;
 
   static int32_t GetErrorCorrectionCodewordCount(int32_t errorCorrectionLevel);
-  static absl::optional<WideString> GenerateErrorCorrection(
+  static std::optional<WideString> GenerateErrorCorrection(
       const WideString& dataCodewords,
       int32_t errorCorrectionLevel);
 };
diff --git a/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp b/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp
index 7affbc81..d903b8f 100644
--- a/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp
+++ b/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp
@@ -77,7 +77,7 @@
 }  // namespace
 
 // static
-absl::optional<WideString> CBC_PDF417HighLevelEncoder::EncodeHighLevel(
+std::optional<WideString> CBC_PDF417HighLevelEncoder::EncodeHighLevel(
     WideStringView msg) {
   const ByteString bytes = FX_UTF8Encode(msg);
   size_t len = bytes.GetLength();
@@ -86,7 +86,7 @@
   for (size_t i = 0; i < len; i++) {
     wchar_t ch = bytes[i] & 0xff;
     if (ch == '?' && bytes[i] != '?')
-      return absl::nullopt;
+      return std::nullopt;
 
     result += ch;
   }
@@ -115,10 +115,10 @@
         textSubMode = EncodeText(result, p, t, textSubMode, &sb);
         p += t;
       } else {
-        absl::optional<size_t> b =
+        std::optional<size_t> b =
             DetermineConsecutiveBinaryCount(result, bytes.raw_span(), p);
         if (!b.has_value())
-          return absl::nullopt;
+          return std::nullopt;
 
         size_t b_value = b.value();
         if (b_value == 0)
@@ -352,7 +352,7 @@
   return idx - startpos;
 }
 
-absl::optional<size_t>
+std::optional<size_t>
 CBC_PDF417HighLevelEncoder::DetermineConsecutiveBinaryCount(
     WideString msg,
     pdfium::span<const uint8_t> bytes,
@@ -384,7 +384,7 @@
       return idx - startpos;
     ch = msg[idx];
     if (bytes[idx] == 63 && ch != '?')
-      return absl::nullopt;
+      return std::nullopt;
     idx++;
   }
   return idx - startpos;
diff --git a/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h b/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h
index 6e8f034..d13968c 100644
--- a/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h
+++ b/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h
@@ -7,9 +7,10 @@
 #ifndef FXBARCODE_PDF417_BC_PDF417HIGHLEVELENCODER_H_
 #define FXBARCODE_PDF417_BC_PDF417HIGHLEVELENCODER_H_
 
+#include <optional>
+
 #include "core/fxcrt/widestring.h"
 #include "fxbarcode/pdf417/BC_PDF417.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 class CBC_PDF417HighLevelEncoder {
@@ -17,7 +18,7 @@
   CBC_PDF417HighLevelEncoder() = delete;
   ~CBC_PDF417HighLevelEncoder() = delete;
 
-  static absl::optional<WideString> EncodeHighLevel(WideStringView msg);
+  static std::optional<WideString> EncodeHighLevel(WideStringView msg);
 
  private:
   enum class EncodingMode { kUnknown = 0, kText, kByte, kNumeric };
@@ -40,7 +41,7 @@
                             WideString* sb);
   static size_t DetermineConsecutiveDigitCount(WideString msg, size_t startpos);
   static size_t DetermineConsecutiveTextCount(WideString msg, size_t startpos);
-  static absl::optional<size_t> DetermineConsecutiveBinaryCount(
+  static std::optional<size_t> DetermineConsecutiveBinaryCount(
       WideString msg,
       pdfium::span<const uint8_t> bytes,
       size_t startpos);
diff --git a/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp b/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp
index 7f665ac..78b1c37 100644
--- a/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp
+++ b/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp
@@ -43,7 +43,7 @@
     const EncodeHighLevelCase& testcase = kEncodeHighLevelCases[i];
     WideStringView input(testcase.input);
     WideString expected(testcase.expected, testcase.expected_length);
-    absl::optional<WideString> result =
+    std::optional<WideString> result =
         CBC_PDF417HighLevelEncoder::EncodeHighLevel(input);
     ASSERT_TRUE(result.has_value());
     EXPECT_EQ(expected, result.value()) << " for case number " << i;
diff --git a/fxbarcode/qrcode/BC_QRCoderEncoder.cpp b/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
index b55255d..80fab76 100644
--- a/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
+++ b/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
@@ -26,6 +26,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -42,7 +43,6 @@
 #include "fxbarcode/qrcode/BC_QRCoderMatrixUtil.h"
 #include "fxbarcode/qrcode/BC_QRCoderMode.h"
 #include "fxbarcode/qrcode/BC_QRCoderVersion.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/check_op.h"
 
@@ -206,7 +206,7 @@
          CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(matrix);
 }
 
-absl::optional<int32_t> ChooseMaskPattern(
+std::optional<int32_t> ChooseMaskPattern(
     CBC_QRCoderBitVector* bits,
     const CBC_QRCoderErrorCorrectionLevel* ecLevel,
     int32_t version,
@@ -217,7 +217,7 @@
        maskPattern++) {
     if (!CBC_QRCoderMatrixUtil::BuildMatrix(bits, ecLevel, version, maskPattern,
                                             matrix)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     int32_t penalty = CalculateMaskPenalty(matrix);
     if (penalty < minPenalty) {
@@ -400,7 +400,7 @@
 
   auto matrix = std::make_unique<CBC_CommonByteMatrix>(
       qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth());
-  absl::optional<int32_t> maskPattern = ChooseMaskPattern(
+  std::optional<int32_t> maskPattern = ChooseMaskPattern(
       &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get());
   if (!maskPattern.has_value())
     return false;
diff --git a/fxjs/cfx_globaldata.cpp b/fxjs/cfx_globaldata.cpp
index 6d6efd5..b07974e 100644
--- a/fxjs/cfx_globaldata.cpp
+++ b/fxjs/cfx_globaldata.cpp
@@ -254,7 +254,7 @@
   bool ret;
   {
     // Span can't outlive call to BufferDone().
-    absl::optional<pdfium::span<uint8_t>> buffer = m_pDelegate->LoadBuffer();
+    std::optional<pdfium::span<uint8_t>> buffer = m_pDelegate->LoadBuffer();
     if (!buffer.has_value() || buffer.value().empty())
       return false;
 
diff --git a/fxjs/cfx_globaldata.h b/fxjs/cfx_globaldata.h
index ac94058..7ca4fd6 100644
--- a/fxjs/cfx_globaldata.h
+++ b/fxjs/cfx_globaldata.h
@@ -8,12 +8,12 @@
 #define FXJS_CFX_GLOBALDATA_H_
 
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/binary_buffer.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "fxjs/cfx_keyvalue.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 
 class CFX_GlobalData {
@@ -23,7 +23,7 @@
     virtual ~Delegate() = default;
 
     virtual bool StoreBuffer(pdfium::span<const uint8_t> pBuffer) = 0;
-    virtual absl::optional<pdfium::span<uint8_t>> LoadBuffer() = 0;
+    virtual std::optional<pdfium::span<uint8_t>> LoadBuffer() = 0;
     virtual void BufferDone() = 0;
   };
 
diff --git a/fxjs/cfx_globaldata_unittest.cpp b/fxjs/cfx_globaldata_unittest.cpp
index 8121701..569d159 100644
--- a/fxjs/cfx_globaldata_unittest.cpp
+++ b/fxjs/cfx_globaldata_unittest.cpp
@@ -23,7 +23,7 @@
     last_buffer_ = DataVector<uint8_t>(buffer.begin(), buffer.end());
     return true;
   }
-  absl::optional<pdfium::span<uint8_t>> LoadBuffer() override {
+  std::optional<pdfium::span<uint8_t>> LoadBuffer() override {
     return pdfium::span<uint8_t>(last_buffer_);
   }
   void BufferDone() override {
diff --git a/fxjs/cfxjs_engine.cpp b/fxjs/cfxjs_engine.cpp
index 35653c9..b3dd904 100644
--- a/fxjs/cfxjs_engine.cpp
+++ b/fxjs/cfxjs_engine.cpp
@@ -574,7 +574,7 @@
   GetIsolate()->SetData(g_embedderDataSlot, nullptr);
 }
 
-absl::optional<IJS_Runtime::JS_Error> CFXJS_Engine::Execute(
+std::optional<IJS_Runtime::JS_Error> CFXJS_Engine::Execute(
     const WideString& script) {
   v8::Isolate::Scope isolate_scope(GetIsolate());
   v8::TryCatch try_catch(GetIsolate());
@@ -599,7 +599,7 @@
     std::tie(line, column) = GetLineAndColumnFromError(msg, context);
     return IJS_Runtime::JS_Error(line, column, WideString::FromUTF8(*error));
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 v8::Local<v8::Object> CFXJS_Engine::NewFXJSBoundObject(uint32_t nObjDefnID,
diff --git a/fxjs/cfxjs_engine.h b/fxjs/cfxjs_engine.h
index b0011fc..91ac103 100644
--- a/fxjs/cfxjs_engine.h
+++ b/fxjs/cfxjs_engine.h
@@ -130,7 +130,7 @@
   void ReleaseEngine();
 
   // Called after FXJS_InitializeEngine call made.
-  absl::optional<IJS_Runtime::JS_Error> Execute(const WideString& script);
+  std::optional<IJS_Runtime::JS_Error> Execute(const WideString& script);
 
   v8::Local<v8::Object> GetThisObj();
   v8::Local<v8::Object> NewFXJSBoundObject(uint32_t nObjDefnID,
diff --git a/fxjs/cfxjs_engine_embeddertest.cpp b/fxjs/cfxjs_engine_embeddertest.cpp
index 70e84ab..f8952af 100644
--- a/fxjs/cfxjs_engine_embeddertest.cpp
+++ b/fxjs/cfxjs_engine_embeddertest.cpp
@@ -40,7 +40,7 @@
   v8::HandleScope handle_scope(isolate());
   v8::Context::Scope context_scope(GetV8Context());
 
-  absl::optional<IJS_Runtime::JS_Error> err =
+  std::optional<IJS_Runtime::JS_Error> err =
       engine()->Execute(WideString(kScript1));
   EXPECT_FALSE(err);
   CheckAssignmentInEngineContext(engine(), kExpected1);
@@ -58,7 +58,7 @@
 
   v8::Context::Scope context_scope(GetV8Context());
   {
-    absl::optional<IJS_Runtime::JS_Error> err =
+    std::optional<IJS_Runtime::JS_Error> err =
         engine()->Execute(WideString(kScript0));
     EXPECT_FALSE(err);
     CheckAssignmentInEngineContext(engine(), kExpected0);
@@ -66,7 +66,7 @@
   {
     // engine1 executing in engine1's context doesn't affect main.
     v8::Context::Scope context_scope1(engine1.GetV8Context());
-    absl::optional<IJS_Runtime::JS_Error> err =
+    std::optional<IJS_Runtime::JS_Error> err =
         engine1.Execute(WideString(kScript1));
     EXPECT_FALSE(err);
     CheckAssignmentInEngineContext(engine(), kExpected0);
@@ -75,7 +75,7 @@
   {
     // engine1 executing in engine2's context doesn't affect engine1.
     v8::Context::Scope context_scope2(engine2.GetV8Context());
-    absl::optional<IJS_Runtime::JS_Error> err =
+    std::optional<IJS_Runtime::JS_Error> err =
         engine1.Execute(WideString(kScript2));
     EXPECT_FALSE(err);
     CheckAssignmentInEngineContext(engine(), kExpected0);
@@ -91,7 +91,7 @@
   v8::HandleScope handle_scope(isolate());
   v8::Context::Scope context_scope(GetV8Context());
 
-  absl::optional<IJS_Runtime::JS_Error> err =
+  std::optional<IJS_Runtime::JS_Error> err =
       engine()->Execute(L"functoon(x) { return x+1; }");
   EXPECT_TRUE(err);
   EXPECT_STREQ(L"SyntaxError: Unexpected token '{'", err->exception.c_str());
@@ -104,7 +104,7 @@
   v8::HandleScope handle_scope(isolate());
   v8::Context::Scope context_scope(GetV8Context());
 
-  absl::optional<IJS_Runtime::JS_Error> err =
+  std::optional<IJS_Runtime::JS_Error> err =
       engine()->Execute(L"let a = 3;\nundefined.colour");
   EXPECT_TRUE(err);
   EXPECT_EQ(
diff --git a/fxjs/cfxjs_engine_unittest.cpp b/fxjs/cfxjs_engine_unittest.cpp
index 8d6c36b..c138255 100644
--- a/fxjs/cfxjs_engine_unittest.cpp
+++ b/fxjs/cfxjs_engine_unittest.cpp
@@ -92,7 +92,7 @@
     EXPECT_FALSE(temp_destroyed);
   }
 
-  absl::optional<IJS_Runtime::JS_Error> err = engine()->Execute(L"gc();");
+  std::optional<IJS_Runtime::JS_Error> err = engine()->Execute(L"gc();");
   EXPECT_FALSE(err);
 
   EXPECT_TRUE(perm_created);
diff --git a/fxjs/cjs_event_context.cpp b/fxjs/cjs_event_context.cpp
index 65eee9d..5fa7cd0 100644
--- a/fxjs/cjs_event_context.cpp
+++ b/fxjs/cjs_event_context.cpp
@@ -22,7 +22,7 @@
 
 CJS_EventContext::~CJS_EventContext() = default;
 
-absl::optional<IJS_Runtime::JS_Error> CJS_EventContext::RunScript(
+std::optional<IJS_Runtime::JS_Error> CJS_EventContext::RunScript(
     const WideString& script) {
   v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate());
   v8::HandleScope handle_scope(m_pRuntime->GetIsolate());
@@ -44,7 +44,7 @@
         1, 1, JSGetStringFromID(JSMessage::kDuplicateEventError));
   }
 
-  absl::optional<IJS_Runtime::JS_Error> err;
+  std::optional<IJS_Runtime::JS_Error> err;
   if (script.GetLength() > 0)
     err = m_pRuntime->ExecuteScript(script);
 
diff --git a/fxjs/cjs_event_context.h b/fxjs/cjs_event_context.h
index a0b266b..793c247 100644
--- a/fxjs/cjs_event_context.h
+++ b/fxjs/cjs_event_context.h
@@ -47,7 +47,7 @@
   ~CJS_EventContext() override;
 
   // IJS_EventContext
-  absl::optional<IJS_Runtime::JS_Error> RunScript(
+  std::optional<IJS_Runtime::JS_Error> RunScript(
       const WideString& script) override;
   void OnDoc_Open(const WideString& strTargetName) override;
   void OnDoc_WillPrint() override;
diff --git a/fxjs/cjs_event_context_stub.cpp b/fxjs/cjs_event_context_stub.cpp
index b8d0518..43ca89b 100644
--- a/fxjs/cjs_event_context_stub.cpp
+++ b/fxjs/cjs_event_context_stub.cpp
@@ -10,7 +10,7 @@
 
 CJS_EventContextStub::~CJS_EventContextStub() = default;
 
-absl::optional<IJS_Runtime::JS_Error> CJS_EventContextStub::RunScript(
+std::optional<IJS_Runtime::JS_Error> CJS_EventContextStub::RunScript(
     const WideString& script) {
   return IJS_Runtime::JS_Error(1, 1, L"JavaScript support not present");
 }
diff --git a/fxjs/cjs_event_context_stub.h b/fxjs/cjs_event_context_stub.h
index 5c9b50a..f6494b2 100644
--- a/fxjs/cjs_event_context_stub.h
+++ b/fxjs/cjs_event_context_stub.h
@@ -15,7 +15,7 @@
   ~CJS_EventContextStub() override;
 
   // IJS_EventContext:
-  absl::optional<IJS_Runtime::JS_Error> RunScript(
+  std::optional<IJS_Runtime::JS_Error> RunScript(
       const WideString& script) override;
 
   void OnDoc_Open(const WideString& strTargetName) override {}
diff --git a/fxjs/cjs_field.cpp b/fxjs/cjs_field.cpp
index 1724f81..08d9b9d 100644
--- a/fxjs/cjs_field.cpp
+++ b/fxjs/cjs_field.cpp
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "constants/access_permissions.h"
@@ -27,7 +28,6 @@
 #include "fxjs/cjs_icon.h"
 #include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/containers/span.h"
 #include "third_party/base/notreached.h"
@@ -68,7 +68,7 @@
     if (IsComboBoxOrTextField(pFormField)) {
       for (auto& pWidget : widgets) {
         if (pWidget) {
-          absl::optional<WideString> sValue = pWidget->OnFormat();
+          std::optional<WideString> sValue = pWidget->OnFormat();
           if (pWidget) {  // Not redundant, may be clobbered by OnFormat.
             pWidget->ResetAppearance(sValue, CPDFSDK_Widget::kValueUnchanged);
           }
@@ -77,7 +77,7 @@
     } else {
       for (auto& pWidget : widgets) {
         if (pWidget) {
-          pWidget->ResetAppearance(absl::nullopt,
+          pWidget->ResetAppearance(std::nullopt,
                                    CPDFSDK_Widget::kValueUnchanged);
         }
       }
@@ -108,13 +108,12 @@
       FormFieldType fieldType = pWidget->GetFieldType();
       if (fieldType == FormFieldType::kComboBox ||
           fieldType == FormFieldType::kTextField) {
-        absl::optional<WideString> sValue = pWidget->OnFormat();
+        std::optional<WideString> sValue = pWidget->OnFormat();
         if (!observed_widget)
           return;
         pWidget->ResetAppearance(sValue, CPDFSDK_Widget::kValueUnchanged);
       } else {
-        pWidget->ResetAppearance(absl::nullopt,
-                                 CPDFSDK_Widget::kValueUnchanged);
+        pWidget->ResetAppearance(std::nullopt, CPDFSDK_Widget::kValueUnchanged);
       }
       if (!observed_widget)
         return;
@@ -132,7 +131,7 @@
   int control_index;
 };
 
-absl::optional<FieldNameData> ParseFieldName(const WideString& field_name) {
+std::optional<FieldNameData> ParseFieldName(const WideString& field_name) {
   auto reverse_it = field_name.rbegin();
   while (reverse_it != field_name.rend()) {
     if (*reverse_it == L'.')
@@ -140,14 +139,14 @@
     ++reverse_it;
   }
   if (reverse_it == field_name.rend()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   WideString suffixal = field_name.Last(reverse_it - field_name.rbegin());
   int control_index = FXSYS_wtoi(suffixal.c_str());
   if (control_index == 0) {
     suffixal.TrimRight(L' ');
     if (suffixal != L"0") {
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
   return FieldNameData(field_name.First(field_name.rend() - reverse_it - 1),
@@ -649,7 +648,7 @@
   swFieldNameTemp.Replace(L"..", L".");
 
   if (pForm->CountFields(swFieldNameTemp) <= 0) {
-    absl::optional<FieldNameData> parsed_data = ParseFieldName(swFieldNameTemp);
+    std::optional<FieldNameData> parsed_data = ParseFieldName(swFieldNameTemp);
     if (!parsed_data.has_value())
       return false;
 
@@ -1905,7 +1904,7 @@
     return CJS_Result::Failure(JSMessage::kBadObjectError);
 
   CPDF_DefaultAppearance FieldAppearance = pFormControl->GetDefaultAppearance();
-  absl::optional<CFX_Color::TypeAndARGB> maybe_type_argb_pair =
+  std::optional<CFX_Color::TypeAndARGB> maybe_type_argb_pair =
       FieldAppearance.GetColorARGB();
 
   CFX_Color crRet;
@@ -1956,7 +1955,7 @@
     return CJS_Result::Failure(JSMessage::kObjectTypeError);
   }
 
-  absl::optional<WideString> wsFontName =
+  std::optional<WideString> wsFontName =
       pFormControl->GetDefaultControlFontName();
   if (!wsFontName.has_value())
     return CJS_Result::Failure(JSMessage::kBadObjectError);
diff --git a/fxjs/cjs_publicmethods.cpp b/fxjs/cjs_publicmethods.cpp
index 0377d93..2cd257d 100644
--- a/fxjs/cjs_publicmethods.cpp
+++ b/fxjs/cjs_publicmethods.cpp
@@ -12,6 +12,7 @@
 #include <iomanip>
 #include <iterator>
 #include <limits>
+#include <optional>
 #include <sstream>
 #include <string>
 #include <utility>
@@ -35,7 +36,6 @@
 #include "fxjs/fx_date_helpers.h"
 #include "fxjs/js_define.h"
 #include "fxjs/js_resources.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/containers/span.h"
 #include "third_party/base/numerics/safe_conversions.h"
@@ -213,9 +213,9 @@
   str->Replace(L",", L".");
 }
 
-absl::optional<double> ApplyNamedOperation(const WideString& wsFunction,
-                                           double dValue1,
-                                           double dValue2) {
+std::optional<double> ApplyNamedOperation(const WideString& wsFunction,
+                                          double dValue1,
+                                          double dValue2) {
   if (wsFunction.EqualsASCIINoCase("AVG") ||
       wsFunction.EqualsASCIINoCase("SUM")) {
     return dValue1 + dValue2;
@@ -226,7 +226,7 @@
     return std::min(dValue1, dValue2);
   if (wsFunction.EqualsASCIINoCase("MAX"))
     return std::max(dValue1, dValue2);
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace
@@ -846,7 +846,7 @@
   strValue.ReleaseBuffer(szNewSize);
 
   // for processing separator style
-  absl::optional<size_t> mark_pos = strValue.Find('.');
+  std::optional<size_t> mark_pos = strValue.Find('.');
   if (mark_pos.has_value()) {
     char mark = DecimalMarkForStyle(iSepStyle);
     if (mark != '.')
@@ -1255,7 +1255,7 @@
   if (isnan(arg1) || isnan(arg2))
     return CJS_Result::Failure(JSMessage::kValueError);
 
-  absl::optional<double> result = ApplyNamedOperation(sFunction, arg1, arg2);
+  std::optional<double> result = ApplyNamedOperation(sFunction, arg1, arg2);
   if (!result.has_value())
     return CJS_Result::Failure(JSMessage::kValueError);
 
@@ -1354,7 +1354,7 @@
            wcscmp(sFunction.c_str(), L"MAX") == 0)) {
         dValue = dTemp;
       }
-      absl::optional<double> dResult =
+      std::optional<double> dResult =
           ApplyNamedOperation(sFunction, dValue, dTemp);
       if (!dResult.has_value())
         return CJS_Result::Failure(JSMessage::kValueError);
diff --git a/fxjs/cjs_result.h b/fxjs/cjs_result.h
index 993a4dc..2e94797 100644
--- a/fxjs/cjs_result.h
+++ b/fxjs/cjs_result.h
@@ -7,8 +7,9 @@
 #ifndef FXJS_CJS_RESULT_H_
 #define FXJS_CJS_RESULT_H_
 
+#include <optional>
+
 #include "fxjs/js_resources.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "v8/include/v8-forward.h"
 
 class CJS_Result {
@@ -50,7 +51,7 @@
   explicit CJS_Result(const WideString&);     // Error with custom message.
   explicit CJS_Result(JSMessage id);          // Error with stock message.
 
-  absl::optional<WideString> error_;
+  std::optional<WideString> error_;
   v8::Local<v8::Value> return_;
 };
 
diff --git a/fxjs/cjs_runtime.cpp b/fxjs/cjs_runtime.cpp
index f7d76da..aba2346 100644
--- a/fxjs/cjs_runtime.cpp
+++ b/fxjs/cjs_runtime.cpp
@@ -166,7 +166,7 @@
   return m_pFormFillEnv.Get();
 }
 
-absl::optional<IJS_Runtime::JS_Error> CJS_Runtime::ExecuteScript(
+std::optional<IJS_Runtime::JS_Error> CJS_Runtime::ExecuteScript(
     const WideString& script) {
   return Execute(script);
 }
diff --git a/fxjs/cjs_runtime.h b/fxjs/cjs_runtime.h
index a3569f6..97e4ebf 100644
--- a/fxjs/cjs_runtime.h
+++ b/fxjs/cjs_runtime.h
@@ -34,7 +34,7 @@
   IJS_EventContext* NewEventContext() override;
   void ReleaseEventContext(IJS_EventContext* pContext) override;
   CPDFSDK_FormFillEnvironment* GetFormFillEnv() const override;
-  absl::optional<IJS_Runtime::JS_Error> ExecuteScript(
+  std::optional<IJS_Runtime::JS_Error> ExecuteScript(
       const WideString& script) override;
 
   CJS_EventContext* GetCurrentEventContext() const;
diff --git a/fxjs/cjs_runtimestub.cpp b/fxjs/cjs_runtimestub.cpp
index 0a68a17..c020664 100644
--- a/fxjs/cjs_runtimestub.cpp
+++ b/fxjs/cjs_runtimestub.cpp
@@ -29,7 +29,7 @@
   return nullptr;
 }
 
-absl::optional<IJS_Runtime::JS_Error> CJS_RuntimeStub::ExecuteScript(
+std::optional<IJS_Runtime::JS_Error> CJS_RuntimeStub::ExecuteScript(
     const WideString& script) {
-  return absl::nullopt;
+  return std::nullopt;
 }
diff --git a/fxjs/cjs_runtimestub.h b/fxjs/cjs_runtimestub.h
index c58e2c4..e1b96a4 100644
--- a/fxjs/cjs_runtimestub.h
+++ b/fxjs/cjs_runtimestub.h
@@ -27,7 +27,7 @@
   void ReleaseEventContext(IJS_EventContext* pContext) override;
   CPDFSDK_FormFillEnvironment* GetFormFillEnv() const override;
 
-  absl::optional<IJS_Runtime::JS_Error> ExecuteScript(
+  std::optional<IJS_Runtime::JS_Error> ExecuteScript(
       const WideString& script) override;
 
  private:
diff --git a/fxjs/cjs_util.cpp b/fxjs/cjs_util.cpp
index 7efb840..e868fcc 100644
--- a/fxjs/cjs_util.cpp
+++ b/fxjs/cjs_util.cpp
@@ -112,7 +112,7 @@
   {
     size_t offset = 0;
     while (true) {
-      absl::optional<size_t> offset_end =
+      std::optional<size_t> offset_end =
           unsafe_fmt_string.Find(L"%", offset + 1);
       if (!offset_end.has_value()) {
         unsafe_conversion_specifiers.push_back(
diff --git a/fxjs/ijs_event_context.h b/fxjs/ijs_event_context.h
index 8e9d23c..607144f 100644
--- a/fxjs/ijs_event_context.h
+++ b/fxjs/ijs_event_context.h
@@ -7,9 +7,10 @@
 #ifndef FXJS_IJS_EVENT_CONTEXT_H_
 #define FXJS_IJS_EVENT_CONTEXT_H_
 
+#include <optional>
+
 #include "core/fxcrt/widestring.h"
 #include "fxjs/ijs_runtime.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CPDF_FormField;
 
@@ -20,7 +21,7 @@
  public:
   virtual ~IJS_EventContext() = default;
 
-  virtual absl::optional<IJS_Runtime::JS_Error> RunScript(
+  virtual std::optional<IJS_Runtime::JS_Error> RunScript(
       const WideString& script) = 0;
 
   virtual void OnDoc_Open(const WideString& strTargetName) = 0;
diff --git a/fxjs/ijs_runtime.h b/fxjs/ijs_runtime.h
index d2ce19f..827d8ca 100644
--- a/fxjs/ijs_runtime.h
+++ b/fxjs/ijs_runtime.h
@@ -8,11 +8,11 @@
 #define FXJS_IJS_RUNTIME_H_
 
 #include <memory>
+#include <optional>
 
 #include "core/fxcrt/fx_memory.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxcrt/widestring.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CJS_Runtime;
 class CPDFSDK_FormFillEnvironment;
@@ -57,7 +57,7 @@
   virtual IJS_EventContext* NewEventContext() = 0;
   virtual void ReleaseEventContext(IJS_EventContext* pContext) = 0;
   virtual CPDFSDK_FormFillEnvironment* GetFormFillEnv() const = 0;
-  virtual absl::optional<JS_Error> ExecuteScript(const WideString& script) = 0;
+  virtual std::optional<JS_Error> ExecuteScript(const WideString& script) = 0;
 
  protected:
   IJS_Runtime() = default;
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index c0f66a6..94fa0f9 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -180,7 +180,7 @@
       m_FormCalcContext = std::make_unique<CFXJSE_FormCalcContext>(
           GetIsolate(), m_JsContext.get(), m_pDocument.Get());
     }
-    absl::optional<WideTextBuffer> wsJavaScript =
+    std::optional<WideTextBuffer> wsJavaScript =
         CFXJSE_FormCalcContext::Translate(m_pDocument->GetHeap(), wsScript);
     if (!wsJavaScript.has_value()) {
       auto undefined_value = std::make_unique<CFXJSE_Value>();
@@ -209,7 +209,7 @@
   if (!refNode)
     return false;
 
-  absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+  std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
       ResolveObjects(refNode, propname, dwFlag);
   if (!maybeResult.has_value())
     return false;
@@ -236,7 +236,7 @@
   if (!refNode)
     return false;
 
-  absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+  std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
       ResolveObjects(refNode, propname, dwFlag);
   if (!maybeResult.has_value())
     return false;
@@ -426,7 +426,7 @@
           &pReturnValue)) {
     return pReturnValue;
   }
-  absl::optional<XFA_SCRIPTATTRIBUTEINFO> info = XFA_GetScriptAttributeByName(
+  std::optional<XFA_SCRIPTATTRIBUTEINFO> info = XFA_GetScriptAttributeByName(
       pObject->GetElementType(), wsPropName.AsStringView());
   if (info.has_value()) {
     (*info.value().callback)(pIsolate, pObject->JSObject(), &pReturnValue,
@@ -467,7 +467,7 @@
   CXFA_Object* pObject = pScriptContext->GetVariablesThis(pOriginalObject);
   WideString wsPropName = WideString::FromUTF8(szPropName);
   WideStringView wsPropNameView = wsPropName.AsStringView();
-  absl::optional<XFA_SCRIPTATTRIBUTEINFO> info =
+  std::optional<XFA_SCRIPTATTRIBUTEINFO> info =
       XFA_GetScriptAttributeByName(pObject->GetElementType(), wsPropNameView);
   if (info.has_value()) {
     CJX_Object* jsObject = pObject->JSObject();
@@ -526,7 +526,7 @@
     return FXJSE_ClassPropType::kMethod;
 
   if (bQueryIn) {
-    absl::optional<XFA_SCRIPTATTRIBUTEINFO> maybe_info =
+    std::optional<XFA_SCRIPTATTRIBUTEINFO> maybe_info =
         XFA_GetScriptAttributeByName(eType, wsPropName.AsStringView());
     if (!maybe_info.has_value())
       return FXJSE_ClassPropType::kNone;
@@ -611,7 +611,7 @@
   if (!pTextNode)
     return;
 
-  absl::optional<WideString> wsScript =
+  std::optional<WideString> wsScript =
       pTextNode->JSObject()->TryCData(XFA_Attribute::Value, true);
   if (!wsScript.has_value())
     return;
@@ -685,20 +685,20 @@
   fxv8::ReentrantDeleteObjectPropertyHelper(GetIsolate(), pObject, "Date");
 }
 
-absl::optional<CFXJSE_Engine::ResolveResult> CFXJSE_Engine::ResolveObjects(
+std::optional<CFXJSE_Engine::ResolveResult> CFXJSE_Engine::ResolveObjects(
     CXFA_Object* refObject,
     WideStringView wsExpression,
     Mask<XFA_ResolveFlag> dwStyles) {
   return ResolveObjectsWithBindNode(refObject, wsExpression, dwStyles, nullptr);
 }
 
-absl::optional<CFXJSE_Engine::ResolveResult>
+std::optional<CFXJSE_Engine::ResolveResult>
 CFXJSE_Engine::ResolveObjectsWithBindNode(CXFA_Object* refObject,
                                           WideStringView wsExpression,
                                           Mask<XFA_ResolveFlag> dwStyles,
                                           CXFA_Node* bindNode) {
   if (wsExpression.IsEmpty())
-    return absl::nullopt;
+    return std::nullopt;
 
   AutoRestorer<bool> resolving_restorer(&m_bResolvingNodes);
   m_bResolvingNodes = true;
@@ -862,12 +862,12 @@
       result.type = ResolveResult::Type::kExistNodes;
 
     if (result.objects.empty())
-      return absl::nullopt;
+      return std::nullopt;
 
     return result;
   }
   if (nNodes == 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   return result;
 }
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index bcac43c..487bf23 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -133,11 +133,11 @@
                                             WideStringView wsScript,
                                             CXFA_Object* pThisObject);
 
-  absl::optional<ResolveResult> ResolveObjects(CXFA_Object* refObject,
-                                               WideStringView wsExpression,
-                                               Mask<XFA_ResolveFlag> dwStyles);
+  std::optional<ResolveResult> ResolveObjects(CXFA_Object* refObject,
+                                              WideStringView wsExpression,
+                                              Mask<XFA_ResolveFlag> dwStyles);
 
-  absl::optional<ResolveResult> ResolveObjectsWithBindNode(
+  std::optional<ResolveResult> ResolveObjectsWithBindNode(
       CXFA_Object* refObject,
       WideStringView wsExpression,
       Mask<XFA_ResolveFlag> dwStyles,
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index cae2f73..b591122 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -14,6 +14,7 @@
 #include <algorithm>
 #include <limits>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -30,7 +31,6 @@
 #include "fxjs/xfa/cfxjse_engine.h"
 #include "fxjs/xfa/cfxjse_value.h"
 #include "fxjs/xfa/cjx_object.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check_op.h"
 #include "third_party/base/numerics/safe_conversions.h"
 #include "v8/include/v8-container.h"
@@ -1123,8 +1123,8 @@
   return fxv8::ReentrantToDoubleHelper(pIsolate, extracted);
 }
 
-absl::optional<double> ExtractDouble(v8::Isolate* pIsolate,
-                                     v8::Local<v8::Value> src) {
+std::optional<double> ExtractDouble(v8::Isolate* pIsolate,
+                                    v8::Local<v8::Value> src) {
   if (src.IsEmpty())
     return 0.0;
 
@@ -1134,7 +1134,7 @@
   v8::Local<v8::Array> arr = src.As<v8::Array>();
   uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
   if (iLength < 3)
-    return absl::nullopt;
+    return std::nullopt;
 
   v8::Local<v8::Value> propertyValue =
       fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 1);
@@ -1235,7 +1235,7 @@
     return v8::Local<v8::Value>();
 
   CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
-  absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+  std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
       pScriptContext->ResolveObjects(
           pScriptContext->GetThisObject(),
           WideString::FromUTF8(bsAccessorName).AsStringView(),
@@ -1251,7 +1251,7 @@
       maybeResult.value().objects.front().Get());
 }
 
-absl::optional<CFXJSE_Engine::ResolveResult> ResolveObjects(
+std::optional<CFXJSE_Engine::ResolveResult> ResolveObjects(
     CFXJSE_HostObject* pHostObject,
     v8::Local<v8::Value> pRefValue,
     ByteStringView bsSomExp,
@@ -1259,7 +1259,7 @@
     bool bHasNoResolveName) {
   CXFA_Document* pDoc = ToFormCalcContext(pHostObject)->GetDocument();
   if (!pDoc)
-    return absl::nullopt;
+    return std::nullopt;
 
   v8::Isolate* pIsolate = ToFormCalcContext(pHostObject)->GetIsolate();
   WideString wsSomExpression = WideString::FromUTF8(bsSomExp);
@@ -1273,12 +1273,12 @@
     } else {
       pNode = CFXJSE_Engine::ToObject(pIsolate, pRefValue);
       if (!pNode)
-        return absl::nullopt;
+        return std::nullopt;
 
       if (bHasNoResolveName) {
         WideString wsName;
         if (CXFA_Node* pXFANode = pNode->AsNode()) {
-          absl::optional<WideString> ret =
+          std::optional<WideString> ret =
               pXFANode->JSObject()->TryAttribute(XFA_Attribute::Name, false);
           if (ret.has_value())
             wsName = ret.value();
@@ -1516,9 +1516,9 @@
     return;
   }
 
-  absl::optional<double> maybe_dividend =
+  std::optional<double> maybe_dividend =
       ExtractDouble(info.GetIsolate(), info[0]);
-  absl::optional<double> maybe_divisor =
+  std::optional<double> maybe_divisor =
       ExtractDouble(info.GetIsolate(), info[1]);
   if (!maybe_dividend.has_value() || !maybe_divisor.has_value()) {
     pContext->ThrowArgumentMismatchException();
@@ -1552,8 +1552,7 @@
     return;
   }
 
-  absl::optional<double> maybe_value =
-      ExtractDouble(info.GetIsolate(), info[0]);
+  std::optional<double> maybe_value = ExtractDouble(info.GetIsolate(), info[0]);
   if (!maybe_value.has_value()) {
     pContext->ThrowArgumentMismatchException();
     return;
@@ -1566,7 +1565,7 @@
       info.GetReturnValue().SetNull();
       return;
     }
-    absl::optional<double> maybe_precision =
+    std::optional<double> maybe_precision =
         ExtractDouble(info.GetIsolate(), info[1]);
     if (!maybe_precision.has_value()) {
       pContext->ThrowArgumentMismatchException();
@@ -2982,7 +2981,7 @@
   }
 
   WideString wsCalcScript = WideString::FromUTF8(bsUtf8Script.AsStringView());
-  absl::optional<WideTextBuffer> wsJavaScriptBuf =
+  std::optional<WideTextBuffer> wsJavaScriptBuf =
       CFXJSE_FormCalcContext::Translate(pContext->GetDocument()->GetHeap(),
                                         wsCalcScript.AsStringView());
   if (!wsJavaScriptBuf.has_value()) {
@@ -4783,7 +4782,7 @@
   }
 
   WideString wsCalcScript = WideString::FromUTF8(bsArg.AsStringView());
-  absl::optional<WideTextBuffer> wsJavaScriptBuf =
+  std::optional<WideTextBuffer> wsJavaScriptBuf =
       CFXJSE_FormCalcContext::Translate(pContext->GetDocument()->GetHeap(),
                                         wsCalcScript.AsStringView());
   if (!wsJavaScriptBuf.has_value()) {
@@ -4972,7 +4971,7 @@
   return bsSomExp;
 }
 
-absl::optional<WideTextBuffer> CFXJSE_FormCalcContext::Translate(
+std::optional<WideTextBuffer> CFXJSE_FormCalcContext::Translate(
     cppgc::Heap* pHeap,
     WideStringView wsFormcalc) {
   if (wsFormcalc.IsEmpty())
@@ -4982,15 +4981,15 @@
   CXFA_FMParser parser(pHeap, &lexer);
   CXFA_FMAST* ast = parser.Parse();
   if (!ast || parser.HasError())
-    return absl::nullopt;
+    return std::nullopt;
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> wsJavaScript = ast->ToJavaScript();
+  std::optional<WideTextBuffer> wsJavaScript = ast->ToJavaScript();
   if (!wsJavaScript.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (CXFA_IsTooBig(wsJavaScript.value()))
-    return absl::nullopt;
+    return std::nullopt;
 
   return wsJavaScript;
 }
@@ -5062,7 +5061,7 @@
     for (uint32_t i = 2; i < iLength; i++) {
       v8::Local<v8::Value> hJSObjValue =
           fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, i);
-      absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+      std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
           ResolveObjects(pThis, hJSObjValue, bsSomExp.AsStringView(),
                          bDotAccessor, bHasNoResolveName);
       if (maybeResult.has_value()) {
@@ -5091,7 +5090,7 @@
     return;
   }
 
-  absl::optional<CFXJSE_Engine::ResolveResult> maybeResult;
+  std::optional<CFXJSE_Engine::ResolveResult> maybeResult;
   ByteString bsAccessorName =
       fxv8::ReentrantToByteStringHelper(info.GetIsolate(), info[1]);
   if (fxv8::IsObject(argAccessor) ||
diff --git a/fxjs/xfa/cfxjse_formcalc_context.h b/fxjs/xfa/cfxjse_formcalc_context.h
index a0bf84f..79fd891 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.h
+++ b/fxjs/xfa/cfxjse_formcalc_context.h
@@ -10,11 +10,11 @@
 #include <stdint.h>
 
 #include <functional>
+#include <optional>
 
 #include "core/fxcrt/bytestring.h"
 #include "core/fxcrt/widetext_buffer.h"
 #include "fxjs/xfa/fxjse.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "v8/include/cppgc/persistent.h"
 #include "v8/include/v8-forward.h"
 #include "v8/include/v8-persistent-handle.h"
@@ -267,8 +267,8 @@
   static void concat_fm_object(CFXJSE_HostObject* pThis,
                                const v8::FunctionCallbackInfo<v8::Value>& info);
 
-  static absl::optional<WideTextBuffer> Translate(cppgc::Heap* pHeap,
-                                                  WideStringView wsFormcalc);
+  static std::optional<WideTextBuffer> Translate(cppgc::Heap* pHeap,
+                                                 WideStringView wsFormcalc);
 
   v8::Local<v8::Value> GlobalPropertyGetter();
   v8::Isolate* GetIsolate() const { return m_pIsolate; }
diff --git a/fxjs/xfa/cfxjse_mapmodule.cpp b/fxjs/xfa/cfxjse_mapmodule.cpp
index 7e656b8..1e43a3a 100644
--- a/fxjs/xfa/cfxjse_mapmodule.cpp
+++ b/fxjs/xfa/cfxjse_mapmodule.cpp
@@ -32,25 +32,25 @@
   m_MeasurementMap[key] = measurement;
 }
 
-absl::optional<int32_t> CFXJSE_MapModule::GetValue(uint32_t key) const {
+std::optional<int32_t> CFXJSE_MapModule::GetValue(uint32_t key) const {
   auto it = m_ValueMap.find(key);
   if (it == m_ValueMap.end())
-    return absl::nullopt;
+    return std::nullopt;
   return it->second;
 }
 
-absl::optional<WideString> CFXJSE_MapModule::GetString(uint32_t key) const {
+std::optional<WideString> CFXJSE_MapModule::GetString(uint32_t key) const {
   auto it = m_StringMap.find(key);
   if (it == m_StringMap.end())
-    return absl::nullopt;
+    return std::nullopt;
   return it->second;
 }
 
-absl::optional<CXFA_Measurement> CFXJSE_MapModule::GetMeasurement(
+std::optional<CXFA_Measurement> CFXJSE_MapModule::GetMeasurement(
     uint32_t key) const {
   auto it = m_MeasurementMap.find(key);
   if (it == m_MeasurementMap.end())
-    return absl::nullopt;
+    return std::nullopt;
   return it->second;
 }
 
diff --git a/fxjs/xfa/cfxjse_mapmodule.h b/fxjs/xfa/cfxjse_mapmodule.h
index 9c75750..81b8f9c 100644
--- a/fxjs/xfa/cfxjse_mapmodule.h
+++ b/fxjs/xfa/cfxjse_mapmodule.h
@@ -10,9 +10,9 @@
 #include <stdint.h>
 
 #include <map>
+#include <optional>
 
 #include "core/fxcrt/widestring.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CXFA_Measurement;
 
@@ -27,9 +27,9 @@
   void SetValue(uint32_t key, int32_t value);
   void SetString(uint32_t key, const WideString& wsString);
   void SetMeasurement(uint32_t key, const CXFA_Measurement& measurement);
-  absl::optional<int32_t> GetValue(uint32_t key) const;
-  absl::optional<WideString> GetString(uint32_t key) const;
-  absl::optional<CXFA_Measurement> GetMeasurement(uint32_t key) const;
+  std::optional<int32_t> GetValue(uint32_t key) const;
+  std::optional<WideString> GetString(uint32_t key) const;
+  std::optional<CXFA_Measurement> GetMeasurement(uint32_t key) const;
   bool HasKey(uint32_t key) const;
   void RemoveKey(uint32_t key);
   void MergeDataFrom(const CFXJSE_MapModule* pSrc);
diff --git a/fxjs/xfa/cfxjse_mapmodule_unittest.cpp b/fxjs/xfa/cfxjse_mapmodule_unittest.cpp
index 3119b58..1a65bed 100644
--- a/fxjs/xfa/cfxjse_mapmodule_unittest.cpp
+++ b/fxjs/xfa/cfxjse_mapmodule_unittest.cpp
@@ -6,9 +6,10 @@
 
 #include "fxjs/xfa/cfxjse_mapmodule.h"
 
+#include <optional>
+
 #include "core/fxcrt/fx_string.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "xfa/fxfa/parser/cxfa_measurement.h"
 
 TEST(CFXJSEMapModule, EmptyModule) {
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.cpp b/fxjs/xfa/cfxjse_resolveprocessor.cpp
index 2829672..fad97d3 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.cpp
+++ b/fxjs/xfa/cfxjse_resolveprocessor.cpp
@@ -213,7 +213,7 @@
     CXFA_Object* curNode,
     CFXJSE_Engine::ResolveResult* rnd,
     WideStringView strAttr) {
-  absl::optional<XFA_SCRIPTATTRIBUTEINFO> info =
+  std::optional<XFA_SCRIPTATTRIBUTEINFO> info =
       XFA_GetScriptAttributeByName(curNode->GetElementType(), strAttr);
   if (!info.has_value())
     return false;
diff --git a/fxjs/xfa/cjx_field.cpp b/fxjs/xfa/cjx_field.cpp
index 7c21b95..c9e2b51 100644
--- a/fxjs/xfa/cjx_field.cpp
+++ b/fxjs/xfa/cjx_field.cpp
@@ -109,7 +109,7 @@
   if (!node->IsWidgetReady())
     return CJS_Result::Success(runtime->NewNull());
 
-  absl::optional<WideString> value = node->GetChoiceListItem(iIndex, true);
+  std::optional<WideString> value = node->GetChoiceListItem(iIndex, true);
   if (!value.has_value())
     return CJS_Result::Success(runtime->NewNull());
 
@@ -172,7 +172,7 @@
   if (!node->IsWidgetReady())
     return CJS_Result::Success(runtime->NewNull());
 
-  absl::optional<WideString> value = node->GetChoiceListItem(iIndex, false);
+  std::optional<WideString> value = node->GetChoiceListItem(iIndex, false);
   if (!value.has_value())
     return CJS_Result::Success(runtime->NewNull());
 
diff --git a/fxjs/xfa/cjx_form.cpp b/fxjs/xfa/cjx_form.cpp
index 462b47a..9513786 100644
--- a/fxjs/xfa/cjx_form.cpp
+++ b/fxjs/xfa/cjx_form.cpp
@@ -136,7 +136,7 @@
     return;
   }
 
-  absl::optional<WideString> checksum =
+  std::optional<WideString> checksum =
       TryAttribute(XFA_Attribute::Checksum, false);
   *pValue = fxv8::NewStringHelper(
       pIsolate,
diff --git a/fxjs/xfa/cjx_hostpseudomodel.cpp b/fxjs/xfa/cjx_hostpseudomodel.cpp
index 00a6eb1..8bdd809 100644
--- a/fxjs/xfa/cjx_hostpseudomodel.cpp
+++ b/fxjs/xfa/cjx_hostpseudomodel.cpp
@@ -300,7 +300,7 @@
     constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
                                               XFA_ResolveFlag::kParent,
                                               XFA_ResolveFlag::kSiblings};
-    absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+    std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
         runtime->ResolveObjects(
             pObject, runtime->ToWideString(params[0]).AsStringView(), kFlags);
     if (!maybeResult.has_value() ||
@@ -385,7 +385,7 @@
     constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
                                               XFA_ResolveFlag::kParent,
                                               XFA_ResolveFlag::kSiblings};
-    absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+    std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
         runtime->ResolveObjects(pObject, wsName.AsStringView(), kFlags);
     if (!maybeResult.has_value() ||
         !maybeResult.value().objects.front()->IsNode())
@@ -448,7 +448,7 @@
       constexpr Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
                                                 XFA_ResolveFlag::kParent,
                                                 XFA_ResolveFlag::kSiblings};
-      absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+      std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
           runtime->ResolveObjects(
               pObject, runtime->ToWideString(params[0]).AsStringView(), kFlags);
       if (!maybeResult.has_value() ||
diff --git a/fxjs/xfa/cjx_node.cpp b/fxjs/xfa/cjx_node.cpp
index d7e2c06..bdae56e 100644
--- a/fxjs/xfa/cjx_node.cpp
+++ b/fxjs/xfa/cjx_node.cpp
@@ -175,7 +175,7 @@
     return CJS_Result::Failure(JSMessage::kParamError);
 
   WideString expression = runtime->ToWideString(params[0]);
-  absl::optional<XFA_ATTRIBUTEINFO> attr =
+  std::optional<XFA_ATTRIBUTEINFO> attr =
       XFA_GetAttributeByName(expression.AsStringView());
   if (attr.has_value() && HasAttribute(attr.value().attribute))
     return CJS_Result::Success(runtime->NewBoolean(true));
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index 2479b4a..f68cdc2 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -218,7 +218,7 @@
                                     bool bNotify) {
   switch (GetXFANode()->GetAttributeType(eAttr)) {
     case XFA_AttributeType::Enum: {
-      absl::optional<XFA_AttributeValue> item =
+      std::optional<XFA_AttributeValue> item =
           XFA_GetAttributeValueByName(wsValue.AsStringView());
       SetEnum(eAttr,
               item.has_value() ? item.value()
@@ -246,7 +246,7 @@
 
 void CJX_Object::SetAttributeByString(WideStringView wsAttr,
                                       const WideString& wsValue) {
-  absl::optional<XFA_ATTRIBUTEINFO> attr = XFA_GetAttributeByName(wsAttr);
+  std::optional<XFA_ATTRIBUTEINFO> attr = XFA_GetAttributeByName(wsAttr);
   if (attr.has_value()) {
     SetAttributeByEnum(attr.value().attribute, wsValue, true);
     return;
@@ -256,8 +256,8 @@
 }
 
 WideString CJX_Object::GetAttributeByString(WideStringView attr) const {
-  absl::optional<WideString> result;
-  absl::optional<XFA_ATTRIBUTEINFO> enum_attr = XFA_GetAttributeByName(attr);
+  std::optional<WideString> result;
+  std::optional<XFA_ATTRIBUTEINFO> enum_attr = XFA_GetAttributeByName(attr);
   if (enum_attr.has_value())
     result = TryAttribute(enum_attr.value().attribute, true);
   else
@@ -269,52 +269,52 @@
   return TryAttribute(attr, true).value_or(WideString());
 }
 
-absl::optional<WideString> CJX_Object::TryAttribute(XFA_Attribute eAttr,
-                                                    bool bUseDefault) const {
+std::optional<WideString> CJX_Object::TryAttribute(XFA_Attribute eAttr,
+                                                   bool bUseDefault) const {
   switch (GetXFANode()->GetAttributeType(eAttr)) {
     case XFA_AttributeType::Enum: {
-      absl::optional<XFA_AttributeValue> value = TryEnum(eAttr, bUseDefault);
+      std::optional<XFA_AttributeValue> value = TryEnum(eAttr, bUseDefault);
       if (!value.has_value())
-        return absl::nullopt;
+        return std::nullopt;
       return WideString::FromASCII(XFA_AttributeValueToName(value.value()));
     }
     case XFA_AttributeType::CData:
       return TryCData(eAttr, bUseDefault);
 
     case XFA_AttributeType::Boolean: {
-      absl::optional<bool> value = TryBoolean(eAttr, bUseDefault);
+      std::optional<bool> value = TryBoolean(eAttr, bUseDefault);
       if (!value.has_value())
-        return absl::nullopt;
+        return std::nullopt;
       return WideString(value.value() ? L"1" : L"0");
     }
     case XFA_AttributeType::Integer: {
-      absl::optional<int32_t> iValue = TryInteger(eAttr, bUseDefault);
+      std::optional<int32_t> iValue = TryInteger(eAttr, bUseDefault);
       if (!iValue.has_value())
-        return absl::nullopt;
+        return std::nullopt;
       return WideString::FormatInteger(iValue.value());
     }
     case XFA_AttributeType::Measure: {
-      absl::optional<CXFA_Measurement> value = TryMeasure(eAttr, bUseDefault);
+      std::optional<CXFA_Measurement> value = TryMeasure(eAttr, bUseDefault);
       if (!value.has_value())
-        return absl::nullopt;
+        return std::nullopt;
       return value->ToString();
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void CJX_Object::RemoveAttribute(WideStringView wsAttr) {
   RemoveMapModuleKey(GetMapKey_Custom(wsAttr));
 }
 
-absl::optional<bool> CJX_Object::TryBoolean(XFA_Attribute eAttr,
-                                            bool bUseDefault) const {
+std::optional<bool> CJX_Object::TryBoolean(XFA_Attribute eAttr,
+                                           bool bUseDefault) const {
   uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
-  absl::optional<int32_t> value = GetMapModuleValueFollowingChain(key);
+  std::optional<int32_t> value = GetMapModuleValueFollowingChain(key);
   if (value.has_value())
     return !!value.value();
   if (!bUseDefault)
-    return absl::nullopt;
+    return std::nullopt;
   return GetXFANode()->GetDefaultBoolean(eAttr);
 }
 
@@ -342,25 +342,25 @@
   return TryInteger(eAttr, true).value_or(0);
 }
 
-absl::optional<int32_t> CJX_Object::TryInteger(XFA_Attribute eAttr,
-                                               bool bUseDefault) const {
+std::optional<int32_t> CJX_Object::TryInteger(XFA_Attribute eAttr,
+                                              bool bUseDefault) const {
   uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
-  absl::optional<int32_t> value = GetMapModuleValueFollowingChain(key);
+  std::optional<int32_t> value = GetMapModuleValueFollowingChain(key);
   if (value.has_value())
     return value.value();
   if (!bUseDefault)
-    return absl::nullopt;
+    return std::nullopt;
   return GetXFANode()->GetDefaultInteger(eAttr);
 }
 
-absl::optional<XFA_AttributeValue> CJX_Object::TryEnum(XFA_Attribute eAttr,
-                                                       bool bUseDefault) const {
+std::optional<XFA_AttributeValue> CJX_Object::TryEnum(XFA_Attribute eAttr,
+                                                      bool bUseDefault) const {
   uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
-  absl::optional<int32_t> value = GetMapModuleValueFollowingChain(key);
+  std::optional<int32_t> value = GetMapModuleValueFollowingChain(key);
   if (value.has_value())
     return static_cast<XFA_AttributeValue>(value.value());
   if (!bUseDefault)
-    return absl::nullopt;
+    return std::nullopt;
   return GetXFANode()->GetDefaultEnum(eAttr);
 }
 
@@ -391,23 +391,22 @@
     OnChanged(eAttr, false);
 }
 
-absl::optional<CXFA_Measurement> CJX_Object::TryMeasure(
-    XFA_Attribute eAttr,
-    bool bUseDefault) const {
+std::optional<CXFA_Measurement> CJX_Object::TryMeasure(XFA_Attribute eAttr,
+                                                       bool bUseDefault) const {
   uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
-  absl::optional<CXFA_Measurement> result =
+  std::optional<CXFA_Measurement> result =
       GetMapModuleMeasurementFollowingChain(key);
   if (result.has_value())
     return result.value();
   if (!bUseDefault)
-    return absl::nullopt;
+    return std::nullopt;
   return GetXFANode()->GetDefaultMeasurement(eAttr);
 }
 
-absl::optional<float> CJX_Object::TryMeasureAsFloat(XFA_Attribute attr) const {
-  absl::optional<CXFA_Measurement> measure = TryMeasure(attr, false);
+std::optional<float> CJX_Object::TryMeasureAsFloat(XFA_Attribute attr) const {
+  std::optional<CXFA_Measurement> measure = TryMeasure(attr, false);
   if (!measure.has_value())
-    return absl::nullopt;
+    return std::nullopt;
   return measure->ToUnit(XFA_Unit::Pt);
 }
 
@@ -433,7 +432,7 @@
                               bool bScriptModify) {
   CXFA_Node* xfaObj = GetXFANode();
   uint32_t key = GetMapKey_Element(xfaObj->GetElementType(), eAttr);
-  absl::optional<WideString> old_value = GetMapModuleString(key);
+  std::optional<WideString> old_value = GetMapModuleString(key);
   if (!old_value.has_value() || old_value.value() != wsValue) {
     if (bNotify)
       OnChanging(eAttr);
@@ -483,7 +482,7 @@
   auto* xfaObj = GetXFANode();
   uint32_t key =
       GetMapKey_Element(xfaObj->GetElementType(), XFA_Attribute::Value);
-  absl::optional<WideString> old_value = GetMapModuleString(key);
+  std::optional<WideString> old_value = GetMapModuleString(key);
   if (!old_value.has_value() || old_value.value() != wsValue) {
     if (bNotify)
       OnChanging(XFA_Attribute::Value);
@@ -495,15 +494,15 @@
   }
 }
 
-absl::optional<WideString> CJX_Object::TryCData(XFA_Attribute eAttr,
-                                                bool bUseDefault) const {
+std::optional<WideString> CJX_Object::TryCData(XFA_Attribute eAttr,
+                                               bool bUseDefault) const {
   uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
-  absl::optional<WideString> value = GetMapModuleStringFollowingChain(key);
+  std::optional<WideString> value = GetMapModuleStringFollowingChain(key);
   if (value.has_value())
     return value;
 
   if (!bUseDefault)
-    return absl::nullopt;
+    return std::nullopt;
 
   return GetXFANode()->GetDefaultCData(eAttr);
 }
@@ -512,7 +511,7 @@
                                      int32_t value,
                                      bool bNotify) {
   uint32_t key = GetMapKey_Element(GetXFAObject()->GetElementType(), eAttr);
-  absl::optional<int32_t> old_value = GetMapModuleValue(key);
+  std::optional<int32_t> old_value = GetMapModuleValue(key);
   if (!old_value.has_value() || old_value.value() != value) {
     if (bNotify)
       OnChanging(eAttr);
@@ -623,7 +622,7 @@
     case XFA_ObjectType::ContentNode: {
       WideString wsContentType;
       if (GetXFANode()->GetElementType() == XFA_Element::ExData) {
-        absl::optional<WideString> ret =
+        std::optional<WideString> ret =
             TryAttribute(XFA_Attribute::ContentType, false);
         if (ret.has_value())
           wsContentType = ret.value();
@@ -690,8 +689,8 @@
   return TryContent(bScriptModify, true).value_or(WideString());
 }
 
-absl::optional<WideString> CJX_Object::TryContent(bool bScriptModify,
-                                                  bool bProto) const {
+std::optional<WideString> CJX_Object::TryContent(bool bScriptModify,
+                                                 bool bProto) const {
   CXFA_Node* pNode = nullptr;
   switch (GetXFANode()->GetObjectType()) {
     case XFA_ObjectType::ContainerNode:
@@ -701,7 +700,7 @@
         CXFA_Value* pValue =
             GetXFANode()->GetChild<CXFA_Value>(0, XFA_Element::Value, false);
         if (!pValue)
-          return absl::nullopt;
+          return std::nullopt;
 
         CXFA_Node* pChildValue = pValue->GetFirstChild();
         if (pChildValue && XFA_FieldIsMultiListBox(GetXFANode())) {
@@ -709,7 +708,7 @@
               XFA_Attribute::ContentType, L"text/xml", false);
         }
         if (!pChildValue)
-          return absl::nullopt;
+          return std::nullopt;
         return pChildValue->JSObject()->TryContent(bScriptModify, bProto);
       }
       break;
@@ -718,7 +717,7 @@
       if (!pContentRawDataNode) {
         XFA_Element element = XFA_Element::Sharptext;
         if (GetXFANode()->GetElementType() == XFA_Element::ExData) {
-          absl::optional<WideString> contentType =
+          std::optional<WideString> contentType =
               TryAttribute(XFA_Attribute::ContentType, false);
           if (contentType.has_value()) {
             if (contentType.value().EqualsASCII("text/html"))
@@ -749,16 +748,16 @@
     }
     return TryCData(XFA_Attribute::Value, false);
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<WideString> CJX_Object::TryNamespace() const {
+std::optional<WideString> CJX_Object::TryNamespace() const {
   if (GetXFANode()->IsModelNode() ||
       GetXFANode()->GetElementType() == XFA_Element::Packet) {
     CFX_XMLNode* pXMLNode = GetXFANode()->GetXMLMappingNode();
     CFX_XMLElement* element = ToXMLElement(pXMLNode);
     if (!element)
-      return absl::nullopt;
+      return std::nullopt;
 
     return element->GetNamespaceURI();
   }
@@ -769,14 +768,14 @@
   CFX_XMLNode* pXMLNode = GetXFANode()->GetXMLMappingNode();
   CFX_XMLElement* element = ToXMLElement(pXMLNode);
   if (!element)
-    return absl::nullopt;
+    return std::nullopt;
 
   if (GetXFANode()->GetElementType() == XFA_Element::DataValue &&
       GetEnum(XFA_Attribute::Contains) == XFA_AttributeValue::MetaData) {
     WideString wsNamespace;
     if (!XFA_FDEExtension_ResolveNamespaceQualifier(
             element, GetCData(XFA_Attribute::QualifiedName), &wsNamespace)) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     return wsNamespace;
   }
@@ -816,29 +815,29 @@
   CreateMapModule()->SetMeasurement(key, value);
 }
 
-absl::optional<int32_t> CJX_Object::GetMapModuleValue(uint32_t key) const {
+std::optional<int32_t> CJX_Object::GetMapModuleValue(uint32_t key) const {
   CFXJSE_MapModule* pModule = GetMapModule();
   if (!pModule)
-    return absl::nullopt;
+    return std::nullopt;
   return pModule->GetValue(key);
 }
 
-absl::optional<WideString> CJX_Object::GetMapModuleString(uint32_t key) const {
+std::optional<WideString> CJX_Object::GetMapModuleString(uint32_t key) const {
   CFXJSE_MapModule* pModule = GetMapModule();
   if (!pModule)
-    return absl::nullopt;
+    return std::nullopt;
   return pModule->GetString(key);
 }
 
-absl::optional<CXFA_Measurement> CJX_Object::GetMapModuleMeasurement(
+std::optional<CXFA_Measurement> CJX_Object::GetMapModuleMeasurement(
     uint32_t key) const {
   CFXJSE_MapModule* pModule = GetMapModule();
   if (!pModule)
-    return absl::nullopt;
+    return std::nullopt;
   return pModule->GetMeasurement(key);
 }
 
-absl::optional<int32_t> CJX_Object::GetMapModuleValueFollowingChain(
+std::optional<int32_t> CJX_Object::GetMapModuleValueFollowingChain(
     uint32_t key) const {
   std::set<const CXFA_Node*> visited;
   for (const CXFA_Node* pNode = GetXFANode(); pNode;
@@ -846,17 +845,17 @@
     if (!visited.insert(pNode).second)
       break;
 
-    absl::optional<int32_t> result = pNode->JSObject()->GetMapModuleValue(key);
+    std::optional<int32_t> result = pNode->JSObject()->GetMapModuleValue(key);
     if (result.has_value())
       return result;
 
     if (pNode->GetPacketType() == XFA_PacketType::Datasets)
       break;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<WideString> CJX_Object::GetMapModuleStringFollowingChain(
+std::optional<WideString> CJX_Object::GetMapModuleStringFollowingChain(
     uint32_t key) const {
   std::set<const CXFA_Node*> visited;
   for (const CXFA_Node* pNode = GetXFANode(); pNode;
@@ -864,7 +863,7 @@
     if (!visited.insert(pNode).second)
       break;
 
-    absl::optional<WideString> result =
+    std::optional<WideString> result =
         pNode->JSObject()->GetMapModuleString(key);
     if (result.has_value())
       return result;
@@ -872,10 +871,10 @@
     if (pNode->GetPacketType() == XFA_PacketType::Datasets)
       break;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<CXFA_Measurement>
+std::optional<CXFA_Measurement>
 CJX_Object::GetMapModuleMeasurementFollowingChain(uint32_t key) const {
   std::set<const CXFA_Node*> visited;
   for (const CXFA_Node* pNode = GetXFANode(); pNode;
@@ -883,7 +882,7 @@
     if (!visited.insert(pNode).second)
       break;
 
-    absl::optional<CXFA_Measurement> result =
+    std::optional<CXFA_Measurement> result =
         pNode->JSObject()->GetMapModuleMeasurement(key);
     if (result.has_value())
       return result;
@@ -891,7 +890,7 @@
     if (pNode->GetPacketType() == XFA_PacketType::Datasets)
       break;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 bool CJX_Object::HasMapModuleKey(uint32_t key) const {
@@ -1015,7 +1014,7 @@
 
   CXFA_Node* pProtoNode = nullptr;
   if (!wsSOM.IsEmpty()) {
-    absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+    std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
         GetDocument()->GetScriptContext()->ResolveObjects(
             pProtoRoot, wsSOM.AsStringView(),
             Mask<XFA_ResolveFlag>{
diff --git a/fxjs/xfa/cjx_object.h b/fxjs/xfa/cjx_object.h
index fb98185..1736d2a 100644
--- a/fxjs/xfa/cjx_object.h
+++ b/fxjs/xfa/cjx_object.h
@@ -9,13 +9,13 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/widestring.h"
 #include "fxjs/gc/heap.h"
 #include "fxjs/xfa/fxjse.h"
 #include "fxjs/xfa/jse_define.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 #include "v8/include/cppgc/garbage-collected.h"
 #include "v8/include/cppgc/member.h"
@@ -126,8 +126,8 @@
   bool HasAttribute(XFA_Attribute eAttr) const;
   WideString GetAttributeByString(WideStringView attr) const;
   WideString GetAttributeByEnum(XFA_Attribute attr) const;
-  absl::optional<WideString> TryAttribute(XFA_Attribute eAttr,
-                                          bool bUseDefault) const;
+  std::optional<WideString> TryAttribute(XFA_Attribute eAttr,
+                                         bool bUseDefault) const;
   void SetAttributeByEnum(XFA_Attribute eAttr,
                           const WideString& wsValue,
                           bool bNotify);
@@ -135,7 +135,7 @@
   void RemoveAttribute(WideStringView wsAttr);
 
   WideString GetContent(bool bScriptModify) const;
-  absl::optional<WideString> TryContent(bool bScriptModify, bool bProto) const;
+  std::optional<WideString> TryContent(bool bScriptModify, bool bProto) const;
   void SetContent(const WideString& wsContent,
                   const WideString& wsXMLValue,
                   bool bNotify,
@@ -172,32 +172,32 @@
   JSE_PROP(ScriptSomInstanceIndex);
   JSE_PROP(ScriptSubmitFormatMode);
 
-  absl::optional<WideString> TryNamespace() const;
+  std::optional<WideString> TryNamespace() const;
 
   int32_t GetInteger(XFA_Attribute eAttr) const;
-  absl::optional<int32_t> TryInteger(XFA_Attribute eAttr,
-                                     bool bUseDefault) const;
+  std::optional<int32_t> TryInteger(XFA_Attribute eAttr,
+                                    bool bUseDefault) const;
   void SetInteger(XFA_Attribute eAttr, int32_t iValue, bool bNotify);
 
   WideString GetCData(XFA_Attribute eAttr) const;
-  absl::optional<WideString> TryCData(XFA_Attribute eAttr,
-                                      bool bUseDefault) const;
+  std::optional<WideString> TryCData(XFA_Attribute eAttr,
+                                     bool bUseDefault) const;
   void SetCData(XFA_Attribute eAttr, const WideString& wsValue);
 
   XFA_AttributeValue GetEnum(XFA_Attribute eAttr) const;
-  absl::optional<XFA_AttributeValue> TryEnum(XFA_Attribute eAttr,
-                                             bool bUseDefault) const;
+  std::optional<XFA_AttributeValue> TryEnum(XFA_Attribute eAttr,
+                                            bool bUseDefault) const;
   void SetEnum(XFA_Attribute eAttr, XFA_AttributeValue eValue, bool bNotify);
 
   bool GetBoolean(XFA_Attribute eAttr) const;
-  absl::optional<bool> TryBoolean(XFA_Attribute eAttr, bool bUseDefault) const;
+  std::optional<bool> TryBoolean(XFA_Attribute eAttr, bool bUseDefault) const;
   void SetBoolean(XFA_Attribute eAttr, bool bValue, bool bNotify);
 
   CXFA_Measurement GetMeasure(XFA_Attribute eAttr) const;
   float GetMeasureInUnit(XFA_Attribute eAttr, XFA_Unit unit) const;
-  absl::optional<CXFA_Measurement> TryMeasure(XFA_Attribute eAttr,
-                                              bool bUseDefault) const;
-  absl::optional<float> TryMeasureAsFloat(XFA_Attribute attr) const;
+  std::optional<CXFA_Measurement> TryMeasure(XFA_Attribute eAttr,
+                                             bool bUseDefault) const;
+  std::optional<float> TryMeasureAsFloat(XFA_Attribute attr) const;
   void SetMeasure(XFA_Attribute eAttr,
                   const CXFA_Measurement& mValue,
                   bool bNotify);
@@ -261,13 +261,13 @@
   void SetMapModuleValue(uint32_t key, int32_t value);
   void SetMapModuleString(uint32_t key, const WideString& wsValue);
   void SetMapModuleMeasurement(uint32_t key, const CXFA_Measurement& value);
-  absl::optional<int32_t> GetMapModuleValue(uint32_t key) const;
-  absl::optional<WideString> GetMapModuleString(uint32_t key) const;
-  absl::optional<CXFA_Measurement> GetMapModuleMeasurement(uint32_t key) const;
-  absl::optional<int32_t> GetMapModuleValueFollowingChain(uint32_t key) const;
-  absl::optional<WideString> GetMapModuleStringFollowingChain(
+  std::optional<int32_t> GetMapModuleValue(uint32_t key) const;
+  std::optional<WideString> GetMapModuleString(uint32_t key) const;
+  std::optional<CXFA_Measurement> GetMapModuleMeasurement(uint32_t key) const;
+  std::optional<int32_t> GetMapModuleValueFollowingChain(uint32_t key) const;
+  std::optional<WideString> GetMapModuleStringFollowingChain(
       uint32_t key) const;
-  absl::optional<CXFA_Measurement> GetMapModuleMeasurementFollowingChain(
+  std::optional<CXFA_Measurement> GetMapModuleMeasurementFollowingChain(
       uint32_t key) const;
   bool HasMapModuleKey(uint32_t key) const;
   void RemoveMapModuleKey(uint32_t key);
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp
index 8fe54e4..76b3a3c 100644
--- a/fxjs/xfa/cjx_tree.cpp
+++ b/fxjs/xfa/cjx_tree.cpp
@@ -47,7 +47,7 @@
   if (pRefNode->GetElementType() == XFA_Element::Xfa)
     pRefNode = runtime->GetThisObject();
 
-  absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+  std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
       runtime->ResolveObjects(
           ToNode(pRefNode), wsExpression.AsStringView(),
           Mask<XFA_ResolveFlag>{
@@ -216,7 +216,7 @@
   pDoc->GetNodeOwner()->PersistList(pNodeList);
 
   CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
-  absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+  std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
       pScriptContext->ResolveObjects(refNode, wsExpression.AsStringView(),
                                      dwFlag);
 
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index dcc9f49..deebd73 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -14,6 +14,7 @@
 #include <iterator>
 #include <map>
 #include <memory>
+#include <optional>
 #include <sstream>
 #include <string>
 #include <vector>
@@ -44,7 +45,6 @@
 #include "testing/utils/file_util.h"
 #include "testing/utils/hash.h"
 #include "testing/utils/path_service.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check_op.h"
 
 #ifdef _WIN32
@@ -229,7 +229,7 @@
   return flags;
 }
 
-absl::optional<std::string> ExpandDirectoryPath(const std::string& path) {
+std::optional<std::string> ExpandDirectoryPath(const std::string& path) {
 #if defined(WORDEXP_AVAILABLE)
   wordexp_t expansion;
   if (wordexp(path.c_str(), &expansion, 0) != 0 || expansion.we_wordc < 1) {
@@ -238,7 +238,7 @@
   }
   // Need to contruct the return value before hand, since wordfree will
   // deallocate |expansion|.
-  absl::optional<std::string> ret_val = {expansion.we_wordv[0]};
+  std::optional<std::string> ret_val = {expansion.we_wordv[0]};
   wordfree(&expansion);
   return ret_val;
 #else
@@ -246,7 +246,7 @@
 #endif  // WORDEXP_AVAILABLE
 }
 
-absl::optional<const char*> GetCustomFontPath(const Options& options) {
+std::optional<const char*> GetCustomFontPath(const Options& options) {
 #if defined(__APPLE__) || (defined(__linux__) && !defined(__ANDROID__))
   // Set custom font path to an empty path. This avoids the fallback to default
   // font paths.
@@ -256,7 +256,7 @@
 
   // No custom font path. Use default.
   if (options.font_directory.empty())
-    return absl::nullopt;
+    return std::nullopt;
 
   // Set custom font path to |options.font_directory|.
   return options.font_directory.c_str();
@@ -608,7 +608,7 @@
         return false;
       }
       std::string path = value;
-      absl::optional<std::string> expanded_path = ExpandDirectoryPath(path);
+      std::optional<std::string> expanded_path = ExpandDirectoryPath(path);
       if (!expanded_path.has_value()) {
         fprintf(stderr, "Failed to expand --font-dir, %s\n", path.c_str());
         return false;
@@ -663,7 +663,7 @@
         return false;
       }
       std::string path = value;
-      absl::optional<std::string> expanded_path = ExpandDirectoryPath(path);
+      std::optional<std::string> expanded_path = ExpandDirectoryPath(path);
       if (!expanded_path.has_value()) {
         fprintf(stderr, "Failed to expand --bin-dir, %s\n", path.c_str());
         return false;
@@ -1930,7 +1930,7 @@
 #endif  // PDF_ENABLE_V8
 
   const char* path_array[2] = {nullptr, nullptr};
-  absl::optional<const char*> custom_font_path = GetCustomFontPath(options);
+  std::optional<const char*> custom_font_path = GetCustomFontPath(options);
   if (custom_font_path.has_value()) {
     path_array[0] = custom_font_path.value();
     config.m_pUserFontPaths = path_array;
diff --git a/testing/scoped_set_tz.h b/testing/scoped_set_tz.h
index 5928958..6b1d284 100644
--- a/testing/scoped_set_tz.h
+++ b/testing/scoped_set_tz.h
@@ -5,10 +5,10 @@
 #ifndef TESTING_SCOPED_SET_TZ_H_
 #define TESTING_SCOPED_SET_TZ_H_
 
+#include <optional>
 #include <string>
 
 #include "core/fxcrt/fx_memory.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class ScopedSetTZ {
  public:
@@ -20,7 +20,7 @@
   ~ScopedSetTZ();
 
  private:
-  absl::optional<std::string> old_tz_;
+  std::optional<std::string> old_tz_;
 };
 
 #endif  // TESTING_SCOPED_SET_TZ_H_
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index eef78ea..eb3d8ae 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -444,13 +444,13 @@
     flags |= FXFONT_FIXED_PITCH;
   }
 
-  absl::optional<std::array<uint32_t, 2>> code_page_range =
+  std::optional<std::array<uint32_t, 2>> code_page_range =
       face->GetOs2CodePageRange();
   if (code_page_range.has_value() && (code_page_range.value()[0] & (1 << 31))) {
     flags |= FXFONT_SYMBOLIC;
   }
 
-  absl::optional<std::array<uint8_t, 2>> panose = face->GetOs2Panose();
+  std::optional<std::array<uint8_t, 2>> panose = face->GetOs2Panose();
   if (panose.has_value() && panose.value()[0] == 2) {
     uint8_t serif = panose.value()[1];
     if ((serif > 1 && serif < 10) || serif > 13) {
@@ -722,7 +722,7 @@
 
   // TODO(crbug.com/pdfium/2085): Use make_span() in fewer places after updating
   // pdfium::span.
-  absl::optional<std::array<uint32_t, 4>> unicode_range =
+  std::optional<std::array<uint32_t, 4>> unicode_range =
       pFace->GetOs2UnicodeRange();
   auto usb_span = pdfium::make_span(pFont->m_dwUsb);
   if (unicode_range.has_value()) {
@@ -731,7 +731,7 @@
     fxcrt::spanclr(usb_span);
   }
 
-  absl::optional<std::array<uint32_t, 2>> code_page_range =
+  std::optional<std::array<uint32_t, 2>> code_page_range =
       pFace->GetOs2CodePageRange();
   auto csb_span = pdfium::make_span(pFont->m_dwCsb);
   if (code_page_range.has_value()) {
diff --git a/xfa/fgas/font/cfgas_gefont.cpp b/xfa/fgas/font/cfgas_gefont.cpp
index 35e8de5..4a4a99b 100644
--- a/xfa/fgas/font/cfgas_gefont.cpp
+++ b/xfa/fgas/font/cfgas_gefont.cpp
@@ -150,7 +150,7 @@
   return dwStyles;
 }
 
-absl::optional<uint16_t> CFGAS_GEFont::GetCharWidth(wchar_t wUnicode) {
+std::optional<uint16_t> CFGAS_GEFont::GetCharWidth(wchar_t wUnicode) {
   auto it = m_CharWidthMap.find(wUnicode);
   if (it != m_CharWidthMap.end())
     return it->second;
@@ -159,23 +159,23 @@
   int32_t glyph;
   std::tie(glyph, pFont) = GetGlyphIndexAndFont(wUnicode, true);
   if (!pFont || glyph == 0xffff) {
-    m_CharWidthMap[wUnicode] = absl::nullopt;
-    return absl::nullopt;
+    m_CharWidthMap[wUnicode] = std::nullopt;
+    return std::nullopt;
   }
   if (pFont != this)
     return pFont->GetCharWidth(wUnicode);
 
   int32_t width_from_cfx_font = m_pFont->GetGlyphWidth(glyph);
   if (width_from_cfx_font < 0) {
-    m_CharWidthMap[wUnicode] = absl::nullopt;
-    return absl::nullopt;
+    m_CharWidthMap[wUnicode] = std::nullopt;
+    return std::nullopt;
   }
   uint16_t width = static_cast<uint16_t>(width_from_cfx_font);
   m_CharWidthMap[wUnicode] = width;
   return width;
 }
 
-absl::optional<FX_RECT> CFGAS_GEFont::GetCharBBox(wchar_t wUnicode) {
+std::optional<FX_RECT> CFGAS_GEFont::GetCharBBox(wchar_t wUnicode) {
   auto it = m_BBoxMap.find(wUnicode);
   if (it != m_BBoxMap.end())
     return it->second;
@@ -184,12 +184,12 @@
   int32_t iGlyph;
   std::tie(iGlyph, pFont) = GetGlyphIndexAndFont(wUnicode, true);
   if (!pFont || iGlyph == 0xFFFF)
-    return absl::nullopt;
+    return std::nullopt;
 
   if (pFont.Get() != this)
     return pFont->GetCharBBox(wUnicode);
 
-  absl::optional<FX_RECT> rtBBox = m_pFont->GetGlyphBBox(iGlyph);
+  std::optional<FX_RECT> rtBBox = m_pFont->GetGlyphBBox(iGlyph);
   if (rtBBox.has_value())
     m_BBoxMap[wUnicode] = rtBBox.value();
 
diff --git a/xfa/fgas/font/cfgas_gefont.h b/xfa/fgas/font/cfgas_gefont.h
index fe910df..7ebf2d9 100644
--- a/xfa/fgas/font/cfgas_gefont.h
+++ b/xfa/fgas/font/cfgas_gefont.h
@@ -11,6 +11,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -20,7 +21,6 @@
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/maybe_owned.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class CFX_Font;
 class CFX_UnicodeEncodingEx;
@@ -40,11 +40,11 @@
                                                const ByteString& font_family);
 
   uint32_t GetFontStyles() const;
-  absl::optional<uint16_t> GetCharWidth(wchar_t wUnicode);
+  std::optional<uint16_t> GetCharWidth(wchar_t wUnicode);
   int32_t GetGlyphIndex(wchar_t wUnicode);
   int32_t GetAscent() const;
   int32_t GetDescent() const;
-  absl::optional<FX_RECT> GetCharBBox(wchar_t wUnicode);
+  std::optional<FX_RECT> GetCharBBox(wchar_t wUnicode);
 
   RetainPtr<CFGAS_GEFont> GetSubstFont(int32_t iGlyphIndex);
   CFX_Font* GetDevFont() const { return m_pFont.Get(); }
@@ -70,11 +70,11 @@
       bool bRecursive);
   WideString GetFamilyName() const;
 
-  absl::optional<uint32_t> m_dwLogFontStyle;
+  std::optional<uint32_t> m_dwLogFontStyle;
   RetainPtr<CPDF_Font> m_pPDFFont;  // Must come before |m_pFont|.
   MaybeOwned<CFX_Font> m_pFont;     // Must come before |m_pFontEncoding|.
   std::unique_ptr<CFX_UnicodeEncodingEx> m_pFontEncoding;
-  std::map<wchar_t, absl::optional<uint16_t>> m_CharWidthMap;
+  std::map<wchar_t, std::optional<uint16_t>> m_CharWidthMap;
   std::map<wchar_t, FX_RECT> m_BBoxMap;
   std::vector<RetainPtr<CFGAS_GEFont>> m_SubstFonts;
   std::map<wchar_t, RetainPtr<CFGAS_GEFont>> m_FontMapper;
diff --git a/xfa/fgas/layout/cfgas_rtfbreak.cpp b/xfa/fgas/layout/cfgas_rtfbreak.cpp
index 540a226..6a2dff7 100644
--- a/xfa/fgas/layout/cfgas_rtfbreak.cpp
+++ b/xfa/fgas/layout/cfgas_rtfbreak.cpp
@@ -122,7 +122,7 @@
 }
 
 void CFGAS_RTFBreak::AppendChar_Combination(CFGAS_Char* pCurChar) {
-  absl::optional<uint16_t> iCharWidthRet;
+  std::optional<uint16_t> iCharWidthRet;
   if (m_pFont) {
     iCharWidthRet = m_pFont->GetCharWidth(pCurChar->char_code());
   }
@@ -212,7 +212,7 @@
                pLastChar->GetCharType() == FX_CHARTYPE::kArabicAlef);
       FX_SAFE_INT32 iCharWidth = 0;
       if (m_pFont) {
-        absl::optional<uint16_t> iCharWidthRet = m_pFont->GetCharWidth(wForm);
+        std::optional<uint16_t> iCharWidthRet = m_pFont->GetCharWidth(wForm);
         if (iCharWidthRet.has_value()) {
           iCharWidth = iCharWidthRet.value();
         } else {
@@ -241,7 +241,7 @@
                                       nullptr);
   FX_SAFE_INT32 iCharWidth = 0;
   if (m_pFont) {
-    absl::optional<uint16_t> iCharWidthRet = m_pFont->GetCharWidth(wForm);
+    std::optional<uint16_t> iCharWidthRet = m_pFont->GetCharWidth(wForm);
     if (!iCharWidthRet.has_value())
       iCharWidthRet = m_pFont->GetCharWidth(pCurChar->char_code());
     iCharWidth = iCharWidthRet.value_or(0);
diff --git a/xfa/fgas/layout/cfgas_txtbreak.cpp b/xfa/fgas/layout/cfgas_txtbreak.cpp
index 22a6277..129ace0 100644
--- a/xfa/fgas/layout/cfgas_txtbreak.cpp
+++ b/xfa/fgas/layout/cfgas_txtbreak.cpp
@@ -65,7 +65,7 @@
     if (pLastChar &&
         (pLastChar->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicShadda) == 0) {
       wchar_t wLast = pLastChar->char_code();
-      absl::optional<uint16_t> maybe_shadda;
+      std::optional<uint16_t> maybe_shadda;
       if (wch == pdfium::arabic::kArabicShadda) {
         maybe_shadda = pdfium::arabic::GetArabicFromShaddaTable(wLast);
       } else if (wLast == pdfium::arabic::kArabicShadda) {
@@ -78,7 +78,7 @@
         pLastChar->m_iCharWidth = 0;
       }
     }
-    absl::optional<uint16_t> iCharWidthRet;
+    std::optional<uint16_t> iCharWidthRet;
     if (m_pFont) {
       iCharWidthRet = m_pFont->GetCharWidth(wch);
     }
@@ -734,7 +734,7 @@
           } else if (i < iLength) {
             wNext = *pStr;
           }
-          absl::optional<uint16_t> maybe_shadda;
+          std::optional<uint16_t> maybe_shadda;
           if (wch == pdfium::arabic::kArabicShadda) {
             maybe_shadda = pdfium::arabic::GetArabicFromShaddaTable(wNext);
           } else if (wNext == pdfium::arabic::kArabicShadda) {
@@ -826,7 +826,7 @@
           pCharPos->m_Origin.x += fOffset;
         }
         if (chartype == FX_CHARTYPE::kCombination) {
-          absl::optional<FX_RECT> rtBBox = pFont->GetCharBBox(wForm);
+          std::optional<FX_RECT> rtBBox = pFont->GetCharBBox(wForm);
           if (rtBBox.has_value()) {
             pCharPos->m_Origin.y =
                 fYBase + fFontSize -
@@ -836,7 +836,7 @@
               wLast != pdfium::unicode::kZeroWidthNoBreakSpace) {
             if (pdfium::unicode::GetCharType(wLast) ==
                 FX_CHARTYPE::kCombination) {
-              absl::optional<FX_RECT> rtOtherBox = pFont->GetCharBBox(wLast);
+              std::optional<FX_RECT> rtOtherBox = pFont->GetCharBBox(wLast);
               if (rtOtherBox.has_value()) {
                 pCharPos->m_Origin.y -=
                     fFontSize * rtOtherBox.value().Height() / iMaxHeight;
diff --git a/xfa/fgas/layout/fgas_arabic.cpp b/xfa/fgas/layout/fgas_arabic.cpp
index 172c3ed..a7d41fe 100644
--- a/xfa/fgas/layout/fgas_arabic.cpp
+++ b/xfa/fgas/layout/fgas_arabic.cpp
@@ -212,9 +212,9 @@
   return (eNext < FX_CHARTYPE::kArabicAlef) ? ft->wFinal : ft->wMedial;
 }
 
-absl::optional<wchar_t> GetArabicFromShaddaTable(wchar_t shadda) {
+std::optional<wchar_t> GetArabicFromShaddaTable(wchar_t shadda) {
   if (shadda < kFirstShaddaTableEntry || shadda > kLastShaddaTableEntry)
-    return absl::nullopt;
+    return std::nullopt;
 
   return kShaddaTable[shadda - kFirstShaddaTableEntry];
 }
diff --git a/xfa/fgas/layout/fgas_arabic.h b/xfa/fgas/layout/fgas_arabic.h
index 6b5ba66..45d8584 100644
--- a/xfa/fgas/layout/fgas_arabic.h
+++ b/xfa/fgas/layout/fgas_arabic.h
@@ -7,7 +7,7 @@
 #ifndef XFA_FGAS_LAYOUT_FGAS_ARABIC_H_
 #define XFA_FGAS_LAYOUT_FGAS_ARABIC_H_
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
 
 class CFGAS_Char;
 
@@ -23,7 +23,7 @@
 wchar_t GetFormChar(const CFGAS_Char* cur,
                     const CFGAS_Char* prev,
                     const CFGAS_Char* next);
-absl::optional<wchar_t> GetArabicFromShaddaTable(wchar_t shadda);
+std::optional<wchar_t> GetArabicFromShaddaTable(wchar_t shadda);
 
 }  // namespace arabic
 }  // namespace pdfium
diff --git a/xfa/fwl/cfwl_barcode.h b/xfa/fwl/cfwl_barcode.h
index 45da19c..eb89003 100644
--- a/xfa/fwl/cfwl_barcode.h
+++ b/xfa/fwl/cfwl_barcode.h
@@ -10,9 +10,9 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
 #include "fxbarcode/BC_Library.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "xfa/fwl/cfwl_edit.h"
 
 class CFX_Barcode;
@@ -62,17 +62,17 @@
 
   BC_TYPE m_type = BC_TYPE::kUnknown;
   Status m_eStatus = Status::kNormal;
-  absl::optional<BC_TEXT_LOC> m_eTextLocation;
-  absl::optional<BC_CHAR_ENCODING> m_eCharEncoding;
-  absl::optional<bool> m_bCalChecksum;
-  absl::optional<bool> m_bPrintChecksum;
-  absl::optional<char> m_cStartChar;
-  absl::optional<char> m_cEndChar;
-  absl::optional<int8_t> m_nWideNarrowRatio;
-  absl::optional<int32_t> m_nModuleHeight;
-  absl::optional<int32_t> m_nModuleWidth;
-  absl::optional<int32_t> m_nDataLength;
-  absl::optional<int32_t> m_nECLevel;
+  std::optional<BC_TEXT_LOC> m_eTextLocation;
+  std::optional<BC_CHAR_ENCODING> m_eCharEncoding;
+  std::optional<bool> m_bCalChecksum;
+  std::optional<bool> m_bPrintChecksum;
+  std::optional<char> m_cStartChar;
+  std::optional<char> m_cEndChar;
+  std::optional<int8_t> m_nWideNarrowRatio;
+  std::optional<int32_t> m_nModuleHeight;
+  std::optional<int32_t> m_nModuleWidth;
+  std::optional<int32_t> m_nDataLength;
+  std::optional<int32_t> m_nECLevel;
   std::unique_ptr<CFX_Barcode> m_pBarcodeEngine;
 };
 
diff --git a/xfa/fwl/cfwl_combobox.h b/xfa/fwl/cfwl_combobox.h
index 590b889..efe9c8c 100644
--- a/xfa/fwl/cfwl_combobox.h
+++ b/xfa/fwl/cfwl_combobox.h
@@ -72,8 +72,8 @@
     return EditCanCopy();
   }
   bool EditCanSelectAll() const { return m_pEdit->GetTextLength() > 0; }
-  absl::optional<WideString> EditCopy() const { return m_pEdit->Copy(); }
-  absl::optional<WideString> EditCut() { return m_pEdit->Cut(); }
+  std::optional<WideString> EditCopy() const { return m_pEdit->Copy(); }
+  std::optional<WideString> EditCut() { return m_pEdit->Cut(); }
   bool EditPaste(const WideString& wsPaste) { return m_pEdit->Paste(wsPaste); }
   void EditSelectAll() { m_pEdit->SelectAll(); }
   void EditDelete() { m_pEdit->ClearText(); }
diff --git a/xfa/fwl/cfwl_datetimepicker.cpp b/xfa/fwl/cfwl_datetimepicker.cpp
index dd0cf21..8d9bf7e 100644
--- a/xfa/fwl/cfwl_datetimepicker.cpp
+++ b/xfa/fwl/cfwl_datetimepicker.cpp
@@ -436,11 +436,11 @@
   m_pEdit->ClearSelection();
 }
 
-absl::optional<WideString> CFWL_DateTimePicker::Copy() {
+std::optional<WideString> CFWL_DateTimePicker::Copy() {
   return m_pEdit->Copy();
 }
 
-absl::optional<WideString> CFWL_DateTimePicker::Cut() {
+std::optional<WideString> CFWL_DateTimePicker::Cut() {
   return m_pEdit->Cut();
 }
 
diff --git a/xfa/fwl/cfwl_datetimepicker.h b/xfa/fwl/cfwl_datetimepicker.h
index 75c73ac..5e1d248 100644
--- a/xfa/fwl/cfwl_datetimepicker.h
+++ b/xfa/fwl/cfwl_datetimepicker.h
@@ -60,8 +60,8 @@
   std::pair<size_t, size_t> GetSelection() const {
     return m_pEdit->GetSelection();
   }
-  absl::optional<WideString> Copy();
-  absl::optional<WideString> Cut();
+  std::optional<WideString> Copy();
+  std::optional<WideString> Cut();
   bool Paste(const WideString& wsPaste);
   bool Undo();
   bool Redo();
diff --git a/xfa/fwl/cfwl_edit.cpp b/xfa/fwl/cfwl_edit.cpp
index 9d624c9..e619c92 100644
--- a/xfa/fwl/cfwl_edit.cpp
+++ b/xfa/fwl/cfwl_edit.cpp
@@ -204,16 +204,16 @@
   m_pEditEngine->SetAliasChar(wAlias);
 }
 
-absl::optional<WideString> CFWL_Edit::Copy() {
+std::optional<WideString> CFWL_Edit::Copy() {
   if (!m_pEditEngine->HasSelection())
-    return absl::nullopt;
+    return std::nullopt;
 
   return m_pEditEngine->GetSelectedText();
 }
 
-absl::optional<WideString> CFWL_Edit::Cut() {
+std::optional<WideString> CFWL_Edit::Cut() {
   if (!m_pEditEngine->HasSelection())
-    return absl::nullopt;
+    return std::nullopt;
 
   WideString cut_text = m_pEditEngine->DeleteSelectedText();
   UpdateCaret();
diff --git a/xfa/fwl/cfwl_edit.h b/xfa/fwl/cfwl_edit.h
index 2a85935..66d8664 100644
--- a/xfa/fwl/cfwl_edit.h
+++ b/xfa/fwl/cfwl_edit.h
@@ -80,8 +80,8 @@
   int32_t GetLimit() const;
   void SetLimit(int32_t nLimit);
   void SetAliasChar(wchar_t wAlias);
-  absl::optional<WideString> Copy();
-  absl::optional<WideString> Cut();
+  std::optional<WideString> Copy();
+  std::optional<WideString> Cut();
   bool Paste(const WideString& wsPaste);
   bool Undo();
   bool Redo();
diff --git a/xfa/fxfa/cxfa_ffbarcode.cpp b/xfa/fxfa/cxfa_ffbarcode.cpp
index 4ba37bb..aaf3690 100644
--- a/xfa/fxfa/cxfa_ffbarcode.cpp
+++ b/xfa/fxfa/cxfa_ffbarcode.cpp
@@ -93,16 +93,16 @@
     {0xfb48155c, "code3Of9", BC_TYPE::kCode39},
 };
 
-absl::optional<BC_CHAR_ENCODING> CharEncodingFromString(
+std::optional<BC_CHAR_ENCODING> CharEncodingFromString(
     const WideString& value) {
   if (value.CompareNoCase(L"UTF-16"))
     return BC_CHAR_ENCODING::kUnicode;
   if (value.CompareNoCase(L"UTF-8"))
     return BC_CHAR_ENCODING::kUTF8;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<BC_TEXT_LOC> TextLocFromAttribute(XFA_AttributeValue value) {
+std::optional<BC_TEXT_LOC> TextLocFromAttribute(XFA_AttributeValue value) {
   switch (value) {
     case XFA_AttributeValue::None:
       return BC_TEXT_LOC::kNone;
@@ -115,7 +115,7 @@
     case XFA_AttributeValue::BelowEmbedded:
       return BC_TEXT_LOC::kBelowEmbed;
     default:
-      return absl::nullopt;
+      return std::nullopt;
   }
 }
 
@@ -198,49 +198,49 @@
   auto* pBarCodeWidget = static_cast<CFWL_Barcode*>(GetNormalWidget());
   pBarCodeWidget->SetType(bc_type);
 
-  absl::optional<WideString> encoding_string = barcode_->GetCharEncoding();
+  std::optional<WideString> encoding_string = barcode_->GetCharEncoding();
   if (encoding_string.has_value()) {
-    absl::optional<BC_CHAR_ENCODING> encoding =
+    std::optional<BC_CHAR_ENCODING> encoding =
         CharEncodingFromString(encoding_string.value());
     if (encoding.has_value())
       pBarCodeWidget->SetCharEncoding(encoding.value());
   }
 
-  absl::optional<bool> calcChecksum = barcode_->GetChecksum();
+  std::optional<bool> calcChecksum = barcode_->GetChecksum();
   if (calcChecksum.has_value())
     pBarCodeWidget->SetCalChecksum(calcChecksum.value());
 
-  absl::optional<int32_t> dataLen = barcode_->GetDataLength();
+  std::optional<int32_t> dataLen = barcode_->GetDataLength();
   if (dataLen.has_value())
     pBarCodeWidget->SetDataLength(dataLen.value());
 
-  absl::optional<char> startChar = barcode_->GetStartChar();
+  std::optional<char> startChar = barcode_->GetStartChar();
   if (startChar.has_value())
     pBarCodeWidget->SetStartChar(startChar.value());
 
-  absl::optional<char> endChar = barcode_->GetEndChar();
+  std::optional<char> endChar = barcode_->GetEndChar();
   if (endChar.has_value())
     pBarCodeWidget->SetEndChar(endChar.value());
 
-  absl::optional<int32_t> ecLevel = barcode_->GetECLevel();
+  std::optional<int32_t> ecLevel = barcode_->GetECLevel();
   if (ecLevel.has_value())
     pBarCodeWidget->SetErrorCorrectionLevel(ecLevel.value());
 
-  absl::optional<int32_t> width = barcode_->GetModuleWidth();
+  std::optional<int32_t> width = barcode_->GetModuleWidth();
   if (width.has_value())
     pBarCodeWidget->SetModuleWidth(width.value());
 
-  absl::optional<int32_t> height = barcode_->GetModuleHeight();
+  std::optional<int32_t> height = barcode_->GetModuleHeight();
   if (height.has_value())
     pBarCodeWidget->SetModuleHeight(height.value());
 
-  absl::optional<bool> printCheck = barcode_->GetPrintChecksum();
+  std::optional<bool> printCheck = barcode_->GetPrintChecksum();
   if (printCheck.has_value())
     pBarCodeWidget->SetPrintChecksum(printCheck.value());
 
-  absl::optional<XFA_AttributeValue> text_attr = barcode_->GetTextLocation();
+  std::optional<XFA_AttributeValue> text_attr = barcode_->GetTextLocation();
   if (text_attr.has_value()) {
-    absl::optional<BC_TEXT_LOC> textLoc =
+    std::optional<BC_TEXT_LOC> textLoc =
         TextLocFromAttribute(text_attr.value());
     if (textLoc.has_value())
       pBarCodeWidget->SetTextLocation(textLoc.value());
@@ -248,7 +248,7 @@
 
   // Truncated is currently not a supported flag.
 
-  absl::optional<int8_t> ratio = barcode_->GetWideNarrowRatio();
+  std::optional<int8_t> ratio = barcode_->GetWideNarrowRatio();
   if (ratio.has_value())
     pBarCodeWidget->SetWideNarrowRatio(ratio.value());
 
diff --git a/xfa/fxfa/cxfa_ffcombobox.cpp b/xfa/fxfa/cxfa_ffcombobox.cpp
index bdcc9b1..6764ca6 100644
--- a/xfa/fxfa/cxfa_ffcombobox.cpp
+++ b/xfa/fxfa/cxfa_ffcombobox.cpp
@@ -253,13 +253,13 @@
          ToComboBox(GetNormalWidget())->EditRedo();
 }
 
-absl::optional<WideString> CXFA_FFComboBox::Copy() {
+std::optional<WideString> CXFA_FFComboBox::Copy() {
   return ToComboBox(GetNormalWidget())->EditCopy();
 }
 
-absl::optional<WideString> CXFA_FFComboBox::Cut() {
+std::optional<WideString> CXFA_FFComboBox::Cut() {
   if (!m_pNode->IsChoiceListAllowTextEntry())
-    return absl::nullopt;
+    return std::nullopt;
 
   return ToComboBox(GetNormalWidget())->EditCut();
 }
diff --git a/xfa/fxfa/cxfa_ffcombobox.h b/xfa/fxfa/cxfa_ffcombobox.h
index d1c8113..1227dff 100644
--- a/xfa/fxfa/cxfa_ffcombobox.h
+++ b/xfa/fxfa/cxfa_ffcombobox.h
@@ -37,8 +37,8 @@
   bool CanSelectAll() override;
   bool Undo() override;
   bool Redo() override;
-  absl::optional<WideString> Copy() override;
-  absl::optional<WideString> Cut() override;
+  std::optional<WideString> Copy() override;
+  std::optional<WideString> Cut() override;
   bool Paste(const WideString& wsPaste) override;
   void SelectAll() override;
   void Delete() override;
diff --git a/xfa/fxfa/cxfa_ffdatetimeedit.cpp b/xfa/fxfa/cxfa_ffdatetimeedit.cpp
index 8e57833..a490ccb 100644
--- a/xfa/fxfa/cxfa_ffdatetimeedit.cpp
+++ b/xfa/fxfa/cxfa_ffdatetimeedit.cpp
@@ -92,7 +92,7 @@
   GetNormalWidget()->ModifyStyleExts(dwExtendedStyle, 0xFFFFFFFF);
 
   uint32_t dwEditStyles = 0;
-  absl::optional<int32_t> numCells = m_pNode->GetNumberOfCells();
+  std::optional<int32_t> numCells = m_pNode->GetNumberOfCells();
   if (numCells.has_value() && numCells.value() > 0) {
     dwEditStyles |= FWL_STYLEEXT_EDT_CombText;
     pPicker->SetEditLimit(numCells.value());
@@ -243,7 +243,7 @@
   return GetPickerWidget()->GetEditTextLength() > 0;
 }
 
-absl::optional<WideString> CXFA_FFDateTimeEdit::Copy() {
+std::optional<WideString> CXFA_FFDateTimeEdit::Copy() {
   return GetPickerWidget()->Copy();
 }
 
@@ -255,7 +255,7 @@
   return GetPickerWidget()->Redo();
 }
 
-absl::optional<WideString> CXFA_FFDateTimeEdit::Cut() {
+std::optional<WideString> CXFA_FFDateTimeEdit::Cut() {
   return GetPickerWidget()->Cut();
 }
 
diff --git a/xfa/fxfa/cxfa_ffdatetimeedit.h b/xfa/fxfa/cxfa_ffdatetimeedit.h
index 44b2e32..93eb0a6 100644
--- a/xfa/fxfa/cxfa_ffdatetimeedit.h
+++ b/xfa/fxfa/cxfa_ffdatetimeedit.h
@@ -39,8 +39,8 @@
   bool CanSelectAll() override;
   bool Undo() override;
   bool Redo() override;
-  absl::optional<WideString> Copy() override;
-  absl::optional<WideString> Cut() override;
+  std::optional<WideString> Copy() override;
+  std::optional<WideString> Cut() override;
   bool Paste(const WideString& wsPaste) override;
   void SelectAll() override;
   void Delete() override;
diff --git a/xfa/fxfa/cxfa_ffdocview.cpp b/xfa/fxfa/cxfa_ffdocview.cpp
index 616d26a..41f6f31 100644
--- a/xfa/fxfa/cxfa_ffdocview.cpp
+++ b/xfa/fxfa/cxfa_ffdocview.cpp
@@ -467,7 +467,7 @@
     pRefNode = node->IsWidgetReady() ? node : nullptr;
   }
   WideString wsExpression = (!pRefNode ? L"$form." : L"") + wsName;
-  absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+  std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
       pScriptContext->ResolveObjects(
           pRefNode, wsExpression.AsStringView(),
           Mask<XFA_ResolveFlag>{
@@ -661,7 +661,7 @@
     CFXJSE_Engine* pScriptContext =
         pWidgetNode->GetDocument()->GetScriptContext();
     WideString wsRef = item->GetRef();
-    absl::optional<CFXJSE_Engine::ResolveResult> maybeRS =
+    std::optional<CFXJSE_Engine::ResolveResult> maybeRS =
         pScriptContext->ResolveObjects(
             pWidgetNode, wsRef.AsStringView(),
             Mask<XFA_ResolveFlag>{
diff --git a/xfa/fxfa/cxfa_ffnumericedit.cpp b/xfa/fxfa/cxfa_ffnumericedit.cpp
index 33513e5..75face7 100644
--- a/xfa/fxfa/cxfa_ffnumericedit.cpp
+++ b/xfa/fxfa/cxfa_ffnumericedit.cpp
@@ -55,7 +55,7 @@
   if (!m_pNode->IsHorizontalScrollPolicyOff())
     dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
 
-  absl::optional<int32_t> numCells = m_pNode->GetNumberOfCells();
+  std::optional<int32_t> numCells = m_pNode->GetNumberOfCells();
   if (numCells.has_value() && numCells.value() > 0) {
     dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
     pWidget->SetLimit(numCells.value());
diff --git a/xfa/fxfa/cxfa_ffpageview.cpp b/xfa/fxfa/cxfa_ffpageview.cpp
index 5549bfb..4da33a0 100644
--- a/xfa/fxfa/cxfa_ffpageview.cpp
+++ b/xfa/fxfa/cxfa_ffpageview.cpp
@@ -416,7 +416,7 @@
     CXFA_Traverse* pTraverse =
         pTraversal->GetChild<CXFA_Traverse>(0, XFA_Element::Traverse, false);
     if (pTraverse) {
-      absl::optional<WideString> traverseWidgetName =
+      std::optional<WideString> traverseWidgetName =
           pTraverse->JSObject()->TryAttribute(XFA_Attribute::Ref, true);
       if (traverseWidgetName.has_value())
         return FindWidgetByName(traverseWidgetName.value(), pWidget);
diff --git a/xfa/fxfa/cxfa_fftextedit.cpp b/xfa/fxfa/cxfa_fftextedit.cpp
index 2fd4d46..fdec8fb 100644
--- a/xfa/fxfa/cxfa_fftextedit.cpp
+++ b/xfa/fxfa/cxfa_fftextedit.cpp
@@ -100,7 +100,7 @@
   if (eType == XFA_Element::ExData)
     iMaxChars = 0;
 
-  absl::optional<int32_t> numCells = m_pNode->GetNumberOfCells();
+  std::optional<int32_t> numCells = m_pNode->GetNumberOfCells();
   if (!numCells.has_value()) {
     pWidget->SetLimit(iMaxChars);
   } else if (numCells == 0) {
@@ -397,11 +397,11 @@
   return ToEdit(GetNormalWidget())->Redo();
 }
 
-absl::optional<WideString> CXFA_FFTextEdit::Copy() {
+std::optional<WideString> CXFA_FFTextEdit::Copy() {
   return ToEdit(GetNormalWidget())->Copy();
 }
 
-absl::optional<WideString> CXFA_FFTextEdit::Cut() {
+std::optional<WideString> CXFA_FFTextEdit::Cut() {
   return ToEdit(GetNormalWidget())->Cut();
 }
 
diff --git a/xfa/fxfa/cxfa_fftextedit.h b/xfa/fxfa/cxfa_fftextedit.h
index 53fd536..73affe8 100644
--- a/xfa/fxfa/cxfa_fftextedit.h
+++ b/xfa/fxfa/cxfa_fftextedit.h
@@ -62,8 +62,8 @@
   bool CanSelectAll() override;
   bool Undo() override;
   bool Redo() override;
-  absl::optional<WideString> Copy() override;
-  absl::optional<WideString> Cut() override;
+  std::optional<WideString> Copy() override;
+  std::optional<WideString> Cut() override;
   bool Paste(const WideString& wsPaste) override;
   void SelectAll() override;
   void Delete() override;
diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp
index 6c69912..61d8542 100644
--- a/xfa/fxfa/cxfa_ffwidget.cpp
+++ b/xfa/fxfa/cxfa_ffwidget.cpp
@@ -496,12 +496,12 @@
   return false;
 }
 
-absl::optional<WideString> CXFA_FFWidget::Copy() {
-  return absl::nullopt;
+std::optional<WideString> CXFA_FFWidget::Copy() {
+  return std::nullopt;
 }
 
-absl::optional<WideString> CXFA_FFWidget::Cut() {
-  return absl::nullopt;
+std::optional<WideString> CXFA_FFWidget::Cut() {
+  return std::nullopt;
 }
 
 bool CXFA_FFWidget::Paste(const WideString& wsPaste) {
diff --git a/xfa/fxfa/cxfa_ffwidget.h b/xfa/fxfa/cxfa_ffwidget.h
index e9afcab..3af75b2 100644
--- a/xfa/fxfa/cxfa_ffwidget.h
+++ b/xfa/fxfa/cxfa_ffwidget.h
@@ -146,8 +146,8 @@
   virtual bool CanDeSelect();
   virtual bool Undo();
   virtual bool Redo();
-  virtual absl::optional<WideString> Copy();
-  virtual absl::optional<WideString> Cut();
+  virtual std::optional<WideString> Copy();
+  virtual std::optional<WideString> Cut();
   virtual bool Paste(const WideString& wsPaste);
   virtual void SelectAll();
   virtual void Delete();
diff --git a/xfa/fxfa/cxfa_textlayout.cpp b/xfa/fxfa/cxfa_textlayout.cpp
index 0bcd594..44278d2 100644
--- a/xfa/fxfa/cxfa_textlayout.cpp
+++ b/xfa/fxfa/cxfa_textlayout.cpp
@@ -811,7 +811,7 @@
           while (iTabCount-- > 0)
             wsText += L'\t';
         } else {
-          absl::optional<WideString> obj =
+          std::optional<WideString> obj =
               m_pTextParser->GetEmbeddedObj(m_pTextProvider, pXMLNode);
           if (obj.has_value())
             wsText = obj.value();
diff --git a/xfa/fxfa/cxfa_textparser.cpp b/xfa/fxfa/cxfa_textparser.cpp
index 15b5178..5c4879c 100644
--- a/xfa/fxfa/cxfa_textparser.cpp
+++ b/xfa/fxfa/cxfa_textparser.cpp
@@ -350,7 +350,7 @@
   }
 
   if (pStyle) {
-    absl::optional<WideString> last_family = pStyle->GetLastFontFamily();
+    std::optional<WideString> last_family = pStyle->GetLastFontFamily();
     if (last_family.has_value())
       wsFamily = last_family.value();
 
@@ -499,19 +499,19 @@
   return fLineHeight;
 }
 
-absl::optional<WideString> CXFA_TextParser::GetEmbeddedObj(
+std::optional<WideString> CXFA_TextParser::GetEmbeddedObj(
     const CXFA_TextProvider* pTextProvider,
     const CFX_XMLNode* pXMLNode) {
   if (!pXMLNode)
-    return absl::nullopt;
+    return std::nullopt;
 
   const CFX_XMLElement* pElement = ToXMLElement(pXMLNode);
   if (!pElement)
-    return absl::nullopt;
+    return std::nullopt;
 
   WideString wsAttr = pElement->GetAttribute(L"xfa:embed");
   if (wsAttr.IsEmpty())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (wsAttr[0] == L'#')
     wsAttr.Delete(0);
@@ -519,12 +519,12 @@
   WideString ws =
       GetLowerCaseElementAttributeOrDefault(pElement, L"xfa:embedType", L"som");
   if (!ws.EqualsASCII("uri"))
-    return absl::nullopt;
+    return std::nullopt;
 
   ws = GetLowerCaseElementAttributeOrDefault(pElement, L"xfa:embedMode",
                                              L"formatted");
   if (!(ws.EqualsASCII("raw") || ws.EqualsASCII("formatted")))
-    return absl::nullopt;
+    return std::nullopt;
 
   return pTextProvider->GetEmbeddedObj(wsAttr);
 }
diff --git a/xfa/fxfa/cxfa_textparser.h b/xfa/fxfa/cxfa_textparser.h
index 3e92bc2..651afe6 100644
--- a/xfa/fxfa/cxfa_textparser.h
+++ b/xfa/fxfa/cxfa_textparser.h
@@ -11,6 +11,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/css/cfx_css.h"
@@ -20,7 +21,6 @@
 #include "core/fxcrt/widestring.h"
 #include "core/fxge/dib/fx_dib.h"
 #include "fxjs/gc/heap.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "v8/include/cppgc/garbage-collected.h"
 #include "xfa/fxfa/fxfa_basic.h"
 
@@ -110,7 +110,7 @@
                       bool bFirst,
                       float fVerScale) const;
 
-  absl::optional<WideString> GetEmbeddedObj(
+  std::optional<WideString> GetEmbeddedObj(
       const CXFA_TextProvider* pTextProvider,
       const CFX_XMLNode* pXMLNode);
   Context* GetParseContextFromMap(const CFX_XMLNode* pXMLNode);
diff --git a/xfa/fxfa/cxfa_textprovider.cpp b/xfa/fxfa/cxfa_textprovider.cpp
index 2186c4b..a346923 100644
--- a/xfa/fxfa/cxfa_textprovider.cpp
+++ b/xfa/fxfa/cxfa_textprovider.cpp
@@ -53,7 +53,7 @@
 
     CXFA_Node* pChildNode = pValueNode->GetFirstChild();
     if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) {
-      absl::optional<WideString> contentType =
+      std::optional<WideString> contentType =
           pChildNode->JSObject()->TryAttribute(XFA_Attribute::ContentType,
                                                false);
       if (contentType.has_value() &&
@@ -77,7 +77,7 @@
 
     CXFA_Node* pChildNode = pValueNode->GetFirstChild();
     if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) {
-      absl::optional<WideString> contentType =
+      std::optional<WideString> contentType =
           pChildNode->JSObject()->TryAttribute(XFA_Attribute::ContentType,
                                                false);
       if (contentType.has_value() &&
@@ -132,10 +132,10 @@
   return !m_pNode->TryWidth().has_value();
 }
 
-absl::optional<WideString> CXFA_TextProvider::GetEmbeddedObj(
+std::optional<WideString> CXFA_TextProvider::GetEmbeddedObj(
     const WideString& wsAttr) const {
   if (m_eType != Type::kText)
-    return absl::nullopt;
+    return std::nullopt;
 
   CXFA_Node* pParent = m_pNode->GetParent();
   CXFA_Document* pDocument = m_pNode->GetDocument();
@@ -149,7 +149,7 @@
         wsAttr.AsStringView());
   }
   if (!pIDNode || !pIDNode->IsWidgetReady())
-    return absl::nullopt;
+    return std::nullopt;
 
   return pIDNode->GetValue(XFA_ValuePicture::kDisplay);
 }
diff --git a/xfa/fxfa/cxfa_textprovider.h b/xfa/fxfa/cxfa_textprovider.h
index b24e9e9..414b24d 100644
--- a/xfa/fxfa/cxfa_textprovider.h
+++ b/xfa/fxfa/cxfa_textprovider.h
@@ -7,9 +7,10 @@
 #ifndef XFA_FXFA_CXFA_TEXTPROVIDER_H_
 #define XFA_FXFA_CXFA_TEXTPROVIDER_H_
 
+#include <optional>
+
 #include "core/fxcrt/widestring.h"
 #include "fxjs/gc/heap.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "v8/include/cppgc/garbage-collected.h"
 #include "v8/include/cppgc/member.h"
 #include "v8/include/cppgc/visitor.h"
@@ -37,7 +38,7 @@
   CXFA_Para* GetParaIfExists();
   CXFA_Font* GetFontIfExists();
   bool IsCheckButtonAndAutoWidth() const;
-  absl::optional<WideString> GetEmbeddedObj(const WideString& wsAttr) const;
+  std::optional<WideString> GetEmbeddedObj(const WideString& wsAttr) const;
 
  private:
   CXFA_TextProvider(CXFA_Node* pNode, Type eType);
diff --git a/xfa/fxfa/formcalc/cxfa_fmexpression.cpp b/xfa/fxfa/formcalc/cxfa_fmexpression.cpp
index 2b2f089..35bbfe2 100644
--- a/xfa/fxfa/formcalc/cxfa_fmexpression.cpp
+++ b/xfa/fxfa/formcalc/cxfa_fmexpression.cpp
@@ -773,7 +773,7 @@
   ContainerTrace(visitor, expressions_);
 }
 
-absl::optional<WideTextBuffer> CXFA_FMAST::ToJavaScript() const {
+std::optional<WideTextBuffer> CXFA_FMAST::ToJavaScript() const {
   WideTextBuffer js;
   if (expressions_.empty()) {
     js << "// comments only";
@@ -798,13 +798,13 @@
             ? CXFA_FMAssignExpression::ReturnType::kImplied
             : CXFA_FMAssignExpression::ReturnType::kInferred;
     if (!expr->ToJavaScript(&js, ret_type))
-      return absl::nullopt;
+      return std::nullopt;
   }
   js << "return pfm_rt.get_val(pfm_ret);\n";
   js << "}).call(this);";
 
   if (CXFA_IsTooBig(js))
-    return absl::nullopt;
+    return std::nullopt;
 
   return js;
 }
diff --git a/xfa/fxfa/formcalc/cxfa_fmexpression.h b/xfa/fxfa/formcalc/cxfa_fmexpression.h
index e00921f..f53da0b 100644
--- a/xfa/fxfa/formcalc/cxfa_fmexpression.h
+++ b/xfa/fxfa/formcalc/cxfa_fmexpression.h
@@ -7,12 +7,12 @@
 #ifndef XFA_FXFA_FORMCALC_CXFA_FMEXPRESSION_H_
 #define XFA_FXFA_FORMCALC_CXFA_FMEXPRESSION_H_
 
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/widestring.h"
 #include "core/fxcrt/widetext_buffer.h"
 #include "fxjs/gc/heap.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "v8/include/cppgc/garbage-collected.h"
 #include "v8/include/cppgc/member.h"
 #include "xfa/fxfa/formcalc/cxfa_fmlexer.h"
@@ -594,7 +594,7 @@
   ~CXFA_FMAST();
 
   void Trace(cppgc::Visitor* visitor) const;
-  absl::optional<WideTextBuffer> ToJavaScript() const;
+  std::optional<WideTextBuffer> ToJavaScript() const;
 
  private:
   explicit CXFA_FMAST(
diff --git a/xfa/fxfa/formcalc/cxfa_fmparser.cpp b/xfa/fxfa/formcalc/cxfa_fmparser.cpp
index 7c73c37..cc8e7fc 100644
--- a/xfa/fxfa/formcalc/cxfa_fmparser.cpp
+++ b/xfa/fxfa/formcalc/cxfa_fmparser.cpp
@@ -651,7 +651,7 @@
 
     switch (m_token.GetType()) {
       case TOKlparen: {
-        absl::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
+        std::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
             expressions = ParseArgumentList();
         if (!expressions.has_value())
           return nullptr;
@@ -682,7 +682,7 @@
         if (!NextToken())
           return nullptr;
         if (m_token.GetType() == TOKlparen) {
-          absl::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
+          std::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
               expressions = ParseArgumentList();
           if (!expressions.has_value())
             return nullptr;
@@ -800,10 +800,10 @@
 
 // Argument lists are zero or more comma seperated simple expressions found
 // between '(' and ')'
-absl::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
+std::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
 CXFA_FMParser::ParseArgumentList() {
   if (m_token.GetType() != TOKlparen || !NextToken())
-    return absl::nullopt;
+    return std::nullopt;
 
   std::vector<cppgc::Member<CXFA_FMSimpleExpression>> expressions;
   bool first_arg = true;
@@ -812,16 +812,16 @@
       first_arg = false;
     } else {
       if (m_token.GetType() != TOKcomma || !NextToken())
-        return absl::nullopt;
+        return std::nullopt;
     }
 
     CXFA_FMSimpleExpression* exp = ParseSimpleExpression();
     if (!exp)
-      return absl::nullopt;
+      return std::nullopt;
 
     expressions.push_back(exp);
     if (expressions.size() > kMaxPostExpressions)
-      return absl::nullopt;
+      return std::nullopt;
   }
 
   return expressions;
diff --git a/xfa/fxfa/formcalc/cxfa_fmparser.h b/xfa/fxfa/formcalc/cxfa_fmparser.h
index e8b6c44..22ce68d 100644
--- a/xfa/fxfa/formcalc/cxfa_fmparser.h
+++ b/xfa/fxfa/formcalc/cxfa_fmparser.h
@@ -7,11 +7,11 @@
 #ifndef XFA_FXFA_FORMCALC_CXFA_FMPARSER_H_
 #define XFA_FXFA_FORMCALC_CXFA_FMPARSER_H_
 
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/unowned_ptr_exclusion.h"
 #include "fxjs/gc/heap.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "v8/include/cppgc/macros.h"
 #include "v8/include/cppgc/member.h"
 #include "xfa/fxfa/formcalc/cxfa_fmexpression.h"
@@ -60,7 +60,7 @@
   CXFA_FMSimpleExpression* ParsePostExpression(CXFA_FMSimpleExpression* e);
   CXFA_FMSimpleExpression* ParseIndexExpression();
   CXFA_FMSimpleExpression* ParseLiteral();
-  absl::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
+  std::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
   ParseArgumentList();
 
   UnownedPtr<cppgc::Heap> const m_heap;
diff --git a/xfa/fxfa/formcalc/cxfa_fmparser_unittest.cpp b/xfa/fxfa/formcalc/cxfa_fmparser_unittest.cpp
index 98c73f0..00b1e3c 100644
--- a/xfa/fxfa/formcalc/cxfa_fmparser_unittest.cpp
+++ b/xfa/fxfa/formcalc/cxfa_fmparser_unittest.cpp
@@ -19,7 +19,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   // TODO(dsinclair): This is a little weird .....
   EXPECT_STREQ(L"// comments only", buf.value().MakeString().c_str());
@@ -35,7 +35,7 @@
   // EXPECT_TRUE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(L"// comments only", buf.value().MakeString().c_str());
 }
@@ -65,7 +65,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(ret, buf.value().MakeString().c_str());
 }
@@ -135,7 +135,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_EQ(ret, buf.value().AsStringView());
 }
@@ -201,7 +201,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(ret, buf.value().MakeString().c_str());
 }
@@ -240,7 +240,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(ret, buf.value().MakeString().c_str());
 }
@@ -329,7 +329,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(ret, buf.value().MakeString().c_str());
 }
@@ -371,7 +371,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(ret, buf.value().MakeString().c_str());
 }
@@ -403,7 +403,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(ret, buf.value().MakeString().c_str());
 }
@@ -437,7 +437,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(ret, buf.value().MakeString().c_str());
 }
@@ -471,7 +471,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(ret, buf.value().MakeString().c_str());
 }
@@ -505,7 +505,7 @@
   EXPECT_FALSE(parser.HasError());
 
   CXFA_FMToJavaScriptDepth::Reset();
-  absl::optional<WideTextBuffer> buf = ast->ToJavaScript();
+  std::optional<WideTextBuffer> buf = ast->ToJavaScript();
   ASSERT_TRUE(buf.has_value());
   EXPECT_STREQ(ret, buf.value().MakeString().c_str());
 }
diff --git a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp
index 370d5c0..2df317e 100644
--- a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.cpp
@@ -92,14 +92,14 @@
 
   CFX_SizeF containerSize;
   if (eType == XFA_Element::Subform || eType == XFA_Element::ExclGroup) {
-    absl::optional<CXFA_Measurement> wValue =
+    std::optional<CXFA_Measurement> wValue =
         pFormNode->JSObject()->TryMeasure(XFA_Attribute::W, false);
     if (wValue.has_value() && wValue->GetValue() > kXFALayoutPrecision) {
       containerSize.width = wValue->ToUnit(XFA_Unit::Pt);
       *bContainerWidthAutoSize = false;
     }
 
-    absl::optional<CXFA_Measurement> hValue =
+    std::optional<CXFA_Measurement> hValue =
         pFormNode->JSObject()->TryMeasure(XFA_Attribute::H, false);
     if (hValue.has_value() && hValue->GetValue() > kXFALayoutPrecision) {
       containerSize.height = hValue->ToUnit(XFA_Unit::Pt);
@@ -108,14 +108,14 @@
   }
 
   if (*bContainerWidthAutoSize && eType == XFA_Element::Subform) {
-    absl::optional<CXFA_Measurement> maxW =
+    std::optional<CXFA_Measurement> maxW =
         pFormNode->JSObject()->TryMeasure(XFA_Attribute::MaxW, false);
     if (maxW.has_value() && maxW->GetValue() > kXFALayoutPrecision) {
       containerSize.width = maxW->ToUnit(XFA_Unit::Pt);
       *bContainerWidthAutoSize = false;
     }
 
-    absl::optional<CXFA_Measurement> maxH =
+    std::optional<CXFA_Measurement> maxH =
         pFormNode->JSObject()->TryMeasure(XFA_Attribute::MaxH, false);
     if (maxH.has_value() && maxH->GetValue() > kXFALayoutPrecision) {
       containerSize.height = maxH->ToUnit(XFA_Unit::Pt);
@@ -138,12 +138,12 @@
   if (bContainerWidthAutoSize) {
     componentSize.width = fContentCalculatedWidth;
     if (pMarginNode) {
-      absl::optional<CXFA_Measurement> leftInset =
+      std::optional<CXFA_Measurement> leftInset =
           pMarginNode->JSObject()->TryMeasure(XFA_Attribute::LeftInset, false);
       if (leftInset.has_value())
         componentSize.width += leftInset->ToUnit(XFA_Unit::Pt);
 
-      absl::optional<CXFA_Measurement> rightInset =
+      std::optional<CXFA_Measurement> rightInset =
           pMarginNode->JSObject()->TryMeasure(XFA_Attribute::RightInset, false);
       if (rightInset.has_value())
         componentSize.width += rightInset->ToUnit(XFA_Unit::Pt);
@@ -153,12 +153,12 @@
   if (bContainerHeightAutoSize) {
     componentSize.height = fContentCalculatedHeight;
     if (pMarginNode) {
-      absl::optional<CXFA_Measurement> topInset =
+      std::optional<CXFA_Measurement> topInset =
           pMarginNode->JSObject()->TryMeasure(XFA_Attribute::TopInset, false);
       if (topInset.has_value())
         componentSize.height += topInset->ToUnit(XFA_Unit::Pt);
 
-      absl::optional<CXFA_Measurement> bottomInset =
+      std::optional<CXFA_Measurement> bottomInset =
           pMarginNode->JSObject()->TryMeasure(XFA_Attribute::BottomInset,
                                               false);
       if (bottomInset.has_value())
@@ -337,7 +337,7 @@
 
 XFA_AttributeValue GetLayout(CXFA_Node* pFormNode, bool* bRootForceTb) {
   *bRootForceTb = false;
-  absl::optional<XFA_AttributeValue> layoutMode =
+  std::optional<XFA_AttributeValue> layoutMode =
       pFormNode->JSObject()->TryEnum(XFA_Attribute::Layout, false);
   if (layoutMode.has_value())
     return layoutMode.value();
@@ -366,7 +366,7 @@
     if (!bPreFind)
       eKeepType = XFA_Attribute::Next;
 
-    absl::optional<XFA_AttributeValue> previous =
+    std::optional<XFA_AttributeValue> previous =
         pKeep->JSObject()->TryEnum(eKeepType, false);
     if (previous == XFA_AttributeValue::ContentArea ||
         previous == XFA_AttributeValue::PageArea) {
@@ -382,7 +382,7 @@
   if (!bPreFind)
     eKeepType = XFA_Attribute::Previous;
 
-  absl::optional<XFA_AttributeValue> next =
+  std::optional<XFA_AttributeValue> next =
       pKeep->JSObject()->TryEnum(eKeepType, false);
   if (next == XFA_AttributeValue::ContentArea ||
       next == XFA_AttributeValue::PageArea) {
@@ -391,7 +391,7 @@
   return false;
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage> FindBreakBeforeNode(
+std::optional<CXFA_ContentLayoutProcessor::Stage> FindBreakBeforeNode(
     CXFA_Node* pContainerNode,
     CXFA_Node** pCurActionNode) {
   for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode;
@@ -411,10 +411,10 @@
         break;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage> FindBreakAfterNode(
+std::optional<CXFA_ContentLayoutProcessor::Stage> FindBreakAfterNode(
     CXFA_Node* pContainerNode,
     CXFA_Node** pCurActionNode) {
   for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode;
@@ -434,7 +434,7 @@
         break;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode) {
@@ -498,7 +498,7 @@
       while (bChanged) {
         bChanged = false;
         {
-          absl::optional<float> fRelSplitPos = pFormNode->FindSplitPos(
+          std::optional<float> fRelSplitPos = pFormNode->FindSplitPos(
               pNotify->GetFFDoc()->GetDocView(), pLayoutItem->GetIndex(),
               *fProposedSplitPos - fCurVerticalOffset);
           if (fRelSplitPos.has_value()) {
@@ -876,7 +876,7 @@
       break;
   }
 
-  absl::optional<Stage> ret;
+  std::optional<Stage> ret;
   switch (nCurStage) {
     case Stage::kKeep:
       ret = HandleKeep(pChildContainer->GetFirstChild(), &pCurActionNode);
@@ -934,7 +934,7 @@
   return {Stage::kDone, nullptr};
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage>
+std::optional<CXFA_ContentLayoutProcessor::Stage>
 CXFA_ContentLayoutProcessor::ProcessKeepNodesForCheckNext(
     CXFA_Node** pCurActionNode,
     CXFA_Node** pNextContainer,
@@ -948,35 +948,35 @@
       m_pKeepHeadNode = *pNextContainer;
       m_bIsProcessKeep = true;
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (!m_bIsProcessKeep || !m_pKeepHeadNode) {
     if (m_bKeepBreakFinish)
       *pLastKeepNode = true;
     m_bKeepBreakFinish = false;
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   m_pKeepTailNode = *pNextContainer;
   if (m_bKeepBreakFinish) {
     *pNextContainer = m_pKeepHeadNode;
     ProcessKeepNodesEnd();
-    return absl::nullopt;
+    return std::nullopt;
   }
 
-  absl::optional<Stage> ret =
+  std::optional<Stage> ret =
       FindBreakBeforeNode((*pNextContainer)->GetFirstChild(), pCurActionNode);
   if (!ret.has_value()) {
     *pNextContainer = m_pKeepHeadNode;
     ProcessKeepNodesEnd();
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return ret;
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage>
+std::optional<CXFA_ContentLayoutProcessor::Stage>
 CXFA_ContentLayoutProcessor::ProcessKeepNodesForBreakBefore(
     CXFA_Node** pCurActionNode,
     CXFA_Node* pContainerNode) {
@@ -1647,7 +1647,7 @@
           if (!bUseBreakControl || !m_pViewLayoutProcessor)
             break;
 
-          absl::optional<CXFA_ViewLayoutProcessor::BreakData> break_data =
+          std::optional<CXFA_ViewLayoutProcessor::BreakData> break_data =
               m_pViewLayoutProcessor->ProcessBreakBefore(m_pCurChildNode);
           if (!break_data.has_value() || !break_data.value().bCreatePage ||
               GetFormNode()->GetElementType() == XFA_Element::Form) {
@@ -1688,7 +1688,7 @@
           if (!bUseBreakControl || !m_pViewLayoutProcessor)
             break;
 
-          absl::optional<CXFA_ViewLayoutProcessor::BreakData> break_data =
+          std::optional<CXFA_ViewLayoutProcessor::BreakData> break_data =
               m_pViewLayoutProcessor->ProcessBreakAfter(m_pCurChildNode);
           if (!break_data.has_value() ||
               GetFormNode()->GetElementType() == XFA_Element::Form) {
@@ -2431,7 +2431,7 @@
       pFormNode = pLayoutContext->m_pOverflowNode;
       bUseInherited = true;
     }
-    absl::optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
+    std::optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
         m_pViewLayoutProcessor->ProcessOverflow(pFormNode, false);
     if (overflow_data.has_value()) {
       pOverflowLeaderNode = overflow_data.value().pLeader;
@@ -2633,7 +2633,7 @@
   if (pProcessor->GetFormNode()->GetIntact() == XFA_AttributeValue::None &&
       eLayout == XFA_AttributeValue::Tb) {
     if (m_pViewLayoutProcessor) {
-      absl::optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
+      std::optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
           m_pViewLayoutProcessor->ProcessOverflow(pFormNode, true);
       if (overflow_data.has_value()) {
         pOverflowLeaderNode = overflow_data.value().pLeader;
@@ -2654,7 +2654,7 @@
   if (!pFormNode && pLayoutContext)
     pFormNode = pLayoutContext->m_pOverflowProcessor->GetFormNode();
   if (m_pViewLayoutProcessor) {
-    absl::optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
+    std::optional<CXFA_ViewLayoutProcessor::OverflowData> overflow_data =
         m_pViewLayoutProcessor->ProcessOverflow(pFormNode, true);
     if (overflow_data.has_value()) {
       pOverflowLeaderNode = overflow_data.value().pLeader;
@@ -2669,15 +2669,15 @@
   return Result::kPageFullBreak;
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage>
+std::optional<CXFA_ContentLayoutProcessor::Stage>
 CXFA_ContentLayoutProcessor::HandleKeep(CXFA_Node* pBreakAfterNode,
                                         CXFA_Node** pCurActionNode) {
   if (m_bKeepBreakFinish)
-    return absl::nullopt;
+    return std::nullopt;
   return FindBreakAfterNode(pBreakAfterNode, pCurActionNode);
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage>
+std::optional<CXFA_ContentLayoutProcessor::Stage>
 CXFA_ContentLayoutProcessor::HandleBookendLeader(CXFA_Node* pParentContainer,
                                                  CXFA_Node** pCurActionNode) {
   for (CXFA_Node* pBookendNode = *pCurActionNode
@@ -2693,18 +2693,18 @@
         break;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage>
+std::optional<CXFA_ContentLayoutProcessor::Stage>
 CXFA_ContentLayoutProcessor::HandleBreakBefore(CXFA_Node* pChildContainer,
                                                CXFA_Node** pCurActionNode) {
   if (!*pCurActionNode)
-    return absl::nullopt;
+    return std::nullopt;
 
   CXFA_Node* pBreakBeforeNode = (*pCurActionNode)->GetNextSibling();
   if (!m_bKeepBreakFinish) {
-    absl::optional<Stage> ret =
+    std::optional<Stage> ret =
         FindBreakBeforeNode(pBreakBeforeNode, pCurActionNode);
     if (ret.has_value())
       return ret.value();
@@ -2716,7 +2716,7 @@
   return Stage::kContainer;
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage>
+std::optional<CXFA_ContentLayoutProcessor::Stage>
 CXFA_ContentLayoutProcessor::HandleBreakAfter(CXFA_Node* pChildContainer,
                                               CXFA_Node** pCurActionNode) {
   if (*pCurActionNode) {
@@ -2728,7 +2728,7 @@
   return HandleKeep(pBreakAfterNode, pCurActionNode);
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage>
+std::optional<CXFA_ContentLayoutProcessor::Stage>
 CXFA_ContentLayoutProcessor::HandleCheckNextChildContainer(
     CXFA_Node* pParentContainer,
     CXFA_Node* pChildContainer,
@@ -2743,10 +2743,10 @@
       DeleteLayoutGeneratedNode(pSaveNode);
   }
   if (!pNextChildContainer)
-    return absl::nullopt;
+    return std::nullopt;
 
   bool bLastKeep = false;
-  absl::optional<Stage> ret = ProcessKeepNodesForCheckNext(
+  std::optional<Stage> ret = ProcessKeepNodesForCheckNext(
       pCurActionNode, &pNextChildContainer, &bLastKeep);
   if (ret.has_value())
     return ret.value();
@@ -2761,7 +2761,7 @@
   return m_bIsProcessKeep ? Stage::kKeep : Stage::kContainer;
 }
 
-absl::optional<CXFA_ContentLayoutProcessor::Stage>
+std::optional<CXFA_ContentLayoutProcessor::Stage>
 CXFA_ContentLayoutProcessor::HandleBookendTrailer(CXFA_Node* pParentContainer,
                                                   CXFA_Node** pCurActionNode) {
   for (CXFA_Node* pBookendNode = *pCurActionNode
@@ -2777,7 +2777,7 @@
         break;
     }
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 void CXFA_ContentLayoutProcessor::ProcessKeepNodesEnd() {
diff --git a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h
index 9267ebc..173e39d 100644
--- a/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h
+++ b/xfa/fxfa/layout/cxfa_contentlayoutprocessor.h
@@ -11,13 +11,13 @@
 
 #include <list>
 #include <map>
+#include <optional>
 #include <utility>
 #include <vector>
 
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "fxjs/gc/heap.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "v8/include/cppgc/garbage-collected.h"
 #include "v8/include/cppgc/macros.h"
 #include "v8/include/cppgc/member.h"
@@ -72,7 +72,7 @@
     Context();
     ~Context();
 
-    absl::optional<float> m_fCurColumnWidth;
+    std::optional<float> m_fCurColumnWidth;
     UnownedPtr<std::vector<float>> m_prgSpecifiedColumnWidths;
     UnownedPtr<CXFA_ContentLayoutProcessor> m_pOverflowProcessor;  // OK, stack
     UnownedPtr<CXFA_Node> m_pOverflowNode;                         // Ok, stack
@@ -154,11 +154,11 @@
       CXFA_Node* pParentContainer,
       CXFA_Node* pCurActionNode);
 
-  absl::optional<Stage> ProcessKeepNodesForCheckNext(CXFA_Node** pCurActionNode,
-                                                     CXFA_Node** pNextContainer,
-                                                     bool* pLastKeepNode);
+  std::optional<Stage> ProcessKeepNodesForCheckNext(CXFA_Node** pCurActionNode,
+                                                    CXFA_Node** pNextContainer,
+                                                    bool* pLastKeepNode);
 
-  absl::optional<Stage> ProcessKeepNodesForBreakBefore(
+  std::optional<Stage> ProcessKeepNodesForBreakBefore(
       CXFA_Node** pCurActionNode,
       CXFA_Node* pContainerNode);
 
@@ -192,20 +192,20 @@
       Context* pLayoutContext,
       bool bNewRow);
 
-  absl::optional<Stage> HandleKeep(CXFA_Node* pBreakAfterNode,
-                                   CXFA_Node** pCurActionNode);
-  absl::optional<Stage> HandleBookendLeader(CXFA_Node* pParentContainer,
-                                            CXFA_Node** pCurActionNode);
-  absl::optional<Stage> HandleBreakBefore(CXFA_Node* pChildContainer,
-                                          CXFA_Node** pCurActionNode);
-  absl::optional<Stage> HandleBreakAfter(CXFA_Node* pChildContainer,
+  std::optional<Stage> HandleKeep(CXFA_Node* pBreakAfterNode,
+                                  CXFA_Node** pCurActionNode);
+  std::optional<Stage> HandleBookendLeader(CXFA_Node* pParentContainer,
+                                           CXFA_Node** pCurActionNode);
+  std::optional<Stage> HandleBreakBefore(CXFA_Node* pChildContainer,
                                          CXFA_Node** pCurActionNode);
-  absl::optional<Stage> HandleCheckNextChildContainer(
+  std::optional<Stage> HandleBreakAfter(CXFA_Node* pChildContainer,
+                                        CXFA_Node** pCurActionNode);
+  std::optional<Stage> HandleCheckNextChildContainer(
       CXFA_Node* pParentContainer,
       CXFA_Node* pChildContainer,
       CXFA_Node** pCurActionNode);
-  absl::optional<Stage> HandleBookendTrailer(CXFA_Node* pParentContainer,
-                                             CXFA_Node** pCurActionNode);
+  std::optional<Stage> HandleBookendTrailer(CXFA_Node* pParentContainer,
+                                            CXFA_Node** pCurActionNode);
   void ProcessKeepNodesEnd();
   void AdjustContainerSpecifiedSize(Context* pContext,
                                     CFX_SizeF* pSize,
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
index c8ec206..e3c30ed 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
+++ b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.cpp
@@ -176,7 +176,7 @@
   bool bTargetAllFind = true;
   while (true) {
     WideString wsExpr;
-    absl::optional<size_t> iSplitNextIndex = 0;
+    std::optional<size_t> iSplitNextIndex = 0;
     if (!bTargetAllFind) {
       iSplitNextIndex = pTargetAll->Find(' ', iSplitIndex);
       if (!iSplitNextIndex.has_value())
@@ -201,7 +201,7 @@
       if (wsExpr.First(4).EqualsASCII("som(") && wsExpr.Back() == L')')
         wsProcessedTarget = wsExpr.Substr(4, wsExpr.GetLength() - 5);
 
-      absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+      std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
           pDocument->GetScriptContext()->ResolveObjects(
               pPageSetRoot, wsProcessedTarget.AsStringView(),
               Mask<XFA_ResolveFlag>{
@@ -222,8 +222,8 @@
   pNode->ClearFlag(XFA_NodeFlag::kUnusedNode);
 }
 
-// Note: Returning nullptr is not the same as returning absl::nullopt.
-absl::optional<CXFA_ViewLayoutItem*> CheckContentAreaNotUsed(
+// Note: Returning nullptr is not the same as returning std::nullopt.
+std::optional<CXFA_ViewLayoutItem*> CheckContentAreaNotUsed(
     CXFA_ViewLayoutItem* pPageAreaLayoutItem,
     CXFA_Node* pContentArea) {
   for (CXFA_LayoutItem* pChild = pPageAreaLayoutItem->GetFirstChild(); pChild;
@@ -232,7 +232,7 @@
     if (pLayoutItem && pLayoutItem->GetFormNode() == pContentArea) {
       if (!pLayoutItem->GetFirstChild())
         return pLayoutItem;
-      return absl::nullopt;
+      return std::nullopt;
     }
   }
   return nullptr;
@@ -853,22 +853,22 @@
   return ret;
 }
 
-absl::optional<CXFA_ViewLayoutProcessor::BreakData>
+std::optional<CXFA_ViewLayoutProcessor::BreakData>
 CXFA_ViewLayoutProcessor::ProcessBreakBefore(const CXFA_Node* pBreakNode) {
   return ProcessBreakBeforeOrAfter(pBreakNode, /*bBefore=*/true);
 }
 
-absl::optional<CXFA_ViewLayoutProcessor::BreakData>
+std::optional<CXFA_ViewLayoutProcessor::BreakData>
 CXFA_ViewLayoutProcessor::ProcessBreakAfter(const CXFA_Node* pBreakNode) {
   return ProcessBreakBeforeOrAfter(pBreakNode, /*bBefore=*/false);
 }
 
-absl::optional<CXFA_ViewLayoutProcessor::BreakData>
+std::optional<CXFA_ViewLayoutProcessor::BreakData>
 CXFA_ViewLayoutProcessor::ProcessBreakBeforeOrAfter(const CXFA_Node* pBreakNode,
                                                     bool bBefore) {
   CXFA_Node* pFormNode = pBreakNode->GetContainerParent();
   if (!pFormNode->PresenceRequiresSpace())
-    return absl::nullopt;
+    return std::nullopt;
 
   BreakData break_data = ExecuteBreakBeforeOrAfter(pBreakNode, bBefore);
   CXFA_Document* pDocument = pBreakNode->GetDocument();
@@ -876,20 +876,20 @@
   pFormNode = pFormNode->GetContainerParent();
   if (break_data.pLeader) {
     if (!break_data.pLeader->IsContainerNode())
-      return absl::nullopt;
+      return std::nullopt;
 
     pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
     break_data.pLeader = pDocument->DataMerge_CopyContainer(
         break_data.pLeader, pFormNode, pDataScope, true, true, true);
     if (!break_data.pLeader)
-      return absl::nullopt;
+      return std::nullopt;
 
     pDocument->DataMerge_UpdateBindingRelations(break_data.pLeader);
     SetLayoutGeneratedNodeFlag(break_data.pLeader);
   }
   if (break_data.pTrailer) {
     if (!break_data.pTrailer->IsContainerNode())
-      return absl::nullopt;
+      return std::nullopt;
 
     if (!pDataScope)
       pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
@@ -897,7 +897,7 @@
     break_data.pTrailer = pDocument->DataMerge_CopyContainer(
         break_data.pTrailer, pFormNode, pDataScope, true, true, true);
     if (!break_data.pTrailer)
-      return absl::nullopt;
+      return std::nullopt;
 
     pDocument->DataMerge_UpdateBindingRelations(break_data.pTrailer);
     SetLayoutGeneratedNodeFlag(break_data.pTrailer);
@@ -1017,11 +1017,11 @@
   return true;
 }
 
-absl::optional<CXFA_ViewLayoutProcessor::OverflowData>
+std::optional<CXFA_ViewLayoutProcessor::OverflowData>
 CXFA_ViewLayoutProcessor::ProcessOverflow(CXFA_Node* pFormNode,
                                           bool bCreatePage) {
   if (!pFormNode)
-    return absl::nullopt;
+    return std::nullopt;
 
   CXFA_Node* pLeaderTemplate = nullptr;
   CXFA_Node* pTrailerTemplate = nullptr;
@@ -1044,7 +1044,7 @@
         overflow_data.pLeader = pDocument->DataMerge_CopyContainer(
             pLeaderTemplate, pFormNode, pDataScope, true, true, true);
         if (!overflow_data.pLeader)
-          return absl::nullopt;
+          return std::nullopt;
 
         pDocument->DataMerge_UpdateBindingRelations(overflow_data.pLeader);
         SetLayoutGeneratedNodeFlag(overflow_data.pLeader);
@@ -1056,7 +1056,7 @@
         overflow_data.pTrailer = pDocument->DataMerge_CopyContainer(
             pTrailerTemplate, pFormNode, pDataScope, true, true, true);
         if (!overflow_data.pTrailer)
-          return absl::nullopt;
+          return std::nullopt;
 
         pDocument->DataMerge_UpdateBindingRelations(overflow_data.pTrailer);
         SetLayoutGeneratedNodeFlag(overflow_data.pTrailer);
@@ -1066,7 +1066,7 @@
     if (bIsOverflowNode)
       break;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 CXFA_Node* CXFA_ViewLayoutProcessor::ResolveBookendLeaderOrTrailer(
@@ -1129,7 +1129,7 @@
     CXFA_Node* pOccurNode =
         pPageSet->GetFirstChildByClass<CXFA_Occur>(XFA_Element::Occur);
     if (pOccurNode) {
-      absl::optional<int32_t> ret =
+      std::optional<int32_t> ret =
           pOccurNode->JSObject()->TryInteger(XFA_Attribute::Max, false);
       if (ret.has_value())
         iMax = ret.value();
@@ -1298,7 +1298,7 @@
   if (m_ePageSetMode != XFA_AttributeValue::DuplexPaginated)
     return true;
 
-  absl::optional<XFA_AttributeValue> ret =
+  std::optional<XFA_AttributeValue> ret =
       pPageArea->JSObject()->TryEnum(XFA_Attribute::OddOrEven, true);
   if (!ret.has_value() || ret == XFA_AttributeValue::Any)
     return true;
@@ -1327,7 +1327,7 @@
       CXFA_Node* pOccurNode =
           m_pCurPageArea->GetFirstChildByClass<CXFA_Occur>(XFA_Element::Occur);
       if (pOccurNode) {
-        absl::optional<int32_t> ret =
+        std::optional<int32_t> ret =
             pOccurNode->JSObject()->TryInteger(XFA_Attribute::Max, false);
         if (ret.has_value())
           iMax = ret.value();
@@ -1389,7 +1389,7 @@
     if (pContentArea->GetParent() != m_pCurPageArea)
       return false;
 
-    absl::optional<CXFA_ViewLayoutItem*> pContentAreaLayout =
+    std::optional<CXFA_ViewLayoutItem*> pContentAreaLayout =
         CheckContentAreaNotUsed(GetCurrentViewRecord()->pCurPageArea.Get(),
                                 pContentArea);
     if (!pContentAreaLayout.has_value())
@@ -1432,7 +1432,7 @@
     return 0;
 
   int32_t iMin = 0;
-  absl::optional<int32_t> ret;
+  std::optional<int32_t> ret;
   CXFA_Node* pOccurNode =
       pPageArea->GetFirstChildByClass<CXFA_Occur>(XFA_Element::Occur);
   if (pOccurNode) {
@@ -1476,7 +1476,7 @@
   if (!pOccurNode)
     return;
 
-  absl::optional<int32_t> iMin =
+  std::optional<int32_t> iMin =
       pOccurNode->JSObject()->TryInteger(XFA_Attribute::Min, false);
   if (!iMin.has_value() || iCurSetCount >= iMin.value())
     return;
@@ -1544,7 +1544,7 @@
   CXFA_Node* pOccurNode =
       pPageNode->GetFirstChildByClass<CXFA_Occur>(XFA_Element::Occur);
   int32_t iMax = 0;
-  absl::optional<int32_t> ret;
+  std::optional<int32_t> ret;
   if (pOccurNode) {
     ret = pOccurNode->JSObject()->TryInteger(XFA_Attribute::Max, false);
     if (ret.has_value())
diff --git a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h
index 859621d..1c65e00 100644
--- a/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h
+++ b/xfa/fxfa/layout/cxfa_viewlayoutprocessor.h
@@ -10,12 +10,12 @@
 #include <iterator>
 #include <list>
 #include <map>
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxcrt/unowned_ptr_exclusion.h"
 #include "fxjs/gc/heap.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "v8/include/cppgc/garbage-collected.h"
 #include "v8/include/cppgc/member.h"
 #include "v8/include/cppgc/prefinalizer.h"
@@ -67,10 +67,10 @@
   CXFA_ViewLayoutItem* GetRootLayoutItem() const {
     return m_pPageSetRootLayoutItem;
   }
-  absl::optional<BreakData> ProcessBreakBefore(const CXFA_Node* pBreakNode);
-  absl::optional<BreakData> ProcessBreakAfter(const CXFA_Node* pBreakNode);
-  absl::optional<OverflowData> ProcessOverflow(CXFA_Node* pFormNode,
-                                               bool bCreatePage);
+  std::optional<BreakData> ProcessBreakBefore(const CXFA_Node* pBreakNode);
+  std::optional<BreakData> ProcessBreakAfter(const CXFA_Node* pBreakNode);
+  std::optional<OverflowData> ProcessOverflow(CXFA_Node* pFormNode,
+                                              bool bCreatePage);
   CXFA_Node* QueryOverflow(CXFA_Node* pFormNode);
   CXFA_Node* ProcessBookendLeader(const CXFA_Node* pBookendNode);
   CXFA_Node* ProcessBookendTrailer(const CXFA_Node* pBookendNode);
@@ -133,7 +133,7 @@
                                            bool bLeader);
   CXFA_Node* ResolveBookendLeaderOrTrailer(const CXFA_Node* pBookendNode,
                                            bool bLeader);
-  absl::optional<BreakData> ProcessBreakBeforeOrAfter(
+  std::optional<BreakData> ProcessBreakBeforeOrAfter(
       const CXFA_Node* pBreakNode,
       bool bBefore);
   BreakData ExecuteBreakBeforeOrAfter(const CXFA_Node* pCurNode, bool bBefore);
diff --git a/xfa/fxfa/parser/cxfa_barcode.cpp b/xfa/fxfa/parser/cxfa_barcode.cpp
index 2801dc1..ceb96e3 100644
--- a/xfa/fxfa/parser/cxfa_barcode.cpp
+++ b/xfa/fxfa/parser/cxfa_barcode.cpp
@@ -71,15 +71,15 @@
   return WideString(JSObject()->GetCData(XFA_Attribute::Type));
 }
 
-absl::optional<WideString> CXFA_Barcode::GetCharEncoding() {
+std::optional<WideString> CXFA_Barcode::GetCharEncoding() {
   return JSObject()->TryCData(XFA_Attribute::CharEncoding, true);
 }
 
-absl::optional<bool> CXFA_Barcode::GetChecksum() {
-  absl::optional<XFA_AttributeValue> checksum =
+std::optional<bool> CXFA_Barcode::GetChecksum() {
+  std::optional<XFA_AttributeValue> checksum =
       JSObject()->TryEnum(XFA_Attribute::Checksum, true);
   if (!checksum.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   switch (checksum.value()) {
     case XFA_AttributeValue::None:
@@ -92,81 +92,81 @@
     default:
       break;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
-absl::optional<int32_t> CXFA_Barcode::GetDataLength() {
-  absl::optional<WideString> wsDataLength =
+std::optional<int32_t> CXFA_Barcode::GetDataLength() {
+  std::optional<WideString> wsDataLength =
       JSObject()->TryCData(XFA_Attribute::DataLength, true);
   if (!wsDataLength.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   return FXSYS_wtoi(wsDataLength->c_str());
 }
 
-absl::optional<char> CXFA_Barcode::GetStartChar() {
-  absl::optional<WideString> wsStartEndChar =
+std::optional<char> CXFA_Barcode::GetStartChar() {
+  std::optional<WideString> wsStartEndChar =
       JSObject()->TryCData(XFA_Attribute::StartChar, true);
   if (!wsStartEndChar.has_value() || wsStartEndChar->IsEmpty())
-    return absl::nullopt;
+    return std::nullopt;
 
   return static_cast<char>(wsStartEndChar.value()[0]);
 }
 
-absl::optional<char> CXFA_Barcode::GetEndChar() {
-  absl::optional<WideString> wsStartEndChar =
+std::optional<char> CXFA_Barcode::GetEndChar() {
+  std::optional<WideString> wsStartEndChar =
       JSObject()->TryCData(XFA_Attribute::EndChar, true);
   if (!wsStartEndChar.has_value() || wsStartEndChar->IsEmpty())
-    return absl::nullopt;
+    return std::nullopt;
 
   return static_cast<char>(wsStartEndChar.value()[0]);
 }
 
-absl::optional<int32_t> CXFA_Barcode::GetECLevel() {
-  absl::optional<WideString> wsECLevel =
+std::optional<int32_t> CXFA_Barcode::GetECLevel() {
+  std::optional<WideString> wsECLevel =
       JSObject()->TryCData(XFA_Attribute::ErrorCorrectionLevel, true);
   if (!wsECLevel.has_value())
-    return absl::nullopt;
+    return std::nullopt;
   return FXSYS_wtoi(wsECLevel->c_str());
 }
 
-absl::optional<int32_t> CXFA_Barcode::GetModuleWidth() {
-  absl::optional<CXFA_Measurement> moduleWidthHeight =
+std::optional<int32_t> CXFA_Barcode::GetModuleWidth() {
+  std::optional<CXFA_Measurement> moduleWidthHeight =
       JSObject()->TryMeasure(XFA_Attribute::ModuleWidth, true);
   if (!moduleWidthHeight.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   return static_cast<int32_t>(moduleWidthHeight->ToUnit(XFA_Unit::Pt));
 }
 
-absl::optional<int32_t> CXFA_Barcode::GetModuleHeight() {
-  absl::optional<CXFA_Measurement> moduleWidthHeight =
+std::optional<int32_t> CXFA_Barcode::GetModuleHeight() {
+  std::optional<CXFA_Measurement> moduleWidthHeight =
       JSObject()->TryMeasure(XFA_Attribute::ModuleHeight, true);
   if (!moduleWidthHeight.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   return static_cast<int32_t>(moduleWidthHeight->ToUnit(XFA_Unit::Pt));
 }
 
-absl::optional<bool> CXFA_Barcode::GetPrintChecksum() {
+std::optional<bool> CXFA_Barcode::GetPrintChecksum() {
   return JSObject()->TryBoolean(XFA_Attribute::PrintCheckDigit, true);
 }
 
-absl::optional<XFA_AttributeValue> CXFA_Barcode::GetTextLocation() {
+std::optional<XFA_AttributeValue> CXFA_Barcode::GetTextLocation() {
   return JSObject()->TryEnum(XFA_Attribute::TextLocation, true);
 }
 
-absl::optional<bool> CXFA_Barcode::GetTruncate() {
+std::optional<bool> CXFA_Barcode::GetTruncate() {
   return JSObject()->TryBoolean(XFA_Attribute::Truncate, true);
 }
 
-absl::optional<int8_t> CXFA_Barcode::GetWideNarrowRatio() {
-  absl::optional<WideString> wsWideNarrowRatio =
+std::optional<int8_t> CXFA_Barcode::GetWideNarrowRatio() {
+  std::optional<WideString> wsWideNarrowRatio =
       JSObject()->TryCData(XFA_Attribute::WideNarrowRatio, true);
   if (!wsWideNarrowRatio.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
-  absl::optional<size_t> ptPos = wsWideNarrowRatio->Find(':');
+  std::optional<size_t> ptPos = wsWideNarrowRatio->Find(':');
   if (!ptPos.has_value())
     return static_cast<int8_t>(FXSYS_wtoi(wsWideNarrowRatio->c_str()));
 
diff --git a/xfa/fxfa/parser/cxfa_barcode.h b/xfa/fxfa/parser/cxfa_barcode.h
index a297ec0..99b24ad 100644
--- a/xfa/fxfa/parser/cxfa_barcode.h
+++ b/xfa/fxfa/parser/cxfa_barcode.h
@@ -7,7 +7,8 @@
 #ifndef XFA_FXFA_PARSER_CXFA_BARCODE_H_
 #define XFA_FXFA_PARSER_CXFA_BARCODE_H_
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include <optional>
+
 #include "xfa/fxfa/parser/cxfa_node.h"
 
 class CXFA_Barcode final : public CXFA_Node {
@@ -20,18 +21,18 @@
   XFA_FFWidgetType GetDefaultFFWidgetType() const override;
 
   WideString GetBarcodeType();
-  absl::optional<WideString> GetCharEncoding();
-  absl::optional<bool> GetChecksum();
-  absl::optional<int32_t> GetDataLength();
-  absl::optional<char> GetStartChar();
-  absl::optional<char> GetEndChar();
-  absl::optional<int32_t> GetECLevel();
-  absl::optional<int32_t> GetModuleWidth();
-  absl::optional<int32_t> GetModuleHeight();
-  absl::optional<bool> GetPrintChecksum();
-  absl::optional<XFA_AttributeValue> GetTextLocation();
-  absl::optional<bool> GetTruncate();
-  absl::optional<int8_t> GetWideNarrowRatio();
+  std::optional<WideString> GetCharEncoding();
+  std::optional<bool> GetChecksum();
+  std::optional<int32_t> GetDataLength();
+  std::optional<char> GetStartChar();
+  std::optional<char> GetEndChar();
+  std::optional<int32_t> GetECLevel();
+  std::optional<int32_t> GetModuleWidth();
+  std::optional<int32_t> GetModuleHeight();
+  std::optional<bool> GetPrintChecksum();
+  std::optional<XFA_AttributeValue> GetTextLocation();
+  std::optional<bool> GetTruncate();
+  std::optional<int8_t> GetWideNarrowRatio();
 
  private:
   CXFA_Barcode(CXFA_Document* doc, XFA_PacketType packet);
diff --git a/xfa/fxfa/parser/cxfa_box.cpp b/xfa/fxfa/parser/cxfa_box.cpp
index cd644aa..db331c5 100644
--- a/xfa/fxfa/parser/cxfa_box.cpp
+++ b/xfa/fxfa/parser/cxfa_box.cpp
@@ -111,11 +111,11 @@
   return JSObject()->GetBoolean(XFA_Attribute::Circular);
 }
 
-absl::optional<int32_t> CXFA_Box::GetStartAngle() {
+std::optional<int32_t> CXFA_Box::GetStartAngle() {
   return JSObject()->TryInteger(XFA_Attribute::StartAngle, false);
 }
 
-absl::optional<int32_t> CXFA_Box::GetSweepAngle() {
+std::optional<int32_t> CXFA_Box::GetSweepAngle() {
   return JSObject()->TryInteger(XFA_Attribute::SweepAngle, false);
 }
 
@@ -256,8 +256,8 @@
   rtDraw.top = center.y - b;
   rtDraw.width = a + a;
   rtDraw.height = b + b;
-  absl::optional<int32_t> startAngle = GetStartAngle();
-  absl::optional<int32_t> sweepAngle = GetSweepAngle();
+  std::optional<int32_t> startAngle = GetStartAngle();
+  std::optional<int32_t> sweepAngle = GetSweepAngle();
   if (!startAngle.has_value() && !sweepAngle.has_value()) {
     fillPath->AddEllipse(rtDraw);
     return;
diff --git a/xfa/fxfa/parser/cxfa_box.h b/xfa/fxfa/parser/cxfa_box.h
index 5012094..b906573 100644
--- a/xfa/fxfa/parser/cxfa_box.h
+++ b/xfa/fxfa/parser/cxfa_box.h
@@ -52,8 +52,8 @@
 
  private:
   bool IsCircular();
-  absl::optional<int32_t> GetStartAngle();
-  absl::optional<int32_t> GetSweepAngle();
+  std::optional<int32_t> GetStartAngle();
+  std::optional<int32_t> GetSweepAngle();
 
   std::vector<CXFA_Stroke*> GetStrokesInternal(bool bNull);
   void DrawFill(const std::vector<CXFA_Stroke*>& strokes,
diff --git a/xfa/fxfa/parser/cxfa_color.cpp b/xfa/fxfa/parser/cxfa_color.cpp
index 044372d..ed78cd7 100644
--- a/xfa/fxfa/parser/cxfa_color.cpp
+++ b/xfa/fxfa/parser/cxfa_color.cpp
@@ -95,13 +95,13 @@
 CXFA_Color::~CXFA_Color() = default;
 
 FX_ARGB CXFA_Color::GetValue() const {
-  absl::optional<WideString> val =
+  std::optional<WideString> val =
       JSObject()->TryCData(XFA_Attribute::Value, false);
   return val.has_value() ? StringToFXARGB(val->AsStringView()) : 0xFF000000;
 }
 
 FX_ARGB CXFA_Color::GetValueOrDefault(FX_ARGB defaultValue) const {
-  absl::optional<WideString> val =
+  std::optional<WideString> val =
       JSObject()->TryCData(XFA_Attribute::Value, false);
   return val.has_value() ? StringToFXARGB(val->AsStringView()) : defaultValue;
 }
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 45c7849..28b1f3b 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -106,7 +106,7 @@
       if (!pContentRawDataNode) {
         XFA_Element element = XFA_Element::Sharptext;
         if (pChildNode->GetElementType() == XFA_Element::ExData) {
-          absl::optional<WideString> contentType =
+          std::optional<WideString> contentType =
               pChildNode->JSObject()->TryAttribute(XFA_Attribute::ContentType,
                                                    false);
           if (contentType.has_value()) {
@@ -352,7 +352,7 @@
     dwFlags |= XFA_ResolveFlag::kParent;
     dwFlags |= XFA_ResolveFlag::kSiblings;
   }
-  absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+  std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
       pDocument->GetScriptContext()->ResolveObjectsWithBindNode(
           pDataScope, wsRef.AsStringView(), dwFlags, pTemplateNode);
   if (!maybeResult.has_value())
@@ -752,7 +752,7 @@
       if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup)
         continue;
 
-      absl::optional<WideString> ns = pDDGroupNode->JSObject()->TryNamespace();
+      std::optional<WideString> ns = pDDGroupNode->JSObject()->TryNamespace();
       if (!ns.has_value() ||
           !ns.value().EqualsASCII("http://ns.adobe.com/data-description/")) {
         continue;
@@ -1201,7 +1201,7 @@
                   : WideString();
           const Mask<XFA_ResolveFlag> kFlags = {XFA_ResolveFlag::kChildren,
                                                 XFA_ResolveFlag::kCreateNode};
-          absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+          std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
               pDocument->GetScriptContext()->ResolveObjectsWithBindNode(
                   pDataScope, wsRef.AsStringView(), kFlags, pTemplateNode);
           CXFA_Object* pObject =
@@ -1259,8 +1259,7 @@
         if (pDDGroupNode->GetElementType() != XFA_Element::DataGroup)
           continue;
 
-        absl::optional<WideString> ns =
-            pDDGroupNode->JSObject()->TryNamespace();
+        std::optional<WideString> ns = pDDGroupNode->JSObject()->TryNamespace();
         if (!ns.has_value() ||
             !ns.value().EqualsASCII("http://ns.adobe.com/data-description/")) {
           continue;
@@ -1341,12 +1340,12 @@
         if (pDatasetsChild->GetNameHash() != XFA_HASHCODE_Data)
           continue;
 
-        absl::optional<WideString> namespaceURI =
+        std::optional<WideString> namespaceURI =
             pDatasetsChild->JSObject()->TryNamespace();
         if (!namespaceURI.has_value())
           continue;
 
-        absl::optional<WideString> datasetsURI =
+        std::optional<WideString> datasetsURI =
             pDatasetsNode->JSObject()->TryNamespace();
         if (!datasetsURI.has_value())
           continue;
@@ -1561,7 +1560,7 @@
 
     CXFA_Node* pProtoNode = nullptr;
     if (!wsSOM.IsEmpty()) {
-      absl::optional<CFXJSE_Engine::ResolveResult> maybeResult =
+      std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
           m_pScriptContext->ResolveObjects(
               pUseHrefNode, wsSOM,
               Mask<XFA_ResolveFlag>{
@@ -1701,7 +1700,7 @@
       continue;
 
     if (!pDDRoot && pChildNode->GetNameHash() == XFA_HASHCODE_DataDescription) {
-      absl::optional<WideString> namespaceURI =
+      std::optional<WideString> namespaceURI =
           pChildNode->JSObject()->TryNamespace();
       if (!namespaceURI.has_value())
         continue;
@@ -1710,7 +1709,7 @@
         pDDRoot = pChildNode;
       }
     } else if (!pDataRoot && pChildNode->GetNameHash() == XFA_HASHCODE_Data) {
-      absl::optional<WideString> namespaceURI =
+      std::optional<WideString> namespaceURI =
           pChildNode->JSObject()->TryNamespace();
       if (!namespaceURI.has_value())
         continue;
diff --git a/xfa/fxfa/parser/cxfa_document.h b/xfa/fxfa/parser/cxfa_document.h
index ac09825..0bccfe0 100644
--- a/xfa/fxfa/parser/cxfa_document.h
+++ b/xfa/fxfa/parser/cxfa_document.h
@@ -12,12 +12,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxcrt/widestring.h"
 #include "fxjs/gc/heap.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 #include "v8/include/cppgc/garbage-collected.h"
 #include "v8/include/cppgc/member.h"
@@ -179,7 +179,7 @@
   std::map<uint32_t, cppgc::Member<CXFA_Node>> m_rgGlobalBinding;
   std::vector<cppgc::Member<CXFA_Node>> m_pPendingPageSet;
   XFA_VERSION m_eCurVersionMode = XFA_VERSION_DEFAULT;
-  absl::optional<bool> m_Interactive;
+  std::optional<bool> m_Interactive;
   bool m_bStrictScoping = false;
   bool m_bScripting = false;
 };
diff --git a/xfa/fxfa/parser/cxfa_document_builder.cpp b/xfa/fxfa/parser/cxfa_document_builder.cpp
index c103284..d6333e9 100644
--- a/xfa/fxfa/parser/cxfa_document_builder.cpp
+++ b/xfa/fxfa/parser/cxfa_document_builder.cpp
@@ -6,6 +6,7 @@
 
 #include "xfa/fxfa/parser/cxfa_document_builder.h"
 
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -19,7 +20,6 @@
 #include "core/fxcrt/xml/cfx_xmlnode.h"
 #include "core/fxcrt/xml/cfx_xmltext.h"
 #include "fxjs/xfa/cjx_object.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/check.h"
 #include "third_party/base/notreached.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
@@ -96,7 +96,7 @@
   return true;
 }
 
-absl::optional<WideString> FindAttributeWithNS(
+std::optional<WideString> FindAttributeWithNS(
     CFX_XMLElement* pElement,
     WideStringView wsLocalAttributeName,
     WideStringView wsNamespaceURIPrefix) {
@@ -121,7 +121,7 @@
     }
     return it.second;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 CFX_XMLNode* GetDataSetsFromXDP(CFX_XMLNode* pXMLDocumentNode) {
@@ -377,7 +377,7 @@
       continue;
 
     WideString wsPacketName = pElement->GetLocalTagName();
-    absl::optional<XFA_PACKETINFO> packet_info =
+    std::optional<XFA_PACKETINFO> packet_info =
         XFA_GetPacketByName(wsPacketName.AsStringView());
     if (packet_info.has_value() && packet_info.value().uri &&
         !MatchNodeName(pElement, packet_info.value().name,
@@ -677,7 +677,7 @@
           if (wsAttrName.EqualsASCII("nil") && it.second.EqualsASCII("true"))
             IsNeedValue = false;
 
-          absl::optional<XFA_ATTRIBUTEINFO> attr =
+          std::optional<XFA_ATTRIBUTEINFO> attr =
               XFA_GetAttributeByName(wsAttrName.AsStringView());
           if (!attr.has_value())
             continue;
@@ -795,7 +795,7 @@
 
         XFA_Element eNodeType = XFA_Element::DataModel;
         if (eNodeType == XFA_Element::DataModel) {
-          absl::optional<WideString> wsDataNodeAttr =
+          std::optional<WideString> wsDataNodeAttr =
               FindAttributeWithNS(pXMLElement, L"dataNode",
                                   L"http://www.xfa.org/schema/xfa-data/1.0/");
           if (wsDataNodeAttr.has_value()) {
@@ -806,7 +806,7 @@
           }
         }
         if (eNodeType == XFA_Element::DataModel) {
-          absl::optional<WideString> wsContentType =
+          std::optional<WideString> wsContentType =
               FindAttributeWithNS(pXMLElement, L"contentType",
                                   L"http://www.xfa.org/schema/xfa-data/1.0/");
           if (wsContentType.has_value() && !wsContentType.value().IsEmpty())
diff --git a/xfa/fxfa/parser/cxfa_localemgr.cpp b/xfa/fxfa/parser/cxfa_localemgr.cpp
index f49275e..dcdd626 100644
--- a/xfa/fxfa/parser/cxfa_localemgr.cpp
+++ b/xfa/fxfa/parser/cxfa_localemgr.cpp
@@ -1231,7 +1231,7 @@
   m_pDefLocale = pLocale;
 }
 
-absl::optional<WideString> CXFA_LocaleMgr::GetConfigLocaleName(
+std::optional<WideString> CXFA_LocaleMgr::GetConfigLocaleName(
     CXFA_Node* pConfig) const {
   if (m_bConfigLocaleCached)
     return m_wsConfigLocale;
@@ -1260,7 +1260,7 @@
   if (!pLocale)
     return m_wsConfigLocale;
 
-  absl::optional<WideString> wsMaybeLocale =
+  std::optional<WideString> wsMaybeLocale =
       pLocale->JSObject()->TryCData(XFA_Attribute::Value, false);
   if (!wsMaybeLocale.has_value() || wsMaybeLocale.value().IsEmpty())
     return m_wsConfigLocale;
diff --git a/xfa/fxfa/parser/cxfa_localemgr.h b/xfa/fxfa/parser/cxfa_localemgr.h
index d06f211..3c8376c 100644
--- a/xfa/fxfa/parser/cxfa_localemgr.h
+++ b/xfa/fxfa/parser/cxfa_localemgr.h
@@ -7,12 +7,12 @@
 #ifndef XFA_FXFA_PARSER_CXFA_LOCALEMGR_H_
 #define XFA_FXFA_PARSER_CXFA_LOCALEMGR_H_
 
+#include <optional>
 #include <vector>
 
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxcrt/widestring.h"
 #include "fxjs/gc/heap.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "v8/include/cppgc/garbage-collected.h"
 #include "v8/include/cppgc/member.h"
 #include "xfa/fgas/crt/locale_mgr_iface.h"
@@ -52,7 +52,7 @@
   GCedLocaleIface* GetLocaleByName(const WideString& wsLocaleName) override;
 
   void SetDefLocale(GCedLocaleIface* pLocale);
-  absl::optional<WideString> GetConfigLocaleName(CXFA_Node* pConfig) const;
+  std::optional<WideString> GetConfigLocaleName(CXFA_Node* pConfig) const;
 
  private:
   CXFA_LocaleMgr(cppgc::Heap* pHeap,
@@ -74,7 +74,7 @@
   // 3. we might have tried and gotten something.
   // So |m_bConfigLocaleCached| indicates whether we've already tried,
   // and |m_wsConfigLocale| is the possibly nothing we got if we tried.
-  mutable absl::optional<WideString> m_wsConfigLocale;
+  mutable std::optional<WideString> m_wsConfigLocale;
   mutable bool m_bConfigLocaleCached = false;
 
   LangID m_eDeflcid;
diff --git a/xfa/fxfa/parser/cxfa_margin.cpp b/xfa/fxfa/parser/cxfa_margin.cpp
index 7c0eee4..933725e 100644
--- a/xfa/fxfa/parser/cxfa_margin.cpp
+++ b/xfa/fxfa/parser/cxfa_margin.cpp
@@ -57,18 +57,18 @@
   return TryBottomInset().value_or(0);
 }
 
-absl::optional<float> CXFA_Margin::TryLeftInset() const {
+std::optional<float> CXFA_Margin::TryLeftInset() const {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::LeftInset);
 }
 
-absl::optional<float> CXFA_Margin::TryTopInset() const {
+std::optional<float> CXFA_Margin::TryTopInset() const {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::TopInset);
 }
 
-absl::optional<float> CXFA_Margin::TryRightInset() const {
+std::optional<float> CXFA_Margin::TryRightInset() const {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::RightInset);
 }
 
-absl::optional<float> CXFA_Margin::TryBottomInset() const {
+std::optional<float> CXFA_Margin::TryBottomInset() const {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::BottomInset);
 }
diff --git a/xfa/fxfa/parser/cxfa_margin.h b/xfa/fxfa/parser/cxfa_margin.h
index e54b03e..90ca5dc 100644
--- a/xfa/fxfa/parser/cxfa_margin.h
+++ b/xfa/fxfa/parser/cxfa_margin.h
@@ -19,10 +19,10 @@
   float GetRightInset() const;
   float GetBottomInset() const;
 
-  absl::optional<float> TryLeftInset() const;
-  absl::optional<float> TryTopInset() const;
-  absl::optional<float> TryRightInset() const;
-  absl::optional<float> TryBottomInset() const;
+  std::optional<float> TryLeftInset() const;
+  std::optional<float> TryTopInset() const;
+  std::optional<float> TryRightInset() const;
+  std::optional<float> TryBottomInset() const;
 
  private:
   CXFA_Margin(CXFA_Document* doc, XFA_PacketType packet);
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 9a5552e..1adf44c 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -1165,13 +1165,13 @@
   return pNewNode;
 }
 
-absl::optional<XFA_Element> CXFA_Node::GetFirstPropertyWithFlag(
+std::optional<XFA_Element> CXFA_Node::GetFirstPropertyWithFlag(
     XFA_PropertyFlag flag) const {
   for (const auto& prop : m_Properties) {
     if (prop.flags & flag)
       return prop.property;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 const CXFA_Node::AttributeData* CXFA_Node::GetAttributeData(
@@ -1249,7 +1249,7 @@
   if (!bFilterOneOfProperties || !nodes.empty())
     return nodes;
 
-  absl::optional<XFA_Element> property =
+  std::optional<XFA_Element> property =
       GetFirstPropertyWithFlag(XFA_PropertyFlag::kDefaultOneOf);
   if (!property.has_value())
     return nodes;
@@ -1414,7 +1414,7 @@
 }
 
 GCedLocaleIface* CXFA_Node::GetLocale() {
-  absl::optional<WideString> localeName = GetLocaleName();
+  std::optional<WideString> localeName = GetLocaleName();
   if (!localeName.has_value())
     return nullptr;
   if (localeName.value().EqualsASCII("ambient"))
@@ -1422,17 +1422,17 @@
   return GetDocument()->GetLocaleMgr()->GetLocaleByName(localeName.value());
 }
 
-absl::optional<WideString> CXFA_Node::GetLocaleName() {
+std::optional<WideString> CXFA_Node::GetLocaleName() {
   CXFA_Node* pForm = ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form));
   if (!pForm)
-    return absl::nullopt;
+    return std::nullopt;
 
   CXFA_Subform* pTopSubform =
       pForm->GetFirstChildByClass<CXFA_Subform>(XFA_Element::Subform);
   if (!pTopSubform)
-    return absl::nullopt;
+    return std::nullopt;
 
-  absl::optional<WideString> localeName;
+  std::optional<WideString> localeName;
   CXFA_Node* pLocaleNode = this;
   do {
     localeName =
@@ -1457,7 +1457,7 @@
 
   LocaleIface* pLocale = GetDocument()->GetLocaleMgr()->GetDefLocale();
   if (!pLocale)
-    return absl::nullopt;
+    return std::nullopt;
 
   return pLocale->GetName();
 }
@@ -1468,7 +1468,7 @@
   XFA_AttributeValue eLayoutType =
       layout.value_or(XFA_AttributeValue::Position);
   if (pKeep) {
-    absl::optional<XFA_AttributeValue> intact =
+    std::optional<XFA_AttributeValue> intact =
         GetIntactFromKeep(pKeep, eLayoutType);
     if (intact.has_value())
       return intact.value();
@@ -1501,7 +1501,7 @@
 
       XFA_VERSION version = m_pDocument->GetCurVersionMode();
       if (eParLayout == XFA_AttributeValue::Tb && version < XFA_VERSION_208) {
-        absl::optional<CXFA_Measurement> measureH =
+        std::optional<CXFA_Measurement> measureH =
             JSObject()->TryMeasure(XFA_Attribute::H, false);
         if (measureH.has_value())
           return XFA_AttributeValue::ContentArea;
@@ -2042,57 +2042,55 @@
   return pInstance;
 }
 
-absl::optional<bool> CXFA_Node::GetDefaultBoolean(XFA_Attribute attr) const {
-  absl::optional<void*> value =
+std::optional<bool> CXFA_Node::GetDefaultBoolean(XFA_Attribute attr) const {
+  std::optional<void*> value =
       GetDefaultValue(attr, XFA_AttributeType::Boolean);
   if (!value.has_value())
-    return absl::nullopt;
+    return std::nullopt;
   return !!value.value();
 }
 
-absl::optional<int32_t> CXFA_Node::GetDefaultInteger(XFA_Attribute attr) const {
-  absl::optional<void*> value =
+std::optional<int32_t> CXFA_Node::GetDefaultInteger(XFA_Attribute attr) const {
+  std::optional<void*> value =
       GetDefaultValue(attr, XFA_AttributeType::Integer);
   if (!value.has_value())
-    return absl::nullopt;
+    return std::nullopt;
   return static_cast<int32_t>(reinterpret_cast<uintptr_t>(value.value()));
 }
 
-absl::optional<CXFA_Measurement> CXFA_Node::GetDefaultMeasurement(
+std::optional<CXFA_Measurement> CXFA_Node::GetDefaultMeasurement(
     XFA_Attribute attr) const {
-  absl::optional<void*> value =
+  std::optional<void*> value =
       GetDefaultValue(attr, XFA_AttributeType::Measure);
   if (!value.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   WideString str = WideString(static_cast<const wchar_t*>(value.value()));
   return CXFA_Measurement(str.AsStringView());
 }
 
-absl::optional<WideString> CXFA_Node::GetDefaultCData(
-    XFA_Attribute attr) const {
-  absl::optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::CData);
+std::optional<WideString> CXFA_Node::GetDefaultCData(XFA_Attribute attr) const {
+  std::optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::CData);
   if (!value.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   return WideString(static_cast<const wchar_t*>(value.value()));
 }
 
-absl::optional<XFA_AttributeValue> CXFA_Node::GetDefaultEnum(
+std::optional<XFA_AttributeValue> CXFA_Node::GetDefaultEnum(
     XFA_Attribute attr) const {
-  absl::optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Enum);
+  std::optional<void*> value = GetDefaultValue(attr, XFA_AttributeType::Enum);
   if (!value.has_value())
-    return absl::nullopt;
+    return std::nullopt;
   return static_cast<XFA_AttributeValue>(
       reinterpret_cast<uintptr_t>(value.value()));
 }
 
-absl::optional<void*> CXFA_Node::GetDefaultValue(
-    XFA_Attribute attr,
-    XFA_AttributeType eType) const {
+std::optional<void*> CXFA_Node::GetDefaultValue(XFA_Attribute attr,
+                                                XFA_AttributeType eType) const {
   const AttributeData* data = GetAttributeData(attr);
   if (!data || data->type != eType)
-    return absl::nullopt;
+    return std::nullopt;
   return data->default_value;
 }
 
@@ -2257,7 +2255,7 @@
 }
 
 int32_t CXFA_Node::GetRotate() const {
-  absl::optional<int32_t> degrees =
+  std::optional<int32_t> degrees =
       JSObject()->TryInteger(XFA_Attribute::Rotate, false);
   return degrees.has_value() ? XFA_MapRotation(degrees.value()) / 90 * 90 : 0;
 }
@@ -2349,13 +2347,13 @@
   return JSObject()->GetProperty<CXFA_Bind>(0, XFA_Element::Bind);
 }
 
-absl::optional<XFA_AttributeValue> CXFA_Node::GetIntactFromKeep(
+std::optional<XFA_AttributeValue> CXFA_Node::GetIntactFromKeep(
     const CXFA_Keep* pKeep,
     XFA_AttributeValue eLayoutType) const {
-  absl::optional<XFA_AttributeValue> intact =
+  std::optional<XFA_AttributeValue> intact =
       pKeep->JSObject()->TryEnum(XFA_Attribute::Intact, false);
   if (!intact.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (intact.value() != XFA_AttributeValue::None ||
       eLayoutType != XFA_AttributeValue::Row ||
@@ -2369,7 +2367,7 @@
     return intact;
   }
 
-  absl::optional<XFA_AttributeValue> value =
+  std::optional<XFA_AttributeValue> value =
       pKeep->JSObject()->TryEnum(XFA_Attribute::Previous, false);
   if (value == XFA_AttributeValue::ContentArea ||
       value == XFA_AttributeValue::PageArea) {
@@ -2381,7 +2379,7 @@
   if (!pNode)
     return intact;
 
-  absl::optional<XFA_AttributeValue> ret =
+  std::optional<XFA_AttributeValue> ret =
       pNode->JSObject()->TryEnum(XFA_Attribute::Next, false);
   if (ret == XFA_AttributeValue::ContentArea ||
       ret == XFA_AttributeValue::PageArea) {
@@ -2390,27 +2388,27 @@
   return intact;
 }
 
-absl::optional<float> CXFA_Node::TryWidth() {
+std::optional<float> CXFA_Node::TryWidth() {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::W);
 }
 
-absl::optional<float> CXFA_Node::TryHeight() {
+std::optional<float> CXFA_Node::TryHeight() {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::H);
 }
 
-absl::optional<float> CXFA_Node::TryMinWidth() {
+std::optional<float> CXFA_Node::TryMinWidth() {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MinW);
 }
 
-absl::optional<float> CXFA_Node::TryMinHeight() {
+std::optional<float> CXFA_Node::TryMinHeight() {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MinH);
 }
 
-absl::optional<float> CXFA_Node::TryMaxWidth() {
+std::optional<float> CXFA_Node::TryMaxWidth() {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MaxW);
 }
 
-absl::optional<float> CXFA_Node::TryMaxHeight() {
+std::optional<float> CXFA_Node::TryMaxHeight() {
   return JSObject()->TryMeasureAsFloat(XFA_Attribute::MaxH);
 }
 
@@ -3007,10 +3005,10 @@
   if (border && border->GetPresence() != XFA_AttributeValue::Visible)
     return CFX_RectF();
 
-  absl::optional<float> left = mgUI->TryLeftInset();
-  absl::optional<float> top = mgUI->TryTopInset();
-  absl::optional<float> right = mgUI->TryRightInset();
-  absl::optional<float> bottom = mgUI->TryBottomInset();
+  std::optional<float> left = mgUI->TryLeftInset();
+  std::optional<float> top = mgUI->TryTopInset();
+  std::optional<float> right = mgUI->TryRightInset();
+  std::optional<float> bottom = mgUI->TryBottomInset();
   if (border) {
     bool bVisible = false;
     float fThickness = 0;
@@ -3254,28 +3252,28 @@
   if (para)
     pSize->width += para->GetMarginLeft() + para->GetTextIndent();
 
-  absl::optional<float> width = TryWidth();
+  std::optional<float> width = TryWidth();
   if (width.has_value()) {
     pSize->width = width.value();
   } else {
-    absl::optional<float> min = TryMinWidth();
+    std::optional<float> min = TryMinWidth();
     if (min.has_value())
       pSize->width = std::max(pSize->width, min.value());
 
-    absl::optional<float> max = TryMaxWidth();
+    std::optional<float> max = TryMaxWidth();
     if (max.has_value() && max.value() > 0)
       pSize->width = std::min(pSize->width, max.value());
   }
 
-  absl::optional<float> height = TryHeight();
+  std::optional<float> height = TryHeight();
   if (height.has_value()) {
     pSize->height = height.value();
   } else {
-    absl::optional<float> min = TryMinHeight();
+    std::optional<float> min = TryMinHeight();
     if (min.has_value())
       pSize->height = std::max(pSize->height, min.value());
 
-    absl::optional<float> max = TryMaxHeight();
+    std::optional<float> max = TryMaxHeight();
     if (max.has_value() && max.value() > 0)
       pSize->height = std::min(pSize->height, max.value());
   }
@@ -3384,7 +3382,7 @@
                     XFA_UnitPx2Pt(img_height, dpi.height));
 
   CFX_RectF rtFit;
-  absl::optional<float> width = TryWidth();
+  std::optional<float> width = TryWidth();
   if (width.has_value()) {
     rtFit.width = width.value();
     GetWidthWithoutMargin(rtFit.width);
@@ -3392,7 +3390,7 @@
     rtFit.width = rtImage.width;
   }
 
-  absl::optional<float> height = TryHeight();
+  std::optional<float> height = TryHeight();
   if (height.has_value()) {
     rtFit.height = height.value();
     GetHeightWithoutMargin(rtFit.height);
@@ -3457,11 +3455,11 @@
   if (margin)
     fWidthCalc += margin->GetLeftInset() + margin->GetRightInset();
 
-  absl::optional<float> min = TryMinWidth();
+  std::optional<float> min = TryMinWidth();
   if (min.has_value())
     fWidthCalc = std::max(fWidthCalc, min.value());
 
-  absl::optional<float> max = TryMaxWidth();
+  std::optional<float> max = TryMaxWidth();
   if (max.has_value() && max.value() > 0)
     fWidthCalc = std::min(fWidthCalc, max.value());
 
@@ -3480,11 +3478,11 @@
   if (margin)
     fHeightCalc += margin->GetTopInset() + margin->GetBottomInset();
 
-  absl::optional<float> min = TryMinHeight();
+  std::optional<float> min = TryMinHeight();
   if (min.has_value())
     fHeightCalc = std::max(fHeightCalc, min.value());
 
-  absl::optional<float> max = TryMaxHeight();
+  std::optional<float> max = TryMaxHeight();
   if (max.has_value() && max.value() > 0)
     fHeightCalc = std::min(fHeightCalc, max.value());
 
@@ -3514,7 +3512,7 @@
   m_pLayoutData->SetWidgetHeight(-1.0f);
   float fWidth = 0;
   if (*pCalcWidth > 0 && *pCalcHeight < 0) {
-    absl::optional<float> height = TryHeight();
+    std::optional<float> height = TryHeight();
     if (height.has_value()) {
       *pCalcHeight = height.value();
     } else {
@@ -3526,8 +3524,8 @@
     return;
   }
   if (*pCalcWidth < 0 && *pCalcHeight < 0) {
-    absl::optional<float> height;
-    absl::optional<float> width = TryWidth();
+    std::optional<float> height;
+    std::optional<float> width = TryWidth();
     if (width.has_value()) {
       fWidth = width.value();
       height = TryHeight();
@@ -3586,14 +3584,14 @@
   return sz;
 }
 
-absl::optional<float> CXFA_Node::FindSplitPos(CXFA_FFDocView* pDocView,
-                                              size_t szBlockIndex,
-                                              float fCalcHeight) {
+std::optional<float> CXFA_Node::FindSplitPos(CXFA_FFDocView* pDocView,
+                                             size_t szBlockIndex,
+                                             float fCalcHeight) {
   if (!HasCreatedUIWidget())
-    return absl::nullopt;
+    return std::nullopt;
 
   if (GetFFWidgetType() == XFA_FFWidgetType::kSubform)
-    return absl::nullopt;
+    return std::nullopt;
 
   switch (GetFFWidgetType()) {
     case XFA_FFWidgetType::kText:
@@ -3633,7 +3631,7 @@
       if (szBlockIndex == 0)
         fCalcHeight += fTopInset;
       if (fabs(fHeight - fCalcHeight) < kXFAWidgetPrecision)
-        return absl::nullopt;
+        return std::nullopt;
     }
     return fCalcHeight;
   }
@@ -3674,14 +3672,14 @@
   std::vector<float>* pFieldArray = &pFieldData->m_FieldSplitArray;
   size_t szFieldSplitCount = pFieldArray->size();
   if (szFieldSplitCount < szBlockIndex * 3)
-    return absl::nullopt;
+    return std::nullopt;
 
   for (size_t i = 0; i < szBlockIndex * 3; i += 3) {
     iLinesCount -= static_cast<int32_t>((*pFieldArray)[i + 1]);
     fHeight -= (*pFieldArray)[i + 2];
   }
   if (iLinesCount == 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   float fLineHeight = GetLineHeight();
   float fFontSize = GetFontSize();
@@ -3757,7 +3755,7 @@
       pFieldArray->push_back(0);
       pFieldArray->push_back(fCalcHeight);
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (fCalcHeight - fStartOffset < fLineHeight) {
@@ -3785,7 +3783,7 @@
         pFieldArray->push_back(iLinesCount);
         pFieldArray->push_back(fCalcHeight);
       }
-      return absl::nullopt;
+      return std::nullopt;
     }
     if (fHeight - fStartOffset - fTextHeight < fFontSize) {
       iLineNum -= 1;
@@ -3807,7 +3805,7 @@
     pFieldArray->push_back(fSplitHeight);
   }
   if (fabs(fSplitHeight - fCalcHeight) < kXFAWidgetPrecision)
-    return absl::nullopt;
+    return std::nullopt;
   return fSplitHeight;
 }
 
@@ -3867,7 +3865,7 @@
     pTextLayout->StartLayout(fWidth);
   }
   if (*pCalcWidth < 0 && *pCalcHeight < 0) {
-    absl::optional<float> width = TryWidth();
+    std::optional<float> width = TryWidth();
     if (width.has_value()) {
       pTextLayout->StartLayout(GetWidthWithoutMargin(width.value()));
       *pCalcWidth = width.value();
@@ -3998,7 +3996,7 @@
   CXFA_Node* pText = pItems->GetFirstChild();
   int32_t i = 0;
   while (pText) {
-    absl::optional<WideString> wsContent =
+    std::optional<WideString> wsContent =
         pText->JSObject()->TryContent(false, true);
     if (wsContent == wsValue)
       return static_cast<XFA_CheckState>(i);
@@ -4218,8 +4216,8 @@
   return pItem->CountChildren(XFA_Element::Unknown, false);
 }
 
-absl::optional<WideString> CXFA_Node::GetChoiceListItem(int32_t nIndex,
-                                                        bool bSaveValue) {
+std::optional<WideString> CXFA_Node::GetChoiceListItem(int32_t nIndex,
+                                                       bool bSaveValue) {
   std::vector<CXFA_Node*> pItemsArray;
   int32_t iCount = 0;
   for (CXFA_Node* pNode = GetFirstChild(); pNode;
@@ -4233,7 +4231,7 @@
       break;
   }
   if (iCount == 0)
-    return absl::nullopt;
+    return std::nullopt;
 
   CXFA_Node* pItems = pItemsArray[0];
   if (iCount > 1) {
@@ -4245,12 +4243,12 @@
       pItems = pItemsArray[1];
   }
   if (!pItems)
-    return absl::nullopt;
+    return std::nullopt;
 
   CXFA_Node* pItem =
       pItems->GetChild<CXFA_Node>(nIndex, XFA_Element::Unknown, false);
   if (!pItem)
-    return absl::nullopt;
+    return std::nullopt;
 
   return pItem->JSObject()->GetContent(false);
 }
@@ -4611,14 +4609,14 @@
   return false;
 }
 
-absl::optional<int32_t> CXFA_Node::GetNumberOfCells() {
+std::optional<int32_t> CXFA_Node::GetNumberOfCells() {
   CXFA_Node* pUIChild = GetUIChildNode();
   if (!pUIChild)
-    return absl::nullopt;
+    return std::nullopt;
 
   CXFA_Comb* pNode = pUIChild->GetChild<CXFA_Comb>(0, XFA_Element::Comb, false);
   if (!pNode)
-    return absl::nullopt;
+    return std::nullopt;
 
   return pNode->JSObject()->GetInteger(XFA_Attribute::NumberOfCells);
 }
@@ -4737,7 +4735,7 @@
         auto* pPicture =
             pFormat->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false);
         if (pPicture) {
-          absl::optional<WideString> picture =
+          std::optional<WideString> picture =
               pPicture->JSObject()->TryContent(false, true);
           if (picture.has_value())
             return picture.value();
@@ -4772,7 +4770,7 @@
       if (pUI) {
         if (CXFA_Picture* pPicture =
                 pUI->GetChild<CXFA_Picture>(0, XFA_Element::Picture, false)) {
-          absl::optional<WideString> picture =
+          std::optional<WideString> picture =
               pPicture->JSObject()->TryContent(false, true);
           if (picture.has_value())
             return picture.value();
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index d0c6798..5ed0487 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -10,6 +10,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -21,7 +22,6 @@
 #include "core/fxcrt/widestring.h"
 #include "core/fxge/dib/fx_dib.h"
 #include "fxjs/gc/gced_tree_node_mixin.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/base/containers/span.h"
 #include "v8/include/cppgc/member.h"
 #include "v8/include/cppgc/visitor.h"
@@ -234,7 +234,7 @@
   bool HasBindItem() const;
   CXFA_Node* GetContainerNode();
   GCedLocaleIface* GetLocale();
-  absl::optional<WideString> GetLocaleName();
+  std::optional<WideString> GetLocaleName();
   XFA_AttributeValue GetIntact();
   WideString GetNameExpression();
 
@@ -264,12 +264,12 @@
 
   CXFA_Node* GetInstanceMgrOfSubform();
 
-  absl::optional<bool> GetDefaultBoolean(XFA_Attribute attr) const;
-  absl::optional<int32_t> GetDefaultInteger(XFA_Attribute attr) const;
-  absl::optional<CXFA_Measurement> GetDefaultMeasurement(
+  std::optional<bool> GetDefaultBoolean(XFA_Attribute attr) const;
+  std::optional<int32_t> GetDefaultInteger(XFA_Attribute attr) const;
+  std::optional<CXFA_Measurement> GetDefaultMeasurement(
       XFA_Attribute attr) const;
-  absl::optional<WideString> GetDefaultCData(XFA_Attribute attr) const;
-  absl::optional<XFA_AttributeValue> GetDefaultEnum(XFA_Attribute attr) const;
+  std::optional<WideString> GetDefaultCData(XFA_Attribute attr) const;
+  std::optional<XFA_AttributeValue> GetDefaultEnum(XFA_Attribute attr) const;
 
   bool IsOpenAccess() const;
 
@@ -294,7 +294,7 @@
   WideString GetRawValue() const;
 
   int32_t GetRotate() const;
-  absl::optional<float> TryWidth();
+  std::optional<float> TryWidth();
 
   CXFA_Node* GetExclGroupIfExists();
 
@@ -332,9 +332,9 @@
   void StartWidgetLayout(CXFA_FFDoc* doc,
                          float* pCalcWidth,
                          float* pCalcHeight);
-  absl::optional<float> FindSplitPos(CXFA_FFDocView* pDocView,
-                                     size_t szBlockIndex,
-                                     float fCalcHeight);
+  std::optional<float> FindSplitPos(CXFA_FFDocView* pDocView,
+                                    size_t szBlockIndex,
+                                    float fCalcHeight);
 
   bool LoadCaption(CXFA_FFDoc* doc);
   CXFA_TextLayout* GetCaptionTextLayout();
@@ -375,7 +375,7 @@
 
   bool IsChoiceListAllowTextEntry();
   size_t CountChoiceListItems(bool bSaveValue);
-  absl::optional<WideString> GetChoiceListItem(int32_t nIndex, bool bSaveValue);
+  std::optional<WideString> GetChoiceListItem(int32_t nIndex, bool bSaveValue);
   bool IsChoiceListMultiSelect();
   bool IsChoiceListCommitOnSelect();
   std::vector<WideString> GetChoiceListItems(bool bSaveValue);
@@ -404,7 +404,7 @@
 
   bool IsHorizontalScrollPolicyOff();
   bool IsVerticalScrollPolicyOff();
-  absl::optional<int32_t> GetNumberOfCells();
+  std::optional<int32_t> GetNumberOfCells();
 
   bool SetValue(XFA_ValuePicture eValueType, const WideString& wsValue);
   WideString GetValue(XFA_ValuePicture eValueType);
@@ -452,11 +452,11 @@
   bool HasFlag(XFA_NodeFlag dwFlag) const;
   const PropertyData* GetPropertyData(XFA_Element property) const;
   const AttributeData* GetAttributeData(XFA_Attribute attr) const;
-  absl::optional<XFA_Element> GetFirstPropertyWithFlag(
+  std::optional<XFA_Element> GetFirstPropertyWithFlag(
       XFA_PropertyFlag flag) const;
   void OnRemoved(bool bNotify) const;
-  absl::optional<void*> GetDefaultValue(XFA_Attribute attr,
-                                        XFA_AttributeType eType) const;
+  std::optional<void*> GetDefaultValue(XFA_Attribute attr,
+                                       XFA_AttributeType eType) const;
   CXFA_Node* GetChildInternal(size_t index,
                               XFA_Element eType,
                               bool bOnlyChild) const;
@@ -505,16 +505,16 @@
   void SyncValue(const WideString& wsValue, bool bNotify);
   CXFA_Value* GetDefaultValueIfExists();
   CXFA_Bind* GetBindIfExists() const;
-  absl::optional<XFA_AttributeValue> GetIntactFromKeep(
+  std::optional<XFA_AttributeValue> GetIntactFromKeep(
       const CXFA_Keep* pKeep,
       XFA_AttributeValue eLayoutType) const;
   CXFA_Node* GetTransparentParent();
 
-  absl::optional<float> TryHeight();
-  absl::optional<float> TryMinWidth();
-  absl::optional<float> TryMinHeight();
-  absl::optional<float> TryMaxWidth();
-  absl::optional<float> TryMaxHeight();
+  std::optional<float> TryHeight();
+  std::optional<float> TryMinWidth();
+  std::optional<float> TryMinHeight();
+  std::optional<float> TryMaxWidth();
+  std::optional<float> TryMaxHeight();
   XFA_EventError ProcessEventInternal(CXFA_FFDocView* pDocView,
                                       XFA_AttributeValue iActivity,
                                       CXFA_Event* event,
diff --git a/xfa/fxfa/parser/cxfa_occur.cpp b/xfa/fxfa/parser/cxfa_occur.cpp
index 515ffdd..9c20573 100644
--- a/xfa/fxfa/parser/cxfa_occur.cpp
+++ b/xfa/fxfa/parser/cxfa_occur.cpp
@@ -41,14 +41,12 @@
 CXFA_Occur::~CXFA_Occur() = default;
 
 int32_t CXFA_Occur::GetMax() {
-  absl::optional<int32_t> max =
-      JSObject()->TryInteger(XFA_Attribute::Max, true);
+  std::optional<int32_t> max = JSObject()->TryInteger(XFA_Attribute::Max, true);
   return max.has_value() ? max.value() : GetMin();
 }
 
 int32_t CXFA_Occur::GetMin() {
-  absl::optional<int32_t> min =
-      JSObject()->TryInteger(XFA_Attribute::Min, true);
+  std::optional<int32_t> min = JSObject()->TryInteger(XFA_Attribute::Min, true);
   return min.has_value() && min.value() >= 0 ? min.value() : 1;
 }
 
@@ -56,7 +54,7 @@
   int32_t iMin = GetMin();
   int32_t iMax = GetMax();
 
-  absl::optional<int32_t> init =
+  std::optional<int32_t> init =
       JSObject()->TryInteger(XFA_Attribute::Initial, false);
   return {iMin, iMax,
           init.has_value() && init.value() >= iMin ? init.value() : iMin};
diff --git a/xfa/fxfa/parser/cxfa_script.cpp b/xfa/fxfa/parser/cxfa_script.cpp
index 4b4e8ce..6bec90f 100644
--- a/xfa/fxfa/parser/cxfa_script.cpp
+++ b/xfa/fxfa/parser/cxfa_script.cpp
@@ -55,7 +55,7 @@
 CXFA_Script::~CXFA_Script() = default;
 
 CXFA_Script::Type CXFA_Script::GetContentType() {
-  absl::optional<WideString> cData =
+  std::optional<WideString> cData =
       JSObject()->TryCData(XFA_Attribute::ContentType, false);
   if (!cData.has_value())
     return Type::Formcalc;
diff --git a/xfa/fxfa/parser/cxfa_validate.cpp b/xfa/fxfa/parser/cxfa_validate.cpp
index 2ca3811..e725976 100644
--- a/xfa/fxfa/parser/cxfa_validate.cpp
+++ b/xfa/fxfa/parser/cxfa_validate.cpp
@@ -62,7 +62,7 @@
 }
 
 void CXFA_Validate::SetNullTest(const WideString& wsValue) {
-  absl::optional<XFA_AttributeValue> item =
+  std::optional<XFA_AttributeValue> item =
       XFA_GetAttributeValueByName(wsValue.AsStringView());
   JSObject()->SetEnum(
       XFA_Attribute::NullTest,
diff --git a/xfa/fxfa/parser/xfa_basic_data.cpp b/xfa/fxfa/parser/xfa_basic_data.cpp
index 4ae0dc0..0cd5f74 100644
--- a/xfa/fxfa/parser/xfa_basic_data.cpp
+++ b/xfa/fxfa/parser/xfa_basic_data.cpp
@@ -164,14 +164,14 @@
   return kPacketTable[static_cast<uint8_t>(ePacket)].info;
 }
 
-absl::optional<XFA_PACKETINFO> XFA_GetPacketByName(WideStringView wsName) {
+std::optional<XFA_PACKETINFO> XFA_GetPacketByName(WideStringView wsName) {
   uint32_t hash = FX_HashCode_GetW(wsName);
   auto* elem = std::lower_bound(
       std::begin(kPacketTable), std::end(kPacketTable), hash,
       [](const PacketTableRecord& a, uint32_t hash) { return a.hash < hash; });
   if (elem != std::end(kPacketTable) && wsName.EqualsASCII(elem->info.name))
     return elem->info;
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 ByteStringView XFA_ElementToName(XFA_Element elem) {
@@ -195,17 +195,17 @@
   return kAttributeNames[static_cast<size_t>(attr)];
 }
 
-absl::optional<XFA_ATTRIBUTEINFO> XFA_GetAttributeByName(WideStringView name) {
+std::optional<XFA_ATTRIBUTEINFO> XFA_GetAttributeByName(WideStringView name) {
   uint32_t hash = FX_HashCode_GetW(name);
   auto* elem = std::lower_bound(
       std::begin(kAttributeRecords), std::end(kAttributeRecords), hash,
       [](const AttributeRecord& a, uint32_t hash) { return a.hash < hash; });
   if (elem == std::end(kAttributeRecords))
-    return absl::nullopt;
+    return std::nullopt;
 
   size_t index = std::distance(std::begin(kAttributeRecords), elem);
   if (!name.EqualsASCII(kAttributeNames[index]))
-    return absl::nullopt;
+    return std::nullopt;
 
   XFA_ATTRIBUTEINFO result;
   result.attribute = elem->attribute;
@@ -217,7 +217,7 @@
   return kAttributeValueNames[static_cast<int32_t>(item)];
 }
 
-absl::optional<XFA_AttributeValue> XFA_GetAttributeValueByName(
+std::optional<XFA_AttributeValue> XFA_GetAttributeValueByName(
     WideStringView name) {
   auto* it =
       std::lower_bound(std::begin(kAttributeValueRecords),
@@ -226,22 +226,22 @@
                          return arg.uHash < hash;
                        });
   if (it == std::end(kAttributeValueRecords))
-    return absl::nullopt;
+    return std::nullopt;
 
   size_t index = std::distance(std::begin(kAttributeValueRecords), it);
   if (!name.EqualsASCII(kAttributeValueNames[index]))
-    return absl::nullopt;
+    return std::nullopt;
 
   return it->eName;
 }
 
-absl::optional<XFA_SCRIPTATTRIBUTEINFO> XFA_GetScriptAttributeByName(
+std::optional<XFA_SCRIPTATTRIBUTEINFO> XFA_GetScriptAttributeByName(
     XFA_Element element,
     WideStringView attribute_name) {
-  absl::optional<XFA_ATTRIBUTEINFO> attr =
+  std::optional<XFA_ATTRIBUTEINFO> attr =
       XFA_GetAttributeByName(attribute_name);
   if (!attr.has_value())
-    return absl::nullopt;
+    return std::nullopt;
 
   while (element != XFA_Element::Unknown) {
     auto compound_key = std::make_pair(element, attr.value().attribute);
@@ -263,5 +263,5 @@
     }
     element = kElementRecords[static_cast<size_t>(element)].parent;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
diff --git a/xfa/fxfa/parser/xfa_basic_data.h b/xfa/fxfa/parser/xfa_basic_data.h
index b338bec..f17e350 100644
--- a/xfa/fxfa/parser/xfa_basic_data.h
+++ b/xfa/fxfa/parser/xfa_basic_data.h
@@ -9,9 +9,10 @@
 
 #include <stddef.h>
 
+#include <optional>
+
 #include "core/fxcrt/widestring.h"
 #include "fxjs/xfa/cjx_object.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "xfa/fxfa/fxfa_basic.h"
 
 using XFA_ATTRIBUTE_CALLBACK = void (*)(v8::Isolate* pIsolate,
@@ -51,19 +52,19 @@
 };
 
 XFA_PACKETINFO XFA_GetPacketByIndex(XFA_PacketType ePacket);
-absl::optional<XFA_PACKETINFO> XFA_GetPacketByName(WideStringView wsName);
+std::optional<XFA_PACKETINFO> XFA_GetPacketByName(WideStringView wsName);
 
 ByteStringView XFA_ElementToName(XFA_Element elem);
 XFA_Element XFA_GetElementByName(WideStringView name);
 
 ByteStringView XFA_AttributeToName(XFA_Attribute attr);
-absl::optional<XFA_ATTRIBUTEINFO> XFA_GetAttributeByName(WideStringView name);
+std::optional<XFA_ATTRIBUTEINFO> XFA_GetAttributeByName(WideStringView name);
 
 ByteStringView XFA_AttributeValueToName(XFA_AttributeValue item);
-absl::optional<XFA_AttributeValue> XFA_GetAttributeValueByName(
+std::optional<XFA_AttributeValue> XFA_GetAttributeValueByName(
     WideStringView name);
 
-absl::optional<XFA_SCRIPTATTRIBUTEINFO> XFA_GetScriptAttributeByName(
+std::optional<XFA_SCRIPTATTRIBUTEINFO> XFA_GetScriptAttributeByName(
     XFA_Element eElement,
     WideStringView wsAttributeName);
 
diff --git a/xfa/fxfa/parser/xfa_basic_data_unittest.cpp b/xfa/fxfa/parser/xfa_basic_data_unittest.cpp
index f30d655..d7b740b 100644
--- a/xfa/fxfa/parser/xfa_basic_data_unittest.cpp
+++ b/xfa/fxfa/parser/xfa_basic_data_unittest.cpp
@@ -7,7 +7,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(XFABasicDataTest, GetPacketByName) {
-  absl::optional<XFA_PACKETINFO> result = XFA_GetPacketByName(L"");
+  std::optional<XFA_PACKETINFO> result = XFA_GetPacketByName(L"");
   EXPECT_FALSE(result.has_value());
 
   result = XFA_GetPacketByName(L"nonesuch");
@@ -49,7 +49,7 @@
 }
 
 TEST(XFABasicDataTest, GetAttributeByName) {
-  absl::optional<XFA_ATTRIBUTEINFO> result = XFA_GetAttributeByName(L"");
+  std::optional<XFA_ATTRIBUTEINFO> result = XFA_GetAttributeByName(L"");
   EXPECT_FALSE(result.has_value());
 
   result = XFA_GetAttributeByName(L"nonesuch");
@@ -74,7 +74,7 @@
 }
 
 TEST(XFABasicDataTest, GetAttributeValueByName) {
-  absl::optional<XFA_AttributeValue> result = XFA_GetAttributeValueByName(L"");
+  std::optional<XFA_AttributeValue> result = XFA_GetAttributeValueByName(L"");
   EXPECT_FALSE(result.has_value());
 
   result = XFA_GetAttributeValueByName(L"nonesuch");
diff --git a/xfa/fxfa/parser/xfa_utils.cpp b/xfa/fxfa/parser/xfa_utils.cpp
index a594ffd..33def0f 100644
--- a/xfa/fxfa/parser/xfa_utils.cpp
+++ b/xfa/fxfa/parser/xfa_utils.cpp
@@ -112,7 +112,7 @@
 }
 
 bool ContentNodeNeedtoExport(CXFA_Node* pContentNode) {
-  absl::optional<WideString> wsContent =
+  std::optional<WideString> wsContent =
       pContentNode->JSObject()->TryContent(false, false);
   if (!wsContent.has_value())
     return false;
@@ -139,7 +139,7 @@
   if (!bProto && !pNode->JSObject()->HasAttribute(eName))
     return WideString();
 
-  absl::optional<WideString> value =
+  std::optional<WideString> value =
       pNode->JSObject()->TryAttribute(eName, false);
   if (!value.has_value())
     return WideString();
@@ -181,7 +181,7 @@
       if (!pRawValueNode)
         break;
 
-      absl::optional<WideString> contentType =
+      std::optional<WideString> contentType =
           pNode->JSObject()->TryAttribute(XFA_Attribute::ContentType, false);
       if (pRawValueNode->GetElementType() == XFA_Element::SharpxHTML &&
           contentType.has_value() &&
@@ -201,7 +201,7 @@
       } else if (pRawValueNode->GetElementType() == XFA_Element::Sharpxml &&
                  contentType.has_value() &&
                  contentType.value().EqualsASCII("text/xml")) {
-        absl::optional<WideString> rawValue =
+        std::optional<WideString> rawValue =
             pRawValueNode->JSObject()->TryAttribute(XFA_Attribute::Value,
                                                     false);
         if (!rawValue.has_value() || rawValue->IsEmpty())
@@ -338,7 +338,7 @@
   if (!pTemplateRoot)
     return WideString();
 
-  absl::optional<WideString> templateNS =
+  std::optional<WideString> templateNS =
       pTemplateRoot->JSObject()->TryNamespace();
   if (!templateNS.has_value())
     return WideString();