Weakly cache CPDF_TransferFunc in CPDF_DocRenderData.

Typical Retainable/Observable pattern.

Change-Id: If69ec41501a252e30697a38dd45b652c3c5f79b0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/58130
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_generalstate.cpp b/core/fpdfapi/page/cpdf_generalstate.cpp
index be2ec3a..9a7d9db 100644
--- a/core/fpdfapi/page/cpdf_generalstate.cpp
+++ b/core/fpdfapi/page/cpdf_generalstate.cpp
@@ -7,7 +7,6 @@
 #include "core/fpdfapi/page/cpdf_generalstate.h"
 
 #include "core/fpdfapi/parser/cpdf_document.h"
-#include "core/fpdfapi/render/cpdf_docrenderdata.h"
 #include "core/fpdfapi/render/cpdf_transferfunc.h"
 
 namespace {
@@ -263,10 +262,12 @@
     : m_BlendMode(that.m_BlendMode),
       m_BlendType(that.m_BlendType),
       m_pSoftMask(that.m_pSoftMask),
+      m_SMaskMatrix(that.m_SMaskMatrix),
       m_StrokeAlpha(that.m_StrokeAlpha),
       m_FillAlpha(that.m_FillAlpha),
       m_pTR(that.m_pTR),
       m_pTransferFunc(that.m_pTransferFunc),
+      m_Matrix(that.m_Matrix),
       m_RenderIntent(that.m_RenderIntent),
       m_StrokeAdjust(that.m_StrokeAdjust),
       m_AlphaSource(that.m_AlphaSource),
@@ -278,28 +279,9 @@
       m_pUCR(that.m_pUCR),
       m_pHT(that.m_pHT),
       m_Flatness(that.m_Flatness),
-      m_Smoothness(that.m_Smoothness) {
-  m_Matrix = that.m_Matrix;
-  m_SMaskMatrix = that.m_SMaskMatrix;
+      m_Smoothness(that.m_Smoothness) {}
 
-  if (that.m_pTransferFunc && that.m_pTransferFunc->GetDocument()) {
-    auto* pDocCache =
-        CPDF_DocRenderData::FromDocument(that.m_pTransferFunc->GetDocument());
-    if (pDocCache)
-      m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR.Get());
-  }
-}
-
-CPDF_GeneralState::StateData::~StateData() {
-  if (m_pTransferFunc && m_pTransferFunc->GetDocument()) {
-    auto* pDocCache =
-        CPDF_DocRenderData::FromDocument(m_pTransferFunc->GetDocument());
-    if (pDocCache) {
-      m_pTransferFunc.Reset();  // Give up our reference first.
-      pDocCache->MaybePurgeTransferFunc(m_pTR.Get());
-    }
-  }
-}
+CPDF_GeneralState::StateData::~StateData() = default;
 
 RetainPtr<CPDF_GeneralState::StateData> CPDF_GeneralState::StateData::Clone()
     const {
diff --git a/core/fpdfapi/render/cpdf_docrenderdata.cpp b/core/fpdfapi/render/cpdf_docrenderdata.cpp
index 306edc1..7e95724 100644
--- a/core/fpdfapi/render/cpdf_docrenderdata.cpp
+++ b/core/fpdfapi/render/cpdf_docrenderdata.cpp
@@ -58,17 +58,12 @@
     return nullptr;
 
   auto it = m_TransferFuncMap.find(pObj);
-  if (it != m_TransferFuncMap.end())
-    return it->second;
+  if (it != m_TransferFuncMap.end() && it->second)
+    return pdfium::WrapRetain(it->second.Get());
 
-  m_TransferFuncMap[pObj] = CreateTransferFunc(pObj);
-  return m_TransferFuncMap[pObj];
-}
-
-void CPDF_DocRenderData::MaybePurgeTransferFunc(const CPDF_Object* pObj) {
-  auto it = m_TransferFuncMap.find(pObj);
-  if (it != m_TransferFuncMap.end() && it->second->HasOneRef())
-    m_TransferFuncMap.erase(it);
+  auto pFunc = CreateTransferFunc(pObj);
+  m_TransferFuncMap[pObj].Reset(pFunc.Get());
+  return pFunc;
 }
 
 RetainPtr<CPDF_TransferFunc> CPDF_DocRenderData::CreateTransferFunc(
diff --git a/core/fpdfapi/render/cpdf_docrenderdata.h b/core/fpdfapi/render/cpdf_docrenderdata.h
index 696b758..1300dfe 100644
--- a/core/fpdfapi/render/cpdf_docrenderdata.h
+++ b/core/fpdfapi/render/cpdf_docrenderdata.h
@@ -12,8 +12,8 @@
 #include "core/fpdfapi/page/cpdf_countedobject.h"
 #include "core/fpdfapi/parser/cpdf_document.h"
 #include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.h"
-#include "core/fxcrt/unowned_ptr.h"
 
 class CPDF_Font;
 class CPDF_Object;
@@ -35,7 +35,6 @@
   void MaybePurgeCachedType3(CPDF_Type3Font* pFont);
 
   RetainPtr<CPDF_TransferFunc> GetTransferFunc(const CPDF_Object* pObj);
-  void MaybePurgeTransferFunc(const CPDF_Object* pObj);
 
  protected:
   // protected for use by test subclasses.
@@ -44,7 +43,8 @@
 
  private:
   std::map<CPDF_Font*, RetainPtr<CPDF_Type3Cache>> m_Type3FaceMap;
-  std::map<const CPDF_Object*, RetainPtr<CPDF_TransferFunc>> m_TransferFuncMap;
+  std::map<const CPDF_Object*, ObservedPtr<CPDF_TransferFunc>>
+      m_TransferFuncMap;
 };
 
 #endif  // CORE_FPDFAPI_RENDER_CPDF_DOCRENDERDATA_H_
diff --git a/core/fpdfapi/render/cpdf_transferfunc.h b/core/fpdfapi/render/cpdf_transferfunc.h
index 74fc01d..bf14320 100644
--- a/core/fpdfapi/render/cpdf_transferfunc.h
+++ b/core/fpdfapi/render/cpdf_transferfunc.h
@@ -9,6 +9,7 @@
 
 #include <vector>
 
+#include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/fx_dib.h"
@@ -17,7 +18,7 @@
 class CPDF_Document;
 class CFX_DIBBase;
 
-class CPDF_TransferFunc final : public Retainable {
+class CPDF_TransferFunc final : public Retainable, public Observable {
  public:
   template <typename T, typename... Args>
   friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);