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
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index d2a17d2..aad9af0 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -893,6 +893,9 @@
   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 @@
 #if defined _SKIA_SUPPORT_
   DebugVerifyDeviceIsPreMultiplied();
 #endif
-#if defined _SKIA_SUPPORT_PATHS_
-  UnPreMultiplyDevice();
-#endif
 }
 
 bool CPDF_RenderStatus::DrawObjWithBlend(CPDF_PageObject* pObj,
@@ -1547,6 +1547,9 @@
                            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 @@
 }
 #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 f74f0ce..b7e9fa6 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.h
+++ b/core/fpdfapi/render/cpdf_renderstatus.h
@@ -66,10 +66,6 @@
   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 03fece7..8358e43 100644
--- a/core/fxge/cfx_fxgedevice.h
+++ b/core/fxge/cfx_fxgedevice.h
@@ -39,10 +39,6 @@
                        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 6da1df7..d38b298 100644
--- a/core/fxge/cfx_renderdevice.h
+++ b/core/fxge/cfx_renderdevice.h
@@ -230,10 +230,6 @@
   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 63db7ad..8389955 100644
--- a/core/fxge/dib/fx_dib_main.cpp
+++ b/core/fxge/dib/fx_dib_main.cpp
@@ -67,7 +67,7 @@
   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 daf2cdf..1719ae1 100644
--- a/core/fxge/fx_dib.h
+++ b/core/fxge/fx_dib.h
@@ -371,20 +371,25 @@
 
   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);
 
-  uint8_t* m_pBuffer;
-  bool m_bExtBuf;
-#ifdef _SKIA_SUPPORT_PATHS_
-  bool m_bUnPreMultiply;
+#if defined _SKIA_SUPPORT_PATHS_
+  enum class Format { kCleared, kPreMultiplied, kUnPreMultiplied };
 #endif
+
+  uint8_t* m_pBuffer;
+#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 1013527..64fa6ff 100644
--- a/core/fxge/ge/cfx_renderdevice.cpp
+++ b/core/fxge/ge/cfx_renderdevice.cpp
@@ -822,12 +822,6 @@
 }
 #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 973c4f2..136bab7 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 @@
   }
 }
 
-#ifdef _SKIA_SUPPORT_
 bool AddColors(const CPDF_ExpIntFunc* pFunc, SkTDArray<SkColor>* skColors) {
   if (pFunc->CountInputs() != 1)
     return false;
@@ -497,6 +496,7 @@
   clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt));
 }
 
+#ifdef _SKIA_SUPPORT_
 void SetBitmapMatrix(const CFX_Matrix* pMatrix,
                      int width,
                      int height,
@@ -1171,14 +1171,12 @@
     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 @@
     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 @@
     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 @@
   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 @@
   m_pCanvas->restore();
   return true;
 }
-#endif  // _SKIA_SUPPORT_
 
 uint8_t* CFX_SkiaDeviceDriver::GetBuffer() const {
   return m_pBitmap->GetBuffer();
@@ -1680,6 +1676,7 @@
 #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 @@
 #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 @@
 #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 @@
       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 @@
       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 @@
 #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 @@
 }
 #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 @@
 }
 #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 f2576a8..06b7be3 100644
--- a/core/fxge/skia/fx_skia_device.h
+++ b/core/fxge/skia/fx_skia_device.h
@@ -140,13 +140,11 @@
                       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 @@
   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 e8a8a6e..44204b7 100644
--- a/fpdfsdk/fpdfformfill.cpp
+++ b/fpdfsdk/fpdfformfill.cpp
@@ -137,6 +137,9 @@
     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 d5f9a0e..959bf14 100644
--- a/fpdfsdk/fpdfview.cpp
+++ b/fpdfsdk/fpdfview.cpp
@@ -598,6 +598,9 @@
   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);
 }