Change parameter type of RenderDeviceDriverIface::DrawPath().

This CL uses a struct CFX_FillRenderOptions |fill_options| as the input
of fill options instead of the integer parameter |fill_mode| for
RenderDeviceDriverIface::DrawPath().

Bug: pdfium:1531
Change-Id: I1a0f075673c3f056f689924f6d76811219815734
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/71271
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Hui Yingst <nigi@chromium.org>
diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp
index 70ff9e8..84ade5a 100644
--- a/core/fxge/agg/fx_agg_driver.cpp
+++ b/core/fxge/agg/fx_agg_driver.cpp
@@ -1333,8 +1333,13 @@
                                    const CFX_GraphStateData* pGraphState,
                                    uint32_t fill_color,
                                    uint32_t stroke_color,
-                                   int fill_mode,
+                                   const CFX_FillRenderOptions& fill_options,
                                    BlendMode blend_type) {
+  // TODO(https://crbug.com/pdfium/1531): Completely remove |fill_mode| by using
+  // |fill_options|. Meanwhile remove/update the use of
+  // GetAlternateOrWindingFillMode(), IsAlternateOrWindingFillMode(),
+  // GetAlternateOrWindingFillType() and |kAlternateOrWindingFillModeMask|.
+  const int fill_mode = GetIntegerFlagsFromFillOptions(fill_options);
   ASSERT(GetAlternateOrWindingFillMode(fill_mode) !=
          kAlternateOrWindingFillModeMask);
 
@@ -1354,8 +1359,8 @@
                         static_cast<float>(GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
     rasterizer.add_path(path_data.m_PathData);
     rasterizer.filling_rule(GetAlternateOrWindingFillType(fill_mode));
-    if (!RenderRasterizer(rasterizer, fill_color,
-                          !!(fill_mode & FXFILL_FULLCOVER), false)) {
+    if (!RenderRasterizer(rasterizer, fill_color, fill_options.full_cover,
+                          false)) {
       return false;
     }
   }
@@ -1363,7 +1368,7 @@
   if (!pGraphState || !stroke_alpha)
     return true;
 
-  if (fill_mode & FX_ZEROAREA_FILL) {
+  if (fill_options.zero_area) {
     CAgg_PathData path_data;
     path_data.BuildPath(pPathData, pObject2Device);
     agg::rasterizer_scanline_aa rasterizer;
@@ -1371,9 +1376,9 @@
                         static_cast<float>(GetDeviceCaps(FXDC_PIXEL_WIDTH)),
                         static_cast<float>(GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
     RasterizeStroke(&rasterizer, &path_data.m_PathData, nullptr, pGraphState, 1,
-                    !!(fill_mode & FX_STROKE_TEXT_MODE));
-    return RenderRasterizer(rasterizer, stroke_color,
-                            !!(fill_mode & FXFILL_FULLCOVER), m_bGroupKnockout);
+                    fill_options.stroke_text_mode);
+    return RenderRasterizer(rasterizer, stroke_color, fill_options.full_cover,
+                            m_bGroupKnockout);
   }
   CFX_Matrix matrix1;
   CFX_Matrix matrix2;
@@ -1394,9 +1399,9 @@
                       static_cast<float>(GetDeviceCaps(FXDC_PIXEL_WIDTH)),
                       static_cast<float>(GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
   RasterizeStroke(&rasterizer, &path_data.m_PathData, &matrix2, pGraphState,
-                  matrix1.a, !!(fill_mode & FX_STROKE_TEXT_MODE));
-  return RenderRasterizer(rasterizer, stroke_color,
-                          !!(fill_mode & FXFILL_FULLCOVER), m_bGroupKnockout);
+                  matrix1.a, fill_options.stroke_text_mode);
+  return RenderRasterizer(rasterizer, stroke_color, fill_options.full_cover,
+                          m_bGroupKnockout);
 }
 
 bool CFX_AggDeviceDriver::SetPixel(int x, int y, uint32_t color) {
diff --git a/core/fxge/agg/fx_agg_driver.h b/core/fxge/agg/fx_agg_driver.h
index c29342b..8add201 100644
--- a/core/fxge/agg/fx_agg_driver.h
+++ b/core/fxge/agg/fx_agg_driver.h
@@ -59,7 +59,7 @@
                 const CFX_GraphStateData* pGraphState,
                 uint32_t fill_color,
                 uint32_t stroke_color,
-                int fill_mode,
+                const CFX_FillRenderOptions& fill_options,
                 BlendMode blend_type) override;
   bool SetPixel(int x, int y, uint32_t color) override;
   bool FillRectWithBlend(const FX_RECT& rect,
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index 724fb8f..f6be878 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -530,11 +530,10 @@
     uint32_t stroke_color,
     const CFX_FillRenderOptions& fill_options,
     BlendMode blend_type) {
+  const bool fill =
+      fill_options.fill_type != CFX_FillRenderOptions::FillType::kNoFill;
+  uint8_t fill_alpha = fill ? FXARGB_A(fill_color) : 0;
   uint8_t stroke_alpha = pGraphState ? FXARGB_A(stroke_color) : 0;
-  uint8_t fill_alpha =
-      fill_options.fill_type != CFX_FillRenderOptions::FillType::kNoFill
-          ? FXARGB_A(fill_color)
-          : 0;
   pdfium::span<const FX_PATHPOINT> points = pPathData->GetPoints();
   if (stroke_alpha == 0 && points.size() == 2) {
     CFX_PointF pos1 = points[0].m_Point;
@@ -592,8 +591,8 @@
         return true;
     }
   }
-  if (fill_options.fill_type != CFX_FillRenderOptions::FillType::kNoFill &&
-      stroke_alpha == 0 && !fill_options.stroke && !fill_options.text_mode) {
+  if (fill && stroke_alpha == 0 && !fill_options.stroke &&
+      !fill_options.text_mode) {
     CFX_PathData newPath;
     bool bThin = false;
     bool setIdentity = false;
@@ -611,21 +610,20 @@
       if (pObject2Device && !pObject2Device->IsIdentity() && !setIdentity)
         pMatrix = pObject2Device;
 
-      int smooth_path = FX_ZEROAREA_FILL;
+      CFX_FillRenderOptions path_options;
+      path_options.zero_area = true;
       if (fill_options.aliased_path)
-        smooth_path |= FXFILL_NOPATHSMOOTH;
+        path_options.aliased_path = true;
 
       m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor,
-                                smooth_path, blend_type);
+                                path_options, blend_type);
     }
   }
 
