summaryrefslogtreecommitdiff
path: root/fpdfsdk
diff options
context:
space:
mode:
Diffstat (limited to 'fpdfsdk')
-rw-r--r--fpdfsdk/fpdfedit_embeddertest.cpp69
-rw-r--r--fpdfsdk/fpdfeditpath.cpp46
-rw-r--r--fpdfsdk/fpdfview.cpp4
-rw-r--r--fpdfsdk/fpdfview_c_api_test.c4
-rw-r--r--fpdfsdk/fsdk_define.h3
5 files changed, 126 insertions, 0 deletions
diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp
index ca2a457147..6826317ef2 100644
--- a/fpdfsdk/fpdfedit_embeddertest.cpp
+++ b/fpdfsdk/fpdfedit_embeddertest.cpp
@@ -259,6 +259,39 @@ TEST_F(FPDFEditEmbeddertest, AddPaths) {
// Make sure the path has 5 points (1 FXPT_TYPE::MoveTo and 4
// FXPT_TYPE::LineTo).
ASSERT_EQ(5, FPDFPath_CountPoint(green_rect));
+ // Verify actual coordinates.
+ FPDF_PATHSEGMENT segment = FPDFPath_GetPathSegment(green_rect, 0);
+ float x;
+ float y;
+ EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+ EXPECT_EQ(100, x);
+ EXPECT_EQ(100, y);
+ EXPECT_EQ(FPDF_SEGMENT_MOVETO, FPDFPathSegment_GetType(segment));
+ EXPECT_FALSE(FPDFPathSegment_GetClose(segment));
+ segment = FPDFPath_GetPathSegment(green_rect, 1);
+ EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+ EXPECT_EQ(100, x);
+ EXPECT_EQ(140, y);
+ EXPECT_EQ(FPDF_SEGMENT_LINETO, FPDFPathSegment_GetType(segment));
+ EXPECT_FALSE(FPDFPathSegment_GetClose(segment));
+ segment = FPDFPath_GetPathSegment(green_rect, 2);
+ EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+ EXPECT_EQ(140, x);
+ EXPECT_EQ(140, y);
+ EXPECT_EQ(FPDF_SEGMENT_LINETO, FPDFPathSegment_GetType(segment));
+ EXPECT_FALSE(FPDFPathSegment_GetClose(segment));
+ segment = FPDFPath_GetPathSegment(green_rect, 3);
+ EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+ EXPECT_EQ(140, x);
+ EXPECT_EQ(100, y);
+ EXPECT_EQ(FPDF_SEGMENT_LINETO, FPDFPathSegment_GetType(segment));
+ EXPECT_FALSE(FPDFPathSegment_GetClose(segment));
+ segment = FPDFPath_GetPathSegment(green_rect, 4);
+ EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+ EXPECT_EQ(100, x);
+ EXPECT_EQ(100, y);
+ EXPECT_EQ(FPDF_SEGMENT_LINETO, FPDFPathSegment_GetType(segment));
+ EXPECT_TRUE(FPDFPathSegment_GetClose(segment));
EXPECT_TRUE(FPDFPath_SetDrawMode(green_rect, FPDF_FILLMODE_WINDING, 0));
FPDFPage_InsertObject(page, green_rect);
@@ -277,6 +310,27 @@ TEST_F(FPDFEditEmbeddertest, AddPaths) {
// Make sure the path has 3 points (1 FXPT_TYPE::MoveTo and 2
// FXPT_TYPE::LineTo).
ASSERT_EQ(3, FPDFPath_CountPoint(black_path));
+ // Verify actual coordinates.
+ segment = FPDFPath_GetPathSegment(black_path, 0);
+ EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+ EXPECT_EQ(400, x);
+ EXPECT_EQ(100, y);
+ EXPECT_EQ(FPDF_SEGMENT_MOVETO, FPDFPathSegment_GetType(segment));
+ EXPECT_FALSE(FPDFPathSegment_GetClose(segment));
+ segment = FPDFPath_GetPathSegment(black_path, 1);
+ EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+ EXPECT_EQ(400, x);
+ EXPECT_EQ(200, y);
+ EXPECT_EQ(FPDF_SEGMENT_LINETO, FPDFPathSegment_GetType(segment));
+ EXPECT_FALSE(FPDFPathSegment_GetClose(segment));
+ segment = FPDFPath_GetPathSegment(black_path, 2);
+ EXPECT_TRUE(FPDFPathSegment_GetPoint(segment, &x, &y));
+ EXPECT_EQ(300, x);
+ EXPECT_EQ(100, y);
+ EXPECT_EQ(FPDF_SEGMENT_LINETO, FPDFPathSegment_GetType(segment));
+ EXPECT_TRUE(FPDFPathSegment_GetClose(segment));
+ // Make sure out of bounds index access fails properly.
+ EXPECT_EQ(nullptr, FPDFPath_GetPathSegment(black_path, 3));
FPDFPage_InsertObject(page, black_path);
page_bitmap = RenderPage(page);
@@ -317,6 +371,21 @@ TEST_F(FPDFEditEmbeddertest, PathsPoints) {
// This should fail gracefully, even if path is NULL.
ASSERT_EQ(-1, FPDFPath_CountPoint(nullptr));
+ // FPDFPath_GetPathSegment() with a non-path.
+ ASSERT_EQ(nullptr, FPDFPath_GetPathSegment(img, 0));
+ // FPDFPath_GetPathSegment() with a NULL path.
+ ASSERT_EQ(nullptr, FPDFPath_GetPathSegment(nullptr, 0));
+ float x;
+ float y;
+ // FPDFPathSegment_GetPoint() with a NULL segment.
+ EXPECT_FALSE(FPDFPathSegment_GetPoint(nullptr, &x, &y));
+
+ // FPDFPathSegment_GetType() with a NULL segment.
+ ASSERT_EQ(FPDF_SEGMENT_UNKNOWN, FPDFPathSegment_GetType(nullptr));
+
+ // FPDFPathSegment_GetClose() with a NULL segment.
+ EXPECT_FALSE(FPDFPathSegment_GetClose(nullptr));
+
FPDFPageObj_Destroy(img);
}
diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp
index 164ab7015f..a91dfdb421 100644
--- a/fpdfsdk/fpdfeditpath.cpp
+++ b/fpdfsdk/fpdfeditpath.cpp
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <vector>
+
#include "public/fpdf_edit.h"
#include "core/fpdfapi/page/cpdf_path.h"
@@ -26,6 +28,13 @@ static_assert(CFX_GraphStateData::LineJoinRound == FPDF_LINEJOIN_ROUND,
static_assert(CFX_GraphStateData::LineJoinBevel == FPDF_LINEJOIN_BEVEL,
"CFX_GraphStateData::LineJoinBevel value mismatch");
+static_assert(static_cast<int>(FXPT_TYPE::LineTo) == FPDF_SEGMENT_LINETO,
+ "FXPT_TYPE::LineTo value mismatch");
+static_assert(static_cast<int>(FXPT_TYPE::BezierTo) == FPDF_SEGMENT_BEZIERTO,
+ "FXPT_TYPE::BezierTo value mismatch");
+static_assert(static_cast<int>(FXPT_TYPE::MoveTo) == FPDF_SEGMENT_MOVETO,
+ "FXPT_TYPE::MoveTo value mismatch");
+
FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV FPDFPageObj_CreateNewPath(float x,
float y) {
auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>();
@@ -125,6 +134,16 @@ FPDF_EXPORT int FPDF_CALLCONV FPDFPath_CountPoint(FPDF_PAGEOBJECT path) {
return pdfium::CollectionSize<int>(pPathObj->m_Path.GetPoints());
}
+FPDF_EXPORT FPDF_PATHSEGMENT FPDF_CALLCONV
+FPDFPath_GetPathSegment(FPDF_PAGEOBJECT path, int index) {
+ auto* pPathObj = CPDFPathObjectFromFPDFPageObject(path);
+ if (!pPathObj)
+ return nullptr;
+
+ const std::vector<FX_PATHPOINT>& points = pPathObj->m_Path.GetPoints();
+ return pdfium::IndexInBounds(points, index) ? &points[index] : nullptr;
+}
+
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_MoveTo(FPDF_PAGEOBJECT path,
float x,
float y) {
@@ -229,3 +248,30 @@ FPDF_EXPORT void FPDF_CALLCONV FPDFPath_SetLineCap(FPDF_PAGEOBJECT path,
pPathObj->m_GraphState.SetLineCap(lineCap);
pPathObj->SetDirty(true);
}
+
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFPathSegment_GetPoint(FPDF_PATHSEGMENT segment, float* x, float* y) {
+ auto* pPathPoint = FXPathPointFromFPDFPathSegment(segment);
+ if (!pPathPoint || !x || !y)
+ return false;
+
+ *x = pPathPoint->m_Point.x;
+ *y = pPathPoint->m_Point.y;
+
+ return true;
+}
+
+FPDF_EXPORT int FPDF_CALLCONV
+FPDFPathSegment_GetType(FPDF_PATHSEGMENT segment) {
+ auto* pPathPoint = FXPathPointFromFPDFPathSegment(segment);
+
+ return pPathPoint ? static_cast<int>(pPathPoint->m_Type)
+ : FPDF_SEGMENT_UNKNOWN;
+}
+
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFPathSegment_GetClose(FPDF_PATHSEGMENT segment) {
+ auto* pPathPoint = FXPathPointFromFPDFPathSegment(segment);
+
+ return pPathPoint ? pPathPoint->m_CloseFigure : false;
+}
diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp
index 9e9c31ddc9..c52c598783 100644
--- a/fpdfsdk/fpdfview.cpp
+++ b/fpdfsdk/fpdfview.cpp
@@ -357,6 +357,10 @@ CFX_DIBitmap* CFXBitmapFromFPDFBitmap(FPDF_BITMAP bitmap) {
return static_cast<CFX_DIBitmap*>(bitmap);
}
+const FX_PATHPOINT* FXPathPointFromFPDFPathSegment(FPDF_PATHSEGMENT segment) {
+ return static_cast<const FX_PATHPOINT*>(segment);
+}
+
unsigned long Utf16EncodeMaybeCopyAndReturnLength(const WideString& text,
void* buffer,
unsigned long buflen) {
diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c
index 415543dbe2..b3fe303eac 100644
--- a/fpdfsdk/fpdfview_c_api_test.c
+++ b/fpdfsdk/fpdfview_c_api_test.c
@@ -149,6 +149,10 @@ int CheckPDFiumCApi() {
CHK(FPDFPath_SetFillColor);
CHK(FPDFPath_GetFillColor);
CHK(FPDFPath_CountPoint);
+ CHK(FPDFPath_GetPathSegment);
+ CHK(FPDFPathSegment_GetPoint);
+ CHK(FPDFPathSegment_GetType);
+ CHK(FPDFPathSegment_GetClose);
CHK(FPDFPath_MoveTo);
CHK(FPDFPath_LineTo);
CHK(FPDFPath_BezierTo);
diff --git a/fpdfsdk/fsdk_define.h b/fpdfsdk/fsdk_define.h
index e58ddb1a49..68ba585c0a 100644
--- a/fpdfsdk/fsdk_define.h
+++ b/fpdfsdk/fsdk_define.h
@@ -28,6 +28,7 @@ class CPDF_PageRenderContext;
class CPDF_PathObject;
class CPDF_Stream;
class IFSDK_PAUSE_Adapter;
+class FX_PATHPOINT;
// Layering prevents fxcrt from knowing about FPDF_FILEACCESS, so this can't
// be a static method of IFX_SeekableReadStream.
@@ -74,6 +75,8 @@ ByteString CFXByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string);
CFX_DIBitmap* CFXBitmapFromFPDFBitmap(FPDF_BITMAP bitmap);
+const FX_PATHPOINT* FXPathPointFromFPDFPathSegment(FPDF_PATHSEGMENT segment);
+
unsigned long Utf16EncodeMaybeCopyAndReturnLength(const WideString& text,
void* buffer,
unsigned long buflen);