Move some fpdfsdk page rendering code into cpdfsdk_renderpage.cpp.

Add files dedicated to shared rendering code, instead of having the code
live in fpdfsdk/fpdf_view.cpp, with a declaration in
fpdfsdk/cpdfsdk_helpers.h.

Change-Id: I1042aaf07785485ca71bec4cc4e7a2047684caed
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/65454
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/BUILD.gn b/fpdfsdk/BUILD.gn
index 1c77fee..9eb9562 100644
--- a/fpdfsdk/BUILD.gn
+++ b/fpdfsdk/BUILD.gn
@@ -39,6 +39,8 @@
     "cpdfsdk_pageview.h",
     "cpdfsdk_pauseadapter.cpp",
     "cpdfsdk_pauseadapter.h",
+    "cpdfsdk_renderpage.cpp",
+    "cpdfsdk_renderpage.h",
     "cpdfsdk_widget.cpp",
     "cpdfsdk_widget.h",
     "cpdfsdk_widgethandler.cpp",
diff --git a/fpdfsdk/cpdfsdk_helpers.h b/fpdfsdk/cpdfsdk_helpers.h
index 9e2cb32..f59f105 100644
--- a/fpdfsdk/cpdfsdk_helpers.h
+++ b/fpdfsdk/cpdfsdk_helpers.h
@@ -32,7 +32,6 @@
 class CPDF_Font;
 class CPDF_LinkExtract;
 class CPDF_PageObject;
-class CPDF_PageRenderContext;
 class CPDF_Stream;
 class CPDF_StructElement;
 class CPDF_StructTree;
@@ -40,7 +39,6 @@
 class CPDF_TextPageFind;
 class CPDFSDK_FormFillEnvironment;
 class CPDFSDK_InteractiveForm;
-class CPDFSDK_PauseAdapter;
 class FX_PATHPOINT;
 struct CPDF_JavaScript;
 
@@ -263,18 +261,6 @@
 void SetPDFSandboxPolicy(FPDF_DWORD policy, FPDF_BOOL enable);
 FPDF_BOOL IsPDFSandboxPolicyEnabled(FPDF_DWORD policy);
 
-// TODO(dsinclair): Where should this live?
-void RenderPageWithContext(CPDF_Page* pPage,
-                           CPDF_PageRenderContext* pContext,
-                           int start_x,
-                           int start_y,
-                           int size_x,
-                           int size_y,
-                           int rotate,
-                           int flags,
-                           bool bNeedToRestore,
-                           CPDFSDK_PauseAdapter* pause);
-
 void SetPDFUnsupportInfo(UNSUPPORT_INFO* unsp_info);
 UNSUPPORT_INFO* GetPDFUnssuportInto();
 void ReportUnsupportedFeatures(CPDF_Document* pDoc);
