summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrbpotter <rbpotter@chromium.org>2017-08-16 16:45:44 -0700
committerChromium commit bot <commit-bot@chromium.org>2017-08-17 00:06:48 +0000
commit8d7672e941fa58326c4c6aeac47418e9b36527e9 (patch)
treefd24ca408405e8e47fe508dd9e673bdfaca74d3c
parent574015e0ad53c592fe8a923390b31edeb30c41fe (diff)
downloadpdfium-8d7672e941fa58326c4c6aeac47418e9b36527e9.tar.xz
Fix some issues with individual image mask rendering
Re-enable individual image mask rendering to improve spool sizes, with bug fixes and improvements: - Fix bug with missing images by ensuring all masks are recorded - Fix printing to landscape paper sizes - Improve spool sizes by processing the location of the masks in the progressive renderer when rendering to the printer instead of needlessly fully rendering them (they will be rendered as bitmaps anyway). Bug: chromium:753700 Change-Id: I86bdcce9f10855274c56ba2ddae2c2522b36426d Reviewed-on: https://pdfium-review.googlesource.com/11115 Commit-Queue: Rebekah Potter <rbpotter@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org>
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser.cpp6
-rw-r--r--core/fpdfapi/render/cpdf_progressiverenderer.cpp21
-rw-r--r--core/fpdfapi/render/cpdf_renderstatus.cpp2
-rw-r--r--core/fpdfapi/render/cpdf_renderstatus.h3
-rw-r--r--fpdfsdk/fpdfview.cpp16
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>();