Change FXDIB_BLEND_FOO typedefs to an enum class.

BUG=pdfium:1085

Change-Id: Ieb43d4588e1d689e327e428dcbbf7adba45ce178
Reviewed-on: https://pdfium-review.googlesource.com/c/44545
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index b29d5b3..717a83c 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -439,7 +439,7 @@
   graphD.strokeAlpha = pPageObj->m_GeneralState.GetStrokeAlpha();
   graphD.blendType = pPageObj->m_GeneralState.GetBlendType();
   if (graphD.fillAlpha == 1.0f && graphD.strokeAlpha == 1.0f &&
-      graphD.blendType == FXDIB_BLEND_NORMAL) {
+      graphD.blendType == BlendMode::kNormal) {
     return;
   }
 
@@ -455,7 +455,7 @@
     if (graphD.strokeAlpha != 1.0f)
       gsDict->SetNewFor<CPDF_Number>("CA", graphD.strokeAlpha);
 
-    if (graphD.blendType != FXDIB_BLEND_NORMAL) {
+    if (graphD.blendType != BlendMode::kNormal) {
       gsDict->SetNewFor<CPDF_Name>("BM",
                                    pPageObj->m_GeneralState.GetBlendMode());
     }
@@ -479,7 +479,7 @@
   GraphicsData defaultGraphics;
   defaultGraphics.fillAlpha = 1.0f;
   defaultGraphics.strokeAlpha = 1.0f;
-  defaultGraphics.blendType = FXDIB_BLEND_NORMAL;
+  defaultGraphics.blendType = BlendMode::kNormal;
   auto it = m_pObjHolder->m_GraphicsMap.find(defaultGraphics);
 
   // If default graphics already exists, return it.
diff --git a/core/fpdfapi/page/cpdf_allstates.cpp b/core/fpdfapi/page/cpdf_allstates.cpp
index 3e6692b..81df192 100644
--- a/core/fpdfapi/page/cpdf_allstates.cpp
+++ b/core/fpdfapi/page/cpdf_allstates.cpp
@@ -99,7 +99,7 @@
         CPDF_Array* pArray = pObject->AsArray();
         m_GeneralState.SetBlendMode(pArray ? pArray->GetStringAt(0)
                                            : pObject->GetString());
-        if (m_GeneralState.GetBlendType() > FXDIB_BLEND_MULTIPLY)
+        if (m_GeneralState.GetBlendType() > BlendMode::kMultiply)
           pParser->GetPageObjectHolder()->SetBackgroundAlphaNeeded(true);
         break;
       }
diff --git a/core/fpdfapi/page/cpdf_contentparser.cpp b/core/fpdfapi/page/cpdf_contentparser.cpp
index cf31447..90d6925 100644
--- a/core/fpdfapi/page/cpdf_contentparser.cpp
+++ b/core/fpdfapi/page/cpdf_contentparser.cpp
@@ -103,7 +103,7 @@
   }
   if (pForm->GetTransparency().IsGroup()) {
     CPDF_GeneralState* pState = &m_pParser->GetCurStates()->m_GeneralState;
-    pState->SetBlendType(FXDIB_BLEND_NORMAL);
+    pState->SetBlendType(BlendMode::kNormal);
     pState->SetStrokeAlpha(1.0f);
     pState->SetFillAlpha(1.0f);
     pState->SetSoftMask(nullptr);
diff --git a/core/fpdfapi/page/cpdf_generalstate.cpp b/core/fpdfapi/page/cpdf_generalstate.cpp
index 7687626..cf942ab 100644
--- a/core/fpdfapi/page/cpdf_generalstate.cpp
+++ b/core/fpdfapi/page/cpdf_generalstate.cpp
@@ -27,43 +27,43 @@
   return 0;
 }
 
-int GetBlendTypeInternal(const ByteString& mode) {
+BlendMode GetBlendTypeInternal(const ByteString& mode) {
   switch (mode.GetID()) {
     case FXBSTR_ID('N', 'o', 'r', 'm'):
     case FXBSTR_ID('C', 'o', 'm', 'p'):
-      return FXDIB_BLEND_NORMAL;
+      return BlendMode::kNormal;
     case FXBSTR_ID('M', 'u', 'l', 't'):
-      return FXDIB_BLEND_MULTIPLY;
+      return BlendMode::kMultiply;
     case FXBSTR_ID('S', 'c', 'r', 'e'):
-      return FXDIB_BLEND_SCREEN;
+      return BlendMode::kScreen;
     case FXBSTR_ID('O', 'v', 'e', 'r'):
-      return FXDIB_BLEND_OVERLAY;
+      return BlendMode::kOverlay;
     case FXBSTR_ID('D', 'a', 'r', 'k'):
-      return FXDIB_BLEND_DARKEN;
+      return BlendMode::kDarken;
     case FXBSTR_ID('L', 'i', 'g', 'h'):
-      return FXDIB_BLEND_LIGHTEN;
+      return BlendMode::kLighten;
     case FXBSTR_ID('C', 'o', 'l', 'o'):
       if (mode.GetLength() == 10)
-        return FXDIB_BLEND_COLORDODGE;
+        return BlendMode::kColorDodge;
       if (mode.GetLength() == 9)
-        return FXDIB_BLEND_COLORBURN;
-      return FXDIB_BLEND_COLOR;
+        return BlendMode::kColorBurn;
+      return BlendMode::kColor;
     case FXBSTR_ID('H', 'a', 'r', 'd'):
-      return FXDIB_BLEND_HARDLIGHT;
+      return BlendMode::kHardLight;
     case FXBSTR_ID('S', 'o', 'f', 't'):
-      return FXDIB_BLEND_SOFTLIGHT;
+      return BlendMode::kSoftLight;
     case FXBSTR_ID('D', 'i', 'f', 'f'):
-      return FXDIB_BLEND_DIFFERENCE;
+      return BlendMode::kDifference;
     case FXBSTR_ID('E', 'x', 'c', 'l'):
-      return FXDIB_BLEND_EXCLUSION;
+      return BlendMode::kExclusion;
     case FXBSTR_ID('H', 'u', 'e', 0):
-      return FXDIB_BLEND_HUE;
+      return BlendMode::kHue;
     case FXBSTR_ID('S', 'a', 't', 'u'):
-      return FXDIB_BLEND_SATURATION;
+      return BlendMode::kSaturation;
     case FXBSTR_ID('L', 'u', 'm', 'i'):
-      return FXDIB_BLEND_LUMINOSITY;
+      return BlendMode::kLuminosity;
   }
-  return FXDIB_BLEND_NORMAL;
+  return BlendMode::kNormal;
 }
 
 }  // namespace
@@ -81,48 +81,48 @@
 
 ByteString CPDF_GeneralState::GetBlendMode() const {
   switch (GetBlendType()) {
-    case FXDIB_BLEND_NORMAL:
+    case BlendMode::kNormal:
       return ByteString(pdfium::transparency::kNormal);
-    case FXDIB_BLEND_MULTIPLY:
+    case BlendMode::kMultiply:
       return ByteString(pdfium::transparency::kMultiply);
-    case FXDIB_BLEND_SCREEN:
+    case BlendMode::kScreen:
       return ByteString(pdfium::transparency::kScreen);
-    case FXDIB_BLEND_OVERLAY:
+    case BlendMode::kOverlay:
       return ByteString(pdfium::transparency::kOverlay);
-    case FXDIB_BLEND_DARKEN:
+    case BlendMode::kDarken:
       return ByteString(pdfium::transparency::kDarken);
-    case FXDIB_BLEND_LIGHTEN:
+    case BlendMode::kLighten:
       return ByteString(pdfium::transparency::kLighten);
-    case FXDIB_BLEND_COLORDODGE:
+    case BlendMode::kColorDodge:
       return ByteString(pdfium::transparency::kColorDodge);
-    case FXDIB_BLEND_COLORBURN:
+    case BlendMode::kColorBurn:
       return ByteString(pdfium::transparency::kColorBurn);
-    case FXDIB_BLEND_HARDLIGHT:
+    case BlendMode::kHardLight:
       return ByteString(pdfium::transparency::kHardLight);
-    case FXDIB_BLEND_SOFTLIGHT:
+    case BlendMode::kSoftLight:
       return ByteString(pdfium::transparency::kSoftLight);
-    case FXDIB_BLEND_DIFFERENCE:
+    case BlendMode::kDifference:
       return ByteString(pdfium::transparency::kDifference);
-    case FXDIB_BLEND_EXCLUSION:
+    case BlendMode::kExclusion:
       return ByteString(pdfium::transparency::kExclusion);
-    case FXDIB_BLEND_HUE:
+    case BlendMode::kHue:
       return ByteString(pdfium::transparency::kHue);
-    case FXDIB_BLEND_SATURATION:
+    case BlendMode::kSaturation:
       return ByteString(pdfium::transparency::kSaturation);
-    case FXDIB_BLEND_COLOR:
+    case BlendMode::kColor:
       return ByteString(pdfium::transparency::kColor);
-    case FXDIB_BLEND_LUMINOSITY:
+    case BlendMode::kLuminosity:
       return ByteString(pdfium::transparency::kLuminosity);
   }
   return ByteString(pdfium::transparency::kNormal);
 }
 
-int CPDF_GeneralState::GetBlendType() const {
+BlendMode CPDF_GeneralState::GetBlendType() const {
   const StateData* pData = m_Ref.GetObject();
-  return pData ? pData->m_BlendType : FXDIB_BLEND_NORMAL;
+  return pData ? pData->m_BlendType : BlendMode::kNormal;
 }
 
-void CPDF_GeneralState::SetBlendType(int type) {
+void CPDF_GeneralState::SetBlendType(BlendMode type) {
   m_Ref.GetPrivateCopy()->m_BlendType = type;
 }
 
diff --git a/core/fpdfapi/page/cpdf_generalstate.h b/core/fpdfapi/page/cpdf_generalstate.h
index 096271f..4df3d0e 100644
--- a/core/fpdfapi/page/cpdf_generalstate.h
+++ b/core/fpdfapi/page/cpdf_generalstate.h
@@ -29,8 +29,8 @@
   void SetRenderIntent(const ByteString& ri);
 
   ByteString GetBlendMode() const;
-  int GetBlendType() const;
-  void SetBlendType(int type);
+  BlendMode GetBlendType() const;
+  void SetBlendType(BlendMode type);
 
   float GetFillAlpha() const;
   void SetFillAlpha(float alpha);
@@ -85,7 +85,7 @@
     ~StateData() override;
 
     ByteString m_BlendMode = pdfium::transparency::kNormal;
-    int m_BlendType = FXDIB_BLEND_NORMAL;
+    BlendMode m_BlendType = BlendMode::kNormal;
     UnownedPtr<CPDF_Object> m_pSoftMask;
     CFX_Matrix m_SMaskMatrix;
     float m_StrokeAlpha = 1.0f;
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.h b/core/fpdfapi/page/cpdf_pageobjectholder.h
index 4f5a60f..5949329 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder.h
+++ b/core/fpdfapi/page/cpdf_pageobjectholder.h
@@ -18,6 +18,7 @@
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/unowned_ptr.h"
+#include "core/fxge/fx_dib.h"
 
 class CPDF_ContentParser;
 class CPDF_Dictionary;
@@ -30,13 +31,15 @@
 struct GraphicsData {
   float fillAlpha;
   float strokeAlpha;
-  int blendType;
+  BlendMode blendType;
+
   bool operator<(const GraphicsData& other) const;
 };
 
 struct FontData {
   ByteString baseFont;
   ByteString type;
+
   bool operator<(const FontData& other) const;
 };
 
diff --git a/core/fpdfapi/page/cpdf_pageobjectholder_unittest.cpp b/core/fpdfapi/page/cpdf_pageobjectholder_unittest.cpp
index ddad795..7760256 100644
--- a/core/fpdfapi/page/cpdf_pageobjectholder_unittest.cpp
+++ b/core/fpdfapi/page/cpdf_pageobjectholder_unittest.cpp
@@ -18,7 +18,7 @@
   // Verify self-comparisions.
   for (float c1 : {fMin, 1.0f, 2.0f, fMax, fInf, fNan}) {
     for (float c2 : {fMin, 1.0f, 2.0f, fMax, fInf, fNan}) {
-      for (int c3 : {1, 2})
+      for (BlendMode c3 : {BlendMode::kMultiply, BlendMode::kScreen})
         EXPECT_FALSE(GraphicsData({c1, c2, c3}) < GraphicsData({c1, c2, c3}));
     }
   }
@@ -27,7 +27,7 @@
 
   // Insert in reverse index permuted order.
   size_t x = 0;
-  for (int c3 : {2, 1}) {
+  for (BlendMode c3 : {BlendMode::kScreen, BlendMode::kMultiply}) {
     for (float c2 : {fNan, fInf, fMax, 2.0f, 1.0f, fMin}) {
       for (float c1 : {fNan, fInf, fMax, 2.0f, 1.0f, fMin}) {
         graphics_map[{c1, c2, c3}] = x++;
@@ -56,7 +56,7 @@
   EXPECT_EQ(72u, x);
 
   // Erase in forward index permuted order.
-  for (int c3 : {1, 2}) {
+  for (BlendMode c3 : {BlendMode::kMultiply, BlendMode::kScreen}) {
     for (float c2 : {fMin, 1.0f, 2.0f, fMax, fInf, fNan}) {
       for (float c1 : {fMin, 1.0f, 2.0f, fMax, fInf, fNan})
         graphics_map.erase({c1, c2, c3});
diff --git a/core/fpdfapi/render/cpdf_devicebuffer.cpp b/core/fpdfapi/render/cpdf_devicebuffer.cpp
index b29db00..4029f2e 100644
--- a/core/fpdfapi/render/cpdf_devicebuffer.cpp
+++ b/core/fpdfapi/render/cpdf_devicebuffer.cpp
@@ -64,7 +64,7 @@
                                     m_pBitmap->GetHeight());
   m_pContext->GetBackground(pBuffer, m_pObject.Get(), nullptr, &m_Matrix);
   pBuffer->CompositeBitmap(0, 0, pBuffer->GetWidth(), pBuffer->GetHeight(),
-                           m_pBitmap, 0, 0, FXDIB_BLEND_NORMAL, nullptr, false);
+                           m_pBitmap, 0, 0, BlendMode::kNormal, nullptr, false);
   m_pDevice->StretchDIBits(pBuffer, m_Rect.left, m_Rect.top, m_Rect.Width(),
                            m_Rect.Height());
 }
diff --git a/core/fpdfapi/render/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp
index 362cf55..03e00a2 100644
--- a/core/fpdfapi/render/cpdf_imagerenderer.cpp
+++ b/core/fpdfapi/render/cpdf_imagerenderer.cpp
@@ -118,7 +118,7 @@
     return DrawPatternImage(m_pObj2Device.Get());
 
   if (m_BitmapAlpha != 255 || !state.HasRef() || !state.GetFillOP() ||
-      state.GetOPMode() != 0 || state.GetBlendType() != FXDIB_BLEND_NORMAL ||
+      state.GetOPMode() != 0 || state.GetBlendType() != BlendMode::kNormal ||
       state.GetStrokeAlpha() != 1.0f || state.GetFillAlpha() != 1.0f) {
     return StartDIBBase();
   }
@@ -142,7 +142,7 @@
   int format = pColorSpace->GetFamily();
   if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
       format == PDFCS_DEVICEN) {
-    m_BlendType = FXDIB_BLEND_DARKEN;
+    m_BlendType = BlendMode::kDarken;
   }
   pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
   return StartDIBBase();
@@ -152,7 +152,7 @@
                                CPDF_ImageObject* pImageObject,
                                const CFX_Matrix* pObj2Device,
                                bool bStdCS,
-                               int blendType) {
+                               BlendMode blendType) {
   ASSERT(pImageObject);
   m_pRenderStatus = pStatus;
   m_bStdCS = bStdCS;
@@ -178,7 +178,7 @@
                                const CFX_Matrix* pImage2Device,
                                uint32_t flags,
                                bool bStdCS,
-                               int blendType) {
+                               BlendMode blendType) {
   m_pRenderStatus = pStatus;
   m_pDIBBase = pDIBBase;
   m_FillArgb = bitmap_argb;
@@ -222,7 +222,7 @@
 
   CPDF_ImageRenderer image_render;
   if (image_render.Start(&bitmap_render, pDIBBase, 0xffffffff, 255, pNewMatrix,
-                         m_Flags, true, FXDIB_BLEND_NORMAL)) {
+                         m_Flags, true, BlendMode::kNormal)) {
     image_render.Continue(nullptr);
   }
   if (m_Loader.MatteColor() == 0xffffffff)
@@ -333,7 +333,7 @@
   bitmap_render.Initialize(nullptr, nullptr);
   CPDF_ImageRenderer image_render;
   if (image_render.Start(&bitmap_render, m_pDIBBase, 0, 255, &new_matrix,
-                         m_Flags, true, FXDIB_BLEND_NORMAL)) {
+                         m_Flags, true, BlendMode::kNormal)) {
     image_render.Continue(nullptr);
   }
   CFX_DefaultRenderDevice bitmap_device2;
diff --git a/core/fpdfapi/render/cpdf_imagerenderer.h b/core/fpdfapi/render/cpdf_imagerenderer.h
index c538d9f..6df412f 100644
--- a/core/fpdfapi/render/cpdf_imagerenderer.h
+++ b/core/fpdfapi/render/cpdf_imagerenderer.h
@@ -13,6 +13,7 @@
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/dib/cfx_imagerenderer.h"
+#include "core/fxge/fx_dib.h"
 
 class CFX_DIBitmap;
 class CFX_DIBBase;
@@ -33,7 +34,7 @@
              CPDF_ImageObject* pImageObject,
              const CFX_Matrix* pObj2Device,
              bool bStdCS,
-             int blendType);
+             BlendMode blendType);
 
   bool Start(CPDF_RenderStatus* pStatus,
              const RetainPtr<CFX_DIBBase>& pDIBBase,
@@ -42,7 +43,7 @@
              const CFX_Matrix* pImage2Device,
              uint32_t flags,
              bool bStdCS,
-             int blendType);
+             BlendMode blendType);
 
   bool Continue(PauseIndicatorIface* pPause);
   bool GetResult() const { return m_Result; }
@@ -76,7 +77,7 @@
   std::unique_ptr<CFX_ImageRenderer> m_DeviceHandle;
   int m_Status = 0;
   int m_BitmapAlpha = 0;
-  int m_BlendType = FXDIB_BLEND_NORMAL;
+  BlendMode m_BlendType = BlendMode::kNormal;
   FX_ARGB m_FillArgb = 0;
   uint32_t m_Flags = 0;
   bool m_bPatternColor = false;
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 4e9c69b..b409203 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -1110,7 +1110,7 @@
 
   m_pImageRenderer = pdfium::MakeUnique<CPDF_ImageRenderer>();
   if (!m_pImageRenderer->Start(this, pObj->AsImage(), &mtObj2Device, false,
-                               FXDIB_BLEND_NORMAL)) {
+                               BlendMode::kNormal)) {
     if (!m_pImageRenderer->GetResult())
       DrawObjWithBackground(pObj, mtObj2Device);
     m_pImageRenderer.reset();
@@ -1437,7 +1437,7 @@
 #if defined _SKIA_SUPPORT_
   DebugVerifyDeviceIsPreMultiplied();
 #endif
-  int blend_type = pPageObj->m_GeneralState.GetBlendType();
+  BlendMode blend_type = pPageObj->m_GeneralState.GetBlendType();
   CPDF_Dictionary* pSMaskDict =
       ToDictionary(pPageObj->m_GeneralState.GetSoftMask());
   if (pSMaskDict) {
@@ -1488,12 +1488,12 @@
       int format = pColorSpace->GetFamily();
       if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION ||
           format == PDFCS_DEVICEN) {
-        blend_type = FXDIB_BLEND_DARKEN;
+        blend_type = BlendMode::kDarken;
       }
       pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
     }
   }
-  if (!pSMaskDict && group_alpha == 1.0f && blend_type == FXDIB_BLEND_NORMAL &&
+  if (!pSMaskDict && group_alpha == 1.0f && blend_type == BlendMode::kNormal &&
       !bTextClip && !bGroupTransparent) {
     return false;
   }
@@ -1502,7 +1502,7 @@
     int rendCaps = m_pDevice->GetRenderCaps();
     if (!(transparency.IsIsolated() || pSMaskDict || bTextClip) &&
         (rendCaps & FXRC_BLEND_MODE)) {
-      int oldBlend = m_curBlend;
+      BlendMode oldBlend = m_curBlend;
       m_curBlend = blend_type;
       bRet = DrawObjWithBlend(pPageObj, mtObj2Device);
       m_curBlend = oldBlend;
@@ -1910,7 +1910,7 @@
         image_matrix.Concat(matrix);
         CPDF_ImageRenderer renderer;
         if (renderer.Start(this, pType3Char->GetBitmap(), fill_argb, 255,
-                           &image_matrix, 0, false, FXDIB_BLEND_NORMAL)) {
+                           &image_matrix, 0, false, BlendMode::kNormal)) {
           renderer.Continue(nullptr);
         }
         if (!renderer.GetResult())
@@ -1948,7 +1948,7 @@
                            glyph.m_pGlyph->m_pBitmap->GetWidth(),
                            glyph.m_pGlyph->m_pBitmap->GetHeight(),
                            glyph.m_pGlyph->m_pBitmap, fill_argb, 0, 0,
-                           FXDIB_BLEND_NORMAL, nullptr, false, 0);
+                           BlendMode::kNormal, nullptr, false, 0);
   }
   m_pDevice->SetBitMask(pBitmap, rect.left, rect.top, fill_argb);
   return true;
@@ -2315,18 +2315,18 @@
       } else {
         if (pPattern->colored()) {
           pScreen->CompositeBitmap(start_x, start_y, width, height,
-                                   pPatternBitmap, 0, 0, FXDIB_BLEND_NORMAL,
+                                   pPatternBitmap, 0, 0, BlendMode::kNormal,
                                    nullptr, false);
         } else {
           pScreen->CompositeMask(start_x, start_y, width, height,
                                  pPatternBitmap, fill_argb, 0, 0,
-                                 FXDIB_BLEND_NORMAL, nullptr, false, 0);
+                                 BlendMode::kNormal, nullptr, false, 0);
         }
       }
     }
   }
   CompositeDIBitmap(pScreen, clip_box.left, clip_box.top, 0, 255,
-                    FXDIB_BLEND_NORMAL, CPDF_Transparency());
+                    BlendMode::kNormal, CPDF_Transparency());
 }
 
 void CPDF_RenderStatus::DrawPathWithPattern(CPDF_PathObject* pPathObj,
@@ -2380,12 +2380,12 @@
     int top,
     FX_ARGB mask_argb,
     int bitmap_alpha,
-    int blend_mode,
+    BlendMode blend_mode,
     const CPDF_Transparency& transparency) {
   if (!pDIBitmap)
     return;
 
-  if (blend_mode == FXDIB_BLEND_NORMAL) {
+  if (blend_mode == BlendMode::kNormal) {
     if (!pDIBitmap->IsAlphaMask()) {
       if (bitmap_alpha < 255) {
 #ifdef _SKIA_SUPPORT_
@@ -2416,7 +2416,8 @@
     }
   }
   bool bIsolated = transparency.IsIsolated();
-  bool bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects;
+  bool bBackAlphaRequired =
+      blend_mode != BlendMode::kNormal && bIsolated && !m_bDropObjects;
   bool bGetBackGround =
       ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
       (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
@@ -2440,7 +2441,7 @@
       RetainPtr<CFX_DIBitmap> pForeBitmap = m_pDevice->GetBitmap();
       pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                               pForeBitmap, rect.left, rect.top,
-                              FXDIB_BLEND_NORMAL, nullptr, false);
+                              BlendMode::kNormal, nullptr, false);
       left = std::min(left, 0);
       top = std::min(top, 0);
       if (pDIBitmap->IsAlphaMask()) {
@@ -2470,7 +2471,7 @@
   FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
                top + pDIBitmap->GetHeight());
   RetainPtr<CFX_DIBitmap> pBackdrop = GetBackdrop(
-      m_pCurObj.Get(), rect, blend_mode > FXDIB_BLEND_NORMAL && bIsolated,
+      m_pCurObj.Get(), rect, blend_mode != BlendMode::kNormal && bIsolated,
       &back_left, &back_top);
   if (!pBackdrop)
     return;
@@ -2492,7 +2493,7 @@
   pBackdrop1->Clear((uint32_t)-1);
   pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(),
                               pBackdrop->GetHeight(), pBackdrop, 0, 0,
-                              FXDIB_BLEND_NORMAL, nullptr, false);
+                              BlendMode::kNormal, nullptr, false);
   pBackdrop = std::move(pBackdrop1);
   m_pDevice->SetDIBits(pBackdrop, back_left, back_top);
 }
diff --git a/core/fpdfapi/render/cpdf_renderstatus.h b/core/fpdfapi/render/cpdf_renderstatus.h
index a4f3fd4..1911758a 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.h
+++ b/core/fpdfapi/render/cpdf_renderstatus.h
@@ -16,6 +16,7 @@
 #include "core/fpdfapi/render/cpdf_renderoptions.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/cfx_renderdevice.h"
+#include "core/fxge/fx_dib.h"
 
 class CFX_PathData;
 class CPDF_Color;
@@ -111,7 +112,7 @@
                          int top,
                          FX_ARGB mask_argb,
                          int bitmap_alpha,
-                         int blend_mode,
+                         BlendMode blend_mode,
                          const CPDF_Transparency& transparency);
 
  private:
@@ -202,7 +203,7 @@
   uint32_t m_GroupFamily = 0;
   UnownedPtr<CPDF_Type3Char> m_pType3Char;
   FX_ARGB m_T3FillColor = 0;
-  int m_curBlend = FXDIB_BLEND_NORMAL;
+  BlendMode m_curBlend = BlendMode::kNormal;
 };
 
 #endif  // CORE_FPDFAPI_RENDER_CPDF_RENDERSTATUS_H_
diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp
index 39b31b5..6e680b9 100644
--- a/core/fxge/agg/fx_agg_driver.cpp
+++ b/core/fxge/agg/fx_agg_driver.cpp
@@ -1311,8 +1311,8 @@
                                    uint32_t fill_color,
                                    uint32_t stroke_color,
                                    int fill_mode,
-                                   int blend_type) {
-  if (blend_type != FXDIB_BLEND_NORMAL)
+                                   BlendMode blend_type) {
+  if (blend_type != BlendMode::kNormal)
     return false;
 
   if (!GetBuffer())
@@ -1410,8 +1410,8 @@
 
 bool CFX_AggDeviceDriver::FillRectWithBlend(const FX_RECT& rect,
                                             uint32_t fill_color,
-                                            int blend_type) {
-  if (blend_type != FXDIB_BLEND_NORMAL)
+                                            BlendMode blend_type) {
+  if (blend_type != BlendMode::kNormal)
     return false;
 
   if (!m_pBitmap->GetBuffer())
@@ -1438,7 +1438,7 @@
   m_pBitmap->CompositeMask(draw_rect.left, draw_rect.top, draw_rect.Width(),
                            draw_rect.Height(), m_pClipRgn->GetMask(),
                            fill_color, draw_rect.left - clip_rect.left,
-                           draw_rect.top - clip_rect.top, FXDIB_BLEND_NORMAL,
+                           draw_rect.top - clip_rect.top, BlendMode::kNormal,
                            nullptr, m_bRgbByteOrder, 0);
   return true;
 }
@@ -1469,7 +1469,7 @@
       return true;
 
     pBack->CompositeBitmap(0, 0, pBack->GetWidth(), pBack->GetHeight(),
-                           m_pBitmap, 0, 0, FXDIB_BLEND_NORMAL, nullptr, false);
+                           m_pBitmap, 0, 0, BlendMode::kNormal, nullptr, false);
   } else {
     pBack = m_pBitmap->Clone(&rect);
     if (!pBack)
@@ -1496,7 +1496,7 @@
                                     const FX_RECT* pSrcRect,
                                     int left,
                                     int top,
-                                    int blend_type) {
+                                    BlendMode blend_type) {
   if (!m_pBitmap->GetBuffer())
     return true;
 
@@ -1519,7 +1519,7 @@
                                         int dest_height,
                                         const FX_RECT* pClipRect,
                                         uint32_t flags,
-                                        int blend_type) {
+                                        BlendMode blend_type) {
   if (!m_pBitmap->GetBuffer())
     return true;
 
@@ -1551,7 +1551,7 @@
     const CFX_Matrix* pMatrix,
     uint32_t render_flags,
     std::unique_ptr<CFX_ImageRenderer>* handle,
-    int blend_type) {
+    BlendMode blend_type) {
   if (!m_pBitmap->GetBuffer())
     return true;
 
diff --git a/core/fxge/agg/fx_agg_driver.h b/core/fxge/agg/fx_agg_driver.h
index 6d6b988..9a8458e 100644
--- a/core/fxge/agg/fx_agg_driver.h
+++ b/core/fxge/agg/fx_agg_driver.h
@@ -57,11 +57,11 @@
                 uint32_t fill_color,
                 uint32_t stroke_color,
                 int fill_mode,
-                int blend_type) override;
+                BlendMode blend_type) override;
   bool SetPixel(int x, int y, uint32_t color) override;
   bool FillRectWithBlend(const FX_RECT& rect,
                          uint32_t fill_color,
-                         int blend_type) override;
+                         BlendMode blend_type) override;
   bool GetClipBox(FX_RECT* pRect) override;
   bool GetDIBits(const RetainPtr<CFX_DIBitmap>& pBitmap,
                  int left,
@@ -72,7 +72,7 @@
                  const FX_RECT* pSrcRect,
                  int left,
                  int top,
-                 int blend_type) override;
+                 BlendMode blend_type) override;
   bool StretchDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                      uint32_t color,
                      int dest_left,