-  const int fill_mode = GetIntegerFlagsFromFillOptions(fill_options);
-  if (fill_options.fill_type != CFX_FillRenderOptions::FillType::kNoFill &&
-      fill_alpha && stroke_alpha < 0xff && fill_options.stroke) {
+  if (fill && fill_alpha && stroke_alpha < 0xff && fill_options.stroke) {
     if (m_RenderCaps & FXRC_FILLSTROKE_PATH) {
       return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState,
-                                       fill_color, stroke_color, fill_mode,
+                                       fill_color, stroke_color, fill_options,
                                        blend_type);
     }
     return DrawFillStrokePath(pPathData, pObject2Device, pGraphState,
@@ -633,7 +631,7 @@
                               blend_type);
   }
   return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState,
-                                   fill_color, stroke_color, fill_mode,
+                                   fill_color, stroke_color, fill_options,
                                    blend_type);
 }
 
@@ -684,7 +682,7 @@
   matrix.Translate(-rect.left, -rect.top);
   if (!bitmap_device.GetDeviceDriver()->DrawPath(
           pPathData, &matrix, pGraphState, fill_color, stroke_color,
-          GetIntegerFlagsFromFillOptions(fill_options), blend_type)) {
+          fill_options, blend_type)) {
     return false;
   }
 #if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
