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