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