filter/source/pdf/impdialog.cxx | 30 +++++++++++------------ filter/source/pdf/impdialog.hxx | 4 +-- filter/source/pdf/pdfexport.cxx | 7 +++++ filter/uiconfig/ui/pdfgeneralpage.ui | 4 +-- include/vcl/pdfwriter.hxx | 2 - vcl/source/gdi/pdfwriter_impl.cxx | 45 ++++++++++++++++++++++++----------- vcl/source/gdi/pdfwriter_impl.hxx | 2 + 7 files changed, 60 insertions(+), 34 deletions(-)
New commits: commit eee7b87e3b39cf2c112ece7cc96ab39f613836ab Author: Thorsten Behrens <thorsten.behr...@cib.de> AuthorDate: Tue Jan 15 01:24:54 2019 +0100 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Mon Mar 11 04:10:07 2019 +0100 Export PDF/A as 2b * replace export dialog option with 2b (from 1b) * keep A-1 support for UNO * add new SelectPdfVersion filter config param value of '2' Change-Id: Ia7eca732ef3d018dd5bb1bda79876400d6d03a02 diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx index fc75951aeb42..372505851e33 100644 --- a/filter/source/pdf/impdialog.cxx +++ b/filter/source/pdf/impdialog.cxx @@ -462,7 +462,7 @@ ImpPDFTabGeneralPage::ImpPDFTabGeneralPage(TabPageParent pParent, const SfxItemS , mxNfQuality(m_xBuilder->weld_metric_spin_button("quality", FUNIT_PERCENT)) , mxCbReduceImageResolution(m_xBuilder->weld_check_button("reduceresolution")) , mxCoReduceImageResolution(m_xBuilder->weld_combo_box_text("resolution")) - , mxCbPDFA1b(m_xBuilder->weld_check_button("pdfa")) + , mxCbPDFA2b(m_xBuilder->weld_check_button("pdfa")) , mxCbTaggedPDF(m_xBuilder->weld_check_button("tagged")) , mxCbExportFormFields(m_xBuilder->weld_check_button("forms")) , mxFormsFrame(m_xBuilder->weld_widget("formsframe")) @@ -530,16 +530,16 @@ void ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent) mxCbWatermark->connect_toggled( LINK( this, ImpPDFTabGeneralPage, ToggleWatermarkHdl ) ); mxFtWatermark->set_sensitive(false ); mxEdWatermark->set_sensitive( false ); - mxCbPDFA1b->connect_toggled(LINK(this, ImpPDFTabGeneralPage, ToggleExportPDFAHdl)); + mxCbPDFA2b->connect_toggled(LINK(this, ImpPDFTabGeneralPage, ToggleExportPDFAHdl)); switch( pParent->mnPDFTypeSelection ) { default: - case 0: mxCbPDFA1b->set_active( false ); // PDF 1.5 + mxCbPDFA2b->set_active( false ); // PDF 1.5 break; - case 1: mxCbPDFA1b->set_active(true); // PDF/A-1a + case 2: mxCbPDFA2b->set_active(true); // PDF/A-2a break; } - ToggleExportPDFAHdl( *mxCbPDFA1b ); + ToggleExportPDFAHdl( *mxCbPDFA2b ); mxCbExportFormFields->connect_toggled( LINK( this, ImpPDFTabGeneralPage, ToggleExportFormFieldsHdl ) ); @@ -547,7 +547,7 @@ void ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent) mbTaggedPDFUserSelection = pParent->mbUseTaggedPDF; mbExportFormFieldsUserSelection = pParent->mbExportFormFields; - if( !mxCbPDFA1b->get_active() ) + if( !mxCbPDFA2b->get_active() ) { // the value for PDF/A set by the ToggleExportPDFAHdl method called before mxCbTaggedPDF->set_active( mbTaggedPDFUserSelection ); @@ -643,9 +643,9 @@ void ImpPDFTabGeneralPage::GetFilterConfigItem( ImpPDFTabDialog* pParent ) } pParent->mnPDFTypeSelection = 0; - if( mxCbPDFA1b->get_active() ) + if( mxCbPDFA2b->get_active() ) { - pParent->mnPDFTypeSelection = 1; + pParent->mnPDFTypeSelection = 2; pParent->mbUseTaggedPDF = mbTaggedPDFUserSelection; pParent->mbExportFormFields = mbExportFormFieldsUserSelection; } @@ -759,11 +759,11 @@ IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleExportPDFAHdl, weld::ToggleButton&, ImpPDFTabSecurityPage* pSecPage = mpParent ? mpParent->getSecurityPage() : nullptr; if (pSecPage) { - pSecPage->ImplPDFASecurityControl(!mxCbPDFA1b->get_active()); + pSecPage->ImplPDFASecurityControl(!mxCbPDFA2b->get_active()); } // PDF/A-1 needs tagged PDF, so force disable the control, will be forced in pdfexport. - bool bPDFA1Sel = mxCbPDFA1b->get_active(); + bool bPDFA1Sel = mxCbPDFA2b->get_active(); mxFormsFrame->set_sensitive(bPDFA1Sel); if(bPDFA1Sel) { @@ -784,14 +784,14 @@ IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleExportPDFAHdl, weld::ToggleButton&, mxCbExportFormFields->set_sensitive(true); } - // PDF/A-1 doesn't allow launch action, so enable/disable the selection on + // PDF/A-2 doesn't allow launch action, so enable/disable the selection on // Link page ImpPDFTabLinksPage* pLinksPage = mpParent ? mpParent->getLinksPage() : nullptr; if (pLinksPage) - pLinksPage->ImplPDFALinkControl(!mxCbPDFA1b->get_active()); + pLinksPage->ImplPDFALinkControl(!mxCbPDFA2b->get_active()); // if a password was set, inform the user that this will not be used in PDF/A case - if( mxCbPDFA1b->get_active() && pSecPage && pSecPage->hasPassword() ) + if( mxCbPDFA2b->get_active() && pSecPage && pSecPage->hasPassword() ) { std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xContainer.get(), VclMessageType::Warning, VclButtonsType::Ok, @@ -1347,11 +1347,11 @@ void ImpPDFTabLinksPage::SetFilterConfigItem( const ImpPDFTabDialog* pParent ) // now check the status of PDF/A selection // and set the link action accordingly - // PDF/A-1 doesn't allow launch action on links + // PDF/A-2 doesn't allow launch action on links ImpPDFTabGeneralPage* pGeneralPage = pParent->getGeneralPage(); if (pGeneralPage) - ImplPDFALinkControl(!pGeneralPage->mxCbPDFA1b->get_active()); + ImplPDFALinkControl(!pGeneralPage->mxCbPDFA2b->get_active()); } diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx index b2b0073a0775..6381c554bc47 100644 --- a/filter/source/pdf/impdialog.hxx +++ b/filter/source/pdf/impdialog.hxx @@ -190,7 +190,7 @@ class ImpPDFTabGeneralPage : public SfxTabPage std::unique_ptr<weld::MetricSpinButton> mxNfQuality; std::unique_ptr<weld::CheckButton> mxCbReduceImageResolution; std::unique_ptr<weld::ComboBoxText> mxCoReduceImageResolution; - std::unique_ptr<weld::CheckButton> mxCbPDFA1b; + std::unique_ptr<weld::CheckButton> mxCbPDFA2b; std::unique_ptr<weld::CheckButton> mxCbTaggedPDF; std::unique_ptr<weld::CheckButton> mxCbExportFormFields; std::unique_ptr<weld::Widget> mxFormsFrame; @@ -235,7 +235,7 @@ public: void GetFilterConfigItem(ImpPDFTabDialog* paParent); void SetFilterConfigItem(ImpPDFTabDialog* paParent); - bool IsPdfaSelected() const { return mxCbPDFA1b->get_active(); } + bool IsPdfaSelected() const { return mxCbPDFA2b->get_active(); } }; /// Class tab page viewer diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx index c7e307f21453..387e2307ae9a 100644 --- a/filter/source/pdf/pdfexport.cxx +++ b/filter/source/pdf/pdfexport.cxx @@ -572,6 +572,13 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& mbEncrypt = false; // no encryption xEnc.clear(); break; + case 2: + aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_2; + mbUseTaggedPDF = true; // force the tagged PDF as well + mbRemoveTransparencies = false; // PDF/A-2 does allow transparencies + mbEncrypt = false; // no encryption + xEnc.clear(); + break; } // copy in context the values default in the constructor or set by the FilterData sequence of properties diff --git a/filter/uiconfig/ui/pdfgeneralpage.ui b/filter/uiconfig/ui/pdfgeneralpage.ui index 631b31cee483..f3d2d874bd02 100644 --- a/filter/uiconfig/ui/pdfgeneralpage.ui +++ b/filter/uiconfig/ui/pdfgeneralpage.ui @@ -463,11 +463,11 @@ </child> <child> <object class="GtkCheckButton" id="pdfa"> - <property name="label" translatable="yes" context="pdfgeneralpage|pdfa">Archive P_DF/A-1a (ISO 19005-1)</property> + <property name="label" translatable="yes" context="pdfgeneralpage|pdfa">Archive P_DF/A-2b (ISO 19005-2)</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> - <property name="tooltip_text" translatable="yes" context="pdfgeneralpage|pdfa|tooltip_text">Creates an ISO 19005-1 compliant PDF file, ideal for long-term document preservation</property> + <property name="tooltip_text" translatable="yes" context="pdfgeneralpage|pdfa|tooltip_text">Creates an ISO 19005-2 compliant PDF file, ideal for long-term document preservation</property> <property name="use_underline">True</property> <property name="xalign">0</property> <property name="draw_indicator">True</property> diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx index 3c9afafc8180..231018c319a6 100644 --- a/include/vcl/pdfwriter.hxx +++ b/include/vcl/pdfwriter.hxx @@ -103,7 +103,7 @@ public: enum class Orientation { Portrait, Inherit }; // in case the below enum is added PDF_1_6 PDF_1_7, please add them just after PDF_1_5 - enum class PDFVersion { PDF_1_2, PDF_1_3, PDF_1_4, PDF_1_5, PDF_A_1 };//i59651, PDF/A-1b & -1a, only -1b implemented for now + enum class PDFVersion { PDF_1_2, PDF_1_3, PDF_1_4, PDF_1_5, PDF_A_1, PDF_A_2 };//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/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 181d2003f3e4..cd553e2fe7fe 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -1719,6 +1719,7 @@ void PDFWriterImpl::PDFPage::appendWaveLine( sal_Int32 nWidth, sal_Int32 nY, sal m_pEncryptionBuffer( nullptr ), m_nEncryptionBufferSize( 0 ), m_bIsPDF_A1( false ), + m_bIsPDF_A2( false ), m_rOuterFace( i_rOuterFace ) { #ifdef DO_TEST_PDF @@ -1820,6 +1821,9 @@ void PDFWriterImpl::PDFPage::appendWaveLine( sal_Int32 nWidth, sal_Int32 nY, sal 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_5; //we could even use 1.7 features } PDFWriterImpl::~PDFWriterImpl() @@ -2628,11 +2632,15 @@ sal_Int32 PDFWriterImpl::emitStructure( PDFStructureElement& rEle ) aLine.append( "/RoleMap<<" ); for (auto const& role : m_aRoleMap) { - aLine.append( '/' ); - aLine.append(role.first); - aLine.append( '/' ); - aLine.append( role.second ); - aLine.append( '\n' ); + // hack! + if (role.first != role.second) + { + aLine.append( '/' ); + aLine.append(role.first); + aLine.append( '/' ); + aLine.append( role.second ); + aLine.append( '\n' ); + } } aLine.append( ">>\n" ); } @@ -3799,7 +3807,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 ) + if( m_bIsPDF_A1 || m_bIsPDF_A2 ) aLine.append( "/F 4" ); aLine.append( "/Subtype/Link/Border[0 0 0]/Rect[" ); @@ -4021,7 +4029,7 @@ bool PDFWriterImpl::emitNoteAnnotations() // 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 ) + if( m_bIsPDF_A1 || m_bIsPDF_A2 ) aLine.append( "/F 4" ); aLine.append( "/Subtype/Text/Rect[" ); @@ -4820,8 +4828,11 @@ bool PDFWriterImpl::emitWidgetAnnotations() } else if( rWidget.m_aListEntries.empty() ) { - // create a reset form action - aLine.append( "/AA<</D<</Type/Action/S/ResetForm>>>>\n" ); + if( !m_bIsPDF_A2 ) + { + // create a reset form action + aLine.append( "/AA<</D<</Type/Action/S/ResetForm>>>>\n" ); + } } else if( rWidget.m_bSubmit ) { @@ -5240,7 +5251,7 @@ bool PDFWriterImpl::emitCatalog() aLine.append( getResourceDictObj() ); aLine.append( " 0 R" ); // NeedAppearances must not be used if PDF is signed - if( m_bIsPDF_A1 + if( m_bIsPDF_A1 || m_bIsPDF_A2 #if HAVE_FEATURE_NSS || ( m_nSignatureObject != -1 ) #endif @@ -5560,7 +5571,7 @@ sal_Int32 PDFWriterImpl::emitNamedDestinations() // emits the output intent dictionary sal_Int32 PDFWriterImpl::emitOutputIntent() { - if( !m_bIsPDF_A1 ) + if( !m_bIsPDF_A1 && !m_bIsPDF_A2 ) return 0; //emit the sRGB standard profile, in ICC format, in a stream, per IEC61966-2.1 @@ -5667,7 +5678,7 @@ static void escapeStringXML( const OUString& rStr, OUString &rValue) // emits the document metadata sal_Int32 PDFWriterImpl::emitDocumentMetadata() { - if( !m_bIsPDF_A1 ) + if( !m_bIsPDF_A1 && !m_bIsPDF_A2 ) return 0; //get the object number for all the destinations @@ -5688,8 +5699,14 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() //PDF/A part ( ISO 19005-1:2005 - 6.7.11 ) aMetadataStream.append( " <rdf:Description rdf:about=\"\"\n" ); aMetadataStream.append( " xmlns:pdfaid=\"http://www.aiim.org/pdfa/ns/id/\">\n" ); - aMetadataStream.append( " <pdfaid:part>1</pdfaid:part>\n" ); - aMetadataStream.append( " <pdfaid:conformance>A</pdfaid:conformance>\n" ); + if( m_bIsPDF_A2 ) + aMetadataStream.append( " <pdfaid:part>2</pdfaid:part>\n" ); + else + aMetadataStream.append( " <pdfaid:part>1</pdfaid:part>\n" ); + if( m_bIsPDF_A2 ) + aMetadataStream.append( " <pdfaid:conformance>B</pdfaid:conformance>\n" ); + else + aMetadataStream.append( " <pdfaid:conformance>A</pdfaid:conformance>\n" ); aMetadataStream.append( " </rdf:Description>\n" ); //... Dublin Core properties go here if( !m_aContext.DocumentInfo.Title.isEmpty() || diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index 0aa63514b2c5..ca0dadcc4861 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -1005,6 +1005,8 @@ i12626 /* true if PDF/A-1a or PDF/A-1b is output */ bool m_bIsPDF_A1; + /* true if PDF/A-2a is output */ + bool m_bIsPDF_A2; PDFWriter& m_rOuterFace; /* _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits