Store CPDF_Path::GetPoints() results in span.

Same for CFX_PathData::GetPoints(). Help transition the path classes to
be able to return spans instead of vectors.

Change-Id: I7b1ebf24dd8e8c8dec363b8b3d539142a7ec8b81
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/67654
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index d5c13c7..9a9785c 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -35,6 +35,7 @@
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fpdfapi/parser/fpdf_parser_utility.h"
 #include "third_party/base/ptr_util.h"
+#include "third_party/base/span.h"
 #include "third_party/base/stl_util.h"
 
 namespace {
@@ -348,7 +349,7 @@
 
   *buf << pPathObj->matrix() << " cm ";
 
-  const auto& points = pPathObj->path().GetPoints();
+  pdfium::span<const FX_PATHPOINT> points = pPathObj->path().GetPoints();
   if (pPathObj->path().IsRect()) {
     CFX_PointF diff = points[2].m_Point - points[0].m_Point;
     *buf << points[0].m_Point << " " << diff << " re";
diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp
index 3e5a552..9931fe0 100644
--- a/core/fxge/agg/fx_agg_driver.cpp
+++ b/core/fxge/agg/fx_agg_driver.cpp
@@ -18,6 +18,7 @@
 #include "core/fxge/dib/cfx_imagerenderer.h"
 #include "core/fxge/dib/cfx_imagestretcher.h"
 #include "third_party/base/ptr_util.h"
+#include "third_party/base/span.h"
 #include "third_party/base/stl_util.h"
 
 // Ignore fallthrough warnings in agg23 headers.
@@ -1088,7 +1089,7 @@
 
 void CAgg_PathData::BuildPath(const CFX_PathData* pPathData,
                               const CFX_Matrix* pObject2Device) {
-  const std::vector<FX_PATHPOINT>& points = pPathData->GetPoints();
+  pdfium::span<const FX_PATHPOINT> points = pPathData->GetPoints();
   for (size_t i = 0; i < points.size(); ++i) {
     CFX_PointF pos = points[i].m_Point;
     if (pObject2Device)
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index 5a51b6d..67a80b6 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -24,6 +24,7 @@
 #include "core/fxge/fx_font.h"
 #include "core/fxge/scoped_font_transform.h"
 #include "third_party/base/ptr_util.h"
+#include "third_party/base/span.h"
 
 #define EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em)
 
@@ -81,21 +82,25 @@
 #endif  // PDF_ENABLE_XFA
 
 void Outline_CheckEmptyContour(OUTLINE_PARAMS* param) {
-  std::vector<FX_PATHPOINT>& points = param->m_pPath->GetPoints();
-  size_t size = points.size();
+  size_t size;
+  {
+    pdfium::span<const FX_PATHPOINT> points = param->m_pPath->GetPoints();
+    size = points.size();
 
-  if (size >= 2 && points[size - 2].IsTypeAndOpen(FXPT_TYPE::MoveTo) &&
-      points[size - 2].m_Point == points[size - 1].m_Point) {
-    size -= 2;
+    if (size >= 2 && points[size - 2].IsTypeAndOpen(FXPT_TYPE::MoveTo) &&
+        points[size - 2].m_Point == points[size - 1].m_Point) {
+      size -= 2;
+    }
+    if (size >= 4 && points[size - 4].IsTypeAndOpen(FXPT_TYPE::MoveTo) &&
+        points[size - 3].IsTypeAndOpen(FXPT_TYPE::BezierTo) &&
+        points[size - 3].m_Point == points[size - 4].m_Point &&
+        points[size - 2].m_Point == points[size - 4].m_Point &&
+        points[size - 1].m_Point == points[size - 4].m_Point) {
+      size -= 4;
+    }
   }
-  if (size >= 4 && points[size - 4].IsTypeAndOpen(FXPT_TYPE::MoveTo) &&
-      points[size - 3].IsTypeAndOpen(FXPT_TYPE::BezierTo) &&
-      points[size - 3].m_Point == points[size - 4].m_Point &&
-      points[size - 2].m_Point == points[size - 4].m_Point &&
-      points[size - 1].m_Point == points[size - 4].m_Point) {
-    size -= 4;
-  }
-  points.resize(size);
+  // Only safe after |points| has been destroyed.
+  param->m_pPath->GetPoints().resize(size);
 }
 
 int Outline_MoveTo(const FT_Vector* to, void* user) {
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index 4c79891..e5d20f9 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -27,6 +27,7 @@
 #include "core/fxge/renderdevicedriver_iface.h"
 #include "core/fxge/text_char_pos.h"
 #include "core/fxge/text_glyph_pos.h"
+#include "third_party/base/span.h"
 
 #if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
 #include "third_party/skia/include/core/SkTypes.h"
@@ -513,7 +514,7 @@
                                          BlendMode blend_type) {
   uint8_t stroke_alpha = pGraphState ? FXARGB_A(stroke_color) : 0;
   uint8_t fill_alpha = (fill_mode & 3) ? FXARGB_A(fill_color) : 0;
-  const std::vector<FX_PATHPOINT>& points = pPathData->GetPoints();
+  pdfium::span<const FX_PATHPOINT> points = pPathData->GetPoints();
   if (stroke_alpha == 0 && points.size() == 2) {
     CFX_PointF pos1 = points[0].m_Point;
     CFX_PointF pos2 = points[1].m_Point;
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index 5fbf481..6617438 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -34,6 +34,7 @@
 #include "core/fxge/text_char_pos.h"
 #include "third_party/base/logging.h"
 #include "third_party/base/ptr_util.h"
+#include "third_party/base/span.h"
 #include "third_party/base/stl_util.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkClipOp.h"
@@ -313,7 +314,7 @@
 
 SkPath BuildPath(const CFX_PathData* pPathData) {
   SkPath sk_path;
-  const std::vector<FX_PATHPOINT>& points = pPathData->GetPoints();
+  pdfium::span<const FX_PATHPOINT> points = pPathData->GetPoints();
   for (size_t i = 0; i < points.size(); ++i) {
     const CFX_PointF& point = points[i].m_Point;
     FXPT_TYPE point_type = points[i].m_Type;
diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp
index 11d5555..968eac5 100644
--- a/core/fxge/win32/fx_win32_device.cpp
+++ b/core/fxge/win32/fx_win32_device.cpp
@@ -152,7 +152,7 @@
                  const CFX_Matrix* pMatrix) {
   BeginPath(hDC);
 
-  const std::vector<FX_PATHPOINT>& points = pPathData->GetPoints();
+  pdfium::span<const FX_PATHPOINT> points = pPathData->GetPoints();
   for (size_t i = 0; i < points.size(); ++i) {
     CFX_PointF pos = points[i].m_Point;
     if (pMatrix)
diff --git a/fpdfsdk/fpdf_editpath.cpp b/fpdfsdk/fpdf_editpath.cpp
index aaa4b72..3f9ae21 100644
--- a/fpdfsdk/fpdf_editpath.cpp
+++ b/fpdfsdk/fpdf_editpath.cpp
@@ -12,6 +12,7 @@
 #include "core/fxcrt/fx_system.h"
 #include "fpdfsdk/cpdfsdk_helpers.h"
 #include "third_party/base/ptr_util.h"
+#include "third_party/base/span.h"
 #include "third_party/base/stl_util.h"
 
 // These checks are here because core/ and public/ cannot depend on each other.
@@ -81,7 +82,7 @@
   if (!pPathObj)
     return nullptr;
 
-  const std::vector<FX_PATHPOINT>& points = pPathObj->path().GetPoints();
+  pdfium::span<const FX_PATHPOINT> points = pPathObj->path().GetPoints();
   if (!pdfium::IndexInBounds(points, index))
     return nullptr;
 
diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp
index bac805b..86bed33 100644
--- a/fpdfsdk/fpdf_transformpage.cpp
+++ b/fpdfsdk/fpdf_transformpage.cpp
@@ -26,6 +26,7 @@
 #include "core/fxge/render_defines.h"
 #include "fpdfsdk/cpdfsdk_helpers.h"
 #include "third_party/base/ptr_util.h"
+#include "third_party/base/span.h"
 
 namespace {
 
@@ -68,7 +69,7 @@
   if (!pPathData)
     return;
 
-  const std::vector<FX_PATHPOINT>& points = pPathData->GetPoints();
+  pdfium::span<const FX_PATHPOINT> points = pPathData->GetPoints();
   if (path.IsRect()) {
     CFX_PointF diff = points[2].m_Point - points[0].m_Point;
     buf << points[0].m_Point.x << " " << points[0].m_Point.y << " " << diff.x
@@ -351,7 +352,7 @@
     return nullptr;
   }
 
-  const std::vector<FX_PATHPOINT>& points =
+  pdfium::span<const FX_PATHPOINT> points =
       pClipPath->GetPath(path_index).GetPoints();
   if (!pdfium::IndexInBounds(points, segment_index))
     return nullptr;