Return failure/unsupported in RenderDeviceDriverIface::StartDIBits()
Currently, StartDIBits() returns false to mean failure, but failure can
either be "something went wrong" or "operation not supported". Change
the bool return value to a Result enum to tell these two cases apart.
Then change CPDF_ImageRenderer::StartDIBBase() to return when something
goes wrong, and only use the fallback code in the not supported case.
Change-Id: I209bbd8e5d974ebd5ad485f2a706c59486730df0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/122595
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/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp
index bf9891c..56c71a2 100644
--- a/core/fpdfapi/render/cpdf_imagerenderer.cpp
+++ b/core/fpdfapi/render/cpdf_imagerenderer.cpp
@@ -423,7 +423,7 @@
m_pRenderStatus->GetRenderDevice()->StartDIBitsWithBlend(
m_pDIBBase, m_Alpha, m_FillArgb, m_ImageMatrix, m_ResampleOptions,
m_BlendType);
- if (result.success) {
+ if (result.result == RenderDeviceDriverIface::Result::kSuccess) {
m_DeviceHandle = std::move(result.agg_image_renderer);
if (m_DeviceHandle) {
m_Mode = Mode::kBlend;
@@ -432,6 +432,12 @@
return false;
}
+ if (result.result == RenderDeviceDriverIface::Result::kFailure) {
+ m_Result = false;
+ return false;
+ }
+
+ CHECK_EQ(result.result, RenderDeviceDriverIface::Result::kNotSupported);
if ((fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
(fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) {
#if BUILDFLAG(IS_WIN)
diff --git a/core/fxge/agg/cfx_agg_devicedriver.cpp b/core/fxge/agg/cfx_agg_devicedriver.cpp
index a847ddb..06b1fd1 100644
--- a/core/fxge/agg/cfx_agg_devicedriver.cpp
+++ b/core/fxge/agg/cfx_agg_devicedriver.cpp
@@ -1433,12 +1433,12 @@
const FXDIB_ResampleOptions& options,
BlendMode blend_type) {
if (m_pBitmap->GetBuffer().empty()) {
- return {true, nullptr};
+ return {Result::kSuccess, nullptr};
}
- return {true, std::make_unique<CFX_AggImageRenderer>(
- m_pBitmap, m_pClipRgn.get(), std::move(bitmap), alpha, argb,
- matrix, options, m_bRgbByteOrder)};
+ return {Result::kSuccess, std::make_unique<CFX_AggImageRenderer>(
+ m_pBitmap, m_pClipRgn.get(), std::move(bitmap),
+ alpha, argb, matrix, options, m_bRgbByteOrder)};
}
bool CFX_AggDeviceDriver::ContinueDIBits(CFX_AggImageRenderer* pHandle,
diff --git a/core/fxge/renderdevicedriver_iface.cpp b/core/fxge/renderdevicedriver_iface.cpp
index b637735..f5a59db 100644
--- a/core/fxge/renderdevicedriver_iface.cpp
+++ b/core/fxge/renderdevicedriver_iface.cpp
@@ -92,8 +92,8 @@
#endif // defined(PDF_USE_SKIA)
RenderDeviceDriverIface::StartResult::StartResult(
- bool success,
+ Result result,
std::unique_ptr<CFX_AggImageRenderer> agg_image_renderer)
- : success(success), agg_image_renderer(std::move(agg_image_renderer)) {}
+ : result(result), agg_image_renderer(std::move(agg_image_renderer)) {}
RenderDeviceDriverIface::StartResult::~StartResult() = default;
diff --git a/core/fxge/renderdevicedriver_iface.h b/core/fxge/renderdevicedriver_iface.h
index d19f6b8..ee4f4bf 100644
--- a/core/fxge/renderdevicedriver_iface.h
+++ b/core/fxge/renderdevicedriver_iface.h
@@ -40,12 +40,14 @@
class RenderDeviceDriverIface {
public:
+ enum class Result { kFailure, kSuccess, kNotSupported };
+
struct StartResult {
- StartResult(bool success,
+ StartResult(Result result,
std::unique_ptr<CFX_AggImageRenderer> agg_image_renderer);
~StartResult();
- const bool success;
+ const Result result;
std::unique_ptr<CFX_AggImageRenderer> agg_image_renderer;
};
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index d9a2379..a1bb41b 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -1450,9 +1450,9 @@
const FXDIB_ResampleOptions& options,
BlendMode blend_type) {
FX_RECT rect(0, 0, bitmap->GetWidth(), bitmap->GetHeight());
- return {StartDIBitsSkia(std::move(bitmap), rect, alpha, color, matrix,
- options, blend_type),
- nullptr};
+ bool success = StartDIBitsSkia(std::move(bitmap), rect, alpha, color, matrix,
+ options, blend_type);
+ return {success ? Result::kSuccess : Result::kFailure, nullptr};
}
void CFX_DIBitmap::UnPreMultiply() {
diff --git a/core/fxge/win32/cgdi_display_driver.cpp b/core/fxge/win32/cgdi_display_driver.cpp
index f5aefcb..ad4a090 100644
--- a/core/fxge/win32/cgdi_display_driver.cpp
+++ b/core/fxge/win32/cgdi_display_driver.cpp
@@ -222,5 +222,5 @@
const CFX_Matrix& matrix,
const FXDIB_ResampleOptions& options,
BlendMode blend_type) {
- return {false, nullptr};
+ return {Result::kNotSupported, nullptr};
}
diff --git a/core/fxge/win32/cgdi_printer_driver.cpp b/core/fxge/win32/cgdi_printer_driver.cpp
index 8918a56..7281bc5 100644
--- a/core/fxge/win32/cgdi_printer_driver.cpp
+++ b/core/fxge/win32/cgdi_printer_driver.cpp
@@ -132,7 +132,7 @@
BlendMode blend_type) {
if (alpha != 1.0f || bitmap->IsAlphaFormat() ||
(bitmap->IsMaskFormat() && (bitmap->GetBPP() != 1))) {
- return {false, nullptr};
+ return {Result::kNotSupported, nullptr};
}
CFX_FloatRect unit_rect = matrix.GetUnitRect();
FX_RECT full_rect = unit_rect.GetOuterRect();
@@ -140,29 +140,30 @@
matrix.d != 0) {
bool bFlipX = matrix.a < 0;
bool bFlipY = matrix.d > 0;
- return {StretchDIBits(std::move(bitmap), color,
- bFlipX ? full_rect.right : full_rect.left,
- bFlipY ? full_rect.bottom : full_rect.top,
- bFlipX ? -full_rect.Width() : full_rect.Width(),
- bFlipY ? -full_rect.Height() : full_rect.Height(),
- nullptr, FXDIB_ResampleOptions(), blend_type),
- nullptr};
+ bool success = StretchDIBits(
+ std::move(bitmap), color, bFlipX ? full_rect.right : full_rect.left,
+ bFlipY ? full_rect.bottom : full_rect.top,
+ bFlipX ? -full_rect.Width() : full_rect.Width(),
+ bFlipY ? -full_rect.Height() : full_rect.Height(), nullptr,
+ FXDIB_ResampleOptions(), blend_type);
+ return {success ? Result::kSuccess : Result::kFailure, nullptr};
}
if (fabs(matrix.a) >= 0.5f || fabs(matrix.d) >= 0.5f) {
- return {false, nullptr};
+ return {Result::kNotSupported, nullptr};
}
const bool flip_x = matrix.c > 0;
const bool flip_y = matrix.b < 0;
bitmap = bitmap->SwapXY(flip_x, flip_y);
if (!bitmap) {
- return {false, nullptr};
+ return {Result::kFailure, nullptr};
}
- return {StretchDIBits(std::move(bitmap), color, full_rect.left, full_rect.top,
- full_rect.Width(), full_rect.Height(), nullptr,
- FXDIB_ResampleOptions(), blend_type),
- nullptr};
+ bool success =
+ StretchDIBits(std::move(bitmap), color, full_rect.left, full_rect.top,
+ full_rect.Width(), full_rect.Height(), nullptr,
+ FXDIB_ResampleOptions(), blend_type);
+ return {success ? Result::kSuccess : Result::kFailure, nullptr};
}
bool CGdiPrinterDriver::DrawDeviceText(
diff --git a/core/fxge/win32/cps_printer_driver.cpp b/core/fxge/win32/cps_printer_driver.cpp
index f7c121a..fd6b3cc 100644
--- a/core/fxge/win32/cps_printer_driver.cpp
+++ b/core/fxge/win32/cps_printer_driver.cpp
@@ -191,11 +191,12 @@
const FXDIB_ResampleOptions& options,
BlendMode blend_type) {
if (blend_type != BlendMode::kNormal || alpha != 1.0f) {
- return {false, nullptr};
+ return {Result::kNotSupported, nullptr};
}
- return {m_PSRenderer.DrawDIBits(std::move(bitmap), color, matrix, options),
- nullptr};
+ bool success =
+ m_PSRenderer.DrawDIBits(std::move(bitmap), color, matrix, options);
+ return {success ? Result::kSuccess : Result::kFailure, nullptr};
}
bool CPSPrinterDriver::DrawDeviceText(
diff --git a/core/fxge/win32/ctext_only_printer_driver.cpp b/core/fxge/win32/ctext_only_printer_driver.cpp
index 8f20bd7..1b5b361 100644
--- a/core/fxge/win32/ctext_only_printer_driver.cpp
+++ b/core/fxge/win32/ctext_only_printer_driver.cpp
@@ -117,7 +117,7 @@
const CFX_Matrix& matrix,
const FXDIB_ResampleOptions& options,
BlendMode blend_type) {
- return {false, nullptr};
+ return {Result::kNotSupported, nullptr};
}
bool CTextOnlyPrinterDriver::DrawDeviceText(
diff --git a/xfa/fxfa/cxfa_imagerenderer.cpp b/xfa/fxfa/cxfa_imagerenderer.cpp
index 575f1a9..b78764c 100644
--- a/xfa/fxfa/cxfa_imagerenderer.cpp
+++ b/xfa/fxfa/cxfa_imagerenderer.cpp
@@ -33,10 +33,11 @@
options.bInterpolateBilinear = true;
RenderDeviceDriverIface::StartResult result = m_pDevice->StartDIBits(
m_pBitmap, /*alpha=*/1.0f, /*argb=*/0, m_ImageMatrix, options);
- if (!result.success) {
+ if (result.result == RenderDeviceDriverIface::Result::kFailure) {
return false;
}
+ CHECK_EQ(result.result, RenderDeviceDriverIface::Result::kSuccess);
m_DeviceHandle = std::move(result.agg_image_renderer);
if (!m_DeviceHandle) {
return false;