diff --git a/fpdfsdk/cpdfsdk_renderpage.cpp b/fpdfsdk/cpdfsdk_renderpage.cpp
new file mode 100644
index 0000000..ce492e6
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_renderpage.cpp
@@ -0,0 +1,102 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fpdfsdk/cpdfsdk_renderpage.h"
+
+#include <utility>
+
+#include "core/fpdfapi/render/cpdf_pagerendercache.h"
+#include "core/fpdfapi/render/cpdf_pagerendercontext.h"
+#include "core/fpdfapi/render/cpdf_progressiverenderer.h"
+#include "core/fpdfapi/render/cpdf_renderoptions.h"
+#include "core/fpdfdoc/cpdf_annotlist.h"
+#include "core/fxge/cfx_renderdevice.h"
+#include "fpdfsdk/cpdfsdk_pauseadapter.h"
+#include "public/fpdfview.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+void RenderPageImpl(CPDF_PageRenderContext* pContext,
+                    CPDF_Page* pPage,
+                    const CFX_Matrix& matrix,
+                    const FX_RECT& clipping_rect,
+                    int flags,
+                    bool need_to_restore,
+                    CPDFSDK_PauseAdapter* pause) {
+  if (!pContext->m_pOptions)
+    pContext->m_pOptions = pdfium::MakeUnique<CPDF_RenderOptions>();
+
+  auto& options = pContext->m_pOptions->GetOptions();
+  options.bClearType = !!(flags & FPDF_LCD_TEXT);
+  options.bNoNativeText = !!(flags & FPDF_NO_NATIVETEXT);
+  options.bLimitedImageCache = !!(flags & FPDF_RENDER_LIMITEDIMAGECACHE);
+  options.bForceHalftone = !!(flags & FPDF_RENDER_FORCEHALFTONE);
+  options.bNoTextSmooth = !!(flags & FPDF_RENDER_NO_SMOOTHTEXT);
+  options.bNoImageSmooth = !!(flags & FPDF_RENDER_NO_SMOOTHIMAGE);
+  options.bNoPathSmooth = !!(flags & FPDF_RENDER_NO_SMOOTHPATH);
+
+  // Grayscale output
+  if (flags & FPDF_GRAYSCALE)
+    pContext->m_pOptions->SetColorMode(CPDF_RenderOptions::kGray);
+
+  const CPDF_OCContext::UsageType usage =
+      (flags & FPDF_PRINTING) ? CPDF_OCContext::Print : CPDF_OCContext::View;
+  pContext->m_pOptions->SetOCContext(
+      pdfium::MakeRetain<CPDF_OCContext>(pPage->GetDocument(), usage));
+
+  pContext->m_pDevice->SaveState();
+  pContext->m_pDevice->SetBaseClip(clipping_rect);
+  pContext->m_pDevice->SetClip_Rect(clipping_rect);
+  pContext->m_pContext = pdfium::MakeUnique<CPDF_RenderContext>(
+      pPage->GetDocument(), pPage->m_pPageResources.Get(),
+      static_cast<CPDF_PageRenderCache*>(pPage->GetRenderCache()));
+
+  pContext->m_pContext->AppendLayer(pPage, &matrix);
+
+  if (flags & FPDF_ANNOT) {
+    auto pOwnedList = pdfium::MakeUnique<CPDF_AnnotList>(pPage);
+    CPDF_AnnotList* pList = pOwnedList.get();
+    pContext->m_pAnnots = std::move(pOwnedList);
+    bool bPrinting =
+        pContext->m_pDevice->GetDeviceType() != DeviceType::kDisplay;
+    pList->DisplayAnnots(pPage, pContext->m_pContext.get(), bPrinting, &matrix,
+                         false, nullptr);
+  }
+
+  pContext->m_pRenderer = pdfium::MakeUnique<CPDF_ProgressiveRenderer>(
+      pContext->m_pContext.get(), pContext->m_pDevice.get(),
+      pContext->m_pOptions.get());
+  pContext->m_pRenderer->Start(pause);
+  if (need_to_restore)
+    pContext->m_pDevice->RestoreState(false);
+}
+
+}  // namespace
+
+void CPDFSDK_RenderPage(CPDF_PageRenderContext* pContext,
+                        CPDF_Page* pPage,
+                        const CFX_Matrix& matrix,
+                        const FX_RECT& clipping_rect,
+                        int flags) {
+  RenderPageImpl(pContext, pPage, matrix, clipping_rect, flags,
+                 /*need_to_restore=*/true, /*pause=*/nullptr);
+}
+
+void CPDFSDK_RenderPageWithContext(CPDF_PageRenderContext* pContext,
+                                   CPDF_Page* pPage,
+                                   int start_x,
+                                   int start_y,
+                                   int size_x,
+                                   int size_y,
+                                   int rotate,
+                                   int flags,
+                                   bool need_to_restore,
+                                   CPDFSDK_PauseAdapter* pause) {
+  const FX_RECT rect(start_x, start_y, start_x + size_x, start_y + size_y);
+  RenderPageImpl(pContext, pPage, pPage->GetDisplayMatrix(rect, rotate), rect,
+                 flags, need_to_restore, pause);
+}
diff --git a/fpdfsdk/cpdfsdk_renderpage.h b/fpdfsdk/cpdfsdk_renderpage.h
new file mode 100644
index 0000000..cb7a600
--- /dev/null
+++ b/fpdfsdk/cpdfsdk_renderpage.h
@@ -0,0 +1,35 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FPDFSDK_CPDFSDK_RENDERPAGE_H_
+#define FPDFSDK_CPDFSDK_RENDERPAGE_H_
+
+class CFX_Matrix;
+class CPDFSDK_PauseAdapter;
+class CPDF_Page;
+class CPDF_PageRenderContext;
+struct FX_RECT;
+
+void CPDFSDK_RenderPage(CPDF_PageRenderContext* pContext,
+                        CPDF_Page* pPage,
+                        const CFX_Matrix& matrix,
+                        const FX_RECT& clipping_rect,
+                        int flags);
+
+// TODO(thestig): Consider giving this a better name, and make its parameters
+// more similar to those of CPDFSDK_RenderPage().
+void CPDFSDK_RenderPageWithContext(CPDF_PageRenderContext* pContext,
+                                   CPDF_Page* pPage,
+                                   int start_x,
+                                   int start_y,
+                                   int size_x,
+                                   int size_y,
+                                   int rotate,
+                                   int flags,
+                                   bool need_to_restore,
+                                   CPDFSDK_PauseAdapter* pause);
+
+#endif  // FPDFSDK_CPDFSDK_RENDERPAGE_H_
diff --git a/fpdfsdk/fpdf_progressive.cpp b/fpdfsdk/fpdf_progressive.cpp
index 6ce6dc1..cb138c7 100644
--- a/fpdfsdk/fpdf_progressive.cpp
+++ b/fpdfsdk/fpdf_progressive.cpp
@@ -12,12 +12,16 @@
 #include "core/fpdfapi/render/cpdf_pagerendercontext.h"
 #include "core/fpdfapi/render/cpdf_progressiverenderer.h"
 #include "core/fxge/cfx_defaultrenderdevice.h"
