filter/source/pdf/pdfexport.cxx                            |   17 +++
 include/vcl/pdfwriter.hxx                                  |   16 +++
 officecfg/registry/schema/org/openoffice/Office/Common.xcs |   15 +++
 vcl/inc/pdf/pdfwriter_impl.hxx                             |   11 +-
 vcl/source/gdi/pdfwriter_impl.cxx                          |   56 +++++++------
 5 files changed, 84 insertions(+), 31 deletions(-)

New commits:
commit 2c85b8083a78b65b7f608d1333678216329e746b
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Thu Oct 31 22:59:30 2024 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Nov 8 08:27:42 2024 +0100

    pdf: initial PDF 2.0 and PDF/A-4 support
    
    Added PDF 2.0 and PDF/A-4 version to enums. Write the PDF 2.0
    support for the file headers. Add the identical considitons as
    for the PDF/A-4 as they were for PDF/A-3.
    
    Change-Id: Iccf5afbf09c4cd0cd1ae7122c860e8cbefe3a6fd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175922
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx
index b0143fc243ed..f01a231292f4 100644
--- a/filter/source/pdf/pdfexport.cxx
+++ b/filter/source/pdf/pdfexport.cxx
@@ -743,21 +743,29 @@ bool PDFExport::Export( const OUString& rFile, const 
Sequence< PropertyValue >&
                 aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_7;
                 break;
             case 1:
-                aContext.Version    = vcl::PDFWriter::PDFVersion::PDF_A_1;
+                aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_1;
                 bUseTaggedPDF = true;           // force the tagged PDF as well
                 mbRemoveTransparencies = true;  // does not allow 
transparencies
                 bEncrypt = false;               // no encryption
                 xEnc.clear();
                 break;
             case 2:
-                aContext.Version    = vcl::PDFWriter::PDFVersion::PDF_A_2;
+                aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_2;
                 bUseTaggedPDF = true;           // force the tagged PDF as well
                 mbRemoveTransparencies = false; // does allow transparencies
                 bEncrypt = false;               // no encryption
                 xEnc.clear();
                 break;
             case 3:
-                aContext.Version    = vcl::PDFWriter::PDFVersion::PDF_A_3;
+                aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_3;
+                bUseTaggedPDF = true;           // force the tagged PDF as well
+                mbRemoveTransparencies = false; // does allow transparencies
+                bEncrypt = false;               // no encryption
+                xEnc.clear();
+                break;
+            case 4:
+                // TODO - determine what is allowed for PDFA/4
+                aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_4;
                 bUseTaggedPDF = true;           // force the tagged PDF as well
                 mbRemoveTransparencies = false; // does allow transparencies
                 bEncrypt = false;               // no encryption
@@ -772,6 +780,9 @@ bool PDFExport::Export( const OUString& rFile, const 
Sequence< PropertyValue >&
             case 17:
                 aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_7;
                 break;
+            case 20:
+                aContext.Version = vcl::PDFWriter::PDFVersion::PDF_2_0;
+                break;
             }
 
             // PDF/UA support
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index 37f8a4251f7b..7f041fda0716 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -100,8 +100,20 @@ public:
 
     enum class Orientation { Portrait, Inherit };
 
-    // in case the below enum is added PDF_2_0, please add just after PDF_1_7
-    enum class PDFVersion { PDF_1_4, PDF_1_5, PDF_1_6, PDF_1_7, PDF_A_1, 
PDF_A_2, PDF_A_3 };//i59651, PDF/A-1b & -1a, only -1b implemented for now
+
+    enum class PDFVersion
+    {
+        PDF_1_4,
+        PDF_1_5,
+        PDF_1_6,
+        PDF_1_7,
+        PDF_2_0,
+        PDF_A_1,
+        PDF_A_2,
+        PDF_A_3,
+        PDF_A_4, // Based on PDF 2.0
+    }; //i59651, PDF/A-1b & -1a, only -1b implemented for now
+
     // for the meaning of DestAreaType please look at PDF Reference Manual
     // version 1.4 section 8.2.1, page 475
     enum class DestAreaType { XYZ, FitRectangle };
diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
index aa8bca5cee00..14d538e1026d 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs
@@ -4999,6 +4999,11 @@
                   <desc>PDF 1.7</desc>
                 </info>
               </enumeration>
+              <enumeration oor:value="20">
+                <info>
+                  <desc>PDF 2.0</desc>
+                </info>
+              </enumeration>
               <enumeration oor:value="1">
                 <info>
                   <desc>PDF/A-1 (ISO 19005-1:2005)</desc>
@@ -5009,6 +5014,16 @@
                   <desc>PDF/A-2 (ISO 19005-2:2011)</desc>
                 </info>
               </enumeration>
+              <enumeration oor:value="3">
+                <info>
+                  <desc>PDF/A-3 (ISO 19005-3:2012)</desc>
+                </info>
+              </enumeration>
+              <enumeration oor:value="4">
+                <info>
+                  <desc>PDF/A-4 (ISO 19005-4)</desc>
+                </info>
+              </enumeration>
             </constraints>
             <value>0</value>
           </prop>
diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx
index c30956d0e1ee..525d600183b2 100644
--- a/vcl/inc/pdf/pdfwriter_impl.hxx
+++ b/vcl/inc/pdf/pdfwriter_impl.hxx
@@ -1072,14 +1072,17 @@ i12626
     void drawEmphasisMark(  tools::Long nX, tools::Long nY, const 
tools::PolyPolygon& rPolyPoly, bool bPolyLine, const tools::Rectangle& rRect1, 
const tools::Rectangle& rRect2 );
 
     /* true if PDF/A-1a or PDF/A-1b is output */
-    bool            m_bIsPDF_A1;
+    bool m_bIsPDF_A1 = false;
     /* true if PDF/A-2a is output */
-    bool            m_bIsPDF_A2;
+    bool m_bIsPDF_A2 = false;
+    /* true if PDF/A-3 is output */
+    bool m_bIsPDF_A3 = false;
+    /* true if PDF/A-4 is output */
+    bool m_bIsPDF_A4 = false;
 
     /* PDF/UA support enabled */
-    bool m_bIsPDF_UA;
+    bool m_bIsPDF_UA = false;
 
-    bool            m_bIsPDF_A3;
 
     PDFWriter&      m_rOuterFace;
 
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index de21ea9ab1d6..7a91cadd3ed1 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -641,6 +641,10 @@ const char* getPDFVersionStr(PDFWriter::PDFVersion 
ePDFVersion)
         case PDFWriter::PDFVersion::PDF_A_3:
         case PDFWriter::PDFVersion::PDF_1_7:
             return "1.7";
+        // PDF 2.0
+        case PDFWriter::PDFVersion::PDF_A_4:
+        case PDFWriter::PDFVersion::PDF_2_0:
+            return "2.0";
     }
 }
 
