Split path construction and painting in content generation
Path construction will be used to create clipping paths when processing
the graphics of a page object. Split the path construction into a
separate function to reuse the code.
Bug: pdfium:1558
Change-Id: I91f42e61712786c3b559a509bcd4d89547d2e377
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/71730
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Daniel Hosseinian <dhoss@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 580b36e..573b40c 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -331,7 +331,7 @@
*buf << "/" << PDF_NameEncode(name) << " Do Q\n";
}
-// Processing path with operators from Tables 4.9 and 4.10 of PDF spec 1.7:
+// Processing path construction with operators from Table 4.9 of PDF spec 1.7:
// "re" appends a rectangle (here, used only if the whole path is a rectangle)
// "m" moves current point to the given coordinates
// "l" creates a line from current point to the new point
@@ -339,6 +339,45 @@
// points as the Bezier control points
// Note: "l", "c" change the current point
// "h" closes the subpath (appends a line from current to starting point)
+void CPDF_PageContentGenerator::ProcessPathPoints(std::ostringstream* buf,
+ CPDF_Path* pPath) {
+ pdfium::span<const FX_PATHPOINT> points = pPath->GetPoints();
+ if (pPath->IsRect()) {
+ CFX_PointF diff = points[2].m_Point - points[0].m_Point;
+ *buf << points[0].m_Point << " " << diff << " re";
+ return;
+ }
+ for (size_t i = 0; i < points.size(); ++i) {
+ if (i > 0)
+ *buf << " ";
+
+ *buf << points[i].m_Point;
+
+ FXPT_TYPE point_type = points[i].m_Type;
+ if (point_type == FXPT_TYPE::MoveTo) {
+ *buf << " m";
+ } else if (point_type == FXPT_TYPE::LineTo) {
+ *buf << " l";
+ } else if (point_type == FXPT_TYPE::BezierTo) {
+ if (i + 2 >= points.size() ||
+ !points[i].IsTypeAndOpen(FXPT_TYPE::BezierTo) ||
+ !points[i + 1].IsTypeAndOpen(FXPT_TYPE::BezierTo) ||
+ points[i + 2].m_Type != FXPT_TYPE::BezierTo) {
+ // If format is not supported, close the path and paint
+ *buf << " h";
+ break;
+ }
+ *buf << " ";
+ *buf << points[i + 1].m_Point << " ";
+ *buf << points[i + 2].m_Point << " c";
+ i += 2;
+ }
+ if (points[i].m_CloseFigure)
+ *buf << " h";
+ }
+}
+
+// Processing path painting with operators from Table 4.10 of PDF spec 1.7:
// Path painting operators: "S", "n", "B", "f", "B*", "f*", depending on
// the filling mode and whether we want stroking the path or not.
// "Q" restores the graphics state imposed by the ProcessGraphics method.
@@ -347,41 +386,8 @@
ProcessGraphics(buf, pPathObj);
*buf << pPathObj->matrix() << " cm ";
+ ProcessPathPoints(buf, &pPathObj->path());
- 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";
- } else {
- for (size_t i = 0; i < points.size(); ++i) {
- if (i > 0)
- *buf << " ";
-
- *buf << points[i].m_Point;
-
- FXPT_TYPE point_type = points[i].m_Type;
- if (point_type == FXPT_TYPE::MoveTo) {
- *buf << " m";
- } else if (point_type == FXPT_TYPE::LineTo) {
- *buf << " l";
- } else if (point_type == FXPT_TYPE::BezierTo) {
- if (i + 2 >= points.size() ||
- !points[i].IsTypeAndOpen(FXPT_TYPE::BezierTo) ||
- !points[i + 1].IsTypeAndOpen(FXPT_TYPE::BezierTo) ||
- points[i + 2].m_Type != FXPT_TYPE::BezierTo) {
- // If format is not supported, close the path and paint
- *buf << " h";
- break;
- }
- *buf << " ";
- *buf << points[i + 1].m_Point << " ";
- *buf << points[i + 2].m_Point << " c";
- i += 2;
- }
- if (points[i].m_CloseFigure)
- *buf << " h";
- }
- }
if (pPathObj->has_no_filltype())
*buf << (pPathObj->stroke() ? " S" : " n");
else if (pPathObj->has_winding_filltype())
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
index 40d19ae..f1126f2 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
@@ -22,6 +22,7 @@
class CPDF_Object;
class CPDF_PageObject;
class CPDF_PageObjectHolder;
+class CPDF_Path;
class CPDF_PathObject;
class CPDF_TextObject;
@@ -37,6 +38,7 @@
friend class CPDF_PageContentGeneratorTest;
void ProcessPageObject(std::ostringstream* buf, CPDF_PageObject* pPageObj);
+ void ProcessPathPoints(std::ostringstream* buf, CPDF_Path* pPath);
void ProcessPath(std::ostringstream* buf, CPDF_PathObject* pPathObj);
void ProcessImage(std::ostringstream* buf, CPDF_ImageObject* pImageObj);
void ProcessGraphics(std::ostringstream* buf, CPDF_PageObject* pPageObj);