-#include "core/fxge/cfx_renderdevice.h"
 #include "fpdfsdk/cpdfsdk_helpers.h"
 #include "fpdfsdk/cpdfsdk_pauseadapter.h"
+#include "fpdfsdk/cpdfsdk_renderpage.h"
 #include "public/fpdfview.h"
 #include "third_party/base/ptr_util.h"
 
+#ifdef _SKIA_SUPPORT_PATHS_
+#include "core/fxge/cfx_renderdevice.h"
+#endif
+
 // These checks are here because core/ and public/ cannot depend on each other.
 static_assert(CPDF_ProgressiveRenderer::kReady == FPDF_RENDER_READY,
               "CPDF_ProgressiveRenderer::kReady value mismatch");
@@ -56,8 +60,9 @@
   pDevice->Attach(pBitmap, !!(flags & FPDF_REVERSE_BYTE_ORDER), nullptr, false);
 
   CPDFSDK_PauseAdapter pause_adapter(pause);
-  RenderPageWithContext(pPage, pContext, start_x, start_y, size_x, size_y,
-                        rotate, flags, false, &pause_adapter);
+  CPDFSDK_RenderPageWithContext(pContext, pPage, start_x, start_y, size_x,
+                                size_y, rotate, flags,
+                                /*need_to_restore=*/false, &pause_adapter);
 
 #ifdef _SKIA_SUPPORT_PATHS_
   pDevice->Flush(false);
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 194e92f..8f7a3b7 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -24,10 +24,8 @@
 #include "core/fpdfapi/render/cpdf_docrenderdata.h"
 #include "core/fpdfapi/render/cpdf_pagerendercache.h"
 #include "core/fpdfapi/render/cpdf_pagerendercontext.h"
-#include "core/fpdfapi/render/cpdf_progressiverenderer.h"
 #include "core/fpdfapi/render/cpdf_rendercontext.h"
 #include "core/fpdfapi/render/cpdf_renderoptions.h"
-#include "core/fpdfdoc/cpdf_annotlist.h"
 #include "core/fpdfdoc/cpdf_nametree.h"
 #include "core/fpdfdoc/cpdf_viewerpreferences.h"
 #include "core/fxcrt/cfx_readonlymemorystream.h"
@@ -41,7 +39,7 @@
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_helpers.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
-#include "fpdfsdk/cpdfsdk_pauseadapter.h"
+#include "fpdfsdk/cpdfsdk_renderpage.h"
 #include "fxjs/ijs_runtime.h"
 #include "public/fpdf_formfill.h"
 #include "third_party/base/ptr_util.h"
@@ -54,6 +52,7 @@
 #endif  // PDF_ENABLE_XFA
 
 #if defined(OS_WIN)
+#include "core/fpdfapi/render/cpdf_progressiverenderer.h"
 #include "core/fpdfapi/render/cpdf_windowsrenderdevice.h"
 #include "public/fpdf_edit.h"
 
