Encapsulate CPDF_PageObjectHolder.

Bug: pdfium:1680
Change-Id: Ia4a268e3363980cf7f0051f79c55315672d57269
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/79893
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 8fb52b7..1dfef98 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -174,16 +174,15 @@
     const CPDF_Object* pResource,
     const ByteString& bsType) const {
   DCHECK(pResource);
-  if (!m_pObjHolder->m_pResources) {
-    m_pObjHolder->m_pResources.Reset(
-        m_pDocument->NewIndirect<CPDF_Dictionary>());
+  if (!m_pObjHolder->GetResources()) {
+    m_pObjHolder->SetResources(m_pDocument->NewIndirect<CPDF_Dictionary>());
     m_pObjHolder->GetDict()->SetNewFor<CPDF_Reference>(
         "Resources", m_pDocument.Get(),
-        m_pObjHolder->m_pResources->GetObjNum());
+        m_pObjHolder->GetResources()->GetObjNum());
   }
-  CPDF_Dictionary* pResList = m_pObjHolder->m_pResources->GetDictFor(bsType);
+  CPDF_Dictionary* pResList = m_pObjHolder->GetResources()->GetDictFor(bsType);
   if (!pResList)
-    pResList = m_pObjHolder->m_pResources->SetNewFor<CPDF_Dictionary>(bsType);
+    pResList = m_pObjHolder->GetResources()->SetNewFor<CPDF_Dictionary>(bsType);
 
   ByteString name;
   int idnum = 1;
@@ -459,9 +458,9 @@
   }
 
   ByteString name;
-  auto it = m_pObjHolder->m_GraphicsMap.find(graphD);
-  if (it != m_pObjHolder->m_GraphicsMap.end()) {
-    name = it->second;
+  Optional<ByteString> maybe_name = m_pObjHolder->GraphicsMapSearch(graphD);
+  if (maybe_name.has_value()) {
+    name = std::move(maybe_name.value());
   } else {
     auto gsDict = pdfium::MakeRetain<CPDF_Dictionary>();
     if (graphD.fillAlpha != 1.0f)
@@ -476,7 +475,7 @@
     }
     CPDF_Object* pDict = m_pDocument->AddIndirectObject(gsDict);
     name = RealizeResource(pDict, "ExtGState");
-    m_pObjHolder->m_GraphicsMap[graphD] = name;
+    m_pObjHolder->GraphicsMapInsert(graphD, name);
   }
   *buf << "/" << PDF_NameEncode(name) << " gs ";
 }
@@ -495,20 +494,19 @@
   defaultGraphics.fillAlpha = 1.0f;
   defaultGraphics.strokeAlpha = 1.0f;
   defaultGraphics.blendType = BlendMode::kNormal;
-  auto it = m_pObjHolder->m_GraphicsMap.find(defaultGraphics);
 
-  // If default graphics already exists, return it.
-  if (it != m_pObjHolder->m_GraphicsMap.end())
-    return it->second;
+  Optional<ByteString> maybe_name =
+      m_pObjHolder->GraphicsMapSearch(defaultGraphics);
+  if (maybe_name.has_value())
+    return maybe_name.value();
 
-  // Otherwise, create them.
   auto gsDict = pdfium::MakeRetain<CPDF_Dictionary>();
   gsDict->SetNewFor<CPDF_Number>("ca", defaultGraphics.fillAlpha);
   gsDict->SetNewFor<CPDF_Number>("CA", defaultGraphics.strokeAlpha);
   gsDict->SetNewFor<CPDF_Name>("BM", "Normal");
   CPDF_Object* pDict = m_pDocument->AddIndirectObject(gsDict);
   ByteString name = RealizeResource(pDict, "ExtGState");
-  m_pObjHolder->m_GraphicsMap[defaultGraphics] = name;
+  m_pObjHolder->GraphicsMapInsert(defaultGraphics, name);
   return name;
 }
 
@@ -539,10 +537,11 @@
     return;
   }
   data.baseFont = pFont->GetBaseFontName();
-  auto it = m_pObjHolder->m_FontsMap.find(data);
+
   ByteString dictName;
