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>
30#include <tools/multisel.hxx>
32#include <editeng/lrspitem.hxx>
33#include <editeng/langitem.hxx>
34#include <tools/urlobj.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
88using namespace ::com::sun::star;
89
90// Some static data structures
91
97
99
100#if OSL_DEBUG_LEVEL > 1
101
102static 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
129namespace
130{
131// ODF Style Names:
132const char aTableHeadingName[] = "Table Heading";
133const char aQuotations[] = "Quotations";
134const char aCaption[] = "Caption";
135const char aHeading[] = "Heading";
136const char aQuotation[] = "Quotation";
137const char aSourceText[] = "Source Text";
138
139// PDF Tag Names:
140constexpr OUStringLiteral aDocumentString = u"Document";
141constexpr OUStringLiteral aDivString = u"Div";
142constexpr OUStringLiteral aSectString = u"Sect";
143constexpr OUStringLiteral aHString = u"H";
144constexpr OUStringLiteral aH1String = u"H1";
145constexpr OUStringLiteral aH2String = u"H2";
146constexpr OUStringLiteral aH3String = u"H3";
147constexpr OUStringLiteral aH4String = u"H4";
148constexpr OUStringLiteral aH5String = u"H5";
149constexpr OUStringLiteral aH6String = u"H6";
150constexpr OUStringLiteral aListString = u"L";
151constexpr OUStringLiteral aListItemString = u"LI";
152constexpr OUStringLiteral aListBodyString = u"LBody";
153constexpr OUStringLiteral aBlockQuoteString = u"BlockQuote";
154constexpr OUStringLiteral aCaptionString = u"Caption";
155constexpr OUStringLiteral aIndexString = u"Index";
156constexpr OUStringLiteral aTOCString = u"TOC";
157constexpr OUStringLiteral aTOCIString = u"TOCI";
158constexpr OUStringLiteral aTableString = u"Table";
159constexpr OUStringLiteral aTRString = u"TR";
160constexpr OUStringLiteral aTDString = u"TD";
161constexpr OUStringLiteral aTHString = u"TH";
162constexpr OUStringLiteral aBibEntryString = u"BibEntry";
163constexpr OUStringLiteral aQuoteString = u"Quote";
164constexpr OUStringLiteral aSpanString = u"Span";
165constexpr OUStringLiteral aCodeString = u"Code";
166constexpr OUStringLiteral aFigureString = u"Figure";
167constexpr OUStringLiteral aFormulaString = u"Formula";
168constexpr OUStringLiteral aLinkString = u"Link";
169constexpr OUStringLiteral aNoteString = u"Note";
170
171// returns true if first paragraph in cell frame has 'table heading' style
172bool 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:
191bool 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:
212void* 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
236bool 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
269bool 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
421void 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
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
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
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 {
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:
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 {
746 bActualText = true;
747 else
748 {
749 bBaselineShift =
750 bTextDecorationType =
751 bLanguage = true;
752 }
753 break;
754
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.Contains(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
999
1000 // Header, Footer: NonStructElement
1001
1003 break;
1004
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
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
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:
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 )
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
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 :
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
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{
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
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
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 ) &&
1628 {
1629 // Select the hyperlink:
1630 mrSh.SwCursorShell::Right( 1, SwCursorSkipMode::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(
1636 p->rINetAttr.GetINetFormat().GetValue(),
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 bool bHeaderFooter = pDoc->IsInHeaderFooter( *pTNd );
1686
1687 // Create links for all selected rectangles:
1688 const size_t nNumOfRects = aTmp.size();
1689 for ( size_t i = 0; i < nNumOfRects; ++i )
1690 {
1691 // Link Rectangle
1692 const SwRect& rLinkRect( aTmp[ i ] );
1693
1694 // Link PageNums
1695 std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( rLinkRect );
1696
1697 for (sal_Int32 aLinkPageNum : aLinkPageNums)
1698 {
1699 // Link Export
1700 tools::Rectangle aRect(SwRectToPDFRect(pSelectionPage, rLinkRect.SVRect()));
1701 const sal_Int32 nLinkId =
1702 pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
1703
1704 // Store link info for tagged pdf output:
1705 const IdMapEntry aLinkEntry( rLinkRect, nLinkId );
1706 s_aLinkIdMap.push_back( aLinkEntry );
1707
1708 // Connect Link and Destination:
1709 if ( bIntern )
1710 pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
1711 else
1712 pPDFExtOutDevData->SetLinkURL( nLinkId, aURL );
1713
1714 // #i44368# Links in Header/Footer
1715 if ( bHeaderFooter )
1716 MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, aURL, bIntern );
1717 }
1718 }
1719 }
1720 }
1721 }
1722 mrSh.SwCursorShell::ClearMark();
1723 }
1724
1725 // HYPERLINKS (Graphics, Frames, OLEs )
1726
1727 SwFrameFormats* pTable = pDoc->GetSpzFrameFormats();
1728 const size_t nSpzFrameFormatsCount = pTable->size();
1729 for( size_t n = 0; n < nSpzFrameFormatsCount; ++n )
1730 {
1731 SwFrameFormat* pFrameFormat = (*pTable)[n];
1732 const SwFormatURL* pItem;
1733 if ( RES_DRAWFRMFMT != pFrameFormat->Which() &&
1734 GetFrameOfModify(mrSh.GetLayout(), *pFrameFormat, SwFrameType::Fly) &&
1735 (pItem = pFrameFormat->GetAttrSet().GetItemIfSet( RES_URL )) )
1736 {
1737 const SwPageFrame* pCurrPage =
1738 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1739
1740 OUString aURL( pItem->GetURL() );
1741 if (aURL.isEmpty())
1742 continue;
1743 const bool bIntern = '#' == aURL[0];
1744
1745 // Create the destination for internal links:
1746 sal_Int32 nDestId = -1;
1747 if ( bIntern )
1748 {
1749 aURL = aURL.copy( 1 );
1750 mrSh.SwCursorShell::ClearMark();
1751 if (! JumpToSwMark( &mrSh, aURL ))
1752 {
1753 continue; // target deleted
1754 }
1755
1756 // Destination Rectangle
1757 const SwRect& rDestRect = mrSh.GetCharRect();
1758
1759 pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1760
1761 // Destination PageNum
1762 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
1763
1764 // Destination Export
1765 if ( -1 != nDestPageNum )
1766 {
1767 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
1768 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
1769 }
1770 }
1771
1772 if ( !bIntern || -1 != nDestId )
1773 {
1774 Point aNullPt;
1775 const SwRect aLinkRect = pFrameFormat->FindLayoutRect( false, &aNullPt );
1776
1777 // Link PageNums
1778 std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( aLinkRect );
1779
1780 // Link Export
1781 for (sal_Int32 aLinkPageNum : aLinkPageNums)
1782 {
1783 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, aLinkRect.SVRect()));
1784 const sal_Int32 nLinkId =
1785 pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
1786
1787 // Connect Link and Destination:
1788 if ( bIntern )
1789 pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
1790 else
1791 pPDFExtOutDevData->SetLinkURL( nLinkId, aURL );
1792
1793 // #i44368# Links in Header/Footer
1794 const SwFormatAnchor &rAnch = pFrameFormat->GetAnchor();
1795 if (RndStdIds::FLY_AT_PAGE != rAnch.GetAnchorId())
1796 {
1797 const SwPosition* pPosition = rAnch.GetContentAnchor();
1798 if ( pPosition && pDoc->IsInHeaderFooter( pPosition->GetNode() ) )
1799 {
1800 const SwTextNode* pTNd = pPosition->GetNode().GetTextNode();
1801 if ( pTNd )
1802 MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, aLinkRect, nDestId, aURL, bIntern );
1803 }
1804 }
1805 }
1806 }
1807 }
1808 else if (pFrameFormat->Which() == RES_DRAWFRMFMT)
1809 {
1810 // Turn media shapes into Screen annotations.
1811 if (SdrObject* pObject = pFrameFormat->FindRealSdrObject())
1812 {
1813 SwRect aSnapRect(pObject->GetSnapRect());
1814 std::vector<sal_Int32> aScreenPageNums = CalcOutputPageNums(aSnapRect);
1815 if (aScreenPageNums.empty())
1816 continue;
1817
1818 uno::Reference<drawing::XShape> xShape(pObject->getUnoShape(), uno::UNO_QUERY);
1819 if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape")
1820 {
1821 uno::Reference<beans::XPropertySet> xShapePropSet(xShape, uno::UNO_QUERY);
1822 OUString aMediaURL;
1823 xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
1824 if (!aMediaURL.isEmpty())
1825 {
1826 const SwPageFrame* pCurrPage = mrSh.GetLayout()->GetPageAtPos(aSnapRect.Center());
1827 tools::Rectangle aPDFRect(SwRectToPDFRect(pCurrPage, aSnapRect.SVRect()));
1828 for (sal_Int32 nScreenPageNum : aScreenPageNums)
1829 {
1830 sal_Int32 nScreenId = pPDFExtOutDevData->CreateScreen(aPDFRect, nScreenPageNum);
1831 if (aMediaURL.startsWith("vnd.sun.star.Package:"))
1832 {
1833 // Embedded media.
1834 OUString aTempFileURL;
1835 xShapePropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL;
1836 pPDFExtOutDevData->SetScreenStream(nScreenId, aTempFileURL);
1837 }
1838 else
1839 // Linked media.
1840 pPDFExtOutDevData->SetScreenURL(nScreenId, aMediaURL);
1841 }
1842 }
1843 }
1844 }
1845 }
1846 mrSh.SwCursorShell::ClearMark();
1847 }
1848
1849 // REFERENCES
1850
1851 std::vector<SwFormatField*> vpFields;
1852 mrSh.GetFieldType( SwFieldIds::GetRef, OUString() )->GatherFields(vpFields);
1853 for(auto pFormatField : vpFields )
1854 {
1855 if( pFormatField->GetTextField() && pFormatField->IsFieldInDoc() )
1856 {
1857 const SwTextNode* pTNd = pFormatField->GetTextField()->GetpTextNode();
1858 OSL_ENSURE( nullptr != pTNd, "Enhanced pdf export - text node is missing" );
1859 if(!lcl_TryMoveToNonHiddenField(mrSh, *pTNd, *pFormatField))
1860 continue;
1861 // Select the field:
1862 mrSh.SwCursorShell::SetMark();
1863 mrSh.SwCursorShell::Right( 1, SwCursorSkipMode::Chars );
1864
1865 // Link Rectangles
1866 SwRects aTmp;
1867 aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() );
1868 OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
1869
1870 mrSh.SwCursorShell::ClearMark();
1871
1872 // Destination Rectangle
1873 const SwGetRefField* pField = static_cast<SwGetRefField*>(pFormatField->GetField());
1874 const OUString& rRefName = pField->GetSetRefName();
1875 mrSh.GotoRefMark( rRefName, pField->GetSubType(), pField->GetSeqNo() );
1876 const SwRect& rDestRect = mrSh.GetCharRect();
1877
1878 const SwPageFrame* pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1879
1880 // Destination PageNum
1881 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
1882
1883 if ( -1 != nDestPageNum )
1884 {
1885 // Destination Export
1886 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
1887 const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
1888
1889 // #i44368# Links in Header/Footer
1890 const bool bHeaderFooter = pDoc->IsInHeaderFooter( *pTNd );
1891
1892 // Create links for all selected rectangles:
1893 const size_t nNumOfRects = aTmp.size();
1894 for ( size_t i = 0; i < nNumOfRects; ++i )
1895 {
1896 // Link rectangle
1897 const SwRect& rLinkRect( aTmp[ i ] );
1898
1899 // Link PageNums
1900 std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( rLinkRect );
1901
1902 for (sal_Int32 aLinkPageNum : aLinkPageNums)
1903 {
1904 // Link Export
1905 aRect = SwRectToPDFRect(pCurrPage, rLinkRect.SVRect());
1906 const sal_Int32 nLinkId =
1907 pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
1908
1909 // Store link info for tagged pdf output:
1910 const IdMapEntry aLinkEntry( rLinkRect, nLinkId );
1911 s_aLinkIdMap.push_back( aLinkEntry );
1912
1913 // Connect Link and Destination:
1914 pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
1915
1916 // #i44368# Links in Header/Footer
1917 if ( bHeaderFooter )
1918 {
1919 MakeHeaderFooterLinks( *pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, "", true );
1920 }
1921 }
1922 }
1923 }
1924 }
1925 mrSh.SwCursorShell::ClearMark();
1926 }
1927
1929
1930 // FOOTNOTES
1931
1932 const size_t nFootnoteCount = pDoc->GetFootnoteIdxs().size();
1933 for ( size_t nIdx = 0; nIdx < nFootnoteCount; ++nIdx )
1934 {
1935 // Set cursor to text node that contains the footnote:
1936 const SwTextFootnote* pTextFootnote = pDoc->GetFootnoteIdxs()[ nIdx ];
1937 SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
1938
1939 mrSh.GetCursor_()->GetPoint()->Assign(rTNd, pTextFootnote->GetStart());
1940
1941 // 1. Check if the whole paragraph is hidden
1942 // 2. Check for hidden text attribute
1943 if (rTNd.GetTextNode()->IsHidden() || mrSh.SelectHiddenRange()
1945 && sw::IsFootnoteDeleted(pDoc->getIDocumentRedlineAccess(), *pTextFootnote)))
1946 {
1947 continue;
1948 }
1949
1950 SwCursorSaveState aSaveState( *mrSh.GetCursor_() );
1951
1952 // Select the footnote:
1953 mrSh.SwCursorShell::SetMark();
1954 mrSh.SwCursorShell::Right( 1, SwCursorSkipMode::Chars );
1955
1956 // Link Rectangle
1957 SwRects aTmp;
1958 aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() );
1959 OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
1960
1962 mrSh.SwCursorShell::ClearMark();
1963
1964 if (aTmp.empty())
1965 continue;
1966
1967 const SwRect aLinkRect( aTmp[ 0 ] );
1968
1969 // Goto footnote text:
1970 if ( mrSh.GotoFootnoteText() )
1971 {
1972 // Destination Rectangle
1973 const SwRect& rDestRect = mrSh.GetCharRect();
1974 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
1975 if ( -1 != nDestPageNum )
1976 {
1977 const SwPageFrame* pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1978 // Destination PageNum
1979 tools::Rectangle aRect = SwRectToPDFRect(pCurrPage, rDestRect.SVRect());
1980 // Back link rectangle calculation
1981 const SwPageFrame* fnBodyPage = pCurrPage->getRootFrame()->GetPageByPageNum(nDestPageNum+1);
1982 SwRect fnSymbolRect;
1983 if (fnBodyPage->IsVertical()){
1984 tools::Long fnSymbolTop = fnBodyPage->GetTopMargin() + fnBodyPage->getFrameArea().Top();
1985 tools::Long symbolHeight = rDestRect.Top() - fnSymbolTop;
1986 fnSymbolRect = SwRect(rDestRect.Pos().X(),fnSymbolTop,rDestRect.Width(),symbolHeight);
1987 } else {
1988 if (fnBodyPage->IsRightToLeft()){
1989 tools::Long fnSymbolRight = fnBodyPage->getFrameArea().Right() - fnBodyPage->GetRightMargin();
1990 tools::Long symbolWidth = fnSymbolRight - rDestRect.Right();
1991 fnSymbolRect = SwRect(rDestRect.Pos().X(),rDestRect.Pos().Y(),symbolWidth,rDestRect.Height());
1992 } else {
1993 tools::Long fnSymbolLeft = fnBodyPage->GetLeftMargin() + fnBodyPage->getFrameArea().Left();
1994 tools::Long symbolWidth = rDestRect.Left() - fnSymbolLeft;
1995 fnSymbolRect = SwRect(fnSymbolLeft,rDestRect.Pos().Y(),symbolWidth,rDestRect.Height());
1996 }
1997 }
1998 tools::Rectangle aFootnoteSymbolRect = SwRectToPDFRect(pCurrPage, fnSymbolRect.SVRect());
1999
2000 // Export back link
2001 const sal_Int32 nBackLinkId = pPDFExtOutDevData->CreateLink(aFootnoteSymbolRect, nDestPageNum);
2002 // Destination Export
2003 const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2005 // Link PageNums
2006 sal_Int32 aLinkPageNum = CalcOutputPageNum( aLinkRect );
2007 pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2008 // Link Export
2009 aRect = SwRectToPDFRect(pCurrPage, aLinkRect.SVRect());
2010 const sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, aLinkPageNum);
2011 // Back link destination Export
2012 const sal_Int32 nBackDestId = pPDFExtOutDevData->CreateDest(aRect, aLinkPageNum);
2013 // Store link info for tagged pdf output:
2014 const IdMapEntry aLinkEntry( aLinkRect, nLinkId );
2015 s_aLinkIdMap.push_back( aLinkEntry );
2016
2017 // Store backlink info for tagged pdf output:
2018 const IdMapEntry aBackLinkEntry( aFootnoteSymbolRect, nBackLinkId );
2019 s_aLinkIdMap.push_back( aBackLinkEntry );
2020 // Connect Links and Destinations:
2021 pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
2022 pPDFExtOutDevData->SetLinkDest( nBackLinkId, nBackDestId );
2023 }
2024 }
2025 }
2026
2027 // OUTLINE
2028
2029 if( pPDFExtOutDevData->GetIsExportBookmarks() )
2030 {
2031 typedef std::pair< sal_Int8, sal_Int32 > StackEntry;
2032 std::stack< StackEntry > aOutlineStack;
2033 aOutlineStack.push( StackEntry( -1, -1 ) ); // push default value
2034
2035 const SwOutlineNodes::size_type nOutlineCount =
2037 for ( SwOutlineNodes::size_type i = 0; i < nOutlineCount; ++i )
2038 {
2039 // Check if outline is hidden
2040 const SwTextNode* pTNd = mrSh.GetNodes().GetOutLineNds()[ i ]->GetTextNode();
2041 OSL_ENSURE( nullptr != pTNd, "Enhanced pdf export - text node is missing" );
2042
2043 if ( pTNd->IsHidden() ||
2044 !sw::IsParaPropsNode(*mrSh.GetLayout(), *pTNd) ||
2045 // #i40292# Skip empty outlines:
2046 pTNd->GetText().isEmpty())
2047 continue;
2048
2049 // Get parent id from stack:
2050 const sal_Int8 nLevel = static_cast<sal_Int8>(mrSh.getIDocumentOutlineNodesAccess()->getOutlineLevel( i ));
2051 sal_Int8 nLevelOnTopOfStack = aOutlineStack.top().first;
2052 while ( nLevelOnTopOfStack >= nLevel &&
2053 nLevelOnTopOfStack != -1 )
2054 {
2055 aOutlineStack.pop();
2056 nLevelOnTopOfStack = aOutlineStack.top().first;
2057 }
2058 const sal_Int32 nParent = aOutlineStack.top().second;
2059
2060 // Destination rectangle
2062 const SwRect& rDestRect = mrSh.GetCharRect();
2063
2064 const SwPageFrame* pCurrPage =
2065 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2066
2067 // Destination PageNum
2068 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2069
2070 if ( -1 != nDestPageNum )
2071 {
2072 // Destination Export
2073 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2074 const sal_Int32 nDestId =
2075 pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2076
2077 // Outline entry text
2078 const OUString& rEntry = mrSh.getIDocumentOutlineNodesAccess()->getOutlineText(
2079 i, mrSh.GetLayout(), true, false, false );
2080
2081 // Create a new outline item:
2082 const sal_Int32 nOutlineId =
2083 pPDFExtOutDevData->CreateOutlineItem( nParent, rEntry, nDestId );
2084
2085 // Push current level and nOutlineId on stack:
2086 aOutlineStack.push( StackEntry( nLevel, nOutlineId ) );
2087 }
2088 }
2089 }
2090
2091 if( pPDFExtOutDevData->GetIsExportNamedDestinations() )
2092 {
2093 // #i56629# the iteration to convert the OOo bookmark (#bookmark)
2094 // into PDF named destination, see section 8.2.1 in PDF 1.4 spec
2095 // We need:
2096 // 1. a name for the destination, formed from the standard OOo bookmark name
2097 // 2. the destination, obtained from where the bookmark destination lies
2098 IDocumentMarkAccess* const pMarkAccess = mrSh.GetDoc()->getIDocumentMarkAccess();
2099 for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
2100 ppMark != pMarkAccess->getBookmarksEnd();
2101 ++ppMark)
2102 {
2103 //get the name
2104 const ::sw::mark::IMark* pBkmk = *ppMark;
2105 mrSh.SwCursorShell::ClearMark();
2106 const OUString& sBkName = pBkmk->GetName();
2107
2108 //jump to it
2109 if (! JumpToSwMark( &mrSh, sBkName ))
2110 {
2111 continue;
2112 }
2113
2114 // Destination Rectangle
2115 const SwRect& rDestRect = mrSh.GetCharRect();
2116
2117 const SwPageFrame* pCurrPage =
2118 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2119
2120 // Destination PageNum
2121 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2122
2123 // Destination Export
2124 if ( -1 != nDestPageNum )
2125 {
2126 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2127 pPDFExtOutDevData->CreateNamedDest(sBkName, aRect, nDestPageNum);
2128 }
2129 }
2130 mrSh.SwCursorShell::ClearMark();
2131 //<--- i56629
2132 }
2133 }
2134 else
2135 {
2136
2137 // LINKS FROM EDITENGINE
2138
2139 std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
2140 for ( const auto& rBookmark : rBookmarks )
2141 {
2142 OUString aBookmarkName( rBookmark.aBookmark );
2143 const bool bIntern = '#' == aBookmarkName[0];
2144 if ( bIntern )
2145 {
2146 aBookmarkName = aBookmarkName.copy( 1 );
2147 JumpToSwMark( &mrSh, aBookmarkName );
2148
2149 // Destination Rectangle
2150 const SwRect& rDestRect = mrSh.GetCharRect();
2151
2152 const SwPageFrame* pCurrPage =
2153 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2154
2155 // Destination PageNum
2156 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2157
2158 if ( -1 != nDestPageNum )
2159 {
2160 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2161 if ( rBookmark.nLinkId != -1 )
2162 {
2163 // Destination Export
2164 const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2165
2166 // Connect Link and Destination:
2167 pPDFExtOutDevData->SetLinkDest( rBookmark.nLinkId, nDestId );
2168 }
2169 else
2170 {
2171 pPDFExtOutDevData->DescribeRegisteredDest(rBookmark.nDestId, aRect, nDestPageNum);
2172 }
2173 }
2174 }
2175 else
2176 pPDFExtOutDevData->SetLinkURL( rBookmark.nLinkId, aBookmarkName );
2177 }
2178 rBookmarks.clear();
2179 }
2180
2181 // Restore view, cursor, and outdev:
2182 mrSh.LockView( bOldLockView );
2183 mrSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent);
2184 mrOut.Pop();
2185}
2186
2188{
2189 auto pPDFExtOutDevData = dynamic_cast<vcl::PDFExtOutDevData*>(mrOut.GetExtOutDevData());
2190 if (!pPDFExtOutDevData)
2191 {
2192 return;
2193 }
2194
2195 std::vector<SwFormatField*> aFields;
2197 if (!pType)
2198 {
2199 return;
2200 }
2201
2202 pType->GatherFields(aFields);
2203 const auto pPageFrame = static_cast<const SwPageFrame*>(mrSh.GetLayout()->Lower());
2204 for (const auto pFormatField : aFields)
2205 {
2206 if (!pFormatField->GetTextField() || !pFormatField->IsFieldInDoc())
2207 {
2208 continue;
2209 }
2210
2211 const auto& rAuthorityField
2212 = *static_cast<const SwAuthorityField*>(pFormatField->GetField());
2213 if (!rAuthorityField.HasURL())
2214 {
2215 continue;
2216 }
2217
2218 const OUString& rURL = rAuthorityField.GetAuthEntry()->GetAuthorField(AUTH_FIELD_URL);
2219 const SwTextNode& rTextNode = pFormatField->GetTextField()->GetTextNode();
2220 if (!lcl_TryMoveToNonHiddenField(mrSh, rTextNode, *pFormatField))
2221 {
2222 continue;
2223 }
2224
2225 // Select the field.
2226 mrSh.SwCursorShell::SetMark();
2227 mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars);
2228
2229 // Create the links.
2230 for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_())
2231 {
2232 for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
2233 {
2234 tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, rLinkRect.SVRect()));
2235 sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, rLinkPageNum);
2236 IdMapEntry aLinkEntry(rLinkRect, nLinkId);
2237 s_aLinkIdMap.push_back(aLinkEntry);
2238 pPDFExtOutDevData->SetLinkURL(nLinkId, rURL);
2239 }
2240 }
2241
2242 mrSh.SwCursorShell::ClearMark();
2243 }
2244}
2245
2246// Returns the page number in the output pdf on which the given rect is located.
2247// If this page is duplicated, method will return first occurrence of it.
2249{
2250 std::vector< sal_Int32 > aPageNums = CalcOutputPageNums( rRect );
2251 if ( !aPageNums.empty() )
2252 return aPageNums[0];
2253 return -1;
2254}
2255
2256// Returns a vector of the page numbers in the output pdf on which the given
2257// rect is located. There can be many such pages since StringRangeEnumerator
2258// allows duplication of its entries.
2260 const SwRect& rRect ) const
2261{
2262 std::vector< sal_Int32 > aPageNums;
2263
2264 // Document page number.
2265 sal_Int32 nPageNumOfRect = mrSh.GetPageNumAndSetOffsetForPDF( mrOut, rRect );
2266 if ( nPageNumOfRect < 0 )
2267 return aPageNums;
2268
2269 // What will be the page numbers of page nPageNumOfRect in the output pdf?
2270 if ( mpRangeEnum )
2271 {
2272 if ( mbSkipEmptyPages )
2273 // Map the page number to the range without empty pages.
2274 nPageNumOfRect = maPageNumberMap[ nPageNumOfRect ];
2275
2276 if ( mpRangeEnum->hasValue( nPageNumOfRect ) )
2277 {
2278 sal_Int32 nOutputPageNum = 0;
2281 for ( ; aIter != aEnd; ++aIter )
2282 {
2283 if ( *aIter == nPageNumOfRect )
2284 aPageNums.push_back( nOutputPageNum );
2285 ++nOutputPageNum;
2286 }
2287 }
2288 }
2289 else
2290 {
2291 if ( mbSkipEmptyPages )
2292 {
2293 sal_Int32 nOutputPageNum = 0;
2294 for ( size_t i = 0; i < maPageNumberMap.size(); ++i )
2295 {
2296 if ( maPageNumberMap[i] >= 0 ) // is not empty?
2297 {
2298 if ( i == static_cast<size_t>( nPageNumOfRect ) )
2299 {
2300 aPageNums.push_back( nOutputPageNum );
2301 break;
2302 }
2303 ++nOutputPageNum;
2304 }
2305 }
2306 }
2307 else
2308 aPageNums.push_back( nPageNumOfRect );
2309 }
2310
2311 return aPageNums;
2312}
2313
2315 const SwTextNode& rTNd,
2316 const SwRect& rLinkRect,
2317 sal_Int32 nDestId,
2318 const OUString& rURL,
2319 bool bIntern ) const
2320{
2321 // We assume, that the primary link has just been exported. Therefore
2322 // the offset of the link rectangle calculates as follows:
2323 const Point aOffset = rLinkRect.Pos() + mrOut.GetMapMode().GetOrigin();
2324
2326 for ( SwTextFrame* pTmpFrame = aIter.First(); pTmpFrame; pTmpFrame = aIter.Next() )
2327 {
2328 // Add offset to current page:
2329 const SwPageFrame* pPageFrame = pTmpFrame->FindPageFrame();
2330 SwRect aHFLinkRect( rLinkRect );
2331 aHFLinkRect.Pos() = pPageFrame->getFrameArea().Pos() + aOffset;
2332
2333 // #i97135# the gcc_x64 optimizer gets aHFLinkRect != rLinkRect wrong
2334 // fool it by comparing the position only (the width and height are the
2335 // same anyway)
2336 if ( aHFLinkRect.Pos() != rLinkRect.Pos() )
2337 {
2338 // Link PageNums
2339 std::vector<sal_Int32> aHFLinkPageNums = CalcOutputPageNums( aHFLinkRect );
2340
2341 for (sal_Int32 aHFLinkPageNum : aHFLinkPageNums)
2342 {
2343 // Link Export
2344 tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, aHFLinkRect.SVRect()));
2345 const sal_Int32 nHFLinkId =
2346 rPDFExtOutDevData.CreateLink(aRect, aHFLinkPageNum);
2347
2348 // Connect Link and Destination:
2349 if ( bIntern )
2350 rPDFExtOutDevData.SetLinkDest( nHFLinkId, nDestId );
2351 else
2352 rPDFExtOutDevData.SetLinkURL( nHFLinkId, rURL );
2353 }
2354 }
2355 }
2356}
2357
2358/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void lcl_DBGCheckStack()
static std::vector< sal_uInt16 > aStructStack
std::set< tools::Long, lt_TableColumn > TableColumnsMapEntry
std::map< const SwNumberTreeNode *, sal_Int32 > NumListIdMap
std::map< const SwNumberTreeNode *, sal_Int32 > NumListBodyIdMap
std::vector< IdMapEntry > LinkIdMap
std::map< const void *, sal_Int32 > FrameTagIdMap
std::map< const SwTable *, TableColumnsMapEntry > TableColumnsMap
std::pair< SwRect, sal_Int32 > IdMapEntry
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...
sal_Int32 GetDate() const
wrapper iterator: wraps iterator of implementation while hiding MarkBase class; only IMark instances ...
Provides access to the marks of a document.
virtual const_iterator_t getBookmarksBegin() const =0
returns a STL-like random access iterator to the begin of the sequence the IBookmarks.
virtual const_iterator_t getBookmarksEnd() const =0
returns a STL-like random access iterator to the end of the sequence of IBookmarks.
virtual tSortedOutlineNodeList::size_type getOutlineNodesCount() const =0
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
virtual int getOutlineLevel(const tSortedOutlineNodeList::size_type nIdx) const =0
static OUString decode(std::u16string_view rText, DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
void SetMapUnit(MapUnit eUnit)
const Point & GetOrigin() const
vcl::ExtOutDevData * GetExtOutDevData() const
void SetMapMode()
const MapMode & GetMapMode() const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
static sal_uInt16 IsMath(const SvGlobalName &rName)
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, const Color **ppColor, bool bUseStarFormat=false)
const Date & GetNullDate() const
SvxAdjust GetAdjust() const
short GetTextFirstLineOffset() const
SwTextAttr * GetAttr(TextFrameIndex nPos) const
Returns the attribute for a position.
Definition: itratr.cxx:143
const SvxAdjustItem & GetAdjust(bool=true) const
Definition: paratr.hxx:194
OUString const & GetAuthorField(ToxAuthorityField ePos) const
Definition: authfld.hxx:195
invariant for SwAuthorityField is that it is always registered at its SwAuthorityFieldType via AddFie...
Definition: authfld.hxx:155
SwAuthEntry * GetAuthEntry() const
Definition: authfld.hxx:182
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:31
const SwTableBox * GetTabBox() const
Definition: cellfrm.hxx:52
Represents the style of a text portion.
Definition: charfmt.hxx:27
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:58
SwFormatColl * GetFormatColl() const
Definition: node.hxx:476
A helper class to save cursor state (position).
Definition: swcrsr.hxx:233
bool GotoRefMark(const OUString &rRefMark, sal_uInt16 nSubType, sal_uInt16 nSeqNo)
jump to reference marker
Definition: crstrvl.cxx:1272
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:336
const SwRect & GetCharRect() const
Definition: crsrsh.hxx:525
bool GotoFootnoteAnchor()
jump from footnote to anchor
Definition: trvlfnfl.cxx:167
bool GotoFootnoteText()
jump from content to footnote
Definition: trvlfnfl.cxx:89
bool GotoOutline(const OUString &rName)
Definition: crstrvl.cxx:1041
bool GotoFormatField(const SwFormatField &rField)
Definition: crstrvl.cxx:870
bool GotoINetAttr(const SwTextINetFormat &rAttr)
Definition: crstrvl.cxx:2126
bool SelectHiddenRange()
If the current cursor position is inside a hidden range, the hidden range is selected.
Definition: crsrsh.cxx:3460
void RestoreSavePos()
Restore cursor state to the one saved by SwCursorSaveState.
Definition: swcrsr.cxx:2333
Definition: doc.hxx:192
SwNodes & GetNodes()
Definition: doc.hxx:413
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:336
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:638
const SfxPoolItem & GetDefault(sal_uInt16 nFormatHint) const
Get the default attribute in this document.
Definition: docfmt.cxx:663
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1793
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:748
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1414
bool IsInHeaderFooter(const SwNode &) const
Definition: doclay.cxx:1550
void GetINetAttrs(SwGetINetAttrs &rArr, bool bIncludeInToxContent=true)
Definition: editsh.cxx:688
SwFieldType * GetFieldType(size_t nField, SwFieldIds nResId=SwFieldIds::Unknown) const
get field types with a ResId, if 0 get all
Definition: edfld.cxx:64
static TableColumnsMap & GetTableColumnsMap()
static NumListBodyIdMap & GetNumListBodyIdMap()
sal_Int32 CalcOutputPageNum(const SwRect &rRect) const
static FrameTagIdMap & GetFrameTagIdMap()
SwEnhancedPDFExportHelper(SwEditShell &rSh, OutputDevice &rOut, const OUString &rPageRange, bool bSkipEmptyPages, bool bEditEngineOnly, const SwPrintData &rPrintData)
static TableColumnsMap s_aTableColumnsMap
static LanguageType GetDefaultLanguage()
static NumListBodyIdMap s_aNumListBodyIdMap
static NumListIdMap & GetNumListIdMap()
std::vector< sal_Int32 > CalcOutputPageNums(const SwRect &rRect) const
void ExportAuthorityEntryLinks()
Exports bibliography entry links.
void MakeHeaderFooterLinks(vcl::PDFExtOutDevData &rPDFExtOutDevData, const SwTextNode &rTNd, const SwRect &rLinkRect, sal_Int32 nDestId, const OUString &rURL, bool bIntern) const
std::vector< sal_Int32 > maPageNumberMap
The problem is that numbers in StringRangeEnumerator aren't accordant to real page numbers if mbSkipE...
tools::Rectangle SwRectToPDFRect(const SwPageFrame *pCurrPage, const tools::Rectangle &rRectangle) const
std::unique_ptr< StringRangeEnumerator > mpRangeEnum
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:242
void GatherFields(std::vector< SwFormatField * > &rvFormatFields, bool bCollectOnlyInDocNodes=true) const
Definition: fldbas.cxx:203
Base class of all fields.
Definition: fldbas.hxx:292
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:250
LanguageType GetLanguage() const
Language at field position.
Definition: fldbas.hxx:408
bool HasFollow() const
Definition: flowfrm.hxx:166
bool IsFollow() const
Definition: flowfrm.hxx:167
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2709
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
FontLineStyle GetUnderline() const
Definition: swfont.hxx:272
short GetEscapement() const
Definition: swfont.hxx:279
FontStrikeout GetStrikeout() const
Definition: swfont.hxx:276
FontEmphasisMark GetEmphasisMark() const
Definition: swfont.hxx:286
SwFontScript GetActual() const
Definition: swfont.hxx:184
FontLineStyle GetOverline() const
Definition: swfont.hxx:274
LanguageType GetLanguage() const
Definition: swfont.hxx:283
FlyAnchors.
Definition: fmtanchr.hxx:37
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:69
const SwField * GetField() const
Definition: fmtfld.hxx:130
const OUString & GetURL() const
Definition: fmturl.hxx:66
Base class for various Writer styles.
Definition: format.hxx:47
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
const OUString & GetName() const
Definition: format.hxx:131
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:83
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
SwFormat * DerivedFrom() const
Definition: format.hxx:128
const SwRect & getFrameArea() const
Definition: frame.hxx:179
Style of a layout element.
Definition: frmfmt.hxx:62
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2718
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2771
Specific frame formats (frames, DrawObjects).
size_t size() const
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool IsRowFrame() const
Definition: frame.hxx:1222
bool IsCellFrame() const
Definition: frame.hxx:1226
bool IsTextFrame() const
Definition: frame.hxx:1234
tools::Long GetLeftMargin() const
Definition: ssfrm.cxx:47
tools::Long GetRightMargin() const
Definition: ssfrm.cxx:49
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1115
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1099
SwFrame * GetNext()
Definition: frame.hxx:676
bool IsPageFrame() const
Definition: frame.hxx:1178
bool IsTabFrame() const
Definition: frame.hxx:1218
SwFrameType GetType() const
Definition: frame.hxx:519
bool IsHeaderFrame() const
Definition: frame.hxx:1190
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:564
bool IsInTab() const
Definition: frame.hxx:955
SwFrame * GetLower()
Definition: findfrm.cxx:194
bool IsRightToLeft() const
Definition: frame.hxx:987
const SwRowFrame * IsInFollowFlowRow() const
Definition: findfrm.cxx:1842
bool IsFlowFrame() const
Definition: frame.hxx:1242
SwLayoutFrame * GetNextCellLeaf()
Definition: findfrm.cxx:1579
bool IsFooterFrame() const
Definition: frame.hxx:1194
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
bool IsVertical() const
Definition: frame.hxx:973
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
bool IsNoTextFrame() const
Definition: frame.hxx:1238
bool IsFlyFrame() const
Definition: frame.hxx:1210
SwFrame * GetPrev()
Definition: frame.hxx:677
bool IsSctFrame() const
Definition: frame.hxx:1214
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
const SwRowFrame * IsInSplitTableRow() const
Definition: findfrm.cxx:1809
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:602
tools::Long GetTopMargin() const
Definition: ssfrm.cxx:43
SwLayoutFrame * GetPrevCellLeaf()
Definition: findfrm.cxx:1589
bool IsInSct() const
Definition: frame.hxx:967
virtual sal_uInt16 GetSubType() const override
Get/set sub type.
Definition: reffld.cxx:369
const OUString & GetSetRefName() const
Definition: reffld.hxx:109
sal_uInt16 GetSeqNo() const
Get/set SequenceNo (of interest only for REF_SEQUENCEFLD).
Definition: reffld.hxx:134
TElementType * Next()
Definition: calbck.hxx:364
TElementType * First()
Definition: calbck.hxx:356
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:70
const SwFrame * Lower() const
Definition: layfrm.hxx:101
Base class for anything that can be part of a line in the Writer layout.
Definition: porlin.hxx:52
PortionType GetWhichPor() const
Definition: porlin.hxx:102
TextFrameIndex GetLen() const
Definition: porlin.hxx:77
const SwContentNode * GetNode() const
Definition: notxtfrm.hxx:66
Marks a node in the document model.
Definition: ndindex.hxx:31
Base class of the Writer document model elements.
Definition: node.hxx:84
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:876
SwDoc & GetDoc()
Definition: node.hxx:217
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:164
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:240
SwNode * DocumentSectionStartNode(SwNode *pNode) const
Definition: nodes.cxx:2508
A tree of numbered nodes.
virtual bool IsCounted() const
Return if this node is counted.
bool IsFirst(const SwNumberTreeNode *pNode) const
Return if a node is first non-phantom child of this node.
SwNumberTreeNode * GetPred(bool bSibling=false) const
Returns the greatest descendant of the root that is smaller than this node, aka the predecessor of th...
SwNumberTreeNode * GetParent() const
Returns the parent of this node.
const SwOLEObj & GetOLEObj() const
Definition: ndole.hxx:115
css::uno::Reference< css::embed::XEmbeddedObject > const & GetOleRef()
Definition: ndole.cxx:940
const SwPosition * GetPoint() const
Definition: pam.hxx:261
A page of the document layout.
Definition: pagefrm.hxx:58
bool IsEmptyPage() const
Definition: pagefrm.hxx:157
SwTwips Height() const
Definition: possiz.hxx:49
bool GetResolved() const
Definition: docufld.cxx:1782
virtual OUString GetPar1() const override
Author.
Definition: docufld.cxx:1806
const OUString & GetText() const
Definition: docufld.hxx:493
Date GetDate() const
Definition: docufld.hxx:481
SwPostItMode GetPrintPostIts() const
Definition: printdata.hxx:145
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1381
tools::Long GetRightMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1405
tools::Long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1402
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1380
tools::Long GetBottomMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1403
tools::Long GetLeftMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1404
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1378
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1379
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Height(tools::Long nNew)
Definition: swrect.hxx:193
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
void Pos(const Point &rNew)
Definition: swrect.hxx:171
Point Center() const
Definition: swrect.hxx:338
tools::Rectangle SVRect() const
Definition: swrect.hxx:292
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
SwPageFrame * GetPageByPageNum(sal_uInt16 _nPageNum) const
Get page frame by physical page number looping through the lowers, which are page frame,...
Definition: trvlfrm.cxx:1602
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:627
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding).
Definition: rootfrm.hxx:421
SwRowFrame is one table row in the document layout.
Definition: rowfrm.hxx:29
bool IsRepeatedHeadline() const
Definition: rowfrm.hxx:90
const SwTableLine * GetTabLine() const
Definition: rowfrm.hxx:70
SwSection * GetSection()
Definition: sectfrm.hxx:97
const SwTOXBase * GetTOXBase() const
Definition: section.cxx:586
SectionType GetType() const
Definition: section.hxx:171
static void FillProgName(const OUString &rName, OUString &rFillName, SwGetPoolIdFromName)
TOXTypes GetType() const
Definition: tox.hxx:722
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:47
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:773
const SwTabFrame * GetFollow() const
Definition: tabfrm.hxx:250
const SwTable * GetTable() const
Definition: tabfrm.hxx:158
bool IsInHeadline(const SwFrame &rFrame) const
Definition: tabfrm.cxx:5771
sal_Int32 getRowSpan() const
Definition: swtable.hxx:514
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:113
const Frame_Info * mpFrameInfo
void SetAttributes(vcl::PDFWriter::StructElement eType)
static bool IsExportTaggedPDF(const OutputDevice &rOut)
SwTaggedPDFHelper(const Num_Info *pNumInfo, const Frame_Info *pFrameInfo, const Por_Info *pPorInfo, OutputDevice const &rOut)
vcl::PDFExtOutDevData * mpPDFExtOutDevData
void BeginTag(vcl::PDFWriter::StructElement aTagRole, const OUString &rTagName)
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
sal_uInt16 Which() const
Definition: txatbase.hxx:116
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:199
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:70
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1231
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:463
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1303
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:86
bool IsOutline() const
Returns if this text node is an outline.
Definition: ndtxt.cxx:4076
const SwNodeNum * GetNum(SwRootFrame const *pLayout=nullptr, SwListRedlineType eRedline=SwListRedlineType::SHOW) const
Definition: ndtxt.cxx:4033
bool IsCountedInList() const
Definition: ndtxt.cxx:4331
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2870
bool IsListRestart() const
Definition: ndtxt.cxx:4211
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4106
bool IsHidden() const
Definition: ndtxt.cxx:4673
const OUString & GetText() const
Definition: ndtxt.hxx:222
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:723
SwTextPaintInfo & GetInfo()
Definition: itrpaint.hxx:57
SwTextFrame * GetTextFrame()
Definition: inftxt.hxx:288
SwFont * GetFont()
Definition: inftxt.hxx:232
const OUString & GetText() const
Definition: inftxt.hxx:240
TextFrameIndex GetIdx() const
Definition: inftxt.hxx:273
bool IsViewLocked() const
Definition: viewsh.hxx:474
sal_Int32 GetPageNumAndSetOffsetForPDF(OutputDevice &rOut, const SwRect &rRect) const
Definition: viewsh.cxx:2715
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2190
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
SwDoc * GetDoc() const
Definition: viewsh.hxx:290
sal_uInt16 GetPageCount() const
Definition: viewsh.cxx:2672
void LockView(bool b)
Definition: viewsh.hxx:475
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2842
size_type size() const
constexpr void SetLeft(tools::Long v)
constexpr void SetTop(tools::Long v)
constexpr tools::Long Top() const
void SetSize(const Size &)
constexpr Size GetSize() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
constexpr tools::Long Left() const
bool SetCurrentStructureElement(sal_Int32 nElement)
void SetStructureBoundingBox(const tools::Rectangle &rRect)
void CreateNote(const tools::Rectangle &rRect, const PDFNote &rNote, sal_Int32 nPageNr=-1)
sal_Int32 CreateDest(const tools::Rectangle &rRect, sal_Int32 nPageNr=-1, PDFWriter::DestAreaType eType=PDFWriter::DestAreaType::XYZ)
std::vector< PDFExtOutDevBookmarkEntry > & GetBookmarks()
bool GetIsExportTaggedPDF() const
void SetDocumentLocale(const css::lang::Locale &rLoc)
void SetStructureAttributeNumerical(PDFWriter::StructAttribute eAttr, sal_Int32 nValue)
bool GetIsExportNotes() const
void SetScreenStream(sal_Int32 nScreenId, const OUString &rURL)
sal_Int32 GetCurrentStructureElement() const
void SetStructureAttribute(PDFWriter::StructAttribute eAttr, PDFWriter::StructAttributeValue eVal)
void SetActualText(const OUString &rText)
void SetScreenURL(sal_Int32 nScreenId, const OUString &rURL)
void DescribeRegisteredDest(sal_Int32 nDestId, const tools::Rectangle &rRect, sal_Int32 nPageNr, PDFWriter::DestAreaType eType=PDFWriter::DestAreaType::XYZ)
void SetLinkURL(sal_Int32 nLinkId, const OUString &rURL)
bool GetIsExportBookmarks() const
sal_Int32 CreateOutlineItem(sal_Int32 nParent, const OUString &rText, sal_Int32 nDestID)
sal_Int32 BeginStructureElement(PDFWriter::StructElement eType, const OUString &rAlias=OUString())
bool GetIsExportNamedDestinations() const
sal_Int32 CreateNamedDest(const OUString &sDestName, const tools::Rectangle &rRect, sal_Int32 nPageNr=-1)
sal_Int32 CreateLink(const tools::Rectangle &rRect, sal_Int32 nPageNr=-1)
sal_Int32 CreateScreen(const tools::Rectangle &rRect, sal_Int32 nPageNr)
void SetLinkDest(sal_Int32 nLinkId, sal_Int32 nDestId)
URL aURL
virtual SotClipboardFormatId GetFormat(const TransferableDataHelper &aHelper) override
float u
std::vector< SwGetINetAttr > SwGetINetAttrs
Definition: editsh.hxx:127
bool JumpToSwMark(SwViewShell const *pVwSh, std::u16string_view rMark)
Definition: edtwin3.cxx:117
EmbeddedObjectRef * pObject
@ TableOfAuthorities
DocumentType eType
LINESTYLE_NONE
STRIKEOUT_NONE
SwFrame * GetFrameOfModify(const SwRootFrame *pLayout, sw::BroadcastingModify const &, SwFrameType const nFrameType, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr)
Definition: frmtool.cxx:3786
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_CTL_LANGUAGE(29)
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_CJK_LANGUAGE(24)
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(159)
constexpr TypedWhichId< SwFormatURL > RES_URL(111)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
LanguageType GetAppLanguage()
Definition: init.cxx:725
void * p
sal_Int64 n
#define LANGUAGE_SYSTEM
sal_Int16 GetI18NScriptTypeOfLanguage(LanguageType nLang)
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:390
const LanguageTag & getLocale()
int i
const SvxPageUsage aArr[]
void GotoPrevLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1436
bool IsFootnoteDeleted(IDocumentRedlineAccess const &rIDRA, SwTextFootnote const &rTextFootnote)
Definition: ftnidx.cxx:37
bool IsParaPropsNode(SwRootFrame const &rLayout, SwTextNode const &rNode)
Definition: txtfrm.cxx:313
SwTextNode * GetParaPropsNode(SwRootFrame const &rLayout, SwNode const &rNode)
Definition: txtfrm.cxx:330
long Long
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
sal_Int16 nId
SwPostItMode
this must match the definitions in css::text::NotePrintMode
Definition: printdata.hxx:43
sal_uIntPtr sal_uLong
const SwFrame & mrFrame
const SwFrame & mrFrame
const SwLinePortion & mrPor
const SwTextPainter & mrTextPainter
For querying the INet-attributes for Navigator.
Definition: editsh.hxx:119
Marks a position in the document model.
Definition: pam.hxx:37
SwNode & GetNode() const
Definition: pam.hxx:80
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:230
OUString Contents
OUString Title
SvxAdjust
SwFontScript
Definition: swfont.hxx:124
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:164
std::vector< SwRect > SwRects
Definition: swregion.hxx:26
@ AUTH_FIELD_URL
Definition: toxe.hxx:110
@ TOX_INDEX
Definition: toxe.hxx:41
signed char sal_Int8
size_t pos