@@ -81,14 +81,14 @@
                      int dest_height,
                      const FX_RECT* pClipRect,
                      uint32_t flags,
-                     int blend_type) override;
+                     BlendMode blend_type) override;
   bool StartDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                    int bitmap_alpha,
                    uint32_t color,
                    const CFX_Matrix* pMatrix,
                    uint32_t flags,
                    std::unique_ptr<CFX_ImageRenderer>* handle,
-                   int blend_type) override;
+                   BlendMode blend_type) override;
   bool ContinueDIBits(CFX_ImageRenderer* handle,
                       PauseIndicatorIface* pPause) override;
   bool DrawDeviceText(int nChars,
diff --git a/core/fxge/cfx_defaultrenderdevice.h b/core/fxge/cfx_defaultrenderdevice.h
index 937088f..d001775 100644
--- a/core/fxge/cfx_defaultrenderdevice.h
+++ b/core/fxge/cfx_defaultrenderdevice.h
@@ -36,7 +36,7 @@
                        int left,
                        int top,
                        int bitmap_alpha,
-                       int blend_type) override;
+                       BlendMode blend_type) override;
 #endif
 };
 
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index f00d7f9..8afff1e 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -510,7 +510,7 @@
                                          uint32_t fill_color,
                                          uint32_t stroke_color,
                                          int fill_mode,
-                                         int blend_type) {
+                                         BlendMode blend_type) {
   uint8_t stroke_alpha = pGraphState ? FXARGB_A(stroke_color) : 0;
   uint8_t fill_alpha = (fill_mode & 3) ? FXARGB_A(fill_color) : 0;
   const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints();
@@ -618,7 +618,7 @@
                                           uint32_t fill_color,
                                           uint32_t stroke_color,
                                           int fill_mode,
-                                          int blend_type) {
+                                          BlendMode blend_type) {
   if (!(m_RenderCaps & FXRC_GET_BITS))
     return false;
   CFX_FloatRect bbox;
@@ -665,12 +665,12 @@
 #endif
   FX_RECT src_rect(0, 0, rect.Width(), rect.Height());
   return m_pDeviceDriver->SetDIBits(bitmap, 0, &src_rect, rect.left, rect.top,
-                                    FXDIB_BLEND_NORMAL);
+                                    BlendMode::kNormal);
 }
 
 bool CFX_RenderDevice::FillRectWithBlend(const FX_RECT& rect,
                                          uint32_t fill_color,
-                                         int blend_type) {
+                                         BlendMode blend_type) {
   if (m_pDeviceDriver->FillRectWithBlend(rect, fill_color, blend_type))
     return true;
 
@@ -690,7 +690,7 @@
   }
   FX_RECT src_rect(0, 0, rect.Width(), rect.Height());
   m_pDeviceDriver->SetDIBits(bitmap, 0, &src_rect, rect.left, rect.top,
-                             FXDIB_BLEND_NORMAL);
+                             BlendMode::kNormal);
   return true;
 }
 
@@ -698,7 +698,7 @@
                                         const CFX_PointF& ptLineTo,
                                         uint32_t color,
                                         int fill_mode,
-                                        int blend_type) {
+                                        BlendMode blend_type) {
   if ((color >= 0xff000000) && m_pDeviceDriver->DrawCosmeticLine(
                                    ptMoveTo, ptLineTo, color, blend_type)) {
     return true;
@@ -725,7 +725,7 @@
 bool CFX_RenderDevice::SetDIBitsWithBlend(const RetainPtr<CFX_DIBBase>& pBitmap,
                                           int left,
                                           int top,
-                                          int blend_mode) {
+                                          BlendMode blend_mode) {
   ASSERT(!pBitmap->IsAlphaMask());
   FX_RECT dest_rect(left, top, left + pBitmap->GetWidth(),
                     top + pBitmap->GetHeight());
@@ -736,7 +736,7 @@
   FX_RECT src_rect(dest_rect.left - left, dest_rect.top - top,
                    dest_rect.left - left + dest_rect.Width(),
                    dest_rect.top - top + dest_rect.Height());
-  if ((blend_mode == FXDIB_BLEND_NORMAL || (m_RenderCaps & FXRC_BLEND_MODE)) &&
+  if ((blend_mode == BlendMode::kNormal || (m_RenderCaps & FXRC_BLEND_MODE)) &&
       (!pBitmap->HasAlpha() || (m_RenderCaps & FXRC_ALPHA_IMAGE))) {
     return m_pDeviceDriver->SetDIBits(pBitmap, 0, &src_rect, dest_rect.left,
                                       dest_rect.top, blend_mode);
@@ -762,7 +762,7 @@
   }
   FX_RECT rect(0, 0, bg_pixel_width, bg_pixel_height);
   return m_pDeviceDriver->SetDIBits(background, 0, &rect, dest_rect.left,
-                                    dest_rect.top, FXDIB_BLEND_NORMAL);
+                                    dest_rect.top, BlendMode::kNormal);
 }
 
 bool CFX_RenderDevice::StretchDIBitsWithFlagsAndBlend(
@@ -772,7 +772,7 @@
     int dest_width,
     int dest_height,
     uint32_t flags,
-    int blend_mode) {
+    BlendMode blend_mode) {
   FX_RECT dest_rect(left, top, left + dest_width, top + dest_height);
   FX_RECT clip_box = m_ClipBox;
   clip_box.Intersect(dest_rect);
@@ -787,7 +787,7 @@
                                   uint32_t argb) {
   FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
   return m_pDeviceDriver->SetDIBits(pBitmap, argb, &src_rect, left, top,
-                                    FXDIB_BLEND_NORMAL);
+                                    BlendMode::kNormal);
 }
 
 bool CFX_RenderDevice::StretchBitMask(const RetainPtr<CFX_DIBBase>& pBitmap,
@@ -813,7 +813,7 @@
   clip_box.Intersect(dest_rect);
   return m_pDeviceDriver->StretchDIBits(pBitmap, argb, left, top, dest_width,
                                         dest_height, &clip_box, flags,
-                                        FXDIB_BLEND_NORMAL);
+                                        BlendMode::kNormal);
 }
 
 bool CFX_RenderDevice::StartDIBitsWithBlend(
@@ -823,7 +823,7 @@
     const CFX_Matrix* pMatrix,
     uint32_t flags,
     std::unique_ptr<CFX_ImageRenderer>* handle,
-    int blend_mode) {
+    BlendMode blend_mode) {
   return m_pDeviceDriver->StartDIBits(pBitmap, bitmap_alpha, argb, pMatrix,
                                       flags, handle, blend_mode);
 }
@@ -843,7 +843,7 @@
                                        int left,
                                        int top,
                                        int bitmap_alpha,
-                                       int blend_type) {
+                                       BlendMode blend_type) {
   return m_pDeviceDriver->SetBitsWithMask(pBitmap, pMask, left, top,
                                           bitmap_alpha, blend_type);
 }
@@ -1021,7 +1021,7 @@
     if (anti_alias == FXFT_RENDER_MODE_NORMAL) {
       if (!bitmap->CompositeMask(left.ValueOrDie(), top.ValueOrDie(), ncols,
                                  nrows, pGlyph, fill_color, 0, 0,
-                                 FXDIB_BLEND_NORMAL, nullptr, false, 0)) {
+                                 BlendMode::kNormal, nullptr, false, 0)) {
         return false;
       }
       continue;
@@ -1089,7 +1089,7 @@
       fill_mode |= FX_FILL_TEXT_MODE;
       if (!DrawPathWithBlend(&TransformedPath, pUser2Device, pGraphState,
                              fill_color, stroke_color, fill_mode,
-                             FXDIB_BLEND_NORMAL)) {
+                             BlendMode::kNormal)) {
         return false;
       }
     }
diff --git a/core/fxge/cfx_renderdevice.h b/core/fxge/cfx_renderdevice.h
index f0d7898..d181616 100644
--- a/core/fxge/cfx_renderdevice.h
+++ b/core/fxge/cfx_renderdevice.h
@@ -138,7 +138,7 @@
                 uint32_t stroke_color,
                 int fill_mode) {
     return DrawPathWithBlend(pPathData, pObject2Device, pGraphState, fill_color,
-                             stroke_color, fill_mode, FXDIB_BLEND_NORMAL);
+                             stroke_color, fill_mode, BlendMode::kNormal);
   }
   bool DrawPathWithBlend(const CFX_PathData* pPathData,
                          const CFX_Matrix* pObject2Device,
@@ -146,27 +146,27 @@
                          uint32_t fill_color,
                          uint32_t stroke_color,
                          int fill_mode,
-                         int blend_type);
+                         BlendMode blend_type);
   bool FillRect(const FX_RECT& rect, uint32_t color) {
-    return FillRectWithBlend(rect, color, FXDIB_BLEND_NORMAL);
+    return FillRectWithBlend(rect, color, BlendMode::kNormal);
   }
 
   RetainPtr<CFX_DIBitmap> GetBackDrop();
   bool GetDIBits(const RetainPtr<CFX_DIBitmap>& pBitmap, int left, int top);
   bool SetDIBits(const RetainPtr<CFX_DIBBase>& pBitmap, int left, int top) {
-    return SetDIBitsWithBlend(pBitmap, left, top, FXDIB_BLEND_NORMAL);
+    return SetDIBitsWithBlend(pBitmap, left, top, BlendMode::kNormal);
   }
   bool SetDIBitsWithBlend(const RetainPtr<CFX_DIBBase>& pBitmap,
                           int left,
                           int top,
-                          int blend_type);
+                          BlendMode blend_type);
   bool StretchDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                      int left,
                      int top,
                      int dest_width,
                      int dest_height) {
     return StretchDIBitsWithFlagsAndBlend(pBitmap, left, top, dest_width,
-                                          dest_height, 0, FXDIB_BLEND_NORMAL);
+                                          dest_height, 0, BlendMode::kNormal);
   }
   bool StretchDIBitsWithFlagsAndBlend(const RetainPtr<CFX_DIBBase>& pBitmap,
                                       int left,
@@ -174,7 +174,7 @@
                                       int dest_width,
                                       int dest_height,
                                       uint32_t flags,
-                                      int blend_type);
+                                      BlendMode blend_type);
   bool SetBitMask(const RetainPtr<CFX_DIBBase>& pBitmap,
                   int left,
                   int top,
@@ -199,7 +199,7 @@
                    uint32_t flags,
                    std::unique_ptr<CFX_ImageRenderer>* handle) {
     return StartDIBitsWithBlend(pBitmap, bitmap_alpha, color, pMatrix, flags,
-                                handle, FXDIB_BLEND_NORMAL);
+                                handle, BlendMode::kNormal);
   }
   bool StartDIBitsWithBlend(const RetainPtr<CFX_DIBBase>& pBitmap,
                             int bitmap_alpha,
@@ -207,7 +207,7 @@
                             const CFX_Matrix* pMatrix,
                             uint32_t flags,
                             std::unique_ptr<CFX_ImageRenderer>* handle,
-                            int blend_type);
+                            BlendMode blend_type);
   bool ContinueDIBits(CFX_ImageRenderer* handle, PauseIndicatorIface* pPause);
 
   bool DrawNormalText(int nChars,
@@ -271,7 +271,7 @@
                                int left,
                                int top,
                                int bitmap_alpha,
-                               int blend_type);
+                               BlendMode blend_type);
 #endif
 #if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
   void Flush(bool release);
@@ -286,13 +286,15 @@
                           uint32_t fill_color,
                           uint32_t stroke_color,
                           int fill_mode,
-                          int blend_type);
+                          BlendMode blend_type);
   bool DrawCosmeticLine(const CFX_PointF& ptMoveTo,
                         const CFX_PointF& ptLineTo,
                         uint32_t color,
                         int fill_mode,
-                        int blend_type);
-  bool FillRectWithBlend(const FX_RECT& rect, uint32_t color, int blend_type);
+                        BlendMode blend_type);
+  bool FillRectWithBlend(const FX_RECT& rect,
+                         uint32_t color,
+                         BlendMode blend_type);
 
   RetainPtr<CFX_DIBitmap> m_pBitmap;
   int m_Width;
diff --git a/core/fxge/dib/cfx_bitmapcomposer.cpp b/core/fxge/dib/cfx_bitmapcomposer.cpp
index 22e1bc9..000ad91 100644
--- a/core/fxge/dib/cfx_bitmapcomposer.cpp
+++ b/core/fxge/dib/cfx_bitmapcomposer.cpp
@@ -9,10 +9,9 @@
 #include "core/fxge/cfx_cliprgn.h"
 #include "core/fxge/dib/cfx_dibitmap.h"
 
