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_pDoc->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 
282  if ( nCurRedlinePos < m_rExport.m_pDoc->getIDocumentRedlineAccess().GetRedlineTable().size() )
283  {
284  // nCurRedlinePos point to the next redline
286  if( pCurRedline )
287  ++nRedLinePos;
288 
289  for ( ; nRedLinePos < m_rExport.m_pDoc->getIDocumentRedlineAccess().GetRedlineTable().size(); ++nRedLinePos )
290  {
291  const SwRangeRedline* pRedl = m_rExport.m_pDoc->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  {
502  const SwModify* pOldMod = m_rExport.m_pOutFormatNode;
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_pDoc->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 ( dynamic_cast< const SwContentNode *>( m_pOutFormatNode ) != nullptr ) //paragraph
1583  {
1584  const SwContentNode *pNd = static_cast<const SwContentNode *>(m_pOutFormatNode);
1585  SwPosition aPos( *pNd );
1586  nDir = m_pDoc->GetTextDirection( aPos );
1587  }
1588  else if ( dynamic_cast< const SwTextFormatColl *>( m_pOutFormatNode ) != nullptr )
1589  {
1591  nDir = SvxFrameDirection::Horizontal_RL_TB;
1592  else
1593  nDir = SvxFrameDirection::Horizontal_LR_TB; //what else can we do :-(
1594  }
1595  }
1596 
1597  if ( nDir == SvxFrameDirection::Environment )
1598  {
1599  // fdo#44029 put direction right when the locale are RTL.
1601  nDir = SvxFrameDirection::Horizontal_RL_TB;
1602  else
1603  nDir = SvxFrameDirection::Horizontal_LR_TB; //Set something
1604  }
1605 
1606  return nDir;
1607 }
1608 
1610 {
1611  const SwFrameFormat *pFlyFormat = &rFlyFormat;
1612  const SvxFrameDirectionItem* pItem = nullptr;
1613  while ( pFlyFormat )
1614  {
1615  pItem = &pFlyFormat->GetFrameDir();
1616  if ( SvxFrameDirection::Environment == pItem->GetValue() )
1617  {
1618  pItem = nullptr;
1619  const SwFormatAnchor* pAnchor = &pFlyFormat->GetAnchor();
1620  if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
1621  pAnchor->GetContentAnchor() )
1622  {
1623  pFlyFormat = pAnchor->GetContentAnchor()->nNode.GetNode().GetFlyFormat();
1624  }
1625  else
1626  pFlyFormat = nullptr;
1627  }
1628  else
1629  pFlyFormat = nullptr;
1630  }
1631 
1632  SvxFrameDirection nRet;
1633  if ( pItem )
1634  nRet = pItem->GetValue();
1635  else
1636  nRet = GetCurrentPageDirection();
1637 
1638  OSL_ENSURE( nRet != SvxFrameDirection::Environment, "leaving with environment direction" );
1639  return nRet;
1640 }
1641 
1643 {
1644  const SwFrameFormat &rFormat = m_pCurrentPageDesc
1646  : m_pDoc->GetPageDesc(0).GetMaster();
1647 
1648  const SfxPoolItem* pItem = nullptr;
1649  //If not set, or "no fill", get real bg
1650  SfxItemState eState = rFormat.GetItemState(RES_BACKGROUND, true, &pItem);
1651 
1652  const SvxBrushItem* pRet = static_cast<const SvxBrushItem*>(pItem);
1653  if (SfxItemState::SET != eState || !pRet || (!pRet->GetGraphic() &&
1654  pRet->GetColor() == COL_TRANSPARENT))
1655  {
1656  pRet = &(DefaultItemGet<SvxBrushItem>(*m_pDoc,RES_BACKGROUND));
1657  }
1658  return pRet;
1659 }
1660 
1661 std::shared_ptr<SvxBrushItem> WW8Export::TrueFrameBgBrush(const SwFrameFormat &rFlyFormat) const
1662 {
1663  const SwFrameFormat *pFlyFormat = &rFlyFormat;
1664  const SvxBrushItem* pRet = nullptr;
1665 
1666  while (pFlyFormat)
1667  {
1668  //If not set, or "no fill", get real bg
1669  const SfxPoolItem* pItem = nullptr;
1670  SfxItemState eState =
1671  pFlyFormat->GetItemState(RES_BACKGROUND, true, &pItem);
1672  pRet = static_cast<const SvxBrushItem*>(pItem);
1673  if (SfxItemState::SET != eState || !pRet || (!pRet->GetGraphic() &&
1674  pRet->GetColor() == COL_TRANSPARENT))
1675  {
1676  pRet = nullptr;
1677  const SwFormatAnchor* pAnchor = &pFlyFormat->GetAnchor();
1678  if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
1679  pAnchor->GetContentAnchor())
1680  {
1681  pFlyFormat =
1682  pAnchor->GetContentAnchor()->nNode.GetNode().GetFlyFormat();
1683  }
1684  else
1685  pFlyFormat = nullptr;
1686  }
1687  else
1688  pFlyFormat = nullptr;
1689  }
1690 
1691  if (!pRet)
1692  pRet = GetCurrentPageBgBrush();
1693 
1694  const Color aTmpColor( COL_WHITE );
1695  std::shared_ptr<SvxBrushItem> aRet(std::make_shared<SvxBrushItem>(aTmpColor, RES_BACKGROUND));
1696 
1697  if (pRet && (pRet->GetGraphic() ||( pRet->GetColor() != COL_TRANSPARENT)))
1698  {
1699  aRet.reset(pRet->Clone());
1700  }
1701 
1702  return aRet;
1703 }
1704 
1705 /*
1706 Convert characters that need to be converted, the basic replacements and the
1707 ridiculously complicated title case attribute mapping to hardcoded upper case
1708 because word doesn't have the feature
1709 */
1710 OUString SwWW8AttrIter::GetSnippet(const OUString &rStr, sal_Int32 nCurrentPos,
1711  sal_Int32 nLen) const
1712 {
1713  if (!nLen)
1714  return OUString();
1715 
1716  OUString aSnippet(rStr.copy(nCurrentPos, nLen));
1717  // 0x0a ( Hard Line Break ) -> 0x0b
1718  // 0xad ( soft hyphen ) -> 0x1f
1719  // 0x2011 ( hard hyphen ) -> 0x1e
1720  aSnippet = aSnippet.replace(0x0A, 0x0B);
1721  aSnippet = aSnippet.replace(CHAR_HARDHYPHEN, 0x1e);
1722  aSnippet = aSnippet.replace(CHAR_SOFTHYPHEN, 0x1f);
1723 
1724  m_rExport.m_aCurrentCharPropStarts.push( nCurrentPos );
1725  const SfxPoolItem &rItem = GetItem(RES_CHRATR_CASEMAP);
1726 
1727  if (SvxCaseMap::Capitalize == static_cast<const SvxCaseMapItem&>(rItem).GetValue())
1728  {
1730  sal_uInt16 nScriptType = g_pBreakIt->GetBreakIter()->getScriptType(aSnippet, 0);
1731 
1732  LanguageType nLanguage;
1733  switch (nScriptType)
1734  {
1735  case i18n::ScriptType::ASIAN:
1736  nLanguage = static_cast<const SvxLanguageItem&>(GetItem(RES_CHRATR_CJK_LANGUAGE)).GetLanguage();
1737  break;
1738  case i18n::ScriptType::COMPLEX:
1739  nLanguage = static_cast<const SvxLanguageItem&>(GetItem(RES_CHRATR_CTL_LANGUAGE)).GetLanguage();
1740  break;
1741  case i18n::ScriptType::LATIN:
1742  default:
1743  nLanguage = static_cast<const SvxLanguageItem&>(GetItem(RES_CHRATR_LANGUAGE)).GetLanguage();
1744  break;
1745  }
1746 
1747  SvxFont aFontHelper;
1748  aFontHelper.SetCaseMap(SvxCaseMap::Capitalize);
1749  aFontHelper.SetLanguage(nLanguage);
1750  aSnippet = aFontHelper.CalcCaseMap(aSnippet);
1751 
1752  //If we weren't at the begin of a word undo the case change.
1753  //not done before doing the casemap because the sequence might start
1754  //with whitespace
1755  if (!g_pBreakIt->GetBreakIter()->isBeginWord(
1756  rStr, nCurrentPos, g_pBreakIt->GetLocale(nLanguage),
1757  i18n::WordType::ANYWORD_IGNOREWHITESPACES ) )
1758  {
1759  aSnippet = OUStringChar(rStr[nCurrentPos]) + aSnippet.copy(1);
1760  }
1761  }
1763 
1764  return aSnippet;
1765 }
1766 
1774 {
1777  while( nPos < nMax )
1778  {
1779  const SwRangeRedline* pRedl = rExport.m_pDoc->getIDocumentRedlineAccess().GetRedlineTable()[ nPos++ ];
1780  const SwPosition* pStt = pRedl->Start();
1781  const SwPosition* pEnd = pStt == pRedl->GetPoint()
1782  ? pRedl->GetMark()
1783  : pRedl->GetPoint();
1784  // Looking for deletions, which ends in current pTextNode
1785  if( RedlineType::Delete == pRedl->GetRedlineData().GetType() &&
1786  pEnd->nNode == *pTextNode && pStt->nNode != *pTextNode &&
1787  pStt->nNode.GetNode().IsTextNode() )
1788  {
1789  pTextNode = pStt->nNode.GetNode().GetTextNode();
1790  nMax = nPos;
1791  nPos = 0;
1792  }
1793  }
1794  return static_cast<SwTextFormatColl&>( pTextNode->GetAnyFormatColl() );
1795 }
1796 
1797 void WW8AttributeOutput::FormatDrop( const SwTextNode& rNode, const SwFormatDrop &rSwFormatDrop, sal_uInt16 nStyle,
1799 {
1800  short nDropLines = rSwFormatDrop.GetLines();
1801  short nDistance = rSwFormatDrop.GetDistance();
1802  int rFontHeight, rDropHeight, rDropDescent;
1803 
1804  SVBT16 nSty;
1805  ShortToSVBT16( nStyle, nSty );
1806  m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), nSty, nSty+2 ); // Style #
1807 
1808  m_rWW8Export.InsUInt16( NS_sprm::PPc::val ); // Alignment (sprmPPc)
1809  m_rWW8Export.pO->push_back( 0x20 );
1810 
1811  m_rWW8Export.InsUInt16( NS_sprm::PWr::val ); // Wrapping (sprmPWr)
1812  m_rWW8Export.pO->push_back( 0x02 );
1813 
1814  m_rWW8Export.InsUInt16( NS_sprm::PDcs::val ); // Dropcap (sprmPDcs)
1815  int nDCS = ( nDropLines << 3 ) | 0x01;
1816  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( nDCS ) );
1817 
1818  m_rWW8Export.InsUInt16( NS_sprm::PDxaFromText::val ); // Distance from text (sprmPDxaFromText)
1819  m_rWW8Export.InsUInt16( nDistance );
1820 
1821  if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1822  {
1823  m_rWW8Export.InsUInt16( NS_sprm::PDyaLine::val ); // Line spacing
1824  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -rDropHeight ) );
1825  m_rWW8Export.InsUInt16( 0 );
1826  }
1827 
1828  m_rWW8Export.WriteCR( pTextNodeInfoInner );
1829 
1830  if ( pTextNodeInfo )
1831  {
1832 #ifdef DBG_UTIL
1833  SAL_INFO( "sw.ww8", pTextNodeInfo->toString());
1834 #endif
1835  TableInfoCell( pTextNodeInfoInner );
1836  }
1837 
1838  m_rWW8Export.m_pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
1839  m_rWW8Export.pO->clear();
1840 
1841  if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1842  {
1843  const SwCharFormat *pSwCharFormat = rSwFormatDrop.GetCharFormat();
1844  if ( pSwCharFormat )
1845  {
1847  m_rWW8Export.InsUInt16( m_rWW8Export.GetId( pSwCharFormat ) );
1848  }
1849 
1850  m_rWW8Export.InsUInt16( NS_sprm::CHpsPos::val ); // Lower the chars
1851  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -((nDropLines - 1)*rDropDescent) / 10 ) );
1852 
1853  m_rWW8Export.InsUInt16( NS_sprm::CHps::val ); // Font Size
1854  m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( rFontHeight / 10 ) );
1855  }
1856 
1857  m_rWW8Export.m_pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->size(), m_rWW8Export.pO->data() );
1858  m_rWW8Export.pO->clear();
1859 }
1860 
1861 sal_Int32 MSWordExportBase::GetNextPos( SwWW8AttrIter const * aAttrIter, const SwTextNode& rNode, sal_Int32 nCurrentPos )
1862 {
1863  // Get the bookmarks for the normal run
1864  const sal_Int32 nNextPos = aAttrIter->WhereNext();
1865  sal_Int32 nNextBookmark = nNextPos;
1866  sal_Int32 nNextAnnotationMark = nNextPos;
1867 
1868  if( nNextBookmark > nCurrentPos ) //no need to search for bookmarks otherwise (checked in UpdatePosition())
1869  {
1870  GetSortedBookmarks( rNode, nCurrentPos, nNextBookmark - nCurrentPos );
1871  NearestBookmark( nNextBookmark, nCurrentPos, false );
1872  GetSortedAnnotationMarks(*aAttrIter, nCurrentPos, nNextAnnotationMark - nCurrentPos);
1873  NearestAnnotationMark( nNextAnnotationMark, nCurrentPos, false );
1874  }
1875  return std::min( nNextPos, std::min( nNextBookmark, nNextAnnotationMark ) );
1876 }
1877 
1878 void MSWordExportBase::UpdatePosition( SwWW8AttrIter* aAttrIter, sal_Int32 nCurrentPos )
1879 {
1880  sal_Int32 nNextPos;
1881 
1882  // go to next attribute if no bookmark is found or if the bookmark is after the next attribute position
1883  // It may happened that the WhereNext() wasn't used in the previous increment because there was a
1884  // bookmark before it. Use that position before trying to find another one.
1885  bool bNextBookmark = NearestBookmark( nNextPos, nCurrentPos, true );
1886  if( nCurrentPos == aAttrIter->WhereNext() && ( !bNextBookmark || nNextPos > aAttrIter->WhereNext() ) )
1887  aAttrIter->NextPos();
1888 }
1889 
1890 bool MSWordExportBase::GetBookmarks( const SwTextNode& rNd, sal_Int32 nStt,
1891  sal_Int32 nEnd, IMarkVector& rArr )
1892 {
1893  IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess();
1894  sal_uLong nNd = rNd.GetIndex( );
1895 
1896  const sal_Int32 nMarks = pMarkAccess->getAllMarksCount();
1897  for ( sal_Int32 i = 0; i < nMarks; i++ )
1898  {
1899  IMark* pMark = pMarkAccess->getAllMarksBegin()[i];
1900 
1901  switch (IDocumentMarkAccess::GetType( *pMark ))
1902  {
1911  continue; // ignore irrelevant marks
1915  break;
1916  }
1917 
1918  // Only keep the bookmarks starting or ending in this node
1919  if ( pMark->GetMarkStart().nNode == nNd ||
1920  pMark->GetMarkEnd().nNode == nNd )
1921  {
1922  const sal_Int32 nBStart = pMark->GetMarkStart().nContent.GetIndex();
1923  const sal_Int32 nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
1924 
1925  // Keep only the bookmarks starting or ending in the snippet
1926  bool bIsStartOk = ( pMark->GetMarkStart().nNode == nNd ) && ( nBStart >= nStt ) && ( nBStart <= nEnd );
1927  bool bIsEndOk = ( pMark->GetMarkEnd().nNode == nNd ) && ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
1928 
1929  if ( bIsStartOk || bIsEndOk )
1930  {
1931  rArr.push_back( pMark );
1932  }
1933  }
1934  }
1935  return ( !rArr.empty() );
1936 }
1937 
1938 bool MSWordExportBase::GetAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nStt,
1939  sal_Int32 nEnd, IMarkVector& rArr )
1940 {
1941  IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess();
1942  sal_uLong nNd = rAttrs.GetNode().GetIndex();
1943 
1944  const sal_Int32 nMarks = pMarkAccess->getAnnotationMarksCount();
1945  for ( sal_Int32 i = 0; i < nMarks; i++ )
1946  {
1947  IMark* pMark = pMarkAccess->getAnnotationMarksBegin()[i];
1948 
1949  // Only keep the bookmarks starting or ending in this node
1950  if ( pMark->GetMarkStart().nNode == nNd ||
1951  pMark->GetMarkEnd().nNode == nNd )
1952  {
1953  const sal_Int32 nBStart = pMark->GetMarkStart().nContent.GetIndex();
1954  const sal_Int32 nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
1955 
1956  // Keep only the bookmarks starting or ending in the snippet
1957  bool bIsStartOk = ( pMark->GetMarkStart().nNode == nNd ) && ( nBStart >= nStt ) && ( nBStart <= nEnd );
1958  bool bIsEndOk = ( pMark->GetMarkEnd().nNode == nNd ) && ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
1959 
1960  // Annotation marks always have at least one character: the anchor
1961  // point of the comment field. In this case Word wants only the
1962  // comment field, so ignore the annotation mark itself.
1963  bool bSingleChar = pMark->GetMarkStart().nNode == pMark->GetMarkEnd().nNode && nBStart + 1 == nBEnd;
1964 
1965  if (bSingleChar)
1966  {
1967  if (rAttrs.HasFlysAt(nBStart))
1968  {
1969  // There is content (an at-char anchored frame) between the annotation mark
1970  // start/end, so still emit range start/end.
1971  bSingleChar = false;
1972  }
1973  }
1974 
1975  if ( ( bIsStartOk || bIsEndOk ) && !bSingleChar )
1976  {
1977  rArr.push_back( pMark );
1978  }
1979  }
1980  }
1981  return ( !rArr.empty() );
1982 }
1983 
1984 namespace {
1985 
1986 class CompareMarksEnd
1987 {
1988 public:
1989  bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
1990  {
1991  const sal_Int32 nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
1992  const sal_Int32 nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
1993 
1994  return nOEnd < nTEnd;
1995  }
1996 };
1997 
1998 }
1999 
2000 bool MSWordExportBase::NearestBookmark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly )
2001 {
2002  bool bHasBookmark = false;
2003 
2004  if ( !m_rSortedBookmarksStart.empty() )
2005  {
2006  IMark* pMarkStart = m_rSortedBookmarksStart.front();
2007  const sal_Int32 nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
2008  if( !bNextPositionOnly || (nNext > nCurrentPos ))
2009  {
2010  rNearest = nNext;
2011  bHasBookmark = true;
2012  }
2013  }
2014 
2015  if ( !m_rSortedBookmarksEnd.empty() )
2016  {
2017  IMark* pMarkEnd = m_rSortedBookmarksEnd[0];
2018  const sal_Int32 nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
2019  if( !bNextPositionOnly || nNext > nCurrentPos )
2020  {
2021  if ( !bHasBookmark )
2022  rNearest = nNext;
2023  else
2024  rNearest = std::min( rNearest, nNext );
2025  bHasBookmark = true;
2026  }
2027  }
2028 
2029  return bHasBookmark;
2030 }
2031 
2032 void MSWordExportBase::NearestAnnotationMark( sal_Int32& rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly )
2033 {
2034  bool bHasAnnotationMark = false;
2035 
2036  if ( !m_rSortedAnnotationMarksStart.empty() )
2037  {
2038  IMark* pMarkStart = m_rSortedAnnotationMarksStart.front();
2039  const sal_Int32 nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
2040  if( !bNextPositionOnly || (nNext > nCurrentPos ))
2041  {
2042  rNearest = nNext;
2043  bHasAnnotationMark = true;
2044  }
2045  }
2046 
2047  if ( !m_rSortedAnnotationMarksEnd.empty() )
2048  {
2049  IMark* pMarkEnd = m_rSortedAnnotationMarksEnd[0];
2050  const sal_Int32 nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
2051  if( !bNextPositionOnly || nNext > nCurrentPos )
2052  {
2053  if ( !bHasAnnotationMark )
2054  rNearest = nNext;
2055  else
2056  rNearest = std::min( rNearest, nNext );
2057  }
2058  }
2059 }
2060 
2061 void MSWordExportBase::GetSortedAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int32 nCurrentPos, sal_Int32 nLen )
2062 {
2063  IMarkVector aMarksStart;
2064  if (GetAnnotationMarks(rAttrs, nCurrentPos, nCurrentPos + nLen, aMarksStart))
2065  {
2066  IMarkVector aSortedEnd;
2067  IMarkVector aSortedStart;
2068  for ( IMark* pMark : aMarksStart )
2069  {
2070  // Remove the positions equal to the current pos
2071  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
2072  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
2073 
2074  const SwTextNode& rNode = rAttrs.GetNode();
2075  if ( nStart > nCurrentPos && ( pMark->GetMarkStart().nNode == rNode.GetIndex()) )
2076  aSortedStart.push_back( pMark );
2077 
2078  if ( nEnd > nCurrentPos && nEnd <= ( nCurrentPos + nLen ) && (pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
2079  aSortedEnd.push_back( pMark );
2080  }
2081 
2082  // Sort the bookmarks by end position
2083  std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
2084 
2085  m_rSortedAnnotationMarksStart.swap( aSortedStart );
2086  m_rSortedAnnotationMarksEnd.swap( aSortedEnd );
2087  }
2088  else
2089  {
2091  m_rSortedAnnotationMarksEnd.clear( );
2092  }
2093 }
2094 
2095 void MSWordExportBase::GetSortedBookmarks( const SwTextNode& rNode, sal_Int32 nCurrentPos, sal_Int32 nLen )
2096 {
2097  IMarkVector aMarksStart;
2098  if ( GetBookmarks( rNode, nCurrentPos, nCurrentPos + nLen, aMarksStart ) )
2099  {
2100  IMarkVector aSortedEnd;
2101  IMarkVector aSortedStart;
2102  for ( IMark* pMark : aMarksStart )
2103  {
2104  // Remove the positions equal to the current pos
2105  const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
2106  const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
2107 
2108  if ( nStart > nCurrentPos && ( pMark->GetMarkStart().nNode == rNode.GetIndex()) )
2109  aSortedStart.push_back( pMark );
2110 
2111  if ( nEnd > nCurrentPos && nEnd <= ( nCurrentPos + nLen ) && (pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
2112  aSortedEnd.push_back( pMark );
2113  }
2114 
2115  // Sort the bookmarks by end position
2116  std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
2117 
2118  m_rSortedBookmarksStart.swap( aSortedStart );
2119  m_rSortedBookmarksEnd.swap( aSortedEnd );
2120  }
2121  else
2122  {
2123  m_rSortedBookmarksStart.clear( );
2124  m_rSortedBookmarksEnd.clear( );
2125  }
2126 }
2127 
2129 {
2131  return false;
2132 
2133  const SwPageDesc * pPageDesc = rNd.FindPageDesc()->GetFollow();
2134 
2135  if (m_pCurrentPageDesc != pPageDesc)
2136  {
2138  {
2139  return true;
2140  }
2141  }
2142 
2143  return false;
2144 }
2145 
2147 {
2148  SwSoftPageBreakList tmp;
2149  rNd.fillSoftPageBreakList(tmp);
2150  // hack: move the break behind any field marks; currently we can't hide the
2151  // field mark instruction so the layout position is quite meaningless
2152  IDocumentMarkAccess const& rIDMA(*rNd.GetDoc()->getIDocumentMarkAccess());
2153  sal_Int32 pos(-1);
2154  for (auto const& it : tmp)
2155  {
2156  if (pos < it) // previous one might have skipped over it
2157  {
2158  pos = it;
2159  while (auto const*const pMark = rIDMA.getFieldmarkFor(SwPosition(const_cast<SwTextNode&>(rNd), pos)))
2160  {
2161  if (pMark->GetMarkEnd().nNode != rNd)
2162  {
2163  pos = rNd.Len(); // skip everything
2164  break;
2165  }
2166  pos = pMark->GetMarkEnd().nContent.GetIndex(); // no +1, it's behind the char
2167  }
2168  pList.insert(pos);
2169  }
2170  }
2171  pList.insert(0);
2172  pList.insert( rNd.GetText().getLength() );
2173  return pList.size() > 2 && NeedSectionBreak( rNd );
2174 }
2175 
2177 {
2178  SAL_INFO( "sw.ww8", "<OutWW8_SwTextNode>" );
2179 
2180  ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo( m_pTableInfo->getTableNodeInfo( &rNode ) );
2181 
2182  //For i120928,identify the last node
2183  bool bLastCR = false;
2184  bool bExported = false;
2185  {
2186  SwNodeIndex aNextIdx(rNode,1);
2187  SwNodeIndex aLastIdx(rNode.GetNodes().GetEndOfContent());
2188  if (aNextIdx == aLastIdx)
2189  bLastCR = true;
2190  }
2191 
2192  // In order to make sure watermark is stored in 'header.xml', check nTextTyp.
2193  // if it is document.xml, don't write the tags (watermark should be only in the 'header')
2194  SwWW8AttrIter aWatermarkAttrIter( *this, rNode );
2195  if (( TXT_HDFT != m_nTextTyp) && aWatermarkAttrIter.IsWatermarkFrame())
2196  {
2197  return;
2198  }
2199 
2200  bool bFlyInTable = m_pParentFrame && IsInTable();
2201 
2202  SwTextFormatColl& rTextColl = lcl_getFormatCollection( *this, &rNode );
2203  if ( !bFlyInTable )
2204  m_nStyleBeforeFly = GetId( rTextColl );
2205 
2206  // nStyleBeforeFly may change when we recurse into another node, so we
2207  // have to remember it in nStyle
2208  sal_uInt16 nStyle = m_nStyleBeforeFly;
2209 
2210  SwWW8AttrIter aAttrIter( *this, rNode );
2211  rtl_TextEncoding eChrSet = aAttrIter.GetCharSet();
2212 
2213  if ( m_bStartTOX )
2214  {
2215  // ignore TOX header section
2216  const SwSectionNode* pSectNd = rNode.FindSectionNode();
2217  if ( pSectNd && SectionType::ToxContent == pSectNd->GetSection().GetType() )
2218  {
2219  AttrOutput().StartTOX( pSectNd->GetSection() );
2220  m_aCurrentCharPropStarts.push( 0 );
2221  }
2222  }
2223 
2224  // Emulate: If 1-row table is marked as don't split, then set the row as don't split.
2225  if ( IsInTable() )
2226  {
2227  const SwTableNode* pTableNode = rNode.FindTableNode();
2228  if ( pTableNode )
2229  {
2230  const SwTable& rTable = pTableNode->GetTable();
2231  const SwTableBox* pBox = rNode.GetTableBox();
2232 
2233  // export formula cell as formula field instead of only its cell content in DOCX
2234  if ( pBox->IsFormulaOrValueBox() == RES_BOXATR_FORMULA &&
2235  GetExportFormat() == MSWordExportBase::ExportFormat::DOCX )
2236  {
2237  SwTableBoxFormula* pFormula = pBox->GetFrameFormat()->GetTableBoxFormula().Clone();
2238  pFormula->PtrToBoxNm( &pTableNode->GetTable() );
2239  OutputField( nullptr, ww::eEquals, " =" + pFormula->GetFormula(),
2241  }
2242 
2243  const bool bKeep = rTable.GetFrameFormat()->GetKeep().GetValue();
2244  const bool bDontSplit = !rTable.GetFrameFormat()->GetLayoutSplit().GetValue();
2245  // bKeep handles this a different way later on, so ignore now
2246  if ( !bKeep && bDontSplit && rTable.GetTabLines().size() == 1 )
2247  {
2248  // bDontSplit : set don't split once for the row
2249  // but only for non-complex tables
2250  const SwTableLine* pLine = pBox ? pBox->GetUpper() : nullptr;
2251  if ( pLine && !pLine->GetUpper() )
2252  {
2253  // check if box is first in that line:
2254  if ( 0 == pLine->GetBoxPos( pBox ) && pBox->GetSttNd() )
2255  {
2256  // check if paragraph is first in that line:
2257  if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) )
2258  pLine->GetFrameFormat()->SetFormatAttr(SwFormatRowSplit(!bDontSplit));
2259  }
2260  }
2261  }
2262  }
2263  }
2264 
2265  SwSoftPageBreakList softBreakList;
2266  // Let's decide if we need to split the paragraph because of a section break
2267  bool bNeedParaSplit = NeedTextNodeSplit( rNode, softBreakList )
2268  && !IsInTable();
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  ++aBreakIt;
2278 
2279  AttrOutput().StartParagraph( pTextNodeInfo );
2280 
2281  const SwSection* pTOXSect = nullptr;
2282  if( m_bInWriteTOX )
2283  {
2284  // check for end of TOX
2285  SwNodeIndex aIdx( rNode, 1 );
2286  if( !aIdx.GetNode().IsTextNode() )
2287  {
2288  const SwSectionNode* pTOXSectNd = rNode.FindSectionNode();
2289  if ( pTOXSectNd )
2290  {
2291  pTOXSect = &pTOXSectNd->GetSection();
2292 
2293  const SwNode* pNxt = rNode.GetNodes().GoNext( &aIdx );
2294  if( pNxt && pNxt->FindSectionNode() == pTOXSectNd )
2295  pTOXSect = nullptr;
2296  }
2297  }
2298  }
2299 
2300  if ( aAttrIter.RequiresImplicitBookmark() )
2301  {
2302  OUString sBkmkName = "_toc" + OUString::number( rNode.GetIndex() );
2303  // Add a bookmark converted to a Word name.
2304  AppendBookmark( BookmarkToWord( sBkmkName ) );
2305  }
2306 
2307  // Call this before write out fields and runs
2308  AttrOutput().GenerateBookmarksForSequenceField(rNode, aAttrIter);
2309 
2310  const OUString& aStr( rNode.GetText() );
2311 
2312  sal_Int32 const nEnd = bNeedParaSplit ? *aBreakIt : aStr.getLength();
2313  bool bIncludeEndOfParaCRInRedlineProperties = false;
2314  sal_Int32 nOpenAttrWithRange = 0;
2315 
2316  ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner;
2317  if ( pTextNodeInfo )
2318  {
2319  pTextNodeInfoInner = pTextNodeInfo->getFirstInner();
2320  }
2321 
2322  do {
2323 
2324  const SwRedlineData* pRedlineData = aAttrIter.GetRunLevelRedline( nCurrentPos );
2325  FlyProcessingState nStateOfFlyFrame = FLY_PROCESSED;
2326  bool bPostponeWritingText = false ;
2327  OUString aSavedSnippet ;
2328 
2329  sal_Int32 nNextAttr = GetNextPos( &aAttrIter, rNode, nCurrentPos );
2330 
2331  // Skip un-exportable attributes.
2332  if (!aAttrIter.IsExportableAttr(nCurrentPos))
2333  {
2334  nCurrentPos = nNextAttr;
2335  UpdatePosition(&aAttrIter, nCurrentPos);
2336  eChrSet = aAttrIter.GetCharSet();
2337  continue;
2338  }
2339 
2340  // Is this the only run in this paragraph and it's empty?
2341  bool bSingleEmptyRun = nCurrentPos == 0 && nNextAttr == 0;
2342  AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun );
2343 
2344  if( nNextAttr > nEnd )
2345  nNextAttr = nEnd;
2346 
2347  if( m_nTextTyp == TXT_FTN || m_nTextTyp == TXT_EDN )
2348  {
2349  if( AttrOutput().FootnoteEndnoteRefTag() )
2350  {
2351  AttrOutput().EndRun( &rNode, nCurrentPos, nNextAttr == nEnd );
2352  AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun );
2353  }
2354  }
2355 
2356  /*
2357  1) If there is a text node and an overlapping anchor, then write them in two different
2358  runs and not as part of the same run.
2359  2) Ensure that it is a text node and not in a fly.
2360  3) If the anchor is associated with a text node with empty text then we ignore.
2361  */
2362  if( rNode.IsTextNode()
2363  && GetExportFormat() == MSWordExportBase::ExportFormat::DOCX
2364  && aStr != OUStringChar(CH_TXTATR_BREAKWORD) && !aStr.isEmpty()
2365  && !rNode.GetFlyFormat()
2366  && aAttrIter.IsAnchorLinkedToThisNode(rNode.GetIndex()) )
2367  {
2368  bPostponeWritingText = true ;
2369  }
2370 
2371  nStateOfFlyFrame = aAttrIter.OutFlys( nCurrentPos );
2372  AttrOutput().SetStateOfFlyFrame( nStateOfFlyFrame );
2373  AttrOutput().SetAnchorIsLinkedToNode( bPostponeWritingText && (FLY_POSTPONED != nStateOfFlyFrame) );
2374  // Append bookmarks in this range after flys, exclusive of final
2375  // position of this range
2376  AppendBookmarks( rNode, nCurrentPos, nNextAttr - nCurrentPos );
2377  // Sadly only possible for main or glossary document parts: ECMA-376 Part 1 sect. 11.3.2
2378  if ( m_nTextTyp == TXT_MAINTEXT )
2379  AppendAnnotationMarks(aAttrIter, nCurrentPos, nNextAttr - nCurrentPos);
2380 
2381  // At the moment smarttags are only written for paragraphs, at the
2382  // beginning of the paragraph.
2383  if (nCurrentPos == 0)
2384  AppendSmartTags(rNode);
2385 
2386  bool bTextAtr = aAttrIter.IsTextAttr( nCurrentPos );
2387  nOpenAttrWithRange += aAttrIter.OutAttrWithRange( rNode, nCurrentPos );
2388 
2389  sal_Int32 nLen = nNextAttr - nCurrentPos;
2390  if ( !bTextAtr && nLen )
2391  {
2392  sal_Unicode ch = aStr[nCurrentPos];
2393 
2394  const sal_Int32 ofs = (ch == CH_TXT_ATR_FIELDSTART
2395  || ch == CH_TXT_ATR_FIELDSEP
2396  || ch == CH_TXT_ATR_FIELDEND
2397  || ch == CH_TXT_ATR_FORMELEMENT)
2398  ? 1 : 0;
2399 
2400  IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess();
2401  if ( ch == CH_TXT_ATR_FIELDSTART )
2402  {
2403  SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
2404  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkAt(aPosition);
2405  assert(pFieldmark);
2406 
2407  // Date field is exported as content control, not as a simple field
2408  if (pFieldmark->GetFieldname() == ODF_FORMDATE)
2409  {
2410  if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
2411  {
2412  OutputField( nullptr, lcl_getFieldId( pFieldmark ),
2413  lcl_getFieldCode( pFieldmark ),
2415  WriteFormData( *pFieldmark );
2416  }
2417  }
2418  else
2419  {
2420 
2421  if (pFieldmark->GetFieldname() == ODF_FORMTEXT
2422  && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
2423  {
2424  AppendBookmark( pFieldmark->GetName() );
2425  }
2426  ww::eField eFieldId = lcl_getFieldId( pFieldmark );
2427  OUString sCode = lcl_getFieldCode( pFieldmark );
2428  if (pFieldmark->GetFieldname() == ODF_UNHANDLED )
2429  {
2430  IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
2431  if ( it != pFieldmark->GetParameters()->end() )
2432  {
2433  OUString sFieldId;
2434  it->second >>= sFieldId;
2435  eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
2436  }
2437 
2438  it = pFieldmark->GetParameters()->find( ODF_CODE_PARAM );
2439  if ( it != pFieldmark->GetParameters()->end() )
2440  {
2441  it->second >>= sCode;
2442  }
2443  }
2444 
2445  OutputField( nullptr, eFieldId, sCode, FieldFlags::Start | FieldFlags::CmdStart );
2446 
2447  if (pFieldmark->GetFieldname() == ODF_FORMTEXT)
2448  WriteFormData( *pFieldmark );
2449  else if (pFieldmark->GetFieldname() == ODF_HYPERLINK)
2450  WriteHyperlinkData( *pFieldmark );
2451  }
2452  }
2453  else if (ch == CH_TXT_ATR_FIELDSEP)
2454  {
2455  SwPosition aPosition(rNode, SwIndex(&rNode, nCurrentPos));
2456  // the innermost field is the correct one
2457  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkFor(aPosition);
2458  assert(pFieldmark);
2459  // DateFieldmark / ODF_FORMDATE is not a field...
2460  if (pFieldmark->GetFieldname() != ODF_FORMDATE)
2461  {
2462  OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::CmdEnd );
2463 
2464  if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
2465  {
2466  // Check for the presence of a linked OLE object
2467  IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_OLE_PARAM );
2468  if ( it != pFieldmark->GetParameters()->end() )
2469  {
2470  OUString sOleId;
2471  uno::Any aValue = it->second;
2472  aValue >>= sOleId;
2473  if ( !sOleId.isEmpty() )
2474  OutputLinkedOLE( sOleId );
2475  }
2476  }
2477  }
2478  }
2479  else if ( ch == CH_TXT_ATR_FIELDEND )
2480  {
2481  SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
2482  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkAt(aPosition);
2483 
2484  assert(pFieldmark);
2485 
2486  if (pFieldmark->GetFieldname() == ODF_FORMDATE)
2487  {
2488  if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
2489  {
2490  OutputField( nullptr, ww::eFORMDATE, OUString(), FieldFlags::Close );
2491  }
2492  }
2493  else
2494  {
2495  ww::eField eFieldId = lcl_getFieldId( pFieldmark );
2496  if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
2497  {
2498  IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
2499  if ( it != pFieldmark->GetParameters()->end() )
2500  {
2501  OUString sFieldId;
2502  it->second >>= sFieldId;
2503  eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
2504  }
2505  }
2506 
2507  OutputField( nullptr, eFieldId, OUString(), FieldFlags::Close );
2508 
2509  if (pFieldmark->GetFieldname() == ODF_FORMTEXT
2510  && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
2511  {
2512  AppendBookmark( pFieldmark->GetName() );
2513  }
2514  }
2515  }
2516  else if ( ch == CH_TXT_ATR_FORMELEMENT )
2517  {
2518  SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
2519  ::sw::mark::IFieldmark const*const pFieldmark = pMarkAccess->getFieldmarkAt(aPosition);
2520  assert(pFieldmark);
2521 
2522  bool const isDropdownOrCheckbox(pFieldmark->GetFieldname() == ODF_FORMDROPDOWN ||
2523  pFieldmark->GetFieldname() == ODF_FORMCHECKBOX);
2524  if ( isDropdownOrCheckbox )
2525  AppendBookmark( pFieldmark->GetName() );
2526  OutputField( nullptr, lcl_getFieldId( pFieldmark ),
2527  lcl_getFieldCode( pFieldmark ),
2529  if ( isDropdownOrCheckbox )
2530  WriteFormData( *pFieldmark );
2531  // tdf#129514 need CmdEnd for docx
2532  OutputField(nullptr, lcl_getFieldId(pFieldmark), OUString(),
2534  if ( isDropdownOrCheckbox )
2535  AppendBookmark( pFieldmark->GetName() );
2536  }
2537  nLen -= ofs;
2538 
2539  // if paragraph needs to be split, write only until split position
2540  assert(!bNeedParaSplit || nCurrentPos <= *aBreakIt);
2541  if( bNeedParaSplit && nCurrentPos + ofs + nLen > *aBreakIt)
2542  nLen = *aBreakIt - nCurrentPos - ofs;
2543  assert(0 <= nLen);
2544 
2545  OUString aSnippet( aAttrIter.GetSnippet( aStr, nCurrentPos + ofs, nLen ) );
2546  if ( ( m_nTextTyp == TXT_EDN || m_nTextTyp == TXT_FTN ) && nCurrentPos == 0 && nLen > 0 )
2547  {
2548  // Allow MSO to emulate LO footnote text starting at left margin - only meaningful with hanging indent
2549  sal_Int32 nFirstLineIndent=0;
2551  const SwTextNode* pTextNode( rNode.GetTextNode() );
2552  if ( pTextNode && pTextNode->GetAttr(aSet) )
2553  {
2554  const SvxLRSpaceItem* pLRSpace = aSet.GetItem<SvxLRSpaceItem>(RES_LR_SPACE);
2555  if ( pLRSpace )
2556  nFirstLineIndent = pLRSpace->GetTextFirstLineOffset();
2557  }
2558 
2559  // Insert tab for aesthetic purposes #i24762#
2560  if ( m_bAddFootnoteTab && nFirstLineIndent < 0 && aSnippet[0] != 0x09 )
2561  aSnippet = "\x09" + aSnippet;
2562  m_bAddFootnoteTab = false;
2563  }
2564 
2565  if ( bPostponeWritingText && ( FLY_POSTPONED != nStateOfFlyFrame ) )
2566  {
2567  bPostponeWritingText = true ;
2568  aSavedSnippet = aSnippet ;
2569  }
2570  else
2571  {
2572  bPostponeWritingText = false ;
2573  AttrOutput().RunText( aSnippet, eChrSet );
2574  }
2575  }
2576 
2577  if ( aAttrIter.IsDropCap( nNextAttr ) )
2578  AttrOutput().FormatDrop( rNode, aAttrIter.GetSwFormatDrop(), nStyle, pTextNodeInfo, pTextNodeInfoInner );
2579 
2580  // Only output character attributes if this is not a postponed text run.
2581  if (0 != nEnd && !(bPostponeWritingText && FLY_PROCESSED == nStateOfFlyFrame))
2582  {
2583  // Output the character attributes
2584  // #i51277# do this before writing flys at end of paragraph
2586  aAttrIter.OutAttr( nCurrentPos, false );
2587  AttrOutput().EndRunProperties( pRedlineData );
2588  }
2589 
2590  // At the end of line, output the attributes until the CR.
2591  // Exception: footnotes at the end of line
2592  if ( nNextAttr == nEnd )
2593  {
2594  OSL_ENSURE( nOpenAttrWithRange >= 0, "odd to see this happening, expected >= 0" );
2595  if ( !bTextAtr && nOpenAttrWithRange <= 0 )
2596  {
2597  if ( aAttrIter.IncludeEndOfParaCRInRedlineProperties( nEnd ) )
2598  bIncludeEndOfParaCRInRedlineProperties = true;
2599  else
2600  {
2601  // insert final graphic anchors if any before CR
2602  nStateOfFlyFrame = aAttrIter.OutFlys( nEnd );
2603  // insert final bookmarks if any before CR and after flys
2604  AppendBookmarks( rNode, nEnd, 1 );
2605  AppendAnnotationMarks(aAttrIter, nEnd, 1);
2606  if ( pTOXSect )
2607  {
2609  AttrOutput().EndTOX( *pTOXSect ,false);
2610  }
2611  //For i120928,the position of the bullet's graphic is at end of doc
2612  if (bLastCR && (!bExported))
2613  {
2614  ExportGrfBullet(rNode);
2615  bExported = true;
2616  }
2617 
2618  WriteCR( pTextNodeInfoInner );
2619  }
2620  }
2621  }
2622 
2623  if (0 == nEnd)
2624  {
2625  // Output the character attributes
2626  // do it after WriteCR for an empty paragraph (otherwise
2627  // WW8_WrFkp::Append throws SPRMs away...)
2629  aAttrIter.OutAttr( nCurrentPos, false );
2630  AttrOutput().EndRunProperties( pRedlineData );
2631  }
2632 
2633  // Exception: footnotes at the end of line
2634  if ( nNextAttr == nEnd )
2635  {
2636  OSL_ENSURE(nOpenAttrWithRange >= 0,
2637  "odd to see this happening, expected >= 0");
2638  bool bAttrWithRange = (nOpenAttrWithRange > 0);
2639  if ( nCurrentPos != nEnd )
2640  {
2641  nOpenAttrWithRange += aAttrIter.OutAttrWithRange( rNode, nEnd );
2642  OSL_ENSURE(nOpenAttrWithRange == 0,
2643  "odd to see this happening, expected 0");
2644  }
2645 
2646  // !bIncludeEndOfParaCRInRedlineProperties implies we have just
2647  // emitted a CR, in which case we want to pass force=true to
2648  // OutputFKP to ensure that an FKP entry for direct character
2649  // formatting is written even if empty, so that the next one will
2650  // start after the CR.
2651  AttrOutput().OutputFKP(!bIncludeEndOfParaCRInRedlineProperties);
2652 
2653  if (bTextAtr || bAttrWithRange || bIncludeEndOfParaCRInRedlineProperties)
2654  {
2655  // insert final graphic anchors if any before CR
2656  nStateOfFlyFrame = aAttrIter.OutFlys( nEnd );
2657  // insert final bookmarks if any before CR and after flys
2658  AppendBookmarks( rNode, nEnd, 1 );
2659  AppendAnnotationMarks(aAttrIter, nEnd, 1);
2660  WriteCR( pTextNodeInfoInner );
2661  // #i120928 - position of the bullet's graphic is at end of doc
2662  if (bLastCR && (!bExported))
2663  {
2664  ExportGrfBullet(rNode);
2665  bExported = true;
2666  }
2667 
2668  if ( pTOXSect )
2669  {
2671  AttrOutput().EndTOX( *pTOXSect );
2672  }
2673 
2674  if (bIncludeEndOfParaCRInRedlineProperties)
2675  {
2676  AttrOutput().Redline( aAttrIter.GetRunLevelRedline( nEnd ) );
2677  //If there was no redline property emitted, force adding
2678  //another entry for the CR so that in the case that this
2679  //has no redline, but the next para does, then this one is
2680  //not merged with the next
2681  AttrOutput().OutputFKP(true);
2682  }
2683  }
2684  }
2685 
2687 
2688  if( bPostponeWritingText && FLY_PROCESSED == nStateOfFlyFrame )
2689  {
2690  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2691  //write the postponed text run
2692  AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun );
2695  if (0 != nEnd)
2696  {
2698  aAttrIter.OutAttr( nCurrentPos, false );
2699  AttrOutput().EndRunProperties( pRedlineData );
2700  }
2701  AttrOutput().RunText( aSavedSnippet, eChrSet );
2702  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2703  }
2704  else if( bPostponeWritingText && !aSavedSnippet.isEmpty() )
2705  {
2706  //write the postponed text run
2707  AttrOutput().RunText( aSavedSnippet, eChrSet );
2708  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2709  }
2710  else
2711  AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd);
2712 
2713  nCurrentPos = nNextAttr;
2714  UpdatePosition( &aAttrIter, nCurrentPos );
2715  eChrSet = aAttrIter.GetCharSet();
2716  }
2717  while ( nCurrentPos < nEnd );
2718 
2719  // if paragraph is split, put the section break between the parts
2720  if( bNeedParaSplit && *aBreakIt != rNode.GetText().getLength() )
2721  {
2722  const SwPageDesc* pNextPageDesc = m_pCurrentPageDesc->GetFollow();
2723  assert(pNextPageDesc);
2724  PrepareNewPageDesc( rNode.GetpSwAttrSet(), rNode, nullptr , pNextPageDesc);
2725  }
2726  else if (!bNeedParaSplit)
2727  {
2728  // else check if section break needed after the paragraph
2729  AttrOutput().SectionBreaks(rNode);
2730  }
2731 
2733 
2734  AttrOutput().ParagraphStyle( nStyle );
2735 
2736  if ( m_pParentFrame && IsInTable() ) // Fly-Attrs
2737  OutputFormat( m_pParentFrame->GetFrameFormat(), false, false, true );
2738 
2739  if ( pTextNodeInfo )
2740  {
2741 #ifdef DBG_UTIL
2742  SAL_INFO( "sw.ww8", pTextNodeInfo->toString());
2743 #endif
2744 
2745  AttrOutput().TableInfoCell( pTextNodeInfoInner );
2746  if (pTextNodeInfoInner->isFirstInTable())
2747  {
2748  const SwTable * pTable = pTextNodeInfoInner->getTable();
2749 
2750  const SwTableFormat* pTabFormat = pTable->GetFrameFormat();
2751  if (pTabFormat != nullptr)
2752  {
2753  if (pTabFormat->GetBreak().GetBreak() == SvxBreak::PageBefore)
2754  AttrOutput().PageBreakBefore(true);
2755  }
2756  }
2757  }
2758 
2759  if ( !bFlyInTable )
2760  {
2761  SfxItemSet* pTmpSet = nullptr;
2762  const sal_uInt8 nPrvNxtNd = rNode.HasPrevNextLayNode();
2763 
2764  if( (ND_HAS_PREV_LAYNODE|ND_HAS_NEXT_LAYNODE ) != nPrvNxtNd )
2765  {
2766  const SfxPoolItem* pItem;
2767  if( SfxItemState::SET == rNode.GetSwAttrSet().GetItemState(
2768  RES_UL_SPACE, true, &pItem ) &&
2769  ( ( !( ND_HAS_PREV_LAYNODE & nPrvNxtNd ) &&
2770  static_cast<const SvxULSpaceItem*>(pItem)->GetUpper()) ||
2771  ( !( ND_HAS_NEXT_LAYNODE & nPrvNxtNd ) &&
2772  static_cast<const SvxULSpaceItem*>(pItem)->GetLower()) ))
2773  {
2774  pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
2775  SvxULSpaceItem aUL( *static_cast<const SvxULSpaceItem*>(pItem) );
2776  // #i25901#- consider compatibility option
2778  {
2779  if( !(ND_HAS_PREV_LAYNODE & nPrvNxtNd ))
2780  aUL.SetUpper( 0 );
2781  }
2782  // #i25901# - consider compatibility option
2784  {
2785  if( !(ND_HAS_NEXT_LAYNODE & nPrvNxtNd ))
2786  aUL.SetLower( 0 );
2787  }
2788  pTmpSet->Put( aUL );
2789  }
2790  }
2791 
2792  const bool bParaRTL = aAttrIter.IsParaRTL();
2793 
2794  int nNumberLevel = -1;
2795  if (rNode.IsNumbered())
2796  nNumberLevel = rNode.GetActualListLevel();
2797  if (nNumberLevel >= 0 && nNumberLevel < MAXLEVEL)
2798  {
2799  const SwNumRule* pRule = rNode.GetNumRule();
2800  sal_uInt8 nLvl = static_cast< sal_uInt8 >(nNumberLevel);
2801  const SwNumFormat* pFormat = pRule->GetNumFormat( nLvl );
2802  if( !pFormat )
2803  pFormat = &pRule->Get( nLvl );
2804 
2805  if( !pTmpSet )
2806  pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
2807 
2808  SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*pTmpSet, RES_LR_SPACE));
2809  // #i86652#
2810  if ( pFormat->GetPositionAndSpaceMode() ==
2812  {
2813  aLR.SetTextLeft( aLR.GetTextLeft() + pFormat->GetAbsLSpace() );
2814  }
2815 
2816  if( rNode.IsNumbered() && rNode.IsCountedInList() )
2817  {
2818  // #i86652#
2819  if ( pFormat->GetPositionAndSpaceMode() ==
2821  {
2822  if (bParaRTL)
2823  {
2824  aLR.SetTextFirstLineOffsetValue(aLR.GetTextFirstLineOffset() + pFormat->GetAbsLSpace() - pFormat->GetFirstLineOffset()); //TODO: overflow
2825  }
2826  else
2827  {
2828  aLR.SetTextFirstLineOffset(aLR.GetTextFirstLineOffset() + GetWordFirstLineOffset(*pFormat));
2829  }
2830  }
2831 
2832  // correct fix for issue i94187
2833  if (SfxItemState::SET !=
2834  pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2835  {
2836  // List style set via paragraph style - then put it into the itemset.
2837  // This is needed to get list level and list id exported for
2838  // the paragraph.
2839  pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
2840 
2841  // Put indent values into the itemset in case that the list
2842  // style is applied via paragraph style and the list level
2843  // indent values are not applicable.
2844  if ( pFormat->GetPositionAndSpaceMode() ==
2847  {
2848  pTmpSet->Put( aLR );
2849  }
2850  }
2851  }
2852  else
2853  pTmpSet->ClearItem(RES_PARATR_NUMRULE);
2854 
2855  // #i86652#
2856  if ( pFormat->GetPositionAndSpaceMode() ==
2858  {
2859  pTmpSet->Put(aLR);
2860 
2861  //#i21847#
2862  SvxTabStopItem aItem(
2863  ItemGet<SvxTabStopItem>(*pTmpSet, RES_PARATR_TABSTOP));
2864  SvxTabStop aTabStop(pFormat->GetAbsLSpace());
2865  aItem.Insert(aTabStop);
2866  pTmpSet->Put(aItem);
2867 
2869  }
2870  }
2871 
2872  /*
2873  If a given para is using the SvxFrameDirection::Environment direction we
2874  cannot export that, if it's ltr then that's ok as that is word's
2875  default. Otherwise we must add a RTL attribute to our export list
2876  Only necessary if the ParaStyle doesn't define the direction.
2877  */
2878  const SvxFrameDirectionItem* pItem =
2880  if (
2881  (!pItem || pItem->GetValue() == SvxFrameDirection::Environment) &&
2882  rTextColl.GetFrameDir().GetValue() == SvxFrameDirection::Environment
2883  )
2884  {
2885  if ( !pTmpSet )
2886  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2887 
2888  if ( bParaRTL )
2889  pTmpSet->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_RL_TB, RES_FRAMEDIR));
2890  else
2891  pTmpSet->Put(SvxFrameDirectionItem(SvxFrameDirection::Horizontal_LR_TB, RES_FRAMEDIR));
2892 
2893  const SvxAdjustItem* pAdjust = rNode.GetSwAttrSet().GetItem(RES_PARATR_ADJUST);
2894  if ( pAdjust && (pAdjust->GetAdjust() == SvxAdjust::Left || pAdjust->GetAdjust() == SvxAdjust::Right ) )
2895  pTmpSet->Put( *pAdjust, RES_PARATR_ADJUST );
2896  }
2897  // move code for handling of numbered,
2898  // but not counted paragraphs to this place. Otherwise, the paragraph
2899  // isn't exported as numbered, but not counted, if no other attribute
2900  // is found in <pTmpSet>
2901  // #i44815# adjust numbering/indents for numbered paragraphs
2902  // without number (NO_NUMLEVEL)
2903  // #i47013# need to check rNode.GetNumRule()!=NULL as well.
2904  if ( ! rNode.IsCountedInList() && rNode.GetNumRule()!=nullptr )
2905  {
2906  // WW8 does not know numbered paragraphs without number
2907  // (NO_NUMLEVEL). In WW8AttributeOutput::ParaNumRule(), we will export
2908  // the RES_PARATR_NUMRULE as list-id 0, which in WW8 means
2909  // no numbering. Here, we will adjust the indents to match
2910  // visually.
2911 
2912  if ( !pTmpSet )
2913  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2914 
2915  // create new LRSpace item, based on the current (if present)
2916  const SfxPoolItem* pPoolItem = nullptr;
2917  pTmpSet->GetItemState(RES_LR_SPACE, true, &pPoolItem);
2918  SvxLRSpaceItem aLRSpace(
2919  ( pPoolItem == nullptr )
2920  ? SvxLRSpaceItem(0, 0, 0, 0, RES_LR_SPACE)
2921  : *static_cast<const SvxLRSpaceItem*>( pPoolItem ) );
2922 
2923  // new left margin = old left + label space
2924  const SwNumRule* pRule = rNode.GetNumRule();
2925  int nLevel = rNode.GetActualListLevel();
2926 
2927  if (nLevel < 0)
2928  nLevel = 0;
2929 
2930  if (nLevel >= MAXLEVEL)
2931  nLevel = MAXLEVEL - 1;
2932 
2933  const SwNumFormat& rNumFormat = pRule->Get( static_cast< sal_uInt16 >(nLevel) );
2934 
2935  // #i86652#
2936  if ( rNumFormat.GetPositionAndSpaceMode() ==
2938  {
2939  aLRSpace.SetTextLeft( aLRSpace.GetLeft() + rNumFormat.GetAbsLSpace() );
2940  }
2941  else
2942  {
2943  aLRSpace.SetTextLeft( aLRSpace.GetLeft() + rNumFormat.GetIndentAt() );
2944  }
2945 
2946  // new first line indent = 0
2947  // (first line indent is ignored for NO_NUMLEVEL)
2948  if (!bParaRTL)
2949  aLRSpace.SetTextFirstLineOffset( 0 );
2950 
2951  // put back the new item
2952  pTmpSet->Put( aLRSpace );
2953 
2954  // assure that numbering rule is in <pTmpSet>
2955  if (SfxItemState::SET != pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2956  {
2957  pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
2958  }
2959  }
2960 
2961  // #i75457#
2962  // Export page break after attribute from paragraph style.
2963  // If page break attribute at the text node exist, an existing page
2964  // break after at the paragraph style hasn't got to be considered.
2965  if ( !rNode.GetpSwAttrSet() ||
2966  SfxItemState::SET != rNode.GetpSwAttrSet()->GetItemState(RES_BREAK, false) )
2967  {
2968  const SvxFormatBreakItem& rBreakAtParaStyle
2969  = ItemGet<SvxFormatBreakItem>(rNode.GetSwAttrSet(), RES_BREAK);
2970  if (rBreakAtParaStyle.GetBreak() == SvxBreak::PageAfter)
2971  {
2972  if ( !pTmpSet )
2973  {
2974  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2975  }
2976  pTmpSet->Put(rBreakAtParaStyle);
2977  }
2978  else if( pTmpSet )
2979  { // Even a pagedesc item is set, the break item can be set 'NONE',
2980  // this has to be overruled.
2981  const SwFormatPageDesc& rPageDescAtParaStyle =
2982  ItemGet<SwFormatPageDesc>( rNode, RES_PAGEDESC );
2983  if( rPageDescAtParaStyle.KnowsPageDesc() )
2984  pTmpSet->ClearItem( RES_BREAK );
2985  }
2986  }
2987 
2988  // #i76520# Emulate non-splitting tables
2989  if ( IsInTable() )
2990  {
2991  const SwTableNode* pTableNode = rNode.FindTableNode();
2992 
2993  if ( pTableNode )
2994  {
2995  const SwTable& rTable = pTableNode->GetTable();
2996  const SvxFormatKeepItem& rKeep = rTable.GetFrameFormat()->GetKeep();
2997  const bool bKeep = rKeep.GetValue();
2998  const bool bDontSplit = !(bKeep ||
2999  rTable.GetFrameFormat()->GetLayoutSplit().GetValue());
3000 
3001  if ( bKeep || bDontSplit )
3002  {
3003  // bKeep: set keep at first paragraphs in all lines
3004  // bDontSplit : set keep at first paragraphs in all lines except from last line
3005  // but only for non-complex tables
3006  const SwTableBox* pBox = rNode.GetTableBox();
3007  const SwTableLine* pLine = pBox ? pBox->GetUpper() : nullptr;
3008 
3009  if ( pLine && !pLine->GetUpper() )
3010  {
3011  // check if box is first in that line:
3012  if ( 0 == pLine->GetBoxPos( pBox ) && pBox->GetSttNd() )
3013  {
3014  // check if paragraph is first in that line:
3015  if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) )
3016  {
3017  bool bSetAtPara = false;
3018  if ( bKeep )
3019  bSetAtPara = true;
3020  else if ( bDontSplit )
3021  {
3022  // check if pLine isn't last line in table
3023  if ( rTable.GetTabLines().size() - rTable.GetTabLines().GetPos( pLine ) != 1 )
3024  bSetAtPara = true;
3025  }
3026 
3027  if ( bSetAtPara )
3028  {
3029  if ( !pTmpSet )
3030  pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
3031 
3032  const SvxFormatKeepItem aKeepItem( true, RES_KEEP );
3033  pTmpSet->Put( aKeepItem );
3034  }
3035  }
3036  }
3037  }
3038  }
3039  }
3040  }
3041 
3042  const SfxItemSet* pNewSet = pTmpSet ? pTmpSet : rNode.GetpSwAttrSet();
3043  if( pNewSet )
3044  { // Para-Attrs
3045  m_pStyAttr = &rNode.GetAnyFormatColl().GetAttrSet();
3046 
3047  const SwModify* pOldMod = m_pOutFormatNode;
3048  m_pOutFormatNode = &rNode;
3049 
3050  // Pap-Attrs, so script is not necessary
3051  OutputItemSet( *pNewSet, true, false, i18n::ScriptType::LATIN, false);
3052 
3053  m_pStyAttr = nullptr;
3054  m_pOutFormatNode = pOldMod;
3055 
3056  if( pNewSet != rNode.GetpSwAttrSet() )
3057  delete pNewSet;
3058  }
3059  }
3060 
3061  // The formatting of the paragraph marker has two sources:
3062  // 0) If there is a RES_PARATR_LIST_AUTOFMT, then use that.
3063  // 1) If there are hints at the end of the paragraph, then use that.
3064  // 2) Else use the RES_CHRATR_BEGIN..RES_TXTATR_END range of the paragraph
3065  // properties.
3066  //
3067  // Exception: if there is a character style hint at the end of the
3068  // paragraph only, then still go with 2), as RES_TXTATR_CHARFMT is always
3069  // set as a hint.
3071  bool bCharFormatOnly = true;
3072 
3073  SwFormatAutoFormat const& rListAutoFormat(static_cast<SwFormatAutoFormat const&>(rNode.GetAttr(RES_PARATR_LIST_AUTOFMT)));
3074  if (std::shared_ptr<SfxItemSet> const& pSet = rListAutoFormat.GetStyleHandle())
3075  {
3076  aParagraphMarkerProperties.Put(*pSet);
3077  bCharFormatOnly = false;
3078  }
3079  else if (const SwpHints* pTextAttrs = rNode.GetpSwpHints())
3080  {
3081  for( size_t i = 0; i < pTextAttrs->Count(); ++i )
3082  {
3083  const SwTextAttr* pHt = pTextAttrs->Get(i);
3084  const sal_Int32 startPos = pHt->GetStart(); // first Attr characters
3085  const sal_Int32* endPos = pHt->End(); // end Attr characters
3086  // Check if these attributes are for the last character in the paragraph
3087  // - which means the paragraph marker. If a paragraph has 7 characters,
3088  // then properties on character 8 are for the paragraph marker
3089  if( endPos && (startPos == *endPos ) && (*endPos == rNode.GetText().getLength()) )
3090  {
3091  SAL_INFO( "sw.ww8", startPos << "startPos == endPos" << *endPos);
3092  sal_uInt16 nWhich = pHt->GetAttr().Which();
3093  SAL_INFO( "sw.ww8", "nWhich" << nWhich);
3094  if ((nWhich == RES_TXTATR_AUTOFMT && bCharFormatOnly)
3095  || nWhich == RES_TXTATR_CHARFMT)
3096  {
3097  aParagraphMarkerProperties.Put(pHt->GetAttr());
3098  }
3099  if (nWhich != RES_TXTATR_CHARFMT)
3100  bCharFormatOnly = false;
3101  }
3102  }
3103  }
3104  if (rNode.GetpSwAttrSet() && bCharFormatOnly)
3105  {
3106  aParagraphMarkerProperties.Put(*rNode.GetpSwAttrSet());
3107  }
3108  const SwRedlineData* pRedlineParagraphMarkerDelete = AttrOutput().GetParagraphMarkerRedline( rNode, RedlineType::Delete );
3109  const SwRedlineData* pRedlineParagraphMarkerInsert = AttrOutput().GetParagraphMarkerRedline( rNode, RedlineType::Insert );
3110  const SwRedlineData* pParagraphRedlineData = aAttrIter.GetParagraphLevelRedline( );
3111  AttrOutput().EndParagraphProperties(aParagraphMarkerProperties, pParagraphRedlineData, pRedlineParagraphMarkerDelete, pRedlineParagraphMarkerInsert);
3112 
3113  AttrOutput().EndParagraph( pTextNodeInfoInner );
3114  }while(*aBreakIt != rNode.GetText().getLength() && bNeedParaSplit );
3115 
3116  SAL_INFO( "sw.ww8", "</OutWW8_SwTextNode>" );
3117 }
3118 
3119 // Tables
3120 
3122 {
3123  m_rWW8Export.WriteStringAsPara( OUString() );
3124 }
3125 
3127 {
3128  bool bRet = false;
3129  const SfxPoolItem* pI;
3130  if( pSet)
3131  {
3132  bool bNoPageBreak = false;
3133  if ( SfxItemState::SET != pSet->GetItemState(RES_PAGEDESC, true, &pI)
3134  || nullptr == static_cast<const SwFormatPageDesc*>(pI)->GetPageDesc() )
3135  {
3136  bNoPageBreak = true;
3137  }
3138 
3139  if (bNoPageBreak)
3140  {
3141  if (SfxItemState::SET == pSet->GetItemState(RES_BREAK, true, &pI))
3142  {
3143  SvxBreak eBreak = static_cast<const SvxFormatBreakItem*>(pI)->GetBreak();
3144  switch (eBreak)
3145  {
3146  case SvxBreak::PageBefore:
3147  case SvxBreak::PageAfter:
3148  bNoPageBreak = false;
3149  break;
3150  default:
3151  break;
3152  }
3153  }
3154  }
3155  bRet = bNoPageBreak;
3156  }
3157  return bRet;
3158 }
3159 
3161 {
3162  const SwSection& rSection = rSectionNode.GetSection();
3163 
3164  SwNodeIndex aIdx( rSectionNode, 1 );
3165  const SwNode& rNd = aIdx.GetNode();
3166  if ( !rNd.IsSectionNode() && !IsInTable() ) //No sections in table
3167  {
3168  // if the first Node inside the section has an own
3169  // PageDesc or PageBreak attribute, then don't write
3170  // here the section break
3171  sal_uLong nRstLnNum = 0;
3172  const SfxItemSet* pSet;
3173  if ( rNd.IsContentNode() )
3174  {
3175  pSet = &rNd.GetContentNode()->GetSwAttrSet();
3176  nRstLnNum = pSet->Get( RES_LINENUMBER ).GetStartValue();
3177  }
3178  else
3179  pSet = nullptr;
3180 
3181  if ( pSet && NoPageBreakSection( pSet ) )
3182  pSet = nullptr;
3183  else
3184  AttrOutput().SectionBreaks( rSectionNode );
3185 
3186  const bool bInTOX = rSection.GetType() == SectionType::ToxContent || rSection.GetType() == SectionType::ToxHeader;
3187  if ( !pSet && !bInTOX )
3188  {
3189  // new Section with no own PageDesc/-Break
3190  // -> write follow section break;
3191  const SwSectionFormat* pFormat = rSection.GetFormat();
3192  ReplaceCr( msword::PageBreak ); // Indicator for Page/Section-Break
3193 
3194  // Get the page in use at the top of this section
3195  const SwPageDesc *pCurrent = SwPageDesc::GetPageDescOfNode(rNd);
3196  if (!pCurrent)
3197  pCurrent = m_pCurrentPageDesc;
3198 
3199  AppendSection( pCurrent, pFormat, nRstLnNum );
3200  }
3201  }
3202  if ( SectionType::ToxContent == rSection.GetType() )
3203  {
3204  m_bStartTOX = true;
3205  UpdateTocSectionNodeProperties(rSectionNode);
3206  }
3207 }
3208 
3209 // tdf#121561: During export of the ODT file with TOC inside into DOCX format,
3210 // the TOC title is being exported as regular paragraph. We should surround it
3211 // with <w:sdt><w:sdtPr><w:sdtContent> to make it (TOC title) recognizable
3212 // by MS Word as part of the TOC.
3214 {
3215  // check section type
3216  {
3217  const SwSection& rSection = rSectionNode.GetSection();
3218  if (SectionType::ToxContent != rSection.GetType())
3219  return;
3220 
3221  const SwTOXBase* pTOX = rSection.GetTOXBase();
3222  if (pTOX)
3223  {
3224  TOXTypes type = pTOX->GetType();
3225  if (type != TOXTypes::TOX_CONTENT)
3226  return;
3227  }
3228  }
3229 
3230  // get section node, skip toc-header node
3231  const SwSectionNode* pSectNd = &rSectionNode;
3232  {
3233  SwNodeIndex aIdxNext( *pSectNd, 1 );
3234  const SwNode& rNdNext = aIdxNext.GetNode();
3235 
3236  if (rNdNext.IsSectionNode())
3237  {
3238  const SwSectionNode* pSectNdNext = static_cast<const SwSectionNode*>(&rNdNext);
3239  if (SectionType::ToxHeader == pSectNdNext->GetSection().GetType() &&
3240  pSectNdNext->StartOfSectionNode()->IsSectionNode())
3241  {
3242  pSectNd = pSectNdNext;
3243  }
3244  }
3245  }
3246 
3247  // get node of the first paragraph inside TOC
3248  SwNodeIndex aIdxNext( *pSectNd, 1 );
3249  const SwNode& rNdTocPara = aIdxNext.GetNode();
3250  const SwContentNode* pNode = rNdTocPara.GetContentNode();
3251  if (!pNode)
3252  return;
3253 
3254  // put required flags into grab bag of the first node in TOC
3255  {
3256  uno::Sequence<beans::PropertyValue> aDocPropertyValues(comphelper::InitPropertySequence(
3257  {
3258  {"ooxml:CT_SdtDocPart_docPartGallery", uno::makeAny(OUString("Table of Contents"))},
3259  {"ooxml:CT_SdtDocPart_docPartUnique", uno::makeAny(OUString("true"))},
3260  }));
3261 
3262  uno::Sequence<beans::PropertyValue> aSdtPrPropertyValues(comphelper::InitPropertySequence(
3263  {
3264  {"ooxml:CT_SdtPr_docPartObj", uno::makeAny(aDocPropertyValues)},
3265  }));
3266 
3268  aGrabBag.GetGrabBag()["SdtPr"] <<= aSdtPrPropertyValues;
3269 
3270  // create temp attr set
3271  SwAttrSet aSet(pNode->GetSwAttrSet());
3272  aSet.Put(aGrabBag);
3273 
3274  // set new attr to node
3275  const_cast<SwContentNode*>(pNode)->SetAttr(aSet);
3276  }
3277 
3278  // set flag for the next node after TOC
3279  // in order to indicate that std area has been finished
3280  // see, DomainMapper::lcl_startParagraphGroup() for the same functionality during load
3281  {
3282  SwNodeIndex aEndTocNext( *rSectionNode.EndOfSectionNode(), 1 );
3283  const SwNode& rEndTocNextNode = aEndTocNext.GetNode();
3284  const SwContentNode* pNodeAfterToc = rEndTocNextNode.GetContentNode();
3285  if (pNodeAfterToc)
3286  {
3288  aGrabBag.GetGrabBag()["ParaSdtEndBefore"] <<= true;
3289 
3290  // create temp attr set
3291  SwAttrSet aSet(pNodeAfterToc->GetSwAttrSet());
3292  aSet.Put(aGrabBag);
3293 
3294  // set new attr to node
3295  const_cast<SwContentNode*>(pNodeAfterToc)->SetAttr(aSet);
3296  }
3297  }
3298 }
3299 
3300 void WW8Export::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFormat* pFormat, sal_uLong nLnNum )
3301 {
3302  pSepx->AppendSep(Fc2Cp(Strm().Tell()), pPageDesc, pFormat, nLnNum);
3303 }
3304 
3305 // Flys
3306 
3307 void WW8AttributeOutput::OutputFlyFrame_Impl( const ww8::Frame& rFormat, const Point& rNdTopLeft )
3308 {
3309  const SwFrameFormat &rFrameFormat = rFormat.GetFrameFormat();
3310  const SwFormatAnchor& rAnch = rFrameFormat.GetAnchor();
3311 
3312  bool bUseEscher = true;
3313 
3314  if (rFormat.IsInline())
3315  {
3317  bUseEscher = eType != ww8::Frame::eGraphic && eType != ww8::Frame::eOle;
3318 
3319  /*
3320  A special case for converting some inline form controls to form fields
3321  when in winword 8+ mode
3322  */
3323  if (bUseEscher && (eType == ww8::Frame::eFormControl))
3324  {
3325  if ( m_rWW8Export.MiserableFormFieldExportHack( rFrameFormat ) )
3326  return ;
3327  }
3328  }
3329 
3330  if (bUseEscher)
3331  {
3332  // write as escher
3333  m_rWW8Export.AppendFlyInFlys(rFormat, rNdTopLeft);
3334  }
3335  else
3336  {
3337  bool bDone = false;
3338 
3339  // Fetch from node and last node the position in the section
3340  const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
3341 
3342  sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1 : 0;
3343  sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
3344 
3345  if( nStt >= nEnd ) // no range, hence no valid node
3346  return;
3347 
3348  if ( !m_rWW8Export.IsInTable() && rFormat.IsInline() )
3349  {
3350  //Test to see if this textbox contains only a single graphic/ole
3351  SwTextNode* pParTextNode = rAnch.GetContentAnchor()->nNode.GetNode().GetTextNode();
3352  if ( pParTextNode && !m_rWW8Export.m_pDoc->GetNodes()[ nStt ]->IsNoTextNode() )
3353  bDone = true;
3354  }
3355  if( !bDone )
3356  {
3357 
3358  m_rWW8Export.SaveData( nStt, nEnd );
3359 
3360  Point aOffset;
3362  {
3363  /* Munge flys in fly into absolutely positioned elements for word 6 */
3364  const SwTextNode* pParTextNode = rAnch.GetContentAnchor()->nNode.GetNode().GetTextNode();
3365  const SwRect aPageRect = pParTextNode->FindPageFrameRect();
3366 
3367  aOffset = rFrameFormat.FindLayoutRect().Pos();
3368  aOffset -= aPageRect.Pos();
3369 
3370  m_rWW8Export.m_pFlyOffset = &aOffset;
3371  m_rWW8Export.m_eNewAnchorType = RndStdIds::FLY_AT_PAGE;
3372  }
3373 
3374  m_rWW8Export.m_pParentFrame = &rFormat;
3375  if (
3376  m_rWW8Export.IsInTable() &&
3377  (RndStdIds::FLY_AT_PAGE != rAnch.GetAnchorId()) &&
3378  !m_rWW8Export.m_pDoc->GetNodes()[ nStt ]->IsNoTextNode()
3379  )
3380  {
3381  // note: set Flag bOutTable again,
3382  // because we deliver the normal content of the table cell, and no border
3383  // ( Flag was deleted above in aSaveData() )
3384  m_rWW8Export.m_bOutTable = true;
3385  const OUString& aName = rFrameFormat.GetName();
3389  }
3390  else
3392 
3394  }
3395  }
3396 }
3397 
3399 {
3400  if ( !rFormat.GetContentNode() )
3401  return;
3402 
3403  const SwContentNode &rNode = *rFormat.GetContentNode();
3404  Point aLayPos;
3405 
3406  // get the Layout Node-Position
3407  if (RndStdIds::FLY_AT_PAGE == rFormat.GetFrameFormat().GetAnchor().GetAnchorId())
3408  aLayPos = rNode.FindPageFrameRect().Pos();
3409  else
3410  aLayPos = rNode.FindLayoutRect().Pos();
3411 
3412  OutputFlyFrame_Impl( rFormat, aLayPos );
3413 }
3414 
3415 // write data of any redline
3417 {
3418  if ( !pRedline )
3419  return;
3420 
3421  if ( pRedline->Next() )
3422  Redline( pRedline->Next() );
3423 
3424  static const sal_uInt16 insSprmIds[ 3 ] =
3425  {
3426  // Ids for insert // for WW8
3428  };
3429  static const sal_uInt16 delSprmIds[ 3 ] =
3430  {
3431  // Ids for delete // for WW8
3433  };
3434 
3435  const sal_uInt16* pSprmIds = nullptr;
3436  switch( pRedline->GetType() )
3437  {
3438  case RedlineType::Insert:
3439  pSprmIds = insSprmIds;
3440  break;
3441 
3442  case RedlineType::Delete:
3443  pSprmIds = delSprmIds;
3444  break;
3445 
3446  case RedlineType::Format:
3448  m_rWW8Export.pO->push_back( 7 ); // len
3449  m_rWW8Export.pO->push_back( 1 );
3452  break;
3453  default:
3454  OSL_ENSURE(false, "Unhandled redline type for export");
3455  break;
3456  }
3457 
3458  if ( pSprmIds )
3459  {
3460  m_rWW8Export.InsUInt16( pSprmIds[0] );
3461  m_rWW8Export.pO->push_back( 1 );
3462 
3463  m_rWW8Export.InsUInt16( pSprmIds[1] );
3465 
3466  m_rWW8Export.InsUInt16( pSprmIds[2] );
3468  }
3469 }
3470 
3472 {
3473  switch ( rNode.GetNodeType() )
3474  {
3475  case SwNodeType::Text:
3476  OutputTextNode( *rNode.GetTextNode() );
3477  break;
3478  case SwNodeType::Grf:
3479  OutputGrfNode( *rNode.GetGrfNode() );
3480  break;
3481  case SwNodeType::Ole:
3482  OutputOLENode( *rNode.GetOLENode() );
3483  break;
3484  default:
3485  SAL_WARN("sw.ww8", "Unhandled node, type == " << static_cast<int>(rNode.GetNodeType()) );
3486  break;
3487  }
3488 }
3489 
3490 
3491 WW8Ruby::WW8Ruby(const SwTextNode& rNode, const SwFormatRuby& rRuby, const MSWordExportBase& rExport ):
3492  m_nJC(0),
3493  m_cDirective(0),
3494  m_nRubyHeight(0),
3495  m_nBaseHeight(0)
3496 {
3497  switch ( rRuby.GetAdjustment() )
3498  {
3499  case css::text::RubyAdjust_LEFT:
3500  m_nJC = 3;
3501  m_cDirective = 'l';
3502  break;
3503  case css::text::RubyAdjust_CENTER:
3504  //defaults to 0
3505  break;
3506  case css::text::RubyAdjust_RIGHT:
3507  m_nJC = 4;
3508  m_cDirective = 'r';
3509  break;
3510  case css::text::RubyAdjust_BLOCK:
3511  m_nJC = 1;
3512  m_cDirective = 'd';
3513  break;
3514  case css::text::RubyAdjust_INDENT_BLOCK:
3515  m_nJC = 2;
3516  m_cDirective = 'd';
3517  break;
3518  default:
3519  OSL_ENSURE( false,"Unhandled Ruby justification code" );
3520  break;
3521  }
3522 
3523  if ( rRuby.GetPosition() == css::text::RubyPosition::INTER_CHARACTER )
3524  {
3525  m_nJC = 5;
3526  m_cDirective = 0;
3527  }
3528 
3529  /*
3530  MS needs to know the name and size of the font used in the ruby item,
3531  but we could have written it in a mixture of asian and western
3532  scripts, and each of these can be a different font and size than the
3533  other, so we make a guess based upon the first character of the text,
3534  defaulting to asian.
3535  */
3537  sal_uInt16 nRubyScript = g_pBreakIt->GetBreakIter()->getScriptType(rRuby.GetText(), 0);
3538 
3539  const SwTextRuby* pRubyText = rRuby.GetTextRuby();
3540  const SwCharFormat* pFormat = pRubyText ? pRubyText->GetCharFormat() : nullptr;
3541 
3542  if (pFormat)
3543  {
3544  const auto& rFont
3545  = ItemGet<SvxFontItem>(*pFormat, GetWhichOfScript(RES_CHRATR_FONT, nRubyScript));
3546  m_sFontFamily = rFont.GetFamilyName();
3547 
3548  const auto& rHeight = ItemGet<SvxFontHeightItem>(
3549  *pFormat, GetWhichOfScript(RES_CHRATR_FONTSIZE, nRubyScript));
3550  m_nRubyHeight = rHeight.GetHeight();
3551  }
3552  else
3553  {
3554  /*Get defaults if no formatting on ruby text*/
3555 
3556  const SfxItemPool* pPool = rNode.GetSwAttrSet().GetPool();
3557  pPool = pPool ? pPool : &rExport.m_pDoc->GetAttrPool();
3558 
3559 
3560  const auto& rFont
3561  = DefaultItemGet<SvxFontItem>(*pPool, GetWhichOfScript(RES_CHRATR_FONT, nRubyScript));
3562  m_sFontFamily = rFont.GetFamilyName();
3563 
3564  const auto& rHeight = DefaultItemGet<SvxFontHeightItem>(
3565  *pPool, GetWhichOfScript(RES_CHRATR_FONTSIZE, nRubyScript));
3566  m_nRubyHeight = rHeight.GetHeight();
3567  }
3568 
3569  const OUString &rText = rNode.GetText();
3570  sal_uInt16 nScript = i18n::ScriptType::LATIN;
3571 
3572  if (!rText.isEmpty())
3573  nScript = g_pBreakIt->GetBreakIter()->getScriptType(rText, 0);
3574 
3575  sal_uInt16 nWhich = GetWhichOfScript(RES_CHRATR_FONTSIZE, nScript);
3576  auto& rHeightItem = static_cast<const SvxFontHeightItem&>(rExport.GetItem(nWhich));
3577  m_nBaseHeight = rHeightItem.GetHeight();
3578 }
3579 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long GetLeft() const
bool GetValue() const
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:962
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
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:1710
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:282
const OUString & GetBaseURL() const
Definition: shellio.hxx:439
virtual void AppendSmartTags(SwTextNode &)
Definition: wrtww8.hxx:706
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:983
void GetCurrentItems(ww::bytes &rItems) const
Definition: wrtw8nds.cxx:866
bool m_bLinkedTextboxesHelperInitialized
Definition: wrtww8.hxx:509
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
sal_uInt16 AddRedlineAuthor(std::size_t nId)
Definition: wrtww8.cxx:1650
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:1827
constexpr TypedWhichId< SvxTabStopItem > RES_PARATR_TABSTOP(68)
bool GetWholeWord() const
Definition: paratr.hxx:92
bool IsSectionNode() const
Definition: node.hxx:644
std::unique_ptr< WW8Fib > pFib
File Information Block.
Definition: wrtww8.hxx:987
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:771
static const SwPageDesc * GetPageDescOfNode(const SwNode &rNd)
Given a SwNode return the pagedesc in use at that location.
Definition: pagedesc.cxx:312
OUString & GetRefName()
Definition: fmtrfmrk.hxx:66
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:1771
SwTableBox * GetTableBox() const
If node is in a table return the respective table box.
Definition: node.cxx:749
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_METAFIELD(49)
RndStdIds m_eNewAnchorType
Definition: wrtww8.hxx:516
bool m_bAddFootnoteTab
Definition: wrtww8.hxx:566
const OUString & GetText() const
Definition: ndtxt.hxx:211
OUString const & GetPrimaryKey() const
Definition: tox.hxx:640
#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:1509
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:219
std::string GetValue
const SwRedlineData * Next() const
Definition: redline.hxx:130
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: node.cxx:1198
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:127
SvxBreak GetBreak() const
virtual void Redline(const SwRedlineData *pRedline) override
Output redlining.
Definition: wrtw8nds.cxx:3416
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:275
sal_uInt8 GetLines() const
Definition: paratr.hxx:86
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:1758
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:474
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2686
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_FONTSIZE(8)
const SwPosition * GetMark() const
Definition: pam.hxx:209
const SwAttrSet * m_pStyAttr
Definition: wrtww8.hxx:530
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:469
LanguageType GetLanguage(SfxItemSet const &aSet, sal_uInt16 nLangWhichId)
Definition: langhelper.cxx:399
rtl_TextEncoding meChrSet
Definition: wrtww8.hxx:1499
SwFrameFormat & GetFirstMaster()
Definition: pagedesc.hxx:219
bool MiserableFormFieldExportHack(const SwFrameFormat &rFrameFormat)
Definition: wrtw8esh.cxx:352
Provides access to the marks of a document.
bool m_bOutPageDescs
PageDescs (section properties) are being written.
Definition: wrtww8.hxx:547
#define ODF_FORMCHECKBOX
eFORMDATE
bool mbCharIsRTL
Definition: wrtww8.hxx:1501
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:466
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
bool NeedSectionBreak(const SwNode &rNd) const
Definition: wrtw8nds.cxx:2128
bool HasDummyChar() const
Definition: txatbase.hxx:101
SwTableLine is one table row in the document model.
Definition: swtable.hxx:344
void SetTextLeft(const long nL, const sal_uInt16 nProp=100)
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:515
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:1609
sal_uInt16 m_nStyleBeforeFly
style number of the node
Definition: wrtww8.hxx:477
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:4426
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1682
virtual void StartRunProperties()=0
Called before we start outputting the attributes.
WW8_CP Fc2Cp(sal_uLong nFc) const
Definition: wrtww8.hxx:1092
const SwTOXType * GetTOXType() const
Definition: tox.hxx:578
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:291
void AppendFlyInFlys(const ww8::Frame &rFrameFormat, const Point &rNdTopLeft)
Definition: wrtw8esh.cxx:969
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:177
OUString FieldString(ww::eField eIndex)
Definition: ww8atr.cxx:2585
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:4111
std::shared_ptr< SvxBrushItem > TrueFrameBgBrush(const SwFrameFormat &rFlyFormat) const
Definition: wrtw8nds.cxx:1661
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:201
sal_uInt32 m_nBaseHeight
const SwRedlineData * GetParagraphMarkerRedline(const SwTextNode &rNode, RedlineType aRedlineType)
Definition: ww8atr.cxx:5525
size_type size() const
Definition: swtable.hxx:74
sal_uInt16 NextWhich()
IMarkVector m_rSortedAnnotationMarksEnd
Definition: wrtww8.hxx:581
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:1512
#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:541
sal_Int32 WhereNext() const
Definition: wrtww8.hxx:1544
WEIGHT_BOLD
sal_uInt16 GetScript() const
Definition: wrtww8.hxx:1545
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:1984
#define ODF_HYPERLINK
constexpr TypedWhichId< SvxCaseMapItem > RES_CHRATR_CASEMAP(RES_CHRATR_BEGIN)
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:170
sal_uInt16 IsFormulaOrValueBox() const
Definition: swtable.cxx:2550
void WriteText()
Iterate through the nodes and call the appropriate OutputNode() on them.
Definition: wrtww8.cxx:2775
sal_uInt16 sal_Unicode
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
const SwTextRuby * GetTextRuby() const
Definition: fmtruby.hxx:59
RedlineType GetType() const
Definition: redline.hxx:125
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:1731
SwWW8AttrIter(const SwWW8AttrIter &)=delete
ePAGEREF
SwNodeType GetNodeType() const
Definition: node.hxx:144
MSWordExportBase & m_rExport
Definition: wrtww8.hxx:1433
std::map< OUString, LinkedTextboxInfo > m_aLinkedTextboxesHelper
Definition: wrtww8.hxx:508
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:756
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:2154
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:1642
MSWordAttrIter * m_pChpIter
Definition: wrtww8.hxx:494
FieldId eFieldId
bool m_bInWriteEscher
Definition: wrtww8.hxx:552
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:497
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:95
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:1864
INetProtocol
ww8::Frames maFlyFrames
Definition: wrtww8.hxx:1511
constexpr TypedWhichId< SwFormatAutoFormat > RES_TXTATR_AUTOFMT(50)
static void UpdateTocSectionNodeProperties(const SwSectionNode &rSectionNode)
Definition: wrtw8nds.cxx:3213
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:473
void OutputItem(const SfxPoolItem &rHt)
Call the right virtual function according to the type of the item.
Definition: ww8atr.cxx:5188
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:1547
SW_DLLPUBLIC void PtrToBoxNm(const SwTable *pTable)
create from the internal formula (for CORE) the external formula (for UI)
Definition: cellfml.cxx:571
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:1752
constexpr TypedWhichId< SvxWeightItem > RES_CHRATR_WEIGHT(15)
SwFormatColl & GetAnyFormatColl() const
Definition: node.hxx:716
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:2061
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:1735
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:569
bool IsContentNode() const
Definition: node.hxx:628
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:443
void NextPos()
Definition: wrtww8.hxx:1533
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:492
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:3160
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
Style of a layout element.
Definition: frmfmt.hxx:57
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:1861
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:1797
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:725
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:991
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:3491
void NearestAnnotationMark(sal_Int32 &rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly)
Find the nearest annotation mark from the current position.
Definition: wrtw8nds.cxx:2032
void UpdatePosition(SwWW8AttrIter *pAttrIter, sal_Int32 nCurrentPos)
Update the information for GetNextPos().
Definition: wrtw8nds.cxx:1878
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:1500
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:878
const SwTOXBase * GetTOXBase() const
Definition: section.cxx:617
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
bool IsParaRTL() const
Definition: wrtww8.hxx:1546
const SwModify * m_pOutFormatNode
Definition: wrtww8.hxx:531
virtual void OutputTextNode(SwTextNode &)
Output SwTextNode.
Definition: wrtw8nds.cxx:2176
sw::util::CharRuns maCharRuns
Definition: wrtww8.hxx:1496
void OutputContentNode(SwContentNode &)
Call the right (virtual) function according to the type of the item.
Definition: wrtw8nds.cxx:3471
bool HasContent() const
Definition: txatbase.hxx:106
virtual void ExportGrfBullet(const SwTextNode &rNd)=0
SwContentNode * GetContentNode()
Definition: node.hxx:615
sal_uInt8 HasPrevNextLayNode() const
Definition: node.cxx:845
vector_type::size_type size_type
Definition: docary.hxx:228
FlyAnchors.
Definition: fmtanchr.hxx:34
sal_uInt16 GetLevel() const
Definition: tox.hxx:634
static void WriteShort(SvStream &rStrm, sal_Int16 nVal)
Definition: wrtww8.hxx:953
const ww8::Frame * m_pParentFrame
Definition: wrtww8.hxx:512
SwDoc * GetDoc()
Definition: node.hxx:702
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:892
const SfxItemSet * GetItemSet(const SfxPoolItem &rAttr)
Returns the item set associated with a character/inet/auto style.
Definition: atrstck.cxx:133
float u
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:179
const SwRedlineData * GetRunLevelRedline(sal_Int32 nPos)
Definition: wrtw8nds.cxx:1490
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:195
const DateTime & GetTimeStamp() const
Definition: redline.hxx:129
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2808
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.
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:366
virtual const_iterator_t getAnnotationMarksBegin() const =0
bool KnowsPageDesc() const
Definition: atrfrm.cxx:653
short GetTextFirstLineOffset() const
void OutputFlyFrame(const ww8::Frame &rFormat)
Output frames.
Definition: wrtw8nds.cxx:3398
virtual void EndRuby(const SwTextNode &rNode, sal_Int32 nPos) override
Output ruby end.
Definition: wrtw8nds.cxx:901
size
virtual void WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner=ww8::WW8TableNodeInfoInner::Pointer_t()) override
Definition: wrtww8.cxx:1854
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:396
Marks a node in the document model.
Definition: ndindex.hxx:31
SwWW8Writer & GetWriter() const
Definition: wrtww8.hxx:1171
SwFrameFormat * GetFrameFormat()
Definition: swtable.hxx:425
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
void StartCommentOutput(const OUString &rName)
Definition: ww8atr.cxx:1869
static void CorrectTabStopInSet(SfxItemSet &rSet, sal_Int32 nAbsLeft)
Definition: ww8atr.cxx:659
const SvxFormatBreakItem & GetBreak(bool=true) const
Definition: frmatr.hxx:90
bool HasSwAttrSet() const
Definition: node.hxx:444
void InsUInt16(sal_uInt16 n)
Definition: wrtww8.hxx:1143
sal_uInt8 GetChars() const
Definition: paratr.hxx:89
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:1503
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
Definition: swtable.hxx:356
void InsUInt32(sal_uInt32 n)
Definition: wrtww8.hxx:1145
void EndTOX(const SwSection &rSect, bool bCareEnd=true)
Definition: ww8atr.cxx:2482
SwTableLines & GetTabLines()
Definition: swtable.hxx:198
OUString GetName() const
IMarkVector m_rSortedAnnotationMarksStart
Definition: wrtww8.hxx:580
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:110
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:2095
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:246
virtual void EndRunProperties(const SwRedlineData *pRedlineData)=0
Called after we end outputting the attributes.
eFORMTEXT
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
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.
long GetIndentAt() const
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:458
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:1494
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:217
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
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:579
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:439
OUString BookmarkToWriter(const OUString &rBookmark)
Definition: wrtw8nds.cxx:1199
#define ODF_TOC
const SwPageDesc * m_pCurrentPageDesc
Definition: wrtww8.hxx:490
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:3378
const OUString & GetFormula() const
Definition: cellfml.hxx:136
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:1172
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
OUString const & GetSecondaryKey() const
Definition: tox.hxx:646
std::set< sal_Int32 > SwSoftPageBreakList
Definition: wrtww8.hxx:129
FlyProcessingState
enum to state the present state of the fly
Definition: wrtww8.hxx:161
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:2883
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:731
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:985
bool IsCountedInList() const
Definition: ndtxt.cxx:4254
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:403
const sal_uInt8 PageBreak
std::pair< OUString, sal_uLong > aBookmarkPair
Definition: wrtww8.hxx:405
sw::util::CharRuns::const_iterator maCharRunIter
Definition: wrtww8.hxx:1497
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:1941
sal_uInt8 m_nTextTyp
Definition: wrtww8.hxx:541
ww8::Frames m_aFrames
Definition: wrtww8.hxx:489
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1734
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:386
bool m_bOutFlyFrameAttrs
Definition: wrtww8.hxx:546
bool NearestBookmark(sal_Int32 &rNearest, const sal_Int32 nCurrentPos, bool bNextPositionOnly)
Find the nearest bookmark from the current position.
Definition: wrtw8nds.cxx:2000
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:554
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
virtual void AppendSection(const SwPageDesc *pPageDesc, const SwSectionFormat *pFormat, sal_uLong nLnNum) override
Definition: wrtw8nds.cxx:3300
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:1890
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:1700
virtual void TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfo) override
Definition: wrtww8.cxx:1974
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:181
bool GetAnnotationMarks(const SwWW8AttrIter &rAttrs, sal_Int32 nStt, sal_Int32 nEnd, IMarkVector &rArr)
Definition: wrtw8nds.cxx:1938
TOXTypes GetType() const
Definition: tox.hxx:699
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:723
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:352
SwTableBox * GetUpper()
Definition: swtable.hxx:362
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:209
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:1429
sal_Int32 nCurrentSwPos
Definition: wrtww8.hxx:1504
#define SAL_WARN(area, stream)
const SwCharFormat * GetCharFormat() const
Definition: paratr.hxx:98
Base class for WW8Export and DocxExport.
Definition: wrtww8.hxx:445
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:1505
constexpr TypedWhichId< SwFormatLineNumber > RES_LINENUMBER(116)
sal_uInt16 GetPos(const SwTableLine *pBox) const
Definition: swtable.hxx:96
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:1550
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:910
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:1507
const SwTextNode & GetNode() const
Definition: wrtww8.hxx:1557
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:153
MSWordAttrIter(const MSWordAttrIter &)=delete
static SwTextFormatColl & lcl_getFormatCollection(MSWordExportBase &rExport, const SwTextNode *pTextNode)
Delivers the right paragraph style.
Definition: wrtw8nds.cxx:1773
virtual void WriteHyperlinkData(const ::sw::mark::IFieldmark &rFieldmark)=0
static bool NoPageBreakSection(const SfxItemSet *pSet)
Definition: wrtw8nds.cxx:3126
virtual SwTableBoxFormula * Clone(SfxItemPool *pPool=nullptr) const override
Definition: cellatr.cxx:71
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:50
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:577
const SfxPoolItem & GetAttr(sal_uInt16 nWhich, bool bInParent=true) const
SS for PoolItems: hard attributation.
Definition: node.hxx:730
virtual void AppendBookmark(const OUString &rName)=0
void EndCommentOutput(const OUString &rName)
Definition: ww8atr.cxx:1875
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:1959
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:3307
virtual bool EndURL(bool) override
Output URL end.
Definition: wrtw8nds.cxx:1181
#define CH_TXT_ATR_FIELDSEP
Definition: hintids.hxx:180
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:421
static ww::eField lcl_getFieldId(const IFieldmark *const pFieldmark)
Definition: wrtw8nds.cxx:131
bool IsTextNode() const
Definition: node.hxx:636
The class MSWordAttrIter is a helper class to build the Fkp.chpx.
Definition: wrtww8.hxx:1426
std::shared_ptr< WW8TableNodeInfo > Pointer_t
static void WriteLong(SvStream &rStrm, sal_Int32 nVal)
Definition: wrtww8.hxx:956
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:2948
bool NeedTextNodeSplit(const SwTextNode &rNd, SwSoftPageBreakList &pList) const
Definition: wrtw8nds.cxx:2146
SwFrameFormat * GetFlyFormat() const
If node is in a fly return the respective format.
Definition: node.cxx:714
aStr
SwCharFormat * GetCharFormat()
Definition: txtatr2.cxx:227
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1288
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:1214
virtual void EmptyParagraph() override
Empty paragraph.
Definition: wrtw8nds.cxx:3121
std::unique_ptr< WW8_WrPlcPn > m_pChpPlc
Definition: wrtww8.hxx:493
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:1609
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2739
OUString ConvertURL(const OUString &rUrl, bool bAbsoluteOut)
Definition: wrtw8nds.cxx:916
IMarkVector m_rSortedBookmarksStart
Definition: wrtww8.hxx:578
SwDoc * m_pDoc
Definition: wrtww8.hxx:568
#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:1315
std::vector< aBookmarkPair > m_aImplicitBookmarks
Definition: wrtww8.hxx:488
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:844
#define ODF_FORMDROPDOWN
bool IsAnchorLinkedToThisNode(sal_uLong nNodePos)
Definition: wrtw8nds.cxx:611
std::unique_ptr< MSWordStyles > m_pStyles
Definition: wrtww8.hxx:495
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)