@@ -78,61 +77,6 @@
 
 bool g_bLibraryInitialized = false;
 
-void RenderPageImpl(CPDF_PageRenderContext* pContext,
-                    CPDF_Page* pPage,
-                    const CFX_Matrix& matrix,
-                    const FX_RECT& clipping_rect,
-                    int flags,
-                    bool bNeedToRestore,
-                    CPDFSDK_PauseAdapter* pause) {
-  if (!pContext->m_pOptions)
-    pContext->m_pOptions = pdfium::MakeUnique<CPDF_RenderOptions>();
-
-  auto& options = pContext->m_pOptions->GetOptions();
-  options.bClearType = !!(flags & FPDF_LCD_TEXT);
-  options.bNoNativeText = !!(flags & FPDF_NO_NATIVETEXT);
-  options.bLimitedImageCache = !!(flags & FPDF_RENDER_LIMITEDIMAGECACHE);
-  options.bForceHalftone = !!(flags & FPDF_RENDER_FORCEHALFTONE);
-  options.bNoTextSmooth = !!(flags & FPDF_RENDER_NO_SMOOTHTEXT);
-  options.bNoImageSmooth = !!(flags & FPDF_RENDER_NO_SMOOTHIMAGE);
-  options.bNoPathSmooth = !!(flags & FPDF_RENDER_NO_SMOOTHPATH);
-
-  // Grayscale output
-  if (flags & FPDF_GRAYSCALE)
-    pContext->m_pOptions->SetColorMode(CPDF_RenderOptions::kGray);
-
-  const CPDF_OCContext::UsageType usage =
-      (flags & FPDF_PRINTING) ? CPDF_OCContext::Print : CPDF_OCContext::View;
-  pContext->m_pOptions->SetOCContext(
-      pdfium::MakeRetain<CPDF_OCContext>(pPage->GetDocument(), usage));
-
-  pContext->m_pDevice->SaveState();
-  pContext->m_pDevice->SetBaseClip(clipping_rect);
-  pContext->m_pDevice->SetClip_Rect(clipping_rect);
-  pContext->m_pContext = pdfium::MakeUnique<CPDF_RenderContext>(
-      pPage->GetDocument(), pPage->m_pPageResources.Get(),
-      static_cast<CPDF_PageRenderCache*>(pPage->GetRenderCache()));
-
-  pContext->m_pContext->AppendLayer(pPage, &matrix);
-
-  if (flags & FPDF_ANNOT) {
-    auto pOwnedList = pdfium::MakeUnique<CPDF_AnnotList>(pPage);
-    CPDF_AnnotList* pList = pOwnedList.get();
-    pContext->m_pAnnots = std::move(pOwnedList);
-    bool bPrinting =
-        pContext->m_pDevice->GetDeviceType() != DeviceType::kDisplay;
-    pList->DisplayAnnots(pPage, pContext->m_pContext.get(), bPrinting, &matrix,
-                         false, nullptr);
-  }
-
-  pContext->m_pRenderer = pdfium::MakeUnique<CPDF_ProgressiveRenderer>(
-      pContext->m_pContext.get(), pContext->m_pDevice.get(),
-      pContext->m_pOptions.get());
-  pContext->m_pRenderer->Start(pause);
-  if (bNeedToRestore)
-    pContext->m_pDevice->RestoreState(false);
-}
-
 FPDF_DOCUMENT LoadDocumentImpl(
     const RetainPtr<IFX_SeekableReadStream>& pFileAccess,
     FPDF_BYTESTRING password) {
@@ -545,7 +489,7 @@
   // of masks. Full page bitmaps result in large spool sizes, so they should
   // only be used when necessary. For large numbers of masks, rendering each
   // individually is inefficient and unlikely to significantly improve spool
-  // size. TODO (rbpotter): Find out why this still breaks printing for some
+  // size. TODO(rbpotter): Find out why this still breaks printing for some
   // PDFs (see crbug.com/777837).
   const bool bEnableImageMasks = false;
   const bool bNewBitmap = pPage->BackgroundAlphaNeeded() ||
@@ -554,8 +498,9 @@
   const bool bHasMask = pPage->HasImageMask() && !bNewBitmap;
   if (!bNewBitmap && !bHasMask) {
     pContext->m_pDevice = pdfium::MakeUnique<CPDF_WindowsRenderDevice>(dc);
-    RenderPageWithContext(pPage, pContext, start_x, start_y, size_x, size_y,
-                          rotate, flags, true, nullptr);
+    CPDFSDK_RenderPageWithContext(pContext, pPage, start_x, start_y, size_x,
+                                  size_y, rotate, flags,
+                                  /*need_to_restore=*/true, /*pause=*/nullptr);
     return;
   }
 
@@ -572,8 +517,9 @@
     pContext->m_pOptions->GetOptions().bBreakForMasks = true;
   }
 
