LibreOffice Module sw (master)  1
EnhancedPDFExportHelper.cxx
Go to the documentation of this file.
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 
20 #include <com/sun/star/embed/XEmbeddedObject.hpp>
21 #include <com/sun/star/i18n/ScriptType.hpp>
22 #include <com/sun/star/drawing/XShape.hpp>
23 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <hintids.hxx>
26 
27 #include <sot/exchange.hxx>
28 #include <vcl/outdev.hxx>
29 #include <vcl/pdfextoutdevdata.hxx>
30 #include <tools/multisel.hxx>
31 #include <editeng/adjustitem.hxx>
32 #include <editeng/lrspitem.hxx>
33 #include <editeng/langitem.hxx>
34 #include <tools/urlobj.hxx>
35 #include <svl/languageoptions.hxx>
36 #include <svl/zforlist.hxx>
37 #include <swatrset.hxx>
38 #include <frmatr.hxx>
39 #include <paratr.hxx>
40 #include <ndtxt.hxx>
41 #include <ndole.hxx>
42 #include <section.hxx>
43 #include <tox.hxx>
44 #include <fmtfld.hxx>
45 #include <txtinet.hxx>
46 #include <fmtinfmt.hxx>
47 #include <fchrfmt.hxx>
48 #include <charfmt.hxx>
49 #include <fmtanchr.hxx>
50 #include <fmturl.hxx>
51 #include <editsh.hxx>
52 #include <viscrs.hxx>
53 #include <txtfld.hxx>
54 #include <reffld.hxx>
55 #include <doc.hxx>
57 #include <docary.hxx>
58 #include <mdiexp.hxx>
59 #include <docufld.hxx>
60 #include <ftnidx.hxx>
61 #include <txtftn.hxx>
62 #include <rootfrm.hxx>
63 #include <pagefrm.hxx>
64 #include <txtfrm.hxx>
65 #include <tabfrm.hxx>
66 #include <rowfrm.hxx>
67 #include <cellfrm.hxx>
68 #include <sectfrm.hxx>
69 #include <flyfrm.hxx>
70 #include <notxtfrm.hxx>
71 #include "porfld.hxx"
72 #include <SwStyleNameMapper.hxx>
73 #include "itrpaint.hxx"
75 #include <IMark.hxx>
76 #include <printdata.hxx>
77 #include <SwNodeNum.hxx>
78 #include <calbck.hxx>
79 #include <stack>
80 #include <frmtool.hxx>
81 #include <strings.hrc>
82 #include <frameformats.hxx>
83 
84 #include <tools/globname.hxx>
85 #include <svx/svdobj.hxx>
86 
87 using namespace ::com::sun::star;
88 
89 // Some static data structures
90 
96 
98 
99 #if OSL_DEBUG_LEVEL > 1
100 
101 static std::vector< sal_uInt16 > aStructStack;
102 
104 {
105  /* NonStructElement = 0 Document = 1 Part = 2
106  * Article = 3 Section = 4 Division = 5
107  * BlockQuote = 6 Caption = 7 TOC = 8
108  * TOCI = 9 Index = 10 Paragraph = 11
109  * Heading = 12 H1-6 = 13 - 18 List = 19
110  * ListItem = 20 LILabel = 21 LIBody = 22
111  * Table = 23 TableRow = 24 TableHeader = 25
112  * TableData = 26 Span = 27 Quote = 28
113  * Note = 29 Reference = 30 BibEntry = 31
114  * Code = 32 Link = 33 Figure = 34
115  * Formula = 35 Form = 36 Continued frame = 99
116  */
117 
118  sal_uInt16 nElement;
119  for ( const auto& rItem : aStructStack )
120  {
121  nElement = rItem;
122  }
123  (void)nElement;
124 };
125 
126 #endif
127 
128 namespace
129 {
130 // ODF Style Names:
131 const char aTableHeadingName[] = "Table Heading";
132 const char aQuotations[] = "Quotations";
133 const char aCaption[] = "Caption";
134 const char aHeading[] = "Heading";
135 const char aQuotation[] = "Quotation";
136 const char aSourceText[] = "Source Text";
137 
138 // PDF Tag Names:
139 const char aDocumentString[] = "Document";
140 const char aDivString[] = "Div";
141 const char aSectString[] = "Sect";
142 const char aHString[] = "H";
143 const char aH1String[] = "H1";
144 const char aH2String[] = "H2";
145 const char aH3String[] = "H3";
146 const char aH4String[] = "H4";
147 const char aH5String[] = "H5";
148 const char aH6String[] = "H6";
149 const char aListString[] = "L";
150 const char aListItemString[] = "LI";
151 const char aListBodyString[] = "LBody";
152 const char aBlockQuoteString[] = "BlockQuote";
153 const char aCaptionString[] = "Caption";
154 const char aIndexString[] = "Index";
155 const char aTOCString[] = "TOC";
156 const char aTOCIString[] = "TOCI";
157 const char aTableString[] = "Table";
158 const char aTRString[] = "TR";
159 const char aTDString[] = "TD";
160 const char aTHString[] = "TH";
161 const char aBibEntryString[] = "BibEntry";
162 const char aQuoteString[] = "Quote";
163 const char aSpanString[] = "Span";
164 const char aCodeString[] = "Code";
165 const char aFigureString[] = "Figure";
166 const char aFormulaString[] = "Formula";
167 const char aLinkString[] = "Link";
168 const char aNoteString[] = "Note";
169 
170 // returns true if first paragraph in cell frame has 'table heading' style
171 bool lcl_IsHeadlineCell( const SwCellFrame& rCellFrame )
172 {
173  bool bRet = false;
174 
175  const SwContentFrame *pCnt = rCellFrame.ContainsContent();
176  if ( pCnt && pCnt->IsTextFrame() )
177  {
178  SwTextNode const*const pTextNode = static_cast<const SwTextFrame*>(pCnt)->GetTextNodeForParaProps();
179  const SwFormat* pTextFormat = pTextNode->GetFormatColl();
180 
181  OUString sStyleName;
183  bRet = sStyleName == aTableHeadingName;
184  }
185 
186  return bRet;
187 }
188 
189 // List all frames for which the NonStructElement tag is set:
190 bool lcl_IsInNonStructEnv( const SwFrame& rFrame )
191 {
192  bool bRet = false;
193 
194  if ( nullptr != rFrame.FindFooterOrHeader() &&
195  !rFrame.IsHeaderFrame() && !rFrame.IsFooterFrame() )
196  {
197  bRet = true;
198  }
199  else if ( rFrame.IsInTab() && !rFrame.IsTabFrame() )
200  {
201  const SwTabFrame* pTabFrame = rFrame.FindTabFrame();
202  if ( rFrame.GetUpper() != pTabFrame &&
203  pTabFrame->IsFollow() && pTabFrame->IsInHeadline( rFrame ) )
204  bRet = true;
205  }
206 
207  return bRet;
208 }
209 
210 // Generate key from frame for reopening tags:
211 void* lcl_GetKeyFromFrame( const SwFrame& rFrame )
212 {
213  void* pKey = nullptr;
214 
215  if ( rFrame.IsPageFrame() )
216  pKey = const_cast<void*>(static_cast<void const *>(&(static_cast<const SwPageFrame&>(rFrame).GetFormat()->getIDocumentSettingAccess())));
217  else if ( rFrame.IsTextFrame() )
218  pKey = const_cast<void*>(static_cast<void const *>(static_cast<const SwTextFrame&>(rFrame).GetTextNodeFirst()));
219  else if ( rFrame.IsSctFrame() )
220  pKey = const_cast<void*>(static_cast<void const *>(static_cast<const SwSectionFrame&>(rFrame).GetSection()));
221  else if ( rFrame.IsTabFrame() )
222  pKey = const_cast<void*>(static_cast<void const *>(static_cast<const SwTabFrame&>(rFrame).GetTable()));
223  else if ( rFrame.IsRowFrame() )
224  pKey = const_cast<void*>(static_cast<void const *>(static_cast<const SwRowFrame&>(rFrame).GetTabLine()));
225  else if ( rFrame.IsCellFrame() )
226  {
227  const SwTabFrame* pTabFrame = rFrame.FindTabFrame();
228  const SwTable* pTable = pTabFrame->GetTable();
229  pKey = const_cast<void*>(static_cast<void const *>(& static_cast<const SwCellFrame&>(rFrame).GetTabBox()->FindStartOfRowSpan( *pTable )));
230  }
231 
232  return pKey;
233 }
234 
235 bool lcl_HasPreviousParaSameNumRule(SwTextFrame const& rTextFrame, const SwTextNode& rNode)
236 {
237  bool bRet = false;
238  SwNodeIndex aIdx( rNode );
239  const SwDoc& rDoc = rNode.GetDoc();
240  const SwNodes& rNodes = rDoc.GetNodes();
241  const SwNode* pNode = &rNode;
242  const SwNumRule* pNumRule = rNode.GetNumRule();
243 
244  while (pNode != rNodes.DocumentSectionStartNode(const_cast<SwNode*>(static_cast<SwNode const *>(&rNode))) )
245  {
246  sw::GotoPrevLayoutTextFrame(aIdx, rTextFrame.getRootFrame());
247 
248  if (aIdx.GetNode().IsTextNode())
249  {
250  const SwTextNode *const pPrevTextNd = sw::GetParaPropsNode(
251  *rTextFrame.getRootFrame(), *aIdx.GetNode().GetTextNode());
252  const SwNumRule * pPrevNumRule = pPrevTextNd->GetNumRule();
253 
254  // We find the previous text node. Now check, if the previous text node
255  // has the same numrule like rNode:
256  if ( (pPrevNumRule == pNumRule) &&
257  (!pPrevTextNd->IsOutline() == !rNode.IsOutline()))
258  bRet = true;
259 
260  break;
261  }
262 
263  pNode = &aIdx.GetNode();
264  }
265  return bRet;
266 }
267 
268 bool lcl_TryMoveToNonHiddenField(SwEditShell& rShell, const SwTextNode& rNd, const SwFormatField& rField)
269 {
270  // 1. Check if the whole paragraph is hidden
271  // 2. Move to the field
272  // 3. Check for hidden text attribute
273  if(rNd.IsHidden())
274  return false;
275  if(!rShell.GotoFormatField(rField) || rShell.SelectHiddenRange())
276  {
277  rShell.SwCursorShell::ClearMark();
278  return false;
279  }
280  return true;
281 };
282 
283 } // end namespace
284 
286  const Frame_Info* pFrameInfo,
287  const Por_Info* pPorInfo,
288  OutputDevice const & rOut )
289  : nEndStructureElement( 0 ),
290  nRestoreCurrentTag( -1 ),
291  mpNumInfo( pNumInfo ),
292  mpFrameInfo( pFrameInfo ),
293  mpPorInfo( pPorInfo )
294 {
296  dynamic_cast< vcl::PDFExtOutDevData*>( rOut.GetExtOutDevData() );
297 
299  return;
300 
301 #if OSL_DEBUG_LEVEL > 1
302  sal_Int32 nCurrentStruct = mpPDFExtOutDevData->GetCurrentStructureElement();
304 #endif
305  if ( mpNumInfo )
307  else if ( mpFrameInfo )
309  else if ( mpPorInfo )
311  else
313 
314 #if OSL_DEBUG_LEVEL > 1
317  (void)nCurrentStruct;
318 #endif
319 }
320 
322 {
324  return;
325 
326 #if OSL_DEBUG_LEVEL > 1
327  sal_Int32 nCurrentStruct = mpPDFExtOutDevData->GetCurrentStructureElement();
329 #endif
331 
332 #if OSL_DEBUG_LEVEL > 1
335  (void)nCurrentStruct;
336 #endif
337 }
338 
340 {
341  bool bRet = false;
342  sal_Int32 nReopenTag = -1;
343  bool bContinue = false; // in some cases we just have to reopen a tag without early returning
344 
345  if ( mpFrameInfo )
346  {
347  const SwFrame& rFrame = mpFrameInfo->mrFrame;
348  const SwFrame* pKeyFrame = nullptr;
349 
350  // Reopen an existing structure element if
351  // - rFrame is not the first page frame (reopen Document tag)
352  // - rFrame is a follow frame (reopen Master tag)
353  // - rFrame is a fly frame anchored at content (reopen Anchor paragraph tag)
354  // - rFrame is a fly frame anchored at page (reopen Document tag)
355  // - rFrame is a follow flow row (reopen TableRow tag)
356  // - rFrame is a cell frame in a follow flow row (reopen TableData tag)
357  if ( ( rFrame.IsPageFrame() && static_cast<const SwPageFrame&>(rFrame).GetPrev() ) ||
358  ( rFrame.IsFlowFrame() && SwFlowFrame::CastFlowFrame(&rFrame)->IsFollow() ) ||
359  ( rFrame.IsRowFrame() && rFrame.IsInFollowFlowRow() ) ||
360  ( rFrame.IsCellFrame() && const_cast<SwFrame&>(rFrame).GetPrevCellLeaf() ) )
361  {
362  pKeyFrame = &rFrame;
363  }
364  else if ( rFrame.IsFlyFrame() )
365  {
366  const SwFormatAnchor& rAnchor =
367  static_cast<const SwFlyFrame*>(&rFrame)->GetFormat()->GetAnchor();
368  if ((RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId()) ||
369  (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
370  (RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId()))
371  {
372  pKeyFrame = static_cast<const SwFlyFrame&>(rFrame).GetAnchorFrame();
373  bContinue = true;
374  }
375  }
376 
377  if ( pKeyFrame )
378  {
379  void* pKey = lcl_GetKeyFromFrame( *pKeyFrame );
380 
381  if ( pKey )
382  {
384  const FrameTagIdMap::const_iterator aIter = rFrameTagIdMap.find( pKey );
385  if ( aIter != rFrameTagIdMap.end() )
386  nReopenTag = (*aIter).second;
387  }
388  }
389  }
390 
391  if ( -1 != nReopenTag )
392  {
394  const bool bSuccess = mpPDFExtOutDevData->SetCurrentStructureElement( nReopenTag );
395  OSL_ENSURE( bSuccess, "Failed to reopen tag" );
396 
397 #if OSL_DEBUG_LEVEL > 1
398  aStructStack.push_back( 99 );
399 #endif
400 
401  bRet = bSuccess;
402  }
403 
404  return bRet && !bContinue;
405 }
406 
408 {
409  if ( nRestoreCurrentTag != -1 )
410  {
412  OSL_ENSURE( bSuccess, "Failed to restore reopened tag" );
413 
414 #if OSL_DEBUG_LEVEL > 1
415  aStructStack.pop_back();
416 #endif
417  }
418 }
419 
420 void SwTaggedPDFHelper::BeginTag( vcl::PDFWriter::StructElement eType, const OUString& rString )
421 {
422  // write new tag
423  const sal_Int32 nId = mpPDFExtOutDevData->BeginStructureElement( eType, rString );
425 
426 #if OSL_DEBUG_LEVEL > 1
427  aStructStack.push_back( static_cast<sal_uInt16>(eType) );
428 #endif
429 
430  // Store the id of the current structure element if
431  // - it is a list structure element
432  // - it is a list body element with children
433  // - rFrame is the first page frame
434  // - rFrame is a master frame
435  // - rFrame has objects anchored to it
436  // - rFrame is a row frame or cell frame in a split table row
437 
438  if ( mpNumInfo )
439  {
440  const SwTextFrame& rTextFrame = static_cast<const SwTextFrame&>(mpNumInfo->mrFrame);
441  SwTextNode const*const pTextNd = rTextFrame.GetTextNodeForParaProps();
442  const SwNodeNum* pNodeNum = pTextNd->GetNum(rTextFrame.getRootFrame());
443 
444  if ( vcl::PDFWriter::List == eType )
445  {
447  rNumListIdMap[ pNodeNum ] = nId;
448  }
449  else if ( vcl::PDFWriter::LIBody == eType )
450  {
452  rNumListBodyIdMap[ pNodeNum ] = nId;
453  }
454  }
455  else if ( mpFrameInfo )
456  {
457  const SwFrame& rFrame = mpFrameInfo->mrFrame;
458 
459  if ( ( rFrame.IsPageFrame() && !static_cast<const SwPageFrame&>(rFrame).GetPrev() ) ||
460  ( rFrame.IsFlowFrame() && !SwFlowFrame::CastFlowFrame(&rFrame)->IsFollow() && SwFlowFrame::CastFlowFrame(&rFrame)->HasFollow() ) ||
461  ( rFrame.IsTextFrame() && rFrame.GetDrawObjs() ) ||
462  ( rFrame.IsRowFrame() && rFrame.IsInSplitTableRow() ) ||
463  ( rFrame.IsCellFrame() && const_cast<SwFrame&>(rFrame).GetNextCellLeaf() ) )
464  {
465  const void* pKey = lcl_GetKeyFromFrame( rFrame );
466 
467  if ( pKey )
468  {
470  rFrameTagIdMap[ pKey ] = nId;
471  }
472  }
473  }
474 
475  SetAttributes( eType );
476 }
477 
479 {
481 
482 #if OSL_DEBUG_LEVEL > 1
483  aStructStack.pop_back();
484 #endif
485 }
486 
487 // Sets the attributes according to the structure type.
489 {
490  sal_Int32 nVal;
491 
492  /*
493  * ATTRIBUTES FOR BLSE
494  */
495  if ( mpFrameInfo )
496  {
498  const SwFrame* pFrame = &mpFrameInfo->mrFrame;
499  SwRectFnSet aRectFnSet(pFrame);
500 
501  bool bPlacement = false;
502  bool bWritingMode = false;
503  bool bSpaceBefore = false;
504  bool bSpaceAfter = false;
505  bool bStartIndent = false;
506  bool bEndIndent = false;
507  bool bTextIndent = false;
508  bool bTextAlign = false;
509  bool bWidth = false;
510  bool bHeight = false;
511  bool bBox = false;
512  bool bRowSpan = false;
513 
514  // Check which attributes to set:
515 
516  switch ( eType )
517  {
519  bWritingMode = true;
520  break;
521 
522  case vcl::PDFWriter::Table :
523  bPlacement =
524  bWritingMode =
525  bSpaceBefore =
526  bSpaceAfter =
527  bStartIndent =
528  bEndIndent =
529  bWidth =
530  bHeight =
531  bBox = true;
532  break;
533 
535  bPlacement =
536  bWritingMode = true;
537  break;
538 
541  bPlacement =
542  bWritingMode =
543  bWidth =
544  bHeight =
545  bRowSpan = true;
546  break;
547 
548  case vcl::PDFWriter::H1 :
549  case vcl::PDFWriter::H2 :
550  case vcl::PDFWriter::H3 :
551  case vcl::PDFWriter::H4 :
552  case vcl::PDFWriter::H5 :
553  case vcl::PDFWriter::H6 :
558 
559  bPlacement =
560  bWritingMode =
561  bSpaceBefore =
562  bSpaceAfter =
563  bStartIndent =
564  bEndIndent =
565  bTextIndent =
566  bTextAlign = true;
567  break;
568 
571  bPlacement =
572  bWidth =
573  bHeight =
574  bBox = true;
575  break;
576  default :
577  break;
578  }
579 
580  // Set the attributes:
581 
582  if ( bPlacement )
583  {
584  eVal = vcl::PDFWriter::TableHeader == eType ||
585  vcl::PDFWriter::TableData == eType ?
588 
590  }
591 
592  if ( bWritingMode )
593  {
594  eVal = pFrame->IsVertical() ?
596  pFrame->IsRightToLeft() ?
599 
600  if ( vcl::PDFWriter::LrTb != eVal )
602  }
603 
604  if ( bSpaceBefore )
605  {
606  nVal = aRectFnSet.GetTopMargin(*pFrame);
607  if ( 0 != nVal )
609  }
610 
611  if ( bSpaceAfter )
612  {
613  nVal = aRectFnSet.GetBottomMargin(*pFrame);
614  if ( 0 != nVal )
616  }
617 
618  if ( bStartIndent )
619  {
620  nVal = aRectFnSet.GetLeftMargin(*pFrame);
621  if ( 0 != nVal )
623  }
624 
625  if ( bEndIndent )
626  {
627  nVal = aRectFnSet.GetRightMargin(*pFrame);
628  if ( 0 != nVal )
630  }
631 
632  if ( bTextIndent )
633  {
634  OSL_ENSURE( pFrame->IsTextFrame(), "Frame type <-> tag attribute mismatch" );
635  const SvxLRSpaceItem &rSpace =
636  static_cast<const SwTextFrame*>(pFrame)->GetTextNodeForParaProps()->GetSwAttrSet().GetLRSpace();
637  nVal = rSpace.GetTextFirstLineOffset();
638  if ( 0 != nVal )
640  }
641 
642  if ( bTextAlign )
643  {
644  OSL_ENSURE( pFrame->IsTextFrame(), "Frame type <-> tag attribute mismatch" );
645  const SwAttrSet& aSet = static_cast<const SwTextFrame*>(pFrame)->GetTextNodeForParaProps()->GetSwAttrSet();
646  const SvxAdjust nAdjust = aSet.GetAdjust().GetAdjust();
647  if ( SvxAdjust::Block == nAdjust || SvxAdjust::Center == nAdjust ||
648  ( (pFrame->IsRightToLeft() && SvxAdjust::Left == nAdjust) ||
649  (!pFrame->IsRightToLeft() && SvxAdjust::Right == nAdjust) ) )
650  {
651  eVal = SvxAdjust::Block == nAdjust ?
653  SvxAdjust::Center == nAdjust ?
656 
658  }
659  }
660 
661  // Formally here bAlternateText was triggered for PDF export, but this
662  // was moved for more general use to primitives and usage in
663  // VclMetafileProcessor2D (see processGraphicPrimitive2D).
664 
665  if ( bWidth )
666  {
667  nVal = aRectFnSet.GetWidth(pFrame->getFrameArea());
669  }
670 
671  if ( bHeight )
672  {
673  nVal = aRectFnSet.GetHeight(pFrame->getFrameArea());
675  }
676 
677  if ( bBox )
678  {
679  // BBox only for non-split tables:
680  if ( vcl::PDFWriter::Table != eType ||
681  ( pFrame->IsTabFrame() &&
682  !static_cast<const SwTabFrame*>(pFrame)->IsFollow() &&
683  !static_cast<const SwTabFrame*>(pFrame)->HasFollow() ) )
684  {
686  }
687  }
688 
689  if ( bRowSpan )
690  {
691  const SwCellFrame* pThisCell = dynamic_cast<const SwCellFrame*>(pFrame);
692  if ( pThisCell )
693  {
694  nVal = pThisCell->GetTabBox()->getRowSpan();
695  if ( nVal > 1 )
697 
698  // calculate colspan:
699  const SwTabFrame* pTabFrame = pThisCell->FindTabFrame();
700  const SwTable* pTable = pTabFrame->GetTable();
701 
702  SwRectFnSet fnRectX(pTabFrame);
703 
705 
706  const tools::Long nLeft = fnRectX.GetLeft(pThisCell->getFrameArea());
707  const tools::Long nRight = fnRectX.GetRight(pThisCell->getFrameArea());
708  const TableColumnsMapEntry::const_iterator aLeftIter = rCols.find( nLeft );
709  const TableColumnsMapEntry::const_iterator aRightIter = rCols.find( nRight );
710 
711  OSL_ENSURE( aLeftIter != rCols.end() && aRightIter != rCols.end(), "Colspan trouble" );
712  if ( aLeftIter != rCols.end() && aRightIter != rCols.end() )
713  {
714  nVal = std::distance( aLeftIter, aRightIter );
715  if ( nVal > 1 )
717  }
718  }
719  }
720  }
721 
722  /*
723  * ATTRIBUTES FOR ILSE
724  */
725  else if ( mpPorInfo )
726  {
727  const SwLinePortion* pPor = &mpPorInfo->mrPor;
729 
730  bool bActualText = false;
731  bool bBaselineShift = false;
732  bool bTextDecorationType = false;
733  bool bLinkAttribute = false;
734  bool bLanguage = false;
735 
736  // Check which attributes to set:
737 
738  switch ( eType )
739  {
740  case vcl::PDFWriter::Span :
741  case vcl::PDFWriter::Quote :
742  case vcl::PDFWriter::Code :
745  bActualText = true;
746  else
747  {
748  bBaselineShift =
749  bTextDecorationType =
750  bLanguage = true;
751  }
752  break;
753 
754  case vcl::PDFWriter::Link :
755  bTextDecorationType =
756  bBaselineShift =
757  bLinkAttribute =
758  bLanguage = true;
759  break;
760 
761  default:
762  break;
763  }
764 
765  if ( bActualText )
766  {
767  OUString aActualText;
769  aActualText = OUString(u'\x00ad'); // soft hyphen
770  else
771  aActualText = rInf.GetText().copy(sal_Int32(rInf.GetIdx()), sal_Int32(pPor->GetLen()));
772  mpPDFExtOutDevData->SetActualText( aActualText );
773  }
774 
775  if ( bBaselineShift )
776  {
777  // TODO: Calculate correct values!
778  nVal = rInf.GetFont()->GetEscapement();
779  if ( nVal > 0 ) nVal = 33;
780  else if ( nVal < 0 ) nVal = -33;
781 
782  if ( 0 != nVal )
783  {
784  nVal = nVal * pPor->Height() / 100;
786  }
787  }
788 
789  if ( bTextDecorationType )
790  {
791  if ( LINESTYLE_NONE != rInf.GetFont()->GetUnderline() )
793  if ( LINESTYLE_NONE != rInf.GetFont()->GetOverline() )
795  if ( STRIKEOUT_NONE != rInf.GetFont()->GetStrikeout() )
797  if ( FontEmphasisMark::NONE != rInf.GetFont()->GetEmphasisMark() )
799  }
800 
801  if ( bLanguage )
802  {
803 
804  const LanguageType nCurrentLanguage = rInf.GetFont()->GetLanguage();
806 
807  if ( nDefaultLang != nCurrentLanguage )
808  mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::Language, static_cast<sal_uInt16>(nCurrentLanguage) );
809  }
810 
811  if ( bLinkAttribute )
812  {
814  SwRect aPorRect;
815  rInf.CalcRect( *pPor, &aPorRect );
816  const Point aPorCenter = aPorRect.Center();
817  auto aIter = std::find_if(rLinkIdMap.begin(), rLinkIdMap.end(),
818  [&aPorCenter](const IdMapEntry& rEntry) { return rEntry.first.IsInside(aPorCenter); });
819  if (aIter != rLinkIdMap.end())
820  {
821  sal_Int32 nLinkId = (*aIter).second;
823  }
824  }
825  }
826 }
827 
829 {
830  OSL_ENSURE( mpNumInfo, "List without mpNumInfo?" );
831  if ( !mpNumInfo )
832  return;
833 
834  const SwFrame& rFrame = mpNumInfo->mrFrame;
835  OSL_ENSURE( rFrame.IsTextFrame(), "numbered only for text frames" );
836  const SwTextFrame& rTextFrame = static_cast<const SwTextFrame&>(rFrame);
837 
838  // Lowers of NonStructureElements should not be considered:
839 
840  if ( lcl_IsInNonStructEnv( rTextFrame ) || rTextFrame.IsFollow() )
841  return;
842 
843  const SwTextNode *const pTextNd = rTextFrame.GetTextNodeForParaProps();
844  const SwNumRule* pNumRule = pTextNd->GetNumRule();
845  const SwNodeNum* pNodeNum = pTextNd->GetNum(rTextFrame.getRootFrame());
846 
847  const bool bNumbered = !pTextNd->IsOutline() && pNodeNum && pNodeNum->GetParent() && pNumRule;
848 
849  // Check, if we have to reopen a list or a list body:
850  // First condition:
851  // Paragraph is numbered/bulleted
852  if ( !bNumbered )
853  return;
854 
855  const SwNumberTreeNode* pParent = pNodeNum->GetParent();
856  const bool bSameNumbering = lcl_HasPreviousParaSameNumRule(rTextFrame, *pTextNd);
857 
858  // Second condition: current numbering is not 'interrupted'
859  if ( bSameNumbering )
860  {
861  sal_Int32 nReopenTag = -1;
862 
863  // Two cases:
864  // 1. We have to reopen an existing list body tag:
865  // - If the current node is either the first child of its parent
866  // and its level > 1 or
867  // - Numbering should restart at the current node and its level > 1
868  // - The current item has no label
869  const bool bNewSubListStart = pParent->GetParent() && (pParent->IsFirst( pNodeNum ) || pTextNd->IsListRestart() );
870  const bool bNoLabel = !pTextNd->IsCountedInList() && !pTextNd->IsListRestart();
871  if ( bNewSubListStart || bNoLabel )
872  {
873  // Fine, we try to reopen the appropriate list body
875 
876  if ( bNewSubListStart )
877  {
878  // The list body tag associated with the parent has to be reopened
879  // to start a new list inside the list body
880  NumListBodyIdMap::const_iterator aIter;
881 
882  do
883  aIter = rNumListBodyIdMap.find( pParent );
884  while ( aIter == rNumListBodyIdMap.end() && nullptr != ( pParent = pParent->GetParent() ) );
885 
886  if ( aIter != rNumListBodyIdMap.end() )
887  nReopenTag = (*aIter).second;
888  }
889  else // if(bNoLabel)
890  {
891  // The list body tag of a 'counted' predecessor has to be reopened
892  const SwNumberTreeNode* pPrevious = pNodeNum->GetPred(true);
893  while ( pPrevious )
894  {
895  if ( pPrevious->IsCounted())
896  {
897  // get id of list body tag
898  const NumListBodyIdMap::const_iterator aIter = rNumListBodyIdMap.find( pPrevious );
899  if ( aIter != rNumListBodyIdMap.end() )
900  {
901  nReopenTag = (*aIter).second;
902  break;
903  }
904  }
905  pPrevious = pPrevious->GetPred(true);
906  }
907  }
908  }
909  // 2. We have to reopen an existing list tag:
910  else if ( !pParent->IsFirst( pNodeNum ) && !pTextNd->IsListRestart() )
911  {
912  // any other than the first node in a list level has to reopen the current
913  // list. The current list is associated in a map with the first child of the list:
915 
916  // Search backwards and check if any of the previous nodes has a list associated with it:
917  const SwNumberTreeNode* pPrevious = pNodeNum->GetPred(true);
918  while ( pPrevious )
919  {
920  // get id of list tag
921  const NumListIdMap::const_iterator aIter = rNumListIdMap.find( pPrevious );
922  if ( aIter != rNumListIdMap.end() )
923  {
924  nReopenTag = (*aIter).second;
925  break;
926  }
927 
928  pPrevious = pPrevious->GetPred(true);
929  }
930  }
931 
932  if ( -1 != nReopenTag )
933  {
936 
937 #if OSL_DEBUG_LEVEL > 1
938  aStructStack.push_back( 99 );
939 #endif
940  }
941  }
942  else
943  {
944  // clear list maps in case a list has been interrupted
946  rNumListIdMap.clear();
948  rNumListBodyIdMap.clear();
949  }
950 
951  // New tags:
952  const bool bNewListTag = (pNodeNum->GetParent()->IsFirst( pNodeNum ) || pTextNd->IsListRestart() || !bSameNumbering);
953  const bool bNewItemTag = bNewListTag || pTextNd->IsCountedInList(); // If the text node is not counted, we do not start a new list item:
954 
955  if ( bNewListTag )
956  BeginTag( vcl::PDFWriter::List, aListString );
957 
958  if ( bNewItemTag )
959  {
960  BeginTag( vcl::PDFWriter::ListItem, aListItemString );
961  BeginTag( vcl::PDFWriter::LIBody, aListBodyString );
962  }
963 }
964 
966 {
967  const SwFrame* pFrame = &mpFrameInfo->mrFrame;
968 
969  // Lowers of NonStructureElements should not be considered:
970 
971  if ( lcl_IsInNonStructEnv( *pFrame ) )
972  return;
973 
974  // Check if we have to reopen an existing structure element.
975  // This has to be done e.g., if pFrame is a follow frame.
976  if ( CheckReopenTag() )
977  return;
978 
979  sal_uInt16 nPDFType = USHRT_MAX;
980  OUString aPDFType;
981 
982  switch ( pFrame->GetType() )
983  {
984  /*
985  * GROUPING ELEMENTS
986  */
987 
988  case SwFrameType::Page :
989 
990  // Document: Document
991 
992  nPDFType = vcl::PDFWriter::Document;
993  aPDFType = aDocumentString;
994  break;
995 
996  case SwFrameType::Header :
997  case SwFrameType::Footer :
998 
999  // Header, Footer: NonStructElement
1000 
1002  break;
1003 
1004  case SwFrameType::FtnCont :
1005 
1006  // Footnote container: Division
1007 
1008  nPDFType = vcl::PDFWriter::Division;
1009  aPDFType = aDivString;
1010  break;
1011 
1012  case SwFrameType::Ftn :
1013 
1014  // Footnote frame: Note
1015 
1016  // Note: vcl::PDFWriter::Note is actually a ILSE. Nevertheless
1017  // we treat it like a grouping element!
1018  nPDFType = vcl::PDFWriter::Note;
1019  aPDFType = aNoteString;
1020  break;
1021 
1022  case SwFrameType::Section :
1023 
1024  // Section: TOX, Index, or Sect
1025 
1026  {
1027  const SwSection* pSection =
1028  static_cast<const SwSectionFrame*>(pFrame)->GetSection();
1029  if ( SectionType::ToxContent == pSection->GetType() )
1030  {
1031  const SwTOXBase* pTOXBase = pSection->GetTOXBase();
1032  if ( pTOXBase )
1033  {
1034  if ( TOX_INDEX == pTOXBase->GetType() )
1035  {
1036  nPDFType = vcl::PDFWriter::Index;
1037  aPDFType = aIndexString;
1038  }
1039  else
1040  {
1041  nPDFType = vcl::PDFWriter::TOC;
1042  aPDFType = aTOCString;
1043  }
1044  }
1045  }
1046  else if ( SectionType::Content == pSection->GetType() )
1047  {
1048  nPDFType = vcl::PDFWriter::Section;
1049  aPDFType = aSectString;
1050  }
1051  }
1052  break;
1053 
1054  /*
1055  * BLOCK-LEVEL STRUCTURE ELEMENTS
1056  */
1057 
1058  case SwFrameType::Txt :
1059  {
1060  const SwTextNode* pTextNd =
1061  static_cast<const SwTextFrame*>(pFrame)->GetTextNodeForParaProps();
1062 
1063  const SwFormat* pTextFormat = pTextNd->GetFormatColl();
1064  const SwFormat* pParentTextFormat = pTextFormat ? pTextFormat->DerivedFrom() : nullptr;
1065 
1066  OUString sStyleName;
1067  OUString sParentStyleName;
1068 
1069  if ( pTextFormat)
1071  if ( pParentTextFormat)
1072  SwStyleNameMapper::FillProgName( pParentTextFormat->GetName(), sParentStyleName, SwGetPoolIdFromName::TxtColl );
1073 
1074  // This is the default. If the paragraph could not be mapped to
1075  // any of the standard pdf tags, we write a user defined tag
1076  // <stylename> with role = P
1077  nPDFType = vcl::PDFWriter::Paragraph;
1078  aPDFType = sStyleName;
1079 
1080  // Quotations: BlockQuote
1081 
1082  if (sStyleName == aQuotations)
1083  {
1084  nPDFType = vcl::PDFWriter::BlockQuote;
1085  aPDFType = aBlockQuoteString;
1086  }
1087 
1088  // Caption: Caption
1089 
1090  else if (sStyleName == aCaption)
1091  {
1092  nPDFType = vcl::PDFWriter::Caption;
1093  aPDFType = aCaptionString;
1094  }
1095 
1096  // Caption: Caption
1097 
1098  else if (sParentStyleName == aCaption)
1099  {
1100  nPDFType = vcl::PDFWriter::Caption;
1101  aPDFType = sStyleName + aCaptionString;
1102  }
1103 
1104  // Heading: H
1105 
1106  else if (sStyleName == aHeading)
1107  {
1108  nPDFType = vcl::PDFWriter::Heading;
1109  aPDFType = aHString;
1110  }
1111 
1112  // Heading: H1 - H6
1113 
1114  if (pTextNd->IsOutline()
1115  && sw::IsParaPropsNode(*pFrame->getRootFrame(), *pTextNd))
1116  {
1117  int nRealLevel = pTextNd->GetAttrOutlineLevel()-1;
1118  nRealLevel = std::min(nRealLevel, 5);
1119 
1120  nPDFType = static_cast<sal_uInt16>(vcl::PDFWriter::H1 + nRealLevel);
1121  switch(nRealLevel)
1122  {
1123  case 0 :
1124  aPDFType = aH1String;
1125  break;
1126  case 1 :
1127  aPDFType = aH2String;
1128  break;
1129  case 2 :
1130  aPDFType = aH3String;
1131  break;
1132  case 3 :
1133  aPDFType = aH4String;
1134  break;
1135  case 4 :
1136  aPDFType = aH5String;
1137  break;
1138  default:
1139  aPDFType = aH6String;
1140  break;
1141  }
1142  }
1143 
1144  // Section: TOCI
1145 
1146  else if ( pFrame->IsInSct() )
1147  {
1148  const SwSectionFrame* pSctFrame = pFrame->FindSctFrame();
1149  const SwSection* pSection = pSctFrame->GetSection();
1150 
1151  if ( SectionType::ToxContent == pSection->GetType() )
1152  {
1153  const SwTOXBase* pTOXBase = pSection->GetTOXBase();
1154  if ( pTOXBase && TOX_INDEX != pTOXBase->GetType() )
1155  {
1156  // Special case: Open additional TOCI tag:
1157  BeginTag( vcl::PDFWriter::TOCI, aTOCIString );
1158  }
1159  }
1160  }
1161  }
1162  break;
1163 
1164  case SwFrameType::Tab :
1165 
1166  // TabFrame: Table
1167 
1168  nPDFType = vcl::PDFWriter::Table;
1169  aPDFType = aTableString;
1170 
1171  {
1172  // set up table column data:
1173  const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>(pFrame);
1174  const SwTable* pTable = pTabFrame->GetTable();
1175 
1177  const TableColumnsMap::const_iterator aIter = rTableColumnsMap.find( pTable );
1178 
1179  if ( aIter == rTableColumnsMap.end() )
1180  {
1181  SwRectFnSet aRectFnSet(pTabFrame);
1182  TableColumnsMapEntry& rCols = rTableColumnsMap[ pTable ];
1183 
1184  const SwTabFrame* pMasterFrame = pTabFrame->IsFollow() ? pTabFrame->FindMaster( true ) : pTabFrame;
1185 
1186  while ( pMasterFrame )
1187  {
1188  const SwRowFrame* pRowFrame = static_cast<const SwRowFrame*>(pMasterFrame->GetLower());
1189 
1190  while ( pRowFrame )
1191  {
1192  const SwFrame* pCellFrame = pRowFrame->GetLower();
1193 
1194  const tools::Long nLeft = aRectFnSet.GetLeft(pCellFrame->getFrameArea());
1195  rCols.insert( nLeft );
1196 
1197  while ( pCellFrame )
1198  {
1199  const tools::Long nRight = aRectFnSet.GetRight(pCellFrame->getFrameArea());
1200  rCols.insert( nRight );
1201  pCellFrame = pCellFrame->GetNext();
1202  }
1203  pRowFrame = static_cast<const SwRowFrame*>(pRowFrame->GetNext());
1204  }
1205  pMasterFrame = pMasterFrame->GetFollow();
1206  }
1207  }
1208  }
1209 
1210  break;
1211 
1212  /*
1213  * TABLE ELEMENTS
1214  */
1215 
1216  case SwFrameType::Row :
1217 
1218  // RowFrame: TR
1219 
1220  if ( !static_cast<const SwRowFrame*>(pFrame)->IsRepeatedHeadline() )
1221  {
1222  nPDFType = vcl::PDFWriter::TableRow;
1223  aPDFType = aTRString;
1224  }
1225  else
1226  {
1228  }
1229  break;
1230 
1231  case SwFrameType::Cell :
1232 
1233  // CellFrame: TH, TD
1234 
1235  {
1236  const SwTabFrame* pTable = static_cast<const SwCellFrame*>(pFrame)->FindTabFrame();
1237  if ( pTable->IsInHeadline( *pFrame ) || lcl_IsHeadlineCell( *static_cast<const SwCellFrame*>(pFrame) ) )
1238  {
1239  nPDFType = vcl::PDFWriter::TableHeader;
1240  aPDFType = aTHString;
1241  }
1242  else
1243  {
1244  nPDFType = vcl::PDFWriter::TableData;
1245  aPDFType = aTDString;
1246  }
1247  }
1248  break;
1249 
1250  /*
1251  * ILLUSTRATION
1252  */
1253 
1254  case SwFrameType::Fly :
1255 
1256  // FlyFrame: Figure, Formula, Control
1257  // fly in content or fly at page
1258  {
1259  const SwFlyFrame* pFly = static_cast<const SwFlyFrame*>(pFrame);
1260  if ( pFly->Lower() && pFly->Lower()->IsNoTextFrame() )
1261  {
1262  bool bFormula = false;
1263 
1264  const SwNoTextFrame* pNoTextFrame = static_cast<const SwNoTextFrame*>(pFly->Lower());
1265  SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTextFrame->GetNode()->GetOLENode());
1266  if ( pOLENd )
1267  {
1268  SwOLEObj& aOLEObj = pOLENd->GetOLEObj();
1269  uno::Reference< embed::XEmbeddedObject > aRef = aOLEObj.GetOleRef();
1270  if ( aRef.is() )
1271  {
1272  bFormula = 0 != SotExchange::IsMath( SvGlobalName( aRef->getClassID() ) );
1273  }
1274  }
1275  if ( bFormula )
1276  {
1277  nPDFType = vcl::PDFWriter::Formula;
1278  aPDFType = aFormulaString;
1279  }
1280  else
1281  {
1282  nPDFType = vcl::PDFWriter::Figure;
1283  aPDFType = aFigureString;
1284  }
1285  }
1286  else
1287  {
1288  nPDFType = vcl::PDFWriter::Division;
1289  aPDFType = aDivString;
1290  }
1291  }
1292  break;
1293 
1294  default: break;
1295  }
1296 
1297  if ( USHRT_MAX != nPDFType )
1298  {
1299  BeginTag( static_cast<vcl::PDFWriter::StructElement>(nPDFType), aPDFType );
1300  }
1301 }
1302 
1304 {
1305  while ( nEndStructureElement > 0 )
1306  {
1307  EndTag();
1309  }
1310 
1311  CheckRestoreTag();
1312 }
1313 
1315 {
1316  const SwLinePortion* pPor = &mpPorInfo->mrPor;
1318  const SwTextFrame* pFrame = rInf.GetTextFrame();
1319 
1320  // Lowers of NonStructureElements should not be considered:
1321 
1322  if ( lcl_IsInNonStructEnv( *pFrame ) )
1323  return;
1324 
1325  sal_uInt16 nPDFType = USHRT_MAX;
1326  OUString aPDFType;
1327 
1328  switch ( pPor->GetWhichPor() )
1329  {
1330  case PortionType::Hyphen :
1332  // Check for alternative spelling:
1333  case PortionType::HyphenStr :
1335  nPDFType = vcl::PDFWriter::Span;
1336  aPDFType = aSpanString;
1337  break;
1338 
1339  case PortionType::Lay :
1340  case PortionType::Text :
1341  case PortionType::Para :
1342  {
1343  std::pair<SwTextNode const*, sal_Int32> const pos(
1344  pFrame->MapViewToModel(rInf.GetIdx()));
1345  SwTextAttr const*const pInetFormatAttr =
1346  pos.first->GetTextAttrAt(pos.second, RES_TXTATR_INETFMT);
1347 
1348  OUString sStyleName;
1349  if ( !pInetFormatAttr )
1350  {
1351  std::vector<SwTextAttr *> const charAttrs(
1352  pos.first->GetTextAttrsAt(pos.second, RES_TXTATR_CHARFMT));
1353  // TODO: handle more than 1 char style?
1354  const SwCharFormat* pCharFormat = (charAttrs.size())
1355  ? (*charAttrs.begin())->GetCharFormat().GetCharFormat() : nullptr;
1356  if ( pCharFormat )
1357  SwStyleNameMapper::FillProgName( pCharFormat->GetName(), sStyleName, SwGetPoolIdFromName::TxtColl );
1358  }
1359 
1360  // Check for Link:
1361  if( pInetFormatAttr )
1362  {
1363  nPDFType = vcl::PDFWriter::Link;
1364  aPDFType = aLinkString;
1365  }
1366  // Check for Quote/Code character style:
1367  else if (sStyleName == aQuotation)
1368  {
1369  nPDFType = vcl::PDFWriter::Quote;
1370  aPDFType = aQuoteString;
1371  }
1372  else if (sStyleName == aSourceText)
1373  {
1374  nPDFType = vcl::PDFWriter::Code;
1375  aPDFType = aCodeString;
1376  }
1377  else
1378  {
1379  const LanguageType nCurrentLanguage = rInf.GetFont()->GetLanguage();
1380  const SwFontScript nFont = rInf.GetFont()->GetActual();
1382 
1383  if ( LINESTYLE_NONE != rInf.GetFont()->GetUnderline() ||
1384  LINESTYLE_NONE != rInf.GetFont()->GetOverline() ||
1385  STRIKEOUT_NONE != rInf.GetFont()->GetStrikeout() ||
1386  FontEmphasisMark::NONE != rInf.GetFont()->GetEmphasisMark() ||
1387  0 != rInf.GetFont()->GetEscapement() ||
1388  SwFontScript::Latin != nFont ||
1389  nCurrentLanguage != nDefaultLang ||
1390  !sStyleName.isEmpty())
1391  {
1392  nPDFType = vcl::PDFWriter::Span;
1393  if (!sStyleName.isEmpty())
1394  aPDFType = sStyleName;
1395  else
1396  aPDFType = aSpanString;
1397  }
1398  }
1399  }
1400  break;
1401 
1402  case PortionType::Footnote :
1403  nPDFType = vcl::PDFWriter::Link;
1404  aPDFType = aLinkString;
1405  break;
1406 
1407  case PortionType::Field :
1408  {
1409  // check field type:
1410  TextFrameIndex const nIdx = static_cast<const SwFieldPortion*>(pPor)->IsFollow()
1411  ? rInf.GetIdx() - TextFrameIndex(1)
1412  : rInf.GetIdx();
1413  const SwTextAttr* pHint = mpPorInfo->mrTextPainter.GetAttr( nIdx );
1414  if ( pHint && RES_TXTATR_FIELD == pHint->Which() )
1415  {
1416  const SwField* pField = pHint->GetFormatField().GetField();
1417  if ( SwFieldIds::GetRef == pField->Which() )
1418  {
1419  nPDFType = vcl::PDFWriter::Link;
1420  aPDFType = aLinkString;
1421  }
1422  else if ( SwFieldIds::TableOfAuthorities == pField->Which() )
1423  {
1424  nPDFType = vcl::PDFWriter::BibEntry;
1425  aPDFType = aBibEntryString;
1426  }
1427  }
1428  }
1429  break;
1430 
1431  case PortionType::Table :
1432  case PortionType::TabRight :
1433  case PortionType::TabCenter :
1436  break;
1437  default: break;
1438  }
1439 
1440  if ( USHRT_MAX != nPDFType )
1441  {
1442  BeginTag( static_cast<vcl::PDFWriter::StructElement>(nPDFType), aPDFType );
1443  }
1444 }
1445 
1447 {
1448  vcl::PDFExtOutDevData* pPDFExtOutDevData = dynamic_cast< vcl::PDFExtOutDevData*>( rOut.GetExtOutDevData() );
1449  return pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportTaggedPDF();
1450 }
1451 
1453  OutputDevice& rOut,
1454  const OUString& rPageRange,
1455  bool bSkipEmptyPages,
1456  bool bEditEngineOnly,
1457  const SwPrintData& rPrintData )
1458  : mrSh( rSh ),
1459  mrOut( rOut ),
1460  mbSkipEmptyPages( bSkipEmptyPages ),
1461  mbEditEngineOnly( bEditEngineOnly ),
1462  mrPrintData( rPrintData )
1463 {
1464  if ( !rPageRange.isEmpty() )
1465  mpRangeEnum.reset( new StringRangeEnumerator( rPageRange, 0, mrSh.GetPageCount()-1 ) );
1466 
1467  if ( mbSkipEmptyPages )
1468  {
1469  maPageNumberMap.resize( mrSh.GetPageCount() );
1470  const SwPageFrame* pCurrPage =
1471  static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1472  sal_Int32 nPageNumber = 0;
1473  for ( size_t i = 0, n = maPageNumberMap.size(); i < n && pCurrPage; ++i )
1474  {
1475  if ( pCurrPage->IsEmptyPage() )
1476  maPageNumberMap[i] = -1;
1477  else
1478  maPageNumberMap[i] = nPageNumber++;
1479 
1480  pCurrPage = static_cast<const SwPageFrame*>( pCurrPage->GetNext() );
1481  }
1482  }
1483 
1484  aTableColumnsMap.clear();
1485  aLinkIdMap.clear();
1486  aNumListIdMap.clear();
1487  aNumListBodyIdMap.clear();
1488  aFrameTagIdMap.clear();
1489 
1490 #if OSL_DEBUG_LEVEL > 1
1491  aStructStack.clear();
1492 #endif
1493 
1494  const sal_Int16 nScript = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
1495  sal_uInt16 nLangRes = RES_CHRATR_LANGUAGE;
1496 
1497  if ( i18n::ScriptType::ASIAN == nScript )
1498  nLangRes = RES_CHRATR_CJK_LANGUAGE;
1499  else if ( i18n::ScriptType::COMPLEX == nScript )
1500  nLangRes = RES_CHRATR_CTL_LANGUAGE;
1501 
1502  eLanguageDefault = static_cast<const SvxLanguageItem*>(&mrSh.GetDoc()->GetDefault( nLangRes ))->GetLanguage();
1503 
1505 }
1506 
1508 {
1509 }
1510 
1512  const tools::Rectangle& rRectangle) const
1513 {
1514  SwPostItMode nPostItMode = mrPrintData.GetPrintPostIts();
1515  if (nPostItMode != SwPostItMode::InMargins)
1516  return rRectangle;
1517  //the page has been scaled by 75% and vertically centered, so adjust these
1518  //rectangles equivalently
1519  tools::Rectangle aRect(rRectangle);
1520  Size aRectSize(aRect.GetSize());
1521  double fScale = 0.75;
1522  aRectSize.setWidth( aRectSize.Width() * fScale );
1523  aRectSize.setHeight( aRectSize.Height() * fScale );
1524  tools::Long nOrigHeight = pCurrPage->getFrameArea().Height();
1525  tools::Long nNewHeight = nOrigHeight*fScale;
1526  tools::Long nShiftY = (nOrigHeight-nNewHeight)/2;
1527  aRect.SetLeft( aRect.Left() * fScale );
1528  aRect.SetTop( aRect.Top() * fScale );
1529  aRect.Move(0, nShiftY);
1530  aRect.SetSize(aRectSize);
1531  return aRect;
1532 }
1533 
1535 {
1536  vcl::PDFExtOutDevData* pPDFExtOutDevData =
1537  dynamic_cast< vcl::PDFExtOutDevData*>( mrOut.GetExtOutDevData() );
1538 
1539  if ( !pPDFExtOutDevData )
1540  return;
1541 
1542  // set the document locale
1543 
1544  css::lang::Locale aDocLocale( LanguageTag( SwEnhancedPDFExportHelper::GetDefaultLanguage() ).getLocale() );
1545  pPDFExtOutDevData->SetDocumentLocale( aDocLocale );
1546 
1547  // Prepare the output device:
1548 
1549  mrOut.Push( PushFlags::MAPMODE );
1550  MapMode aMapMode( mrOut.GetMapMode() );
1551  aMapMode.SetMapUnit( MapUnit::MapTwip );
1552  mrOut.SetMapMode( aMapMode );
1553 
1554  // Create new cursor and lock the view:
1555 
1556  SwDoc* pDoc = mrSh.GetDoc();
1557  mrSh.SwCursorShell::Push();
1558  mrSh.SwCursorShell::ClearMark();
1559  const bool bOldLockView = mrSh.IsViewLocked();
1560  mrSh.LockView( true );
1561 
1562  if ( !mbEditEngineOnly )
1563  {
1564 
1565  // POSTITS
1566 
1567  if ( pPDFExtOutDevData->GetIsExportNotes() )
1568  {
1569  std::vector<SwFormatField*> vpFields;
1570  mrSh.GetFieldType(SwFieldIds::Postit, OUString())->GatherFields(vpFields);
1571  for(auto pFormatField : vpFields)
1572  {
1573  const SwTextNode* pTNd = pFormatField->GetTextField()->GetpTextNode();
1574  OSL_ENSURE(nullptr != pTNd, "Enhanced pdf export - text node is missing");
1575  if(!lcl_TryMoveToNonHiddenField(mrSh, *pTNd, *pFormatField))
1576  continue;
1577  // Link Rectangle
1578  const SwRect& rNoteRect = mrSh.GetCharRect();
1579  const SwPageFrame* pCurrPage = static_cast<const SwPageFrame*>(mrSh.GetLayout()->Lower());
1580 
1581  // Link PageNums
1582  std::vector<sal_Int32> aNotePageNums = CalcOutputPageNums(rNoteRect);
1583  for (sal_Int32 aNotePageNum : aNotePageNums)
1584  {
1585 
1586  // Use the NumberFormatter to get the date string:
1587  const SwPostItField* pField = static_cast<SwPostItField*>(pFormatField->GetField());
1588  SvNumberFormatter* pNumFormatter = pDoc->GetNumberFormatter();
1589  const Date aDateDiff(pField->GetDate() - pNumFormatter->GetNullDate());
1590  const sal_uLong nFormat = pNumFormatter->GetStandardFormat(SvNumFormatType::DATE, pField->GetLanguage());
1591  OUString sDate;
1592  const Color* pColor;
1593  pNumFormatter->GetOutputString(aDateDiff.GetDate(), nFormat, sDate, &pColor);
1594 
1595  vcl::PDFNote aNote;
1596  // The title should consist of the author and the date:
1597  aNote.Title = pField->GetPar1() + ", " + sDate + ", " + (pField->GetResolved() ? SwResId(STR_RESOLVED) : "");
1598  // Guess what the contents contains...
1599  aNote.Contents = pField->GetText();
1600 
1601  // Link Export
1602  tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rNoteRect.SVRect()));
1603  pPDFExtOutDevData->CreateNote(aRect, aNote, aNotePageNum);
1604  }
1605  mrSh.SwCursorShell::ClearMark();
1606  }
1607  }
1608 
1609  // HYPERLINKS
1610 
1612  mrSh.GetINetAttrs( aArr );
1613  for( auto &rAttr : aArr )
1614  {
1615  SwGetINetAttr* p = &rAttr;
1616  OSL_ENSURE( nullptr != p, "Enhanced pdf export - SwGetINetAttr is missing" );
1617 
1618  const SwTextNode* pTNd = p->rINetAttr.GetpTextNode();
1619  OSL_ENSURE( nullptr != pTNd, "Enhanced pdf export - text node is missing" );
1620 
1621  // 1. Check if the whole paragraph is hidden
1622  // 2. Move to the hyperlink
1623  // 3. Check for hidden text attribute
1624  if ( !pTNd->IsHidden() &&
1625  mrSh.GotoINetAttr( p->rINetAttr ) &&
1626  !mrSh.SelectHiddenRange() )
1627  {
1628  // Select the hyperlink:
1629  mrSh.SwCursorShell::Right( 1, CRSR_SKIP_CHARS );
1630  if ( mrSh.SwCursorShell::SelectTextAttr( RES_TXTATR_INETFMT, true ) )
1631  {
1632  // First, we create the destination, because there may be more
1633  // than one link to this destination:
1634  OUString aURL( INetURLObject::decode(
1637 
1638  // We have to distinguish between intern and real URLs
1639  const bool bIntern = '#' == aURL[0];
1640 
1641  // GetCursor_() is a SwShellCursor, which is derived from
1642  // SwSelPaintRects, therefore the rectangles of the current
1643  // selection can be easily obtained:
1644  // Note: We make a copy of the rectangles, because they may
1645  // be deleted again in JumpToSwMark.
1646  SwRects aTmp;
1647  aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() );
1648  OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
1649 
1650  const SwPageFrame* pSelectionPage =
1651  static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1652 
1653  // Create the destination for internal links:
1654  sal_Int32 nDestId = -1;
1655  if ( bIntern )
1656  {
1657  aURL = aURL.copy( 1 );
1658  mrSh.SwCursorShell::ClearMark();
1659  if (! JumpToSwMark( &mrSh, aURL ))
1660  {
1661  continue; // target deleted
1662  }
1663 
1664  // Destination Rectangle
1665  const SwRect& rDestRect = mrSh.GetCharRect();
1666 
1667  const SwPageFrame* pCurrPage =
1668  static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1669 
1670  // Destination PageNum
1671  const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
1672 
1673  // Destination Export
1674  if ( -1 != nDestPageNum )
1675  {
1676  tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
1677  nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
1678  }
1679  }
1680 
1681  if ( !bIntern || -1 != nDestId )
1682  {
1683  // #i44368# Links in Header/Footer
1684  const SwPosition aPos( *pTNd );
1685  const bool bHeaderFooter = pDoc->IsInHeaderFooter( aPos.nNode );
1686 
1687  // Create links for all selected rectangles:
1688  const size_t nNumOfRects = aTmp.size();
1689  for ( size_t i = 0; i < nNumOfRects; ++i )
1690  {
1691  // Link Rectangle
1692  const SwRect& rLinkRect( aTmp[ i ] );
1693 
1694  // Link PageNums
1695  std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( rLinkRect );
1696 
1697  for (sal_Int32 aLinkPageNum : aLinkPageNums)
1698  {
1699  // Link Export
1700  tools::Rectangle aRect(SwRectToPDFRect(pSelectionPage, rLinkRect.SVRect()));
1701  const sal_Int32 nLinkId =
1702  pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
1703 
1704  // Store link info for tagged pdf output:
1705  const IdMapEntry aLinkEntry( rLinkRect, nLinkId );
1706  aLinkIdMap.push_back( aLinkEntry );
1707 
1708  // Connect Link and Destination:
1709  if ( bIntern )
1710  pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
1711  else
1712  pPDFExtOutDevData->SetLinkURL( nLinkId, aURL );
1713 
1714  // #i44368# Links in Header/Footer
1715  if ( bHeaderFooter )
1716  MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, aURL, bIntern );
1717  }
1718  }
1719  }
1720  }
1721  }
1722  mrSh.SwCursorShell::ClearMark();
1723  }
1724 
1725  // HYPERLINKS (Graphics, Frames, OLEs )
1726 
1727  SwFrameFormats* pTable = pDoc->GetSpzFrameFormats();
1728  const size_t nSpzFrameFormatsCount = pTable->size();
1729  for( size_t n = 0; n < nSpzFrameFormatsCount; ++n )
1730  {
1731  SwFrameFormat* pFrameFormat = (*pTable)[n];
1732  const SfxPoolItem* pItem;
1733  if ( RES_DRAWFRMFMT != pFrameFormat->Which() &&
1734  GetFrameOfModify(mrSh.GetLayout(), *pFrameFormat, SwFrameType::Fly) &&
1735  SfxItemState::SET == pFrameFormat->GetAttrSet().GetItemState( RES_URL, true, &pItem ) )
1736  {
1737  const SwPageFrame* pCurrPage =
1738  static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1739 
1740  OUString aURL( static_cast<const SwFormatURL*>(pItem)->GetURL() );
1741  const bool bIntern = !aURL.isEmpty() && '#' == aURL[0];
1742 
1743  // Create the destination for internal links:
1744  sal_Int32 nDestId = -1;
1745  if ( bIntern )
1746  {
1747  aURL = aURL.copy( 1 );
1748  mrSh.SwCursorShell::ClearMark();
1749  if (! JumpToSwMark( &mrSh, aURL ))
1750  {
1751  continue; // target deleted
1752  }
1753 
1754  // Destination Rectangle
1755  const SwRect& rDestRect = mrSh.GetCharRect();
1756 
1757  pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1758 
1759  // Destination PageNum
1760  const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
1761 
1762  // Destination Export
1763  if ( -1 != nDestPageNum )
1764  {
1765  tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
1766  nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
1767  }
1768  }
1769 
1770  if ( !bIntern || -1 != nDestId )
1771  {
1772  Point aNullPt;
1773  const SwRect aLinkRect = pFrameFormat->FindLayoutRect( false, &aNullPt );
1774 
1775  // Link PageNums
1776  std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( aLinkRect );
1777 
1778  // Link Export
1779  for (sal_Int32 aLinkPageNum : aLinkPageNums)
1780  {
1781  tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, aLinkRect.SVRect()));
1782  const sal_Int32 nLinkId =
1783  pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
1784 
1785  // Connect Link and Destination:
1786  if ( bIntern )
1787  pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
1788  else
1789  pPDFExtOutDevData->SetLinkURL( nLinkId, aURL );
1790 
1791  // #i44368# Links in Header/Footer
1792  const SwFormatAnchor &rAnch = pFrameFormat->GetAnchor();
1793  if (RndStdIds::FLY_AT_PAGE != rAnch.GetAnchorId())
1794  {
1795  const SwPosition* pPosition = rAnch.GetContentAnchor();
1796  if ( pPosition && pDoc->IsInHeaderFooter( pPosition->nNode ) )
1797  {
1798  const SwTextNode* pTNd = pPosition->nNode.GetNode().GetTextNode();
1799  if ( pTNd )
1800  MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, aLinkRect, nDestId, aURL, bIntern );
1801  }
1802  }
1803  }
1804  }
1805  }
1806  else if (pFrameFormat->Which() == RES_DRAWFRMFMT)
1807  {
1808  // Turn media shapes into Screen annotations.
1809  if (SdrObject* pObject = pFrameFormat->FindRealSdrObject())
1810  {
1811  SwRect aSnapRect = pObject->GetSnapRect();
1812  std::vector<sal_Int32> aScreenPageNums = CalcOutputPageNums(aSnapRect);
1813  if (aScreenPageNums.empty())
1814  continue;
1815 
1816  uno::Reference<drawing::XShape> xShape(pObject->getUnoShape(), uno::UNO_QUERY);
1817  if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape")
1818  {
1819  uno::Reference<beans::XPropertySet> xShapePropSet(xShape, uno::UNO_QUERY);
1820  OUString aMediaURL;
1821  xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
1822  if (!aMediaURL.isEmpty())
1823  {
1824  const SwPageFrame* pCurrPage = mrSh.GetLayout()->GetPageAtPos(aSnapRect.Center());
1825  tools::Rectangle aPDFRect(SwRectToPDFRect(pCurrPage, aSnapRect.SVRect()));
1826  for (sal_Int32 nScreenPageNum : aScreenPageNums)
1827  {
1828  sal_Int32 nScreenId = pPDFExtOutDevData->CreateScreen(aPDFRect, nScreenPageNum);
1829  if (aMediaURL.startsWith("vnd.sun.star.Package:"))
1830  {
1831  // Embedded media.
1832  OUString aTempFileURL;
1833  xShapePropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL;
1834  pPDFExtOutDevData->SetScreenStream(nScreenId, aTempFileURL);
1835  }
1836  else
1837  // Linked media.
1838  pPDFExtOutDevData->SetScreenURL(nScreenId, aMediaURL);
1839  }
1840  }
1841  }
1842  }
1843  }
1844  mrSh.SwCursorShell::ClearMark();
1845  }
1846 
1847  // REFERENCES
1848 
1849  std::vector<SwFormatField*> vpFields;
1850  mrSh.GetFieldType( SwFieldIds::GetRef, OUString() )->GatherFields(vpFields);
1851  for(auto pFormatField : vpFields )
1852  {
1853  if( pFormatField->GetTextField() && pFormatField->IsFieldInDoc() )
1854  {
1855  const SwTextNode* pTNd = pFormatField->GetTextField()->GetpTextNode();
1856  OSL_ENSURE( nullptr != pTNd, "Enhanced pdf export - text node is missing" );
1857  if(!lcl_TryMoveToNonHiddenField(mrSh, *pTNd, *pFormatField))
1858  continue;
1859  // Select the field:
1860  mrSh.SwCursorShell::SetMark();
1861  mrSh.SwCursorShell::Right( 1, CRSR_SKIP_CHARS );
1862 
1863  // Link Rectangles
1864  SwRects aTmp;
1865  aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() );
1866  OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
1867 
1868  mrSh.SwCursorShell::ClearMark();
1869 
1870  // Destination Rectangle
1871  const SwGetRefField* pField = static_cast<SwGetRefField*>(pFormatField->GetField());
1872  const OUString& rRefName = pField->GetSetRefName();
1873  mrSh.GotoRefMark( rRefName, pField->GetSubType(), pField->GetSeqNo() );
1874  const SwRect& rDestRect = mrSh.GetCharRect();
1875 
1876  const SwPageFrame* pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1877 
1878  // Destination PageNum
1879  const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
1880 
1881  if ( -1 != nDestPageNum )
1882  {
1883  // Destination Export
1884  tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
1885  const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
1886 
1887  // #i44368# Links in Header/Footer
1888  const SwPosition aPos( *pTNd );
1889  const bool bHeaderFooter = pDoc->IsInHeaderFooter( aPos.nNode );
1890 
1891  // Create links for all selected rectangles:
1892  const size_t nNumOfRects = aTmp.size();
1893  for ( size_t i = 0; i < nNumOfRects; ++i )
1894  {
1895  // Link rectangle
1896  const SwRect& rLinkRect( aTmp[ i ] );
1897 
1898  // Link PageNums
1899  std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( rLinkRect );
1900 
1901  for (sal_Int32 aLinkPageNum : aLinkPageNums)
1902  {
1903  // Link Export
1904  aRect = SwRectToPDFRect(pCurrPage, rLinkRect.SVRect());
1905  const sal_Int32 nLinkId =
1906  pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
1907 
1908  // Store link info for tagged pdf output:
1909  const IdMapEntry aLinkEntry( rLinkRect, nLinkId );
1910  aLinkIdMap.push_back( aLinkEntry );
1911 
1912  // Connect Link and Destination:
1913  pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
1914 
1915  // #i44368# Links in Header/Footer
1916  if ( bHeaderFooter )
1917  {
1918  MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, "", true );
1919  }
1920  }
1921  }
1922  }
1923  }
1924  mrSh.SwCursorShell::ClearMark();
1925  }
1926 
1927  // FOOTNOTES
1928 
1929  const size_t nFootnoteCount = pDoc->GetFootnoteIdxs().size();
1930  for ( size_t nIdx = 0; nIdx < nFootnoteCount; ++nIdx )
1931  {
1932  // Set cursor to text node that contains the footnote:
1933  const SwTextFootnote* pTextFootnote = pDoc->GetFootnoteIdxs()[ nIdx ];
1934  SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
1935 
1936  mrSh.GetCursor_()->GetPoint()->nNode = rTNd;
1937  mrSh.GetCursor_()->GetPoint()->nContent.Assign( &rTNd, pTextFootnote->GetStart() );
1938 
1939  // 1. Check if the whole paragraph is hidden
1940  // 2. Check for hidden text attribute
1941  if (rTNd.GetTextNode()->IsHidden() || mrSh.SelectHiddenRange()
1942  || (mrSh.GetLayout()->IsHideRedlines()
1943  && sw::IsFootnoteDeleted(pDoc->getIDocumentRedlineAccess(), *pTextFootnote)))
1944  {
1945  continue;
1946  }
1947 
1948  SwCursorSaveState aSaveState( *mrSh.GetCursor_() );
1949 
1950  // Select the footnote:
1951  mrSh.SwCursorShell::SetMark();
1952  mrSh.SwCursorShell::Right( 1, CRSR_SKIP_CHARS );
1953 
1954  // Link Rectangle
1955  SwRects aTmp;
1956  aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() );
1957  OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
1958 
1960  mrSh.SwCursorShell::ClearMark();
1961 
1962  if (aTmp.empty())
1963  continue;
1964 
1965  const SwRect aLinkRect( aTmp[ 0 ] );
1966 
1967  // Goto footnote text:
1968  if ( mrSh.GotoFootnoteText() )
1969  {
1970  // Link PageNums
1971  std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( aLinkRect );
1972 
1973  // Destination Rectangle
1974  const SwRect& rDestRect = mrSh.GetCharRect();
1975 
1976  const SwPageFrame* pCurrPage =
1977  static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1978 
1979  // Destination PageNum
1980  const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
1981 
1982  for (sal_Int32 aLinkPageNum : aLinkPageNums)
1983  {
1984  // Link Export
1985  tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, aLinkRect.SVRect()));
1986  const sal_Int32 nLinkId =
1987  pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
1988 
1989  // Store link info for tagged pdf output:
1990  const IdMapEntry aLinkEntry( aLinkRect, nLinkId );
1991  aLinkIdMap.push_back( aLinkEntry );
1992 
1993  if ( -1 != nDestPageNum )
1994  {
1995  aRect = SwRectToPDFRect(pCurrPage, rDestRect.SVRect());
1996  // Destination Export
1997  const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(rDestRect.SVRect(), nDestPageNum);
1998 
1999  // Connect Link and Destination:
2000  pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
2001  }
2002  }
2003  }
2004  }
2005 
2006  // OUTLINE
2007 
2008  if( pPDFExtOutDevData->GetIsExportBookmarks() )
2009  {
2010  typedef std::pair< sal_Int8, sal_Int32 > StackEntry;
2011  std::stack< StackEntry > aOutlineStack;
2012  aOutlineStack.push( StackEntry( -1, -1 ) ); // push default value
2013 
2014  const SwOutlineNodes::size_type nOutlineCount =
2016  for ( SwOutlineNodes::size_type i = 0; i < nOutlineCount; ++i )
2017  {
2018  // Check if outline is hidden
2019  const SwTextNode* pTNd = mrSh.GetNodes().GetOutLineNds()[ i ]->GetTextNode();
2020  OSL_ENSURE( nullptr != pTNd, "Enhanced pdf export - text node is missing" );
2021 
2022  if ( pTNd->IsHidden() ||
2023  !sw::IsParaPropsNode(*mrSh.GetLayout(), *pTNd) ||
2024  // #i40292# Skip empty outlines:
2025  pTNd->GetText().isEmpty())
2026  continue;
2027 
2028  // Get parent id from stack:
2029  const sal_Int8 nLevel = static_cast<sal_Int8>(mrSh.getIDocumentOutlineNodesAccess()->getOutlineLevel( i ));
2030  sal_Int8 nLevelOnTopOfStack = aOutlineStack.top().first;
2031  while ( nLevelOnTopOfStack >= nLevel &&
2032  nLevelOnTopOfStack != -1 )
2033  {
2034  aOutlineStack.pop();
2035  nLevelOnTopOfStack = aOutlineStack.top().first;
2036  }
2037  const sal_Int32 nParent = aOutlineStack.top().second;
2038 
2039  // Destination rectangle
2040  mrSh.GotoOutline(i);
2041  const SwRect& rDestRect = mrSh.GetCharRect();
2042 
2043  const SwPageFrame* pCurrPage =
2044  static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2045 
2046  // Destination PageNum
2047  const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2048 
2049  if ( -1 != nDestPageNum )
2050  {
2051  // Destination Export
2052  tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2053  const sal_Int32 nDestId =
2054  pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2055 
2056  // Outline entry text
2057  const OUString& rEntry = mrSh.getIDocumentOutlineNodesAccess()->getOutlineText(
2058  i, mrSh.GetLayout(), true, false, false );
2059 
2060  // Create a new outline item:
2061  const sal_Int32 nOutlineId =
2062  pPDFExtOutDevData->CreateOutlineItem( nParent, rEntry, nDestId );
2063 
2064  // Push current level and nOutlineId on stack:
2065  aOutlineStack.push( StackEntry( nLevel, nOutlineId ) );
2066  }
2067  }
2068  }
2069 
2070  if( pPDFExtOutDevData->GetIsExportNamedDestinations() )
2071  {
2072  // #i56629# the iteration to convert the OOo bookmark (#bookmark)
2073  // into PDF named destination, see section 8.2.1 in PDF 1.4 spec
2074  // We need:
2075  // 1. a name for the destination, formed from the standard OOo bookmark name
2076  // 2. the destination, obtained from where the bookmark destination lies
2077  IDocumentMarkAccess* const pMarkAccess = mrSh.GetDoc()->getIDocumentMarkAccess();
2078  for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
2079  ppMark != pMarkAccess->getBookmarksEnd();
2080  ++ppMark)
2081  {
2082  //get the name
2083  const ::sw::mark::IMark* pBkmk = *ppMark;
2084  mrSh.SwCursorShell::ClearMark();
2085  const OUString& sBkName = pBkmk->GetName();
2086 
2087  //jump to it
2088  if (! JumpToSwMark( &mrSh, sBkName ))
2089  {
2090  continue;
2091  }
2092 
2093  // Destination Rectangle
2094  const SwRect& rDestRect = mrSh.GetCharRect();
2095 
2096  const SwPageFrame* pCurrPage =
2097  static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2098 
2099  // Destination PageNum
2100  const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2101 
2102  // Destination Export
2103  if ( -1 != nDestPageNum )
2104  {
2105  tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2106  pPDFExtOutDevData->CreateNamedDest(sBkName, aRect, nDestPageNum);
2107  }
2108  }
2109  mrSh.SwCursorShell::ClearMark();
2110  //<--- i56629
2111  }
2112  }
2113  else
2114  {
2115 
2116  // LINKS FROM EDITENGINE
2117 
2118  std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
2119  for ( const auto& rBookmark : rBookmarks )
2120  {
2121  OUString aBookmarkName( rBookmark.aBookmark );
2122  const bool bIntern = '#' == aBookmarkName[0];
2123  if ( bIntern )
2124  {
2125  aBookmarkName = aBookmarkName.copy( 1 );
2126  JumpToSwMark( &mrSh, aBookmarkName );
2127 
2128  // Destination Rectangle
2129  const SwRect& rDestRect = mrSh.GetCharRect();
2130 
2131  const SwPageFrame* pCurrPage =
2132  static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2133 
2134  // Destination PageNum
2135  const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2136 
2137  if ( -1 != nDestPageNum )
2138  {
2139  tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2140  if ( rBookmark.nLinkId != -1 )
2141  {
2142  // Destination Export
2143  const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2144 
2145  // Connect Link and Destination:
2146  pPDFExtOutDevData->SetLinkDest( rBookmark.nLinkId, nDestId );
2147  }
2148  else
2149  {
2150  pPDFExtOutDevData->DescribeRegisteredDest(rBookmark.nDestId, aRect, nDestPageNum);
2151  }
2152  }
2153  }
2154  else
2155  pPDFExtOutDevData->SetLinkURL( rBookmark.nLinkId, aBookmarkName );
2156  }
2157  rBookmarks.clear();
2158  }
2159 
2160  // Restore view, cursor, and outdev:
2161  mrSh.LockView( bOldLockView );
2162  mrSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent);
2163  mrOut.Pop();
2164 }
2165 
2166 // Returns the page number in the output pdf on which the given rect is located.
2167 // If this page is duplicated, method will return first occurrence of it.
2169 {
2170  std::vector< sal_Int32 > aPageNums = CalcOutputPageNums( rRect );
2171  if ( !aPageNums.empty() )
2172  return aPageNums[0];
2173  return -1;
2174 }
2175 
2176 // Returns a vector of the page numbers in the output pdf on which the given
2177 // rect is located. There can be many such pages since StringRangeEnumerator
2178 // allows duplication of its entries.
2180  const SwRect& rRect ) const
2181 {
2182  std::vector< sal_Int32 > aPageNums;
2183 
2184  // Document page number.
2185  sal_Int32 nPageNumOfRect = mrSh.GetPageNumAndSetOffsetForPDF( mrOut, rRect );
2186  if ( nPageNumOfRect < 0 )
2187  return aPageNums;
2188 
2189  // What will be the page numbers of page nPageNumOfRect in the output pdf?
2190  if ( mpRangeEnum )
2191  {
2192  if ( mbSkipEmptyPages )
2193  // Map the page number to the range without empty pages.
2194  nPageNumOfRect = maPageNumberMap[ nPageNumOfRect ];
2195 
2196  if ( mpRangeEnum->hasValue( nPageNumOfRect ) )
2197  {
2198  sal_Int32 nOutputPageNum = 0;
2201  for ( ; aIter != aEnd; ++aIter )
2202  {
2203  if ( *aIter == nPageNumOfRect )
2204  aPageNums.push_back( nOutputPageNum );
2205  ++nOutputPageNum;
2206  }
2207  }
2208  }
2209  else
2210  {
2211  if ( mbSkipEmptyPages )
2212  {
2213  sal_Int32 nOutputPageNum = 0;
2214  for ( size_t i = 0; i < maPageNumberMap.size(); ++i )
2215  {
2216  if ( maPageNumberMap[i] >= 0 ) // is not empty?
2217  {
2218  if ( i == static_cast<size_t>( nPageNumOfRect ) )
2219  {
2220  aPageNums.push_back( nOutputPageNum );
2221  break;
2222  }
2223  ++nOutputPageNum;
2224  }
2225  }
2226  }
2227  else
2228  aPageNums.push_back( nPageNumOfRect );
2229  }
2230 
2231  return aPageNums;
2232 }
2233 
2235  const SwTextNode& rTNd,
2236  const SwRect& rLinkRect,
2237  sal_Int32 nDestId,
2238  const OUString& rURL,
2239  bool bIntern ) const
2240 {
2241  // We assume, that the primary link has just been exported. Therefore
2242  // the offset of the link rectangle calculates as follows:
2243  const Point aOffset = rLinkRect.Pos() + mrOut.GetMapMode().GetOrigin();
2244 
2246  for ( SwTextFrame* pTmpFrame = aIter.First(); pTmpFrame; pTmpFrame = aIter.Next() )
2247  {
2248  // Add offset to current page:
2249  const SwPageFrame* pPageFrame = pTmpFrame->FindPageFrame();
2250  SwRect aHFLinkRect( rLinkRect );
2251  aHFLinkRect.Pos() = pPageFrame->getFrameArea().Pos() + aOffset;
2252 
2253  // #i97135# the gcc_x64 optimizer gets aHFLinkRect != rLinkRect wrong
2254  // fool it by comparing the position only (the width and height are the
2255  // same anyway)
2256  if ( aHFLinkRect.Pos() != rLinkRect.Pos() )
2257  {
2258  // Link PageNums
2259  std::vector<sal_Int32> aHFLinkPageNums = CalcOutputPageNums( aHFLinkRect );
2260 
2261  for (sal_Int32 aHFLinkPageNum : aHFLinkPageNums)
2262  {
2263  // Link Export
2264  tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, aHFLinkRect.SVRect()));
2265  const sal_Int32 nHFLinkId =
2266  rPDFExtOutDevData.CreateLink(aRect, aHFLinkPageNum);
2267 
2268  // Connect Link and Destination:
2269  if ( bIntern )
2270  rPDFExtOutDevData.SetLinkDest( nHFLinkId, nDestId );
2271  else
2272  rPDFExtOutDevData.SetLinkURL( nHFLinkId, rURL );
2273  }
2274  }
2275  }
2276 }
2277 
2278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwFieldType * GetFieldType(size_t nField, SwFieldIds nResId=SwFieldIds::Unknown) const
get field types with a ResId, if 0 get all
Definition: edfld.cxx:64
Date GetDate() const
Definition: docufld.hxx:474
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:547
Base class of the Writer layout elements.
Definition: frame.hxx:297
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1358
static LanguageType GetDefaultLanguage()
URL aURL
bool IsFollow() const
Definition: flowfrm.hxx:166
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:545
OUString Title
Marks a position in the document model.
Definition: pam.hxx:35
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2091
const SwField * GetField() const
Definition: fmtfld.hxx:111
const SwPageFrame * GetPageAtPos(const Point &rPt, const Size *pSize=nullptr, bool bExtend=false) const
Point rPt: The point that should be used to find the page Size pSize: If given, we return the (first)...
Definition: findfrm.cxx:572
bool JumpToSwMark(SwViewShell const *pVwSh, const OUString &rMark)
Definition: edtwin3.cxx:118
const SwNodeNum * GetNum(SwRootFrame const *pLayout=nullptr) const
Definition: ndtxt.cxx:3933
OUString Contents
bool IsInSct() const
Definition: frame.hxx:945
LanguageType GetLanguage() const
Language at field position.
Definition: fldbas.hxx:406
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:161
A tree of numbered nodes.
void setWidth(tools::Long nWidth)
sal_uInt16 Height() const
Definition: possiz.hxx:50
SwPostItMode GetPrintPostIts() const
Definition: printdata.hxx:145
const SwOLEObj & GetOLEObj() const
Definition: ndole.hxx:112
SwFont * GetFont()
Definition: inftxt.hxx:238
const OUString & GetText() const
Definition: ndtxt.hxx:211
bool IsOutline() const
Returns if this text node is an outline.
Definition: ndtxt.cxx:3968
SwTextAttr * GetAttr(TextFrameIndex nPos) const
Returns the attribute for a position.
Definition: itratr.cxx:143
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1407
virtual OUString getOutlineText(const tSortedOutlineNodeList::size_type nIdx, SwRootFrame const *pLayout, const bool bWithNumber=true, const bool bWithSpacesForLevel=false, const bool bWithFootnote=true) const =0
vcl::PDFExtOutDevData * mpPDFExtOutDevData
tools::Long GetLeftMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1383
signed char sal_Int8
const SwTable * GetTable() const
Definition: tabfrm.hxx:144
SwNodeIndex nNode
Definition: pam.hxx:37
bool SetCurrentStructureElement(sal_Int32 nElement)
std::unique_ptr< StringRangeEnumerator > mpRangeEnum
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2629
SwFrameType GetType() const
Definition: frame.hxx:500
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
sal_uIntPtr sal_uLong
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
SwNumberTreeNode * GetPred(bool bSibling=false) const
Returns the greatest descendant of the root that is smaller than this node, aka the predecessor of th...
long Long
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2686
void SetScreenURL(sal_Int32 nScreenId, const OUString &rURL)
void BeginTag(vcl::PDFWriter::StructElement aTagRole, const OUString &rTagName)
Base class of all fields.
Definition: fldbas.hxx:293
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:399
SwNumberTreeNode * GetParent() const
Returns the parent of this node.
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:30
SwNode * DocumentSectionStartNode(SwNode *pNode) const
Definition: nodes.cxx:2297
css::uno::Reference< css::embed::XEmbeddedObject > const & GetOleRef()
Definition: ndole.cxx:913
sal_Int64 n
Provides access to the marks of a document.
Definition: doc.hxx:184
void SetStructureAttribute(PDFWriter::StructAttribute eAttr, PDFWriter::StructAttributeValue eVal)
TElementType * Next()
Definition: calbck.hxx:353
bool HasFollow() const
Definition: flowfrm.hxx:165
sal_Int16 nId
virtual OUString GetPar1() const override
Author.
Definition: docufld.cxx:1798
void MakeHeaderFooterLinks(vcl::PDFExtOutDevData &rPDFExtOutDevData, const SwTextNode &rTNd, const SwRect &rLinkRect, sal_Int32 nDestId, const OUString &rURL, bool bIntern) const
const MapMode & GetMapMode() const
bool IsFootnoteDeleted(IDocumentRedlineAccess const &rIDRA, SwTextFootnote const &rTextFootnote)
Definition: ftnidx.cxx:37
SwNode & GetNode() const
Definition: ndindex.hxx:119
bool IsFirst(const SwNumberTreeNode *pNode) const
Return if a node is first non-phantom child of this node.
void Pos(const Point &rNew)
Definition: swrect.hxx:169
FontStrikeout GetStrikeout() const
Definition: swfont.hxx:272
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1682
bool IsCellFrame() const
Definition: frame.hxx:1204
std::vector< IdMapEntry > LinkIdMap
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
sal_uInt16 Which() const
Definition: txatbase.hxx:110
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1359
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2647
bool IsListRestart() const
Definition: ndtxt.cxx:4105
EmbeddedObjectRef * pObject
void SetMapMode()
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:739
bool IsInHeaderFooter(const SwNodeIndex &rIdx) const
Definition: doclay.cxx:1550
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:3998
void lcl_DBGCheckStack()
void GetINetAttrs(SwGetINetAttrs &rArr)
Definition: editsh.cxx:687
void GatherFields(std::vector< SwFormatField * > &rvFormatFields, bool bCollectOnlyInDocNodes=true) const
Definition: fldbas.cxx:193
void SetAttributes(vcl::PDFWriter::StructElement eType)
bool SelectHiddenRange()
If the current cursor position is inside a hidden range, the hidden range is selected.
Definition: crsrsh.cxx:3412
bool GetIsExportNamedDestinations() const
bool IsFlyFrame() const
Definition: frame.hxx:1188
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
const SwLinePortion & mrPor
const SwTableBox * GetTabBox() const
Definition: cellfrm.hxx:52
tools::Long Left() const
LINESTYLE_NONE
void SetLeft(tools::Long v)
SwIndex nContent
Definition: pam.hxx:38
const SwRect & getFrameArea() const
Definition: frame.hxx:177
size_t pos
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_CTL_LANGUAGE(29)
bool IsInTab() const
Definition: frame.hxx:933
bool GotoFootnoteText()
jump from content to footnote
Definition: trvlfnfl.cxx:83
const OUString & GetName() const
Definition: format.hxx:111
const SfxPoolItem & GetDefault(sal_uInt16 nFormatHint) const
Get the default attribute in this document.
Definition: docfmt.cxx:653
std::vector< SwGetINetAttr > SwGetINetAttrs
Definition: editsh.hxx:126
const OUString & GetText() const
Definition: docufld.hxx:485
const SwRowFrame * IsInSplitTableRow() const
Definition: findfrm.cxx:1752
SwTextPaintInfo & GetInfo()
Definition: itrpaint.hxx:57
bool IsTextFrame() const
Definition: frame.hxx:1212
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
void SetLinkDest(sal_Int32 nLinkId, sal_Int32 nDestId)
SwDoc * GetDoc() const
Definition: viewsh.hxx:281
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:191
bool IsSctFrame() const
Definition: frame.hxx:1192
FontEmphasisMark GetEmphasisMark() const
Definition: swfont.hxx:282
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1357
static sal_uInt16 IsMath(const SvGlobalName &rName)
size_type size() const
static FrameTagIdMap & GetFrameTagIdMap()
bool IsFlowFrame() const
Definition: frame.hxx:1220
sal_Int32 GetCurrentStructureElement() const
SwFontScript GetActual() const
Definition: swfont.hxx:182
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
Specific frame formats (frames, DrawObjects).
Base class for various Writer styles.
Definition: format.hxx:43
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:328
virtual const_iterator_t getBookmarksEnd() const =0
returns a STL-like random access iterator to the end of the sequence of IBookmarks.
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1293
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
Style of a layout element.
Definition: frmfmt.hxx:57
A helper class to save cursor state (position).
Definition: swcrsr.hxx:232
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:717
sal_uInt16 GetPageCount() const
Definition: viewsh.cxx:2514
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
SvxAdjust
int i
std::map< const SwTable *, TableColumnsMapEntry > TableColumnsMap
SwDoc & GetDoc()
Definition: node.hxx:211
const SwPosition * GetPoint() const
Definition: pam.hxx:207
bool GetIsExportTaggedPDF() const
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
static TableColumnsMap aTableColumnsMap
const SwTOXBase * GetTOXBase() const
Definition: section.cxx:617
#define LANGUAGE_SYSTEM
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
void SetStructureAttributeNumerical(PDFWriter::StructAttribute eAttr, sal_Int32 nValue)
SwPageFrame * FindPageFrame()
Definition: frame.hxx:660
const SwTextINetFormat & rINetAttr
Definition: editsh.hxx:120
constexpr TypedWhichId< SwFormatURL > RES_URL(111)
const SwTextPainter & mrTextPainter
const SwFrame * Lower() const
Definition: layfrm.hxx:101
void SetSize(const Size &rSize)
TElementType * First()
Definition: calbck.hxx:345
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1360
SwSection * GetSection()
Definition: sectfrm.hxx:84
FontLineStyle GetOverline() const
Definition: swfont.hxx:270
FlyAnchors.
Definition: fmtanchr.hxx:34
const SvxPageUsage aArr[]
SwTaggedPDFHelper(const Num_Info *pNumInfo, const Frame_Info *pFrameInfo, const Por_Info *pPorInfo, OutputDevice const &rOut)
bool GotoINetAttr(const SwTextINetFormat &rAttr)
Definition: crstrvl.cxx:1993
std::pair< SwRect, sal_Int32 > IdMapEntry
virtual int getOutlineLevel(const tSortedOutlineNodeList::size_type nIdx) const =0
SwLayoutFrame * GetUpper()
Definition: frame.hxx:658
const SwFrame & mrFrame
sal_Int32 CreateDest(const tools::Rectangle &rRect, sal_Int32 nPageNr=-1, PDFWriter::DestAreaType eType=PDFWriter::DestAreaType::XYZ)
static sal_Int16 GetI18NScriptTypeOfLanguage(LanguageType nLang)
float u
void CalcRect(const SwLinePortion &rPor, SwRect *pRect, SwRect *pIntersect=nullptr, const bool bInsideBox=false) const
Calculate the rectangular area where the portion takes place.
Definition: inftxt.cxx:752
virtual tSortedOutlineNodeList::size_type getOutlineNodesCount() const =0
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2779
bool IsRowFrame() const
Definition: frame.hxx:1200
sal_Int32 CalcOutputPageNum(const SwRect &rRect) const
static bool IsExportTaggedPDF(const OutputDevice &rOut)
bool GetIsExportNotes() const
const SwRowFrame * IsInFollowFlowRow() const
Definition: findfrm.cxx:1785
tools::Long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1381
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:278
Marks a node in the document model.
Definition: ndindex.hxx:31
void SetTop(tools::Long v)
std::vector< sal_Int32 > maPageNumberMap
The problem is that numbers in StringRangeEnumerator aren't accordant to real page numbers if mbSkipE...
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:231
OUString SwResId(const char *pId)
Definition: swmodule.cxx:165
tools::Long GetRightMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1384
const SwTextNode * GetpTextNode() const
Definition: txtinet.hxx:46
tools::Long Top() const
TextFrameIndex GetLen() const
Definition: porlin.hxx:74
A page of the document layout.
Definition: pagefrm.hxx:41
SwTextFrame * GetTextFrame()
Definition: inftxt.hxx:291
sal_Int32 BeginStructureElement(PDFWriter::StructElement eType, const OUString &rAlias=OUString())
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1223
SwPostItMode
this must match the definitions in css::text::NotePrintMode
Definition: printdata.hxx:42
sal_Int32 CreateScreen(const tools::Rectangle &rRect, sal_Int32 nPageNr)
Size GetSize() const
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:110
const OUString & GetText() const
Definition: inftxt.hxx:246
Point Center() const
Definition: swrect.cxx:35
SwTextNode * GetParaPropsNode(SwRootFrame const &rLayout, SwNodeIndex const &rNode)
Definition: txtfrm.cxx:324
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1093
FontLineStyle GetUnderline() const
Definition: swfont.hxx:268
const LanguageTag & getLocale()
void DescribeRegisteredDest(sal_Int32 nDestId, const tools::Rectangle &rRect, sal_Int32 nPageNr, PDFWriter::DestAreaType eType=PDFWriter::DestAreaType::XYZ)
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:78
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:50
void SetLinkURL(sal_Int32 nLinkId, const OUString &rURL)
const SwFrame & mrFrame
SwFormat * DerivedFrom() const
Definition: format.hxx:108
std::map< const SwNumberTreeNode *, sal_Int32 > NumListBodyIdMap
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
void CreateNote(const tools::Rectangle &rRect, const PDFNote &rNote, sal_Int32 nPageNr=-1)
For querying the INet-attributes for Navigator.
Definition: editsh.hxx:117
const Frame_Info * mpFrameInfo
LanguageType GetLanguage() const
Definition: swfont.hxx:279
std::vector< SwRect > SwRects
Definition: swregion.hxx:26
const SwContentNode * GetNode() const
Definition: notxtfrm.hxx:66
std::map< const SwNumberTreeNode *, sal_Int32 > NumListIdMap
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
sal_uInt16 GetSeqNo() const
Get/set SequenceNo (of interest only for REF_SEQUENCEFLD).
Definition: reffld.hxx:132
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:231
tools::Rectangle SVRect() const
Definition: swrect.hxx:280
tools::Long GetBottomMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1382
bool IsTabFrame() const
Definition: frame.hxx:1196
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
static std::vector< sal_uInt16 > aStructStack
static TableColumnsMap & GetTableColumnsMap()
PortionType GetWhichPor() const
Definition: porlin.hxx:95
std::set< long, lt_TableColumn > TableColumnsMapEntry
void LockView(bool b)
Definition: viewsh.hxx:462
sal_Int32 GetPageNumAndSetOffsetForPDF(OutputDevice &rOut, const SwRect &rRect) const
Definition: viewsh.cxx:2540
TOXTypes GetType() const
Definition: tox.hxx:731
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:254
std::vector< PDFExtOutDevBookmarkEntry > & GetBookmarks()
virtual const_iterator_t getBookmarksBegin() const =0
returns a STL-like random access iterator to the begin of the sequence the IBookmarks.
bool IsCountedInList() const
Definition: ndtxt.cxx:4220
bool IsNoTextFrame() const
Definition: frame.hxx:1216
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
static void FillProgName(const OUString &rName, OUString &rFillName, SwGetPoolIdFromName)
LanguageType GetAppLanguage()
Definition: init.cxx:728
SwNodes & GetNodes()
Definition: doc.hxx:403
sal_Int32 CreateNamedDest(const OUString &sDestName, const tools::Rectangle &rRect, sal_Int32 nPageNr=-1)
bool IsRightToLeft() const
Definition: frame.hxx:965
sal_Int32 CreateLink(const tools::Rectangle &rRect, sal_Int32 nPageNr=-1)
const SwRect & GetCharRect() const
Definition: crsrsh.hxx:516
SwFrame * GetLower()
Definition: findfrm.cxx:169
std::map< const void *, sal_Int32 > FrameTagIdMap
bool IsPageFrame() const
Definition: frame.hxx:1156
void * p
const OUString & GetSetRefName() const
Definition: reffld.hxx:107
bool IsHidden() const
Definition: ndtxt.cxx:4539
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(157)
SwFontScript
Definition: swfont.hxx:122
bool IsParaPropsNode(SwRootFrame const &rLayout, SwTextNode const &rNode)
Definition: txtfrm.cxx:307
const Point & GetOrigin() const
std::vector< sal_Int32 > CalcOutputPageNums(const SwRect &rRect) const
void SetDocumentLocale(const css::lang::Locale &rLoc)
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:417
sal_Int32 CreateOutlineItem(sal_Int32 nParent, const OUString &rText, sal_Int32 nDestID)
static NumListIdMap & GetNumListIdMap()
void GotoPrevLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1446
const SwTabFrame * GetFollow() const
Definition: tabfrm.hxx:243
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
bool IsVertical() const
Definition: frame.hxx:951
void SetActualText(const OUString &rText)
const sal_uInt16 CRSR_SKIP_CHARS
Definition: swcrsr.hxx:65
bool GetIsExportBookmarks() const
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:628
vcl::ExtOutDevData * GetExtOutDevData() const
SwFormatColl * GetFormatColl() const
Definition: node.hxx:455
size_t size() const
virtual bool IsCounted() const
Return if this node is counted.
void SetScreenStream(sal_Int32 nScreenId, const OUString &rURL)
SectionType GetType() const
Definition: section.hxx:170
SwEnhancedPDFExportHelper(SwEditShell &rSh, OutputDevice &rOut, const OUString &rPageRange, bool bSkipEmptyPages, bool bEditEngineOnly, const SwPrintData &rPrintData)
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
STRIKEOUT_NONE
std::vector< SwNode * >::size_type size_type
const Date & GetNullDate() const
const SwContentFrame * ContainsContent() const
Checks if the frame contains one or more ContentFrame's anywhere in his subsidiary structure; if so t...
Definition: findfrm.cxx:66
static NumListBodyIdMap & GetNumListBodyIdMap()
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2073
void Push(PushFlags nFlags=PushFlags::ALL)
static NumListBodyIdMap aNumListBodyIdMap
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
short GetEscapement() const
Definition: swfont.hxx:275
void SetStructureBoundingBox(const tools::Rectangle &rRect)
bool GotoOutline(const OUString &rName)
Definition: crstrvl.cxx:984
void Height(tools::Long nNew)
Definition: swrect.hxx:191
tools::Rectangle SwRectToPDFRect(const SwPageFrame *pCurrPage, const tools::Rectangle &rRectangle) const
virtual sal_uInt16 GetSubType() const override
Get/set sub type.
Definition: reffld.cxx:369
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:69
bool GotoFormatField(const SwFormatField &rField)
Definition: crstrvl.cxx:830
bool IsFooterFrame() const
Definition: frame.hxx:1172
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, const Color **ppColor, bool bUseStarFormat=false)
SwRootFrame * getRootFrame()
Definition: frame.hxx:659
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_CJK_LANGUAGE(24)
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2739
bool IsViewLocked() const
Definition: viewsh.hxx:461
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:30
bool GetResolved() const
Definition: docufld.cxx:1774
SwFrame * GetFrameOfModify(const SwRootFrame *pLayout, SwModify const &, SwFrameType const nFrameType, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr)
bool GotoRefMark(const OUString &rRefMark, sal_uInt16 nSubType, sal_uInt16 nSeqNo)
jump to reference marker
Definition: crstrvl.cxx:1215
void RestoreSavePos()
Restore cursor state to the one saved by SwCursorSaveState.
Definition: swcrsr.cxx:2303
const SwFormatINetFormat & GetINetFormat() const
Definition: txatbase.hxx:224
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:844
SwRowFrame is one table row in the document layout.
Definition: rowfrm.hxx:28
bool IsHeaderFrame() const
Definition: frame.hxx:1168
bool IsInHeadline(const SwFrame &rFrame) const
Definition: tabfrm.cxx:5442
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1077
SwFrame * GetNext()
Definition: frame.hxx:656
Base class of the Writer document model elements.
Definition: node.hxx:79
tools::Long getRowSpan() const
Definition: swtable.cxx:100
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo
static OUString decode(OUString const &rText, DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)