Avoid applying alpha multiple times
An initial alpha was introduced in [1] to correctly render
the transparency of embedded images. However, this change
caused alpha to be applied multiple times when group transparency
is set.
This patch avoids applying the initial alpha when rendering objects
within a transparency group.
[1] https://pdfium-review.googlesource.com/c/pdfium/+/118830
Bug: 346598551
Change-Id: I76ae8ab17e0e5e0531e69f5867822e649c150e17
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/121650
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@google.com>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@google.com>
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 18da44b..e1f5ff0 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -347,6 +347,7 @@
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();
@@ -368,6 +369,7 @@
status.SetTransparency(m_Transparency);
status.SetDropObjects(m_bDropObjects);
status.SetFormResource(std::move(pResources));
+ status.SetInGroup(m_bInGroup);
status.Initialize(this, &pFormObj->graphic_states());
status.m_curBlend = m_curBlend;
{
@@ -585,6 +587,7 @@
}
RetainPtr<const CPDF_Dictionary> pFormResource;
float group_alpha = 1.0f;
+ float initial_alpha = 1.0f;
CPDF_Transparency transparency = m_Transparency;
bool bGroupTransparent = false;
const CPDF_FormObject* pFormObj = pPageObj->AsForm();
@@ -593,13 +596,14 @@
transparency = pFormObj->form()->GetTransparency();
bGroupTransparent = transparency.IsIsolated();
pFormResource = pFormObj->form()->GetDict()->GetDictFor("Resources");
+ initial_alpha = m_InitialStates.general_state().GetFillAlpha();
}
bool bTextClip =
(pPageObj->clip_path().HasRef() &&
pPageObj->clip_path().GetTextCount() > 0 && !m_bPrint &&
!(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP));
if (!pSMaskDict && group_alpha == 1.0f && blend_type == BlendMode::kNormal &&
- !bTextClip && !bGroupTransparent) {
+ !bTextClip && !bGroupTransparent && initial_alpha == 1.0f) {
return false;
}
if (m_bPrint) {
@@ -670,6 +674,7 @@
bitmap_render.SetStdCS(true);
bitmap_render.SetDropObjects(m_bDropObjects);
bitmap_render.SetFormResource(std::move(pFormResource));
+ bitmap_render.SetInGroup(transparency.IsGroup());
bitmap_render.Initialize(nullptr, nullptr);
bitmap_render.ProcessObjectNoClip(pPageObj, new_matrix);
#if defined(PDF_USE_SKIA)
@@ -695,6 +700,9 @@
if (transparency.IsGroup()) {
bitmap_device.MultiplyAlpha(group_alpha);
}
+ if (initial_alpha != 1.0f && !m_bInGroup) {
+ bitmap_device.MultiplyAlpha(initial_alpha);
+ }
transparency = m_Transparency;
if (pPageObj->IsForm()) {
transparency.SetGroup();
diff --git a/core/fpdfapi/render/cpdf_renderstatus.h b/core/fpdfapi/render/cpdf_renderstatus.h
index 3dc9df1..8331b4a 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.h
+++ b/core/fpdfapi/render/cpdf_renderstatus.h
@@ -65,6 +65,7 @@
void SetTransparency(const CPDF_Transparency& transparency) {
m_Transparency = transparency;
}
+ void SetInGroup(bool bInGroup) { m_bInGroup = bInGroup; }
void Initialize(const CPDF_RenderStatus* pParentStatus,
const CPDF_GraphicStates* pInitialStates);
@@ -200,6 +201,7 @@
bool m_bDropObjects = false;
bool m_bStdCS = false;
bool m_bLoadMask = false;
+ bool m_bInGroup = false;
CPDF_ColorSpace::Family m_GroupFamily = CPDF_ColorSpace::Family::kUnknown;
FX_ARGB m_T3FillColor = 0;
BlendMode m_curBlend = BlendMode::kNormal;
diff --git a/core/fpdfapi/render/cpdf_rendertiling.cpp b/core/fpdfapi/render/cpdf_rendertiling.cpp
index cd906cd..a08f095 100644
--- a/core/fpdfapi/render/cpdf_rendertiling.cpp
+++ b/core/fpdfapi/render/cpdf_rendertiling.cpp
@@ -125,6 +125,10 @@
if (!pPattern->colored()) {
pStates = CPDF_RenderStatus::CloneObjStates(&pPageObj->graphic_states(),
bStroke);
+ } else if (pPageObj->AsPath()) {
+ pStates = std::make_unique<CPDF_GraphicStates>();
+ pStates->SetDefaultStates();
+ pStates->mutable_general_state().SetFillAlpha(pPageObj->general_state().GetFillAlpha());
}
RetainPtr<const CPDF_Dictionary> pFormResource =
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS
index 1d66c26..69c0113 100644
--- a/testing/SUPPRESSIONS
+++ b/testing/SUPPRESSIONS
@@ -659,9 +659,6 @@
# TODO(pdfium:2001): Remove after associated bug is fixed
bug_2001.pdf * * * *
-# TODO(crbug.com/42271122): Remove after associated bug is fixed
-bug_2106.in * * * *
-
# TODO(chromium:237527): Remove after associated bug is fixed
bug_237527_1.in * * * *