summaryrefslogtreecommitdiff
path: root/vcl/source/gdi/pdfwriter_impl.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/gdi/pdfwriter_impl.hxx')
-rw-r--r--vcl/source/gdi/pdfwriter_impl.hxx1375
1 files changed, 1375 insertions, 0 deletions
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
new file mode 100644
index 000000000000..2eacdc215dd8
--- /dev/null
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -0,0 +1,1375 @@
+/*************************************************************************
+ *
+ * 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
+ * <http://www.openoffice.org/license.html>
+ * 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 "vcl/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 <vcl/sallayout.hxx>
+#include "pdffontcache.hxx"
+
+#include <vector>
+#include <map>
+#include <hash_map>
+#include <list>
+
+#include <boost/shared_array.hpp>
+
+class ImplFontSelectData;
+class ImplFontMetricData;
+class FontSubsetInfo;
+class ZCodec;
+
+// 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<sal_Int32> m_aStreamObjects;
+ sal_Int32 m_nStreamLengthObject;
+ sal_uInt64 m_nBeginStreamPos;
+ std::vector<sal_Int32> m_aAnnotations;
+ std::vector<sal_Int32> 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 )
+ {
+ 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 ) {}
+ ~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<sal_Ucs> m_pUnicodes;
+ sal_uInt8 m_nSubsetGlyphID;
+
+ public:
+ GlyphEmit() : m_nUnicodes(0), m_nSubsetGlyphID(0)
+ {
+ rtl_zeroMemory( m_aBufferedUnicodes, sizeof( m_aBufferedUnicodes ) );
+ m_nMaxUnicodes = sizeof(m_aBufferedUnicodes)/sizeof(m_aBufferedUnicodes[0]);
+ }
+ ~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 std::hash_map< rtl::OString, SvMemoryStream*, rtl::OStringHash > PDFAppearanceStreams;
+ typedef std::hash_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;
+ USHORT 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<sal_Int32> m_aKids; // widget children, contains object numbers
+ std::vector<sal_Int32> 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<rtl::OUString> m_aListEntries;
+ std::vector<sal_Int32> 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<PDFWriter::StructAttribute, PDFStructureAttribute > 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;
+ PDFDocInfo m_aDocInfo;
+ /* 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<JPGEmit> 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<PDFNamedDest> m_aNamedDests;
+ //<---
+ /* contains all dests ever set during the PDF creation,
+ dest id is always the dest's position in this vector
+ */
+ std::vector<PDFDest> m_aDests;
+ /* contains all links ever set during PDF creation,
+ link id is always the link's position in this vector
+ */
+ std::vector<PDFLink> 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<sal_Int32, sal_Int32> m_aLinkPropertyMap;
+ /* contains all outline items,
+ object 0 is the outline root
+ */
+ std::vector<PDFOutlineEntry> m_aOutline;
+ /* contains all notes set during PDF creation
+ */
+ std::vector<PDFNoteEntry> m_aNotes;
+ /* the root of the structure tree
+ */
+ std::vector<PDFStructureElement> 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 */
+ std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >
+ m_aRoleMap;
+
+ /* contains all widgets used in the PDF
+ */
+ std::vector<PDFWidget> m_aWidgets;
+ /* maps radio group id to index of radio group control in m_aWidgets */
+ std::map< sal_Int32, sal_Int32 > m_aRadioGroupWidgets;
+ /* used to store control id during beginControlAppearance/endControlAppearance */
+ sal_Int32 m_nCurrentControl;
+ /* hash_map for field names, used to ensure unique field names */
+ std::hash_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 */
+ sal_uInt8 m_nPadString[ENCRYPTED_PWD_SIZE];
+/* the owner password, in clear text */
+ rtl::OUString m_aOwnerPassword;
+/* the padded owner password */
+ sal_uInt8 m_nPaddedOwnerPassword[ENCRYPTED_PWD_SIZE];
+/* the encryption dictionary owner password, according to algorithm 3.3 */
+ sal_uInt8 m_nEncryptedOwnerPassword[ENCRYPTED_PWD_SIZE];
+/* the user password, in clear text */
+ rtl::OUString m_aUserPassword;
+/* the padded user password */
+ sal_uInt8 m_nPaddedUserPassword[ENCRYPTED_PWD_SIZE];
+/* the encryption dictionary user password, according to algorithm 3.4 or 3.5 depending on the
+ security handler revision */
+ sal_uInt8 m_nEncryptedUserPassword[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_uInt8 m_nEncryptionKey[MAXIMUM_RC4_KEY_LENGTH];
+ 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;
+/* the document ID, the raw MD5 hash */
+ sal_uInt8 m_nDocID[MD5_DIGEST_SIZE];
+/* string buffer to hold document ID, this is the output string */
+ rtl::OStringBuffer m_aDocID;
+/* string to hold the PDF creation date */
+ rtl::OStringBuffer m_aCreationDateString;
+/* string to hold the PDF creation date, for PDF/A metadata */
+ rtl::OStringBuffer 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 )
+ {
+ if( m_nEncryptionBufferSize < newSize )
+ {
+/* reallocate the buffer, the used function allocate as rtl_allocateMemory
+ if the pointer parameter is NULL */
+ m_pEncryptionBuffer = (sal_uInt8*)rtl_reallocateMemory( m_pEncryptionBuffer, newSize );
+ if( m_pEncryptionBuffer )
+ m_nEncryptionBufferSize = newSize;
+ else
+ m_nEncryptionBufferSize = 0;
+ }
+ return ( m_nEncryptionBufferSize != 0 );
+ }
+/* init the internal pad string */
+ void initPadString()
+ {
+ static const sal_uInt8 nPadString[32] =
+ {
+ 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
+ 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A
+ };
+
+ for(sal_uInt32 i = 0; i < sizeof( nPadString ); i++ )
+ m_nPadString[i] = nPadString[i];
+
+ };
+/* initialize the encryption engine */
+ void initEncryption();
+
+/* 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 )
+ {
+ if( m_aContext.Encrypt )
+ {
+ m_bEncryptThisStream = true;
+ register sal_Int32 i = m_nKeyLength;
+ m_nEncryptionKey[i++] = (sal_uInt8)nObject;
+ m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 8 );
+ m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 16 );
+//the other location of m_nEncryptionKey are already set to 0, our fixed generation number
+// do the MD5 hash
+ sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ];
+ // the i+2 to take into account the generation number, always zero
+ rtl_digest_MD5( &m_nEncryptionKey, i+2, nMD5Sum, sizeof(nMD5Sum) );
+// initialize the RC4 with the key
+// key legth: see algoritm 3.1, step 4: (N+5) max 16
+ rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 );
+ }
+ };
+
+ void disableStreamEncryption() { m_bEncryptThisStream = false; };
+
+/* */
+ void enableStringEncryption( register sal_Int32 nObject )
+ {
+ register sal_Int32 i = m_nKeyLength;
+ m_nEncryptionKey[i++] = (sal_uInt8)nObject;
+ m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 8 );
+ m_nEncryptionKey[i++] = (sal_uInt8)( nObject >> 16 );
+//the other location of m_nEncryptionKey are already set to 0, our fixed generation number
+// do the MD5 hash
+ sal_uInt8 nMD5Sum[ RTL_DIGEST_LENGTH_MD5 ];
+ // the i+2 to take into account the generation number, always zero
+ rtl_digest_MD5( &m_nEncryptionKey, i+2, nMD5Sum, sizeof(nMD5Sum) );
+// initialize the RC4 with the key
+// key legth: see algoritm 3.1, step 4: (N+5) max 16
+ rtl_cipher_initARCFOUR( m_aCipher, rtl_Cipher_DirectionEncode, nMD5Sum, m_nRC4KeyLength, NULL, 0 );
+ };
+
+// 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 );
+ 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<PDFGlyph>& rGlyphs, rtl::OStringBuffer& rLine, const Point& rAlignOffset, const Matrix3& rRotScale, double fAngle, double fXScale, double fSkew, sal_Int32 nFontHeight );
+ void drawHorizontalGlyphs( const std::vector<PDFGlyph>& 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& );
+ // returns an empty rect if no redirection is happending
+ Rectangle getRedirectTargetRect() const;
+ 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
+ <true/> if no NonStructElement was found in ancestor path and tagged
+ PDF output is enabled
+ <false/> else
+ */
+ bool checkEmitStructure();
+
+ /* draws an emphasis mark */
+ void drawEmphasisMark( long nX, long nY, const PolyPolygon& rPolyPoly, BOOL bPolyLine, const Rectangle& rRect1, const Rectangle& rRect2 );
+
+ /* true if PDF/A-1a or PDF/A-1b is output */
+ sal_Bool m_bIsPDF_A1;
+
+/*
+i12626
+methods for PDF security
+
+ pad a password according algorithm 3.2, step 1 */
+ void padPassword( const rtl::OUString aPassword, sal_uInt8 *paPasswordTarget );
+/* algorithm 3.2: compute an encryption key */
+ void computeEncryptionKey( sal_uInt8 *paThePaddedPassword, sal_uInt8 *paEncryptionKey );
+/* algorithm 3.3: computing the encryption dictionary'ss owner password value ( /O ) */
+ void computeODictionaryValue();
+/* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */
+ void computeUDictionaryValue();
+
+public:
+ PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext );
+ ~PDFWriterImpl();
+
+ /* 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, ImplFontSelectData* pFont );
+ void getFontMetric( ImplFontSelectData* 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 ); }
+
+ 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 setDocInfo( const PDFDocInfo& rInfo );
+ const PDFDocInfo& getDocInfo() const { return m_aDocInfo; }
+
+ 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 );
+ void setMapMode() { setMapMode( m_aMapMode ); }
+
+
+ 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 ) ? TRUE : 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( 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;
+ }
+
+ void setAntiAlias( sal_Int32 nAntiAlias )
+ {
+ m_aGraphicsStack.front().m_nAntiAlias = nAntiAlias;
+ m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateAntiAlias;
+ }
+
+ /* 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, 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, USHORT 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 drawWaveLine( const Point& rStart, const Point& rStop, sal_Int32 nDelta, sal_Int32 nLineWidth );
+
+ void drawPixel( const Point& rPt, const Color& rColor );
+ void drawPixel( const Polygon& rPts, const Color* pColors = NULL );
+
+ 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 drawMask( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap, const Color& rFillColor );
+ void drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const Size& rSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask );
+
+ void drawGradient( const Rectangle& rRect, const Gradient& rGradient );
+ void drawGradient( const PolyPolygon& rPolyPoly, 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 endTransparencyGroup( const Rectangle& rBoundingBox, const Bitmap& rAlphaMask );
+ void beginPattern( const Rectangle& rCell );
+ sal_Int32 endPattern( const SvtGraphicFill::Transform& rTransform );
+ void drawPolyPolygon( const PolyPolygon& rPolyPoly, sal_Int32 nPattern, bool bEOFill );
+
+ 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 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 );
+ sal_Int32 getCurrentStructureElement();
+ 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 );
+ void beginControlAppearance( sal_Int32 nControl );
+ bool endControlAppearance( PDFWriter::WidgetState eState );
+
+ // 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
+
+