@@ -1250,10 +1254,6 @@ PDFWriterImpl::PDFWriterImpl( const 
PDFWriter::PDFWriterContext& rContext,
         m_nRC4KeyLength(0),
         m_bEncryptThisStream( false ),
         m_nAccessPermissions(0),
-        m_bIsPDF_A1( false ),
-        m_bIsPDF_A2( false ),
-        m_bIsPDF_UA( false ),
-        m_bIsPDF_A3( false ),
         m_rOuterFace( i_rOuterFace )
 {
     m_aStructure.emplace_back( );
@@ -1331,17 +1331,27 @@ PDFWriterImpl::PDFWriterImpl( const 
PDFWriter::PDFWriterContext& rContext,
     // insert outline root
     m_aOutline.emplace_back( );
 
-    m_bIsPDF_A1 = (m_aContext.Version == PDFWriter::PDFVersion::PDF_A_1);
-    if( m_bIsPDF_A1 )
-        m_aContext.Version = PDFWriter::PDFVersion::PDF_1_4; //meaning we need 
PDF 1.4, PDF/A flavour
-
-    m_bIsPDF_A2 = (m_aContext.Version == PDFWriter::PDFVersion::PDF_A_2);
-    if( m_bIsPDF_A2 )
-        m_aContext.Version = PDFWriter::PDFVersion::PDF_1_7;
-
-    m_bIsPDF_A3 = (m_aContext.Version == PDFWriter::PDFVersion::PDF_A_3);
-    if( m_bIsPDF_A3 )
-        m_aContext.Version = PDFWriter::PDFVersion::PDF_1_7;
+    switch (m_aContext.Version)
+    {
+        case PDFWriter::PDFVersion::PDF_A_1:
+            m_bIsPDF_A1 = true;
+            m_aContext.Version = PDFWriter::PDFVersion::PDF_1_4; //meaning we 
need PDF 1.4, PDF/A flavour
+            break;
+        case PDFWriter::PDFVersion::PDF_A_2:
+            m_bIsPDF_A2 = true;
+            m_aContext.Version = PDFWriter::PDFVersion::PDF_1_7;
+            break;
+        case PDFWriter::PDFVersion::PDF_A_3:
+            m_bIsPDF_A3 = true;
+            m_aContext.Version = PDFWriter::PDFVersion::PDF_1_7;
+            break;
+        case PDFWriter::PDFVersion::PDF_A_4:
+            m_bIsPDF_A4 = true;
+            m_aContext.Version = PDFWriter::PDFVersion::PDF_2_0;
+            break;
+        default:
+            break;
+    }
 
     if (m_aContext.UniversalAccessibilityCompliance)
     {
@@ -3698,7 +3708,7 @@ bool PDFWriterImpl::emitLinkAnnotations()
 // i59651: key /F set bits Print to 1 rest to 0. We don't set NoZoom NoRotate 
to 1, since it's a 'should'
 // see PDF 8.4.2 and ISO 19005-1:2005 6.5.3
         aLine.append( "<</Type/Annot" );
-        if( m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3)
+        if (m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3 || m_bIsPDF_A4)
             aLine.append( "/F 4" );
         aLine.append( "/Subtype/Link/Border[0 0 0]/Rect[" );
 
@@ -4043,7 +4053,7 @@ void PDFWriterImpl::emitTextAnnotationLine(OStringBuffer 
& aLine, PDFNoteEntry c
 
     // i59651: key /F set bits Print to 1 rest to 0. We don't set NoZoom 
NoRotate to 1, since it's a 'should'
     // see PDF 8.4.2 and ISO 19005-1:2005 6.5.3
-    if (m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3)
+    if (m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3 || m_bIsPDF_A4)
         aLine.append("/F 4 ");
 
     aLine.append("/Popup ");
@@ -4636,7 +4646,7 @@ bool PDFWriterImpl::emitAppearances( PDFWidget& rWidget, 
OStringBuffer& rAnnotDi
 
             // PDF/A requires sub-dicts for /FT/Btn objects (clause
             // 6.3.3)
-            if( m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3)
+            if( m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3 || m_bIsPDF_A4)
             {
                 if( rWidget.m_eType == PDFWriter::RadioButton ||
                     rWidget.m_eType == PDFWriter::CheckBox ||
@@ -5016,7 +5026,7 @@ bool PDFWriterImpl::emitWidgetAnnotations()
         }
         if( rWidget.m_eType == PDFWriter::PushButton )
         {
-            if(!m_bIsPDF_A1)
+            if (!m_bIsPDF_A1)
             {
                 OStringBuffer aDest;
                 if( rWidget.m_nDest != -1 && appendDest( 
m_aDestinationIdTranslation[ rWidget.m_nDest ], aDest ) )
@@ -5544,7 +5554,7 @@ bool PDFWriterImpl::emitCatalog()
         aLine.append( getResourceDictObj() );
         aLine.append( " 0 R" );
         // NeedAppearances must not be used if PDF is signed
-        if( m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3
+        if(m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3 || m_bIsPDF_A4
 #if HAVE_FEATURE_NSS
             || ( m_nSignatureObject != -1 )
 #endif
@@ -5856,7 +5866,7 @@ sal_Int32 PDFWriterImpl::emitNamedDestinations()
 // emits the output intent dictionary
 sal_Int32 PDFWriterImpl::emitOutputIntent()
 {
-    if( !m_bIsPDF_A1 && !m_bIsPDF_A2 && !m_bIsPDF_A3 )
+    if (!m_bIsPDF_A1 && !m_bIsPDF_A2 && !m_bIsPDF_A3 && !m_bIsPDF_A4)
         return 0;
 
     //emit the sRGB standard profile, in ICC format, in a stream, per 
IEC61966-2.1
@@ -5959,7 +5969,7 @@ static void lcl_assignMeta(const 
css::uno::Sequence<OUString>& rValues, std::vec
 // emits the document metadata
 sal_Int32 PDFWriterImpl::emitDocumentMetadata()
 {
-    if( !m_bIsPDF_A1 && !m_bIsPDF_A2 && !m_bIsPDF_A3 && !m_bIsPDF_UA)
+    if( !m_bIsPDF_A1 && !m_bIsPDF_A2 && !m_bIsPDF_A3 && !m_bIsPDF_A4 && 
!m_bIsPDF_UA)
         return 0;
 
     //get the object number for all the destinations
@@ -5975,6 +5985,8 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata()
             aMetadata.mnPDF_A = 2;
         else if (m_bIsPDF_A3)
             aMetadata.mnPDF_A = 3;
+        else if (m_bIsPDF_A4)
+            aMetadata.mnPDF_A = 4;
 
         aMetadata.mbPDF_UA = m_bIsPDF_UA;
 

Reply via email to