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