Introduce CPDF_Page::RenderContextClearer.

The need to reset this to nullptr in a few places precludes using
early returns down the road.

-- Remove redundant set to null followed by set to new.
-- Use MakeUnique<> in a few more places along the way.

Change-Id: Ic04ccf205c2bdfedf3e991750f42abe79cbade64
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/61970
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp
index 86256d5..1d1ce32 100644
--- a/core/fpdfapi/page/cpdf_page.cpp
+++ b/core/fpdfapi/page/cpdf_page.cpp
@@ -209,3 +209,10 @@
       break;
   }
 }
+
+CPDF_Page::RenderContextClearer::RenderContextClearer(CPDF_Page* pPage)
+    : m_pPage(pPage) {}
+
+CPDF_Page::RenderContextClearer::~RenderContextClearer() {
+  m_pPage->SetRenderContext(nullptr);
+}
diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h
index 8c4fae3..9bdb75d 100644
--- a/core/fpdfapi/page/cpdf_page.h
+++ b/core/fpdfapi/page/cpdf_page.h
@@ -16,6 +16,7 @@
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/observed_ptr.h"
 #include "core/fxcrt/retain_ptr.h"
+#include "core/fxcrt/unowned_ptr.h"
 #include "third_party/base/optional.h"
 
 class CPDF_Dictionary;
@@ -41,6 +42,15 @@
     virtual void ResetBitmapForImage(const RetainPtr<CPDF_Image>& pImage) = 0;
   };
 
+  class RenderContextClearer {
+   public:
+    explicit RenderContextClearer(CPDF_Page* pPage);
+    ~RenderContextClearer();
+
+   private:
+    UnownedPtr<CPDF_Page> const m_pPage;
+  };
+
   template <typename T, typename... Args>
   friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
 
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 40d58a4..c9253b9 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -524,6 +524,7 @@
 
   auto pOwnedContext = pdfium::MakeUnique<CPDF_PageRenderContext>();
   CPDF_PageRenderContext* pContext = pOwnedContext.get();
+  CPDF_Page::RenderContextClearer clearer(pPage);
   pPage->SetRenderContext(std::move(pOwnedContext));
 
   RetainPtr<CFX_DIBitmap> pBitmap;
@@ -572,9 +573,6 @@
       pContext->m_pRenderer->Continue(nullptr);
     }
 
-    // Reset rendering context
-    pPage->SetRenderContext(nullptr);
-
     // Begin rendering to the printer. Add flag to indicate the renderer should
     // pause after each image mask.
     pOwnedContext = pdfium::MakeUnique<CPDF_PageRenderContext>();
@@ -612,8 +610,6 @@
     if (!bitsStretched)
       WinDC.SetDIBits(pBitmap, 0, 0);
   }
-
-  pPage->SetRenderContext(nullptr);
 }
 #endif  // defined(OS_WIN)
 
@@ -632,11 +628,14 @@
   if (!pPage)
     return;
 
-  CPDF_PageRenderContext* pContext = new CPDF_PageRenderContext;
-  pPage->SetRenderContext(pdfium::WrapUnique(pContext));
+  auto pOwnedContext = pdfium::MakeUnique<CPDF_PageRenderContext>();
+  CPDF_PageRenderContext* pContext = pOwnedContext.get();
+  CPDF_Page::RenderContextClearer clearer(pPage);
+  pPage->SetRenderContext(std::move(pOwnedContext));
 
-  CFX_DefaultRenderDevice* pDevice = new CFX_DefaultRenderDevice;
-  pContext->m_pDevice.reset(pDevice);
+  auto pOwnedDevice = pdfium::MakeUnique<CFX_DefaultRenderDevice>();
+  CFX_DefaultRenderDevice* pDevice = pOwnedDevice.get();
+  pContext->m_pDevice = std::move(pOwnedDevice);
 
   RetainPtr<CFX_DIBitmap> pBitmap(CFXDIBitmapFromFPDFBitmap(bitmap));
   pDevice->Attach(pBitmap, !!(flags & FPDF_REVERSE_BYTE_ORDER), nullptr, false);
@@ -647,7 +646,6 @@
   pDevice->Flush(true);
   pBitmap->UnPreMultiply();
 #endif
-  pPage->SetRenderContext(nullptr);
 }
 
 FPDF_EXPORT void FPDF_CALLCONV
@@ -665,6 +663,7 @@
 
   auto pOwnedContext = pdfium::MakeUnique<CPDF_PageRenderContext>();
   CPDF_PageRenderContext* pContext = pOwnedContext.get();
+  CPDF_Page::RenderContextClearer clearer(pPage);
   pPage->SetRenderContext(std::move(pOwnedContext));
 
   auto pOwnedDevice = pdfium::MakeUnique<CFX_DefaultRenderDevice>();
@@ -685,8 +684,6 @@
     transform_matrix *= CFXMatrixFromFSMatrix(*matrix);
   RenderPageImpl(pContext, pPage, transform_matrix, clip_rect, flags, true,
                  nullptr);
-
-  pPage->SetRenderContext(nullptr);
 }
 
 #ifdef _SKIA_SUPPORT_
@@ -697,14 +694,17 @@
   if (!pPage)
     return nullptr;
 
-  CPDF_PageRenderContext* pContext = new CPDF_PageRenderContext;
-  pPage->SetRenderContext(pdfium::WrapUnique(pContext));
-  CFX_DefaultRenderDevice* skDevice = new CFX_DefaultRenderDevice;
+  auto pOwnedContext = pdfium::MakeUnique<CPDF_PageRenderContext>();
+  CPDF_PageRenderContext* pContext = pOwnedContext.get();
+  CPDF_Page::RenderContextClearer clearer(pPage);
+  pPage->SetRenderContext(std::move(pOwnedContext));
+
+  auto skDevice = pdfium::MakeUnique<CFX_DefaultRenderDevice>();
   FPDF_RECORDER recorder = skDevice->CreateRecorder(size_x, size_y);
-  pContext->m_pDevice.reset(skDevice);
+  pContext->m_pDevice = std::move(skDevice);
+
   RenderPageWithContext(pContext, page, 0, 0, size_x, size_y, 0, 0, true,
                         nullptr);
-  pPage->SetRenderContext(nullptr);
   return recorder;
 }
 #endif  // _SKIA_SUPPORT_