Make CPDF_ScaledRenderBuffer Windows-only
Refactor its only user in CPDF_RenderStatus to draw directly to its
render device on non-Windows platforms. For Windows, optionally draw
with CPDF_ScaledRenderBuffer when needed. Move the code that determines
if CPDF_ScaledRenderBuffer is needed to CPDF_RenderStatus. Then
CPDF_ScaledRenderBuffer can become slightly simpler.
Change-Id: I026cd6d0c898d462d3129c493ad0161ae0507555
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/123213
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/render/BUILD.gn b/core/fpdfapi/render/BUILD.gn
index bb76ef8..a3964f2 100644
--- a/core/fpdfapi/render/BUILD.gn
+++ b/core/fpdfapi/render/BUILD.gn
@@ -29,8 +29,6 @@
"cpdf_renderstatus.h",
"cpdf_rendertiling.cpp",
"cpdf_rendertiling.h",
- "cpdf_scaledrenderbuffer.cpp",
- "cpdf_scaledrenderbuffer.h",
"cpdf_textrenderer.cpp",
"cpdf_textrenderer.h",
"cpdf_type3cache.cpp",
@@ -54,6 +52,8 @@
visibility = [ "../../../*" ]
if (is_win) {
sources += [
+ "cpdf_scaledrenderbuffer.cpp",
+ "cpdf_scaledrenderbuffer.h",
"cpdf_windowsrenderdevice.cpp",
"cpdf_windowsrenderdevice.h",
]
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index ee09437..e50d012 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -48,7 +48,6 @@
#include "core/fpdfapi/render/cpdf_renderoptions.h"
#include "core/fpdfapi/render/cpdf_rendershading.h"
#include "core/fpdfapi/render/cpdf_rendertiling.h"
-#include "core/fpdfapi/render/cpdf_scaledrenderbuffer.h"
#include "core/fpdfapi/render/cpdf_textrenderer.h"
#include "core/fpdfapi/render/cpdf_type3cache.h"
#include "core/fxcrt/autorestorer.h"
@@ -74,6 +73,10 @@
#include "core/fxge/text_char_pos.h"
#include "core/fxge/text_glyph_pos.h"
+#if BUILDFLAG(IS_WIN)
+#include "core/fpdfapi/render/cpdf_scaledrenderbuffer.h"
+#endif
+
namespace {
constexpr int kRenderMaxRecursionDepth = 64;
@@ -334,26 +337,48 @@
if (rect.IsEmpty())
return;
- int res = (pObj->IsImage() && IsPrint()) ? 0 : 300;
+ const bool needs_buffer =
+ !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS);
+ if (!needs_buffer) {
+ DrawObjWithBackgroundToDevice(pObj, mtObj2Device, m_pDevice, CFX_Matrix());
+ return;
+ }
+
+#if BUILDFLAG(IS_WIN)
CPDF_ScaledRenderBuffer buffer(m_pDevice, rect);
+ int res = (pObj->IsImage() && IsPrint()) ? 0 : 300;
if (!buffer.Initialize(m_pContext, pObj, m_Options, res)) {
return;
}
+
+ DrawObjWithBackgroundToDevice(pObj, mtObj2Device, buffer.GetDevice(),
+ buffer.GetMatrix());
+ buffer.OutputToDevice();
+#else
+ NOTREACHED_NORETURN();
+#endif
+}
+
+void CPDF_RenderStatus::DrawObjWithBackgroundToDevice(
+ CPDF_PageObject* obj,
+ const CFX_Matrix& object_to_device,
+ CFX_RenderDevice* device,
+ const CFX_Matrix& device_matrix) {
RetainPtr<const CPDF_Dictionary> pFormResource;
- CFX_Matrix matrix = mtObj2Device * buffer.GetMatrix();
- const CPDF_FormObject* pFormObj = pObj->AsForm();
- if (pFormObj)
+ const CPDF_FormObject* pFormObj = obj->AsForm();
+ if (pFormObj) {
pFormResource = pFormObj->form()->GetDict()->GetDictFor("Resources");
- CPDF_RenderStatus status(m_pContext, buffer.GetDevice());
+ }
+
+ CPDF_RenderStatus status(m_pContext, device);
status.SetOptions(m_Options);
- status.SetDeviceMatrix(buffer.GetMatrix());
+ status.SetDeviceMatrix(device_matrix);
status.SetTransparency(m_Transparency);
status.SetDropObjects(m_bDropObjects);
status.SetFormResource(std::move(pFormResource));
status.SetInGroup(m_bInGroup);
status.Initialize(nullptr, nullptr);
- status.RenderSingleObject(pObj, matrix);
- buffer.OutputToDevice();
+ status.RenderSingleObject(obj, object_to_device * device_matrix);
}
bool CPDF_RenderStatus::ProcessForm(const CPDF_FormObject* pFormObj,
diff --git a/core/fpdfapi/render/cpdf_renderstatus.h b/core/fpdfapi/render/cpdf_renderstatus.h
index 9df2711..5f89694 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.h
+++ b/core/fpdfapi/render/cpdf_renderstatus.h
@@ -136,6 +136,10 @@
const CFX_Matrix& mtObj2Device);
void DrawObjWithBackground(CPDF_PageObject* pObj,
const CFX_Matrix& mtObj2Device);
+ void DrawObjWithBackgroundToDevice(CPDF_PageObject* obj,
+ const CFX_Matrix& object_to_device,
+ CFX_RenderDevice* device,
+ const CFX_Matrix& device_matrix);
bool DrawObjWithBlend(CPDF_PageObject* pObj, const CFX_Matrix& mtObj2Device);
bool ProcessPath(CPDF_PathObject* path_obj, const CFX_Matrix& mtObj2Device);
void ProcessPathPattern(CPDF_PathObject* path_obj,
diff --git a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
index b8c10fb..ce54ff3 100644
--- a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
+++ b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
@@ -6,6 +6,7 @@
#include "core/fpdfapi/render/cpdf_scaledrenderbuffer.h"
+#include "build/build_config.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/render/cpdf_devicebuffer.h"
#include "core/fpdfapi/render/cpdf_rendercontext.h"
@@ -20,7 +21,9 @@
CPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer(CFX_RenderDevice* device,
const FX_RECT& rect)
- : device_(device), rect_(rect) {}
+ : device_(device),
+ bitmap_device_(std::make_unique<CFX_DefaultRenderDevice>()),
+ rect_(rect) {}
CPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer() = default;
@@ -28,13 +31,8 @@
const CPDF_PageObject* pObj,
const CPDF_RenderOptions& options,
int max_dpi) {
- if (device_->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
- return true;
- }
-
matrix_ = CPDF_DeviceBuffer::CalculateMatrix(device_, rect_, max_dpi,
/*scale=*/true);
- bitmap_device_ = std::make_unique<CFX_DefaultRenderDevice>();
bool bIsAlpha =
!!(device_->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT);
FXDIB_Format dibFormat = bIsAlpha ? FXDIB_Format::kArgb : FXDIB_Format::kRgb;
@@ -61,17 +59,14 @@
return true;
}
-CFX_RenderDevice* CPDF_ScaledRenderBuffer::GetDevice() const {
- return bitmap_device_ ? static_cast<CFX_RenderDevice*>(bitmap_device_.get())
- : device_.get();
+CFX_DefaultRenderDevice* CPDF_ScaledRenderBuffer::GetDevice() {
+ return bitmap_device_.get();
}
void CPDF_ScaledRenderBuffer::OutputToDevice() {
- if (bitmap_device_) {
#if defined(PDF_USE_SKIA)
- bitmap_device_->SyncInternalBitmaps();
+ bitmap_device_->SyncInternalBitmaps();
#endif
- device_->StretchDIBits(bitmap_device_->GetBitmap(), rect_.left, rect_.top,
- rect_.Width(), rect_.Height());
- }
+ device_->StretchDIBits(bitmap_device_->GetBitmap(), rect_.left, rect_.top,
+ rect_.Width(), rect_.Height());
}
diff --git a/core/fpdfapi/render/cpdf_scaledrenderbuffer.h b/core/fpdfapi/render/cpdf_scaledrenderbuffer.h
index 16eb4f4..6a9c8c4 100644
--- a/core/fpdfapi/render/cpdf_scaledrenderbuffer.h
+++ b/core/fpdfapi/render/cpdf_scaledrenderbuffer.h
@@ -28,13 +28,13 @@
const CPDF_RenderOptions& options,
int max_dpi);
- CFX_RenderDevice* GetDevice() const;
+ CFX_DefaultRenderDevice* GetDevice();
const CFX_Matrix& GetMatrix() const { return matrix_; }
void OutputToDevice();
private:
UnownedPtr<CFX_RenderDevice> const device_;
- std::unique_ptr<CFX_DefaultRenderDevice> bitmap_device_;
+ std::unique_ptr<CFX_DefaultRenderDevice> const bitmap_device_;
const FX_RECT rect_;
CFX_Matrix matrix_;
};