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