-CFX_BitmapComposer::CFX_BitmapComposer()
-    : m_bRgbByteOrder(false), m_BlendType(FXDIB_BLEND_NORMAL) {}
+CFX_BitmapComposer::CFX_BitmapComposer() = default;
 
-CFX_BitmapComposer::~CFX_BitmapComposer() {}
+CFX_BitmapComposer::~CFX_BitmapComposer() = default;
 
 void CFX_BitmapComposer::Compose(const RetainPtr<CFX_DIBitmap>& pDest,
                                  const CFX_ClipRgn* pClipRgn,
@@ -24,7 +23,7 @@
                                  bool bFlipY,
                                  bool bRgbByteOrder,
                                  int alpha_flag,
-                                 int blend_type) {
+                                 BlendMode blend_type) {
   m_pBitmap = pDest;
   m_pClipRgn = pClipRgn;
   m_DestLeft = dest_rect.left;
@@ -50,7 +49,7 @@
                                  uint32_t* pSrcPalette) {
   m_SrcFormat = src_format;
   if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette,
-                         m_MaskColor, FXDIB_BLEND_NORMAL,
+                         m_MaskColor, BlendMode::kNormal,
                          m_pClipMask != nullptr || (m_BitmapAlpha < 255),
                          m_bRgbByteOrder, m_AlphaFlag)) {
     return false;
diff --git a/core/fxge/dib/cfx_bitmapcomposer.h b/core/fxge/dib/cfx_bitmapcomposer.h
index 50a53db..ef7083d 100644
--- a/core/fxge/dib/cfx_bitmapcomposer.h
+++ b/core/fxge/dib/cfx_bitmapcomposer.h
@@ -14,6 +14,7 @@
 #include "core/fxcrt/unowned_ptr.h"
 #include "core/fxge/dib/cfx_scanlinecompositor.h"
 #include "core/fxge/dib/scanlinecomposer_iface.h"
+#include "core/fxge/fx_dib.h"
 
 class CFX_ClipRgn;
 class CFX_DIBitmap;
@@ -33,7 +34,7 @@
                bool bFlipY,
                bool bRgbByteOrder,
                int alpha_flag,
-               int blend_type);
+               BlendMode blend_type);
 
   // ScanlineComposerIface
   bool SetInfo(int width,
@@ -71,8 +72,8 @@
   bool m_bFlipX;
   bool m_bFlipY;
   int m_AlphaFlag;
-  bool m_bRgbByteOrder;
-  int m_BlendType;
+  bool m_bRgbByteOrder = false;
+  BlendMode m_BlendType = BlendMode::kNormal;
   std::vector<uint8_t> m_pScanlineV;
   std::vector<uint8_t> m_pClipScanV;
   std::vector<uint8_t> m_pAddClipScan;
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp
index 1ab615a..dcf5fdc 100644
--- a/core/fxge/dib/cfx_dibitmap.cpp
+++ b/core/fxge/dib/cfx_dibitmap.cpp
@@ -862,7 +862,7 @@
                                    const RetainPtr<CFX_DIBBase>& pSrcBitmap,
                                    int src_left,
                                    int src_top,
-                                   int blend_type,
+                                   BlendMode blend_type,
                                    const CFX_ClipRgn* pClipRgn,
                                    bool bRgbByteOrder) {
   if (!m_pBuffer)
@@ -934,7 +934,7 @@
                                  uint32_t color,
                                  int src_left,
                                  int src_top,
-                                 int blend_type,
+                                 BlendMode blend_type,
                                  const CFX_ClipRgn* pClipRgn,
                                  bool bRgbByteOrder,
                                  int alpha_flag) {
diff --git a/core/fxge/dib/cfx_dibitmap.h b/core/fxge/dib/cfx_dibitmap.h
index 8ab83c3..58f69ed 100644
--- a/core/fxge/dib/cfx_dibitmap.h
+++ b/core/fxge/dib/cfx_dibitmap.h
@@ -11,6 +11,7 @@
 #include "core/fxcrt/maybe_owned.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/dib/cfx_dibbase.h"
+#include "core/fxge/fx_dib.h"
 
 class CFX_DIBitmap : public CFX_DIBBase {
  public:
@@ -67,7 +68,7 @@
                        const RetainPtr<CFX_DIBBase>& pSrcBitmap,
                        int src_left,
                        int src_top,
-                       int blend_type,
+                       BlendMode blend_type,
                        const CFX_ClipRgn* pClipRgn,
                        bool bRgbByteOrder);
 
@@ -79,7 +80,7 @@
                      uint32_t color,
                      int src_left,
                      int src_top,
-                     int blend_type,
+                     BlendMode blend_type,
                      const CFX_ClipRgn* pClipRgn,
                      bool bRgbByteOrder,
                      int alpha_flag);
diff --git a/core/fxge/dib/cfx_imagerenderer.cpp b/core/fxge/dib/cfx_imagerenderer.cpp
index b4d95b8..9641bc0 100644
--- a/core/fxge/dib/cfx_imagerenderer.cpp
+++ b/core/fxge/dib/cfx_imagerenderer.cpp
@@ -47,7 +47,7 @@
                                       m_Matrix.c > 0, m_Matrix.b < 0);
       m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox,
                          true, m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder,
-                         0, FXDIB_BLEND_NORMAL);
+                         0, BlendMode::kNormal);
       m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>(
           &m_Composer, pSource, dest_height, dest_width, bitmap_clip,
           dib_flags);
@@ -76,7 +76,7 @@
   bitmap_clip.Offset(-image_rect.left, -image_rect.top);
   m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox,
                      false, false, false, m_bRgbByteOrder, 0,
-                     FXDIB_BLEND_NORMAL);
+                     BlendMode::kNormal);
   m_Status = 1;
   m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>(
       &m_Composer, pSource, dest_width, dest_height, bitmap_clip, dib_flags);
@@ -109,14 +109,14 @@
     m_pDevice->CompositeMask(
         m_pTransformer->result().left, m_pTransformer->result().top,
         pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, m_MaskColor, 0, 0,
-        FXDIB_BLEND_NORMAL, m_pClipRgn.Get(), m_bRgbByteOrder, m_AlphaFlag);
+        BlendMode::kNormal, m_pClipRgn.Get(), m_bRgbByteOrder, m_AlphaFlag);
   } else {
     if (m_BitmapAlpha != 255)
       pBitmap->MultiplyAlpha(m_BitmapAlpha);
     m_pDevice->CompositeBitmap(
         m_pTransformer->result().left, m_pTransformer->result().top,
         pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, 0, 0,
-        FXDIB_BLEND_NORMAL, m_pClipRgn.Get(), m_bRgbByteOrder);
+        BlendMode::kNormal, m_pClipRgn.Get(), m_bRgbByteOrder);
   }
   return false;
 }
diff --git a/core/fxge/dib/cfx_scanlinecompositor.cpp b/core/fxge/dib/cfx_scanlinecompositor.cpp
index bfa20e8..4c6d741 100644
--- a/core/fxge/dib/cfx_scanlinecompositor.cpp
+++ b/core/fxge/dib/cfx_scanlinecompositor.cpp
@@ -45,38 +45,38 @@
     0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD,
     0xFD, 0xFE, 0xFE, 0xFF};
 
