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