[Skia] Fix issues for printing 24 BPP images
When using `CFX_SkiaDeviceDriver` for rendering to a 24 BPP bitmap, it
creates an internal bitmap buffer for fast processing and saves the
actual output bitmap as `m_pOriginalBitmap`. Keeping both the original
and the internal bitmaps up-to-date is the key to get the correct
printing result.
This CL improves the rendering process in the following ways:
1. For `CFX_SkiaDeviceDriver` only: Add
`CFX_RenderDevice::SyncInternalBitmaps()` method to make the
underlying `m_pDeviceDriver` transfer the rendering result from its
internal buffer to the `CFX_RenderDevice` bitmap. This allows
syncing without destroying the `m_pDeviceDriver`.
2. In `CPDF_DeviceBuffer::OutputToDevice()`, `pBuffer` is used for
creating a `CFX_RenderDevice` already before it got passed into
`GetBackground()` to be painted white. This means the "old"
`CFX_RenderDevice`'s device driver contains an internal buffer
that's out-dated (without the white paint). To keep the existing
`CFX_RenderDevice` buffers fresh, use it as a parameter of
`GetBackground()` and replace `pBuffer` so that its buffer gets
updated and we can avoid creating a new layer of `CFX_RenderDevice`.
Also, removes the pixel tests that are fixed by this CL from the
suppression list.
Bug: chromium:1470768, pdfium:2054
Change-Id: I8442664ae58dc528442b40a8503100f9501f5ea1
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/111431
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Nigi <nigi@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_devicebuffer.cpp b/core/fpdfapi/render/cpdf_devicebuffer.cpp
index b7722f1..5bf308a 100644
--- a/core/fpdfapi/render/cpdf_devicebuffer.cpp
+++ b/core/fpdfapi/render/cpdf_devicebuffer.cpp
@@ -84,7 +84,7 @@
auto pBuffer = pdfium::MakeRetain<CFX_DIBitmap>();
m_pDevice->CreateCompatibleBitmap(pBuffer, m_pBitmap->GetWidth(),
m_pBitmap->GetHeight());
- m_pContext->GetBackground(pBuffer, m_pObject, nullptr, m_Matrix);
+ m_pContext->GetBackground(m_pDevice, m_pObject, nullptr, m_Matrix);
pBuffer->CompositeBitmap(0, 0, pBuffer->GetWidth(), pBuffer->GetHeight(),
m_pBitmap, 0, 0, BlendMode::kNormal, nullptr, false);
m_pDevice->StretchDIBits(pBuffer, m_Rect.left, m_Rect.top, m_Rect.Width(),
diff --git a/core/fpdfapi/render/cpdf_rendercontext.cpp b/core/fpdfapi/render/cpdf_rendercontext.cpp
index 4116840..7589b41 100644
--- a/core/fpdfapi/render/cpdf_rendercontext.cpp
+++ b/core/fpdfapi/render/cpdf_rendercontext.cpp
@@ -21,6 +21,7 @@
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/dib/fx_dib.h"
+#include "third_party/base/check.h"
CPDF_RenderContext::CPDF_RenderContext(
CPDF_Document* pDoc,
@@ -32,15 +33,14 @@
CPDF_RenderContext::~CPDF_RenderContext() = default;
-void CPDF_RenderContext::GetBackground(RetainPtr<CFX_DIBitmap> pBuffer,
+void CPDF_RenderContext::GetBackground(CFX_RenderDevice* pDevice,
const CPDF_PageObject* pObj,
const CPDF_RenderOptions* pOptions,
const CFX_Matrix& mtFinal) {
- CFX_DefaultRenderDevice device;
- device.Attach(std::move(pBuffer));
- device.FillRect(FX_RECT(0, 0, device.GetWidth(), device.GetHeight()),
- 0xffffffff);
- Render(&device, pObj, pOptions, &mtFinal);
+ CHECK(pDevice);
+ pDevice->FillRect(FX_RECT(0, 0, pDevice->GetWidth(), pDevice->GetHeight()),
+ 0xffffffff);
+ Render(pDevice, pObj, pOptions, &mtFinal);
}
void CPDF_RenderContext::AppendLayer(CPDF_PageObjectHolder* pObjectHolder,
diff --git a/core/fpdfapi/render/cpdf_rendercontext.h b/core/fpdfapi/render/cpdf_rendercontext.h
index 383e798..1012e81 100644
--- a/core/fpdfapi/render/cpdf_rendercontext.h
+++ b/core/fpdfapi/render/cpdf_rendercontext.h
@@ -13,7 +13,6 @@
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
-class CFX_DIBitmap;
class CFX_Matrix;
class CFX_RenderDevice;
class CPDF_Dictionary;
@@ -52,7 +51,7 @@
const CPDF_RenderOptions* pOptions,
const CFX_Matrix* pLastMatrix);
- void GetBackground(RetainPtr<CFX_DIBitmap> pBuffer,
+ void GetBackground(CFX_RenderDevice* pDevice,
const CPDF_PageObject* pObj,
const CPDF_RenderOptions* pOptions,
const CFX_Matrix& mtFinal);
diff --git a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
index 26e8b7f..4cba877 100644
--- a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
+++ b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp
@@ -57,8 +57,7 @@
}
m_Matrix.Scale(0.5f, 0.5f);
}
- pContext->GetBackground(m_pBitmapDevice->GetBitmap(), pObj, pOptions,
- m_Matrix);
+ pContext->GetBackground(m_pBitmapDevice.get(), pObj, pOptions, m_Matrix);
return true;
}
@@ -69,6 +68,11 @@
void CPDF_ScaledRenderBuffer::OutputToDevice() {
if (m_pBitmapDevice) {
+#if defined(_SKIA_SUPPORT_)
+ if (!m_pBitmapDevice->SyncInternalBitmaps()) {
+ return;
+ }
+#endif
m_pDevice->StretchDIBits(m_pBitmapDevice->GetBitmap(), m_Rect.left,
m_Rect.top, m_Rect.Width(), m_Rect.Height());
}
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index 2280f6f..93c3306 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -1002,6 +1002,10 @@
return m_pDeviceDriver->SetBitsWithMask(pBitmap, pMask, left, top,
bitmap_alpha, blend_type);
}
+
+bool CFX_RenderDevice::SyncInternalBitmaps() {
+ return m_pDeviceDriver->SyncInternalBitmaps();
+}
#endif
bool CFX_RenderDevice::DrawNormalText(pdfium::span<const TextCharPos> pCharPos,
diff --git a/core/fxge/cfx_renderdevice.h b/core/fxge/cfx_renderdevice.h
index 8e6e380..b7ce809 100644
--- a/core/fxge/cfx_renderdevice.h
+++ b/core/fxge/cfx_renderdevice.h
@@ -221,6 +221,7 @@
int top,
int bitmap_alpha,
BlendMode blend_type);
+ bool SyncInternalBitmaps();
#endif
protected:
diff --git a/core/fxge/renderdevicedriver_iface.cpp b/core/fxge/renderdevicedriver_iface.cpp
index b549ea2..1b97a08 100644
--- a/core/fxge/renderdevicedriver_iface.cpp
+++ b/core/fxge/renderdevicedriver_iface.cpp
@@ -83,4 +83,8 @@
}
void RenderDeviceDriverIface::SetGroupKnockout(bool group_knockout) {}
+
+bool RenderDeviceDriverIface::SyncInternalBitmaps() {
+ return true;
+}
#endif
diff --git a/core/fxge/renderdevicedriver_iface.h b/core/fxge/renderdevicedriver_iface.h
index 09dd93c..4f9690b 100644
--- a/core/fxge/renderdevicedriver_iface.h
+++ b/core/fxge/renderdevicedriver_iface.h
@@ -116,6 +116,11 @@
int bitmap_alpha,
BlendMode blend_type);
virtual void SetGroupKnockout(bool group_knockout);
+
+ // For `CFX_SkiaDeviceDriver` only:
+ // Syncs the current rendering result from the internal buffer to the output
+ // bitmap if such internal buffer exists.
+ virtual bool SyncInternalBitmaps();
#endif
// Multiplies the device by a constant alpha, returning `true` on success.
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index 25d4a1e..6a79272 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -1541,6 +1541,22 @@
m_bGroupKnockout = group_knockout;
}
+bool CFX_SkiaDeviceDriver::SyncInternalBitmaps() {
+ if (!m_pOriginalBitmap) {
+ return true;
+ }
+
+ int width = m_pOriginalBitmap->GetWidth();
+ int height = m_pOriginalBitmap->GetHeight();
+ DCHECK_EQ(width, m_pBitmap->GetWidth());
+ DCHECK_EQ(height, m_pBitmap->GetHeight());
+ DCHECK_EQ(FXDIB_Format::kRgb, m_pOriginalBitmap->GetFormat());
+ m_pOriginalBitmap->TransferBitmap(/*dest_left=*/0, /*dest_top=*/0, width,
+ height, m_pBitmap, /*src_left=*/0,
+ /*src_top=*/0);
+ return true;
+}
+
void CFX_SkiaDeviceDriver::Clear(uint32_t color) {
m_pCanvas->clear(color);
}
diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h
index c66ceb8..29d699b 100644
--- a/core/fxge/skia/fx_skia_device.h
+++ b/core/fxge/skia/fx_skia_device.h
@@ -108,6 +108,7 @@
int bitmap_alpha,
BlendMode blend_type) override;
void SetGroupKnockout(bool group_knockout) override;
+ bool SyncInternalBitmaps() override;
bool StretchDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
uint32_t color,
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS
index 377aef5..51eefa4 100644
--- a/testing/SUPPRESSIONS
+++ b/testing/SUPPRESSIONS
@@ -704,21 +704,12 @@
# GDI
# TODO(pdfium:2054): Remove after associated bug is fixed
-bug_1012369.in * * * gdi
bug_1258968.in * * * gdi
bug_1383708.in * * * gdi
-bug_1469.in * * * gdi
-bug_1693.in * * * gdi
-bug_1733.in * * * gdi
-bug_1750.in * * * gdi
-bug_512557.pdf * * * gdi
-bug_71.in * * * gdi
bug_718762.in * * * gdi
-bug_867501.pdf * * * gdi
bug_966263.in * * * gdi
bug_986108.in * * * gdi
image_transformer_other.in * * * gdi
-jpxdecode_without_smaskindata.in * * * gdi
# TODO(pdfium:2055): Remove after associated bug is fixed
barcode_test.pdf * * * gdi
@@ -761,7 +752,6 @@
# TODO(pdfium:2056): Remove after associated bug is fixed
bug_1015233.in * * * gdi
-bug_1087.pdf * * * gdi
bug_1099446.in * * * gdi
bug_1161.in * * * gdi
bug_1236.in * * * gdi
@@ -771,13 +761,11 @@
bug_1396266.in * * * gdi
bug_1430333.in * * * gdi
bug_1822.in * * * gdi
-bug_1845.in * * * gdi
bug_1847.in * * * gdi
bug_1949.in * * * gdi
bug_1966.in * * * gdi
bug_1972_1.in * * * gdi
bug_1972_3.in * * * gdi
-bug_1976.in * * * gdi
bug_1995.in * * * gdi
bug_451366.in * * * gdi
bug_632.in * * * gdi