xref: /trunk/main/vcl/source/gdi/pdfwriter_impl.hxx (revision c1e8cc3a)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _VCL_PDFWRITER_IMPL_HXX
24 #define _VCL_PDFWRITER_IMPL_HXX
25 
26 #include "vcl/pdfwriter.hxx"
27 #include "rtl/ustring.hxx"
28 #include "osl/file.h"
29 #include "tools/gen.hxx"
30 #include "tools/stream.hxx"
31 #include "vcl/outdev.hxx"
32 #include "vcl/bitmapex.hxx"
33 #include "vcl/gradient.hxx"
34 #include "vcl/hatch.hxx"
35 #include "vcl/wall.hxx"
36 #include "outdata.hxx"
37 #include "rtl/strbuf.hxx"
38 #include "rtl/cipher.h"
39 #include "rtl/digest.h"
40 #include "com/sun/star/util/XURLTransformer.hpp"
41 #include "com/sun/star/lang/Locale.hpp"
42 
43 #include <sallayout.hxx>
44 #include "pdffontcache.hxx"
45 
46 #include <vector>
47 #include <map>
48 #include <hash_map>
49 #include <list>
50 
51 #include <boost/shared_array.hpp>
52 
53 class ImplFontSelectData;
54 class ImplFontMetricData;
55 class FontSubsetInfo;
56 class ZCodec;
57 class EncHashTransporter;
58 struct BitStreamState;
59 
60 // the maximum password length
61 #define ENCRYPTED_PWD_SIZE     32
62 #define MD5_DIGEST_SIZE        16
63 #define SECUR_40BIT_KEY         5
64 // security 128 bit
65 #define SECUR_128BIT_KEY       16
66 // maximum length of MD5 digest input, in step 2 of algorithm 3.1
67 // PDF spec ver. 1.4: see there for details
68 #define MAXIMUM_RC4_KEY_LENGTH (SECUR_128BIT_KEY+3+2)
69 
70 namespace vcl
71 {
72 
73 class PDFSalLayout;
74 class PDFStreamIf;
75 class Matrix3;
76 
77 class PDFWriterImpl
78 {
79     friend class PDFSalLayout;
80     friend class PDFStreamIf;
81 public:
82     // definition of structs
83     struct BuiltinFont
84     {
85         const char *        		m_pName;                     // Name
86         const char *        		m_pStyleName;                // StyleName
87         const char *        		m_pPSName;					 // PSName
88         int							m_nAscent;
89         int							m_nDescent;
90         FontFamily					m_eFamily;                   // Family
91 		CharSet						m_eCharSet;                  // CharSet
92 	    FontPitch					m_ePitch;                    // Pitch
93 		FontWidth					m_eWidthType;                // WidthType
94 		FontWeight					m_eWeight;                   // Weight
95 		FontItalic					m_eItalic;                   // Italic
96         int							m_aWidths[256];				 // character metrics
97 
98         rtl::OString getNameObject() const;
99     };
100 
101 
102     enum ResourceKind { ResXObject, ResExtGState, ResShading, ResPattern };
103     typedef std::map< rtl::OString, sal_Int32 > ResourceMap;
104     struct ResourceDict
105     {
106         // note: handle fonts globally for performance
107         ResourceMap m_aXObjects;
108         ResourceMap m_aExtGStates;
109         ResourceMap m_aShadings;
110         ResourceMap m_aPatterns;
111 
112         void append( rtl::OStringBuffer&, sal_Int32 nFontDictObject );
113     };
114 
115     struct PDFPage
116     {
117         PDFWriterImpl*				m_pWriter;
118         sal_Int32					m_nPageWidth;			// in inch/72
119         sal_Int32					m_nPageHeight;			// in inch/72
120         PDFWriter::Orientation		m_eOrientation;
121         sal_Int32					m_nPageObject;
122         sal_Int32					m_nPageIndex;
123         std::vector<sal_Int32>		m_aStreamObjects;
124         sal_Int32					m_nStreamLengthObject;
125         sal_uInt64					m_nBeginStreamPos;
126         std::vector<sal_Int32>		m_aAnnotations;
127         std::vector<sal_Int32>		m_aMCIDParents;
128         PDFWriter::PageTransition	m_eTransition;
129         sal_uInt32					m_nTransTime;
130         sal_uInt32					m_nDuration;
131         bool                        m_bHasWidgets;
132 
133         PDFPage( PDFWriterImpl* pWriter, sal_Int32 nPageWidth, sal_Int32 nPageHeight, PDFWriter::Orientation eOrientation );
134         ~PDFPage();
135 
136         void beginStream();
137         void endStream();
138         bool emit( sal_Int32 nParentPage );
139 
140         // converts point from ref device coordinates to
141         // page coordinates and appends the point to the buffer
142         // if bNeg is true, the coordinates are inverted AFTER transformation
143         // to page (useful for transformation matrices
144         // if pOutPoint is set it will be updated to the emitted point
145         // (in PDF map mode, that is 10th of point)
146         void appendPoint( const Point& rPoint, rtl::OStringBuffer& rBuffer, bool bNeg = false, Point* pOutPoint = NULL ) const;
147         // appends a B2DPoint without further transformation
148         void appendPixelPoint( const basegfx::B2DPoint& rPoint, rtl::OStringBuffer& rBuffer ) const;
149         // appends a rectangle
150         void appendRect( const Rectangle& rRect, rtl::OStringBuffer& rBuffer ) const;
151         // converts a rectangle to 10th points page space
152         void convertRect( Rectangle& rRect ) const;
153         // appends a polygon optionally closing it
154         void appendPolygon( const Polygon& rPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const;
155         // appends a polygon optionally closing it
156         void appendPolygon( const basegfx::B2DPolygon& rPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const;
157         // appends a polypolygon optionally closing the subpaths
158         void appendPolyPolygon( const PolyPolygon& rPolyPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const;
159         // appends a polypolygon optionally closing the subpaths
160         void appendPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPoly, rtl::OStringBuffer& rBuffer, bool bClose = true ) const;
161         // converts a length (either vertical or horizontal; this
162         // can be important if the source MapMode is not
163         // symmetrical) to page length and appends it to the buffer
164         // if pOutLength is set it will be updated to the emitted length
165         // (in PDF map mode, that is 10th of point)
166         void appendMappedLength( sal_Int32 nLength, rtl::OStringBuffer& rBuffer, bool bVertical = true, sal_Int32* pOutLength = NULL ) const;
167         // the same for double values
168         void appendMappedLength( double fLength, rtl::OStringBuffer& rBuffer, bool bVertical = true, sal_Int32* pOutLength = NULL, sal_Int32 nPrecision = 5 ) const;
169         // appends LineInfo
170         // returns false if too many dash array entry were created for
171         // the implementation limits of some PDF readers
172         bool appendLineInfo( const LineInfo& rInfo, rtl::OStringBuffer& rBuffer ) const;
173         // appends a horizontal waveline with vertical offset (helper for drawWaveLine)
174         void appendWaveLine( sal_Int32 nLength, sal_Int32 nYOffset, sal_Int32 nDelta, rtl::OStringBuffer& rBuffer ) const;
175 
getWidthvcl::PDFWriterImpl::PDFPage176         sal_Int32 getWidth() const { return m_nPageWidth ? m_nPageWidth : m_pWriter->m_nInheritedPageWidth; }
getHeightvcl::PDFWriterImpl::PDFPage177         sal_Int32 getHeight() const { return m_nPageHeight ? m_nPageHeight : m_pWriter->m_nInheritedPageHeight; }
178     };
179 
180     friend struct PDFPage;
181 
182     struct BitmapID
183     {
184         Size		m_aPixelSize;
185         sal_Int32	m_nSize;
186         sal_Int32	m_nChecksum;
187         sal_Int32	m_nMaskChecksum;
188 
BitmapIDvcl::PDFWriterImpl::BitmapID189         BitmapID() : m_nSize( 0 ), m_nChecksum( 0 ), m_nMaskChecksum( 0 ) {}
190 
operator =vcl::PDFWriterImpl::BitmapID191         BitmapID& operator=( const BitmapID& rCopy )
192         {
193             m_aPixelSize	= rCopy.m_aPixelSize;
194             m_nSize			= rCopy.m_nSize;
195             m_nChecksum		= rCopy.m_nChecksum;
196             m_nMaskChecksum	= rCopy.m_nMaskChecksum;
197             return *this;
198         }
199 
operator ==vcl::PDFWriterImpl::BitmapID200         bool operator==( const BitmapID& rComp )
201         {
202             return (m_aPixelSize == rComp.m_aPixelSize &&
203                     m_nSize == rComp.m_nSize &&
204                     m_nChecksum == rComp.m_nChecksum &&
205                     m_nMaskChecksum == rComp.m_nMaskChecksum );
206         }
207     };
208 
209     struct BitmapEmit
210     {
211         BitmapID	m_aID;
212         BitmapEx	m_aBitmap;
213         sal_Int32	m_nObject;
214         bool		m_bDrawMask;
215 
BitmapEmitvcl::PDFWriterImpl::BitmapEmit216         BitmapEmit() : m_bDrawMask( false ) {}
217     };
218 
219     struct JPGEmit
220     {
221         BitmapID			m_aID;
222         SvMemoryStream*		m_pStream;
223         Bitmap				m_aMask;
224         sal_Int32			m_nObject;
225         bool                m_bTrueColor;
226 
JPGEmitvcl::PDFWriterImpl::JPGEmit227         JPGEmit() : m_pStream( NULL ) {}
~JPGEmitvcl::PDFWriterImpl::JPGEmit228         ~JPGEmit() { delete m_pStream; }
229     };
230 
231     struct GradientEmit
232     {
233         Gradient	m_aGradient;
234         Size		m_aSize;
235         sal_Int32	m_nObject;
236     };
237 
238 	// for tilings (drawWallpaper, begin/endPattern)
239     struct TilingEmit
240     {
241         sal_Int32                   m_nObject;
242         Rectangle                   m_aRectangle;
243         Size                        m_aCellSize;
244         SvtGraphicFill::Transform   m_aTransform;
245         ResourceDict                m_aResources;
246         SvMemoryStream*             m_pTilingStream;
247 
TilingEmitvcl::PDFWriterImpl::TilingEmit248         TilingEmit()
249                 : m_nObject( 0 ),
250                   m_pTilingStream( NULL )
251         {}
252     };
253 
254     // for transparency group XObjects
255     struct TransparencyEmit
256     {
257         sal_Int32			m_nObject;
258         sal_Int32			m_nExtGStateObject;
259         double				m_fAlpha;
260         Rectangle			m_aBoundRect;
261         SvMemoryStream*		m_pContentStream;
262         SvMemoryStream*		m_pSoftMaskStream;
263 
TransparencyEmitvcl::PDFWriterImpl::TransparencyEmit264         TransparencyEmit()
265                 : m_nObject( 0 ),
266                   m_nExtGStateObject( -1 ),
267                   m_fAlpha( 0.0 ),
268                   m_pContentStream( NULL ),
269                   m_pSoftMaskStream( NULL )
270         {}
~TransparencyEmitvcl::PDFWriterImpl::TransparencyEmit271         ~TransparencyEmit()
272         {
273             delete m_pContentStream;
274             delete m_pSoftMaskStream;
275         }
276     };
277 
278     // font subsets
279     class GlyphEmit
280     {
281         // performance: actually this should probably a vector;
282         sal_Ucs		                    m_aBufferedUnicodes[3];
283         sal_Int32                       m_nUnicodes;
284         sal_Int32                       m_nMaxUnicodes;
285         boost::shared_array<sal_Ucs>    m_pUnicodes;
286         sal_uInt8                       m_nSubsetGlyphID;
287 
288     public:
GlyphEmit()289         GlyphEmit() : m_nUnicodes(0), m_nSubsetGlyphID(0)
290         {
291             rtl_zeroMemory( m_aBufferedUnicodes, sizeof( m_aBufferedUnicodes ) );
292             m_nMaxUnicodes = sizeof(m_aBufferedUnicodes)/sizeof(m_aBufferedUnicodes[0]);
293         }
~GlyphEmit()294         ~GlyphEmit()
295         {
296         }
297 
setGlyphId(sal_uInt8 i_nId)298         void setGlyphId( sal_uInt8 i_nId ) { m_nSubsetGlyphID = i_nId; }
getGlyphId() const299         sal_uInt8 getGlyphId() const { return m_nSubsetGlyphID; }
300 
addCode(sal_Ucs i_cCode)301         void addCode( sal_Ucs i_cCode )
302         {
303             if( m_nUnicodes == m_nMaxUnicodes )
304             {
305                 sal_Ucs* pNew = new sal_Ucs[ 2 * m_nMaxUnicodes];
306                 if( m_pUnicodes.get() )
307                     rtl_copyMemory( pNew, m_pUnicodes.get(), m_nMaxUnicodes * sizeof(sal_Ucs) );
308                 else
309                     rtl_copyMemory( pNew, m_aBufferedUnicodes, m_nMaxUnicodes * sizeof(sal_Ucs) );
310                 m_pUnicodes.reset( pNew );
311                 m_nMaxUnicodes *= 2;
312             }
313             if( m_pUnicodes.get() )
314                 m_pUnicodes[ m_nUnicodes++ ] = i_cCode;
315             else
316                 m_aBufferedUnicodes[ m_nUnicodes++ ] = i_cCode;
317         }
countCodes() const318         sal_Int32 countCodes() const { return m_nUnicodes; }
getCode(sal_Int32 i_nIndex) const319         sal_Ucs getCode( sal_Int32 i_nIndex ) const
320         {
321             sal_Ucs nRet = 0;
322             if( i_nIndex < m_nUnicodes )
323                 nRet = m_pUnicodes.get() ? m_pUnicodes[ i_nIndex ] : m_aBufferedUnicodes[ i_nIndex ];
324             return nRet;
325         }
326     };
327     typedef std::map< sal_GlyphId, GlyphEmit > FontEmitMapping;
328     struct FontEmit
329     {
330         sal_Int32			m_nFontID;
331         FontEmitMapping		m_aMapping;
332 
FontEmitvcl::PDFWriterImpl::FontEmit333         FontEmit( sal_Int32 nID ) : m_nFontID( nID ) {}
334     };
335     typedef std::list< FontEmit > FontEmitList;
336     struct Glyph
337     {
338         sal_Int32	m_nFontID;
339         sal_uInt8	m_nSubsetGlyphID;
340     };
341     typedef std::map< sal_GlyphId, Glyph > FontMapping;
342     struct FontSubset
343     {
344         FontEmitList		m_aSubsets;
345         FontMapping			m_aMapping;
346     };
347     typedef std::map< const ImplFontData*, FontSubset > FontSubsetData;
348     struct EmbedCode
349     {
350         sal_Ucs				m_aUnicode;
351         rtl::OString		m_aName;
352     };
353     struct EmbedEncoding
354     {
355         sal_Int32						m_nFontID;
356         std::vector< EmbedCode >		m_aEncVector;
357         std::map< sal_Ucs, sal_Int8 >	m_aCMap;
358     };
359     struct EmbedFont
360     {
361         sal_Int32						m_nNormalFontID;
362         std::list< EmbedEncoding >		m_aExtendedEncodings;
363 
EmbedFontvcl::PDFWriterImpl::EmbedFont364         EmbedFont() : m_nNormalFontID( 0 ) {}
365     };
366     typedef std::map< const ImplFontData*, EmbedFont > FontEmbedData;
367 
368     struct PDFDest
369     {
370         sal_Int32					m_nPage;
371         PDFWriter::DestAreaType		m_eType;
372         Rectangle					m_aRect;
373     };
374 
375 //--->i56629
376     struct PDFNamedDest
377     {
378         rtl::OUString               m_aDestName;
379         sal_Int32					m_nPage;
380         PDFWriter::DestAreaType		m_eType;
381         Rectangle					m_aRect;
382     };
383 //<---
384 
385     struct PDFOutlineEntry
386     {
387         sal_Int32					m_nParentID;
388         sal_Int32					m_nObject;
389         sal_Int32					m_nParentObject;
390         sal_Int32					m_nNextObject;
391         sal_Int32					m_nPrevObject;
392         std::vector< sal_Int32 >	m_aChildren;
393         rtl::OUString				m_aTitle;
394         sal_Int32					m_nDestID;
395 
PDFOutlineEntryvcl::PDFWriterImpl::PDFOutlineEntry396         PDFOutlineEntry()
397                 : m_nParentID( -1 ),
398                   m_nObject( 0 ),
399                   m_nParentObject( 0 ),
400                   m_nNextObject( 0 ),
401                   m_nPrevObject( 0 ),
402                   m_nDestID( -1 )
403         {}
404     };
405 
406     struct PDFAnnotation
407     {
408         sal_Int32					m_nObject;
409         Rectangle					m_aRect;
410         sal_Int32					m_nPage;
411 
PDFAnnotationvcl::PDFWriterImpl::PDFAnnotation412         PDFAnnotation()
413                 : m_nObject( -1 ),
414                   m_nPage( -1 )
415         {}
416     };
417 
418     struct PDFLink : public PDFAnnotation
419     {
420         sal_Int32					m_nDest; // set to -1 for URL, to a dest else
421         rtl::OUString				m_aURL;
422         sal_Int32                   m_nStructParent; // struct parent entry
423 
PDFLinkvcl::PDFWriterImpl::PDFLink424         PDFLink()
425                 : m_nDest( -1 ),
426                   m_nStructParent( -1 )
427         {}
428     };
429 
430     struct PDFNoteEntry : public PDFAnnotation
431     {
432         PDFNote						m_aContents;
433 
PDFNoteEntryvcl::PDFWriterImpl::PDFNoteEntry434         PDFNoteEntry()
435         {}
436     };
437 
438     typedef std::hash_map< rtl::OString, SvMemoryStream*, rtl::OStringHash > PDFAppearanceStreams;
439     typedef std::hash_map< rtl::OString, PDFAppearanceStreams, rtl::OStringHash > PDFAppearanceMap;
440 
441     struct PDFWidget : public PDFAnnotation
442     {
443         PDFWriter::WidgetType		m_eType;
444         rtl::OString				m_aName;
445         rtl::OUString				m_aDescription;
446         rtl::OUString				m_aText;
447         sal_uInt16						m_nTextStyle;
448         rtl::OUString				m_aValue;
449         rtl::OString                m_aDAString;
450         rtl::OString                m_aDRDict;
451         rtl::OString				m_aMKDict;
452 		rtl::OString				m_aMKDictCAString;	// i12626, added to be able to encrypt the /CA text string
453 														// since the object number is not known at the moment
454 														// of filling m_aMKDict, the string will be encrypted when emitted.
455 														// the /CA string MUST BE the last added to m_aMKDict
456 														// see code for details
457         sal_Int32					m_nFlags;
458         sal_Int32					m_nParent; // if not 0, parent's object number
459         std::vector<sal_Int32>		m_aKids; // widget children, contains object numbers
460         std::vector<sal_Int32>      m_aKidsIndex; // widget children, contains index to m_aWidgets
461         rtl::OUString               m_aOnValue;
462         sal_Int32                   m_nTabOrder; // lowest number gets first in tab order
463         sal_Int32					m_nRadioGroup;
464         sal_Int32					m_nMaxLen;
465         bool                        m_bSubmit;
466         bool                        m_bSubmitGet;
467         sal_Int32                   m_nDest;
468         std::vector<rtl::OUString>	m_aListEntries;
469         std::vector<sal_Int32>      m_aSelectedEntries;
470         PDFAppearanceMap			m_aAppearances;
PDFWidgetvcl::PDFWriterImpl::PDFWidget471         PDFWidget()
472                 : m_eType( PDFWriter::PushButton ),
473                   m_nTextStyle( 0 ),
474                   m_nFlags( 0 ),
475                   m_nParent( 0 ),
476                   m_nRadioGroup( -1 ),
477                   m_nMaxLen( 0 ),
478                   m_bSubmit( false ),
479                   m_bSubmitGet( false ),
480                   m_nDest( -1 )
481         {}
482     };
483 
484     struct PDFStructureAttribute
485     {
486         PDFWriter::StructAttributeValue		eValue;
487         sal_Int32							nValue;
488 
PDFStructureAttributevcl::PDFWriterImpl::PDFStructureAttribute489         PDFStructureAttribute()
490                 : eValue( PDFWriter::Invalid ),
491                   nValue( 0 )
492         {}
493 
PDFStructureAttributevcl::PDFWriterImpl::PDFStructureAttribute494         PDFStructureAttribute( PDFWriter::StructAttributeValue eVal )
495                 : eValue( eVal ),
496                   nValue( 0 )
497         {}
498 
PDFStructureAttributevcl::PDFWriterImpl::PDFStructureAttribute499         PDFStructureAttribute( sal_Int32 nVal )
500                 : eValue( PDFWriter::Invalid ),
501                   nValue( nVal )
502         {}
503     };
504 
505     typedef std::map<PDFWriter::StructAttribute, PDFStructureAttribute > PDFStructAttributes;
506 
507     struct PDFStructureElementKid // for Kids entries
508     {
509         sal_Int32 nObject;  // an object number if nMCID is -1,
510                             // else the page object relevant to MCID
511         sal_Int32 nMCID;    // an MCID if >= 0
512 
PDFStructureElementKidvcl::PDFWriterImpl::PDFStructureElementKid513         PDFStructureElementKid( sal_Int32 nObj ) : nObject( nObj ), nMCID( -1 ) {}
PDFStructureElementKidvcl::PDFWriterImpl::PDFStructureElementKid514         PDFStructureElementKid( sal_Int32 MCID, sal_Int32 nPage ) : nObject( nPage ), nMCID( MCID ) {}
515     };
516 
517     struct PDFStructureElement
518     {
519         sal_Int32											m_nObject;
520         PDFWriter::StructElement							m_eType;
521         rtl::OString                                        m_aAlias;
522         sal_Int32											m_nOwnElement; // index into structure vector
523         sal_Int32											m_nParentElement; // index into structure vector
524         sal_Int32											m_nFirstPageObject;
525         bool												m_bOpenMCSeq;
526         std::list< sal_Int32 >								m_aChildren; // indexes into structure vector
527         std::list< PDFStructureElementKid >                 m_aKids;
528         PDFStructAttributes									m_aAttributes;
529         Rectangle											m_aBBox;
530         rtl::OUString										m_aActualText;
531         rtl::OUString										m_aAltText;
532         com::sun::star::lang::Locale                        m_aLocale;
533 
534         // m_aContents contains the element's marked content sequence
535         // as pairs of (page nr, MCID)
536 
PDFStructureElementvcl::PDFWriterImpl::PDFStructureElement537         PDFStructureElement()
538                 : m_nObject( 0 ),
539                   m_eType( PDFWriter::NonStructElement ),
540                   m_nOwnElement( -1 ),
541                   m_nParentElement( -1 ),
542                   m_nFirstPageObject( 0 ),
543                   m_bOpenMCSeq( false )
544         {
545         }
546 
547     };
548 
549     struct PDFAddStream
550     {
551         rtl::OUString           m_aMimeType;
552         PDFOutputStream*        m_pStream;
553         sal_Int32               m_nStreamObject;
554         bool                    m_bCompress;
555 
PDFAddStreamvcl::PDFWriterImpl::PDFAddStream556         PDFAddStream() : m_pStream( NULL ), m_nStreamObject( 0 ), m_bCompress( true ) {}
557     };
558 
559 
560     // helper structure for drawLayout and friends
561     struct PDFGlyph
562     {
563         Point       m_aPos;
564         sal_Int32   m_nNativeWidth;
565         sal_Int32   m_nGlyphId;
566         sal_Int32   m_nMappedFontId;
567         sal_uInt8   m_nMappedGlyphId;
568 
PDFGlyphvcl::PDFWriterImpl::PDFGlyph569         PDFGlyph( const Point& rPos,
570                   sal_Int32 nNativeWidth,
571                   sal_Int32 nGlyphId,
572                   sal_Int32 nFontId,
573                   sal_uInt8 nMappedGlyphId )
574         : m_aPos( rPos ), m_nNativeWidth( nNativeWidth ), m_nGlyphId( nGlyphId ),
575           m_nMappedFontId( nFontId ), m_nMappedGlyphId( nMappedGlyphId )
576         {}
577     };
578 
579 
580     static const sal_Char* getStructureTag( PDFWriter::StructElement );
581     static const sal_Char* getAttributeTag( PDFWriter::StructAttribute eAtr );
582     static const sal_Char* getAttributeValueTag( PDFWriter::StructAttributeValue eVal );
583 
584     // returns true if compression was done
585     // else false
586     static bool compressStream( SvMemoryStream* );
587 
588     static void convertLineInfoToExtLineInfo( const LineInfo& rIn, PDFWriter::ExtLineInfo& rOut );
589 private:
590     static const BuiltinFont m_aBuiltinFonts[14];
591 
592     OutputDevice*						m_pReferenceDevice;
593 
594     MapMode								m_aMapMode; // PDFWriterImpl scaled units
595     std::vector< PDFPage >				m_aPages;
596     /* maps object numbers to file offsets (needed for xref) */
597     std::vector< sal_uInt64 >			m_aObjects;
598     /* contains Bitmaps until they are written to the
599      *  file stream as XObjects*/
600     std::list< BitmapEmit >				m_aBitmaps;
601     /* contains JPG streams until written to file     */
602     std::list<JPGEmit>					m_aJPGs;
603     /*--->i56629 contains all named destinations ever set during the PDF creation,
604        destination id is always the destination's position in this vector
605      */
606     std::vector<PDFNamedDest>		    m_aNamedDests;
607     //<---
608     /* contains all dests ever set during the PDF creation,
609        dest id is always the dest's position in this vector
610      */
611     std::vector<PDFDest>				m_aDests;
612     /** contains destinations accessible via a public Id, instead of being linked to by an ordinary link
613     */
614     ::std::map< sal_Int32, sal_Int32 >  m_aDestinationIdTranslation;
615     /* contains all links ever set during PDF creation,
616        link id is always the link's position in this vector
617     */
618     std::vector<PDFLink>				m_aLinks;
619     /* makes correctly encoded for export to PDF URLS
620     */
621     com::sun::star::uno::Reference< com::sun::star::util::XURLTransformer > m_xTrans;
622     /* maps arbitrary link ids for structure attributes to real link ids
623        (for setLinkPropertyId)
624     */
625     std::map<sal_Int32, sal_Int32>		m_aLinkPropertyMap;
626     /* contains all outline items,
627        object 0 is the outline root
628      */
629     std::vector<PDFOutlineEntry>		m_aOutline;
630     /* contains all notes set during PDF creation
631      */
632     std::vector<PDFNoteEntry>			m_aNotes;
633 	/* the root of the structure tree
634      */
635     std::vector<PDFStructureElement>	m_aStructure;
636     /* current object in the structure hierarchy
637      */
638     sal_Int32							m_nCurrentStructElement;
639     /* structure parent tree */
640     std::vector< rtl::OString >         m_aStructParentTree;
641     /* emit strucure marks currently (aka. NonStructElement or not)
642      */
643     bool								m_bEmitStructure;
644     bool								m_bNewMCID;
645     /* role map of struct tree root */
646     std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >
647                                         m_aRoleMap;
648 
649     /* contains all widgets used in the PDF
650      */
651     std::vector<PDFWidget>				m_aWidgets;
652     /* maps radio group id to index of radio group control in m_aWidgets */
653     std::map< sal_Int32, sal_Int32 >	m_aRadioGroupWidgets;
654     /* used to store control id during beginControlAppearance/endControlAppearance */
655     sal_Int32							m_nCurrentControl;
656     /* hash_map for field names, used to ensure unique field names */
657     std::hash_map< rtl::OString, sal_Int32, rtl::OStringHash > m_aFieldNameMap;
658 
659     /* contains Bitmaps for gradient functions until they are written
660      *  to the file stream */
661     std::list< GradientEmit >			m_aGradients;
662     /* contains bitmap tiling patterns */
663     std::vector< TilingEmit >		    m_aTilings;
664     std::list< TransparencyEmit >		m_aTransparentObjects;
665     /*  contains all font subsets in use */
666     FontSubsetData						m_aSubsets;
667     bool                                m_bEmbedStandardFonts;
668     FontEmbedData						m_aEmbeddedFonts;
669     FontEmbedData                       m_aSystemFonts;
670     sal_Int32							m_nNextFID;
671     PDFFontCache                        m_aFontCache;
672 
673     sal_Int32							m_nInheritedPageWidth;  // in inch/72
674     sal_Int32							m_nInheritedPageHeight; // in inch/72
675     PDFWriter::Orientation				m_eInheritedOrientation;
676     sal_Int32							m_nCurrentPage;
677 
678     sal_Int32							m_nCatalogObject;
679     sal_Int32							m_nResourceDict;
680     ResourceDict                        m_aGlobalResourceDict;
681     sal_Int32                           m_nFontDictObject;
682     std::map< sal_Int32, sal_Int32 >    m_aBuiltinFontToObjectMap;
683 
684     PDFWriter::PDFWriterContext			m_aContext;
685     oslFileHandle						m_aFile;
686     bool								m_bOpen;
687 
688 
689     /* output redirection; e.g. to accumulate content streams for
690        XObjects
691      */
692     struct StreamRedirect
693     {
694         SvStream*		m_pStream;
695         MapMode   		m_aMapMode;
696         Rectangle       m_aTargetRect;
697         ResourceDict    m_aResourceDict;
698     };
699     std::list< StreamRedirect >			m_aOutputStreams;
700 
701     // graphics state
702     struct GraphicsState
703     {
704         Font			                 m_aFont;
705         MapMode			                 m_aMapMode;
706         Color			                 m_aLineColor;
707         Color			                 m_aFillColor;
708         Color			                 m_aTextLineColor;
709         Color			                 m_aOverlineColor;
710         basegfx::B2DPolyPolygon			 m_aClipRegion;
711         bool                             m_bClipRegion;
712         sal_Int32		                 m_nAntiAlias;
713         sal_Int32		                 m_nLayoutMode;
714         LanguageType                     m_aDigitLanguage;
715         sal_Int32		                 m_nTransparentPercent;
716         sal_uInt16		                 m_nFlags;
717         sal_uInt16                       m_nUpdateFlags;
718 
719         static const sal_uInt16 updateFont                  = 0x0001;
720         static const sal_uInt16 updateMapMode               = 0x0002;
721         static const sal_uInt16 updateLineColor             = 0x0004;
722         static const sal_uInt16 updateFillColor             = 0x0008;
723         static const sal_uInt16 updateTextLineColor         = 0x0010;
724         static const sal_uInt16 updateOverlineColor         = 0x0020;
725         static const sal_uInt16 updateClipRegion            = 0x0040;
726         static const sal_uInt16 updateAntiAlias             = 0x0080;
727         static const sal_uInt16 updateLayoutMode            = 0x0100;
728         static const sal_uInt16 updateTransparentPercent    = 0x0200;
729         static const sal_uInt16 updateDigitLanguage         = 0x0400;
730 
GraphicsStatevcl::PDFWriterImpl::GraphicsState731         GraphicsState() :
732                 m_aLineColor( COL_TRANSPARENT ),
733                 m_aFillColor( COL_TRANSPARENT ),
734                 m_aTextLineColor( COL_TRANSPARENT ),
735                 m_aOverlineColor( COL_TRANSPARENT ),
736                 m_bClipRegion( false ),
737                 m_nAntiAlias( 1 ),
738                 m_nLayoutMode( 0 ),
739                 m_aDigitLanguage( 0 ),
740                 m_nTransparentPercent( 0 ),
741                 m_nFlags( 0xffff ),
742                 m_nUpdateFlags( 0xffff )
743         {}
GraphicsStatevcl::PDFWriterImpl::GraphicsState744         GraphicsState( const GraphicsState& rState ) :
745                 m_aFont( rState.m_aFont ),
746                 m_aMapMode( rState.m_aMapMode ),
747                 m_aLineColor( rState.m_aLineColor ),
748                 m_aFillColor( rState.m_aFillColor ),
749                 m_aTextLineColor( rState.m_aTextLineColor ),
750                 m_aOverlineColor( rState.m_aOverlineColor ),
751                 m_aClipRegion( rState.m_aClipRegion ),
752                 m_bClipRegion( rState.m_bClipRegion ),
753                 m_nAntiAlias( rState.m_nAntiAlias ),
754                 m_nLayoutMode( rState.m_nLayoutMode ),
755                 m_aDigitLanguage( rState.m_aDigitLanguage ),
756                 m_nTransparentPercent( rState.m_nTransparentPercent ),
757                 m_nFlags( rState.m_nFlags ),
758                 m_nUpdateFlags( rState.m_nUpdateFlags )
759         {
760         }
761 
operator =vcl::PDFWriterImpl::GraphicsState762         GraphicsState& operator=(const GraphicsState& rState )
763         {
764             m_aFont					= rState.m_aFont;
765             m_aMapMode				= rState.m_aMapMode;
766             m_aLineColor			= rState.m_aLineColor;
767             m_aFillColor			= rState.m_aFillColor;
768             m_aTextLineColor		= rState.m_aTextLineColor;
769             m_aOverlineColor		= rState.m_aOverlineColor;
770             m_aClipRegion			= rState.m_aClipRegion;
771             m_bClipRegion           = rState.m_bClipRegion;
772             m_nAntiAlias			= rState.m_nAntiAlias;
773             m_nLayoutMode			= rState.m_nLayoutMode;
774             m_aDigitLanguage        = rState.m_aDigitLanguage;
775             m_nTransparentPercent	= rState.m_nTransparentPercent;
776             m_nFlags				= rState.m_nFlags;
777             m_nUpdateFlags          = rState.m_nUpdateFlags;
778             return *this;
779         }
780     };
781     std::list< GraphicsState >				m_aGraphicsStack;
782     GraphicsState							m_aCurrentPDFState;
783 
784     ZCodec*									m_pCodec;
785     SvMemoryStream*							m_pMemStream;
786 
787     std::vector< PDFAddStream >             m_aAdditionalStreams;
788     std::set< PDFWriter::ErrorCode >        m_aErrors;
789 
790     rtlDigest                               m_aDocDigest;
791 
792 /*
793 variables for PDF security
794 i12626
795 */
796 /* used to cipher the stream data and for password management */
797 	rtlCipher								m_aCipher;
798 	rtlDigest								m_aDigest;
799 	/* pad string used for password in Standard security handler */
800 	static const sal_uInt8					s_nPadString[ENCRYPTED_PWD_SIZE];
801 
802 	/* the encryption key, formed with the user password according to algorithm 3.2, maximum length is 16 bytes + 3 + 2
803 	for 128 bit security   */
804 	sal_Int32								m_nKeyLength; // key length, 16 or 5
805 	sal_Int32								m_nRC4KeyLength; // key length, 16 or 10, to be input to the algorith 3.1
806 
807 	/* set to true if the following stream must be encrypted, used inside writeBuffer() */
808 	sal_Bool								m_bEncryptThisStream;
809 
810 	/* the numerical value of the access permissions, according to PDF spec, must be signed */
811 	sal_Int32                               m_nAccessPermissions;
812 	/* string to hold the PDF creation date */
813 	rtl::OString						    m_aCreationDateString;
814 	/* string to hold the PDF creation date, for PDF/A metadata */
815 	rtl::OString						    m_aCreationMetaDateString;
816 	/* the buffer where the data are encrypted, dynamically allocated */
817 	sal_uInt8								*m_pEncryptionBuffer;
818 	/* size of the buffer */
819 	sal_Int32								m_nEncryptionBufferSize;
820 
821 	/* check and reallocate the buffer for encryption */
822 	sal_Bool checkEncryptionBufferSize( sal_Int32 newSize );
823 	/* this function implements part of the PDF spec algorithm 3.1 in encryption, the rest (the actual encryption) is in PDFWriterImpl::writeBuffer */
824     void checkAndEnableStreamEncryption( sal_Int32 nObject );
825 
disableStreamEncryption()826 	void disableStreamEncryption() { m_bEncryptThisStream = false; };
827 
828 	/* */
829     void enableStringEncryption( sal_Int32 nObject );
830 
831 // test if the encryption is active, if yes than encrypt the unicode string  and add to the OStringBuffer parameter
832 	void appendUnicodeTextStringEncrypt( const rtl::OUString& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer );
833 
834 	void appendLiteralStringEncrypt( const rtl::OUString& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer, rtl_TextEncoding nEnc = RTL_TEXTENCODING_ASCII_US );
835 	void appendLiteralStringEncrypt( const rtl::OString& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer );
836 	void appendLiteralStringEncrypt( rtl::OStringBuffer& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer );
837 
838     /* creates fonts and subsets that will be emitted later */
839     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[] );
840 
841     /*  emits a text object according to the passed layout */
842     /* TODO: remove rText as soon as SalLayout will change so that rText is not necessary anymore */
843     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 );
844     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 );
845     void drawLayout( SalLayout& rLayout, const String& rText, bool bTextLines );
846     void drawRelief( SalLayout& rLayout, const String& rText, bool bTextLines );
847     void drawShadow( SalLayout& rLayout, const String& rText, bool bTextLines );
848 
849     /*  writes differences between graphics stack and current real PDF
850      *   state to the file
851      */
852     void updateGraphicsState();
853 
854     /* writes a transparency group object */
855     bool writeTransparentObject( TransparencyEmit& rObject );
856 
857     /* writes an XObject of type image, may create
858        a second for the mask
859      */
860     bool writeBitmapObject( BitmapEmit& rObject, bool bMask = false );
861 
862     bool writeJPG( JPGEmit& rEmit );
863 
864     /* tries to find the bitmap by its id and returns its emit data if exists,
865        else creates a new emit data block */
866     const BitmapEmit& createBitmapEmit( const BitmapEx& rBitmapEx, bool bDrawMask = false );
867 
868     /* writes the Do operation inside the content stream */
869     void drawBitmap( const Point& rDestPt, const Size& rDestSize, const BitmapEmit& rBitmap, const Color& rFillColor );
870     /* write the function object for a Gradient */
871     bool writeGradientFunction( GradientEmit& rObject );
872     /* creates a GradientEmit and returns its object number */
873     sal_Int32 createGradient(  const Gradient& rGradient, const Size& rSize );
874 
875     /* writes all tilings */
876     bool emitTilings();
877     /* writes all gradient patterns */
878     bool emitGradients();
879     /* writes a builtin font object and returns its objectid (or 0 in case of failure ) */
880     sal_Int32 emitBuiltinFont( const ImplFontData*, sal_Int32 nObject = -1 );
881     /* writes a type1 embedded font object and returns its mapping from font ids to object ids (or 0 in case of failure ) */
882     std::map< sal_Int32, sal_Int32 > emitEmbeddedFont( const ImplFontData*, EmbedFont& );
883     /* writes a type1 system font object and returns its mapping from font ids to object ids (or 0 in case of failure ) */
884     std::map< sal_Int32, sal_Int32 > emitSystemFont( const ImplFontData*, EmbedFont& );
885     /* writes a font descriptor and returns its object id (or 0) */
886     sal_Int32 emitFontDescriptor( const ImplFontData*, FontSubsetInfo&, sal_Int32 nSubsetID, sal_Int32 nStream );
887     /* writes a ToUnicode cmap, returns the corresponding stream object */
888     sal_Int32 createToUnicodeCMap( sal_uInt8* pEncoding, sal_Ucs* pUnicodes, sal_Int32* pUnicodesPerGlyph, sal_Int32* pEncToUnicodeIndex, int nGlyphs );
889 
890     /* get resource dict object number */
getResourceDictObj()891     sal_Int32 getResourceDictObj()
892     {
893         if( m_nResourceDict <= 0 )
894             m_nResourceDict = createObject();
895         return m_nResourceDict;
896     }
897     /* get the font dict object */
getFontDictObject()898     sal_Int32 getFontDictObject()
899     {
900         if( m_nFontDictObject <= 0 )
901             m_nFontDictObject = createObject();
902         return m_nFontDictObject;
903     }
904     /* push resource into current (redirected) resource dict */
905     void pushResource( ResourceKind eKind, const rtl::OString& rResource, sal_Int32 nObject );
906 
907     void appendBuiltinFontsToDict( rtl::OStringBuffer& rDict ) const;
908     /* writes a the font dictionary and emits all font objects
909      * returns object id of font directory (or 0 on error)
910      */
911     bool emitFonts();
912 	/* writes the Resource dictionary;
913      * returns dict object id (or 0 on error)
914      */
915     sal_Int32 emitResources();
916     // appends a dest
917     bool appendDest( sal_Int32 nDestID, rtl::OStringBuffer& rBuffer );
918     // write all links
919     bool emitLinkAnnotations();
920     // write all notes
921     bool emitNoteAnnotations();
922     // write the appearance streams of a widget
923     bool emitAppearances( PDFWidget& rWidget, rtl::OStringBuffer& rAnnotDict );
924     // clean up radio button "On" values
925     void ensureUniqueRadioOnValues();
926     // write all widgets
927     bool emitWidgetAnnotations();
928     // writes all annotation objects
929     bool emitAnnotations();
930     // writes the dest dict for the catalog
931     sal_Int32 emitDestDict();
932     //write the named destination stuff
933     sal_Int32 emitNamedDestinations();//i56629
934     // writes outline dict and tree
935     sal_Int32 emitOutline();
936     // puts the attribute objects of a structure element into the returned string,
937     // helper for emitStructure
938     rtl::OString emitStructureAttributes( PDFStructureElement& rEle );
939     //--->i94258
940     // the maximum array elements allowed for PDF array object
941     static const sal_uInt32 ncMaxPDFArraySize = 8191;
942     //check if internal dummy container are needed in the structure elements
943     void addInternalStructureContainer( PDFStructureElement& rEle );
944     //<---i94258
945     // writes document structure
946     sal_Int32 emitStructure( PDFStructureElement& rEle );
947     // writes structure parent tree
948     sal_Int32 emitStructParentTree( sal_Int32 nTreeObject );
949     // writes page tree and catalog
950     bool emitCatalog();
951     // writes xref and trailer
952     bool emitTrailer();
953     // emit additional streams collected; also create there object numbers
954     bool emitAdditionalStreams();
955     // emits info dict (if applicable)
956     sal_Int32 emitInfoDict( );
957 
958     // acrobat reader 5 and 6 use the order of the annotations
959     // as their tab order; since PDF1.5 one can make the
960     // tab order explicit by using the structure tree
961     void sortWidgets();
962 
963     // updates the count numbers of outline items
964     sal_Int32 updateOutlineItemCount( std::vector< sal_Int32 >& rCounts,
965                                       sal_Int32 nItemLevel,
966                                       sal_Int32 nCurrentItemId );
967     // default appearances for widgets
968     sal_Int32 findRadioGroupWidget( const PDFWriter::RadioButtonWidget& rRadio );
969     Font replaceFont( const Font& rControlFont, const Font& rAppSetFont );
970     sal_Int32 getBestBuiltinFont( const Font& rFont );
971     sal_Int32 getSystemFont( const Font& i_rFont );
972 
973     // used for edit and listbox
974     Font drawFieldBorder( PDFWidget&, const PDFWriter::AnyWidget&, const StyleSettings& );
975 
976     void createDefaultPushButtonAppearance( PDFWidget&, const PDFWriter::PushButtonWidget& rWidget );
977     void createDefaultCheckBoxAppearance( PDFWidget&, const PDFWriter::CheckBoxWidget& rWidget );
978     void createDefaultRadioButtonAppearance( PDFWidget&, const PDFWriter::RadioButtonWidget& rWidget );
979     void createDefaultEditAppearance( PDFWidget&, const PDFWriter::EditWidget& rWidget );
980     void createDefaultListBoxAppearance( PDFWidget&, const PDFWriter::ListBoxWidget& rWidget );
981 
982     /* ensure proper escapement and uniqueness of field names */
983     void createWidgetFieldName( sal_Int32 i_nWidgetsIndex, const PDFWriter::AnyWidget& i_rInWidget );
984     /* adds an entry to m_aObjects and returns its index+1,
985      * sets the offset to ~0
986      */
987     sal_Int32 createObject();
988     /* sets the offset of object n to the current position of output file+1
989      */
990     bool updateObject( sal_Int32 n );
991 
992     bool writeBuffer( const void* pBuffer, sal_uInt64 nBytes );
993     void beginCompression();
994     void endCompression();
995     void beginRedirect( SvStream* pStream, const Rectangle& );
996     // returns an empty rect if no redirection is happending
997     Rectangle getRedirectTargetRect() const;
998     SvStream* endRedirect();
999 
1000     void endPage();
1001 
1002     void beginStructureElementMCSeq();
1003     void endStructureElementMCSeq();
1004     /** checks whether a non struct element lies in the ancestor hierarchy
1005         of the current structure element
1006 
1007         @returns
1008         <true/> if no NonStructElement was found in ancestor path and tagged
1009         PDF output is enabled
1010         <false/> else
1011      */
1012     bool checkEmitStructure();
1013 
1014     /* draws an emphasis mark */
1015     void drawEmphasisMark(  long nX, long nY, const PolyPolygon& rPolyPoly, sal_Bool bPolyLine, const Rectangle& rRect1, const Rectangle& rRect2 );
1016 
1017     /* true if PDF/A-1a or PDF/A-1b is output */
1018     sal_Bool        m_bIsPDF_A1;
1019     PDFWriter&      m_rOuterFace;
1020 
1021     /*
1022     i12626
1023     methods for PDF security
1024 
1025     pad a password according  algorithm 3.2, step 1 */
1026     static void padPassword( const rtl::OUString& i_rPassword, sal_uInt8* o_pPaddedPW );
1027     /* algorithm 3.2: compute an encryption key */
1028 	static bool computeEncryptionKey( EncHashTransporter*,
1029 	                                  vcl::PDFWriter::PDFEncryptionProperties& io_rProperties,
1030 	                                  sal_Int32 i_nAccessPermissions
1031 	                                 );
1032 	/* algorithm 3.3: computing the encryption dictionary'ss owner password value ( /O ) */
1033 	static bool computeODictionaryValue( const sal_uInt8* i_pPaddedOwnerPassword, const sal_uInt8* i_pPaddedUserPassword,
1034 	                                     std::vector< sal_uInt8 >& io_rOValue,
1035 	                                     sal_Int32 i_nKeyLength
1036 	                                    );
1037 	/* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */
1038 	static bool computeUDictionaryValue( EncHashTransporter* i_pTransporter,
1039 	                                     vcl::PDFWriter::PDFEncryptionProperties& io_rProperties,
1040 	                                     sal_Int32 i_nKeyLength,
1041 	                                     sal_Int32 i_nAccessPermissions
1042 	                                    );
1043 
1044 	static void computeDocumentIdentifier( std::vector< sal_uInt8 >& o_rIdentifier,
1045 	                                       const vcl::PDFWriter::PDFDocInfo& i_rDocInfo,
1046 	                                       rtl::OString& o_rCString1,
1047 	                                       rtl::OString& o_rCString2
1048 	                                      );
1049 	static sal_Int32 computeAccessPermissions( const vcl::PDFWriter::PDFEncryptionProperties& i_rProperties,
1050 	                                           sal_Int32& o_rKeyLength, sal_Int32& o_rRC4KeyLength );
1051     void setupDocInfo();
1052     bool prepareEncryption( const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >& );
1053 
1054 	// helper for playMetafile
1055     void implWriteGradient( const PolyPolygon& rPolyPoly, const Gradient& rGradient,
1056                             VirtualDevice* pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& );
1057     void implWriteBitmapEx( const Point& rPoint, const Size& rSize, const BitmapEx& rBitmapEx,
1058                            VirtualDevice* pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& );
1059 
1060     // helpers for CCITT 1bit bitmap stream
1061     void putG4Bits( sal_uInt32 i_nLength, sal_uInt32 i_nCode, BitStreamState& io_rState );
1062     void putG4Span( long i_nSpan, bool i_bWhitePixel, BitStreamState& io_rState );
1063     void writeG4Stream( BitmapReadAccess* i_pBitmap );
1064 
1065     // color helper functions
1066     void appendStrokingColor( const Color& rColor, rtl::OStringBuffer& rBuffer );
1067     void appendNonStrokingColor( const Color& rColor, rtl::OStringBuffer& rBuffer );
1068 public:
1069     PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, const com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >&, PDFWriter& );
1070     ~PDFWriterImpl();
1071 
1072     static com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder >
1073            initEncryption( const rtl::OUString& i_rOwnerPassword,
1074                            const rtl::OUString& i_rUserPassword,
1075                            bool b128Bit );
1076 
1077     /*	for OutputDevice so the reference device can have a list
1078      *	that contains only suitable fonts (subsettable or builtin)
1079      *	produces a new font list
1080      */
1081     ImplDevFontList* filterDevFontList( ImplDevFontList* pFontList );
1082     /*  for OutputDevice: get layout for builtin fonts
1083      */
1084     bool isBuiltinFont( const ImplFontData* ) const;
1085     SalLayout* GetTextLayout( ImplLayoutArgs& rArgs, ImplFontSelectData* pFont );
1086     void getFontMetric( ImplFontSelectData* pFont, ImplFontMetricData* pMetric ) const;
1087 
1088 
1089     /* for documentation of public functions please see pdfwriter.hxx */
1090 
1091     OutputDevice* getReferenceDevice();
1092 
1093     /* document structure */
1094     sal_Int32 newPage( sal_Int32 nPageWidth , sal_Int32 nPageHeight, PDFWriter::Orientation eOrientation );
1095     bool emit();
1096     std::set< PDFWriter::ErrorCode > getErrors();
insertError(PDFWriter::ErrorCode eErr)1097     void insertError( PDFWriter::ErrorCode eErr ) { m_aErrors.insert( eErr ); }
1098     void playMetafile( const GDIMetaFile&, vcl::PDFExtOutDevData*, const vcl::PDFWriter::PlayMetafileContext&, VirtualDevice* pDummyDev = NULL );
1099 
getCurPageSize() const1100     Size getCurPageSize() const
1101     {
1102         Size aSize;
1103         if( m_nCurrentPage >= 0 && m_nCurrentPage < (sal_Int32)m_aPages.size() )
1104             aSize = Size( m_aPages[ m_nCurrentPage ].m_nPageWidth, m_aPages[ m_nCurrentPage ].m_nPageHeight );
1105         return aSize;
1106     }
1107 
getVersion() const1108     PDFWriter::PDFVersion getVersion() const { return m_aContext.Version; }
1109 
setDocumentLocale(const com::sun::star::lang::Locale & rLoc)1110     void setDocumentLocale( const com::sun::star::lang::Locale& rLoc )
1111     { m_aContext.DocumentLocale = rLoc; }
1112 
1113 
1114     /* graphics state */
1115     void push( sal_uInt16 nFlags );
1116     void pop();
1117 
1118     void setFont( const Font& rFont );
1119 
1120     void setMapMode( const MapMode& rMapMode );
setMapMode()1121     void setMapMode() { setMapMode( m_aMapMode ); }
1122 
1123 
getMapMode()1124     const MapMode& getMapMode() { return m_aGraphicsStack.front().m_aMapMode; }
1125 
setLineColor(const Color & rColor)1126     void setLineColor( const Color& rColor )
1127     {
1128         m_aGraphicsStack.front().m_aLineColor = ImplIsColorTransparent(rColor) ? Color( COL_TRANSPARENT ) : rColor;
1129         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateLineColor;
1130     }
1131 
setFillColor(const Color & rColor)1132     void setFillColor( const Color& rColor )
1133     {
1134         m_aGraphicsStack.front().m_aFillColor = ImplIsColorTransparent(rColor) ? Color( COL_TRANSPARENT ) : rColor;
1135         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFillColor;
1136     }
1137 
setTextLineColor()1138     void setTextLineColor()
1139     {
1140         m_aGraphicsStack.front().m_aTextLineColor = Color( COL_TRANSPARENT );
1141         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateTextLineColor;
1142     }
1143 
setTextLineColor(const Color & rColor)1144     void setTextLineColor( const Color& rColor )
1145     {
1146         m_aGraphicsStack.front().m_aTextLineColor = rColor;
1147         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateTextLineColor;
1148     }
1149 
setOverlineColor()1150     void setOverlineColor()
1151     {
1152         m_aGraphicsStack.front().m_aOverlineColor = Color( COL_TRANSPARENT );
1153         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateOverlineColor;
1154     }
1155 
setOverlineColor(const Color & rColor)1156     void setOverlineColor( const Color& rColor )
1157     {
1158         m_aGraphicsStack.front().m_aOverlineColor = rColor;
1159         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateOverlineColor;
1160     }
1161 
setTextFillColor(const Color & rColor)1162     void setTextFillColor( const Color& rColor )
1163     {
1164         m_aGraphicsStack.front().m_aFont.SetFillColor( rColor );
1165         m_aGraphicsStack.front().m_aFont.SetTransparent( ImplIsColorTransparent( rColor ) ? sal_True : sal_False );
1166         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFont;
1167     }
setTextFillColor()1168     void setTextFillColor()
1169     {
1170         m_aGraphicsStack.front().m_aFont.SetFillColor( Color( COL_TRANSPARENT ) );
1171         m_aGraphicsStack.front().m_aFont.SetTransparent( sal_True );
1172         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFont;
1173     }
setTextColor(const Color & rColor)1174     void setTextColor( const Color& rColor )
1175     {
1176         m_aGraphicsStack.front().m_aFont.SetColor( rColor );
1177         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFont;
1178     }
1179 
clearClipRegion()1180     void clearClipRegion()
1181     {
1182         m_aGraphicsStack.front().m_aClipRegion.clear();
1183         m_aGraphicsStack.front().m_bClipRegion = false;
1184         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateClipRegion;
1185     }
1186 
1187     void setClipRegion( const basegfx::B2DPolyPolygon& rRegion );
1188 
1189     void moveClipRegion( sal_Int32 nX, sal_Int32 nY );
1190 
1191     bool intersectClipRegion( const Rectangle& rRect );
1192 
1193     bool intersectClipRegion( const basegfx::B2DPolyPolygon& rRegion );
1194 
setLayoutMode(sal_Int32 nLayoutMode)1195     void setLayoutMode( sal_Int32 nLayoutMode )
1196     {
1197         m_aGraphicsStack.front().m_nLayoutMode = nLayoutMode;
1198         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateLayoutMode;
1199     }
1200 
setDigitLanguage(LanguageType eLang)1201     void setDigitLanguage( LanguageType eLang )
1202     {
1203         m_aGraphicsStack.front().m_aDigitLanguage = eLang;
1204         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateDigitLanguage;
1205     }
1206 
setTextAlign(TextAlign eAlign)1207     void setTextAlign( TextAlign eAlign )
1208     {
1209         m_aGraphicsStack.front().m_aFont.SetAlign( eAlign );
1210         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateFont;
1211     }
1212 
setAntiAlias(sal_Int32 nAntiAlias)1213     void setAntiAlias( sal_Int32 nAntiAlias )
1214     {
1215         m_aGraphicsStack.front().m_nAntiAlias = nAntiAlias;
1216         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsState::updateAntiAlias;
1217     }
1218 
1219     /* actual drawing functions */
1220     void drawText( const Point& rPos, const String& rText, xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN, bool bTextLines = true );
1221     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 );
1222     void drawStretchText( const Point& rPos, sal_uLong nWidth, const String& rText,
1223                           xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN,
1224                           bool bTextLines = true  );
1225     void drawText( const Rectangle& rRect, const String& rOrigStr, sal_uInt16 nStyle, bool bTextLines = true  );
1226     void drawTextLine( const Point& rPos, long nWidth, FontStrikeout eStrikeout, FontUnderline eUnderline, FontUnderline eOverline, bool bUnderlineAbove );
1227     void drawWaveTextLine( rtl::OStringBuffer& aLine, long nWidth, FontUnderline eTextLine, Color aColor, bool bIsAbove );
1228     void drawStraightTextLine( rtl::OStringBuffer& aLine, long nWidth, FontUnderline eTextLine, Color aColor, bool bIsAbove );
1229     void drawStrikeoutLine( rtl::OStringBuffer& aLine, long nWidth, FontStrikeout eStrikeout, Color aColor );
1230     void drawStrikeoutChar( const Point& rPos, long nWidth, FontStrikeout eStrikeout );
1231 
1232     void drawLine( const Point& rStart, const Point& rStop );
1233     void drawLine( const Point& rStart, const Point& rStop, const LineInfo& rInfo );
1234     void drawPolygon( const Polygon& rPoly );
1235     void drawPolyPolygon( const PolyPolygon& rPolyPoly );
1236     void drawPolyLine( const Polygon& rPoly );
1237     void drawPolyLine( const Polygon& rPoly, const LineInfo& rInfo );
1238     void drawPolyLine( const Polygon& rPoly, const PDFWriter::ExtLineInfo& rInfo );
1239     void drawWaveLine( const Point& rStart, const Point& rStop, sal_Int32 nDelta, sal_Int32 nLineWidth );
1240 
1241     void drawPixel( const Point& rPt, const Color& rColor );
1242     void drawPixel( const Polygon& rPts, const Color* pColors = NULL );
1243 
1244     void drawRectangle( const Rectangle& rRect );
1245     void drawRectangle( const Rectangle& rRect, sal_uInt32 nHorzRound, sal_uInt32 nVertRound );
1246     void drawEllipse( const Rectangle& rRect );
1247     void drawArc( const Rectangle& rRect, const Point& rStart, const Point& rStop, bool bWithPie, bool bWidthChord );
1248 
1249     void drawBitmap( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap );
1250     void drawBitmap( const Point& rDestPoint, const Size& rDestSize, const BitmapEx& rBitmap );
1251     void drawMask( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap, const Color& rFillColor );
1252     void drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const Size& rSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask );
1253 
1254     void drawGradient( const Rectangle& rRect, const Gradient& rGradient );
1255     void drawGradient( const PolyPolygon& rPolyPoly, const Gradient& rGradient );
1256     void drawHatch( const PolyPolygon& rPolyPoly, const Hatch& rHatch );
1257     void drawWallpaper( const Rectangle& rRect, const Wallpaper& rWall );
1258     void drawTransparent( const PolyPolygon& rPolyPoly, sal_uInt32 nTransparentPercent );
1259     void beginTransparencyGroup();
1260     void endTransparencyGroup( const Rectangle& rBoundingBox, sal_uInt32 nTransparentPercent );
1261     void endTransparencyGroup( const Rectangle& rBoundingBox, const Bitmap& rAlphaMask );
1262     void beginPattern( const Rectangle& rCell );
1263     sal_Int32 endPattern( const SvtGraphicFill::Transform& rTransform );
1264     void drawPolyPolygon( const PolyPolygon& rPolyPoly, sal_Int32 nPattern, bool bEOFill );
1265 
1266     void emitComment( const char* pComment );
1267 
1268     //--->i56629 named destinations
1269     sal_Int32 createNamedDest( const rtl::OUString& sDestName, const Rectangle& rRect, sal_Int32 nPageNr = -1, PDFWriter::DestAreaType eType = PDFWriter::XYZ );
1270 
1271     //--->i59651
1272     //emits output intent
1273     sal_Int32   emitOutputIntent();
1274 
1275     //emits the document metadata
1276     sal_Int32   emitDocumentMetadata();
1277 
1278     // links
1279     sal_Int32 createLink( const Rectangle& rRect, sal_Int32 nPageNr = -1 );
1280     sal_Int32 createDest( const Rectangle& rRect, sal_Int32 nPageNr = -1, PDFWriter::DestAreaType eType = PDFWriter::XYZ );
1281     sal_Int32 registerDestReference( sal_Int32 nDestId, const Rectangle& rRect, sal_Int32 nPageNr = -1, PDFWriter::DestAreaType eType = PDFWriter::XYZ );
1282     sal_Int32 setLinkDest( sal_Int32 nLinkId, sal_Int32 nDestId );
1283     sal_Int32 setLinkURL( sal_Int32 nLinkId, const rtl::OUString& rURL );
1284     void setLinkPropertyId( sal_Int32 nLinkId, sal_Int32 nPropertyId );
1285 
1286     // outline
1287     sal_Int32 createOutlineItem( sal_Int32 nParent = 0, const rtl::OUString& rText = rtl::OUString(), sal_Int32 nDestID = -1 );
1288     sal_Int32 setOutlineItemParent( sal_Int32 nItem, sal_Int32 nNewParent );
1289     sal_Int32 setOutlineItemText( sal_Int32 nItem, const rtl::OUString& rText );
1290     sal_Int32 setOutlineItemDest( sal_Int32 nItem, sal_Int32 nDestID );
1291 
1292     // notes
1293     void createNote( const Rectangle& rRect, const PDFNote& rNote, sal_Int32 nPageNr = -1 );
1294     // structure elements
1295     sal_Int32 beginStructureElement( PDFWriter::StructElement eType, const rtl::OUString& rAlias );
1296     void endStructureElement();
1297     bool setCurrentStructureElement( sal_Int32 nElement );
1298     sal_Int32 getCurrentStructureElement();
1299     bool setStructureAttribute( enum PDFWriter::StructAttribute eAttr, enum PDFWriter::StructAttributeValue eVal );
1300     bool setStructureAttributeNumerical( enum PDFWriter::StructAttribute eAttr, sal_Int32 nValue );
1301     void setStructureBoundingBox( const Rectangle& rRect );
1302     void setActualText( const String& rText );
1303     void setAlternateText( const String& rText );
1304 
1305     // transitional effects
1306     void setAutoAdvanceTime( sal_uInt32 nSeconds, sal_Int32 nPageNr = -1 );
1307     void setPageTransition( PDFWriter::PageTransition eType, sal_uInt32 nMilliSec, sal_Int32 nPageNr = -1 );
1308 
1309     // controls
1310     sal_Int32 createControl( const PDFWriter::AnyWidget& rControl, sal_Int32 nPageNr = -1 );
1311     void beginControlAppearance( sal_Int32 nControl );
1312     bool endControlAppearance( PDFWriter::WidgetState eState );
1313 
1314     // additional streams
1315     void addStream( const String& rMimeType, PDFOutputStream* pStream, bool bCompress );
1316 
1317     // helper: eventually begin marked content sequence and
1318     // emit a comment in debug case
MARK(const char * pString)1319     void MARK( const char*
1320 #if OSL_DEBUG_LEVEL > 1
1321         pString
1322 #endif
1323         )
1324     {
1325         beginStructureElementMCSeq();
1326 #if OSL_DEBUG_LEVEL > 1
1327         emitComment( pString );
1328 #endif
1329     }
1330 };
1331 
1332 }
1333 
1334 #endif //_VCL_PDFEXPORT_HXX
1335 
1336 
1337