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,