Add CFX_SkiaDeviceDriver(SkCanvas*) constructor
Adds a new CFX_SkiaDeviceDriver constructor that accepts an (unowned)
SkCanvas. This allows CFX_SkiaDeviceDriver to use any SkCanvas
implementation, rather than just one backed by SkBitmap or
SkPictureRecorder.
Removes internal APIs that use SkPictureRecorder, as all APIs other than
FPDF_RenderPageSkp() only need an SkCanvas.
For the constructor accepting a CFX_DIBitmap, replaces the (owned)
SkCanvas wrapping an SkBitmap with the (unowned) SkCanvas associated
with a raster SkSurface. This makes the SkCanvas uniformly unowned,
eliminating a special case in the destructor.
Bug: pdfium:2034
Change-Id: I2fb4420807fd3a763b59bde889758d4fa52ab3e3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/108071
Reviewed-by: Nigi <nigi@chromium.org>
Commit-Queue: Nigi <nigi@chromium.org>
Auto-Submit: K. Moon <kmoon@chromium.org>
diff --git a/core/fxge/cfx_defaultrenderdevice.h b/core/fxge/cfx_defaultrenderdevice.h
index f9c20fe..112c4c7 100644
--- a/core/fxge/cfx_defaultrenderdevice.h
+++ b/core/fxge/cfx_defaultrenderdevice.h
@@ -13,8 +13,7 @@
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/dib/fx_dib.h"
-class SkPictureRecorder;
-struct SkRect;
+class SkCanvas;
class CFX_DefaultRenderDevice final : public CFX_RenderDevice {
public:
@@ -34,9 +33,8 @@
RetainPtr<CFX_DIBitmap> pBackdropBitmap);
#if defined(_SKIA_SUPPORT_)
- bool AttachRecorder(SkPictureRecorder* recorder);
+ bool AttachCanvas(SkCanvas* canvas);
void Clear(uint32_t color);
- std::unique_ptr<SkPictureRecorder> CreateRecorder(const SkRect& bounds);
bool SetBitsWithMask(const RetainPtr<CFX_DIBBase>& pBitmap,
const RetainPtr<CFX_DIBBase>& pMask,
int left,
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index a8d22eb..c600e3f 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -64,13 +64,13 @@
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPathEffect.h"
#include "third_party/skia/include/core/SkPathUtils.h"
-#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkRSXform.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSamplingOptions.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/core/SkStream.h"
+#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkTextBlob.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/effects/SkDashPathEffect.h"
@@ -832,10 +832,8 @@
bool bGroupKnockout)
: m_pBitmap(std::move(pBitmap)),
m_pBackdropBitmap(pBackdropBitmap),
- m_pRecorder(nullptr),
m_bRgbByteOrder(bRgbByteOrder),
m_bGroupKnockout(bGroupKnockout) {
- SkBitmap skBitmap;
SkColorType color_type;
const int bpp = m_pBitmap->GetBPP();
if (bpp == 8) {
@@ -865,14 +863,13 @@
SkImageInfo imageInfo =
SkImageInfo::Make(m_pBitmap->GetWidth(), m_pBitmap->GetHeight(),
color_type, kPremul_SkAlphaType);
- skBitmap.installPixels(imageInfo, m_pBitmap->GetBuffer().data(),
- m_pBitmap->GetPitch());
- m_pCanvas = new SkCanvas(skBitmap);
+ surface_ = SkSurfaces::WrapPixels(imageInfo, m_pBitmap->GetBuffer().data(),
+ m_pBitmap->GetPitch());
+ m_pCanvas = surface_->getCanvas();
}
-CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkPictureRecorder* recorder)
- : m_pRecorder(recorder), m_bGroupKnockout(false) {
- m_pCanvas = m_pRecorder->getRecordingCanvas();
+CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkCanvas* canvas)
+ : m_pCanvas(canvas), m_bGroupKnockout(false) {
int width = m_pCanvas->imageInfo().width();
int height = m_pCanvas->imageInfo().height();
DCHECK_EQ(kUnknown_SkColorType, m_pCanvas->imageInfo().colorType());
@@ -896,10 +893,6 @@
height, m_pBitmap, /*src_left=*/0,
/*src_top=*/0);
}
-
- if (!m_pRecorder) {
- delete m_pCanvas.ExtractAsDangling();
- }
}
bool CFX_SkiaDeviceDriver::DrawDeviceText(
@@ -1809,15 +1802,6 @@
static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver())->Clear(color);
}
-std::unique_ptr<SkPictureRecorder> CFX_DefaultRenderDevice::CreateRecorder(
- const SkRect& bounds) {
- auto recorder = std::make_unique<SkPictureRecorder>();
- recorder->beginRecording(bounds);
-
- SetDeviceDriver(std::make_unique<CFX_SkiaDeviceDriver>(recorder.get()));
- return recorder;
-}
-
bool CFX_DefaultRenderDevice::AttachSkiaImpl(
RetainPtr<CFX_DIBitmap> pBitmap,
bool bRgbByteOrder,
@@ -1836,10 +1820,11 @@
return true;
}
-bool CFX_DefaultRenderDevice::AttachRecorder(SkPictureRecorder* recorder) {
- if (!recorder)
+bool CFX_DefaultRenderDevice::AttachCanvas(SkCanvas* canvas) {
+ if (!canvas) {
return false;
- SetDeviceDriver(std::make_unique<CFX_SkiaDeviceDriver>(recorder));
+ }
+ SetDeviceDriver(std::make_unique<CFX_SkiaDeviceDriver>(canvas));
return true;
}
diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h
index e6b2529..1051526 100644
--- a/core/fxge/skia/fx_skia_device.h
+++ b/core/fxge/skia/fx_skia_device.h
@@ -20,11 +20,12 @@
#include "third_party/base/span.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "third_party/skia/include/core/SkRSXform.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
class CFX_Font;
class CFX_Matrix;
class SkCanvas;
-class SkPictureRecorder;
+class SkSurface;
class TextCharPos;
struct CFX_TextRenderOptions;
@@ -40,7 +41,7 @@
RetainPtr<CFX_DIBitmap> pBackdropBitmap,
bool bGroupKnockout);
- explicit CFX_SkiaDeviceDriver(SkPictureRecorder* recorder);
+ explicit CFX_SkiaDeviceDriver(SkCanvas* canvas);
~CFX_SkiaDeviceDriver() override;
/** Options */
@@ -218,8 +219,8 @@
// bitmap is 24 bpp and cannot be directly used as the back of a SkCanvas.
RetainPtr<CFX_DIBitmap> m_pOriginalBitmap;
+ sk_sp<SkSurface> surface_;
UnownedPtr<SkCanvas> m_pCanvas;
- UnownedPtr<SkPictureRecorder> const m_pRecorder;
CFX_FillRenderOptions m_FillOptions;
bool m_bRgbByteOrder;
bool m_bGroupKnockout;
diff --git a/fpdfsdk/fpdf_formfill.cpp b/fpdfsdk/fpdf_formfill.cpp
index 8c1a083..0a6ae85 100644
--- a/fpdfsdk/fpdf_formfill.cpp
+++ b/fpdfsdk/fpdf_formfill.cpp
@@ -28,6 +28,10 @@
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "public/fpdfview.h"
+#if defined(_SKIA_SUPPORT_)
+#include "third_party/skia/include/core/SkPictureRecorder.h" // nogncheck
+#endif // defined(_SKIA_SUPPORT_)
+
#ifdef PDF_ENABLE_XFA
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
@@ -194,8 +198,10 @@
auto pDevice = std::make_unique<CFX_DefaultRenderDevice>();
#if defined(_SKIA_SUPPORT_)
- if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
- pDevice->AttachRecorder(static_cast<SkPictureRecorder*>(recorder));
+ if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer() && recorder) {
+ pDevice->AttachCanvas(
+ static_cast<SkPictureRecorder*>(recorder)->getRecordingCanvas());
+ }
#endif
RetainPtr<CFX_DIBitmap> holder(CFXDIBitmapFromFPDFBitmap(bitmap));
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index d65579d..430b660 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -731,8 +731,9 @@
int size_x,
int size_y) {
auto skDevice = std::make_unique<CFX_DefaultRenderDevice>();
- std::unique_ptr<SkPictureRecorder> recorder =
- skDevice->CreateRecorder(SkRect::MakeWH(size_x, size_y));
+ auto recorder = std::make_unique<SkPictureRecorder>();
+ recorder->beginRecording(SkRect::MakeWH(size_x, size_y));
+ skDevice->AttachCanvas(recorder->getRecordingCanvas());
CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
if (!pPage) {