-  if (it != m_pObjHolder->m_FontsMap.end()) {
-    dictName = it->second;
+  Optional<ByteString> maybe_name = m_pObjHolder->FontsMapSearch(data);
+  if (maybe_name.has_value()) {
+    dictName = std::move(maybe_name.value());
   } else {
     CPDF_Object* pIndirectFont = pFont->GetFontDict();
     if (pIndirectFont->IsInline()) {
@@ -558,7 +557,7 @@
       pIndirectFont = m_pDocument->AddIndirectObject(pFontDict);
     }
     dictName = RealizeResource(pIndirectFont, "Font");
-    m_pObjHolder->m_FontsMap[data] = dictName;
+    m_pObjHolder->FontsMapInsert(data, dictName);
   }
   *buf << "/" << PDF_NameEncode(dictName) << " ";
   WriteFloat(*buf, pTextObj->GetFontSize()) << " Tf ";
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
index 96014b5..786e08c 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
@@ -39,10 +39,11 @@
     pGen->ProcessPath(buf, pPathObj);
   }
 
-  CPDF_Dictionary* TestGetResource(CPDF_PageContentGenerator* pGen,
-                                   const ByteString& type,
-                                   const ByteString& name) {
-    return pGen->m_pObjHolder->m_pResources->GetDictFor(type)->GetDictFor(name);
+  const CPDF_Dictionary* TestGetResource(CPDF_PageContentGenerator* pGen,
+                                         const ByteString& type,
+                                         const ByteString& name) {
+    const CPDF_Dictionary* pResources = pGen->m_pObjHolder->GetResources();
+    return pResources->GetDictFor(type)->GetDictFor(name);
   }
 
   void TestProcessText(CPDF_PageContentGenerator* pGen,
@@ -206,7 +207,7 @@
   EXPECT_EQ(" gs 1 0 0 1 0 0 cm 1 2 m 3 4 l 5 6 l h B Q\n",
             pathString.Last(43));
   ASSERT_GT(pathString.GetLength(), 91U);
-  CPDF_Dictionary* externalGS =
+  const CPDF_Dictionary* externalGS =
       TestGetResource(&generator, "ExtGState",
                       pathString.Substr(48, pathString.GetLength() - 91));
   ASSERT_TRUE(externalGS);
@@ -282,13 +283,13 @@
   EXPECT_EQ(compareString1, firstString.First(compareString1.GetLength()));
   EXPECT_EQ(compareString2, midString.Last(compareString2.GetLength()));
   EXPECT_EQ(compareString3, lastString.Last(compareString3.GetLength()));
-  CPDF_Dictionary* externalGS = TestGetResource(
+  const CPDF_Dictionary* externalGS = TestGetResource(
       &generator, "ExtGState",
       midString.First(midString.GetLength() - compareString2.GetLength()));
   ASSERT_TRUE(externalGS);
   EXPECT_EQ(0.5f, externalGS->GetNumberFor("ca"));
   EXPECT_EQ(0.8f, externalGS->GetNumberFor("CA"));
-  CPDF_Dictionary* fontDict = TestGetResource(
+  const CPDF_Dictionary* fontDict = TestGetResource(
       &generator, "Font",
       lastString.First(lastString.GetLength() - compareString3.GetLength()));
   ASSERT_TRUE(fontDict);
@@ -361,7 +362,7 @@
             textString.GetLength());
   EXPECT_EQ(compareString1, textString.First(compareString1.GetLength()));
   EXPECT_EQ(compareString2, textString.Last(compareString2.GetLength()));
-  CPDF_Dictionary* fontDict = TestGetResource(
+  const CPDF_Dictionary* fontDict = TestGetResource(
       &generator, "Font",
       textString.Substr(compareString1.GetLength(),
                         textString.GetLength() - compareString1.GetLength() -
@@ -371,7 +372,7 @@
   EXPECT_EQ("Font", fontDict->GetNameFor("Type"));
   EXPECT_EQ("TrueType", fontDict->GetNameFor("Subtype"));
   EXPECT_EQ("Helvetica", fontDict->GetNameFor("BaseFont"));
-  CPDF_Dictionary* fontDesc = fontDict->GetDictFor("FontDescriptor");
+  const CPDF_Dictionary* fontDesc = fontDict->GetDictFor("FontDescriptor");
   ASSERT_TRUE(fontDesc);
   EXPECT_TRUE(fontDesc->GetObjNum());
   EXPECT_EQ("FontDescriptor", fontDesc->GetNameFor("Type"));
diff --git a/core/fpdfapi/page/cpdf_annotcontext.cpp b/core/fpdfapi/page/cpdf_annotcontext.cpp
index 0698e5f..6e3b119 100644
--- a/core/fpdfapi/page/cpdf_annotcontext.cpp
+++ b/core/fpdfapi/page/cpdf_annotcontext.cpp
@@ -31,7 +31,6 @@
   pStream->GetDict()->SetMatrixFor("Matrix", CFX_Matrix());
 
   m_pAnnotForm = std::make_unique<CPDF_Form>(
-      m_pPage->GetDocument(), m_pPage->AsPDFPage()->m_pResources.Get(),
-      pStream);
+      m_pPage->GetDocument(), m_pPage->AsPDFPage()->GetResources(), pStream);
   m_pAnnotForm->ParseContent();
 }
diff --git a/core/fpdfapi/page/cpdf_contentparser.cpp b/core/fpdfapi/page/cpdf_contentparser.cpp
index 27cbdfc..cebce3f 100644
--- a/core/fpdfapi/page/cpdf_contentparser.cpp
+++ b/core/fpdfapi/page/cpdf_contentparser.cpp
@@ -82,9 +82,8 @@
 
   CPDF_Dictionary* pResources = pForm->GetDict()->GetDictFor("Resources");
   m_pParser = std::make_unique<CPDF_StreamContentParser>(
-      pForm->GetDocument(), pForm->m_pPageResources.Get(),
-      pForm->m_pResources.Get(), pParentMatrix, pForm, pResources, form_bbox,
-      pGraphicStates, pParsedSet);
+      pForm->GetDocument(), pForm->GetPageResources(), pForm->GetResources(),
+      pParentMatrix, pForm, pResources, form_bbox, pGraphicStates, pParsedSet);
   m_pParser->GetCurStates()->m_CTM = form_matrix;
   m_pParser->GetCurStates()->m_ParentMatrix = form_matrix;
   if (ClipPath.HasRef()) {
@@ -188,10 +187,10 @@
   if (!m_pParser) {
     m_ParsedSet.clear();
     m_pParser = std::make_unique<CPDF_StreamContentParser>(
-        m_pObjectHolder->GetDocument(), m_pObjectHolder->m_pPageResources.Get(),
+        m_pObjectHolder->GetDocument(), m_pObjectHolder->GetPageResources(),
         nullptr, nullptr, m_pObjectHolder.Get(),
-        m_pObjectHolder->m_pResources.Get(), m_pObjectHolder->GetBBox(),
-        nullptr, &m_ParsedSet);
+        m_pObjectHolder->GetResources(), m_pObjectHolder->GetBBox(), nullptr,
+        &m_ParsedSet);
     m_pParser->GetCurStates()->m_ColorState.SetDefault();
   }
   if (m_CurrentOffset >= m_Size)
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.cpp b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
index eb6107c..a919117 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.cpp
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.cpp
@@ -84,6 +84,33 @@
   return dirty_streams;
 }
 
+Optional<ByteString> CPDF_PageObjectHolder::GraphicsMapSearch(
+    const GraphicsData& gd) {
+  auto it = m_GraphicsMap.find(gd);
+  if (it == m_GraphicsMap.end())
+    return pdfium::nullopt;
+
+  return it->second;
+}
+
+void CPDF_PageObjectHolder::GraphicsMapInsert(const GraphicsData& gd,
+                                              const ByteString& str) {
+  m_GraphicsMap[gd] = str;
+}
+
+Optional<ByteString> CPDF_PageObjectHolder::FontsMapSearch(const FontData& fd) {
+  auto it = m_FontsMap.find(fd);
+  if (it == m_FontsMap.end())
+    return pdfium::nullopt;
+
+  return it->second;
+}
+
+void CPDF_PageObjectHolder::FontsMapInsert(const FontData& fd,
+                                           const ByteString& str) {
+  m_FontsMap[fd] = str;
+}
+
 void CPDF_PageObjectHolder::LoadTransparencyInfo() {
   CPDF_Dictionary* pGroup = m_pDict->GetDictFor("Group");
   if (!pGroup)
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.h b/core/fpdfapi/page/cpdf_pageobjectholder.h
index 98900f4..29ab76d 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.h
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.h
@@ -14,15 +14,16 @@
 #include <vector>
 
 #include "core/fpdfapi/page/cpdf_transparency.h"
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/dib/fx_dib.h"
+#include "third_party/base/optional.h"
 
 class CPDF_ContentParser;
-class CPDF_Dictionary;
 class CPDF_Document;
 class CPDF_PageObject;
 class CPDF_Stream;
@@ -66,8 +67,10 @@
   ParseState GetParseState() const { return m_ParseState; }
 
   CPDF_Document* GetDocument() const { return m_pDocument.Get(); }
-
   CPDF_Dictionary* GetDict() const { return m_pDict.Get(); }
+  CPDF_Dictionary* GetResources() const { return m_pResources.Get(); }
+  void SetResources(CPDF_Dictionary* pDict) { m_pResources.Reset(pDict); }
+  CPDF_Dictionary* GetPageResources() const { return m_pPageResources.Get(); }
   size_t GetPageObjectCount() const { return m_PageObjectList.size(); }
   CPDF_PageObject* GetPageObjectByIndex(size_t index) const;
   void AppendPageObject(std::unique_ptr<CPDF_PageObject> pPageObj);
@@ -97,14 +100,19 @@
   bool HasDirtyStreams() const { return !m_DirtyStreams.empty(); }
   std::set<int32_t> TakeDirtyStreams();
 
-  RetainPtr<CPDF_Dictionary> m_pPageResources;
-  RetainPtr<CPDF_Dictionary> m_pResources;
-  std::map<GraphicsData, ByteString> m_GraphicsMap;
-  std::map<FontData, ByteString> m_FontsMap;
+  Optional<ByteString> GraphicsMapSearch(const GraphicsData& gd);
+  void GraphicsMapInsert(const GraphicsData& gd, const ByteString& str);
+
+  Optional<ByteString> FontsMapSearch(const FontData& fd);
+  void FontsMapInsert(const FontData& fd, const ByteString& str);
 
  protected:
   void LoadTransparencyInfo();
 
+  RetainPtr<CPDF_Dictionary> m_pPageResources;
+  RetainPtr<CPDF_Dictionary> m_pResources;
+  std::map<GraphicsData, ByteString> m_GraphicsMap;
+  std::map<FontData, ByteString> m_FontsMap;
   CFX_FloatRect m_BBox;
   CPDF_Transparency m_Transparency;
 
diff --git a/core/fpdfapi/render/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp
index c733e3c..8b29b26 100644
--- a/core/fpdfapi/render/cpdf_imagerenderer.cpp
+++ b/core/fpdfapi/render/cpdf_imagerenderer.cpp
@@ -141,8 +141,7 @@
   } else {
     pDocument = m_pImageObject->GetImage()->GetDocument();
   }
-  CPDF_Dictionary* pPageResources =
-      pPage ? pPage->m_pPageResources.Get() : nullptr;
+  CPDF_Dictionary* pPageResources = pPage ? pPage->GetPageResources() : nullptr;
   CPDF_Object* pCSObj =
       m_pImageObject->GetImage()->GetStream()->GetDict()->GetDirectObjectFor(
           "ColorSpace");
diff --git a/core/fpdfapi/render/cpdf_pagerendercache.cpp b/core/fpdfapi/render/cpdf_pagerendercache.cpp
index 0d60794..ca8722e 100644
--- a/core/fpdfapi/render/cpdf_pagerendercache.cpp
+++ b/core/fpdfapi/render/cpdf_pagerendercache.cpp
@@ -85,7 +85,7 @@
         std::make_unique<CPDF_ImageCacheEntry>(m_pPage->GetDocument(), pImage);
   }
   CPDF_DIB::LoadState ret = m_pCurImageCacheEntry->StartGetCachedBitmap(
-      m_pPage->m_pPageResources.Get(), pRenderStatus, bStdCS);
+      m_pPage->GetPageResources(), pRenderStatus, bStdCS);
   if (ret == CPDF_DIB::LoadState::kContinue)
     return true;
 
diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp
index be21cf3..af65813 100644
--- a/core/fpdfdoc/cpdf_annot.cpp
+++ b/core/fpdfdoc/cpdf_annot.cpp
@@ -199,8 +199,8 @@
   if (it != m_APMap.end())
     return it->second.get();
 
-  auto pNewForm = std::make_unique<CPDF_Form>(
-      m_pDocument.Get(), pPage->m_pResources.Get(), pStream);
+  auto pNewForm = std::make_unique<CPDF_Form>(m_pDocument.Get(),
+                                              pPage->GetResources(), pStream);
   pNewForm->ParseContent();
 
   CPDF_Form* pResult = pNewForm.get();
@@ -406,7 +406,7 @@
     return false;
 
   CPDF_RenderContext context(
-      pPage->GetDocument(), pPage->m_pPageResources.Get(),
+      pPage->GetDocument(), pPage->GetPageResources(),
       static_cast<CPDF_PageRenderCache*>(pPage->GetRenderCache()));
   context.AppendLayer(pForm, matrix);
   context.Render(pDevice, pOptions, nullptr);
diff --git a/fpdfsdk/cpdfsdk_renderpage.cpp b/fpdfsdk/cpdfsdk_renderpage.cpp
index dcca929..1f7facc 100644
--- a/fpdfsdk/cpdfsdk_renderpage.cpp
+++ b/fpdfsdk/cpdfsdk_renderpage.cpp
@@ -59,7 +59,7 @@
   pContext->m_pDevice->SetBaseClip(clipping_rect);
   pContext->m_pDevice->SetClip_Rect(clipping_rect);
   pContext->m_pContext = std::make_unique<CPDF_RenderContext>(
-      pPage->GetDocument(), pPage->m_pPageResources.Get(),
+      pPage->GetDocument(), pPage->GetPageResources(),
       static_cast<CPDF_PageRenderCache*>(pPage->GetRenderCache()));
 
   pContext->m_pContext->AppendLayer(pPage, matrix);
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp
index ae1db92..346bb6c 100644
--- a/fpdfsdk/fpdf_edit_embeddertest.cpp
+++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -2559,7 +2559,8 @@
 
   // Check that the ExtGState was created
   CPDF_Page* cpage = CPDFPageFromFPDFPage(page.get());
