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