include/vcl/filter/PDFiumLibrary.hxx | 2 include/vcl/pdf/PDFAnnotationMarker.hxx | 2 vcl/qa/cppunit/PDFiumLibraryTest.cxx | 58 +++++++++++++++++++++ vcl/qa/cppunit/data/Annotations_Adobe_FreeText.pdf |binary vcl/source/filter/ipdf/pdfread.cxx | 10 +++ vcl/source/pdf/PDFiumLibrary.cxx | 30 ++++++++++ 6 files changed, 102 insertions(+)
New commits: commit ad5e3b9b509a455b481a9e6bdf4902dbf60c305a Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Thu Jun 13 22:03:37 2024 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Fri Jun 14 06:27:16 2024 +0200 annot: make sure the annotation subtypes in PDFium match with ours Change-Id: Ic18f394b532118f39988a650d046880b049c9ec3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168810 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx index 4c3872979d1d..ffdc94adcf29 100644 --- a/vcl/source/pdf/PDFiumLibrary.cxx +++ b/vcl/source/pdf/PDFiumLibrary.cxx @@ -170,6 +170,36 @@ static_assert(static_cast<int>(vcl::pdf::PDFAnnotAActionType::Calculate) == FPDF_ANNOT_AACTION_CALCULATE, "PDFAnnotAActionType::Calculate) value mismatch"); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Unknown) == FPDF_ANNOT_UNKNOWN); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Text) == FPDF_ANNOT_TEXT); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Link) == FPDF_ANNOT_LINK); +static_assert(int(vcl::pdf::PDFAnnotationSubType::FreeText) == FPDF_ANNOT_FREETEXT); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Line) == FPDF_ANNOT_LINE); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Square) == FPDF_ANNOT_SQUARE); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Circle) == FPDF_ANNOT_CIRCLE); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Polygon) == FPDF_ANNOT_POLYGON); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Polyline) == FPDF_ANNOT_POLYLINE); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Highlight) == FPDF_ANNOT_HIGHLIGHT); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Underline) == FPDF_ANNOT_UNDERLINE); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Squiggly) == FPDF_ANNOT_SQUIGGLY); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Strikeout) == FPDF_ANNOT_STRIKEOUT); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Stamp) == FPDF_ANNOT_STAMP); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Caret) == FPDF_ANNOT_CARET); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Ink) == FPDF_ANNOT_INK); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Popup) == FPDF_ANNOT_POPUP); +static_assert(int(vcl::pdf::PDFAnnotationSubType::FileAttachment) == FPDF_ANNOT_FILEATTACHMENT); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Sound) == FPDF_ANNOT_SOUND); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Movie) == FPDF_ANNOT_MOVIE); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Widget) == FPDF_ANNOT_WIDGET); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Screen) == FPDF_ANNOT_SCREEN); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Printermark) == FPDF_ANNOT_PRINTERMARK); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Trapnet) == FPDF_ANNOT_TRAPNET); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Watermark) == FPDF_ANNOT_WATERMARK); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Threed) == FPDF_ANNOT_THREED); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Richmedia) == FPDF_ANNOT_RICHMEDIA); +static_assert(int(vcl::pdf::PDFAnnotationSubType::XFAWidget) == FPDF_ANNOT_XFAWIDGET); +static_assert(int(vcl::pdf::PDFAnnotationSubType::Redact) == FPDF_ANNOT_REDACT); + namespace { /// Callback class to be used with FPDF_SaveWithVersion(). commit 647642468d42aba2e259d85d068652756d5aa20c Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Thu Jun 13 20:53:56 2024 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Fri Jun 14 06:27:03 2024 +0200 annot: read PDF FreeText annotation "DS" and "RC" keys DS (DefaultStyle) and RC (RichContent") contain xhtml, css3 rich text content for the text presented by the FreeText annotation in the document. This adds reading of those 2 things to the PDFium library, PDFium based import and the PDFAnnotationFreeTextMarker class. Change-Id: I32f89640611c730c8a1a8d1a2107e2e11669ec18 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168787 Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> Tested-by: Jenkins diff --git a/include/vcl/filter/PDFiumLibrary.hxx b/include/vcl/filter/PDFiumLibrary.hxx index d90da7286020..e008a502be58 100644 --- a/include/vcl/filter/PDFiumLibrary.hxx +++ b/include/vcl/filter/PDFiumLibrary.hxx @@ -46,6 +46,8 @@ inline constexpr OString constDictionaryKeyContents = "Contents"_ostr; inline constexpr OString constDictionaryKeyPopup = "Popup"_ostr; inline constexpr OString constDictionaryKeyModificationDate = "M"_ostr; inline constexpr OString constDictionaryKeyInteriorColor = "IC"_ostr; +inline constexpr OString constDictionaryKey_DefaultStyle = "DS"_ostr; +inline constexpr OString constDictionaryKey_RichContent = "RC"_ostr; class PDFiumBitmap; class PDFiumDocument; diff --git a/include/vcl/pdf/PDFAnnotationMarker.hxx b/include/vcl/pdf/PDFAnnotationMarker.hxx index d1217c65c3af..0c559a4cedae 100644 --- a/include/vcl/pdf/PDFAnnotationMarker.hxx +++ b/include/vcl/pdf/PDFAnnotationMarker.hxx @@ -37,6 +37,8 @@ struct VCL_DLLPUBLIC PDFAnnotationMarkerStamp : public PDFAnnotationMarker /** Free text annotation marker - showing text of the annotation in the document */ struct VCL_DLLPUBLIC PDFAnnotationMarkerFreeText : public PDFAnnotationMarker { + OUString maDefaultStyle; + OUString maRichContent; }; struct VCL_DLLPUBLIC PDFAnnotationMarkerCircle : public PDFAnnotationMarker diff --git a/vcl/qa/cppunit/PDFiumLibraryTest.cxx b/vcl/qa/cppunit/PDFiumLibraryTest.cxx index d11c66bae323..df65a6450ca0 100644 --- a/vcl/qa/cppunit/PDFiumLibraryTest.cxx +++ b/vcl/qa/cppunit/PDFiumLibraryTest.cxx @@ -412,6 +412,64 @@ CPPUNIT_TEST_FIXTURE(PDFiumLibraryTest, testAnnotationsDifferentTypes) } } +CPPUNIT_TEST_FIXTURE(PDFiumLibraryTest, testAnnotationsFreeText) +{ + OUString aURL = getFullUrl(u"Annotations_Adobe_FreeText.pdf"); + SvFileStream aStream(aURL, StreamMode::READ); + + std::vector<vcl::PDFGraphicResult> aResults; + CPPUNIT_ASSERT_EQUAL(size_t(1), vcl::ImportPDFUnloaded(aURL, aResults)); + + vcl::PDFGraphicResult& rResult = aResults[0]; + + Graphic aGraphic = rResult.GetGraphic(); + aGraphic.makeAvailable(); + + OUString aDefaultStyle; + OUString aRichContent; + + { + auto pVectorGraphicData = aGraphic.getVectorGraphicData(); + CPPUNIT_ASSERT(pVectorGraphicData); + CPPUNIT_ASSERT_EQUAL(VectorGraphicDataType::Pdf, pVectorGraphicData->getType()); + + auto& rDataContainer = pVectorGraphicData->getBinaryDataContainer(); + + auto pPdfium = vcl::pdf::PDFiumLibrary::get(); + auto pDocument + = pPdfium->openDocument(rDataContainer.getData(), rDataContainer.getSize(), OString()); + CPPUNIT_ASSERT(pDocument); + + CPPUNIT_ASSERT_EQUAL(1, pDocument->getPageCount()); + + auto pPage = pDocument->openPage(0); + CPPUNIT_ASSERT(pPage); + + CPPUNIT_ASSERT_EQUAL(1, pPage->getAnnotationCount()); + + auto pAnnotation = pPage->getAnnotation(0); + CPPUNIT_ASSERT(pAnnotation); + CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::FreeText, pAnnotation->getSubType()); + + aDefaultStyle = pAnnotation->getString(vcl::pdf::constDictionaryKey_DefaultStyle); + CPPUNIT_ASSERT_EQUAL(false, aDefaultStyle.isEmpty()); + + aRichContent = pAnnotation->getString(vcl::pdf::constDictionaryKey_RichContent); + CPPUNIT_ASSERT_EQUAL(false, aRichContent.isEmpty()); + } + + auto const& rAnnotations = rResult.GetAnnotations(); + CPPUNIT_ASSERT_EQUAL(size_t(1), rAnnotations.size()); + + CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::FreeText, rAnnotations[0].meSubType); + + auto* pMarker + = static_cast<vcl::pdf::PDFAnnotationMarkerFreeText*>(rAnnotations[0].mpMarker.get()); + + CPPUNIT_ASSERT_EQUAL(aDefaultStyle, pMarker->maDefaultStyle); + CPPUNIT_ASSERT_EQUAL(aRichContent, pMarker->maRichContent); +} + CPPUNIT_TEST_FIXTURE(PDFiumLibraryTest, testTools) { OUString sConverted = vcl::pdf::convertPdfDateToISO8601(u"D:20200612201322+02'00"); diff --git a/vcl/qa/cppunit/data/Annotations_Adobe_FreeText.pdf b/vcl/qa/cppunit/data/Annotations_Adobe_FreeText.pdf new file mode 100755 index 000000000000..32cb3a6cbc31 Binary files /dev/null and b/vcl/qa/cppunit/data/Annotations_Adobe_FreeText.pdf differ diff --git a/vcl/source/filter/ipdf/pdfread.cxx b/vcl/source/filter/ipdf/pdfread.cxx index c7cf5794dffa..c60e8bb4a792 100644 --- a/vcl/source/filter/ipdf/pdfread.cxx +++ b/vcl/source/filter/ipdf/pdfread.cxx @@ -329,6 +329,16 @@ findAnnotations(const std::unique_ptr<vcl::pdf::PDFiumPage>& pPage, basegfx::B2D { auto pMarker = std::make_shared<vcl::pdf::PDFAnnotationMarkerFreeText>(); rPDFGraphicAnnotation.mpMarker = pMarker; + if (pAnnotation->hasKey(vcl::pdf::constDictionaryKey_DefaultStyle)) + { + pMarker->maDefaultStyle + = pAnnotation->getString(vcl::pdf::constDictionaryKey_DefaultStyle); + } + if (pAnnotation->hasKey(vcl::pdf::constDictionaryKey_RichContent)) + { + pMarker->maRichContent + = pAnnotation->getString(vcl::pdf::constDictionaryKey_RichContent); + } } else if (eSubtype == vcl::pdf::PDFAnnotationSubType::Stamp) {