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