From 3d1ab2d09ab96a6393c0612d9c4153d10d5028ce Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Thu, 10 May 2018 18:07:35 +0000 Subject: Add CPDF_Transparency. Encapsulates transparency status instead of having it be a raw int. Change-Id: I8b10dafa97da112795cf84c46cf416a0294551d5 Reviewed-on: https://pdfium-review.googlesource.com/32194 Commit-Queue: Lei Zhang Reviewed-by: dsinclair --- BUILD.gn | 2 ++ core/fpdfapi/page/cpdf_contentparser.cpp | 2 +- core/fpdfapi/page/cpdf_form.cpp | 2 +- core/fpdfapi/page/cpdf_page.cpp | 3 +- core/fpdfapi/page/cpdf_pageobjectholder.cpp | 4 +-- core/fpdfapi/page/cpdf_pageobjectholder.h | 8 ++--- core/fpdfapi/render/cpdf_imagerenderer.cpp | 16 +++++----- core/fpdfapi/render/cpdf_renderstatus.cpp | 47 ++++++++++++++--------------- core/fpdfapi/render/cpdf_renderstatus.h | 7 +++-- core/fpdfapi/render/cpdf_transparency.cpp | 9 ++++++ core/fpdfapi/render/cpdf_transparency.h | 25 +++++++++++++++ fpdfsdk/fpdf_editpage.cpp | 4 +-- 12 files changed, 83 insertions(+), 46 deletions(-) create mode 100644 core/fpdfapi/render/cpdf_transparency.cpp create mode 100644 core/fpdfapi/render/cpdf_transparency.h diff --git a/BUILD.gn b/BUILD.gn index 8be7f1658d..c1e127010f 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -679,6 +679,8 @@ jumbo_static_library("fpdfapi") { "core/fpdfapi/render/cpdf_textrenderer.h", "core/fpdfapi/render/cpdf_transferfunc.cpp", "core/fpdfapi/render/cpdf_transferfunc.h", + "core/fpdfapi/render/cpdf_transparency.cpp", + "core/fpdfapi/render/cpdf_transparency.h", "core/fpdfapi/render/cpdf_type3cache.cpp", "core/fpdfapi/render/cpdf_type3cache.h", "core/fpdfapi/render/cpdf_type3glyphs.cpp", diff --git a/core/fpdfapi/page/cpdf_contentparser.cpp b/core/fpdfapi/page/cpdf_contentparser.cpp index f558ac823a..26fd0189f8 100644 --- a/core/fpdfapi/page/cpdf_contentparser.cpp +++ b/core/fpdfapi/page/cpdf_contentparser.cpp @@ -93,7 +93,7 @@ CPDF_ContentParser::CPDF_ContentParser(CPDF_Form* pForm, m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, true); } - if (pForm->GetTransparency() & PDFTRANS_GROUP) { + if (pForm->GetTransparency().IsGroup()) { CPDF_GeneralState* pState = &m_pParser->GetCurStates()->m_GeneralState; pState->SetBlendType(FXDIB_BLEND_NORMAL); pState->SetStrokeAlpha(1.0f); diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp index bb06cbfe6f..3abeff4829 100644 --- a/core/fpdfapi/page/cpdf_form.cpp +++ b/core/fpdfapi/page/cpdf_form.cpp @@ -25,7 +25,7 @@ CPDF_Form::CPDF_Form(CPDF_Document* pDoc, m_pResources = pParentResources; if (!m_pResources) m_pResources = pPageResources; - m_iTransparency = 0; + m_Transparency = CPDF_Transparency(); LoadTransInfo(); } diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp index eee6673650..7c0a3234c9 100644 --- a/core/fpdfapi/page/cpdf_page.cpp +++ b/core/fpdfapi/page/cpdf_page.cpp @@ -67,7 +67,8 @@ CPDF_Page::CPDF_Page(CPDF_Document* pDocument, break; } - m_iTransparency = PDFTRANS_ISOLATED; + m_Transparency = CPDF_Transparency(); + m_Transparency.SetIsolated(); LoadTransInfo(); } diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.cpp b/core/fpdfapi/page/cpdf_pageobjectholder.cpp index d8858279ca..1d39802658 100644 --- a/core/fpdfapi/page/cpdf_pageobjectholder.cpp +++ b/core/fpdfapi/page/cpdf_pageobjectholder.cpp @@ -81,9 +81,9 @@ void CPDF_PageObjectHolder::LoadTransInfo() { pdfium::transparency::kTransparency) { return; } - m_iTransparency |= PDFTRANS_GROUP; + m_Transparency.SetGroup(); if (pGroup->GetIntegerFor(pdfium::transparency::kI)) - m_iTransparency |= PDFTRANS_ISOLATED; + m_Transparency.SetIsolated(); } size_t CPDF_PageObjectHolder::GetPageObjectCount() const { diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.h b/core/fpdfapi/page/cpdf_pageobjectholder.h index dc1a607cf0..61004444c0 100644 --- a/core/fpdfapi/page/cpdf_pageobjectholder.h +++ b/core/fpdfapi/page/cpdf_pageobjectholder.h @@ -12,6 +12,7 @@ #include #include "core/fpdfapi/page/cpdf_pageobjectlist.h" +#include "core/fpdfapi/render/cpdf_transparency.h" #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" @@ -23,9 +24,6 @@ class CPDF_Document; class CPDF_Stream; class PauseIndicatorIface; -#define PDFTRANS_GROUP 0x0100 -#define PDFTRANS_ISOLATED 0x0200 - // These structs are used to keep track of resources that have already been // generated in the page object holder. struct GraphicsData { @@ -72,7 +70,7 @@ class CPDF_PageObjectHolder { const CFX_Matrix& GetLastCTM() const { return m_LastCTM; } const CFX_FloatRect& GetBBox() const { return m_BBox; } - int GetTransparency() const { return m_iTransparency; } + const CPDF_Transparency& GetTransparency() const { return m_Transparency; } bool BackgroundAlphaNeeded() const { return m_bBackgroundAlphaNeeded; } void SetBackgroundAlphaNeeded(bool needed) { m_bBackgroundAlphaNeeded = needed; @@ -101,7 +99,7 @@ class CPDF_PageObjectHolder { const UnownedPtr m_pFormDict; UnownedPtr m_pDocument; CFX_FloatRect m_BBox; - int m_iTransparency = 0; + CPDF_Transparency m_Transparency; bool m_bBackgroundAlphaNeeded = false; std::vector m_MaskBoundingBoxes; ParseState m_ParseState = CONTENT_NOT_PARSED; diff --git a/core/fpdfapi/render/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp index e9e6420632..a5e2e27a25 100644 --- a/core/fpdfapi/render/cpdf_imagerenderer.cpp +++ b/core/fpdfapi/render/cpdf_imagerenderer.cpp @@ -233,7 +233,8 @@ void CPDF_ImageRenderer::CalculateDrawImage( const FX_RECT& rect) const { CPDF_RenderStatus bitmap_render; bitmap_render.Initialize(m_pRenderStatus->GetContext(), pBitmapDevice2, - nullptr, nullptr, nullptr, nullptr, nullptr, 0, + nullptr, nullptr, nullptr, nullptr, nullptr, + CPDF_Transparency(), m_pRenderStatus->GetDropObjects(), nullptr, true); CPDF_ImageRenderer image_render; if (image_render.Start(&bitmap_render, pDIBSource, 0xffffffff, 255, @@ -283,10 +284,10 @@ bool CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) { bitmap_device1.GetBitmap()->Clear(0xffffff); CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pRenderStatus->GetContext(), &bitmap_device1, - nullptr, nullptr, nullptr, nullptr, - m_pRenderStatus->GetRenderOptions(), 0, - m_pRenderStatus->GetDropObjects(), nullptr, true); + bitmap_render.Initialize( + m_pRenderStatus->GetContext(), &bitmap_device1, nullptr, nullptr, nullptr, + nullptr, m_pRenderStatus->GetRenderOptions(), CPDF_Transparency(), + m_pRenderStatus->GetDropObjects(), nullptr, true); CFX_Matrix patternDevice = *pObj2Device; patternDevice.Translate(static_cast(-rect.left), static_cast(-rect.top)); @@ -337,7 +338,8 @@ bool CPDF_ImageRenderer::DrawMaskedImage() { #endif CPDF_RenderStatus bitmap_render; bitmap_render.Initialize(m_pRenderStatus->GetContext(), &bitmap_device1, - nullptr, nullptr, nullptr, nullptr, nullptr, 0, + nullptr, nullptr, nullptr, nullptr, nullptr, + CPDF_Transparency(), m_pRenderStatus->GetDropObjects(), nullptr, true); CPDF_ImageRenderer image_render; if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix, @@ -467,7 +469,7 @@ bool CPDF_ImageRenderer::StartDIBSource() { if (pStretched) { m_pRenderStatus->CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb, m_BitmapAlpha, - m_BlendType, false); + m_BlendType, CPDF_Transparency()); } return false; } diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 565be85412..6752fd1250 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -1017,7 +1017,7 @@ bool CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext, const CPDF_RenderStatus* pParentState, const CPDF_GraphicStates* pInitialStates, const CPDF_RenderOptions* pOptions, - int transparency, + const CPDF_Transparency& transparency, bool bDropObjects, const CPDF_Dictionary* pFormResource, bool bStdCS, @@ -1063,7 +1063,7 @@ bool CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext, m_InitialStates.DefaultStates(); } m_pImageRenderer.reset(); - m_iTransparency = transparency; + m_Transparency = transparency; return true; } @@ -1241,7 +1241,7 @@ void CPDF_RenderStatus::DrawObjWithBackground(CPDF_PageObject* pObj, } CPDF_RenderStatus status; status.Initialize(m_pContext.Get(), buffer.GetDevice(), buffer.GetMatrix(), - nullptr, nullptr, nullptr, &m_Options, m_iTransparency, + nullptr, nullptr, nullptr, &m_Options, m_Transparency, m_bDropObjects, pFormResource); status.RenderSingleObject(pObj, &matrix); buffer.OutputToDevice(); @@ -1265,7 +1265,7 @@ bool CPDF_RenderStatus::ProcessForm(const CPDF_FormObject* pFormObj, pFormDict ? pFormDict->GetDictFor("Resources") : nullptr; CPDF_RenderStatus status; status.Initialize(m_pContext.Get(), m_pDevice, nullptr, m_pStopObj, this, - pFormObj, &m_Options, m_iTransparency, m_bDropObjects, + pFormObj, &m_Options, m_Transparency, m_bDropObjects, pResources, false); status.m_curBlend = m_curBlend; { @@ -1477,13 +1477,13 @@ bool CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj, } const CPDF_Dictionary* pFormResource = nullptr; float group_alpha = 1.0f; - int iTransparency = m_iTransparency; + CPDF_Transparency transparency = m_Transparency; bool bGroupTransparent = false; const CPDF_FormObject* pFormObj = pPageObj->AsForm(); if (pFormObj) { group_alpha = pFormObj->m_GeneralState.GetFillAlpha(); - iTransparency = pFormObj->form()->GetTransparency(); - bGroupTransparent = !!(iTransparency & PDFTRANS_ISOLATED); + transparency = pFormObj->form()->GetTransparency(); + bGroupTransparent = transparency.IsIsolated(); const CPDF_Dictionary* pFormDict = pFormObj->form()->GetFormDict(); if (pFormDict) pFormResource = pFormDict->GetDictFor("Resources"); @@ -1526,11 +1526,10 @@ bool CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj, !bTextClip && !bGroupTransparent) { return false; } - bool isolated = !!(iTransparency & PDFTRANS_ISOLATED); if (m_bPrint) { bool bRet = false; int rendCaps = m_pDevice->GetRenderCaps(); - if (!((iTransparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) && + if (!(transparency.IsIsolated() || pSMaskDict || bTextClip) && (rendCaps & FXRC_BLEND_MODE)) { int oldBlend = m_curBlend; m_curBlend = blend_type; @@ -1551,7 +1550,8 @@ bool CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj, int height = rect.Height(); CFX_DefaultRenderDevice bitmap_device; RetainPtr oriDevice; - if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) { + if (!transparency.IsIsolated() && + (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) { oriDevice = pdfium::MakeRetain(); if (!m_pDevice->CreateCompatibleBitmap(oriDevice, width, height)) return true; @@ -1589,9 +1589,9 @@ bool CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj, } } CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pContext.Get(), &bitmap_device, nullptr, - m_pStopObj, nullptr, nullptr, &m_Options, 0, - m_bDropObjects, pFormResource, true); + bitmap_render.Initialize( + m_pContext.Get(), &bitmap_device, nullptr, m_pStopObj, nullptr, nullptr, + &m_Options, CPDF_Transparency(), m_bDropObjects, pFormResource, true); bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix); #if defined _SKIA_SUPPORT_PATHS_ bitmap_device.Flush(true); @@ -1611,19 +1611,19 @@ bool CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj, pTextMask.Reset(); } int32_t blitAlpha = 255; - if (iTransparency & PDFTRANS_GROUP && group_alpha != 1.0f) { + if (group_alpha != 1.0f && transparency.IsGroup()) { blitAlpha = (int32_t)(group_alpha * 255); #ifndef _SKIA_SUPPORT_ bitmap->MultiplyAlpha(blitAlpha); blitAlpha = 255; #endif } - iTransparency = m_iTransparency; + transparency = m_Transparency; if (pPageObj->IsForm()) { - iTransparency |= PDFTRANS_GROUP; + transparency.SetGroup(); } CompositeDIBitmap(bitmap, rect.left, rect.top, 0, blitAlpha, blend_type, - iTransparency); + transparency); #if defined _SKIA_SUPPORT_ DebugVerifyDeviceIsPreMultiplied(); #endif @@ -2358,7 +2358,7 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, } } CompositeDIBitmap(pScreen, clip_box.left, clip_box.top, 0, 255, - FXDIB_BLEND_NORMAL, false); + FXDIB_BLEND_NORMAL, CPDF_Transparency()); } void CPDF_RenderStatus::DrawPathWithPattern(CPDF_PathObject* pPathObj, @@ -2413,7 +2413,7 @@ void CPDF_RenderStatus::CompositeDIBitmap( FX_ARGB mask_argb, int bitmap_alpha, int blend_mode, - int iTransparency) { + const CPDF_Transparency& transparency) { if (!pDIBitmap) return; @@ -2447,15 +2447,14 @@ void CPDF_RenderStatus::CompositeDIBitmap( } } } - bool bIsolated = !!(iTransparency & PDFTRANS_ISOLATED); - bool bGroup = !!(iTransparency & PDFTRANS_GROUP); + bool bIsolated = transparency.IsIsolated(); bool bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects; bool bGetBackGround = ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) || (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired); if (bGetBackGround) { - if (bIsolated || !bGroup) { + if (bIsolated || !transparency.IsGroup()) { if (!pDIBitmap->IsAlphaMask()) m_pDevice->SetDIBitsWithBlend(pDIBitmap, left, top, blend_mode); return; @@ -2583,8 +2582,8 @@ RetainPtr CPDF_RenderStatus::LoadSMask( : CPDF_RenderOptions::kAlpha); CPDF_RenderStatus status; status.Initialize(m_pContext.Get(), &bitmap_device, nullptr, nullptr, nullptr, - nullptr, &options, 0, m_bDropObjects, pFormResource, true, - nullptr, 0, nCSFamily, bLuminosity); + nullptr, &options, CPDF_Transparency(), m_bDropObjects, + pFormResource, true, nullptr, 0, nCSFamily, bLuminosity); status.RenderObjectList(&form, &matrix); auto pMask = pdfium::MakeRetain(); diff --git a/core/fpdfapi/render/cpdf_renderstatus.h b/core/fpdfapi/render/cpdf_renderstatus.h index 5618196ce6..19d613c02e 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.h +++ b/core/fpdfapi/render/cpdf_renderstatus.h @@ -12,6 +12,7 @@ #include "core/fpdfapi/page/cpdf_clippath.h" #include "core/fpdfapi/page/cpdf_graphicstates.h" +#include "core/fpdfapi/page/cpdf_pageobjectholder.h" #include "core/fpdfapi/render/cpdf_renderoptions.h" #include "core/fxcrt/unowned_ptr.h" #include "core/fxge/cfx_renderdevice.h" @@ -48,7 +49,7 @@ class CPDF_RenderStatus { const CPDF_RenderStatus* pParentStatus, const CPDF_GraphicStates* pInitialStates, const CPDF_RenderOptions* pOptions, - int transparency, + const CPDF_Transparency& transparency, bool bDropObjects, const CPDF_Dictionary* pFormResource = nullptr, bool bStdCS = false, @@ -99,7 +100,7 @@ class CPDF_RenderStatus { FX_ARGB mask_argb, int bitmap_alpha, int blend_mode, - int iTransparency); + const CPDF_Transparency& transparency); private: bool ProcessTransparency(CPDF_PageObject* PageObj, @@ -177,7 +178,7 @@ class CPDF_RenderStatus { CPDF_GraphicStates m_InitialStates; std::unique_ptr m_pImageRenderer; bool m_bPrint = false; - int m_iTransparency = 0; + CPDF_Transparency m_Transparency; bool m_bDropObjects = false; bool m_bStdCS = false; uint32_t m_GroupFamily = 0; diff --git a/core/fpdfapi/render/cpdf_transparency.cpp b/core/fpdfapi/render/cpdf_transparency.cpp new file mode 100644 index 0000000000..b85da3dae0 --- /dev/null +++ b/core/fpdfapi/render/cpdf_transparency.cpp @@ -0,0 +1,9 @@ +// Copyright 2018 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/fpdfapi/render/cpdf_transparency.h" + +CPDF_Transparency::CPDF_Transparency() = default; + +CPDF_Transparency::CPDF_Transparency(const CPDF_Transparency& other) = default; diff --git a/core/fpdfapi/render/cpdf_transparency.h b/core/fpdfapi/render/cpdf_transparency.h new file mode 100644 index 0000000000..92f7c83b73 --- /dev/null +++ b/core/fpdfapi/render/cpdf_transparency.h @@ -0,0 +1,25 @@ +// Copyright 2018 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CORE_FPDFAPI_RENDER_CPDF_TRANSPARENCY_H_ +#define CORE_FPDFAPI_RENDER_CPDF_TRANSPARENCY_H_ + +class CPDF_Transparency { + public: + CPDF_Transparency(); + + CPDF_Transparency(const CPDF_Transparency& other); + + bool IsGroup() const { return m_bGroup; } + bool IsIsolated() const { return m_bIsolated; } + + void SetGroup() { m_bGroup = true; } + void SetIsolated() { m_bIsolated = true; } + + private: + bool m_bGroup = false; + bool m_bIsolated = false; +}; + +#endif // CORE_FPDFAPI_RENDER_CPDF_TRANSPARENCY_H_ diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp index ec29891fdf..1a9198b291 100644 --- a/fpdfsdk/fpdf_editpage.cpp +++ b/fpdfsdk/fpdf_editpage.cpp @@ -393,8 +393,8 @@ FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) { if (pPageObj->IsForm()) { const CPDF_Form* pForm = pPageObj->AsForm()->form(); if (pForm) { - int trans = pForm->GetTransparency(); - if ((trans & PDFTRANS_ISOLATED) || (trans & PDFTRANS_GROUP)) + const CPDF_Transparency& trans = pForm->GetTransparency(); + if (trans.IsGroup() || trans.IsIsolated()) return true; } } -- cgit v1.2.3