/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #ifndef _VCL_PDFWRITER_IMPL_HXX #define _VCL_PDFWRITER_IMPL_HXX #include "vcl/pdfwriter.hxx" #include "rtl/ustring.hxx" #include "osl/file.h" #include "tools/gen.hxx" #include "tools/stream.hxx" #include "vcl/outdev.hxx" #include "vcl/bitmapex.hxx" #include "vcl/gradient.hxx" #include "vcl/hatch.hxx" #include "vcl/wall.hxx" #include "outdata.hxx" #include "rtl/strbuf.hxx" #include "rtl/cipher.h" #include "rtl/digest.h" #include "com/sun/star/util/XURLTransformer.hpp" #include "com/sun/star/lang/Locale.hpp" #include #include #include "pdffontcache.hxx" #include #include #include #include #include class FontSelectPattern; class ImplFontMetricData; class FontSubsetInfo; class ZCodec; class EncHashTransporter; struct BitStreamState; // the maximum password length #define ENCRYPTED_PWD_SIZE 32 #define MD5_DIGEST_SIZE 16 #define SECUR_40BIT_KEY 5 // security 128 bit #define SECUR_128BIT_KEY 16 // maximum length of MD5 digest input, in step 2 of algorithm 3.1 // PDF spec ver. 1.4: see there for details #define MAXIMUM_RC4_KEY_LENGTH (SECUR_128BIT_KEY+3+2) namespace vcl { class PDFSalLayout; class PDFStreamIf; class Matrix3; class PDFWriterImpl { friend class PDFSalLayout; friend class PDFStreamIf; public: // definition of structs struct BuiltinFont { const char * m_pName; // Name const char * m_pStyleName; // StyleName const char * m_pPSName; // PSName int m_nAscent; int m_nDescent; FontFamily m_eFamily; // Family CharSet m_eCharSet; // CharSet FontPitch m_ePitch; // Pitch FontWidth m_eWidthType; // WidthType FontWeight m_eWeight; // Weight FontItalic m_eItalic; // Italic int m_aWidths[256]; // character metrics rtl::OString getNameObject() const; }; enum ResourceKind { ResXObject, ResExtGState, ResShading, ResPattern }; typedef std::map< rtl::OString, sal_Int32 > ResourceMap; struct ResourceDict { // note: handle fonts globally for performance ResourceMap m_aXObjects; ResourceMap m_aExtGStates; ResourceMap m_aShadings; ResourceMap m_aPatterns; void append( rtl::OStringBuffer&, sal_Int32 nFontDictObject ); }; struct PDFPage { PDFWriterImpl* m_pWriter; sal_Int32 m_nPageWidth; // in inch/72 sal_Int32 m_nPageHeight; // in inch/72 PDFWriter::Orientation m_eOrientation; sal_Int32 m_nPageObject; sal_Int32 m_nPageIndex; std::vector m_aStreamObjects; sal_Int32 m_nStreamLengthObject; sal_uInt64 m_nBeginStreamPos; std::vector m_aAnnotations; std::vector m_aMCIDParents; PDFWriter::PageTransition m_eTransition; sal_uInt32 m_nTransTime; sal_uInt32 m_nDuration; bool m_bHasWidgets; PDFPage( PDFWriterImpl* pWriter, sal_Int32 nPageWidth, sal_Int32 nPageHeight, PDFWriter::Orientation eOrientation ); ~PDFPage(); void beginStream(); void endStream(); bool emit( sal_Int32 nParentPage ); // converts point from ref device coordinates to // page coordinates and appends the point to the buffer // if bNeg is true, the coordinates are inverted AFTER transformation // to page (useful for transformation matrices // if pOutPoint is set it will be updated to the emitted point // (in PDF map mode, that is 10th of point) void appendPoint( const Point& rPoint, rtl::OStringBuffer& rBuffer, bool bNeg = false, Point* pOutPoint = NULL ) const; // appends a B2DPoint without further transformation void appendPixelPoint( const basegfx::B2DPoint& rPoint, rtl::OStringBuffer& rBuffer ) const; // appends a rectangle void appendRect( const Rectangle& rRect, rtl::OStringBuffer& rBuffer ) const; // converts a rectangle to 10th points page space void convertRect( Rectangle& rRect ) const; // appends a polygon optionally closing it void appendPolygon( const Polygon& rPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const; // appends a polygon optionally closing it void appendPolygon( const basegfx::B2DPolygon& rPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const; // appends a polypolygon optionally closing the subpaths void appendPolyPolygon( const PolyPolygon& rPolyPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const; // appends a polypolygon optionally closing the subpaths void appendPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const; // converts a length (either vertical or horizontal; this // can be important if the source MapMode is not // symmetrical) to page length and appends it to the buffer // if pOutLength is set it will be updated to the emitted length // (in PDF map mode, that is 10th of point) void appendMappedLength( sal_Int32 nLength, rtl::OStringBuffer& rBuffer, bool bVertical = true, sal_Int32* pOutLength = NULL ) const; // the same for double values void appendMappedLength( double fLength, rtl::OStringBuffer& rBuffer, bool bVertical = true, sal_Int32* pOutLength = NULL, sal_Int32 nPrecision = 5 ) const; // appends LineInfo // returns false if too many dash array entry were created for // the implementation limits of some PDF readers bool appendLineInfo( const LineInfo& rInfo, rtl::OStringBuffer& rBuffer ) const; // appends a horizontal waveline with vertical offset (helper for drawWaveLine) void appendWaveLine( sal_Int32 nLength, sal_Int32 nYOffset, sal_Int32 nDelta, rtl::OStringBuffer& rBuffer ) const; sal_Int32 getWidth() const { return m_nPageWidth ? m_nPageWidth : m_pWriter->m_nInheritedPageWidth; } sal_Int32 getHeight() const { return m_nPageHeight ? m_nPageHeight : m_pWriter->m_nInheritedPageHeight; } }; friend struct PDFPage; struct BitmapID { Size m_aPixelSize; sal_Int32 m_nSize; sal_Int32 m_nChecksum; sal_Int32 m_nMaskChecksum; BitmapID() : m_nSize( 0 ), m_nChecksum( 0 ), m_nMaskChecksum( 0 ) {} BitmapID& operator=( const BitmapID& rCopy ) { m_aPixelSize = rCopy.m_aPixelSize; m_nSize = rCopy.m_nSize; m_nChecksum = rCopy.m_nChecksum; m_nMaskChecksum = rCopy.m_nMaskChecksum; return *this; } bool operator==( const BitmapID& rComp ) const { return (m_aPixelSize == rComp.m_aPixelSize && m_nSize == rComp.m_nSize && m_nChecksum == rComp.m_nChecksum && m_nMaskChecksum == rComp.m_nMaskChecksum ); } }; struct BitmapEmit { BitmapID m_aID; BitmapEx m_aBitmap; sal_Int32 m_nObject; bool m_bDrawMask; BitmapEmit() : m_bDrawMask( false ) {} }; struct JPGEmit { BitmapID m_aID; SvMemoryStream* m_pStream; Bitmap m_aMask; sal_Int32 m_nObject; bool m_bTrueColor; JPGEmit() : m_pStream( NULL ), m_bTrueColor( false ) {} ~JPGEmit() { delete m_pStream; } }; struct GradientEmit { Gradient m_aGradient; Size m_aSize; sal_Int32 m_nObject; }; // for tilings (drawWallpaper, begin/endPattern) struct TilingEmit { sal_Int32 m_nObject; Rectangle m_aRectangle; Size m_aCellSize; SvtGraphicFill::Transform m_aTransform; ResourceDict m_aResources; SvMemoryStream* m_pTilingStream; TilingEmit() : m_nObject( 0 ), m_pTilingStream( NULL ) {} }; // for transparency group XObjects struct TransparencyEmit { sal_Int32 m_nObject; sal_Int32 m_nExtGStateObject; double m_fAlpha; Rectangle m_aBoundRect; SvMemoryStream* m_pContentStream; SvMemoryStream* m_pSoftMaskStream; TransparencyEmit() : m_nObject( 0 ), m_nExtGStateObject( -1 ), m_fAlpha( 0.0 ), m_pContentStream( NULL ), m_pSoftMaskStream( NULL ) {} ~TransparencyEmit() { delete m_pContentStream; delete m_pSoftMaskStream; } }; // font subsets class GlyphEmit { // performance: actually this should probably a vector; sal_Ucs m_aBufferedUnicodes[3]; sal_Int32 m_nUnicodes; sal_Int32 m_nMaxUnicodes; boost::shared_array m_pUnicodes; sal_uInt8 m_nSubsetGlyphID; public: GlyphEmit() : m_nUnicodes(0), m_nSubsetGlyphID(0) { rtl_zeroMemory( m_aBufferedUnicodes, sizeof( m_aBufferedUnicodes ) ); m_nMaxUnicodes = SAL_N_ELEMENTS(m_aBufferedUnicodes); } ~GlyphEmit() { } void setGlyphId( sal_uInt8 i_nId ) { m_nSubsetGlyphID = i_nId; } sal_uInt8 getGlyphId() const { return m_nSubsetGlyphID; } void addCode( sal_Ucs i_cCode ) { if( m_nUnicodes == m_nMaxUnicodes ) { sal_Ucs* pNew = new sal_Ucs[ 2 * m_nMaxUnicodes]; if( m_pUnicodes.get() ) rtl_copyMemory( pNew, m_pUnicodes.get(), m_nMaxUnicodes * sizeof(sal_Ucs) ); else rtl_copyMemory( pNew, m_aBufferedUnicodes, m_nMaxUnicodes * sizeof(sal_Ucs) ); m_pUnicodes.reset( pNew ); m_nMaxUnicodes *= 2; } if( m_pUnicodes.get() ) m_pUnicodes[ m_nUnicodes++ ] = i_cCode; else m_aBufferedUnicodes[ m_nUnicodes++ ] = i_cCode; } sal_Int32 countCodes() const { return m_nUnicodes; } sal_Ucs getCode( sal_Int32 i_nIndex ) const { sal_Ucs nRet = 0; if( i_nIndex < m_nUnicodes ) nRet = m_pUnicodes.get() ? m_pUnicodes[ i_nIndex ] : m_aBufferedUnicodes[ i_nIndex ]; return nRet; } }; typedef std::map< sal_GlyphId, GlyphEmit > FontEmitMapping; struct FontEmit { sal_Int32 m_nFontID; FontEmitMapping m_aMapping; FontEmit( sal_Int32 nID ) : m_nFontID( nID ) {} }; typedef std::list< FontEmit > FontEmitList; struct Glyph { sal_Int32 m_nFontID; sal_uInt8 m_nSubsetGlyphID; }; typedef std::map< sal_GlyphId, Glyph > FontMapping; struct FontSubset { FontEmitList m_aSubsets; FontMapping m_aMapping; }; typedef std::map< const ImplFontData*, FontSubset > FontSubsetData; struct EmbedCode { sal_Ucs m_aUnicode; rtl::OString m_aName; }; struct EmbedEncoding { sal_Int32 m_nFontID; std::vector< EmbedCode > m_aEncVector; std::map< sal_Ucs, sal_Int8 > m_aCMap; }; struct EmbedFont { sal_Int32 m_nNormalFontID; std::list< EmbedEncoding > m_aExtendedEncodings; EmbedFont() : m_nNormalFontID( 0 ) {} }; typedef std::map< const ImplFontData*, EmbedFont > FontEmbedData; struct PDFDest { sal_Int32 m_nPage; PDFWriter::DestAreaType m_eType; Rectangle m_aRect; }; //--->i56629 struct PDFNamedDest { rtl::OUString m_aDestName; sal_Int32 m_nPage; PDFWriter::DestAreaType m_eType; Rectangle m_aRect; }; struct PDFOutlineEntry { sal_Int32 m_nParentID; sal_Int32 m_nObject; sal_Int32 m_nParentObject; sal_Int32 m_nNextObject; sal_Int32 m_nPrevObject; std::vector< sal_Int32 > m_aChildren; rtl::OUString m_aTitle; sal_Int32 m_nDestID; PDFOutlineEntry() : m_nParentID( -1 ), m_nObject( 0 ), m_nParentObject( 0 ), m_nNextObject( 0 ), m_nPrevObject( 0 ), m_nDestID( -1 ) {} }; struct PDFAnnotation { sal_Int32 m_nObject; Rectangle m_aRect; sal_Int32 m_nPage; PDFAnnotation() : m_nObject( -1 ), m_nPage( -1 ) {} }; struct PDFLink : public PDFAnnotation { sal_Int32 m_nDest; // set to -1 for URL, to a dest else rtl::OUString m_aURL; sal_Int32 m_nStructParent; // struct parent entry PDFLink() : m_nDest( -1 ), m_nStructParent( -1 ) {} }; struct PDFNoteEntry : public PDFAnnotation { PDFNote m_aContents; PDFNoteEntry() {} }; typedef boost::unordered_map< rtl::OString, SvMemoryStream*, rtl::OStringHash > PDFAppearanceStreams; typedef boost::unordered_map< rtl::OString, PDFAppearanceStreams, rtl::OStringHash > PDFAppearanceMap; struct PDFWidget : public PDFAnnotation { PDFWriter::WidgetType m_eType; rtl::OString m_aName; rtl::OUString m_aDescription; rtl::OUString m_aText; sal_uInt16 m_nTextStyle; rtl::OUString m_aValue; rtl::OString m_aDAString; rtl::OString m_aDRDict; rtl::OString m_aMKDict; rtl::OString m_aMKDictCAString; // i12626, added to be able to encrypt the /CA text string // since the object number is not known at the moment // of filling m_aMKDict, the string will be encrypted when emitted. // the /CA string MUST BE the last added to m_aMKDict // see code for details sal_Int32 m_nFlags; sal_Int32 m_nParent; // if not 0, parent's object number std::vector m_aKids; // widget children, contains object numbers std::vector m_aKidsIndex; // widget children, contains index to m_aWidgets rtl::OUString m_aOnValue; sal_Int32 m_nTabOrder; // lowest number gets first in tab order sal_Int32 m_nRadioGroup; sal_Int32 m_nMaxLen; bool m_bSubmit; bool m_bSubmitGet; sal_Int32 m_nDest; std::vector m_aListEntries; std::vector m_aSelectedEntries; PDFAppearanceMap m_aAppearances; PDFWidget() : m_eType( PDFWriter::PushButton ), m_nTextStyle( 0 ), m_nFlags( 0 ), m_nParent( 0 ), m_nRadioGroup( -1 ), m_nMaxLen( 0 ), m_bSubmit( false ), m_bSubmitGet( false ), m_nDest( -1 ) {} }; struct PDFStructureAttribute { PDFWriter::StructAttributeValue eValue; sal_Int32 nValue; PDFStructureAttribute() : eValue( PDFWriter::Invalid ), nValue( 0 ) {} PDFStructureAttribute( PDFWriter::StructAttributeValue eVal ) : eValue( eVal ), nValue( 0 ) {} PDFStructureAttribute( sal_Int32 nVal ) : eValue( PDFWriter::Invalid ), nValue( nVal ) {} }; typedef std::map PDFStructAttributes; struct PDFStructureElementKid // for Kids entries { sal_Int32 nObject; // an object number if nMCID is -1, // else the page object relevant to MCID sal_Int32 nMCID; // an MCID if >= 0 PDFStructureElementKid( sal_Int32 nObj ) : nObject( nObj ), nMCID( -1 ) {} PDFStructureElementKid( sal_Int32 MCID, sal_Int32 nPage ) : nObject( nPage ), nMCID( MCID ) {} }; struct PDFStructureElement { sal_Int32 m_nObject; PDFWriter::StructElement m_eType; rtl::OString m_aAlias; sal_Int32 m_nOwnElement; // index into structure vector sal_Int32 m_nParentElement; // index into structure vector sal_Int32 m_nFirstPageObject; bool m_bOpenMCSeq; std::list< sal_Int32 > m_aChildren; // indexes into structure vector std::list< PDFStructureElementKid > m_aKids; PDFStructAttributes m_aAttributes; Rectangle m_aBBox; rtl::OUString m_aActualText; rtl::OUString m_aAltText; com::sun::star::lang::Locale m_aLocale; // m_aContents contains the element's marked content sequence // as pairs of (page nr, MCID) PDFStructureElement() : m_nObject( 0 ), m_eType( PDFWriter::NonStructElement ), m_nOwnElement( -1 ), m_nParentElement( -1 ), m_nFirstPageObject( 0 ), m_bOpenMCSeq( false ) { } }; struct PDFAddStream { rtl::OUString m_aMimeType; PDFOutputStream* m_pStream; sal_Int32 m_nStreamObject; bool m_bCompress; PDFAddStream() : m_pStream( NULL ), m_nStreamObject( 0 ), m_bCompress( true ) {} }; // helper structure for drawLayout and friends struct PDFGlyph { Point m_aPos; sal_Int32 m_nNativeWidth; sal_Int32 m_nGlyphId; sal_Int32 m_nMappedFontId; sal_uInt8 m_nMappedGlyphId; PDFGlyph( const Point& rPos, sal_Int32 nNativeWidth, sal_Int32 nGlyphId, sal_Int32 nFontId, sal_uInt8 nMappedGlyphId ) : m_aPos( rPos ), m_nNativeWidth( nNativeWidth ), m_nGlyphId( nGlyphId ), m_nMappedFontId( nFontId ), m_nMappedGlyphId( nMappedGlyphId ) {} }; static const sal_Char* getStructureTag( PDFWriter::StructElement ); static const sal_Char* getAttributeTag( PDFWriter::StructAttribute eAtr ); static const sal_Char* getAttributeValueTag( PDFWriter::StructAttributeValue eVal ); // returns true if compression was done // else false static bool compressStream( SvMemoryStream* ); static void convertLineInfoToExtLineInfo( const LineInfo& rIn, PDFWriter::ExtLineInfo& rOut ); private: static const BuiltinFont m_aBuiltinFonts[14]; OutputDevice* m_pReferenceDevice; MapMode m_aMapMode; // PDFWriterImpl scaled units std::vector< PDFPage > m_aPages; /* maps object numbers to file offsets (needed for xref) */ std::vector< sal_uInt64 > m_aObjects; /* contains Bitmaps until they are written to the * file stream as XObjects*/ std::list< BitmapEmit > m_aBitmaps; /* contains JPG streams until written to file */ std::list m_aJPGs; /*--->i56629 contains all named destinations ever set during the PDF creation, destination id is always the destination's position in this vector */ std::vector m_aNamedDests; /* contains all dests ever set during the PDF creation, dest id is always the dest's position in this vector */ std::vector m_aDests; /** contains destinations accessible via a public Id, instead of being linked to by an ordinary link */ ::std::map< sal_Int32, sal_Int32 > m_aDestinationIdTranslation; /* contains all links ever set during PDF creation, link id is always the link's position in this vector */ std::vector m_aLinks; /* makes correctly encoded for export to PDF URLS */ com::sun::star::uno::Reference< com::sun::star::util::XURLTransformer > m_xTrans; /* maps arbitrary link ids for structure attributes to real link ids (for setLinkPropertyId) */ std::map m_aLinkPropertyMap; /* contains all outline items, object 0 is the outline root */ std::vector m_aOutline; /* contains all notes set during PDF creation */ std::vector m_aNotes; /* the root of the structure tree */ std::vector m_aStructure; /* current object in the structure hierarchy */ sal_Int32 m_nCurrentStructElement; /* structure parent tree */ std::vector< rtl::OString > m_aStructParentTree; /* emit strucure marks currently (aka. NonStructElement or not) */ bool m_bEmitStructure; bool m_bNewMCID; /* role map of struct tree root */ boost::unordered_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aRoleMap; /* contains all widgets used in the PDF */ std::vector m_aWidgets; /* maps radio group id to index of radio group control in m_aWidgets */ std::map< sal_Int32, sal_Int32 > m_aRadioGroupWidgets; /* boost::unordered_map for field names, used to ensure unique field names */ boost::unordered_map< rtl::OString, sal_Int32, rtl::OStringHash > m_aFieldNameMap; /* contains Bitmaps for gradient functions until they are written * to the file stream */ std::list< GradientEmit > m_aGradients; /* contains bitmap tiling patterns */ std::vector< TilingEmit > m_aTilings; std::list< TransparencyEmit > m_aTransparentObjects; /* contains all font subsets in use */ FontSubsetData m_aSubsets; bool m_bEmbedStandardFonts; FontEmbedData m_aEmbeddedFonts; FontEmbedData m_aSystemFonts; sal_Int32 m_nNextFID; PDFFontCache m_aFontCache; sal_Int32 m_nInheritedPageWidth; // in inch/72 sal_Int32 m_nInheritedPageHeight; // in inch/72 PDFWriter::Orientation m_eInheritedOrientation; sal_Int32 m_nCurrentPage; sal_Int32 m_nCatalogObject; sal_Int32 m_nResourceDict; ResourceDict m_aGlobalResourceDict; sal_Int32 m_nFontDictObject; std::map< sal_Int32, sal_Int32 > m_aBuiltinFontToObjectMap; PDFWriter::PDFWriterContext m_aContext; oslFileHandle m_aFile; bool m_bOpen; /* output redirection; e.g. to accumulate content streams for XObjects */ struct StreamRedirect { SvStream* m_pStream; MapMode m_aMapMode; Rectangle m_aTargetRect; ResourceDict m_aResourceDict; }; std::list< StreamRedirect > m_aOutputStreams; // graphics state struct GraphicsState { Font m_aFont; MapMode m_aMapMode; Color m_aLineColor; Color m_aFillColor; Color m_aTextLineColor; Color m_aOverlineColor; basegfx::B2DPolyPolygon m_aClipRegion; bool m_bClipRegion; sal_Int32 m_nAntiAlias; sal_Int32 m_nLayoutMode; LanguageType m_aDigitLanguage; sal_Int32 m_nTransparentPercent; sal_uInt16 m_nFlags; sal_uInt16 m_nUpdateFlags; static const sal_uInt16 updateFont = 0x0001; static const sal_uInt16 updateMapMode = 0x0002; static const sal_uInt16 updateLineColor = 0x0004; static const sal_uInt16 updateFillColor = 0x0008; static const sal_uInt16 updateTextLineColor = 0x0010; static const sal_uInt16 updateOverlineColor = 0x0020; static const sal_uInt16 updateClipRegion = 0x0040; static const sal_uInt16 updateAntiAlias = 0x0080; static const sal_uInt16 updateLayoutMode = 0x0100; static const sal_uInt16 updateTransparentPercent = 0x0200; static const sal_uInt16 updateDigitLanguage = 0x0400; GraphicsState() : m_aLineColor( COL_TRANSPARENT ), m_aFillColor( COL_TRANSPARENT ), m_aTextLineColor( COL_TRANSPARENT ), m_aOverlineColor( COL_TRANSPARENT ), m_bClipRegion( false ), m_nAntiAlias( 1 ), m_nLayoutMode( 0 ), m_aDigitLanguage( 0 ), m_nTransparentPercent( 0 ), m_nFlags( 0xffff ), m_nUpdateFlags( 0xffff ) {} GraphicsState( const GraphicsState& rState ) : m_aFont( rState.m_aFont ), m_aMapMode( rState.m_aMapMode ), m_aLineColor( rState.m_aLineColor ), m_aFillColor( rState.m_aFillColor ), m_aTextLineColor( rState.m_aTextLineColor ), m_aOverlineColor( rState.m_aOverlineColor ), m_aClipRegion( rState.m_aClipRegion ), m_bClipRegion( rState.m_bClipRegion ), m_nAntiAlias( rState.m_nAntiAlias ), m_nLayoutMode( rState.m_nLayoutMode ), m_aDigitLanguage( rState.m_aDigitLanguage ), m_nTransparentPercent( rState.m_nTransparentPercent ), m_nFlags( rState.m_nFlags ), m_nUpdateFlags( rState.m_nUpdateFlags ) { } GraphicsState& operator=(const GraphicsState& rState ) { m_aFont = rState.m_aFont; m_aMapMode = rState.m_aMapMode; m_aLineColor = rState.m_aLineColor; m_aFillColor = rState.m_aFillColor; m_aTextLineColor = rState.m_aTextLineColor; m_aOverlineColor = rState.m_aOverlineColor; m_aClipRegion = rState.m_aClipRegion; m_bClipRegion = rState.m_bClipRegion; m_nAntiAlias = rState.m_nAntiAlias; m_nLayoutMode = rState.m_nLayoutMode; m_aDigitLanguage = rState.m_aDigitLanguage; m_nTransparentPercent = rState.m_nTransparentPercent; m_nFlags = rState.m_nFlags; m_nUpdateFlags = rState.m_nUpdateFlags; return *this; } }; std::list< GraphicsState > m_aGraphicsStack; GraphicsState m_aCurrentPDFState; ZCodec* m_pCodec; SvMemoryStream* m_pMemStream; std::vector< PDFAddStream > m_aAdditionalStreams; std::set< PDFWriter::ErrorCode > m_aErrors; rtlDigest m_aDocDigest; /* variables for PDF security i12626 */ /* used to cipher the stream data and for password management */ rtlCipher m_aCipher; rtlDigest m_aDigest; /* pad string used for password in Standard security handler */ static const sal_uInt8 s_nPadString[ENCRYPTED_PWD_SIZE]; /* the encryption key, formed with the user password according to algorithm 3.2, maximum length is 16 bytes + 3 + 2 for 128 bit security */ sal_Int32 m_nKeyLength; // key length, 16 or 5 sal_Int32 m_nRC4KeyLength; // key length, 16 or 10, to be input to the algorith 3.1 /* set to true if the following stream must be encrypted, used inside writeBuffer() */ sal_Bool m_bEncryptThisStream; /* the numerical value of the access permissions, according to PDF spec, must be signed */ sal_Int32 m_nAccessPermissions; /* string to hold the PDF creation date */ rtl::OString m_aCreationDateString; /* string to hold the PDF creation date, for PDF/A metadata */ rtl::OString m_aCreationMetaDateString; /* the buffer where the data are encrypted, dynamically allocated */ sal_uInt8 *m_pEncryptionBuffer; /* size of the buffer */ sal_Int32 m_nEncryptionBufferSize; /* check and reallocate the buffer for encryption */ sal_Bool checkEncryptionBufferSize( register sal_Int32 newSize ); /* this function implements part of the PDF spec algorithm 3.1 in encryption, the rest (the actual encryption) is in PDFWriterImpl::writeBuffer */ void checkAndEnableStreamEncryption( register sal_Int32 nObject ); void disableStreamEncryption() { m_bEncryptThisStream = false; }; /* */ void enableStringEncryption( register sal_Int32 nObject ); // test if the encryption is active, if yes than encrypt the unicode string and add to the OStringBuffer parameter void appendUnicodeTextStringEncrypt( const rtl::OUString& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer ); void appendLiteralStringEncrypt( const rtl::OUString& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer, rtl_TextEncoding nEnc = RTL_TEXTENCODING_ASCII_US ); void appendLiteralStringEncrypt( const rtl::OString& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer ); void appendLiteralStringEncrypt( rtl::OStringBuffer& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer ); /* creates fonts and subsets that will be emitted later */ void registerGlyphs( int nGlyphs, sal_GlyphId* pGlyphs, sal_Int32* pGlpyhWidths, sal_Ucs* pUnicodes, sal_Int32* pUnicodesPerGlyph, sal_uInt8* pMappedGlyphs, sal_Int32* pMappedFontObjects, const ImplFontData* pFallbackFonts[] ); /* emits a text object according to the passed layout */ /* TODO: remove rText as soon as SalLayout will change so that rText is not necessary anymore */ void drawVerticalGlyphs( const std::vector& rGlyphs, rtl::OStringBuffer& rLine, const Point& rAlignOffset, const Matrix3& rRotScale, double fAngle, double fXScale, double fSkew, sal_Int32 nFontHeight ); void drawHorizontalGlyphs( const std::vector& rGlyphs, rtl::OStringBuffer& rLine, const Point& rAlignOffset, double fAngle, double fXScale, double fSkew, sal_Int32 nFontHeight, sal_Int32 nPixelFontHeight ); void drawLayout( SalLayout& rLayout, const String& rText, bool bTextLines ); void drawRelief( SalLayout& rLayout, const String& rText, bool bTextLines ); void drawShadow( SalLayout& rLayout, const String& rText, bool bTextLines ); /* writes differences between graphics stack and current real PDF * state to the file */ void updateGraphicsState(); /* writes a transparency group object */ bool writeTransparentObject( TransparencyEmit& rObject ); /* writes an XObject of type image, may create a second for the mask */ bool writeBitmapObject( BitmapEmit& rObject, bool bMask = false ); bool writeJPG( JPGEmit& rEmit ); /* tries to find the bitmap by its id and returns its emit data if exists, else creates a new emit data block */ const BitmapEmit& createBitmapEmit( const BitmapEx& rBitmapEx, bool bDrawMask = false ); /* writes the Do operation inside the content stream */ void drawBitmap( const Point& rDestPt, const Size& rDestSize, const BitmapEmit& rBitmap, const Color& rFillColor ); /* write the function object for a Gradient */ bool writeGradientFunction( GradientEmit& rObject ); /* creates a GradientEmit and returns its object number */ sal_Int32 createGradient( const Gradient& rGradient, const Size& rSize ); /* writes all tilings */ bool emitTilings(); /* writes all gradient patterns */ bool emitGradients(); /* writes a builtin font object and returns its objectid (or 0 in case of failure ) */ sal_Int32 emitBuiltinFont( const ImplFontData*, sal_Int32 nObject = -1 ); /* writes a type1 embedded font object and returns its mapping from font ids to object ids (or 0 in case of failure ) */ std::map< sal_Int32, sal_Int32 > emitEmbeddedFont( const ImplFontData*, EmbedFont& ); /* writes a type1 system font object and returns its mapping from font ids to object ids (or 0 in case of failure ) */ std::map< sal_Int32, sal_Int32 > emitSystemFont( const ImplFontData*, EmbedFont& ); /* writes a font descriptor and returns its object id (or 0) */ sal_Int32 emitFontDescriptor( const ImplFontData*, FontSubsetInfo&, sal_Int32 nSubsetID, sal_Int32 nStream ); /* writes a ToUnicode cmap, returns the corresponding stream object */ sal_Int32 createToUnicodeCMap( sal_uInt8* pEncoding, sal_Ucs* pUnicodes, sal_Int32* pUnicodesPerGlyph, sal_Int32* pEncToUnicodeIndex, int nGlyphs ); /* get resource dict object number */ sal_Int32 getResourceDictObj() { if( m_nResourceDict <= 0 ) m_nResourceDict = createObject(); return m_nResourceDict; } /* get the font dict object */ sal_Int32 getFontDictObject() { if( m_nFontDictObject <= 0 ) m_nFontDictObject = createObject(); return m_nFontDictObject; } /* push resource into current (redirected) resource dict */ void pushResource( ResourceKind eKind, const rtl::OString& rResource, sal_Int32 nObject ); void appendBuiltinFontsToDict( rtl::OStringBuffer& rDict ) const; /* writes a the font dictionary and emits all font objects * returns object id of font directory (or 0 on error) */ bool emitFonts(); /* writes the Resource dictionary; * returns dict object id (or 0 on error) */ sal_Int32 emitResources(); // appends a dest bool appendDest( sal_Int32 nDestID, rtl::OStringBuffer& rBuffer ); // write all links bool emitLinkAnnotations(); // write all notes bool emitNoteAnnotations(); // write the appearance streams of a widget bool emitAppearances( PDFWidget& rWidget, rtl::OStringBuffer& rAnnotDict ); // clean up radio button "On" values void ensureUniqueRadioOnValues(); // write all widgets bool emitWidgetAnnotations(); // writes all annotation objects bool emitAnnotations(); // writes the dest dict for the catalog sal_Int32 emitDestDict(); //write the named destination stuff sal_Int32 emitNamedDestinations();//i56629 // writes outline dict and tree sal_Int32 emitOutline(); // puts the attribute objects of a structure element into the returned string, // helper for emitStructure rtl::OString emitStructureAttributes( PDFStructureElement& rEle ); //--->i94258 // the maximum array elements allowed for PDF array object static const sal_uInt32 ncMaxPDFArraySize = 8191; //check if internal dummy container are needed in the structure elements void addInternalStructureContainer( PDFStructureElement& rEle ); //<---i94258 // writes document structure sal_Int32 emitStructure( PDFStructureElement& rEle ); // writes structure parent tree sal_Int32 emitStructParentTree( sal_Int32 nTreeObject ); // writes page tree and catalog bool emitCatalog(); // writes xref and trailer bool emitTrailer(); // emit additional streams collected; also create there object numbers bool emitAdditionalStreams(); // emits info dict (if applicable) sal_Int32 emitInfoDict( ); // acrobat reader 5 and 6 use the order of the annotations // as their tab order; since PDF1.5 one can make the // tab order explicit by using the structure tree void sortWidgets(); // updates the count numbers of outline items sal_Int32 updateOutlineItemCount( std::vector< sal_Int32 >& rCounts, sal_Int32 nItemLevel, sal_Int32 nCurrentItemId ); // default appearences for widgets sal_Int32 findRadioGroupWidget( const PDFWriter::RadioButtonWidget& rRadio ); Font replaceFont( const Font& rControlFont, const Font& rAppSetFont ); sal_Int32 getBestBuiltinFont( const Font& rFont ); sal_Int32 getSystemFont( const Font& i_rFont ); // used for edit and listbox Font drawFieldBorder( PDFWidget&, const PDFWriter::AnyWidget&, const StyleSettings& ); void createDefaultPushButtonAppearance( PDFWidget&, const PDFWriter::PushButtonWidget& rWidget ); void createDefaultCheckBoxAppearance( PDFWidget&, const PDFWriter::CheckBoxWidget& rWidget ); void createDefaultRadioButtonAppearance( PDFWidget&, const PDFWriter::RadioButtonWidget& rWidget ); void createDefaultEditAppearance( PDFWidget&, const PDFWriter::EditWidget& rWidget ); void createDefaultListBoxAppearance( PDFWidget&, const PDFWriter::ListBoxWidget& rWidget ); /* ensure proper escapement and uniqueness of field names */ void createWidgetFieldName( sal_Int32 i_nWidgetsIndex, const PDFWriter::AnyWidget& i_rInWidget ); /* adds an entry to m_aObjects and returns its index+1, * sets the offset to ~0 */ sal_Int32 createObject(); /* sets the offset of object n to the current position of output file+1 */ bool updateObject( sal_Int32 n ); bool writeBuffer( const void* pBuffer, sal_uInt64 nBytes ); void beginCompression(); void endCompression(); void beginRedirect( SvStream* pStream, const Rectangle& ); SvStream* endRedirect(); void endPage(); void beginStructureElementMCSeq(); void endStructureElementMCSeq(); /** checks whether a non struct element lies in the ancestor hierarchy of the current structure element @returns if no NonStructElement was found in ancestor path and tagged PDF output is enabled else */ bool checkEmitStructure(); /* draws an emphasis mark */ void drawEmphasisMark( long nX, long nY, const PolyPolygon& rPolyPoly, sal_Bool bPolyLine, const Rectangle& rRect1, const Rectangle& rRect2 ); /* true if PDF/A-1a or PDF/A-1b is output */ sal_Bool m_bIsPDF_A1; PDFWriter& m_rOuterFace; /* i12626 methods for PDF security pad a password according algorithm 3.2, step 1 */ static void padPassword( const rtl::OUString& i_rPassword, sal_uInt8* o_pPaddedPW ); /* algorithm 3.2: compute an encryption key */ static bool computeEncryptionKey( EncHashTransporter*, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, sal_Int32 i_nAccessPermissions ); /* algorithm 3.3: computing the encryption dictionary'ss owner password value ( /O ) */ static bool computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, const sal_uInt8* i_pPaddedUserPassword, std::vector< sal_uInt8 >& io_rOValue, sal_Int32 i_nKeyLength ); /* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */ static bool computeUDictionaryValue( EncHashTransporter* i_pTransporter, vcl::PDFWriter::PDFEncryptionProperties& io_rProperties, sal_Int32 i_nKeyLength, sal_Int32 i_nAccessPermissions ); static void computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIdentifier, const vcl::PDFWriter::PDFDocInfo& i_rDocInfo, rtl::OString& o_rCString1, rtl::OString& o_rCString2 ); static sal_Int32 computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties, sal_Int32& o_rKeyLength, sal_Int32& o_rRC4KeyLength ); void setupDocInfo(); bool prepareEncryption( const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& ); // helper for playMetafile void implWriteGradient( const PolyPolygon& rPolyPoly, const Gradient& rGradient, VirtualDevice* pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& ); void implWriteBitmapEx( const Point& rPoint, const Size& rSize, const BitmapEx& rBitmapEx, VirtualDevice* pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& ); // helpers for CCITT 1bit bitmap stream void putG4Bits( sal_uInt32 i_nLength, sal_uInt32 i_nCode, BitStreamState& io_rState ); void putG4Span( long i_nSpan, bool i_bWhitePixel, BitStreamState& io_rState ); void writeG4Stream( BitmapReadAccess* i_pBitmap ); // color helper functions void appendStrokingColor( const Color& rColor, rtl::OStringBuffer& rBuffer ); void appendNonStrokingColor( const Color& rColor, rtl::OStringBuffer& rBuffer ); public: PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >&, PDFWriter& ); ~PDFWriterImpl(); static com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > initEncryption( const rtl::OUString& i_rOwnerPassword, const rtl::OUString& i_rUserPassword, bool b128Bit ); /* for OutputDevice so the reference device can have a list * that contains only suitable fonts (subsettable or builtin) * produces a new font list */ ImplDevFontList* filterDevFontList( ImplDevFontList* pFontList ); /* for OutputDevice: get layout for builtin fonts */ bool isBuiltinFont( const ImplFontData* ) const; SalLayout* GetTextLayout( ImplLayoutArgs& rArgs, FontSelectPattern* pFont ); void getFontMetric( FontSelectPattern* pFont, ImplFontMetricData* pMetric ) const; /* for documentation of public functions please see pdfwriter.hxx */ OutputDevice* getReferenceDevice(); /* document structure */ sal_Int32 newPage( sal_Int32 nPageWidth , sal_Int32 nPageHeight, PDFWriter::Orientation eOrientation ); bool emit(); std::set< PDFWriter::ErrorCode > getErrors(); void insertError( PDFWriter::ErrorCode eErr ) { m_aErrors.insert( eErr ); } void playMetafile( const GDIMetaFile&, vcl::PDFExtOutDevData*, const vcl::PDFWriter::PlayMetafileContext&, VirtualDevice* pDummyDev = NULL ); Size getCurPageSize() const { Size aSize; if( m_nCurrentPage >= 0 && m_nCurrentPage < (sal_Int32)m_aPages.size() ) aSize = Size( m_aPages[ m_nCurrentPage ].m_nPageWidth, m_aPages[ m_nCurrentPage ].m_nPageHeight ); return aSize; } PDFWriter::PDFVersion getVersion() const { return m_aContext.Version; } void setDocumentLocale( const com::sun::star::lang::Locale& rLoc ) { m_aContext.DocumentLocale = rLoc; } /* graphics state */ void push( sal_uInt16 nFlags ); void pop(); void setFont( const Font& rFont ); void setMapMode( const MapMode& rMapMode ); const MapMode& getMapMode() { return m_aGraphicsStack.front().m_aMapMode; } void setLineColor( const Color& rColor ) { m_aGraphicsStack.front().m_aLineColor = ImplIsColorTransparent(rColor) ? Color( COL_TRANSPARENT ) : rColor; m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateLineColor; } void setFillColor( const Color& rColor ) { m_aGraphicsStack.front().m_aFillColor = ImplIsColorTransparent(rColor) ? Color( COL_TRANSPARENT ) : rColor; m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFillColor; } void setTextLineColor() { m_aGraphicsStack.front().m_aTextLineColor = Color( COL_TRANSPARENT ); m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateTextLineColor; } void setTextLineColor( const Color& rColor ) { m_aGraphicsStack.front().m_aTextLineColor = rColor; m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateTextLineColor; } void setOverlineColor() { m_aGraphicsStack.front().m_aOverlineColor = Color( COL_TRANSPARENT ); m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateOverlineColor; } void setOverlineColor( const Color& rColor ) { m_aGraphicsStack.front().m_aOverlineColor = rColor; m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateOverlineColor; } void setTextFillColor( const Color& rColor ) { m_aGraphicsStack.front().m_aFont.SetFillColor( rColor ); m_aGraphicsStack.front().m_aFont.SetTransparent( ImplIsColorTransparent( rColor ) ? sal_True : sal_False ); m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFont; } void setTextFillColor() { m_aGraphicsStack.front().m_aFont.SetFillColor( Color( COL_TRANSPARENT ) ); m_aGraphicsStack.front().m_aFont.SetTransparent( sal_True ); m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFont; } void setTextColor( const Color& rColor ) { m_aGraphicsStack.front().m_aFont.SetColor( rColor ); m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFont; } void clearClipRegion() { m_aGraphicsStack.front().m_aClipRegion.clear(); m_aGraphicsStack.front().m_bClipRegion = false; m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateClipRegion; } void setClipRegion( const basegfx::B2DPolyPolygon& rRegion ); void moveClipRegion( sal_Int32 nX, sal_Int32 nY ); bool intersectClipRegion( const Rectangle& rRect ); bool intersectClipRegion( const basegfx::B2DPolyPolygon& rRegion ); void setLayoutMode( sal_Int32 nLayoutMode ) { m_aGraphicsStack.front().m_nLayoutMode = nLayoutMode; m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateLayoutMode; } void setDigitLanguage( LanguageType eLang ) { m_aGraphicsStack.front().m_aDigitLanguage = eLang; m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateDigitLanguage; } void setTextAlign( TextAlign eAlign ) { m_aGraphicsStack.front().m_aFont.SetAlign( eAlign ); m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFont; } /* actual drawing functions */ void drawText( const Point& rPos, const String& rText, xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN, bool bTextLines = true ); void drawTextArray( const Point& rPos, const String& rText, const sal_Int32* pDXArray = NULL, xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN, bool bTextLines = true ); void drawStretchText( const Point& rPos, sal_uLong nWidth, const String& rText, xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN, bool bTextLines = true ); void drawText( const Rectangle& rRect, const String& rOrigStr, sal_uInt16 nStyle, bool bTextLines = true ); void drawTextLine( const Point& rPos, long nWidth, FontStrikeout eStrikeout, FontUnderline eUnderline, FontUnderline eOverline, bool bUnderlineAbove ); void drawWaveTextLine( rtl::OStringBuffer& aLine, long nWidth, FontUnderline eTextLine, Color aColor, bool bIsAbove ); void drawStraightTextLine( rtl::OStringBuffer& aLine, long nWidth, FontUnderline eTextLine, Color aColor, bool bIsAbove ); void drawStrikeoutLine( rtl::OStringBuffer& aLine, long nWidth, FontStrikeout eStrikeout, Color aColor ); void drawStrikeoutChar( const Point& rPos, long nWidth, FontStrikeout eStrikeout ); void drawLine( const Point& rStart, const Point& rStop ); void drawLine( const Point& rStart, const Point& rStop, const LineInfo& rInfo ); void drawPolygon( const Polygon& rPoly ); void drawPolyPolygon( const PolyPolygon& rPolyPoly ); void drawPolyLine( const Polygon& rPoly ); void drawPolyLine( const Polygon& rPoly, const LineInfo& rInfo ); void drawPolyLine( const Polygon& rPoly, const PDFWriter::ExtLineInfo& rInfo ); void drawPixel( const Point& rPt, const Color& rColor ); void drawRectangle( const Rectangle& rRect ); void drawRectangle( const Rectangle& rRect, sal_uInt32 nHorzRound, sal_uInt32 nVertRound ); void drawEllipse( const Rectangle& rRect ); void drawArc( const Rectangle& rRect, const Point& rStart, const Point& rStop, bool bWithPie, bool bWidthChord ); void drawBitmap( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap ); void drawBitmap( const Point& rDestPoint, const Size& rDestSize, const BitmapEx& rBitmap ); void drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const Size& rSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask ); void drawGradient( const Rectangle& rRect, const Gradient& rGradient ); void drawHatch( const PolyPolygon& rPolyPoly, const Hatch& rHatch ); void drawWallpaper( const Rectangle& rRect, const Wallpaper& rWall ); void drawTransparent( const PolyPolygon& rPolyPoly, sal_uInt32 nTransparentPercent ); void beginTransparencyGroup(); void endTransparencyGroup( const Rectangle& rBoundingBox, sal_uInt32 nTransparentPercent ); void emitComment( const char* pComment ); //--->i56629 named destinations sal_Int32 createNamedDest( const rtl::OUString& sDestName, const Rectangle& rRect, sal_Int32 nPageNr = -1, PDFWriter::DestAreaType eType = PDFWriter::XYZ ); //--->i59651 //emits output intent sal_Int32 emitOutputIntent(); //emits the document metadata sal_Int32 emitDocumentMetadata(); // links sal_Int32 createLink( const Rectangle& rRect, sal_Int32 nPageNr = -1 ); sal_Int32 createDest( const Rectangle& rRect, sal_Int32 nPageNr = -1, PDFWriter::DestAreaType eType = PDFWriter::XYZ ); sal_Int32 registerDestReference( sal_Int32 nDestId, const Rectangle& rRect, sal_Int32 nPageNr = -1, PDFWriter::DestAreaType eType = PDFWriter::XYZ ); sal_Int32 setLinkDest( sal_Int32 nLinkId, sal_Int32 nDestId ); sal_Int32 setLinkURL( sal_Int32 nLinkId, const rtl::OUString& rURL ); void setLinkPropertyId( sal_Int32 nLinkId, sal_Int32 nPropertyId ); // outline sal_Int32 createOutlineItem( sal_Int32 nParent = 0, const rtl::OUString& rText = rtl::OUString(), sal_Int32 nDestID = -1 ); sal_Int32 setOutlineItemParent( sal_Int32 nItem, sal_Int32 nNewParent ); sal_Int32 setOutlineItemText( sal_Int32 nItem, const rtl::OUString& rText ); sal_Int32 setOutlineItemDest( sal_Int32 nItem, sal_Int32 nDestID ); // notes void createNote( const Rectangle& rRect, const PDFNote& rNote, sal_Int32 nPageNr = -1 ); // structure elements sal_Int32 beginStructureElement( PDFWriter::StructElement eType, const rtl::OUString& rAlias ); void endStructureElement(); bool setCurrentStructureElement( sal_Int32 nElement ); bool setStructureAttribute( enum PDFWriter::StructAttribute eAttr, enum PDFWriter::StructAttributeValue eVal ); bool setStructureAttributeNumerical( enum PDFWriter::StructAttribute eAttr, sal_Int32 nValue ); void setStructureBoundingBox( const Rectangle& rRect ); void setActualText( const String& rText ); void setAlternateText( const String& rText ); // transitional effects void setAutoAdvanceTime( sal_uInt32 nSeconds, sal_Int32 nPageNr = -1 ); void setPageTransition( PDFWriter::PageTransition eType, sal_uInt32 nMilliSec, sal_Int32 nPageNr = -1 ); // controls sal_Int32 createControl( const PDFWriter::AnyWidget& rControl, sal_Int32 nPageNr = -1 ); // additional streams void addStream( const String& rMimeType, PDFOutputStream* pStream, bool bCompress ); // helper: eventually begin marked content sequence and // emit a comment in debug case void MARK( const char* #if OSL_DEBUG_LEVEL > 1 pString #endif ) { beginStructureElementMCSeq(); #if OSL_DEBUG_LEVEL > 1 emitComment( pString ); #endif } }; } #endif //_VCL_PDFEXPORT_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */