From 1629f609d3722f25491bbbb53b2cce97a03a5867 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Fri, 21 Apr 2017 14:11:26 -0700 Subject: Add CFX_RenderDevice::AutoRestorer() Avoid cleanup on every return path. Change-Id: I6978adb6f31020d812ac88c5d46c703d1461d373 Reviewed-on: https://pdfium-review.googlesource.com/4435 Reviewed-by: Lei Zhang Reviewed-by: Tom Sepez Commit-Queue: Tom Sepez --- core/fpdfapi/render/cpdf_rendercontext.cpp | 22 ++++-------- core/fpdfapi/render/cpdf_renderstatus.cpp | 47 +++++++++++--------------- core/fxge/cfx_renderdevice.h | 11 ++++++ fpdfsdk/fpdfformfill.cpp | 54 +++++++++++++++--------------- fpdfsdk/fxedit/fxet_edit.cpp | 4 +-- xfa/fxfa/cxfa_ffwidget.cpp | 15 ++++----- xfa/fxgraphics/cfx_graphics.cpp | 7 ++-- 7 files changed, 73 insertions(+), 87 deletions(-) diff --git a/core/fpdfapi/render/cpdf_rendercontext.cpp b/core/fpdfapi/render/cpdf_rendercontext.cpp index 07af2cc172..e4ef9af94d 100644 --- a/core/fpdfapi/render/cpdf_rendercontext.cpp +++ b/core/fpdfapi/render/cpdf_rendercontext.cpp @@ -64,34 +64,24 @@ void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_RenderOptions* pOptions, const CFX_Matrix* pLastMatrix) { for (auto& layer : m_Layers) { - pDevice->SaveState(); + CFX_RenderDevice::StateRestorer restorer(pDevice); + CPDF_RenderStatus status; if (pLastMatrix) { CFX_Matrix FinalMatrix = layer.m_Matrix; FinalMatrix.Concat(*pLastMatrix); - CPDF_RenderStatus status; status.Initialize(this, pDevice, pLastMatrix, pStopObj, nullptr, nullptr, pOptions, layer.m_pObjectHolder->m_Transparency, false, nullptr); status.RenderObjectList(layer.m_pObjectHolder, &FinalMatrix); - if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) - m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize); - if (status.m_bStopped) { - pDevice->RestoreState(false); - break; - } } else { - CPDF_RenderStatus status; status.Initialize(this, pDevice, nullptr, pStopObj, nullptr, nullptr, pOptions, layer.m_pObjectHolder->m_Transparency, false, nullptr); status.RenderObjectList(layer.m_pObjectHolder, &layer.m_Matrix); - if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) - m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize); - if (status.m_bStopped) { - pDevice->RestoreState(false); - break; - } } - pDevice->RestoreState(false); + if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) + m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize); + if (status.m_bStopped) + break; } } diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 465105a64d..d41561c057 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -1252,10 +1252,11 @@ bool CPDF_RenderStatus::ProcessForm(const CPDF_FormObject* pFormObj, &m_Options, m_Transparency, m_bDropObjects, pResources, false); status.m_curBlend = m_curBlend; - m_pDevice->SaveState(); - status.RenderObjectList(pFormObj->m_pForm.get(), &matrix); - m_bStopped = status.m_bStopped; - m_pDevice->RestoreState(false); + { + CFX_RenderDevice::StateRestorer restorer(m_pDevice); + status.RenderObjectList(pFormObj->m_pForm.get(), &matrix); + m_bStopped = status.m_bStopped; + } #if defined _SKIA_SUPPORT_ DebugVerifyDeviceIsPreMultiplied(); #endif @@ -1876,9 +1877,9 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, pFormResource, false, pType3Char, fill_argb); status.m_Type3FontCache = m_Type3FontCache; status.m_Type3FontCache.push_back(pType3Font); - m_pDevice->SaveState(); + + CFX_RenderDevice::StateRestorer restorer(m_pDevice); status.RenderObjectList(pType3Char->m_pForm.get(), &matrix); - m_pDevice->RestoreState(false); } else { CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox(); matrix.TransformRect(rect_f); @@ -2131,22 +2132,19 @@ void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern, if (!pattern->Load()) return; - m_pDevice->SaveState(); + CFX_RenderDevice::StateRestorer restorer(m_pDevice); if (pPageObj->IsPath()) { - if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) { - m_pDevice->RestoreState(false); + if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) return; - } } else if (pPageObj->IsImage()) { m_pDevice->SetClip_Rect(pPageObj->GetBBox(pObj2Device)); } else { return; } FX_RECT rect; - if (GetObjectClippedRect(pPageObj, pObj2Device, false, rect)) { - m_pDevice->RestoreState(false); + if (GetObjectClippedRect(pPageObj, pObj2Device, false, rect)) return; - } + CFX_Matrix matrix = *pattern->pattern_to_form(); matrix.Concat(*pObj2Device); GetScaledMatrix(matrix); @@ -2155,7 +2153,6 @@ void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern, : pPageObj->m_GeneralState.GetFillAlpha())); DrawShading(pattern, &matrix, rect, alpha, m_Options.m_ColorMode == RENDER_COLOR_ALPHA); - m_pDevice->RestoreState(false); } void CPDF_RenderStatus::ProcessShading(const CPDF_ShadingObject* pShadingObj, @@ -2180,22 +2177,20 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, if (!pPattern->Load()) return; - m_pDevice->SaveState(); + CFX_RenderDevice::StateRestorer restorer(m_pDevice); if (pPageObj->IsPath()) { - if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) { - m_pDevice->RestoreState(false); + if (!SelectClipPath(pPageObj->AsPath(), pObj2Device, bStroke)) return; - } } else if (pPageObj->IsImage()) { m_pDevice->SetClip_Rect(pPageObj->GetBBox(pObj2Device)); } else { return; } + FX_RECT clip_box = m_pDevice->GetClipBox(); - if (clip_box.IsEmpty()) { - m_pDevice->RestoreState(false); + if (clip_box.IsEmpty()) return; - } + CFX_Matrix dCTM = m_pDevice->GetCTM(); float sa = fabs(dCTM.a); float sd = fabs(dCTM.d); @@ -2254,17 +2249,15 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, CFX_Matrix matrix = *pObj2Device; matrix.Translate(original.x - mtPattern2Device.e, original.y - mtPattern2Device.f); - m_pDevice->SaveState(); + CFX_RenderDevice::StateRestorer restorer2(m_pDevice); CPDF_RenderStatus status; status.Initialize(m_pContext, m_pDevice, nullptr, nullptr, this, pStates.get(), &m_Options, pPattern->form()->m_Transparency, m_bDropObjects, pFormResource); status.RenderObjectList(pPattern->form(), &matrix); - m_pDevice->RestoreState(false); } } - m_pDevice->RestoreState(false); return; } if (bAligned) { @@ -2299,10 +2292,9 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, m_pContext->GetDocument(), m_pContext->GetPageCache(), pPattern, pObj2Device, width, height, m_Options.m_Flags); } - if (!pPatternBitmap) { - m_pDevice->RestoreState(false); + if (!pPatternBitmap) return; - } + if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor); @@ -2364,7 +2356,6 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, } CompositeDIBitmap(pScreen, clip_box.left, clip_box.top, 0, 255, FXDIB_BLEND_NORMAL, false); - m_pDevice->RestoreState(false); } void CPDF_RenderStatus::DrawPathWithPattern(CPDF_PathObject* pPathObj, diff --git a/core/fxge/cfx_renderdevice.h b/core/fxge/cfx_renderdevice.h index 794c2fec6b..6aa4528f05 100644 --- a/core/fxge/cfx_renderdevice.h +++ b/core/fxge/cfx_renderdevice.h @@ -83,6 +83,17 @@ class FXTEXT_CHARPOS { class CFX_RenderDevice { public: + class StateRestorer { + public: + explicit StateRestorer(CFX_RenderDevice* pDevice) : m_pDevice(pDevice) { + m_pDevice->SaveState(); + } + ~StateRestorer() { m_pDevice->RestoreState(false); } + + private: + CFX_RenderDevice* m_pDevice; + }; + CFX_RenderDevice(); virtual ~CFX_RenderDevice(); diff --git a/fpdfsdk/fpdfformfill.cpp b/fpdfsdk/fpdfformfill.cpp index 6610f81c65..a050dc0161 100644 --- a/fpdfsdk/fpdfformfill.cpp +++ b/fpdfsdk/fpdfformfill.cpp @@ -115,37 +115,37 @@ void FFLCommon(FPDF_FORMHANDLE hHandle, #endif CFX_RetainPtr holder(CFXBitmapFromFPDFBitmap(bitmap)); pDevice->Attach(holder, false, nullptr, false); - pDevice->SaveState(); - pDevice->SetClip_Rect(clip); - - CPDF_RenderOptions options; - if (flags & FPDF_LCD_TEXT) - options.m_Flags |= RENDER_CLEARTYPE; - else - options.m_Flags &= ~RENDER_CLEARTYPE; - - // Grayscale output - if (flags & FPDF_GRAYSCALE) { - options.m_ColorMode = RENDER_COLOR_GRAY; - options.m_ForeColor = 0; - options.m_BackColor = 0xffffff; - } - options.m_AddFlags = flags >> 8; - options.m_bDrawAnnots = flags & FPDF_ANNOT; + { + CFX_RenderDevice::StateRestorer restorer(pDevice.get()); + pDevice->SetClip_Rect(clip); + + CPDF_RenderOptions options; + if (flags & FPDF_LCD_TEXT) + options.m_Flags |= RENDER_CLEARTYPE; + else + options.m_Flags &= ~RENDER_CLEARTYPE; + + // Grayscale output + if (flags & FPDF_GRAYSCALE) { + options.m_ColorMode = RENDER_COLOR_GRAY; + options.m_ForeColor = 0; + options.m_BackColor = 0xffffff; + } + options.m_AddFlags = flags >> 8; + options.m_bDrawAnnots = flags & FPDF_ANNOT; #ifdef PDF_ENABLE_XFA - options.m_pOCContext = - pdfium::MakeRetain(pPDFDoc, CPDF_OCContext::View); - if (CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, true)) - pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip); + options.m_pOCContext = + pdfium::MakeRetain(pPDFDoc, CPDF_OCContext::View); + if (CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, true)) + pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip); #else // PDF_ENABLE_XFA - options.m_pOCContext = pdfium::MakeRetain( - pPage->m_pDocument, CPDF_OCContext::View); - if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage)) - pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options); + options.m_pOCContext = pdfium::MakeRetain( + pPage->m_pDocument, CPDF_OCContext::View); + if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage)) + pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options); #endif // PDF_ENABLE_XFA - - pDevice->RestoreState(false); + } #ifdef _SKIA_SUPPORT_PATHS_ pDevice->Flush(); holder->UnPreMultiply(); diff --git a/fpdfsdk/fxedit/fxet_edit.cpp b/fpdfsdk/fxedit/fxet_edit.cpp index 5b84c9b95e..cf4fdc3d91 100644 --- a/fpdfsdk/fxedit/fxet_edit.cpp +++ b/fpdfsdk/fxedit/fxet_edit.cpp @@ -681,7 +681,7 @@ void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, CFX_ByteTextBuf sTextBuf; int32_t nFontIndex = -1; CFX_PointF ptBT; - pDevice->SaveState(); + CFX_RenderDevice::StateRestorer restorer(pDevice); if (!rcClip.IsEmpty()) { CFX_FloatRect rcTemp = rcClip; pUser2Device->TransformRect(rcTemp); @@ -770,8 +770,6 @@ void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, sTextBuf.MakeString(), crOldFill, nHorzScale); } } - - pDevice->RestoreState(false); } CFX_Edit::CFX_Edit() diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp index 06de436e09..b74e1dcaf7 100644 --- a/xfa/fxfa/cxfa_ffwidget.cpp +++ b/xfa/fxfa/cxfa_ffwidget.cpp @@ -886,8 +886,7 @@ void XFA_DrawImage(CFX_Graphics* pGS, rtFit.top = rtImage.bottom() - rtImage.height; } CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); - pRenderDevice->SaveState(); - + CFX_RenderDevice::StateRestorer restorer(pRenderDevice); CFX_PathData path; path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top); pRenderDevice->SetClip_PathFill(&path, pMatrix, FXFILL_WINDING); @@ -898,12 +897,12 @@ void XFA_DrawImage(CFX_Graphics* pGS, mtImage.Concat(*pMatrix); CXFA_ImageRenderer imageRender; - bool bRet = imageRender.Start(pRenderDevice, pDIBitmap, 0, 255, &mtImage, - FXDIB_INTERPOL); - while (bRet) - bRet = imageRender.Continue(nullptr); - - pRenderDevice->RestoreState(false); + if (!imageRender.Start(pRenderDevice, pDIBitmap, 0, 255, &mtImage, + FXDIB_INTERPOL)) { + return; + } + while (imageRender.Continue(nullptr)) + continue; } static const uint8_t g_inv_base64[128] = { diff --git a/xfa/fxgraphics/cfx_graphics.cpp b/xfa/fxgraphics/cfx_graphics.cpp index a3821dd067..b7595eea8d 100644 --- a/xfa/fxgraphics/cfx_graphics.cpp +++ b/xfa/fxgraphics/cfx_graphics.cpp @@ -375,11 +375,9 @@ void CFX_Graphics::FillPathWithPattern(CFX_Path* path, m_info.fillColor->m_info.pattern->m_foreArgb); } } - - m_renderDevice->SaveState(); + CFX_RenderDevice::StateRestorer restorer(m_renderDevice); m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode); SetDIBitsWithMatrix(bmp, &pattern->m_matrix); - m_renderDevice->RestoreState(false); } void CFX_Graphics::FillPathWithShading(CFX_Path* path, @@ -494,10 +492,9 @@ void CFX_Graphics::FillPathWithShading(CFX_Path* path, } } if (result) { - m_renderDevice->SaveState(); + CFX_RenderDevice::StateRestorer restorer(m_renderDevice); m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode); SetDIBitsWithMatrix(bmp, matrix); - m_renderDevice->RestoreState(false); } } -- cgit v1.2.3