Add FPDFAnnot_GetLine() API
This is similar to FPDFAnnot_GetVertices() for polygon/polyline
annotations, but this one is for line annotations and the point list has
a fixed size of 2.
Change-Id: If910caaef8c41a9965f2ba47f87c34ea33355f99
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/76730
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/constants/annotation_common.h b/constants/annotation_common.h
index be64206..656842b 100644
--- a/constants/annotation_common.h
+++ b/constants/annotation_common.h
@@ -32,6 +32,9 @@
// Entries for ink annotations
constexpr char kInkList[] = "InkList";
+// Entries for line annotations
+constexpr char kL[] = "L";
+
} // namespace annotation
} // namespace pdfium
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 51b4332..85f86e5 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -887,6 +887,32 @@
return points_len;
}
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetLine(FPDF_ANNOTATION annot,
+ FS_POINTF* start,
+ FS_POINTF* end) {
+ if (!start || !end)
+ return false;
+
+ FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot);
+ if (subtype != FPDF_ANNOT_LINE)
+ return false;
+
+ CPDF_Dictionary* annot_dict = GetAnnotDictFromFPDFAnnotation(annot);
+ if (!annot_dict)
+ return false;
+
+ CPDF_Array* line = annot_dict->GetArrayFor(pdfium::annotation::kL);
+ if (!line || line->size() < 4)
+ return false;
+
+ start->x = line->GetNumberAt(0);
+ start->y = line->GetNumberAt(1);
+ end->x = line->GetNumberAt(2);
+ end->y = line->GetNumberAt(3);
+
+ return true;
+}
+
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_HasKey(FPDF_ANNOTATION annot,
FPDF_BYTESTRING key) {
CPDF_Dictionary* pAnnotDict = GetAnnotDictFromFPDFAnnotation(annot);
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 233f842..8a016b9 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -3377,3 +3377,48 @@
UnloadPage(page);
}
+
+TEST_F(FPDFAnnotEmbedderTest, LineAnnotation) {
+ ASSERT_TRUE(OpenDocument("line_annot.pdf"));
+ FPDF_PAGE page = LoadPage(0);
+ ASSERT_TRUE(page);
+ EXPECT_EQ(2, FPDFPage_GetAnnotCount(page));
+
+ {
+ ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
+ ASSERT_TRUE(annot);
+
+ // FPDFAnnot_GetVertices() positive testing.
+ FS_POINTF start;
+ FS_POINTF end;
+ ASSERT_TRUE(FPDFAnnot_GetLine(annot.get(), &start, &end));
+ EXPECT_FLOAT_EQ(159.0f, start.x);
+ EXPECT_FLOAT_EQ(296.0f, start.y);
+ EXPECT_FLOAT_EQ(472.0f, end.x);
+ EXPECT_FLOAT_EQ(243.42f, end.y);
+
+ // FPDFAnnot_GetVertices() negative testing.
+ EXPECT_FALSE(FPDFAnnot_GetLine(nullptr, nullptr, nullptr));
+ EXPECT_FALSE(FPDFAnnot_GetLine(annot.get(), nullptr, nullptr));
+ }
+
+ {
+ ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 1));
+ ASSERT_TRUE(annot);
+
+ // Too few elements in the line array.
+ FS_POINTF start;
+ FS_POINTF end;
+ EXPECT_FALSE(FPDFAnnot_GetLine(annot.get(), &start, &end));
+ }
+
+ {
+ // Wrong annotation type.
+ ScopedFPDFAnnotation ink_annot(FPDFPage_CreateAnnot(page, FPDF_ANNOT_INK));
+ FS_POINTF start;
+ FS_POINTF end;
+ EXPECT_FALSE(FPDFAnnot_GetLine(ink_annot.get(), &start, &end));
+ }
+
+ UnloadPage(page);
+}
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c
index b47b04f..ff511f4 100644
--- a/fpdfsdk/fpdf_view_c_api_test.c
+++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -61,6 +61,7 @@
CHK(FPDFAnnot_GetFormFieldValue);
CHK(FPDFAnnot_GetInkListCount);
CHK(FPDFAnnot_GetInkListPath);
+ CHK(FPDFAnnot_GetLine);
CHK(FPDFAnnot_GetLink);
CHK(FPDFAnnot_GetLinkedAnnot);
CHK(FPDFAnnot_GetNumberValue);
diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h
index d121344..6c8a237 100644
--- a/public/fpdf_annot.h
+++ b/public/fpdf_annot.h
@@ -440,6 +440,19 @@
unsigned long length);
// Experimental API.
+// Get the starting and ending coordinates of a line annotation.
+//
+// annot - handle to an annotation, as returned by e.g. FPDFPage_GetAnnot()
+// start - starting point
+// end - ending point
+//
+// Returns true if the annotation is of type line, |start| and |end| are not
+// NULL, false otherwise.
+FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetLine(FPDF_ANNOTATION annot,
+ FS_POINTF* start,
+ FS_POINTF* end);
+
+// Experimental API.
// Check if |annot|'s dictionary has |key| as a key.
//
// annot - handle to an annotation.
diff --git a/testing/resources/line_annot.in b/testing/resources/line_annot.in
new file mode 100644
index 0000000..f8aecf2
--- /dev/null
+++ b/testing/resources/line_annot.in
@@ -0,0 +1,48 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 1
+ /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [
+ 4 0 R 5 0 R
+ ]
+ /Tabs /R
+>>
+endobj
+{{object 4 0}} <<
+ /Type /Annot
+ /Subtype /Line
+ /NM (Line-1)
+ /F 4
+ /L [159 296 472 243.42]
+ /P 3 0 R
+ /C [1 0.90196 0]
+ /Rect [293 530 349 542]
+>>
+endobj
+{{object 5 0}} <<
+ /Type /Annot
+ /Subtype /Line
+ /NM (Line-2)
+ /F 4
+ /L [159 296 472]
+ /P 3 0 R
+ /C [1 0.90196 0]
+ /Rect [293 530 349 542]
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/line_annot.pdf b/testing/resources/line_annot.pdf
new file mode 100644
index 0000000..0511d4c
--- /dev/null
+++ b/testing/resources/line_annot.pdf
@@ -0,0 +1,60 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /Count 1
+ /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /Annots [
+ 4 0 R 5 0 R
+ ]
+ /Tabs /R
+>>
+endobj
+4 0 obj <<
+ /Type /Annot
+ /Subtype /Line
+ /NM (Line-1)
+ /F 4
+ /L [159 296 472 243.42]
+ /P 3 0 R
+ /C [1 0.90196 0]
+ /Rect [293 530 349 542]
+>>
+endobj
+5 0 obj <<
+ /Type /Annot
+ /Subtype /Line
+ /NM (Line-2)
+ /F 4
+ /L [159 296 472]
+ /P 3 0 R
+ /C [1 0.90196 0]
+ /Rect [293 530 349 542]
+>>
+endobj
+xref
+0 6
+0000000000 65535 f
+0000000015 00000 n
+0000000068 00000 n
+0000000131 00000 n
+0000000251 00000 n
+0000000408 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 6
+>>
+startxref
+558
+%%EOF