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 <vprint.hxx>
78#include <SwNodeNum.hxx>
79#include <calbck.hxx>
80#include <stack>
81#include <frmtool.hxx>
82#include <strings.hrc>
83#include <frameformats.hxx>
84#include <tblafmt.hxx>
85#include <authfld.hxx>
86#include <dcontact.hxx>
87
88#include <tools/globname.hxx>
89#include <svx/svdobj.hxx>
90
91using namespace ::com::sun::star;
92
93// Some static data structures
94
100
102
103#if OSL_DEBUG_LEVEL > 1
104
105static std::vector< sal_uInt16 > aStructStack;
106
108{
109 /* NonStructElement = 0 Document = 1 Part = 2
110 * Article = 3 Section = 4 Division = 5
111 * BlockQuote = 6 Caption = 7 TOC = 8
112 * TOCI = 9 Index = 10 Paragraph = 11
113 * Heading = 12 H1-6 = 13 - 18 List = 19
114 * ListItem = 20 LILabel = 21 LIBody = 22
115 * Table = 23 TableRow = 24 TableHeader = 25
116 * TableData = 26 Span = 27 Quote = 28
117 * Note = 29 Reference = 30 BibEntry = 31
118 * Code = 32 Link = 33 Figure = 34
119 * Formula = 35 Form = 36 Continued frame = 99
120 */
121
122 sal_uInt16 nElement;
123 for ( const auto& rItem : aStructStack )
124 {
125 nElement = rItem;
126 }
127 (void)nElement;
128};
129
130#endif
131
132namespace
133{
134// ODF Style Names:
135const char aTableHeadingName[] = "Table Heading";
136const char aQuotations[] = "Quotations";
137const char aCaption[] = "Caption";
138const char aHeading[] = "Heading";
139const char aQuotation[] = "Quotation";
140const char aSourceText[] = "Source Text";
141
142// PDF Tag Names:
143constexpr OUStringLiteral aDocumentString = u"Document";
144constexpr OUStringLiteral aDivString = u"Div";
145constexpr OUStringLiteral aSectString = u"Sect";
146constexpr OUStringLiteral aHString = u"H";
147constexpr OUStringLiteral aH1String = u"H1";
148constexpr OUStringLiteral aH2String = u"H2";
149constexpr OUStringLiteral aH3String = u"H3";
150constexpr OUStringLiteral aH4String = u"H4";
151constexpr OUStringLiteral aH5String = u"H5";
152constexpr OUStringLiteral aH6String = u"H6";
153constexpr OUStringLiteral aH7String = u"H7";
154constexpr OUStringLiteral aH8String = u"H8";
155constexpr OUStringLiteral aH9String = u"H9";
156constexpr OUStringLiteral aH10String = u"H10";
157constexpr OUStringLiteral aListString = u"L";
158constexpr OUStringLiteral aListItemString = u"LI";
159constexpr OUStringLiteral aListLabelString = u"Lbl";
160constexpr OUStringLiteral aListBodyString = u"LBody";
161constexpr OUStringLiteral aBlockQuoteString = u"BlockQuote";
162constexpr OUStringLiteral aCaptionString = u"Caption";
163constexpr OUStringLiteral aIndexString = u"Index";
164constexpr OUStringLiteral aTOCString = u"TOC";
165constexpr OUStringLiteral aTOCIString = u"TOCI";
166constexpr OUStringLiteral aTableString = u"Table";
167constexpr OUStringLiteral aTRString = u"TR";
168constexpr OUStringLiteral aTDString = u"TD";
169constexpr OUStringLiteral aTHString = u"TH";
170constexpr OUStringLiteral aBibEntryString = u"BibEntry";
171constexpr OUStringLiteral aQuoteString = u"Quote";
172constexpr OUStringLiteral aSpanString = u"Span";
173constexpr OUStringLiteral aCodeString = u"Code";
174constexpr OUStringLiteral aFigureString = u"Figure";
175constexpr OUStringLiteral aFormulaString = u"Formula";
176constexpr OUStringLiteral aLinkString = u"Link";
177constexpr OUStringLiteral aNoteString = u"Note";
178
179// returns true if first paragraph in cell frame has 'table heading' style
180bool lcl_IsHeadlineCell( const SwCellFrame& rCellFrame )
181{
182 bool bRet = false;
183
184 const SwContentFrame *pCnt = rCellFrame.ContainsContent();
185 if ( pCnt && pCnt->IsTextFrame() )
186 {
187 SwTextNode const*const pTextNode = static_cast<const SwTextFrame*>(pCnt)->GetTextNodeForParaProps();
188 const SwFormat* pTextFormat = pTextNode->GetFormatColl();
189
190 OUString sStyleName;
192 bRet = sStyleName == aTableHeadingName;
193 }
194
195 // tdf#153935 wild guessing for 1st row based on table autoformat
196 if (!bRet && !rCellFrame.GetUpper()->GetPrev())
197 {
198 SwTable const*const pTable(rCellFrame.FindTabFrame()->GetTable());
199 assert(pTable);
200 OUString const& rStyleName(pTable->GetTableStyleName());
201 if (!rStyleName.isEmpty())
202 {
203 if (SwTableAutoFormat const*const pTableAF =
204 pTable->GetFrameFormat()->GetDoc()->GetTableStyles().FindAutoFormat(rStyleName))
205 {
206 bRet |= pTableAF->HasHeaderRow();
207 }
208 }
209 }
210
211 return bRet;
212}
213
214// List all frames for which the NonStructElement tag is set:
215bool lcl_IsInNonStructEnv( const SwFrame& rFrame )
216{
217 bool bRet = false;
218
219 if ( nullptr != rFrame.FindFooterOrHeader() &&
220 !rFrame.IsHeaderFrame() && !rFrame.IsFooterFrame() )
221 {
222 bRet = true;
223 }
224 else if ( rFrame.IsInTab() && !rFrame.IsTabFrame() )
225 {
226 const SwTabFrame* pTabFrame = rFrame.FindTabFrame();
227 if ( rFrame.GetUpper() != pTabFrame &&
228 pTabFrame->IsFollow() && pTabFrame->IsInHeadline( rFrame ) )
229 bRet = true;
230 }
231
232 return bRet;
233}
234
235// Generate key from frame for reopening tags:
236void* lcl_GetKeyFromFrame( const SwFrame& rFrame )
237{
238 void* pKey = nullptr;
239
240 if ( rFrame.IsPageFrame() )
241 pKey = const_cast<void*>(static_cast<void const *>(&(static_cast<const SwPageFrame&>(rFrame).GetFormat()->getIDocumentSettingAccess())));
242 else if ( rFrame.IsTextFrame() )
243 pKey = const_cast<void*>(static_cast<void const *>(static_cast<const SwTextFrame&>(rFrame).GetTextNodeFirst()));
244 else if ( rFrame.IsSctFrame() )
245 pKey = const_cast<void*>(static_cast<void const *>(static_cast<const SwSectionFrame&>(rFrame).GetSection()));
246 else if ( rFrame.IsTabFrame() )
247 pKey = const_cast<void*>(static_cast<void const *>(static_cast<const SwTabFrame&>(rFrame).GetTable()));
248 else if ( rFrame.IsRowFrame() )
249 pKey = const_cast<void*>(static_cast<void const *>(static_cast<const SwRowFrame&>(rFrame).GetTabLine()));
250 else if ( rFrame.IsCellFrame() )
251 {
252 const SwTabFrame* pTabFrame = rFrame.FindTabFrame();
253 const SwTable* pTable = pTabFrame->GetTable();
254 pKey = const_cast<void*>(static_cast<void const *>(& static_cast<const SwCellFrame&>(rFrame).GetTabBox()->FindStartOfRowSpan( *pTable )));
255 }
256
257 return pKey;
258}
259
260bool lcl_HasPreviousParaSameNumRule(SwTextFrame const& rTextFrame, const SwTextNode& rNode)
261{
262 bool bRet = false;
263 SwNodeIndex aIdx( rNode );
264 const SwDoc& rDoc = rNode.GetDoc();
265 const SwNodes& rNodes = rDoc.GetNodes();
266 const SwNode* pNode = &rNode;
267 const SwNumRule* pNumRule = rNode.GetNumRule();
268
269 while (pNode != rNodes.DocumentSectionStartNode(const_cast<SwNode*>(static_cast<SwNode const *>(&rNode))) )
270 {
271 sw::GotoPrevLayoutTextFrame(aIdx, rTextFrame.getRootFrame());
272
273 if (aIdx.GetNode().IsTextNode())
274 {
275 const SwTextNode *const pPrevTextNd = sw::GetParaPropsNode(
276 *rTextFrame.getRootFrame(), *aIdx.GetNode().GetTextNode());
277 const SwNumRule * pPrevNumRule = pPrevTextNd->GetNumRule();
278
279 // We find the previous text node. Now check, if the previous text node
280 // has the same numrule like rNode:
281 if ( (pPrevNumRule == pNumRule) &&
282 (!pPrevTextNd->IsOutline() == !rNode.IsOutline()))
283 bRet = true;
284
285 break;
286 }
287
288 pNode = &aIdx.GetNode();
289 }
290 return bRet;
291}
292
293bool lcl_TryMoveToNonHiddenField(SwEditShell& rShell, const SwTextNode& rNd, const SwFormatField& rField)
294{
295 // 1. Check if the whole paragraph is hidden
296 // 2. Move to the field
297 // 3. Check for hidden text attribute
298 if(rNd.IsHidden())
299 return false;
300 if(!rShell.GotoFormatField(rField) || rShell.IsInHiddenRange(/*bSelect=*/false))
301 {
302 rShell.SwCursorShell::ClearMark();
303 return false;
304 }
305 return true;
306};
307
308} // end namespace
309
311 const Frame_Info* pFrameInfo,
312 const Por_Info* pPorInfo,
313 OutputDevice const & rOut )
314 : m_nEndStructureElement( 0 ),
315 m_nRestoreCurrentTag( -1 ),
316 mpNumInfo( pNumInfo ),
317 mpFrameInfo( pFrameInfo ),
318 mpPorInfo( pPorInfo )
319{
321 dynamic_cast< vcl::PDFExtOutDevData*>( rOut.GetExtOutDevData() );
322
324 return;
325
326#if OSL_DEBUG_LEVEL > 1
327 sal_Int32 nCurrentStruct = mpPDFExtOutDevData->GetCurrentStructureElement();
329#endif
330 if ( mpNumInfo )
332 else if ( mpFrameInfo )
334 else if ( mpPorInfo )
336 else
338
339#if OSL_DEBUG_LEVEL > 1
342 (void)nCurrentStruct;
343#endif
344}
345
347{
349 return;
350
351#if OSL_DEBUG_LEVEL > 1
352 sal_Int32 nCurrentStruct = mpPDFExtOutDevData->GetCurrentStructureElement();
354#endif
356
357#if OSL_DEBUG_LEVEL > 1
360 (void)nCurrentStruct;
361#endif
362}
363
365{
366 SwFrame const*const pAnchorFrame(GetAnchoredObj(&rObj)->GetAnchorFrame());
367 return pAnchorFrame ? lcl_GetKeyFromFrame(*pAnchorFrame) : nullptr;
368}
369
371{
372 bool bRet = false;
373 void const* pReopenKey(nullptr);
374 bool bContinue = false; // in some cases we just have to reopen a tag without early returning
375
376 if ( mpFrameInfo )
377 {
378 const SwFrame& rFrame = mpFrameInfo->mrFrame;
379 const SwFrame* pKeyFrame = nullptr;
380
381 // Reopen an existing structure element if
382 // - rFrame is not the first page frame (reopen Document tag)
383 // - rFrame is a follow frame (reopen Master tag)
384 // - rFrame is a fly frame anchored at content (reopen Anchor paragraph tag)
385 // - rFrame is a fly frame anchored at page (reopen Document tag)
386 // - rFrame is a follow flow row (reopen TableRow tag)
387 // - rFrame is a cell frame in a follow flow row (reopen TableData tag)
388 if ( ( rFrame.IsPageFrame() && static_cast<const SwPageFrame&>(rFrame).GetPrev() ) ||
389 ( rFrame.IsFlowFrame() && SwFlowFrame::CastFlowFrame(&rFrame)->IsFollow() ) ||
390 ( rFrame.IsRowFrame() && rFrame.IsInFollowFlowRow() ) ||
391 ( rFrame.IsCellFrame() && const_cast<SwFrame&>(rFrame).GetPrevCellLeaf() ) )
392 {
393 pKeyFrame = &rFrame;
394 }
395 else if (rFrame.IsFlyFrame() && !mpFrameInfo->m_isLink)
396 {
397 const SwFormatAnchor& rAnchor =
398 static_cast<const SwFlyFrame*>(&rFrame)->GetFormat()->GetAnchor();
399 if ((RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId()) ||
400 (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
401 (RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId()))
402 {
403 pKeyFrame = static_cast<const SwFlyFrame&>(rFrame).GetAnchorFrame();
404 bContinue = true;
405 }
406 }
407
408 if ( pKeyFrame )
409 {
410 void const*const pKey = lcl_GetKeyFromFrame(*pKeyFrame);
412 if (rFrameTagSet.find(pKey) != rFrameTagSet.end()
413 || rFrame.IsFlyFrame()) // for hell layer flys
414 {
415 pReopenKey = pKey;
416 }
417 }
418 }
419
420 if (pReopenKey)
421 {
422 sal_Int32 const id = mpPDFExtOutDevData->EnsureStructureElement(pReopenKey);
425
426#if OSL_DEBUG_LEVEL > 1
427 aStructStack.push_back( 99 );
428#endif
429
430 bRet = true;
431 }
432
433 return bRet && !bContinue;
434}
435
437{
438 if ( m_nRestoreCurrentTag != -1 )
439 {
441 OSL_ENSURE( bSuccess, "Failed to restore reopened tag" );
442
443#if OSL_DEBUG_LEVEL > 1
444 aStructStack.pop_back();
445#endif
446 }
447}
448
449void SwTaggedPDFHelper::BeginTag( vcl::PDFWriter::StructElement eType, const OUString& rString )
450{
451 void const* pKey(nullptr);
452
453 if ( mpFrameInfo )
454 {
455 const SwFrame& rFrame = mpFrameInfo->mrFrame;
456
457 if ( ( rFrame.IsPageFrame() && !static_cast<const SwPageFrame&>(rFrame).GetPrev() ) ||
458 ( rFrame.IsFlowFrame() && !SwFlowFrame::CastFlowFrame(&rFrame)->IsFollow() && SwFlowFrame::CastFlowFrame(&rFrame)->HasFollow() ) ||
459 ( rFrame.IsTextFrame() && rFrame.GetDrawObjs() ) ||
460 ( rFrame.IsRowFrame() && rFrame.IsInSplitTableRow() ) ||
461 ( rFrame.IsCellFrame() && const_cast<SwFrame&>(rFrame).GetNextCellLeaf() ) )
462 {
463 pKey = lcl_GetKeyFromFrame(rFrame);
464
465 if (pKey)
466 {
468 assert(rFrameTagSet.find(pKey) == rFrameTagSet.end());
469 rFrameTagSet.emplace(pKey);
470 }
471 }
472 }
473
474 // write new tag
475 const sal_Int32 nId = mpPDFExtOutDevData->EnsureStructureElement(pKey);
479
480#if OSL_DEBUG_LEVEL > 1
481 aStructStack.push_back( o3tl::narrowing<sal_uInt16>(eType) );
482#endif
483
484 // Store the id of the current structure element if
485 // - it is a list structure element
486 // - it is a list body element with children
487 // - rFrame is the first page frame
488 // - rFrame is a master frame
489 // - rFrame has objects anchored to it
490 // - rFrame is a row frame or cell frame in a split table row
491
492 if ( mpNumInfo )
493 {
494 const SwTextFrame& rTextFrame = static_cast<const SwTextFrame&>(mpNumInfo->mrFrame);
495 SwTextNode const*const pTextNd = rTextFrame.GetTextNodeForParaProps();
496 const SwNodeNum* pNodeNum = pTextNd->GetNum(rTextFrame.getRootFrame());
497
499 {
501 rNumListIdMap[ pNodeNum ] = nId;
502 }
503 else if ( vcl::PDFWriter::LIBody == eType )
504 {
506 rNumListBodyIdMap[ pNodeNum ] = nId;
507 }
508 }
509 else if ( mpFrameInfo )
510 {
511 const SwFrame& rFrame = mpFrameInfo->mrFrame;
512
513 if (vcl::PDFWriter::LIBody == eType && rFrame.IsTextFrame())
514 {
515 SwTextFrame const& rTextFrame(static_cast<const SwTextFrame&>(rFrame));
516 SwTextNode const*const pTextNd(rTextFrame.GetTextNodeForParaProps());
517 SwNodeNum const*const pNodeNum(pTextNd->GetNum(rTextFrame.getRootFrame()));
519 rNumListBodyIdMap[ pNodeNum ] = nId;
520 }
521 }
522
524}
525
527{
529
530#if OSL_DEBUG_LEVEL > 1
531 aStructStack.pop_back();
532#endif
533}
534
535namespace {
536
537 // link the link annotation to the link structured element
538 void LinkLinkLink(vcl::PDFExtOutDevData & rPDFExtOutDevData, SwRect const& rRect)
539 {
541 const Point aCenter = rRect.Center();
542 auto aIter = std::find_if(rLinkIdMap.begin(), rLinkIdMap.end(),
543 [&aCenter](const IdMapEntry& rEntry) { return rEntry.first.Contains(aCenter); });
544 if (aIter != rLinkIdMap.end())
545 {
546 sal_Int32 nLinkId = (*aIter).second;
548 }
549 }
550}
551
552// Sets the attributes according to the structure type.
554{
555 sal_Int32 nVal;
556
557 /*
558 * ATTRIBUTES FOR BLSE
559 */
560 if ( mpFrameInfo )
561 {
563 const SwFrame* pFrame = &mpFrameInfo->mrFrame;
564 SwRectFnSet aRectFnSet(pFrame);
565
566 bool bPlacement = false;
567 bool bWritingMode = false;
568 bool bSpaceBefore = false;
569 bool bSpaceAfter = false;
570 bool bStartIndent = false;
571 bool bEndIndent = false;
572 bool bTextIndent = false;
573 bool bTextAlign = false;
574 bool bWidth = false;
575 bool bHeight = false;
576 bool bBox = false;
577 bool bRowSpan = false;
578 bool bAltText = false;
579
580 // Check which attributes to set:
581
582 switch ( eType )
583 {
585 bWritingMode = true;
586 break;
587
589 bPlacement =
590 bWritingMode =
591 bSpaceBefore =
592 bSpaceAfter =
593 bStartIndent =
594 bEndIndent =
595 bWidth =
596 bHeight =
597 bBox = true;
598 break;
599
601 bPlacement =
602 bWritingMode = true;
603 break;
604
607 [[fallthrough]];
609 bPlacement =
610 bWritingMode =
611 bWidth =
612 bHeight =
613 bRowSpan = true;
614 break;
615
616 case vcl::PDFWriter::H1 :
617 case vcl::PDFWriter::H2 :
618 case vcl::PDFWriter::H3 :
619 case vcl::PDFWriter::H4 :
620 case vcl::PDFWriter::H5 :
621 case vcl::PDFWriter::H6 :
626
627 bPlacement =
628 bWritingMode =
629 bSpaceBefore =
630 bSpaceAfter =
631 bStartIndent =
632 bEndIndent =
633 bTextIndent =
634 bTextAlign = true;
635 break;
636
639 bAltText =
640 bPlacement =
641 bWidth =
642 bHeight =
643 bBox = true;
644 break;
645
647 if (pFrame->IsFlyFrame()) // this can be something else too
648 {
649 bAltText = true;
650 bBox = true;
651 }
652 break;
653
655 if (pFrame->IsHeaderFrame() || pFrame->IsFooterFrame())
656 {
657 // ISO 14289-1:2014, Clause: 7.8
660 pFrame->IsHeaderFrame()
663 }
664 break;
665
666 default :
667 break;
668 }
669
670 // Set the attributes:
671
672 if ( bPlacement )
673 {
678
680 }
681
682 if ( bWritingMode )
683 {
684 eVal = pFrame->IsVertical() ?
686 pFrame->IsRightToLeft() ?
689
690 if ( vcl::PDFWriter::LrTb != eVal )
692 }
693
694 if ( bSpaceBefore )
695 {
696 nVal = aRectFnSet.GetTopMargin(*pFrame);
697 if ( 0 != nVal )
699 }
700
701 if ( bSpaceAfter )
702 {
703 nVal = aRectFnSet.GetBottomMargin(*pFrame);
704 if ( 0 != nVal )
706 }
707
708 if ( bStartIndent )
709 {
710 nVal = aRectFnSet.GetLeftMargin(*pFrame);
711 if ( 0 != nVal )
713 }
714
715 if ( bEndIndent )
716 {
717 nVal = aRectFnSet.GetRightMargin(*pFrame);
718 if ( 0 != nVal )
720 }
721
722 if ( bTextIndent )
723 {
724 OSL_ENSURE( pFrame->IsTextFrame(), "Frame type <-> tag attribute mismatch" );
725 const SvxFirstLineIndentItem& rFirstLine(
726 static_cast<const SwTextFrame*>(pFrame)->GetTextNodeForParaProps()->GetSwAttrSet().GetFirstLineIndent());
727 nVal = rFirstLine.GetTextFirstLineOffset();
728 if ( 0 != nVal )
730 }
731
732 if ( bTextAlign )
733 {
734 OSL_ENSURE( pFrame->IsTextFrame(), "Frame type <-> tag attribute mismatch" );
735 const SwAttrSet& aSet = static_cast<const SwTextFrame*>(pFrame)->GetTextNodeForParaProps()->GetSwAttrSet();
736 const SvxAdjust nAdjust = aSet.GetAdjust().GetAdjust();
737 if ( SvxAdjust::Block == nAdjust || SvxAdjust::Center == nAdjust ||
738 ( (pFrame->IsRightToLeft() && SvxAdjust::Left == nAdjust) ||
739 (!pFrame->IsRightToLeft() && SvxAdjust::Right == nAdjust) ) )
740 {
741 eVal = SvxAdjust::Block == nAdjust ?
743 SvxAdjust::Center == nAdjust ?
746
748 }
749 }
750
751 // ISO 14289-1:2014, Clause: 7.3
752 // ISO 14289-1:2014, Clause: 7.7
753 // For images (but not embedded objects), an ObjectInfoPrimitive2D is
754 // created, but it's not evaluated by VclMetafileProcessor2D any more;
755 // that would require producing StructureTagPrimitive2D here but that
756 // looks impossible so instead duplicate the code that sets the Alt
757 // text here again.
758 if (bAltText)
759 {
760 SwFlyFrameFormat const& rFly(*static_cast<SwFlyFrame const*>(pFrame)->GetFormat());
761 OUString const sep(
762 (rFly.GetObjTitle().isEmpty() || rFly.GetObjDescription().isEmpty())
763 ? OUString() : OUString(" - "));
764 OUString const altText(rFly.GetObjTitle() + sep + rFly.GetObjDescription());
765 if (!altText.isEmpty())
766 {
768 }
769 }
770
771 if ( bWidth )
772 {
773 nVal = aRectFnSet.GetWidth(pFrame->getFrameArea());
775 }
776
777 if ( bHeight )
778 {
779 nVal = aRectFnSet.GetHeight(pFrame->getFrameArea());
781 }
782
783 if ( bBox )
784 {
785 // BBox only for non-split tables:
787 ( pFrame->IsTabFrame() &&
788 !static_cast<const SwTabFrame*>(pFrame)->IsFollow() &&
789 !static_cast<const SwTabFrame*>(pFrame)->HasFollow() ) )
790 {
792 }
793 }
794
795 if ( bRowSpan )
796 {
797 if ( pFrame->IsCellFrame() )
798 {
799 const SwCellFrame* pThisCell = static_cast<const SwCellFrame*>(pFrame);
800 nVal = pThisCell->GetTabBox()->getRowSpan();
801 if ( nVal > 1 )
803
804 // calculate colspan:
805 const SwTabFrame* pTabFrame = pThisCell->FindTabFrame();
806 const SwTable* pTable = pTabFrame->GetTable();
807
808 SwRectFnSet fnRectX(pTabFrame);
809
811
812 const tools::Long nLeft = fnRectX.GetLeft(pThisCell->getFrameArea());
813 const tools::Long nRight = fnRectX.GetRight(pThisCell->getFrameArea());
814 const TableColumnsMapEntry::const_iterator aLeftIter = rCols.find( nLeft );
815 const TableColumnsMapEntry::const_iterator aRightIter = rCols.find( nRight );
816
817 OSL_ENSURE( aLeftIter != rCols.end() && aRightIter != rCols.end(), "Colspan trouble" );
818 if ( aLeftIter != rCols.end() && aRightIter != rCols.end() )
819 {
820 nVal = std::distance( aLeftIter, aRightIter );
821 if ( nVal > 1 )
823 }
824 }
825 }
826
828 {
829 SwRect const aRect(mpFrameInfo->mrFrame.getFrameArea());
830 LinkLinkLink(*mpPDFExtOutDevData, aRect);
831 }
832 }
833
834 /*
835 * ATTRIBUTES FOR ILSE
836 */
837 else if ( mpPorInfo )
838 {
839 const SwLinePortion* pPor = &mpPorInfo->mrPor;
841
842 bool bActualText = false;
843 bool bBaselineShift = false;
844 bool bTextDecorationType = false;
845 bool bLinkAttribute = false;
846 bool bLanguage = false;
847
848 // Check which attributes to set:
849
850 switch ( eType )
851 {
857 bActualText = true;
858 else
859 {
860 bBaselineShift =
861 bTextDecorationType =
862 bLanguage = true;
863 }
864 break;
865
867 bTextDecorationType =
868 bBaselineShift =
869 bLinkAttribute =
870 bLanguage = true;
871 break;
872
874 bTextDecorationType =
875 bBaselineShift =
876 bLinkAttribute =
877 bLanguage = true;
878 break;
879
880 default:
881 break;
882 }
883
884 if ( bActualText )
885 {
886 OUString aActualText;
888 aActualText = OUString(u'\x00ad'); // soft hyphen
889 else
890 aActualText = rInf.GetText().copy(sal_Int32(rInf.GetIdx()), sal_Int32(pPor->GetLen()));
891 mpPDFExtOutDevData->SetActualText( aActualText );
892 }
893
894 if ( bBaselineShift )
895 {
896 // TODO: Calculate correct values!
897 nVal = rInf.GetFont()->GetEscapement();
898 if ( nVal > 0 ) nVal = 33;
899 else if ( nVal < 0 ) nVal = -33;
900
901 if ( 0 != nVal )
902 {
903 nVal = nVal * pPor->Height() / 100;
905 }
906 }
907
908 if ( bTextDecorationType )
909 {
910 if ( LINESTYLE_NONE != rInf.GetFont()->GetUnderline() )
912 if ( LINESTYLE_NONE != rInf.GetFont()->GetOverline() )
914 if ( STRIKEOUT_NONE != rInf.GetFont()->GetStrikeout() )
916 if ( FontEmphasisMark::NONE != rInf.GetFont()->GetEmphasisMark() )
918 }
919
920 if ( bLanguage )
921 {
922
923 const LanguageType nCurrentLanguage = rInf.GetFont()->GetLanguage();
925
926 if ( nDefaultLang != nCurrentLanguage )
927 mpPDFExtOutDevData->SetStructureAttributeNumerical( vcl::PDFWriter::Language, static_cast<sal_uInt16>(nCurrentLanguage) );
928 }
929
930 if ( bLinkAttribute )
931 {
932 SwRect aPorRect;
933 rInf.CalcRect( *pPor, &aPorRect );
934 LinkLinkLink(*mpPDFExtOutDevData, aPorRect);
935 }
936 }
937 else if (mpNumInfo && eType == vcl::PDFWriter::List)
938 {
939 SwTextFrame const& rFrame(static_cast<SwTextFrame const&>(mpNumInfo->mrFrame));
940 SwTextNode const& rNode(*rFrame.GetTextNodeForParaProps());
941 SwNumRule const*const pNumRule = rNode.GetNumRule();
942 assert(pNumRule); // was required for List
943
944 auto ToPDFListNumbering = [](SvxNumberFormat const& rFormat) {
945 switch (rFormat.GetNumberingType())
946 {
947 case css::style::NumberingType::CHARS_UPPER_LETTER:
949 case css::style::NumberingType::CHARS_LOWER_LETTER:
951 case css::style::NumberingType::ROMAN_UPPER:
953 case css::style::NumberingType::ROMAN_LOWER:
955 case css::style::NumberingType::ARABIC:
957 case css::style::NumberingType::CHAR_SPECIAL:
958 switch (rFormat.GetBulletChar())
959 {
960 case u'\u2022': case u'\uE12C': case u'\uE01E': case u'\uE437':
962 case u'\u2218': case u'\u25CB': case u'\u25E6':
964 case u'\u25A0': case u'\u25AA': case u'\uE00A':
966 default:
968 }
969 default: // the other 50 types
971 }
972 };
973
974 // Note: for every level, BeginNumberedListStructureElements() produces
975 // a separate List element, so even though in PDF this is limited to
976 // the whole List we can just export the current level here.
978 ToPDFListNumbering(pNumRule->Get(rNode.GetActualListLevel())));
979 // ISO 14289-1:2014, Clause: 7.6
981 }
982}
983
985{
986 OSL_ENSURE( mpNumInfo, "List without mpNumInfo?" );
987 if ( !mpNumInfo )
988 return;
989
990 const SwFrame& rFrame = mpNumInfo->mrFrame;
991 assert(rFrame.IsTextFrame());
992 const SwTextFrame& rTextFrame = static_cast<const SwTextFrame&>(rFrame);
993
994 // Lowers of NonStructureElements should not be considered:
995 if (lcl_IsInNonStructEnv(rTextFrame))
996 return;
997
998 // do it for the first one in the follow chain that has content
999 for (SwFlowFrame const* pPrecede = rTextFrame.GetPrecede(); pPrecede; pPrecede = pPrecede->GetPrecede())
1000 {
1001 SwTextFrame const*const pText(static_cast<SwTextFrame const*>(pPrecede));
1002 if (!pText->HasPara() || pText->GetPara()->HasContentPortions())
1003 {
1004 return;
1005 }
1006 }
1007
1008 const SwTextNode *const pTextNd = rTextFrame.GetTextNodeForParaProps();
1009 const SwNumRule* pNumRule = pTextNd->GetNumRule();
1010 const SwNodeNum* pNodeNum = pTextNd->GetNum(rTextFrame.getRootFrame());
1011
1012 const bool bNumbered = !pTextNd->IsOutline() && pNodeNum && pNodeNum->GetParent() && pNumRule;
1013
1014 // Check, if we have to reopen a list or a list body:
1015 // First condition:
1016 // Paragraph is numbered/bulleted
1017 if ( !bNumbered )
1018 return;
1019
1020 const SwNumberTreeNode* pParent = pNodeNum->GetParent();
1021 const bool bSameNumbering = lcl_HasPreviousParaSameNumRule(rTextFrame, *pTextNd);
1022
1023 // Second condition: current numbering is not 'interrupted'
1024 if ( bSameNumbering )
1025 {
1026 sal_Int32 nReopenTag = -1;
1027
1028 // Two cases:
1029 // 1. We have to reopen an existing list body tag:
1030 // - If the current node is either the first child of its parent
1031 // and its level > 1 or
1032 // - Numbering should restart at the current node and its level > 1
1033 // - The current item has no label
1034 const bool bNewSubListStart = pParent->GetParent() && (pParent->IsFirst( pNodeNum ) || pTextNd->IsListRestart() );
1035 const bool bNoLabel = !pTextNd->IsCountedInList() && !pTextNd->IsListRestart();
1036 if ( bNewSubListStart || bNoLabel )
1037 {
1038 // Fine, we try to reopen the appropriate list body
1040
1041 if ( bNewSubListStart )
1042 {
1043 // The list body tag associated with the parent has to be reopened
1044 // to start a new list inside the list body
1045 NumListBodyIdMap::const_iterator aIter;
1046
1047 do
1048 aIter = rNumListBodyIdMap.find( pParent );
1049 while ( aIter == rNumListBodyIdMap.end() && nullptr != ( pParent = pParent->GetParent() ) );
1050
1051 if ( aIter != rNumListBodyIdMap.end() )
1052 nReopenTag = (*aIter).second;
1053 }
1054 else // if(bNoLabel)
1055 {
1056 // The list body tag of a 'counted' predecessor has to be reopened
1057 const SwNumberTreeNode* pPrevious = pNodeNum->GetPred(true);
1058 while ( pPrevious )
1059 {
1060 if ( pPrevious->IsCounted())
1061 {
1062 // get id of list body tag
1063 const NumListBodyIdMap::const_iterator aIter = rNumListBodyIdMap.find( pPrevious );
1064 if ( aIter != rNumListBodyIdMap.end() )
1065 {
1066 nReopenTag = (*aIter).second;
1067 break;
1068 }
1069 }
1070 pPrevious = pPrevious->GetPred(true);
1071 }
1072 }
1073 }
1074 // 2. We have to reopen an existing list tag:
1075 else if ( !pParent->IsFirst( pNodeNum ) && !pTextNd->IsListRestart() )
1076 {
1077 // any other than the first node in a list level has to reopen the current
1078 // list. The current list is associated in a map with the first child of the list:
1080
1081 // Search backwards and check if any of the previous nodes has a list associated with it:
1082 const SwNumberTreeNode* pPrevious = pNodeNum->GetPred(true);
1083 while ( pPrevious )
1084 {
1085 // get id of list tag
1086 const NumListIdMap::const_iterator aIter = rNumListIdMap.find( pPrevious );
1087 if ( aIter != rNumListIdMap.end() )
1088 {
1089 nReopenTag = (*aIter).second;
1090 break;
1091 }
1092
1093 pPrevious = pPrevious->GetPred(true);
1094 }
1095 }
1096
1097 if ( -1 != nReopenTag )
1098 {
1101
1102#if OSL_DEBUG_LEVEL > 1
1103 aStructStack.push_back( 99 );
1104#endif
1105 }
1106 }
1107 else
1108 {
1109 // clear list maps in case a list has been interrupted
1111 rNumListIdMap.clear();
1113 rNumListBodyIdMap.clear();
1114 }
1115
1116 // New tags:
1117 const bool bNewListTag = (pNodeNum->GetParent()->IsFirst( pNodeNum ) || pTextNd->IsListRestart() || !bSameNumbering);
1118 const bool bNewItemTag = bNewListTag || pTextNd->IsCountedInList(); // If the text node is not counted, we do not start a new list item:
1119
1120 if ( bNewListTag )
1121 BeginTag( vcl::PDFWriter::List, aListString );
1122
1123 if ( bNewItemTag )
1124 {
1125 BeginTag( vcl::PDFWriter::ListItem, aListItemString );
1126 assert(rTextFrame.GetPara());
1127 // check whether to open LBody now or delay until after Lbl
1129 {
1130 BeginTag(vcl::PDFWriter::LIBody, aListBodyString);
1131 }
1132 }
1133}
1134
1136{
1137 const SwFrame* pFrame = &mpFrameInfo->mrFrame;
1138
1139 // Lowers of NonStructureElements should not be considered:
1140
1141 if (lcl_IsInNonStructEnv(*pFrame) && !pFrame->IsFlyFrame())
1142 return;
1143
1144 // Check if we have to reopen an existing structure element.
1145 // This has to be done e.g., if pFrame is a follow frame.
1146 if ( CheckReopenTag() )
1147 return;
1148
1149 sal_uInt16 nPDFType = USHRT_MAX;
1150 OUString aPDFType;
1151
1152 switch ( pFrame->GetType() )
1153 {
1154 /*
1155 * GROUPING ELEMENTS
1156 */
1157
1158 case SwFrameType::Page :
1159
1160 // Document: Document
1161
1162 nPDFType = vcl::PDFWriter::Document;
1163 aPDFType = aDocumentString;
1164 break;
1165
1166 case SwFrameType::Header :
1167 case SwFrameType::Footer :
1168
1169 // Header, Footer: NonStructElement
1170
1172 break;
1173
1175
1176 // Footnote container: Division
1177
1178 nPDFType = vcl::PDFWriter::Division;
1179 aPDFType = aDivString;
1180 break;
1181
1182 case SwFrameType::Ftn :
1183
1184 // Footnote frame: Note
1185
1186 // Note: vcl::PDFWriter::Note is actually a ILSE. Nevertheless
1187 // we treat it like a grouping element!
1188 nPDFType = vcl::PDFWriter::Note;
1189 aPDFType = aNoteString;
1190 break;
1191
1193
1194 // Section: TOX, Index, or Sect
1195
1196 {
1197 const SwSection* pSection =
1198 static_cast<const SwSectionFrame*>(pFrame)->GetSection();
1199 if ( SectionType::ToxContent == pSection->GetType() )
1200 {
1201 const SwTOXBase* pTOXBase = pSection->GetTOXBase();
1202 if ( pTOXBase )
1203 {
1204 if ( TOX_INDEX == pTOXBase->GetType() )
1205 {
1206 nPDFType = vcl::PDFWriter::Index;
1207 aPDFType = aIndexString;
1208 }
1209 else
1210 {
1211 nPDFType = vcl::PDFWriter::TOC;
1212 aPDFType = aTOCString;
1213 }
1214 }
1215 }
1216 else if ( SectionType::Content == pSection->GetType() )
1217 {
1218 nPDFType = vcl::PDFWriter::Section;
1219 aPDFType = aSectString;
1220 }
1221 }
1222 break;
1223
1224 /*
1225 * BLOCK-LEVEL STRUCTURE ELEMENTS
1226 */
1227
1228 case SwFrameType::Txt :
1229 {
1230 SwTextFrame const& rTextFrame(*static_cast<const SwTextFrame*>(pFrame));
1231 // lazy open LBody after Lbl
1233 {
1234 BeginTag(vcl::PDFWriter::LIBody, aListBodyString);
1235 }
1236
1237 const SwTextNode *const pTextNd(rTextFrame.GetTextNodeForParaProps());
1238
1239 const SwFormat* pTextFormat = pTextNd->GetFormatColl();
1240 const SwFormat* pParentTextFormat = pTextFormat ? pTextFormat->DerivedFrom() : nullptr;
1241
1242 OUString sStyleName;
1243 OUString sParentStyleName;
1244
1245 if ( pTextFormat)
1247 if ( pParentTextFormat)
1248 SwStyleNameMapper::FillProgName( pParentTextFormat->GetName(), sParentStyleName, SwGetPoolIdFromName::TxtColl );
1249
1250 // This is the default. If the paragraph could not be mapped to
1251 // any of the standard pdf tags, we write a user defined tag
1252 // <stylename> with role = P
1253 nPDFType = vcl::PDFWriter::Paragraph;
1254 aPDFType = sStyleName;
1255
1256 // Quotations: BlockQuote
1257
1258 if (sStyleName == aQuotations)
1259 {
1260 nPDFType = vcl::PDFWriter::BlockQuote;
1261 aPDFType = aBlockQuoteString;
1262 }
1263
1264 // Caption: Caption
1265
1266 else if (sStyleName == aCaption)
1267 {
1268 nPDFType = vcl::PDFWriter::Caption;
1269 aPDFType = aCaptionString;
1270 }
1271
1272 // Caption: Caption
1273
1274 else if (sParentStyleName == aCaption)
1275 {
1276 nPDFType = vcl::PDFWriter::Caption;
1277 aPDFType = sStyleName + aCaptionString;
1278 }
1279
1280 // Heading: H
1281
1282 else if (sStyleName == aHeading)
1283 {
1284 nPDFType = vcl::PDFWriter::Heading;
1285 aPDFType = aHString;
1286 }
1287
1288 // Heading: H1 - H6
1289
1290 if (int nRealLevel = pTextNd->GetAttrOutlineLevel() - 1;
1291 nRealLevel >= 0
1292 && !pTextNd->IsInRedlines()
1293 && sw::IsParaPropsNode(*pFrame->getRootFrame(), *pTextNd))
1294 {
1295 switch(nRealLevel)
1296 {
1297 case 0 :
1298 aPDFType = aH1String;
1299 break;
1300 case 1 :
1301 aPDFType = aH2String;
1302 break;
1303 case 2 :
1304 aPDFType = aH3String;
1305 break;
1306 case 3 :
1307 aPDFType = aH4String;
1308 break;
1309 case 4 :
1310 aPDFType = aH5String;
1311 break;
1312 case 5:
1313 aPDFType = aH6String;
1314 break;
1315 case 6:
1316 aPDFType = aH7String;
1317 break;
1318 case 7:
1319 aPDFType = aH8String;
1320 break;
1321 case 8:
1322 aPDFType = aH9String;
1323 break;
1324 case 9:
1325 aPDFType = aH10String;
1326 break;
1327 default:
1328 assert(false);
1329 break;
1330 }
1331
1332 // PDF/UA allows unlimited headings, but PDF only up to H6
1333 // ... and apparently the extra H7.. must be declared in
1334 // RoleMap, or veraPDF complains.
1335 nRealLevel = std::min(nRealLevel, 5);
1336 nPDFType = o3tl::narrowing<sal_uInt16>(vcl::PDFWriter::H1 + nRealLevel);
1337 }
1338
1339 // Section: TOCI
1340
1341 else if ( pFrame->IsInSct() )
1342 {
1343 const SwSectionFrame* pSctFrame = pFrame->FindSctFrame();
1344 const SwSection* pSection = pSctFrame->GetSection();
1345
1346 if ( SectionType::ToxContent == pSection->GetType() )
1347 {
1348 const SwTOXBase* pTOXBase = pSection->GetTOXBase();
1349 if ( pTOXBase && TOX_INDEX != pTOXBase->GetType() )
1350 {
1351 // Special case: Open additional TOCI tag:
1352 BeginTag( vcl::PDFWriter::TOCI, aTOCIString );
1353 }
1354 }
1355 }
1356 }
1357 break;
1358
1359 case SwFrameType::Tab :
1360
1361 // TabFrame: Table
1362
1363 nPDFType = vcl::PDFWriter::Table;
1364 aPDFType = aTableString;
1365
1366 {
1367 // set up table column data:
1368 const SwTabFrame* pTabFrame = static_cast<const SwTabFrame*>(pFrame);
1369 const SwTable* pTable = pTabFrame->GetTable();
1370
1372 const TableColumnsMap::const_iterator aIter = rTableColumnsMap.find( pTable );
1373
1374 if ( aIter == rTableColumnsMap.end() )
1375 {
1376 SwRectFnSet aRectFnSet(pTabFrame);
1377 TableColumnsMapEntry& rCols = rTableColumnsMap[ pTable ];
1378
1379 const SwTabFrame* pMasterFrame = pTabFrame->IsFollow() ? pTabFrame->FindMaster( true ) : pTabFrame;
1380
1381 while ( pMasterFrame )
1382 {
1383 const SwRowFrame* pRowFrame = static_cast<const SwRowFrame*>(pMasterFrame->GetLower());
1384
1385 while ( pRowFrame )
1386 {
1387 const SwFrame* pCellFrame = pRowFrame->GetLower();
1388
1389 const tools::Long nLeft = aRectFnSet.GetLeft(pCellFrame->getFrameArea());
1390 rCols.insert( nLeft );
1391
1392 while ( pCellFrame )
1393 {
1394 const tools::Long nRight = aRectFnSet.GetRight(pCellFrame->getFrameArea());
1395 rCols.insert( nRight );
1396 pCellFrame = pCellFrame->GetNext();
1397 }
1398 pRowFrame = static_cast<const SwRowFrame*>(pRowFrame->GetNext());
1399 }
1400 pMasterFrame = pMasterFrame->GetFollow();
1401 }
1402 }
1403 }
1404
1405 break;
1406
1407 /*
1408 * TABLE ELEMENTS
1409 */
1410
1411 case SwFrameType::Row :
1412
1413 // RowFrame: TR
1414
1415 if ( !static_cast<const SwRowFrame*>(pFrame)->IsRepeatedHeadline() )
1416 {
1417 nPDFType = vcl::PDFWriter::TableRow;
1418 aPDFType = aTRString;
1419 }
1420 else
1421 {
1423 }
1424 break;
1425
1426 case SwFrameType::Cell :
1427
1428 // CellFrame: TH, TD
1429
1430 {
1431 const SwTabFrame* pTable = static_cast<const SwCellFrame*>(pFrame)->FindTabFrame();
1432 if ( pTable->IsInHeadline( *pFrame ) || lcl_IsHeadlineCell( *static_cast<const SwCellFrame*>(pFrame) ) )
1433 {
1434 nPDFType = vcl::PDFWriter::TableHeader;
1435 aPDFType = aTHString;
1436 }
1437 else
1438 {
1439 nPDFType = vcl::PDFWriter::TableData;
1440 aPDFType = aTDString;
1441 }
1442 }
1443 break;
1444
1445 /*
1446 * ILLUSTRATION
1447 */
1448
1449 case SwFrameType::Fly :
1450
1451 // FlyFrame: Figure, Formula, Control
1452 // fly in content or fly at page
1453 if (mpFrameInfo->m_isLink)
1454 { // tdf#154939 additional inner link element for flys
1455 nPDFType = vcl::PDFWriter::Link;
1456 aPDFType = aLinkString;
1457 }
1458 else
1459 {
1460 const SwFlyFrame* pFly = static_cast<const SwFlyFrame*>(pFrame);
1461 if (pFly->GetAnchorFrame()->FindFooterOrHeader() != nullptr
1462 || pFly->GetFrameFormat().GetAttrSet().Get(RES_DECORATIVE).GetValue())
1463 {
1465 }
1466 else if (pFly->Lower() && pFly->Lower()->IsNoTextFrame())
1467 {
1468 bool bFormula = false;
1469
1470 const SwNoTextFrame* pNoTextFrame = static_cast<const SwNoTextFrame*>(pFly->Lower());
1471 SwOLENode* pOLENd = const_cast<SwOLENode*>(pNoTextFrame->GetNode()->GetOLENode());
1472 if ( pOLENd )
1473 {
1474 SwOLEObj& aOLEObj = pOLENd->GetOLEObj();
1475 uno::Reference< embed::XEmbeddedObject > aRef = aOLEObj.GetOleRef();
1476 if ( aRef.is() )
1477 {
1478 bFormula = 0 != SotExchange::IsMath( SvGlobalName( aRef->getClassID() ) );
1479 }
1480 }
1481 if ( bFormula )
1482 {
1483 nPDFType = vcl::PDFWriter::Formula;
1484 aPDFType = aFormulaString;
1485 }
1486 else
1487 {
1488 nPDFType = vcl::PDFWriter::Figure;
1489 aPDFType = aFigureString;
1490 }
1491 }
1492 else
1493 {
1494 nPDFType = vcl::PDFWriter::Division;
1495 aPDFType = aDivString;
1496 }
1497 }
1498 break;
1499
1500 default: break;
1501 }
1502
1503 if ( USHRT_MAX != nPDFType )
1504 {
1505 BeginTag( static_cast<vcl::PDFWriter::StructElement>(nPDFType), aPDFType );
1506 }
1507}
1508
1510{
1511 while ( m_nEndStructureElement > 0 )
1512 {
1513 EndTag();
1515 }
1516
1518}
1519
1521{
1522 const SwLinePortion* pPor = &mpPorInfo->mrPor;
1524 const SwTextFrame* pFrame = rInf.GetTextFrame();
1525
1526 // Lowers of NonStructureElements should not be considered:
1527
1528 if ( lcl_IsInNonStructEnv( *pFrame ) )
1529 return;
1530
1531 sal_uInt16 nPDFType = USHRT_MAX;
1532 OUString aPDFType;
1533
1534 switch ( pPor->GetWhichPor() )
1535 {
1536 case PortionType::Hyphen :
1538 // Check for alternative spelling:
1541 nPDFType = vcl::PDFWriter::Span;
1542 aPDFType = aSpanString;
1543 break;
1544
1545 case PortionType::Lay :
1546 case PortionType::Text :
1547 case PortionType::Para :
1548 {
1549 std::pair<SwTextNode const*, sal_Int32> const pos(
1550 pFrame->MapViewToModel(rInf.GetIdx()));
1551 SwTextAttr const*const pInetFormatAttr =
1552 pos.first->GetTextAttrAt(pos.second, RES_TXTATR_INETFMT);
1553
1554 OUString sStyleName;
1555 if ( !pInetFormatAttr )
1556 {
1557 std::vector<SwTextAttr *> const charAttrs(
1558 pos.first->GetTextAttrsAt(pos.second, RES_TXTATR_CHARFMT));
1559 // TODO: handle more than 1 char style?
1560 const SwCharFormat* pCharFormat = (charAttrs.size())
1561 ? (*charAttrs.begin())->GetCharFormat().GetCharFormat() : nullptr;
1562 if ( pCharFormat )
1564 }
1565
1566 // Check for Link:
1567 if( pInetFormatAttr )
1568 {
1569 nPDFType = vcl::PDFWriter::Link;
1570 aPDFType = aLinkString;
1571 }
1572 // Check for Quote/Code character style:
1573 else if (sStyleName == aQuotation)
1574 {
1575 nPDFType = vcl::PDFWriter::Quote;
1576 aPDFType = aQuoteString;
1577 }
1578 else if (sStyleName == aSourceText)
1579 {
1580 nPDFType = vcl::PDFWriter::Code;
1581 aPDFType = aCodeString;
1582 }
1583 else
1584 {
1585 const LanguageType nCurrentLanguage = rInf.GetFont()->GetLanguage();
1586 const SwFontScript nFont = rInf.GetFont()->GetActual();
1588
1589 if ( LINESTYLE_NONE != rInf.GetFont()->GetUnderline() ||
1590 LINESTYLE_NONE != rInf.GetFont()->GetOverline() ||
1591 STRIKEOUT_NONE != rInf.GetFont()->GetStrikeout() ||
1592 FontEmphasisMark::NONE != rInf.GetFont()->GetEmphasisMark() ||
1593 0 != rInf.GetFont()->GetEscapement() ||
1594 SwFontScript::Latin != nFont ||
1595 nCurrentLanguage != nDefaultLang ||
1596 !sStyleName.isEmpty())
1597 {
1598 nPDFType = vcl::PDFWriter::Span;
1599 if (!sStyleName.isEmpty())
1600 aPDFType = sStyleName;
1601 else
1602 aPDFType = aSpanString;
1603 }
1604 }
1605 }
1606 break;
1607
1609 nPDFType = vcl::PDFWriter::Link;
1610 aPDFType = aLinkString;
1611 break;
1612
1613 case PortionType::Field :
1614 {
1615 // check field type:
1616 TextFrameIndex const nIdx = static_cast<const SwFieldPortion*>(pPor)->IsFollow()
1617 ? rInf.GetIdx() - TextFrameIndex(1)
1618 : rInf.GetIdx();
1619 const SwTextAttr* pHint = mpPorInfo->mrTextPainter.GetAttr( nIdx );
1620 if ( pHint && RES_TXTATR_FIELD == pHint->Which() )
1621 {
1622 const SwField* pField = pHint->GetFormatField().GetField();
1623 if ( SwFieldIds::GetRef == pField->Which() )
1624 {
1625 nPDFType = vcl::PDFWriter::Link;
1626 aPDFType = aLinkString;
1627 }
1628 else if ( SwFieldIds::TableOfAuthorities == pField->Which() )
1629 {
1630 nPDFType = vcl::PDFWriter::BibEntry;
1631 aPDFType = aBibEntryString;
1632 }
1633 }
1634 }
1635 break;
1636
1637 // for FootnoteNum, is called twice: outer generates Lbl, inner Link
1640 { // tdf#152218 link both directions
1641 nPDFType = vcl::PDFWriter::Link;
1642 aPDFType = aLinkString;
1643 break;
1644 }
1645 [[fallthrough]];
1650 { // only works for multiple lines via wrapper from PaintSwFrame
1651 nPDFType = vcl::PDFWriter::LILabel;
1652 aPDFType = aListLabelString;
1653 }
1654 break;
1655
1656 case PortionType::Tab :
1661 break;
1662 default: break;
1663 }
1664
1665 if ( USHRT_MAX != nPDFType )
1666 {
1667 BeginTag( static_cast<vcl::PDFWriter::StructElement>(nPDFType), aPDFType );
1668 }
1669}
1670
1672{
1673 vcl::PDFExtOutDevData* pPDFExtOutDevData = dynamic_cast< vcl::PDFExtOutDevData*>( rOut.GetExtOutDevData() );
1674 return pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportTaggedPDF();
1675}
1676
1678 OutputDevice& rOut,
1679 const OUString& rPageRange,
1680 bool bSkipEmptyPages,
1681 bool bEditEngineOnly,
1682 const SwPrintData& rPrintData )
1683 : mrSh( rSh ),
1684 mrOut( rOut ),
1685 mbSkipEmptyPages( bSkipEmptyPages ),
1686 mbEditEngineOnly( bEditEngineOnly ),
1687 mrPrintData( rPrintData )
1688{
1689 if ( !rPageRange.isEmpty() )
1690 mpRangeEnum.reset( new StringRangeEnumerator( rPageRange, 0, mrSh.GetPageCount()-1 ) );
1691
1692 if ( mbSkipEmptyPages )
1693 {
1694 maPageNumberMap.resize( mrSh.GetPageCount() );
1695 const SwPageFrame* pCurrPage =
1696 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1697 sal_Int32 nPageNumber = 0;
1698 for ( size_t i = 0, n = maPageNumberMap.size(); i < n && pCurrPage; ++i )
1699 {
1700 if ( pCurrPage->IsEmptyPage() )
1701 maPageNumberMap[i] = -1;
1702 else
1703 maPageNumberMap[i] = nPageNumber++;
1704
1705 pCurrPage = static_cast<const SwPageFrame*>( pCurrPage->GetNext() );
1706 }
1707 }
1708
1709 s_aTableColumnsMap.clear();
1710 s_aLinkIdMap.clear();
1711 s_aNumListIdMap.clear();
1712 s_aNumListBodyIdMap.clear();
1713 s_FrameTagSet.clear();
1714
1715#if OSL_DEBUG_LEVEL > 1
1716 aStructStack.clear();
1717#endif
1718
1720 sal_uInt16 nLangRes = RES_CHRATR_LANGUAGE;
1721
1722 if ( i18n::ScriptType::ASIAN == nScript )
1723 nLangRes = RES_CHRATR_CJK_LANGUAGE;
1724 else if ( i18n::ScriptType::COMPLEX == nScript )
1725 nLangRes = RES_CHRATR_CTL_LANGUAGE;
1726
1727 s_eLanguageDefault = static_cast<const SvxLanguageItem*>(&mrSh.GetDoc()->GetDefault( nLangRes ))->GetLanguage();
1728
1730}
1731
1733{
1734}
1735
1737 const tools::Rectangle& rRectangle) const
1738{
1739 if (!::sw::IsShrinkPageForPostIts(mrSh, mrPrintData)) // tdf#148729
1740 {
1741 return rRectangle;
1742 }
1743 //the page has been scaled by 75% and vertically centered, so adjust these
1744 //rectangles equivalently
1745 tools::Rectangle aRect(rRectangle);
1746 Size aRectSize(aRect.GetSize());
1747 double fScale = 0.75;
1748 aRectSize.setWidth( aRectSize.Width() * fScale );
1749 aRectSize.setHeight( aRectSize.Height() * fScale );
1750 tools::Long nOrigHeight = pCurrPage->getFrameArea().Height();
1751 tools::Long nNewHeight = nOrigHeight*fScale;
1752 tools::Long nShiftY = (nOrigHeight-nNewHeight)/2;
1753 aRect.SetLeft( aRect.Left() * fScale );
1754 aRect.SetTop( aRect.Top() * fScale );
1755 aRect.Move(0, nShiftY);
1756 aRect.SetSize(aRectSize);
1757 return aRect;
1758}
1759
1761{
1762 vcl::PDFExtOutDevData* pPDFExtOutDevData =
1763 dynamic_cast< vcl::PDFExtOutDevData*>( mrOut.GetExtOutDevData() );
1764
1765 if ( !pPDFExtOutDevData )
1766 return;
1767
1768 // set the document locale
1769
1770 css::lang::Locale aDocLocale( LanguageTag( SwEnhancedPDFExportHelper::GetDefaultLanguage() ).getLocale() );
1771 pPDFExtOutDevData->SetDocumentLocale( aDocLocale );
1772
1773 // Prepare the output device:
1774
1776 MapMode aMapMode( mrOut.GetMapMode() );
1777 aMapMode.SetMapUnit( MapUnit::MapTwip );
1778 mrOut.SetMapMode( aMapMode );
1779
1780 // Create new cursor and lock the view:
1781
1782 SwDoc* pDoc = mrSh.GetDoc();
1783 mrSh.SwCursorShell::Push();
1784 mrSh.SwCursorShell::ClearMark();
1785 const bool bOldLockView = mrSh.IsViewLocked();
1786 mrSh.LockView( true );
1787
1788 if ( !mbEditEngineOnly )
1789 {
1790
1791 // POSTITS
1792
1793 if ( pPDFExtOutDevData->GetIsExportNotes() )
1794 {
1795 std::vector<SwFormatField*> vpFields;
1796 mrSh.GetFieldType(SwFieldIds::Postit, OUString())->GatherFields(vpFields);
1797 for(auto pFormatField : vpFields)
1798 {
1799 const SwTextNode* pTNd = pFormatField->GetTextField()->GetpTextNode();
1800 OSL_ENSURE(nullptr != pTNd, "Enhanced pdf export - text node is missing");
1801 if(!lcl_TryMoveToNonHiddenField(mrSh, *pTNd, *pFormatField))
1802 continue;
1803 // Link Rectangle
1804 const SwRect& rNoteRect = mrSh.GetCharRect();
1805 const SwPageFrame* pCurrPage = static_cast<const SwPageFrame*>(mrSh.GetLayout()->Lower());
1806
1807 // Link PageNums
1808 std::vector<sal_Int32> aNotePageNums = CalcOutputPageNums(rNoteRect);
1809 for (sal_Int32 aNotePageNum : aNotePageNums)
1810 {
1811
1812 // Use the NumberFormatter to get the date string:
1813 const SwPostItField* pField = static_cast<SwPostItField*>(pFormatField->GetField());
1814 SvNumberFormatter* pNumFormatter = pDoc->GetNumberFormatter();
1815 const Date aDateDiff(pField->GetDate() - pNumFormatter->GetNullDate());
1816 const sal_uLong nFormat = pNumFormatter->GetStandardFormat(SvNumFormatType::DATE, pField->GetLanguage());
1817 OUString sDate;
1818 const Color* pColor;
1819 pNumFormatter->GetOutputString(aDateDiff.GetDate(), nFormat, sDate, &pColor);
1820
1821 vcl::PDFNote aNote;
1822 // The title should consist of the author and the date:
1823 aNote.Title = pField->GetPar1() + ", " + sDate + ", " + (pField->GetResolved() ? SwResId(STR_RESOLVED) : "");
1824 // Guess what the contents contains...
1825 aNote.Contents = pField->GetText();
1826
1827 // Link Export
1828 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rNoteRect.SVRect()));
1829 pPDFExtOutDevData->CreateNote(aRect, aNote, aNotePageNum);
1830 }
1831 mrSh.SwCursorShell::ClearMark();
1832 }
1833 }
1834
1835 // HYPERLINKS
1836
1839 for( auto &rAttr : aArr )
1840 {
1841 SwGetINetAttr* p = &rAttr;
1842 OSL_ENSURE( nullptr != p, "Enhanced pdf export - SwGetINetAttr is missing" );
1843
1844 const SwTextNode* pTNd = p->rINetAttr.GetpTextNode();
1845 OSL_ENSURE( nullptr != pTNd, "Enhanced pdf export - text node is missing" );
1846
1847 // 1. Check if the whole paragraph is hidden
1848 // 2. Move to the hyperlink
1849 // 3. Check for hidden text attribute
1850 if ( !pTNd->IsHidden() &&
1851 mrSh.GotoINetAttr( p->rINetAttr ) &&
1852 !mrSh.IsInHiddenRange(/*bSelect=*/false) )
1853 {
1854 // Select the hyperlink:
1855 mrSh.SwCursorShell::Right( 1, SwCursorSkipMode::Chars );
1856 if ( mrSh.SwCursorShell::SelectTextAttr( RES_TXTATR_INETFMT, true ) )
1857 {
1858 // First, we create the destination, because there may be more
1859 // than one link to this destination:
1860 OUString aURL( INetURLObject::decode(
1861 p->rINetAttr.GetINetFormat().GetValue(),
1863
1864 // We have to distinguish between internal and real URLs
1865 const bool bInternal = '#' == aURL[0];
1866
1867 // GetCursor_() is a SwShellCursor, which is derived from
1868 // SwSelPaintRects, therefore the rectangles of the current
1869 // selection can be easily obtained:
1870 // Note: We make a copy of the rectangles, because they may
1871 // be deleted again in JumpToSwMark.
1872 SwRects aTmp;
1873 aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() );
1874 OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
1875 OUString const altText(mrSh.GetSelText());
1876
1877 const SwPageFrame* pSelectionPage =
1878 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1879
1880 // Create the destination for internal links:
1881 sal_Int32 nDestId = -1;
1882 if ( bInternal )
1883 {
1884 aURL = aURL.copy( 1 );
1885 mrSh.SwCursorShell::ClearMark();
1886 if (! JumpToSwMark( &mrSh, aURL ))
1887 {
1888 continue; // target deleted
1889 }
1890
1891 // Destination Rectangle
1892 const SwRect& rDestRect = mrSh.GetCharRect();
1893
1894 const SwPageFrame* pCurrPage =
1895 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1896
1897 // Destination PageNum
1898 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
1899
1900 // Destination Export
1901 if ( -1 != nDestPageNum )
1902 {
1903 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
1904 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
1905 }
1906 }
1907
1908 if ( !bInternal || -1 != nDestId )
1909 {
1910 // #i44368# Links in Header/Footer
1911 const bool bHeaderFooter = pDoc->IsInHeaderFooter( *pTNd );
1912
1913 // Create links for all selected rectangles:
1914 const size_t nNumOfRects = aTmp.size();
1915 for ( size_t i = 0; i < nNumOfRects; ++i )
1916 {
1917 // Link Rectangle
1918 const SwRect& rLinkRect( aTmp[ i ] );
1919
1920 // Link PageNums
1921 std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( rLinkRect );
1922
1923 for (sal_Int32 aLinkPageNum : aLinkPageNums)
1924 {
1925 // Link Export
1926 tools::Rectangle aRect(SwRectToPDFRect(pSelectionPage, rLinkRect.SVRect()));
1927 const sal_Int32 nLinkId =
1928 pPDFExtOutDevData->CreateLink(aRect, altText, aLinkPageNum);
1929
1930 // Store link info for tagged pdf output:
1931 const IdMapEntry aLinkEntry( rLinkRect, nLinkId );
1932 s_aLinkIdMap.push_back( aLinkEntry );
1933
1934 // Connect Link and Destination:
1935 if ( bInternal )
1936 pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
1937 else
1938 pPDFExtOutDevData->SetLinkURL( nLinkId, aURL );
1939
1940 // #i44368# Links in Header/Footer
1941 if ( bHeaderFooter )
1942 MakeHeaderFooterLinks(*pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, aURL, bInternal, altText);
1943 }
1944 }
1945 }
1946 }
1947 }
1948 mrSh.SwCursorShell::ClearMark();
1949 }
1950
1951 // HYPERLINKS (Graphics, Frames, OLEs )
1952
1953 for(sw::SpzFrameFormat* pFrameFormat: *pDoc->GetSpzFrameFormats())
1954 {
1955 const SwFormatURL* pItem;
1956 if ( RES_DRAWFRMFMT != pFrameFormat->Which() &&
1957 GetFrameOfModify(mrSh.GetLayout(), *pFrameFormat, SwFrameType::Fly) &&
1958 (pItem = pFrameFormat->GetAttrSet().GetItemIfSet( RES_URL )) )
1959 {
1960 const SwPageFrame* pCurrPage =
1961 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1962
1963 OUString aURL( pItem->GetURL() );
1964 if (aURL.isEmpty())
1965 continue;
1966 const bool bInternal = '#' == aURL[0];
1967
1968 // Create the destination for internal links:
1969 sal_Int32 nDestId = -1;
1970 if ( bInternal )
1971 {
1972 aURL = aURL.copy( 1 );
1973 mrSh.SwCursorShell::ClearMark();
1974 if (! JumpToSwMark( &mrSh, aURL ))
1975 {
1976 continue; // target deleted
1977 }
1978
1979 // Destination Rectangle
1980 const SwRect& rDestRect = mrSh.GetCharRect();
1981
1982 pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
1983
1984 // Destination PageNum
1985 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
1986
1987 // Destination Export
1988 if ( -1 != nDestPageNum )
1989 {
1990 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
1991 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
1992 }
1993 }
1994
1995 if ( !bInternal || -1 != nDestId )
1996 {
1997 Point aNullPt;
1998 const SwRect aLinkRect = pFrameFormat->FindLayoutRect( false, &aNullPt );
1999 OUString const formatName(pFrameFormat->GetName());
2000 // Link PageNums
2001 std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( aLinkRect );
2002
2003 // Link Export
2004 for (sal_Int32 aLinkPageNum : aLinkPageNums)
2005 {
2006 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, aLinkRect.SVRect()));
2007 const sal_Int32 nLinkId =
2008 pPDFExtOutDevData->CreateLink(aRect, formatName, aLinkPageNum);
2009
2010 // Store link info for tagged pdf output:
2011 const IdMapEntry aLinkEntry(aLinkRect, nLinkId);
2012 s_aLinkIdMap.push_back(aLinkEntry);
2013
2014 // Connect Link and Destination:
2015 if ( bInternal )
2016 pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
2017 else
2018 pPDFExtOutDevData->SetLinkURL( nLinkId, aURL );
2019
2020 // #i44368# Links in Header/Footer
2021 const SwFormatAnchor &rAnch = pFrameFormat->GetAnchor();
2022 if (RndStdIds::FLY_AT_PAGE != rAnch.GetAnchorId())
2023 {
2024 const SwNode* pAnchorNode = rAnch.GetAnchorNode();
2025 if ( pAnchorNode && pDoc->IsInHeaderFooter( *pAnchorNode ) )
2026 {
2027 const SwTextNode* pTNd = pAnchorNode->GetTextNode();
2028 if ( pTNd )
2029 MakeHeaderFooterLinks(*pPDFExtOutDevData, *pTNd, aLinkRect, nDestId, aURL, bInternal, formatName);
2030 }
2031 }
2032 }
2033 }
2034 }
2035 else if (pFrameFormat->Which() == RES_DRAWFRMFMT)
2036 {
2037 // Turn media shapes into Screen annotations.
2038 if (SdrObject* pObject = pFrameFormat->FindRealSdrObject())
2039 {
2040 SwRect aSnapRect(pObject->GetSnapRect());
2041 std::vector<sal_Int32> aScreenPageNums = CalcOutputPageNums(aSnapRect);
2042 if (aScreenPageNums.empty())
2043 continue;
2044
2045 uno::Reference<drawing::XShape> xShape(pObject->getUnoShape(), uno::UNO_QUERY);
2046 if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape")
2047 {
2048 uno::Reference<beans::XPropertySet> xShapePropSet(xShape, uno::UNO_QUERY);
2049 OUString title;
2050 xShapePropSet->getPropertyValue("Title") >>= title;
2051 OUString description;
2052 xShapePropSet->getPropertyValue("Description") >>= description;
2053 OUString const altText(title.isEmpty()
2054 ? description
2055 : description.isEmpty()
2056 ? title
2057 : OUString::Concat(title) + OUString::Concat("\n") + OUString::Concat(description));
2058
2059 OUString aMediaURL;
2060 xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
2061 if (!aMediaURL.isEmpty())
2062 {
2063 OUString const mimeType(xShapePropSet->getPropertyValue("MediaMimeType").get<OUString>());
2064 const SwPageFrame* pCurrPage = mrSh.GetLayout()->GetPageAtPos(aSnapRect.Center());
2065 tools::Rectangle aPDFRect(SwRectToPDFRect(pCurrPage, aSnapRect.SVRect()));
2066 for (sal_Int32 nScreenPageNum : aScreenPageNums)
2067 {
2068 sal_Int32 nScreenId = pPDFExtOutDevData->CreateScreen(aPDFRect, altText, mimeType, nScreenPageNum, pObject);
2069 if (aMediaURL.startsWith("vnd.sun.star.Package:"))
2070 {
2071 // Embedded media.
2072 OUString aTempFileURL;
2073 xShapePropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL;
2074 pPDFExtOutDevData->SetScreenStream(nScreenId, aTempFileURL);
2075 }
2076 else
2077 // Linked media.
2078 pPDFExtOutDevData->SetScreenURL(nScreenId, aMediaURL);
2079 }
2080 }
2081 }
2082 }
2083 }
2084 mrSh.SwCursorShell::ClearMark();
2085 }
2086
2087 // REFERENCES
2088
2089 std::vector<SwFormatField*> vpFields;
2090 mrSh.GetFieldType( SwFieldIds::GetRef, OUString() )->GatherFields(vpFields);
2091 for(auto pFormatField : vpFields )
2092 {
2093 if( pFormatField->GetTextField() && pFormatField->IsFieldInDoc() )
2094 {
2095 const SwTextNode* pTNd = pFormatField->GetTextField()->GetpTextNode();
2096 OSL_ENSURE( nullptr != pTNd, "Enhanced pdf export - text node is missing" );
2097 if(!lcl_TryMoveToNonHiddenField(mrSh, *pTNd, *pFormatField))
2098 continue;
2099 // Select the field:
2100 mrSh.SwCursorShell::SetMark();
2101 mrSh.SwCursorShell::Right( 1, SwCursorSkipMode::Chars );
2102
2103 // Link Rectangles
2104 SwRects aTmp;
2105 aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() );
2106 OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
2107
2108 mrSh.SwCursorShell::ClearMark();
2109
2110 // Destination Rectangle
2111 const SwGetRefField* pField = static_cast<SwGetRefField*>(pFormatField->GetField());
2112 const OUString& rRefName = pField->GetSetRefName();
2113 mrSh.GotoRefMark( rRefName, pField->GetSubType(), pField->GetSeqNo() );
2114 const SwRect& rDestRect = mrSh.GetCharRect();
2115
2116 const SwPageFrame* pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2117
2118 // Destination PageNum
2119 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2120
2121 if ( -1 != nDestPageNum )
2122 {
2123 // Destination Export
2124 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2125 const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2126
2127 // #i44368# Links in Header/Footer
2128 const bool bHeaderFooter = pDoc->IsInHeaderFooter( *pTNd );
2129 OUString const content(pField->ExpandField(true, mrSh.GetLayout()));
2130
2131 // Create links for all selected rectangles:
2132 const size_t nNumOfRects = aTmp.size();
2133 for ( size_t i = 0; i < nNumOfRects; ++i )
2134 {
2135 // Link rectangle
2136 const SwRect& rLinkRect( aTmp[ i ] );
2137
2138 // Link PageNums
2139 std::vector<sal_Int32> aLinkPageNums = CalcOutputPageNums( rLinkRect );
2140
2141 for (sal_Int32 aLinkPageNum : aLinkPageNums)
2142 {
2143 // Link Export
2144 aRect = SwRectToPDFRect(pCurrPage, rLinkRect.SVRect());
2145 const sal_Int32 nLinkId =
2146 pPDFExtOutDevData->CreateLink(aRect, content, aLinkPageNum);
2147
2148 // Store link info for tagged pdf output:
2149 const IdMapEntry aLinkEntry( rLinkRect, nLinkId );
2150 s_aLinkIdMap.push_back( aLinkEntry );
2151
2152 // Connect Link and Destination:
2153 pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
2154
2155 // #i44368# Links in Header/Footer
2156 if ( bHeaderFooter )
2157 {
2158 MakeHeaderFooterLinks(*pPDFExtOutDevData, *pTNd, rLinkRect, nDestId, "", true, content);
2159 }
2160 }
2161 }
2162 }
2163 }
2164 mrSh.SwCursorShell::ClearMark();
2165 }
2166
2168
2169 // FOOTNOTES
2170
2171 const size_t nFootnoteCount = pDoc->GetFootnoteIdxs().size();
2172 for ( size_t nIdx = 0; nIdx < nFootnoteCount; ++nIdx )
2173 {
2174 // Set cursor to text node that contains the footnote:
2175 const SwTextFootnote* pTextFootnote = pDoc->GetFootnoteIdxs()[ nIdx ];
2176 SwTextNode& rTNd = const_cast<SwTextNode&>(pTextFootnote->GetTextNode());
2177
2178 mrSh.GetCursor_()->GetPoint()->Assign(rTNd, pTextFootnote->GetStart());
2179
2180 // 1. Check if the whole paragraph is hidden
2181 // 2. Check for hidden text attribute
2182 if (rTNd.GetTextNode()->IsHidden() || mrSh.IsInHiddenRange(/*bSelect=*/false)
2184 && sw::IsFootnoteDeleted(pDoc->getIDocumentRedlineAccess(), *pTextFootnote)))
2185 {
2186 continue;
2187 }
2188
2189 SwCursorSaveState aSaveState( *mrSh.GetCursor_() );
2190
2191 // Select the footnote:
2192 mrSh.SwCursorShell::SetMark();
2193 mrSh.SwCursorShell::Right( 1, SwCursorSkipMode::Chars );
2194
2195 // Link Rectangle
2196 SwRects aTmp;
2197 aTmp.insert( aTmp.begin(), mrSh.SwCursorShell::GetCursor_()->begin(), mrSh.SwCursorShell::GetCursor_()->end() );
2198 OSL_ENSURE( !aTmp.empty(), "Enhanced pdf export - rectangles are missing" );
2199
2201 mrSh.SwCursorShell::ClearMark();
2202
2203 if (aTmp.empty())
2204 continue;
2205
2206 const SwRect aLinkRect( aTmp[ 0 ] );
2207
2208 // Goto footnote text:
2209 if ( mrSh.GotoFootnoteText() )
2210 {
2211 // Destination Rectangle
2212 const SwRect& rDestRect = mrSh.GetCharRect();
2213 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2214 if ( -1 != nDestPageNum )
2215 {
2216 const SwPageFrame* pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2217 // Destination PageNum
2218 tools::Rectangle aRect = SwRectToPDFRect(pCurrPage, rDestRect.SVRect());
2219 // Back link rectangle calculation
2220 const SwPageFrame* fnBodyPage = pCurrPage->getRootFrame()->GetPageByPageNum(nDestPageNum+1);
2221 SwRect fnSymbolRect;
2222 if (fnBodyPage->IsVertical()){
2223 tools::Long fnSymbolTop = fnBodyPage->GetTopMargin() + fnBodyPage->getFrameArea().Top();
2224 tools::Long symbolHeight = rDestRect.Top() - fnSymbolTop;
2225 fnSymbolRect = SwRect(rDestRect.Pos().X(),fnSymbolTop,rDestRect.Width(),symbolHeight);
2226 } else {
2227 if (fnBodyPage->IsRightToLeft()){
2228 tools::Long fnSymbolRight = fnBodyPage->getFrameArea().Right() - fnBodyPage->GetRightMargin();
2229 tools::Long symbolWidth = fnSymbolRight - rDestRect.Right();
2230 fnSymbolRect = SwRect(rDestRect.Pos().X(),rDestRect.Pos().Y(),symbolWidth,rDestRect.Height());
2231 } else {
2232 tools::Long fnSymbolLeft = fnBodyPage->GetLeftMargin() + fnBodyPage->getFrameArea().Left();
2233 tools::Long symbolWidth = rDestRect.Left() - fnSymbolLeft;
2234 fnSymbolRect = SwRect(fnSymbolLeft,rDestRect.Pos().Y(),symbolWidth,rDestRect.Height());
2235 }
2236 }
2237 tools::Rectangle aFootnoteSymbolRect = SwRectToPDFRect(pCurrPage, fnSymbolRect.SVRect());
2238
2239 OUString const numStrSymbol(pTextFootnote->GetFootnote().GetViewNumStr(*pDoc, mrSh.GetLayout(), true));
2240 OUString const numStrRef(pTextFootnote->GetFootnote().GetViewNumStr(*pDoc, mrSh.GetLayout(), false));
2241
2242 // Export back link
2243 const sal_Int32 nBackLinkId = pPDFExtOutDevData->CreateLink(aFootnoteSymbolRect, numStrSymbol, nDestPageNum);
2244 // Destination Export
2245 const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2247 // Link PageNums
2248 sal_Int32 aLinkPageNum = CalcOutputPageNum( aLinkRect );
2249 pCurrPage = static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2250 // Link Export
2251 aRect = SwRectToPDFRect(pCurrPage, aLinkRect.SVRect());
2252 const sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, numStrRef, aLinkPageNum);
2253 // Back link destination Export
2254 const sal_Int32 nBackDestId = pPDFExtOutDevData->CreateDest(aRect, aLinkPageNum);
2255 // Store link info for tagged pdf output:
2256 const IdMapEntry aLinkEntry( aLinkRect, nLinkId );
2257 s_aLinkIdMap.push_back( aLinkEntry );
2258
2259 // Store backlink info for tagged pdf output:
2260 const IdMapEntry aBackLinkEntry( aFootnoteSymbolRect, nBackLinkId );
2261 s_aLinkIdMap.push_back( aBackLinkEntry );
2262 // Connect Links and Destinations:
2263 pPDFExtOutDevData->SetLinkDest( nLinkId, nDestId );
2264 pPDFExtOutDevData->SetLinkDest( nBackLinkId, nBackDestId );
2265 }
2266 }
2267 }
2268
2269 // OUTLINE
2270
2271 if( pPDFExtOutDevData->GetIsExportBookmarks() )
2272 {
2273 typedef std::pair< sal_Int8, sal_Int32 > StackEntry;
2274 std::stack< StackEntry > aOutlineStack;
2275 aOutlineStack.push( StackEntry( -1, -1 ) ); // push default value
2276
2277 const SwOutlineNodes::size_type nOutlineCount =
2279 for ( SwOutlineNodes::size_type i = 0; i < nOutlineCount; ++i )
2280 {
2281 // Check if outline is hidden
2282 const SwTextNode* pTNd = mrSh.GetNodes().GetOutLineNds()[ i ]->GetTextNode();
2283 OSL_ENSURE( nullptr != pTNd, "Enhanced pdf export - text node is missing" );
2284
2285 if ( pTNd->IsHidden() ||
2286 !sw::IsParaPropsNode(*mrSh.GetLayout(), *pTNd) ||
2287 // #i40292# Skip empty outlines:
2288 pTNd->GetText().isEmpty())
2289 continue;
2290
2291 // Get parent id from stack:
2292 const sal_Int8 nLevel = static_cast<sal_Int8>(mrSh.getIDocumentOutlineNodesAccess()->getOutlineLevel( i ));
2293 sal_Int8 nLevelOnTopOfStack = aOutlineStack.top().first;
2294 while ( nLevelOnTopOfStack >= nLevel &&
2295 nLevelOnTopOfStack != -1 )
2296 {
2297 aOutlineStack.pop();
2298 nLevelOnTopOfStack = aOutlineStack.top().first;
2299 }
2300 const sal_Int32 nParent = aOutlineStack.top().second;
2301
2302 // Destination rectangle
2304 const SwRect& rDestRect = mrSh.GetCharRect();
2305
2306 const SwPageFrame* pCurrPage =
2307 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2308
2309 // Destination PageNum
2310 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2311
2312 if ( -1 != nDestPageNum )
2313 {
2314 // Destination Export
2315 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2316 const sal_Int32 nDestId =
2317 pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2318
2319 // Outline entry text
2320 const OUString& rEntry = mrSh.getIDocumentOutlineNodesAccess()->getOutlineText(
2321 i, mrSh.GetLayout(), true, false, false );
2322
2323 // Create a new outline item:
2324 const sal_Int32 nOutlineId =
2325 pPDFExtOutDevData->CreateOutlineItem( nParent, rEntry, nDestId );
2326
2327 // Push current level and nOutlineId on stack:
2328 aOutlineStack.push( StackEntry( nLevel, nOutlineId ) );
2329 }
2330 }
2331 }
2332
2333 if( pPDFExtOutDevData->GetIsExportNamedDestinations() )
2334 {
2335 // #i56629# the iteration to convert the OOo bookmark (#bookmark)
2336 // into PDF named destination, see section 8.2.1 in PDF 1.4 spec
2337 // We need:
2338 // 1. a name for the destination, formed from the standard OOo bookmark name
2339 // 2. the destination, obtained from where the bookmark destination lies
2340 IDocumentMarkAccess* const pMarkAccess = mrSh.GetDoc()->getIDocumentMarkAccess();
2341 for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
2342 ppMark != pMarkAccess->getBookmarksEnd();
2343 ++ppMark)
2344 {
2345 //get the name
2346 const ::sw::mark::IMark* pBkmk = *ppMark;
2347 mrSh.SwCursorShell::ClearMark();
2348 const OUString& sBkName = pBkmk->GetName();
2349
2350 //jump to it
2351 if (! JumpToSwMark( &mrSh, sBkName ))
2352 {
2353 continue;
2354 }
2355
2356 // Destination Rectangle
2357 const SwRect& rDestRect = mrSh.GetCharRect();
2358
2359 const SwPageFrame* pCurrPage =
2360 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2361
2362 // Destination PageNum
2363 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2364
2365 // Destination Export
2366 if ( -1 != nDestPageNum )
2367 {
2368 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2369 pPDFExtOutDevData->CreateNamedDest(sBkName, aRect, nDestPageNum);
2370 }
2371 }
2372 mrSh.SwCursorShell::ClearMark();
2373 //<--- i56629
2374 }
2375 }
2376 else
2377 {
2378
2379 // LINKS FROM EDITENGINE
2380
2381 std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
2382 for ( const auto& rBookmark : rBookmarks )
2383 {
2384 OUString aBookmarkName( rBookmark.aBookmark );
2385 const bool bInternal = '#' == aBookmarkName[0];
2386 if ( bInternal )
2387 {
2388 aBookmarkName = aBookmarkName.copy( 1 );
2389 JumpToSwMark( &mrSh, aBookmarkName );
2390
2391 // Destination Rectangle
2392 const SwRect& rDestRect = mrSh.GetCharRect();
2393
2394 const SwPageFrame* pCurrPage =
2395 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2396
2397 // Destination PageNum
2398 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2399
2400 if ( -1 != nDestPageNum )
2401 {
2402 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2403 if ( rBookmark.nLinkId != -1 )
2404 {
2405 // Destination Export
2406 const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2407
2408 // Connect Link and Destination:
2409 pPDFExtOutDevData->SetLinkDest( rBookmark.nLinkId, nDestId );
2410 }
2411 else
2412 {
2413 pPDFExtOutDevData->DescribeRegisteredDest(rBookmark.nDestId, aRect, nDestPageNum);
2414 }
2415 }
2416 }
2417 else
2418 pPDFExtOutDevData->SetLinkURL( rBookmark.nLinkId, aBookmarkName );
2419 }
2420 rBookmarks.clear();
2421 }
2422
2423 // Restore view, cursor, and outdev:
2424 mrSh.LockView( bOldLockView );
2425 mrSh.SwCursorShell::Pop(SwCursorShell::PopMode::DeleteCurrent);
2426 mrOut.Pop();
2427}
2428
2430{
2431 auto pPDFExtOutDevData = dynamic_cast<vcl::PDFExtOutDevData*>(mrOut.GetExtOutDevData());
2432 if (!pPDFExtOutDevData)
2433 {
2434 return;
2435 }
2436
2437 // Create PDF destinations for bibliography table entries
2438 std::vector<std::tuple<const SwTOXBase*, const OUString*, sal_Int32>> vDestinations;
2439 // string is the row node text, sal_Int32 is number of the destination
2440 // Note: This way of iterating doesn't seem to take into account TOXes
2441 // that are in a frame, probably in some other cases too
2442 {
2443 mrSh.GotoPage(1);
2444 while (mrSh.GotoNextTOXBase())
2445 {
2446 const SwTOXBase* pIteratedTOX = nullptr;
2447 while ((pIteratedTOX = mrSh.GetCurTOX()) != nullptr
2448 && pIteratedTOX->GetType() == TOX_AUTHORITIES)
2449 {
2450 if (const SwNode& rCurrentNode = mrSh.GetCursor()->GetPoint()->GetNode();
2451 rCurrentNode.GetNodeType() == SwNodeType::Text)
2452 {
2454 == SectionType::ToxContent) // this checks it's not a heading
2455 {
2456 // Destination Rectangle
2457 const SwRect& rDestRect = mrSh.GetCharRect();
2458
2459 const SwPageFrame* pCurrPage =
2460 static_cast<const SwPageFrame*>( mrSh.GetLayout()->Lower() );
2461
2462 // Destination PageNum
2463 const sal_Int32 nDestPageNum = CalcOutputPageNum( rDestRect );
2464
2465 // Destination Export
2466 if ( -1 != nDestPageNum )
2467 {
2468 tools::Rectangle aRect(SwRectToPDFRect(pCurrPage, rDestRect.SVRect()));
2469 const sal_Int32 nDestId = pPDFExtOutDevData->CreateDest(aRect, nDestPageNum);
2470 const OUString* vNodeText = &static_cast<const SwTextNode*>(&rCurrentNode)->GetText();
2471 vDestinations.emplace_back(pIteratedTOX, vNodeText, nDestId);
2472 }
2473 }
2474 }
2476 }
2477 }
2478 }
2479
2480 // Generate links to matching entries in the bibliography tables
2481 std::vector<SwFormatField*> aFields;
2483 if (!pType)
2484 {
2485 return;
2486 }
2487
2488 pType->GatherFields(aFields);
2489 const auto pPageFrame = static_cast<const SwPageFrame*>(mrSh.GetLayout()->Lower());
2490 for (const auto pFormatField : aFields)
2491 {
2492 if (!pFormatField->GetTextField() || !pFormatField->IsFieldInDoc())
2493 {
2494 continue;
2495 }
2496
2497 const auto& rAuthorityField
2498 = *static_cast<const SwAuthorityField*>(pFormatField->GetField());
2499
2500 if (auto targetType = rAuthorityField.GetTargetType();
2501 targetType == SwAuthorityField::TargetType::UseDisplayURL
2502 || targetType == SwAuthorityField::TargetType::UseTargetURL)
2503 {
2504 // Since the target type specifies to use an URL, link to it
2505 const OUString& rURL = rAuthorityField.GetAbsoluteURL();
2506 if (rURL.getLength() == 0)
2507 {
2508 continue;
2509 }
2510
2511 const SwTextNode& rTextNode = pFormatField->GetTextField()->GetTextNode();
2512 if (!lcl_TryMoveToNonHiddenField(mrSh, rTextNode, *pFormatField))
2513 {
2514 continue;
2515 }
2516
2517 OUString const content(rAuthorityField.ExpandField(true, mrSh.GetLayout()));
2518
2519 // Select the field.
2520 mrSh.SwCursorShell::SetMark();
2521 mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars);
2522
2523 // Create the links.
2524 for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_())
2525 {
2526 for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
2527 {
2528 tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, rLinkRect.SVRect()));
2529 sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, content, rLinkPageNum);
2530 IdMapEntry aLinkEntry(rLinkRect, nLinkId);
2531 s_aLinkIdMap.push_back(aLinkEntry);
2532 pPDFExtOutDevData->SetLinkURL(nLinkId, rURL);
2533 }
2534 }
2535 mrSh.SwCursorShell::ClearMark();
2536 }
2537 else if (targetType == SwAuthorityField::TargetType::BibliographyTableRow)
2538 {
2539 // As the target type specifies, try linking to a bibliography table row
2540 sal_Int32 nDestId = -1;
2541
2542 std::unordered_map<const SwTOXBase*, OUString> vFormattedFieldStrings;
2543 for (const auto& rDestinationTuple : vDestinations)
2544 {
2545 if (vFormattedFieldStrings.find(std::get<0>(rDestinationTuple))
2546 == vFormattedFieldStrings.end())
2547 vFormattedFieldStrings.emplace(std::get<0>(rDestinationTuple),
2548 rAuthorityField.GetAuthority(mrSh.GetLayout(),
2549 &std::get<0>(rDestinationTuple)->GetTOXForm()));
2550
2551 if (vFormattedFieldStrings.at(std::get<0>(rDestinationTuple)) == *std::get<1>(rDestinationTuple))
2552 {
2553 nDestId = std::get<2>(rDestinationTuple);
2554 break;
2555 }
2556 }
2557
2558 if (nDestId == -1)
2559 continue;
2560
2561 const SwTextNode& rTextNode = pFormatField->GetTextField()->GetTextNode();
2562 if (!lcl_TryMoveToNonHiddenField(mrSh, rTextNode, *pFormatField))
2563 {
2564 continue;
2565 }
2566
2567 OUString const content(rAuthorityField.ExpandField(true, mrSh.GetLayout()));
2568
2569 // Select the field.
2570 mrSh.SwCursorShell::SetMark();
2571 mrSh.SwCursorShell::Right(1, SwCursorSkipMode::Chars);
2572
2573 // Create the links.
2574 for (const auto& rLinkRect : *mrSh.SwCursorShell::GetCursor_())
2575 {
2576 for (const auto& rLinkPageNum : CalcOutputPageNums(rLinkRect))
2577 {
2578 tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, rLinkRect.SVRect()));
2579 sal_Int32 nLinkId = pPDFExtOutDevData->CreateLink(aRect, content, rLinkPageNum);
2580 IdMapEntry aLinkEntry(rLinkRect, nLinkId);
2581 s_aLinkIdMap.push_back(aLinkEntry);
2582 pPDFExtOutDevData->SetLinkDest(nLinkId, nDestId);
2583 }
2584 }
2585 mrSh.SwCursorShell::ClearMark();
2586 }
2587 }
2588}
2589
2590// Returns the page number in the output pdf on which the given rect is located.
2591// If this page is duplicated, method will return first occurrence of it.
2593{
2594 std::vector< sal_Int32 > aPageNums = CalcOutputPageNums( rRect );
2595 if ( !aPageNums.empty() )
2596 return aPageNums[0];
2597 return -1;
2598}
2599
2600// Returns a vector of the page numbers in the output pdf on which the given
2601// rect is located. There can be many such pages since StringRangeEnumerator
2602// allows duplication of its entries.
2604 const SwRect& rRect ) const
2605{
2606 std::vector< sal_Int32 > aPageNums;
2607
2608 // Document page number.
2609 sal_Int32 nPageNumOfRect = mrSh.GetPageNumAndSetOffsetForPDF( mrOut, rRect );
2610 if ( nPageNumOfRect < 0 )
2611 return aPageNums;
2612
2613 // What will be the page numbers of page nPageNumOfRect in the output pdf?
2614 if ( mpRangeEnum )
2615 {
2616 if ( mbSkipEmptyPages )
2617 // Map the page number to the range without empty pages.
2618 nPageNumOfRect = maPageNumberMap[ nPageNumOfRect ];
2619
2620 if ( mpRangeEnum->hasValue( nPageNumOfRect ) )
2621 {
2622 sal_Int32 nOutputPageNum = 0;
2625 for ( ; aIter != aEnd; ++aIter )
2626 {
2627 if ( *aIter == nPageNumOfRect )
2628 aPageNums.push_back( nOutputPageNum );
2629 ++nOutputPageNum;
2630 }
2631 }
2632 }
2633 else
2634 {
2635 if ( mbSkipEmptyPages )
2636 {
2637 sal_Int32 nOutputPageNum = 0;
2638 for ( size_t i = 0; i < maPageNumberMap.size(); ++i )
2639 {
2640 if ( maPageNumberMap[i] >= 0 ) // is not empty?
2641 {
2642 if ( i == static_cast<size_t>( nPageNumOfRect ) )
2643 {
2644 aPageNums.push_back( nOutputPageNum );
2645 break;
2646 }
2647 ++nOutputPageNum;
2648 }
2649 }
2650 }
2651 else
2652 aPageNums.push_back( nPageNumOfRect );
2653 }
2654
2655 return aPageNums;
2656}
2657
2659 const SwTextNode& rTNd,
2660 const SwRect& rLinkRect,
2661 sal_Int32 nDestId,
2662 const OUString& rURL,
2663 bool bInternal,
2664 OUString const& rContent) const
2665{
2666 // We assume, that the primary link has just been exported. Therefore
2667 // the offset of the link rectangle calculates as follows:
2668 const Point aOffset = rLinkRect.Pos() + mrOut.GetMapMode().GetOrigin();
2669
2671 for ( SwTextFrame* pTmpFrame = aIter.First(); pTmpFrame; pTmpFrame = aIter.Next() )
2672 {
2673 // Add offset to current page:
2674 const SwPageFrame* pPageFrame = pTmpFrame->FindPageFrame();
2675 SwRect aHFLinkRect( rLinkRect );
2676 aHFLinkRect.Pos() = pPageFrame->getFrameArea().Pos() + aOffset;
2677
2678 // #i97135# the gcc_x64 optimizer gets aHFLinkRect != rLinkRect wrong
2679 // fool it by comparing the position only (the width and height are the
2680 // same anyway)
2681 if ( aHFLinkRect.Pos() != rLinkRect.Pos() )
2682 {
2683 // Link PageNums
2684 std::vector<sal_Int32> aHFLinkPageNums = CalcOutputPageNums( aHFLinkRect );
2685
2686 for (sal_Int32 aHFLinkPageNum : aHFLinkPageNums)
2687 {
2688 // Link Export
2689 tools::Rectangle aRect(SwRectToPDFRect(pPageFrame, aHFLinkRect.SVRect()));
2690 const sal_Int32 nHFLinkId =
2691 rPDFExtOutDevData.CreateLink(aRect, rContent, aHFLinkPageNum);
2692
2693 // Connect Link and Destination:
2694 if ( bInternal )
2695 rPDFExtOutDevData.SetLinkDest( nHFLinkId, nDestId );
2696 else
2697 rPDFExtOutDevData.SetLinkURL( nHFLinkId, rURL );
2698 }
2699 }
2700 }
2701}
2702
2703/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void lcl_DBGCheckStack()
static std::vector< sal_uInt16 > aStructStack
std::set< tools::Long, lt_TableColumn > TableColumnsMapEntry
std::set< const void * > FrameTagSet
std::map< const SwNumberTreeNode *, sal_Int32 > NumListIdMap
std::map< const SwNumberTreeNode *, sal_Int32 > NumListBodyIdMap
std::vector< IdMapEntry > LinkIdMap
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 SfxPoolItem & Get(sal_uInt16 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
const SwFrame * GetAnchorFrame() const
SwTextAttr * GetAttr(TextFrameIndex nPos) const
Returns the attribute for a position.
Definition: itratr.cxx:147
const SvxAdjustItem & GetAdjust(bool=true) const
Definition: paratr.hxx:203
Represents an inserted bibliography entry, created using Insert -> Table of Contents and Index -> Bib...
Definition: authfld.hxx:161
OUString GetAbsoluteURL() const
Returns absolute target URL in case there is one (GetTargetType() should be checked).
Definition: authfld.cxx:647
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:59
SwFormatColl * GetFormatColl() const
Definition: node.hxx:497
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:1404
SwShellCursor * GetCursor_()
Definition: crsrsh.hxx:343
const SwRect & GetCharRect() const
Definition: crsrsh.hxx:536
bool IsInHiddenRange(const bool bSelect)
If the current cursor position is inside a hidden range true is returned.
Definition: crsrsh.cxx:3780
bool GotoFootnoteAnchor()
jump from footnote to anchor
Definition: trvlfnfl.cxx:167
bool MovePara(SwWhichPara, SwMoveFnCollection const &)
Definition: crsrsh.cxx:982
bool GotoPage(sal_uInt16 nPage)
Definition: crsrsh.cxx:1488
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
OUString GetSelText() const
get selected text of a node at current cursor
Definition: crsrsh.cxx:2862
bool GotoFootnoteText()
jump from content to footnote
Definition: trvlfnfl.cxx:89
bool GotoNextTOXBase(const OUString *=nullptr)
jump to the next index
Definition: crstrvl.cxx:266
bool GotoOutline(const OUString &rName)
Definition: crstrvl.cxx:1173
bool GotoFormatField(const SwFormatField &rField)
Definition: crstrvl.cxx:1001
bool GotoINetAttr(const SwTextINetFormat &rAttr)
Definition: crstrvl.cxx:2285
void RestoreSavePos()
Restore cursor state to the one saved by SwCursorSaveState.
Definition: swcrsr.cxx:2339
Definition: doc.hxx:197
SwNodes & GetNodes()
Definition: doc.hxx:422
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:349
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:649
const SfxPoolItem & GetDefault(sal_uInt16 nFormatHint) const
Get the default attribute in this document.
Definition: docfmt.cxx:672
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1890
const sw::FrameFormats< sw::SpzFrameFormat * > * GetSpzFrameFormats() const
Definition: doc.hxx:759
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1429
bool IsInHeaderFooter(const SwNode &) const
Definition: doclay.cxx:1582
const SwFrame * GetAnchorFrame(const SdrObject *_pDrawObj=nullptr) const
Definition: dcontact.cxx:804
virtual void const * GetPDFAnchorStructureElementKey(SdrObject const &rObj) override
virtual const SwAnchoredObject * GetAnchoredObj(const SdrObject *_pSdrObj) const override
Definition: dcontact.cxx:762
void GetINetAttrs(SwGetINetAttrs &rArr, bool bIncludeInToxContent=true)
Definition: editsh.cxx:687
const SwTOXBase * GetCurTOX() const
Get current listing before or at the Cursor.
Definition: edtox.cxx:191
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 FrameTagSet & GetFrameTagSet()
static TableColumnsMap & GetTableColumnsMap()
static NumListBodyIdMap & GetNumListBodyIdMap()
sal_Int32 CalcOutputPageNum(const SwRect &rRect) const
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.
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
void MakeHeaderFooterLinks(vcl::PDFExtOutDevData &rPDFExtOutDevData, const SwTextNode &rTNd, const SwRect &rLinkRect, sal_Int32 nDestId, const OUString &rURL, bool bIntern, OUString const &rContent) const
std::unique_ptr< StringRangeEnumerator > mpRangeEnum
Instances of SwFields and those derived from it occur 0 to n times.
Definition: fldbas.hxx:247
void GatherFields(std::vector< SwFormatField * > &rvFormatFields, bool bCollectOnlyInDocNodes=true) const
Definition: fldbas.cxx:205
Base class of all fields.
Definition: fldbas.hxx:296
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
Definition: fldbas.cxx:491
SwFieldIds Which() const
ResId.
Definition: fldbas.cxx:263
LanguageType GetLanguage() const
Language at field position.
Definition: fldbas.hxx:412
OUString GetObjDescription() const
Definition: atrfrm.cxx:3226
OUString GetObjTitle() const
Definition: atrfrm.cxx:3184
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
virtual SwFrameFormat & GetFrameFormat() override
Definition: fly.cxx:3044
FontLineStyle GetUnderline() const
Definition: swfont.hxx:275
short GetEscapement() const
Definition: swfont.hxx:282
FontStrikeout GetStrikeout() const
Definition: swfont.hxx:279
FontEmphasisMark GetEmphasisMark() const
Definition: swfont.hxx:289
SwFontScript GetActual() const
Definition: swfont.hxx:187
FontLineStyle GetOverline() const
Definition: swfont.hxx:277
LanguageType GetLanguage() const
Definition: swfont.hxx:286
FlyAnchors.
Definition: fmtanchr.hxx:37
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1614
const SwField * GetField() const
Definition: fmtfld.hxx:131
OUString GetViewNumStr(const SwDoc &rDoc, SwRootFrame const *pLayout, bool bInclStrings=false) const
Returns string to be displayed of footnote / endnote.
Definition: atrftn.cxx:218
SfxPoolItem subclass that wraps a URL.
Definition: fmturl.hxx:33
const OUString & GetURL() const
Definition: fmturl.hxx:65
Base class for various Writer styles.
Definition: format.hxx:47
const OUString & GetName() const
Definition: format.hxx:131
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
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool IsRowFrame() const
Definition: frame.hxx:1228
bool IsCellFrame() const
Definition: frame.hxx:1232
bool IsTextFrame() const
Definition: frame.hxx:1240
tools::Long GetLeftMargin() const
Definition: ssfrm.cxx:48
tools::Long GetRightMargin() const
Definition: ssfrm.cxx:50
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1121
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1105
SwFrame * GetNext()
Definition: frame.hxx:682
bool IsPageFrame() const
Definition: frame.hxx:1184
bool IsTabFrame() const
Definition: frame.hxx:1224
SwFrameType GetType() const
Definition: frame.hxx:521
bool IsHeaderFrame() const
Definition: frame.hxx:1196
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:568
bool IsInTab() const
Definition: frame.hxx:961
SwFrame * GetLower()
Definition: findfrm.cxx:196
bool IsRightToLeft() const
Definition: frame.hxx:993
const SwRowFrame * IsInFollowFlowRow() const
Definition: findfrm.cxx:1874
bool IsFlowFrame() const
Definition: frame.hxx:1248
SwLayoutFrame * GetNextCellLeaf()
Definition: findfrm.cxx:1611
bool IsFooterFrame() const
Definition: frame.hxx:1200
SwLayoutFrame * GetUpper()
Definition: frame.hxx:684
bool IsVertical() const
Definition: frame.hxx:979
SwRootFrame * getRootFrame()
Definition: frame.hxx:685
bool IsNoTextFrame() const
Definition: frame.hxx:1244
bool IsFlyFrame() const
Definition: frame.hxx:1216
SwFrame * GetPrev()
Definition: frame.hxx:683
bool IsSctFrame() const
Definition: frame.hxx:1220
SwPageFrame * FindPageFrame()
Definition: frame.hxx:686
const SwRowFrame * IsInSplitTableRow() const
Definition: findfrm.cxx:1841
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:633
tools::Long GetTopMargin() const
Definition: ssfrm.cxx:44
SwLayoutFrame * GetPrevCellLeaf()
Definition: findfrm.cxx:1621
bool IsInSct() const
Definition: frame.hxx:973
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:380
TElementType * First()
Definition: calbck.hxx:372
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:72
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:77
Marks a node in the document model.
Definition: ndindex.hxx:31
Base class of the Writer document model elements.
Definition: node.hxx:98
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
SwDoc & GetDoc()
Definition: node.hxx:233
bool IsInRedlines() const
Checks if this node is in redlines.
Definition: node.cxx:2155
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:968
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:165
SwNodeType GetNodeType() const
Definition: node.hxx:166
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:236
SwNode * DocumentSectionStartNode(SwNode *pNode) const
Definition: nodes.cxx:2532
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:87
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:116
css::uno::Reference< css::embed::XEmbeddedObject > const & GetOleRef()
Definition: ndole.cxx:1012
const SwPosition * GetPoint() const
Definition: pam.hxx:253
A page of the document layout.
Definition: pagefrm.hxx:60
bool IsEmptyPage() const
Definition: pagefrm.hxx:161
bool HasContentPortions() const
Definition: porlay.cxx:2679
bool HasNumberingPortion(FootnoteOrNot) const
Definition: porlay.cxx:2659
SwTwips Height() const
Definition: possiz.hxx:49
bool GetResolved() const
Definition: docufld.cxx:1794
virtual OUString GetPar1() const override
Author.
Definition: docufld.cxx:1818
const OUString & GetText() const
Definition: docufld.hxx:501
Date GetDate() const
Definition: docufld.hxx:485
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1387
tools::Long GetRightMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1411
tools::Long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1408
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1386
tools::Long GetBottomMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1409
tools::Long GetLeftMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1410
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1384
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1385
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:1603
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:658
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding).
Definition: rootfrm.hxx:434
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 SwSection & GetSection() const
Definition: node.hxx:590
const SwTOXBase * GetTOXBase() const
Definition: section.cxx:591
SectionType GetType() const
Definition: section.hxx:173
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:49
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:798
const SwTabFrame * GetFollow() const
Definition: tabfrm.hxx:255
const SwTable * GetTable() const
Definition: tabfrm.hxx:162
bool IsInHeadline(const SwFrame &rFrame) const
Definition: tabfrm.cxx:5966
sal_Int32 getRowSpan() const
Definition: swtable.hxx:540
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
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:208
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
sal_uInt16 Which() const
Definition: txatbase.hxx:116
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:199
SwTextAttr subclass for footnotes and endnotes.
Definition: txtftn.hxx:34
const SwTextNode & GetTextNode() const
Definition: txtftn.hxx:72
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
bool HasPara() const
Definition: txtfrm.hxx:853
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1318
SwParaPortion * GetPara()
Definition: txtcache.cxx:90
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:472
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1390
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
bool IsOutline() const
Returns if this text node is an outline.
Definition: ndtxt.cxx:4138
const SwNodeNum * GetNum(SwRootFrame const *pLayout=nullptr, SwListRedlineType eRedline=SwListRedlineType::SHOW) const
Definition: ndtxt.cxx:4095
bool IsCountedInList() const
Definition: ndtxt.cxx:4393
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2921
int GetActualListLevel(SwListRedlineType eRedline=SwListRedlineType::SHOW) const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4248
bool IsListRestart() const
Definition: ndtxt.cxx:4273
int GetAttrOutlineLevel() const
Returns outline level of this text node.
Definition: ndtxt.cxx:4168
bool IsHidden() const
Definition: ndtxt.cxx:4749
const OUString & GetText() const
Definition: ndtxt.hxx:244
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:735
SwTextPaintInfo & GetInfo()
Definition: itrpaint.hxx:63
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:490
sal_Int32 GetPageNumAndSetOffsetForPDF(OutputDevice &rOut, const SwRect &rRect) const
Definition: viewsh.cxx:2717
const SwNodes & GetNodes() const
Definition: viewsh.cxx:2181
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2163
SwDoc * GetDoc() const
Definition: viewsh.hxx:308
sal_uInt16 GetPageCount() const
Definition: viewsh.cxx:2674
void LockView(bool b)
Definition: viewsh.hxx:491
const IDocumentOutlineNodes * getIDocumentOutlineNodesAccess() const
Definition: viewsh.cxx:2844
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 CreateScreen(const tools::Rectangle &rRect, OUString const &rAltText, OUString const &rMimeType, sal_Int32 nPageNr, SdrObject const *pObj)
sal_Int32 EnsureStructureElement(void const *key)
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 BeginStructureElement(sal_Int32 id)
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)
void SetAlternateText(const OUString &rText)
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)
bool GetIsExportNamedDestinations() const
sal_Int32 CreateNamedDest(const OUString &sDestName, const tools::Rectangle &rRect, sal_Int32 nPageNr=-1)
sal_Int32 CreateLink(const tools::Rectangle &rRect, OUString const &rAltText, sal_Int32 nPageNr=-1)
void InitStructureElement(sal_Int32 id, PDFWriter::StructElement eType, const OUString &rAlias)
void SetLinkDest(sal_Int32 nLinkId, sal_Int32 nDestId)
Any value
URL aURL
virtual SotClipboardFormatId GetFormat(const TransferableDataHelper &aHelper) override
float u
std::vector< SwGetINetAttr > SwGetINetAttrs
Definition: editsh.hxx:128
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:3813
constexpr TypedWhichId< SwFormatURL > RES_URL(117)
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< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(165)
constexpr TypedWhichId< SfxBoolItem > RES_DECORATIVE(140)
LanguageType GetAppLanguage()
Definition: init.cxx:741
void * p
sal_Int64 n
#define LANGUAGE_SYSTEM
sal_Int16 nAdjust
sal_Int16 GetI18NScriptTypeOfLanguage(LanguageType nLang)
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:365
const LanguageTag & getLocale()
int i
const SvxPageUsage aArr[]
void GotoPrevLayoutTextFrame(SwNodeIndex &rIndex, SwRootFrame const *const pLayout)
Definition: docnum.cxx:1438
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
bool IsShrinkPageForPostIts(SwViewShell const &rShell, SwPrintData const &)
Definition: vprint.cxx:435
long Long
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
sal_Int16 nId
bool GoNextPara(SwPaM &rPam, SwMoveFnCollection const &aPosPara)
Definition: pam.cxx:1275
SwMoveFnCollection const & fnParaStart
Definition: paminit.cxx:48
sal_uIntPtr sal_uLong
const SwFrame & mrFrame
const SwFrame & mrFrame
const SwLinePortion & mrPor
const SwTextPainter & mrTextPainter
bool const m_isNumberingLabel
For querying the INet-attributes for Navigator.
Definition: editsh.hxx:120
SwNode & GetNode() const
Definition: pam.hxx:81
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
Definition: pam.cxx:231
OUString Contents
OUString Title
SvxAdjust
SwFontScript
Definition: swfont.hxx:124
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
std::vector< SwRect > SwRects
Definition: swregion.hxx:26
@ TOX_INDEX
Definition: toxe.hxx:41
@ TOX_AUTHORITIES
Definition: toxe.hxx:47
signed char sal_Int8
size_t pos