-  CPDF_Dictionary* graphics_dict = cpage->m_pResources->GetDictFor("ExtGState");
+  const CPDF_Dictionary* graphics_dict =
+      cpage->GetResources()->GetDictFor("ExtGState");
   ASSERT_TRUE(graphics_dict);
   EXPECT_EQ(2u, graphics_dict->size());
 
@@ -2612,7 +2613,8 @@
 
   // Check the ExtGState
   CPDF_Page* cpage = CPDFPageFromFPDFPage(page);
-  CPDF_Dictionary* graphics_dict = cpage->m_pResources->GetDictFor("ExtGState");
+  const CPDF_Dictionary* graphics_dict =
+      cpage->GetResources()->GetDictFor("ExtGState");
   ASSERT_TRUE(graphics_dict);
   EXPECT_EQ(2u, graphics_dict->size());
 
@@ -2653,7 +2655,7 @@
   FPDFPageObj_Transform(text_object, 1, 0, 0, 1, 300, 300);
   FPDFPage_InsertObject(page, text_object);
   EXPECT_TRUE(FPDFPage_GenerateContent(page));
-  CPDF_Dictionary* font_dict = cpage->m_pResources->GetDictFor("Font");
+  const CPDF_Dictionary* font_dict = cpage->GetResources()->GetDictFor("Font");
   ASSERT_TRUE(font_dict);
   EXPECT_EQ(1u, font_dict->size());
 