-int Blend(int blend_mode, int back_color, int src_color) {
+int Blend(BlendMode blend_mode, int back_color, int src_color) {
   switch (blend_mode) {
-    case FXDIB_BLEND_NORMAL:
+    case BlendMode::kNormal:
       return src_color;
-    case FXDIB_BLEND_MULTIPLY:
+    case BlendMode::kMultiply:
       return src_color * back_color / 255;
-    case FXDIB_BLEND_SCREEN:
+    case BlendMode::kScreen:
       return src_color + back_color - src_color * back_color / 255;
-    case FXDIB_BLEND_OVERLAY:
-      return Blend(FXDIB_BLEND_HARDLIGHT, src_color, back_color);
-    case FXDIB_BLEND_DARKEN:
+    case BlendMode::kOverlay:
+      return Blend(BlendMode::kHardLight, src_color, back_color);
+    case BlendMode::kDarken:
       return src_color < back_color ? src_color : back_color;
-    case FXDIB_BLEND_LIGHTEN:
+    case BlendMode::kLighten:
       return src_color > back_color ? src_color : back_color;
-    case FXDIB_BLEND_COLORDODGE: {
+    case BlendMode::kColorDodge: {
       if (src_color == 255)
         return src_color;
 
       return std::min(back_color * 255 / (255 - src_color), 255);
     }
-    case FXDIB_BLEND_COLORBURN: {
+    case BlendMode::kColorBurn: {
       if (src_color == 0)
         return src_color;
 
       return 255 - std::min((255 - back_color) * 255 / src_color, 255);
     }
-    case FXDIB_BLEND_HARDLIGHT:
+    case BlendMode::kHardLight:
       if (src_color < 128)
         return (src_color * back_color * 2) / 255;
 
-      return Blend(FXDIB_BLEND_SCREEN, back_color, 2 * src_color - 255);
-    case FXDIB_BLEND_SOFTLIGHT: {
+      return Blend(BlendMode::kScreen, back_color, 2 * src_color - 255);
+    case BlendMode::kSoftLight: {
       if (src_color < 128) {
         return back_color -
                (255 - 2 * src_color) * back_color * (255 - back_color) / 255 /
@@ -86,10 +86,10 @@
              (2 * src_color - 255) * (color_sqrt[back_color] - back_color) /
                  255;
     }
-    case FXDIB_BLEND_DIFFERENCE:
+    case BlendMode::kDifference:
       return back_color < src_color ? src_color - back_color
                                     : back_color - src_color;
-    case FXDIB_BLEND_EXCLUSION:
+    case BlendMode::kExclusion:
       return back_color + src_color - 2 * back_color * src_color / 255;
   }
   return src_color;
@@ -147,7 +147,7 @@
   return color;
 }
 
-void RGB_Blend(int blend_mode,
+void RGB_Blend(BlendMode blend_mode,
                const uint8_t* src_scan,
                const uint8_t* dest_scan,
                int results[3]) {
@@ -161,16 +161,16 @@
   back.green = dest_scan[1];
   back.blue = dest_scan[0];
   switch (blend_mode) {
-    case FXDIB_BLEND_HUE:
+    case BlendMode::kHue:
       result = SetLum(SetSat(src, Sat(back)), Lum(back));
       break;
-    case FXDIB_BLEND_SATURATION:
+    case BlendMode::kSaturation:
       result = SetLum(SetSat(back, Sat(src)), Lum(back));
       break;
-    case FXDIB_BLEND_COLOR:
+    case BlendMode::kColor:
       result = SetLum(src, Lum(back));
       break;
-    case FXDIB_BLEND_LUMINOSITY:
+    case BlendMode::kLuminosity:
       result = SetLum(back, Lum(src));
       break;
   }
@@ -216,12 +216,12 @@
   }
 }
 
-bool IsNonSeparableBlendMode(int mode) {
+bool IsNonSeparableBlendMode(BlendMode mode) {
   switch (mode) {
-    case FXDIB_BLEND_HUE:
-    case FXDIB_BLEND_SATURATION:
-    case FXDIB_BLEND_COLOR:
-    case FXDIB_BLEND_LUMINOSITY:
+    case BlendMode::kHue:
+    case BlendMode::kSaturation:
+    case BlendMode::kColor:
+    case BlendMode::kLuminosity:
       return true;
     default:
       return false;
@@ -234,11 +234,11 @@
 
 uint8_t GetGrayWithBlend(const uint8_t* src_scan,
                          const uint8_t* dest_scan,
-                         int blend_type) {
+                         BlendMode blend_type) {
   uint8_t gray = GetGray(src_scan);
   if (IsNonSeparableBlendMode(blend_type))
-    gray = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
-  else if (blend_type != FXDIB_BLEND_NORMAL)
+    gray = blend_type == BlendMode::kLuminosity ? gray : *dest_scan;
+  else if (blend_type != BlendMode::kNormal)
     gray = Blend(blend_type, *dest_scan, gray);
   return gray;
 }
@@ -246,7 +246,7 @@
 void CompositeRow_Argb2Graya(uint8_t* dest_scan,
                              const uint8_t* src_scan,
                              int pixel_count,
-                             int blend_type,
+                             BlendMode blend_type,
                              const uint8_t* clip_scan,
                              const uint8_t* src_alpha_scan,
                              uint8_t* dst_alpha_scan) {
@@ -277,9 +277,9 @@
     int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
     uint8_t gray = GetGray(src_scan);
     // TODO(npm): Does this if really need src_alpha_scan or was that a bug?
-    if (blend_type != FXDIB_BLEND_NORMAL && src_alpha_scan) {
+    if (blend_type != BlendMode::kNormal && src_alpha_scan) {
       if (IsNonSeparableBlendMode(blend_type))
-        gray = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+        gray = blend_type == BlendMode::kLuminosity ? gray : *dest_scan;
       else
         gray = Blend(blend_type, *dest_scan, gray);
     }
@@ -293,7 +293,7 @@
 void CompositeRow_Argb2Gray(uint8_t* dest_scan,
                             const uint8_t* src_scan,
                             int pixel_count,
-                            int blend_type,
+                            BlendMode blend_type,
                             const uint8_t* clip_scan,
                             const uint8_t* src_alpha_scan) {
   uint8_t gray;
@@ -315,7 +315,7 @@
                            const uint8_t* src_scan,
                            int src_Bpp,
                            int pixel_count,
-                           int blend_type,
+                           BlendMode blend_type,
                            const uint8_t* clip_scan) {
   uint8_t gray;
   for (int col = 0; col < pixel_count; ++col) {
@@ -333,11 +333,11 @@
                             const uint8_t* src_scan,
                             int src_Bpp,
                             int pixel_count,
-                            int blend_type,
+                            BlendMode blend_type,
                             const uint8_t* clip_scan,
                             uint8_t* dest_alpha_scan) {
   for (int col = 0; col < pixel_count; ++col) {
-    if (blend_type != FXDIB_BLEND_NORMAL && *dest_alpha_scan == 0) {
+    if (blend_type != BlendMode::kNormal && *dest_alpha_scan == 0) {
       *dest_scan = GetGray(src_scan);
       ++dest_scan;
       ++dest_alpha_scan;
@@ -374,7 +374,7 @@
 void CompositeRow_Argb2Argb(uint8_t* dest_scan,
                             const uint8_t* src_scan,
                             int pixel_count,
-                            int blend_type,
+                            BlendMode blend_type,
                             const uint8_t* clip_scan,
                             uint8_t* dest_alpha_scan,
                             const uint8_t* src_alpha_scan) {
@@ -433,7 +433,7 @@
     if (bNonseparableBlend)
       RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
     for (int color = 0; color < 3; ++color) {
-      if (blend_type != FXDIB_BLEND_NORMAL) {
+      if (blend_type != BlendMode::kNormal) {
         int blended = bNonseparableBlend
                           ? blended_colors[color]
                           : Blend(blend_type, *dest_scan, *src_scan);
@@ -455,7 +455,7 @@
 void CompositeRow_Rgb2Argb_Blend_NoClip(uint8_t* dest_scan,
                                         const uint8_t* src_scan,
                                         int width,
-                                        int blend_type,
+                                        BlendMode blend_type,
                                         int src_Bpp,
                                         uint8_t* dest_alpha_scan) {
   int blended_colors[3];
@@ -507,7 +507,7 @@
 void CompositeRow_Rgb2Argb_Blend_Clip(uint8_t* dest_scan,
                                       const uint8_t* src_scan,
                                       int width,
-                                      int blend_type,
+                                      BlendMode blend_type,
                                       int src_Bpp,
                                       const uint8_t* clip_scan,
                                       uint8_t* dest_alpha_scan) {
@@ -660,7 +660,7 @@
 void CompositeRow_Argb2Rgb_Blend(uint8_t* dest_scan,
                                  const uint8_t* src_scan,
                                  int width,
-                                 int blend_type,
+                                 BlendMode blend_type,
                                  int dest_Bpp,
                                  const uint8_t* clip_scan,
                                  const uint8_t* src_alpha_scan) {
@@ -794,7 +794,7 @@
 void CompositeRow_Rgb2Rgb_Blend_NoClip(uint8_t* dest_scan,
                                        const uint8_t* src_scan,
                                        int width,
-                                       int blend_type,
+                                       BlendMode blend_type,
                                        int dest_Bpp,
                                        int src_Bpp) {
   int blended_colors[3];
@@ -823,7 +823,7 @@
 void CompositeRow_Rgb2Rgb_Blend_Clip(uint8_t* dest_scan,
                                      const uint8_t* src_scan,
                                      int width,
-                                     int blend_type,
+                                     BlendMode blend_type,
                                      int dest_Bpp,
                                      int src_Bpp,
                                      const uint8_t* clip_scan) {
@@ -907,17 +907,17 @@
                                const uint8_t* src_scan,
                                const uint8_t* pPalette,
                                int pixel_count,
-                               int blend_type,
+                               BlendMode blend_type,
                                const uint8_t* clip_scan,
                                const uint8_t* src_alpha_scan) {
   if (src_alpha_scan) {
-    if (blend_type != FXDIB_BLEND_NORMAL) {
+    if (blend_type != BlendMode::kNormal) {
       bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
       for (int col = 0; col < pixel_count; col++) {
         uint8_t gray = pPalette[*src_scan];
         int src_alpha = GetAlpha(*src_alpha_scan++, clip_scan, col);
         if (bNonseparableBlend)
-          gray = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+          gray = blend_type == BlendMode::kLuminosity ? gray : *dest_scan;
         else
           gray = Blend(blend_type, *dest_scan, gray);
         if (src_alpha)
@@ -940,12 +940,12 @@
       src_scan++;
     }
   } else {
-    if (blend_type != FXDIB_BLEND_NORMAL) {
+    if (blend_type != BlendMode::kNormal) {
       bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
       for (int col = 0; col < pixel_count; col++) {
         uint8_t gray = pPalette[*src_scan];
         if (bNonseparableBlend)
-          gray = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+          gray = blend_type == BlendMode::kLuminosity ? gray : *dest_scan;
         else
           gray = Blend(blend_type, *dest_scan, gray);
         if (clip_scan && clip_scan[col] < 255)
@@ -973,12 +973,12 @@
                                 const uint8_t* src_scan,
                                 const uint8_t* pPalette,
                                 int pixel_count,
-                                int blend_type,
+                                BlendMode blend_type,
                                 const uint8_t* clip_scan,
                                 uint8_t* dest_alpha_scan,
                                 const uint8_t* src_alpha_scan) {
   if (src_alpha_scan) {
-    if (blend_type != FXDIB_BLEND_NORMAL) {
+    if (blend_type != BlendMode::kNormal) {
       bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
       for (int col = 0; col < pixel_count; col++) {
         uint8_t gray = pPalette[*src_scan];
@@ -1004,7 +1004,7 @@
             back_alpha + src_alpha - back_alpha * src_alpha / 255;
         int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
         if (bNonseparableBlend)
-          gray = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+          gray = blend_type == BlendMode::kLuminosity ? gray : *dest_scan;
         else
           gray = Blend(blend_type, *dest_scan, gray);
         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
@@ -1040,7 +1040,7 @@
       dest_scan++;
     }
   } else {
-    if (blend_type != FXDIB_BLEND_NORMAL) {
+    if (blend_type != BlendMode::kNormal) {
       bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
       for (int col = 0; col < pixel_count; col++) {
         uint8_t gray = pPalette[*src_scan];
@@ -1062,7 +1062,7 @@
         *dest_alpha_scan++ = dest_alpha;
         int alpha_ratio = src_alpha * 255 / dest_alpha;
         if (bNonseparableBlend)
-          gray = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+          gray = blend_type == BlendMode::kLuminosity ? gray : *dest_scan;
         else
           gray = Blend(blend_type, *dest_scan, gray);
         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
@@ -1100,11 +1100,11 @@
                                int src_left,
                                const uint8_t* pPalette,
                                int pixel_count,
-                               int blend_type,
+                               BlendMode blend_type,
                                const uint8_t* clip_scan) {
   int reset_gray = pPalette[0];
   int set_gray = pPalette[1];
-  if (blend_type != FXDIB_BLEND_NORMAL) {
+  if (blend_type != BlendMode::kNormal) {
     bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
     for (int col = 0; col < pixel_count; col++) {
       uint8_t gray =
@@ -1112,7 +1112,7 @@
               ? set_gray
               : reset_gray;
       if (bNonseparableBlend)
-        gray = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+        gray = blend_type == BlendMode::kLuminosity ? gray : *dest_scan;
       else
         gray = Blend(blend_type, *dest_scan, gray);
       if (clip_scan && clip_scan[col] < 255) {
@@ -1143,12 +1143,12 @@
                                 int src_left,
                                 const uint8_t* pPalette,
                                 int pixel_count,
-                                int blend_type,
+                                BlendMode blend_type,
                                 const uint8_t* clip_scan,
                                 uint8_t* dest_alpha_scan) {
   int reset_gray = pPalette[0];
   int set_gray = pPalette[1];
-  if (blend_type != FXDIB_BLEND_NORMAL) {
+  if (blend_type != BlendMode::kNormal) {
     bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
     for (int col = 0; col < pixel_count; col++) {
       uint8_t gray =
@@ -1172,7 +1172,7 @@
       *dest_alpha_scan++ = dest_alpha;
       int alpha_ratio = src_alpha * 255 / dest_alpha;
       if (bNonseparableBlend)
-        gray = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+        gray = blend_type == BlendMode::kLuminosity ? gray : *dest_scan;
       else
         gray = Blend(blend_type, *dest_scan, gray);
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
@@ -1512,7 +1512,7 @@
                                 int src_g,
                                 int src_b,
                                 int pixel_count,
-                                int blend_type,
+                                BlendMode blend_type,
                                 const uint8_t* clip_scan) {
   for (int col = 0; col < pixel_count; col++) {
     int src_alpha;
@@ -1548,7 +1548,7 @@
       dest_scan++;
       *dest_scan =
           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
-    } else if (blend_type != FXDIB_BLEND_NORMAL) {
+    } else if (blend_type != BlendMode::kNormal) {
       int blended = Blend(blend_type, *dest_scan, src_b);
       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
@@ -1578,7 +1578,7 @@
                                 int src_g,
                                 int src_b,
                                 int pixel_count,
-                                int blend_type,
+                                BlendMode blend_type,
                                 const uint8_t* clip_scan,
                                 uint8_t* dest_alpha_scan) {
   for (int col = 0; col < pixel_count; col++) {
@@ -1619,7 +1619,7 @@
       *dest_scan =
           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
       dest_scan++;
-    } else if (blend_type != FXDIB_BLEND_NORMAL) {
+    } else if (blend_type != BlendMode::kNormal) {
       int blended = Blend(blend_type, *dest_scan, src_b);
       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
@@ -1650,7 +1650,7 @@
                                int src_g,
                                int src_b,
                                int pixel_count,
-                               int blend_type,
+                               BlendMode blend_type,
                                int Bpp,
                                const uint8_t* clip_scan) {
   for (int col = 0; col < pixel_count; col++) {
@@ -1675,7 +1675,7 @@
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
       dest_scan++;
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
-    } else if (blend_type != FXDIB_BLEND_NORMAL) {
+    } else if (blend_type != BlendMode::kNormal) {
       int blended = Blend(blend_type, *dest_scan, src_b);
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
       dest_scan++;
@@ -1778,9 +1778,9 @@
                                int src_b,
                                int src_left,
                                int pixel_count,
-                               int blend_type,
+                               BlendMode blend_type,
                                const uint8_t* clip_scan) {
-  if (blend_type == FXDIB_BLEND_NORMAL && !clip_scan && mask_alpha == 255) {
+  if (blend_type == BlendMode::kNormal && !clip_scan && mask_alpha == 255) {
     FX_ARGB argb = ArgbEncode(0xff, src_r, src_g, src_b);
     for (int col = 0; col < pixel_count; col++) {
       if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
@@ -1824,7 +1824,7 @@
       dest_scan++;
       *dest_scan =
           FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
-    } else if (blend_type != FXDIB_BLEND_NORMAL) {
+    } else if (blend_type != BlendMode::kNormal) {
       int blended = Blend(blend_type, *dest_scan, src_b);
       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
@@ -1855,10 +1855,10 @@
                               int src_b,
                               int src_left,
                               int pixel_count,
-                              int blend_type,
+                              BlendMode blend_type,
                               int Bpp,
                               const uint8_t* clip_scan) {
-  if (blend_type == FXDIB_BLEND_NORMAL && !clip_scan && mask_alpha == 255) {
+  if (blend_type == BlendMode::kNormal && !clip_scan && mask_alpha == 255) {
     for (int col = 0; col < pixel_count; col++) {
       if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
         dest_scan[2] = src_r;
@@ -1895,7 +1895,7 @@
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
       dest_scan++;
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
-    } else if (blend_type != FXDIB_BLEND_NORMAL) {
+    } else if (blend_type != BlendMode::kNormal) {
       int blended = Blend(blend_type, *dest_scan, src_b);
       *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
       dest_scan++;
@@ -2009,7 +2009,7 @@
 void CompositeRow_Argb2Argb_RgbByteOrder(uint8_t* dest_scan,
                                          const uint8_t* src_scan,
                                          int pixel_count,
-                                         int blend_type,
+                                         BlendMode blend_type,
                                          const uint8_t* clip_scan) {
   int blended_colors[3];
   bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
@@ -2052,7 +2052,7 @@
     }
     for (int color = 0; color < 3; color++) {
       int index = 2 - color;
-      if (blend_type != FXDIB_BLEND_NORMAL) {
+      if (blend_type != BlendMode::kNormal) {
         int blended = bNonseparableBlend
                           ? blended_colors[color]
                           : Blend(blend_type, dest_scan[index], *src_scan);
@@ -2073,7 +2073,7 @@
 void CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(uint8_t* dest_scan,
                                                      const uint8_t* src_scan,
                                                      int width,
-                                                     int blend_type,
+                                                     BlendMode blend_type,
                                                      int src_Bpp) {
   int blended_colors[3];
   bool bNonseparableBlend = IsNonSeparableBlendMode(blend_type);
@@ -2116,7 +2116,7 @@
 void CompositeRow_Argb2Rgb_Blend_RgbByteOrder(uint8_t* dest_scan,
                                               const uint8_t* src_scan,
                                               int width,
-                                              int blend_type,
+                                              BlendMode blend_type,
                                               int dest_Bpp,
                                               const uint8_t* clip_scan) {
   int blended_colors[3];
@@ -2173,7 +2173,7 @@
 void CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(uint8_t* dest_scan,
                                                     const uint8_t* src_scan,
                                                     int width,
-                                                    int blend_type,
+                                                    BlendMode blend_type,
                                                     int dest_Bpp,
                                                     int src_Bpp) {
   int blended_colors[3];
@@ -2255,7 +2255,7 @@
 void CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(uint8_t* dest_scan,
                                                    const uint8_t* src_scan,
                                                    int width,
-                                                   int blend_type,
+                                                   BlendMode blend_type,
                                                    int src_Bpp,
                                                    const uint8_t* clip_scan) {
   int blended_colors[3];
@@ -2306,7 +2306,7 @@
 void CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(uint8_t* dest_scan,
                                                   const uint8_t* src_scan,
                                                   int width,
-                                                  int blend_type,
+                                                  BlendMode blend_type,
                                                   int dest_Bpp,
                                                   int src_Bpp,
                                                   const uint8_t* clip_scan) {
@@ -2578,7 +2578,7 @@
                                              int src_g,
                                              int src_b,
                                              int pixel_count,
-                                             int blend_type,
+                                             BlendMode blend_type,
                                              const uint8_t* clip_scan) {
   for (int col = 0; col < pixel_count; col++) {
     int src_alpha;
@@ -2614,7 +2614,7 @@
           FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
       dest_scan[0] =
           FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
-    } else if (blend_type != FXDIB_BLEND_NORMAL) {
+    } else if (blend_type != BlendMode::kNormal) {
       int blended = Blend(blend_type, dest_scan[2], src_b);
       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
@@ -2640,7 +2640,7 @@
                                             int src_g,
                                             int src_b,
                                             int pixel_count,
-                                            int blend_type,
+                                            BlendMode blend_type,
                                             int Bpp,
                                             const uint8_t* clip_scan) {
   for (int col = 0; col < pixel_count; col++) {
@@ -2667,7 +2667,7 @@
           FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
       dest_scan[0] =
           FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
-    } else if (blend_type != FXDIB_BLEND_NORMAL) {
+    } else if (blend_type != BlendMode::kNormal) {
       int blended = Blend(blend_type, dest_scan[2], src_b);
       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha);
       blended = Blend(blend_type, dest_scan[1], src_g);
@@ -2691,9 +2691,9 @@
                                             int src_b,
                                             int src_left,
                                             int pixel_count,
-                                            int blend_type,
+                                            BlendMode blend_type,
                                             const uint8_t* clip_scan) {
-  if (blend_type == FXDIB_BLEND_NORMAL && !clip_scan && mask_alpha == 255) {
+  if (blend_type == BlendMode::kNormal && !clip_scan && mask_alpha == 255) {
     FX_ARGB argb = ArgbEncode(0xff, src_r, src_g, src_b);
     for (int col = 0; col < pixel_count; col++) {
       if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
@@ -2737,7 +2737,7 @@
           FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
       dest_scan[0] =
           FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
-    } else if (blend_type != FXDIB_BLEND_NORMAL) {
+    } else if (blend_type != BlendMode::kNormal) {
       int blended = Blend(blend_type, dest_scan[2], src_b);
       blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
       dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
@@ -2764,10 +2764,10 @@
                                            int src_b,
                                            int src_left,
                                            int pixel_count,
-                                           int blend_type,
+                                           BlendMode blend_type,
                                            int Bpp,
                                            const uint8_t* clip_scan) {
-  if (blend_type == FXDIB_BLEND_NORMAL && !clip_scan && mask_alpha == 255) {
+  if (blend_type == BlendMode::kNormal && !clip_scan && mask_alpha == 255) {
     for (int col = 0; col < pixel_count; col++) {
       if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
         dest_scan[2] = src_b;
@@ -2806,7 +2806,7 @@
           FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
       dest_scan[0] =
           FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
-    } else if (blend_type != FXDIB_BLEND_NORMAL) {
+    } else if (blend_type != BlendMode::kNormal) {
       int back_color = dest_scan[2];
       int blended = Blend(blend_type, back_color, src_b);
       dest_scan[2] = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
@@ -2827,17 +2827,16 @@
 
 }  // namespace
 
-CFX_ScanlineCompositor::CFX_ScanlineCompositor()
-    : m_BlendType(FXDIB_BLEND_NORMAL), m_bRgbByteOrder(false) {}
+CFX_ScanlineCompositor::CFX_ScanlineCompositor() = default;
 
-CFX_ScanlineCompositor::~CFX_ScanlineCompositor() {}
+CFX_ScanlineCompositor::~CFX_ScanlineCompositor() = default;
 
 bool CFX_ScanlineCompositor::Init(FXDIB_Format dest_format,
                                   FXDIB_Format src_format,
                                   int32_t width,
                                   uint32_t* pSrcPalette,
                                   uint32_t mask_color,
-                                  int blend_type,
+                                  BlendMode blend_type,
                                   bool bClip,
                                   bool bRgbByteOrder,
                                   int alpha_flag) {
@@ -2866,7 +2865,7 @@
   }
   m_iTransparency =
       (src_format & 0x0200 ? 0 : 1) + (dest_format & 0x0200 ? 0 : 2) +
-      (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0) + (bClip ? 8 : 0) +
+      (blend_type == BlendMode::kNormal ? 4 : 0) + (bClip ? 8 : 0) +
       (src_format & 0x0400 ? 16 : 0) + (dest_format & 0x0400 ? 32 : 0);
   return true;
 }
diff --git a/core/fxge/dib/cfx_scanlinecompositor.h b/core/fxge/dib/cfx_scanlinecompositor.h
index 1c373f0..fc86299 100644
--- a/core/fxge/dib/cfx_scanlinecompositor.h
+++ b/core/fxge/dib/cfx_scanlinecompositor.h
@@ -10,11 +10,11 @@
 #include <memory>
 
 #include "core/fxge/dib/cfx_dibbase.h"
+#include "core/fxge/fx_dib.h"
 
 class CFX_ScanlineCompositor {
  public:
   CFX_ScanlineCompositor();
-
   ~CFX_ScanlineCompositor();
 
   bool Init(FXDIB_Format dest_format,
@@ -22,7 +22,7 @@
             int32_t width,
             uint32_t* pSrcPalette,
             uint32_t mask_color,
-            int blend_type,
+            BlendMode blend_type,
             bool bClip,
             bool bRgbByteOrder,
             int alpha_flag);
@@ -70,8 +70,8 @@
   int m_MaskRed;
   int m_MaskGreen;
   int m_MaskBlue;
-  int m_BlendType;
-  bool m_bRgbByteOrder;
+  BlendMode m_BlendType = BlendMode::kNormal;
+  bool m_bRgbByteOrder = false;
 };
 
 #endif  // CORE_FXGE_DIB_CFX_SCANLINECOMPOSITOR_H_
diff --git a/core/fxge/fx_dib.h b/core/fxge/fx_dib.h
index 4842d11..96cd82a 100644
--- a/core/fxge/fx_dib.h
+++ b/core/fxge/fx_dib.h
@@ -55,22 +55,26 @@
 #define FXDIB_BICUBIC_INTERPOL 0x80
 #define FXDIB_NOSMOOTH 0x100
 
-#define FXDIB_BLEND_NORMAL 0
-#define FXDIB_BLEND_MULTIPLY 1
-#define FXDIB_BLEND_SCREEN 2
-#define FXDIB_BLEND_OVERLAY 3
-#define FXDIB_BLEND_DARKEN 4
-#define FXDIB_BLEND_LIGHTEN 5
-#define FXDIB_BLEND_COLORDODGE 6
-#define FXDIB_BLEND_COLORBURN 7
-#define FXDIB_BLEND_HARDLIGHT 8
-#define FXDIB_BLEND_SOFTLIGHT 9
-#define FXDIB_BLEND_DIFFERENCE 10
-#define FXDIB_BLEND_EXCLUSION 11
-#define FXDIB_BLEND_HUE 21
-#define FXDIB_BLEND_SATURATION 22
-#define FXDIB_BLEND_COLOR 23
-#define FXDIB_BLEND_LUMINOSITY 24
+// See PDF 1.7 spec, table 7.2 and 7.3. The enum values need to be in the same
+// order as listed in the spec.
+enum class BlendMode {
+  kNormal = 0,
+  kMultiply,
+  kScreen,
+  kOverlay,
+  kDarken,
+  kLighten,
+  kColorDodge,
+  kColorBurn,
+  kHardLight,
+  kSoftLight,
+  kDifference,
+  kExclusion,
+  kHue,
+  kSaturation,
+  kColor,
+  kLuminosity,
+};
 
 constexpr uint32_t FXSYS_BGR(uint8_t b, uint8_t g, uint8_t r) {
   return (b << 16) | (g << 8) | r;
diff --git a/core/fxge/renderdevicedriver_iface.cpp b/core/fxge/renderdevicedriver_iface.cpp
index 646851f..fbd4335 100644
--- a/core/fxge/renderdevicedriver_iface.cpp
+++ b/core/fxge/renderdevicedriver_iface.cpp
@@ -31,14 +31,14 @@
 
 bool RenderDeviceDriverIface::FillRectWithBlend(const FX_RECT& rect,
                                                 uint32_t fill_color,
-                                                int blend_type) {
+                                                BlendMode blend_type) {
   return false;
 }
 
 bool RenderDeviceDriverIface::DrawCosmeticLine(const CFX_PointF& ptMoveTo,
                                                const CFX_PointF& ptLineTo,
                                                uint32_t color,
-                                               int blend_type) {
+                                               BlendMode blend_type) {
   return false;
 }
 
@@ -86,7 +86,7 @@
     int left,
     int top,
     int bitmap_alpha,
-    int blend_type) {
+    BlendMode blend_type) {
   return false;
 }
 
diff --git a/core/fxge/renderdevicedriver_iface.h b/core/fxge/renderdevicedriver_iface.h
index 62287ab..051254d 100644
--- a/core/fxge/renderdevicedriver_iface.h
+++ b/core/fxge/renderdevicedriver_iface.h
@@ -12,6 +12,7 @@
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/retain_ptr.h"
+#include "core/fxge/fx_dib.h"
 
 class CFX_DIBitmap;
 class CFX_DIBBase;
@@ -48,15 +49,15 @@
                         uint32_t fill_color,
                         uint32_t stroke_color,
                         int fill_mode,
-                        int blend_type) = 0;
+                        BlendMode blend_type) = 0;
   virtual bool SetPixel(int x, int y, uint32_t color);
   virtual bool FillRectWithBlend(const FX_RECT& rect,
                                  uint32_t fill_color,
-                                 int blend_type);
+                                 BlendMode blend_type);
   virtual bool DrawCosmeticLine(const CFX_PointF& ptMoveTo,
                                 const CFX_PointF& ptLineTo,
                                 uint32_t color,
-                                int blend_type);
+                                BlendMode blend_type);
 
   virtual bool GetClipBox(FX_RECT* pRect) = 0;
   virtual bool GetDIBits(const RetainPtr<CFX_DIBitmap>& pBitmap,
@@ -68,7 +69,7 @@
                          const FX_RECT* pSrcRect,
                          int dest_left,
                          int dest_top,
-                         int blend_type) = 0;
+                         BlendMode blend_type) = 0;
   virtual bool StretchDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                              uint32_t color,
                              int dest_left,
@@ -77,14 +78,14 @@
                              int dest_height,
                              const FX_RECT* pClipRect,
                              uint32_t flags,
-                             int blend_type) = 0;
+                             BlendMode blend_type) = 0;
   virtual bool StartDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                            int bitmap_alpha,
                            uint32_t color,
                            const CFX_Matrix* pMatrix,
                            uint32_t flags,
                            std::unique_ptr<CFX_ImageRenderer>* handle,
-                           int blend_type) = 0;
+                           BlendMode blend_type) = 0;
   virtual bool ContinueDIBits(CFX_ImageRenderer* handle,
                               PauseIndicatorIface* pPause);
   virtual bool DrawDeviceText(int nChars,
@@ -105,7 +106,7 @@
                                int left,
                                int top,
                                int bitmap_alpha,
-                               int blend_type);
+                               BlendMode blend_type);
 #if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
   virtual void Flush();
 #endif
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index ce9bb42..63a44cb 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -318,39 +318,39 @@
   return skMatrix;
 }
 
-SkBlendMode GetSkiaBlendMode(int blend_type) {
+SkBlendMode GetSkiaBlendMode(BlendMode blend_type) {
   switch (blend_type) {
-    case FXDIB_BLEND_MULTIPLY:
+    case BlendMode::kMultiply:
       return SkBlendMode::kMultiply;
-    case FXDIB_BLEND_SCREEN:
+    case BlendMode::kScreen:
       return SkBlendMode::kScreen;
-    case FXDIB_BLEND_OVERLAY:
+    case BlendMode::kOverlay:
       return SkBlendMode::kOverlay;
-    case FXDIB_BLEND_DARKEN:
+    case BlendMode::kDarken:
       return SkBlendMode::kDarken;
-    case FXDIB_BLEND_LIGHTEN:
+    case BlendMode::kLighten:
       return SkBlendMode::kLighten;
-    case FXDIB_BLEND_COLORDODGE:
+    case BlendMode::kColorDodge:
       return SkBlendMode::kColorDodge;
-    case FXDIB_BLEND_COLORBURN:
+    case BlendMode::kColorBurn:
       return SkBlendMode::kColorBurn;
-    case FXDIB_BLEND_HARDLIGHT:
+    case BlendMode::kHardLight:
       return SkBlendMode::kHardLight;
-    case FXDIB_BLEND_SOFTLIGHT:
+    case BlendMode::kSoftLight:
       return SkBlendMode::kSoftLight;
-    case FXDIB_BLEND_DIFFERENCE:
+    case BlendMode::kDifference:
       return SkBlendMode::kDifference;
-    case FXDIB_BLEND_EXCLUSION:
+    case BlendMode::kExclusion:
       return SkBlendMode::kExclusion;
-    case FXDIB_BLEND_HUE:
+    case BlendMode::kHue:
       return SkBlendMode::kHue;
-    case FXDIB_BLEND_SATURATION:
+    case BlendMode::kSaturation:
       return SkBlendMode::kSaturation;
-    case FXDIB_BLEND_COLOR:
+    case BlendMode::kColor:
       return SkBlendMode::kColor;
-    case FXDIB_BLEND_LUMINOSITY:
+    case BlendMode::kLuminosity:
       return SkBlendMode::kLuminosity;
-    case FXDIB_BLEND_NORMAL:
+    case BlendMode::kNormal:
     default:
       return SkBlendMode::kSrcOver;
   }
@@ -563,7 +563,7 @@
 void SetBitmapPaint(bool isAlphaMask,
                     uint32_t argb,
                     int bitmap_alpha,
-                    int blend_type,
+                    BlendMode blend_type,
                     SkPaint* paint) {
   paint->setAntiAlias(true);
   if (isAlphaMask) {
@@ -695,7 +695,7 @@
                 uint32_t fill_color,
                 uint32_t stroke_color,
                 int fill_mode,
-                int blend_type) {
+                BlendMode blend_type) {
     if (m_debugDisable)
       return false;
     Dump(__func__);
@@ -1074,7 +1074,7 @@
                    uint32_t fill_color,
                    uint32_t stroke_color,
                    int fill_mode,
-                   int blend_type,
+                   BlendMode blend_type,
                    bool group_knockout) const {
     return MatrixChanged(pMatrix, m_drawMatrix) ||
            StateChanged(pState, m_drawState) || fill_color != m_fillColor ||
@@ -1391,7 +1391,7 @@
   float m_scaleX = 0;
   uint32_t m_fillColor = 0;
   uint32_t m_strokeColor = 0;
-  int m_blendType = FXDIB_BLEND_NORMAL;
+  BlendMode m_blendType = BlendMode::kNormal;
   int m_commandIndex = 0;     // active position in clip command stack
   int m_drawIndex = INT_MAX;  // position of the pending path or text draw
   int m_clipIndex = 0;        // position reflecting depth of canvas clip stacck
@@ -1880,7 +1880,7 @@
     uint32_t fill_color,                    // fill color
     uint32_t stroke_color,                  // stroke color
     int fill_mode,  // fill mode, WINDING or ALTERNATE. 0 for not filled
-    int blend_type) {
+    BlendMode blend_type) {
   if (fill_mode & FX_ZEROAREA_FILL)
     return true;
   if (m_pCache->DrawPath(pPathData, pObject2Device, pGraphState, fill_color,
@@ -1941,13 +1941,13 @@
 bool CFX_SkiaDeviceDriver::DrawCosmeticLine(const CFX_PointF& ptMoveTo,
                                             const CFX_PointF& ptLineTo,
                                             uint32_t color,
-                                            int blend_type) {
+                                            BlendMode blend_type) {
   return false;
 }
 
 bool CFX_SkiaDeviceDriver::FillRectWithBlend(const FX_RECT& rect,
                                              uint32_t fill_color,
-                                             int blend_type) {
+                                             BlendMode blend_type) {
   m_pCache->FlushForDraw();
   SkPaint spaint;
   spaint.setAntiAlias(true);
@@ -2212,7 +2212,7 @@
       return true;
 
     pBack->CompositeBitmap(0, 0, pBack->GetWidth(), pBack->GetHeight(),
-                           m_pBitmap, 0, 0, FXDIB_BLEND_NORMAL, nullptr, false);
+                           m_pBitmap, 0, 0, BlendMode::kNormal, nullptr, false);
   } else {
     pBack = m_pBitmap->Clone(&rect);
     if (!pBack)
@@ -2242,7 +2242,7 @@
                                      const FX_RECT* pSrcRect,
                                      int left,
                                      int top,
-                                     int blend_type) {
+                                     BlendMode blend_type) {
   if (!m_pBitmap || !m_pBitmap->GetBuffer())
     return true;
 
@@ -2275,7 +2275,7 @@
                                          int dest_height,
                                          const FX_RECT* pClipRect,
                                          uint32_t flags,
-                                         int blend_type) {
+                                         BlendMode blend_type) {
 #ifdef _SKIA_SUPPORT_
   m_pCache->FlushForDraw();
   if (!m_pBitmap->GetBuffer())
@@ -2325,7 +2325,7 @@
     const CFX_Matrix* pMatrix,
     uint32_t render_flags,
     std::unique_ptr<CFX_ImageRenderer>* handle,
-    int blend_type) {
+    BlendMode blend_type) {
 #ifdef _SKIA_SUPPORT_
   m_pCache->FlushForDraw();
   DebugValidate(m_pBitmap, m_pBackdropBitmap);
@@ -2456,7 +2456,7 @@
     const RetainPtr<CFX_DIBBase>& pMask,
     int bitmap_alpha,
     const CFX_Matrix* pMatrix,
-    int blend_type) {
+    BlendMode blend_type) {
   DebugValidate(m_pBitmap, m_pBackdropBitmap);
   std::unique_ptr<uint8_t, FxFreeDeleter> src8Storage, mask8Storage;
   std::unique_ptr<uint32_t, FxFreeDeleter> src32Storage, mask32Storage;
@@ -2498,7 +2498,7 @@
     int dest_left,
     int dest_top,
     int bitmap_alpha,
-    int blend_type) {
+    BlendMode blend_type) {
   if (!m_pBitmap || !m_pBitmap->GetBuffer())
     return true;
   CFX_Matrix m(pBitmap->GetWidth(), 0, 0, -pBitmap->GetHeight(), dest_left,
@@ -2599,7 +2599,7 @@
     int left,
     int top,
     int bitmap_alpha,
-    int blend_type) {
+    BlendMode blend_type) {
   CFX_SkiaDeviceDriver* skDriver =
       static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver());
   if (skDriver)
diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h
index 4baeacb..23c8514 100644
--- a/core/fxge/skia/fx_skia_device.h
+++ b/core/fxge/skia/fx_skia_device.h
@@ -62,17 +62,17 @@
                 uint32_t fill_color,
                 uint32_t stroke_color,
                 int fill_mode,
-                int blend_type) override;
+                BlendMode blend_type) override;
 
   bool FillRectWithBlend(const FX_RECT& rect,
                          uint32_t fill_color,
-                         int blend_type) override;
+                         BlendMode blend_type) override;
 
   /** Draw a single pixel (device dependant) line */
   bool DrawCosmeticLine(const CFX_PointF& ptMoveTo,
                         const CFX_PointF& ptLineTo,
                         uint32_t color,
-                        int blend_type) override;
+                        BlendMode blend_type) override;
 
   bool GetClipBox(FX_RECT* pRect) override;
 
@@ -88,14 +88,14 @@
                  const FX_RECT* pSrcRect,
                  int dest_left,
                  int dest_top,
-                 int blend_type) override;
+                 BlendMode blend_type) override;
 #ifdef _SKIA_SUPPORT_
   bool SetBitsWithMask(const RetainPtr<CFX_DIBBase>& pBitmap,
                        const RetainPtr<CFX_DIBBase>& pMask,
                        int dest_left,
                        int dest_top,
                        int bitmap_alpha,
-                       int blend_type) override;
+                       BlendMode blend_type) override;
 #endif
 
 #ifdef _SKIA_SUPPORT_PATHS_
@@ -110,7 +110,7 @@
                      int dest_height,
                      const FX_RECT* pClipRect,
                      uint32_t flags,
-                     int blend_type) override;
+                     BlendMode blend_type) override;
 
   bool StartDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                    int bitmap_alpha,
@@ -118,7 +118,7 @@
                    const CFX_Matrix* pMatrix,
                    uint32_t flags,
                    std::unique_ptr<CFX_ImageRenderer>* handle,
-                   int blend_type) override;
+                   BlendMode blend_type) override;
 
   bool ContinueDIBits(CFX_ImageRenderer* handle,
                       PauseIndicatorIface* pPause) override;
@@ -127,7 +127,7 @@
                         const RetainPtr<CFX_DIBBase>& pMask,
                         int bitmap_alpha,
                         const CFX_Matrix* pMatrix,
-                        int blend_type);
+                        BlendMode blend_type);
 
   bool DrawDeviceText(int nChars,
                       const FXTEXT_CHARPOS* pCharPos,
diff --git a/core/fxge/skia/fx_skia_device_embeddertest.cpp b/core/fxge/skia/fx_skia_device_embeddertest.cpp
index 3965a11c..0a3a8ec 100644
--- a/core/fxge/skia/fx_skia_device_embeddertest.cpp
+++ b/core/fxge/skia/fx_skia_device_embeddertest.cpp
@@ -61,7 +61,7 @@
     driver->SetClip_PathFill(&clipPath, &clipMatrix, 0);
   if (state.m_graphic == State::Graphic::kPath) {
     driver->DrawPath(&path1, &matrix, &graphState, 0xFF112233, 0,
-                     FXFILL_WINDING, 0);
+                     FXFILL_WINDING, BlendMode::kNormal);
   } else if (state.m_graphic == State::Graphic::kText) {
     driver->DrawDeviceText(SK_ARRAY_COUNT(charPos), charPos, &font, &matrix,
                            fontSize, 0xFF445566);
@@ -84,7 +84,7 @@
     driver->SetClip_PathFill(&clipPath, &clipMatrix2, 0);
   if (state.m_graphic == State::Graphic::kPath) {
     driver->DrawPath(&path2, &matrix2, &graphState, 0xFF112233, 0,
-                     FXFILL_WINDING, 0);
+                     FXFILL_WINDING, BlendMode::kNormal);
   } else if (state.m_graphic == State::Graphic::kText) {
     driver->DrawDeviceText(SK_ARRAY_COUNT(charPos), charPos, &font, &matrix2,
                            fontSize, 0xFF445566);
diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp
index fec656e..537e675 100644
--- a/core/fxge/win32/fx_win32_device.cpp
+++ b/core/fxge/win32/fx_win32_device.cpp
@@ -959,8 +959,8 @@
                                 uint32_t fill_color,
                                 uint32_t stroke_color,
                                 int fill_mode,
-                                int blend_type) {
-  if (blend_type != FXDIB_BLEND_NORMAL)
+                                BlendMode blend_type) {
+  if (blend_type != BlendMode::kNormal)
     return false;
 
   CWin32Platform* pPlatform =
@@ -975,12 +975,12 @@
     if (bbox.Width() <= 0) {
       return DrawCosmeticLine(CFX_PointF(bbox.left, bbox.top),
                               CFX_PointF(bbox.left, bbox.bottom + 1),
-                              fill_color, FXDIB_BLEND_NORMAL);
+                              fill_color, BlendMode::kNormal);
     }
     if (bbox.Height() <= 0) {
       return DrawCosmeticLine(CFX_PointF(bbox.left, bbox.top),
                               CFX_PointF(bbox.right + 1, bbox.top), fill_color,
-                              FXDIB_BLEND_NORMAL);
+                              BlendMode::kNormal);
     }
   }
   int fill_alpha = FXARGB_A(fill_color);
@@ -1061,8 +1061,8 @@
 
 bool CGdiDeviceDriver::FillRectWithBlend(const FX_RECT& rect,
                                          uint32_t fill_color,
-                                         int blend_type) {
-  if (blend_type != FXDIB_BLEND_NORMAL)
+                                         BlendMode blend_type) {
+  if (blend_type != BlendMode::kNormal)
     return false;
 
   int alpha;
@@ -1116,8 +1116,8 @@
 bool CGdiDeviceDriver::DrawCosmeticLine(const CFX_PointF& ptMoveTo,
                                         const CFX_PointF& ptLineTo,
                                         uint32_t color,
-                                        int blend_type) {
-  if (blend_type != FXDIB_BLEND_NORMAL)
+                                        BlendMode blend_type) {
+  if (blend_type != BlendMode::kNormal)
     return false;
 
   int alpha;
@@ -1191,8 +1191,8 @@
                                   const FX_RECT* pSrcRect,
                                   int left,
                                   int top,
-                                  int blend_type) {
-  ASSERT(blend_type == FXDIB_BLEND_NORMAL);
+                                  BlendMode blend_type) {
+  ASSERT(blend_type == BlendMode::kNormal);
   if (pSource->IsAlphaMask()) {
     int width = pSource->GetWidth(), height = pSource->GetHeight();
     int alpha = FXARGB_A(color);
@@ -1201,17 +1201,17 @@
       if (!background->Create(width, height, FXDIB_Rgb32) ||
           !GetDIBits(background, left, top) ||
           !background->CompositeMask(0, 0, width, height, pSource, color, 0, 0,
-                                     FXDIB_BLEND_NORMAL, nullptr, false, 0)) {
+                                     BlendMode::kNormal, nullptr, false, 0)) {
         return false;
       }
       FX_RECT src_rect(0, 0, width, height);
-      return SetDIBits(background, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL);
+      return SetDIBits(background, 0, &src_rect, left, top, BlendMode::kNormal);
     }
     FX_RECT clip_rect(left, top, left + pSrcRect->Width(),
                       top + pSrcRect->Height());
     return StretchDIBits(pSource, color, left - pSrcRect->left,
                          top - pSrcRect->top, width, height, &clip_rect, 0,
-                         FXDIB_BLEND_NORMAL);
+                         BlendMode::kNormal);
   }
   int width = pSrcRect->Width(), height = pSrcRect->Height();
   if (pSource->HasAlpha()) {
@@ -1219,12 +1219,12 @@
     if (!bitmap->Create(width, height, FXDIB_Rgb) ||
         !GetDIBits(bitmap, left, top) ||
         !bitmap->CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left,
-                                 pSrcRect->top, FXDIB_BLEND_NORMAL, nullptr,
+                                 pSrcRect->top, BlendMode::kNormal, nullptr,
                                  false)) {
       return false;
     }
     FX_RECT src_rect(0, 0, width, height);
-    return SetDIBits(bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL);
+    return SetDIBits(bitmap, 0, &src_rect, left, top, BlendMode::kNormal);
   }
   CFX_DIBExtractor temp(pSource);
   RetainPtr<CFX_DIBitmap> pBitmap = temp.GetBitmap();
@@ -1257,7 +1257,7 @@
 
   FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight());
   return SetDIBits(pStretched, color, &src_rect, pClipRect->left,
-                   pClipRect->top, FXDIB_BLEND_NORMAL);
+                   pClipRect->top, BlendMode::kNormal);
 }
 
 bool CGdiDisplayDriver::StretchDIBits(const RetainPtr<CFX_DIBBase>& pSource,
@@ -1268,7 +1268,7 @@
                                       int dest_height,
                                       const FX_RECT* pClipRect,
                                       uint32_t flags,
-                                      int blend_type) {
+                                      BlendMode blend_type) {
   ASSERT(pSource && pClipRect);
   if (flags || dest_width > 10000 || dest_width < -10000 ||
       dest_height > 10000 || dest_height < -10000) {
@@ -1295,14 +1295,14 @@
         !GetDIBits(background, image_rect.left + clip_rect.left,
                    image_rect.top + clip_rect.top) ||
         !background->CompositeMask(0, 0, clip_width, clip_height, pStretched,
-                                   color, 0, 0, FXDIB_BLEND_NORMAL, nullptr,
+                                   color, 0, 0, BlendMode::kNormal, nullptr,
                                    false, 0)) {
       return false;
     }
 
     FX_RECT src_rect(0, 0, clip_width, clip_height);
     return SetDIBits(background, 0, &src_rect, image_rect.left + clip_rect.left,
-                     image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL);
+                     image_rect.top + clip_rect.top, BlendMode::kNormal);
   }
   if (pSource->HasAlpha()) {
     CWin32Platform* pPlatform =
@@ -1333,7 +1333,7 @@
                                     const CFX_Matrix* pMatrix,
                                     uint32_t render_flags,
                                     std::unique_ptr<CFX_ImageRenderer>* handle,
-                                    int blend_type) {
+                                    BlendMode blend_type) {
   return false;
 }
 
diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp
index 4d8452d..1f9b951 100644
--- a/core/fxge/win32/fx_win32_print.cpp
+++ b/core/fxge/win32/fx_win32_print.cpp
@@ -73,17 +73,17 @@
                                   const FX_RECT* pSrcRect,
                                   int left,
                                   int top,
-                                  int blend_type) {
+                                  BlendMode blend_type) {
   if (pSource->IsAlphaMask()) {
     FX_RECT clip_rect(left, top, left + pSrcRect->Width(),
                       top + pSrcRect->Height());
     return StretchDIBits(pSource, color, left - pSrcRect->left,
                          top - pSrcRect->top, pSource->GetWidth(),
                          pSource->GetHeight(), &clip_rect, 0,
-                         FXDIB_BLEND_NORMAL);
+                         BlendMode::kNormal);
   }
   ASSERT(pSource && !pSource->IsAlphaMask() && pSrcRect);
-  ASSERT(blend_type == FXDIB_BLEND_NORMAL);
+  ASSERT(blend_type == BlendMode::kNormal);
   if (pSource->HasAlpha())
     return false;
 
@@ -103,7 +103,7 @@
                                       int dest_height,
                                       const FX_RECT* pClipRect,
                                       uint32_t flags,
-                                      int blend_type) {
+                                      BlendMode blend_type) {
   if (pSource->IsAlphaMask()) {
     int alpha = FXARGB_A(color);
     if (pSource->GetBPP() != 1 || alpha != 255)
@@ -164,7 +164,7 @@
                                     const CFX_Matrix* pMatrix,
                                     uint32_t render_flags,
                                     std::unique_ptr<CFX_ImageRenderer>* handle,
-                                    int blend_type) {
+                                    BlendMode blend_type) {
   if (bitmap_alpha < 255 || pSource->HasAlpha() ||
       (pSource->IsAlphaMask() && (pSource->GetBPP() != 1))) {
     return false;
@@ -440,8 +440,8 @@
                                 FX_ARGB fill_color,
                                 FX_ARGB stroke_color,
                                 int fill_mode,
-                                int blend_type) {
-  if (blend_type != FXDIB_BLEND_NORMAL) {
+                                BlendMode blend_type) {
+  if (blend_type != BlendMode::kNormal) {
     return false;
   }
   return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState,
@@ -458,8 +458,8 @@
                                  const FX_RECT* pSrcRect,
                                  int left,
                                  int top,
-                                 int blend_type) {
-  if (blend_type != FXDIB_BLEND_NORMAL)
+                                 BlendMode blend_type) {
+  if (blend_type != BlendMode::kNormal)
     return false;
   return m_PSRenderer.SetDIBits(pBitmap, color, left, top);
 }
@@ -472,8 +472,8 @@
                                      int dest_height,
                                      const FX_RECT* pClipRect,
                                      uint32_t flags,
-                                     int blend_type) {
-  if (blend_type != FXDIB_BLEND_NORMAL)
+                                     BlendMode blend_type) {
+  if (blend_type != BlendMode::kNormal)
     return false;
   return m_PSRenderer.StretchDIBits(pBitmap, color, dest_left, dest_top,
                                     dest_width, dest_height, flags);
@@ -485,8 +485,8 @@
                                    const CFX_Matrix* pMatrix,
                                    uint32_t render_flags,
                                    std::unique_ptr<CFX_ImageRenderer>* handle,
-                                   int blend_type) {
-  if (blend_type != FXDIB_BLEND_NORMAL)
+                                   BlendMode blend_type) {
+  if (blend_type != BlendMode::kNormal)
     return false;
 
   if (bitmap_alpha < 255)
@@ -560,7 +560,7 @@
                                       uint32_t fill_color,
                                       uint32_t stroke_color,
                                       int fill_mode,
-                                      int blend_type) {
+                                      BlendMode blend_type) {
   return false;
 }
 
@@ -569,7 +569,7 @@
                                        const FX_RECT* pSrcRect,
                                        int left,
                                        int top,
-                                       int blend_type) {
+                                       BlendMode blend_type) {
   return false;
 }
 
@@ -590,7 +590,7 @@
     int dest_height,
     const FX_RECT* pClipRect,
     uint32_t flags,
-    int blend_type) {
+    BlendMode blend_type) {
   return false;
 }
 
@@ -601,7 +601,7 @@
     const CFX_Matrix* pMatrix,
     uint32_t render_flags,
     std::unique_ptr<CFX_ImageRenderer>* handle,
-    int blend_type) {
+    BlendMode blend_type) {
   return false;
 }
 
diff --git a/core/fxge/win32/win32_int.h b/core/fxge/win32/win32_int.h
index 7b4f9ab..2a61a4e 100644
--- a/core/fxge/win32/win32_int.h
+++ b/core/fxge/win32/win32_int.h
@@ -149,14 +149,14 @@
                 uint32_t fill_color,
                 uint32_t stroke_color,
                 int fill_mode,
-                int blend_type) override;
+                BlendMode blend_type) override;
   bool FillRectWithBlend(const FX_RECT& rect,
                          uint32_t fill_color,
-                         int blend_type) override;
+                         BlendMode blend_type) override;
   bool DrawCosmeticLine(const CFX_PointF& ptMoveTo,
                         const CFX_PointF& ptLineTo,
                         uint32_t color,
-                        int blend_type) override;
+                        BlendMode blend_type) override;
   bool GetClipBox(FX_RECT* pRect) override;
 
   void DrawLine(float x1, float y1, float x2, float y2);
@@ -202,7 +202,7 @@
                  const FX_RECT* pSrcRect,
                  int left,
                  int top,
-                 int blend_type) override;
+                 BlendMode blend_type) override;
   bool StretchDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                      uint32_t color,
                      int dest_left,
@@ -211,14 +211,14 @@
                      int dest_height,
                      const FX_RECT* pClipRect,
                      uint32_t flags,
-                     int blend_type) override;
+                     BlendMode blend_type) override;
   bool StartDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                    int bitmap_alpha,
                    uint32_t color,
                    const CFX_Matrix* pMatrix,
                    uint32_t render_flags,
                    std::unique_ptr<CFX_ImageRenderer>* handle,
-                   int blend_type) override;
+                   BlendMode blend_type) override;
   bool UseFoxitStretchEngine(const RetainPtr<CFX_DIBBase>& pSource,
                              uint32_t color,
                              int dest_left,
@@ -241,7 +241,7 @@
                  const FX_RECT* pSrcRect,
                  int left,
                  int top,
-                 int blend_type) override;
+                 BlendMode blend_type) override;
   bool StretchDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                      uint32_t color,
                      int dest_left,
@@ -250,14 +250,14 @@
                      int dest_height,
                      const FX_RECT* pClipRect,
                      uint32_t flags,
-                     int blend_type) override;
+                     BlendMode blend_type) override;
   bool StartDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                    int bitmap_alpha,
                    uint32_t color,
                    const CFX_Matrix* pMatrix,
                    uint32_t render_flags,
                    std::unique_ptr<CFX_ImageRenderer>* handle,
-                   int blend_type) override;
+                   BlendMode blend_type) override;
   bool DrawDeviceText(int nChars,
                       const FXTEXT_CHARPOS* pCharPos,
                       CFX_Font* pFont,
@@ -293,14 +293,14 @@
                 uint32_t fill_color,
                 uint32_t stroke_color,
                 int fill_mode,
-                int blend_type) override;
+                BlendMode blend_type) override;
   bool GetClipBox(FX_RECT* pRect) override;
   bool SetDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                  uint32_t color,
                  const FX_RECT* pSrcRect,
                  int left,
                  int top,
-                 int blend_type) override;
+                 BlendMode blend_type) override;
   bool StretchDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                      uint32_t color,
                      int dest_left,
@@ -309,14 +309,14 @@
                      int dest_height,
                      const FX_RECT* pClipRect,
                      uint32_t flags,
-                     int blend_type) override;
+                     BlendMode blend_type) override;
   bool StartDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                    int bitmap_alpha,
                    uint32_t color,
                    const CFX_Matrix* pMatrix,
                    uint32_t render_flags,
                    std::unique_ptr<CFX_ImageRenderer>* handle,
-                   int blend_type) override;
+                   BlendMode blend_type) override;
   bool DrawDeviceText(int nChars,
                       const FXTEXT_CHARPOS* pCharPos,
                       CFX_Font* pFont,
@@ -356,14 +356,14 @@
                 uint32_t fill_color,
                 uint32_t stroke_color,
                 int fill_mode,
-                int blend_type) override;
+                BlendMode blend_type) override;
   bool GetClipBox(FX_RECT* pRect) override;
   bool SetDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                  uint32_t color,
                  const FX_RECT* pSrcRect,
                  int left,
                  int top,
-                 int blend_type) override;
+                 BlendMode blend_type) override;
   bool StretchDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                      uint32_t color,
                      int dest_left,
@@ -372,14 +372,14 @@
                      int dest_height,
                      const FX_RECT* pClipRect,
                      uint32_t flags,
-                     int blend_type) override;
+                     BlendMode blend_type) override;
   bool StartDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
                    int bitmap_alpha,
                    uint32_t color,
                    const CFX_Matrix* pMatrix,
                    uint32_t render_flags,
                    std::unique_ptr<CFX_ImageRenderer>* handle,
-                   int blend_type) override;
+                   BlendMode blend_type) override;
   bool DrawDeviceText(int nChars,
                       const FXTEXT_CHARPOS* pCharPos,
                       CFX_Font* pFont,
diff --git a/fpdfsdk/fpdf_editpage.cpp b/fpdfsdk/fpdf_editpage.cpp
index 981baec..47f4caa 100644
--- a/fpdfsdk/fpdf_editpage.cpp
+++ b/fpdfsdk/fpdf_editpage.cpp
@@ -486,8 +486,7 @@
   if (!pPageObj)
     return false;
 
-  int blend_type = pPageObj->m_GeneralState.GetBlendType();
-  if (blend_type != FXDIB_BLEND_NORMAL)
+  if (pPageObj->m_GeneralState.GetBlendType() != BlendMode::kNormal)
     return true;
 
   const CPDF_Dictionary* pSMaskDict =
@@ -498,20 +497,18 @@
   if (pPageObj->m_GeneralState.GetFillAlpha() != 1.0f)
     return true;
 
-  if (pPageObj->IsPath() && pPageObj->m_GeneralState.GetStrokeAlpha() != 1.0f) {
+  if (pPageObj->IsPath() && pPageObj->m_GeneralState.GetStrokeAlpha() != 1.0f)
     return true;
-  }
 
-  if (pPageObj->IsForm()) {
-    const CPDF_Form* pForm = pPageObj->AsForm()->form();
-    if (pForm) {
-      const CPDF_Transparency& trans = pForm->GetTransparency();
-      if (trans.IsGroup() || trans.IsIsolated())
-        return true;
-    }
-  }
+  if (!pPageObj->IsForm())
+    return false;
 
-  return false;
+  const CPDF_Form* pForm = pPageObj->AsForm()->form();
+  if (!pForm)
+    return false;
+
+  const CPDF_Transparency& trans = pForm->GetTransparency();
+  return trans.IsGroup() || trans.IsIsolated();
 }
 
 FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 136841d..f924a36 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -498,7 +498,7 @@
 
   pDst->Clear(0xffffffff);
   pDst->CompositeBitmap(0, 0, size_x_bm, size_y_bm, pSrc, 0, 0,
-                        FXDIB_BLEND_NORMAL, nullptr, false);
+                        BlendMode::kNormal, nullptr, false);
 
   if (device->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
     device->StretchDIBits(pDst, mask_area.left, mask_area.top, size_x_bm,
@@ -606,7 +606,7 @@
       if (pDst->Create(size_x, size_y, FXDIB_Rgb32)) {
         memset(pDst->GetBuffer(), -1, pBitmap->GetPitch() * size_y);
         pDst->CompositeBitmap(0, 0, size_x, size_y, pBitmap, 0, 0,
-                              FXDIB_BLEND_NORMAL, nullptr, false);
+                              BlendMode::kNormal, nullptr, false);
         WinDC.StretchDIBits(pDst, 0, 0, size_x, size_y);
         bitsStretched = true;
       }
diff --git a/xfa/fxfa/cxfa_imagerenderer.cpp b/xfa/fxfa/cxfa_imagerenderer.cpp
index 5f90b3c..9cfccb9 100644
--- a/xfa/fxfa/cxfa_imagerenderer.cpp
+++ b/xfa/fxfa/cxfa_imagerenderer.cpp
@@ -22,7 +22,7 @@
 bool CXFA_ImageRenderer::Start() {
   if (m_pDevice->StartDIBitsWithBlend(m_pDIBBase, 255, 0, &m_ImageMatrix,
                                       FXDIB_INTERPOL, &m_DeviceHandle,
-                                      FXDIB_BLEND_NORMAL)) {
+                                      BlendMode::kNormal)) {
     if (m_DeviceHandle) {
       m_Status = 3;
       return true;
@@ -62,7 +62,7 @@
   if (m_pDIBBase->IsOpaqueImage()) {
     if (m_pDevice->StretchDIBitsWithFlagsAndBlend(
             m_pDIBBase, dest_left, dest_top, dest_width, dest_height,
-            FXDIB_INTERPOL, FXDIB_BLEND_NORMAL)) {
+            FXDIB_INTERPOL, BlendMode::kNormal)) {
       return false;
     }
   }
@@ -103,7 +103,7 @@
     } else {
       m_pDevice->SetDIBitsWithBlend(pBitmap, m_pTransformer->result().left,
                                     m_pTransformer->result().top,
-                                    FXDIB_BLEND_NORMAL);
+                                    BlendMode::kNormal);
     }
     return false;
   }
@@ -134,7 +134,7 @@
     if (pDIBitmap->IsAlphaMask())
       return;
 
-    m_pDevice->SetDIBitsWithBlend(pDIBitmap, left, top, FXDIB_BLEND_NORMAL);
+    m_pDevice->SetDIBitsWithBlend(pDIBitmap, left, top, BlendMode::kNormal);
     return;
   }
   if (!pDIBitmap->HasAlpha() ||