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");
     }

Reply via email to