@@ -736,8 +734,7 @@
   path.AppendPoint(ptMoveTo, FXPT_TYPE::MoveTo);
   path.AppendPoint(ptLineTo, FXPT_TYPE::LineTo);
   return m_pDeviceDriver->DrawPath(&path, nullptr, &graph_state, 0, color,
-                                   GetIntegerFlagsFromFillOptions(fill_options),
-                                   blend_type);
+                                   fill_options, blend_type);
 }
 
 bool CFX_RenderDevice::GetDIBits(const RetainPtr<CFX_DIBitmap>& pBitmap,
diff --git a/core/fxge/renderdevicedriver_iface.h b/core/fxge/renderdevicedriver_iface.h
index c6357b0..025356c 100644
--- a/core/fxge/renderdevicedriver_iface.h
+++ b/core/fxge/renderdevicedriver_iface.h
@@ -56,7 +56,7 @@
                         const CFX_GraphStateData* pGraphState,
                         uint32_t fill_color,
                         uint32_t stroke_color,
-                        int fill_mode,
+                        const CFX_FillRenderOptions& fill_options,
                         BlendMode blend_type) = 0;
   virtual bool SetPixel(int x, int y, uint32_t color);
   virtual bool FillRectWithBlend(const FX_RECT& rect,
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index 9008917..be8d8ac 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -2054,8 +2054,13 @@
     const CFX_GraphStateData* pGraphState,  // graphic state, for pen attributes
     uint32_t fill_color,                    // fill color
     uint32_t stroke_color,                  // stroke color
-    int fill_mode,  // fill mode, WINDING or ALTERNATE. 0 for not filled
+    const CFX_FillRenderOptions& fill_options,
     BlendMode blend_type) {
+  // TODO(https://crbug.com/pdfium/1531): Completely remove |fill_mode| by using
+  // |fill_options|. Meanwhile remove/update the use of
+  // GetAlternateOrWindingFillMode(), IsAlternateFillMode(),
+  // GetAlternateOrWindingFillType(),|kAlternateOrWindingFillModeMask|.
+  const int fill_mode = GetIntegerFlagsFromFillOptions(fill_options);
   ASSERT(GetAlternateOrWindingFillMode(fill_mode) !=
          kAlternateOrWindingFillModeMask);
   if (m_pCache->DrawPath(pPathData, pObject2Device, pGraphState, fill_color,
@@ -2069,7 +2074,7 @@
     skMatrix.setIdentity();
   SkPaint skPaint;
   skPaint.setAntiAlias(true);
-  if (fill_mode & FXFILL_FULLCOVER)
+  if (fill_options.full_cover)
     skPaint.setBlendMode(SkBlendMode::kPlus);
   int stroke_alpha = FXARGB_A(stroke_color);
   bool is_paint_stroke = pGraphState && stroke_alpha;
diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h
index 634cb7a..110c921 100644
--- a/core/fxge/skia/fx_skia_device.h
+++ b/core/fxge/skia/fx_skia_device.h
@@ -65,7 +65,7 @@
                 const CFX_GraphStateData* pGraphState,
                 uint32_t fill_color,
                 uint32_t stroke_color,
-                int fill_mode,
+                const CFX_FillRenderOptions& fill_options,
                 BlendMode blend_type) override;
 
   bool FillRectWithBlend(const FX_RECT& rect,
diff --git a/core/fxge/skia/fx_skia_device_embeddertest.cpp b/core/fxge/skia/fx_skia_device_embeddertest.cpp
index 128ca69..f8bb383 100644
--- a/core/fxge/skia/fx_skia_device_embeddertest.cpp
+++ b/core/fxge/skia/fx_skia_device_embeddertest.cpp
@@ -64,7 +64,8 @@
     driver->SetClip_PathFill(&clipPath, &clipMatrix, CFX_FillRenderOptions());
   if (state.m_graphic == State::Graphic::kPath) {
     driver->DrawPath(&path1, &matrix, &graphState, 0xFF112233, 0,
-                     FXFILL_WINDING, BlendMode::kNormal);
+                     CFX_FillRenderOptions::WindingOptions(),
+                     BlendMode::kNormal);
   } else if (state.m_graphic == State::Graphic::kText) {
     driver->DrawDeviceText(SK_ARRAY_COUNT(charPos), charPos, &font, matrix,
                            fontSize, 0xFF445566);
@@ -87,7 +88,8 @@
     driver->SetClip_PathFill(&clipPath, &clipMatrix2, CFX_FillRenderOptions());
   if (state.m_graphic == State::Graphic::kPath) {
     driver->DrawPath(&path2, &matrix2, &graphState, 0xFF112233, 0,
-                     FXFILL_WINDING, BlendMode::kNormal);
+                     CFX_FillRenderOptions::WindingOptions(),
+                     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 109d8b6..392e829 100644
--- a/core/fxge/win32/fx_win32_device.cpp
+++ b/core/fxge/win32/fx_win32_device.cpp
@@ -969,7 +969,7 @@
                                 const CFX_GraphStateData* pGraphState,
                                 uint32_t fill_color,
                                 uint32_t stroke_color,
-                                int fill_mode,
+                                const CFX_FillRenderOptions& fill_options,
                                 BlendMode blend_type) {
   if (blend_type != BlendMode::kNormal)
     return false;
@@ -1002,24 +1002,24 @@
     return false;
 
   if (pPlatform->m_GdiplusExt.IsAvailable()) {
-    if (bDrawAlpha || ((m_DeviceType != DeviceType::kPrinter &&
-                        !(fill_mode & FXFILL_FULLCOVER)) ||
-                       (pGraphState && !pGraphState->m_DashArray.empty()))) {
+    if (bDrawAlpha ||
+        ((m_DeviceType != DeviceType::kPrinter && !fill_options.full_cover) ||
+         (pGraphState && !pGraphState->m_DashArray.empty()))) {
       if (!((!pMatrix || !pMatrix->WillScale()) && pGraphState &&
             pGraphState->m_LineWidth == 1.0f &&
             (pPathData->GetPoints().size() == 5 ||
              pPathData->GetPoints().size() == 4) &&
             pPathData->IsRect())) {
-        if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix,
-                                             pGraphState, fill_color,
-                                             stroke_color, fill_mode)) {
+        if (pPlatform->m_GdiplusExt.DrawPath(
+                m_hDC, pPathData, pMatrix, pGraphState, fill_color,
+                stroke_color, GetIntegerFlagsFromFillOptions(fill_options))) {
           return true;
         }
       }
     }
   }
-  int old_fill_mode = fill_mode;
-  fill_mode &= 3;
+  const bool fill =
+      fill_options.fill_type != CFX_FillRenderOptions::FillType::kNoFill;
   HPEN hPen = nullptr;
   HBRUSH hBrush = nullptr;
   if (pGraphState && stroke_alpha) {
@@ -1027,8 +1027,8 @@
     hPen = CreateExtPen(pGraphState, pMatrix, stroke_color);
     hPen = (HPEN)SelectObject(m_hDC, hPen);
   }
-  if (fill_mode && fill_alpha) {
-    SetPolyFillMode(m_hDC, fill_mode);
+  if (fill && fill_alpha) {
+    SetPolyFillMode(m_hDC, FillTypeToGdiFillType(fill_options.fill_type));
     hBrush = CreateBrush(fill_color);
     hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
   }
@@ -1044,8 +1044,8 @@
   } else {
     SetPathToDC(m_hDC, pPathData, pMatrix);
     if (pGraphState && stroke_alpha) {
-      if (fill_mode && fill_alpha) {
-        if (old_fill_mode & FX_FILL_TEXT_MODE) {
+      if (fill && fill_alpha) {
+        if (fill_options.text_mode) {
           StrokeAndFillPath(m_hDC);
         } else {
           FillPath(m_hDC);
@@ -1055,7 +1055,7 @@
       } else {
         StrokePath(m_hDC);
       }
-    } else if (fill_mode && fill_alpha) {
+    } else if (fill && fill_alpha) {
       FillPath(m_hDC);
     }
   }
diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp
index 408d258..1ddb881 100644
--- a/core/fxge/win32/fx_win32_print.cpp
+++ b/core/fxge/win32/fx_win32_print.cpp
@@ -451,12 +451,13 @@
                                 const CFX_GraphStateData* pGraphState,
                                 FX_ARGB fill_color,
                                 FX_ARGB stroke_color,
-                                int fill_mode,
+                                const CFX_FillRenderOptions& fill_options,
                                 BlendMode blend_type) {
   if (blend_type != BlendMode::kNormal)
     return false;
   return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState,
-                               fill_color, stroke_color, fill_mode & 3);
+                               fill_color, stroke_color,
+                               static_cast<int>(fill_options.fill_type));
 }
 
 bool CPSPrinterDriver::GetClipBox(FX_RECT* pRect) {
@@ -575,7 +576,7 @@
                                       const CFX_GraphStateData* pGraphState,
                                       uint32_t fill_color,
                                       uint32_t stroke_color,
-                                      int fill_mode,
+                                      const CFX_FillRenderOptions& fill_options,
                                       BlendMode blend_type) {
   return false;
 }
diff --git a/core/fxge/win32/win32_int.h b/core/fxge/win32/win32_int.h
index f81457b..121f7de 100644
--- a/core/fxge/win32/win32_int.h
+++ b/core/fxge/win32/win32_int.h
@@ -95,7 +95,7 @@
                 const CFX_GraphStateData* pGraphState,
                 uint32_t fill_color,
                 uint32_t stroke_color,
-                int fill_mode,
+                const CFX_FillRenderOptions& fill_options,
                 BlendMode blend_type) override;
   bool FillRectWithBlend(const FX_RECT& rect,
                          uint32_t fill_color,
@@ -246,7 +246,7 @@
                 const CFX_GraphStateData* pGraphState,
                 uint32_t fill_color,
                 uint32_t stroke_color,
-                int fill_mode,
+                const CFX_FillRenderOptions& fill_options,
                 BlendMode blend_type) override;
   bool GetClipBox(FX_RECT* pRect) override;
   bool SetDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,
@@ -310,7 +310,7 @@
                 const CFX_GraphStateData* pGraphState,
                 uint32_t fill_color,
                 uint32_t stroke_color,
-                int fill_mode,
+                const CFX_FillRenderOptions& fill_options,
                 BlendMode blend_type) override;
   bool GetClipBox(FX_RECT* pRect) override;
   bool SetDIBits(const RetainPtr<CFX_DIBBase>& pBitmap,