blob: 68e77cd828007c88551185bd60f5ed3bb86aeb08 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_filter.hxx"
#include "pdfexport.hxx"
#include "impdialog.hxx"
#include "pdf.hrc"
#include "tools/urlobj.hxx"
#include "tools/fract.hxx"
#include "tools/poly.hxx"
#include "vcl/mapmod.hxx"
#include "vcl/virdev.hxx"
#include "vcl/metaact.hxx"
#include "vcl/gdimtf.hxx"
#include "vcl/jobset.hxx"
#include "vcl/salbtype.hxx"
#include "vcl/bmpacc.hxx"
#include "vcl/svapp.hxx"
#include "toolkit/awt/vclxdevice.hxx"
#include "unotools/localfilehelper.hxx"
#include "unotools/processfactory.hxx"
#include "svtools/FilterConfigItem.hxx"
#include "svtools/filter.hxx"
#include "svl/solar.hrc"
#include "comphelper/string.hxx"
#include "comphelper/storagehelper.hxx"
#include "unotools/streamwrap.hxx"
#include "com/sun/star/io/XSeekable.hpp"
#include "basegfx/polygon/b2dpolygon.hxx"
#include "basegfx/polygon/b2dpolypolygon.hxx"
#include "basegfx/polygon/b2dpolygontools.hxx"
#include "unotools/saveopt.hxx" // only for testing of relative saving options in PDF
#include "vcl/graphictools.hxx"
#include "com/sun/star/beans/XPropertySet.hpp"
#include "com/sun/star/awt/Rectangle.hpp"
#include "com/sun/star/awt/XDevice.hpp"
#include "com/sun/star/util/MeasureUnit.hpp"
#include "com/sun/star/frame/XModel.hpp"
#include "com/sun/star/frame/XModuleManager.hpp"
#include "com/sun/star/frame/XStorable.hpp"
#include "com/sun/star/frame/XController.hpp"
#include "com/sun/star/document/XDocumentProperties.hpp"
#include "com/sun/star/document/XDocumentPropertiesSupplier.hpp"
#include "com/sun/star/container/XNameAccess.hpp"
#include "com/sun/star/view/XViewSettingsSupplier.hpp"
#include "com/sun/star/task/XInteractionRequest.hpp"
#include "com/sun/star/task/PDFExportException.hpp"
#include "unotools/configmgr.hxx"
#include "cppuhelper/exc_hlp.hxx"
#include "cppuhelper/compbase1.hxx"
#include "cppuhelper/basemutex.hxx"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/drawing/XShapes.hpp"
#include "com/sun/star/graphic/XGraphicProvider.hpp"
using namespace ::rtl;
using namespace ::vcl;
using namespace ::com::sun::star;
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::PDFExport( const Reference< XComponent >& rxSrcDoc,
const Reference< task::XStatusIndicator >& rxStatusIndicator,
const Reference< task::XInteractionHandler >& rxIH,
const Reference< lang::XMultiServiceFactory >& xFactory ) :
mxSrcDoc ( rxSrcDoc ),
mxMSF ( xFactory ),
mxStatusIndicator ( rxStatusIndicator ),
mxIH ( rxIH ),
mbUseTaggedPDF ( sal_False ),
mnPDFTypeSelection ( 0 ),
mbExportNotes ( sal_True ),
mbExportNotesPages ( sal_False ),
mbEmbedStandardFonts ( sal_False ),//in preparation for i54636 and i76458.
//already used for i59651 (PDF/A-1)
mbUseTransitionEffects ( sal_True ),
mbExportBookmarks ( sal_True ),
mnOpenBookmarkLevels ( -1 ),
mbUseLosslessCompression ( sal_False ),
mbReduceImageResolution ( sal_False ),
mbSkipEmptyPages ( sal_True ),
mbAddStream ( sal_False ),
mnMaxImageResolution ( 300 ),
mnQuality ( 90 ),
mnFormsFormat ( 0 ),
mbExportFormFields ( sal_True ),
mbAllowDuplicateFieldNames ( sal_False ),
mnProgressValue ( 0 ),
mbRemoveTransparencies ( sal_False ),
mbWatermark ( sal_False ),
mbHideViewerToolbar ( sal_False ),
mbHideViewerMenubar ( sal_False ),
mbHideViewerWindowControls ( sal_False ),
mbFitWindow ( sal_False ),
mbCenterWindow ( sal_False ),
mbOpenInFullScreenMode ( sal_False ),
mbDisplayPDFDocumentTitle ( sal_True ),
mnPDFDocumentMode ( 0 ),
mnPDFDocumentAction ( 0 ),
mnZoom ( 100 ),
mnInitialPage ( 1 ),
mnPDFPageLayout ( 0 ),
mbFirstPageLeft ( sal_False ),
mbEncrypt ( sal_False ),
mbRestrictPermissions ( sal_False ),
mnPrintAllowed ( 2 ),
mnChangesAllowed ( 4 ),
mbCanCopyOrExtract ( sal_True ),
mbCanExtractForAccessibility( sal_True ),
mnCachePatternId ( -1 ),
//--->i56629
mbExportRelativeFsysLinks ( sal_False ),
mnDefaultLinkAction ( 0 ),
mbConvertOOoTargetToPDFTarget( sal_False ),
mbExportBmkToDest ( sal_False )
//<---
{
}
// -----------------------------------------------------------------------------
PDFExport::~PDFExport()
{
}
// -----------------------------------------------------------------------------
sal_Bool PDFExport::ExportSelection( vcl::PDFWriter& rPDFWriter, Reference< com::sun::star::view::XRenderable >& rRenderable, Any& rSelection,
MultiSelection aMultiSelection, Sequence< PropertyValue >& rRenderOptions, sal_Int32 nPageCount )
{
sal_Bool bRet = sal_False;
try
{
Any* pFirstPage = NULL;
Any* pLastPage = NULL;
sal_Bool bExportNotesPages = sal_False;
for( sal_Int32 nData = 0, nDataCount = rRenderOptions.getLength(); nData < nDataCount; ++nData )
{
if( rRenderOptions[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) ) )
pFirstPage = &rRenderOptions[ nData ].Value;
else if( rRenderOptions[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) ) )
pLastPage = &rRenderOptions[ nData ].Value;
else if( rRenderOptions[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) ) )
rRenderOptions[ nData ].Value >>= bExportNotesPages;
}
OutputDevice* pOut = rPDFWriter.GetReferenceDevice();
if( pOut )
{
vcl::PDFExtOutDevData* pPDFExtOutDevData = PTR_CAST( vcl::PDFExtOutDevData, pOut->GetExtOutDevData() );
if ( nPageCount )
{
pPDFExtOutDevData->SetIsExportNotesPages( bExportNotesPages );
sal_Int32 nSel = aMultiSelection.FirstSelected();
sal_Int32 nIncreasingPageNumber(0);
while ( nSel != sal_Int32(SFX_ENDOFSELECTION) )
{
Sequence< PropertyValue > aRenderer( rRenderable->getRenderer( nSel - 1, rSelection, rRenderOptions ) );
awt::Size aPageSize;
for( sal_Int32 nProperty = 0, nPropertyCount = aRenderer.getLength(); nProperty < nPropertyCount; ++nProperty )
{
if( aRenderer[ nProperty ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) )
aRenderer[ nProperty].Value >>= aPageSize;
}
// #119348# The PageNumber at PDFExtOutDevDatahas to be the target page number,
// e.g. when exporting only page#2 from two pages, the old mechanism would
// have set it to '1', but a üpage '1' does not yet exist in the export. This
// will make PDFWriterImpl::createLink and PDFWriterImpl::setLinkURL fail (see there).
pPDFExtOutDevData->SetCurrentPageNumber(nIncreasingPageNumber++ /* nSel - 1 */);
GDIMetaFile aMtf;
const MapMode aMapMode( MAP_100TH_MM );
const Size aMtfSize( aPageSize.Width, aPageSize.Height );
pOut->Push();
pOut->EnableOutput( sal_False );
pOut->SetMapMode( aMapMode );
aMtf.SetPrefSize( aMtfSize );
aMtf.SetPrefMapMode( aMapMode );
aMtf.Record( pOut );
// --> FME 2004-10-08 #i35176#
// IsLastPage property.
const sal_Int32 nCurrentRenderer = nSel - 1;
nSel = aMultiSelection.NextSelected();
if ( pLastPage && sal_Int32(SFX_ENDOFSELECTION) == nSel )
*pLastPage <<= sal_True;
// <--
rRenderable->render( nCurrentRenderer, rSelection, rRenderOptions );
aMtf.Stop();
aMtf.WindStart();
if( aMtf.GetActionCount() &&
( !mbSkipEmptyPages || aPageSize.Width || aPageSize.Height ) )
bRet = ImplExportPage( rPDFWriter, *pPDFExtOutDevData, aMtf ) || bRet;
pOut->Pop();
if ( mxStatusIndicator.is() )
mxStatusIndicator->setValue( mnProgressValue );
if ( pFirstPage )
*pFirstPage <<= sal_False;
++mnProgressValue;
}
}
else
{
bRet = sal_True; // #i18334# SJ: nPageCount == 0,
rPDFWriter.NewPage( 10000, 10000 ); // creating dummy page
rPDFWriter.SetMapMode( MAP_100TH_MM ); //
}
}
}
catch( RuntimeException )
{
}
return bRet;
}
class PDFExportStreamDoc : public vcl::PDFOutputStream
{
Reference< XComponent > m_xSrcDoc;
Sequence< beans::NamedValue > m_aPreparedPassword;
public:
PDFExportStreamDoc( const Reference< XComponent >& xDoc, const Sequence<beans::NamedValue>& rPwd )
: m_xSrcDoc( xDoc ),
m_aPreparedPassword( rPwd )
{}
virtual ~PDFExportStreamDoc();
virtual void write( const Reference< XOutputStream >& xStream );
};
PDFExportStreamDoc::~PDFExportStreamDoc()
{
}
void PDFExportStreamDoc::write( const Reference< XOutputStream >& xStream )
{
Reference< com::sun::star::frame::XStorable > xStore( m_xSrcDoc, UNO_QUERY );
if( xStore.is() )
{
Sequence< beans::PropertyValue > aArgs( 2 + ((m_aPreparedPassword.getLength() > 0) ? 1 : 0) );
aArgs.getArray()[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
aArgs.getArray()[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
aArgs.getArray()[1].Value <<= xStream;
if( m_aPreparedPassword.getLength() )
{
aArgs.getArray()[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptionData" ) );
aArgs.getArray()[2].Value <<= m_aPreparedPassword;
}
try
{
xStore->storeToURL( OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ),
aArgs );
}
catch( IOException& )
{
}
}
}
static OUString getMimetypeForDocument( const Reference< XMultiServiceFactory >& xFactory,
const Reference< XComponent >& xDoc ) throw()
{
OUString aDocMimetype;
// get document service name
Reference< com::sun::star::frame::XStorable > xStore( xDoc, UNO_QUERY );
Reference< frame::XModuleManager > xModuleManager(
xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ) ) ),
uno::UNO_QUERY );
if( xModuleManager.is() && xStore.is() )
{
OUString aDocServiceName = xModuleManager->identify( Reference< XInterface >( xStore, uno::UNO_QUERY ) );
if ( aDocServiceName.getLength() )
{
// get the actual filter name
OUString aFilterName;
Reference< lang::XMultiServiceFactory > xConfigProvider(
xFactory->createInstance(
OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) ) ),
uno::UNO_QUERY );
if( xConfigProvider.is() )
{
uno::Sequence< uno::Any > aArgs( 1 );
beans::PropertyValue aPathProp;
aPathProp.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
aPathProp.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/" ) );
aArgs[0] <<= aPathProp;
Reference< container::XNameAccess > xSOFConfig(
xConfigProvider->createInstanceWithArguments(
OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ),
aArgs ),
uno::UNO_QUERY );
Reference< container::XNameAccess > xApplConfig;
xSOFConfig->getByName( aDocServiceName ) >>= xApplConfig;
if ( xApplConfig.is() )
{
xApplConfig->getByName( OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupFactoryActualFilter" ) ) ) >>= aFilterName;
if( aFilterName.getLength() )
{
// find the related type name
OUString aTypeName;
Reference< container::XNameAccess > xFilterFactory(
xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
uno::UNO_QUERY );
Sequence< beans::PropertyValue > aFilterData;
xFilterFactory->getByName( aFilterName ) >>= aFilterData;
for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
if ( aFilterData[nInd].Name.equalsAscii( "Type" ) )
aFilterData[nInd].Value >>= aTypeName;
if ( aTypeName.getLength() )
{
// find the mediatype
Reference< container::XNameAccess > xTypeDetection(
xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
UNO_QUERY );
Sequence< beans::PropertyValue > aTypeData;
xTypeDetection->getByName( aTypeName ) >>= aTypeData;
for ( sal_Int32 nInd = 0; nInd < aTypeData.getLength(); nInd++ )
if ( aTypeData[nInd].Name.equalsAscii( "MediaType" ) )
aTypeData[nInd].Value >>= aDocMimetype;
}
}
}
}
}
}
return aDocMimetype;
}
sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& rFilterData )
{
INetURLObject aURL( rFile );
OUString aFile;
sal_Bool bRet = sal_False;
std::set< PDFWriter::ErrorCode > aErrors;
if( aURL.GetProtocol() != INET_PROT_FILE )
{
String aTmp;
if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFile, aTmp ) )
aURL = INetURLObject(aTmp);
}
if( aURL.GetProtocol() == INET_PROT_FILE )
{
Reference< XRenderable > xRenderable( mxSrcDoc, UNO_QUERY );
if( xRenderable.is() )
{
VCLXDevice* pXDevice = new VCLXDevice;
OUString aPageRange;
Any aSelection;
PDFWriter::PDFWriterContext aContext;
rtl::OUString aOpenPassword, aPermissionPassword;
Reference< beans::XMaterialHolder > xEnc;
Sequence< beans::NamedValue > aPreparedPermissionPassword;
// getting the string for the creator
String aCreator;
Reference< XServiceInfo > xInfo( mxSrcDoc, UNO_QUERY );
if ( xInfo.is() )
{
if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.presentation.PresentationDocument" ) ) )
aCreator.AppendAscii( "Impress" );
else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.drawing.DrawingDocument" ) ) )
aCreator.AppendAscii( "Draw" );
else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.text.TextDocument" ) ) )
aCreator.AppendAscii( "Writer" );
else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.sheet.SpreadsheetDocument" ) ) )
aCreator.AppendAscii( "Calc" );
else if ( xInfo->supportsService( rtl::OUString::createFromAscii( "com.sun.star.formula.FormulaProperties" ) ) )
aCreator.AppendAscii( "Math" );
}
Reference< document::XDocumentPropertiesSupplier > xDocumentPropsSupplier( mxSrcDoc, UNO_QUERY );
if ( xDocumentPropsSupplier.is() )
{
Reference< document::XDocumentProperties > xDocumentProps( xDocumentPropsSupplier->getDocumentProperties() );
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());
}
}
// getting the string for the producer
String aProducer;
::utl::ConfigManager* pMgr = ::utl::ConfigManager::GetConfigManager();
if ( pMgr )
{
Any aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
::rtl::OUString sProductName;
aProductName >>= sProductName;
aProducer = sProductName;
aProductName = pMgr->GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
aProductName >>= sProductName;
aProducer.AppendAscii(" ");
aProducer += String( sProductName );
}
aContext.DocumentInfo.Producer = aProducer;
aContext.DocumentInfo.Creator = aCreator;
for( sal_Int32 nData = 0, nDataCount = rFilterData.getLength(); nData < nDataCount; ++nData )
{
if( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ) )
rFilterData[ nData ].Value >>= aPageRange;
else if( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Selection" ) ) )
rFilterData[ nData ].Value >>= aSelection;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "UseLosslessCompression" ) ) )
rFilterData[ nData ].Value >>= mbUseLosslessCompression;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ) )
rFilterData[ nData ].Value >>= mnQuality;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ReduceImageResolution" ) ) )
rFilterData[ nData ].Value >>= mbReduceImageResolution;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) ) )
rFilterData[ nData ].Value >>= mbSkipEmptyPages;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxImageResolution" ) ) )
rFilterData[ nData ].Value >>= mnMaxImageResolution;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "UseTaggedPDF" ) ) )
rFilterData[ nData ].Value >>= mbUseTaggedPDF;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectPdfVersion" ) ) )
rFilterData[ nData ].Value >>= mnPDFTypeSelection;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotes" ) ) )
rFilterData[ nData ].Value >>= mbExportNotes;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) ) )
rFilterData[ nData ].Value >>= mbExportNotesPages;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EmbedStandardFonts" ) ) )
rFilterData[ nData ].Value >>= mbEmbedStandardFonts;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "UseTransitionEffects" ) ) )
rFilterData[ nData ].Value >>= mbUseTransitionEffects;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportFormFields" ) ) )
rFilterData[ nData ].Value >>= mbExportFormFields;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "FormsType" ) ) )
rFilterData[ nData ].Value >>= mnFormsFormat;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowDuplicateFieldNames" ) ) )
rFilterData[ nData ].Value >>= mbAllowDuplicateFieldNames;
//viewer properties
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerToolbar" ) ) )
rFilterData[ nData ].Value >>= mbHideViewerToolbar;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerMenubar" ) ) )
rFilterData[ nData ].Value >>= mbHideViewerMenubar;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "HideViewerWindowControls" ) ) )
rFilterData[ nData ].Value >>= mbHideViewerWindowControls;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ResizeWindowToInitialPage" ) ) )
rFilterData[ nData ].Value >>= mbFitWindow;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "CenterWindow" ) ) )
rFilterData[ nData ].Value >>= mbCenterWindow;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenInFullScreenMode" ) ) )
rFilterData[ nData ].Value >>= mbOpenInFullScreenMode;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "DisplayPDFDocumentTitle" ) ) )
rFilterData[ nData ].Value >>= mbDisplayPDFDocumentTitle;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialView" ) ) )
rFilterData[ nData ].Value >>= mnPDFDocumentMode;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Magnification" ) ) )
rFilterData[ nData ].Value >>= mnPDFDocumentAction;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Zoom" ) ) )
rFilterData[ nData ].Value >>= mnZoom;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialPage" ) ) )
rFilterData[ nData ].Value >>= mnInitialPage;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageLayout" ) ) )
rFilterData[ nData ].Value >>= mnPDFPageLayout;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "FirstPageOnLeft" ) ) )
rFilterData[ nData ].Value >>= aContext.FirstPageLeft;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsAddStream" ) ) )
rFilterData[ nData ].Value >>= mbAddStream;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Watermark" ) ) )
{
maWatermark = rFilterData[ nData ].Value;
mbWatermark = sal_True;
}
//now all the security related properties...
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EncryptFile" ) ) )
rFilterData[ nData ].Value >>= mbEncrypt;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "DocumentOpenPassword" ) ) )
rFilterData[ nData ].Value >>= aOpenPassword;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "RestrictPermissions" ) ) )
rFilterData[ nData ].Value >>= mbRestrictPermissions;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PermissionPassword" ) ) )
rFilterData[ nData ].Value >>= aPermissionPassword;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPasswords" ) ) )
rFilterData[ nData ].Value >>= xEnc;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PreparedPermissionPassword" ) ) )
rFilterData[ nData ].Value >>= aPreparedPermissionPassword;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Printing" ) ) )
rFilterData[ nData ].Value >>= mnPrintAllowed;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "Changes" ) ) )
rFilterData[ nData ].Value >>= mnChangesAllowed;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableCopyingOfContent" ) ) )
rFilterData[ nData ].Value >>= mbCanCopyOrExtract;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableTextAccessForAccessibilityTools" ) ) )
rFilterData[ nData ].Value >>= mbCanExtractForAccessibility;
//--->i56629 links extra (relative links and other related stuff)
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportLinksRelativeFsys" ) ) )
rFilterData[ nData ].Value >>= mbExportRelativeFsysLinks;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PDFViewSelection" ) ) )
rFilterData[ nData ].Value >>= mnDefaultLinkAction;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ConvertOOoTargetToPDFTarget" ) ) )
rFilterData[ nData ].Value >>= mbConvertOOoTargetToPDFTarget;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarksToPDFDestination" ) ) )
rFilterData[ nData ].Value >>= mbExportBmkToDest;
//<---
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarks" ) ) )
rFilterData[ nData ].Value >>= mbExportBookmarks;
else if ( rFilterData[ nData ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenBookmarkLevels" ) ) )
rFilterData[ nData ].Value >>= mnOpenBookmarkLevels;
}
aContext.URL = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
//set the correct version, depending on user request
switch( mnPDFTypeSelection )
{
default:
case 0:
aContext.Version = PDFWriter::PDF_1_4;
break;
case 1:
aContext.Version = PDFWriter::PDF_A_1;
//force the tagged PDF as well
mbUseTaggedPDF = sal_True;
//force embedding of standard fonts
mbEmbedStandardFonts = sal_True;
//force disabling of form conversion
mbExportFormFields = sal_False;
// PDF/A does not allow transparencies
mbRemoveTransparencies = sal_True;
// no encryption
mbEncrypt = sal_False;
xEnc.clear();
break;
}
//copy in context the values default in the contructor or set by the FilterData sequence of properties
aContext.Tagged = mbUseTaggedPDF;
//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;
aContext.EmbedStandardFonts = mbEmbedStandardFonts;
switch( mnPDFDocumentMode )
{
default:
case 0:
aContext.PDFDocumentMode = PDFWriter::ModeDefault;
break;
case 1:
aContext.PDFDocumentMode = PDFWriter::UseOutlines;
break;
case 2:
aContext.PDFDocumentMode = PDFWriter::UseThumbs;
break;
}
switch( mnPDFDocumentAction )
{
default:
case 0:
aContext.PDFDocumentAction = PDFWriter::ActionDefault;
break;
case 1:
aContext.PDFDocumentAction = PDFWriter::FitInWindow;
break;
case 2:
aContext.PDFDocumentAction = PDFWriter::FitWidth;
break;
case 3:
aContext.PDFDocumentAction = PDFWriter::FitVisible;
break;
case 4:
aContext.PDFDocumentAction = PDFWriter::ActionZoom;
aContext.Zoom = mnZoom;
break;
}
switch( mnPDFPageLayout )
{
default:
case 0:
aContext.PageLayout = PDFWriter::DefaultLayout;
break;
case 1:
aContext.PageLayout = PDFWriter::SinglePage;
break;
case 2:
aContext.PageLayout = PDFWriter::Continuous;
break;
case 3:
aContext.PageLayout = PDFWriter::ContinuousFacing;
break;
}
aContext.FirstPageLeft = mbFirstPageLeft;
//check if PDF/A, which does not allow encryption
if( aContext.Version != PDFWriter::PDF_A_1 )
{
//set values needed in encryption
//set encryption level, fixed, but here it can set by the UI if needed.
// true is 128 bit, false 40
//note that in 40 bit mode the UI needs reworking, since the current UI is meaningfull only for
//128bit security mode
aContext.Encryption.Security128bit = sal_True;
//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.getLength() > 0) )
{
mbEncrypt = sal_True;
//permission set as desired, done after
}
else
{
//force permission to default
mnPrintAllowed = 2 ;
mnChangesAllowed = 4 ;
mbCanCopyOrExtract = sal_True;
mbCanExtractForAccessibility = sal_True ;
}
switch( mnPrintAllowed )
{
case 0: //initialized when aContext is build, means no printing
break;
default:
case 2:
aContext.Encryption.CanPrintFull = sal_True;
case 1:
aContext.Encryption.CanPrintTheDocument = sal_True;
break;
}
switch( mnChangesAllowed )
{
case 0: //already in struct PDFSecPermissions CTOR
break;
case 1:
aContext.Encryption.CanAssemble = sal_True;
break;
case 2:
aContext.Encryption.CanFillInteractive = sal_True;
break;
case 3:
aContext.Encryption.CanAddOrModify = sal_True;
break;
default:
case 4:
aContext.Encryption.CanModifyTheContent =
aContext.Encryption.CanCopyOrExtract =
aContext.Encryption.CanAddOrModify =
aContext.Encryption.CanFillInteractive = sal_True;
break;
}
aContext.Encryption.CanCopyOrExtract = mbCanCopyOrExtract;
aContext.Encryption.CanExtractForAccessibility = mbCanExtractForAccessibility;
if( mbEncrypt && ! xEnc.is() )
xEnc = PDFWriter::InitEncryption( aPermissionPassword, aOpenPassword, aContext.Encryption.Security128bit );
if( mbEncrypt && aPermissionPassword.getLength() && ! aPreparedPermissionPassword.getLength() )
aPreparedPermissionPassword = comphelper::OStorageHelper::CreatePackageEncryptionData( aPermissionPassword );
}
// after this point we don't need the legacy clear passwords anymore
// however they are still inside the passed filter data sequence
// which is sadly out out our control
aPermissionPassword = rtl::OUString();
aOpenPassword = rtl::OUString();
/*
* 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 )
{
case 1:
aContext.SubmitFormat = PDFWriter::PDF;
break;
case 2:
aContext.SubmitFormat = PDFWriter::HTML;
break;
case 3:
aContext.SubmitFormat = PDFWriter::XML;
break;
default:
case 0:
aContext.SubmitFormat = PDFWriter::FDF;
break;
}
aContext.AllowDuplicateFieldNames = mbAllowDuplicateFieldNames;
//get model
Reference< frame::XModel > xModel( mxSrcDoc, UNO_QUERY );
{
//---> i56629 Relative link stuff
//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 )
{
default:
//default: URI, without fragment conversion (the bookmark in PDF may not work)
case 0:
aContext.DefaultLinkAction = PDFWriter::URIAction;
break;
//view PDF through the reader application
case 1:
aContext.ForcePDFAction = sal_True;
aContext.DefaultLinkAction = PDFWriter::LaunchAction;
break;
//view PDF through an Internet browser
case 2:
aContext.DefaultLinkAction = PDFWriter::URIActionDestination;
break;
}
aContext.ConvertOOoTargetToPDFTarget = mbConvertOOoTargetToPDFTarget;
// check for Link Launch action, not allowed on PDF/A-1
// this code chunk checks when the filter is called from scripting
if( aContext.Version == PDFWriter::PDF_A_1 &&
aContext.DefaultLinkAction == PDFWriter::LaunchAction )
{ //force the similar allowed URI action
aContext.DefaultLinkAction = PDFWriter::URIActionDestination;
//and remove the remote goto action forced on PDF file
aContext.ForcePDFAction = sal_False;
}
//<---
}
// all context data set, time to create the printing device
PDFWriter* pPDFWriter = new PDFWriter( aContext, xEnc );
OutputDevice* pOut = pPDFWriter->GetReferenceDevice();
vcl::PDFExtOutDevData* pPDFExtOutDevData = NULL;
DBG_ASSERT( pOut, "PDFExport::Export: no reference device" );
pXDevice->SetOutputDevice( pOut );
if( mbAddStream )
{
// export stream
// get mimetype
OUString aSrcMimetype = getMimetypeForDocument( mxMSF, mxSrcDoc );
pPDFWriter->AddStream( aSrcMimetype,
new PDFExportStreamDoc( mxSrcDoc, aPreparedPermissionPassword ),
false
);
}
if ( pOut )
{
DBG_ASSERT( pOut->GetExtOutDevData() == NULL, "PDFExport: ExtOutDevData already set!!!" );
pPDFExtOutDevData = new vcl::PDFExtOutDevData( *pOut );
pOut->SetExtOutDevData( pPDFExtOutDevData );
pPDFExtOutDevData->SetIsExportNotes( mbExportNotes );
pPDFExtOutDevData->SetIsExportTaggedPDF( mbUseTaggedPDF );
pPDFExtOutDevData->SetIsExportTransitionEffects( mbUseTransitionEffects );
pPDFExtOutDevData->SetFormsFormat( mnFormsFormat );
pPDFExtOutDevData->SetIsExportFormFields( mbExportFormFields );
pPDFExtOutDevData->SetIsExportBookmarks( mbExportBookmarks );
pPDFExtOutDevData->SetIsLosslessCompression( mbUseLosslessCompression );
pPDFExtOutDevData->SetIsReduceImageResolution( mbReduceImageResolution );
pPDFExtOutDevData->SetIsExportNamedDestinations( mbExportBmkToDest );
Sequence< PropertyValue > aRenderOptions( 6 );
aRenderOptions[ 0 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) );
aRenderOptions[ 0 ].Value <<= Reference< awt::XDevice >( pXDevice );
aRenderOptions[ 1 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportNotesPages" ) );
aRenderOptions[ 1 ].Value <<= sal_False;
Any& rExportNotesValue = aRenderOptions[ 1 ].Value;
aRenderOptions[ 2 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) );
aRenderOptions[ 2 ].Value <<= sal_True;
aRenderOptions[ 3 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) );
aRenderOptions[ 3 ].Value <<= sal_False;
aRenderOptions[ 4 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) );
aRenderOptions[ 4 ].Value <<= mbSkipEmptyPages;
aRenderOptions[ 5 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) );
aRenderOptions[ 5 ].Value <<= aPageRange;
if( aPageRange.getLength() || !aSelection.hasValue() )
{
aSelection = Any();
aSelection <<= mxSrcDoc;
}
sal_Bool bSecondPassForImpressNotes = sal_False;
bool bReChangeToNormalView = false;
::rtl::OUString sShowOnlineLayout( RTL_CONSTASCII_USTRINGPARAM( "ShowOnlineLayout"));
uno::Reference< beans::XPropertySet > xViewProperties;
if ( aCreator.EqualsAscii( "Writer" ) )
{
//i92835 if Writer is in web layout mode this has to be switched to normal view and back to web view in the end
try
{
Reference< view::XViewSettingsSupplier > xVSettingsSupplier( xModel->getCurrentController(), uno::UNO_QUERY_THROW );
xViewProperties = xVSettingsSupplier->getViewSettings();
xViewProperties->getPropertyValue( sShowOnlineLayout ) >>= bReChangeToNormalView;
if( bReChangeToNormalView )
{
xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( false ) );
}
}
catch( const uno::Exception& )
{
}
}
const sal_Int32 nPageCount = xRenderable->getRendererCount( aSelection, aRenderOptions );
const Range aRange( 1, nPageCount );
MultiSelection aMultiSelection;
if ( mbExportNotesPages && aCreator.EqualsAscii( "Impress" ) )
{
uno::Reference< drawing::XShapes > xShapes; // sj: do not allow to export notes when
if ( ! ( aSelection >>= xShapes ) ) // exporting a selection -> todo: in the dialog
bSecondPassForImpressNotes = sal_True; // the export notes checkbox needs to be disabled
}
if( !aPageRange.getLength() )
{
aMultiSelection.SetTotalRange( aRange );
aMultiSelection.Select( aRange );
}
else
{
aMultiSelection = MultiSelection( aPageRange );
aMultiSelection.SetTotalRange( aRange );
}
if ( mxStatusIndicator.is() )
{
ByteString aResMgrName( "pdffilter" );
ResMgr* pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
if ( pResMgr )
{
sal_Int32 nTotalPageCount = aMultiSelection.GetSelectCount();
if ( bSecondPassForImpressNotes )
nTotalPageCount *= 2;
mxStatusIndicator->start( String( ResId( PDF_PROGRESS_BAR, *pResMgr ) ), nTotalPageCount );
delete pResMgr;
}
}
if( nPageCount > 0 )
bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aMultiSelection, aRenderOptions, nPageCount );
else
bRet = sal_False;
if ( bRet && bSecondPassForImpressNotes )
{
rExportNotesValue <<= sal_True;
bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aMultiSelection, aRenderOptions, nPageCount );
}
if ( mxStatusIndicator.is() )
mxStatusIndicator->end();
// if during the export the doc locale was set copy it to PDF writer
const com::sun::star::lang::Locale& rLoc( pPDFExtOutDevData->GetDocumentLocale() );
if( rLoc.Language.getLength() )
pPDFWriter->SetDocumentLocale( rLoc );
if( bRet )
{
pPDFExtOutDevData->PlayGlobalActions( *pPDFWriter );
pPDFWriter->Emit();
aErrors = pPDFWriter->GetErrors();
}
pOut->SetExtOutDevData( NULL );
if( bReChangeToNormalView )
{
try
{
xViewProperties->setPropertyValue( sShowOnlineLayout, uno::makeAny( true ) );
}
catch( const uno::Exception& )
{
}
}
}
delete pPDFExtOutDevData;
delete pPDFWriter;
}
}
// show eventual errors during export
showErrors( aErrors );
return bRet;
}
namespace
{
typedef cppu::WeakComponentImplHelper1< task::XInteractionRequest > PDFErrorRequestBase;
class PDFErrorRequest : private cppu::BaseMutex,
public PDFErrorRequestBase
{
task::PDFExportException maExc;
public:
PDFErrorRequest( const task::PDFExportException& i_rExc );
// XInteractionRequest
virtual uno::Any SAL_CALL getRequest() throw (uno::RuntimeException);
virtual uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL getContinuations() throw (uno::RuntimeException);
};
PDFErrorRequest::PDFErrorRequest( const task::PDFExportException& i_rExc ) :
PDFErrorRequestBase( m_aMutex ),
maExc( i_rExc )
{
}
uno::Any SAL_CALL PDFErrorRequest::getRequest() throw (uno::RuntimeException)
{
osl::MutexGuard const guard( m_aMutex );
uno::Any aRet;
aRet <<= maExc;
return aRet;
}
uno::Sequence< uno::Reference< task::XInteractionContinuation > > SAL_CALL PDFErrorRequest::getContinuations() throw (uno::RuntimeException)
{
return uno::Sequence< uno::Reference< task::XInteractionContinuation > >();
}
} // namespace
void PDFExport::showErrors( const std::set< PDFWriter::ErrorCode >& rErrors )
{
if( ! rErrors.empty() && mxIH.is() )
{
task::PDFExportException aExc;
aExc.ErrorCodes.realloc( sal_Int32(rErrors.size()) );
sal_Int32 i = 0;
for( std::set< PDFWriter::ErrorCode >::const_iterator it = rErrors.begin();
it != rErrors.end(); ++it, i++ )
{
aExc.ErrorCodes.getArray()[i] = (sal_Int32)*it;
}
Reference< task::XInteractionRequest > xReq( new PDFErrorRequest( aExc ) );
mxIH->handle( xReq );
}
}
// -----------------------------------------------------------------------------
sal_Bool PDFExport::ImplExportPage( PDFWriter& rWriter, PDFExtOutDevData& rPDFExtOutDevData, const GDIMetaFile& rMtf )
{
const Size aSizePDF( OutputDevice::LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_POINT ) );
Point aOrigin;
Rectangle aPageRect( aOrigin, rMtf.GetPrefSize() );
sal_Bool bRet = sal_True;
rWriter.NewPage( aSizePDF.Width(), aSizePDF.Height() );
rWriter.SetMapMode( rMtf.GetPrefMapMode() );
vcl::PDFWriter::PlayMetafileContext aCtx;
GDIMetaFile aMtf;
if( mbRemoveTransparencies )
{
aCtx.m_bTransparenciesWereRemoved = rWriter.GetReferenceDevice()->
RemoveTransparenciesFromMetaFile( rMtf, aMtf, mnMaxImageResolution, mnMaxImageResolution,
false, true, mbReduceImageResolution );
}
else
{
aMtf = rMtf;
}
aCtx.m_nMaxImageResolution = mbReduceImageResolution ? mnMaxImageResolution : 0;
aCtx.m_bOnlyLosslessCompression = mbUseLosslessCompression;
aCtx.m_nJPEGQuality = mnQuality;
basegfx::B2DRectangle aB2DRect( aPageRect.Left(), aPageRect.Top(), aPageRect.Right(), aPageRect.Bottom() );
rWriter.SetClipRegion( basegfx::B2DPolyPolygon( basegfx::tools::createPolygonFromRect( aB2DRect ) ) );
rWriter.PlayMetafile( aMtf, aCtx, &rPDFExtOutDevData );
rPDFExtOutDevData.ResetSyncData();
if( mbWatermark )
ImplWriteWatermark( rWriter, aSizePDF );
return bRet;
}
// -----------------------------------------------------------------------------
void PDFExport::ImplWriteWatermark( PDFWriter& rWriter, const Size& rPageSize )
{
OUString aText( RTL_CONSTASCII_USTRINGPARAM( "Watermark" ) );
Font aFont( OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica" ) ), Size( 0, 3*rPageSize.Height()/4 ) );
aFont.SetItalic( ITALIC_NONE );
aFont.SetWidthType( WIDTH_NORMAL );
aFont.SetWeight( WEIGHT_NORMAL );
aFont.SetAlign( ALIGN_BOTTOM );
long nTextWidth = rPageSize.Width();
if( rPageSize.Width() < rPageSize.Height() )
{
nTextWidth = rPageSize.Height();
aFont.SetOrientation( 2700 );
}
if( ! ( maWatermark >>= aText ) )
{
// more complicated watermark ?
}
// adjust font height for text to fit
OutputDevice* pDev = rWriter.GetReferenceDevice();
pDev->Push( PUSH_ALL );
pDev->SetFont( aFont );
pDev->SetMapMode( MapMode( MAP_POINT ) );
int w = 0;
while( ( w = pDev->GetTextWidth( aText ) ) > nTextWidth )
{
long nNewHeight = aFont.GetHeight() * nTextWidth / w;
if( nNewHeight == aFont.GetHeight() )
{
nNewHeight--;
if( nNewHeight <= 0 )
break;
}
aFont.SetHeight( nNewHeight );
pDev->SetFont( aFont );
}
long nTextHeight = pDev->GetTextHeight();
// leave some maneuvering room for rounding issues, also
// some fonts go a little outside ascent/descent
nTextHeight += nTextHeight/20;
pDev->Pop();
rWriter.Push( PUSH_ALL );
rWriter.SetMapMode( MapMode( MAP_POINT ) );
rWriter.SetFont( aFont );
rWriter.SetTextColor( COL_RED );
Point aTextPoint;
Rectangle aTextRect;
if( rPageSize.Width() > rPageSize.Height() )
{
aTextPoint = Point( (rPageSize.Width()-w)/2,
rPageSize.Height()-(rPageSize.Height()-nTextHeight)/2 );
aTextRect = Rectangle( Point( (rPageSize.Width()-w)/2,
(rPageSize.Height()-nTextHeight)/2 ),
Size( w, nTextHeight ) );
}
else
{
aTextPoint = Point( (rPageSize.Width()-nTextHeight)/2,
(rPageSize.Height()-w)/2 );
aTextRect = Rectangle( aTextPoint, Size( nTextHeight, w ) );
}
rWriter.SetClipRegion();
rWriter.BeginTransparencyGroup();
rWriter.DrawText( aTextPoint, aText );
rWriter.EndTransparencyGroup( aTextRect, 50 );
rWriter.Pop();
}