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