CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj, const FX_RECT& rect, int& left, int& top, FX_BOOL bBackAlphaRequired) { FX_RECT bbox = rect; bbox.Intersect(m_pDevice->GetClipBox()); left = bbox.left; top = bbox.top; CFX_Matrix deviceCTM = m_pDevice->GetCTM(); FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a); FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d); int width = FXSYS_round(bbox.Width() * scaleX); int height = FXSYS_round(bbox.Height() * scaleY); std::unique_ptr<CFX_DIBitmap> pBackdrop(new CFX_DIBitmap); if (bBackAlphaRequired && !m_bDropObjects) pBackdrop->Create(width, height, FXDIB_Argb); else m_pDevice->CreateCompatibleBitmap(pBackdrop.get(), width, height); if (!pBackdrop->GetBuffer()) return nullptr; FX_BOOL bNeedDraw; if (pBackdrop->HasAlpha()) bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT); else bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS); if (!bNeedDraw) { m_pDevice->GetDIBits(pBackdrop.get(), left, top); return pBackdrop.release(); } CFX_Matrix FinalMatrix = m_DeviceMatrix; FinalMatrix.TranslateI(-left, -top); FinalMatrix.Scale(scaleX, scaleY); pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff); CFX_FxgeDevice device; device.Attach(pBackdrop.get(), false, nullptr, false); m_pContext->Render(&device, pObj, &m_Options, &FinalMatrix); return pBackdrop.release(); }
void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, int top, FX_ARGB mask_argb, int bitmap_alpha, int blend_mode, int Transparency) { if (pDIBitmap == NULL) { return; } FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED; FX_BOOL bGroup = Transparency & PDFTRANS_GROUP; if (blend_mode == FXDIB_BLEND_NORMAL) { if (!pDIBitmap->IsAlphaMask()) { if (bitmap_alpha < 255) { pDIBitmap->MultiplyAlpha(bitmap_alpha); } if (m_pDevice->SetDIBits(pDIBitmap, left, top)) { return; } } else { FX_DWORD fill_argb = m_Options.TranslateColor(mask_argb); if (bitmap_alpha < 255) { ((uint8_t*)&fill_argb)[3] = ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255; } if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) { return; } } } FX_BOOL bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects; FX_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 (pDIBitmap->IsAlphaMask()) { return; } m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode); } else { FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight()); rect.Intersect(m_pDevice->GetClipBox()); CFX_DIBitmap* pClone = NULL; FX_BOOL bClone = FALSE; if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) { bClone = TRUE; pClone = m_pDevice->GetBackDrop()->Clone(&rect); CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap(); pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pForeBitmap, rect.left, rect.top); left = left >= 0 ? 0 : left; top = top >= 0 ? 0 : top; if (!pDIBitmap->IsAlphaMask()) pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap, left, top, blend_mode); else pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap, mask_argb, left, top, blend_mode); } else { pClone = pDIBitmap; } if (m_pDevice->GetBackDrop()) { m_pDevice->SetDIBits(pClone, rect.left, rect.top); } else { if (pDIBitmap->IsAlphaMask()) { return; } m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode); } if (bClone) { delete pClone; } } return; } int back_left, back_top; FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight()); nonstd::unique_ptr<CFX_DIBitmap> pBackdrop( GetBackdrop(m_pCurObj, rect, back_left, back_top, blend_mode > FXDIB_BLEND_NORMAL && bIsolated)); if (!pBackdrop) return; if (!pDIBitmap->IsAlphaMask()) { pBackdrop->CompositeBitmap(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap, 0, 0, blend_mode); } else { pBackdrop->CompositeMask(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap, mask_argb, 0, 0, blend_mode); } nonstd::unique_ptr<CFX_DIBitmap> pBackdrop1(new CFX_DIBitmap); pBackdrop1->Create(pBackdrop->GetWidth(), pBackdrop->GetHeight(), FXDIB_Rgb32); pBackdrop1->Clear((FX_DWORD)-1); pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(), pBackdrop->GetHeight(), pBackdrop.get(), 0, 0); pBackdrop = nonstd::move(pBackdrop1); m_pDevice->SetDIBits(pBackdrop.get(), back_left, back_top); }