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