summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-09-20 22:52:43 +0200
committerChromium commit bot <commit-bot@chromium.org>2017-09-20 21:04:08 +0000
commit36eed87d19e741be9909500c45dd12e50ff6a1ab (patch)
tree7311bbf0ba29245308ca79b34acb22086d6cbdd0
parent0c2e705f8d8dec68c1afc8344872fe8bee527c48 (diff)
downloadpdfium-36eed87d19e741be9909500c45dd12e50ff6a1ab.tar.xz
Add FPDFPath_GetPoint() APIchromium/3221
Combined with the previously added FPDFPath_CountPoint(), this allows getting the coordinates of all points of a path. Change-Id: Ic969723d4b01ee427498d38ce323c74147b87a9c Reviewed-on: https://pdfium-review.googlesource.com/14111 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: dsinclair <dsinclair@chromium.org>
-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
-rw-r--r--public/fpdf_edit.h46
-rw-r--r--public/fpdfview.h1
7 files changed, 173 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);
diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h
index 9ee11cb5ec..d73a740efd 100644
--- a/public/fpdf_edit.h
+++ b/public/fpdf_edit.h
@@ -42,6 +42,12 @@
#define FPDF_PAGEOBJ_SHADING 4
#define FPDF_PAGEOBJ_FORM 5
+// The path segment constants.
+#define FPDF_SEGMENT_UNKNOWN -1
+#define FPDF_SEGMENT_LINETO 0
+#define FPDF_SEGMENT_BEZIERTO 1
+#define FPDF_SEGMENT_MOVETO 2
+
#define FPDF_FILLMODE_ALTERNATE 1
#define FPDF_FILLMODE_WINDING 2
@@ -552,6 +558,7 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_GetFillColor(FPDF_PAGEOBJECT path,
unsigned int* B,
unsigned int* A);
+// Experimental API.
// Get number of point objects inside |path|.
//
// path - handle to a path.
@@ -562,6 +569,45 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPath_GetFillColor(FPDF_PAGEOBJECT path,
// Returns the number of objects in |path| or -1 on failure.
FPDF_EXPORT int FPDF_CALLCONV FPDFPath_CountPoint(FPDF_PAGEOBJECT path);
+// Experimental API.
+// Get segment in |path| at |index|.
+//
+// path - handle to a path.
+// index - the index of a segment.
+//
+// Returns the handle to the segment, or NULL on faiure.
+FPDF_EXPORT FPDF_PATHSEGMENT FPDF_CALLCONV
+FPDFPath_GetPathSegment(FPDF_PAGEOBJECT path, int index);
+
+// Experimental API.
+// Get coordinates of |segment|.
+//
+// segment - handle to a segment.
+// x - the horizontal position of the segment.
+// y - the vertical position of the segment.
+//
+// Returns TRUE on success, otherwise |x| and |y| is not set.
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFPathSegment_GetPoint(FPDF_PATHSEGMENT segment, float* x, float* y);
+
+// Experimental API.
+// Get type of |segment|.
+//
+// segment - handle to a segment.
+//
+// Returns one of the FPDF_SEGMENT_* values on success,
+// FPDF_SEGMENT_UNKNOWN on error.
+FPDF_EXPORT int FPDF_CALLCONV FPDFPathSegment_GetType(FPDF_PATHSEGMENT segment);
+
+// Experimental API.
+// Gets if the |segment| closes the current subpath of a given path.
+//
+// segment - handle to a segment.
+//
+// Returns close flag for non-NULL segment, FALSE otherwise.
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
+FPDFPathSegment_GetClose(FPDF_PATHSEGMENT segment);
+
// Move a path's current point.
//
// path - the handle to the path object.
diff --git a/public/fpdfview.h b/public/fpdfview.h
index 135d00a8f4..3f180335d3 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -52,6 +52,7 @@ typedef void* FPDF_SCHHANDLE;
typedef void* FPDF_STRUCTELEMENT;
typedef void* FPDF_STRUCTTREE;
typedef void* FPDF_TEXTPAGE;
+typedef void const* FPDF_PATHSEGMENT;
#ifdef PDF_ENABLE_XFA
typedef void* FPDF_STRINGHANDLE;