summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcaryclark <caryclark@google.com>2016-11-22 12:44:25 -0800
committerCommit bot <commit-bot@chromium.org>2016-11-22 12:44:25 -0800
commit687fbde2e4ee13637cb3fd9b1fec39a436ef73d7 (patch)
tree9c0d588a6494957b1bfeb12944c6f41e07a01711
parent89a2d92549d25df6786d53de5671eb141e1fd3e2 (diff)
downloadpdfium-687fbde2e4ee13637cb3fd9b1fec39a436ef73d7.tar.xz
handle antialiased rendering as premultiplied
Transparencies and bitmap patterns need to be unpremultiplied after Skia renders them so that PDFium can use its own compositing. Also added some linear (i.e. axial) gradient support, although its unclear if any of the test corpus uses this feature. R=dsinclair@chromium.org Review-Url: https://codereview.chromium.org/2520073003
-rw-r--r--core/fpdfapi/render/cpdf_renderstatus.cpp15
-rw-r--r--core/fpdfapi/render/cpdf_renderstatus.h4
-rw-r--r--core/fxge/cfx_fxgedevice.h4
-rw-r--r--core/fxge/cfx_renderdevice.h4
-rw-r--r--core/fxge/dib/fx_dib_main.cpp2
-rw-r--r--core/fxge/fx_dib.h19
-rw-r--r--core/fxge/ge/cfx_renderdevice.cpp6
-rw-r--r--core/fxge/skia/fx_skia_device.cpp97
-rw-r--r--core/fxge/skia/fx_skia_device.h6
-rw-r--r--fpdfsdk/fpdfformfill.cpp3
-rw-r--r--fpdfsdk/fpdfview.cpp3
11 files changed, 69 insertions, 94 deletions
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index d2a17d27fc..aad9af04e3 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -893,6 +893,9 @@ std::unique_ptr<CFX_DIBitmap> DrawPatternBitmap(
CPDF_RenderContext context(pDoc, pCache);
context.AppendLayer(pPattern->form(), &mtPattern2Bitmap);
context.Render(&bitmap_device, &options, nullptr);
+#if defined _SKIA_SUPPORT_PATHS_
+ pBitmap->UnPreMultiply();
+#endif
return pBitmap;
}
@@ -1136,9 +1139,6 @@ void CPDF_RenderStatus::ProcessObjectNoClip(CPDF_PageObject* pObj,
#if defined _SKIA_SUPPORT_
DebugVerifyDeviceIsPreMultiplied();
#endif
-#if defined _SKIA_SUPPORT_PATHS_
- UnPreMultiplyDevice();
-#endif
}
bool CPDF_RenderStatus::DrawObjWithBlend(CPDF_PageObject* pObj,
@@ -1547,6 +1547,9 @@ bool CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj,
nullptr, nullptr, &m_Options, 0, m_bDropObjects,
pFormResource, true);
bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
+#if defined _SKIA_SUPPORT_PATHS_
+ bitmap->UnPreMultiply();
+#endif
m_bStopped = bitmap_render.m_bStopped;
if (pSMaskDict) {
CFX_Matrix smask_matrix = *pPageObj->m_GeneralState.GetSMaskMatrix();
@@ -1650,12 +1653,6 @@ void CPDF_RenderStatus::DebugVerifyDeviceIsPreMultiplied() const {
}
#endif
-#if defined _SKIA_SUPPORT_PATHS_
-void CPDF_RenderStatus::UnPreMultiplyDevice() {
- m_pDevice->UnPreMultiplyDevice();
-}
-#endif
-
bool CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj,
const CFX_Matrix* pObj2Device,
CFX_PathData* pClippingPath) {
diff --git a/core/fpdfapi/render/cpdf_renderstatus.h b/core/fpdfapi/render/cpdf_renderstatus.h
index f74f0ce9ae..b7e9fa6d0a 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.h
+++ b/core/fpdfapi/render/cpdf_renderstatus.h
@@ -66,10 +66,6 @@ class CPDF_RenderStatus {
void DebugVerifyDeviceIsPreMultiplied() const;
#endif
-#if defined _SKIA_SUPPORT_PATHS_
- void UnPreMultiplyDevice();
-#endif
-
CPDF_RenderOptions m_Options;
CPDF_Dictionary* m_pFormResource;
CPDF_Dictionary* m_pPageResource;
diff --git a/core/fxge/cfx_fxgedevice.h b/core/fxge/cfx_fxgedevice.h
index 03fece7df5..8358e43666 100644
--- a/core/fxge/cfx_fxgedevice.h
+++ b/core/fxge/cfx_fxgedevice.h
@@ -39,10 +39,6 @@ class CFX_FxgeDevice : public CFX_RenderDevice {
int blend_type) override;
#endif
-#ifdef _SKIA_SUPPORT_PATHS_
- void UnPreMultiplyDevice() override;
-#endif
-
private:
bool m_bOwnedBitmap;
};
diff --git a/core/fxge/cfx_renderdevice.h b/core/fxge/cfx_renderdevice.h
index 6da1df7e92..d38b2981ba 100644
--- a/core/fxge/cfx_renderdevice.h
+++ b/core/fxge/cfx_renderdevice.h
@@ -230,10 +230,6 @@ class CFX_RenderDevice {
void Flush();
#endif
-#ifdef _SKIA_SUPPORT_PATHS_
- virtual void UnPreMultiplyDevice();
-#endif
-
private:
void InitDeviceInfo();
void UpdateClipBox();
diff --git a/core/fxge/dib/fx_dib_main.cpp b/core/fxge/dib/fx_dib_main.cpp
index 63db7adb91..83899553a2 100644
--- a/core/fxge/dib/fx_dib_main.cpp
+++ b/core/fxge/dib/fx_dib_main.cpp
@@ -67,7 +67,7 @@ CFX_DIBitmap::CFX_DIBitmap() {
m_pBuffer = nullptr;
m_pPalette = nullptr;
#ifdef _SKIA_SUPPORT_PATHS_
- m_bUnPreMultiply = false;
+ m_nFormat = Format::kCleared;
#endif
}
diff --git a/core/fxge/fx_dib.h b/core/fxge/fx_dib.h
index daf2cdf9a5..1719ae13e5 100644
--- a/core/fxge/fx_dib.h
+++ b/core/fxge/fx_dib.h
@@ -371,20 +371,25 @@ class CFX_DIBitmap : public CFX_DIBSource {
bool ConvertColorScale(uint32_t forecolor, uint32_t backcolor);
-#ifdef _SKIA_SUPPORT_PATHS_
- bool IsMarkedForUnPreMultiply() const { return m_bUnPreMultiply; }
-
- void MarkForUnPreMultiply(bool mark) { m_bUnPreMultiply = mark; }
+#if defined _SKIA_SUPPORT_ || _SKIA_SUPPORT_PATHS_
+ void PreMultiply();
+#endif
+#if defined _SKIA_SUPPORT_PATHS_
+ void UnPreMultiply();
#endif
protected:
bool GetGrayData(void* pIccTransform = nullptr);
+#if defined _SKIA_SUPPORT_PATHS_
+ enum class Format { kCleared, kPreMultiplied, kUnPreMultiplied };
+#endif
+
uint8_t* m_pBuffer;
- bool m_bExtBuf;
-#ifdef _SKIA_SUPPORT_PATHS_
- bool m_bUnPreMultiply;
+#if defined _SKIA_SUPPORT_PATHS_
+ Format m_nFormat;
#endif
+ bool m_bExtBuf;
};
class CFX_DIBExtractor {
diff --git a/core/fxge/ge/cfx_renderdevice.cpp b/core/fxge/ge/cfx_renderdevice.cpp
index 10135273c6..64fa6ff452 100644
--- a/core/fxge/ge/cfx_renderdevice.cpp
+++ b/core/fxge/ge/cfx_renderdevice.cpp
@@ -822,12 +822,6 @@ bool CFX_RenderDevice::SetBitsWithMask(const CFX_DIBSource* pBitmap,
}
#endif
-#ifdef _SKIA_SUPPORT_PATHS_
-void CFX_RenderDevice::UnPreMultiplyDevice() {
- SkASSERT(0);
-}
-#endif
-
bool CFX_RenderDevice::DrawNormalText(int nChars,
const FXTEXT_CHARPOS* pCharPos,
CFX_Font* pFont,
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index 973c4f2b34..136bab71c6 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -34,14 +34,14 @@
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/effects/SkDashPathEffect.h"
#include "third_party/skia/include/pathops/SkPathOps.h"
+#include "third_party/skia/include/core/SkShader.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
#ifdef _SKIA_SUPPORT_
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkColorPriv.h"
#include "third_party/skia/include/core/SkMaskFilter.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
-#include "third_party/skia/include/core/SkShader.h"
-#include "third_party/skia/include/effects/SkGradientShader.h"
#endif // _SKIA_SUPPORT_
#ifdef SK_DEBUG
@@ -313,7 +313,6 @@ SkBlendMode GetSkiaBlendMode(int blend_type) {
}
}
-#ifdef _SKIA_SUPPORT_
bool AddColors(const CPDF_ExpIntFunc* pFunc, SkTDArray<SkColor>* skColors) {
if (pFunc->CountInputs() != 1)
return false;
@@ -497,6 +496,7 @@ void ClipAngledGradient(const SkPoint pts[2],
clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt));
}
+#ifdef _SKIA_SUPPORT_
void SetBitmapMatrix(const CFX_Matrix* pMatrix,
int width,
int height,
@@ -1171,14 +1171,12 @@ bool CFX_SkiaDeviceDriver::DrawDeviceText(int nChars,
positions[index] = {cp.m_OriginX * flip, cp.m_OriginY * vFlip};
glyphs[index] = (uint16_t)cp.m_GlyphIndex;
}
+#ifdef _SKIA_SUPPORT_PATHS_
+ m_pBitmap->PreMultiply();
+#endif // _SKIA_SUPPORT_PATHS_
m_pCanvas->drawPosText(glyphs.begin(), nChars * 2, positions.begin(), paint);
m_pCanvas->restore();
-#ifdef _SKIA_SUPPORT_PATHS_
- if (FXARGB_A(color) < 255) {
- m_pBitmap->MarkForUnPreMultiply(true);
- }
-#endif // _SKIA_SUPPORT_PATHS_
return true;
}
@@ -1449,6 +1447,9 @@ bool CFX_SkiaDeviceDriver::DrawPath(
DebugShowSkiaPath(*fillPath);
DebugShowCanvasMatrix(m_pCanvas);
DebugShowCanvasClip(m_pCanvas);
+#ifdef _SKIA_SUPPORT_PATHS_
+ m_pBitmap->PreMultiply();
+#endif // _SKIA_SUPPORT_PATHS_
m_pCanvas->drawPath(*fillPath, skPaint);
}
if (pGraphState && stroke_alpha) {
@@ -1457,15 +1458,12 @@ bool CFX_SkiaDeviceDriver::DrawPath(
DebugShowCanvasClip(m_pCanvas);
skPaint.setStyle(SkPaint::kStroke_Style);
skPaint.setColor(stroke_color);
+#ifdef _SKIA_SUPPORT_PATHS_
+ m_pBitmap->PreMultiply();
+#endif // _SKIA_SUPPORT_PATHS_
m_pCanvas->drawPath(skPath, skPaint);
}
m_pCanvas->restore();
-#ifdef _SKIA_SUPPORT_PATHS_
- if ((fill_mode & 3 && FXARGB_A(fill_color) < 255) ||
- (pGraphState && stroke_alpha < 255)) {
- m_pBitmap->MarkForUnPreMultiply(true);
- }
-#endif // _SKIA_SUPPORT_PATHS_
return true;
}
@@ -1498,7 +1496,6 @@ bool CFX_SkiaDeviceDriver::FillRectWithBlend(const FX_RECT* pRect,
return true;
}
-#ifdef _SKIA_SUPPORT_
bool CFX_SkiaDeviceDriver::DrawShading(const CPDF_ShadingPattern* pPattern,
const CFX_Matrix* pMatrix,
const FX_RECT& clip_rect,
@@ -1632,7 +1629,6 @@ bool CFX_SkiaDeviceDriver::DrawShading(const CPDF_ShadingPattern* pPattern,
m_pCanvas->restore();
return true;
}
-#endif // _SKIA_SUPPORT_
uint8_t* CFX_SkiaDeviceDriver::GetBuffer() const {
return m_pBitmap->GetBuffer();
@@ -1680,6 +1676,7 @@ bool CFX_SkiaDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top) {
#endif // _SKIA_SUPPORT_
#ifdef _SKIA_SUPPORT_PATHS_
+ m_pBitmap->UnPreMultiply();
FX_RECT rect(left, top, left + pBitmap->GetWidth(),
top + pBitmap->GetHeight());
CFX_DIBitmap* pBack = nullptr;
@@ -1844,7 +1841,7 @@ bool CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource,
#ifdef _SKIA_SUPPORT_PATHS_
if (!m_pBitmap->GetBuffer())
return true;
-
+ m_pBitmap->UnPreMultiply();
CFX_ImageRenderer* pRenderer = new CFX_ImageRenderer;
pRenderer->Start(m_pBitmap, m_pClipRgn.get(), pSource, bitmap_alpha, argb,
pMatrix, render_flags, m_bRgbByteOrder, 0, nullptr);
@@ -1866,17 +1863,27 @@ bool CFX_SkiaDeviceDriver::ContinueDIBits(void* handle, IFX_Pause* pPause) {
#endif // _SKIA_SUPPORT_PATHS_
}
-#ifdef _SKIA_SUPPORT_
+#if defined _SKIA_SUPPORT_
void CFX_SkiaDeviceDriver::PreMultiply(CFX_DIBitmap* pDIBitmap) {
- void* buffer = pDIBitmap->GetBuffer();
+ pDIBitmap->PreMultiply();
+}
+#endif // _SKIA_SUPPORT_
+
+void CFX_DIBitmap::PreMultiply() {
+ if (this->GetBPP() != 32)
+ return;
+ void* buffer = this->GetBuffer();
if (!buffer)
return;
- if (pDIBitmap->GetBPP() != 32) {
+#if defined _SKIA_SUPPORT_PATHS_
+ Format priorFormat = m_nFormat;
+ m_nFormat = Format::kPreMultiplied;
+ if (priorFormat != Format::kUnPreMultiplied)
return;
- }
- int height = pDIBitmap->GetHeight();
- int width = pDIBitmap->GetWidth();
- int rowBytes = pDIBitmap->GetPitch();
+#endif
+ int height = this->GetHeight();
+ int width = this->GetWidth();
+ int rowBytes = this->GetPitch();
SkImageInfo unpremultipliedInfo =
SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType);
SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes);
@@ -1884,24 +1891,24 @@ void CFX_SkiaDeviceDriver::PreMultiply(CFX_DIBitmap* pDIBitmap) {
SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType);
SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes);
unpremultiplied.readPixels(premultiplied);
- pDIBitmap->DebugVerifyBitmapIsPreMultiplied();
+ this->DebugVerifyBitmapIsPreMultiplied();
}
-#endif // _SKIA_SUPPORT_
#ifdef _SKIA_SUPPORT_PATHS_
-void CFX_SkiaDeviceDriver::UnPreMultiply(CFX_DIBitmap* pDIBitmap) {
- if (!pDIBitmap->IsMarkedForUnPreMultiply())
+void CFX_DIBitmap::UnPreMultiply() {
+ if (this->GetBPP() != 32)
return;
- pDIBitmap->DebugVerifyBitmapIsPreMultiplied();
- void* buffer = pDIBitmap->GetBuffer();
+ void* buffer = this->GetBuffer();
if (!buffer)
return;
- if (pDIBitmap->GetBPP() != 32) {
+ Format priorFormat = m_nFormat;
+ m_nFormat = Format::kUnPreMultiplied;
+ if (priorFormat != Format::kPreMultiplied)
return;
- }
- int height = pDIBitmap->GetHeight();
- int width = pDIBitmap->GetWidth();
- int rowBytes = pDIBitmap->GetPitch();
+ this->DebugVerifyBitmapIsPreMultiplied();
+ int height = this->GetHeight();
+ int width = this->GetWidth();
+ int rowBytes = this->GetPitch();
SkImageInfo premultipliedInfo =
SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType);
SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes);
@@ -1909,7 +1916,6 @@ void CFX_SkiaDeviceDriver::UnPreMultiply(CFX_DIBitmap* pDIBitmap) {
SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType);
SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes);
premultiplied.readPixels(unpremultiplied);
- pDIBitmap->MarkForUnPreMultiply(false);
}
#endif // _SKIA_SUPPORT_PATHS_
@@ -1977,10 +1983,10 @@ void CFX_SkiaDeviceDriver::Clear(uint32_t color) {
#endif // _SKIA_SUPPORT_
void CFX_SkiaDeviceDriver::Dump() const {
-#if SHOW_SKIA_PATH
+#if SHOW_SKIA_PATH && defined _SKIA_SUPPORT_
if (m_pCache)
m_pCache->Dump(this);
-#endif // SHOW_SKIA_PATH
+#endif // SHOW_SKIA_PATH && defined _SKIA_SUPPORT_
}
#ifdef _SKIA_SUPPORT_
@@ -1990,12 +1996,6 @@ void CFX_SkiaDeviceDriver::DebugVerifyBitmapIsPreMultiplied() const {
}
#endif // _SKIA_SUPPORT_
-#ifdef _SKIA_SUPPORT_PATHS_
-void CFX_SkiaDeviceDriver::UnPreMultiplyDevice() {
- UnPreMultiply(m_pBitmap);
-}
-#endif // _SKIA_SUPPORT_PATHS_
-
CFX_FxgeDevice::CFX_FxgeDevice() {
#ifdef _SKIA_SUPPORT_
m_bOwnedBitmap = false;
@@ -2087,15 +2087,6 @@ bool CFX_FxgeDevice::SetBitsWithMask(const CFX_DIBSource* pBitmap,
}
#endif // _SKIA_SUPPORT_
-#ifdef _SKIA_SUPPORT_PATHS_
-void CFX_FxgeDevice::UnPreMultiplyDevice() {
- CFX_SkiaDeviceDriver* skDriver =
- static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver());
- if (skDriver)
- skDriver->UnPreMultiplyDevice();
-}
-#endif // _SKIA_SUPPORT_PATHS_
-
void CFX_DIBSource::DebugVerifyBitmapIsPreMultiplied(void* opt) const {
#ifdef SK_DEBUG
SkASSERT(32 == GetBPP());
diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h
index f2576a888d..06b7be3d82 100644
--- a/core/fxge/skia/fx_skia_device.h
+++ b/core/fxge/skia/fx_skia_device.h
@@ -140,13 +140,11 @@ class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver {
FX_FLOAT font_size,
uint32_t color) override;
-#ifdef _SKIA_SUPPORT_
bool DrawShading(const CPDF_ShadingPattern* pPattern,
const CFX_Matrix* pMatrix,
const FX_RECT& clip_rect,
int alpha,
bool bAlphaMode) override;
-#endif
virtual uint8_t* GetBuffer() const;
@@ -157,10 +155,6 @@ class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver {
void Flush();
SkPictureRecorder* GetRecorder() const { return m_pRecorder; }
static void PreMultiply(CFX_DIBitmap* pDIBitmap);
-#ifdef _SKIA_SUPPORT_PATHS_
- void UnPreMultiplyDevice();
- void UnPreMultiply(CFX_DIBitmap* pDIBitmap);
-#endif
SkCanvas* SkiaCanvas() { return m_pCanvas; }
void DebugVerifyBitmapIsPreMultiplied() const;
void Dump() const;
diff --git a/fpdfsdk/fpdfformfill.cpp b/fpdfsdk/fpdfformfill.cpp
index e8a8a6e2d0..44204b766a 100644
--- a/fpdfsdk/fpdfformfill.cpp
+++ b/fpdfsdk/fpdfformfill.cpp
@@ -137,6 +137,9 @@ void FFLCommon(FPDF_FORMHANDLE hHandle,
pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options);
#endif // PDF_ENABLE_XFA
+#ifdef _SKIA_SUPPORT_PATHS
+ CFXBitmapFromFPDFBitmap(bitmap)->UnPreMultiply();
+#endif
pDevice->RestoreState(false);
delete options.m_pOCContext;
options.m_pOCContext = nullptr;
diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
index d5f9a0e810..959bf14390 100644
--- a/fpdfsdk/fpdfview.cpp
+++ b/fpdfsdk/fpdfview.cpp
@@ -598,6 +598,9 @@ DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap,
FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
rotate, flags, true, nullptr);
+#ifdef _SKIA_SUPPORT_PATHS_
+ pBitmap->UnPreMultiply();
+#endif
pPage->SetRenderContext(nullptr);
}