LibreOffice Module sw (master)  1
wrtw8nds.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 <vector>
21 #include <utility>
22 #include <algorithm>
23 #include <iostream>
24 
25 #include "docxexport.hxx"
26 
27 #include <i18nlangtag/mslangid.hxx>
28 #include <hintids.hxx>
29 #include <tools/urlobj.hxx>
30 #include <editeng/cmapitem.hxx>
31 #include <editeng/langitem.hxx>
32 #include <editeng/svxfont.hxx>
33 #include <editeng/lrspitem.hxx>
34 #include <editeng/brushitem.hxx>
35 #include <editeng/fontitem.hxx>
36 #include <editeng/keepitem.hxx>
37 #include <editeng/fhgtitem.hxx>
38 #include <editeng/ulspitem.hxx>
40 #include <editeng/frmdiritem.hxx>
41 #include <editeng/tstpitem.hxx>
42 #include <editeng/wghtitem.hxx>
43 #include <svl/grabbagitem.hxx>
44 #include <svl/urihelper.hxx>
45 #include <svl/whiter.hxx>
46 #include <fmtpdsc.hxx>
47 #include <fmtlsplt.hxx>
48 #include <fmtanchr.hxx>
49 #include <fmtcntnt.hxx>
50 #include <frmatr.hxx>
51 #include <paratr.hxx>
52 #include <txatbase.hxx>
53 #include <fmtinfmt.hxx>
54 #include <fmtrfmrk.hxx>
55 #include <fchrfmt.hxx>
56 #include <fmtautofmt.hxx>
57 #include <charfmt.hxx>
58 #include <tox.hxx>
59 #include <ndtxt.hxx>
60 #include <pam.hxx>
61 #include <doc.hxx>
63 #include <IDocumentMarkAccess.hxx>
64 #include <docary.hxx>
65 #include <swtable.hxx>
66 #include <swtblfmt.hxx>
67 #include <section.hxx>
68 #include <pagedesc.hxx>
69 #include <swrect.hxx>
70 #include <reffld.hxx>
71 #include <redline.hxx>
72 #include <txttxmrk.hxx>
73 #include <fmtline.hxx>
74 #include <fmtruby.hxx>
75 #include <breakit.hxx>
76 #include <txtatr.hxx>
77 #include <cellatr.hxx>
78 #include <fmtrowsplt.hxx>
79 #include <com/sun/star/drawing/XShape.hpp>
80 #include <com/sun/star/i18n/BreakIterator.hpp>
81 #include <com/sun/star/i18n/ScriptType.hpp>
82 #include <com/sun/star/i18n/WordType.hpp>
83 #include <com/sun/star/text/RubyPosition.hpp>
84 #include <oox/export/vmlexport.hxx>
85 #include <sal/log.hxx>
87 
88 #include "sprmids.hxx"
89 
90 #include "writerhelper.hxx"
91 #include "writerwordglue.hxx"
92 #include <numrule.hxx>
93 #include "wrtww8.hxx"
94 #include "ww8par.hxx"
95 #include <IMark.hxx>
96 #include "ww8attributeoutput.hxx"
97 
98 #include <ndgrf.hxx>
99 #include <ndole.hxx>
100 
101 #include <cstdio>
102 
103 using namespace ::com::sun::star;
104 using namespace ::com::sun::star::i18n;
105 using namespace sw::util;
106 using namespace sw::types;
107 using namespace sw::mark;
108 using namespace ::oox::vml;
109 
110 static OUString lcl_getFieldCode( const IFieldmark* pFieldmark )
111 {
112  assert(pFieldmark);
113 
114  if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT )
115  return " FORMTEXT ";
116  if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN )
117  return " FORMDROPDOWN ";
118  if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX )
119  return " FORMCHECKBOX ";
120  if ( pFieldmark->GetFieldname( ) == ODF_FORMDATE )
121  return " ODFFORMDATE ";
122  if ( pFieldmark->GetFieldname( ) == ODF_TOC )
123  return " TOC ";
124  if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
125  return " HYPERLINK ";
126  if ( pFieldmark->GetFieldname( ) == ODF_PAGEREF )
127  return " PAGEREF ";
128  return pFieldmark->GetFieldname();
129 }
130 
131 static ww::eField lcl_getFieldId(const IFieldmark*const pFieldmark)
132 {
133  assert(pFieldmark);
134 
135  if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT )
136  return ww::eFORMTEXT;
137  if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN )
138  return ww::eFORMDROPDOWN;
139  if ( pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX )
140  return ww::eFORMCHECKBOX;
141  if ( pFieldmark->GetFieldname( ) == ODF_FORMDATE )
142  return ww::eFORMDATE;
143  if ( pFieldmark->GetFieldname( ) == ODF_TOC )
144  return ww::eTOC;
145  if ( pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
146  return ww::eHYPERLINK;
147  if ( pFieldmark->GetFieldname( ) == ODF_PAGEREF )
148  return ww::ePAGEREF;
149  return ww::eUNKNOWN;
150 }
151 
153  : pOld( rExport.m_pChpIter ), m_rExport( rExport )
154 {
155  m_rExport.m_pChpIter = this;
156 }
157 
159 {
161 }
162 
163 namespace {
164 
165 class sortswflys
166 {
167 public:
168  bool operator()(const ww8::Frame &rOne, const ww8::Frame &rTwo) const
169  {
170  return rOne.GetPosition() < rTwo.GetPosition();
171  }
172 };
173 
174 }
175 
177 {
178  OSL_ENSURE(maCharRuns.begin() != maCharRuns.end(), "Impossible");
179  mnScript = maCharRunIter->mnScript;
180  meChrSet = maCharRunIter->meCharSet;
181  mbCharIsRTL = maCharRunIter->mbRTL;
182 }
183 
185  MSWordAttrIter(rWr),
186  rNd(rTextNd),
187  maCharRuns(GetPseudoCharRuns(rTextNd)),
188  pCurRedline(nullptr),
189  nCurrentSwPos(0),
190  nCurRedlinePos(SwRedlineTable::npos),
191  mrSwFormatDrop(rTextNd.GetSwAttrSet().GetDrop())
192 {
193 
194  SwPosition aPos(rTextNd);
195  mbParaIsRTL = SvxFrameDirection::Horizontal_RL_TB == rWr.m_rDoc.GetTextDirection(aPos);
196 
197  maCharRunIter = maCharRuns.begin();
198  IterToCurrent();
199 
200  /*
201  #i2916#
202  Get list of any graphics which may be anchored from this paragraph.
203  */
205  std::sort(maFlyFrames.begin(), maFlyFrames.end(), sortswflys());
206 
207  /*
208  #i18480#
209  If we are inside a frame then anything anchored inside this frame can
210  only be supported by word anchored inline ("as character"), so force
211  this in the supportable case.
212  */
213  if (rWr.m_bInWriteEscher)
214  {
215  for ( auto& aFlyFrame : maFlyFrames )
216  aFlyFrame.ForceTreatAsInline();
217  }
218 
219  maFlyIter = maFlyFrames.begin();
220 
222  {
223  SwPosition aPosition( rNd, SwIndex( const_cast<SwTextNode*>(&rNd) ) );
225  }
226 
228 }
229 
230 static sal_Int32 lcl_getMinPos( sal_Int32 pos1, sal_Int32 pos2 )
231 {
232  if ( pos1 >= 0 && pos2 >= 0 )
233  {
234  // both valid: return minimum one
235  return std::min(pos1, pos2);
236  }
237 
238  // return the valid one, if any, or -1
239  return std::max(pos1, pos2);
240 }
241 
242 sal_Int32 SwWW8AttrIter::SearchNext( sal_Int32 nStartPos )
243 {
244  const OUString aText = rNd.GetText();
245  sal_Int32 fieldEndPos = aText.indexOf(CH_TXT_ATR_FIELDEND, nStartPos - 1);
246  // HACK: for (so far) mysterious reasons the sdtContent element closes
247  // too late in testDateFormField() unless an empty run is exported at
248  // the end of the fieldmark; hence find *also* the position after the
249  // CH_TXT_ATR_FIELDEND here
250  if (0 <= fieldEndPos && fieldEndPos < nStartPos)
251  {
252  ++fieldEndPos;
253  }
254  sal_Int32 fieldSepPos = aText.indexOf(CH_TXT_ATR_FIELDSEP, nStartPos);
255  sal_Int32 fieldStartPos = aText.indexOf(CH_TXT_ATR_FIELDSTART, nStartPos);
256  sal_Int32 formElementPos = aText.indexOf(CH_TXT_ATR_FORMELEMENT, nStartPos - 1);
257  if (0 <= formElementPos && formElementPos < nStartPos)
258  {
259  ++formElementPos; // tdf#133604 put this in its own run
260  }
261 
262  const sal_Int32 pos = lcl_getMinPos(
263  lcl_getMinPos(lcl_getMinPos(fieldEndPos, fieldSepPos), fieldStartPos),
264  formElementPos );
265 
266  sal_Int32 nMinPos = (pos>=0) ? pos : SAL_MAX_INT32;
267 
268  // first the redline, then the attributes
269  if( pCurRedline )
270  {
271  const SwPosition* pEnd = pCurRedline->End();
272  if (pEnd->nNode == rNd)
273  {
274  const sal_Int32 i = pEnd->nContent.GetIndex();
275  if ( i >= nStartPos && i < nMinPos )
276  {
277  nMinPos = i;
278  }
279  }
280  }
281 
283  {
284  // nCurRedlinePos point to the next redline
286  if( pCurRedline )
287  ++nRedLinePos;
288 
289  for ( ; nRedLinePos < m_rExport.m_rDoc.getIDocumentRedlineAccess().GetRedlineTable().size(); ++nRedLinePos )
290  {
291  const SwRangeRedline* pRedl = m_rExport.m_rDoc.getIDocumentRedlineAccess().GetRedlineTable()[ nRedLinePos ];
292 
293  const SwPosition* pStt = pRedl->Start();
294  const SwPosition* pEnd = pStt == pRedl->GetPoint()
295  ? pRedl->GetMark()
296  : pRedl->GetPoint();
297 
298  if( pStt->nNode == rNd )
299  {
300  const sal_Int32 i = pStt->nContent.GetIndex();
301  if( i >= nStartPos && i < nMinPos )
302  nMinPos = i;
303  }
304  else
305  break;
306 
307  if( pEnd->nNode == rNd )
308  {
309  const sal_Int32 i = pEnd->nContent.GetIndex();
310  if( i >= nStartPos && i < nMinPos )
311  {
312  nMinPos = i;
313  }
314  }
315  }
316  }
317 
318  if (mrSwFormatDrop.GetWholeWord() && nStartPos <= rNd.GetDropLen(0))
319  nMinPos = rNd.GetDropLen(0);
320  else if(nStartPos <= mrSwFormatDrop.GetChars())
321  nMinPos = mrSwFormatDrop.GetChars();
322 
323  if(const SwpHints* pTextAttrs = rNd.GetpSwpHints())
324  {
325 
326 // can be optimized if we consider that the TextAttrs are sorted by start position.
327 // but then we'd have to save 2 indices
328  for( size_t i = 0; i < pTextAttrs->Count(); ++i )
329  {
330  const SwTextAttr* pHt = pTextAttrs->Get(i);
331  sal_Int32 nPos = pHt->GetStart(); // first Attr characters
332  if( nPos >= nStartPos && nPos <= nMinPos )
333  nMinPos = nPos;
334 
335  if( pHt->End() ) // Attr with end
336  {
337  nPos = *pHt->End(); // last Attr character + 1
338  if( nPos >= nStartPos && nPos <= nMinPos )
339  nMinPos = nPos;
340  }
341  if (pHt->HasDummyChar())
342  {
343  // pos + 1 because of CH_TXTATR in Text
344  nPos = pHt->GetStart() + 1;
345  if( nPos >= nStartPos && nPos <= nMinPos )
346  nMinPos = nPos;
347  }
348  }
349  }
350 
351  if (maCharRunIter != maCharRuns.end())
352  {
353  if (maCharRunIter->mnEndPos < nMinPos)
354  nMinPos = maCharRunIter->mnEndPos;
355  IterToCurrent();
356  }
357 
358  // #i2916# Check to see if there are any graphics anchored to characters in this paragraph's text.
359  sal_Int32 nNextFlyPos = 0;
360  ww8::FrameIter aTmpFlyIter = maFlyIter;
361  while (aTmpFlyIter != maFlyFrames.end() && nNextFlyPos < nStartPos)
362  {
363  const SwPosition &rAnchor = aTmpFlyIter->GetPosition();
364  nNextFlyPos = rAnchor.nContent.GetIndex();
365 
366  ++aTmpFlyIter;
367  }
368  if (nNextFlyPos >= nStartPos && nNextFlyPos < nMinPos)
369  nMinPos = nNextFlyPos;
370 
371  //nMinPos found and not going to change at this point
372 
373  if (maCharRunIter != maCharRuns.end())
374  {
375  if (maCharRunIter->mnEndPos == nMinPos)
376  ++maCharRunIter;
377  }
378 
379  return nMinPos;
380 }
381 
382 void SwWW8AttrIter::OutAttr( sal_Int32 nSwPos, bool bWriteCombChars)
383 {
385 
386  /*
387  Depending on whether text is in CTL/CJK or Western, get the id of that
388  script, the idea is that the font that is actually in use to render this
389  range of text ends up in pFont
390  */
391  sal_uInt16 nFontId = GetWhichOfScript( RES_CHRATR_FONT, GetScript() );
392 
393  const SvxFontItem &rParentFont = ItemGet<SvxFontItem>(
394  static_cast<const SwTextFormatColl&>(rNd.GetAnyFormatColl()), nFontId);
395  const SvxFontItem *pFont = &rParentFont;
396  const SfxPoolItem *pGrabBag = nullptr;
397 
398  SfxItemSet aExportSet(*rNd.GetSwAttrSet().GetPool(),
400 
401  //The hard formatting properties that affect the entire paragraph
402  if (rNd.HasSwAttrSet())
403  {
404  // only copy hard attributes - bDeep = false
405  aExportSet.Set(rNd.GetSwAttrSet(), false/*bDeep*/);
406  // get the current font item. Use rNd.GetSwAttrSet instead of aExportSet:
407  const SvxFontItem &rNdFont = ItemGet<SvxFontItem>(rNd.GetSwAttrSet(), nFontId);
408  pFont = &rNdFont;
409  aExportSet.ClearItem(nFontId);
410  }
411 
412  //The additional hard formatting properties that affect this range in the
413  //paragraph
414  ww8::PoolItems aRangeItems;
415  if (const SwpHints* pTextAttrs = rNd.GetpSwpHints())
416  {
417  for( size_t i = 0; i < pTextAttrs->Count(); ++i )
418  {
419  const SwTextAttr* pHt = pTextAttrs->Get(i);
420  const sal_Int32* pEnd = pHt->End();
421 
422  if (pEnd ? ( nSwPos >= pHt->GetStart() && nSwPos < *pEnd)
423  : nSwPos == pHt->GetStart() )
424  {
425  sal_uInt16 nWhich = pHt->GetAttr().Which();
426  if (nWhich == RES_TXTATR_AUTOFMT)
427  {
428  const SwFormatAutoFormat& rAutoFormat = static_cast<const SwFormatAutoFormat&>(pHt->GetAttr());
429  const std::shared_ptr<SfxItemSet>& pSet = rAutoFormat.GetStyleHandle();
430  SfxWhichIter aIter( *pSet );
431  const SfxPoolItem* pItem;
432  sal_uInt16 nWhichId = aIter.FirstWhich();
433  while( nWhichId )
434  {
435  if( SfxItemState::SET == pSet->GetItemState( nWhichId, false, &pItem ))
436  {
437  if (nWhichId == nFontId)
438  pFont = &(item_cast<SvxFontItem>(*pItem));
439  else if (nWhichId == RES_CHRATR_GRABBAG)
440  pGrabBag = pItem;
441  else
442  aRangeItems[nWhichId] = pItem;
443  }
444  nWhichId = aIter.NextWhich();
445  }
446  }
447  else
448  aRangeItems[nWhich] = (&(pHt->GetAttr()));
449  }
450  else if (nSwPos < pHt->GetStart())
451  break;
452  }
453  }
454 
455  /*
456  For #i24291# we need to explicitly remove any properties from the
457  aExportSet which a SwCharFormat would override, we can't rely on word doing
458  this for us like writer does
459  */
460  const SwFormatCharFormat *pCharFormatItem =
461  HasItem< SwFormatCharFormat >( aRangeItems, RES_TXTATR_CHARFMT );
462  if ( pCharFormatItem )
463  ClearOverridesFromSet( *pCharFormatItem, aExportSet );
464 
465  // check toggle properties in DOCX output
466  {
468  handleToggleProperty(aExportSet, pCharFormatItem, RES_CHRATR_WEIGHT, &aBoldProperty);
469  }
470 
471  // tdf#113790: AutoFormat style overwrites char style, so remove all
472  // elements from CHARFMT grab bag which are set in AUTOFMT grab bag
473  if (const SfxGrabBagItem *pAutoFmtGrabBag = dynamic_cast<const SfxGrabBagItem*>(pGrabBag))
474  {
475  if (const SfxGrabBagItem *pCharFmtGrabBag = aExportSet.GetItem<SfxGrabBagItem>(RES_CHRATR_GRABBAG, false))
476  {
477  std::unique_ptr<SfxGrabBagItem> pNewCharFmtGrabBag(pCharFmtGrabBag->Clone());
478  assert(pNewCharFmtGrabBag);
479  auto & rNewFmtMap = pNewCharFmtGrabBag->GetGrabBag();
480  for (auto const & item : pAutoFmtGrabBag->GetGrabBag())
481  {
482  if (item.second.hasValue())
483  rNewFmtMap.erase(item.first);
484  }
485  aExportSet.Put(std::move(pNewCharFmtGrabBag));
486  }
487  }
488 
489  ww8::PoolItems aExportItems;
490  GetPoolItems( aExportSet, aExportItems, false );
491 
492  if( rNd.GetpSwpHints() == nullptr )
493  m_rExport.SetCurItemSet(&aExportSet);
494 
495  for ( const auto& aRangeItem : aRangeItems )
496  {
497  aExportItems[aRangeItem.first] = aRangeItem.second;
498  }
499 
500  if ( !aExportItems.empty() )
501  {
504  m_rExport.m_aCurrentCharPropStarts.push( nSwPos );
505 
506  // tdf#38778 Fix output of the font in DOC run for fields
507  const SvxFontItem * pFontToOutput = ( rParentFont != *pFont )? pFont : nullptr;
508 
509  m_rExport.ExportPoolItemsToCHP( aExportItems, GetScript(), pFontToOutput, bWriteCombChars );
510 
511  // HasTextItem only allowed in the above range
513  m_rExport.m_pOutFormatNode = pOldMod;
514  }
515 
516  if( rNd.GetpSwpHints() == nullptr )
517  m_rExport.SetCurItemSet(nullptr);
518 
519  OSL_ENSURE( pFont, "must be *some* font associated with this txtnode" );
520  if ( pFont )
521  {
522  SvxFontItem aFont( *pFont );
523 
524  if ( rParentFont != aFont )
525  m_rExport.AttrOutput().OutputItem( aFont );
526  }
527 
528  // Output grab bag attributes
529  if (pGrabBag)
530  m_rExport.AttrOutput().OutputItem( *pGrabBag );
531 }
532 
533 // Toggle Properties
534 //
535 // If the value of the toggle property appears at multiple levels of the style hierarchy (17.7.2), their
536 // effective values shall be combined as follows:
537 //
538 // value_{effective} = val_{table} XOR val_{paragraph} XOR val_{character}
539 //
540 // If the value specified by the document defaults is true, the effective value is true.
541 // Otherwise, the values are combined by a Boolean XOR as follows:
542 // i.e., the effective value to be applied to the content shall be true if its effective value is true for
543 // an odd number of levels of the style hierarchy.
544 //
545 // To prevent such logic inside output, it is required to write inline w:b token on content level.
546 void SwWW8AttrIter::handleToggleProperty(SfxItemSet& rExportSet, const SwFormatCharFormat* pCharFormatItem,
547  sal_uInt16 nWhich, const SfxPoolItem* pValue)
548 {
549  if (rExportSet.HasItem(nWhich) || !pValue)
550  return;
551 
552  bool hasPropertyInCharStyle = false;
553  bool hasPropertyInParaStyle = false;
554 
555  // get bold flag from specified character style
556  if (pCharFormatItem)
557  {
558  if (const SwCharFormat* pCharFormat = pCharFormatItem->GetCharFormat())
559  {
560  const SfxPoolItem* pItem = nullptr;
561  if (pCharFormat->GetAttrSet().HasItem(nWhich, &pItem))
562  {
563  hasPropertyInCharStyle = (*pItem == *pValue);
564  }
565  }
566  }
567 
568  // get bold flag from specified paragraph style
569  {
570  SwTextFormatColl& rTextColl = static_cast<SwTextFormatColl&>( rNd.GetAnyFormatColl() );
571  sal_uInt16 nStyle = m_rExport.m_pStyles->GetSlot( &rTextColl );
572  nStyle = ( nStyle != 0xfff ) ? nStyle : 0;
573  const SwFormat* pFormat = m_rExport.m_pStyles->GetSwFormat(nStyle);
574  if (pFormat)
575  {
576  const SfxPoolItem* pItem = nullptr;
577  if (pFormat->GetAttrSet().HasItem(nWhich, &pItem))
578  {
579  hasPropertyInParaStyle = (*pItem == *pValue);
580  }
581  }
582  }
583 
584  // add inline property
585  if (hasPropertyInCharStyle && hasPropertyInParaStyle)
586  {
587  rExportSet.Put(*pValue);
588  }
589 }
590 
592 {
593  if (maFlyFrames.size() != 1)
594  return false;
595 
596  while ( maFlyIter != maFlyFrames.end() )
597  {
598  const SdrObject* pSdrObj = maFlyIter->GetFrameFormat().FindRealSdrObject();
599 
600  if (pSdrObj)
601  {
602  if (VMLExport::IsWaterMarkShape(pSdrObj->GetName()))
603  return true;
604  }
605  ++maFlyIter;
606  }
607 
608  return false;
609 }
610 
612 {
613  if ( maFlyIter == maFlyFrames.end() )
614  return false;
615 
616  /* if current node position and the anchor position are the same
617  then the frame anchor is linked to this node
618  */
619  return nNodePos == maFlyIter->GetPosition().nNode.GetIndex();
620 }
621 
622 bool SwWW8AttrIter::HasFlysAt(sal_Int32 nSwPos) const
623 {
624  for (const auto& rFly : maFlyFrames)
625  {
626  const SwPosition& rAnchor = rFly.GetPosition();
627  const sal_Int32 nPos = rAnchor.nContent.GetIndex();
628  if (nPos == nSwPos)
629  {
630  return true;
631  }
632  }
633 
634  return false;
635 }
636 
638 {
639  // collection point to first gather info about all of the potentially linked textboxes: to be analyzed later.
640  OUString sLinkChainName;
641  ww8::FrameIter linkedTextboxesIter = maFlyIter;
642  while ( linkedTextboxesIter != maFlyFrames.end() )
643  {
644  uno::Reference< drawing::XShape > xShape;
645  ww8::Frame aFrame = *linkedTextboxesIter;
646  const SdrObject* pSdrObj = aFrame.GetFrameFormat().FindRealSdrObject();
647  if( pSdrObj )
648  xShape.set(const_cast<SdrObject*>(pSdrObj)->getUnoShape(), uno::UNO_QUERY);
649  uno::Reference< beans::XPropertySet > xPropertySet(xShape, uno::UNO_QUERY);
650  uno::Reference< beans::XPropertySetInfo > xPropertySetInfo;
651  if( xPropertySet.is() )
652  xPropertySetInfo = xPropertySet->getPropertySetInfo();
653  if( xPropertySetInfo.is() )
654  {
655  MSWordExportBase::LinkedTextboxInfo aLinkedTextboxInfo;
656 
657  if( xPropertySetInfo->hasPropertyByName("LinkDisplayName") )
658  xPropertySet->getPropertyValue("LinkDisplayName") >>= sLinkChainName;
659  else if( xPropertySetInfo->hasPropertyByName("ChainName") )
660  xPropertySet->getPropertyValue("ChainName") >>= sLinkChainName;
661 
662  if( xPropertySetInfo->hasPropertyByName("ChainNextName") )
663  xPropertySet->getPropertyValue("ChainNextName") >>= aLinkedTextboxInfo.sNextChain;
664  if( xPropertySetInfo->hasPropertyByName("ChainPrevName") )
665  xPropertySet->getPropertyValue("ChainPrevName") >>= aLinkedTextboxInfo.sPrevChain;
666 
667  //collect a list of linked textboxes: those with a NEXT or PREVIOUS link
668  if( !aLinkedTextboxInfo.sNextChain.isEmpty() || !aLinkedTextboxInfo.sPrevChain.isEmpty() )
669  {
670  assert( !sLinkChainName.isEmpty() );
671 
672  //there are many discarded duplicates in documents - no duplicates allowed in the list, so try to find the real one.
673  //if this LinkDisplayName/ChainName already exists on a different shape...
674  // the earlier processed duplicates are thrown out unless this one can be proved as bad. (last processed duplicate usually is stored)
675  auto linkFinder = m_rExport.m_aLinkedTextboxesHelper.find(sLinkChainName);
676  if( linkFinder != m_rExport.m_aLinkedTextboxesHelper.end() )
677  {
678  //If my NEXT/PREV targets have already been discovered, but don't match me, then assume I'm an abandoned remnant
679  // (this logic fails if both me and one of my links are duplicated, and the remnants were added first.)
680  linkFinder = m_rExport.m_aLinkedTextboxesHelper.find(aLinkedTextboxInfo.sNextChain);
681  if( (linkFinder != m_rExport.m_aLinkedTextboxesHelper.end()) && (linkFinder->second.sPrevChain != sLinkChainName) )
682  {
683  ++linkedTextboxesIter;
684  break;
685  }
686 
687  linkFinder = m_rExport.m_aLinkedTextboxesHelper.find(aLinkedTextboxInfo.sPrevChain);
688  if( (linkFinder != m_rExport.m_aLinkedTextboxesHelper.end()) && (linkFinder->second.sNextChain != sLinkChainName) )
689  {
690  ++linkedTextboxesIter;
691  break;
692  }
693  }
695  m_rExport.m_aLinkedTextboxesHelper[sLinkChainName] = aLinkedTextboxInfo;
696  }
697  }
698  ++linkedTextboxesIter;
699  }
700 
701  /*
702  #i2916#
703  May have an anchored graphic to be placed, loop through sorted array
704  and output all at this position
705  */
706  while ( maFlyIter != maFlyFrames.end() )
707  {
708  const SwPosition &rAnchor = maFlyIter->GetPosition();
709  const sal_Int32 nPos = rAnchor.nContent.GetIndex();
710 
711  if ( nPos > nSwPos )
712  return FLY_NOT_PROCESSED ; // We haven't processed the fly
713 
714  const SdrObject* pSdrObj = maFlyIter->GetFrameFormat().FindRealSdrObject();
715 
716  if (pSdrObj)
717  {
718  if (VMLExport::IsWaterMarkShape(pSdrObj->GetName()))
719  {
720  // This is a watermark object. Should be written ONLY in the header
722  {
723  // Should write a watermark in the header
725  }
726  else
727  {
728  // Should not write watermark object in the main body text
729  }
730  }
731  else
732  {
733  // This is not a watermark object - write normally
735  }
736  }
737  else
738  {
739  // This is not a watermark object - write normally
741  }
742  ++maFlyIter;
743  }
745 }
746 
747 bool SwWW8AttrIter::IsTextAttr( sal_Int32 nSwPos ) const
748 {
749  // search for attrs with dummy character or content
750  if (const SwpHints* pTextAttrs = rNd.GetpSwpHints())
751  {
752  for (size_t i = 0; i < pTextAttrs->Count(); ++i)
753  {
754  const SwTextAttr* pHt = pTextAttrs->Get(i);
755  if (nSwPos == pHt->GetStart())
756  {
757  if (pHt->HasDummyChar() || pHt->HasContent() )
758  {
759  return true;
760  }
761  }
762  else if (nSwPos < pHt->GetStart())
763  {
764  break; // sorted by start
765  }
766  }
767  }
768 
769  return false;
770 }
771 
772 bool SwWW8AttrIter::IsExportableAttr(sal_Int32 nSwPos) const
773 {
774  if (const SwpHints* pTextAttrs = rNd.GetpSwpHints())
775  {
776  for (size_t i = 0; i < pTextAttrs->Count(); ++i)
777  {
778  const SwTextAttr* pHt = pTextAttrs->GetSortedByEnd(i);
779  const sal_Int32 nStart = pHt->GetStart();
780  const sal_Int32 nEnd = pHt->End() ? *pHt->End() : INT_MAX;
781  if (nSwPos >= nStart && nSwPos < nEnd)
782  {
783  switch (pHt->GetAttr().Which())
784  {
785  // Metadata fields should be dynamically generated, not dumped as text.
787  return false;
788  }
789  }
790  }
791  }
792 
793  return true;
794 }
795 
796 bool SwWW8AttrIter::IsDropCap( int nSwPos )
797 {
798  // see if the current position falls on a DropCap
799  int nDropChars = mrSwFormatDrop.GetChars();
800  bool bWholeWord = mrSwFormatDrop.GetWholeWord();
801  if (bWholeWord)
802  {
803  const sal_Int32 nWordLen = rNd.GetDropLen(0);
804  if(nSwPos == nWordLen && nSwPos != 0)
805  return true;
806  }
807  else
808  {
809  if (nSwPos == nDropChars && nSwPos != 0)
810  return true;
811  }
812  return false;
813 }
814 
816 {
817  return std::any_of(m_rExport.m_aImplicitBookmarks.begin(), m_rExport.m_aImplicitBookmarks.end(),
818  [this](const aBookmarkPair& rBookmarkPair) { return rBookmarkPair.second == rNd.GetIndex(); });
819 }
820 
821 //HasItem is for the summary of the double attributes: Underline and WordlineMode as TextItems.
822 // OutAttr () calls the output function, which can call HasItem() for other items at the attribute's start position.
823 // Only attributes with end can be queried.
824 // It searches with bDeep
825 const SfxPoolItem* SwWW8AttrIter::HasTextItem( sal_uInt16 nWhich ) const
826 {
827  const SfxPoolItem* pRet = nullptr;
828  const SwpHints* pTextAttrs = rNd.GetpSwpHints();
829  if (pTextAttrs && !m_rExport.m_aCurrentCharPropStarts.empty())
830  {
831  const sal_Int32 nTmpSwPos = m_rExport.m_aCurrentCharPropStarts.top();
832  for (size_t i = 0; i < pTextAttrs->Count(); ++i)
833  {
834  const SwTextAttr* pHt = pTextAttrs->Get(i);
835  const SfxPoolItem* pItem = &pHt->GetAttr();
836  const sal_Int32 * pAtrEnd = nullptr;
837  if( nullptr != ( pAtrEnd = pHt->End() ) && // only Attr with an end
838  nTmpSwPos >= pHt->GetStart() && nTmpSwPos < *pAtrEnd )
839  {
840  if ( nWhich == pItem->Which() )
841  {
842  pRet = pItem; // found it
843  break;
844  }
845  else if( RES_TXTATR_INETFMT == pHt->Which() ||
846  RES_TXTATR_CHARFMT == pHt->Which() ||
847  RES_TXTATR_AUTOFMT == pHt->Which() )
848  {
849  const SfxItemSet* pSet = CharFormat::GetItemSet( pHt->GetAttr() );
850  const SfxPoolItem* pCharItem;
851  if ( pSet &&
852  SfxItemState::SET == pSet->GetItemState( nWhich, pHt->Which() != RES_TXTATR_AUTOFMT, &pCharItem ) )
853  {
854  pRet = pCharItem; // found it
855  break;
856  }
857  }
858  }
859  else if (nTmpSwPos < pHt->GetStart())
860  break; // nothing more to come
861  }
862  }
863  return pRet;
864 }
865 
867 {
868  rItems.insert(rItems.end(), pO->begin(), pO->end());
869 }
870 
871 const SfxPoolItem& SwWW8AttrIter::GetItem(sal_uInt16 nWhich) const
872 {
873  const SfxPoolItem* pRet = HasTextItem(nWhich);
874  return pRet ? *pRet : rNd.SwContentNode::GetAttr(nWhich);
875 }
876 
877 void WW8AttributeOutput::StartRuby( const SwTextNode& rNode, sal_Int32 /*nPos*/, const SwFormatRuby& rRuby )
878 {
879  WW8Ruby aWW8Ruby(rNode, rRuby, GetExport());
880  OUString aStr( FieldString( ww::eEQ ) + "\\* jc" );
881  aStr += OUString::number(aWW8Ruby.GetJC()) + " \\* \"Font:";
882  aStr += aWW8Ruby.GetFontFamily() + "\" \\* hps";
883  aStr += OUString::number((aWW8Ruby.GetRubyHeight() + 5) / 10) + " \\o";
884  if (aWW8Ruby.GetDirective())
885  {
886  aStr += OUStringLiteral(u"\\a") + OUStringChar(aWW8Ruby.GetDirective());
887  }
888  aStr += "(\\s\\up " + OUString::number((aWW8Ruby.GetBaseHeight() + 10) / 20 - 1) + "(";
889  aStr += rRuby.GetText() + ")";
890 
891  // The parameter separator depends on the FIB.lid
892  if ( m_rWW8Export.pFib->getNumDecimalSep() == '.' )
893  aStr += ",";
894  else
895  aStr += ";";
896 
897  m_rWW8Export.OutputField( nullptr, ww::eEQ, aStr,
899 }
900 
901 void WW8AttributeOutput::EndRuby(const SwTextNode& /*rNode*/, sal_Int32 /*nPos*/)
902 {
903  m_rWW8Export.WriteChar( ')' );
905 }
906 
907 /*#i15387# Better ideas welcome*/
908 static OUString &TruncateBookmark( OUString &rRet )
909 {
910  if ( rRet.getLength() > 40 )
911  rRet = rRet.copy( 0, 40 );
912  OSL_ENSURE( rRet.getLength() <= 40, "Word cannot have bookmarks longer than 40 chars" );
913  return rRet;
914 }
915 
916 OUString AttributeOutputBase::ConvertURL( const OUString& rUrl, bool bAbsoluteOut )
917 {
918  OUString sURL = rUrl;
919 
920  INetURLObject anAbsoluteParent(m_sBaseURL);
921  OUString sConvertedParent = INetURLObject::GetScheme( anAbsoluteParent.GetProtocol() ) + anAbsoluteParent.GetURLPath();
922  OUString sParentPath = sConvertedParent.isEmpty() ? m_sBaseURL : sConvertedParent;
923 
924  if ( bAbsoluteOut )
925  {
926  INetURLObject anAbsoluteNew;
927 
928  if ( anAbsoluteParent.GetNewAbsURL( rUrl, &anAbsoluteNew ) )
929  sURL = anAbsoluteNew.GetMainURL( INetURLObject::DecodeMechanism::NONE );
930  }
931  else
932  {
933  OUString sToConvert = rUrl.replaceAll( "\\", "/" );
934  INetURLObject aURL( sToConvert );
935  sToConvert = INetURLObject::GetScheme( aURL.GetProtocol() ) + aURL.GetURLPath();
937  if ( !sRelative.isEmpty() )
938  sURL = sRelative;
939  }
940 
941  return sURL;
942 }
943 
944 bool AttributeOutputBase::AnalyzeURL( const OUString& rUrl, const OUString& /*rTarget*/, OUString* pLinkURL, OUString* pMark )
945 {
946  bool bBookMarkOnly = false;
947 
948  OUString sMark;
949  OUString sURL;
950 
951  if ( rUrl.getLength() > 1 && rUrl[0] == '#' )
952  {
953  sMark = BookmarkToWriter( rUrl.copy(1) );
954 
955  const sal_Int32 nPos = sMark.lastIndexOf( cMarkSeparator );
956 
957  const OUString sRefType(nPos>=0 && nPos+1<sMark.getLength() ?
958  sMark.copy(nPos+1).replaceAll(" ", "") :
959  OUString());
960 
961  // #i21465# Only interested in outline references
962  if ( !sRefType.isEmpty() &&
963  (sRefType == "outline" || sRefType == "graphic" || sRefType == "frame" || sRefType == "ole" || sRefType == "region" || sRefType == "table") )
964  {
965  for ( const auto& rBookmarkPair : GetExport().m_aImplicitBookmarks )
966  {
967  if ( rBookmarkPair.first == sMark )
968  {
969  sMark = "_toc" + OUString::number( rBookmarkPair.second );
970  break;
971  }
972  }
973  }
974  }
975  else
976  {
977  INetURLObject aURL( rUrl, INetProtocol::NotValid );
980  INetProtocol aProtocol = aURL.GetProtocol();
981 
982  if ( aProtocol == INetProtocol::File || aProtocol == INetProtocol::NotValid )
983  {
984  // INetProtocol::NotValid - may be a relative link
985  bool bExportRelative = m_aSaveOpt.IsSaveRelFSys();
986  sURL = ConvertURL( rUrl, !bExportRelative );
987  }
988  }
989 
990  if ( !sMark.isEmpty() && sURL.isEmpty() )
991  bBookMarkOnly = true;
992 
993  *pMark = sMark;
994  *pLinkURL = sURL;
995  return bBookMarkOnly;
996 }
997 
998 bool WW8AttributeOutput::AnalyzeURL( const OUString& rUrl, const OUString& rTarget, OUString* pLinkURL, OUString* pMark )
999 {
1000  bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
1001 
1002  OUString sURL = *pLinkURL;
1003 
1004  if ( !sURL.isEmpty() )
1006 
1007  if ( bBookMarkOnly )
1008  sURL = FieldString( ww::eHYPERLINK );
1009  else
1010  sURL = FieldString( ww::eHYPERLINK ) + "\"" + sURL + "\"";
1011 
1012  if ( !pMark->isEmpty() )
1013  sURL += " \\l \"" + *pMark + "\"";
1014 
1015  if ( !rTarget.isEmpty() )
1016  sURL += " \\n " + rTarget;
1017 
1018  *pLinkURL = sURL;
1019 
1020  return bBookMarkOnly;
1021 }
1022 
1023 void WW8AttributeOutput::WriteBookmarkInActParagraph( const OUString& rName, sal_Int32 nFirstRunPos, sal_Int32 nLastRunPos )
1024 {
1025  m_aBookmarksOfParagraphStart.insert(std::pair<sal_Int32, OUString>(nFirstRunPos, rName));
1026  m_aBookmarksOfParagraphEnd.insert(std::pair<sal_Int32, OUString>(nLastRunPos, rName));
1027 }
1028 
1029 bool WW8AttributeOutput::StartURL( const OUString &rUrl, const OUString &rTarget )
1030 {
1031  INetURLObject aURL( rUrl );
1032  OUString sURL;
1033  OUString sMark;
1034 
1035  bool bBookMarkOnly = AnalyzeURL( rUrl, rTarget, &sURL, &sMark );
1036 
1038 
1039  // write the reference to the "picture" structure
1040  sal_uLong nDataStt = m_rWW8Export.pDataStrm->Tell();
1041  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() );
1042 
1043  // WinWord 2000 doesn't write this - so it's a temp solution by W97 ?
1044  m_rWW8Export.WriteChar( 0x01 );
1045 
1046  static sal_uInt8 aArr1[] = {
1047  0x03, 0x6a, 0,0,0,0, // sprmCPicLocation
1048 
1049  0x06, 0x08, 0x01, // sprmCFData
1050  0x55, 0x08, 0x01, // sprmCFSpec
1051  0x02, 0x08, 0x01 // sprmCFFieldVanish
1052  };
1053  sal_uInt8* pDataAdr = aArr1 + 2;
1054  Set_UInt32( pDataAdr, nDataStt );
1055 
1056  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), sizeof( aArr1 ), aArr1 );
1057 
1059 
1060  // now write the picture structure
1061  sURL = aURL.GetURLNoMark();
1062 
1063  // Compare the URL written by AnalyzeURL with the original one to see if
1064  // the output URL is absolute or relative.
1065  OUString sRelativeURL;
1066  if ( !rUrl.isEmpty() )
1068  bool bAbsolute = sRelativeURL == rUrl;
1069 
1070  static sal_uInt8 aURLData1[] = {
1071  0,0,0,0, // len of struct
1072  0x44,0, // the start of "next" data
1073  0,0,0,0,0,0,0,0,0,0, // PIC-Structure!
1074  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // |
1075  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // |
1076  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // |
1077  0,0,0,0, // /
1078  };
1079  static sal_uInt8 MAGIC_A[] = {
1080  // start of "next" data
1081  0xD0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
1082  0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
1083  };
1084 
1085  m_rWW8Export.pDataStrm->WriteBytes(aURLData1, sizeof(aURLData1));
1086  /* Write HFD Structure */
1087  sal_uInt8 nAnchor = 0x00;
1088  if ( !sMark.isEmpty() )
1089  nAnchor = 0x08;
1090  m_rWW8Export.pDataStrm->WriteUChar(nAnchor); // HFDBits
1091  m_rWW8Export.pDataStrm->WriteBytes(MAGIC_A, sizeof(MAGIC_A)); //clsid
1092 
1093  /* Write Hyperlink Object see [MS-OSHARED] spec*/
1095  sal_uInt32 nFlag = bBookMarkOnly ? 0 : 0x01;
1096  if ( bAbsolute )
1097  nFlag |= 0x02;
1098  if ( !sMark.isEmpty() )
1099  nFlag |= 0x08;
1101 
1102  INetProtocol eProto = aURL.GetProtocol();
1103  if ( eProto == INetProtocol::File || eProto == INetProtocol::Smb )
1104  {
1105  // version 1 (for a document)
1106 
1107  static sal_uInt8 MAGIC_C[] = {
1108  0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109  0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
1110  0x00, 0x00
1111  };
1112 
1113  static sal_uInt8 MAGIC_D[] = {
1114  0xFF, 0xFF, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,
1115  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1116  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1117  };
1118 
1119  // save the links to files as relative
1121  if ( eProto == INetProtocol::File && sURL.startsWith( "/" ) )
1122  sURL = aURL.PathToFileName();
1123 
1124  // special case for the absolute windows names
1125  // (convert '/c:/foo/bar.doc' into 'c:\foo\bar.doc')
1126  if (sURL.getLength()>=3)
1127  {
1128  const sal_Unicode aDrive = sURL[1];
1129  if ( sURL[0]=='/' && sURL[2]==':' &&
1130  ( (aDrive>='A' && aDrive<='Z' ) || (aDrive>='a' && aDrive<='z') ) )
1131  {
1132  sURL = sURL.copy(1).replaceAll("/", "\\");
1133  }
1134  }
1135 
1136  // n#261623 convert smb notation to '\\'
1137  const char pSmb[] = "smb://";
1138  if ( eProto == INetProtocol::Smb && sURL.startsWith( pSmb ) )
1139  {
1140  sURL = sURL.copy( sizeof(pSmb)-3 ).replaceAll( "/", "\\" );
1141  }
1142 
1143  m_rWW8Export.pDataStrm->WriteBytes(MAGIC_C, sizeof(MAGIC_C));
1144  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sURL.getLength()+1 );
1146  RTL_TEXTENCODING_MS_1252 );
1147  m_rWW8Export.pDataStrm->WriteBytes(MAGIC_D, sizeof(MAGIC_D));
1148 
1149  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.getLength() + 6 );
1150  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.getLength() );
1153  }
1154  else if ( eProto != INetProtocol::NotValid )
1155  {
1156  // version 2 (simple url)
1157  // and write some data to the data stream, but don't ask
1158  // what the data mean, except for the URL.
1159  // The First piece is the WW8_PIC structure.
1160  static sal_uInt8 MAGIC_B[] = {
1161  0xE0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
1162  0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
1163  };
1164 
1165  m_rWW8Export.pDataStrm->WriteBytes(MAGIC_B, sizeof(MAGIC_B));
1166  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2 * ( sURL.getLength() + 1 ) );
1168  }
1169 
1170  if ( !sMark.isEmpty() )
1171  {
1172  SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sMark.getLength()+1 );
1174  }
1176  m_rWW8Export.pDataStrm->Tell() - nDataStt );
1177 
1178  return true;
1179 }
1180 
1182 {
1183  m_rWW8Export.OutputField( nullptr, ww::eHYPERLINK, OUString(), FieldFlags::Close );
1184 
1185  return true;
1186 }
1187 
1188 OUString BookmarkToWord(const OUString &rBookmark)
1189 {
1190  OUString sRet(INetURLObject::encode(
1191  rBookmark.replace(' ', '_'), // Spaces are prohibited in bookmark name
1193  INetURLObject::EncodeMechanism::All, RTL_TEXTENCODING_ASCII_US));
1194  // Unicode letters are allowed
1195  sRet = INetURLObject::decode(sRet, INetURLObject::DecodeMechanism::Unambiguous, RTL_TEXTENCODING_UTF8);
1196  return TruncateBookmark(sRet);
1197 }
1198 
1199 OUString BookmarkToWriter(const OUString &rBookmark)
1200 {
1201  return INetURLObject::decode(rBookmark,
1202  INetURLObject::DecodeMechanism::Unambiguous, RTL_TEXTENCODING_ASCII_US);
1203 }
1204 
1206 {
1207  if(m_rExport.HasRefToAttr(rAttr.GetRefName()))
1209  &rAttr.GetRefName(), 0 ));
1210 }
1211 
1212 void SwWW8AttrIter::SplitRun( sal_Int32 nSplitEndPos )
1213 {
1214  auto aIter = std::find_if(maCharRuns.begin(), maCharRuns.end(),
1215  [nSplitEndPos](const CharRunEntry& rCharRun) { return rCharRun.mnEndPos >= nSplitEndPos; });
1216  if (aIter == maCharRuns.end() || aIter->mnEndPos == nSplitEndPos)
1217  return;
1218 
1219  CharRunEntry aNewEntry = *aIter;
1220  aIter->mnEndPos = nSplitEndPos;
1221  maCharRuns.insert( ++aIter, aNewEntry);
1222  maCharRunIter = maCharRuns.begin();
1223  IterToCurrent();
1225 }
1226 
1227 void WW8AttributeOutput::FieldVanish( const OUString& rText, ww::eField /*eType*/ )
1228 {
1229  ww::bytes aItems;
1230  m_rWW8Export.GetCurrentItems( aItems );
1231 
1232  // sprmCFFieldVanish
1234  aItems.push_back( 1 );
1235 
1236  sal_uInt16 nStt_sprmCFSpec = aItems.size();
1237 
1238  // sprmCFSpec -- fSpec-Attribut true
1239  SwWW8Writer::InsUInt16( aItems, 0x855 );
1240  aItems.push_back( 1 );
1241 
1242  m_rWW8Export.WriteChar( '\x13' );
1243  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.size(),
1244  aItems.data() );
1245  m_rWW8Export.OutSwString(rText, 0, rText.getLength());
1246  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), nStt_sprmCFSpec,
1247  aItems.data() );
1248  m_rWW8Export.WriteChar( '\x15' );
1249  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.size(),
1250  aItems.data() );
1251 }
1252 
1253 void AttributeOutputBase::TOXMark( const SwTextNode& rNode, const SwTOXMark& rAttr )
1254 {
1255  // it's a field; so get the Text from the Node and build the field
1256  OUString sText;
1258 
1259  const SwTextTOXMark& rTextTOXMark = *rAttr.GetTextTOXMark();
1260  const sal_Int32* pTextEnd = rTextTOXMark.End();
1261  if ( pTextEnd ) // has range?
1262  {
1263  sText = rNode.GetExpandText(nullptr, rTextTOXMark.GetStart(),
1264  *pTextEnd - rTextTOXMark.GetStart() );
1265  }
1266  else
1267  sText = rAttr.GetAlternativeText();
1268 
1269  switch ( rAttr.GetTOXType()->GetType() )
1270  {
1271  case TOX_INDEX:
1272  eType = ww::eXE;
1273  if ( !rAttr.GetPrimaryKey().isEmpty() )
1274  {
1275  if ( !rAttr.GetSecondaryKey().isEmpty() )
1276  {
1277  sText = rAttr.GetSecondaryKey() + ":" + sText;
1278  }
1279 
1280  sText = rAttr.GetPrimaryKey() + ":" + sText;
1281  }
1282  sText = " XE \"" + sText + "\" ";
1283  break;
1284 
1285  case TOX_USER:
1286  sText += "\" \\f \"" + OUStringChar(static_cast<char>( 'A' + GetExport( ).GetId( *rAttr.GetTOXType() ) ));
1287  [[fallthrough]];
1288  case TOX_CONTENT:
1289  {
1290  eType = ww::eTC;
1291  sText = " TC \"" + sText;
1292  sal_uInt16 nLvl = rAttr.GetLevel();
1293  if (nLvl > WW8ListManager::nMaxLevel)
1295 
1296  sText += "\" \\l " + OUString::number(nLvl) + " ";
1297  }
1298  break;
1299  default:
1300  OSL_ENSURE( false, "Unhandled option for toc export" );
1301  break;
1302  }
1303 
1304  if (!sText.isEmpty())
1305  FieldVanish( sText, eType );
1306 }
1307 
1308 int SwWW8AttrIter::OutAttrWithRange(const SwTextNode& rNode, sal_Int32 nPos)
1309 {
1310  int nRet = 0;
1311  if ( const SwpHints* pTextAttrs = rNd.GetpSwpHints() )
1312  {
1313  m_rExport.m_aCurrentCharPropStarts.push( nPos );
1314  const sal_Int32* pEnd;
1315  // first process ends of attributes with extent
1316  for (size_t i = 0; i < pTextAttrs->Count(); ++i)
1317  {
1318  const SwTextAttr* pHt = pTextAttrs->GetSortedByEnd(i);
1319  const SfxPoolItem* pItem = &pHt->GetAttr();
1320  switch ( pItem->Which() )
1321  {
1322  case RES_TXTATR_INETFMT:
1323  pEnd = pHt->End();
1324  if (nPos == *pEnd && nPos != pHt->GetStart())
1325  {
1326  if (m_rExport.AttrOutput().EndURL(nPos == rNd.Len()))
1327  --nRet;
1328  }
1329  break;
1330  case RES_TXTATR_REFMARK:
1331  pEnd = pHt->End();
1332  if (nullptr != pEnd && nPos == *pEnd && nPos != pHt->GetStart())
1333  {
1334  OutSwFormatRefMark(*static_cast<const SwFormatRefMark*>(pItem));
1335  --nRet;
1336  }
1337  break;
1338  case RES_TXTATR_CJK_RUBY:
1339  pEnd = pHt->End();
1340  if (nPos == *pEnd && nPos != pHt->GetStart())
1341  {
1342  m_rExport.AttrOutput().EndRuby(rNode, nPos);
1343  --nRet;
1344  }
1345  break;
1346  }
1347  if (nPos < pHt->GetAnyEnd())
1348  break; // sorted by end
1349  }
1350  for ( size_t i = 0; i < pTextAttrs->Count(); ++i )
1351  {
1352  const SwTextAttr* pHt = pTextAttrs->Get(i);
1353  const SfxPoolItem* pItem = &pHt->GetAttr();
1354  switch ( pItem->Which() )
1355  {
1356  case RES_TXTATR_INETFMT:
1357  if ( nPos == pHt->GetStart() )
1358  {
1359  const SwFormatINetFormat *rINet = static_cast< const SwFormatINetFormat* >( pItem );
1360  if ( m_rExport.AttrOutput().StartURL( rINet->GetValue(), rINet->GetTargetFrame() ) )
1361  ++nRet;
1362  }
1363  pEnd = pHt->End();
1364  if (nPos == *pEnd && nPos == pHt->GetStart())
1365  { // special case: empty must be handled here
1366  if (m_rExport.AttrOutput().EndURL(nPos == rNd.Len()))
1367  --nRet;
1368  }
1369  break;
1370  case RES_TXTATR_REFMARK:
1371  if ( nPos == pHt->GetStart() )
1372  {
1373  OutSwFormatRefMark( *static_cast< const SwFormatRefMark* >( pItem ) );
1374  ++nRet;
1375  }
1376  pEnd = pHt->End();
1377  if (nullptr != pEnd && nPos == *pEnd && nPos == pHt->GetStart())
1378  { // special case: empty TODO: is this possible or would empty one have pEnd null?
1379  OutSwFormatRefMark( *static_cast< const SwFormatRefMark* >( pItem ) );
1380  --nRet;
1381  }
1382  break;
1383  case RES_TXTATR_TOXMARK:
1384  if ( nPos == pHt->GetStart() )
1385  m_rExport.AttrOutput().TOXMark( rNd, *static_cast< const SwTOXMark* >( pItem ) );
1386  break;
1387  case RES_TXTATR_CJK_RUBY:
1388  if ( nPos == pHt->GetStart() )
1389  {
1390  m_rExport.AttrOutput().StartRuby( rNd, nPos, *static_cast< const SwFormatRuby* >( pItem ) );
1391  ++nRet;
1392  }
1393  pEnd = pHt->End();
1394  if (nPos == *pEnd && nPos == pHt->GetStart())
1395  { // special case: empty must be handled here
1396  m_rExport.AttrOutput().EndRuby( rNd, nPos );
1397  --nRet;
1398  }
1399  break;
1400  }
1401  if (nPos < pHt->GetStart())
1402  break; // sorted by start
1403  }
1404  m_rExport.m_aCurrentCharPropStarts.pop(); // HasTextItem only allowed in the above range
1405  }
1406  return nRet;
1407 }
1408 
1410 {
1411  // search next Redline
1414  {
1416  const SwPosition* pEnd = pRange->End();
1417  const SwPosition* pStart = pRange->Start();
1418  bool bBreak = true;
1419  // In word the paragraph end marker is a real character, in writer it is not.
1420  // Here we find out if the para end marker we will emit is affected by
1421  // redlining, in which case it must be included by the range of character
1422  // attributes that contains the redlining information.
1423  if (pEnd->nNode == rNd)
1424  {
1425  if (pEnd->nContent.GetIndex() == nEnd)
1426  {
1427  // This condition detects if the pseudo-char we will export
1428  // should be explicitly included by the redlining char
1429  // properties on this node because the redlining ends right
1430  // after it
1431  return true;
1432  }
1433  bBreak = false;
1434  }
1435  if (pStart->nNode == rNd)
1436  {
1437  if (pStart->nContent.GetIndex() == nEnd)
1438  {
1439  // This condition detects if the pseudo-char we will export
1440  // should be explicitly included by the redlining char
1441  // properties on this node because the redlining starts right
1442  // before it
1443  return true;
1444  }
1445  bBreak = false;
1446  }
1447  if (pStart->nNode.GetIndex()-1 == rNd.GetIndex())
1448  {
1449  if (pStart->nContent.GetIndex() == 0)
1450  {
1451  // This condition detects if the pseudo-char we will export
1452  // should be implicitly excluded by the redlining char
1453  // properties starting on the next node.
1454  return true;
1455  }
1456  bBreak = false;
1457  }
1458 
1459  if (bBreak)
1460  break;
1461  }
1462  return false;
1463 }
1464 
1466 {
1467  pCurRedline = nullptr;
1468 
1469  // ToDo : this is not the most ideal ... should start maybe from 'nCurRedlinePos'
1471  {
1472  const SwPosition* pCheckedStt = pRedl->Start();
1473 
1474  if( pCheckedStt->nNode == rNd )
1475  {
1476  // Maybe add here a check that also the start & end of the redline is the entire paragraph
1477 
1478  // Only return if this is a paragraph formatting redline
1479  if (pRedl->GetType() == RedlineType::ParagraphFormat)
1480  {
1481  // write data of this redline
1482  pCurRedline = pRedl;
1483  return &( pCurRedline->GetRedlineData() );
1484  }
1485  }
1486  }
1487  return nullptr;
1488 }
1489 
1491 {
1492  if( pCurRedline )
1493  {
1494  const SwPosition* pEnd = pCurRedline->End();
1495  if (pEnd->nNode != rNd || pEnd->nContent.GetIndex() > nPos)
1496  {
1497  switch( pCurRedline->GetType() )
1498  {
1499  case RedlineType::Insert:
1500  case RedlineType::Delete:
1501  case RedlineType::Format:
1502  // write data of this redline
1503  return &( pCurRedline->GetRedlineData() );
1504  break;
1505  default:
1506  break;
1507  }
1508  }
1509  pCurRedline = nullptr;
1510  ++nCurRedlinePos;
1511  }
1512 
1513  assert(!pCurRedline);
1514  // search next Redline
1516  ++nCurRedlinePos )
1517  {
1519 
1520  const SwPosition* pStt = pRedl->Start();
1521  const SwPosition* pEnd = pStt == pRedl->GetPoint()
1522  ? pRedl->GetMark()
1523  : pRedl->GetPoint();
1524 
1525  if( pStt->nNode == rNd )
1526  {
1527  if( pStt->nContent.GetIndex() >= nPos )
1528  {
1529  if( pStt->nContent.GetIndex() == nPos )
1530  {
1531  switch( pRedl->GetType() )
1532  {
1533  case RedlineType::Insert:
1534  case RedlineType::Delete:
1535  case RedlineType::Format:
1536  // write data of this redline
1537  pCurRedline = pRedl;
1538  return &( pCurRedline->GetRedlineData() );
1539  break;
1540  default:
1541  break;
1542  }
1543  }
1544  break;
1545  }
1546  }
1547  else
1548  {
1549  break;
1550  }
1551 
1552  if( pEnd->nNode == rNd &&
1553  pEnd->nContent.GetIndex() < nPos )
1554  {
1555  pCurRedline = pRedl;
1556  break;
1557  }
1558  }
1559  return nullptr;
1560 }
1561 
1563 {
1564  const SwFrameFormat &rFormat = m_pCurrentPageDesc
1566  : m_rDoc.GetPageDesc( 0 ).GetMaster();
1567  return rFormat.GetFrameDir().GetValue();
1568 }
1569 
1571 {
1572  SvxFrameDirection nDir = SvxFrameDirection::Environment;
1573 
1574  if ( m_bOutPageDescs )
1575  nDir = GetCurrentPageDirection( );
1576  else if ( m_pOutFormatNode )
1577  {
1578  if ( m_bOutFlyFrameAttrs ) //frame
1579  {
1580  nDir = TrueFrameDirection( *static_cast< const SwFrameFormat * >(m_pOutFormatNode) );
1581  }
1582  else if ( auto pNd = dynamic_cast< const SwContentNode *>( m_pOutFormatNode ) ) //paragraph
1583  {
1584  SwPosition aPos( *pNd );
1585  nDir = m_rDoc.GetTextDirection( aPos );
1586  }
1587  else if ( dynamic_cast< const SwTextFormatColl *>( m_pOutFormatNode ) != nullptr )
1588  {
1590  nDir = SvxFrameDirection::Horizontal_RL_TB;
1591  else
1592  nDir = SvxFrameDirection::Horizontal_LR_TB; //what else can we do :-(
1593  }
1594  }
1595 
1596  if ( nDir == SvxFrameDirection::Environment )
1597  {
1598  // fdo#44029 put direction right when the locale are RTL.
1600  nDir = SvxFrameDirection::Horizontal_RL_TB;
1601  else
1602  nDir = SvxFrameDirection::Horizontal_LR_TB; //Set something
1603  }
1604 
1605  return nDir;
1606 }
1607 
1609 {
1610  const SwFrameFormat *pFlyFormat = &rFlyFormat;
1611  const SvxFrameDirectionItem* pItem = nullptr;
1612  while ( pFlyFormat )
1613  {
1614  pItem = &pFlyFormat->GetFrameDir();
1615  if ( SvxFrameDirection::Environment == pItem->GetValue() )
1616  {
1617  pItem = nullptr;
1618  const SwFormatAnchor* pAnchor = &pFlyFormat->GetAnchor();
1619  if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
1620  pAnchor->GetContentAnchor() )
1621  {
1622  pFlyFormat = pAnchor->GetContentAnchor()->nNode.GetNode().GetFlyFormat();
1623  }
1624  else
1625  pFlyFormat = nullptr;
1626  }
1627  else
1628  pFlyFormat = nullptr;
1629  }
1630 
1631  SvxFrameDirection nRet;
1632  if ( pItem )
1633  nRet = pItem->GetValue();
1634  else
1635  nRet = GetCurrentPageDirection();
1636 
1637  OSL_ENSURE( nRet != SvxFrameDirection::Environment, "leaving with environment direction" );
1638  return nRet;
1639 }
1640 
1642 {
1643  const SwFrameFormat &rFormat = m_pCurrentPageDesc
1645  : m_rDoc.GetPageDesc(0).GetMaster();
1646 
1647  const SfxPoolItem* pItem = nullptr;
1648  //If not set, or "no fill", get real bg
1649  SfxItemState eState = rFormat.GetItemState(RES_BACKGROUND, true, &pItem);
1650 
1651  const SvxBrushItem* pRet = static_cast<const SvxBrushItem*>(pItem);
1652  if (SfxItemState::SET != eState || !pRet || (!pRet->GetGraphic() &&
1653  pRet->GetColor() == COL_TRANSPARENT))
1654  {
1655  pRet = &(DefaultItemGet<SvxBrushItem>(m_rDoc,RES_BACKGROUND));
1656  }
1657  return pRet;
1658 }
1659 
1660 std::shared_ptr<SvxBrushItem> WW8Export::TrueFrameBgBrush(const SwFrameFormat &rFlyFormat) const
1661 {
1662  const SwFrameFormat *pFlyFormat = &rFlyFormat;
1663  const SvxBrushItem* pRet = nullptr;
1664 
1665  while (pFlyFormat)
1666  {
1667  //If not set, or "no fill", get real bg
1668  const SfxPoolItem* pItem = nullptr;
1669  SfxItemState eState =
1670  pFlyFormat->GetItemState(RES_BACKGROUND, true, &pItem);
1671  pRet = static_cast<const SvxBrushItem*>(pItem);
1672  if (SfxItemState::SET != eState || !pRet || (!pRet->GetGraphic() &&
1673  pRet->GetColor() == COL_TRANSPARENT))
1674  {
1675  pRet = nullptr;
1676  const SwFormatAnchor* pAnchor = &pFlyFormat->GetAnchor();
1677  if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
1678  pAnchor->GetContentAnchor())
1679  {
1680  pFlyFormat =
1681  pAnchor->GetContentAnchor()->nNode.GetNode().GetFlyFormat();
1682  }
1683  else
1684  pFlyFormat = nullptr;
1685  }
1686  else
1687  pFlyFormat = nullptr;
1688  }
1689 
1690  if (!pRet)
1691  pRet = GetCurrentPageBgBrush();
1692 
1693  const Color aTmpColor( COL_WHITE );
1694  std::shared_ptr<SvxBrushItem> aRet(std::make_shared<SvxBrushItem>(aTmpColor, RES_BACKGROUND));
1695 
1696  if (pRet && (pRet->GetGraphic() ||( pRet->GetColor() != COL_TRANSPARENT)))
1697  {
1698  aRet.reset(pRet->Clone());
1699  }
1700 
1701  return aRet;
1702 }
1703 
1704 /*
1705 Convert characters that need to be converted, the basic replacements and the
1706 ridiculously complicated title case attribute mapping to hardcoded upper case
1707 because word doesn't have the feature
1708 */
1709 OUString SwWW8AttrIter::GetSnippet(const OUString &rStr, sal_Int32 nCurrentPos,
1710  sal_Int32 nLen) const
1711 {
1712  if (!nLen)
1713  return OUString();
1714 
1715  OUString aSnippet(rStr.copy(nCurrentPos, nLen));
1716  // 0x0a ( Hard Line Break ) -> 0x0b
1717  // 0xad ( soft hyphen ) -> 0x1f
1718  // 0x2011 ( hard hyphen ) -> 0x1e
1719  aSnippet = aSnippet.replace(0x0A, 0x0B);
1720  aSnippet = aSnippet.replace(CHAR_HARDHYPHEN, 0x1e);
1721  aSnippet = aSnippet.replace(CHAR_SOFTHYPHEN, 0x1f);
1722 
1723  m_rExport.m_aCurrentCharPropStarts.push( nCurrentPos );
1724  const SfxPoolItem &rItem = GetItem(RES_CHRATR_CASEMAP);
1725 
1726  if (SvxCaseMap::Capitalize == static_cast<const SvxCaseMapItem&>(rItem).GetValue())
1727  {
1729  sal_uInt16 nScriptType = g_pBreakIt->GetBreakIter()->getScriptType(aSnippet, 0);
1730 
1731  LanguageType nLanguage;
1732  switch (nScriptType)
1733  {
1734  case i18n::ScriptType::ASIAN:
1735  nLanguage = static_cast<const SvxLanguageItem&>(GetItem(RES_CHRATR_CJK_LANGUAGE)).GetLanguage();
1736  break;
1737  case i18n::ScriptType::COMPLEX:
1738  nLanguage = static_cast<const SvxLanguageItem&>(GetItem(RES_CHRATR_CTL_LANGUAGE)).GetLanguage();
1739  break;
1740  case i18n::ScriptType::LATIN:
1741  default:
1742  nLanguage = static_cast<const SvxLanguageItem&>(GetItem(RES_CHRATR_LANGUAGE)).GetLanguage();
1743  break;
1744  }
1745 
1746  SvxFont aFontHelper;
1747  aFontHelper.SetCaseMap(SvxCaseMap::Capitalize);
1748  aFontHelper.SetLanguage(nLanguage);
1749  aSnippet = aFontHelper.CalcCaseMap(aSnippet);
1750 
1751  //If we weren't at the begin of a word undo the case change.
1752  //not done before doing the casemap because the sequence might start
1753  //with whitespace
1754  if (!g_pBreakIt->GetBreakIter()->isBeginWord(
1755  rStr, nCurrentPos, g_pBreakIt->GetLocale(nLanguage),
1756  i18n::WordType::ANYWORD_IGNOREWHITESPACES ) )
1757  {
1758  aSnippet = OUStringChar(rStr[nCurrentPos]) + aSnippet.subView(1);
1759  }
1760  }
1762 
1763  return aSnippet;
1764 }
1765 
1773 {
1776  while( nPos < nMax )
1777  {
1778  const SwRangeRedline* pRedl = rExport.m_rDoc.getIDocumentRedlineAccess().GetRedlineTable()[ nPos++ ];
1779  const SwPosition* pStt = pRedl->Start();
1780  const SwPosition* pEnd = pStt == pRedl->GetPoint()
1781  ? pRedl->GetMark()
1782  : pRedl->GetPoint();
1783  // Looking for deletions, which ends in current pTextNode
1784  if( RedlineType::Delete == pRedl->GetRedlineData().GetType() &&
1785  pEnd->nNode == *pTextNode && pStt->nNode != *pTextNode &&
1786  pStt->nNode.GetNode().IsTextNode() )
1787  {
1788  pTextNode = pStt->nNode.GetNode().GetTextNode();
1789  nMax = nPos;
1790  nPos = 0;
1791  }
1792  }
1793  return static_cast<SwTextFormatColl&>( pTextNode->GetAnyFormatColl() );
1794 }
1795 
1796 void WW8AttributeOutput::FormatDrop( const SwTextNode& rNode, const SwFormatDrop &rSwFormatDrop, sal_uInt16 nStyle,
1798 {
1799  short nDropLines = rSwFormatDrop.GetLines();
1800  short nDistance = rSwFormatDrop.GetDistance();
1801  int rFontHeight, rDropHeight, rDropDescent;
1802 
1803  SVBT16 nSty;
1804  ShortToSVBT16( nStyle, nSty );
1805  m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), nSty, nSty+2 ); // Style #
1806 
1807  m_rWW8Export.InsUInt16( NS_sprm::PPc::val ); // Alignment (sprmPPc)
1808  m_rWW8Export.pO->push_back( 0x20 );
1809 
1810  m_rWW8Export.InsUInt16( NS_sprm::PWr::val ); // Wrapping (sprmPWr)
1811  m_rWW8Export.pO->push_back( 0x02 );
1812 
1813  m_rWW8Export.InsUInt16( NS_sprm::PDcs::val ); // Dropcap (sprmPDcs)
1814  int nDCS = ( nDropLines << 3 ) | 0x01;
1815  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( nDCS ) );
1816 
1817  m_rWW8Export.InsUInt16( NS_sprm::PDxaFromText::val ); // Distance from text (sprmPDxaFromText)
1818  m_rWW8Export.InsUInt16( nDistance );
1819 
1820  if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1821  {
1822  m_rWW8Export.InsUInt16( NS_sprm::PDyaLine::val ); // Line spacing
1823  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -rDropHeight ) );
1824  m_rWW8Export.InsUInt16( 0 );
1825  }
1826 
1827  m_rWW8Export.WriteCR( pTextNodeInfoInner );
1828 
1829  if ( pTextNodeInfo )
1830  {
1831 #ifdef DBG_UTIL
1832  SAL_INFO( "sw.ww8", pTextNodeInfo->toString());
1833 #endif
1834  TableInfoCell( pTextNodeInfoInner );
1835  }
1836 
1837  m_rWW8Export.m_pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
1838  m_rWW8Export.pO->clear();
1839 
1840  if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1841  {
1842  const SwCharFormat *pSwCharFormat = rSwFormatDrop.GetCharFormat();
1843  if ( pSwCharFormat )
1844  {
1846  m_rWW8Export.InsUInt16( m_rWW8Export.GetId( pSwCharFormat ) );
1847  }
1848 
1849  m_rWW8Export.InsUInt16( NS_sprm::CHpsPos::val ); // Lower the chars
1850  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -((nDropLines - 1)*rDropDescent) / 10 ) );
1851 
1852  m_rWW8Export.InsUInt16( NS_sprm::CHps::val ); // Font Size
1853  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( rFontHeight / 10 ) );
1854  }
1855 
1856  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
1857  m_rWW8Export.pO->clear();
1858 }
1859 
1860 sal_Int32 MSWordExportBase::GetNextPos( SwWW8AttrIter const * aAttrIter, const SwTextNode& rNode, sal_Int32 nCurrentPos )
1861 {
1862  // Get the bookmarks for the normal run
1863  const sal_Int32 nNextPos = aAttrIter->WhereNext();
1864  sal_Int32 nNextBookmark = nNextPos;
1865  sal_Int32 nNextAnnotationMark = nNextPos;
1866 
1867  if( nNextBookmark > nCurrentPos ) //no need to search for bookmarks otherwise (checked in UpdatePosition())
1868  {
1869  GetSortedBookmarks( rNode, nCurrentPos, nNextBookmark - nCurrentPos );
1870  NearestBookmark( nNextBookmark, nCurrentPos, false );
1871  GetSortedAnnotationMarks(*aAttrIter, nCurrentPos, nNextAnnotationMark - nCurrentPos);
1872  NearestAnnotationMark( nNextAnnotationMark, nCurrentPos, false );
1873  }
1874  return std::min( nNextPos, std::min( nNextBookmark, nNextAnnotationMark ) );
1875 }
1876 
1877 void MSWordExportBase::UpdatePosition( SwWW8AttrIter* aAttrIter, sal_Int32 nCurrentPos )
1878 {
1879  sal_Int32 nNextPos;
1880 
1881  // go to next attribute if no bookmark is found or if the bookmark is after the next attribute position
1882  // It may happened that the WhereNext() wasn't used in the previous increment because there was a
1883  // bookmark before it. Use that position before trying to find another one.
1884  bool bNextBookmark = NearestBookmark( nNextPos, nCurrentPos, true );
1885  if( nCurrentPos == aAttrIter->WhereNext() && ( !bNextBookmark || nNextPos > aAttrIter->WhereNext() ) )
1886  aAttrIter->NextPos();
1887 }
1888 
1889 bool MSWordExportBase::GetBookmarks( const SwTextNode& rNd, sal_Int32 nStt,
1890  sal_Int32 nEnd, IMarkVector& rArr )
1891 {
1892  IDocumentMarkAccess* const pMarkAccess = m_rDoc.getIDocumentMarkAccess();
1893  sal_uLong nNd = rNd.GetIndex( );
1894 
1895  const sal_Int32 nMarks = pMarkAccess->getAllMarksCount();
1896  for ( sal_Int32 i = 0; i < nMarks; i++ )
1897  {
1898  IMark* pMark = pMarkAccess->getAllMarksBegin()[i];
1899 
1900  switch (IDocumentMarkAccess::GetType( *pMark ))
1901  {
1910  continue; // ignore irrelevant marks
1914  break;
1915  }
1916 
1917  // Only keep the bookmarks starting or ending in this node
1918  if ( pMark->GetMarkStart().nNode == nNd ||
1919  pMark->GetMarkEnd().nNode == nNd )
1920  {
1921  const sal_Int32 nBStart = pMark->GetMarkStart().nContent.GetIndex();
1922  const sal_Int32 nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
1923 
1924  // Keep only the bookmarks starting or ending in the snippet
1925  bool bIsStartOk = ( pMark->GetMarkStart().nNode == nNd ) && ( nBStart >= nStt ) && ( nBStart <= nEnd );
1926  bool bIsEndOk = ( pMark->GetMarkEnd().nNode == nNd ) && ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
1927 
1928  if ( bIsStartOk || bIsEndOk )
1929  {
1930  rArr.push_back( pMark );
1931  }
1932  }
1933  }
1934  return ( !rArr.empty() );
1935 }
1936 
1937 bool MSWordExportBase::GetAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nStt,
1938  sal_Int32 nEnd, IMarkVector& rArr )
1939 {
1940  IDocumentMarkAccess* const pMarkAccess = m_rDoc.getIDocumentMarkAccess();
1941  sal_uLong nNd = rAttrs.GetNode().GetIndex();
1942 
1943  const sal_Int32 nMarks = pMarkAccess->getAnnotationMarksCount();
1944  for ( sal_Int32 i = 0; i < nMarks; i++ )
1945  {
1946  IMark* pMark = pMarkAccess->getAnnotationMarksBegin()[i];
1947 
1948  // Only keep the bookmarks starting or ending in this node
1949  if ( pMark->GetMarkStart().nNode == nNd ||
1950  pMark->GetMarkEnd().nNode == nNd )
1951  {
1952  const sal_Int32 nBStart = pMark->GetMarkStart().nContent.GetIndex();
1953  const sal_Int32 nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
1954 
1955  // Keep only the bookmarks starting or ending in the snippet
1956  bool bIsStartOk = ( pMark->GetMarkStart().nNode == nNd ) && ( nBStart >= nStt ) && ( nBStart <= nEnd );
1957  bool bIsEndOk = ( pMark->GetMarkEnd().nNode == nNd ) && ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
1958 
1959  // Annotation marks always have at least one character: the anchor
1960  // point of the comment field. In this case Word wants only the
1961  // comment field, so ignore the annotation mark itself.
1962  bool bSingleChar = pMark->GetMarkStart().nNode == pMark->GetMarkEnd().nNode && nBStart + 1 == nBEnd;
1963 
1964  if (bSingleChar)
1965  {
1966  if (rAttrs.HasFlysAt(nBStart))
1967  {
1968  // There is content (an at-char anchored frame) between the annotation mark
1969  // start/end, so still emit range start/end.
1970  bSingleChar = false;
1971  }
1972  }
1973 
1974  if ( ( bIsStartOk || bIsEndOk ) && !bSingleChar )
1975  {
1976  rArr.push_back( pMark );
1977  }
1978  }
1979  }
1980  return ( !rArr.empty() );
1981 }
1982 
1983 namespace {
1984 
1985 class CompareMarksEnd
1986 {
1987 public:
1988  bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
1989  {
1990  const sal_Int32 nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
1991  const sal_Int32 nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
1992 
1993  return nOEnd < nTEnd;
1994  }
1995 };
1996 
1997 }
1998 
1999 bool MSWordExportBase::NearestBookmark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly )
2000 {
2001  bool bHasBookmark = false;
2002 
2003  if ( !m_rSortedBookmarksStart.empty() )
2004  {
2005  IMark* pMarkStart = m_rSortedBookmarksStart.front();
2006  const sal_Int32 nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
2007  if( !bNextPositionOnly || (nNext > nCurrentPos ))
2008  {
2009  rNearest = nNext;
2010  bHasBookmark = true;
2011  }
2012  }
2013 
2014  if ( !m_rSortedBookmarksEnd.empty() )
2015  {
2016  IMark* pMarkEnd = m_rSortedBookmarksEnd[0];
2017  const sal_Int32 nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
2018  if( !bNextPositionOnly || nNext > nCurrentPos )
2019  {
2020  if ( !bHasBookmark )
2021  rNearest = nNext;
2022  else
2023  rNearest = std::min( rNearest, nNext );
2024  bHasBookmark = true;
2025  }
2026  }
2027 
2028  return bHasBookmark;
2029 }
2030 
2031 void MSWordExportBase::NearestAnnotationMark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly )
2032 {
2033  bool bHasAnnotationMark = false;
2034 
2035  if ( !m_rSortedAnnotationMarksStart.empty() )
2036  {
2037  IMark* pMarkStart = m_rSortedAnnotationMarksStart.front();
2038  const sal_Int32 nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
2039  if( !bNextPositionOnly || (nNext > nCurrentPos ))
2040  {
2041  rNearest = nNext;
2042  bHasAnnotationMark = true;
2043  }
2044  }
2045 
2046  if ( !m_rSortedAnnotationMarksEnd.empty() )
2047  {
2048  IMark* pMarkEnd = m_rSortedAnnotationMarksEnd[0];
2049  const sal_Int32 nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
2050  if( !bNextPositionOnly || nNext > nCurrentPos )
2051  {
2052  if ( !bHasAnnotationMark )
2053  rNearest = nNext;
2054  else
2055  rNearest = std::min( rNearest, nNext );
2056  }
2057  }
2058 }
2059 
2060 void MSWordExportBase::GetSortedAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen )
2061 {
2062  IMarkVector aMarksStart;
2063  if (GetAnnotationMarks(rAttrs, nCurrentPos, nCurrentPos + nLen, aMarksStart))
2064  {
2065  IMarkVector aSortedEnd;
2066  IMarkVector aSortedStart;
2067  for ( IMark* pMark : aMarksStart )
2068  {
2069  // Remove the positions equal to the current pos
2070  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
2071  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
2072 
2073  const SwTextNode& rNode = rAttrs.GetNode();
2074  if ( nStart > nCurrentPos && ( pMark->GetMarkStart().nNode == rNode.GetIndex()) )
2075  aSortedStart.push_back( pMark );
2076 
2077  if ( nEnd > nCurrentPos && nEnd <= ( nCurrentPos + nLen ) && (pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
2078  aSortedEnd.push_back( pMark );
2079  }
2080 
2081  // Sort the bookmarks by end position
2082  std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
2083 
2084  m_rSortedAnnotationMarksStart.swap( aSortedStart );
2085  m_rSortedAnnotationMarksEnd.swap( aSortedEnd );
2086  }
2087  else
2088  {
2090  m_rSortedAnnotationMarksEnd.clear( );
2091  }
2092 }
2093 
2094 void MSWordExportBase::GetSortedBookmarks( const SwTextNode& rNode, sal_Int32 nCurrentPos, sal_Int32 nLen )
2095 {
2096  IMarkVector aMarksStart;
2097  if ( GetBookmarks( rNode, nCurrentPos, nCurrentPos + nLen, aMarksStart ) )
2098  {
2099  IMarkVector aSortedEnd;
2100  IMarkVector aSortedStart;
2101  for ( IMark* pMark : aMarksStart )
2102  {
2103  // Remove the positions equal to the current pos
2104  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
2105  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
2106 
2107  if ( nStart > nCurrentPos && ( pMark->GetMarkStart().nNode == rNode.GetIndex()) )
2108  aSortedStart.push_back( pMark );
2109 
2110  if ( nEnd > nCurrentPos && nEnd <= ( nCurrentPos + nLen ) && (pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
2111  aSortedEnd.push_back( pMark );
2112  }
2113 
2114  // Sort the bookmarks by end position
2115  std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
2116 
2117  m_rSortedBookmarksStart.swap( aSortedStart );
2118  m_rSortedBookmarksEnd.swap( aSortedEnd );
2119  }
2120  else
2121  {
2122  m_rSortedBookmarksStart.clear( );
2123  m_rSortedBookmarksEnd.clear( );
2124  }
2125 }
2126 
2128 {
2130  return false;
2131 
2132  const SwPageDesc * pPageDesc = rNd.FindPageDesc()->GetFollow();
2133 
2134  if (m_pCurrentPageDesc != pPageDesc)
2135  {
2137  {
2138  return true;
2139  }
2140  }
2141 
2142  return false;
2143 }
2144 
2146 {
2147  SwSoftPageBreakList tmp;
2148  rNd.fillSoftPageBreakList(tmp);
2149  // hack: move the break behind any field marks; currently we can't hide the
2150  // field mark instruction so the layout position is quite meaningless
2151  IDocumentMarkAccess const& rIDMA(*rNd.GetDoc().getIDocumentMarkAccess());
2152  sal_Int32 pos(-1);
2153  for (auto const& it : tmp)
2154  {
2155  if (pos < it) // previous one might have skipped over it
2156  {
2157  pos = it;
2158  while (auto const*const pMark = rIDMA.getFieldmarkFor(SwPosition(const_cast<SwTextNode&>(rNd), pos)))
2159  {
2160  if (pMark->GetMarkEnd().nNode != rNd)
2161  {
2162  pos = rNd.Len(); // skip everything
2163  break;
2164  }
2165  pos = pMark->GetMarkEnd().nContent.GetIndex(); // no +1, it's behind the char
2166  }
2167  pList.insert(pos);
2168  }
2169  }
2170  pList.insert(0);
2171  pList.insert( rNd.GetText().getLength() );
2172  return pList.size() > 2 && NeedSectionBreak( rNd );
2173 }
2174 
2176 {
2177  SAL_INFO( "sw.ww8", "<OutWW8_SwTextNode>" );
2178 
2179  ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo( m_pTableInfo->getTableNodeInfo( &rNode ) );
2180 
2181  //For i120928,identify the last node
2182  bool bLastCR = false;
2183  bool bExported = false;
2184  {
2185  SwNodeIndex aNextIdx(rNode,1);
2186  SwNodeIndex aLastIdx(rNode.GetNodes().GetEndOfContent());
2187  if (aNextIdx == aLastIdx)
2188  bLastCR = true;
2189  }
2190 
2191  // In order to make sure watermark is stored in 'header.xml', check nTextTyp.
2192  // if it is document.xml, don't write the tags (watermark should be only in the 'header')
2193  SwWW8AttrIter aWatermarkAttrIter( *this, rNode );
2194  if (( TXT_HDFT != m_nTextTyp) && aWatermarkAttrIter.IsWatermarkFrame())
2195  {
2196  return;
2197  }
2198 
2199  bool bFlyInTable = m_pParentFrame && IsInTable();
2200 
2201  SwTextFormatColl& rTextColl = lcl_getFormatCollection( *this, &rNode );
2202  if ( !bFlyInTable )
2203  m_nStyleBeforeFly = GetId( rTextColl );
2204 
2205  // nStyleBeforeFly may change when we recurse into another node, so we
2206  // have to remember it in nStyle
2207  sal_uInt16 nStyle = m_nStyleBeforeFly;
2208 
2209  SwWW8AttrIter aAttrIter( *this, rNode );
2210  rtl_TextEncoding eChrSet = aAttrIter.GetCharSet();
2211 
2212  if ( m_bStartTOX )
2213  {
2214  // ignore TOX header section
2215  const SwSectionNode* pSectNd = rNode.FindSectionNode();
2216  if ( pSectNd && SectionType::ToxContent == pSectNd->GetSection().GetType() )
2217  {
2218  AttrOutput().StartTOX( pSectNd->GetSection() );
2219  m_aCurrentCharPropStarts.push( 0 );
2220  }
2221  }
2222 
2223  // Emulate: If 1-row table is marked as don't split, then set the row as don't split.
2224  if ( IsInTable() )
2225  {
2226  const SwTableNode* pTableNode = rNode.FindTableNode();
2227  if ( pTableNode )
2228  {
2229  const SwTable& rTable = pTableNode->GetTable();
2230  const SwTableBox* pBox = rNode.GetTableBox();
2231 
2232  // export formula cell as formula field instead of only its cell content in DOCX
2233  if ( pBox->IsFormulaOrValueBox() == RES_BOXATR_FORMULA &&
2234  GetExportFormat() == MSWordExportBase::ExportFormat::DOCX )
2235  {
2236  std::unique_ptr<SwTableBoxFormula> pFormula(pBox->GetFrameFormat()->GetTableBoxFormula().Clone());
2237  pFormula->PtrToBoxNm( &pTableNode->GetTable() );
2238  OutputField( nullptr, ww::eEquals, " =" + pFormula->GetFormula(),
2240  }
2241 
2242  const bool bKeep = rTable.GetFrameFormat()->GetKeep().GetValue();
2243  const bool bDontSplit = !rTable.GetFrameFormat()->GetLayoutSplit().GetValue();
2244  // bKeep handles this a different way later on, so ignore now
2245  if ( !bKeep && bDontSplit && rTable.GetTabLines().size() == 1 )
2246  {
2247  // bDontSplit : set don't split once for the row
2248  // but only for non-complex tables
2249  const SwTableLine* pLine = pBox ? pBox->GetUpper() : nullptr;
2250  if ( pLine && !pLine->GetUpper() )
2251  {
2252  // check if box is first in that line:
2253  if ( 0 == pLine->GetBoxPos( pBox ) && pBox->GetSttNd() )
2254  {
2255  // check if paragraph is first in that line:
2256  if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) )
2257  pLine->GetFrameFormat()->SetFormatAttr(SwFormatRowSplit(!bDontSplit));
2258  }
2259  }
2260  }
2261  }
2262  }
2263 
2264  SwSoftPageBreakList softBreakList;
2265  // Let's decide if we need to split the paragraph because of a section break
2266  bool bNeedParaSplit = NeedTextNodeSplit( rNode, softBreakList )
2267  && !IsInTable();
2268  const SwPageDesc* pNextSplitParaPageDesc = m_pCurrentPageDesc;
2269 
2270  auto aBreakIt = softBreakList.begin();
2271  // iterate through portions on different pages
2272  do
2273  {
2274  sal_Int32 nCurrentPos = *aBreakIt;
2275 
2276  if( softBreakList.size() > 1 ) // not for empty paragraph
2277  {
2278  // no need to split again if the page style won't change anymore
2279  if ( pNextSplitParaPageDesc == pNextSplitParaPageDesc->GetFollow() )
2280  aBreakIt = --softBreakList.end();
2281  else
2282  ++aBreakIt;
2283  }
2284 
2285  AttrOutput().StartParagraph( pTextNodeInfo );
2286 
2287  const SwSection* pTOXSect = nullptr;
2288  if( m_bInWriteTOX )
2289  {
2290  // check for end of TOX
2291  SwNodeIndex aIdx( rNode, 1 );
2292  if( !aIdx.GetNode().IsTextNode() )
2293  {
2294  const SwSectionNode* pTOXSectNd = rNode.FindSectionNode();
2295  if ( pTOXSectNd )
2296  {
2297  pTOXSect = &pTOXSectNd->GetSection();
2298 
2299  const SwNode* pNxt = rNode.GetNodes().GoNext( &aIdx );
2300  if( pNxt && pNxt->FindSectionNode() == pTOXSectNd )
2301  pTOXSect = nullptr;
2302  }
2303  }
2304  }
2305 
2306  if ( aAttrIter.RequiresImplicitBookmark() )
2307  {
2308  OUString sBkmkName = "_toc" + OUString::number( rNode.GetIndex() );
2309  // Add a bookmark converted to a Word name.
2310  AppendBookmark( BookmarkToWord( sBkmkName ) );
2311  }
2312 
2313  // Call this before write out fields and runs
2314  AttrOutput().GenerateBookmarksForSequenceField(rNode, aAttrIter);
2315 
2316  const OUString& aStr( rNode.GetText() );
2317 
2318  sal_Int32 const nEnd = bNeedParaSplit ? *aBreakIt : aStr.getLength();
2319  bool bIncludeEndOfParaCRInRedlineProperties = false;
2320  sal_Int32 nOpenAttrWithRange = 0;
2321 
2322  ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner;
2323  if ( pTextNodeInfo )
2324  {
2325  pTextNodeInfoInner = pTextNodeInfo->getFirstInner();
2326  }
2327 
2328  do {
2329 
2330  const SwRedlineData* pRedlineData = aAttrIter.GetRunLevelRedline( nCurrentPos );
2331  FlyProcessingState nStateOfFlyFrame = FLY_PROCESSED;
2332  bool bPostponeWritingText = false ;
2333  OUString aSavedSnippet ;
2334 
2335  sal_Int32 nNextAttr = GetNextPos( &aAttrIter, rNode, nCurrentPos );
2336 
2337  // Skip un-exportable attributes.
2338  if (!aAttrIter.IsExportableAttr(nCurrentPos))
2339  {
2340  nCurrentPos = nNextAttr;
2341  UpdatePosition(&aAttrIter, nCurrentPos);
2342  eChrSet = aAttrIter.GetCharSet();
2343  continue;
2344  }
2345 
2346  // Is this the only run in this paragraph and it's empty?
2347  bool bSingleEmptyRun = nCurrentPos == 0 && nNextAttr == 0;
2348  AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun );
2349 
2350  if( nNextAttr > nEnd )
2351  nNextAttr = nEnd;
2352 
2353  if( m_nTextTyp == TXT_FTN || m_nTextTyp == TXT_EDN )
2354  {
2355  if( AttrOutput().FootnoteEndnoteRefTag() )
2356  {
2357  AttrOutput().EndRun( &rNode, nCurrentPos, nNextAttr == nEnd );
2358  AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun );
2359  }
2360  }
2361 
2362  /*
2363  1) If there is a text node and an overlapping anchor, then write them in two different
2364  runs and not as part of the same run.
2365  2) Ensure that it is a text node and not in a fly.
2366  3) If the anchor is associated with a text node with empty text then we ignore.
2367  */
2368  if( rNode.IsTextNode()
2369  && GetExportFormat() == MSWordExportBase::ExportFormat::DOCX
2370  && aStr != OUStringChar(CH_TXTATR_BREAKWORD) && !aStr.isEmpty()
2371  && !rNode.GetFlyFormat()
2372  && aAttrIter.IsAnchorLinkedToThisNode(rNode.GetIndex()) )
2373  {
2374  bPostponeWritingText = true ;
2375  }
2376 
2377  nStateOfFlyFrame = aAttrIter.OutFlys( nCurrentPos );
2378  AttrOutput().SetStateOfFlyFrame( nStateOfFlyFrame );
2379  AttrOutput().SetAnchorIsLinkedToNode( bPostponeWritingText && (FLY_POSTPONED != nStateOfFlyFrame) );
2380  // Append bookmarks in this range after flys, exclusive of final
2381  // position of this range
2382  AppendBookmarks( rNode, nCurrentPos, nNextAttr - nCurrentPos );
2383  // Sadly only possible for main or glossary document parts: ECMA-376 Part 1 sect. 11.3.2
2384  if ( m_nTextTyp == TXT_MAINTEXT )
2385  AppendAnnotationMarks(aAttrIter, nCurrentPos, nNextAttr - nCurrentPos);
2386 
2387  // At the moment smarttags are only written for paragraphs, at the
2388  // beginning of the paragraph.
2389  if (nCurrentPos == 0)
2390  AppendSmartTags(rNode);
2391 
2392  bool bTextAtr = aAttrIter.IsTextAttr( nCurrentPos );
2393  nOpenAttrWithRange += aAttrIter.OutAttrWithRange( rNode, nCurrentPos );
2394 
2395  sal_Int32 nLen = nNextAttr - nCurrentPos;
2396  if ( !bTextAtr && nLen )
2397  {
2398  sal_Unicode ch = aStr[nCurrentPos];
2399 
2400  const sal_Int32 ofs = (ch == CH_TXT_ATR_FIELDSTART
2401  || ch == CH_TXT_ATR_FIELDSEP
2402  || ch == CH_TXT_ATR_FIELDEND
2403  || ch == CH_TXT_ATR_FORMELEMENT)
2404  ? 1 : 0;
2405 
2406  IDocumentMarkAccess* const pMarkAccess = m_rDoc.getIDocumentMarkAccess();
2407  if ( ch == CH_TXT_ATR_FIELDSTART )
2408  {
2409  SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
2410  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkAt(aPosition);
2411  assert(pFieldmark);
2412 
2413  // Date field is exported as content control, not as a simple field
2414  if (pFieldmark->GetFieldname() == ODF_FORMDATE)
2415  {
2416  if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
2417  {
2418  OutputField( nullptr, lcl_getFieldId( pFieldmark ),
2419  lcl_getFieldCode( pFieldmark ),
2421  WriteFormData( *pFieldmark );
2422  }
2423  }
2424  else
2425  {
2426 
2427  if (pFieldmark->GetFieldname() == ODF_FORMTEXT
2428  && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
2429  {
2430  AppendBookmark( pFieldmark->GetName() );
2431  }
2432  ww::eField eFieldId = lcl_getFieldId( pFieldmark );
2433  OUString sCode = lcl_getFieldCode( pFieldmark );
2434  if (pFieldmark->GetFieldname() == ODF_UNHANDLED )
2435  {
2436  IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
2437  if ( it != pFieldmark->GetParameters()->end() )
2438  {
2439  OUString sFieldId;
2440  it->second >>= sFieldId;
2441  eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
2442  }
2443 
2444  it = pFieldmark->GetParameters()->find( ODF_CODE_PARAM );
2445  if ( it != pFieldmark->GetParameters()->end() )
2446  {
2447  it->second >>= sCode;
2448  }
2449  }
2450 
2451  OutputField( nullptr, eFieldId, sCode, FieldFlags::Start | FieldFlags::CmdStart );
2452 
2453  if (pFieldmark->GetFieldname() == ODF_FORMTEXT)
2454  WriteFormData( *pFieldmark );
2455  else if (pFieldmark->GetFieldname() == ODF_HYPERLINK)
2456  WriteHyperlinkData( *pFieldmark );
2457  }
2458  }
2459  else if (ch == CH_TXT_ATR_FIELDSEP)
2460  {
2461  SwPosition aPosition(rNode, SwIndex(&rNode, nCurrentPos));
2462  // the innermost field is the correct one
2463  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkFor(aPosition);
2464  assert(pFieldmark);
2465  // DateFieldmark / ODF_FORMDATE is not a field...
2466  if (pFieldmark->GetFieldname() != ODF_FORMDATE)
2467  {
2468  OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::CmdEnd );
2469 
2470  if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
2471  {
2472  // Check for the presence of a linked OLE object
2473  IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_OLE_PARAM );
2474  if ( it != pFieldmark->GetParameters()->end() )
2475  {
2476  OUString sOleId;
2477  uno::Any aValue = it->second;
2478  aValue >>= sOleId;
2479  if ( !sOleId.isEmpty() )
2480  OutputLinkedOLE( sOleId );
2481  }
2482  }
2483  }
2484  }
2485  else if ( ch == CH_TXT_ATR_FIELDEND )
2486  {
2487  SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
2488  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkAt(aPosition);
2489 
2490  assert(pFieldmark);
2491 
2492  if (pFieldmark->GetFieldname() == ODF_FORMDATE)
2493  {
2494  if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
2495  {
2496  OutputField( nullptr, ww::eFORMDATE, OUString(), FieldFlags::Close );
2497  }
2498  }
2499  else
2500  {
2501  ww::eField eFieldId = lcl_getFieldId( pFieldmark );
2502  if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
2503  {
2504  IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
2505  if ( it != pFieldmark->GetParameters()->end() )
2506  {
2507  OUString sFieldId;
2508  it->second >>= sFieldId;
2509  eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
2510  }
2511  }
2512 
2513  OutputField( nullptr, eFieldId, OUString(), FieldFlags::Close );
2514 
2515  if (pFieldmark->GetFieldname() == ODF_FORMTEXT
2516  && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
2517  {
2518  AppendBookmark( pFieldmark->GetName() );
2519  }
2520  }
2521  }
2522  else if ( ch == CH_TXT_ATR_FORMELEMENT )
2523  {
2524  SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
2525  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkAt(aPosition);
2526  assert(pFieldmark);
2527 
2528  bool const isDropdownOrCheckbox(pFieldmark->GetFieldname() == ODF_FORMDROPDOWN ||
2529  pFieldmark->GetFieldname() == ODF_FORMCHECKBOX);
2530  if ( isDropdownOrCheckbox )
2531  AppendBookmark( pFieldmark->GetName() );
2532  OutputField( nullptr, lcl_getFieldId( pFieldmark ),
2533  lcl_getFieldCode( pFieldmark ),
2535  if ( isDropdownOrCheckbox )
2536  WriteFormData( *pFieldmark );
2537  // tdf#129514 need CmdEnd for docx
2538  OutputField(nullptr, lcl_getFieldId(pFieldmark), OUString(),
2540  if ( isDropdownOrCheckbox )
2541  AppendBookmark( pFieldmark->GetName() );
2542  }
2543  nLen -= ofs;
2544 
2545  // if paragraph needs to be split, write only until split position
2546  assert(!bNeedParaSplit || nCurrentPos <= *aBreakIt);
2547  if( bNeedParaSplit && nCurrentPos + ofs + nLen > *aBreakIt)
2548  nLen = *aBreakIt - nCurrentPos - ofs;
2549  assert(0 <= nLen);
2550 
2551  OUString aSnippet( aAttrIter.GetSnippet( aStr, nCurrentPos + ofs, nLen ) );
2552  if ( ( m_nTextTyp == TXT_EDN || m_nTextTyp == TXT_FTN ) && nCurrentPos == 0 && nLen > 0 )
2553  {
2554  // Allow MSO to emulate LO footnote text starting at left margin - only meaningful with hanging indent
2555  sal_Int32 nFirstLineIndent=0;
2557  const SwTextNode* pTextNode( rNode.GetTextNode() );
2558  if ( pTextNode && pTextNode->GetAttr(aSet) )
2559  {
2560  const SvxLRSpaceItem* pLRSpace = aSet.GetItem<SvxLRSpaceItem>(RES_LR_SPACE);
2561  if ( pLRSpace )
2562  nFirstLineIndent = pLRSpace->GetTextFirstLineOffset();
2563  }
2564 
2565  // Insert tab for aesthetic purposes #i24762#
2566  if ( m_bAddFootnoteTab && nFirstLineIndent < 0 && aSnippet[0] != 0x09 )
2567  aSnippet = "\x09" + aSnippet;
2568  m_bAddFootnoteTab = false;
2569  }
2570 
2571  if ( bPostponeWritingText && ( FLY_POSTPONED != nStateOfFlyFrame ) )
2572  {
2573  bPostponeWritingText = true ;
2574  aSavedSnippet = aSnippet ;
2575  }
2576  else
2577  {
2578  bPostponeWritingText = false ;
2579  AttrOutput().RunText( aSnippet, eChrSet );
2580  }
2581  }
2582 
2583  if ( aAttrIter.IsDropCap( nNextAttr ) )
2584  AttrOutput().FormatDrop( rNode, aAttrIter.GetSwFormatDrop(), nStyle, pTextNodeInfo, pTextNodeInfoInner );
2585 
2586  // Only output character attributes if this is not a postponed text run.
2587  if (0 != nEnd && !(bPostponeWritingText && FLY_PROCESSED == nStateOfFlyFrame))
2588  {
2589  // Output the character attributes
2590  // #i51277# do this before writing flys at end of paragraph
2592  aAttrIter.OutAttr( nCurrentPos, false );
2593  AttrOutput().EndRunProperties( pRedlineData );
2594  }
2595 
2596  // At the end of line, output the attributes until the CR.
2597  // Exception: footnotes at the end of line
2598  if ( nNextAttr == nEnd )
2599  {
2600  OSL_ENSURE( nOpenAttrWithRange >= 0, "odd to see this happening, expected >= 0" );
2601  if ( !bTextAtr && nOpenAttrWithRange <= 0 )
2602  {
2603  if ( aAttrIter.IncludeEndOfParaCRInRedlineProperties( nEnd ) )
2604  bIncludeEndOfParaCRInRedlineProperties = true;
2605  else
2606  {
2607  // insert final graphic anchors if any before CR
2608  nStateOfFlyFrame = aAttrIter.OutFlys( nEnd );
2609  // insert final bookmarks if any before CR and after flys
2610  AppendBookmarks( rNode, nEnd, 1 );
2611  AppendAnnotationMarks(aAttrIter, nEnd, 1);
2612  if ( pTOXSect )
2613  {
2615  AttrOutput().EndTOX( *pTOXSect ,false);
2616  }
2617  //For i120928,the position of the bullet's graphic is at end of doc
2618  if (bLastCR && (!bExported))
2619  {
2620  ExportGrfBullet(rNode);
2621  bExported = true;
2622  }
2623 
2624  WriteCR( pTextNodeInfoInner );
2625  }
2626  }
2627  }
2628 
2629  if (0 == nEnd)
2630  {
2631  // Output the character attributes
2632  // do it after WriteCR for an empty paragraph (otherwise
2633  // WW8_WrFkp::Append throws SPRMs away...)
2635  aAttrIter.OutAttr( nCurrentPos, false );
2636  AttrOutput().EndRunProperties( pRedlineData );
2637  }
2638 
2639  // Exception: footnotes at the end of line
2640  if ( nNextAttr == nEnd )
2641  {
2642  OSL_ENSURE(nOpenAttrWithRange >= 0,
2643  "odd to see this happening, expected >= 0");
2644  bool bAttrWithRange = (nOpenAttrWithRange > 0);
2645  if ( nCurrentPos != nEnd )
2646  {
2647  nOpenAttrWithRange += aAttrIter.OutAttrWithRange( rNode, nEnd );
2648  OSL_ENSURE(nOpenAttrWithRange == 0,
2649  "odd to see this happening, expected 0");
2650  }
2651 
2652  // !bIncludeEndOfParaCRInRedlineProperties implies we have just
2653  // emitted a CR, in which case we want to pass force=true to
2654  // OutputFKP to ensure that an FKP entry for direct character
2655  // formatting is written even if empty, so that the next one will
2656  // start after the CR.
2657  AttrOutput().OutputFKP(!bIncludeEndOfParaCRInRedlineProperties);
2658 
2659  if (bTextAtr || bAttrWithRange || bIncludeEndOfParaCRInRedlineProperties)
2660  {
2661  // insert final graphic anchors if any before CR
2662  nStateOfFlyFrame = aAttrIter.OutFlys( nEnd );
2663  // insert final bookmarks if any before CR and after flys
2664  AppendBookmarks( rNode, nEnd, 1 );
2665  AppendAnnotationMarks(aAttrIter, nEnd, 1);
2666  WriteCR( pTextNodeInfoInner );
2667  // #i120928 - position of the bullet's graphic is at end of doc
2668  if (bLastCR && (!bExported))
2669  {
2670  ExportGrfBullet(rNode);
2671  bExported = true;
2672  }
2673 
2674  if ( pTOXSect )
2675  {
2677  AttrOutput().EndTOX( *pTOXSect );
2678  }
2679 
2680  if (bIncludeEndOfParaCRInRedlineProperties)
2681  {
2682  AttrOutput().Redline( aAttrIter.GetRunLevelRedline( nEnd ) );
2683  //If there was no redline property emitted, force adding
2684  //another entry for the CR so that in the case that this
2685  //has no redline, but the next para does, then this one is
2686  //not merged with the next
2687  AttrOutput().OutputFKP(true);
2688  }
2689  }
2690  }
2691 
2693 
2694  if( bPostponeWritingText && FLY_PROCESSED == nStateOfFlyFrame )
2695  {
2696  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2697  //write the postponed text run
2698  AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun );
2701  if (0 != nEnd)
2702  {
2704  aAttrIter.OutAttr( nCurrentPos, false );
2705  AttrOutput().EndRunProperties( pRedlineData );
2706  }
2707  AttrOutput().RunText( aSavedSnippet, eChrSet );
2708  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2709  }
2710  else if( bPostponeWritingText && !aSavedSnippet.isEmpty() )
2711  {
2712  //write the postponed text run
2713  AttrOutput().RunText( aSavedSnippet, eChrSet );
2714  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2715  }
2716  else
2717  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2718 
2719  nCurrentPos = nNextAttr;
2720  UpdatePosition( &aAttrIter, nCurrentPos );
2721  eChrSet = aAttrIter.GetCharSet();
2722  }
2723  while ( nCurrentPos < nEnd );
2724 
2725  // if paragraph is split, put the section break between the parts
2726  if( bNeedParaSplit && *aBreakIt != rNode.GetText().getLength() )
2727  {
2728  pNextSplitParaPageDesc = pNextSplitParaPageDesc->GetFollow();
2729  assert(pNextSplitParaPageDesc);
2730  PrepareNewPageDesc( rNode.GetpSwAttrSet(), rNode, nullptr , pNextSplitParaPageDesc);
2731  }
2732  else
2733  {
2734  // else check if section break needed after the paragraph
2735  bool bCheckSectionBreak = true;
2736  // only try to sectionBreak after a split para if the next node specifies a break
2737  if ( bNeedParaSplit )
2738  {
2739  m_pCurrentPageDesc = pNextSplitParaPageDesc;
2740  SwNodeIndex aNextIndex( rNode, 1 );
2741  const SwTextNode* pNextNode = aNextIndex.GetNode().GetTextNode();
2742  bCheckSectionBreak = pNextNode && !NoPageBreakSection( pNextNode->GetpSwAttrSet() );
2743 
2744  if ( !bCheckSectionBreak )
2745  {
2746  auto rBreak = ItemGet<SvxFormatBreakItem>(rNode.GetSwAttrSet(), RES_BREAK);
2747  if ( rBreak.GetBreak() == SvxBreak::PageAfter )
2748  {
2749  if ( pNextNode && pNextNode->FindPageDesc() != pNextSplitParaPageDesc )
2750  bCheckSectionBreak = true;
2751  else
2752  AttrOutput().SectionBreak(msword::PageBreak, /*bBreakAfter=*/true);
2753  }
2754  }
2755  }
2756 
2757  if ( bCheckSectionBreak )
2758  AttrOutput().SectionBreaks(rNode);
2759  }
2760 
2762 
2763  AttrOutput().ParagraphStyle( nStyle );
2764 
2765  if ( m_pParentFrame && IsInTable() ) // Fly-Attrs
2766  OutputFormat( m_pParentFrame->GetFrameFormat(), false, false, true );
2767 
2768  if ( pTextNodeInfo )
2769  {
2770 #ifdef DBG_UTIL
2771  SAL_INFO( "sw.ww8", pTextNodeInfo->toString());
2772 #endif
2773 
2774  AttrOutput().TableInfoCell( pTextNodeInfoInner );
2775  if (pTextNodeInfoInner->isFirstInTable())
2776  {
2777  const SwTable * pTable = pTextNodeInfoInner->getTable();
2778 
2779  const SwTableFormat* pTabFormat = pTable->GetFrameFormat();
2780  if (pTabFormat != nullptr)
2781  {
2782  if (pTabFormat->GetBreak().GetBreak() == SvxBreak::PageBefore)
2783  AttrOutput().PageBreakBefore(true);
2784  }
2785  }
2786  }
2787 
2788  if ( !bFlyInTable )
2789  {
2790  SfxItemSet* pTmpSet = nullptr;
2791  const sal_uInt8 nPrvNxtNd = rNode.HasPrevNextLayNode();
2792 
2793  if( (ND_HAS_PREV_LAYNODE|ND_HAS_NEXT_LAYNODE ) != nPrvNxtNd )
2794  {
2795  const SfxPoolItem* pItem;
2796  if( SfxItemState::SET == rNode.GetSwAttrSet().GetItemState(
2797  RES_UL_SPACE, true, &pItem ) &&
2798  ( ( !( ND_HAS_PREV_LAYNODE & nPrvNxtNd ) &&
2799  static_cast<const SvxULSpaceItem*>(pItem)->GetUpper()) ||
2800  ( !( ND_HAS_NEXT_LAYNODE & nPrvNxtNd ) &&
2801  static_cast<const SvxULSpaceItem*>(pItem)->GetLower()) ))
2802  {
2803  pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
2804  SvxULSpaceItem aUL( *static_cast<const SvxULSpaceItem*>(pItem) );
2805  // #i25901#- consider compatibility option
2807  {
2808  if( !(ND_HAS_PREV_LAYNODE & nPrvNxtNd ))
2809  aUL.SetUpper( 0 );
2810  }
2811  // #i25901# - consider compatibility option
2813  {
2814  if( !(ND_HAS_NEXT_LAYNODE & nPrvNxtNd ))
2815  aUL.SetLower( 0 );
2816  }
2817  pTmpSet->Put( aUL );
2818  }
2819  }
2820 
2821  const bool bParaRTL = aAttrIter.IsParaRTL();
2822 
2823  int nNumberLevel = -1;
2824  if (rNode.IsNumbered())
2825  nNumberLevel = rNode.GetActualListLevel();
2826  if (nNumberLevel >= 0 && nNumberLevel < MAXLEVEL)
2827  {
2828  const SwNumRule* pRule = rNode.GetNumRule();
2829  sal_uInt8 nLvl = static_cast< sal_uInt8 >(nNumberLevel);
2830  const SwNumFormat* pFormat = pRule->GetNumFormat( nLvl );
2831  if( !pFormat )
2832  pFormat = &pRule->Get( nLvl );
2833 
2834  if( !pTmpSet )
2835  pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
2836 
2837  SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*pTmpSet, RES_LR_SPACE));
2838  // #i86652#
2839  if ( pFormat->GetPositionAndSpaceMode() ==
2841  {
2842  aLR.SetTextLeft( aLR.GetTextLeft() + pFormat->GetAbsLSpace() );
2843  }
2844 
2845  if( rNode.IsNumbered() && rNode.IsCountedInList() )
2846  {
2847  // #i86652#
2848  if ( pFormat->GetPositionAndSpaceMode() ==
2850  {
2851  if (bParaRTL)
2852  {
2853  aLR.SetTextFirstLineOffsetValue(aLR.GetTextFirstLineOffset() + pFormat->GetAbsLSpace() - pFormat->GetFirstLineOffset()); //TODO: overflow
2854  }
2855  else
2856  {
2857  aLR.SetTextFirstLineOffset(aLR.GetTextFirstLineOffset() + GetWordFirstLineOffset(*pFormat));
2858  }
2859  }
2860 
2861  // correct fix for issue i94187
2862  if (SfxItemState::SET !=
2863  pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2864  {
2865  // List style set via paragraph style - then put it into the itemset.
2866  // This is needed to get list level and list id exported for
2867  // the paragraph.
2868  pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
2869 
2870  // Put indent values into the itemset in case that the list
2871  // style is applied via paragraph style and the list level
2872  // indent values are not applicable.
2873  if ( pFormat->GetPositionAndSpaceMode() ==
2876  {
2877  pTmpSet->Put( aLR );
2878  }
2879  }
2880  }
2881  else
2882  pTmpSet->ClearItem(RES_PARATR_NUMRULE);
2883 
2884  // #i86652#
2885  if ( pFormat->GetPositionAndSpaceMode() ==
2887  {
2888  pTmpSet->Put(aLR);
2889 
2890  //#i21847#
2891  SvxTabStopItem aItem(
2892  ItemGet<SvxTabStopItem>(*pTmpSet, RES_PARATR_TABSTOP));
2893  SvxTabStop aTabStop(pFormat->GetAbsLSpace());
2894  aItem.Insert(aTabStop);
2895  pTmpSet->Put(aItem);
2896 
2898  }
2899  }
2900 
2901  /*
2902  If a given para is using the SvxFrameDirection::Environment direction we
2903  cannot export that, if it's ltr then that's ok as that is word's
2904  default. Otherwise we must add a RTL attribute to our export list
2905  Only necessary if the ParaStyle doesn't define the direction.
2906  */
2907  const SvxFrameDirectionItem* pItem =
2909  if (
2910  (!pItem || pItem->GetValue() == SvxFrameDirection::Environment) &&
2911  rTextColl.GetFrameDir().GetValue() == SvxFrameDirection::Environment
2912  )
2913  {
2914  if ( !pTmpSet )
2915  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2916 
2917  if ( bParaRTL )
2918  pTmpSet->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_RL_TB, RES_FRAMEDIR));
2919  else
2920  pTmpSet->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB, RES_FRAMEDIR));
2921 
2922  const SvxAdjustItem* pAdjust = rNode.GetSwAttrSet().GetItem(RES_PARATR_ADJUST);
2923  if ( pAdjust && (pAdjust->GetAdjust() == SvxAdjust::Left || pAdjust->GetAdjust() == SvxAdjust::Right ) )
2924  pTmpSet->Put( *pAdjust, RES_PARATR_ADJUST );
2925  }
2926  // move code for handling of numbered,
2927  // but not counted paragraphs to this place. Otherwise, the paragraph
2928  // isn't exported as numbered, but not counted, if no other attribute
2929  // is found in <pTmpSet>
2930  // #i44815# adjust numbering/indents for numbered paragraphs
2931  // without number (NO_NUMLEVEL)
2932  // #i47013# need to check rNode.GetNumRule()!=NULL as well.
2933  if ( ! rNode.IsCountedInList() && rNode.GetNumRule()!=nullptr )
2934  {
2935  // WW8 does not know numbered paragraphs without number
2936  // (NO_NUMLEVEL). In WW8AttributeOutput::ParaNumRule(), we will export
2937  // the RES_PARATR_NUMRULE as list-id 0, which in WW8 means
2938  // no numbering. Here, we will adjust the indents to match
2939  // visually.
2940 
2941  if ( !pTmpSet )
2942  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2943 
2944  // create new LRSpace item, based on the current (if present)
2945  const SfxPoolItem* pPoolItem = nullptr;
2946  pTmpSet->GetItemState(RES_LR_SPACE, true, &pPoolItem);
2947  SvxLRSpaceItem aLRSpace(
2948  ( pPoolItem == nullptr )
2949  ? SvxLRSpaceItem(0, 0, 0, 0, RES_LR_SPACE)
2950  : *static_cast<const SvxLRSpaceItem*>( pPoolItem ) );
2951 
2952  // new left margin = old left + label space
2953  const SwNumRule* pRule = rNode.GetNumRule();
2954  int nLevel = rNode.GetActualListLevel();
2955 
2956  if (nLevel < 0)
2957  nLevel = 0;
2958 
2959  if (nLevel >= MAXLEVEL)
2960  nLevel = MAXLEVEL - 1;
2961 
2962  const SwNumFormat& rNumFormat = pRule->Get( static_cast< sal_uInt16 >(nLevel) );
2963 
2964  // #i86652#
2965  if ( rNumFormat.GetPositionAndSpaceMode() ==
2967  {
2968  aLRSpace.SetTextLeft( aLRSpace.GetLeft() + rNumFormat.GetAbsLSpace() );
2969  }
2970  else
2971  {
2972  aLRSpace.SetTextLeft( aLRSpace.GetLeft() + rNumFormat.GetIndentAt() );
2973  }
2974 
2975  // new first line indent = 0
2976  // (first line indent is ignored for NO_NUMLEVEL)
2977  if (!bParaRTL)
2978  aLRSpace.SetTextFirstLineOffset( 0 );
2979 
2980  // put back the new item
2981  pTmpSet->Put( aLRSpace );
2982 
2983  // assure that numbering rule is in <pTmpSet>
2984  if (SfxItemState::SET != pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2985  {
2986  pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
2987  }
2988  }
2989 
2990  // #i75457#
2991  // Export page break after attribute from paragraph style.
2992  // If page break attribute at the text node exist, an existing page
2993  // break after at the paragraph style hasn't got to be considered.
2994  if ( !rNode.GetpSwAttrSet() ||
2995  SfxItemState::SET != rNode.GetpSwAttrSet()->GetItemState(RES_BREAK, false) )
2996  {
2997  const SvxFormatBreakItem& rBreakAtParaStyle
2998  = ItemGet<SvxFormatBreakItem>(rNode.GetSwAttrSet(), RES_BREAK);
2999  if (rBreakAtParaStyle.GetBreak() == SvxBreak::PageAfter)
3000  {
3001  if ( !pTmpSet )
3002  {
3003  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
3004  }
3005  pTmpSet->Put(rBreakAtParaStyle);
3006  }
3007  else if( pTmpSet )
3008  { // Even a pagedesc item is set, the break item can be set 'NONE',
3009  // this has to be overruled.
3010  const SwFormatPageDesc& rPageDescAtParaStyle =
3011  ItemGet<SwFormatPageDesc>( rNode, RES_PAGEDESC );
3012  if( rPageDescAtParaStyle.KnowsPageDesc() )
3013  pTmpSet->ClearItem( RES_BREAK );
3014  }
3015  }
3016 
3017  // #i76520# Emulate non-splitting tables
3018  if ( IsInTable() )
3019  {
3020  const SwTableNode* pTableNode = rNode.FindTableNode();
3021 
3022  if ( pTableNode )
3023  {
3024  const SwTable& rTable = pTableNode->GetTable();
3025  const SvxFormatKeepItem& rKeep = rTable.GetFrameFormat()->GetKeep();
3026  const bool bKeep = rKeep.GetValue();
3027  const bool bDontSplit = !(bKeep ||
3028  rTable.GetFrameFormat()->GetLayoutSplit().GetValue());
3029 
3030  if ( bKeep || bDontSplit )
3031  {
3032  // bKeep: set keep at first paragraphs in all lines
3033  // bDontSplit : set keep at first paragraphs in all lines except from last line
3034  // but only for non-complex tables
3035  const SwTableBox* pBox = rNode.GetTableBox();
3036  const SwTableLine* pLine = pBox ? pBox->GetUpper() : nullptr;
3037 
3038  if ( pLine && !pLine->GetUpper() )
3039  {
3040  // check if box is first in that line:
3041  if ( 0 == pLine->GetBoxPos( pBox ) && pBox->GetSttNd() )
3042  {
3043  // check if paragraph is first in that line:
3044  if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) )
3045  {
3046  bool bSetAtPara = false;
3047  if ( bKeep )
3048  bSetAtPara = true;
3049  else if ( bDontSplit )
3050  {
3051  // check if pLine isn't last line in table
3052  if ( rTable.GetTabLines().size() - rTable.GetTabLines().GetPos( pLine ) != 1 )
3053  bSetAtPara = true;
3054  }
3055 
3056  if ( bSetAtPara )
3057  {
3058  if ( !pTmpSet )
3059  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
3060 
3061  const SvxFormatKeepItem aKeepItem( true, RES_KEEP );
3062  pTmpSet->Put( aKeepItem );
3063  }
3064  }
3065  }
3066  }
3067  }
3068  }
3069  }
3070 
3071  const SfxItemSet* pNewSet = pTmpSet ? pTmpSet : rNode.GetpSwAttrSet();
3072  if( pNewSet )
3073  { // Para-Attrs
3074  m_pStyAttr = &rNode.GetAnyFormatColl().GetAttrSet();
3075 
3076  const sw::BroadcastingModify* pOldMod = m_pOutFormatNode;
3077  m_pOutFormatNode = &rNode;
3078 
3079  // Pap-Attrs, so script is not necessary
3080  OutputItemSet( *pNewSet, true, false, i18n::ScriptType::LATIN, false);
3081 
3082  m_pStyAttr = nullptr;
3083  m_pOutFormatNode = pOldMod;
3084 
3085  if( pNewSet != rNode.GetpSwAttrSet() )
3086  delete pNewSet;
3087  }
3088  }
3089 
3090  // The formatting of the paragraph marker has two sources:
3091  // 0) If there is a RES_PARATR_LIST_AUTOFMT, then use that.
3092  // 1) If there are hints at the end of the paragraph, then use that.
3093  // 2) Else use the RES_CHRATR_BEGIN..RES_TXTATR_END range of the paragraph
3094  // properties.
3095  //
3096  // Exception: if there is a character style hint at the end of the
3097  // paragraph only, then still go with 2), as RES_TXTATR_CHARFMT is always
3098  // set as a hint.
3100  bool bCharFormatOnly = true;
3101 
3102  SwFormatAutoFormat const& rListAutoFormat(static_cast<SwFormatAutoFormat const&>(rNode.GetAttr(RES_PARATR_LIST_AUTOFMT)));
3103  if (std::shared_ptr<SfxItemSet> const& pSet = rListAutoFormat.GetStyleHandle())
3104  {
3105  aParagraphMarkerProperties.Put(*pSet);
3106  bCharFormatOnly = false;
3107  }
3108  else if (const SwpHints* pTextAttrs = rNode.GetpSwpHints())
3109  {
3110  for( size_t i = 0; i < pTextAttrs->Count(); ++i )
3111  {
3112  const SwTextAttr* pHt = pTextAttrs->Get(i);
3113  const sal_Int32 startPos = pHt->GetStart(); // first Attr characters
3114  const sal_Int32* endPos = pHt->End(); // end Attr characters
3115  // Check if these attributes are for the last character in the paragraph
3116  // - which means the paragraph marker. If a paragraph has 7 characters,
3117  // then properties on character 8 are for the paragraph marker
3118  if( endPos && (startPos == *endPos ) && (*endPos == rNode.GetText().getLength()) )
3119  {
3120  SAL_INFO( "sw.ww8", startPos << "startPos == endPos" << *endPos);
3121  sal_uInt16 nWhich = pHt->GetAttr().Which();
3122  SAL_INFO( "sw.ww8", "nWhich" << nWhich);
3123  if ((nWhich == RES_TXTATR_AUTOFMT && bCharFormatOnly)
3124  || nWhich == RES_TXTATR_CHARFMT)
3125  {
3126  aParagraphMarkerProperties.Put(pHt->GetAttr());
3127  }
3128  if (nWhich != RES_TXTATR_CHARFMT)
3129  bCharFormatOnly = false;
3130  }
3131  }
3132  }
3133  if (rNode.GetpSwAttrSet() && bCharFormatOnly)
3134  {
3135  aParagraphMarkerProperties.Put(*rNode.GetpSwAttrSet());
3136  }
3137  const SwRedlineData* pRedlineParagraphMarkerDelete = AttrOutput().GetParagraphMarkerRedline( rNode, RedlineType::Delete );
3138  const SwRedlineData* pRedlineParagraphMarkerInsert = AttrOutput().GetParagraphMarkerRedline( rNode, RedlineType::Insert );
3139  const SwRedlineData* pParagraphRedlineData = aAttrIter.GetParagraphLevelRedline( );
3140  AttrOutput().EndParagraphProperties(aParagraphMarkerProperties, pParagraphRedlineData, pRedlineParagraphMarkerDelete, pRedlineParagraphMarkerInsert);
3141 
3142  AttrOutput().EndParagraph( pTextNodeInfoInner );
3143  }while(*aBreakIt != rNode.GetText().getLength() && bNeedParaSplit );
3144 
3145  SAL_INFO( "sw.ww8", "</OutWW8_SwTextNode>" );
3146 }
3147 
3148 // Tables
3149 
3151 {
3152  m_rWW8Export.WriteStringAsPara( OUString() );
3153 }
3154 
3156 {
3157  bool bRet = false;
3158  const SfxPoolItem* pI;
3159  if( pSet)
3160  {
3161  bool bNoPageBreak = false;
3162  if ( SfxItemState::SET != pSet->GetItemState(RES_PAGEDESC, true, &pI)
3163  || nullptr == static_cast<const SwFormatPageDesc*>(pI)->GetPageDesc() )
3164  {
3165  bNoPageBreak = true;
3166  }
3167 
3168  if (bNoPageBreak)
3169  {
3170  if (SfxItemState::SET == pSet->GetItemState(RES_BREAK, true, &pI))
3171  {
3172  SvxBreak eBreak = static_cast<const SvxFormatBreakItem*>(pI)->GetBreak();
3173  switch (eBreak)
3174  {
3175  case SvxBreak::PageBefore:
3176  case SvxBreak::PageAfter:
3177  bNoPageBreak = false;
3178  break;
3179  default:
3180  break;
3181  }
3182  }
3183  }
3184  bRet = bNoPageBreak;
3185  }
3186  return bRet;
3187 }
3188 
3190 {
3191  const SwSection& rSection = rSectionNode.GetSection();
3192 
3193  SwNodeIndex aIdx( rSectionNode, 1 );
3194  const SwNode& rNd = aIdx.GetNode();
3195  if ( !rNd.IsSectionNode() && !IsInTable() ) //No sections in table
3196  {
3197  // if the first Node inside the section has an own
3198  // PageDesc or PageBreak attribute, then don't write
3199  // here the section break
3200  sal_uLong nRstLnNum = 0;
3201  const SfxItemSet* pSet;
3202  if ( rNd.IsContentNode() )
3203  {
3204  pSet = &rNd.GetContentNode()->GetSwAttrSet();
3205  nRstLnNum = pSet->Get( RES_LINENUMBER ).GetStartValue();
3206  }
3207  else
3208  pSet = nullptr;
3209 
3210  if ( pSet && NoPageBreakSection( pSet ) )
3211  pSet = nullptr;
3212  else
3213  AttrOutput().SectionBreaks( rSectionNode );
3214 
3215  const bool bInTOX = rSection.GetType() == SectionType::ToxContent || rSection.GetType() == SectionType::ToxHeader;
3216  if ( !pSet && !bInTOX )
3217  {
3218  // new Section with no own PageDesc/-Break
3219  // -> write follow section break;
3220  const SwSectionFormat* pFormat = rSection.GetFormat();
3221  ReplaceCr( msword::PageBreak ); // Indicator for Page/Section-Break
3222 
3223  // Get the page in use at the top of this section
3224  const SwPageDesc *pCurrent = SwPageDesc::GetPageDescOfNode(rNd);
3225  if (!pCurrent)
3226  pCurrent = m_pCurrentPageDesc;
3227 
3228  AppendSection( pCurrent, pFormat, nRstLnNum );
3229  }
3230  }
3231  if ( SectionType::ToxContent == rSection.GetType() )
3232  {
3233  m_bStartTOX = true;
3234  UpdateTocSectionNodeProperties(rSectionNode);
3235  }
3236 }
3237 
3238 // tdf#121561: During export of the ODT file with TOC inside into DOCX format,
3239 // the TOC title is being exported as regular paragraph. We should surround it
3240 // with <w:sdt><w:sdtPr><w:sdtContent> to make it (TOC title) recognizable
3241 // by MS Word as part of the TOC.
3243 {
3244  // check section type
3245  {
3246  const SwSection& rSection = rSectionNode.GetSection();
3247  if (SectionType::ToxContent != rSection.GetType())
3248  return;
3249 
3250  const SwTOXBase* pTOX = rSection.GetTOXBase();
3251  if (pTOX)
3252  {
3253  TOXTypes type = pTOX->GetType();
3254  if (type != TOXTypes::TOX_CONTENT)
3255  return;
3256  }
3257  }
3258 
3259  // get section node, skip toc-header node
3260  const SwSectionNode* pSectNd = &rSectionNode;
3261  {
3262  SwNodeIndex aIdxNext( *pSectNd, 1 );
3263  const SwNode& rNdNext = aIdxNext.GetNode();
3264 
3265  if (rNdNext.IsSectionNode())
3266  {
3267  const SwSectionNode* pSectNdNext = static_cast<const SwSectionNode*>(&rNdNext);
3268  if (SectionType::ToxHeader == pSectNdNext->GetSection().GetType() &&
3269  pSectNdNext->StartOfSectionNode()->IsSectionNode())
3270  {
3271  pSectNd = pSectNdNext;
3272  }
3273  }
3274  }
3275 
3276  // get node of the first paragraph inside TOC
3277  SwNodeIndex aIdxNext( *pSectNd, 1 );
3278  const SwNode& rNdTocPara = aIdxNext.GetNode();
3279  const SwContentNode* pNode = rNdTocPara.GetContentNode();
3280  if (!pNode)
3281  return;
3282 
3283  // put required flags into grab bag of the first node in TOC
3284  {
3285  uno::Sequence<beans::PropertyValue> aDocPropertyValues(comphelper::InitPropertySequence(
3286  {
3287  {"ooxml:CT_SdtDocPart_docPartGallery", uno::makeAny(OUString("Table of Contents"))},
3288  {"ooxml:CT_SdtDocPart_docPartUnique", uno::makeAny(OUString("true"))},
3289  }));
3290 
3291  uno::Sequence<beans::PropertyValue> aSdtPrPropertyValues(comphelper::InitPropertySequence(
3292  {
3293  {"ooxml:CT_SdtPr_docPartObj", uno::makeAny(aDocPropertyValues)},
3294  }));
3295 
3297  aGrabBag.GetGrabBag()["SdtPr"] <<= aSdtPrPropertyValues;
3298 
3299  // create temp attr set
3300  SwAttrSet aSet(pNode->GetSwAttrSet());
3301  aSet.Put(aGrabBag);
3302 
3303  // set new attr to node
3304  const_cast<SwContentNode*>(pNode)->SetAttr(aSet);
3305  }
3306 
3307  // set flag for the next node after TOC
3308  // in order to indicate that std area has been finished
3309  // see, DomainMapper::lcl_startParagraphGroup() for the same functionality during load
3310  {
3311  SwNodeIndex aEndTocNext( *rSectionNode.EndOfSectionNode(), 1 );
3312  const SwNode& rEndTocNextNode = aEndTocNext.GetNode();
3313  const SwContentNode* pNodeAfterToc = rEndTocNextNode.GetContentNode();
3314  if (pNodeAfterToc)
3315  {
3317  aGrabBag.GetGrabBag()["ParaSdtEndBefore"] <<= true;
3318 
3319  // create temp attr set
3320  SwAttrSet aSet(pNodeAfterToc->GetSwAttrSet());
3321  aSet.Put(aGrabBag);
3322 
3323  // set new attr to node
3324  const_cast<SwContentNode*>(pNodeAfterToc)->SetAttr(aSet);
3325  }
3326  }
3327 }
3328 
3329 void WW8Export::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum )
3330 {
3331  pSepx->AppendSep(Fc2Cp(Strm().Tell()), pPageDesc, pFormat, nLnNum);
3332 }
3333 
3334 // Flys
3335 
3336 void WW8AttributeOutput::OutputFlyFrame_Impl( const ww8::Frame& rFormat, const Point& rNdTopLeft )
3337 {
3338  const SwFrameFormat &rFrameFormat = rFormat.GetFrameFormat();
3339  const SwFormatAnchor& rAnch = rFrameFormat.GetAnchor();
3340 
3341  bool bUseEscher = true;
3342 
3343  if (rFormat.IsInline())
3344  {
3346  bUseEscher = eType != ww8::Frame::eGraphic && eType != ww8::Frame::eOle;
3347 
3348  /*
3349  A special case for converting some inline form controls to form fields
3350  when in winword 8+ mode
3351  */
3352  if (bUseEscher && (eType == ww8::Frame::eFormControl))
3353  {
3354  if ( m_rWW8Export.MiserableFormFieldExportHack( rFrameFormat ) )
3355  return ;
3356  }
3357  }
3358 
3359  if (bUseEscher)
3360  {
3361  // write as escher
3362  m_rWW8Export.AppendFlyInFlys(rFormat, rNdTopLeft);
3363  }
3364  else
3365  {
3366  bool bDone = false;
3367 
3368  // Fetch from node and last node the position in the section
3369  const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
3370 
3371  sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
3372  sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
3373 
3374  if( nStt >= nEnd ) // no range, hence no valid node
3375  return;
3376 
3377  if ( !m_rWW8Export.IsInTable() && rFormat.IsInline() )
3378  {
3379  //Test to see if this textbox contains only a single graphic/ole
3380  SwTextNode* pParTextNode = rAnch.GetContentAnchor()->nNode.GetNode().GetTextNode();
3381  if ( pParTextNode && !m_rWW8Export.m_rDoc.GetNodes()[ nStt ]->IsNoTextNode() )
3382  bDone = true;
3383  }
3384  if( !bDone )
3385  {
3386 
3387  m_rWW8Export.SaveData( nStt, nEnd );
3388 
3389  Point aOffset;
3391  {
3392  /* Munge flys in fly into absolutely positioned elements for word 6 */
3393  const SwTextNode* pParTextNode = rAnch.GetContentAnchor()->nNode.GetNode().GetTextNode();
3394  const SwRect aPageRect = pParTextNode->FindPageFrameRect();
3395 
3396  aOffset = rFrameFormat.FindLayoutRect().Pos();
3397  aOffset -= aPageRect.Pos();
3398 
3399  m_rWW8Export.m_pFlyOffset = &aOffset;
3400  m_rWW8Export.m_eNewAnchorType = RndStdIds::FLY_AT_PAGE;
3401  }
3402 
3403  m_rWW8Export.m_pParentFrame = &rFormat;
3404  if (
3405  m_rWW8Export.IsInTable() &&
3406  (RndStdIds::FLY_AT_PAGE != rAnch.GetAnchorId()) &&
3407  !m_rWW8Export.m_rDoc.GetNodes()[ nStt ]->IsNoTextNode()
3408  )
3409  {
3410  // note: set Flag bOutTable again,
3411  // because we deliver the normal content of the table cell, and no border
3412  // ( Flag was deleted above in aSaveData() )
3413  m_rWW8Export.m_bOutTable = true;
3414  const OUString& aName = rFrameFormat.GetName();
3418  }
3419  else
3421 
3423  }
3424  }
3425 }
3426 
3428 {
3429  if ( !rFormat.GetContentNode() )
3430  return;
3431 
3432  const SwContentNode &rNode = *rFormat.GetContentNode();
3433  Point aLayPos;
3434 
3435  // get the Layout Node-Position
3436  if (RndStdIds::FLY_AT_PAGE == rFormat.GetFrameFormat().GetAnchor().GetAnchorId())
3437  aLayPos = rNode.FindPageFrameRect().Pos();
3438  else
3439  aLayPos = rNode.FindLayoutRect().Pos();
3440 
3441  OutputFlyFrame_Impl( rFormat, aLayPos );
3442 }
3443 
3444 // write data of any redline
3446 {
3447  if ( !pRedline )
3448  return;
3449 
3450  if ( pRedline->Next() )
3451  Redline( pRedline->Next() );
3452 
3453  static const sal_uInt16 insSprmIds[ 3 ] =
3454  {
3455  // Ids for insert // for WW8
3457  };
3458  static const sal_uInt16 delSprmIds[ 3 ] =
3459  {
3460  // Ids for delete // for WW8
3462  };
3463 
3464  const sal_uInt16* pSprmIds = nullptr;
3465  switch( pRedline->GetType() )
3466  {
3467  case RedlineType::Insert:
3468  pSprmIds = insSprmIds;
3469  break;
3470 
3471  case RedlineType::Delete:
3472  pSprmIds = delSprmIds;
3473  break;
3474 
3475  case RedlineType::Format:
3477  m_rWW8Export.pO->push_back( 7 ); // len
3478  m_rWW8Export.pO->push_back( 1 );
3481  break;
3482  default:
3483  OSL_ENSURE(false, "Unhandled redline type for export");
3484  break;
3485  }
3486 
3487  if ( pSprmIds )
3488  {
3489  m_rWW8Export.InsUInt16( pSprmIds[0] );
3490  m_rWW8Export.pO->push_back( 1 );
3491 
3492  m_rWW8Export.InsUInt16( pSprmIds[1] );
3494 
3495  m_rWW8Export.InsUInt16( pSprmIds[2] );
3497  }
3498 }
3499 
3501 {
3502  switch ( rNode.GetNodeType() )
3503  {
3504  case SwNodeType::Text:
3505  OutputTextNode( *rNode.GetTextNode() );
3506  break;
3507  case SwNodeType::Grf:
3508  OutputGrfNode( *rNode.GetGrfNode() );
3509  break;
3510  case SwNodeType::Ole:
3511  OutputOLENode( *rNode.GetOLENode() );
3512  break;
3513  default:
3514  SAL_WARN("sw.ww8", "Unhandled node, type == " << static_cast<int>(rNode.GetNodeType()) );
3515  break;
3516  }
3517 }
3518 
3519 
3520 WW8Ruby::WW8Ruby(const SwTextNode& rNode, const SwFormatRuby& rRuby, const MSWordExportBase& rExport ):
3521  m_nJC(0),
3522  m_cDirective(0),
3523  m_nRubyHeight(0),
3524  m_nBaseHeight(0)
3525 {
3526  switch ( rRuby.GetAdjustment() )
3527  {
3528  case css::text::RubyAdjust_LEFT:
3529  m_nJC = 3;
3530  m_cDirective = 'l';
3531  break;
3532  case css::text::RubyAdjust_CENTER:
3533  //defaults to 0
3534  break;
3535  case css::text::RubyAdjust_RIGHT:
3536  m_nJC = 4;
3537  m_cDirective = 'r';
3538  break;
3539  case css::text::RubyAdjust_BLOCK:
3540  m_nJC = 1;
3541  m_cDirective = 'd';
3542  break;
3543  case css::text::RubyAdjust_INDENT_BLOCK:
3544  m_nJC = 2;
3545  m_cDirective = 'd';
3546  break;
3547  default:
3548  OSL_ENSURE( false,"Unhandled Ruby justification code" );
3549  break;
3550  }
3551 
3552  if ( rRuby.GetPosition() == css::text::RubyPosition::INTER_CHARACTER )
3553  {
3554  m_nJC = 5;
3555  m_cDirective = 0;
3556  }
3557 
3558  /*
3559  MS needs to know the name and size of the font used in the ruby item,
3560  but we could have written it in a mixture of asian and western
3561  scripts, and each of these can be a different font and size than the
3562  other, so we make a guess based upon the first character of the text,
3563  defaulting to asian.
3564  */
3566  sal_uInt16 nRubyScript = g_pBreakIt->GetBreakIter()->getScriptType(rRuby.GetText(), 0);
3567 
3568  const SwTextRuby* pRubyText = rRuby.GetTextRuby();
3569  const SwCharFormat* pFormat = pRubyText ? pRubyText->GetCharFormat() : nullptr;
3570 
3571  if (pFormat)
3572  {
3573  const auto& rFont
3574  = ItemGet<SvxFontItem>(*pFormat, GetWhichOfScript(RES_CHRATR_FONT, nRubyScript));
3575  m_sFontFamily = rFont.GetFamilyName();
3576 
3577  const auto& rHeight = ItemGet<SvxFontHeightItem>(
3578  *pFormat, GetWhichOfScript(RES_CHRATR_FONTSIZE, nRubyScript));
3579  m_nRubyHeight = rHeight.GetHeight();
3580  }
3581  else
3582  {
3583  /*Get defaults if no formatting on ruby text*/
3584 
3585  const SfxItemPool* pPool = rNode.GetSwAttrSet().GetPool();
3586  pPool = pPool ? pPool : &rExport.m_rDoc.GetAttrPool();
3587 
3588 
3589  const auto& rFont
3590  = DefaultItemGet<SvxFontItem>(*pPool, GetWhichOfScript(RES_CHRATR_FONT, nRubyScript));
3591  m_sFontFamily = rFont.GetFamilyName();
3592 
3593  const auto& rHeight = DefaultItemGet<SvxFontHeightItem>(
3594  *pPool, GetWhichOfScript(RES_CHRATR_FONTSIZE, nRubyScript));
3595  m_nRubyHeight = rHeight.GetHeight();
3596  }
3597 
3598  const OUString &rText = rNode.GetText();
3599  sal_uInt16 nScript = i18n::ScriptType::LATIN;
3600 
3601  if (!rText.isEmpty())
3602  nScript = g_pBreakIt->GetBreakIter()->getScriptType(rText, 0);
3603 
3604  sal_uInt16 nWhich = GetWhichOfScript(RES_CHRATR_FONTSIZE, nScript);
3605  auto& rHeightItem = static_cast<const SvxFontHeightItem&>(rExport.GetItem(nWhich));
3606  m_nBaseHeight = rHeightItem.GetHeight();
3607 }
3608 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool GetValue() const
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:983
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:685
virtual void WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner=ww8::WW8TableNodeInfoInner::Pointer_t())=0
SvxBreak
OUString GetSnippet(const OUString &rStr, sal_Int32 nCurrentPos, sal_Int32 nLen) const
Definition: wrtw8nds.cxx:1709
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
eFORMDROPDOWN
TOXTypes
Definition: toxe.hxx:39
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(93)
virtual AttributeOutputBase & AttrOutput() const =0
Access to the attribute output class.
virtual void OutputOLENode(const SwOLENode &)=0
Output SwOLENode.
URL aURL
bool Insert(const SvxTabStop &rTab)
sal_uLong GetIndex() const
Definition: node.hxx:290
const OUString & GetBaseURL() const
Definition: shellio.hxx:439
const sw::BroadcastingModify * m_pOutFormatNode
Definition: wrtww8.hxx:533
virtual void AppendSmartTags(SwTextNode &)
Definition: wrtww8.hxx:708
virtual ::sw::mark::IFieldmark * getFieldmarkAt(const SwPosition &rPos) const =0
get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
virtual const OUString & GetName() const =0
std::unique_ptr< ww::bytes > pO
Buffer.
Definition: wrtww8.hxx:985
void GetCurrentItems(ww::bytes &rItems) const
Definition: wrtw8nds.cxx:866
bool m_bLinkedTextboxesHelperInitialized
Definition: wrtww8.hxx:511
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
sal_uInt16 AddRedlineAuthor(std::size_t nId)
Definition: wrtww8.cxx:1651
bool IsSaveRelFSys() const
virtual void FormatDrop(const SwTextNode &rNode, const SwFormatDrop &rSwFormatDrop, sal_uInt16 nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner)=0
const SwFormatLayoutSplit & GetLayoutSplit(bool=true) const
Definition: fmtlsplt.hxx:46
Marks a position in the document model.
Definition: pam.hxx:35
void OutSwString(const OUString &, sal_Int32 nStt, sal_Int32 nLen)
Definition: wrtww8.cxx:1828
constexpr TypedWhichId< SvxTabStopItem > RES_PARATR_TABSTOP(68)
bool GetWholeWord() const
Definition: paratr.hxx:108
bool IsSectionNode() const
Definition: node.hxx:647
std::unique_ptr< WW8Fib > pFib
File Information Block.
Definition: wrtww8.hxx:989
virtual void SectionBreaks(const SwNode &rNode)=0
Called in order to output section breaks.
ww8::Frames GetFramesInNode(const ww8::Frames &rFrames, const SwNode &rNode)
Get the Frames anchored to a given node.
const SfxPoolItem & GetItem(sal_uInt16 nWhich) const
Definition: wrtww8.cxx:775
static const SwPageDesc * GetPageDescOfNode(const SwNode &rNd)
Given a SwNode return the pagedesc in use at that location.
Definition: pagedesc.cxx:311
OUString & GetRefName()
Definition: fmtrfmrk.hxx:65
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
SvxAdjust GetAdjust() const
sal_uInt8 SVBT16[2]
virtual void EndParagraphProperties(const SfxItemSet &rParagraphMarkerProperties, const SwRedlineData *pRedlineData, const SwRedlineData *pRedlineParagraphMarkerDeleted, const SwRedlineData *pRedlineParagraphMarkerInserted)=0
Called after we end outputting the attributes.
#define ODF_OLE_PARAM
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:161
void WriteStringAsPara(const OUString &rText)
Definition: wrtww8.cxx:1772
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:752
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_METAFIELD(49)
RndStdIds m_eNewAnchorType
Definition: wrtww8.hxx:518
bool m_bAddFootnoteTab
Definition: wrtww8.hxx:568
const OUString & GetText() const
Definition: ndtxt.hxx:213
OUString const & GetPrimaryKey() const
Definition: tox.hxx:642
#define ODF_PAGEREF
sal_uInt16 GetId(const SwTextFormatColl &rColl) const
Return the numeric id of the style.
Definition: wrtw8sty.cxx:134
const SwFormatDrop & mrSwFormatDrop
Definition: wrtww8.hxx:1511
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:221
std::string GetValue
const SwRedlineData * Next() const
Definition: redline.hxx:129
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: node.cxx:1216
std::multimap< sal_Int32, OUString > m_aBookmarksOfParagraphEnd
eFORMCHECKBOX
const SwNumFormat * GetNumFormat(sal_uInt16 i) const
Definition: number.cxx:89
constexpr TypedWhichId< SvxFormatKeepItem > RES_KEEP(110)
OUString GetURLPath(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
SwNodeIndex nNode
Definition: pam.hxx:37
virtual bool AnalyzeURL(const OUString &rURL, const OUString &rTarget, OUString *pLinkURL, OUString *pMark) override
Definition: wrtw8nds.cxx:998
std::size_t GetAuthor() const
Definition: redline.hxx:126
SvxBreak GetBreak() const
virtual void Redline(const SwRedlineData *pRedline) override
Output redlining.
Definition: wrtw8nds.cxx:3445
const SwRedlineData * GetParagraphLevelRedline()
Definition: wrtw8nds.cxx:1465
std::vector< sal_uInt8 > bytes
Definition: types.hxx:29
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:274
sal_uInt8 GetLines() const
Definition: paratr.hxx:102
sal_uIntPtr sal_uLong
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
virtual void EndRuby(const SwTextNode &rNode, sal_Int32 nPos)=0
Output ruby end.
static void WriteString8(SvStream &rStrm, const OUString &rStr, bool bAddZero, rtl_TextEncoding eCodeSet)
Definition: wrtww8.cxx:1759
constexpr TypedWhichId< SwNumRuleItem > RES_PARATR_NUMRULE(72)
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:475
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2687
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_FONTSIZE(8)
const SwPosition * GetMark() const
Definition: pam.hxx:209
const SwAttrSet * m_pStyAttr
Definition: wrtww8.hxx:532
const SvxFrameDirectionItem & GetFrameDir(bool=true) const
Definition: frmatr.hxx:94
const SwPageDesc * FindPageDesc(size_t *pPgDescNdIdx=nullptr) const
Search PageDesc with which this node is formatted.
Definition: node.cxx:472
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:398
rtl_TextEncoding meChrSet
Definition: wrtww8.hxx:1501
SwFrameFormat & GetFirstMaster()
Definition: pagedesc.hxx:218
bool MiserableFormFieldExportHack(const SwFrameFormat &rFrameFormat)
Definition: wrtw8esh.cxx:351
Provides access to the marks of a document.
bool m_bOutPageDescs
PageDescs (section properties) are being written.
Definition: wrtww8.hxx:549
#define ODF_FORMCHECKBOX
eFORMDATE
bool mbCharIsRTL
Definition: wrtww8.hxx:1503
virtual void StartRuby(const SwTextNode &rNode, sal_Int32 nPos, const SwFormatRuby &rRuby)=0
Output ruby start.
virtual void OutputLinkedOLE(const OUString &)=0
sal_uInt16 FirstWhich()
#define ODF_CODE_PARAM
std::stack< sal_Int32 > m_aCurrentCharPropStarts
To remember the position in a run.
Definition: wrtww8.hxx:468
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
bool NeedSectionBreak(const SwNode &rNd) const
Definition: wrtw8nds.cxx:2127
bool HasDummyChar() const
Definition: txatbase.hxx:101
SwTableLine is one table row in the document model.
Definition: swtable.hxx:351
SwNode & GetNode() const
Definition: ndindex.hxx:119
const OUString & GetName() const
Definition: numrule.hxx:223
bool GetNewAbsURL(OUString const &rTheRelURIRef, INetURLObject *pTheAbsURIRef) const
Point * m_pFlyOffset
Definition: wrtww8.hxx:517
const std::shared_ptr< SfxItemSet > & GetStyleHandle() const
Definition: fmtautofmt.hxx:49
SvxFrameDirection
static OUString GetRelURL(OUString const &rTheBaseURIRef, OUString const &rTheAbsURIRef, EncodeMechanism eEncodeMechanism=EncodeMechanism::WasEncoded, DecodeMechanism eDecodeMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
SwSectionFormat * GetFormat()
Definition: section.hxx:336
SvxFrameDirection GetTextDirection(const SwPosition &rPos, const Point *pPt=nullptr) const
Definition: doclay.cxx:1610
sal_uInt16 m_nStyleBeforeFly
style number of the node
Definition: wrtww8.hxx:479
void Pos(const Point &rNew)
Definition: swrect.hxx:169
bool AreListLevelIndentsApplicable() const
Determines, if the list level indent attributes can be applied to the paragraph.
Definition: ndtxt.cxx:4391
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1705
virtual void StartRunProperties()=0
Called before we start outputting the attributes.
WW8_CP Fc2Cp(sal_uLong nFc) const
Definition: wrtww8.hxx:1094
const SwTOXType * GetTOXType() const
Definition: tox.hxx:580
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
sal_uInt16 Which() const
Definition: txatbase.hxx:110
void Set_UInt32(sal_uInt8 *&p, sal_uInt32 n)
Definition: ww8struc.hxx:53
static constexpr sal_uInt16 val
Definition: sprmids.hxx:277
virtual sal_Int32 getAnnotationMarksCount() const =0
void OutputItemSet(const SfxItemSet &rSet, bool bPapFormat, bool bChpFormat, sal_uInt16 nScript, bool bExportParentItemSet)
Use OutputItem() on an item set according to the parameters.
Definition: ww8atr.cxx:294
void AppendFlyInFlys(const ww8::Frame &rFrameFormat, const Point &rNdTopLeft)
Definition: wrtw8esh.cxx:968
virtual SvxBrushItem * Clone(SfxItemPool *pPool=nullptr) const override
constexpr TypedWhichId< SfxGrabBagItem > RES_CHRATR_GRABBAG(43)
SVL_DLLPUBLIC OUString simpleNormalizedMakeRelative(OUString const &baseUriReference, OUString const &uriReference)
virtual const SfxPoolItem * HasTextItem(sal_uInt16 nWhich) const override
Definition: wrtw8nds.cxx:825
#define CH_TXT_ATR_FORMELEMENT
Definition: hintids.hxx:176
OUString FieldString(ww::eField eIndex)
Definition: ww8atr.cxx:2599
virtual ExportFormat GetExportFormat() const =0
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4081
std::shared_ptr< SvxBrushItem > TrueFrameBgBrush(const SwFrameFormat &rFlyFormat) const
Definition: wrtw8nds.cxx:1660
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:203
sal_uInt32 m_nBaseHeight
const SwRedlineData * GetParagraphMarkerRedline(const SwTextNode &rNode, RedlineType aRedlineType)
Definition: ww8atr.cxx:5535
size_type size() const
Definition: swtable.hxx:75
sal_uInt16 NextWhich()
IMarkVector m_rSortedAnnotationMarksEnd
Definition: wrtww8.hxx:583
virtual void SectionBreak(sal_uInt8 nC, bool bBreakAfter, const WW8_SepInfo *pSectionInfo=nullptr)=0
Write a section break msword::ColumnBreak or msword::PageBreak bBreakAfter: the break must be schedul...
void GetPoolItems(const SfxItemSet &rSet, ww8::PoolItems &rItems, bool bExportParentItemSet)
Get the SfxPoolItems of a SfxItemSet.
virtual void SetAnchorIsLinkedToNode(bool)
If the node has an anchor linked.
ww8::FrameIter maFlyIter
Definition: wrtww8.hxx:1514
#define CHAR_SOFTHYPHEN
Definition: swtypes.hxx:166
OUString PathToFileName() const
size_type size() const
Definition: docary.hxx:266
OUString BookmarkToWord(const OUString &rBookmark)
Definition: wrtw8nds.cxx:1188
const SwSection & GetSection() const
Definition: node.hxx:544
sal_Int32 WhereNext() const
Definition: wrtww8.hxx:1546
WEIGHT_BOLD
sal_uInt16 GetScript() const
Definition: wrtww8.hxx:1547
void GenerateBookmarksForSequenceField(const SwTextNode &rNode, SwWW8AttrIter &rAttrIter)
MSO uses bookmarks to reference sequence fields, so we need to generate these additional bookmarks du...
Definition: ww8atr.cxx:1998
#define ODF_HYPERLINK
constexpr TypedWhichId< SvxCaseMapItem > RES_CHRATR_CASEMAP(RES_CHRATR_BEGIN)
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:169
sal_uInt16 IsFormulaOrValueBox() const
Definition: swtable.cxx:2538
void WriteText()
Iterate through the nodes and call the appropriate OutputNode() on them.
Definition: wrtww8.cxx:2776
sal_uInt16 sal_Unicode
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
void SetTextLeft(const tools::Long nL, const sal_uInt16 nProp=100)
const SwTextRuby * GetTextRuby() const
Definition: fmtruby.hxx:59
RedlineType GetType() const
Definition: redline.hxx:124
virtual void PageBreakBefore(bool bBreak)=0
Page break As a paragraph property - the paragraph should be on the next page.
virtual void AppendBookmarks(const SwTextNode &rNd, sal_Int32 nCurrentPos, sal_Int32 nLen)=0
virtual void OutputField(const SwField *pField, ww::eField eFieldType, const OUString &rFieldCmd, FieldFlags nMode=FieldFlags::All) override
Write the field.
Definition: ww8atr.cxx:1745
SwWW8AttrIter(const SwWW8AttrIter &)=delete
ePAGEREF
SwNodeType GetNodeType() const
Definition: node.hxx:144
MSWordExportBase & m_rExport
Definition: wrtww8.hxx:1435
std::map< OUString, LinkedTextboxInfo > m_aLinkedTextboxesHelper
Definition: wrtww8.hxx:510
SwIndex nContent
Definition: pam.hxx:38
bool empty() const
Definition: docary.hxx:265
eUNKNOWN
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
size_t pos
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_CTL_LANGUAGE(29)
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &pos) const =0
void OutputFormat(const SwFormat &rFormat, bool bPapFormat, bool bChpFormat, bool bFlyFormat=false)
Output attributes.
Definition: ww8atr.cxx:759
virtual bool StartURL(const OUString &rUrl, const OUString &rTarget) override
Output URL start.
Definition: wrtw8nds.cxx:1029
const OUString & GetName() const
Definition: format.hxx:111
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
void StartTOX(const SwSection &rSect)
Definition: ww8atr.cxx:2168
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
virtual void StartRun(const SwRedlineData *pRedlineData, sal_Int32 nPos, bool bSingleEmptyRun=false)=0
Start of the text run.
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
const SvxBrushItem * GetCurrentPageBgBrush() const
Definition: wrtw8nds.cxx:1641
MSWordAttrIter * m_pChpIter
Definition: wrtww8.hxx:496
FieldId eFieldId
bool m_bInWriteEscher
Definition: wrtww8.hxx:554
virtual void SetStateOfFlyFrame(FlyProcessingState)
Set the state of the Fly at current position.
virtual void StartParagraphProperties()=0
Called before we start outputting the attributes.
virtual bool IsFlyProcessingPostponed()
Is processing of fly postponed ?
constexpr TypedWhichId< SwFormatRuby > RES_TXTATR_CJK_RUBY(53)
const SwTable & GetTable() const
Definition: node.hxx:500
virtual void ResetFlyProcessingFlag()
Reset the flag for FlyProcessing.
constexpr TypedWhichId< SfxGrabBagItem > RES_PARATR_GRABBAG(81)
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
virtual parameter_map_t * GetParameters()=0
sal_uInt16 GetDistance() const
Definition: paratr.hxx:111
const SvxFormatKeepItem & GetKeep(bool=true) const
Definition: frmatr.hxx:86
const Graphic * GetGraphic(OUString const &referer=OUString()) const
void WriteChar(sal_Unicode c) override
Definition: wrtww8.cxx:1865
INetProtocol
ww8::Frames maFlyFrames
Definition: wrtww8.hxx:1513
constexpr TypedWhichId< SwFormatAutoFormat > RES_TXTATR_AUTOFMT(50)
static void UpdateTocSectionNodeProperties(const SwSectionNode &rSectionNode)
Definition: wrtw8nds.cxx:3242
void handleToggleProperty(SfxItemSet &rExportSet, const SwFormatCharFormat *pCharFormatItem, sal_uInt16 nWhich, const SfxPoolItem *pValue)
Definition: wrtw8nds.cxx:546
ww8::WW8TableInfo::Pointer_t m_pTableInfo
Definition: wrtww8.hxx:475
size_type size() const
void OutputItem(const SfxPoolItem &rHt)
Call the right virtual function according to the type of the item.
Definition: ww8atr.cxx:5198
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
SwAttrPool * GetPool() const
Definition: swatrset.hxx:190
rtl_TextEncoding GetCharSet() const
Definition: wrtww8.hxx:1549
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
const SwFrameFormat & GetFrameFormat() const
Get the writer SwFrameFormat that this object describes.
const SwRedlineData & GetRedlineData(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1783
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_WEIGHT(15)
SwFormatColl & GetAnyFormatColl() const
Definition: node.hxx:710
Base class for various Writer styles.
Definition: format.hxx:43
const T & item_cast(const SfxPoolItem &rItem)
Provide a dynamic_cast style cast for SfxPoolItems.
void GetSortedAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen)
Definition: wrtw8nds.cxx:2060
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:163
const OUString & GetText() const
Definition: fmtruby.hxx:61
DocumentType eType
static void WriteString16(SvStream &rStrm, const OUString &rStr, bool bAddZero)
Definition: wrtww8.cxx:1736
void IterToCurrent()
Definition: wrtw8nds.cxx:176
virtual const_iterator_t getAllMarksBegin() const =0
returns a STL-like random access iterator to the begin of the sequence of marks.
const Color & GetColor() const
virtual sal_uLong ReplaceCr(sal_uInt8 nChar)=0
const OUString & GetAlternativeText() const
Definition: tox.hxx:571
bool IsContentNode() const
Definition: node.hxx:631
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:451
void NextPos()
Definition: wrtww8.hxx:1535
sal_uInt32 GetRubyHeight() const
virtual bool AnalyzeURL(const OUString &rUrl, const OUString &rTarget, OUString *pLinkURL, OUString *pMark)
Definition: wrtw8nds.cxx:944
std::unique_ptr< WW8_WrPlcPn > m_pPapPlc
Definition: wrtww8.hxx:494
sal_uInt16 GetPosition() const
Definition: fmtruby.hxx:70
WW8Export & m_rWW8Export
Reference to the export, where to get the data from.
void OutputSectionNode(const SwSectionNode &)
Output SwSectionNode.
Definition: wrtw8nds.cxx:3189
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
Style of a layout element.
Definition: frmfmt.hxx:58
size_t Count() const
Definition: ndhints.hxx:142
#define SAL_MAX_INT32
virtual void RunText(const OUString &rText, rtl_TextEncoding eCharSet=RTL_TEXTENCODING_UTF8)=0
Output text (inside a run).
static bool isRightToLeft(LanguageType nLang)
sal_Int32 GetNextPos(SwWW8AttrIter const *pAttrIter, const SwTextNode &rNode, sal_Int32 nCurrentPos)
Get the next position in the text node to output.
Definition: wrtw8nds.cxx:1860
const sal_uInt8 ND_HAS_PREV_LAYNODE
Definition: ndtyp.hxx:63
void SplitRun(sal_Int32 nSplitEndPos)
Definition: wrtw8nds.cxx:1212
virtual ~MSWordAttrIter()
Definition: wrtw8nds.cxx:158
virtual void FormatDrop(const SwTextNode &rNode, const SwFormatDrop &rSwFormatDrop, sal_uInt16 nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner) override
Definition: wrtw8nds.cxx:1796
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
void SetCurItemSet(const SfxItemSet *pS)
Setter for pISet.
Definition: wrtww8.hxx:727
std::map< sal_uInt16, const SfxPoolItem *, sw::util::ItemSort > PoolItems
STL container of SfxPoolItems (Attributes)
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
std::vector< Frame >::iterator FrameIter
STL iterator for Frames.
std::unique_ptr< WW8_WrPlcSepx > pSepx
Sections/headers/footers.
Definition: wrtww8.hxx:993
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:131
sal_Int32 GetAbsLSpace() const
WW8Ruby(const SwTextNode &rNode, const SwFormatRuby &rRuby, const MSWordExportBase &rExport)
Definition: wrtw8nds.cxx:3520
void NearestAnnotationMark(sal_Int32 &rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly)
Find the nearest annotation mark from the current position.
Definition: wrtw8nds.cxx:2031
SwDoc & GetDoc()
Definition: node.hxx:211
void UpdatePosition(SwWW8AttrIter *pAttrIter, sal_Int32 nCurrentPos)
Update the information for GetNextPos().
Definition: wrtw8nds.cxx:1877
const SwPosition * GetPoint() const
Definition: pam.hxx:207
OUString GetURLNoMark(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
sal_uInt16 mnScript
Definition: wrtww8.hxx:1502
FlyProcessingState OutFlys(sal_Int32 nSwPos)
Definition: wrtw8nds.cxx:637
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
const SwPageDesc & GetPageDesc(const size_t i) const
Definition: doc.hxx:880
const SwTOXBase * GetTOXBase() const
Definition: section.cxx:619
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
bool IsParaRTL() const
Definition: wrtww8.hxx:1548
virtual void OutputTextNode(SwTextNode &)
Output SwTextNode.
Definition: wrtw8nds.cxx:2175
sw::util::CharRuns maCharRuns
Definition: wrtww8.hxx:1498
void OutputContentNode(SwContentNode &)
Call the right (virtual) function according to the type of the item.
Definition: wrtw8nds.cxx:3500
bool HasContent() const
Definition: txatbase.hxx:106
virtual void ExportGrfBullet(const SwTextNode &rNd)=0
SwContentNode * GetContentNode()
Definition: node.hxx:618
sal_uInt8 HasPrevNextLayNode() const
Definition: node.cxx:848
vector_type::size_type size_type
Definition: docary.hxx:228
FlyAnchors.
Definition: fmtanchr.hxx:34
sal_uInt16 GetLevel() const
Definition: tox.hxx:636
static void WriteShort(SvStream &rStrm, sal_Int16 nVal)
Definition: wrtww8.hxx:955
tools::Long GetLeft() const
const ww8::Frame * m_pParentFrame
Definition: wrtww8.hxx:514
virtual WW8Export & GetExport() override
Return the right export class.
static sal_Int32 lcl_getMinPos(sal_Int32 pos1, sal_Int32 pos2)
Definition: wrtw8nds.cxx:230
void SetTextFirstLineOffset(const short nF, const sal_uInt16 nProp=100)
std::size_t WriteBytes(const void *pData, std::size_t nSize)
virtual void StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo)=0
Start of the paragraph.
Marks a character position inside a document model node.
Definition: index.hxx:33
bool HasRefToAttr(const OUString &rName)
Find the reference.
Definition: ww8atr.cxx:895
const SfxItemSet * GetItemSet(const SfxPoolItem &rAttr)
Returns the item set associated with a character/inet/auto style.
Definition: atrstck.cxx:132
float u
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:178
const SwRedlineData * GetRunLevelRedline(sal_Int32 nPos)
Definition: wrtw8nds.cxx:1490
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:190
const DateTime & GetTimeStamp() const
Definition: redline.hxx:128
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2775
SvxFrameDirection GetDefaultFrameDirection() const
Definition: wrtw8nds.cxx:1570
const std::map< OUString, css::uno::Any > & GetGrabBag() const
static OUString GetScheme(INetProtocol eTheScheme)
virtual void OutputField(const SwField *pField, ww::eField eFieldType, const OUString &rFieldCmd, FieldFlags nMode=FieldFlags::All)=0
Write the field.
SwDoc & m_rDoc
Definition: wrtww8.hxx:570
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:373
virtual const_iterator_t getAnnotationMarksBegin() const =0
bool KnowsPageDesc() const
Definition: atrfrm.cxx:654
short GetTextFirstLineOffset() const
void OutputFlyFrame(const ww8::Frame &rFormat)
Output frames.
Definition: wrtw8nds.cxx:3427
virtual void EndRuby(const SwTextNode &rNode, sal_Int32 nPos) override
Output ruby end.
Definition: wrtw8nds.cxx:901
virtual void WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner=ww8::WW8TableNodeInfoInner::Pointer_t()) override
Definition: wrtww8.cxx:1855
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:400
Marks a node in the document model.
Definition: ndindex.hxx:31
SwWW8Writer & GetWriter() const
Definition: wrtww8.hxx:1173
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:432
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:696
void StartCommentOutput(const OUString &rName)
Definition: ww8atr.cxx:1883
static void CorrectTabStopInSet(SfxItemSet &rSet, sal_Int32 nAbsLeft)
Definition: ww8atr.cxx:662
const SvxFormatBreakItem & GetBreak(bool=true) const
Definition: frmatr.hxx:90
bool HasSwAttrSet() const
Definition: node.hxx:452
const_iterator end() const
void InsUInt16(sal_uInt16 n)
Definition: wrtww8.hxx:1145
sal_uInt8 GetChars() const
Definition: paratr.hxx:105
virtual void OutputGrfNode(const SwGrfNode &)=0
Output SwGrfNode.
virtual void TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo)=0
const sal_Unicode cMarkSeparator
Definition: swtypes.hxx:129
const SwRangeRedline * pCurRedline
Definition: wrtww8.hxx:1505
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
Definition: swtable.hxx:363
void InsUInt32(sal_uInt32 n)
Definition: wrtww8.hxx:1147
void EndTOX(const SwSection &rSect, bool bCareEnd=true)
Definition: ww8atr.cxx:2496
SwTableLines & GetTabLines()
Definition: swtable.hxx:200
OUString GetName() const
IMarkVector m_rSortedAnnotationMarksStart
Definition: wrtww8.hxx:582
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:111
sal_uInt32 GetBaseHeight() const
sal_Int16 GetWordFirstLineOffset(const SwNumFormat &rFormat)
Definition: wrtw8num.cxx:148
const SwPosition * Start() const
Definition: pam.hxx:212
void GetSortedBookmarks(const SwTextNode &rNd, sal_Int32 nCurrentPos, sal_Int32 nLen)
Definition: wrtw8nds.cxx:2094
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:245
virtual void EndRunProperties(const SwRedlineData *pRedlineData)=0
Called after we end outputting the attributes.
eFORMTEXT
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
const_iterator begin() const
virtual const SwRangeRedline * GetRedline(const SwPosition &rPos, SwRedlineTable::size_type *pFndPos) const =0
CharRuns GetPseudoCharRuns(const SwTextNode &rTextNd)
Collect the ranges of Text which share.
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:462
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:62
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void fillSoftPageBreakList(SwSoftPageBreakList &rBreak) const
const SwTextNode & rNd
Definition: wrtww8.hxx:1496
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:79
virtual void RTLAndCJKState(bool bIsRTL, sal_uInt16 nScript)=0
Export the state of RTL/CJK.
OUString const & GetFontFamily() const
#define ODF_UNHANDLED
const css::lang::Locale & GetLocale(const LanguageType aLang)
Definition: breakit.hxx:67
SwFrameFormat & GetMaster()
Definition: pagedesc.hxx:216
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:680
void OutSwFormatRefMark(const SwFormatRefMark &rAttr)
Definition: wrtw8nds.cxx:1205
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
sal_Int32 GetDropLen(sal_Int32 nWishLen) const
nWishLen = 0 indicates that we want a whole word
Definition: txtdrop.cxx:124
void SetCaseMap(const SvxCaseMap eNew)
virtual void WriteBookmarkInActParagraph(const OUString &rName, sal_Int32 nFirstRunPos, sal_Int32 nLastRunPos) override
Insert a bookmark inside the currently processed paragraph.
Definition: wrtw8nds.cxx:1023
sal_uInt32 m_nRubyHeight
#define CHAR_HARDHYPHEN
Definition: swtypes.hxx:165
char GetDirective() const
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(149)
SwCharFormat * GetCharFormat() const
Definition: fchrfmt.hxx:70
constexpr sal_uInt16 RES_TXTATR_END(RES_TXTATR_NOEND_END)
IMarkVector m_rSortedBookmarksEnd
Definition: wrtww8.hxx:581
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:446
OUString BookmarkToWriter(const OUString &rBookmark)
Definition: wrtw8nds.cxx:1199
#define ODF_TOC
const SwPageDesc * m_pCurrentPageDesc
Definition: wrtww8.hxx:492
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:67
SfxItemState
OUString GetExpandText(SwRootFrame const *pLayout, const sal_Int32 nIdx=0, const sal_Int32 nLen=-1, const bool bWithNum=false, const bool bAddSpaceAfterListLabelStr=false, const bool bWithSpacesForLevel=false, const ExpandMode eAdditionalMode=ExpandMode::ExpandFootnote) const
add 4th optional parameter indicating, when that a spa...
Definition: ndtxt.cxx:3345
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
virtual void StartRuby(const SwTextNode &rNode, sal_Int32 nPos, const SwFormatRuby &rRuby) override
Output ruby start.
Definition: wrtw8nds.cxx:877
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(105)
bool HasFlysAt(sal_Int32 nSwPos) const
Definition: wrtw8nds.cxx:622
sal_Int32 GetJC() const
virtual const SfxPoolItem & GetItem(sal_uInt16 nWhich) const override
Definition: wrtw8nds.cxx:871
static OUString & TruncateBookmark(OUString &rRet)
Definition: wrtw8nds.cxx:908
bool GetDropSize(int &rFontHeight, int &rDropHeight, int &rDropDescent) const
Passes back info needed on the dropcap dimensions.
Definition: txtdrop.cxx:230
virtual sal_Int32 getAllMarksCount() const =0
returns the number of marks.
SvStream & Strm() const
Definition: wrtww8.hxx:1174
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
OUString const & GetSecondaryKey() const
Definition: tox.hxx:648
FlyProcessingState
enum to state the present state of the fly
Definition: wrtww8.hxx:163
unsigned char sal_uInt8
const OUString & GetTargetFrame() const
Definition: fmtinfmt.hxx:89
Make exporting a Writer Frame easy.
bool IsDropCap(int nSwPos)
Definition: wrtw8nds.cxx:796
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2850
const SwContentNode * GetContentNode() const
Get the node this frame is anchored into.
bool IncludeEndOfParaCRInRedlineProperties(sal_Int32 nPos) const
Definition: wrtw8nds.cxx:1409
bool IsWatermarkFrame()
Definition: wrtw8nds.cxx:591
TOXTypes GetType() const
Definition: tox.hxx:733
sal_uInt32 DateTime2DTTM(const DateTime &rDT)
Convert from DTTM to Writer's DateTime.
virtual void AppendAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen)=0
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
#define SAL_INFO(area, stream)
OUString aName
SvStream & WriteUChar(unsigned char nChar)
sal_Int32 GetIndex() const
Definition: index.hxx:91
SvStream * pDataStrm
Streams for WW97 Export.
Definition: wrtww8.hxx:987
bool IsCountedInList() const
Definition: ndtxt.cxx:4219
INetProtocol GetProtocol() const
#define ODF_FORMTEXT
LanguageType GetAppLanguage()
Definition: init.cxx:728
IDocumentSettingAccess const & getIDocumentSettingAccess() const
Definition: doc.cxx:176
SwNodes & GetNodes()
Definition: doc.hxx:405
const sal_uInt8 PageBreak
std::pair< OUString, sal_uLong > aBookmarkPair
Definition: wrtww8.hxx:407
sw::util::CharRuns::const_iterator maCharRunIter
Definition: wrtww8.hxx:1499
const SwPosition * End() const
Definition: pam.hxx:217
OUString CalcCaseMap(const OUString &rTxt) const
std::multimap< sal_Int32, OUString > m_aBookmarksOfParagraphStart
Bookmarks of the current paragraph.
virtual void SaveData(sal_uLong nStt, sal_uLong nEnd) override
Remember some of the members so that we can recurse in WriteText().
Definition: wrtww8.cxx:1942
sal_uInt8 m_nTextTyp
Definition: wrtww8.hxx:543
ww8::Frames m_aFrames
Definition: wrtww8.hxx:491
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1765
bool HasItem(sal_uInt16 nWhich, const SfxPoolItem **ppItem=nullptr) const
const sal_Int32 * End() const
Definition: txatbase.hxx:148
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:393
bool m_bOutFlyFrameAttrs
Definition: wrtww8.hxx:548
bool NearestBookmark(sal_Int32 &rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly)
Find the nearest bookmark from the current position.
Definition: wrtw8nds.cxx:1999
virtual void FieldVanish(const OUString &rText, ww::eField eType)=0
virtual bool EndURL(bool isAtEndOfParagraph)=0
Output URL end.
sal_uInt64 Tell() const
std::shared_ptr< WW8TableNodeInfoInner > Pointer_t
constexpr TypedWhichId< SwTOXMark > RES_TXTATR_TOXMARK(47)
bool m_bInWriteTOX
Definition: wrtww8.hxx:556
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
virtual void AppendSection(const SwPageDesc *pPageDesc, const SwSectionFormat *pFormat, sal_uLong nLnNum) override
Definition: wrtw8nds.cxx:3329
bool IsPlausableSingleWordSection(const SwFrameFormat &rTitleFormat, const SwFrameFormat &rFollowFormat)
See if two page formats can be expressed as a single word section.
virtual void ParagraphStyle(sal_uInt16 nStyle)=0
Output style.
bool GetBookmarks(const SwTextNode &rNd, sal_Int32 nStt, sal_Int32 nEnd, IMarkVector &rArr)
Definition: wrtw8nds.cxx:1889
sal_Int32 GetFirstLineOffset() const
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
eHYPERLINK
virtual const SwPosition & GetMarkEnd() const =0
static void InsUInt16(ww::bytes &rO, sal_uInt16 n)
Definition: wrtww8.cxx:1701
virtual void TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo) override
Definition: wrtww8.cxx:1975
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:180
bool GetAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nStt, sal_Int32 nEnd, IMarkVector &rArr)
Definition: wrtw8nds.cxx:1937
TOXTypes GetType() const
Definition: tox.hxx:701
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:717
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:355
SwTableBox * GetUpper()
Definition: swtable.hxx:369
virtual bool StartURL(const OUString &rUrl, const OUString &rTarget)=0
Output URL start.
css::text::RubyAdjust GetAdjustment() const
Definition: fmtruby.hxx:73
virtual void PrepareNewPageDesc(const SfxItemSet *pSet, const SwNode &rNd, const SwFormatPageDesc *pNewPgDescFormat, const SwPageDesc *pNewPgDesc)=0
#define ODF_FORMDATE
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:159
void ExportPoolItemsToCHP(ww8::PoolItems &rItems, sal_uInt16 nScript, const SvxFontItem *pFont, bool bWriteCombChars=false)
Export the pool items to attributes (through an attribute output class).
Definition: ww8atr.cxx:208
constexpr TypedWhichId< SwFormatAutoFormat > RES_PARATR_LIST_AUTOFMT(87)
virtual OUString GetFieldname() const =0
ResultType type
virtual void Redline(const SwRedlineData *pRedline)=0
Output redlining.
MSWordAttrIter * pOld
Definition: wrtww8.hxx:1431
sal_Int32 nCurrentSwPos
Definition: wrtww8.hxx:1506
#define SAL_WARN(area, stream)
const SwCharFormat * GetCharFormat() const
Definition: paratr.hxx:114
Base class for WW8Export and DocxExport.
Definition: wrtww8.hxx:447
OUString GetMark(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
static OUString lcl_getFieldCode(const IFieldmark *pFieldmark)
Definition: wrtw8nds.cxx:110
sal_Int32 SearchNext(sal_Int32 nStartPos)
Definition: wrtw8nds.cxx:242
SwRedlineTable::size_type nCurRedlinePos
Definition: wrtww8.hxx:1507
constexpr TypedWhichId< SwFormatLineNumber > RES_LINENUMBER(116)
sal_uInt16 GetPos(const SwTableLine *pBox) const
Definition: swtable.hxx:97
bool IsExportableAttr(sal_Int32 nSwPos) const
Definition: wrtw8nds.cxx:772
SvxFrameDirection GetCurrentPageDirection() const
Right to left?
Definition: wrtw8nds.cxx:1562
const SwFormatDrop & GetSwFormatDrop() const
Definition: wrtww8.hxx:1552
virtual const SwPosition & GetMarkStart() const =0
static OUString GetBookmarkName(sal_uInt16 nTyp, const OUString *pName, sal_uInt16 nSeqNo)
Find the bookmark name.
Definition: ww8atr.cxx:913
virtual void EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner)=0
End of the paragraph.
const SwTextTOXMark * GetTextTOXMark() const
Definition: tox.hxx:162
bool mbParaIsRTL
Definition: wrtww8.hxx:1509
const SwTextNode & GetNode() const
Definition: wrtww8.hxx:1559
bool IsInline() const
Is this frame inline (as character)
WriterSource GetWriterType() const
Get the type of frame that this wraps.
constexpr TypedWhichId< SwFormatRefMark > RES_TXTATR_REFMARK(RES_TXTATR_WITHEND_BEGIN)
SectionType GetType() const
Definition: section.hxx:170
SwGrfNode * GetGrfNode()
Definition: ndgrf.hxx:154
MSWordAttrIter(const MSWordAttrIter &)=delete
static SwTextFormatColl & lcl_getFormatCollection(MSWordExportBase &rExport, const SwTextNode *pTextNode)
Delivers the right paragraph style.
Definition: wrtw8nds.cxx:1772
virtual void WriteHyperlinkData(const ::sw::mark::IFieldmark &rFieldmark)=0
static bool NoPageBreakSection(const SfxItemSet *pSet)
Definition: wrtw8nds.cxx:3155
virtual SwTableBoxFormula * Clone(SfxItemPool *pPool=nullptr) const override
Definition: cellatr.cxx:70
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
If SwFormatDrop is a Client, it is the CharFormat that describes the font for the DropCaps...
Definition: paratr.hxx:62
virtual const SwRedlineTable & GetRedlineTable() const =0
void TOXMark(const SwTextNode &rNode, const SwTOXMark &rAttr)
Definition: wrtw8nds.cxx:1253
std::vector< ::sw::mark::IMark * > IMarkVector
Used to split the runs according to the bookmarks start and ends.
Definition: wrtww8.hxx:579
std::pair< const_iterator, bool > insert(Value &&x)
const SfxPoolItem & GetAttr(sal_uInt16 nWhich, bool bInParent=true) const
SS for PoolItems: hard attributation.
Definition: node.hxx:724
virtual void AppendBookmark(const OUString &rName)=0
void EndCommentOutput(const OUString &rName)
Definition: ww8atr.cxx:1889
void ClearOverridesFromSet(const SwFormatCharFormat &rFormat, SfxItemSet &rSet)
Remove properties from an SfxItemSet which a SwFormatCharFormat overrides.
void OutAttr(sal_Int32 nSwPos, bool bWriteCombinedChars)
Definition: wrtw8nds.cxx:382
virtual void RestoreData() override
Restore what was saved in SaveData().
Definition: wrtww8.cxx:1960
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
bool IsTextAttr(sal_Int32 nSwPos) const
Definition: wrtw8nds.cxx:747
void OutputFlyFrame_Impl(const ww8::Frame &rFormat, const Point &rNdTopLeft) override
Output frames - the implementation.
Definition: wrtw8nds.cxx:3336
virtual bool EndURL(bool) override
Output URL end.
Definition: wrtw8nds.cxx:1181
#define CH_TXT_ATR_FIELDSEP
Definition: hintids.hxx:179
virtual void WriteFormData(const ::sw::mark::IFieldmark &rFieldmark)=0
Write the data of the form field.
int OutAttrWithRange(const SwTextNode &rNode, sal_Int32 nPos)
Definition: wrtw8nds.cxx:1308
SwTableLine * GetUpper()
Definition: swtable.hxx:428
static ww::eField lcl_getFieldId(const IFieldmark *const pFieldmark)
Definition: wrtw8nds.cxx:131
tools::Long GetIndentAt() const
bool IsTextNode() const
Definition: node.hxx:639
The class MSWordAttrIter is a helper class to build the Fkp.chpx.
Definition: wrtww8.hxx:1428
std::shared_ptr< WW8TableNodeInfo > Pointer_t
static void WriteLong(SvStream &rStrm, sal_Int32 nVal)
Definition: wrtww8.hxx:958
const SwPosition & GetPosition() const
Get the position this frame is anchored at.
bool IsInTable() const
Return whether currently exported node is in table.
Definition: wrtww8.cxx:2949
bool NeedTextNodeSplit(const SwTextNode &rNd, SwSoftPageBreakList &pList) const
Definition: wrtw8nds.cxx:2145
SwFrameFormat * GetFlyFormat() const
If node is in a fly return the respective format.
Definition: node.cxx:717
aStr
SwCharFormat * GetCharFormat()
Definition: txtatr2.cxx:228
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1284
virtual void AppendSection(const SwPageDesc *pPageDesc, const SwSectionFormat *pFormat, sal_uLong nLnNum)=0
const sal_uInt8 ND_HAS_NEXT_LAYNODE
Definition: ndtyp.hxx:64
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
virtual void EndRun(const SwTextNode *pNode, sal_Int32 nPos, bool bLastRun=false)=0
End of the text run.
SwRect FindPageFrameRect() const
Definition: node.cxx:1232
virtual void EmptyParagraph() override
Empty paragraph.
Definition: wrtw8nds.cxx:3150
std::unique_ptr< WW8_WrPlcPn > m_pChpPlc
Definition: wrtww8.hxx:495
sal_uInt16 Which() const
constexpr TypedWhichId< SvxAdjustItem > RES_PARATR_ADJUST(64)
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_CJK_LANGUAGE(24)
SvxFrameDirection TrueFrameDirection(const SwFrameFormat &rFlyFormat) const
Right to left?
Definition: wrtw8nds.cxx:1608
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2740
OUString ConvertURL(const OUString &rUrl, bool bAbsoluteOut)
Definition: wrtw8nds.cxx:916
IMarkVector m_rSortedBookmarksStart
Definition: wrtww8.hxx:580
#define ODF_ID_PARAM
virtual MSWordExportBase & GetExport()=0
Return the right export class.
sal_uInt16 nPos
static OUString encode(OUString const &rText, Part ePart, EncodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1317
std::vector< aBookmarkPair > m_aImplicitBookmarks
Definition: wrtww8.hxx:490
virtual void OutputFlyFrame_Impl(const ww8::Frame &rFormat, const Point &rNdTopLeft)=0
Output frames - the implementation.
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:848
#define ODF_FORMDROPDOWN
bool IsAnchorLinkedToThisNode(sal_uLong nNodePos)
Definition: wrtw8nds.cxx:611
std::unique_ptr< MSWordStyles > m_pStyles
Definition: wrtww8.hxx:497
virtual void WritePostitFieldReference()
for docx w:commentReference
virtual void FieldVanish(const OUString &rText, ww::eField eType) override
Definition: wrtw8nds.cxx:1227
OUString m_sFontFamily
virtual void OutputFKP(bool)
Output FKP (Formatted disK Page) - necessary for binary formats only.
bool RequiresImplicitBookmark()
Definition: wrtw8nds.cxx:815
const SwTableBoxFormula & GetTableBoxFormula(bool=true) const
Definition: cellatr.hxx:107
Base class of the Writer document model elements.
Definition: node.hxx:79
static OUString decode(OUString const &rText, DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)