-  RenderPageWithContext(pPage, pContext, start_x, start_y, size_x, size_y,
-                        rotate, flags, true, nullptr);
+  CPDFSDK_RenderPageWithContext(pContext, pPage, start_x, start_y, size_x,
+                                size_y, rotate, flags, /*need_to_restore=*/true,
+                                /*pause=*/nullptr);
 
   if (!bHasMask) {
     CPDF_WindowsRenderDevice WinDC(dc);
@@ -613,8 +559,9 @@
   pContext->m_pOptions = pdfium::MakeUnique<CPDF_RenderOptions>();
   pContext->m_pOptions->GetOptions().bBreakForMasks = true;
 
-  RenderPageWithContext(pPage, pContext, start_x, start_y, size_x, size_y,
-                        rotate, flags, true, nullptr);
+  CPDFSDK_RenderPageWithContext(pContext, pPage, start_x, start_y, size_x,
+                                size_y, rotate, flags, /*need_to_restore=*/true,
+                                /*pause=*/nullptr);
 
   // Render masks
   for (size_t i = 0; i < mask_boxes.size(); i++) {
@@ -654,8 +601,9 @@
 
   RetainPtr<CFX_DIBitmap> pBitmap(CFXDIBitmapFromFPDFBitmap(bitmap));
   pDevice->Attach(pBitmap, !!(flags & FPDF_REVERSE_BYTE_ORDER), nullptr, false);
-  RenderPageWithContext(pPage, pContext, start_x, start_y, size_x, size_y,
-                        rotate, flags, true, nullptr);
+  CPDFSDK_RenderPageWithContext(pContext, pPage, start_x, start_y, size_x,
+                                size_y, rotate, flags, /*need_to_restore=*/true,
+                                /*pause=*/nullptr);
 
 #ifdef _SKIA_SUPPORT_PATHS_
   pDevice->Flush(true);
@@ -697,8 +645,7 @@
   CFX_Matrix transform_matrix = pPage->GetDisplayMatrix(rect, 0);
   if (matrix)
     transform_matrix *= CFXMatrixFromFSMatrix(*matrix);
-  RenderPageImpl(pContext, pPage, transform_matrix, clip_rect, flags, true,
-                 nullptr);
+  CPDFSDK_RenderPage(pContext, pPage, transform_matrix, clip_rect, flags);
 }
 
 #ifdef _SKIA_SUPPORT_
@@ -718,8 +665,8 @@
   FPDF_RECORDER recorder = skDevice->CreateRecorder(size_x, size_y);
   pContext->m_pDevice = std::move(skDevice);
 
-  RenderPageWithContext(pPage, pContext, 0, 0, size_x, size_y, 0, 0, true,
-                        nullptr);
+  CPDFSDK_RenderPageWithContext(pContext, pPage, 0, 0, size_x, size_y, 0, 0,
+                                /*need_to_restore=*/true, /*pause=*/nullptr);
   return recorder;
 }
 #endif  // _SKIA_SUPPORT_
@@ -910,21 +857,6 @@
   destroyer.Unleak(CFXDIBitmapFromFPDFBitmap(bitmap));
 }
 
-void RenderPageWithContext(CPDF_Page* pPage,
-                           CPDF_PageRenderContext* pContext,
-                           int start_x,
-                           int start_y,
-                           int size_x,
-                           int size_y,
-                           int rotate,
-                           int flags,
-                           bool bNeedToRestore,
-                           CPDFSDK_PauseAdapter* pause) {
-  const FX_RECT rect(start_x, start_y, start_x + size_x, start_y + size_y);
-  RenderPageImpl(pContext, pPage, pPage->GetDisplayMatrix(rect, rotate), rect,
-                 flags, bNeedToRestore, pause);
-}
-
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
 FPDF_GetPageSizeByIndexF(FPDF_DOCUMENT document,
                          int page_index,