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_; };