diff --git a/fpdfsdk/fpdf_editimg.cpp b/fpdfsdk/fpdf_editimg.cpp
index e76c77e..f98f223 100644
--- a/fpdfsdk/fpdf_editimg.cpp
+++ b/fpdfsdk/fpdf_editimg.cpp
@@ -244,7 +244,7 @@
 
   // Set up all the rendering code.
   CPDF_Dictionary* page_resources =
-      optional_page ? optional_page->m_pPageResources.Get() : nullptr;
+      optional_page ? optional_page->GetPageResources() : nullptr;
   CPDF_RenderContext context(doc, page_resources, /*pPageCache=*/nullptr);
   CFX_DefaultRenderDevice device;
   device.Attach(result_bitmap, /*bRgbByteOrder=*/false,
@@ -389,7 +389,7 @@
   auto pSource = pdfium::MakeRetain<CPDF_DIB>();
   CPDF_DIB::LoadState ret = pSource->StartLoadDIBBase(
       pPage->GetDocument(), pImg->GetStream(), false, nullptr,
-      pPage->m_pPageResources.Get(), false, 0, false);
+      pPage->GetPageResources(), false, 0, false);
   if (ret == CPDF_DIB::LoadState::kFail)
     return true;
 
diff --git a/fpdfsdk/fpdf_thumbnail.cpp b/fpdfsdk/fpdf_thumbnail.cpp
index df56f1f..ce16b11 100644
--- a/fpdfsdk/fpdf_thumbnail.cpp
+++ b/fpdfsdk/fpdf_thumbnail.cpp
@@ -62,7 +62,7 @@
   auto p_source = pdfium::MakeRetain<CPDF_DIB>();
   const CPDF_DIB::LoadState start_status = p_source->StartLoadDIBBase(
       p_page->GetDocument(), thumb_stream, false, nullptr,
-      p_page->m_pPageResources.Get(), false, 0, false);
+      p_page->GetPageResources(), false, 0, false);
   if (start_status == CPDF_DIB::LoadState::kFail)
     return nullptr;