diff options
-rw-r--r-- | core/fpdfapi/page/cpdf_streamcontentparser.cpp | 6 | ||||
-rw-r--r-- | core/fpdfapi/render/cpdf_progressiverenderer.cpp | 21 | ||||
-rw-r--r-- | core/fpdfapi/render/cpdf_renderstatus.cpp | 2 | ||||
-rw-r--r-- | core/fpdfapi/render/cpdf_renderstatus.h | 3 | ||||
-rw-r--r-- | fpdfsdk/fpdfview.cpp | 16 |
5 files changed, 32 insertions, 16 deletions
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp index 692de0f5eb..1e6bf6c3c8 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp +++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp @@ -658,7 +658,11 @@ void CPDF_StreamContentParser::Handle_BeginImage() { break; } } - AddImage(std::move(pStream)); + CPDF_ImageObject* pObj = AddImage(std::move(pStream)); + // Record the bounding box of this image, so rendering code can draw it + // properly. + if (pObj->GetImage()->IsMask()) + m_pObjectHolder->AddImageMaskBoundingBox(pObj->GetRect()); } void CPDF_StreamContentParser::Handle_BeginMarkedContent() { diff --git a/core/fpdfapi/render/cpdf_progressiverenderer.cpp b/core/fpdfapi/render/cpdf_progressiverenderer.cpp index 4ddc528342..c61902cda7 100644 --- a/core/fpdfapi/render/cpdf_progressiverenderer.cpp +++ b/core/fpdfapi/render/cpdf_progressiverenderer.cpp @@ -72,12 +72,23 @@ void CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause) { iter = m_pCurrentLayer->m_pObjectHolder->GetPageObjectList()->begin(); } int nObjsToGo = kStepLimit; + bool is_mask = false; while (iter != iterEnd) { CPDF_PageObject* pCurObj = iter->get(); if (pCurObj && pCurObj->m_Left <= m_ClipRect.right && pCurObj->m_Right >= m_ClipRect.left && pCurObj->m_Bottom <= m_ClipRect.top && pCurObj->m_Top >= m_ClipRect.bottom) { + if (m_pOptions->m_Flags & RENDER_BREAKFORMASKS && pCurObj->IsImage() && + pCurObj->AsImage()->GetImage()->IsMask()) { + if (m_pDevice->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) { + m_LastObjectRendered = iter; + m_pRenderStatus->ProcessClipPath(pCurObj->m_ClipPath, + &m_pCurrentLayer->m_Matrix); + return; + } + is_mask = true; + } if (m_pRenderStatus->ContinueSingleObject( pCurObj, &m_pCurrentLayer->m_Matrix, pPause)) { return; @@ -98,20 +109,20 @@ void CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause) { return; nObjsToGo = kStepLimit; } - if (pCurObj->IsImage() && pCurObj->AsImage()->GetImage()->IsMask() && - (m_pOptions->m_Flags & RENDER_BREAKFORMASKS)) { - return; - } ++iter; + if (is_mask && iter != iterEnd) + return; } if (m_pCurrentLayer->m_pObjectHolder->IsParsed()) { m_pRenderStatus.reset(); m_pDevice->RestoreState(false); m_pCurrentLayer = nullptr; m_LayerIndex++; - if (pPause && pPause->NeedToPauseNow()) { + if (is_mask || (pPause && pPause->NeedToPauseNow())) { return; } + } else if (is_mask) { + return; } else { m_pCurrentLayer->m_pObjectHolder->ContinueParse(pPause); if (!m_pCurrentLayer->m_pObjectHolder->IsParsed()) diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 6c5d7bc102..439ad4e5f0 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -1383,7 +1383,7 @@ FX_ARGB CPDF_RenderStatus::GetStrokeArgb(CPDF_PageObject* pObj) const { return m_Options.TranslateColor(ArgbEncode(alpha, rgb)); } -void CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath, +void CPDF_RenderStatus::ProcessClipPath(const CPDF_ClipPath& ClipPath, const CFX_Matrix* pObj2Device) { if (!ClipPath.HasRef()) { if (m_LastClipPath.HasRef()) { diff --git a/core/fpdfapi/render/cpdf_renderstatus.h b/core/fpdfapi/render/cpdf_renderstatus.h index 47fbac8a7c..cfaa966ed1 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.h +++ b/core/fpdfapi/render/cpdf_renderstatus.h @@ -62,6 +62,8 @@ class CPDF_RenderStatus { bool ContinueSingleObject(CPDF_PageObject* pObj, const CFX_Matrix* pObj2Device, IFX_Pause* pPause); + void ProcessClipPath(const CPDF_ClipPath& ClipPath, + const CFX_Matrix* pObj2Device); CPDF_RenderContext* GetContext() const { return m_pContext.Get(); } #if defined _SKIA_SUPPORT_ @@ -77,7 +79,6 @@ class CPDF_RenderStatus { friend class CPDF_ImageRenderer; friend class CPDF_RenderContext; - void ProcessClipPath(CPDF_ClipPath ClipPath, const CFX_Matrix* pObj2Device); bool ProcessTransparency(CPDF_PageObject* PageObj, const CFX_Matrix* pObj2Device); void ProcessObjectNoClip(CPDF_PageObject* PageObj, diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp index 51d9c9f6a3..964d769d2b 100644 --- a/fpdfsdk/fpdfview.cpp +++ b/fpdfsdk/fpdfview.cpp @@ -765,6 +765,9 @@ FX_RECT GetMaskDimensionsAndOffsets(CPDF_Page* pPage, // Compute offsets int offset_x = 0; int offset_y = 0; + if (size_x > size_y) + std::swap(size_x_bm, size_y_bm); + switch ((rotate + page_rotation) % 4) { case 0: offset_x = start_x_bm + start_x; @@ -829,9 +832,8 @@ void RenderBitmap(CFX_RenderDevice* device, FXDIB_BLEND_NORMAL, nullptr, false); if (device->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) { - device->StretchDIBitsWithFlagsAndBlend(pDst, mask_area.left, mask_area.top, - size_x_bm, size_y_bm, 0, - FXDIB_BLEND_NORMAL); + device->StretchDIBits(pDst, mask_area.left, mask_area.top, size_x_bm, + size_y_bm); } else { device->SetDIBits(pDst, mask_area.left, mask_area.top); } @@ -854,16 +856,14 @@ FPDF_EXPORT void FPDF_CALLCONV FPDF_RenderPage(HDC dc, CPDF_PageRenderContext* pContext = pPage->GetRenderContext(); CFX_RetainPtr<CFX_DIBitmap> pBitmap; - // TODO(rbpotter): Restore the behavior described below after resolving - // crbug.com/753700 // Don't render the full page to bitmap for a mask unless there are a lot // of masks. Full page bitmaps result in large spool sizes, so they should // only be used when necessary. For large numbers of masks, rendering each // individually is inefficient and unlikely to significantly improve spool - // size. This fix is temporarily disabled due to crbug.com/753700 so all - // image masks will result in the full page rendering as bitmap. + // size. const bool bNewBitmap = - pPage->BackgroundAlphaNeeded() || pPage->HasImageMask(); + pPage->BackgroundAlphaNeeded() || + (pPage->HasImageMask() && pPage->GetMaskBoundingBoxes().size() > 100); const bool bHasMask = pPage->HasImageMask() && !bNewBitmap; if (bNewBitmap || bHasMask) { pBitmap = pdfium::MakeRetain<CFX_DIBitmap>(); |