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