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