summaryrefslogtreecommitdiffstats
path: root/filter/source/pdf/pdfexport.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/pdf/pdfexport.cxx')
-rw-r--r--filter/source/pdf/pdfexport.cxx646
1 files changed, 423 insertions, 223 deletions
diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx
index 604326b4bdbf..03ecbf576c56 100644
--- a/filter/source/pdf/pdfexport.cxx
+++ b/filter/source/pdf/pdfexport.cxx
@@ -22,11 +22,12 @@
#include <tools/debug.hxx>
#include <tools/urlobj.hxx>
#include <tools/poly.hxx>
-#include <tools/diagnose_ex.h>
-#include <unotools/resmgr.hxx>
+#include <comphelper/diagnose_ex.hxx>
+#include <utility>
#include <vcl/canvastools.hxx>
#include <vcl/mapmod.hxx>
#include <vcl/gdimtf.hxx>
+#include <rtl/ustring.hxx>
#include <comphelper/propertyvalue.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/string.hxx>
@@ -36,8 +37,8 @@
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <toolkit/awt/vclxdevice.hxx>
#include <unotools/configmgr.hxx>
-#include <cppuhelper/compbase.hxx>
-#include <cppuhelper/basemutex.hxx>
+#include <comphelper/compbase.hxx>
+#include <officecfg/Office/Common.hxx>
#include "pdfexport.hxx"
#include <strings.hrc>
@@ -48,7 +49,7 @@
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/ModuleManager.hpp>
#include <com/sun/star/frame/XStorable.hpp>
-#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentProperties2.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/view/XViewSettingsSupplier.hpp>
@@ -58,18 +59,22 @@
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/sheet/XSheetRange.hpp>
#include <com/sun/star/security/XCertificate.hpp>
#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/xml/crypto/SEInitializer.hpp>
#include <memory>
+#include <rtl/bootstrap.hxx>
+#include <config_features.h>
+
using namespace ::com::sun::star;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::view;
-using namespace ::com::sun::star::graphic;
PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc,
@@ -80,59 +85,17 @@ PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc,
mxContext ( xContext ),
mxStatusIndicator ( rxStatusIndicator ),
mxIH ( rxIH ),
- mbUseTaggedPDF ( false ),
- mnPDFTypeSelection ( 0 ),
- mbPDFUACompliance ( false),
- mbExportNotes ( true ),
- mbExportPlaceholders ( false ),
- mbUseReferenceXObject ( false ),
- mbExportNotesPages ( false ),
- mbExportOnlyNotesPages ( false ),
- mbUseTransitionEffects ( true ),
- mbExportBookmarks ( true ),
- mbExportHiddenSlides ( false ),
- mbSinglePageSheets ( false ),
- mnOpenBookmarkLevels ( -1 ),
mbUseLosslessCompression ( false ),
mbReduceImageResolution ( true ),
mbSkipEmptyPages ( true ),
- mbAddStream ( false ),
mnMaxImageResolution ( 300 ),
mnQuality ( 80 ),
- mnFormsFormat ( 0 ),
- mbExportFormFields ( true ),
- mbAllowDuplicateFieldNames ( false ),
mnProgressValue ( 0 ),
mbRemoveTransparencies ( false ),
mbIsRedactMode ( false ),
-
- mbHideViewerToolbar ( false ),
- mbHideViewerMenubar ( false ),
- mbHideViewerWindowControls ( false ),
- mbFitWindow ( false ),
- mbCenterWindow ( false ),
- mbOpenInFullScreenMode ( false ),
- mbDisplayPDFDocumentTitle ( true ),
- mnPDFDocumentMode ( 0 ),
- mnPDFDocumentAction ( 0 ),
- mnZoom ( 100 ),
- mnInitialPage ( 1 ),
- mnPDFPageLayout ( 0 ),
-
- mbEncrypt ( false ),
- mbRestrictPermissions ( false ),
- mnPrintAllowed ( 2 ),
- mnChangesAllowed ( 4 ),
- mbCanCopyOrExtract ( true ),
- mbCanExtractForAccessibility( true ),
-
- // #i56629
- mbExportRelativeFsysLinks ( false ),
- mnDefaultLinkAction ( 0 ),
- mbConvertOOoTargetToPDFTarget( false ),
- mbExportBmkToDest ( false ),
- mbSignPDF ( false )
+ maWatermarkColor ( COL_LIGHTGREEN ),
+ maWatermarkFontName ( "Helvetica" )
{
}
@@ -307,19 +270,16 @@ void PDFExportStreamDoc::write( const Reference< XOutputStream >& xStream )
if( !xStore.is() )
return;
- Sequence< beans::PropertyValue > aArgs( 2 + (m_aPreparedPassword.hasElements() ? 1 : 0) );
- aArgs.getArray()[0].Name = "FilterName";
- aArgs.getArray()[1].Name = "OutputStream";
- aArgs.getArray()[1].Value <<= xStream;
- if( m_aPreparedPassword.hasElements() )
- {
- aArgs.getArray()[2].Name = "EncryptionData";
- aArgs.getArray()[2].Value <<= m_aPreparedPassword;
- }
+ std::vector<beans::PropertyValue> aArgs {
+ comphelper::makePropertyValue("FilterName", OUString()),
+ comphelper::makePropertyValue("OutputStream", xStream),
+ };
+ if (m_aPreparedPassword.hasElements())
+ aArgs.push_back(comphelper::makePropertyValue("EncryptionData", m_aPreparedPassword));
try
{
- xStore->storeToURL( "private:stream", aArgs );
+ xStore->storeToURL("private:stream", comphelper::containerToSequence(aArgs));
}
catch( const IOException& )
{
@@ -370,7 +330,7 @@ static OUString getMimetypeForDocument( const Reference< XComponentContext >& xC
Sequence< beans::PropertyValue > aFilterData;
xFilterFactory->getByName( aFilterName ) >>= aFilterData;
- for ( const beans::PropertyValue& rProp : std::as_const(aFilterData) )
+ for (const beans::PropertyValue& rProp : aFilterData)
if ( rProp.Name == "Type" )
rProp.Value >>= aTypeName;
@@ -383,7 +343,7 @@ static OUString getMimetypeForDocument( const Reference< XComponentContext >& xC
Sequence< beans::PropertyValue > aTypeData;
xTypeDetection->getByName( aTypeName ) >>= aTypeData;
- for ( const beans::PropertyValue& rProp : std::as_const(aTypeData) )
+ for (const beans::PropertyValue& rProp : aTypeData)
if ( rProp.Name == "MediaType" )
rProp.Value >>= aDocMimetype;
}
@@ -398,6 +358,25 @@ static OUString getMimetypeForDocument( const Reference< XComponentContext >& xC
return aDocMimetype;
}
+uno::Reference<security::XCertificate>
+PDFExport::GetCertificateFromSubjectName(const std::u16string_view& rSubjectName) const
+{
+ uno::Reference<xml::crypto::XSEInitializer> xSEInitializer
+ = xml::crypto::SEInitializer::create(mxContext);
+ uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext
+ = xSEInitializer->createSecurityContext(OUString());
+ uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment
+ = xSecurityContext->getSecurityEnvironment();
+ for (const auto& xCertificate : xSecurityEnvironment->getPersonalCertificates())
+ {
+ if (xCertificate->getSubjectName() == rSubjectName)
+ {
+ return xCertificate;
+ }
+ }
+
+ return {};
+}
bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& rFilterData )
{
@@ -420,6 +399,53 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
if( xRenderable.is() )
{
+ // The defaults
+ bool bUseTaggedPDF = false;
+ sal_Int32 nPDFTypeSelection = 0;
+ bool bPDFUACompliance = false;
+ bool bExportNotes = true;
+ bool bExportNotesInMargin = false;
+ bool bExportNotesPages = false;
+ bool bExportOnlyNotesPages = false;
+ bool bUseTransitionEffects = true;
+ bool bExportFormFields = true;
+ sal_Int32 nFormsFormat = 0;
+ bool bAllowDuplicateFieldNames = false;
+ bool bHideViewerToolbar = false;
+ bool bHideViewerMenubar = false;
+ bool bHideViewerWindowControls = false;
+ bool bFitWindow = false;
+ bool bCenterWindow = false;
+ bool bOpenInFullScreenMode = false;
+ bool bDisplayPDFDocumentTitle = true;
+ sal_Int32 nPDFDocumentMode = 0;
+ sal_Int32 nPDFDocumentAction = 0;
+ sal_Int32 nZoom = 100;
+ sal_Int32 nInitialPage = 1;
+ sal_Int32 nPDFPageLayout = 0;
+ bool bAddStream = false;
+ bool bEncrypt = false;
+ bool bRestrictPermissions = false;
+ sal_Int32 nPrintAllowed = 2;
+ sal_Int32 nChangesAllowed = 4;
+ bool bCanCopyOrExtract = true;
+ bool bCanExtractForAccessibility = true;
+ // #i56629
+ bool bExportRelativeFsysLinks = false;
+ sal_Int32 nDefaultLinkAction = 0;
+ bool bConvertOOoTargetToPDFTarget = false;
+ bool bExportBmkToDest = false;
+ bool bExportBookmarks = true;
+ bool bExportHiddenSlides = false;
+ bool bSinglePageSheets = false;
+ sal_Int32 nOpenBookmarkLevels = -1;
+ bool bSignPDF = false;
+ OUString sSignLocation, sSignReason, sSignContact, sSignPassword;
+ css::uno::Reference<css::security::XCertificate> aSignCertificate;
+ OUString sSignTSA;
+ bool bExportPlaceholders = false;
+ bool bUseReferenceXObject = false;
+
rtl::Reference<VCLXDevice> xDevice(new VCLXDevice);
OUString aPageRange;
Any aSelection;
@@ -427,7 +453,11 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
OUString aOpenPassword, aPermissionPassword;
Reference< beans::XMaterialHolder > xEnc;
Sequence< beans::NamedValue > aPreparedPermissionPassword;
-
+ std::optional<PropertyValue> oMathTitleRow;
+ std::optional<PropertyValue> oMathFormulaText;
+ std::optional<PropertyValue> oMathBorder;
+ std::optional<PropertyValue> oMathPrintFormat;
+ std::optional<PropertyValue> oMathPrintScale;
// getting the string for the creator
OUString aCreator;
@@ -435,40 +465,74 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
if ( xInfo.is() )
{
if ( xInfo->supportsService( "com.sun.star.presentation.PresentationDocument" ) )
- aCreator += "Impress";
+ aCreator = u"Impress"_ustr;
else if ( xInfo->supportsService( "com.sun.star.drawing.DrawingDocument" ) )
- aCreator += "Draw";
+ aCreator = u"Draw"_ustr;
else if ( xInfo->supportsService( "com.sun.star.text.TextDocument" ) )
- aCreator += "Writer";
+ aCreator = u"Writer"_ustr;
else if ( xInfo->supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) )
- aCreator += "Calc";
+ aCreator = u"Calc"_ustr;
else if ( xInfo->supportsService( "com.sun.star.formula.FormulaProperties" ) )
- aCreator += "Math";
+ aCreator = u"Math"_ustr;
}
Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY );
if ( xDocumentPropsSupplier.is() )
{
- Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() );
+ Reference< document::XDocumentProperties2 > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties(), UNO_QUERY );
if ( xDocumentProps.is() )
{
aContext.DocumentInfo.Title = xDocumentProps->getTitle();
aContext.DocumentInfo.Author = xDocumentProps->getAuthor();
aContext.DocumentInfo.Subject = xDocumentProps->getSubject();
aContext.DocumentInfo.Keywords = ::comphelper::string::convertCommaSeparated(xDocumentProps->getKeywords());
+ aContext.DocumentInfo.ModificationDate
+ = xDocumentProps->getEditingCycles() < 1
+ ? xDocumentProps->getCreationDate()
+ : xDocumentProps->getModificationDate();
+ aContext.DocumentInfo.Contributor = xDocumentProps->getContributor();
+ aContext.DocumentInfo.Coverage = xDocumentProps->getCoverage();
+ aContext.DocumentInfo.Identifier = xDocumentProps->getIdentifier();
+ aContext.DocumentInfo.Publisher = xDocumentProps->getPublisher();
+ aContext.DocumentInfo.Relation = xDocumentProps->getRelation();
+ aContext.DocumentInfo.Rights = xDocumentProps->getRights();
+ aContext.DocumentInfo.Source = xDocumentProps->getSource();
+ aContext.DocumentInfo.Type = xDocumentProps->getType();
}
}
- // getting the string for the producer
- aContext.DocumentInfo.Producer =
- utl::ConfigManager::getProductName() +
- " " +
- utl::ConfigManager::getProductVersion();
+
+ if (!comphelper::IsFuzzing())
+ {
+ OUString arch;
+ auto const ok = rtl::Bootstrap::get("_ARCH", arch);
+ assert(ok); (void) ok;
+ // getting the string for the producer
+ OUString aProducerOverride = officecfg::Office::Common::Save::Document::GeneratorOverride::get();
+ if (!aProducerOverride.isEmpty())
+ aContext.DocumentInfo.Producer = aProducerOverride;
+ else
+ aContext.DocumentInfo.Producer =
+ utl::ConfigManager::getProductName() +
+ " " +
+ utl::ConfigManager::getAboutBoxProductVersion() +
+ " (" + arch + ") / LibreOffice Community";
+ }
+
aContext.DocumentInfo.Creator = aCreator;
+ OUString aSignCertificateSubjectName;
for ( const beans::PropertyValue& rProp : rFilterData )
{
if ( rProp.Name == "PageRange" )
rProp.Value >>= aPageRange;
+ else if ( rProp.Name == "SheetRange" )
+ {
+ Reference< frame::XController > xController( Reference< frame::XModel >( mxSrcDoc, UNO_QUERY_THROW )->getCurrentController() );
+ Reference< sheet::XSheetRange > xView( xController, UNO_QUERY);
+ OUString aSheetRange;
+ rProp.Value >>= aSheetRange;
+ aSelection = xView->getSelectionFromString(aSheetRange);
+ }
else if ( rProp.Name == "Selection" )
aSelection = rProp.Value;
else if ( rProp.Name == "UseLosslessCompression" )
@@ -482,65 +546,99 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
else if ( rProp.Name == "MaxImageResolution" )
rProp.Value >>= mnMaxImageResolution;
else if ( rProp.Name == "UseTaggedPDF" )
- rProp.Value >>= mbUseTaggedPDF;
+ rProp.Value >>= bUseTaggedPDF;
else if ( rProp.Name == "SelectPdfVersion" )
- rProp.Value >>= mnPDFTypeSelection;
+ rProp.Value >>= nPDFTypeSelection;
else if ( rProp.Name == "PDFUACompliance" )
- rProp.Value >>= mbPDFUACompliance;
+ rProp.Value >>= bPDFUACompliance;
else if ( rProp.Name == "ExportNotes" )
- rProp.Value >>= mbExportNotes;
+ rProp.Value >>= bExportNotes;
+ else if ( rProp.Name == "ExportNotesInMargin" )
+ rProp.Value >>= bExportNotesInMargin;
else if ( rProp.Name == "ExportNotesPages" )
- rProp.Value >>= mbExportNotesPages;
+ rProp.Value >>= bExportNotesPages;
else if ( rProp.Name == "ExportOnlyNotesPages" )
- rProp.Value >>= mbExportOnlyNotesPages;
+ rProp.Value >>= bExportOnlyNotesPages;
else if ( rProp.Name == "UseTransitionEffects" )
- rProp.Value >>= mbUseTransitionEffects;
+ rProp.Value >>= bUseTransitionEffects;
else if ( rProp.Name == "ExportFormFields" )
- rProp.Value >>= mbExportFormFields;
+ rProp.Value >>= bExportFormFields;
else if ( rProp.Name == "FormsType" )
- rProp.Value >>= mnFormsFormat;
+ rProp.Value >>= nFormsFormat;
else if ( rProp.Name == "AllowDuplicateFieldNames" )
- rProp.Value >>= mbAllowDuplicateFieldNames;
+ rProp.Value >>= bAllowDuplicateFieldNames;
// viewer properties
else if ( rProp.Name == "HideViewerToolbar" )
- rProp.Value >>= mbHideViewerToolbar;
+ rProp.Value >>= bHideViewerToolbar;
else if ( rProp.Name == "HideViewerMenubar" )
- rProp.Value >>= mbHideViewerMenubar;
+ rProp.Value >>= bHideViewerMenubar;
else if ( rProp.Name == "HideViewerWindowControls" )
- rProp.Value >>= mbHideViewerWindowControls;
+ rProp.Value >>= bHideViewerWindowControls;
else if ( rProp.Name == "ResizeWindowToInitialPage" )
- rProp.Value >>= mbFitWindow;
+ rProp.Value >>= bFitWindow;
else if ( rProp.Name == "CenterWindow" )
- rProp.Value >>= mbCenterWindow;
+ rProp.Value >>= bCenterWindow;
else if ( rProp.Name == "OpenInFullScreenMode" )
- rProp.Value >>= mbOpenInFullScreenMode;
+ rProp.Value >>= bOpenInFullScreenMode;
else if ( rProp.Name == "DisplayPDFDocumentTitle" )
- rProp.Value >>= mbDisplayPDFDocumentTitle;
+ rProp.Value >>= bDisplayPDFDocumentTitle;
else if ( rProp.Name == "InitialView" )
- rProp.Value >>= mnPDFDocumentMode;
+ rProp.Value >>= nPDFDocumentMode;
else if ( rProp.Name == "Magnification" )
- rProp.Value >>= mnPDFDocumentAction;
+ rProp.Value >>= nPDFDocumentAction;
else if ( rProp.Name == "Zoom" )
- rProp.Value >>= mnZoom;
+ rProp.Value >>= nZoom;
else if ( rProp.Name == "InitialPage" )
- rProp.Value >>= mnInitialPage;
+ rProp.Value >>= nInitialPage;
else if ( rProp.Name == "PageLayout" )
- rProp.Value >>= mnPDFPageLayout;
+ rProp.Value >>= nPDFPageLayout;
else if ( rProp.Name == "FirstPageOnLeft" )
rProp.Value >>= aContext.FirstPageLeft;
else if ( rProp.Name == "IsAddStream" )
- rProp.Value >>= mbAddStream;
+ rProp.Value >>= bAddStream;
else if ( rProp.Name == "Watermark" )
rProp.Value >>= msWatermark;
+ else if ( rProp.Name == "WatermarkColor" )
+ {
+ sal_Int32 nColor{};
+ if (rProp.Value >>= nColor)
+ {
+ maWatermarkColor = Color(ColorTransparency, nColor);
+ }
+ }
+ else if (rProp.Name == "WatermarkFontHeight")
+ {
+ sal_Int32 nFontHeight{};
+ if (rProp.Value >>= nFontHeight)
+ {
+ moWatermarkFontHeight = nFontHeight;
+ }
+ }
+ else if (rProp.Name == "WatermarkRotateAngle")
+ {
+ sal_Int32 nRotateAngle{};
+ if (rProp.Value >>= nRotateAngle)
+ {
+ moWatermarkRotateAngle = Degree10(nRotateAngle);
+ }
+ }
+ else if (rProp.Name == "WatermarkFontName")
+ {
+ OUString aFontName{};
+ if (rProp.Value >>= aFontName)
+ {
+ maWatermarkFontName = aFontName;
+ }
+ }
else if ( rProp.Name == "TiledWatermark" )
rProp.Value >>= msTiledWatermark;
// now all the security related properties...
else if ( rProp.Name == "EncryptFile" )
- rProp.Value >>= mbEncrypt;
+ rProp.Value >>= bEncrypt;
else if ( rProp.Name == "DocumentOpenPassword" )
rProp.Value >>= aOpenPassword;
else if ( rProp.Name == "RestrictPermissions" )
- rProp.Value >>= mbRestrictPermissions;
+ rProp.Value >>= bRestrictPermissions;
else if ( rProp.Name == "PermissionPassword" )
rProp.Value >>= aPermissionPassword;
else if ( rProp.Name == "PreparedPasswords" )
@@ -548,81 +646,99 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
else if ( rProp.Name == "PreparedPermissionPassword" )
rProp.Value >>= aPreparedPermissionPassword;
else if ( rProp.Name == "Printing" )
- rProp.Value >>= mnPrintAllowed;
+ rProp.Value >>= nPrintAllowed;
else if ( rProp.Name == "Changes" )
- rProp.Value >>= mnChangesAllowed;
+ rProp.Value >>= nChangesAllowed;
else if ( rProp.Name == "EnableCopyingOfContent" )
- rProp.Value >>= mbCanCopyOrExtract;
+ rProp.Value >>= bCanCopyOrExtract;
else if ( rProp.Name == "EnableTextAccessForAccessibilityTools" )
- rProp.Value >>= mbCanExtractForAccessibility;
+ rProp.Value >>= bCanExtractForAccessibility;
// i56629 links extra (relative links and other related stuff)
else if ( rProp.Name == "ExportLinksRelativeFsys" )
- rProp.Value >>= mbExportRelativeFsysLinks;
+ rProp.Value >>= bExportRelativeFsysLinks;
else if ( rProp.Name == "PDFViewSelection" )
- rProp.Value >>= mnDefaultLinkAction;
+ rProp.Value >>= nDefaultLinkAction;
else if ( rProp.Name == "ConvertOOoTargetToPDFTarget" )
- rProp.Value >>= mbConvertOOoTargetToPDFTarget;
+ rProp.Value >>= bConvertOOoTargetToPDFTarget;
else if ( rProp.Name == "ExportBookmarksToPDFDestination" )
- rProp.Value >>= mbExportBmkToDest;
+ rProp.Value >>= bExportBmkToDest;
else if ( rProp.Name == "ExportBookmarks" )
- rProp.Value >>= mbExportBookmarks;
+ rProp.Value >>= bExportBookmarks;
else if ( rProp.Name == "ExportHiddenSlides" )
- rProp.Value >>= mbExportHiddenSlides;
+ rProp.Value >>= bExportHiddenSlides;
else if ( rProp.Name == "SinglePageSheets" )
- rProp.Value >>= mbSinglePageSheets;
+ rProp.Value >>= bSinglePageSheets;
else if ( rProp.Name == "OpenBookmarkLevels" )
- rProp.Value >>= mnOpenBookmarkLevels;
+ rProp.Value >>= nOpenBookmarkLevels;
else if ( rProp.Name == "SignPDF" )
- rProp.Value >>= mbSignPDF;
+ rProp.Value >>= bSignPDF;
else if ( rProp.Name == "SignatureLocation" )
- rProp.Value >>= msSignLocation;
+ rProp.Value >>= sSignLocation;
else if ( rProp.Name == "SignatureReason" )
- rProp.Value >>= msSignReason;
+ rProp.Value >>= sSignReason;
else if ( rProp.Name == "SignatureContactInfo" )
- rProp.Value >>= msSignContact;
+ rProp.Value >>= sSignContact;
else if ( rProp.Name == "SignaturePassword" )
- rProp.Value >>= msSignPassword;
+ rProp.Value >>= sSignPassword;
else if ( rProp.Name == "SignatureCertificate" )
- rProp.Value >>= maSignCertificate;
+ rProp.Value >>= aSignCertificate;
+ else if (rProp.Name == "SignCertificateSubjectName")
+ rProp.Value >>= aSignCertificateSubjectName;
else if ( rProp.Name == "SignatureTSA" )
- rProp.Value >>= msSignTSA;
+ rProp.Value >>= sSignTSA;
else if ( rProp.Name == "ExportPlaceholders" )
- rProp.Value >>= mbExportPlaceholders;
+ rProp.Value >>= bExportPlaceholders;
else if ( rProp.Name == "UseReferenceXObject" )
- rProp.Value >>= mbUseReferenceXObject;
+ rProp.Value >>= bUseReferenceXObject;
// Redaction & bitmap related stuff
else if ( rProp.Name == "IsRedactMode" )
rProp.Value >>= mbIsRedactMode;
+ // Math-specific render options
+ else if (rProp.Name == "TitleRow")
+ oMathTitleRow = rProp;
+ else if (rProp.Name == "FormulaText")
+ oMathFormulaText = rProp;
+ else if (rProp.Name == "Border")
+ oMathBorder = rProp;
+ else if (rProp.Name == "PrintFormat")
+ oMathPrintFormat = rProp;
+ else if (rProp.Name == "PrintScale")
+ oMathPrintScale = rProp;
+ }
+
+ if (!aSignCertificate.is() && !aSignCertificateSubjectName.isEmpty())
+ {
+ aSignCertificate = GetCertificateFromSubjectName(aSignCertificateSubjectName);
}
aContext.URL = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
// set the correct version, depending on user request
- switch( mnPDFTypeSelection )
+ switch( nPDFTypeSelection )
{
default:
case 0:
- aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_6;
+ aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_7;
break;
case 1:
aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_1;
- mbUseTaggedPDF = true; // force the tagged PDF as well
+ bUseTaggedPDF = true; // force the tagged PDF as well
mbRemoveTransparencies = true; // does not allow transparencies
- mbEncrypt = false; // no encryption
+ bEncrypt = false; // no encryption
xEnc.clear();
break;
case 2:
aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_2;
- mbUseTaggedPDF = true; // force the tagged PDF as well
+ bUseTaggedPDF = true; // force the tagged PDF as well
mbRemoveTransparencies = false; // does allow transparencies
- mbEncrypt = false; // no encryption
+ bEncrypt = false; // no encryption
xEnc.clear();
break;
case 3:
aContext.Version = vcl::PDFWriter::PDFVersion::PDF_A_3;
- mbUseTaggedPDF = true; // force the tagged PDF as well
+ bUseTaggedPDF = true; // force the tagged PDF as well
mbRemoveTransparencies = false; // does allow transparencies
- mbEncrypt = false; // no encryption
+ bEncrypt = false; // no encryption
xEnc.clear();
break;
case 15:
@@ -631,30 +747,38 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
case 16:
aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_6;
break;
+ case 17:
+ aContext.Version = vcl::PDFWriter::PDFVersion::PDF_1_7;
+ break;
}
// PDF/UA support
- aContext.UniversalAccessibilityCompliance = mbPDFUACompliance;
- if (mbPDFUACompliance)
+ aContext.UniversalAccessibilityCompliance = bPDFUACompliance;
+ if (bPDFUACompliance)
{
- mbUseTaggedPDF = true;
+ // ISO 14289-1:2014, Clause: 7.1
+ bUseTaggedPDF = true;
+ // ISO 14289-1:2014, Clause: 7.16
+ bCanExtractForAccessibility = true;
+ // ISO 14289-1:2014, Clause: 7.20
+ bUseReferenceXObject = false;
}
// copy in context the values default in the constructor or set by the FilterData sequence of properties
- aContext.Tagged = mbUseTaggedPDF;
+ aContext.Tagged = bUseTaggedPDF;
// values used in viewer
- aContext.HideViewerToolbar = mbHideViewerToolbar;
- aContext.HideViewerMenubar = mbHideViewerMenubar;
- aContext.HideViewerWindowControls = mbHideViewerWindowControls;
- aContext.FitWindow = mbFitWindow;
- aContext.CenterWindow = mbCenterWindow;
- aContext.OpenInFullScreenMode = mbOpenInFullScreenMode;
- aContext.DisplayPDFDocumentTitle = mbDisplayPDFDocumentTitle;
- aContext.InitialPage = mnInitialPage-1;
- aContext.OpenBookmarkLevels = mnOpenBookmarkLevels;
-
- switch( mnPDFDocumentMode )
+ aContext.HideViewerToolbar = bHideViewerToolbar;
+ aContext.HideViewerMenubar = bHideViewerMenubar;
+ aContext.HideViewerWindowControls = bHideViewerWindowControls;
+ aContext.FitWindow = bFitWindow;
+ aContext.CenterWindow = bCenterWindow;
+ aContext.OpenInFullScreenMode = bOpenInFullScreenMode;
+ aContext.DisplayPDFDocumentTitle = bDisplayPDFDocumentTitle;
+ aContext.InitialPage = nInitialPage-1;
+ aContext.OpenBookmarkLevels = nOpenBookmarkLevels;
+
+ switch( nPDFDocumentMode )
{
default:
case 0:
@@ -667,7 +791,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
aContext.PDFDocumentMode = vcl::PDFWriter::UseThumbs;
break;
}
- switch( mnPDFDocumentAction )
+ switch( nPDFDocumentAction )
{
default:
case 0:
@@ -684,11 +808,11 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
break;
case 4:
aContext.PDFDocumentAction = vcl::PDFWriter::ActionZoom;
- aContext.Zoom = mnZoom;
+ aContext.Zoom = nZoom;
break;
}
- switch( mnPDFPageLayout )
+ switch( nPDFPageLayout )
{
default:
case 0:
@@ -712,20 +836,20 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
{
// set check for permission change password
// if not enabled and no permission password, force permissions to default as if PDF where without encryption
- if( mbRestrictPermissions && (xEnc.is() || !aPermissionPassword.isEmpty()) )
+ if( bRestrictPermissions && (xEnc.is() || !aPermissionPassword.isEmpty()) )
{
- mbEncrypt = true; // permission set as desired, done after
+ bEncrypt = true; // permission set as desired, done after
}
else
{
// force permission to default
- mnPrintAllowed = 2 ;
- mnChangesAllowed = 4 ;
- mbCanCopyOrExtract = true;
- mbCanExtractForAccessibility = true ;
+ nPrintAllowed = 2 ;
+ nChangesAllowed = 4 ;
+ bCanCopyOrExtract = true;
+ bCanExtractForAccessibility = true ;
}
- switch( mnPrintAllowed )
+ switch( nPrintAllowed )
{
case 0: // initialized when aContext is build, means no printing
break;
@@ -738,7 +862,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
break;
}
- switch( mnChangesAllowed )
+ switch( nChangesAllowed )
{
case 0: // already in struct PDFSecPermissions CTOR
break;
@@ -760,11 +884,11 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
break;
}
- aContext.Encryption.CanCopyOrExtract = mbCanCopyOrExtract;
- aContext.Encryption.CanExtractForAccessibility = mbCanExtractForAccessibility;
- if( mbEncrypt && ! xEnc.is() )
+ aContext.Encryption.CanCopyOrExtract = bCanCopyOrExtract;
+ aContext.Encryption.CanExtractForAccessibility = bCanExtractForAccessibility;
+ if( bEncrypt && ! xEnc.is() )
xEnc = vcl::PDFWriter::InitEncryption( aPermissionPassword, aOpenPassword );
- if( mbEncrypt && !aPermissionPassword.isEmpty() && ! aPreparedPermissionPassword.hasElements() )
+ if( bEncrypt && !aPermissionPassword.isEmpty() && ! aPreparedPermissionPassword.hasElements() )
aPreparedPermissionPassword = comphelper::OStorageHelper::CreatePackageEncryptionData( aPermissionPassword );
}
// after this point we don't need the legacy clear passwords anymore
@@ -777,7 +901,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
* FIXME: the entries are only implicitly defined by the resource file. Should there
* ever be an additional form submit format this could get invalid.
*/
- switch( mnFormsFormat )
+ switch( nFormsFormat )
{
case 1:
aContext.SubmitFormat = vcl::PDFWriter::PDF;
@@ -793,7 +917,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
aContext.SubmitFormat = vcl::PDFWriter::FDF;
break;
}
- aContext.AllowDuplicateFieldNames = mbAllowDuplicateFieldNames;
+ aContext.AllowDuplicateFieldNames = bAllowDuplicateFieldNames;
// get model
Reference< frame::XModel > xModel( mxSrcDoc, UNO_QUERY );
@@ -802,9 +926,9 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
// set the base URL of the file: then base URL
aContext.BaseURL = xModel->getURL();
// relative link option is private to PDF Export filter and limited to local filesystem only
- aContext.RelFsys = mbExportRelativeFsysLinks;
- // determine the default acton for PDF links
- switch( mnDefaultLinkAction )
+ aContext.RelFsys = bExportRelativeFsysLinks;
+ // determine the default action for PDF links
+ switch( nDefaultLinkAction )
{
default:
// default: URI, without fragment conversion (the bookmark in PDF may not work)
@@ -821,7 +945,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
aContext.DefaultLinkAction = vcl::PDFWriter::URIActionDestination;
break;
}
- aContext.ConvertOOoTargetToPDFTarget = mbConvertOOoTargetToPDFTarget;
+ aContext.ConvertOOoTargetToPDFTarget = bConvertOOoTargetToPDFTarget;
// check for Link Launch action, not allowed on PDF/A-1
// this code chunk checks when the filter is called from scripting
@@ -835,14 +959,14 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
}
}
- aContext.SignPDF = mbSignPDF;
- aContext.SignLocation = msSignLocation;
- aContext.SignContact = msSignContact;
- aContext.SignReason = msSignReason;
- aContext.SignPassword = msSignPassword;
- aContext.SignCertificate = maSignCertificate;
- aContext.SignTSA = msSignTSA;
- aContext.UseReferenceXObject = mbUseReferenceXObject;
+ aContext.SignPDF = bSignPDF;
+ aContext.SignLocation = sSignLocation;
+ aContext.SignContact = sSignContact;
+ aContext.SignReason = sSignReason;
+ aContext.SignPassword = sSignPassword;
+ aContext.SignCertificate = aSignCertificate;
+ aContext.SignTSA = sSignTSA;
+ aContext.UseReferenceXObject = bUseReferenceXObject;
// all context data set, time to create the printing device
vcl::PDFWriter aPDFWriter( aContext, xEnc );
@@ -851,14 +975,22 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
DBG_ASSERT( pOut, "PDFExport::Export: no reference device" );
xDevice->SetOutputDevice(pOut);
- if( mbAddStream )
+ if( bAddStream )
{
// export stream
// get mimetype
OUString aSrcMimetype = getMimetypeForDocument( mxContext, mxSrcDoc );
- aPDFWriter.AddStream( aSrcMimetype,
- new PDFExportStreamDoc( mxSrcDoc, aPreparedPermissionPassword )
- );
+ OUString aExt;
+ if (aSrcMimetype == "application/vnd.oasis.opendocument.text")
+ aExt = ".odt";
+ else if (aSrcMimetype == "application/vnd.oasis.opendocument.presentation")
+ aExt = ".odp";
+ else if (aSrcMimetype == "application/vnd.oasis.opendocument.spreadsheet")
+ aExt = ".ods";
+ else if (aSrcMimetype == "application/vnd.oasis.opendocument.graphics")
+ aExt = ".odg";
+ std::unique_ptr<vcl::PDFOutputStream> pStream(new PDFExportStreamDoc(mxSrcDoc, aPreparedPermissionPassword));
+ aPDFWriter.AddAttachedFile("Original" + aExt, aSrcMimetype, u"Embedded original document of this PDF file"_ustr, std::move(pStream));
}
if ( pOut )
@@ -866,28 +998,41 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
DBG_ASSERT( pOut->GetExtOutDevData() == nullptr, "PDFExport: ExtOutDevData already set!!!" );
vcl::PDFExtOutDevData aPDFExtOutDevData( *pOut );
pOut->SetExtOutDevData( &aPDFExtOutDevData );
- aPDFExtOutDevData.SetIsExportNotes( mbExportNotes );
- aPDFExtOutDevData.SetIsExportTaggedPDF( mbUseTaggedPDF );
- aPDFExtOutDevData.SetIsExportTransitionEffects( mbUseTransitionEffects );
- aPDFExtOutDevData.SetIsExportFormFields( mbExportFormFields );
- aPDFExtOutDevData.SetIsExportBookmarks( mbExportBookmarks );
- aPDFExtOutDevData.SetIsExportHiddenSlides( mbExportHiddenSlides );
- aPDFExtOutDevData.SetIsSinglePageSheets( mbSinglePageSheets );
+ aPDFExtOutDevData.SetIsExportNotes( bExportNotes );
+ aPDFExtOutDevData.SetIsExportNotesInMargin( bExportNotesInMargin );
+ aPDFExtOutDevData.SetIsExportTaggedPDF( bUseTaggedPDF );
+ aPDFExtOutDevData.SetIsExportTransitionEffects( bUseTransitionEffects );
+ aPDFExtOutDevData.SetIsExportFormFields( bExportFormFields );
+ aPDFExtOutDevData.SetIsExportBookmarks( bExportBookmarks );
+ aPDFExtOutDevData.SetIsExportHiddenSlides( bExportHiddenSlides );
+ aPDFExtOutDevData.SetIsSinglePageSheets( bSinglePageSheets );
aPDFExtOutDevData.SetIsLosslessCompression( mbUseLosslessCompression );
aPDFExtOutDevData.SetCompressionQuality( mnQuality );
aPDFExtOutDevData.SetIsReduceImageResolution( mbReduceImageResolution );
- aPDFExtOutDevData.SetIsExportNamedDestinations( mbExportBmkToDest );
+ aPDFExtOutDevData.SetIsExportNamedDestinations( bExportBmkToDest );
- Sequence< PropertyValue > aRenderOptions{
+ std::vector<PropertyValue> aRenderOptionsVector{
comphelper::makePropertyValue("RenderDevice", uno::Reference<awt::XDevice>(xDevice)),
comphelper::makePropertyValue("ExportNotesPages", false),
comphelper::makePropertyValue("IsFirstPage", true),
comphelper::makePropertyValue("IsLastPage", false),
comphelper::makePropertyValue("IsSkipEmptyPages", mbSkipEmptyPages),
comphelper::makePropertyValue("PageRange", aPageRange),
- comphelper::makePropertyValue("ExportPlaceholders", mbExportPlaceholders),
- comphelper::makePropertyValue("SinglePageSheets", mbSinglePageSheets)
+ comphelper::makePropertyValue("ExportPlaceholders", bExportPlaceholders),
+ comphelper::makePropertyValue("SinglePageSheets", bSinglePageSheets),
+ comphelper::makePropertyValue("ExportNotesInMargin", bExportNotesInMargin)
};
+ if (oMathTitleRow)
+ aRenderOptionsVector.push_back(*oMathTitleRow);
+ if (oMathFormulaText)
+ aRenderOptionsVector.push_back(*oMathFormulaText);
+ if (oMathBorder)
+ aRenderOptionsVector.push_back(*oMathBorder);
+ if (oMathPrintFormat)
+ aRenderOptionsVector.push_back(*oMathPrintFormat);
+ if (oMathPrintScale)
+ aRenderOptionsVector.push_back(*oMathPrintScale);
+ Sequence aRenderOptions = comphelper::containerToSequence(aRenderOptionsVector);
Any& rExportNotesValue = aRenderOptions.getArray()[ 1 ].Value;
if( !aPageRange.isEmpty() || !aSelection.hasValue() )
@@ -895,11 +1040,10 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
aSelection = Any();
aSelection <<= mxSrcDoc;
}
- bool bExportNotesPages = false;
bool bReChangeToNormalView = false;
- static const OUStringLiteral sShowOnlineLayout( u"ShowOnlineLayout" );
+ static constexpr OUString sShowOnlineLayout( u"ShowOnlineLayout"_ustr );
bool bReHideWhitespace = false;
- static const OUStringLiteral sHideWhitespace(u"HideWhitespace");
+ static constexpr OUString sHideWhitespace(u"HideWhitespace"_ustr);
uno::Reference< beans::XPropertySet > xViewProperties;
if ( aCreator == "Writer" )
@@ -912,14 +1056,14 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
xViewProperties->getPropertyValue( sShowOnlineLayout ) >>= bReChangeToNormalView;
if( bReChangeToNormalView )
{
- xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( false ) );
+ xViewProperties->setPropertyValue( sShowOnlineLayout, uno::Any( false ) );
}
// Also, disable hide-whitespace during export.
xViewProperties->getPropertyValue(sHideWhitespace) >>= bReHideWhitespace;
if (bReHideWhitespace)
{
- xViewProperties->setPropertyValue(sHideWhitespace, uno::makeAny(false));
+ xViewProperties->setPropertyValue(sHideWhitespace, uno::Any(false));
}
}
catch( const uno::Exception& )
@@ -930,15 +1074,17 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
const sal_Int32 nPageCount = xRenderable->getRendererCount( aSelection, aRenderOptions );
- if ( mbExportNotesPages && aCreator == "Impress" )
+ if ( bExportNotesPages && aCreator == "Impress" )
{
uno::Reference< drawing::XShapes > xShapes; // do not allow to export notes when exporting a selection
- if ( ! ( aSelection >>= xShapes ) )
- bExportNotesPages = true;
+ if ( aSelection >>= xShapes )
+ bExportNotesPages = false;
}
- const bool bExportPages = !bExportNotesPages || !mbExportOnlyNotesPages;
+ else
+ bExportNotesPages = false;
+ const bool bExportPages = !bExportNotesPages || !bExportOnlyNotesPages;
- if( aPageRange.isEmpty() || mbSinglePageSheets)
+ if( aPageRange.isEmpty() || bSinglePageSheets)
{
aPageRange = OUString::number( 1 ) + "-" + OUString::number(nPageCount );
}
@@ -946,11 +1092,10 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
if ( mxStatusIndicator.is() )
{
- std::locale loc(Translate::Create("flt"));
sal_Int32 nTotalPageCount = aRangeEnum.size();
if ( bExportPages && bExportNotesPages )
nTotalPageCount *= 2;
- mxStatusIndicator->start(Translate::get(PDF_PROGRESS_BAR, loc), nTotalPageCount);
+ mxStatusIndicator->start(FilterResId(PDF_PROGRESS_BAR), nTotalPageCount);
}
bRet = nPageCount > 0;
@@ -982,7 +1127,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
{
try
{
- xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( true ) );
+ xViewProperties->setPropertyValue( sShowOnlineLayout, uno::Any( true ) );
}
catch( const uno::Exception& )
{
@@ -992,7 +1137,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
{
try
{
- xViewProperties->setPropertyValue( sHideWhitespace, uno::makeAny( true ) );
+ xViewProperties->setPropertyValue( sHideWhitespace, uno::Any( true ) );
}
catch( const uno::Exception& )
{
@@ -1012,14 +1157,13 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
namespace
{
-typedef cppu::WeakComponentImplHelper< task::XInteractionRequest > PDFErrorRequestBase;
+typedef comphelper::WeakComponentImplHelper< task::XInteractionRequest > PDFErrorRequestBase;
-class PDFErrorRequest : private cppu::BaseMutex,
- public PDFErrorRequestBase
+class PDFErrorRequest : public PDFErrorRequestBase
{
task::PDFExportException maExc;
public:
- explicit PDFErrorRequest( const task::PDFExportException& i_rExc );
+ explicit PDFErrorRequest( task::PDFExportException aExc );
// XInteractionRequest
virtual uno::Any SAL_CALL getRequest() override;
@@ -1027,16 +1171,15 @@ public:
};
-PDFErrorRequest::PDFErrorRequest( const task::PDFExportException& i_rExc ) :
- PDFErrorRequestBase( m_aMutex ),
- maExc( i_rExc )
+PDFErrorRequest::PDFErrorRequest( task::PDFExportException aExc ) :
+ maExc(std::move( aExc ))
{
}
uno::Any SAL_CALL PDFErrorRequest::getRequest()
{
- osl::MutexGuard const guard( m_aMutex );
+ std::unique_lock guard( m_aMutex );
uno::Any aRet;
aRet <<= maExc;
@@ -1058,7 +1201,7 @@ void PDFExport::showErrors( const std::set< vcl::PDFWriter::ErrorCode >& rErrors
{
task::PDFExportException aExc;
aExc.ErrorCodes = comphelper::containerToSequence<sal_Int32>( rErrors );
- Reference< task::XInteractionRequest > xReq( new PDFErrorRequest( aExc ) );
+ Reference< task::XInteractionRequest > xReq( new PDFErrorRequest( std::move(aExc) ) );
mxIH->handle( xReq );
}
}
@@ -1087,7 +1230,7 @@ void PDFExport::ImplExportPage( vcl::PDFWriter& rWriter, vcl::PDFExtOutDevData&
// Throw them all away in the absence of a way to reposition them to new positions of
// their replacements.
if (aCtx.m_bTransparenciesWereRemoved)
- rPDFExtOutDevData.ResetSyncData();
+ rPDFExtOutDevData.ResetSyncData(&rWriter);
}
else
{
@@ -1103,7 +1246,7 @@ void PDFExport::ImplExportPage( vcl::PDFWriter& rWriter, vcl::PDFExtOutDevData&
rWriter.PlayMetafile( aMtf, aCtx, &rPDFExtOutDevData );
- rPDFExtOutDevData.ResetSyncData();
+ rPDFExtOutDevData.ResetSyncData(nullptr);
if (!msWatermark.isEmpty())
{
@@ -1118,7 +1261,7 @@ void PDFExport::ImplExportPage( vcl::PDFWriter& rWriter, vcl::PDFExtOutDevData&
void PDFExport::ImplWriteWatermark( vcl::PDFWriter& rWriter, const Size& rPageSize )
{
- vcl::Font aFont( "Helvetica", Size( 0, 3*rPageSize.Height()/4 ) );
+ vcl::Font aFont( maWatermarkFontName, Size( 0, moWatermarkFontHeight ? *moWatermarkFontHeight : 3*rPageSize.Height()/4 ) );
aFont.SetItalic( ITALIC_NONE );
aFont.SetWidthType( WIDTH_NORMAL );
aFont.SetWeight( WEIGHT_NORMAL );
@@ -1130,25 +1273,43 @@ void PDFExport::ImplWriteWatermark( vcl::PDFWriter& rWriter, const Size& rPageSi
aFont.SetOrientation( 2700_deg10 );
}
+ if (moWatermarkRotateAngle)
+ {
+ aFont.SetOrientation(*moWatermarkRotateAngle);
+ if (rPageSize.Width() < rPageSize.Height())
+ {
+ // Set text width based on the shorter side, so rotation can't push text outside the
+ // page boundaries.
+ nTextWidth = rPageSize.Width();
+ }
+ }
+
// adjust font height for text to fit
OutputDevice* pDev = rWriter.GetReferenceDevice();
pDev->Push();
pDev->SetFont( aFont );
pDev->SetMapMode( MapMode( MapUnit::MapPoint ) );
int w = 0;
- while( ( w = pDev->GetTextWidth( msWatermark ) ) > nTextWidth )
+ if (moWatermarkFontHeight)
{
- if (w == 0)
- break;
- tools::Long nNewHeight = aFont.GetFontHeight() * nTextWidth / w;
- if( nNewHeight == aFont.GetFontHeight() )
+ w = pDev->GetTextWidth(msWatermark);
+ }
+ else
+ {
+ while( ( w = pDev->GetTextWidth( msWatermark ) ) > nTextWidth )
{
- nNewHeight--;
- if( nNewHeight <= 0 )
+ if (w == 0)
break;
+ tools::Long nNewHeight = aFont.GetFontHeight() * nTextWidth / w;
+ if( nNewHeight == aFont.GetFontHeight() )
+ {
+ nNewHeight--;
+ if( nNewHeight <= 0 )
+ break;
+ }
+ aFont.SetFontHeight( nNewHeight );
+ pDev->SetFont( aFont );
}
- aFont.SetFontHeight( nNewHeight );
- pDev->SetFont( aFont );
}
tools::Long nTextHeight = pDev->GetTextHeight();
// leave some maneuvering room for rounding issues, also
@@ -1157,9 +1318,18 @@ void PDFExport::ImplWriteWatermark( vcl::PDFWriter& rWriter, const Size& rPageSi
pDev->Pop();
rWriter.Push();
+ // tdf#152235 tag around the reference to the XObject on the page
+ sal_Int32 const id = rWriter.EnsureStructureElement();
+ rWriter.InitStructureElement(id, vcl::PDFWriter::NonStructElement, ::std::u16string_view());
+ rWriter.BeginStructureElement(id);
+ rWriter.SetStructureAttribute(vcl::PDFWriter::Type, vcl::PDFWriter::Pagination);
+ rWriter.SetStructureAttribute(vcl::PDFWriter::Subtype, vcl::PDFWriter::Watermark);
+ // HACK: this should produce *nothing* itself but is necessary to output
+ // the Artifact tag here, not inside the XObject
+ rWriter.DrawPolyLine({});
rWriter.SetMapMode( MapMode( MapUnit::MapPoint ) );
rWriter.SetFont( aFont );
- rWriter.SetTextColor( COL_LIGHTGREEN );
+ rWriter.SetTextColor(maWatermarkColor);
Point aTextPoint;
tools::Rectangle aTextRect;
if( rPageSize.Width() > rPageSize.Height() )
@@ -1176,10 +1346,30 @@ void PDFExport::ImplWriteWatermark( vcl::PDFWriter& rWriter, const Size& rPageSi
(rPageSize.Height()-w)/2 );
aTextRect = tools::Rectangle( aTextPoint, Size( nTextHeight, w ) );
}
+
+ if (moWatermarkRotateAngle)
+ {
+ // First set the text's starting point to the center of the page.
+ tools::Rectangle aPageRectangle(Point(0, 0), rPageSize);
+ aTextPoint = aPageRectangle.Center();
+ // Then adjust it so that the text remains centered, based on the rotation angle.
+ basegfx::B2DPolygon aTextPolygon
+ = basegfx::utils::createPolygonFromRect(basegfx::B2DRectangle(0, -nTextHeight, w, 0));
+ basegfx::B2DHomMatrix aMatrix;
+ aMatrix.rotate(-1 * toRadians(*moWatermarkRotateAngle));
+ aTextPolygon.transform(aMatrix);
+ basegfx::B2DPoint aPolygonCenter = aTextPolygon.getB2DRange().getCenter();
+ aTextPoint.AdjustX(-aPolygonCenter.getX());
+ aTextPoint.AdjustY(-aPolygonCenter.getY());
+
+ aTextRect = aPageRectangle;
+ }
+
rWriter.SetClipRegion();
rWriter.BeginTransparencyGroup();
rWriter.DrawText( aTextPoint, msWatermark );
rWriter.EndTransparencyGroup( aTextRect, 50 );
+ rWriter.EndStructureElement();
rWriter.Pop();
}
@@ -1226,6 +1416,15 @@ void PDFExport::ImplWriteTiledWatermark( vcl::PDFWriter& rWriter, const Size& rP
pDev->Pop();
rWriter.Push();
+ // tdf#152235 tag around the reference to the XObject on the page
+ sal_Int32 const id = rWriter.EnsureStructureElement();
+ rWriter.InitStructureElement(id, vcl::PDFWriter::NonStructElement, ::std::u16string_view());
+ rWriter.BeginStructureElement(id);
+ rWriter.SetStructureAttribute(vcl::PDFWriter::Type, vcl::PDFWriter::Pagination);
+ rWriter.SetStructureAttribute(vcl::PDFWriter::Subtype, vcl::PDFWriter::Watermark);
+ // HACK: this should produce *nothing* itself but is necessary to output
+ // the Artifact tag here, not inside the XObject
+ rWriter.DrawPolyLine({});
rWriter.SetMapMode( MapMode( MapUnit::MapPoint ) );
rWriter.SetFont(aFont);
rWriter.SetTextColor( Color(19,20,22) );
@@ -1261,6 +1460,7 @@ void PDFExport::ImplWriteTiledWatermark( vcl::PDFWriter& rWriter, const Size& rP
aTextPoint.Move( nTextWidth*1.5, 0 );
}
+ rWriter.EndStructureElement();
rWriter.Pop();
}