diff options
author | caryclark <caryclark@google.com> | 2016-07-06 10:20:25 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-06 10:20:25 -0700 |
commit | a27d49a3e9eafd7fd911a0a6039ce80284ccb463 (patch) | |
tree | 73fbb66b229652524c21c956e25f88e42d37be88 /core/fpdfapi/fpdf_render | |
parent | c4dedf32b1f5c71740df5be2a9b1446a01df304c (diff) | |
download | pdfium-a27d49a3e9eafd7fd911a0a6039ce80284ccb463.tar.xz |
copy graphics state fully
The dash parameters where not copied; the copy
could point at random data and cause corpus
tests to hang when testing Skia.
PDFium measures text directly by calling FreeType.
Turn off hinting altogether in Skia so that drawn
text matches the metrics that PDFium measures.
Premultiply bits retrieved from images, and check
to see that the device bits are always
premultiplied.
Look for null graphics state and matrices.
R=thestig@chromium.org,dsinclair@chromium.org
BUG=pdfium:532
Review-Url: https://codereview.chromium.org/2120353004
Diffstat (limited to 'core/fpdfapi/fpdf_render')
-rw-r--r-- | core/fpdfapi/fpdf_render/fpdf_render.cpp | 41 | ||||
-rw-r--r-- | core/fpdfapi/fpdf_render/fpdf_render_image.cpp | 19 | ||||
-rw-r--r-- | core/fpdfapi/fpdf_render/render_int.h | 4 |
3 files changed, 59 insertions, 5 deletions
diff --git a/core/fpdfapi/fpdf_render/fpdf_render.cpp b/core/fpdfapi/fpdf_render/fpdf_render.cpp index add2a8ae23..81a02cc6a7 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render.cpp @@ -213,6 +213,9 @@ FX_BOOL CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext, void CPDF_RenderStatus::RenderObjectList( const CPDF_PageObjectHolder* pObjectHolder, const CFX_Matrix* pObj2Device) { +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif CFX_FloatRect clip_rect(m_pDevice->GetClipBox()); CFX_Matrix device2object; device2object.SetReverse(*pObj2Device); @@ -236,9 +239,16 @@ void CPDF_RenderStatus::RenderObjectList( if (m_bStopped) return; } +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif } + void CPDF_RenderStatus::RenderSingleObject(const CPDF_PageObject* pObj, const CFX_Matrix* pObj2Device) { +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); if (++s_CurrentRecursionDepth > kRenderMaxRecursionDepth) { return; @@ -254,6 +264,9 @@ void CPDF_RenderStatus::RenderSingleObject(const CPDF_PageObject* pObj, return; } ProcessObjectNoClip(pObj, pObj2Device); +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif } FX_BOOL CPDF_RenderStatus::ContinueSingleObject(const CPDF_PageObject* pObj, @@ -319,6 +332,9 @@ FX_BOOL CPDF_RenderStatus::GetObjectClippedRect(const CPDF_PageObject* pObj, void CPDF_RenderStatus::ProcessObjectNoClip(const CPDF_PageObject* pObj, const CFX_Matrix* pObj2Device) { +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif FX_BOOL bRet = FALSE; switch (pObj->GetType()) { case CPDF_PageObject::TEXT: @@ -339,6 +355,9 @@ void CPDF_RenderStatus::ProcessObjectNoClip(const CPDF_PageObject* pObj, } if (!bRet) DrawObjWithBackground(pObj, pObj2Device); +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif } FX_BOOL CPDF_RenderStatus::DrawObjWithBlend(const CPDF_PageObject* pObj, @@ -396,8 +415,12 @@ void CPDF_RenderStatus::DrawObjWithBackground(const CPDF_PageObject* pObj, status.RenderSingleObject(pObj, &matrix); buffer.OutputToDevice(); } + FX_BOOL CPDF_RenderStatus::ProcessForm(const CPDF_FormObject* pFormObj, const CFX_Matrix* pObj2Device) { +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif CPDF_Dictionary* pOC = pFormObj->m_pForm->m_pFormDict->GetDictBy("OC"); if (pOC && m_Options.m_pOCContext && !m_Options.m_pOCContext->CheckOCGVisible(pOC)) { @@ -418,8 +441,12 @@ FX_BOOL CPDF_RenderStatus::ProcessForm(const CPDF_FormObject* pFormObj, status.RenderObjectList(pFormObj->m_pForm, &matrix); m_bStopped = status.m_bStopped; m_pDevice->RestoreState(false); +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif return TRUE; } + FX_BOOL IsAvailableMatrix(const CFX_Matrix& matrix) { if (matrix.a == 0 || matrix.d == 0) { return matrix.b != 0 && matrix.c != 0; @@ -645,6 +672,9 @@ FX_BOOL CPDF_RenderStatus::SelectClipPath(const CPDF_PathObject* pPathObj, } FX_BOOL CPDF_RenderStatus::ProcessTransparency(const CPDF_PageObject* pPageObj, const CFX_Matrix* pObj2Device) { +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState.GetObject(); int blend_type = @@ -745,12 +775,10 @@ FX_BOOL CPDF_RenderStatus::ProcessTransparency(const CPDF_PageObject* pPageObj, oriDevice.reset(new CFX_DIBitmap); if (!m_pDevice->CreateCompatibleBitmap(oriDevice.get(), width, height)) return TRUE; - m_pDevice->GetDIBits(oriDevice.get(), rect.left, rect.top); } if (!bitmap_device.Create(width, height, FXDIB_Argb, oriDevice.get())) return TRUE; - CFX_DIBitmap* bitmap = bitmap_device.GetBitmap(); bitmap->Clear(0); CFX_Matrix new_matrix = *pObj2Device; @@ -813,6 +841,9 @@ FX_BOOL CPDF_RenderStatus::ProcessTransparency(const CPDF_PageObject* pPageObj, } CompositeDIBitmap(bitmap, rect.left, rect.top, 0, blitAlpha, blend_type, Transparency); +#if defined _SKIA_SUPPORT_ + DebugVerifyDeviceIsPreMultiplied(); +#endif return TRUE; } @@ -1263,3 +1294,9 @@ void CPDF_ScaledRenderBuffer::OutputToDevice() { m_Rect.top, m_Rect.Width(), m_Rect.Height()); } } + +#if defined _SKIA_SUPPORT_ +void CPDF_RenderStatus::DebugVerifyDeviceIsPreMultiplied() const { + m_pDevice->DebugVerifyBitmapIsPreMultiplied(); +} +#endif diff --git a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp b/core/fpdfapi/fpdf_render/fpdf_render_image.cpp index 10fd5f3f15..b9826a9338 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render_image.cpp @@ -63,8 +63,7 @@ void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, #endif } #ifdef _SKIA_SUPPORT_ - static_cast<CFX_SkiaDeviceDriver*>(m_pDevice->GetDeviceDriver()) - ->PreMultiply(pDIBitmap); + CFX_SkiaDeviceDriver::PreMultiply(pDIBitmap); #endif if (m_pDevice->SetDIBits(pDIBitmap, left, top)) { return; @@ -717,7 +716,7 @@ FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() { bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask); bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap()); #ifdef _SKIA_SUPPORT_ - bitmap_device1.PreMultiply(); // convert unpremultiplied to premultiplied + CFX_SkiaDeviceDriver::PreMultiply(bitmap_device1.GetBitmap()); #endif if (m_BitmapAlpha < 255) { bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha); @@ -737,6 +736,19 @@ FX_BOOL CPDF_ImageRenderer::StartDIBSource() { m_Flags |= RENDER_FORCE_DOWNSAMPLE; } } +#ifdef _SKIA_SUPPORT_ + CFX_DIBitmap* premultiplied = m_pDIBSource->Clone(); + CFX_SkiaDeviceDriver::PreMultiply(premultiplied); + if (m_pRenderStatus->m_pDevice->StartDIBitsWithBlend( + premultiplied, m_BitmapAlpha, m_FillArgb, &m_ImageMatrix, m_Flags, + m_DeviceHandle, m_BlendType)) { + if (m_DeviceHandle) { + m_Status = 3; + return TRUE; + } + return FALSE; + } +#else if (m_pRenderStatus->m_pDevice->StartDIBitsWithBlend( m_pDIBSource, m_BitmapAlpha, m_FillArgb, &m_ImageMatrix, m_Flags, m_DeviceHandle, m_BlendType)) { @@ -746,6 +758,7 @@ FX_BOOL CPDF_ImageRenderer::StartDIBSource() { } return FALSE; } +#endif CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); FX_RECT image_rect = image_rect_f.GetOutterRect(); int dest_width = image_rect.Width(); diff --git a/core/fpdfapi/fpdf_render/render_int.h b/core/fpdfapi/fpdf_render/render_int.h index 67eae91f59..d86a62ab19 100644 --- a/core/fpdfapi/fpdf_render/render_int.h +++ b/core/fpdfapi/fpdf_render/render_int.h @@ -150,6 +150,10 @@ class CPDF_RenderStatus { IFX_Pause* pPause); CPDF_RenderContext* GetContext() { return m_pContext; } +#if defined _SKIA_SUPPORT_ + void DebugVerifyDeviceIsPreMultiplied() const; +#endif + CPDF_RenderOptions m_Options; CPDF_Dictionary* m_pFormResource; CPDF_Dictionary* m_pPageResource; |