vcl/qa/cppunit/pdfexport/pdfexport.cxx | 12 +++++++-- vcl/source/gdi/pdfwriter_impl.cxx | 42 +++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 12 deletions(-)
New commits: commit d41c3c820dad7c78bc57815e0f4a6999d125561d Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Mon Mar 20 20:40:13 2023 +0100 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Wed Mar 22 11:55:55 2023 +0000 vcl: PDF/UA export: produce UF and Desc for embedded files 7.11 Embedded files The file specification dictionary for an embedded file shall contain the F and UF keys and should contain the Desc key (ISO 32000-1:2008, 7.11.3, Table 44.). Also write Alt text as hex/unicode string, not literal string. Change-Id: Id83597cc5ea645bd57c110514bafede433aee572 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149259 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx index 4304846c9834..448ba4ba24ed 100644 --- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx +++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx @@ -3610,13 +3610,19 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest, testMediaShapeAnnot) CPPUNIT_ASSERT(pR); auto pC = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pR->LookupElement("C")); CPPUNIT_ASSERT(pC); + auto pD = dynamic_cast<vcl::filter::PDFDictionaryElement*>(pC->LookupElement("D")); + CPPUNIT_ASSERT(pD); + auto pDesc = dynamic_cast<vcl::filter::PDFHexStringElement*>(pD->LookupElement("Desc")); + CPPUNIT_ASSERT(pDesc); + CPPUNIT_ASSERT_EQUAL(OUString("alternativloser text\nand some description"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(*pDesc)); auto pAlt = dynamic_cast<vcl::filter::PDFArrayElement*>(pC->LookupElement("Alt")); CPPUNIT_ASSERT(pAlt); auto pLang = dynamic_cast<vcl::filter::PDFLiteralStringElement*>(pAlt->GetElement(0)); CPPUNIT_ASSERT_EQUAL(OString(""), pLang->GetValue()); - auto pAltText = dynamic_cast<vcl::filter::PDFLiteralStringElement*>(pAlt->GetElement(1)); - CPPUNIT_ASSERT_EQUAL(OString("alternativloser text\\nand some description"), - pAltText->GetValue()); + auto pAltText = dynamic_cast<vcl::filter::PDFHexStringElement*>(pAlt->GetElement(1)); + CPPUNIT_ASSERT_EQUAL(OUString("alternativloser text\nand some description"), + ::vcl::filter::PDFDocument::DecodeHexStringUTF16BE(*pAltText)); auto pStructParent = dynamic_cast<vcl::filter::PDFNumberElement*>(pAnnot->Lookup("StructParent")); diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index f6776c1d560b..3fe6430fc000 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -3607,17 +3607,33 @@ bool PDFWriterImpl::emitScreenAnnotations() aLine.append("/C<</Type/MediaClip /S/MCD "); if (bEmbed) { - aLine.append("/D << /Type /Filespec /F (<embedded file>) /EF << /F "); + aLine.append("\n/D << /Type /Filespec /F (<embedded file>) "); + if (PDFWriter::PDFVersion::PDF_1_7 <= m_aContext.Version) + { // ISO 14289-1:2014, Clause: 7.11 + aLine.append("/UF (<embedded file>) "); + } + aLine.append("/EF << /F "); aLine.append(rScreen.m_nTempFileObject); - aLine.append(" 0 R >> >>"); + aLine.append(" 0 R >>"); } else { // Linked. - aLine.append("/D << /Type /Filespec /FS /URL /F "); + aLine.append("\n/D << /Type /Filespec /FS /URL /F "); appendLiteralStringEncrypt(rScreen.m_aURL, rScreen.m_nObject, aLine, osl_getThreadTextEncoding()); - aLine.append(" >>"); + if (PDFWriter::PDFVersion::PDF_1_7 <= m_aContext.Version) + { // ISO 14289-1:2014, Clause: 7.11 + aLine.append("/UF "); + appendUnicodeTextStringEncrypt(rScreen.m_aURL, rScreen.m_nObject, aLine); + } + } + if (PDFWriter::PDFVersion::PDF_1_6 <= m_aContext.Version + && !rScreen.m_AltText.isEmpty()) + { // ISO 14289-1:2014, Clause: 7.11 + aLine.append("/Desc "); + appendUnicodeTextStringEncrypt(rScreen.m_AltText, rScreen.m_nObject, aLine); } + aLine.append(" >>\n"); // end of /D // Allow playing the video via a tempfile. aLine.append("/P <</TF (TEMPACCESS)>>"); // ISO 14289-1:2014, Clause: 7.18.6.2 @@ -3626,7 +3642,7 @@ bool PDFWriterImpl::emitScreenAnnotations() // ISO 14289-1:2014, Clause: 7.18.6.2 // Alt text is a "Multi-language Text Array" aLine.append(" /Alt [ () "); - appendLiteralStringEncrypt(rScreen.m_AltText, rScreen.m_nObject, aLine, osl_getThreadTextEncoding()); + appendUnicodeTextStringEncrypt(rScreen.m_AltText, rScreen.m_nObject, aLine); aLine.append(" ] "); aLine.append(">>"); @@ -5207,9 +5223,12 @@ bool PDFWriterImpl::emitCatalog() aLine.append("/F<"); PDFWriter::AppendUnicodeTextString(rAttachedFile.maFilename, aLine); aLine.append("> "); - aLine.append("/UF<"); - PDFWriter::AppendUnicodeTextString(rAttachedFile.maFilename, aLine); - aLine.append("> "); + if (PDFWriter::PDFVersion::PDF_1_7 <= m_aContext.Version) + { + aLine.append("/UF<"); + PDFWriter::AppendUnicodeTextString(rAttachedFile.maFilename, aLine); + aLine.append("> "); + } if (!rAttachedFile.maDescription.isEmpty()) { aLine.append("/Desc <"); @@ -9249,7 +9268,12 @@ void PDFWriterImpl::writeReferenceXObject(const ReferenceXObjectEmit& rEmit) if (m_aContext.UseReferenceXObject && rEmit.m_nEmbeddedObject > 0) { // Write the reference dictionary. - aLine.append("/Ref<< /F << /Type /Filespec /F (<embedded file>) /EF << /F "); + aLine.append("/Ref<< /F << /Type /Filespec /F (<embedded file>) "); + if (PDFWriter::PDFVersion::PDF_1_7 <= m_aContext.Version) + { // ISO 14289-1:2014, Clause: 7.11 + aLine.append("/UF (<embedded file>) "); + } + aLine.append("/EF << /F "); aLine.append(rEmit.m_nEmbeddedObject); aLine.append(" 0 R >> >> /Page 0 >>\n"); }