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