diff options
-rw-r--r-- | fpdfsdk/fpdfannot.cpp | 16 | ||||
-rw-r--r-- | fpdfsdk/fpdfannot_embeddertest.cpp | 45 | ||||
-rw-r--r-- | fpdfsdk/fpdfview_c_api_test.c | 1 | ||||
-rw-r--r-- | public/fpdf_annot.h | 13 |
4 files changed, 75 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); diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h index 6cd06dd9db..6a89ff9384 100644 --- a/public/fpdf_annot.h +++ b/public/fpdf_annot.h @@ -385,6 +385,19 @@ FPDFAnnot_GetStringValue(FPDF_ANNOTATION annot, unsigned long buflen); // Experimental API. +// Get the annotation corresponding to |key| in |annot|'s dictionary. Common +// keys for linking annotations include "IRT" and "Popup". Must call +// FPDFPage_CloseAnnot() when the annotation returned by this function is no +// longer needed. +// +// annot - handle to an annotation. +// key - the key to the requested dictionary entry. +// +// Returns a handle to the linked annotation object, or NULL on failure. +FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV +FPDFAnnot_GetLinkedAnnot(FPDF_ANNOTATION annot, FPDF_WIDESTRING key); + +// Experimental API. // Get the annotation flags of |annot|. // // annot - handle to an annotation. |