summaryrefslogtreecommitdiff
path: root/fpdfsdk
diff options
context:
space:
mode:
Diffstat (limited to 'fpdfsdk')
-rw-r--r--fpdfsdk/fpdfannot.cpp16
-rw-r--r--fpdfsdk/fpdfannot_embeddertest.cpp45
-rw-r--r--fpdfsdk/fpdfview_c_api_test.c1
3 files changed, 62 insertions, 0 deletions
diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp
index 5c4aae2075..ec748e66ec 100644
--- a/fpdfsdk/fpdfannot.cpp
+++ b/fpdfsdk/fpdfannot.cpp
@@ -727,6 +727,22 @@ FPDFAnnot_GetStringValue(FPDF_ANNOTATION annot,
buffer, buflen);
}
+FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV
+FPDFAnnot_GetLinkedAnnot(FPDF_ANNOTATION annot, FPDF_WIDESTRING key) {
+ CPDF_AnnotContext* pAnnot = CPDFAnnotContextFromFPDFAnnotation(annot);
+ if (!pAnnot || !pAnnot->GetAnnotDict())
+ return nullptr;
+
+ CPDF_Dictionary* pLinkedDict =
+ pAnnot->GetAnnotDict()->GetDictFor(CFXByteStringFromFPDFWideString(key));
+ if (!pLinkedDict || pLinkedDict->GetStringFor("Type") != "Annot")
+ return nullptr;
+
+ auto pLinkedAnnot = pdfium::MakeUnique<CPDF_AnnotContext>(
+ pLinkedDict, pAnnot->GetPage(), nullptr);
+ return pLinkedAnnot.release();
+}
+
FPDF_EXPORT int FPDF_CALLCONV FPDFAnnot_GetFlags(FPDF_ANNOTATION annot) {
if (!annot)
return FPDF_ANNOT_FLAG_NONE;
diff --git a/fpdfsdk/fpdfannot_embeddertest.cpp b/fpdfsdk/fpdfannot_embeddertest.cpp
index 4aca839226..47b71667b2 100644
--- a/fpdfsdk/fpdfannot_embeddertest.cpp
+++ b/fpdfsdk/fpdfannot_embeddertest.cpp
@@ -914,6 +914,51 @@ TEST_F(FPDFAnnotEmbeddertest, GetSetStringValue) {
CloseSaved();
}
+TEST_F(FPDFAnnotEmbeddertest, ExtractLinkedAnnotations) {
+ // Open a file with annotations and load its first page.
+ ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf"));
+ FPDF_PAGE page = FPDF_LoadPage(document(), 0);
+ ASSERT_TRUE(page);
+
+ // Retrieve the highlight annotation which has its popup defined.
+ FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0);
+ ASSERT_TRUE(annot);
+ EXPECT_EQ(FPDF_ANNOT_HIGHLIGHT, FPDFAnnot_GetSubtype(annot));
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> popup_key =
+ GetFPDFWideString(L"Popup");
+ ASSERT_TRUE(FPDFAnnot_HasKey(annot, popup_key.get()));
+ ASSERT_EQ(FPDF_OBJECT_REFERENCE,
+ FPDFAnnot_GetValueType(annot, popup_key.get()));
+
+ // Retrieve and verify the popup of the highlight annotation.
+ FPDF_ANNOTATION popup = FPDFAnnot_GetLinkedAnnot(annot, popup_key.get());
+ ASSERT_TRUE(popup);
+ EXPECT_EQ(FPDF_ANNOT_POPUP, FPDFAnnot_GetSubtype(popup));
+ FS_RECTF rect;
+ ASSERT_TRUE(FPDFAnnot_GetRect(popup, &rect));
+ EXPECT_NEAR(612.0f, rect.left, 0.001f);
+ EXPECT_NEAR(578.792, rect.bottom, 0.001f);
+
+ // Attempting to retrieve |annot|'s "IRT"-linked annotation would fail, since
+ // "IRT" is not a key in |annot|'s dictionary.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> irt_key =
+ GetFPDFWideString(L"IRT");
+ ASSERT_FALSE(FPDFAnnot_HasKey(annot, irt_key.get()));
+ EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot, irt_key.get()));
+
+ // Attempting to retrieve |annot|'s parent dictionary as an annotation would
+ // fail, since its parent is not an annotation.
+ std::unique_ptr<unsigned short, pdfium::FreeDeleter> p_key =
+ GetFPDFWideString(L"P");
+ ASSERT_TRUE(FPDFAnnot_HasKey(annot, p_key.get()));
+ EXPECT_EQ(FPDF_OBJECT_REFERENCE, FPDFAnnot_GetValueType(annot, p_key.get()));
+ EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot, p_key.get()));
+
+ FPDFPage_CloseAnnot(popup);
+ FPDFPage_CloseAnnot(annot);
+ UnloadPage(page);
+}
+
TEST_F(FPDFAnnotEmbeddertest, GetFormFieldFlagsTextField) {
// Open file with form text fields.
ASSERT_TRUE(OpenDocument("text_form_multiple.pdf"));
diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c
index 4dd4995cd2..b42dc160da 100644
--- a/fpdfsdk/fpdfview_c_api_test.c
+++ b/fpdfsdk/fpdfview_c_api_test.c
@@ -59,6 +59,7 @@ int CheckPDFiumCApi() {
CHK(FPDFAnnot_HasKey);
CHK(FPDFAnnot_SetStringValue);
CHK(FPDFAnnot_GetStringValue);
+ CHK(FPDFAnnot_GetLinkedAnnot);
CHK(FPDFAnnot_GetFlags);
CHK(FPDFAnnot_SetFlags);
CHK(FPDFAnnot_GetFormFieldFlags);