Cleanup CFX_PathData.

This CL replaces the array of path points with a vector. Cleaning up the usage
as required.

Change-Id: Ifa386a2c847005fef68af748ebe99c4e08961238
Reviewed-on: https://pdfium-review.googlesource.com/2710
Reviewed-by: Nicolás Peña <npm@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 4de89a4..ff8b676 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -148,14 +148,13 @@
 void CPDF_PageContentGenerator::ProcessPath(CFX_ByteTextBuf* buf,
                                             CPDF_PathObject* pPathObj) {
   ProcessGraphics(buf, pPathObj);
-  const FX_PATHPOINT* pPoints = pPathObj->m_Path.GetPoints();
+  auto& pPoints = pPathObj->m_Path.GetPoints();
   if (pPathObj->m_Path.IsRect()) {
     *buf << pPoints[0].m_PointX << " " << pPoints[0].m_PointY << " "
          << (pPoints[2].m_PointX - pPoints[0].m_PointX) << " "
          << (pPoints[2].m_PointY - pPoints[0].m_PointY) << " re";
   } else {
-    int numPoints = pPathObj->m_Path.GetPointCount();
-    for (int i = 0; i < numPoints; i++) {
+    for (size_t i = 0; i < pPoints.size(); i++) {
       if (i > 0)
         *buf << " ";
       *buf << pPoints[i].m_PointX << " " << pPoints[i].m_PointY;
@@ -165,7 +164,7 @@
       } else if (pointType == FXPT_TYPE::LineTo) {
         *buf << " l";
       } else if (pointType == FXPT_TYPE::BezierTo) {
-        if (i + 2 >= numPoints ||
+        if (i + 2 >= pPoints.size() ||
             !pPoints[i].IsTypeAndOpen(FXPT_TYPE::BezierTo) ||
             !pPoints[i + 1].IsTypeAndOpen(FXPT_TYPE::BezierTo) ||
             pPoints[i + 2].m_Type != FXPT_TYPE::BezierTo) {
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
index 0a636a1..42e6e2d 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
@@ -44,6 +44,7 @@
   pPathObj->m_Path.AppendRect(10, 5, 13, 30);
   pPathObj->m_FillType = FXFILL_ALTERNATE;
   pPathObj->m_bStroke = true;
+
   auto pTestPage = pdfium::MakeUnique<CPDF_Page>(nullptr, nullptr, false);
   CPDF_PageContentGenerator generator(pTestPage.get());
   CFX_ByteTextBuf buf;
@@ -51,77 +52,33 @@
   EXPECT_EQ("q 10 5 3 25 re B* Q\n", buf.MakeString());
 
   pPathObj = pdfium::MakeUnique<CPDF_PathObject>();
-  pPathObj->m_Path.SetPointCount(4);
-  FX_PATHPOINT* pPoints = pPathObj->m_Path.GetMutablePoints();
-  pPoints[0].m_PointX = 0;
-  pPoints[0].m_PointY = 0;
-  pPoints[0].m_Type = FXPT_TYPE::MoveTo;
-  pPoints[0].m_CloseFigure = false;
-  pPoints[1].m_PointX = 5.2f;
-  pPoints[1].m_PointY = 0;
-  pPoints[1].m_Type = FXPT_TYPE::LineTo;
-  pPoints[1].m_CloseFigure = false;
-  pPoints[2].m_PointX = 5.2f;
-  pPoints[2].m_PointY = 3.78f;
-  pPoints[2].m_Type = FXPT_TYPE::LineTo;
-  pPoints[2].m_CloseFigure = false;
-  pPoints[3].m_PointX = 0;
-  pPoints[3].m_PointY = 3.78f;
-  pPoints[3].m_Type = FXPT_TYPE::LineTo;
-  pPoints[3].m_CloseFigure = true;
+  pPathObj->m_Path.AppendPoint(0, 0, FXPT_TYPE::MoveTo, false);
+  pPathObj->m_Path.AppendPoint(5.2f, 0, FXPT_TYPE::LineTo, false);
+  pPathObj->m_Path.AppendPoint(5.2f, 3.78f, FXPT_TYPE::LineTo, false);
+  pPathObj->m_Path.AppendPoint(0, 3.78f, FXPT_TYPE::LineTo, true);
   pPathObj->m_FillType = 0;
   pPathObj->m_bStroke = false;
   buf.Clear();
+
   TestProcessPath(&generator, &buf, pPathObj.get());
   EXPECT_EQ("q 0 0 5.2 3.78 re n Q\n", buf.MakeString());
 }
 
 TEST_F(CPDF_PageContentGeneratorTest, ProcessPath) {
   auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>();
-  pPathObj->m_Path.SetPointCount(10);
-  FX_PATHPOINT* pPoints = pPathObj->m_Path.GetMutablePoints();
-  pPoints[0].m_PointX = 3.102f;
-  pPoints[0].m_PointY = 4.67f;
-  pPoints[0].m_Type = FXPT_TYPE::MoveTo;
-  pPoints[0].m_CloseFigure = false;
-  pPoints[1].m_PointX = 5.45f;
-  pPoints[1].m_PointY = 0.29f;
-  pPoints[1].m_Type = FXPT_TYPE::LineTo;
-  pPoints[1].m_CloseFigure = false;
-  pPoints[2].m_PointX = 4.24f;
-  pPoints[2].m_PointY = 3.15f;
-  pPoints[2].m_Type = FXPT_TYPE::BezierTo;
-  pPoints[2].m_CloseFigure = false;
-  pPoints[3].m_PointX = 4.65f;
-  pPoints[3].m_PointY = 2.98f;
-  pPoints[3].m_Type = FXPT_TYPE::BezierTo;
-  pPoints[3].m_CloseFigure = false;
-  pPoints[4].m_PointX = 3.456f;
-  pPoints[4].m_PointY = 0.24f;
-  pPoints[4].m_Type = FXPT_TYPE::BezierTo;
-  pPoints[4].m_CloseFigure = false;
-  pPoints[5].m_PointX = 10.6f;
-  pPoints[5].m_PointY = 11.15f;
-  pPoints[5].m_Type = FXPT_TYPE::LineTo;
-  pPoints[5].m_CloseFigure = false;
-  pPoints[6].m_PointX = 11;
-  pPoints[6].m_PointY = 12.5f;
-  pPoints[6].m_Type = FXPT_TYPE::LineTo;
-  pPoints[6].m_CloseFigure = false;
-  pPoints[7].m_PointX = 11.46f;
-  pPoints[7].m_PointY = 12.67f;
-  pPoints[7].m_Type = FXPT_TYPE::BezierTo;
-  pPoints[7].m_CloseFigure = false;
-  pPoints[8].m_PointX = 11.84f;
-  pPoints[8].m_PointY = 12.96f;
-  pPoints[8].m_Type = FXPT_TYPE::BezierTo;
-  pPoints[8].m_CloseFigure = false;
-  pPoints[9].m_PointX = 12;
-  pPoints[9].m_PointY = 13.64f;
-  pPoints[9].m_Type = FXPT_TYPE::BezierTo;
-  pPoints[9].m_CloseFigure = true;
+  pPathObj->m_Path.AppendPoint(3.102f, 4.67f, FXPT_TYPE::MoveTo, false);
+  pPathObj->m_Path.AppendPoint(5.45f, 0.29f, FXPT_TYPE::LineTo, false);
+  pPathObj->m_Path.AppendPoint(4.24f, 3.15f, FXPT_TYPE::BezierTo, false);
+  pPathObj->m_Path.AppendPoint(4.65f, 2.98f, FXPT_TYPE::BezierTo, false);
+  pPathObj->m_Path.AppendPoint(3.456f, 0.24f, FXPT_TYPE::BezierTo, false);
+  pPathObj->m_Path.AppendPoint(10.6f, 11.15f, FXPT_TYPE::LineTo, false);
+  pPathObj->m_Path.AppendPoint(11, 12.5f, FXPT_TYPE::LineTo, false);
+  pPathObj->m_Path.AppendPoint(11.46f, 12.67f, FXPT_TYPE::BezierTo, false);
+  pPathObj->m_Path.AppendPoint(11.84f, 12.96f, FXPT_TYPE::BezierTo, false);
+  pPathObj->m_Path.AppendPoint(12, 13.64f, FXPT_TYPE::BezierTo, true);
   pPathObj->m_FillType = FXFILL_WINDING;
   pPathObj->m_bStroke = false;
+
   auto pTestPage = pdfium::MakeUnique<CPDF_Page>(nullptr, nullptr, false);
   CPDF_PageContentGenerator generator(pTestPage.get());
   CFX_ByteTextBuf buf;
@@ -134,29 +91,21 @@
 
 TEST_F(CPDF_PageContentGeneratorTest, ProcessGraphics) {
   auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>();
-  pPathObj->m_Path.SetPointCount(3);
-  FX_PATHPOINT* pPoints = pPathObj->m_Path.GetMutablePoints();
-  pPoints[0].m_PointX = 1;
-  pPoints[0].m_PointY = 2;
-  pPoints[0].m_Type = FXPT_TYPE::MoveTo;
-  pPoints[0].m_CloseFigure = false;
-  pPoints[1].m_PointX = 3;
-  pPoints[1].m_PointY = 4;
-  pPoints[1].m_Type = FXPT_TYPE::LineTo;
-  pPoints[1].m_CloseFigure = false;
-  pPoints[2].m_PointX = 5;
-  pPoints[2].m_PointY = 6;
-  pPoints[2].m_Type = FXPT_TYPE::LineTo;
-  pPoints[2].m_CloseFigure = true;
+  pPathObj->m_Path.AppendPoint(1, 2, FXPT_TYPE::MoveTo, false);
+  pPathObj->m_Path.AppendPoint(3, 4, FXPT_TYPE::LineTo, false);
+  pPathObj->m_Path.AppendPoint(5, 6, FXPT_TYPE::LineTo, true);
   pPathObj->m_FillType = FXFILL_WINDING;
   pPathObj->m_bStroke = true;
+
   FX_FLOAT rgb[3] = {0.5f, 0.7f, 0.35f};
   CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
   pPathObj->m_ColorState.SetFillColor(pCS, rgb, 3);
+
   FX_FLOAT rgb2[3] = {1, 0.9f, 0};
   pPathObj->m_ColorState.SetStrokeColor(pCS, rgb2, 3);
   pPathObj->m_GeneralState.SetFillAlpha(0.5f);
   pPathObj->m_GeneralState.SetStrokeAlpha(0.8f);
+
   auto pDoc = pdfium::MakeUnique<CPDF_Document>(nullptr);
   pDoc->CreateNewDoc();
   CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(0);
@@ -165,6 +114,7 @@
   CFX_ByteTextBuf buf;
   TestProcessPath(&generator, &buf, pPathObj.get());
   CFX_ByteString pathString = buf.MakeString();
+
   // Color RGB values used are integers divided by 255.
   EXPECT_EQ("q 0.501961 0.701961 0.34902 rg 1 0.901961 0 RG /",
             pathString.Left(48));
@@ -184,6 +134,7 @@
   EXPECT_EQ("q 0.501961 0.701961 0.34902 rg 1 0.901961 0 RG 10.5 w /",
             pathString2.Left(55));
   EXPECT_EQ(" gs 1 2 m 3 4 l 5 6 l h B Q\n", pathString2.Right(28));
+
   // Compare with the previous (should use same dictionary for gs)
   EXPECT_EQ(pathString.GetLength() + 7, pathString2.GetLength());
   EXPECT_EQ(pathString.Mid(48, pathString.GetLength() - 76),
diff --git a/core/fpdfapi/page/cpdf_path.cpp b/core/fpdfapi/page/cpdf_path.cpp
index 96d6b72..a95ce1e 100644
--- a/core/fpdfapi/page/cpdf_path.cpp
+++ b/core/fpdfapi/page/cpdf_path.cpp
@@ -12,20 +12,12 @@
 
 CPDF_Path::~CPDF_Path() {}
 
-int CPDF_Path::GetPointCount() const {
-  return m_Ref.GetObject()->GetPointCount();
-}
-
-void CPDF_Path::SetPointCount(int count) {
-  m_Ref.GetPrivateCopy()->SetPointCount(count);
-}
-
-const FX_PATHPOINT* CPDF_Path::GetPoints() const {
+const std::vector<FX_PATHPOINT>& CPDF_Path::GetPoints() const {
   return m_Ref.GetObject()->GetPoints();
 }
 
-FX_PATHPOINT* CPDF_Path::GetMutablePoints() {
-  return m_Ref.GetPrivateCopy()->GetPoints();
+void CPDF_Path::ClosePath() {
+  m_Ref.GetPrivateCopy()->ClosePath();
 }
 
 FX_FLOAT CPDF_Path::GetPointX(int index) const {
@@ -73,7 +65,6 @@
                             FXPT_TYPE type,
                             bool close) {
   CFX_PathData data;
-  data.SetPointCount(1);
-  data.SetPoint(0, x, y, type, close);
+  data.AppendPoint(x, y, type, close);
   Append(&data, nullptr);
 }
diff --git a/core/fpdfapi/page/cpdf_path.h b/core/fpdfapi/page/cpdf_path.h
index 21a94be..97dd8fd 100644
--- a/core/fpdfapi/page/cpdf_path.h
+++ b/core/fpdfapi/page/cpdf_path.h
@@ -7,6 +7,8 @@
 #ifndef CORE_FPDFAPI_PAGE_CPDF_PATH_H_
 #define CORE_FPDFAPI_PAGE_CPDF_PATH_H_
 
+#include <vector>
+
 #include "core/fxcrt/cfx_shared_copy_on_write.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxge/cfx_fxgedevice.h"
@@ -22,10 +24,8 @@
   void Emplace() { m_Ref.Emplace(); }
   explicit operator bool() const { return !!m_Ref; }
 
-  int GetPointCount() const;
-  void SetPointCount(int count);
-  const FX_PATHPOINT* GetPoints() const;
-  FX_PATHPOINT* GetMutablePoints();
+  const std::vector<FX_PATHPOINT>& GetPoints() const;
+  void ClosePath();
 
   FX_FLOAT GetPointX(int index) const;
   FX_FLOAT GetPointY(int index) const;
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index 0af43d0..e991e45 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -1506,10 +1506,14 @@
       m_pPathPoints[PathPointCount - 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) {
     PathPointCount--;
   }
+
   CPDF_Path Path;
-  Path.SetPointCount(PathPointCount);
-  FXSYS_memcpy(Path.GetMutablePoints(), m_pPathPoints,
-               sizeof(FX_PATHPOINT) * PathPointCount);
+  for (int i = 0; i < PathPointCount; i++) {
+    FX_PATHPOINT& point = m_pPathPoints[i];
+    Path.AppendPoint(point.m_PointX, point.m_PointY, point.m_Type,
+                     point.m_CloseFigure);
+  }
+
   CFX_Matrix matrix = m_pCurStates->m_CTM;
   matrix.Concat(m_mtContentToUser);
   if (bStroke || FillType) {
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 4f2638f..60b5760 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -611,18 +611,21 @@
     x.FromPoints(x0, x1, x2, x3);
     y.FromPoints(y0, y1, y2, y3);
   }
+
   Coon_Bezier first_half() {
     Coon_Bezier result;
     result.x = x.first_half();
     result.y = y.first_half();
     return result;
   }
+
   Coon_Bezier second_half() {
     Coon_Bezier result;
     result.x = x.second_half();
     result.y = y.second_half();
     return result;
   }
+
   void BezierInterpol(Coon_Bezier& C1,
                       Coon_Bezier& C2,
                       Coon_Bezier& D1,
@@ -630,30 +633,31 @@
     x.BezierInterpol(C1.x, C2.x, D1.x, D2.x);
     y.BezierInterpol(C1.y, C2.y, D1.y, D2.y);
   }
-  void GetPoints(FX_PATHPOINT* pPoints) {
+
+  void GetPoints(std::vector<FX_PATHPOINT>& pPoints, size_t start_idx) {
     float p[4];
     int i;
     x.GetPoints(p);
-    for (i = 0; i < 4; i++) {
-      pPoints[i].m_PointX = p[i];
-    }
+    for (i = 0; i < 4; i++)
+      pPoints[start_idx + i].m_PointX = p[i];
+
     y.GetPoints(p);
-    for (i = 0; i < 4; i++) {
-      pPoints[i].m_PointY = p[i];
-    }
+    for (i = 0; i < 4; i++)
+      pPoints[start_idx + i].m_PointY = p[i];
   }
-  void GetPointsReverse(FX_PATHPOINT* pPoints) {
+
+  void GetPointsReverse(std::vector<FX_PATHPOINT>& pPoints, size_t start_idx) {
     float p[4];
     int i;
     x.GetPointsReverse(p);
-    for (i = 0; i < 4; i++) {
-      pPoints[i].m_PointX = p[i];
-    }
+    for (i = 0; i < 4; i++)
+      pPoints[i + start_idx].m_PointX = p[i];
+
     y.GetPointsReverse(p);
-    for (i = 0; i < 4; i++) {
-      pPoints[i].m_PointY = p[i];
-    }
+    for (i = 0; i < 4; i++)
+      pPoints[i + start_idx].m_PointY = p[i];
   }
+
   float Distance() { return x.Distance() + y.Distance(); }
 };
 
@@ -693,6 +697,7 @@
   }
 };
 
+#define COONCOLOR_THRESHOLD 4
 struct CPDF_PatchDrawer {
   Coon_Color patch_colors[4];
   int max_delta;
@@ -728,15 +733,15 @@
       d_top = div_colors[1].Distance(div_colors[2]);
       d_right = div_colors[2].Distance(div_colors[3]);
     }
-#define COONCOLOR_THRESHOLD 4
+
     if (bSmall ||
         (d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRESHOLD &&
          d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD)) {
-      FX_PATHPOINT* pPoints = path.GetPoints();
-      C1.GetPoints(pPoints);
-      D2.GetPoints(pPoints + 3);
-      C2.GetPointsReverse(pPoints + 6);
-      D1.GetPointsReverse(pPoints + 9);
+      std::vector<FX_PATHPOINT>& pPoints = path.GetPoints();
+      C1.GetPoints(pPoints, 0);
+      D2.GetPoints(pPoints, 3);
+      C2.GetPointsReverse(pPoints, 6);
+      D1.GetPointsReverse(pPoints, 9);
       int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER;
       if (fill_mode & RENDER_NOPATHSMOOTH) {
         fillFlags |= FXFILL_NOPATHSMOOTH;
@@ -814,14 +819,12 @@
   patch.alpha = alpha;
   patch.pDevice = &device;
   patch.fill_mode = fill_mode;
-  patch.path.SetPointCount(13);
-  FX_PATHPOINT* pPoints = patch.path.GetPoints();
-  pPoints[0].m_Type = FXPT_TYPE::MoveTo;
-  pPoints[0].m_CloseFigure = false;
-  for (int i = 1; i < 13; i++) {
-    pPoints[i].m_Type = FXPT_TYPE::BezierTo;
-    pPoints[i].m_CloseFigure = false;
+
+  for (int i = 0; i < 13; i++) {
+    patch.path.AppendPoint(
+        0, 0, i == 0 ? FXPT_TYPE::MoveTo : FXPT_TYPE::BezierTo, false);
   }
+
   CFX_PointF coords[16];
   int point_count = type == kTensorProductPatchMeshShading ? 16 : 12;
   while (!stream.BitStream()->IsEOF()) {
@@ -1368,7 +1371,7 @@
     if (!pPathData)
       continue;
 
-    if (pPathData->GetPointCount() == 0) {
+    if (pPathData->GetPoints().empty()) {
       CFX_PathData EmptyPath;
       EmptyPath.AppendRect(-1, -1, 0, 0);
       int fill_mode = FXFILL_WINDING;
diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp
index 3ae2c37..e17f2df 100644
--- a/core/fxge/agg/fx_agg_driver.cpp
+++ b/core/fxge/agg/fx_agg_driver.cpp
@@ -273,20 +273,20 @@
 
 void CAgg_PathData::BuildPath(const CFX_PathData* pPathData,
                               const CFX_Matrix* pObject2Device) {
-  int nPoints = pPathData->GetPointCount();
-  FX_PATHPOINT* pPoints = pPathData->GetPoints();
-  for (int i = 0; i < nPoints; i++) {
-    FX_FLOAT x = pPoints[i].m_PointX, y = pPoints[i].m_PointY;
-    if (pObject2Device) {
+  const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints();
+  for (size_t i = 0; i < pPoints.size(); i++) {
+    FX_FLOAT x = pPoints[i].m_PointX;
+    FX_FLOAT y = pPoints[i].m_PointY;
+    if (pObject2Device)
       pObject2Device->TransformPoint(x, y);
-    }
+
     HardClip(x, y);
     FXPT_TYPE point_type = pPoints[i].m_Type;
     if (point_type == FXPT_TYPE::MoveTo) {
       m_PathData.move_to(x, y);
     } else if (point_type == FXPT_TYPE::LineTo) {
       if (pPoints[i - 1].IsTypeAndOpen(FXPT_TYPE::MoveTo) &&
-          (i == nPoints - 1 ||
+          (i == pPoints.size() - 1 ||
            pPoints[i + 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) &&
           pPoints[i].m_PointX == pPoints[i - 1].m_PointX &&
           pPoints[i].m_PointY == pPoints[i - 1].m_PointY) {
@@ -553,7 +553,8 @@
     m_pClipRgn = pdfium::MakeUnique<CFX_ClipRgn>(
         GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT));
   }
-  if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) {
+  size_t size = pPathData->GetPoints().size();
+  if (size == 5 || size == 4) {
     CFX_FloatRect rectf;
     if (pPathData->IsRect(pObject2Device, &rectf)) {
       rectf.Intersect(
diff --git a/core/fxge/cfx_pathdata.h b/core/fxge/cfx_pathdata.h
index 46fdfeb..7d5e6e2 100644
--- a/core/fxge/cfx_pathdata.h
+++ b/core/fxge/cfx_pathdata.h
@@ -7,6 +7,8 @@
 #ifndef CORE_FXGE_CFX_PATHDATA_H_
 #define CORE_FXGE_CFX_PATHDATA_H_
 
+#include <vector>
+
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxge/cfx_renderdevice.h"
@@ -28,41 +30,37 @@
   CFX_PathData(const CFX_PathData& src);
   ~CFX_PathData();
 
-  int GetPointCount() const { return m_PointCount; }
-  FXPT_TYPE GetType(int index) const { return m_pPoints[index].m_Type; }
-  bool IsClosingFigure(int index) const {
-    return m_pPoints[index].m_CloseFigure;
-  }
-  FX_FLOAT GetPointX(int index) const { return m_pPoints[index].m_PointX; }
-  FX_FLOAT GetPointY(int index) const { return m_pPoints[index].m_PointY; }
-  FX_PATHPOINT* GetPoints() const { return m_pPoints; }
+  void Clear();
 
-  void SetPointCount(int nPoints);
-  void AllocPointCount(int nPoints);
-  void AddPointCount(int addPoints);
+  FXPT_TYPE GetType(int index) const { return m_Points[index].m_Type; }
+  bool IsClosingFigure(int index) const {
+    return m_Points[index].m_CloseFigure;
+  }
+
+  FX_FLOAT GetPointX(int index) const { return m_Points[index].m_PointX; }
+  FX_FLOAT GetPointY(int index) const { return m_Points[index].m_PointY; }
+  const std::vector<FX_PATHPOINT>& GetPoints() const { return m_Points; }
+  std::vector<FX_PATHPOINT>& GetPoints() { return m_Points; }
+
   CFX_FloatRect GetBoundingBox() const;
   CFX_FloatRect GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const;
+
   void Transform(const CFX_Matrix* pMatrix);
   bool IsRect() const;
-  bool GetZeroAreaPath(CFX_PathData& NewPath,
+  bool GetZeroAreaPath(CFX_PathData* NewPath,
                        CFX_Matrix* pMatrix,
                        bool& bThin,
                        bool bAdjust) const;
   bool IsRect(const CFX_Matrix* pMatrix, CFX_FloatRect* rect) const;
+
+  void Append(const CFX_PathData& data);
   void Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix);
   void AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top);
-  void SetPoint(int index,
-                FX_FLOAT x,
-                FX_FLOAT y,
-                FXPT_TYPE type,
-                bool closeFigure);
-  void TrimPoints(int nPoints);
-  void Copy(const CFX_PathData& src);
+  void AppendPoint(FX_FLOAT x, FX_FLOAT y, FXPT_TYPE type, bool closeFigure);
+  void ClosePath();
 
  private:
-  int m_PointCount;
-  int m_AllocCount;
-  FX_PATHPOINT* m_pPoints;
+  std::vector<FX_PATHPOINT> m_Points;
 };
 
 #endif  // CORE_FXGE_CFX_PATHDATA_H_
diff --git a/core/fxge/ge/cfx_font.cpp b/core/fxge/ge/cfx_font.cpp
index 3ba2667..ef6960a 100644
--- a/core/fxge/ge/cfx_font.cpp
+++ b/core/fxge/ge/cfx_font.cpp
@@ -28,9 +28,7 @@
 namespace {
 
 typedef struct {
-  bool m_bCount;
-  int m_PointCount;
-  FX_PATHPOINT* m_pPoints;
+  CFX_PathData* m_pPath;
   int m_CurX;
   int m_CurY;
   FX_FLOAT m_CoordUnit;
@@ -86,64 +84,51 @@
 }
 
 void Outline_CheckEmptyContour(OUTLINE_PARAMS* param) {
-  if (param->m_PointCount >= 2 &&
-      param->m_pPoints[param->m_PointCount - 2].IsTypeAndOpen(
-          FXPT_TYPE::MoveTo) &&
-      param->m_pPoints[param->m_PointCount - 2].m_PointX ==
-          param->m_pPoints[param->m_PointCount - 1].m_PointX &&
-      param->m_pPoints[param->m_PointCount - 2].m_PointY ==
-          param->m_pPoints[param->m_PointCount - 1].m_PointY) {
-    param->m_PointCount -= 2;
+  std::vector<FX_PATHPOINT>& points = param->m_pPath->GetPoints();
+  size_t size = points.size();
+
+  if (size >= 2 && points[size - 2].IsTypeAndOpen(FXPT_TYPE::MoveTo) &&
+      points[size - 2].m_PointX == points[size - 1].m_PointX &&
+      points[size - 2].m_PointY == points[size - 1].m_PointY) {
+    size -= 2;
   }
-  if (param->m_PointCount >= 4 &&
-      param->m_pPoints[param->m_PointCount - 4].IsTypeAndOpen(
-          FXPT_TYPE::MoveTo) &&
-      param->m_pPoints[param->m_PointCount - 3].IsTypeAndOpen(
-          FXPT_TYPE::BezierTo) &&
-      param->m_pPoints[param->m_PointCount - 3].m_PointX ==
-          param->m_pPoints[param->m_PointCount - 4].m_PointX &&
-      param->m_pPoints[param->m_PointCount - 3].m_PointY ==
-          param->m_pPoints[param->m_PointCount - 4].m_PointY &&
-      param->m_pPoints[param->m_PointCount - 2].m_PointX ==
-          param->m_pPoints[param->m_PointCount - 4].m_PointX &&
-      param->m_pPoints[param->m_PointCount - 2].m_PointY ==
-          param->m_pPoints[param->m_PointCount - 4].m_PointY &&
-      param->m_pPoints[param->m_PointCount - 1].m_PointX ==
-          param->m_pPoints[param->m_PointCount - 4].m_PointX &&
-      param->m_pPoints[param->m_PointCount - 1].m_PointY ==
-          param->m_pPoints[param->m_PointCount - 4].m_PointY) {
-    param->m_PointCount -= 4;
+  if (size >= 4 && points[size - 4].IsTypeAndOpen(FXPT_TYPE::MoveTo) &&
+      points[size - 3].IsTypeAndOpen(FXPT_TYPE::BezierTo) &&
+      points[size - 3].m_PointX == points[size - 4].m_PointX &&
+      points[size - 3].m_PointY == points[size - 4].m_PointY &&
+      points[size - 2].m_PointX == points[size - 4].m_PointX &&
+      points[size - 2].m_PointY == points[size - 4].m_PointY &&
+      points[size - 1].m_PointX == points[size - 4].m_PointX &&
+      points[size - 1].m_PointY == points[size - 4].m_PointY) {
+    size -= 4;
   }
+  points.resize(size);
 }
 
 int Outline_MoveTo(const FXFT_Vector* to, void* user) {
   OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
-  if (!param->m_bCount) {
-    Outline_CheckEmptyContour(param);
-    param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount].m_Type = FXPT_TYPE::MoveTo;
-    param->m_pPoints[param->m_PointCount].m_CloseFigure = false;
-    param->m_CurX = to->x;
-    param->m_CurY = to->y;
-    if (param->m_PointCount)
-      param->m_pPoints[param->m_PointCount - 1].m_CloseFigure = true;
-  }
-  param->m_PointCount++;
+
+  Outline_CheckEmptyContour(param);
+
+  param->m_pPath->ClosePath();
+  param->m_pPath->AppendPoint(to->x / param->m_CoordUnit,
+                              to->y / param->m_CoordUnit, FXPT_TYPE::MoveTo,
+                              false);
+
+  param->m_CurX = to->x;
+  param->m_CurY = to->y;
   return 0;
 }
 
 int Outline_LineTo(const FXFT_Vector* to, void* user) {
   OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
-  if (!param->m_bCount) {
-    param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount].m_Type = FXPT_TYPE::LineTo;
-    param->m_pPoints[param->m_PointCount].m_CloseFigure = false;
-    param->m_CurX = to->x;
-    param->m_CurY = to->y;
-  }
-  param->m_PointCount++;
+
+  param->m_pPath->AppendPoint(to->x / param->m_CoordUnit,
+                              to->y / param->m_CoordUnit, FXPT_TYPE::LineTo,
+                              false);
+
+  param->m_CurX = to->x;
+  param->m_CurY = to->y;
   return 0;
 }
 
@@ -151,31 +136,25 @@
                     const FXFT_Vector* to,
                     void* user) {
   OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
-  if (!param->m_bCount) {
-    param->m_pPoints[param->m_PointCount].m_PointX =
-        (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) /
-        param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount].m_PointY =
-        (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) /
-        param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount].m_Type = FXPT_TYPE::BezierTo;
-    param->m_pPoints[param->m_PointCount].m_CloseFigure = false;
-    param->m_pPoints[param->m_PointCount + 1].m_PointX =
-        (control->x + (to->x - control->x) / 3) / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount + 1].m_PointY =
-        (control->y + (to->y - control->y) / 3) / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount + 1].m_Type = FXPT_TYPE::BezierTo;
-    param->m_pPoints[param->m_PointCount + 1].m_CloseFigure = false;
-    param->m_pPoints[param->m_PointCount + 2].m_PointX =
-        to->x / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount + 2].m_PointY =
-        to->y / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount + 2].m_Type = FXPT_TYPE::BezierTo;
-    param->m_pPoints[param->m_PointCount + 2].m_CloseFigure = false;
-    param->m_CurX = to->x;
-    param->m_CurY = to->y;
-  }
-  param->m_PointCount += 3;
+
+  param->m_pPath->AppendPoint(
+      (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) /
+          param->m_CoordUnit,
+      (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) /
+          param->m_CoordUnit,
+      FXPT_TYPE::BezierTo, false);
+
+  param->m_pPath->AppendPoint(
+      (control->x + (to->x - control->x) / 3) / param->m_CoordUnit,
+      (control->y + (to->y - control->y) / 3) / param->m_CoordUnit,
+      FXPT_TYPE::BezierTo, false);
+
+  param->m_pPath->AppendPoint(to->x / param->m_CoordUnit,
+                              to->y / param->m_CoordUnit, FXPT_TYPE::BezierTo,
+                              false);
+
+  param->m_CurX = to->x;
+  param->m_CurY = to->y;
   return 0;
 }
 
@@ -184,29 +163,21 @@
                     const FXFT_Vector* to,
                     void* user) {
   OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
-  if (!param->m_bCount) {
-    param->m_pPoints[param->m_PointCount].m_PointX =
-        control1->x / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount].m_PointY =
-        control1->y / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount].m_Type = FXPT_TYPE::BezierTo;
-    param->m_pPoints[param->m_PointCount].m_CloseFigure = false;
-    param->m_pPoints[param->m_PointCount + 1].m_PointX =
-        control2->x / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount + 1].m_PointY =
-        control2->y / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount + 1].m_Type = FXPT_TYPE::BezierTo;
-    param->m_pPoints[param->m_PointCount + 1].m_CloseFigure = false;
-    param->m_pPoints[param->m_PointCount + 2].m_PointX =
-        to->x / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount + 2].m_PointY =
-        to->y / param->m_CoordUnit;
-    param->m_pPoints[param->m_PointCount + 2].m_Type = FXPT_TYPE::BezierTo;
-    param->m_pPoints[param->m_PointCount + 2].m_CloseFigure = false;
-    param->m_CurX = to->x;
-    param->m_CurY = to->y;
-  }
-  param->m_PointCount += 3;
+
+  param->m_pPath->AppendPoint(control1->x / param->m_CoordUnit,
+                              control1->y / param->m_CoordUnit,
+                              FXPT_TYPE::BezierTo, false);
+
+  param->m_pPath->AppendPoint(control2->x / param->m_CoordUnit,
+                              control2->y / param->m_CoordUnit,
+                              FXPT_TYPE::BezierTo, false);
+
+  param->m_pPath->AppendPoint(to->x / param->m_CoordUnit,
+                              to->y / param->m_CoordUnit, FXPT_TYPE::BezierTo,
+                              false);
+
+  param->m_CurX = to->x;
+  param->m_CurY = to->y;
   return 0;
 }
 
@@ -683,6 +654,7 @@
       level = s_WeightPow[index] * 2;
     FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
   }
+
   FXFT_Outline_Funcs funcs;
   funcs.move_to = Outline_MoveTo;
   funcs.line_to = Outline_LineTo;
@@ -690,25 +662,21 @@
   funcs.cubic_to = Outline_CubicTo;
   funcs.shift = 0;
   funcs.delta = 0;
+
   OUTLINE_PARAMS params;
-  params.m_bCount = true;
-  params.m_PointCount = 0;
-  FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
-  if (params.m_PointCount == 0)
-    return nullptr;
-  CFX_PathData* pPath = new CFX_PathData;
-  pPath->SetPointCount(params.m_PointCount);
-  params.m_bCount = false;
-  params.m_PointCount = 0;
-  params.m_pPoints = pPath->GetPoints();
+  auto pPath = pdfium::MakeUnique<CFX_PathData>();
+  params.m_pPath = pPath.get();
   params.m_CurX = params.m_CurY = 0;
   params.m_CoordUnit = 64 * 64.0;
+
   FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
+  if (pPath->GetPoints().empty())
+    return nullptr;
+
   Outline_CheckEmptyContour(&params);
-  pPath->TrimPoints(params.m_PointCount);
-  if (params.m_PointCount)
-    pPath->GetPoints()[params.m_PointCount - 1].m_CloseFigure = true;
-  return pPath;
+  pPath->ClosePath();
+
+  return pPath.release();
 }
 
 const CFX_GlyphBitmap* CFX_Font::LoadGlyphBitmap(uint32_t glyph_index,
diff --git a/core/fxge/ge/cfx_pathdata.cpp b/core/fxge/ge/cfx_pathdata.cpp
index 14eabb9..5ad3db4 100644
--- a/core/fxge/ge/cfx_pathdata.cpp
+++ b/core/fxge/ge/cfx_pathdata.cpp
@@ -9,117 +9,62 @@
 #include "core/fxcrt/fx_system.h"
 #include "third_party/base/numerics/safe_math.h"
 
-CFX_PathData::CFX_PathData()
-    : m_PointCount(0), m_AllocCount(0), m_pPoints(nullptr) {}
+CFX_PathData::CFX_PathData() {}
 
-CFX_PathData::~CFX_PathData() {
-  FX_Free(m_pPoints);
+CFX_PathData::~CFX_PathData() {}
+
+CFX_PathData::CFX_PathData(const CFX_PathData& src) : m_Points(src.m_Points) {}
+
+void CFX_PathData::Clear() {
+  m_Points.clear();
 }
 
-void CFX_PathData::SetPointCount(int nPoints) {
-  m_PointCount = nPoints;
-  if (m_AllocCount < nPoints) {
-    FX_Free(m_pPoints);
-    m_pPoints = FX_Alloc(FX_PATHPOINT, nPoints);
-    m_AllocCount = nPoints;
-  }
-}
-
-void CFX_PathData::AllocPointCount(int nPoints) {
-  if (m_AllocCount < nPoints) {
-    FX_PATHPOINT* pNewBuf = FX_Alloc(FX_PATHPOINT, nPoints);
-    if (m_PointCount) {
-      FXSYS_memcpy(pNewBuf, m_pPoints, m_PointCount * sizeof(FX_PATHPOINT));
-    }
-    FX_Free(m_pPoints);
-    m_pPoints = pNewBuf;
-    m_AllocCount = nPoints;
-  }
-}
-
-CFX_PathData::CFX_PathData(const CFX_PathData& src) {
-  m_PointCount = m_AllocCount = src.m_PointCount;
-  m_pPoints = FX_Alloc(FX_PATHPOINT, src.m_PointCount);
-  FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
-}
-
-void CFX_PathData::TrimPoints(int nPoints) {
-  if (m_PointCount <= nPoints) {
+void CFX_PathData::ClosePath() {
+  if (m_Points.empty())
     return;
-  }
-  SetPointCount(nPoints);
-}
-
-void CFX_PathData::AddPointCount(int addPoints) {
-  pdfium::base::CheckedNumeric<int> safe_new_count = m_PointCount;
-  safe_new_count += addPoints;
-  int new_count = safe_new_count.ValueOrDie();
-  AllocPointCount(new_count);
-  m_PointCount = new_count;
+  m_Points.back().m_CloseFigure = true;
 }
 
 void CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix) {
-  int old_count = m_PointCount;
-  AddPointCount(pSrc->m_PointCount);
-  FXSYS_memcpy(m_pPoints + old_count, pSrc->m_pPoints,
-               pSrc->m_PointCount * sizeof(FX_PATHPOINT));
-  if (pMatrix) {
-    for (int i = 0; i < pSrc->m_PointCount; i++) {
-      pMatrix->TransformPoint(m_pPoints[old_count + i].m_PointX,
-                              m_pPoints[old_count + i].m_PointY);
-    }
-  }
+  if (pSrc->m_Points.empty())
+    return;
+
+  size_t cur_size = m_Points.size();
+  m_Points.insert(m_Points.end(), pSrc->m_Points.begin(), pSrc->m_Points.end());
+
+  if (!pMatrix)
+    return;
+
+  for (size_t i = cur_size; i < m_Points.size(); i++)
+    pMatrix->TransformPoint(m_Points[i].m_PointX, m_Points[i].m_PointY);
 }
 
-void CFX_PathData::SetPoint(int index,
-                            FX_FLOAT x,
-                            FX_FLOAT y,
-                            FXPT_TYPE type,
-                            bool closeFigure) {
-  ASSERT(index < m_PointCount);
-  m_pPoints[index].m_PointX = x;
-  m_pPoints[index].m_PointY = y;
-  m_pPoints[index].m_Type = type;
-  m_pPoints[index].m_CloseFigure = closeFigure;
+void CFX_PathData::AppendPoint(FX_FLOAT x,
+                               FX_FLOAT y,
+                               FXPT_TYPE type,
+                               bool closeFigure) {
+  m_Points.push_back({x, y, type, closeFigure});
 }
 
 void CFX_PathData::AppendRect(FX_FLOAT left,
                               FX_FLOAT bottom,
                               FX_FLOAT right,
                               FX_FLOAT top) {
-  int old_count = m_PointCount;
-  AddPointCount(5);
-  FX_PATHPOINT* pPoints = m_pPoints + old_count;
-  pPoints[0].m_PointX = left;
-  pPoints[1].m_PointX = left;
-  pPoints[4].m_PointX = left;
-  pPoints[2].m_PointX = right;
-  pPoints[3].m_PointX = right;
-  pPoints[0].m_PointY = bottom;
-  pPoints[3].m_PointY = bottom;
-  pPoints[4].m_PointY = bottom;
-  pPoints[1].m_PointY = top;
-  pPoints[2].m_PointY = top;
-  pPoints[0].m_Type = FXPT_TYPE::MoveTo;
-  pPoints[1].m_Type = FXPT_TYPE::LineTo;
-  pPoints[2].m_Type = FXPT_TYPE::LineTo;
-  pPoints[3].m_Type = FXPT_TYPE::LineTo;
-  pPoints[0].m_CloseFigure = false;
-  pPoints[1].m_CloseFigure = false;
-  pPoints[2].m_CloseFigure = false;
-  pPoints[3].m_CloseFigure = false;
-  pPoints[4].m_Type = FXPT_TYPE::LineTo;
-  pPoints[4].m_CloseFigure = true;
+  m_Points.push_back({left, bottom, FXPT_TYPE::MoveTo, false});
+  m_Points.push_back({left, top, FXPT_TYPE::LineTo, false});
+  m_Points.push_back({right, top, FXPT_TYPE::LineTo, false});
+  m_Points.push_back({right, bottom, FXPT_TYPE::LineTo, false});
+  m_Points.push_back({left, bottom, FXPT_TYPE::LineTo, true});
 }
 
 CFX_FloatRect CFX_PathData::GetBoundingBox() const {
+  if (m_Points.empty())
+    return CFX_FloatRect();
+
   CFX_FloatRect rect;
-  if (m_PointCount) {
-    rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY);
-    for (int i = 1; i < m_PointCount; i++) {
-      rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
-    }
-  }
+  rect.InitRect(m_Points[0].m_PointX, m_Points[0].m_PointY);
+  for (size_t i = 1; i < m_Points.size(); i++)
+    rect.UpdateRect(m_Points[i].m_PointX, m_Points[i].m_PointY);
   return rect;
 }
 
@@ -264,26 +209,26 @@
                                            FX_FLOAT miter_limit) const {
   CFX_FloatRect rect(100000 * 1.0f, 100000 * 1.0f, -100000 * 1.0f,
                      -100000 * 1.0f);
-  int iPoint = 0;
+  size_t iPoint = 0;
   FX_FLOAT half_width = line_width;
   int iStartPoint = 0;
   int iEndPoint = 0;
   int iMiddlePoint = 0;
   bool bJoin;
-  while (iPoint < m_PointCount) {
-    if (m_pPoints[iPoint].IsTypeAndOpen(FXPT_TYPE::MoveTo)) {
+  while (iPoint < m_Points.size()) {
+    if (m_Points[iPoint].IsTypeAndOpen(FXPT_TYPE::MoveTo)) {
       iStartPoint = iPoint + 1;
       iEndPoint = iPoint;
       bJoin = false;
     } else {
-      if (m_pPoints[iPoint].IsTypeAndOpen(FXPT_TYPE::BezierTo)) {
-        rect.UpdateRect(m_pPoints[iPoint].m_PointX, m_pPoints[iPoint].m_PointY);
-        rect.UpdateRect(m_pPoints[iPoint + 1].m_PointX,
-                        m_pPoints[iPoint + 1].m_PointY);
+      if (m_Points[iPoint].IsTypeAndOpen(FXPT_TYPE::BezierTo)) {
+        rect.UpdateRect(m_Points[iPoint].m_PointX, m_Points[iPoint].m_PointY);
+        rect.UpdateRect(m_Points[iPoint + 1].m_PointX,
+                        m_Points[iPoint + 1].m_PointY);
         iPoint += 2;
       }
-      if (iPoint == m_PointCount - 1 ||
-          m_pPoints[iPoint + 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) {
+      if (iPoint == m_Points.size() - 1 ||
+          m_Points[iPoint + 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) {
         iStartPoint = iPoint - 1;
         iEndPoint = iPoint;
         bJoin = false;
@@ -294,13 +239,13 @@
         bJoin = true;
       }
     }
-    FX_FLOAT start_x = m_pPoints[iStartPoint].m_PointX;
-    FX_FLOAT start_y = m_pPoints[iStartPoint].m_PointY;
-    FX_FLOAT end_x = m_pPoints[iEndPoint].m_PointX;
-    FX_FLOAT end_y = m_pPoints[iEndPoint].m_PointY;
+    FX_FLOAT start_x = m_Points[iStartPoint].m_PointX;
+    FX_FLOAT start_y = m_Points[iStartPoint].m_PointY;
+    FX_FLOAT end_x = m_Points[iEndPoint].m_PointX;
+    FX_FLOAT end_y = m_Points[iEndPoint].m_PointY;
     if (bJoin) {
-      FX_FLOAT middle_x = m_pPoints[iMiddlePoint].m_PointX;
-      FX_FLOAT middle_y = m_pPoints[iMiddlePoint].m_PointY;
+      FX_FLOAT middle_x = m_Points[iMiddlePoint].m_PointX;
+      FX_FLOAT middle_y = m_Points[iMiddlePoint].m_PointY;
       _UpdateLineJoinPoints(rect, start_x, start_y, middle_x, middle_y, end_x,
                             end_y, half_width, miter_limit);
     } else {
@@ -312,143 +257,140 @@
 }
 
 void CFX_PathData::Transform(const CFX_Matrix* pMatrix) {
-  if (!pMatrix) {
+  if (!pMatrix)
     return;
-  }
-  for (int i = 0; i < m_PointCount; i++) {
-    pMatrix->TransformPoint(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
-  }
+  for (auto& point : m_Points)
+    pMatrix->TransformPoint(point.m_PointX, point.m_PointY);
 }
 
-bool CFX_PathData::GetZeroAreaPath(CFX_PathData& NewPath,
+bool CFX_PathData::GetZeroAreaPath(CFX_PathData* NewPath,
                                    CFX_Matrix* pMatrix,
                                    bool& bThin,
                                    bool bAdjust) const {
-  if (m_PointCount < 3) {
+  if (m_Points.size() < 3)
     return false;
-  }
-  if (m_PointCount == 3 && m_pPoints[0].m_Type == FXPT_TYPE::MoveTo &&
-      m_pPoints[1].m_Type == FXPT_TYPE::LineTo &&
-      m_pPoints[2].m_Type == FXPT_TYPE::LineTo &&
-      m_pPoints[0].m_PointX == m_pPoints[2].m_PointX &&
-      m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) {
-    NewPath.AddPointCount(2);
+
+  if (m_Points.size() == 3 && m_Points[0].m_Type == FXPT_TYPE::MoveTo &&
+      m_Points[1].m_Type == FXPT_TYPE::LineTo &&
+      m_Points[2].m_Type == FXPT_TYPE::LineTo &&
+      m_Points[0].m_PointX == m_Points[2].m_PointX &&
+      m_Points[0].m_PointY == m_Points[2].m_PointY) {
     if (bAdjust) {
       if (pMatrix) {
-        FX_FLOAT x = m_pPoints[0].m_PointX, y = m_pPoints[0].m_PointY;
+        FX_FLOAT x = m_Points[0].m_PointX;
+        FX_FLOAT y = m_Points[0].m_PointY;
+        pMatrix->TransformPoint(x, y);
+
+        x = (int)x + 0.5f;
+        y = (int)y + 0.5f;
+        NewPath->AppendPoint(x, y, FXPT_TYPE::MoveTo, false);
+
+        x = m_Points[1].m_PointX;
+        y = m_Points[1].m_PointY;
         pMatrix->TransformPoint(x, y);
         x = (int)x + 0.5f;
         y = (int)y + 0.5f;
-        NewPath.SetPoint(0, x, y, FXPT_TYPE::MoveTo, false);
-        x = m_pPoints[1].m_PointX, y = m_pPoints[1].m_PointY;
-        pMatrix->TransformPoint(x, y);
-        x = (int)x + 0.5f;
-        y = (int)y + 0.5f;
-        NewPath.SetPoint(1, x, y, FXPT_TYPE::LineTo, false);
+        NewPath->AppendPoint(x, y, FXPT_TYPE::LineTo, false);
+
         pMatrix->SetIdentity();
       } else {
-        FX_FLOAT x = (int)m_pPoints[0].m_PointX + 0.5f,
-                 y = (int)m_pPoints[0].m_PointY + 0.5f;
-        NewPath.SetPoint(0, x, y, FXPT_TYPE::MoveTo, false);
-        x = (int)m_pPoints[1].m_PointX + 0.5f,
-        y = (int)m_pPoints[1].m_PointY + 0.5f;
-        NewPath.SetPoint(1, x, y, FXPT_TYPE::LineTo, false);
+        FX_FLOAT x = (int)m_Points[0].m_PointX + 0.5f;
+        FX_FLOAT y = (int)m_Points[0].m_PointY + 0.5f;
+        NewPath->AppendPoint(x, y, FXPT_TYPE::MoveTo, false);
+
+        x = (int)m_Points[1].m_PointX + 0.5f,
+        y = (int)m_Points[1].m_PointY + 0.5f;
+        NewPath->AppendPoint(x, y, FXPT_TYPE::LineTo, false);
       }
     } else {
-      NewPath.SetPoint(0, m_pPoints[0].m_PointX, m_pPoints[0].m_PointY,
-                       FXPT_TYPE::MoveTo, false);
-      NewPath.SetPoint(1, m_pPoints[1].m_PointX, m_pPoints[1].m_PointY,
-                       FXPT_TYPE::LineTo, false);
+      NewPath->AppendPoint(m_Points[0].m_PointX, m_Points[0].m_PointY,
+                           FXPT_TYPE::MoveTo, false);
+      NewPath->AppendPoint(m_Points[1].m_PointX, m_Points[1].m_PointY,
+                           FXPT_TYPE::LineTo, false);
     }
-    if (m_pPoints[0].m_PointX != m_pPoints[1].m_PointX &&
-        m_pPoints[0].m_PointY != m_pPoints[1].m_PointY) {
+    if (m_Points[0].m_PointX != m_Points[1].m_PointX &&
+        m_Points[0].m_PointY != m_Points[1].m_PointY) {
       bThin = true;
     }
     return true;
   }
-  if (((m_PointCount > 3) && (m_PointCount % 2))) {
-    int mid = m_PointCount / 2;
+  if (((m_Points.size() > 3) && (m_Points.size() % 2))) {
+    int mid = m_Points.size() / 2;
     bool bZeroArea = false;
     CFX_PathData t_path;
     for (int i = 0; i < mid; i++) {
-      if (!(m_pPoints[mid - i - 1].m_PointX ==
-                m_pPoints[mid + i + 1].m_PointX &&
-            m_pPoints[mid - i - 1].m_PointY ==
-                m_pPoints[mid + i + 1].m_PointY &&
-            m_pPoints[mid - i - 1].m_Type != FXPT_TYPE::BezierTo &&
-            m_pPoints[mid + i + 1].m_Type != FXPT_TYPE::BezierTo)) {
+      if (!(m_Points[mid - i - 1].m_PointX == m_Points[mid + i + 1].m_PointX &&
+            m_Points[mid - i - 1].m_PointY == m_Points[mid + i + 1].m_PointY &&
+            m_Points[mid - i - 1].m_Type != FXPT_TYPE::BezierTo &&
+            m_Points[mid + i + 1].m_Type != FXPT_TYPE::BezierTo)) {
         bZeroArea = true;
         break;
       }
-      int new_count = t_path.GetPointCount();
-      t_path.AddPointCount(2);
-      t_path.SetPoint(new_count, m_pPoints[mid - i].m_PointX,
-                      m_pPoints[mid - i].m_PointY, FXPT_TYPE::MoveTo, false);
-      t_path.SetPoint(new_count + 1, m_pPoints[mid - i - 1].m_PointX,
-                      m_pPoints[mid - i - 1].m_PointY, FXPT_TYPE::LineTo,
-                      false);
+
+      t_path.AppendPoint(m_Points[mid - i].m_PointX, m_Points[mid - i].m_PointY,
+                         FXPT_TYPE::MoveTo, false);
+      t_path.AppendPoint(m_Points[mid - i - 1].m_PointX,
+                         m_Points[mid - i - 1].m_PointY, FXPT_TYPE::LineTo,
+                         false);
     }
     if (!bZeroArea) {
-      NewPath.Append(&t_path, nullptr);
+      NewPath->Append(&t_path, nullptr);
       bThin = true;
       return true;
     }
   }
   int stratPoint = 0;
-  int next = 0, i;
-  for (i = 0; i < m_PointCount; i++) {
-    FXPT_TYPE point_type = m_pPoints[i].m_Type;
+  int next = 0;
+  for (size_t i = 0; i < m_Points.size(); i++) {
+    FXPT_TYPE point_type = m_Points[i].m_Type;
     if (point_type == FXPT_TYPE::MoveTo) {
       stratPoint = i;
     } else if (point_type == FXPT_TYPE::LineTo) {
-      next = (i + 1 - stratPoint) % (m_PointCount - stratPoint) + stratPoint;
-      if (m_pPoints[next].m_Type != FXPT_TYPE::BezierTo &&
-          m_pPoints[next].m_Type != FXPT_TYPE::MoveTo) {
-        if ((m_pPoints[i - 1].m_PointX == m_pPoints[i].m_PointX &&
-             m_pPoints[i].m_PointX == m_pPoints[next].m_PointX) &&
-            ((m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) *
-                 (m_pPoints[i].m_PointY - m_pPoints[next].m_PointY) >
+      next = (i + 1 - stratPoint) % (m_Points.size() - stratPoint) + stratPoint;
+      if (m_Points[next].m_Type != FXPT_TYPE::BezierTo &&
+          m_Points[next].m_Type != FXPT_TYPE::MoveTo) {
+        if ((m_Points[i - 1].m_PointX == m_Points[i].m_PointX &&
+             m_Points[i].m_PointX == m_Points[next].m_PointX) &&
+            ((m_Points[i].m_PointY - m_Points[i - 1].m_PointY) *
+                 (m_Points[i].m_PointY - m_Points[next].m_PointY) >
              0)) {
           int pre = i;
-          if (FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) <
-              FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[next].m_PointY)) {
+          if (FXSYS_fabs(m_Points[i].m_PointY - m_Points[i - 1].m_PointY) <
+              FXSYS_fabs(m_Points[i].m_PointY - m_Points[next].m_PointY)) {
             pre--;
             next--;
           }
-          int new_count = NewPath.GetPointCount();
-          NewPath.AddPointCount(2);
-          NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX,
-                           m_pPoints[pre].m_PointY, FXPT_TYPE::MoveTo, false);
-          NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX,
-                           m_pPoints[next].m_PointY, FXPT_TYPE::LineTo, false);
-        } else if ((m_pPoints[i - 1].m_PointY == m_pPoints[i].m_PointY &&
-                    m_pPoints[i].m_PointY == m_pPoints[next].m_PointY) &&
-                   ((m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) *
-                        (m_pPoints[i].m_PointX - m_pPoints[next].m_PointX) >
+
+          NewPath->AppendPoint(m_Points[pre].m_PointX, m_Points[pre].m_PointY,
+                               FXPT_TYPE::MoveTo, false);
+          NewPath->AppendPoint(m_Points[next].m_PointX, m_Points[next].m_PointY,
+                               FXPT_TYPE::LineTo, false);
+        } else if ((m_Points[i - 1].m_PointY == m_Points[i].m_PointY &&
+                    m_Points[i].m_PointY == m_Points[next].m_PointY) &&
+                   ((m_Points[i].m_PointX - m_Points[i - 1].m_PointX) *
+                        (m_Points[i].m_PointX - m_Points[next].m_PointX) >
                     0)) {
           int pre = i;
-          if (FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) <
-              FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[next].m_PointX)) {
+          if (FXSYS_fabs(m_Points[i].m_PointX - m_Points[i - 1].m_PointX) <
+              FXSYS_fabs(m_Points[i].m_PointX - m_Points[next].m_PointX)) {
             pre--;
             next--;
           }
-          int new_count = NewPath.GetPointCount();
-          NewPath.AddPointCount(2);
-          NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX,
-                           m_pPoints[pre].m_PointY, FXPT_TYPE::MoveTo, false);
-          NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX,
-                           m_pPoints[next].m_PointY, FXPT_TYPE::LineTo, false);
-        } else if (m_pPoints[i - 1].m_Type == FXPT_TYPE::MoveTo &&
-                   m_pPoints[next].m_Type == FXPT_TYPE::LineTo &&
-                   m_pPoints[i - 1].m_PointX == m_pPoints[next].m_PointX &&
-                   m_pPoints[i - 1].m_PointY == m_pPoints[next].m_PointY &&
-                   m_pPoints[next].m_CloseFigure) {
-          int new_count = NewPath.GetPointCount();
-          NewPath.AddPointCount(2);
-          NewPath.SetPoint(new_count, m_pPoints[i - 1].m_PointX,
-                           m_pPoints[i - 1].m_PointY, FXPT_TYPE::MoveTo, false);
-          NewPath.SetPoint(new_count + 1, m_pPoints[i].m_PointX,
-                           m_pPoints[i].m_PointY, FXPT_TYPE::LineTo, false);
+
+          NewPath->AppendPoint(m_Points[pre].m_PointX, m_Points[pre].m_PointY,
+                               FXPT_TYPE::MoveTo, false);
+          NewPath->AppendPoint(m_Points[next].m_PointX, m_Points[next].m_PointY,
+                               FXPT_TYPE::LineTo, false);
+        } else if (m_Points[i - 1].m_Type == FXPT_TYPE::MoveTo &&
+                   m_Points[next].m_Type == FXPT_TYPE::LineTo &&
+                   m_Points[i - 1].m_PointX == m_Points[next].m_PointX &&
+                   m_Points[i - 1].m_PointY == m_Points[next].m_PointY &&
+                   m_Points[next].m_CloseFigure) {
+          NewPath->AppendPoint(m_Points[i - 1].m_PointX,
+                               m_Points[i - 1].m_PointY, FXPT_TYPE::MoveTo,
+                               false);
+          NewPath->AppendPoint(m_Points[i].m_PointX, m_Points[i].m_PointY,
+                               FXPT_TYPE::LineTo, false);
           bThin = true;
         }
       }
@@ -457,41 +399,38 @@
       continue;
     }
   }
-  if (m_PointCount > 3 && NewPath.GetPointCount()) {
+  size_t new_path_size = NewPath->GetPoints().size();
+  if (m_Points.size() > 3 && new_path_size > 0)
     bThin = true;
-  }
-  if (NewPath.GetPointCount() == 0) {
-    return false;
-  }
-  return true;
+  return new_path_size != 0;
 }
 
 bool CFX_PathData::IsRect() const {
-  if (m_PointCount != 5 && m_PointCount != 4) {
+  if (m_Points.size() != 5 && m_Points.size() != 4)
+    return false;
+
+  if ((m_Points.size() == 5 &&
+       (m_Points[0].m_PointX != m_Points[4].m_PointX ||
+        m_Points[0].m_PointY != m_Points[4].m_PointY)) ||
+      (m_Points[0].m_PointX == m_Points[2].m_PointX &&
+       m_Points[0].m_PointY == m_Points[2].m_PointY) ||
+      (m_Points[1].m_PointX == m_Points[3].m_PointX &&
+       m_Points[1].m_PointY == m_Points[3].m_PointY)) {
     return false;
   }
-  if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX ||
-                             m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
-      (m_pPoints[0].m_PointX == m_pPoints[2].m_PointX &&
-       m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) ||
-      (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX &&
-       m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
-    return false;
-  }
-  if (m_pPoints[0].m_PointX != m_pPoints[3].m_PointX &&
-      m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
+  if (m_Points[0].m_PointX != m_Points[3].m_PointX &&
+      m_Points[0].m_PointY != m_Points[3].m_PointY) {
     return false;
   }
   for (int i = 1; i < 4; i++) {
-    if (m_pPoints[i].m_Type != FXPT_TYPE::LineTo) {
+    if (m_Points[i].m_Type != FXPT_TYPE::LineTo)
       return false;
-    }
-    if (m_pPoints[i].m_PointX != m_pPoints[i - 1].m_PointX &&
-        m_pPoints[i].m_PointY != m_pPoints[i - 1].m_PointY) {
+    if (m_Points[i].m_PointX != m_Points[i - 1].m_PointX &&
+        m_Points[i].m_PointY != m_Points[i - 1].m_PointY) {
       return false;
     }
   }
-  return m_PointCount == 5 || m_pPoints[3].m_CloseFigure;
+  return m_Points.size() == 5 || m_Points[3].m_CloseFigure;
 }
 
 bool CFX_PathData::IsRect(const CFX_Matrix* pMatrix,
@@ -501,41 +440,43 @@
       return false;
 
     if (pRect) {
-      pRect->left = m_pPoints[0].m_PointX;
-      pRect->right = m_pPoints[2].m_PointX;
-      pRect->bottom = m_pPoints[0].m_PointY;
-      pRect->top = m_pPoints[2].m_PointY;
+      pRect->left = m_Points[0].m_PointX;
+      pRect->right = m_Points[2].m_PointX;
+      pRect->bottom = m_Points[0].m_PointY;
+      pRect->top = m_Points[2].m_PointY;
       pRect->Normalize();
     }
     return true;
   }
 
-  if (m_PointCount != 5 && m_PointCount != 4)
+  if (m_Points.size() != 5 && m_Points.size() != 4)
     return false;
 
-  if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX ||
-                             m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
-      (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX &&
-       m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
+  if ((m_Points.size() == 5 &&
+       (m_Points[0].m_PointX != m_Points[4].m_PointX ||
+        m_Points[0].m_PointY != m_Points[4].m_PointY)) ||
+      (m_Points[1].m_PointX == m_Points[3].m_PointX &&
+       m_Points[1].m_PointY == m_Points[3].m_PointY)) {
     return false;
   }
-  if (m_PointCount == 4 && m_pPoints[0].m_PointX != m_pPoints[3].m_PointX &&
-      m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
+  if (m_Points.size() == 4 && m_Points[0].m_PointX != m_Points[3].m_PointX &&
+      m_Points[0].m_PointY != m_Points[3].m_PointY) {
     return false;
   }
 
   FX_FLOAT x[5];
   FX_FLOAT y[5];
-  for (int i = 0; i < m_PointCount; i++) {
-    x[i] = m_pPoints[i].m_PointX;
-    y[i] = m_pPoints[i].m_PointY;
+  for (size_t i = 0; i < m_Points.size(); i++) {
+    x[i] = m_Points[i].m_PointX;
+    y[i] = m_Points[i].m_PointY;
     pMatrix->TransformPoint(x[i], y[i]);
-    if (i) {
-      if (m_pPoints[i].m_Type != FXPT_TYPE::LineTo)
-        return false;
-      if (x[i] != x[i - 1] && y[i] != y[i - 1])
-        return false;
-    }
+
+    if (i == 0)
+      continue;
+    if (m_Points[i].m_Type != FXPT_TYPE::LineTo)
+      return false;
+    if (x[i] != x[i - 1] && y[i] != y[i - 1])
+      return false;
   }
 
   if (pRect) {
@@ -547,8 +488,3 @@
   }
   return true;
 }
-
-void CFX_PathData::Copy(const CFX_PathData& src) {
-  SetPointCount(src.m_PointCount);
-  FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
-}
diff --git a/core/fxge/ge/cfx_renderdevice.cpp b/core/fxge/ge/cfx_renderdevice.cpp
index 12a3dd4..b0be466 100644
--- a/core/fxge/ge/cfx_renderdevice.cpp
+++ b/core/fxge/ge/cfx_renderdevice.cpp
@@ -473,8 +473,8 @@
                                          int blend_type) {
   uint8_t stroke_alpha = pGraphState ? FXARGB_A(stroke_color) : 0;
   uint8_t fill_alpha = (fill_mode & 3) ? FXARGB_A(fill_color) : 0;
-  if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) {
-    FX_PATHPOINT* pPoints = pPathData->GetPoints();
+  const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints();
+  if (stroke_alpha == 0 && pPoints.size() == 2) {
     FX_FLOAT x1 = pPoints[0].m_PointX;
     FX_FLOAT y1 = pPoints[0].m_PointY;
     FX_FLOAT x2 = pPoints[1].m_PointX;
@@ -487,8 +487,7 @@
     return true;
   }
 
-  if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) &&
-      stroke_alpha == 0) {
+  if ((pPoints.size() == 5 || pPoints.size() == 4) && stroke_alpha == 0) {
     CFX_FloatRect rect_f;
     if (!(fill_mode & FXFILL_RECT_AA) &&
         pPathData->IsRect(pObject2Device, &rect_f)) {
@@ -536,7 +535,7 @@
       !(fill_mode & FX_FILL_TEXT_MODE)) {
     CFX_PathData newPath;
     bool bThin = false;
-    if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin,
+    if (pPathData->GetZeroAreaPath(&newPath, (CFX_Matrix*)pObject2Device, bThin,
                                    !!m_pDeviceDriver->GetDriverType())) {
       CFX_GraphStateData graphState;
       graphState.m_LineWidth = 0.0f;
@@ -673,9 +672,8 @@
   }
   CFX_GraphStateData graph_state;
   CFX_PathData path;
-  path.SetPointCount(2);
-  path.SetPoint(0, x1, y1, FXPT_TYPE::MoveTo, false);
-  path.SetPoint(1, x2, y2, FXPT_TYPE::LineTo, false);
+  path.AppendPoint(x1, y1, FXPT_TYPE::MoveTo, false);
+  path.AppendPoint(x2, y2, FXPT_TYPE::LineTo, false);
   return m_pDeviceDriver->DrawPath(&path, nullptr, &graph_state, 0, color,
                                    fill_mode, blend_type);
 }
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index ba21bf4..8263cf6 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -278,9 +278,8 @@
 SkPath BuildPath(const CFX_PathData* pPathData) {
   SkPath skPath;
   const CFX_PathData* pFPath = pPathData;
-  int nPoints = pFPath->GetPointCount();
-  FX_PATHPOINT* pPoints = pFPath->GetPoints();
-  for (int i = 0; i < nPoints; i++) {
+  const std::vector<FX_PATHPOINT>& pPoints = pFPath->GetPoints();
+  for (size_t i = 0; i < pPoints.size(); i++) {
     FX_FLOAT x = pPoints[i].m_PointX;
     FX_FLOAT y = pPoints[i].m_PointY;
     FXPT_TYPE point_type = pPoints[i].m_Type;
@@ -306,7 +305,7 @@
   return skMatrix;
 }
 
-// use when pdf's y-axis points up insead of down
+// use when pdf's y-axis points up instead of down
 SkMatrix ToFlippedSkMatrix(const CFX_Matrix& m, SkScalar flip) {
   SkMatrix skMatrix;
   skMatrix.setAll(m.a * flip, -m.c * flip, m.e, m.b * flip, -m.d * flip, m.f, 0,
@@ -1432,7 +1431,8 @@
         GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT));
   }
 #endif  // _SKIA_SUPPORT_PATHS_
-  if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) {
+  if (pPathData->GetPoints().size() == 5 ||
+      pPathData->GetPoints().size() == 4) {
     CFX_FloatRect rectf;
     if (pPathData->IsRect(deviceMatrix, &rectf)) {
       rectf.Intersect(
diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp
index 7fc47b9..d5f1f4d 100644
--- a/core/fxge/win32/cfx_psrenderer.cpp
+++ b/core/fxge/win32/cfx_psrenderer.cpp
@@ -109,10 +109,11 @@
 
 void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData,
                                 const CFX_Matrix* pObject2Device) {
-  int nPoints = pPathData->GetPointCount();
   CFX_ByteTextBuf buf;
-  buf.EstimateSize(nPoints * 10);
-  for (int i = 0; i < nPoints; i++) {
+  size_t size = pPathData->GetPoints().size();
+  buf.EstimateSize(size * 10);
+
+  for (size_t i = 0; i < size; i++) {
     FXPT_TYPE type = pPathData->GetType(i);
     bool closing = pPathData->IsClosingFigure(i);
     FX_FLOAT x = pPathData->GetPointX(i);
@@ -592,17 +593,17 @@
   matrix.Concat(CFX_Matrix(1.0f, 0, 0, 1.0f, 0, 0));
   const CFX_PathData* pPathData = pFaceCache->LoadGlyphPath(
       pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth);
-  if (!pPathData) {
+  if (!pPathData)
     return;
-  }
+
   CFX_PathData TransformedPath(*pPathData);
-  if (charpos.m_bGlyphAdjust) {
+  if (charpos.m_bGlyphAdjust)
     TransformedPath.Transform(&matrix);
-  }
+
   CFX_ByteTextBuf buf;
   buf << "/X" << *ps_fontnum << " Ff/CharProcs get begin/" << glyphindex
       << "{n ";
-  for (int p = 0; p < TransformedPath.GetPointCount(); p++) {
+  for (size_t p = 0; p < TransformedPath.GetPoints().size(); p++) {
     FX_FLOAT x = TransformedPath.GetPointX(p), y = TransformedPath.GetPointY(p);
     switch (TransformedPath.GetType(p)) {
       case FXPT_TYPE::MoveTo: {
diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp
index add0f0e..b5ce734 100644
--- a/core/fxge/win32/fx_win32_device.cpp
+++ b/core/fxge/win32/fx_win32_device.cpp
@@ -166,10 +166,11 @@
                  const CFX_PathData* pPathData,
                  const CFX_Matrix* pMatrix) {
   BeginPath(hDC);
-  int nPoints = pPathData->GetPointCount();
-  FX_PATHPOINT* pPoints = pPathData->GetPoints();
-  for (int i = 0; i < nPoints; i++) {
-    FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY;
+
+  const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints();
+  for (size_t i = 0; i < pPoints.size(); i++) {
+    FX_FLOAT posx = pPoints[i].m_PointX;
+    FX_FLOAT posy = pPoints[i].m_PointY;
     if (pMatrix)
       pMatrix->TransformPoint(posx, posy);
 
@@ -1019,8 +1020,8 @@
          (pGraphState && pGraphState->m_DashCount))) {
       if (!((!pMatrix || !pMatrix->WillScale()) && pGraphState &&
             pGraphState->m_LineWidth == 1.f &&
-            (pPathData->GetPointCount() == 5 ||
-             pPathData->GetPointCount() == 4) &&
+            (pPathData->GetPoints().size() == 5 ||
+             pPathData->GetPoints().size() == 4) &&
             pPathData->IsRect())) {
         if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix,
                                              pGraphState, fill_color,
@@ -1044,7 +1045,7 @@
     hBrush = CreateBrush(fill_color);
     hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
   }
-  if (pPathData->GetPointCount() == 2 && pGraphState &&
+  if (pPathData->GetPoints().size() == 2 && pGraphState &&
       pGraphState->m_DashCount) {
     FX_FLOAT x1 = pPathData->GetPointX(0);
     FX_FLOAT y1 = pPathData->GetPointY(0);
@@ -1108,7 +1109,7 @@
 bool CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData,
                                         const CFX_Matrix* pMatrix,
                                         int fill_mode) {
-  if (pPathData->GetPointCount() == 5) {
+  if (pPathData->GetPoints().size() == 5) {
     CFX_FloatRect rectf;
     if (pPathData->IsRect(pMatrix, &rectf)) {
       FX_RECT rect = rectf.GetOuterRect();
diff --git a/core/fxge/win32/fx_win32_gdipext.cpp b/core/fxge/win32/fx_win32_gdipext.cpp
index c703e3e..c766ac8f 100644
--- a/core/fxge/win32/fx_win32_gdipext.cpp
+++ b/core/fxge/win32/fx_win32_gdipext.cpp
@@ -1104,11 +1104,10 @@
                            uint32_t fill_argb,
                            uint32_t stroke_argb,
                            int fill_mode) {
-  int nPoints = pPathData->GetPointCount();
-  if (nPoints == 0) {
+  auto& pPoints = pPathData->GetPoints();
+  if (pPoints.empty())
     return true;
-  }
-  FX_PATHPOINT* pPoints = pPathData->GetPoints();
+
   GpGraphics* pGraphics = nullptr;
   CGdiplusExt& GdiplusExt =
       ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
@@ -1122,14 +1121,14 @@
                                 pObject2Device->e, pObject2Device->f, &pMatrix);
     CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix);
   }
-  PointF* points = FX_Alloc(PointF, nPoints);
-  BYTE* types = FX_Alloc(BYTE, nPoints);
+  PointF* points = FX_Alloc(PointF, pPoints.size());
+  BYTE* types = FX_Alloc(BYTE, pPoints.size());
   int nSubPathes = 0;
   bool bSubClose = false;
   int pos_subclose = 0;
   bool bSmooth = false;
   int startpoint = 0;
-  for (int i = 0; i < nPoints; i++) {
+  for (size_t i = 0; i < pPoints.size(); i++) {
     points[i].X = pPoints[i].m_PointX;
     points[i].Y = pPoints[i].m_PointY;
     FX_FLOAT x = pPoints[i].m_PointX;
@@ -1155,7 +1154,7 @@
     } else if (point_type == FXPT_TYPE::LineTo) {
       types[i] = PathPointTypeLine;
       if (pPoints[i - 1].IsTypeAndOpen(FXPT_TYPE::MoveTo) &&
-          (i == nPoints - 1 ||
+          (i == pPoints.size() - 1 ||
            pPoints[i + 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) &&
           points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) {
         points[i].X += 0.01f;
@@ -1195,7 +1194,7 @@
     }
   }
   int new_fill_mode = fill_mode & 3;
-  if (nPoints == 4 && !pGraphState) {
+  if (pPoints.size() == 4 && !pGraphState) {
     int v1, v2;
     if (IsSmallTriangle(points, pObject2Device, v1, v2)) {
       GpPen* pPen = nullptr;
@@ -1208,12 +1207,12 @@
     }
   }
   GpPath* pGpPath = nullptr;
-  CallFunc(GdipCreatePath2)(points, types, nPoints,
+  CallFunc(GdipCreatePath2)(points, types, pPoints.size(),
                             GdiFillType2Gdip(new_fill_mode), &pGpPath);
   if (!pGpPath) {
-    if (pMatrix) {
+    if (pMatrix)
       CallFunc(GdipDeleteMatrix)(pMatrix);
-    }
+
     FX_Free(points);
     FX_Free(types);
     CallFunc(GdipDeleteGraphics)(pGraphics);
@@ -1232,8 +1231,8 @@
       CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath);
     } else {
       int iStart = 0;
-      for (int i = 0; i < nPoints; i++) {
-        if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) {
+      for (size_t i = 0; i < pPoints.size(); i++) {
+        if (i == pPoints.size() - 1 || types[i + 1] == PathPointTypeStart) {
           GpPath* pSubPath;
           CallFunc(GdipCreatePath2)(points + iStart, types + iStart,
                                     i - iStart + 1,
diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp
index a2ea82a..3b0c696 100644
--- a/core/fxge/win32/fx_win32_print.cpp
+++ b/core/fxge/win32/fx_win32_print.cpp
@@ -346,12 +346,13 @@
       ret = ::GetRegionData(hRgn, ret, pData);
       if (ret) {
         CFX_PathData path;
-        path.AllocPointCount(pData->rdh.nCount * 5);
         for (uint32_t i = 0; i < pData->rdh.nCount; i++) {
           RECT* pRect =
               reinterpret_cast<RECT*>(pData->Buffer + pData->rdh.nRgnSize * i);
-          path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom,
-                          (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top);
+          path.AppendRect(static_cast<FX_FLOAT>(pRect->left),
+                          static_cast<FX_FLOAT>(pRect->bottom),
+                          static_cast<FX_FLOAT>(pRect->right),
+                          static_cast<FX_FLOAT>(pRect->top));
         }
         m_PSRenderer.SetClip_PathFill(&path, nullptr, FXFILL_WINDING);
       }
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
index a8368f4..7778408 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
@@ -70,15 +70,14 @@
         CFX_FloatRect rcFocus = pFormFiller->GetFocusBox(pPageView);
         if (!rcFocus.IsEmpty()) {
           CFX_PathData path;
-          path.SetPointCount(5);
-          path.SetPoint(0, rcFocus.left, rcFocus.top, FXPT_TYPE::MoveTo, false);
-          path.SetPoint(1, rcFocus.left, rcFocus.bottom, FXPT_TYPE::LineTo,
-                        false);
-          path.SetPoint(2, rcFocus.right, rcFocus.bottom, FXPT_TYPE::LineTo,
-                        false);
-          path.SetPoint(3, rcFocus.right, rcFocus.top, FXPT_TYPE::LineTo,
-                        false);
-          path.SetPoint(4, rcFocus.left, rcFocus.top, FXPT_TYPE::LineTo, false);
+          path.AppendPoint(rcFocus.left, rcFocus.top, FXPT_TYPE::MoveTo, false);
+          path.AppendPoint(rcFocus.left, rcFocus.bottom, FXPT_TYPE::LineTo,
+                           false);
+          path.AppendPoint(rcFocus.right, rcFocus.bottom, FXPT_TYPE::LineTo,
+                           false);
+          path.AppendPoint(rcFocus.right, rcFocus.top, FXPT_TYPE::LineTo,
+                           false);
+          path.AppendPoint(rcFocus.left, rcFocus.top, FXPT_TYPE::LineTo, false);
 
           CFX_GraphStateData gsd;
           gsd.SetDashCount(1);
diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
index 6d19a6b..7e19505 100644
--- a/fpdfsdk/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -6,6 +6,8 @@
 
 #include "public/fpdf_transformpage.h"
 
+#include <vector>
+
 #include "core/fpdfapi/page/cpdf_clippath.h"
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/page/cpdf_pageobject.h"
@@ -235,8 +237,7 @@
   if (!pPathData)
     return;
 
-  FX_PATHPOINT* pPoints = pPathData->GetPoints();
-
+  const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints();
   if (path.IsRect()) {
     buf << (pPoints[0].m_PointX) << " " << (pPoints[0].m_PointY) << " "
         << (pPoints[2].m_PointX - pPoints[0].m_PointX) << " "
@@ -245,7 +246,7 @@
   }
 
   CFX_ByteString temp;
-  for (int i = 0; i < pPathData->GetPointCount(); i++) {
+  for (size_t i = 0; i < pPoints.size(); i++) {
     buf << (pPoints[i].m_PointX) << " " << (pPoints[i].m_PointY);
     FXPT_TYPE point_type = pPoints[i].m_Type;
     if (point_type == FXPT_TYPE::MoveTo) {
@@ -288,7 +289,7 @@
   for (i = 0; i < pClipPath->GetPathCount(); i++) {
     CPDF_Path path = pClipPath->GetPath(i);
     int iClipType = pClipPath->GetClipType(i);
-    if (path.GetPointCount() == 0) {
+    if (path.GetPoints().empty()) {
       // Empty clipping (totally clipped out)
       strClip << "0 0 m W n ";
     } else {
diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp
index f6e103c..63a887d 100644
--- a/fpdfsdk/fpdfeditpath.cpp
+++ b/fpdfsdk/fpdfeditpath.cpp
@@ -106,15 +106,10 @@
     return false;
 
   auto pPathObj = reinterpret_cast<CPDF_PathObject*>(path);
-  int numPoints = pPathObj->m_Path.GetPointCount();
-  if (numPoints == 0)
+  if (pPathObj->m_Path.GetPoints().empty())
     return false;
 
-  FX_PATHPOINT* pPoints = pPathObj->m_Path.GetMutablePoints();
-  if (pPoints[numPoints - 1].m_CloseFigure)
-    return true;
-
-  pPoints[numPoints - 1].m_CloseFigure = true;
+  pPathObj->m_Path.ClosePath();
   return true;
 }
 
diff --git a/fpdfsdk/pdfwindow/PWL_Caret.cpp b/fpdfsdk/pdfwindow/PWL_Caret.cpp
index 06c8e31..e263a79 100644
--- a/fpdfsdk/pdfwindow/PWL_Caret.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Caret.cpp
@@ -34,7 +34,6 @@
     CFX_FloatRect rcRect = GetCaretRect();
     CFX_FloatRect rcClip = GetClipRect();
     CFX_PathData path;
-    path.SetPointCount(2);
 
     FX_FLOAT fCaretX = rcRect.left + m_fWidth * 0.5f;
     FX_FLOAT fCaretTop = rcRect.top;
@@ -44,14 +43,14 @@
       if (!rcRect.IsEmpty()) {
         fCaretTop = rcRect.top;
         fCaretBottom = rcRect.bottom;
-        path.SetPoint(0, fCaretX, fCaretBottom, FXPT_TYPE::MoveTo, false);
-        path.SetPoint(1, fCaretX, fCaretTop, FXPT_TYPE::LineTo, false);
+        path.AppendPoint(fCaretX, fCaretBottom, FXPT_TYPE::MoveTo, false);
+        path.AppendPoint(fCaretX, fCaretTop, FXPT_TYPE::LineTo, false);
       } else {
         return;
       }
     } else {
-      path.SetPoint(0, fCaretX, fCaretBottom, FXPT_TYPE::MoveTo, false);
-      path.SetPoint(1, fCaretX, fCaretTop, FXPT_TYPE::LineTo, false);
+      path.AppendPoint(fCaretX, fCaretBottom, FXPT_TYPE::MoveTo, false);
+      path.AppendPoint(fCaretX, fCaretTop, FXPT_TYPE::LineTo, false);
     }
 
     CFX_GraphStateData gsd;
diff --git a/fpdfsdk/pdfwindow/PWL_ComboBox.cpp b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
index 1bf1adf..adab4e7 100644
--- a/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
+++ b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp
@@ -147,12 +147,10 @@
         IsFloatBigger(rectWnd.top - rectWnd.bottom,
                       PWL_CBBUTTON_TRIANGLE_HALFLEN)) {
       CFX_PathData path;
-
-      path.SetPointCount(4);
-      path.SetPoint(0, pt1.x, pt1.y, FXPT_TYPE::MoveTo, false);
-      path.SetPoint(1, pt2.x, pt2.y, FXPT_TYPE::LineTo, false);
-      path.SetPoint(2, pt3.x, pt3.y, FXPT_TYPE::LineTo, false);
-      path.SetPoint(3, pt1.x, pt1.y, FXPT_TYPE::LineTo, false);
+      path.AppendPoint(pt1.x, pt1.y, FXPT_TYPE::MoveTo, false);
+      path.AppendPoint(pt2.x, pt2.y, FXPT_TYPE::LineTo, false);
+      path.AppendPoint(pt3.x, pt3.y, FXPT_TYPE::LineTo, false);
+      path.AppendPoint(pt1.x, pt1.y, FXPT_TYPE::LineTo, false);
 
       pDevice->DrawPath(&path, pUser2Device, nullptr,
                         CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_BLACKCOLOR,
diff --git a/fpdfsdk/pdfwindow/PWL_Edit.cpp b/fpdfsdk/pdfwindow/PWL_Edit.cpp
index 5d9c314..5c22d21 100644
--- a/fpdfsdk/pdfwindow/PWL_Edit.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Edit.cpp
@@ -323,21 +323,18 @@
         gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();
 
         CFX_PathData path;
-        path.SetPointCount(nCharArraySafe.ValueOrDie());
 
         for (int32_t i = 0; i < nCharArray - 1; i++) {
-          path.SetPoint(
-              i * 2,
+          path.AppendPoint(
               rcClient.left +
                   ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
               rcClient.bottom, FXPT_TYPE::MoveTo, false);
-          path.SetPoint(
-              i * 2 + 1,
+          path.AppendPoint(
               rcClient.left +
                   ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
               rcClient.top, FXPT_TYPE::LineTo, false);
         }
-        if (path.GetPointCount() > 0) {
+        if (!path.GetPoints().empty()) {
           pDevice->DrawPath(
               &path, pUser2Device, &gsd, 0,
               CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
@@ -355,21 +352,17 @@
         gsd.m_DashPhase = (FX_FLOAT)GetBorderDash().nPhase;
 
         CFX_PathData path;
-        path.SetPointCount(nCharArraySafe.ValueOrDie());
-
         for (int32_t i = 0; i < nCharArray - 1; i++) {
-          path.SetPoint(
-              i * 2,
+          path.AppendPoint(
               rcClient.left +
                   ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
               rcClient.bottom, FXPT_TYPE::MoveTo, false);
-          path.SetPoint(
-              i * 2 + 1,
+          path.AppendPoint(
               rcClient.left +
                   ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
               rcClient.top, FXPT_TYPE::LineTo, false);
         }
-        if (path.GetPointCount() > 0) {
+        if (!path.GetPoints().empty()) {
           pDevice->DrawPath(
               &path, pUser2Device, &gsd, 0,
               CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
diff --git a/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp b/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp
index 2aa2c7e..a202513 100644
--- a/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp
+++ b/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp
@@ -257,12 +257,10 @@
           if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
               rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
             CFX_PathData path;
-
-            path.SetPointCount(4);
-            path.SetPoint(0, pt1.x, pt1.y, FXPT_TYPE::MoveTo, false);
-            path.SetPoint(1, pt2.x, pt2.y, FXPT_TYPE::LineTo, false);
-            path.SetPoint(2, pt3.x, pt3.y, FXPT_TYPE::LineTo, false);
-            path.SetPoint(3, pt1.x, pt1.y, FXPT_TYPE::LineTo, false);
+            path.AppendPoint(pt1.x, pt1.y, FXPT_TYPE::MoveTo, false);
+            path.AppendPoint(pt2.x, pt2.y, FXPT_TYPE::LineTo, false);
+            path.AppendPoint(pt3.x, pt3.y, FXPT_TYPE::LineTo, false);
+            path.AppendPoint(pt1.x, pt1.y, FXPT_TYPE::LineTo, false);
 
             pDevice->DrawPath(&path, pUser2Device, nullptr,
                               CPWL_Utils::PWLColorToFXColor(
@@ -280,12 +278,10 @@
           if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
               rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
             CFX_PathData path;
-
-            path.SetPointCount(4);
-            path.SetPoint(0, pt1.x, pt1.y, FXPT_TYPE::MoveTo, false);
-            path.SetPoint(1, pt2.x, pt2.y, FXPT_TYPE::LineTo, false);
-            path.SetPoint(2, pt3.x, pt3.y, FXPT_TYPE::LineTo, false);
-            path.SetPoint(3, pt1.x, pt1.y, FXPT_TYPE::LineTo, false);
+            path.AppendPoint(pt1.x, pt1.y, FXPT_TYPE::MoveTo, false);
+            path.AppendPoint(pt2.x, pt2.y, FXPT_TYPE::LineTo, false);
+            path.AppendPoint(pt3.x, pt3.y, FXPT_TYPE::LineTo, false);
+            path.AppendPoint(pt1.x, pt1.y, FXPT_TYPE::LineTo, false);
 
             pDevice->DrawPath(&path, pUser2Device, nullptr,
                               CPWL_Utils::PWLColorToFXColor(
diff --git a/fpdfsdk/pdfwindow/PWL_Utils.cpp b/fpdfsdk/pdfwindow/PWL_Utils.cpp
index 8b2813d..9f5e31f 100644
--- a/fpdfsdk/pdfwindow/PWL_Utils.cpp
+++ b/fpdfsdk/pdfwindow/PWL_Utils.cpp
@@ -48,21 +48,19 @@
 void CPWL_Utils::GetPathDataFromArray(CFX_PathData& path,
                                       const CPWL_PathData* pPathData,
                                       int32_t nCount) {
-  path.SetPointCount(nCount);
-
   for (int32_t i = 0; i < nCount; i++) {
     switch (pPathData[i].type) {
       case PWLPT_MOVETO:
-        path.SetPoint(i, pPathData[i].point.x, pPathData[i].point.y,
-                      FXPT_TYPE::MoveTo, false);
+        path.AppendPoint(pPathData[i].point.x, pPathData[i].point.y,
+                         FXPT_TYPE::MoveTo, false);
         break;
       case PWLPT_LINETO:
-        path.SetPoint(i, pPathData[i].point.x, pPathData[i].point.y,
-                      FXPT_TYPE::LineTo, false);
+        path.AppendPoint(pPathData[i].point.x, pPathData[i].point.y,
+                         FXPT_TYPE::LineTo, false);
         break;
       case PWLPT_BEZIERTO:
-        path.SetPoint(i, pPathData[i].point.x, pPathData[i].point.y,
-                      FXPT_TYPE::BezierTo, false);
+        path.AppendPoint(pPathData[i].point.x, pPathData[i].point.y,
+                         FXPT_TYPE::BezierTo, false);
         break;
       default:
         break;
@@ -1234,11 +1232,9 @@
                               int32_t nCount,
                               const FX_COLORREF& color) {
   CFX_PathData path;
-  path.SetPointCount(nCount);
-
-  path.SetPoint(0, pPts[0].x, pPts[0].y, FXPT_TYPE::MoveTo, false);
+  path.AppendPoint(pPts[0].x, pPts[0].y, FXPT_TYPE::MoveTo, false);
   for (int32_t i = 1; i < nCount; i++)
-    path.SetPoint(i, pPts[i].x, pPts[i].y, FXPT_TYPE::LineTo, false);
+    path.AppendPoint(pPts[i].x, pPts[i].y, FXPT_TYPE::LineTo, false);
 
   pDevice->DrawPath(&path, pUser2Device, nullptr, color, 0, FXFILL_ALTERNATE);
 }
@@ -1265,9 +1261,8 @@
                                 const FX_COLORREF& color,
                                 FX_FLOAT fWidth) {
   CFX_PathData path;
-  path.SetPointCount(2);
-  path.SetPoint(0, ptMoveTo.x, ptMoveTo.y, FXPT_TYPE::MoveTo, false);
-  path.SetPoint(1, ptLineTo.x, ptLineTo.y, FXPT_TYPE::LineTo, false);
+  path.AppendPoint(ptMoveTo.x, ptMoveTo.y, FXPT_TYPE::MoveTo, false);
+  path.AppendPoint(ptLineTo.x, ptLineTo.y, FXPT_TYPE::LineTo, false);
 
   CFX_GraphStateData gsd;
   gsd.m_LineWidth = fWidth;
@@ -1350,18 +1345,16 @@
       }
       case BorderStyle::DASH: {
         CFX_PathData path;
-
-        path.SetPointCount(5);
-        path.SetPoint(0, fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f,
-                      FXPT_TYPE::MoveTo, false);
-        path.SetPoint(1, fLeft + fWidth / 2.0f, fTop - fWidth / 2.0f,
-                      FXPT_TYPE::LineTo, false);
-        path.SetPoint(2, fRight - fWidth / 2.0f, fTop - fWidth / 2.0f,
-                      FXPT_TYPE::LineTo, false);
-        path.SetPoint(3, fRight - fWidth / 2.0f, fBottom + fWidth / 2.0f,
-                      FXPT_TYPE::LineTo, false);
-        path.SetPoint(4, fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f,
-                      FXPT_TYPE::LineTo, false);
+        path.AppendPoint(fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f,
+                         FXPT_TYPE::MoveTo, false);
+        path.AppendPoint(fLeft + fWidth / 2.0f, fTop - fWidth / 2.0f,
+                         FXPT_TYPE::LineTo, false);
+        path.AppendPoint(fRight - fWidth / 2.0f, fTop - fWidth / 2.0f,
+                         FXPT_TYPE::LineTo, false);
+        path.AppendPoint(fRight - fWidth / 2.0f, fBottom + fWidth / 2.0f,
+                         FXPT_TYPE::LineTo, false);
+        path.AppendPoint(fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f,
+                         FXPT_TYPE::LineTo, false);
 
         CFX_GraphStateData gsd;
         gsd.SetDashCount(2);
@@ -1382,43 +1375,40 @@
 
         CFX_PathData pathLT;
 
-        pathLT.SetPointCount(7);
-        pathLT.SetPoint(0, fLeft + fHalfWidth, fBottom + fHalfWidth,
-                        FXPT_TYPE::MoveTo, false);
-        pathLT.SetPoint(1, fLeft + fHalfWidth, fTop - fHalfWidth,
-                        FXPT_TYPE::LineTo, false);
-        pathLT.SetPoint(2, fRight - fHalfWidth, fTop - fHalfWidth,
-                        FXPT_TYPE::LineTo, false);
-        pathLT.SetPoint(3, fRight - fHalfWidth * 2, fTop - fHalfWidth * 2,
-                        FXPT_TYPE::LineTo, false);
-        pathLT.SetPoint(4, fLeft + fHalfWidth * 2, fTop - fHalfWidth * 2,
-                        FXPT_TYPE::LineTo, false);
-        pathLT.SetPoint(5, fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2,
-                        FXPT_TYPE::LineTo, false);
-        pathLT.SetPoint(6, fLeft + fHalfWidth, fBottom + fHalfWidth,
-                        FXPT_TYPE::LineTo, false);
+        pathLT.AppendPoint(fLeft + fHalfWidth, fBottom + fHalfWidth,
+                           FXPT_TYPE::MoveTo, false);
+        pathLT.AppendPoint(fLeft + fHalfWidth, fTop - fHalfWidth,
+                           FXPT_TYPE::LineTo, false);
+        pathLT.AppendPoint(fRight - fHalfWidth, fTop - fHalfWidth,
+                           FXPT_TYPE::LineTo, false);
+        pathLT.AppendPoint(fRight - fHalfWidth * 2, fTop - fHalfWidth * 2,
+                           FXPT_TYPE::LineTo, false);
+        pathLT.AppendPoint(fLeft + fHalfWidth * 2, fTop - fHalfWidth * 2,
+                           FXPT_TYPE::LineTo, false);
+        pathLT.AppendPoint(fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2,
+                           FXPT_TYPE::LineTo, false);
+        pathLT.AppendPoint(fLeft + fHalfWidth, fBottom + fHalfWidth,
+                           FXPT_TYPE::LineTo, false);
 
         pDevice->DrawPath(&pathLT, pUser2Device, &gsd,
                           PWLColorToFXColor(crLeftTop, nTransparancy), 0,
                           FXFILL_ALTERNATE);
 
         CFX_PathData pathRB;
-
-        pathRB.SetPointCount(7);
-        pathRB.SetPoint(0, fRight - fHalfWidth, fTop - fHalfWidth,
-                        FXPT_TYPE::MoveTo, false);
-        pathRB.SetPoint(1, fRight - fHalfWidth, fBottom + fHalfWidth,
-                        FXPT_TYPE::LineTo, false);
-        pathRB.SetPoint(2, fLeft + fHalfWidth, fBottom + fHalfWidth,
-                        FXPT_TYPE::LineTo, false);
-        pathRB.SetPoint(3, fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2,
-                        FXPT_TYPE::LineTo, false);
-        pathRB.SetPoint(4, fRight - fHalfWidth * 2, fBottom + fHalfWidth * 2,
-                        FXPT_TYPE::LineTo, false);
-        pathRB.SetPoint(5, fRight - fHalfWidth * 2, fTop - fHalfWidth * 2,
-                        FXPT_TYPE::LineTo, false);
-        pathRB.SetPoint(6, fRight - fHalfWidth, fTop - fHalfWidth,
-                        FXPT_TYPE::LineTo, false);
+        pathRB.AppendPoint(fRight - fHalfWidth, fTop - fHalfWidth,
+                           FXPT_TYPE::MoveTo, false);
+        pathRB.AppendPoint(fRight - fHalfWidth, fBottom + fHalfWidth,
+                           FXPT_TYPE::LineTo, false);
+        pathRB.AppendPoint(fLeft + fHalfWidth, fBottom + fHalfWidth,
+                           FXPT_TYPE::LineTo, false);
+        pathRB.AppendPoint(fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2,
+                           FXPT_TYPE::LineTo, false);
+        pathRB.AppendPoint(fRight - fHalfWidth * 2, fBottom + fHalfWidth * 2,
+                           FXPT_TYPE::LineTo, false);
+        pathRB.AppendPoint(fRight - fHalfWidth * 2, fTop - fHalfWidth * 2,
+                           FXPT_TYPE::LineTo, false);
+        pathRB.AppendPoint(fRight - fHalfWidth, fTop - fHalfWidth,
+                           FXPT_TYPE::LineTo, false);
 
         pDevice->DrawPath(&pathRB, pUser2Device, &gsd,
                           PWLColorToFXColor(crRightBottom, nTransparancy), 0,
@@ -1437,11 +1427,9 @@
       }
       case BorderStyle::UNDERLINE: {
         CFX_PathData path;
-
-        path.SetPointCount(2);
-        path.SetPoint(0, fLeft, fBottom + fWidth / 2, FXPT_TYPE::MoveTo, false);
-        path.SetPoint(1, fRight, fBottom + fWidth / 2, FXPT_TYPE::LineTo,
-                      false);
+        path.AppendPoint(fLeft, fBottom + fWidth / 2, FXPT_TYPE::MoveTo, false);
+        path.AppendPoint(fRight, fBottom + fWidth / 2, FXPT_TYPE::LineTo,
+                         false);
 
         CFX_GraphStateData gsd;
         gsd.m_LineWidth = fWidth;
diff --git a/xfa/fde/cfde_path.cpp b/xfa/fde/cfde_path.cpp
index 825de40..0418513 100644
--- a/xfa/fde/cfde_path.cpp
+++ b/xfa/fde/cfde_path.cpp
@@ -9,70 +9,29 @@
 #include "third_party/base/stl_util.h"
 #include "xfa/fde/fde_object.h"
 
-bool CFDE_Path::StartFigure() {
-  return CloseFigure();
-}
-
-bool CFDE_Path::CloseFigure() {
-  FX_PATHPOINT* pPoint = GetLastPoint();
-  if (pPoint)
-    pPoint->m_CloseFigure = true;
-  return true;
-}
-
-FX_PATHPOINT* CFDE_Path::GetLastPoint() const {
-  int32_t iPoints = m_Path.GetPointCount();
-  if (iPoints == 0)
-    return nullptr;
-  return m_Path.GetPoints() + iPoints - 1;
+void CFDE_Path::CloseFigure() {
+  m_Path.ClosePath();
 }
 
 bool CFDE_Path::FigureClosed() const {
-  FX_PATHPOINT* pPoint = GetLastPoint();
-  return pPoint ? pPoint->m_CloseFigure : true;
-}
-
-FX_PATHPOINT* CFDE_Path::AddPoints(int32_t iCount) {
-  if (iCount < 1)
-    return nullptr;
-
-  int32_t iPoints = m_Path.GetPointCount();
-  m_Path.AddPointCount(iCount);
-  return m_Path.GetPoints() + iPoints;
+  const std::vector<FX_PATHPOINT>& points = m_Path.GetPoints();
+  return points.empty() ? true : points.back().m_CloseFigure;
 }
 
 void CFDE_Path::MoveTo(FX_FLOAT fx, FX_FLOAT fy) {
-  FX_PATHPOINT* pPoint = AddPoints(1);
-  pPoint->m_PointX = fx;
-  pPoint->m_PointY = fy;
-  pPoint->m_Type = FXPT_TYPE::MoveTo;
-  pPoint->m_CloseFigure = false;
+  m_Path.AppendPoint(fx, fy, FXPT_TYPE::MoveTo, false);
 }
 
 void CFDE_Path::LineTo(FX_FLOAT fx, FX_FLOAT fy) {
-  FX_PATHPOINT* pPoint = AddPoints(1);
-  pPoint->m_PointX = fx;
-  pPoint->m_PointY = fy;
-  pPoint->m_Type = FXPT_TYPE::LineTo;
-  pPoint->m_CloseFigure = false;
+  m_Path.AppendPoint(fx, fy, FXPT_TYPE::LineTo, false);
 }
 
 void CFDE_Path::BezierTo(const CFX_PointF& p1,
                          const CFX_PointF& p2,
                          const CFX_PointF& p3) {
-  FX_PATHPOINT* p = AddPoints(3);
-  p[0].m_PointX = p1.x;
-  p[0].m_PointY = p1.y;
-  p[0].m_Type = FXPT_TYPE::BezierTo;
-  p[0].m_CloseFigure = false;
-  p[1].m_PointX = p2.x;
-  p[1].m_PointY = p2.y;
-  p[1].m_Type = FXPT_TYPE::BezierTo;
-  p[1].m_CloseFigure = false;
-  p[2].m_PointX = p3.x;
-  p[2].m_PointY = p3.y;
-  p[2].m_Type = FXPT_TYPE::BezierTo;
-  p[2].m_CloseFigure = false;
+  m_Path.AppendPoint(p1.x, p1.y, FXPT_TYPE::BezierTo, false);
+  m_Path.AppendPoint(p2.x, p2.y, FXPT_TYPE::BezierTo, false);
+  m_Path.AppendPoint(p3.x, p3.y, FXPT_TYPE::BezierTo, false);
 }
 
 void CFDE_Path::ArcTo(bool bStart,
@@ -195,9 +154,9 @@
 }
 
 void CFDE_Path::AddLine(const CFX_PointF& pt1, const CFX_PointF& pt2) {
-  FX_PATHPOINT* pLast = GetLastPoint();
-  if (!pLast || FXSYS_fabs(pLast->m_PointX - pt1.x) > 0.001 ||
-      FXSYS_fabs(pLast->m_PointY - pt1.y) > 0.001) {
+  std::vector<FX_PATHPOINT>& points = m_Path.GetPoints();
+  if (points.empty() || FXSYS_fabs(points.back().m_PointX - pt1.x) > 0.001 ||
+      FXSYS_fabs(points.back().m_PointY - pt1.y) > 0.001) {
     MoveTo(pt1);
   }
   LineTo(pt2);
@@ -207,8 +166,7 @@
   if (!pSrc)
     return;
 
-  int32_t iCount = pSrc->m_Path.GetPointCount();
-  if (iCount < 1)
+  if (pSrc->m_Path.GetPoints().empty())
     return;
   if (bConnect)
     LineTo(pSrc->m_Path.GetPointX(0), pSrc->m_Path.GetPointY(0));
diff --git a/xfa/fde/cfde_path.h b/xfa/fde/cfde_path.h
index ab59950..a3a8180 100644
--- a/xfa/fde/cfde_path.h
+++ b/xfa/fde/cfde_path.h
@@ -14,8 +14,7 @@
 
 class CFDE_Path {
  public:
-  bool StartFigure();
-  bool CloseFigure();
+  void CloseFigure();
 
   void AddBezier(const std::vector<CFX_PointF>& points);
   void AddBeziers(const std::vector<CFX_PointF>& points);
@@ -28,7 +27,6 @@
   void AddPath(const CFDE_Path* pSrc, bool bConnect);
   void AddPolygon(const std::vector<CFX_PointF>& points);
   void AddRectangle(const CFX_RectF& rect);
-  FX_PATHPOINT* AddPoints(int32_t iCount);
 
   CFX_RectF GetBBox() const;
   CFX_RectF GetBBox(FX_FLOAT fLineWidth, FX_FLOAT fMiterLimit) const;
@@ -46,7 +44,6 @@
   void MoveTo(const CFX_PointF& p0) { MoveTo(p0.x, p0.y); }
   void LineTo(const CFX_PointF& p1) { LineTo(p1.x, p1.y); }
 
-  FX_PATHPOINT* GetLastPoint() const;
   void GetCurveTangents(const std::vector<CFX_PointF>& points,
                         std::vector<CFX_PointF>* tangents,
                         bool bClosed,
diff --git a/xfa/fxgraphics/cfx_path.cpp b/xfa/fxgraphics/cfx_path.cpp
index 3288631..d2e8f94 100644
--- a/xfa/fxgraphics/cfx_path.cpp
+++ b/xfa/fxgraphics/cfx_path.cpp
@@ -159,14 +159,14 @@
 FWL_Error CFX_Path::Clear() {
   if (!m_generator)
     return FWL_Error::PropertyInvalid;
-  m_generator->GetPathData()->SetPointCount(0);
+  m_generator->GetPathData()->Clear();
   return FWL_Error::Succeeded;
 }
 
 bool CFX_Path::IsEmpty() const {
   if (!m_generator)
     return false;
-  if (m_generator->GetPathData()->GetPointCount() == 0)
+  if (m_generator->GetPathData()->GetPoints().empty())
     return true;
   return false;
 }
diff --git a/xfa/fxgraphics/cfx_path_generator.cpp b/xfa/fxgraphics/cfx_path_generator.cpp
index c7f4c0b..8da1b4f 100644
--- a/xfa/fxgraphics/cfx_path_generator.cpp
+++ b/xfa/fxgraphics/cfx_path_generator.cpp
@@ -14,33 +14,17 @@
 CFX_PathGenerator::~CFX_PathGenerator() {}
 
 void CFX_PathGenerator::AddPathData(CFX_PathData* pPathData) {
-  if (pPathData && pPathData->GetPointCount() > 0) {
-    int nCount = pPathData->GetPointCount();
-    FX_PATHPOINT* pPoints = pPathData->GetPoints();
-    AddPathData(pPoints, nCount);
-  }
-}
-
-void CFX_PathGenerator::AddPathData(FX_PATHPOINT* pPoints, int nCount) {
-  if (pPoints && nCount > 0) {
-    int nOldCount = m_pPathData->GetPointCount();
-    m_pPathData->AddPointCount(nCount);
-    FX_PATHPOINT* pDstPoints = m_pPathData->GetPoints();
-    FXSYS_memcpy(pDstPoints + nOldCount, pPoints,
-                 sizeof(FX_PATHPOINT) * nCount);
-  }
+  if (!pPathData)
+    return;
+  m_pPathData->Append(pPathData, nullptr);
 }
 
 void CFX_PathGenerator::MoveTo(FX_FLOAT x, FX_FLOAT y) {
-  m_pPathData->AddPointCount(1);
-  m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y,
-                        FXPT_TYPE::MoveTo, false);
+  m_pPathData->AppendPoint(x, y, FXPT_TYPE::MoveTo, false);
 }
 
 void CFX_PathGenerator::LineTo(FX_FLOAT x, FX_FLOAT y) {
-  m_pPathData->AddPointCount(1);
-  m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y,
-                        FXPT_TYPE::LineTo, false);
+  m_pPathData->AppendPoint(x, y, FXPT_TYPE::LineTo, false);
 }
 
 void CFX_PathGenerator::BezierTo(FX_FLOAT ctrl_x1,
@@ -49,31 +33,21 @@
                                  FX_FLOAT ctrl_y2,
                                  FX_FLOAT to_x,
                                  FX_FLOAT to_y) {
-  int old_count = m_pPathData->GetPointCount();
-  m_pPathData->AddPointCount(3);
-  m_pPathData->SetPoint(old_count, ctrl_x1, ctrl_y1, FXPT_TYPE::BezierTo,
-                        false);
-  m_pPathData->SetPoint(old_count + 1, ctrl_x2, ctrl_y2, FXPT_TYPE::BezierTo,
-                        false);
-  m_pPathData->SetPoint(old_count + 2, to_x, to_y, FXPT_TYPE::BezierTo, false);
+  m_pPathData->AppendPoint(ctrl_x1, ctrl_y1, FXPT_TYPE::BezierTo, false);
+  m_pPathData->AppendPoint(ctrl_x2, ctrl_y2, FXPT_TYPE::BezierTo, false);
+  m_pPathData->AppendPoint(to_x, to_y, FXPT_TYPE::BezierTo, false);
 }
 
 void CFX_PathGenerator::Close() {
-  if (m_pPathData->GetPointCount() > 0) {
-    int index = m_pPathData->GetPointCount() - 1;
-    FX_PATHPOINT* pPoints = m_pPathData->GetPoints();
-    pPoints[index].m_CloseFigure = true;
-  }
+  m_pPathData->ClosePath();
 }
 
 void CFX_PathGenerator::AddLine(FX_FLOAT x1,
                                 FX_FLOAT y1,
                                 FX_FLOAT x2,
                                 FX_FLOAT y2) {
-  int old_count = m_pPathData->GetPointCount();
-  m_pPathData->AddPointCount(2);
-  m_pPathData->SetPoint(old_count, x1, y1, FXPT_TYPE::MoveTo, false);
-  m_pPathData->SetPoint(old_count + 1, x2, y2, FXPT_TYPE::LineTo, false);
+  m_pPathData->AppendPoint(x1, y1, FXPT_TYPE::MoveTo, false);
+  m_pPathData->AppendPoint(x2, y2, FXPT_TYPE::LineTo, false);
 }
 
 void CFX_PathGenerator::AddBezier(FX_FLOAT start_x,
@@ -84,15 +58,10 @@
                                   FX_FLOAT ctrl_y2,
                                   FX_FLOAT end_x,
                                   FX_FLOAT end_y) {
-  int old_count = m_pPathData->GetPointCount();
-  m_pPathData->AddPointCount(4);
-  m_pPathData->SetPoint(old_count, start_x, start_y, FXPT_TYPE::MoveTo, false);
-  m_pPathData->SetPoint(old_count + 1, ctrl_x1, ctrl_y1, FXPT_TYPE::BezierTo,
-                        false);
-  m_pPathData->SetPoint(old_count + 2, ctrl_x2, ctrl_y2, FXPT_TYPE::BezierTo,
-                        false);
-  m_pPathData->SetPoint(old_count + 3, end_x, end_y, FXPT_TYPE::BezierTo,
-                        false);
+  m_pPathData->AppendPoint(start_x, start_y, FXPT_TYPE::MoveTo, false);
+  m_pPathData->AppendPoint(ctrl_x1, ctrl_y1, FXPT_TYPE::BezierTo, false);
+  m_pPathData->AppendPoint(ctrl_x2, ctrl_y2, FXPT_TYPE::BezierTo, false);
+  m_pPathData->AppendPoint(end_x, end_y, FXPT_TYPE::BezierTo, false);
 }
 
 void CFX_PathGenerator::AddRectangle(FX_FLOAT x1,
@@ -126,21 +95,17 @@
   py[1] = ty;
   FX_FLOAT sn = FXSYS_sin(start_angle + sweep_angle / 2);
   FX_FLOAT cs = FXSYS_cos(start_angle + sweep_angle / 2);
-  int old_count = m_pPathData->GetPointCount();
-  m_pPathData->AddPointCount(3);
+
   FX_FLOAT bezier_x, bezier_y;
   bezier_x = x + (width * ((px[0] * cs) - (py[0] * sn)));
   bezier_y = y + (height * ((px[0] * sn) + (py[0] * cs)));
-  m_pPathData->SetPoint(old_count, bezier_x, bezier_y, FXPT_TYPE::BezierTo,
-                        false);
+  m_pPathData->AppendPoint(bezier_x, bezier_y, FXPT_TYPE::BezierTo, false);
   bezier_x = x + (width * ((px[1] * cs) - (py[1] * sn)));
   bezier_y = y + (height * ((px[1] * sn) + (py[1] * cs)));
-  m_pPathData->SetPoint(old_count + 1, bezier_x, bezier_y, FXPT_TYPE::BezierTo,
-                        false);
+  m_pPathData->AppendPoint(bezier_x, bezier_y, FXPT_TYPE::BezierTo, false);
   bezier_x = x + (width * FXSYS_cos(start_angle + sweep_angle));
   bezier_y = y + (height * FXSYS_sin(start_angle + sweep_angle));
-  m_pPathData->SetPoint(old_count + 2, bezier_x, bezier_y, FXPT_TYPE::BezierTo,
-                        false);
+  m_pPathData->AppendPoint(bezier_x, bezier_y, FXPT_TYPE::BezierTo, false);
 }
 
 void CFX_PathGenerator::AddArc(FX_FLOAT x,
@@ -166,10 +131,10 @@
   if (sweep_angle <= -FX_PI * 2) {
     sweep_angle = -FX_PI * 2;
   }
-  m_pPathData->AddPointCount(1);
-  m_pPathData->SetPoint(
-      m_pPathData->GetPointCount() - 1, x + (width * FXSYS_cos(start_angle)),
-      y + (height * FXSYS_sin(start_angle)), FXPT_TYPE::MoveTo, false);
+
+  m_pPathData->AppendPoint(x + (width * FXSYS_cos(start_angle)),
+                           y + (height * FXSYS_sin(start_angle)),
+                           FXPT_TYPE::MoveTo, false);
   FX_FLOAT total_sweep = 0, local_sweep = 0, prev_sweep = 0;
   bool done = false;
   do {
@@ -202,16 +167,12 @@
                                FX_FLOAT start_angle,
                                FX_FLOAT sweep_angle) {
   if (sweep_angle == 0) {
-    int old_count = m_pPathData->GetPointCount();
-    m_pPathData->AddPointCount(2);
-    m_pPathData->SetPoint(old_count, x, y, FXPT_TYPE::MoveTo, false);
-    m_pPathData->SetPoint(old_count + 1, x + (width * FXSYS_cos(start_angle)),
-                          y + (height * FXSYS_sin(start_angle)),
-                          FXPT_TYPE::LineTo, false);
+    m_pPathData->AppendPoint(x, y, FXPT_TYPE::MoveTo, false);
+    m_pPathData->AppendPoint(x + (width * FXSYS_cos(start_angle)),
+                             y + (height * FXSYS_sin(start_angle)),
+                             FXPT_TYPE::LineTo, false);
     return;
   }
   AddArc(x, y, width, height, start_angle, sweep_angle);
-  m_pPathData->AddPointCount(1);
-  m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y,
-                        FXPT_TYPE::LineTo, true);
+  m_pPathData->AppendPoint(x, y, FXPT_TYPE::LineTo, true);
 }
diff --git a/xfa/fxgraphics/cfx_path_generator.h b/xfa/fxgraphics/cfx_path_generator.h
index 75e3a57..916400d 100644
--- a/xfa/fxgraphics/cfx_path_generator.h
+++ b/xfa/fxgraphics/cfx_path_generator.h
@@ -19,7 +19,6 @@
   CFX_PathData* GetPathData() const { return m_pPathData.get(); }
 
   void AddPathData(CFX_PathData* path_data);
-  void AddPathData(FX_PATHPOINT* points, int count);
 
   void MoveTo(FX_FLOAT x, FX_FLOAT y);
   void LineTo(FX_FLOAT x, FX_FLOAT y);