summaryrefslogtreecommitdiff
path: root/core/fpdfapi/fpdf_render
diff options
context:
space:
mode:
authorcaryclark <caryclark@google.com>2016-07-06 10:20:25 -0700
committerCommit bot <commit-bot@chromium.org>2016-07-06 10:20:25 -0700
commita27d49a3e9eafd7fd911a0a6039ce80284ccb463 (patch)
tree73fbb66b229652524c21c956e25f88e42d37be88 /core/fpdfapi/fpdf_render
parentc4dedf32b1f5c71740df5be2a9b1446a01df304c (diff)
downloadpdfium-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.cpp41
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_image.cpp19
-rw-r--r--core/fpdfapi/fpdf_render/render_int.h4
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;