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