Make FFLCommon() more robust with absl::variant
FFLCommon() is a helper function that is intended to either takes a
bitmap or a canvas. Currently, the bitmap and canvas are passed in as
two separate parameters, and they may be null. As a result, FFLCommon()
is not quite sure which to use, and tries to use both when initializing
CFX_DefaultRenderDevice.
Combine the 2 parameters into an absl::variant. Now FFLCommon() knows
for certain what the input type is, and can initialize
CFX_DefaultRenderDevice only once. Also tweak the contract with
FFLCommon(), so the callers always pass in a non-null bitmap/canvas.
Change-Id: I12c70a933f8eeb60c7afae1973bcc9614681730c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/123011
Reviewed-by: Tom Sepez <tsepez@google.com>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_formfill.cpp b/fpdfsdk/fpdf_formfill.cpp
index 7d741d0..9b8ee18 100644
--- a/fpdfsdk/fpdf_formfill.cpp
+++ b/fpdfsdk/fpdf_formfill.cpp
@@ -28,6 +28,7 @@
#include "fpdfsdk/cpdfsdk_interactiveform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "public/fpdfview.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
#ifdef PDF_ENABLE_XFA
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
@@ -176,22 +177,50 @@
return pFormFillEnv ? pFormFillEnv->GetOrCreatePageView(pPage) : nullptr;
}
+#if defined(PDF_USE_SKIA)
+using BitmapOrCanvas = absl::variant<CFX_DIBitmap*, SkCanvas*>;
+#else
+using BitmapOrCanvas = absl::variant<CFX_DIBitmap*>;
+#endif
+
+// `dest` must be non-null.
void FFLCommon(FPDF_FORMHANDLE hHandle,
- FPDF_BITMAP bitmap,
- FPDF_SKIA_CANVAS canvas,
FPDF_PAGE fpdf_page,
+ BitmapOrCanvas dest,
int start_x,
int start_y,
int size_x,
int size_y,
int rotate,
int flags) {
- if (!hHandle)
+ if (!hHandle) {
return;
+ }
IPDF_Page* pPage = IPDFPageFromFPDFPage(fpdf_page);
- if (!pPage)
+ if (!pPage) {
return;
+ }
+
+ RetainPtr<CFX_DIBitmap> holder;
+#if defined(PDF_USE_SKIA)
+ SkCanvas* canvas = nullptr;
+#endif
+
+ const bool dest_is_bitmap = absl::holds_alternative<CFX_DIBitmap*>(dest);
+ if (dest_is_bitmap) {
+ holder.Reset(absl::get<CFX_DIBitmap*>(dest));
+ CHECK(holder);
+ } else {
+#if defined(PDF_USE_SKIA)
+ if (!CFX_DefaultRenderDevice::UseSkiaRenderer()) {
+ return;
+ }
+
+ canvas = absl::get<SkCanvas*>(dest);
+ CHECK(canvas);
+#endif
+ }
CPDF_Document* pPDFDoc = pPage->GetDocument();
CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, fpdf_page);
@@ -200,17 +229,19 @@
CFX_Matrix matrix = pPage->GetDisplayMatrix(rect, rotate);
auto pDevice = std::make_unique<CFX_DefaultRenderDevice>();
-#if defined(PDF_USE_SKIA)
- SkCanvas* sk_canvas = SkCanvasFromFPDFSkiaCanvas(canvas);
- if (sk_canvas && CFX_DefaultRenderDevice::UseSkiaRenderer()) {
- if (!pDevice->AttachCanvas(*sk_canvas)) {
+ if (dest_is_bitmap) {
+ if (!pDevice->AttachWithRgbByteOrder(holder,
+ !!(flags & FPDF_REVERSE_BYTE_ORDER))) {
return;
}
- }
+ } else {
+#if defined(PDF_USE_SKIA)
+ if (!pDevice->AttachCanvas(*canvas)) {
+ return;
+ }
#endif
+ }
- RetainPtr<CFX_DIBitmap> holder(CFXDIBitmapFromFPDFBitmap(bitmap));
- pDevice->AttachWithRgbByteOrder(holder, !!(flags & FPDF_REVERSE_BYTE_ORDER));
{
CFX_RenderDevice::StateRestorer restorer(pDevice.get());
pDevice->SetClip_Rect(rect);
@@ -696,8 +727,13 @@
int size_y,
int rotate,
int flags) {
- FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y,
- rotate, flags);
+ CFX_DIBitmap* cbitmap = CFXDIBitmapFromFPDFBitmap(bitmap);
+ if (!cbitmap) {
+ return;
+ }
+
+ FFLCommon(hHandle, page, cbitmap, start_x, start_y, size_x, size_y, rotate,
+ flags);
}
#if defined(PDF_USE_SKIA)
@@ -710,10 +746,15 @@
int size_y,
int rotate,
int flags) {
- FFLCommon(hHandle, nullptr, canvas, page, start_x, start_y, size_x, size_y,
- rotate, flags);
+ SkCanvas* sk_canvas = SkCanvasFromFPDFSkiaCanvas(canvas);
+ if (!sk_canvas) {
+ return;
+ }
+
+ FFLCommon(hHandle, page, sk_canvas, start_x, start_y, size_x, size_y, rotate,
+ flags);
}
-#endif
+#endif // defined(PDF_USE_SKIA)
FPDF_EXPORT void FPDF_CALLCONV
FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,