diff options
author | Arnaud Versini <arnaud.versini@libreoffice.org> | 2019-09-20 19:01:34 +0200 |
---|---|---|
committer | Arnaud Versini <arnaud.versini@libreoffice.org> | 2020-02-08 15:03:07 +0100 |
commit | a795886762a6a4aabd601183598c4e6c819bcb1f (patch) | |
tree | 93a58d738bf27a0c5f75f80dc7e651763916ee5f | |
parent | a2f62a861ba7036e689070c47f72214b1bdd49d4 (diff) |
Add minimum support for PDF/A3
Change-Id: I6ce3a3dbe71df1d3f56279879e3f91bd7c82f784
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/84687
Tested-by: Jenkins
Reviewed-by: Arnaud Versini <arnaud.versini@libreoffice.org>
-rw-r--r-- | filter/source/pdf/impdialog.cxx | 27 | ||||
-rw-r--r-- | filter/source/pdf/impdialog.hxx | 3 | ||||
-rw-r--r-- | filter/source/pdf/pdfexport.cxx | 7 | ||||
-rw-r--r-- | filter/uiconfig/ui/pdfgeneralpage.ui | 106 | ||||
-rw-r--r-- | include/vcl/pdfwriter.hxx | 2 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 21 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.hxx | 2 |
7 files changed, 116 insertions, 52 deletions
diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx index 0fe49d89b9cf..2abce8fdeb08 100644 --- a/filter/source/pdf/impdialog.cxx +++ b/filter/source/pdf/impdialog.cxx @@ -390,10 +390,9 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData() // always write the user selection, never the overridden value const bool bIsPDFUA = mbPDFUACompliance; - const bool bIsPDFA = (1 == mnPDFTypeSelection) || (2 == mnPDFTypeSelection); + const bool bIsPDFA = (1 == mnPDFTypeSelection) || (2 == mnPDFTypeSelection) || (3 == mnPDFTypeSelection); const bool bUserSelectionTags = bIsPDFA || bIsPDFUA; maConfigItem.WriteBool("UseTaggedPDF", bUserSelectionTags ? mbUseTaggedPDFUserSelection : mbUseTaggedPDF); - maConfigItem.WriteInt32("SelectPdfVersion", mnPDFTypeSelection ); maConfigItem.WriteBool("PDFUACompliance", mbPDFUACompliance); @@ -493,9 +492,8 @@ ImpPDFTabGeneralPage::ImpPDFTabGeneralPage(weld::Container* pPage, weld::DialogC , mxCbReduceImageResolution(m_xBuilder->weld_check_button("reduceresolution")) , mxCoReduceImageResolution(m_xBuilder->weld_combo_box("resolution")) , mxCbPDFA(m_xBuilder->weld_check_button("pdfa")) - , mxRbPDFA1b(m_xBuilder->weld_radio_button("pdfa1")) - , mxRbPDFA2b(m_xBuilder->weld_radio_button("pdfa2")) , mxCbPDFUA(m_xBuilder->weld_check_button("pdfua")) + , mxRbPDFAVersion(m_xBuilder->weld_combo_box("pdfaversion")) , mxCbTaggedPDF(m_xBuilder->weld_check_button("tagged")) , mxCbExportFormFields(m_xBuilder->weld_check_button("forms")) , mxFormsFrame(m_xBuilder->weld_widget("formsframe")) @@ -567,18 +565,19 @@ void ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent) mxEdWatermark->set_sensitive( false ); mxCbPDFA->connect_toggled(LINK(this, ImpPDFTabGeneralPage, TogglePDFVersionOrUniversalAccessibilityHandle)); - const bool bIsPDFA = (1 == pParent->mnPDFTypeSelection) || (2 == pParent->mnPDFTypeSelection); + const bool bIsPDFA = (pParent->mnPDFTypeSelection>=1) && (pParent->mnPDFTypeSelection <= 3); mxCbPDFA->set_active(bIsPDFA); switch( pParent->mnPDFTypeSelection ) { case 1: // PDF/A-1 - mxRbPDFA1b->set_active(true); - mxRbPDFA2b->set_active(false); + mxRbPDFAVersion->set_active_id("1"); break; case 2: // PDF/A-2 + mxRbPDFAVersion->set_active_id("2"); + break; + case 3: // PDF/A-3 default: // PDF 1.x - mxRbPDFA1b->set_active(false); - mxRbPDFA2b->set_active(true); + mxRbPDFAVersion->set_active_id("3"); break; } @@ -709,9 +708,12 @@ void ImpPDFTabGeneralPage::GetFilterConfigItem( ImpPDFTabDialog* pParent ) if (bIsPDFA) { - pParent->mnPDFTypeSelection = 2; - if( mxRbPDFA1b->get_active() ) + pParent->mnPDFTypeSelection = 3; + OUString currentPDFAMode = mxRbPDFAVersion->get_active_id(); + if( currentPDFAMode == "1" ) pParent->mnPDFTypeSelection = 1; + else if(currentPDFAMode == "2") + pParent->mnPDFTypeSelection = 2; } pParent->mbPDFUACompliance = bIsPDFUA; @@ -831,8 +833,7 @@ IMPL_LINK_NOARG(ImpPDFTabGeneralPage, TogglePDFVersionOrUniversalAccessibilityHa pSecPage->ImplPDFASecurityControl(!bIsPDFA); mxCbTaggedPDF->set_sensitive(!bIsPDFA && !bIsPDFUA); - mxRbPDFA1b->set_sensitive(bIsPDFA); - mxRbPDFA2b->set_sensitive(bIsPDFA); + mxRbPDFAVersion->set_sensitive(bIsPDFA); if (bIsPDFA || bIsPDFUA) { diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx index 97a7464ffa6d..17fb57890655 100644 --- a/filter/source/pdf/impdialog.hxx +++ b/filter/source/pdf/impdialog.hxx @@ -191,9 +191,8 @@ class ImpPDFTabGeneralPage : public SfxTabPage std::unique_ptr<weld::CheckButton> mxCbReduceImageResolution; std::unique_ptr<weld::ComboBox> mxCoReduceImageResolution; std::unique_ptr<weld::CheckButton> mxCbPDFA; - std::unique_ptr<weld::RadioButton> mxRbPDFA1b; - std::unique_ptr<weld::RadioButton> mxRbPDFA2b; std::unique_ptr<weld::CheckButton> mxCbPDFUA; + std::unique_ptr<weld::ComboBox> mxRbPDFAVersion; std::unique_ptr<weld::CheckButton> mxCbTaggedPDF; std::unique_ptr<weld::CheckButton> mxCbExportFormFields; std::unique_ptr<weld::Widget> mxFormsFrame; diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx index a4e4549b631f..758c7e786114 100644 --- a/filter/source/pdf/pdfexport.cxx +++ b/filter/source/pdf/pdfexport.cxx @@ -607,6 +607,13 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& mbEncrypt = false; // no encryption xEnc.clear(); break; + case 3: + aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_3; + mbUseTaggedPDF = true; // force the tagged PDF as well + mbRemoveTransparencies = false; // does allow transparencies + mbEncrypt = false; // no encryption + xEnc.clear(); + break; case 16: aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_6; break; diff --git a/filter/uiconfig/ui/pdfgeneralpage.ui b/filter/uiconfig/ui/pdfgeneralpage.ui index 9f469063edb5..02bef0174279 100644 --- a/filter/uiconfig/ui/pdfgeneralpage.ui +++ b/filter/uiconfig/ui/pdfgeneralpage.ui @@ -2,6 +2,7 @@ <!-- Generated with glade 3.22.1 --> <interface domain="flt"> <requires lib="gtk+" version="3.18"/> + <object class="GtkSizeGroup"/> <object class="GtkAdjustment" id="adjustment1"> <property name="lower">1</property> <property name="upper">100</property> @@ -517,17 +518,19 @@ <property name="row_spacing">6</property> <property name="column_spacing">12</property> <child> - <object class="GtkLabel" id="label7"> + <object class="GtkCheckButton" id="allowdups"> + <property name="label" translatable="yes" context="pdfgeneralpage|allowdups">Allow duplicate field _names</property> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> <property name="halign">start</property> - <property name="label" translatable="yes" context="pdfgeneralpage|label7">Submit _format:</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">format</property> + <property name="draw_indicator">True</property> </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">0</property> + <property name="top_attach">1</property> + <property name="width">2</property> </packing> </child> <child> @@ -547,19 +550,33 @@ </packing> </child> <child> - <object class="GtkCheckButton" id="allowdups"> - <property name="label" translatable="yes" context="pdfgeneralpage|allowdups">Allow duplicate field _names</property> + <object class="GtkBox" id="submitformatbox"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="halign">start</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel" id="label7"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="valign">baseline</property> + <property name="margin_top">1</property> + <property name="vexpand">True</property> + <property name="label" translatable="yes" context="pdfgeneralpage|label7">Submit _format:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">format</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> </object> <packing> <property name="left_attach">0</property> - <property name="top_attach">1</property> - <property name="width">2</property> + <property name="top_attach">0</property> </packing> </child> </object> @@ -602,31 +619,50 @@ <property name="can_focus">False</property> <property name="column_spacing">14</property> <child> - <object class="GtkRadioButton" id="pdfa2"> - <property name="label" context="pdfgeneralpage|pdfa">PDF/A-2b</property> + <object class="GtkComboBoxText" id="pdfaversion"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> + <property name="can_focus">False</property> + <property name="active">3</property> + <items> + <item id="1" context="pdfgeneralpage|pdfaversion">PDF/A-1b</item> + <item id="2" context="pdfgeneralpage|pdfaversion">PDF/A-2b</item> + <item id="3" context="pdfgeneralpage|pdfaversion">PDF/A-3b</item> + </items> + <accessibility> + <relation type="labelled-by" target="pdfaversionlabel"/> + </accessibility> </object> <packing> - <property name="left_attach">0</property> + <property name="left_attach">1</property> <property name="top_attach">0</property> </packing> </child> <child> - <object class="GtkRadioButton" id="pdfa1"> - <property name="label" context="pdfgeneralpage|pdfa">PDF/A-1b</property> + <object class="GtkBox" id="pdfabox"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - <property name="group">pdfa2</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel" id="pdfaversionlabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="valign">baseline</property> + <property name="vexpand">True</property> + <property name="label" translatable="yes" context="pdfgeneralpage|pdfaversion">PDF/A _version:</property> + <property name="use_underline">True</property> + <accessibility> + <relation type="label-for" target="pdfaversion"/> + </accessibility> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> </object> <packing> - <property name="left_attach">1</property> + <property name="left_attach">0</property> <property name="top_attach">0</property> </packing> </child> @@ -868,6 +904,18 @@ </packing> </child> </object> + <object class="GtkSizeGroup" id="comboBoxSizegroup"> + <widgets> + <widget name="format"/> + <widget name="pdfaversion"/> + </widgets> + </object> + <object class="GtkSizeGroup" id="pdfSizeGroup"> + <widgets> + <widget name="submitformatbox"/> + <widget name="pdfabox"/> + </widgets> + </object> <object class="GtkSizeGroup" id="sizegroupLabel"> <widgets> <widget name="all"/> diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx index 5a628e2f53e3..6527124ea291 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_1_6, PDF_A_1, PDF_A_2 };//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_1_6, PDF_A_1, PDF_A_2, PDF_A_3 };//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 6726b02b7173..27a299d5aa2a 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -1142,6 +1142,7 @@ PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, m_bIsPDF_A1( false ), m_bIsPDF_A2( false ), m_bIsPDF_UA( false ), + m_bIsPDF_A3( false ), m_rOuterFace( i_rOuterFace ) { m_aStructure.emplace_back( ); @@ -1232,6 +1233,10 @@ PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, if( m_bIsPDF_A2 ) m_aContext.Version = PDFWriter::PDFVersion::PDF_1_6; //we could even use 1.7 features + m_bIsPDF_A3 = (m_aContext.Version == PDFWriter::PDFVersion::PDF_A_3); + if( m_bIsPDF_A3 ) + m_aContext.Version = PDFWriter::PDFVersion::PDF_1_6; //we could even use 1.7 features + if (m_aContext.UniversalAccessibilityCompliance) { m_bIsPDF_UA = true; @@ -3167,7 +3172,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 ) + if( m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3) aLine.append( "/F 4" ); aLine.append( "/Subtype/Link/Border[0 0 0]/Rect[" ); @@ -3389,7 +3394,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 || m_bIsPDF_A2 ) + if( m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3 ) aLine.append( "/F 4" ); aLine.append( "/Subtype/Text/Rect[" ); @@ -3939,7 +3944,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 ) + if( m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3) { if( rWidget.m_eType == PDFWriter::RadioButton || rWidget.m_eType == PDFWriter::CheckBox || @@ -4221,7 +4226,7 @@ bool PDFWriterImpl::emitWidgetAnnotations() } else if( rWidget.m_aListEntries.empty() ) { - if( !m_bIsPDF_A2 ) + if( !m_bIsPDF_A2 && !m_bIsPDF_A3 ) { // create a reset form action aLine.append( "/AA<</D<</Type/Action/S/ResetForm>>>>\n" ); @@ -4644,7 +4649,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 + if( m_bIsPDF_A1 || m_bIsPDF_A2 || m_bIsPDF_A3 #if HAVE_FEATURE_NSS || ( m_nSignatureObject != -1 ) #endif @@ -4956,7 +4961,7 @@ sal_Int32 PDFWriterImpl::emitNamedDestinations() // emits the output intent dictionary sal_Int32 PDFWriterImpl::emitOutputIntent() { - if( !m_bIsPDF_A1 && !m_bIsPDF_A2 ) + if( !m_bIsPDF_A1 && !m_bIsPDF_A2 && !m_bIsPDF_A3 ) return 0; //emit the sRGB standard profile, in ICC format, in a stream, per IEC61966-2.1 @@ -5066,7 +5071,7 @@ static void escapeStringXML( const OUString& rStr, OUString &rValue) // emits the document metadata sal_Int32 PDFWriterImpl::emitDocumentMetadata() { - if (!m_bIsPDF_A1 && !m_bIsPDF_A2 && !m_bIsPDF_UA) + if( !m_bIsPDF_A1 && !m_bIsPDF_A2 && !m_bIsPDF_A3 ) return 0; //get the object number for all the destinations @@ -5080,6 +5085,8 @@ sal_Int32 PDFWriterImpl::emitDocumentMetadata() aMetadata.mnPDF_A = 1; else if (m_bIsPDF_A2) aMetadata.mnPDF_A = 2; + else if (m_bIsPDF_A3) + aMetadata.mnPDF_A = 3; aMetadata.mbPDF_UA = m_bIsPDF_UA; diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index c70628ab1789..78800ccd9b39 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -976,6 +976,8 @@ i12626 /* PDF/UA support enabled */ bool m_bIsPDF_UA; + bool m_bIsPDF_A3; + PDFWriter& m_rOuterFace; /* |