LibreOffice Module sw (master)  1
wrtw8sty.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 <algorithm>
21 
22 #include <memory>
23 
24 #include <com/sun/star/i18n/ScriptType.hpp>
25 #include <hintids.hxx>
26 #include <editeng/boxitem.hxx>
27 #include <editeng/fontitem.hxx>
28 #include <svx/svdobj.hxx>
29 #include <svx/svdotext.hxx>
30 #include <svx/svdouno.hxx>
31 #include <editeng/lrspitem.hxx>
32 #include <editeng/fhgtitem.hxx>
33 #include <doc.hxx>
34 #include "wrtww8.hxx"
35 #include <docary.hxx>
36 #include <poolfmt.hxx>
37 #include <fmtpdsc.hxx>
38 #include <pagedesc.hxx>
39 #include <ndtxt.hxx>
40 #include <ftninfo.hxx>
41 #include <fmthdft.hxx>
42 #include <section.hxx>
43 #include <fmtcntnt.hxx>
44 #include <fmtftn.hxx>
45 #include <ndindex.hxx>
46 #include <txtftn.hxx>
47 #include <charfmt.hxx>
48 #include <docufld.hxx>
49 #include <dcontact.hxx>
50 #include <fmtcnct.hxx>
51 #include <ftnidx.hxx>
52 #include <fmtclds.hxx>
53 #include <lineinfo.hxx>
54 #include <fmtline.hxx>
55 #include <swtable.hxx>
56 #include <redline.hxx>
57 #include <msfilter.hxx>
58 #include <swmodule.hxx>
59 #include <charatr.hxx>
60 
61 #include "sprmids.hxx"
62 
63 #include "writerhelper.hxx"
64 #include "writerwordglue.hxx"
65 #include <wwstyles.hxx>
66 #include "ww8par.hxx"
67 #include "ww8attributeoutput.hxx"
68 #include "docxattributeoutput.hxx"
69 #include "rtfattributeoutput.hxx"
70 
71 #include <unordered_set>
72 
73 using namespace css;
74 using namespace sw::util;
75 using namespace nsHdFtFlags;
76 
79 {
80  std::unique_ptr<sal_uInt8[]> m_pData;
81  sal_uInt16 m_nLen;
83  WW8_PdAttrDesc() : m_nLen(0), m_nSepxFcPos(0xffffffff) /*default: none*/
84  { }
85 };
86 
87 namespace {
88 
89 struct WW8_SED
90 {
91  SVBT16 aBits1; // orientation change + internal, Default: 6
92  SVBT32 fcSepx; // FC file offset to beginning of SEPX for section.
93  // 0xFFFFFFFF for no Sprms
94  SVBT16 fnMpr; // used internally by Windows Word, Default: 0
95  SVBT32 fcMpr; // FC, points to offset in FC space for MacWord
96  // Default: 0xffffffff ( nothing )
97  // cbSED is 12 (decimal)), C (hex).
98 };
99 
100 }
101 
102 // class WW8_WrPlc0 is only used for header and footer positioning
103 // ie there is no content support structure
105 {
106 private:
107  std::vector<sal_uLong> aPos; // PTRARR of CPs / FCs
109 
110  WW8_WrPlc0(WW8_WrPlc0 const&) = delete;
111  WW8_WrPlc0& operator=(WW8_WrPlc0 const&) = delete;
112 
113 public:
114  explicit WW8_WrPlc0( sal_uLong nOffset );
115  sal_uInt16 Count() const { return aPos.size(); }
116  void Append( sal_uLong nStartCpOrFc );
117  void Write( SvStream& rStrm );
118 };
119 
120 // Styles
121 
122 #define WW8_RESERVED_SLOTS 15
123 
124 // GetId( SwCharFormat ) for use in text -> zero is not allowed,
125 // use "Default Char Style" instead
126 sal_uInt16 MSWordExportBase::GetId( const SwCharFormat* pFormat ) const
127 {
128  sal_uInt16 nRet = m_pStyles->GetSlot( pFormat );
129  return ( nRet != 0x0fff ) ? nRet : 10; // Default Char Style
130 }
131 
132 // GetId( SwTextFormatColl ) for use in TextNodes -> zero is not allowed,
133 // "Standard" instead
134 sal_uInt16 MSWordExportBase::GetId( const SwTextFormatColl& rColl ) const
135 {
136  sal_uInt16 nRet = m_pStyles->GetSlot( &rColl );
137  return ( nRet != 0xfff ) ? nRet : 0; // Default TextFormatColl
138 }
139 
140 //typedef pFormatT
141 MSWordStyles::MSWordStyles( MSWordExportBase& rExport, bool bListStyles )
142  : m_rExport( rExport ),
143  m_bListStyles(bListStyles)
144 {
145  // if exist any Foot-/End-Notes then get from the EndNoteInfo struct
146  // the CharFormats. They will create it!
148  {
153  }
154  sal_uInt16 nAlloc = WW8_RESERVED_SLOTS + m_rExport.m_rDoc.GetCharFormats()->size() - 1 +
156  (bListStyles ? m_rExport.m_rDoc.GetNumRuleTable().size() - 1 : 0);
157 
158  // somewhat generous ( free for up to 15 )
159  m_pFormatA.reset( new SwFormat*[ nAlloc ] );
160  memset( m_pFormatA.get(), 0, nAlloc * sizeof( SwFormat* ) );
161  memset( m_aHeadingParagraphStyles, -1 , MAXLEVEL * sizeof( sal_uInt16));
162 
164  BuildStyleIds();
165 }
166 
168 {
169 }
170 
171 // Sty_SetWWSlot() dependencies for the styles -> zero is allowed
172 sal_uInt16 MSWordStyles::GetSlot( const SwFormat* pFormat ) const
173 {
174  sal_uInt16 n;
175  for ( n = 0; n < m_nUsedSlots; n++ )
176  if ( m_pFormatA[n] == pFormat )
177  return n;
178  return 0xfff; // 0xfff: WW: zero
179 }
180 
181 sal_uInt16 MSWordStyles::BuildGetSlot( const SwFormat& rFormat )
182 {
183  sal_uInt16 nRet = rFormat.GetPoolFormatId();
184  switch ( nRet )
185  {
187  nRet = 0;
188  break;
189 
199  nRet -= RES_POOLCOLL_HEADLINE1-1;
200  break;
201 
202  default:
203  nRet = m_nUsedSlots++;
204  break;
205  }
206  return nRet;
207 }
208 
209 
210 sal_uInt16 MSWordStyles::GetWWId( const SwFormat& rFormat )
211 {
212  sal_uInt16 nRet = ww::stiUser; // user style as default
213  sal_uInt16 nPoolId = rFormat.GetPoolFormatId();
214  if( nPoolId == RES_POOLCOLL_STANDARD )
215  nRet = 0;
216  else if( nPoolId >= RES_POOLCOLL_HEADLINE1 &&
217  nPoolId <= RES_POOLCOLL_HEADLINE9 )
218  nRet = static_cast< sal_uInt16 >(nPoolId + 1 - RES_POOLCOLL_HEADLINE1);
219  else if( nPoolId >= RES_POOLCOLL_TOX_IDX1 &&
220  nPoolId <= RES_POOLCOLL_TOX_IDX3 )
221  nRet = static_cast< sal_uInt16 >(nPoolId + 10 - RES_POOLCOLL_TOX_IDX1);
222  else if( nPoolId >= RES_POOLCOLL_TOX_CNTNT1 &&
223  nPoolId <= RES_POOLCOLL_TOX_CNTNT5 )
224  nRet = static_cast< sal_uInt16 >(nPoolId + 19 - RES_POOLCOLL_TOX_CNTNT1);
225  else if( nPoolId >= RES_POOLCOLL_TOX_CNTNT6 &&
226  nPoolId <= RES_POOLCOLL_TOX_CNTNT9 )
227  nRet = static_cast< sal_uInt16 >(nPoolId + 24 - RES_POOLCOLL_TOX_CNTNT6);
228  else
229  switch( nPoolId )
230  {
231  case RES_POOLCOLL_FOOTNOTE: nRet = 29; break;
232  case RES_POOLCOLL_MARGINAL: nRet = 30; break;
233  case RES_POOLCOLL_HEADER: nRet = 31; break;
234  case RES_POOLCOLL_FOOTER: nRet = 32; break;
235  case RES_POOLCOLL_TOX_IDXH: nRet = 33; break;
236  case RES_POOLCOLL_LABEL: nRet = 34; break;
237  case RES_POOLCOLL_LABEL_DRAWING: nRet = 35; break;
238  case RES_POOLCOLL_ENVELOPE_ADDRESS: nRet = 36; break;
239  case RES_POOLCOLL_SEND_ADDRESS: nRet = 37; break;
240  case RES_POOLCOLL_ENDNOTE: nRet = 43; break;
241  case RES_POOLCOLL_TOX_AUTHORITIESH: nRet = 44; break;
242  case RES_POOLCOLL_TOX_CNTNTH: nRet = 46; break;
243  case RES_POOLCOLL_BULLET_LEVEL1: nRet = 48; break;
244  case RES_POOLCOLL_LISTS_BEGIN: nRet = 47; break;
245  case RES_POOLCOLL_NUM_LEVEL1: nRet = 49; break;
246  case RES_POOLCOLL_BULLET_LEVEL2: nRet = 54; break;
247  case RES_POOLCOLL_BULLET_LEVEL3: nRet = 55; break;
248  case RES_POOLCOLL_BULLET_LEVEL4: nRet = 56; break;
249  case RES_POOLCOLL_BULLET_LEVEL5: nRet = 57; break;
250  case RES_POOLCOLL_NUM_LEVEL2: nRet = 58; break;
251  case RES_POOLCOLL_NUM_LEVEL3: nRet = 59; break;
252  case RES_POOLCOLL_NUM_LEVEL4: nRet = 60; break;
253  case RES_POOLCOLL_NUM_LEVEL5: nRet = 61; break;
254  case RES_POOLCOLL_DOC_TITLE: nRet = 62; break;
255  case RES_POOLCOLL_DOC_APPENDIX: nRet = 63; break;
256  case RES_POOLCOLL_SIGNATURE: nRet = 64; break;
257  case RES_POOLCOLL_TEXT: nRet = 66; break;
258  case RES_POOLCOLL_TEXT_MOVE: nRet = 67; break;
259  case RES_POOLCOLL_BULLET_NONUM1: nRet = 68; break;
260  case RES_POOLCOLL_BULLET_NONUM2: nRet = 69; break;
261  case RES_POOLCOLL_BULLET_NONUM3: nRet = 70; break;
262  case RES_POOLCOLL_BULLET_NONUM4: nRet = 71; break;
263  case RES_POOLCOLL_BULLET_NONUM5: nRet = 72; break;
264  case RES_POOLCOLL_DOC_SUBTITLE: nRet = 74; break;
265  case RES_POOLCOLL_GREETING: nRet = 75; break;
266  case RES_POOLCOLL_TEXT_IDENT: nRet = 77; break;
267 
268  case RES_POOLCHR_FOOTNOTE_ANCHOR: nRet = 38; break;
269  case RES_POOLCHR_ENDNOTE_ANCHOR: nRet = 42; break;
270  case RES_POOLCHR_INET_NORMAL: nRet = 85; break;
271  case RES_POOLCHR_INET_VISIT: nRet = 86; break;
272  case RES_POOLCHR_HTML_STRONG: nRet = 87; break;
273  case RES_POOLCHR_HTML_EMPHASIS: nRet = 88; break;
274  case RES_POOLCHR_LINENUM: nRet = 40; break;
275  case RES_POOLCHR_PAGENO: nRet = 41; break;
276  }
277  return nRet;
278 }
279 
281 {
282  m_nUsedSlots = WW8_RESERVED_SLOTS; // reserved slots for standard, headingX, and others
283 
284  const SwCharFormats& rArr = *m_rExport.m_rDoc.GetCharFormats(); // first CharFormat
285  // the default character style ( 0 ) will not be outputted !
286  for( size_t n = 1; n < rArr.size(); n++ )
287  {
288  SwCharFormat* pFormat = rArr[n];
289  m_pFormatA[ BuildGetSlot( *pFormat ) ] = pFormat;
290  }
291 
292  const SwTextFormatColls& rArr2 = *m_rExport.m_rDoc.GetTextFormatColls(); // then TextFormatColls
293  // the default character style ( 0 ) will not be outputted !
294  for( size_t n = 1; n < rArr2.size(); n++ )
295  {
296  SwTextFormatColl* pFormat = rArr2[n];
297  sal_uInt16 nId = BuildGetSlot( *pFormat ) ;
298  m_pFormatA[ nId ] = pFormat;
299  if ( pFormat->IsAssignedToListLevelOfOutlineStyle() )
300  {
301  int nLvl = pFormat->GetAssignedOutlineStyleLevel() ;
302  if (nLvl >= 0 && nLvl < MAXLEVEL)
303  m_aHeadingParagraphStyles[nLvl] = nId ;
304  }
305  }
306 
307  if (!m_bListStyles)
308  return;
309 
310  const SwNumRuleTable& rNumRuleTable = m_rExport.m_rDoc.GetNumRuleTable();
311  for (size_t i = 0; i < rNumRuleTable.size(); ++i)
312  {
313  const SwNumRule* pNumRule = rNumRuleTable[i];
314  if (pNumRule->IsAutoRule() || pNumRule->GetName().startsWith("WWNum"))
315  continue;
316  sal_uInt16 nSlot = BuildGetSlot(*pNumRule);
317  m_aNumRules[nSlot] = pNumRule;
318  }
319 }
320 
321 OString MSWordStyles::CreateStyleId(const OUString &rName)
322 {
323  OStringBuffer aStyleIdBuf(rName.getLength());
324  for (int i = 0; i < rName.getLength(); ++i)
325  {
326  sal_Unicode nChar = rName[i];
327  if (('0' <= nChar && nChar <= '9') ||
328  ('a' <= nChar && nChar <= 'z') ||
329  ('A' <= nChar && nChar <= 'Z'))
330  {
331  // first letter should be uppercase
332  if (aStyleIdBuf.isEmpty() && 'a' <= nChar && nChar <= 'z')
333  aStyleIdBuf.append(char(nChar - ('a' - 'A')));
334  else
335  aStyleIdBuf.append(char(nChar));
336  }
337  }
338  return aStyleIdBuf.makeStringAndClear();
339 }
340 
342 {
343  std::unordered_set<OString> aUsed;
344 
345  m_aStyleIds.emplace_back("Normal");
346  aUsed.insert("normal");
347 
348  for (sal_uInt16 n = 1; n < m_nUsedSlots; ++n)
349  {
350  OUString aName;
351  if(m_pFormatA[n])
352  aName = m_pFormatA[n]->GetName();
353  else if (m_aNumRules.find(n) != m_aNumRules.end())
354  aName = m_aNumRules[n]->GetName();
355 
356  OString aStyleId = CreateStyleId(aName);
357 
358  if (aStyleId.isEmpty())
359  aStyleId = "Style";
360 
361  OString aLower(aStyleId.toAsciiLowerCase());
362 
363  // check for uniqueness & construct something unique if we have to
364  if (aUsed.insert(aLower).second)
365  {
366  m_aStyleIds.push_back(aStyleId);
367  }
368  else
369  {
370  int nFree = 1;
371  while (!aUsed.insert(aLower + OString::number(nFree)).second)
372  ++nFree;
373 
374  m_aStyleIds.emplace_back(aStyleId + OString::number(nFree));
375  }
376  }
377 }
378 
379 OString const & MSWordStyles::GetStyleId(sal_uInt16 nId) const
380 {
381  return m_aStyleIds[nId];
382 }
383 
385 static void impl_SkipOdd(std::unique_ptr<ww::bytes> const& pO, std::size_t nTableStrmTell)
386 {
387  if ( ( nTableStrmTell + pO->size() ) & 1 ) // start on even
388  pO->push_back( sal_uInt8(0) ); // Address
389 }
390 
392 {
394 
395  short nLen = m_rWW8Export.pO->size() - 2; // length of the style
396  sal_uInt8* p = m_rWW8Export.pO->data() + nPOPosStdLen1;
397  ShortToSVBT16( nLen, p ); // add
398  p = m_rWW8Export.pO->data() + nPOPosStdLen2;
399  ShortToSVBT16( nLen, p ); // also
400 
402  m_rWW8Export.pO->clear();
403 }
404 
405 void WW8AttributeOutput::StartStyle( const OUString& rName, StyleType eType, sal_uInt16 nWwBase,
406  sal_uInt16 nWwNext, sal_uInt16 /*nWwLink*/, sal_uInt16 nWwId, sal_uInt16 /*nId*/, bool bAutoUpdate )
407 {
408  sal_uInt8 aWW8_STD[ sizeof( WW8_STD ) ] = {};
409  sal_uInt8* pData = aWW8_STD;
410 
411  sal_uInt16 nBit16 = 0x1000; // fInvalHeight
412  nBit16 |= (ww::stiNil & nWwId);
413  Set_UInt16( pData, nBit16 );
414 
415  nBit16 = nWwBase << 4; // istdBase
416  nBit16 |= (eType == STYLE_TYPE_PARA ? 1 : 2); // sgc
417  Set_UInt16( pData, nBit16 );
418 
419  nBit16 = nWwNext << 4; // istdNext
420  nBit16 |= (eType == STYLE_TYPE_PARA ? 2 : 1); // cupx
421  Set_UInt16( pData, nBit16 );
422 
423  pData += sizeof( sal_uInt16 ); // bchUpe
424 
425  nBit16 = bAutoUpdate ? 1 : 0; // fAutoRedef : 1
426  Set_UInt16( pData, nBit16 );
427  // now new:
428  // from Ver8 there are two fields more:
429  // sal_uInt16 fHidden : 1; /* hidden from UI?
430  // sal_uInt16 : 14; /* unused bits
431 
432  sal_uInt16 nLen = static_cast< sal_uInt16 >( ( pData - aWW8_STD ) + 1 +
433  (2 * (rName.getLength() + 1)) ); // temporary
434 
435  nPOPosStdLen1 = m_rWW8Export.pO->size(); // Adr1 for adding the length
436 
438  m_rWW8Export.pO->insert( m_rWW8Export.pO->end(), aWW8_STD, pData );
439 
440  nPOPosStdLen2 = nPOPosStdLen1 + 8; // Adr2 for adding of "end of upx"
441 
442  // write names
443  SwWW8Writer::InsUInt16( *m_rWW8Export.pO, rName.getLength() ); // length
445  m_rWW8Export.pO->push_back( sal_uInt8(0) ); // Despite P-String 0 at the end!
446 }
447 
448 void MSWordStyles::SetStyleDefaults( const SwFormat& rFormat, bool bPap )
449 {
451  m_rExport.m_pOutFormatNode = &rFormat;
452  bool aFlags[ RES_FRMATR_END - RES_CHRATR_BEGIN ];
453  sal_uInt16 nStt, nEnd, n;
454  if( bPap )
455  {
456  nStt = RES_PARATR_BEGIN;
457  nEnd = RES_FRMATR_END;
458  }
459  else
460  {
461  nStt = RES_CHRATR_BEGIN;
462  nEnd = RES_TXTATR_END;
463  }
464 
465  // dynamic defaults
466  const SfxItemPool& rPool = *rFormat.GetAttrSet().GetPool();
467  for( n = nStt; n < nEnd; ++n )
468  aFlags[ n - RES_CHRATR_BEGIN ] = nullptr != rPool.GetPoolDefaultItem( n )
469  || SfxItemState::SET == m_rExport.m_rDoc.GetDfltTextFormatColl()->GetItemState( n, false );
470 
471  // static defaults, that differs between WinWord and SO
472  if( bPap )
473  {
474  aFlags[ static_cast< sal_uInt16 >(RES_PARATR_WIDOWS) - RES_CHRATR_BEGIN ] = true;
475  aFlags[ static_cast< sal_uInt16 >(RES_PARATR_HYPHENZONE) - RES_CHRATR_BEGIN ] = true;
476  aFlags[ static_cast< sal_uInt16 >(RES_FRAMEDIR) - RES_CHRATR_BEGIN ] = true;
477  }
478  else
479  {
480  aFlags[ RES_CHRATR_FONTSIZE - RES_CHRATR_BEGIN ] = true;
481  aFlags[ RES_CHRATR_LANGUAGE - RES_CHRATR_BEGIN ] = true;
482  }
483 
484  const SfxItemSet* pOldI = m_rExport.GetCurItemSet();
485  m_rExport.SetCurItemSet( &rFormat.GetAttrSet() );
486 
487  const bool* pFlags = aFlags + ( nStt - RES_CHRATR_BEGIN );
488  for ( n = nStt; n < nEnd; ++n, ++pFlags )
489  {
490  if ( *pFlags && !m_rExport.ignoreAttributeForStyleDefaults( n )
491  && SfxItemState::SET != rFormat.GetItemState(n, false))
492  {
493  //If we are a character property then see if it is one of the
494  //western/asian ones that must be collapsed together for export to
495  //word. If so default to the western variant.
496  if ( bPap || m_rExport.CollapseScriptsforWordOk(
497  i18n::ScriptType::LATIN, n) )
498  {
499  m_rExport.AttrOutput().OutputItem( rFormat.GetFormatAttr( n ) );
500  }
501  }
502  }
503 
504  m_rExport.SetCurItemSet( pOldI );
505  m_rExport.m_pOutFormatNode = pOldMod;
506 }
507 
508 void WW8AttributeOutput::StartStyleProperties( bool bParProp, sal_uInt16 nStyle )
509 {
511 
512  sal_uInt16 nLen = bParProp ? 2 : 0; // default length
513  m_nStyleLenPos = m_rWW8Export.pO->size(); // adding length
514  // Don't save pointer, because it
515  // changes by _grow!
516 
517  SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nLen ); // Style-Len
518 
520 
521  if ( bParProp )
522  SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nStyle ); // Style-Number
523 }
524 
525 void MSWordStyles::WriteProperties( const SwFormat* pFormat, bool bParProp, sal_uInt16 nPos,
526  bool bInsDefCharSiz )
527 {
528  m_rExport.AttrOutput().StartStyleProperties( bParProp, nPos );
529 
530  OSL_ENSURE( m_rExport.m_pCurrentStyle == nullptr, "Current style not NULL" ); // set current style before calling out
531  m_rExport.m_pCurrentStyle = pFormat;
532 
533  m_rExport.OutputFormat( *pFormat, bParProp, !bParProp );
534 
535  OSL_ENSURE( m_rExport.m_pCurrentStyle == pFormat, "current style was changed" );
536  // reset current style...
537  m_rExport.m_pCurrentStyle = nullptr;
538 
539  if ( bInsDefCharSiz ) // not derived from other Style
540  SetStyleDefaults( *pFormat, bParProp );
541 
543 }
544 
545 void WW8AttributeOutput::EndStyleProperties( bool /*bParProp*/ )
546 {
547  sal_uInt16 nLen = m_rWW8Export.pO->size() - m_nStyleStartSize;
548  sal_uInt8* pUpxLen = m_rWW8Export.pO->data() + m_nStyleLenPos; // adding length
549  ShortToSVBT16( nLen, pUpxLen ); // add default length
550 }
551 
552 void MSWordStyles::GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt16& nBase, sal_uInt16& nNext, sal_uInt16& nLink )
553 {
554  bFormatColl = pFormat->Which() == RES_TXTFMTCOLL || pFormat->Which() == RES_CONDTXTFMTCOLL;
555 
556  // Default: none
557  nBase = 0xfff;
558 
559  // Derived from?
560  if ( !pFormat->IsDefault() )
561  nBase = GetSlot( pFormat->DerivedFrom() );
562 
563  SwFormat* pNext;
564  const SwFormat* pLink = nullptr;
565  if ( bFormatColl )
566  {
567  auto pFormatColl = static_cast<SwTextFormatColl*>(pFormat);
568  pNext = &pFormatColl->GetNextTextFormatColl();
569  pLink = pFormatColl->GetLinkedCharFormat();
570  }
571  else
572  {
573  pNext = pFormat; // CharFormat: next CharFormat == self
574  auto pCharFormat = static_cast<SwCharFormat*>(pFormat);
575  pLink = pCharFormat->GetLinkedParaFormat();
576  }
577 
578  nNext = GetSlot( pNext );
579 
580  if (pLink)
581  {
582  nLink = GetSlot(pLink);
583  }
584 }
585 
587 {
588  m_rWW8Export.pTableStrm->WriteUInt16(0); // empty Style
589 }
590 
591 void MSWordStyles::OutputStyle(const SwNumRule* pNumRule, sal_uInt16 nPos)
592 {
594  /*nBase =*/ 0, /*nWwNext =*/ 0, /*nWwLink =*/ 0, /*nWWId =*/ 0, nPos,
595  /*bAutoUpdateFormat =*/ false );
596 
598 }
599 
600 // OutputStyle applies for TextFormatColls and CharFormats
601 void MSWordStyles::OutputStyle( SwFormat* pFormat, sal_uInt16 nPos )
602 {
603  if ( !pFormat )
605  else
606  {
607  bool bFormatColl;
608  sal_uInt16 nBase, nWwNext;
609  sal_uInt16 nWwLink = 0x0FFF;
610 
611  GetStyleData(pFormat, bFormatColl, nBase, nWwNext, nWwLink);
612 
613  OUString aName = pFormat->GetName();
614  // We want to map LO's default style to Word's "Normal" style.
615  // Word looks for this specific style name when reading docx files.
616  // (It must be the English word regardless of language settings)
617  if ( nPos == 0 )
618  {
619  assert( pFormat->GetPoolFormatId() == RES_POOLCOLL_STANDARD );
620  aName = "Normal";
621  }
622  else if (aName.equalsIgnoreAsciiCase("Normal"))
623  {
624  // If LO has a style named "Normal"(!) rename it to something unique
625  const OUString aBaseName = "LO-" + aName;
626  aName = aBaseName;
627  // Check if we still have a clash, in which case we add a suffix
628  for ( int nSuffix = 0; ; ++nSuffix ) {
629  bool clash=false;
630  for ( sal_uInt16 n = 1; n < m_nUsedSlots; ++n )
631  if ( m_pFormatA[n] &&
632  m_pFormatA[n]->GetName().equalsIgnoreAsciiCase(aName) )
633  {
634  clash = true;
635  break;
636  }
637  if (!clash)
638  break;
639  // TODO: verify if we really need to increment nSuffix in 2 places
640  aName = aBaseName + OUString::number(++nSuffix);
641  }
642  }
643  else if (!bFormatColl && m_rExport.GetExportFormat() == MSWordExportBase::DOCX &&
644  m_rExport.m_pStyles->GetStyleId(nPos).startsWith("ListLabel"))
645  {
646  // tdf#92335 don't export redundant DOCX import style "ListLabel"
647  return;
648  }
649  else if (aName.equalsIgnoreAsciiCase("Internet Link"))
650  {
651  aName = "Hyperlink";
652  }
653  else if (aName.equalsIgnoreAsciiCase("Visited Internet Link"))
654  {
655  aName = "FollowedHyperlink";
656  }
657 
658  m_rExport.AttrOutput().StartStyle( aName, (bFormatColl ? STYLE_TYPE_PARA : STYLE_TYPE_CHAR),
659  nBase, nWwNext, nWwLink, GetWWId( *pFormat ), nPos,
660  pFormat->IsAutoUpdateFormat() );
661 
662  if ( bFormatColl )
663  WriteProperties( pFormat, true, nPos, nBase==0xfff ); // UPX.papx
664 
665  WriteProperties( pFormat, false, nPos, bFormatColl && nBase==0xfff ); // UPX.chpx
666 
668  }
669 }
670 
672 {
673  WW8Fib& rFib = *m_rWW8Export.pFib;
674 
675  sal_uInt64 nCurPos = m_rWW8Export.pTableStrm->Tell();
676  if ( nCurPos & 1 ) // start on even
677  {
678  m_rWW8Export.pTableStrm->WriteChar( char(0) ); // Address
679  ++nCurPos;
680  }
681  rFib.m_fcStshfOrig = rFib.m_fcStshf = nCurPos;
682  m_nStyleCountPos = nCurPos + 2; // count is added later
683 
684  static sal_uInt8 aStShi[] = {
685  0x12, 0x00,
686  0x0F, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x5B, 0x00,
687  0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688  0x00, 0x00 };
689 
690  m_rWW8Export.pTableStrm->WriteBytes(&aStShi, sizeof(aStShi));
691 }
692 
693 void WW8AttributeOutput::EndStyles( sal_uInt16 nNumberOfStyles )
694 {
695  WW8Fib& rFib = *m_rWW8Export.pFib;
696 
699 }
700 
702 {
703  m_rExport.m_bStyDef = true;
704 
706 
707  sal_uInt16 n;
708  // HACK
709  // Ms Office seems to have an internal limitation of 4091 styles
710  // and refuses to load .docx with more, even though the spec seems to allow that;
711  // so simply if there are more styles, don't export those
712  // Implementing check for all exports DOCX, DOC, RTF
713  sal_uInt16 const nLimit = MSWORD_MAX_STYLES_LIMIT;
715 
716  for ( n = 0; n < m_nUsedSlots; n++ )
717  {
718  if (m_aNumRules.find(n) != m_aNumRules.end())
719  OutputStyle(m_aNumRules[n], n);
720  else
721  OutputStyle( m_pFormatA[n], n );
722  }
723 
724  m_rExport.AttrOutput().EndStyles( m_nUsedSlots );
725 
726  m_rExport.m_bStyDef = false;
727 }
728 
729 const SwNumRule* MSWordStyles::GetSwNumRule(sal_uInt16 nId) const
730 {
731  std::map<sal_uInt16, const SwNumRule*>::const_iterator it = m_aNumRules.find(nId);
732  assert(it != m_aNumRules.end());
733  return it->second;
734 }
735 
736 // Fonts
737 
738 wwFont::wwFont(const OUString &rFamilyName, FontPitch ePitch, FontFamily eFamily,
739  rtl_TextEncoding eChrSet)
740  : mbAlt(false), mePitch(ePitch), meFamily(eFamily), meChrSet(eChrSet)
741 {
742  FontMapExport aResult(rFamilyName);
743  msFamilyNm = aResult.msPrimary;
744  msAltNm = aResult.msSecondary;
745  if (!msAltNm.isEmpty() && msAltNm != msFamilyNm &&
746  (msFamilyNm.getLength() + msAltNm.getLength() + 2 <= 65) )
747  {
748  //max size of szFfn in 65 chars
749  mbAlt = true;
750  }
751 
752  maWW8_FFN[0] = static_cast<sal_uInt8>( 6 - 1 + 0x22 + ( 2 * ( 1 + msFamilyNm.getLength() ) ));
753  if (mbAlt)
754  maWW8_FFN[0] = static_cast< sal_uInt8 >(maWW8_FFN[0] + 2 * ( 1 + msAltNm.getLength()));
755 
756  sal_uInt8 aB = 0;
757  switch(ePitch)
758  {
759  case PITCH_VARIABLE:
760  aB |= 2; // aF.prg = 2
761  break;
762  case PITCH_FIXED:
763  aB |= 1;
764  break;
765  default: // aF.prg = 0 : DEFAULT_PITCH (windows.h)
766  break;
767  }
768  aB |= 1 << 2; // aF.fTrueType = 1; don't know any better;
769 
770  switch(eFamily)
771  {
772  case FAMILY_ROMAN:
773  aB |= 1 << 4; // aF.ff = 1;
774  break;
775  case FAMILY_SWISS:
776  aB |= 2 << 4; // aF.ff = 2;
777  break;
778  case FAMILY_MODERN:
779  aB |= 3 << 4; // aF.ff = 3;
780  break;
781  case FAMILY_SCRIPT:
782  aB |= 4 << 4; // aF.ff = 4;
783  break;
784  case FAMILY_DECORATIVE:
785  aB |= 5 << 4; // aF.ff = 5;
786  break;
787  default: // aF.ff = 0; FF_DONTCARE (windows.h)
788  break;
789  }
790  maWW8_FFN[1] = aB;
791 
792  ShortToSVBT16( 400, &maWW8_FFN[2] ); // don't know any better
793  // 400 == FW_NORMAL (windows.h)
794 
795  //#i61927# For unicode fonts like Arial Unicode, Word 97+ sets the chs
796  //to SHIFTJIS presumably to capture that it's a multi-byte encoding font
797  //but Word95 doesn't do this, and sets it to 0 (ANSI), so we should do the
798  //same
800 
801  if (mbAlt)
802  maWW8_FFN[5] = static_cast< sal_uInt8 >(msFamilyNm.getLength() + 1);
803 }
804 
805 void wwFont::Write(SvStream *pTableStrm) const
806 {
807  pTableStrm->WriteBytes(maWW8_FFN, sizeof(maWW8_FFN)); // fixed part
808  // from Ver8 following two fields intersected,
809  // we ignore them.
810  //char panose[ 10 ]; // 0x6 PANOSE
811  //char fs[ 24 ]; // 0x10 FONTSIGNATURE
812  SwWW8Writer::FillCount(*pTableStrm, 0x22);
813  SwWW8Writer::WriteString16(*pTableStrm, msFamilyNm, true);
814  if (mbAlt)
815  SwWW8Writer::WriteString16(*pTableStrm, msAltNm, true);
816 }
817 
818 void wwFont::WriteDocx( DocxAttributeOutput* rAttrOutput ) const
819 {
820  // no font embedding, panose id, subsetting, ... implemented
821 
822  if (msFamilyNm.isEmpty())
823  return;
824 
825  rAttrOutput->StartFont( msFamilyNm );
826 
827  if ( mbAlt )
828  rAttrOutput->FontAlternateName( msAltNm );
830  rAttrOutput->FontFamilyType( meFamily );
831  rAttrOutput->FontPitchType( mePitch );
832  rAttrOutput->EmbedFont( msFamilyNm, meFamily, mePitch );
833 
834  rAttrOutput->EndFont();
835 }
836 
837 void wwFont::WriteRtf( const RtfAttributeOutput* rAttrOutput ) const
838 {
839  rAttrOutput->FontFamilyType( meFamily, *this );
840  rAttrOutput->FontPitchType( mePitch );
841  rAttrOutput->FontCharset(
843  rAttrOutput->StartFont( msFamilyNm );
844  if ( mbAlt )
845  rAttrOutput->FontAlternateName( msAltNm );
846  rAttrOutput->EndFont();
847 }
848 
849 bool operator<(const wwFont &r1, const wwFont &r2)
850 {
851  int nRet = memcmp(r1.maWW8_FFN, r2.maWW8_FFN, sizeof(r1.maWW8_FFN));
852  if (nRet == 0)
853  {
854  nRet = r1.msFamilyNm.compareTo(r2.msFamilyNm);
855  if (nRet == 0)
856  nRet = r1.msAltNm.compareTo(r2.msAltNm);
857  }
858  return nRet < 0;
859 }
860 
861 sal_uInt16 wwFontHelper::GetId(const wwFont &rFont)
862 {
863  sal_uInt16 nRet;
864  std::map<wwFont, sal_uInt16>::const_iterator aIter = maFonts.find(rFont);
865  if (aIter != maFonts.end())
866  nRet = aIter->second;
867  else
868  {
869  nRet = static_cast< sal_uInt16 >(maFonts.size());
870  maFonts[rFont] = nRet;
871  }
872  return nRet;
873 }
874 
876 {
877  GetId(wwFont("Times New Roman", PITCH_VARIABLE,
878  FAMILY_ROMAN, RTL_TEXTENCODING_MS_1252));
879 
881  RTL_TEXTENCODING_SYMBOL));
882 
884  RTL_TEXTENCODING_MS_1252));
885 
886  const SvxFontItem* pFont = GetDfltAttr(RES_CHRATR_FONT);
887 
888  GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
889  pFont->GetFamily(), pFont->GetCharSet()));
890 
891  const SfxItemPool& rPool = rDoc.GetAttrPool();
892  pFont = rPool.GetPoolDefaultItem(RES_CHRATR_FONT);
893  if (nullptr != pFont)
894  {
895  GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
896  pFont->GetFamily(), pFont->GetCharSet()));
897  }
898 
899  if (!bLoadAllFonts)
900  return;
901 
902  const sal_uInt16 aTypes[] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT, 0 };
903  for (const sal_uInt16* pId = aTypes; *pId; ++pId)
904  {
905  for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(*pId))
906  {
907  pFont = static_cast<const SvxFontItem*>(pItem);
908  GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
909  pFont->GetFamily(), pFont->GetCharSet()));
910  }
911  }
912 }
913 
914 sal_uInt16 wwFontHelper::GetId(const SvxFontItem& rFont)
915 {
916  wwFont aFont(rFont.GetFamilyName(), rFont.GetPitch(), rFont.GetFamily(),
917  rFont.GetCharSet());
918  return GetId(aFont);
919 }
920 
921 std::vector< const wwFont* > wwFontHelper::AsVector() const
922 {
923  std::vector<const wwFont *> aFontList( maFonts.size() );
924 
925  for ( const auto& aFont : maFonts )
926  aFontList[aFont.second] = &aFont.first;
927 
928  return aFontList;
929 }
930 
931 void wwFontHelper::WriteFontTable(SvStream *pTableStream, WW8Fib& rFib)
932 {
933  rFib.m_fcSttbfffn = pTableStream->Tell();
934  /*
935  * Reserve some space to fill in the len after we know how big it is
936  */
937  SwWW8Writer::WriteLong(*pTableStream, 0);
938 
939  /*
940  * Convert from fast insertion map to linear vector in the order that we
941  * want to write.
942  */
943  std::vector<const wwFont *> aFontList( AsVector() );
944 
945  /*
946  * Write them all to pTableStream
947  */
948  for ( auto aFont : aFontList )
949  aFont->Write(pTableStream);
950 
951  /*
952  * Write the position and len in the FIB
953  */
954  rFib.m_lcbSttbfffn = pTableStream->Tell() - rFib.m_fcSttbfffn;
955  SwWW8Writer::WriteLong( *pTableStream, rFib.m_fcSttbfffn, maFonts.size());
956 }
957 
959 {
960  std::vector<const wwFont *> aFontList( AsVector() );
961 
962  for ( auto aFont : aFontList )
963  aFont->WriteDocx(&rAttrOutput);
964 }
965 
967 {
968  std::vector<const wwFont *> aFontList( AsVector() );
969 
970  for ( auto aFont : aFontList )
971  aFont->WriteRtf(&rAttrOutput);
972 }
973 
975  : nOfs( nOffset )
976 {
977 }
978 
979 void WW8_WrPlc0::Append( sal_uLong nStartCpOrFc )
980 {
981  aPos.push_back( nStartCpOrFc - nOfs );
982 }
983 
985 {
986  for( const auto& rPos : aPos )
987  {
988  rStrm.WriteUInt32(rPos);
989  }
990 }
991 
992 // class MSWordSections : translate PageDescs into Sections
993 // also deals with header and footer
994 
996  : mbDocumentIsProtected( false )
997 {
998  const SwSectionFormat *pFormat = nullptr;
999  rExport.m_pCurrentPageDesc = &rExport.m_rDoc.GetPageDesc( 0 );
1000 
1001  const SfxPoolItem* pI;
1002  const SwNode* pNd = rExport.m_pCurPam->GetContentNode();
1003  const SfxItemSet* pSet = pNd ? &static_cast<const SwContentNode*>(pNd)->GetSwAttrSet() : nullptr;
1004 
1005  sal_uLong nRstLnNum = pSet ? pSet->Get( RES_LINENUMBER ).GetStartValue() : 0;
1006 
1007  const SwTableNode* pTableNd = rExport.m_pCurPam->GetNode().FindTableNode();
1008  const SwSectionNode* pSectNd = nullptr;
1009  if ( pTableNd )
1010  {
1011  pSet = &pTableNd->GetTable().GetFrameFormat()->GetAttrSet();
1012  pNd = pTableNd;
1013  }
1014  else if (pNd && nullptr != ( pSectNd = pNd->FindSectionNode() ))
1015  {
1016  if ( SectionType::ToxHeader == pSectNd->GetSection().GetType() &&
1017  pSectNd->StartOfSectionNode()->IsSectionNode() )
1018  {
1019  pSectNd = pSectNd->StartOfSectionNode()->GetSectionNode();
1020  }
1021 
1022  if ( SectionType::ToxContent == pSectNd->GetSection().GetType() )
1023  {
1024  pNd = pSectNd;
1025  rExport.m_pCurPam->GetPoint()->nNode = *pNd;
1026  }
1027 
1028  if ( SectionType::Content == pSectNd->GetSection().GetType() )
1029  pFormat = pSectNd->GetSection().GetFormat();
1030  }
1031 
1032  // tdf#118393: FILESAVE: DOCX Export loses header/footer
1033  rExport.m_bFirstTOCNodeWithSection = pSectNd &&
1034  ( SectionType::ToxHeader == pSectNd->GetSection().GetType() ||
1035  SectionType::ToxContent == pSectNd->GetSection().GetType() );
1036 
1037  // Try to get page descriptor of the first node
1038  if ( pSet &&
1039  SfxItemState::SET == pSet->GetItemState( RES_PAGEDESC, true, &pI ) &&
1040  static_cast<const SwFormatPageDesc*>(pI)->GetPageDesc() )
1041  {
1042  AppendSection( *static_cast<const SwFormatPageDesc*>(pI), *pNd, pFormat, nRstLnNum );
1043  }
1044  else
1045  AppendSection( rExport.m_pCurrentPageDesc, pFormat, nRstLnNum, /*bIsFirstParagraph=*/true );
1046 }
1047 
1049  : MSWordSections( rExport )
1050  , m_bHeaderFooterWritten( false )
1051 {
1052  // to be in sync with the AppendSection() call in the MSWordSections
1053  // constructor
1054  aCps.push_back( 0 );
1055 }
1056 
1058 {
1059 }
1060 
1062 {
1063 }
1064 
1066 {
1067  return false; // only relevant for WW8
1068 }
1069 
1071 {
1072  return m_bHeaderFooterWritten;
1073 }
1074 
1075 sal_uInt16 MSWordSections::CurrentNumberOfColumns( const SwDoc &rDoc ) const
1076 {
1077  OSL_ENSURE( !aSects.empty(), "no segment inserted yet" );
1078  if ( aSects.empty() )
1079  return 1;
1080 
1081  return NumberOfColumns( rDoc, aSects.back() );
1082 }
1083 
1084 sal_uInt16 MSWordSections::NumberOfColumns( const SwDoc &rDoc, const WW8_SepInfo& rInfo )
1085 {
1086  const SwPageDesc* pPd = rInfo.pPageDesc;
1087  if ( !pPd )
1088  pPd = &rDoc.GetPageDesc( 0 );
1089 
1090  const SfxItemSet &rSet = pPd->GetMaster().GetAttrSet();
1092  aSet.SetParent( &rSet );
1093 
1094  //0xffffffff, what the hell is going on with that!, fixme most terribly
1095  if ( rInfo.pSectionFormat && reinterpret_cast<SwSectionFormat*>(sal_IntPtr(-1)) != rInfo.pSectionFormat )
1096  aSet.Put( rInfo.pSectionFormat->GetFormatAttr( RES_COL ) );
1097 
1098  const SwFormatCol& rCol = aSet.Get( RES_COL );
1099  const SwColumns& rColumns = rCol.GetColumns();
1100  return rColumns.size();
1101 }
1102 
1104 {
1105  if ( !aSects.empty() )
1106  return &aSects.back();
1107 
1108  return nullptr;
1109 }
1110 
1112  const SwSectionFormat* pSectionFormat, sal_uLong nLnNumRestartNo, bool bIsFirstParagraph )
1113 {
1114  if (HeaderFooterWritten()) {
1115  return; // #i117955# prevent new sections in endnotes
1116  }
1117  aSects.emplace_back( pPd, pSectionFormat, nLnNumRestartNo, std::nullopt, nullptr, bIsFirstParagraph );
1118  NeedsDocumentProtected( aSects.back() );
1119 }
1120 
1121 void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwPageDesc* pPd,
1122  const SwSectionFormat* pSectionFormat, sal_uLong nLnNumRestartNo )
1123 {
1124  if (HeaderFooterWritten()) {
1125  return; // #i117955# prevent new sections in endnotes
1126  }
1127  aCps.push_back( nStartCp );
1128  AppendSection( pPd, pSectionFormat, nLnNumRestartNo );
1129 }
1130 
1132  const SwNode& rNd, const SwSectionFormat* pSectionFormat, sal_uLong nLnNumRestartNo )
1133 {
1134  if (HeaderFooterWritten()) {
1135  return; // #i117955# prevent new sections in endnotes
1136  }
1137 
1138  WW8_SepInfo aI( rPD.GetPageDesc(), pSectionFormat, nLnNumRestartNo, rPD.GetNumOffset(), &rNd );
1139 
1140  aSects.push_back( aI );
1141  NeedsDocumentProtected( aI );
1142 }
1143 
1145  const SwNode& rNd, const SwSectionFormat* pSectionFormat, sal_uLong nLnNumRestartNo )
1146 {
1147  if (HeaderFooterWritten()) {
1148  return; // #i117955# prevent new sections in endnotes
1149  }
1150  aCps.push_back( nStartCp );
1151  AppendSection( rPD, rNd, pSectionFormat, nLnNumRestartNo );
1152 }
1153 
1155 {
1156  sal_uInt8 nInfoFlags = 0;
1157  const SwFootnoteInfo& rInfo = rWrt.m_rDoc.GetFootnoteInfo();
1158  if( !rInfo.m_aErgoSum.isEmpty() ) nInfoFlags |= 0x02;
1159  if( !rInfo.m_aQuoVadis.isEmpty() ) nInfoFlags |= 0x04;
1160 
1161  sal_uInt8 nEmptyStt = 0;
1162  if( nInfoFlags )
1163  {
1164  pTextPos->Append( nCpStt ); // empty footnote separator
1165 
1166  if( 0x02 & nInfoFlags ) // Footnote continuation separator
1167  {
1168  pTextPos->Append( nCpStt );
1169  rWrt.WriteStringAsPara( rInfo.m_aErgoSum );
1170  rWrt.WriteStringAsPara( OUString() );
1171  nCpStt = rWrt.Fc2Cp( rWrt.Strm().Tell() );
1172  }
1173  else
1174  pTextPos->Append( nCpStt );
1175 
1176  if( 0x04 & nInfoFlags ) // Footnote continuation notice
1177  {
1178  pTextPos->Append( nCpStt );
1179  rWrt.WriteStringAsPara( rInfo.m_aQuoVadis );
1180  rWrt.WriteStringAsPara( OUString() );
1181  nCpStt = rWrt.Fc2Cp( rWrt.Strm().Tell() );
1182  }
1183  else
1184  pTextPos->Append( nCpStt );
1185 
1186  nEmptyStt = 3;
1187  }
1188 
1189  while( 6 > nEmptyStt++ )
1190  pTextPos->Append( nCpStt );
1191 
1192  // set the flags at the Dop right away
1193  WW8Dop& rDop = *rWrt.pDop;
1194  // Footnote Info
1195  switch( rInfo.m_eNum )
1196  {
1197  case FTNNUM_PAGE: rDop.rncFootnote = 2; break;
1198  case FTNNUM_CHAPTER: rDop.rncFootnote = 1; break;
1199  default: rDop.rncFootnote = 0; break;
1200  } // rncFootnote
1202  rDop.nFootnote = rInfo.m_nFootnoteOffset + 1;
1203  rDop.fpc = rWrt.m_bFootnoteAtTextEnd ? 2 : 1;
1204 
1205  // Endnote Info
1206  rDop.rncEdn = 0; // rncEdn: Don't Restart
1207  const SwEndNoteInfo& rEndInfo = rWrt.m_rDoc.GetEndNoteInfo();
1209  rDop.nEdn = rEndInfo.m_nFootnoteOffset + 1;
1210  rDop.epc = rWrt.m_bEndAtTextEnd ? 3 : 0;
1211 }
1212 
1213 void MSWordSections::SetHeaderFlag( sal_uInt8& rHeadFootFlags, const SwFormat& rFormat,
1214  sal_uInt8 nFlag )
1215 {
1216  const SfxPoolItem* pItem;
1217  if( SfxItemState::SET == rFormat.GetItemState(RES_HEADER, true, &pItem)
1218  && static_cast<const SwFormatHeader*>(pItem)->IsActive() &&
1219  static_cast<const SwFormatHeader*>(pItem)->GetHeaderFormat() )
1220  rHeadFootFlags |= nFlag;
1221 }
1222 
1223 void MSWordSections::SetFooterFlag( sal_uInt8& rHeadFootFlags, const SwFormat& rFormat,
1224  sal_uInt8 nFlag )
1225 {
1226  const SfxPoolItem* pItem;
1227  if( SfxItemState::SET == rFormat.GetItemState(RES_FOOTER, true, &pItem)
1228  && static_cast<const SwFormatFooter*>(pItem)->IsActive() &&
1229  static_cast<const SwFormatFooter*>(pItem)->GetFooterFormat() )
1230  rHeadFootFlags |= nFlag;
1231 }
1232 
1233 void WW8_WrPlcSepx::OutHeaderFooter( WW8Export& rWrt, bool bHeader,
1234  const SwFormat& rFormat, sal_uLong& rCpPos, sal_uInt8 nHFFlags,
1235  sal_uInt8 nFlag, sal_uInt8 nBreakCode)
1236 {
1237  if ( nFlag & nHFFlags )
1238  {
1239  pTextPos->Append( rCpPos );
1240  rWrt.WriteHeaderFooterText( rFormat, bHeader);
1241  rWrt.WriteStringAsPara( OUString() ); // CR to the end ( otherwise WW complains )
1242  rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() );
1243  }
1244  else
1245  {
1246  pTextPos->Append( rCpPos );
1247  if ((bHeader? rWrt.m_bHasHdr : rWrt.m_bHasFtr) && nBreakCode!=0)
1248  {
1249  rWrt.WriteStringAsPara( OUString() ); // Empty paragraph for empty header/footer
1250  rWrt.WriteStringAsPara( OUString() ); // a CR that WW8 needs for end of the stream
1251  rCpPos = rWrt.Fc2Cp( rWrt.Strm().Tell() );
1252  }
1253  }
1254 }
1255 
1257 {
1258  if (rInfo.IsProtected())
1259  mbDocumentIsProtected = true;
1260 }
1261 
1263 {
1264  bool bRet = false;
1265  if (
1266  pSectionFormat &&
1267  (reinterpret_cast<SwSectionFormat*>(sal_IntPtr(-1)) != pSectionFormat)
1268  )
1269  {
1270  const SwSection *pSection = pSectionFormat->GetSection();
1271  if (pSection && pSection->IsProtect())
1272  {
1273  bRet = true;
1274  }
1275  }
1276  return bRet;
1277 }
1278 
1280 {
1281  // 2 values getting set
1282  // Dop.fFacingPages == Header and Footer different
1283  // Dop.fSwapBordersFacingPgs == mirrored borders
1284  sal_uInt16 nEnd = 0;
1285  for( const WW8_SepInfo& rSepInfo : aSects )
1286  {
1287  if( !rSepInfo.pSectionFormat )
1288  {
1289  const SwPageDesc* pPd = rSepInfo.pPageDesc;
1290  if( pPd->GetFollow() && pPd != pPd->GetFollow() &&
1291  pPd->GetFollow()->GetFollow() == pPd->GetFollow() &&
1292  rSepInfo.pPDNd &&
1293  pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) )
1294  // so this is first page and subsequent, so only respect follow
1295  pPd = pPd->GetFollow();
1296 
1297  // left-/right chain of pagedescs ?
1298  else if( !( 1 & nEnd ) &&
1299  pPd->GetFollow() && pPd != pPd->GetFollow() &&
1300  pPd->GetFollow()->GetFollow() == pPd &&
1301  (( UseOnPage::Left == ( UseOnPage::All & pPd->ReadUseOn() ) &&
1302  UseOnPage::Right == ( UseOnPage::All & pPd->GetFollow()->ReadUseOn() )) ||
1303  ( UseOnPage::Right == ( UseOnPage::All & pPd->ReadUseOn() ) &&
1304  UseOnPage::Left == ( UseOnPage::All & pPd->GetFollow()->ReadUseOn() )) ))
1305  {
1306  rWrt.pDop->fFacingPages = rWrt.pDop->fMirrorMargins = true;
1307  nEnd |= 1;
1308  }
1309 
1310  if( !( 1 & nEnd ) &&
1311  ( !pPd->IsHeaderShared() || !pPd->IsFooterShared() ))
1312  {
1313  rWrt.pDop->fFacingPages = true;
1314  nEnd |= 1;
1315  }
1316  if( !( 2 & nEnd ) &&
1318  {
1319  rWrt.pDop->fSwapBordersFacingPgs =
1320  rWrt.pDop->fMirrorMargins = true;
1321  nEnd |= 2;
1322  }
1323 
1324  if( 3 == nEnd )
1325  break; // We do not need to go any further
1326  }
1327  }
1328 }
1329 
1331 {
1332  const SfxPoolItem* pItem;
1333  return SfxItemState::SET == rFormat.GetItemState(RES_BOX, true, &pItem) &&
1334  ( static_cast<const SvxBoxItem*>(pItem)->GetTop() ||
1335  static_cast<const SvxBoxItem*>(pItem)->GetBottom() ||
1336  static_cast<const SvxBoxItem*>(pItem)->GetLeft() ||
1337  static_cast<const SvxBoxItem*>(pItem)->GetRight() );
1338 }
1339 
1341 {
1342  m_rWW8Export.pO->clear();
1343 }
1344 
1346 {
1348  const SwEndNoteInfo& rEndNoteInfo = m_rWW8Export.m_rDoc.GetEndNoteInfo();
1350  switch( rInfo.m_eNum )
1351  {
1352  case FTNNUM_PAGE: m_rWW8Export.pO->push_back( sal_uInt8/*rncRstPage*/ (2) ); break;
1353  case FTNNUM_CHAPTER: m_rWW8Export.pO->push_back( sal_uInt8/*rncRstSect*/ (1) ); break;
1354  default: m_rWW8Export.pO->push_back( sal_uInt8/*rncCont*/ (0) ); break;
1355  }
1356 
1361  nId = WW8Export::GetNumId(rEndNoteInfo.m_aFormat.GetNumberingType());
1363 }
1364 
1366 {
1367  //If the document is to be exported as protected, then if a segment
1368  //is not protected, set the unlocked flag
1369  if ( m_rWW8Export.pSepx->DocumentIsProtected() && !bProtected )
1370  {
1372  m_rWW8Export.pO->push_back( 1 );
1373  }
1374 }
1375 
1377 {
1378  // sprmSNLnnMod - activate Line Numbering and define Modulo
1381 
1382  // sprmSDxaLnn - xPosition of Line Number
1385 
1386  // sprmSLnc - restart number: 0 per page, 1 per section, 2 never restart
1387  if ( nRestartNo || !rLnNumInfo.IsRestartEachPage() )
1388  {
1390  m_rWW8Export.pO->push_back( nRestartNo ? 1 : 2 );
1391  }
1392 
1393  // sprmSLnnMin - Restart the Line Number with given value
1394  if ( nRestartNo )
1395  {
1397  SwWW8Writer::InsUInt16( *m_rWW8Export.pO, o3tl::narrowing<sal_uInt16>(nRestartNo) - 1 );
1398  }
1399 }
1400 
1402 {
1403  // sprmSFTitlePage
1405  m_rWW8Export.pO->push_back( 1 );
1406 }
1407 
1408 void WW8AttributeOutput::SectionPageBorders( const SwFrameFormat* pPdFormat, const SwFrameFormat* pPdFirstPgFormat )
1409 {
1410  // write border of page
1411  sal_uInt16 nPgBorder = MSWordSections::HasBorderItem( *pPdFormat ) ? 0 : USHRT_MAX;
1412  if ( pPdFormat != pPdFirstPgFormat )
1413  {
1414  if ( MSWordSections::HasBorderItem( *pPdFirstPgFormat ) )
1415  {
1416  if ( USHRT_MAX == nPgBorder )
1417  {
1418  nPgBorder = 1;
1419  // only the first page outlined -> Get the BoxItem from the correct format
1420  m_rWW8Export.m_pISet = &pPdFirstPgFormat->GetAttrSet();
1421  OutputItem( pPdFirstPgFormat->GetFormatAttr( RES_BOX ) );
1422  }
1423  }
1424  else if ( !nPgBorder )
1425  nPgBorder = 2;
1426  }
1427 
1428  // [MS-DOC] 2.9.255 SPgbPropOperand; 2.9.185 PgbOffsetFrom
1429  if (m_bFromEdge)
1430  nPgBorder |= (1<<5);
1431 
1432  if ( USHRT_MAX != nPgBorder )
1433  {
1434  // write the Flag and Border Attribute
1436  SwWW8Writer::InsUInt16( *m_rWW8Export.pO, nPgBorder );
1437  }
1438 }
1439 
1441 {
1443  m_rWW8Export.pO->push_back( bBiDi? 1: 0 );
1444 }
1445 
1446 void WW8AttributeOutput::SectionPageNumbering( sal_uInt16 nNumType, const ::std::optional<sal_uInt16>& oPageRestartNumber )
1447 {
1448  // sprmSNfcPgn
1449  sal_uInt8 nb = WW8Export::GetNumId( nNumType );
1451  m_rWW8Export.pO->push_back( nb );
1452 
1453  if ( oPageRestartNumber )
1454  {
1455  // sprmSFPgnRestart
1457  m_rWW8Export.pO->push_back( 1 );
1458 
1459  // sprmSPgnStart
1461  SwWW8Writer::InsUInt16( *m_rWW8Export.pO, *oPageRestartNumber );
1462  }
1463 }
1464 
1466 {
1467  if ( 2 != nBreakCode ) // new page is the default
1468  {
1470  m_rWW8Export.pO->push_back( nBreakCode );
1471  }
1472 }
1473 
1475 {
1476  if ( !pA )
1477  return;
1478 
1479  if ( !pO->empty() ) // are there attributes ?
1480  {
1481  pA->m_nLen = pO->size();
1482  pA->m_pData.reset(new sal_uInt8 [pO->size()]);
1483  // store for later
1484  memcpy( pA->m_pData.get(), pO->data(), pO->size() );
1485  pO->clear(); // clear HdFt-Text
1486  }
1487  else // no attributes there
1488  {
1489  pA->m_pData.reset();
1490  pA->m_nLen = 0;
1491  }
1492 }
1493 
1494 void WW8AttributeOutput::TextVerticalAdjustment( const drawing::TextVerticalAdjust nVA )
1495 {
1496  if ( drawing::TextVerticalAdjust_TOP == nVA ) // top alignment is the default
1497  return;
1498 
1499  sal_uInt8 nMSVA = 0;
1500  switch( nVA )
1501  {
1502  case drawing::TextVerticalAdjust_CENTER:
1503  nMSVA = 1;
1504  break;
1505  case drawing::TextVerticalAdjust_BOTTOM: //Writer = 2, Word = 3
1506  nMSVA = 3;
1507  break;
1508  case drawing::TextVerticalAdjust_BLOCK: //Writer = 3, Word = 2
1509  nMSVA = 2;
1510  break;
1511  default:
1512  break;
1513  }
1515  m_rWW8Export.pO->push_back( nMSVA );
1516 }
1517 
1519  const SwFrameFormat& rFormat, const SwFrameFormat& rLeftHeaderFormat, const SwFrameFormat& rLeftFooterFormat, const SwFrameFormat& rFirstPageFormat, sal_uInt8 nBreakCode, bool /*bEvenAndOddHeaders*/ )
1520 {
1521  sal_uLong nCpPos = Fc2Cp( Strm().Tell() );
1522 
1524  if ( !(nHeadFootFlags & WW8_HEADER_EVEN) && pDop->fFacingPages )
1525  pSepx->OutHeaderFooter( *this, true, rFormat, nCpPos, nHeadFootFlags, WW8_HEADER_ODD, nBreakCode );
1526  else
1527  pSepx->OutHeaderFooter( *this, true, rLeftHeaderFormat, nCpPos, nHeadFootFlags, WW8_HEADER_EVEN, nBreakCode );
1529  pSepx->OutHeaderFooter( *this, true, rFormat, nCpPos, nHeadFootFlags, WW8_HEADER_ODD, nBreakCode );
1530 
1532  if ( !(nHeadFootFlags & WW8_FOOTER_EVEN) && pDop->fFacingPages )
1533  pSepx->OutHeaderFooter( *this, false, rFormat, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD, nBreakCode );
1534  else
1535  pSepx->OutHeaderFooter( *this, false, rLeftFooterFormat, nCpPos, nHeadFootFlags, WW8_FOOTER_EVEN, nBreakCode );
1537  pSepx->OutHeaderFooter( *this, false, rFormat, nCpPos, nHeadFootFlags, WW8_FOOTER_ODD, nBreakCode );
1538 
1539  //#i24344# Drawing objects cannot be directly shared between main hd/ft
1540  //and title hd/ft so we need to differentiate them
1542  pSepx->OutHeaderFooter( *this, true, rFirstPageFormat, nCpPos, nHeadFootFlags, WW8_HEADER_FIRST, nBreakCode );
1543  pSepx->OutHeaderFooter( *this, false, rFirstPageFormat, nCpPos, nHeadFootFlags, WW8_FOOTER_FIRST, nBreakCode );
1544 }
1545 
1546 namespace
1547 {
1552 bool UsePrevSectionNextStyle(sal_uInt8 nBreakCode, const SwPageDesc* pPd,
1553  const WW8_SepInfo& rSepInfo)
1554 {
1555  if (nBreakCode != 0)
1556  {
1557  // Not a continuous section break.
1558  return false;
1559  }
1560 
1561  if (!pPd->GetFollow())
1562  {
1563  // Page style has no follow style.
1564  return false;
1565  }
1566 
1567  // We start a continuous section break without headers/footers. Possibly the importer had
1568  // headers/footers for this section break and put them to the closest page break's page style's
1569  // next page style. See "find a node in the section that has a page break" in writerfilter/.
1570  // Try the last-in-practice paragraph of the previous section.
1571  const SwSectionFormat* pSection = rSepInfo.pSectionFormat;
1572  if (pSection == reinterpret_cast<SwSectionFormat*>(sal_IntPtr(-1)))
1573  {
1574  return false;
1575  }
1576 
1577  const SwNodeIndex* pSectionStart = pSection->GetContent().GetContentIdx();
1578  if (!pSectionStart)
1579  {
1580  return false;
1581  }
1582 
1583  SwPaM aPaM(*pSectionStart);
1584  aPaM.Move(fnMoveBackward);
1585  if (!aPaM.GetNode().IsTextNode())
1586  {
1587  return false;
1588  }
1589 
1590  SwTextNode* pTextNode = aPaM.GetNode().GetTextNode();
1591  const SwAttrSet* pParaProps = &pTextNode->GetSwAttrSet();
1592  sal_uInt32 nCharHeight = pParaProps->GetSize().GetHeight();
1593  if (nCharHeight > 20)
1594  {
1595  return false;
1596  }
1597 
1598  aPaM.Move(fnMoveBackward);
1599  if (!aPaM.GetNode().IsTextNode())
1600  {
1601  return false;
1602  }
1603 
1604  pTextNode = aPaM.GetNode().GetTextNode();
1605  pParaProps = &pTextNode->GetSwAttrSet();
1606  return pParaProps->HasItem(RES_PAGEDESC);
1607 }
1608 }
1609 
1611 {
1612  const SwPageDesc* pPd = rSepInfo.pPageDesc;
1613 
1614  if ( rSepInfo.pSectionFormat && !pPd )
1615  pPd = &m_rDoc.GetPageDesc( 0 );
1616 
1617  m_pCurrentPageDesc = pPd;
1618 
1619  if ( !pPd )
1620  return;
1621 
1622  bool bOldPg = m_bOutPageDescs;
1623  m_bOutPageDescs = true;
1624 
1626 
1628 
1629  // forms
1631 
1632  // line numbers
1633  const SwLineNumberInfo& rLnNumInfo = m_rDoc.GetLineNumberInfo();
1634  if ( rLnNumInfo.IsPaintLineNumbers() )
1635  AttrOutput().SectionLineNumbering( rSepInfo.nLnNumRestartNo, rLnNumInfo );
1636 
1637  /* sprmSBkc, break code: 0 No break, 1 New column
1638  2 New page, 3 Even page, 4 Odd page
1639  */
1640  sal_uInt8 nBreakCode = 2; // default start new page
1641  bool bOutPgDscSet = true, bLeftRightPgChain = false, bOutputStyleItemSet = false;
1642  const SwFrameFormat* pPdFormat = &pPd->GetMaster();
1643  bool bUsePrevSectionNextStyle = false;
1644  if ( rSepInfo.pSectionFormat )
1645  {
1646  // if pSectionFormat is set, then there is a SectionNode
1647  // valid pointer -> start Section ,
1648  // 0xfff -> Section terminated
1649  nBreakCode = 0; // consecutive section
1650 
1651  if ( rSepInfo.pPDNd && rSepInfo.pPDNd->IsContentNode() )
1652  {
1653  if ( !NoPageBreakSection( &rSepInfo.pPDNd->GetContentNode()->GetSwAttrSet() ) )
1654  {
1655  nBreakCode = 2;
1656  }
1657  }
1658 
1659  if (reinterpret_cast<SwSectionFormat*>(sal_IntPtr(-1)) != rSepInfo.pSectionFormat)
1660  {
1661  if ( nBreakCode == 0 )
1662  bOutPgDscSet = false;
1663 
1664  // produce Itemset, which inherits PgDesk-Attr-Set:
1665  // as child also the parent is searched if 'deep'-OutputItemSet
1666  const SfxItemSet* pPdSet = &pPdFormat->GetAttrSet();
1667 
1668  bUsePrevSectionNextStyle = GetExportFormat() == ExportFormat::DOCX
1669  && UsePrevSectionNextStyle(nBreakCode, pPd, rSepInfo);
1670  if (bUsePrevSectionNextStyle)
1671  {
1672  // Take page margins from the previous section's next style.
1673  pPdSet = &pPd->GetFollow()->GetMaster().GetAttrSet();
1674  }
1675 
1676  SfxItemSet aSet( *pPdSet->GetPool(), pPdSet->GetRanges() );
1677  aSet.SetParent( pPdSet );
1678 
1679  // at the child ONLY change column structure according to Sect-Attr.
1680 
1681  const SvxLRSpaceItem &rSectionLR =
1682  ItemGet<SvxLRSpaceItem>( *(rSepInfo.pSectionFormat), RES_LR_SPACE );
1683  const SvxLRSpaceItem &rPageLR =
1684  ItemGet<SvxLRSpaceItem>( *pPdFormat, RES_LR_SPACE );
1685 
1686  SvxLRSpaceItem aResultLR( rPageLR.GetLeft() +
1687  rSectionLR.GetLeft(), rPageLR.GetRight() +
1688  rSectionLR.GetRight(), 0, 0, RES_LR_SPACE );
1689  //i120133: The Section width should consider section indent value.
1690  if (rSectionLR.GetLeft()+rSectionLR.GetRight()!=0)
1691  {
1692  const SwFormatCol& rCol = dynamic_cast<const SwFormatCol&>(rSepInfo.pSectionFormat->GetFormatAttr(RES_COL));
1693  SwFormatCol aCol(rCol);
1694  aCol.SetAdjustValue(rSectionLR.GetLeft()+rSectionLR.GetRight());
1695  aSet.Put(aCol);
1696  }
1697  else
1698  aSet.Put(rSepInfo.pSectionFormat->GetFormatAttr(RES_COL));
1699 
1700  aSet.Put( aResultLR );
1701 
1702  // and write into the WW-File
1703  const SfxItemSet* pOldI = m_pISet;
1704  m_pISet = &aSet;
1705 
1706  // Switch off test on default item values, if page description
1707  // set (value of <bOutPgDscSet>) isn't written.
1708  AttrOutput().OutputStyleItemSet( aSet, bOutPgDscSet );
1709  bOutputStyleItemSet = true;
1710 
1711  //Cannot export as normal page framedir, as continuous sections
1712  //cannot contain any grid settings like proper sections
1713  AttrOutput().SectionBiDi( SvxFrameDirection::Horizontal_RL_TB == TrueFrameDirection( *rSepInfo.pSectionFormat ) );
1714 
1715  m_pISet = pOldI;
1716  }
1717  }
1718 
1719  // Libreoffice 4.0 introduces support for page styles (SwPageDesc) with
1720  // a different header/footer for the first page. The same effect can be
1721  // achieved by chaining two page styles together (SwPageDesc::GetFollow)
1722  // which are identical except for header/footer.
1723  // The latter method was previously used by the doc/docx import filter.
1724  // In both of these cases, we emit a single Word section with different
1725  // first page header/footer.
1726  const SwFrameFormat* pPdFirstPgFormat = &pPd->GetFirstMaster();
1727  bool titlePage = !pPd->IsFirstShared();
1728  if ( bOutPgDscSet )
1729  {
1730  // if a Follow is set and it does not point to itself,
1731  // then there is a page chain.
1732  // If this emulates a "first page", we can detect it here and write
1733  // it as title page.
1734  // With Left/Right changes it's different - we have to detect where
1735  // the change of pages is, but here it's too late for that!
1736  if ( pPd->GetFollow() && pPd != pPd->GetFollow() &&
1737  pPd->GetFollow()->GetFollow() == pPd->GetFollow() &&
1738  pPd->IsHeaderShared() && pPd->IsFooterShared() &&
1739  ( !rSepInfo.pPDNd || pPd->IsFollowNextPageOfNode( *rSepInfo.pPDNd ) ) )
1740  {
1741  const SwPageDesc *pFollow = pPd->GetFollow();
1742  const SwFrameFormat& rFollowFormat = pFollow->GetMaster();
1743  if (sw::util::IsPlausableSingleWordSection(*pPdFirstPgFormat, rFollowFormat))
1744  {
1745  if (titlePage)
1746  {
1747  // Do nothing. First format is already set.
1748  }
1749  else if (rSepInfo.pPDNd)
1750  pPdFirstPgFormat = pPd->GetPageFormatOfNode( *rSepInfo.pPDNd );
1751  else
1752  pPdFirstPgFormat = &pPd->GetMaster();
1753 
1754  m_pCurrentPageDesc = pPd = pFollow;
1755  pPdFormat = &rFollowFormat;
1756 
1757  // has different headers/footers for the title page
1758  titlePage = true;
1759  }
1760  }
1761 
1762  const SfxItemSet* pOldI = m_pISet;
1763 
1764  const SfxPoolItem* pItem;
1765  if ( titlePage && SfxItemState::SET ==
1766  pPdFirstPgFormat->GetItemState( RES_PAPER_BIN, true, &pItem ) )
1767  {
1768  m_pISet = &pPdFirstPgFormat->GetAttrSet();
1769  m_bOutFirstPage = true;
1770  AttrOutput().OutputItem( *pItem );
1771  m_bOutFirstPage = false;
1772  }
1773 
1774  // left-/right chain of pagedescs ?
1775  if ( pPd->GetFollow() && pPd != pPd->GetFollow() &&
1776  pPd->GetFollow()->GetFollow() == pPd &&
1777  (( UseOnPage::Left == ( UseOnPage::All & pPd->ReadUseOn() ) &&
1778  UseOnPage::Right == ( UseOnPage::All & pPd->GetFollow()->ReadUseOn() )) ||
1779  ( UseOnPage::Right == ( UseOnPage::All & pPd->ReadUseOn() ) &&
1780  UseOnPage::Left == ( UseOnPage::All & pPd->GetFollow()->ReadUseOn() )) ))
1781  {
1782  bLeftRightPgChain = true;
1783 
1784  // which is the reference point? (left or right?)
1785  // assume it is on the right side!
1786  if ( UseOnPage::Left == ( UseOnPage::All & pPd->ReadUseOn() ) )
1787  {
1788  nBreakCode = 3;
1789  pPdFormat = &pPd->GetMaster(); //use the current page for settings (margins/width etc)
1790  pPd = pPd->GetFollow(); //switch to the right page for the right/odd header/footer
1791  }
1792  else
1793  nBreakCode = 4;
1794  }
1795 
1796  m_pISet = &pPdFormat->GetAttrSet();
1797  if (!bOutputStyleItemSet)
1798  {
1799  if (titlePage)
1800  {
1801  m_pFirstPageFormat = pPdFirstPgFormat;
1802  }
1803 
1804  AttrOutput().OutputStyleItemSet( pPdFormat->GetAttrSet(), false );
1805 
1806  if (titlePage)
1807  {
1808  m_pFirstPageFormat = nullptr;
1809  }
1810  }
1811  AttrOutput().SectionPageBorders( pPdFormat, pPdFirstPgFormat );
1812  m_pISet = pOldI;
1813 
1814  // then the rest of the settings from PageDesc
1816 
1817  // will it be only left or only right pages?
1818  if ( 2 == nBreakCode )
1819  {
1820  if ( UseOnPage::Left == ( UseOnPage::All & pPd->ReadUseOn() ) )
1821  nBreakCode = 3;
1822  else if ( UseOnPage::Right == ( UseOnPage::All & pPd->ReadUseOn() ) )
1823  nBreakCode = 4;
1824  }
1825  }
1826 
1827  if (titlePage)
1829 
1830  AttrOutput().SectionType( nBreakCode );
1831 
1832  if( rSepInfo.pPageDesc ) {
1834  }
1835 
1836  // Header or Footer
1837  sal_uInt8 nHeadFootFlags = 0;
1838  // Should we output a w:evenAndOddHeaders tag or not?
1839  // N.B.: despite its name this tag affects _both_ headers and footers!
1840  bool bEvenAndOddHeaders = true;
1841  bool bEvenAndOddFooters = true;
1842 
1843  const SwFrameFormat* pPdLeftHeaderFormat = nullptr;
1844  const SwFrameFormat* pPdLeftFooterFormat = nullptr;
1845  if (bLeftRightPgChain)
1846  {
1847  const SwFrameFormat* pHeaderFormat = pPd->GetStashedFrameFormat(true, true, true);
1848  const SwFrameFormat* pFooterFormat = pPd->GetStashedFrameFormat(false, true, true);
1849  if (pHeaderFormat)
1850  {
1851  pPdLeftHeaderFormat = pHeaderFormat;
1852  bEvenAndOddHeaders = false;
1853  }
1854  else
1855  {
1856  pPdLeftHeaderFormat = &pPd->GetFollow()->GetFirstLeft();
1857  }
1858  if (pFooterFormat)
1859  {
1860  pPdLeftFooterFormat = pFooterFormat;
1861  bEvenAndOddFooters = false;
1862  }
1863  else
1864  {
1865  pPdLeftFooterFormat = &pPd->GetFollow()->GetFirstLeft();
1866  }
1867  }
1868  else
1869  {
1870  const SwFrameFormat* pHeaderFormat = pPd->GetStashedFrameFormat(true, true, false);
1871  const SwFrameFormat* pFooterFormat = pPd->GetStashedFrameFormat(false, true, false);
1872  if (pHeaderFormat)
1873  {
1874  pPdLeftHeaderFormat = pHeaderFormat;
1875  bEvenAndOddHeaders = false;
1876  }
1877  else
1878  {
1879  pPdLeftHeaderFormat = &pPd->GetLeft();
1880  }
1881  if (pFooterFormat)
1882  {
1883  pPdLeftFooterFormat = pFooterFormat;
1884  bEvenAndOddFooters = false;
1885  }
1886  else
1887  {
1888  pPdLeftFooterFormat = &pPd->GetLeft();
1889  }
1890  }
1891 
1892  // Ensure that headers are written if section is first paragraph
1893  if (nBreakCode != 0 || (rSepInfo.pSectionFormat && rSepInfo.bIsFirstParagraph))
1894  {
1895  if ( titlePage )
1896  {
1897  // there is a First Page:
1898  MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFirstPgFormat, WW8_HEADER_FIRST );
1899  MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFirstPgFormat, WW8_FOOTER_FIRST );
1900  }
1901  else
1902  {
1903  if ( pPd->GetStashedFrameFormat(true, true, true) && pPdLeftHeaderFormat && pPdLeftHeaderFormat->GetHeader().GetHeaderFormat() )
1904  {
1905  MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdLeftHeaderFormat, WW8_HEADER_FIRST );
1906  }
1907  if ( pPd->GetStashedFrameFormat(false, true, true) && pPdLeftFooterFormat && pPdLeftFooterFormat->GetFooter().GetFooterFormat() )
1908  {
1909  MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdLeftFooterFormat, WW8_FOOTER_FIRST );
1910  }
1911  }
1912 
1913  MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdFormat, WW8_HEADER_ODD );
1914  MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdFormat, WW8_FOOTER_ODD );
1915 
1916  if ( !pPd->IsHeaderShared() || bLeftRightPgChain )
1917  {
1918  MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdLeftHeaderFormat, WW8_HEADER_EVEN );
1919  }
1920  else if ( pPd->IsHeaderShared() && pPd->GetStashedFrameFormat(true, true, false) && pPdLeftHeaderFormat && pPdLeftHeaderFormat->GetHeader().GetHeaderFormat() )
1921  {
1922  MSWordSections::SetHeaderFlag( nHeadFootFlags, *pPdLeftHeaderFormat, WW8_HEADER_EVEN );
1923  bEvenAndOddHeaders = false;
1924  }
1925 
1926  if ( !pPd->IsFooterShared() || bLeftRightPgChain )
1927  {
1928  MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdLeftFooterFormat, WW8_FOOTER_EVEN );
1929  }
1930  else if ( pPd->IsFooterShared() && pPd->GetStashedFrameFormat(false, true, false) && pPdLeftFooterFormat && pPdLeftFooterFormat->GetFooter().GetFooterFormat() )
1931  {
1932  MSWordSections::SetFooterFlag( nHeadFootFlags, *pPdLeftFooterFormat, WW8_FOOTER_EVEN );
1933  bEvenAndOddFooters = false;
1934  }
1935  }
1936 
1937  // binary filters only
1938  SetupSectionPositions( pA );
1939 
1940  /*
1941  !!!!!!!!!!!
1942  // borders at header and footer texts would be done like this:
1943  // This should use something like pOut,
1944  // which is repeated with every special text line.
1945  const SwFrameFormat* pFFormat = rFt.GetFooterFormat();
1946  const SvxBoxItem& rBox = pFFormat->GetBox(false);
1947  OutWW8_SwFormatBox1( m_rWW8Export.pOut, rBox, false);
1948  !!!!!!!!!!!
1949  You can turn this into paragraph attributes, which are then observed in each paragraph.
1950  Applies to background / border.
1951  !!!!!!!!!!!
1952  */
1953 
1954  const SwTextNode *pOldPageRoot = GetHdFtPageRoot();
1955  SetHdFtPageRoot( rSepInfo.pPDNd ? rSepInfo.pPDNd->GetTextNode() : nullptr );
1956 
1957  if (bUsePrevSectionNextStyle && nHeadFootFlags == 0)
1958  {
1959  // Take headers/footers from the previous section's next style.
1960  pPdFormat = &pPd->GetFollow()->GetMaster();
1961  MSWordSections::SetHeaderFlag(nHeadFootFlags, *pPdFormat, WW8_HEADER_ODD);
1962  MSWordSections::SetFooterFlag(nHeadFootFlags, *pPdFormat, WW8_FOOTER_ODD);
1963  }
1964 
1965  WriteHeadersFooters( nHeadFootFlags, *pPdFormat, *pPdLeftHeaderFormat, *pPdLeftFooterFormat, *pPdFirstPgFormat, nBreakCode, bEvenAndOddHeaders && bEvenAndOddFooters );
1966 
1967  SetHdFtPageRoot( pOldPageRoot );
1968 
1969  AttrOutput().EndSection();
1970 
1971  // outside of the section properties again
1972  m_bOutPageDescs = bOldPg;
1973 }
1974 
1976 {
1977  sal_uLong nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() );
1978 
1979  OSL_ENSURE( !pTextPos, "who set the pointer?" );
1980  pTextPos.reset( new WW8_WrPlc0( nCpStart ) );
1981 
1982  WriteFootnoteEndText( rWrt, nCpStart );
1983  CheckForFacinPg( rWrt );
1984 
1985  unsigned int nOldIndex = rWrt.GetHdFtIndex();
1986  rWrt.SetHdFtIndex( 0 );
1987 
1988  for (const WW8_SepInfo & rSepInfo : aSects)
1989  {
1990  auto pAttrDesc = std::make_shared<WW8_PdAttrDesc>();
1991  m_SectionAttributes.push_back(pAttrDesc);
1992 
1993  rWrt.SectionProperties( rSepInfo, pAttrDesc.get() );
1994 
1995  // FIXME: this writes the section properties, but not of all sections;
1996  // it's possible that later in the document (e.g. in endnotes) sections
1997  // are added, but they won't have their properties written here!
1998  m_bHeaderFooterWritten = true;
1999  }
2000  rWrt.SetHdFtIndex( nOldIndex ); //0
2001 
2002  if ( pTextPos->Count() )
2003  {
2004  // HdFt available?
2005  sal_uLong nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() );
2006  pTextPos->Append( nCpEnd ); // End of last Header/Footer for PlcfHdd
2007 
2008  if ( nCpEnd > nCpStart )
2009  {
2010  ++nCpEnd;
2011  pTextPos->Append( nCpEnd + 1 ); // End of last Header/Footer for PlcfHdd
2012 
2013  rWrt.WriteStringAsPara( OUString() ); // CR to the end ( otherwise WW complains )
2014  }
2015  rWrt.m_pFieldHdFt->Finish( nCpEnd, rWrt.pFib->m_ccpText + rWrt.pFib->m_ccpFootnote );
2016  rWrt.pFib->m_ccpHdr = nCpEnd - nCpStart;
2017  }
2018  else
2019  {
2020  pTextPos.reset();
2021  }
2022 
2023  return rWrt.pFib->m_ccpHdr != 0;
2024 }
2025 
2027 {
2028  OSL_ENSURE(m_SectionAttributes.size() == static_cast<size_t>(aSects.size())
2029  , "WriteSepx(): arrays out of sync!");
2030  for (const auto & rSectionAttribute : m_SectionAttributes) // all sections
2031  {
2032  WW8_PdAttrDesc *const pA = rSectionAttribute.get();
2033  if (pA->m_nLen && pA->m_pData != nullptr)
2034  {
2035  pA->m_nSepxFcPos = rStrm.Tell();
2036  rStrm.WriteUInt16(pA->m_nLen);
2037  rStrm.WriteBytes(pA->m_pData.get(), pA->m_nLen);
2038  }
2039  }
2040 }
2041 
2043 {
2044  OSL_ENSURE(m_SectionAttributes.size() == static_cast<size_t>(aSects.size())
2045  , "WritePlcSed(): arrays out of sync!");
2046  OSL_ENSURE( aCps.size() == aSects.size() + 1, "WrPlcSepx: DeSync" );
2047  sal_uInt64 nFcStart = rWrt.pTableStrm->Tell();
2048 
2049  for( decltype(aSects)::size_type i = 0; i <= aSects.size(); i++ )
2050  {
2051  sal_uInt32 nP = aCps[i];
2052  rWrt.pTableStrm->WriteUInt32(nP);
2053  }
2054 
2055  static WW8_SED aSed = {{4, 0},{0, 0, 0, 0},{0, 0},{0xff, 0xff, 0xff, 0xff}};
2056 
2057  for (const auto & rSectionAttribute : m_SectionAttributes)
2058  {
2059  // Sepx-Pos
2060  UInt32ToSVBT32( rSectionAttribute->m_nSepxFcPos, aSed.fcSepx );
2061  rWrt.pTableStrm->WriteBytes(&aSed, sizeof(aSed));
2062  }
2063  rWrt.pFib->m_fcPlcfsed = nFcStart;
2064  rWrt.pFib->m_lcbPlcfsed = rWrt.pTableStrm->Tell() - nFcStart;
2065 }
2066 
2068 {
2069  // Don't write out the PlcfHdd if ccpHdd is 0: it's a validation failure case.
2070  if( rWrt.pFib->m_ccpHdr != 0 && pTextPos && pTextPos->Count() )
2071  {
2072  rWrt.pFib->m_fcPlcfhdd = rWrt.pTableStrm->Tell();
2073  pTextPos->Write( *rWrt.pTableStrm ); // Plc0
2074  rWrt.pFib->m_lcbPlcfhdd = rWrt.pTableStrm->Tell() -
2075  rWrt.pFib->m_fcPlcfhdd;
2076  }
2077 }
2078 
2079 void MSWordExportBase::WriteHeaderFooterText( const SwFormat& rFormat, bool bHeader )
2080 {
2081  const SwFormatContent *pContent;
2082  if ( bHeader )
2083  {
2084  m_bHasHdr = true;
2085  const SwFormatHeader& rHd = rFormat.GetHeader();
2086  OSL_ENSURE( rHd.GetHeaderFormat(), "Header text is not here" );
2087  pContent = &rHd.GetHeaderFormat()->GetContent();
2088  }
2089  else
2090  {
2091  m_bHasFtr = true;
2092  const SwFormatFooter& rFt = rFormat.GetFooter();
2093  OSL_ENSURE( rFt.GetFooterFormat(), "Footer text is not here" );
2094  pContent = &rFt.GetFooterFormat()->GetContent();
2095  }
2096 
2097  const SwNodeIndex* pSttIdx = pContent->GetContentIdx();
2098 
2099  if ( pSttIdx )
2100  {
2101  SwNodeIndex aIdx( *pSttIdx, 1 ),
2102  aEnd( *pSttIdx->GetNode().EndOfSectionNode() );
2103  SwNodeOffset nStart = aIdx.GetIndex();
2104  SwNodeOffset nEnd = aEnd.GetIndex();
2105 
2106  // range, i.e. valid node
2107  if ( nStart < nEnd )
2108  {
2109  bool bOldKF = m_bOutKF;
2110  m_bOutKF = true;
2111  WriteSpecialText( nStart, nEnd, TXT_HDFT );
2112  m_bOutKF = bOldKF;
2113  }
2114  else
2115  pSttIdx = nullptr;
2116  }
2117 
2118  if ( !pSttIdx )
2119  {
2120  // there is no Header/Footer, but a CR is still necessary
2121  OSL_ENSURE( pSttIdx, "Header/Footer text is not really present" );
2123  }
2124 }
2125 
2126 // class WW8_WrPlcFootnoteEdn : Collect the Footnotes and Endnotes and output their text
2127 // and Plcs at the end of the document.
2128 // WW8_WrPlcFootnoteEdn is the class for Footnotes and Endnotes
2129 
2131 {
2132 }
2133 
2135 {
2136 }
2137 
2139 {
2140  aCps.push_back( nCp );
2141  aContent.push_back( &rFootnote );
2142 }
2143 
2144 WW8_Annotation::WW8_Annotation(const SwPostItField* pPostIt, WW8_CP nRangeStart, WW8_CP nRangeEnd)
2145  :
2147  m_nRangeStart(nRangeStart),
2148  m_nRangeEnd(nRangeEnd)
2149 {
2150  mpRichText = pPostIt->GetTextObject();
2151  if (!mpRichText)
2152  msSimpleText = pPostIt->GetText();
2153  msOwner = pPostIt->GetPar1();
2154  m_sInitials = pPostIt->GetInitials();
2155  maDateTime = DateTime(pPostIt->GetDate(), pPostIt->GetTime());
2156 }
2157 
2159  :
2160  mpRichText(nullptr),
2161  msSimpleText(pRedline->GetComment()),
2162  msOwner(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())),
2163  maDateTime(pRedline->GetTimeStamp()),
2164  m_nRangeStart(0),
2165  m_nRangeEnd(0)
2166 {
2167 }
2168 
2170 {
2171  if (m_nRangeStart != m_nRangeEnd)
2172  {
2173  return true;
2174  }
2175 
2176  return !m_bIgnoreEmpty;
2177 }
2178 
2179 void WW8_WrPlcAnnotations::AddRangeStartPosition(const OUString& rName, WW8_CP nStartCp,
2180  bool bIgnoreEmpty)
2181 {
2182  m_aRangeStartPositions[rName] = std::make_pair(nStartCp, bIgnoreEmpty);
2183 }
2184 
2186 {
2187  aCps.push_back( nCp );
2188  WW8_Annotation* p;
2189  if( m_aRangeStartPositions.find(pPostIt->GetName()) != m_aRangeStartPositions.end() )
2190  {
2191  auto [nStartCp, bIgnoreEmpty] = m_aRangeStartPositions[pPostIt->GetName()];
2192  p = new WW8_Annotation(pPostIt, nStartCp, nCp);
2193  p->m_bIgnoreEmpty = bIgnoreEmpty;
2194  m_aRangeStartPositions.erase(pPostIt->GetName());
2195  }
2196  else
2197  {
2198  p = new WW8_Annotation(pPostIt, nCp, nCp);
2199  }
2200  aContent.push_back( p );
2201 }
2202 
2204 {
2205  maProcessedRedlines.insert(pRedline);
2206  aCps.push_back( nCp );
2207  WW8_Annotation* p = new WW8_Annotation(pRedline);
2208  aContent.push_back( p );
2209 }
2210 
2212 {
2213  return maProcessedRedlines.find(pRedline) == maProcessedRedlines.end();
2214 }
2215 
2217 {
2218  for(const void * p : aContent)
2219  delete static_cast<WW8_Annotation const *>(p);
2220 }
2221 
2223  WW8_CP& rCount )
2224 {
2225  sal_uInt16 nLen = aContent.size();
2226  if ( !nLen )
2227  return false;
2228 
2229  sal_uLong nCpStart = rWrt.Fc2Cp( rWrt.Strm().Tell() );
2230  pTextPos.reset( new WW8_WrPlc0( nCpStart ) );
2231  sal_uInt16 i;
2232 
2233  switch ( nTTyp )
2234  {
2235  case TXT_ATN:
2236  for ( i = 0; i < nLen; i++ )
2237  {
2238  // beginning for PlcfAtnText
2239  pTextPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
2240 
2241  rWrt.WritePostItBegin();
2242  const WW8_Annotation& rAtn = *static_cast<const WW8_Annotation*>(aContent[i]);
2243  if (rAtn.mpRichText)
2244  rWrt.WriteOutliner(*rAtn.mpRichText, nTTyp);
2245  else
2246  {
2247  OUString sText(rAtn.msSimpleText);
2248  rWrt.WriteStringAsPara(sText.replace(0x0A, 0x0B));
2249  }
2250  }
2251  break;
2252 
2253  case TXT_TXTBOX:
2254  case TXT_HFTXTBOX:
2255  for ( i = 0; i < nLen; i++ )
2256  {
2257  // textbox content
2258  WW8_CP nCP = rWrt.Fc2Cp( rWrt.Strm().Tell() );
2259  aCps.insert( aCps.begin()+i, nCP );
2260  pTextPos->Append( nCP );
2261 
2262  if( aContent[ i ] != nullptr )
2263  {
2264  // is it a writer or sdr - textbox?
2265  const SdrObject& rObj = *static_cast<SdrObject const *>(aContent[ i ]);
2266  if (rObj.GetObjInventor() == SdrInventor::FmForm)
2267  {
2268  sal_uInt8 nOldTyp = rWrt.m_nTextTyp;
2269  rWrt.m_nTextTyp = nTTyp;
2270  rWrt.GetOCXExp().ExportControl(rWrt, dynamic_cast<const SdrUnoObj&>(rObj));
2271  rWrt.m_nTextTyp = nOldTyp;
2272  }
2273  else if( dynamic_cast<const SdrTextObj*>( &rObj) != nullptr )
2274  rWrt.WriteSdrTextObj(dynamic_cast<const SdrTextObj&>(rObj), nTTyp);
2275  else
2276  {
2277  const SwFrameFormat* pFormat = ::FindFrameFormat( &rObj );
2278  OSL_ENSURE( pFormat, "where is the format?" );
2279 
2280  const SwNodeIndex* pNdIdx = pFormat->GetContent().GetContentIdx();
2281  OSL_ENSURE( pNdIdx, "where is the StartNode of the Textbox?" );
2282  rWrt.WriteSpecialText( pNdIdx->GetIndex() + 1,
2283  pNdIdx->GetNode().EndOfSectionIndex(),
2284  nTTyp );
2285  {
2286  SwNodeIndex aContentIdx = *pNdIdx;
2287  ++aContentIdx;
2288  if ( aContentIdx.GetNode().IsTableNode() )
2289  {
2290  bool bContainsOnlyTables = true;
2291  do {
2292  aContentIdx = *(aContentIdx.GetNode().EndOfSectionNode());
2293  ++aContentIdx;
2294  if ( !aContentIdx.GetNode().IsTableNode() &&
2295  aContentIdx.GetIndex() != pNdIdx->GetNode().EndOfSectionIndex() )
2296  {
2297  bContainsOnlyTables = false;
2298  }
2299  } while ( aContentIdx.GetNode().IsTableNode() );
2300  if ( bContainsOnlyTables )
2301  {
2302  // Additional paragraph containing a space to
2303  // assure that by WW created RTF from written WW8
2304  // does not crash WW.
2305  rWrt.WriteStringAsPara( " " );
2306  }
2307  }
2308  }
2309  }
2310  }
2311  else if (i < aSpareFormats.size() && aSpareFormats[i])
2312  {
2313  const SwFrameFormat& rFormat = *aSpareFormats[i];
2314  const SwNodeIndex* pNdIdx = rFormat.GetContent().GetContentIdx();
2315  rWrt.WriteSpecialText( pNdIdx->GetIndex() + 1,
2316  pNdIdx->GetNode().EndOfSectionIndex(), nTTyp );
2317  }
2318 
2319  // CR at end of one textbox text ( otherwise WW gpft :-( )
2320  rWrt.WriteStringAsPara( OUString() );
2321  }
2322  break;
2323 
2324  case TXT_EDN:
2325  case TXT_FTN:
2326  for ( i = 0; i < nLen; i++ )
2327  {
2328  // beginning for PlcfFootnoteText/PlcfEdnText
2329  pTextPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
2330 
2331  // Note content
2332  const SwFormatFootnote* pFootnote = static_cast<SwFormatFootnote const *>(aContent[ i ]);
2333  rWrt.WriteFootnoteBegin( *pFootnote );
2334  const SwNodeIndex* pIdx = pFootnote->GetTextFootnote()->GetStartNode();
2335  OSL_ENSURE( pIdx, "Where is the start node of Foot-/Endnote?" );
2336  rWrt.WriteSpecialText( pIdx->GetIndex() + 1,
2337  pIdx->GetNode().EndOfSectionIndex(),
2338  nTTyp );
2339  }
2340  break;
2341 
2342  default:
2343  OSL_ENSURE( false, "What kind of SubDocType is that?" );
2344  }
2345 
2346  pTextPos->Append( rWrt.Fc2Cp( rWrt.Strm().Tell() ));
2347  // CR to the end ( otherwise WW complains )
2348  rWrt.WriteStringAsPara( OUString() );
2349 
2350  WW8_CP nCpEnd = rWrt.Fc2Cp( rWrt.Strm().Tell() );
2351  pTextPos->Append( nCpEnd );
2352  rCount = nCpEnd - nCpStart;
2353 
2354  return ( rCount != 0 );
2355 }
2356 
2357 static bool lcl_AuthorComp( const std::pair<OUString,OUString>& aFirst, const std::pair<OUString,OUString>& aSecond)
2358 {
2359  return aFirst.first < aSecond.first;
2360 }
2361 
2362 static bool lcl_PosComp( const std::pair<WW8_CP, int>& aFirst, const std::pair<WW8_CP, int>& aSecond)
2363 {
2364  return aFirst.first < aSecond.first;
2365 }
2366 
2368  WW8_FC& rTextStart, sal_Int32& rTextCount, WW8_FC& rRefStart, sal_Int32& rRefCount ) const
2369 {
2370 
2371  sal_uInt64 nFcStart = rWrt.pTableStrm->Tell();
2372  sal_uInt16 nLen = aCps.size();
2373  if ( !nLen )
2374  return;
2375 
2376  OSL_ENSURE( aCps.size() + 2 == pTextPos->Count(), "WritePlc: DeSync" );
2377 
2378  std::vector<std::pair<OUString,OUString> > aStrArr;
2379  WW8Fib& rFib = *rWrt.pFib; // n+1-th CP-Pos according to the manual
2380  bool bWriteCP = true;
2381 
2382  switch ( nTTyp )
2383  {
2384  case TXT_ATN:
2385  {
2386  std::vector< std::pair<WW8_CP, int> > aRangeStartPos; // The second of the pair is the original index before sorting.
2387  std::vector< std::pair<WW8_CP, int> > aRangeEndPos; // Same, so we can map between the indexes before/after sorting.
2388  std::map<int, int> aAtnStartMap; // Maps from annotation index to start index.
2389  std::map<int, int> aStartAtnMap; // Maps from start index to annotation index.
2390  std::map<int, int> aStartEndMap; // Maps from start index to end index.
2391  // then write first the GrpXstAtnOwners
2392  int nIdx = 0;
2393  for ( sal_uInt16 i = 0; i < nLen; ++i )
2394  {
2395  const WW8_Annotation& rAtn = *static_cast<const WW8_Annotation*>(aContent[i]);
2396  aStrArr.emplace_back(rAtn.msOwner,rAtn.m_sInitials);
2397  // record start and end positions for ranges
2398  if (rAtn.HasRange())
2399  {
2400  aRangeStartPos.emplace_back(rAtn.m_nRangeStart, nIdx);
2401  aRangeEndPos.emplace_back(rAtn.m_nRangeEnd, nIdx);
2402  ++nIdx;
2403  }
2404  }
2405 
2406  //sort and remove duplicates
2407  std::sort(aStrArr.begin(), aStrArr.end(),&lcl_AuthorComp);
2408  auto aIter = std::unique(aStrArr.begin(), aStrArr.end());
2409  aStrArr.erase(aIter, aStrArr.end());
2410 
2411  // Also sort the start and end positions. We need to reference
2412  // the start index in the annotation table and also need to
2413  // reference the end index in the start table, so build a map
2414  // that knows what index to reference, after sorting.
2415  std::sort(aRangeStartPos.begin(), aRangeStartPos.end(), &lcl_PosComp);
2416  for (decltype(aRangeStartPos)::size_type i = 0; i < aRangeStartPos.size(); ++i)
2417  {
2418  aAtnStartMap[aRangeStartPos[i].second] = i;
2419  aStartAtnMap[i] = aRangeStartPos[i].second;
2420  }
2421  std::sort(aRangeEndPos.begin(), aRangeEndPos.end(), &lcl_PosComp);
2422  for (decltype(aRangeEndPos)::size_type i = 0; i < aRangeEndPos.size(); ++i)
2423  aStartEndMap[aAtnStartMap[ aRangeEndPos[i].second ]] = i;
2424 
2425  for ( decltype(aStrArr)::size_type i = 0; i < aStrArr.size(); ++i )
2426  {
2427  const OUString& sAuthor = aStrArr[i].first;
2428  SwWW8Writer::WriteShort(*rWrt.pTableStrm, sAuthor.getLength());
2429  SwWW8Writer::WriteString16(*rWrt.pTableStrm, sAuthor,
2430  false);
2431  }
2432 
2433  rFib.m_fcGrpStAtnOwners = nFcStart;
2434  nFcStart = rWrt.pTableStrm->Tell();
2435  rFib.m_lcbGrpStAtnOwners = nFcStart - rFib.m_fcGrpStAtnOwners;
2436 
2437  // Commented text ranges
2438  if( !aRangeStartPos.empty() )
2439  {
2440  // Commented text ranges starting positions (Plcfbkf.aCP)
2441  rFib.m_fcPlcfAtnbkf = nFcStart;
2442  for ( decltype(aRangeStartPos)::size_type i = 0; i < aRangeStartPos.size(); ++i )
2443  {
2444  SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeStartPos[i].first );
2445  }
2446  SwWW8Writer::WriteLong( *rWrt.pTableStrm, rFib.m_ccpText + 1);
2447 
2448  // Commented text ranges additional information (Plcfbkf.aFBKF)
2449  for ( decltype(aRangeStartPos)::size_type i = 0; i < aRangeStartPos.size(); ++i )
2450  {
2451  SwWW8Writer::WriteShort( *rWrt.pTableStrm, aStartEndMap[i] ); // FBKF.ibkl
2452  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 ); // FBKF.bkc
2453  }
2454 
2455  nFcStart = rWrt.pTableStrm->Tell();
2456  rFib.m_lcbPlcfAtnbkf = nFcStart - rFib.m_fcPlcfAtnbkf;
2457 
2458  // Commented text ranges ending positions (PlcfBkl.aCP)
2459  rFib.m_fcPlcfAtnbkl = nFcStart;
2460  for ( decltype(aRangeEndPos)::size_type i = 0; i < aRangeEndPos.size(); ++i )
2461  {
2462  SwWW8Writer::WriteLong( *rWrt.pTableStrm, aRangeEndPos[i].first );
2463  }
2464  SwWW8Writer::WriteLong( *rWrt.pTableStrm, rFib.m_ccpText + 1);
2465 
2466  nFcStart = rWrt.pTableStrm->Tell();
2467  rFib.m_lcbPlcfAtnbkl = nFcStart - rFib.m_fcPlcfAtnbkl;
2468 
2469  // Commented text ranges as bookmarks (SttbfAtnBkmk)
2470  rFib.m_fcSttbfAtnbkmk = nFcStart;
2471  SwWW8Writer::WriteShort( *rWrt.pTableStrm, sal_Int16(sal_uInt16(0xFFFF)) ); // SttbfAtnBkmk.fExtend
2472  SwWW8Writer::WriteShort( *rWrt.pTableStrm, aRangeStartPos.size() ); // SttbfAtnBkmk.cData
2473  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0xA ); // SttbfAtnBkmk.cbExtra
2474 
2475  for ( decltype(aRangeStartPos)::size_type i = 0; i < aRangeStartPos.size(); ++i )
2476  {
2477  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 ); // SttbfAtnBkmk.cchData
2478  // One ATNBE structure for all text ranges
2479  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0x0100 ); // ATNBE.bmc
2480  SwWW8Writer::WriteLong( *rWrt.pTableStrm, aStartAtnMap[i] ); // ATNBE.lTag
2481  SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 ); // ATNBE.lTagOld
2482  }
2483 
2484  nFcStart = rWrt.pTableStrm->Tell();
2485  rFib.m_lcbSttbfAtnbkmk = nFcStart - rFib.m_fcSttbfAtnbkmk;
2486  }
2487 
2488  // Write the extended >= Word XP ATRD records
2489  for( sal_uInt16 i = 0; i < nLen; ++i )
2490  {
2491  const WW8_Annotation& rAtn = *static_cast<const WW8_Annotation*>(aContent[i]);
2492 
2493  sal_uInt32 nDTTM = sw::ms::DateTime2DTTM(rAtn.maDateTime);
2494 
2495  SwWW8Writer::WriteLong( *rWrt.pTableStrm, nDTTM );
2496  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
2497  SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
2498  SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
2499  SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
2500  }
2501 
2502  rFib.m_fcAtrdExtra = nFcStart;
2503  nFcStart = rWrt.pTableStrm->Tell();
2504  rFib.m_lcbAtrdExtra = nFcStart - rFib.m_fcAtrdExtra;
2505  rFib.m_fcHplxsdr = 0x01010002; //WTF, but apparently necessary
2506  rFib.m_lcbHplxsdr = 0;
2507  }
2508  break;
2509  case TXT_TXTBOX:
2510  case TXT_HFTXTBOX:
2511  {
2512  pTextPos->Write( *rWrt.pTableStrm );
2513  const std::vector<sal_uInt32>* pShapeIds = GetShapeIdArr();
2514  OSL_ENSURE( pShapeIds, "Where are the ShapeIds?" );
2515 
2516  for ( sal_uInt16 i = 0; i < nLen; ++i )
2517  {
2518  // write textbox story - FTXBXS
2519  // is it a writer or sdr - textbox?
2520  const SdrObject* pObj = static_cast<SdrObject const *>(aContent[ i ]);
2521  sal_Int32 nCnt = 1;
2522  if (dynamic_cast< const SdrTextObj *>( pObj ))
2523  {
2524  // find the "highest" SdrObject of this
2525  const SwFrameFormat& rFormat = *::FindFrameFormat( pObj );
2526 
2527  const SwFormatChain* pChn = &rFormat.GetChain();
2528  while ( pChn->GetNext() )
2529  {
2530  // has a chain?
2531  // then calc the cur pos in the chain
2532  ++nCnt;
2533  pChn = &pChn->GetNext()->GetChain();
2534  }
2535  }
2536  if( nullptr == pObj )
2537  {
2538  if (i < aSpareFormats.size() && aSpareFormats[i])
2539  {
2540  const SwFrameFormat& rFormat = *aSpareFormats[i];
2541 
2542  const SwFormatChain* pChn = &rFormat.GetChain();
2543  while( pChn->GetNext() )
2544  {
2545  // has a chain?
2546  // then calc the cur pos in the chain
2547  ++nCnt;
2548  pChn = &pChn->GetNext()->GetChain();
2549  }
2550  }
2551  }
2552  // long cTxbx / iNextReuse
2553  SwWW8Writer::WriteLong( *rWrt.pTableStrm, nCnt );
2554  // long cReusable
2555  SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
2556  // short fReusable
2557  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
2558  // long reserved
2559  SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 );
2560  // long lid
2562  (*pShapeIds)[i]);
2563  // long txidUndo
2564  SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 );
2565  }
2566  SwWW8Writer::FillCount( *rWrt.pTableStrm, 22 );
2567  bWriteCP = false;
2568  }
2569  break;
2570  }
2571 
2572  if ( bWriteCP )
2573  {
2574  // write CP Positions
2575  for ( sal_uInt16 i = 0; i < nLen; i++ )
2576  SwWW8Writer::WriteLong( *rWrt.pTableStrm, aCps[ i ] );
2577 
2578  // n+1-th CP-Pos according to the manual
2580  rFib.m_ccpText + rFib.m_ccpFootnote + rFib.m_ccpHdr + rFib.m_ccpEdn +
2581  rFib.m_ccpTxbx + rFib.m_ccpHdrTxbx + 1 );
2582 
2583  if ( TXT_ATN == nTTyp )
2584  {
2585  sal_uInt16 nlTag = 0;
2586  for ( sal_uInt16 i = 0; i < nLen; ++i )
2587  {
2588  const WW8_Annotation& rAtn = *static_cast<const WW8_Annotation*>(aContent[i]);
2589 
2590  //aStrArr is sorted
2591  auto aIter = std::lower_bound(aStrArr.begin(),
2592  aStrArr.end(), std::pair<OUString,OUString>(rAtn.msOwner,OUString()),
2593  &lcl_AuthorComp);
2594  OSL_ENSURE(aIter != aStrArr.end() && aIter->first == rAtn.msOwner,
2595  "Impossible");
2596  sal_uInt16 nFndPos = static_cast< sal_uInt16 >(aIter - aStrArr.begin());
2597  OUString sInitials( aIter->second );
2598  sal_uInt8 nInitialsLen = static_cast<sal_uInt8>(sInitials.getLength());
2599  if ( nInitialsLen > 9 )
2600  {
2601  sInitials = sInitials.copy( 0, 9 );
2602  nInitialsLen = 9;
2603  }
2604 
2605  // xstUsrInitl[ 10 ] pascal-style String holding initials
2606  // of annotation author
2607  SwWW8Writer::WriteShort(*rWrt.pTableStrm, nInitialsLen);
2608  SwWW8Writer::WriteString16(*rWrt.pTableStrm, sInitials,
2609  false);
2611  (9 - nInitialsLen) * 2 );
2612 
2613  // documents layout of WriteShort's below:
2614 
2615  // SVBT16 ibst; // index into GrpXstAtnOwners
2616  // SVBT16 ak; // not used
2617  // SVBT16 grfbmc; // not used
2618  // SVBT32 ITagBkmk; // when not -1, this tag identifies the ATNBE
2619 
2620  SwWW8Writer::WriteShort( *rWrt.pTableStrm, nFndPos );
2621  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
2622  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
2623  if (rAtn.HasRange())
2624  {
2625  SwWW8Writer::WriteLong( *rWrt.pTableStrm, nlTag );
2626  ++nlTag;
2627  }
2628  else
2629  SwWW8Writer::WriteLong( *rWrt.pTableStrm, -1 );
2630  }
2631  }
2632  else
2633  {
2634  sal_uInt16 nNo = 0;
2635  for ( sal_uInt16 i = 0; i < nLen; ++i ) // write Flags
2636  {
2637  const SwFormatFootnote* pFootnote = static_cast<SwFormatFootnote const *>(aContent[ i ]);
2639  !pFootnote->GetNumStr().isEmpty() ? 0 : ++nNo );
2640  }
2641  }
2642  }
2643  rRefStart = nFcStart;
2644  nFcStart = rWrt.pTableStrm->Tell();
2645  rRefCount = nFcStart - rRefStart;
2646 
2647  pTextPos->Write( *rWrt.pTableStrm );
2648 
2649  switch ( nTTyp )
2650  {
2651  case TXT_TXTBOX:
2652  case TXT_HFTXTBOX:
2653  for ( sal_uInt16 i = 0; i < nLen; ++i )
2654  {
2655  // write break descriptor (BKD)
2656  // short itxbxs
2658  // short dcpDepend
2659  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0 );
2660  // short flags : icol/fTableBreak/fColumnBreak/fMarked/
2661  // fUnk/fTextOverflow
2662  SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0x800 );
2663  }
2664  SwWW8Writer::FillCount( *rWrt.pTableStrm, 6 );
2665  break;
2666  }
2667 
2668  rTextStart = nFcStart;
2669  rTextCount = rWrt.pTableStrm->Tell() - nFcStart;
2670 }
2671 
2672 const std::vector<sal_uInt32>* WW8_WrPlcSubDoc::GetShapeIdArr() const
2673 {
2674  return nullptr;
2675 }
2676 
2677 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::map< wwFont, sal_uInt16 > maFonts
Keep track of fonts that need to be exported.
Definition: wrtww8.hxx:322
virtual void EndStyleProperties(bool bParProp) override
End of (paragraph or run) properties of a style.
Definition: wrtw8sty.cxx:545
o3tl::sorted_vector< const SwRedlineData * > maProcessedRedlines
Definition: wrtww8.hxx:1271
bool WriteGenericText(WW8Export &rWrt, sal_uInt8 nTTyp, WW8_CP &rCount)
Definition: wrtw8sty.cxx:2222
Date GetDate() const
Definition: docufld.hxx:481
sal_uInt16 CurrentNumberOfColumns(const SwDoc &rDoc) const
Number of columns based on the most recent WW8_SepInfo.
Definition: wrtw8sty.cxx:1075
WW8_CP m_nRangeEnd
Definition: wrtww8.hxx:1258
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:985
SvxNumType GetNumberingType() const
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:686
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
Subgroup labels.
Definition: poolfmt.hxx:345
static sal_uInt16 GetWWId(const SwFormat &rFormat)
Definition: wrtw8sty.cxx:210
constexpr TypedWhichId< SwFormatPageDesc > RES_PAGEDESC(93)
SwCharFormat * GetAnchorCharFormat(SwDoc &rDoc) const
Definition: docftn.cxx:182
const ::std::optional< sal_uInt16 > & GetNumOffset() const
Definition: fmtpdsc.hxx:64
Exporter of the binary Word file formats.
Definition: wrtww8.hxx:989
sal_uInt16 nEdn
Definition: ww8scan.hxx:1686
static bool lcl_AuthorComp(const std::pair< OUString, OUString > &aFirst, const std::pair< OUString, OUString > &aSecond)
Definition: wrtw8sty.cxx:2357
WW8_FC m_fcStshf
Definition: ww8scan.hxx:1250
virtual AttributeOutputBase & AttrOutput() const =0
Access to the attribute output class.
void SetHdFtIndex(unsigned int nHdFtIndex)
Definition: wrtww8.hxx:1134
const sw::BroadcastingModify * m_pOutFormatNode
Definition: wrtww8.hxx:538
void WriteProperties(const SwFormat *pFormat, bool bPap, sal_uInt16 nPos, bool bInsDefCharSiz)
Outputs attributes of one style.
Definition: wrtw8sty.cxx:525
const HdFtFlags WW8_FOOTER_FIRST
Definition: ww8scan.hxx:1601
sal_uInt16 rncEdn
Definition: ww8scan.hxx:1685
virtual void SectionTitlePage()=0
Has different headers/footers for the title page.
Class to collect and output the sections/headers/footers.
Definition: wrtww8.hxx:195
int GetAssignedOutlineStyleLevel() const
Definition: fmtcol.cxx:613
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:681
virtual void EndStyles(sal_uInt16 nNumberOfStyles)=0
End of the styles table.
std::unique_ptr< ww::bytes > pO
Buffer.
Definition: wrtww8.hxx:992
SvStream * pTableStrm
Definition: wrtww8.hxx:994
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
unsigned int GetHdFtIndex() const
Definition: wrtww8.hxx:1133
The class that has handlers for various resource types when exporting as DOCX.
void AddRangeStartPosition(const OUString &rName, WW8_CP nStartCp, bool bIgnoreEmpty)
Definition: wrtw8sty.cxx:2179
#define WW8_RESERVED_SLOTS
Definition: wrtw8sty.cxx:122
std::vector< SwColumn > SwColumns
Definition: fmtclds.hxx:57
const SvxFontHeightItem & GetSize(bool=true) const
Definition: charatr.hxx:77
bool IsSectionNode() const
Definition: node.hxx:648
std::unique_ptr< WW8Fib > pFib
File Information Block.
Definition: wrtww8.hxx:996
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_CTL_FONT(27)
sal_Int32 m_lcbStshf
Definition: ww8scan.hxx:1251
bool m_bEndAtTextEnd
Definition: wrtww8.hxx:563
FAMILY_SCRIPT
std::unique_ptr< WW8_WrPlcField > m_pFieldHdFt
Definition: wrtww8.hxx:526
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
SwFrameFormat & GetLeft()
Definition: pagedesc.hxx:239
void SetStyleDefaults(const SwFormat &rFormat, bool bPap)
Definition: wrtw8sty.cxx:448
sal_uInt8 SVBT16[2]
SvStream & WriteUInt16(sal_uInt16 nUInt16)
bool IsDefault() const
Definition: format.hxx:113
void WriteStringAsPara(const OUString &rText)
Definition: wrtww8.cxx:1778
SwPageDesc * GetPageDesc()
Definition: fmtpdsc.hxx:61
const SwLineNumberInfo & GetLineNumberInfo() const
Definition: lineinfo.cxx:49
bool HasRange() const
An annotation has a range if start != end or the m_bIgnoreEmpty flag is cleared.
Definition: wrtw8sty.cxx:2169
void OutputStyle(SwFormat *pFormat, sal_uInt16 nPos)
Outputs one style - called (in a loop) from OutputStylesTable().
Definition: wrtw8sty.cxx:601
const SwFormatHeader & GetHeader(bool=true) const
Definition: fmthdft.hxx:97
FAMILY_MODERN
virtual void StartStyleProperties(bool bParProp, sal_uInt16 nStyle) override
Start of (paragraph or run) properties of a style.
Definition: wrtw8sty.cxx:508
void Append(sal_uLong nStartCpOrFc)
Definition: wrtw8sty.cxx:979
sal_uInt16 GetId(const SwTextFormatColl &rColl) const
Return the numeric id of the style.
Definition: wrtw8sty.cxx:134
bool m_bFootnoteAtTextEnd
Definition: wrtww8.hxx:562
constexpr TypedWhichId< SwFormatHeader > RES_HEADER(96)
constexpr TypedWhichId< SwFormatCol > RES_COL(109)
WW8_CP m_nRangeStart
Definition: wrtww8.hxx:1258
bool mbAlt
Definition: wrtww8.hxx:304
sal_uInt16 m_nStyleStartSize
For output of styles.
void WriteSpecialText(SwNodeOffset nStart, SwNodeOffset nEnd, sal_uInt8 nTTyp)
Set the pCurPam appropriately and call WriteText().
Definition: wrtww8.cxx:1798
FontFamily meFamily
Definition: wrtww8.hxx:306
sal_uInt16 GetCountBy() const
Definition: lineinfo.hxx:74
virtual void EndStyles(sal_uInt16 nNumberOfStyles) override
End of the styles table.
Definition: wrtw8sty.cxx:693
void SetAdjustValue(sal_Int16 n)
Definition: fmtclds.hxx:96
OUString msFamilyNm
Definition: wrtww8.hxx:302
const SfxPoolItem * GetPoolDefaultItem(sal_uInt16 nWhich) const
virtual void SectFootnoteEndnotePr() override
for footnote/endnote section properties
Definition: wrtw8sty.cxx:1345
std::unique_ptr< sal_Int32[]> pData
void OutputStylesTable()
Output the styles table.
Definition: wrtw8sty.cxx:701
std::vector< const SwFrameFormat * > aSpareFormats
Definition: wrtww8.hxx:1221
Pages/field.
Definition: poolfmt.hxx:114
virtual void EndSection()=0
End of the section properties.
sal_uIntPtr sal_uLong
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_LANGUAGE(10)
tools::Long GetRight() const
void EndFont() const
End the font.
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_FONTSIZE(8)
void WriteFontTable(SvStream *pTableStream, WW8Fib &pFib)
Definition: wrtw8sty.cxx:931
constexpr TypedWhichId< SvxPaperBinItem > RES_PAPER_BIN(90)
SwFrameFormat & GetFirstMaster()
Definition: pagedesc.hxx:240
Doc. subtitle.
Definition: poolfmt.hxx:424
bool IsAutoRule() const
Definition: numrule.hxx:230
sal_Int64 n
const WhichRangesContainer & GetRanges() const
void WritePlcHdd(WW8Export &rWrt) const
Definition: wrtw8sty.cxx:2067
void WriteFootnoteEndText(WW8Export &rWrt, sal_uLong nCpStt)
Definition: wrtw8sty.cxx:1154
bool m_bOutPageDescs
PageDescs (section properties) are being written.
Definition: wrtww8.hxx:554
Definition: doc.hxx:188
constexpr sal_uInt16 RES_FRMATR_END(133)
sal_Int16 nfcFootnoteRef
Definition: ww8scan.hxx:1778
tools::Time GetTime() const
Definition: docufld.hxx:482
virtual void StartStyle(const OUString &rName, StyleType eType, sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 nWwId, sal_uInt16 nId, bool bAutoUpdate)=0
Start of a style in the styles table.
void StartFont(const OUString &rFamilyName) const
Start the font.
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:93
sal_Int16 nId
Content 1st level.
Definition: poolfmt.hxx:375
virtual bool CollapseScriptsforWordOk(sal_uInt16 nScript, sal_uInt16 nWhich)=0
Guess the script (asian/western).
virtual OUString GetPar1() const override
Author.
Definition: docufld.cxx:1800
const_iterator find(const Value &x) const
void WriteRtf(const RtfAttributeOutput *rAttrOutput) const
Definition: wrtw8sty.cxx:837
SwNode & GetNode() const
Definition: ndindex.hxx:121
const OUString & GetName() const
Definition: numrule.hxx:225
virtual void StartStyles() override
Start of the styles table.
Definition: wrtw8sty.cxx:671
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:31
SwSectionFormat * GetFormat()
Definition: section.hxx:340
WW8_FC m_fcPlcfAtnbkf
Definition: ww8scan.hxx:1396
constexpr TypedWhichId< SwConditionTextFormatColl > RES_CONDTXTFMTCOLL(160)
FAMILY_ROMAN
WW8_CP Fc2Cp(sal_uLong nFc) const
Definition: wrtww8.hxx:1101
void BuildStyleIds()
Based on pFormatA, fill in m_aStyleIds with unique, MS-like names.
Definition: wrtw8sty.cxx:341
MSWordStyles(const MSWordStyles &)=delete
static constexpr sal_uInt16 val
Definition: sprmids.hxx:277
virtual void SectionFormProtection(bool bProtected) override
Protection of forms.
Definition: wrtw8sty.cxx:1365
virtual const std::vector< sal_uInt32 > * GetShapeIdArr() const
Definition: wrtw8sty.cxx:2672
bool m_bOutFirstPage
Definition: wrtww8.hxx:555
virtual bool HeaderFooterWritten() override
Definition: wrtw8sty.cxx:1070
std::vector< const wwFont * > AsVector() const
Convert from fast insertion map to linear vector in the order that we want to write.
Definition: wrtw8sty.cxx:921
std::vector< sal_uLong > aPos
Definition: wrtw8sty.cxx:107
const SwNumRule * GetSwNumRule(sal_uInt16 nId) const
Get numbering rule of the nId-th style.
Definition: wrtw8sty.cxx:729
::std::optional< sal_uInt16 > oPgRestartNo
Definition: wrtww8.hxx:179
const SfxItemSet * GetCurItemSet() const
Getter for pISet.
Definition: wrtww8.hxx:730
sal_uInt16 nPOPosStdLen1
For output of styles.
FontPitch GetPitch() const
rtl_TextEncoding meChrSet
Definition: wrtww8.hxx:307
virtual ExportFormat GetExportFormat() const =0
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:205
OString const & GetStyleId(sal_uInt16 nId) const
Get styleId of the nId-th style (nId is its position in pFormatA).
Definition: wrtw8sty.cxx:379
FontFamily GetFamily() const
sal_uInt32 m_lcbAtrdExtra
Definition: ww8scan.hxx:1485
sal_uLong m_nStyleCountPos
For output of styles.
Content 5th level.
Definition: poolfmt.hxx:379
static void SetHeaderFlag(sal_uInt8 &rHeadFootFlags, const SwFormat &rFormat, sal_uInt8 nFlag)
Definition: wrtw8sty.cxx:1213
sal_uInt8 SVBT32[4]
#define MSWORD_MAX_STYLES_LIMIT
Definition: wrtww8.hxx:1632
WW8_FC m_fcSttbfAtnbkmk
Definition: ww8scan.hxx:1369
const SwSection & GetSection() const
Definition: node.hxx:543
virtual void WriteHeadersFooters(sal_uInt8 nHeadFootFlags, const SwFrameFormat &rFormat, const SwFrameFormat &rLeftHeaderFormat, const SwFrameFormat &rLeftFooterFormat, const SwFrameFormat &rFirstPageFormat, sal_uInt8 nBreakCode, bool bEvenAndOddHeaders) override
Output the actual headers and footers.
Definition: wrtw8sty.cxx:1518
void SectionProperties(const WW8_SepInfo &rSectionInfo, WW8_PdAttrDesc *pA=nullptr)
Write section properties.
Definition: wrtw8sty.cxx:1610
const SwTextFootnote * GetTextFootnote() const
Definition: fmtftn.hxx:83
std::vector< WW8_SepInfo > aSects
Definition: wrtww8.hxx:199
sal_uInt16 sal_Unicode
bool IsAssignedToListLevelOfOutlineStyle() const
Definition: fmtcol.hxx:120
bool IsRestartEachPage() const
Definition: lineinfo.hxx:89
constexpr sal_uInt16 RES_PARATR_BEGIN(RES_TXTATR_END)
void FontCharset(sal_uInt8 nCharSet) const
Font charset.
void FontPitchType(FontPitch ePitch) const
Font pitch.
bool IsFollowNextPageOfNode(const SwNode &rNd) const
Definition: pagedesc.cxx:367
virtual void WriteHeadersFooters(sal_uInt8 nHeadFootFlags, const SwFrameFormat &rFormat, const SwFrameFormat &rLeftHeaderFormat, const SwFrameFormat &rLeftFooterFormat, const SwFrameFormat &rFirstPageFormat, sal_uInt8 nBreakCode, bool bEvenAndOddHeaders)=0
Output the actual headers and footers.
virtual void EndStyle()=0
End of a style in the styles table.
const SwFrameFormat * m_pFirstPageFormat
Definition: wrtww8.hxx:458
void OutputFormat(const SwFormat &rFormat, bool bPapFormat, bool bChpFormat, bool bFlyFormat=false)
Output attributes.
Definition: ww8atr.cxx:822
rtl_TextEncoding GetCharSet() const
const SwTextFormatColl * GetDfltTextFormatColl() const
Definition: doc.hxx:776
virtual void SectionLineNumbering(sal_uLong nRestartNo, const SwLineNumberInfo &rLnNumInfo) override
Numbering of the lines in the document.
Definition: wrtw8sty.cxx:1376
void StartFont(const OUString &rFamilyName) const
Start the font.
The class that has handlers for various resource types when exporting as RTF.
const OUString & GetName() const
Definition: format.hxx:115
Footer, for pageformats Client of FrameFormat describing the footer.
Definition: fmthdft.hxx:64
bool bIsFirstParagraph
Definition: wrtww8.hxx:180
StyleType
FontPitch mePitch
Definition: wrtww8.hxx:305
const OUString & GetText() const
Definition: docufld.hxx:492
std::shared_ptr< SwUnoCursor > & m_pCurPam
Definition: wrtww8.hxx:577
Content 6th level.
Definition: poolfmt.hxx:389
SvStream & WriteUInt32(sal_uInt32 nUInt32)
void Append(WW8_CP nCp, const SwPostItField *pPostIt)
Definition: wrtw8sty.cxx:2185
void WritePostItBegin(ww::bytes *pO=nullptr)
Definition: ww8atr.cxx:2666
const SwTable & GetTable() const
Definition: node.hxx:500
const HdFtFlags WW8_FOOTER_EVEN
Definition: ww8scan.hxx:1598
DateTime maDateTime
Definition: wrtww8.hxx:1257
void Set_UInt16(sal_uInt8 *&p, sal_uInt16 n)
Definition: ww8struc.hxx:47
const SfxPoolItem * GetDfltAttr(sal_uInt16 nWhich)
Get the default attribute from corresponding default attribute table.
Definition: hints.cxx:153
const OUString & GetNumStr() const
Definition: fmtftn.hxx:68
void Write(SvStream *pTableStram) const
Definition: wrtw8sty.cxx:805
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:154
virtual OUString GetName() const override
PITCH_VARIABLE
void FontAlternateName(const OUString &rName) const
Alternate name for the font.
Text body indent.
Definition: poolfmt.hxx:254
virtual void SectFootnoteEndnotePr()
for footnote/endnote section properties
SwFrameFormat * FindFrameFormat(SdrObject *pObj)
The Get reverse way: seeks the format to the specified object.
Definition: dcontact.cxx:120
std::map< sal_uInt16, const SwNumRule * > m_aNumRules
Slot <-> List style map.
Definition: wrtww8.hxx:1578
bool IsNewRedlineComment(const SwRedlineData *pRedLine)
Definition: wrtw8sty.cxx:2211
virtual void EndStyle() override
End of a style in the styles table.
Definition: wrtw8sty.cxx:391
void OutputItem(const SfxPoolItem &rHt)
Call the right virtual function according to the type of the item.
Definition: ww8atr.cxx:5357
FAMILY_DECORATIVE
bool m_bHeaderFooterWritten
Definition: wrtww8.hxx:247
SwAttrPool * GetPool() const
Definition: swatrset.hxx:183
virtual void SectionBiDi(bool bBiDi) override
Columns populated from right/numbers on the right side?
Definition: wrtw8sty.cxx:1440
virtual void DefaultStyle() override
Write default style.
Definition: wrtw8sty.cxx:586
Collects and outputs fonts.
Definition: wrtww8.hxx:296
virtual void TextVerticalAdjustment(const css::drawing::TextVerticalAdjust) override
Definition: wrtw8sty.cxx:1494
virtual void SetupSectionPositions(WW8_PdAttrDesc *)
Setup the pA's info.
Definition: wrtww8.hxx:779
sal_uInt16 GetPoolFormatId() const
Get and set Pool style IDs.
Definition: format.hxx:147
constexpr TypedWhichId< SvxHyphenZoneItem > RES_PARATR_HYPHENZONE(69)
const HdFtFlags WW8_HEADER_ODD
Definition: ww8scan.hxx:1597
void Write(SvStream &rStrm)
Definition: wrtw8sty.cxx:984
Base class for various Writer styles.
Definition: format.hxx:46
sal_uInt16 rncFootnote
Definition: ww8scan.hxx:1628
sal_Int32 m_lcbGrpStAtnOwners
Definition: ww8scan.hxx:1367
void ExportControl(WW8Export &rWrt, const SdrUnoObj &rFormObj)
Definition: wrtw8esh.cxx:3029
SwMSConvertControls & GetOCXExp()
Definition: wrtww8.hxx:1049
static void WriteString16(SvStream &rStrm, const OUString &rStr, bool bAddZero)
Definition: wrtww8.cxx:1742
virtual void SetupSectionPositions(WW8_PdAttrDesc *pA) override
Setup the pA's info.
Definition: wrtw8sty.cxx:1474
bool IsProtected() const
Definition: wrtw8sty.cxx:1262
bool IsContentNode() const
Definition: node.hxx:632
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
bool IsHeaderShared() const
Definition: pagedesc.hxx:319
const SwTextNode * GetHdFtPageRoot() const
Top node of host page when in header/footer.
Definition: wrtww8.hxx:785
void FontFamilyType(FontFamily eFamily, const wwFont &rFont) const
Font family.
sal_uInt16 GetPosFromLeft() const
Definition: lineinfo.hxx:71
SwFootnoteNum m_eNum
Definition: ftninfo.hxx:98
virtual ~MSWordSections()
Definition: wrtw8sty.cxx:1057
WW8Export & m_rWW8Export
Reference to the export, where to get the data from.
virtual ~WW8_WrPlcSubDoc()
Definition: wrtw8sty.cxx:2134
void EndFont() const
End the font.
Style of a layout element.
Definition: frmfmt.hxx:59
WW8_FC m_fcHplxsdr
Definition: ww8scan.hxx:1518
#define SW_MOD()
Definition: swmodule.hxx:256
const OutlinerParaObject * mpRichText
Definition: wrtww8.hxx:1253
OUString msOwner
Definition: wrtww8.hxx:1255
Footnote anchor.
Definition: poolfmt.hxx:127
virtual void SectionType(sal_uInt8 nBreakCode)=0
The type of breaking.
void WritePlcSed(WW8Export &rWrt) const
Definition: wrtw8sty.cxx:2042
sal_Int16 nfcEdnRef
Definition: ww8scan.hxx:1779
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
void SetCurItemSet(const SfxItemSet *pS)
Setter for pISet.
Definition: wrtww8.hxx:733
Complimentary close.
Definition: poolfmt.hxx:255
const SwSectionFormat * pSectionFormat
Definition: wrtww8.hxx:176
void BuildStylesTable()
Create the style table, called from the constructor.
Definition: wrtw8sty.cxx:280
static sal_uInt16 NumberOfColumns(const SwDoc &rDoc, const WW8_SepInfo &rInfo)
Number of columns of the provided WW8_SepInfo.
Definition: wrtw8sty.cxx:1084
Internet visited.
Definition: poolfmt.hxx:121
int i
const SwColumns & GetColumns() const
Definition: fmtclds.hxx:112
std::unique_ptr< WW8_WrPlcSepx > pSepx
Sections/headers/footers.
Definition: wrtww8.hxx:1000
WW8_FC m_nSepxFcPos
Definition: wrtw8sty.cxx:82
std::vector< WW8_CP > aCps
Definition: wrtww8.hxx:1219
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:133
WW8_CP m_ccpHdrTxbx
Definition: ww8scan.hxx:1216
const SwFrameFormat * GetFooterFormat() const
Definition: fmthdft.hxx:85
WW8_WrPlcSepx(const WW8_WrPlcSepx &)=delete
For the output of sections.
Definition: wrtw8sty.cxx:78
Subgroup footer.
Definition: poolfmt.hxx:336
sal_Int32 m_lcbSttbfAtnbkmk
Definition: ww8scan.hxx:1370
bool IsProtect() const
Definition: section.cxx:342
const SwFrameFormat * GetStashedFrameFormat(bool bHeader, bool bLeft, bool bFirst) const
Used to restore hidden header/footer formats.
Definition: pagedesc.cxx:446
PITCH_FIXED
const SwPageDesc & GetPageDesc(const size_t i) const
Definition: doc.hxx:881
sal_uInt16 epc
Definition: ww8scan.hxx:1687
void WriteDocx(DocxAttributeOutput *rAttrOutput) const
Definition: wrtw8sty.cxx:818
void FontAlternateName(const OUString &rName) const
Alternate name for the font.
void CheckForFacinPg(const WW8Export &rWrt) const
Definition: wrtw8sty.cxx:1279
virtual void DefaultStyle()=0
Write default style.
sal_uInt8 rtl_TextEncodingToWinCharsetRTF(OUString const &rFontName, OUString const &rAltName, rtl_TextEncoding eTextEncoding)
MSOffice appears to set the charset of unicode fonts to MS 932.
DateTime maDateTime
std::unique_ptr< WW8Dop > pDop
Document Properties.
Definition: wrtww8.hxx:997
Text body.
Definition: poolfmt.hxx:251
bool m_bFirstTOCNodeWithSection
Definition: wrtww8.hxx:498
std::unique_ptr< WW8_WrPlc0 > pTextPos
Definition: wrtww8.hxx:1222
sal_uInt16 m_nFootnoteOffset
Definition: ftninfo.hxx:47
static bool lcl_PosComp(const std::pair< WW8_CP, int > &aFirst, const std::pair< WW8_CP, int > &aSecond)
Definition: wrtw8sty.cxx:2362
bool mbDocumentIsProtected
Definition: wrtww8.hxx:198
SwContentNode * GetContentNode()
Definition: node.hxx:619
static void WriteShort(SvStream &rStrm, sal_Int16 nVal)
Definition: wrtww8.hxx:962
std::unique_ptr< SwFormat *[]> m_pFormatA
Slot <-> Character and paragraph style array (0 for list styles).
Definition: wrtww8.hxx:1575
tools::Long GetLeft() const
UseOnPage ReadUseOn() const
Definition: pagedesc.hxx:236
std::vector< const void * > aContent
Definition: wrtww8.hxx:1220
static sal_uInt8 GetNumId(sal_uInt16 eNumType)
Converts the SVX numbering type to MSONFC.
Definition: ww8atr.cxx:728
virtual void SectionPageNumbering(sal_uInt16 nNumType, const ::std::optional< sal_uInt16 > &oPageRestartNumber)=0
The style of the page numbers.
WW8_FC m_fcGrpStAtnOwners
Definition: ww8scan.hxx:1366
const WW8_SepInfo * CurrentSectionInfo()
The most recent WW8_SepInfo.
Definition: wrtw8sty.cxx:1103
std::size_t WriteBytes(const void *pData, std::size_t nSize)
virtual void StartStyle(const OUString &rName, StyleType eType, sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 nWwIdi, sal_uInt16 nId, bool bAutoUpdate) override
Start of a style in the styles table.
Definition: wrtw8sty.cxx:405
Internet normal.
Definition: poolfmt.hxx:120
size_t size() const
Definition: docary.hxx:88
Header Left&Right.
Definition: poolfmt.hxx:331
const SwFormatFooter & GetFooter(bool=true) const
Definition: fmthdft.hxx:99
void EmbedFont(std::u16string_view name, FontFamily family, FontPitch pitch)
Write out the font into the document, if it's an embedded font.
SvxNumberType m_aFormat
Definition: ftninfo.hxx:46
virtual bool HeaderFooterWritten()
Definition: wrtw8sty.cxx:1065
Endnote anchor.
Definition: poolfmt.hxx:128
SwDoc & m_rDoc
Definition: wrtww8.hxx:575
OUString msSimpleText
Definition: wrtww8.hxx:1254
void AppendSep(WW8_CP nStartCp, const SwPageDesc *pPd, const SwSectionFormat *pSectionFormat, sal_uLong nLnNumRestartNo)
Definition: wrtw8sty.cxx:1121
virtual void StartSection()=0
Start of the section properties.
bool operator<(const wwFont &r1, const wwFont &r2)
Definition: wrtw8sty.cxx:849
virtual void SectionTitlePage() override
Has different headers/footers for the title page.
Definition: wrtw8sty.cxx:1401
std::vector< OString > m_aStyleIds
We need to build style id's for DOCX export; ideally we should roundtrip that, but this is good enoug...
Definition: wrtww8.hxx:1581
Label drawing objects.
Definition: poolfmt.hxx:358
sal_uLong nLnNumRestartNo
Definition: wrtww8.hxx:178
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:388
Connection (text flow) between two FlyFrames.
Definition: fmtcnct.hxx:31
constexpr TypedWhichId< SwTextFormatColl > RES_TXTFMTCOLL(157)
Marks a node in the document model.
Definition: ndindex.hxx:32
std::unique_ptr< sal_uInt8[]> m_pData
Definition: wrtw8sty.cxx:80
bool IsFooterShared() const
Definition: pagedesc.hxx:323
wwFont(const OUString &rFamilyName, FontPitch ePitch, FontFamily eFamily, rtl_TextEncoding eChrSet)
Definition: wrtw8sty.cxx:738
static void SetFooterFlag(sal_uInt8 &rHeadFootFlags, const SwFormat &rFormat, sal_uInt8 nFlag)
Definition: wrtw8sty.cxx:1223
bool m_bListStyles
If list styles are requested to be exported as well.
Definition: wrtww8.hxx:1577
void WriteGenericPlc(WW8Export &rWrt, sal_uInt8 nTTyp, WW8_FC &rTextStt, sal_Int32 &rTextCnt, WW8_FC &rRefStt, sal_Int32 &rRefCnt) const
Definition: wrtw8sty.cxx:2367
const_iterator end() const
sal_Int32 m_lcbStshfOrig
Definition: ww8scan.hxx:1249
MSWordExportBase & m_rExport
Definition: wrtww8.hxx:1573
bool empty() const
void InsUInt16(sal_uInt16 n)
Definition: wrtww8.hxx:1153
bool IsAutoUpdateFormat() const
Query / set bAutoUpdateFormat-flag.
Definition: format.hxx:172
WW8_CP m_ccpTxbx
Definition: ww8scan.hxx:1215
FontPitch
Find suitable names for exporting this font.
Definition: msfilter.hxx:243
virtual void SectionPageNumbering(sal_uInt16 nNumType, const ::std::optional< sal_uInt16 > &oPageRestartNumber) override
The style of the page numbers.
Definition: wrtw8sty.cxx:1446
static bool HasBorderItem(const SwFormat &rFormat)
Should we output borders?
Definition: wrtw8sty.cxx:1330
virtual void SectionPageBorders(const SwFrameFormat *pFormat, const SwFrameFormat *pFirstPageFormat)=0
Description of the page borders.
Represents the style of a text portion.
Definition: charfmt.hxx:26
void SetHdFtPageRoot(const SwTextNode *pNd)
Top node of host page when in header/footer.
Definition: wrtww8.hxx:782
SfxItemPool * GetPool() const
const SvXMLTokenMapEntry aTypes[]
void OutHeaderFooter(WW8Export &rWrt, bool bHeader, const SwFormat &rFormat, sal_uLong &rCpPos, sal_uInt8 nHFFlags, sal_uInt8 nFlag, sal_uInt8 nBreakCode)
Definition: wrtw8sty.cxx:1233
WW8_FC m_fcAtrdExtra
Definition: ww8scan.hxx:1484
SwFlyFrameFormat * GetNext() const
Definition: fmtcnct.hxx:54
Text body first line indent.
Definition: poolfmt.hxx:252
const OUString & GetName() const
Definition: docufld.hxx:495
virtual SdrInventor GetObjInventor() const
< purpose of derivation from SwClient: character style for displaying the numbers.
Definition: lineinfo.hxx:37
sal_Int32 WW8_CP
Definition: ww8struc.hxx:153
static OString CreateStyleId(const OUString &rName)
create style id using only ASCII characters of the style name
Definition: wrtw8sty.cxx:321
virtual void EndStyleProperties(bool bParProp)=0
End of (paragraph or run) properties of a style.
STD - STyle Definition.
Definition: ww8struc.hxx:169
std::vector< std::shared_ptr< WW8_PdAttrDesc > > m_SectionAttributes
Definition: wrtww8.hxx:245
size_t size() const
Definition: charformats.hxx:71
virtual void SectionFormProtection(bool bProtected)=0
Protection of forms.
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:267
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
void FontPitchType(FontPitch ePitch) const
Font pitch.
virtual ~WW8_WrPlcAnnotations() override
Definition: wrtw8sty.cxx:2216
void SetParent(const SfxItemSet *pNew)
void WriteHeaderFooterText(const SwFormat &rFormat, bool bHeader)
Write header/footer text.
Definition: wrtw8sty.cxx:2079
WW8_FC m_fcSttbfffn
Definition: ww8scan.hxx:1301
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
void AppendSection(const SwPageDesc *pPd, const SwSectionFormat *pSectionFormat, sal_uLong nLnNumRestartNo, bool bIsFirstParagraph=false)
Definition: wrtw8sty.cxx:1111
void NeedsDocumentProtected(const WW8_SepInfo &rInfo)
Definition: wrtw8sty.cxx:1256
WW8_CP m_ccpEdn
Definition: ww8scan.hxx:1214
FontFamily
const OUString & GetFamilyName() const
WW8_FC m_fcPlcfAtnbkl
Definition: ww8scan.hxx:1399
SwFormat * DerivedFrom() const
Definition: format.hxx:112
SwFrameFormat & GetMaster()
Definition: pagedesc.hxx:238
sal_uInt16 BuildGetSlot(const SwFormat &rFormat)
Get slot number during building the style table.
Definition: wrtw8sty.cxx:181
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
Content 9th level.
Definition: poolfmt.hxx:392
bool m_bIgnoreEmpty
Definition: wrtww8.hxx:1259
constexpr OUStringLiteral EMPTY
const OutlinerParaObject * GetTextObject() const
Definition: docufld.hxx:497
drawing::TextVerticalAdjust GetVerticalAdjustment() const
Definition: pagedesc.hxx:263
Doc. appendix.
Definition: poolfmt.hxx:425
constexpr sal_uInt16 RES_TXTATR_END(RES_TXTATR_NOEND_END)
virtual void StartStyleProperties(bool bParProp, sal_uInt16 nStyle)=0
Start of (paragraph or run) properties of a style.
sal_uInt32 GetHeight() const
const SwPageDesc * m_pCurrentPageDesc
Definition: wrtww8.hxx:497
const SwPageDesc * pPageDesc
Definition: wrtww8.hxx:175
const SwCharFormats * GetCharFormats() const
Definition: doc.hxx:740
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
const SwFormatChain & GetChain(bool=true) const
Definition: fmtcnct.hxx:70
const SwFrameFormat * GetPageFormatOfNode(const SwNode &rNd, bool bCheckForThisPgDc=true) const
Definition: pagedesc.cxx:342
SwCharFormat * GetCharFormat(SwDoc &rDoc) const
Definition: docftn.cxx:140
void Append(WW8_CP nCp, const SwFormatFootnote &rFootnote)
Definition: wrtw8sty.cxx:2138
SvStream & Strm() const
Definition: wrtww8.hxx:1182
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
bool IsPaintLineNumbers() const
Definition: lineinfo.hxx:80
const SwTextFormatColls * GetTextFormatColls() const
Definition: doc.hxx:778
SvBaseLink * pLink
unsigned char sal_uInt8
sal_uInt16 m_aHeadingParagraphStyles[MAXLEVEL]
Definition: wrtww8.hxx:1574
sal_uInt8 rtl_TextEncodingToWinCharset(rtl_TextEncoding eTextEncoding)
MSOffice appears to set the charset of unicode fonts to MS 932.
sal_uInt32 DateTime2DTTM(const DateTime &rDT)
Convert from DTTM to Writer's DateTime.
SwFrameFormat & GetFirstLeft()
Definition: pagedesc.hxx:241
const SwNumRuleTable & GetNumRuleTable() const
Definition: doc.hxx:1066
Marginalia.
Definition: poolfmt.hxx:258
bool bLoadAllFonts
If true, all fonts are loaded before processing the document.
Definition: wrtww8.hxx:338
OUString aName
FAMILY_SWISS
sal_Int32 m_lcbSttbfffn
Definition: ww8scan.hxx:1302
bool WriteKFText(WW8Export &rWrt)
Definition: wrtw8sty.cxx:1975
const HdFtFlags WW8_HEADER_FIRST
Definition: ww8scan.hxx:1600
Document Properties.
Definition: ww8scan.hxx:1605
sal_uInt16 Count() const
Definition: wrtw8sty.cxx:115
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_CJK_FONT(22)
virtual ~WW8_WrPlcSepx() override
Definition: wrtw8sty.cxx:1061
void FontCharset(sal_uInt8 nCharSet, rtl_TextEncoding nEncoding) const
Font charset.
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
void WriteFootnoteBegin(const SwFormatFootnote &rFootnote, ww::bytes *pO=nullptr)
Definition: ww8atr.cxx:3438
WW8_WrPlc0(WW8_WrPlc0 const &)=delete
static void impl_SkipOdd(std::unique_ptr< ww::bytes > const &pO, std::size_t nTableStrmTell)
For WW8 only - extend pO so that the size of pTableStrm is even.
Definition: wrtw8sty.cxx:385
sal_uInt8 m_nTextTyp
Definition: wrtww8.hxx:548
WW8_Annotation(const SwPostItField *pPostIt, WW8_CP nRangeStart, WW8_CP nRangeEnd)
Definition: wrtw8sty.cxx:2144
bool HasItem(sal_uInt16 nWhich, const SfxPoolItem **ppItem=nullptr) const
void WriteSdrTextObj(const SdrTextObj &rObj, sal_uInt8 nTyp)
Definition: wrtw8esh.cxx:1317
void IncrementHdFtIndex()
Definition: wrtww8.hxx:1135
virtual void EmptyParagraph()=0
Empty paragraph.
sal_uInt16 GetId(const SvxFontItem &rFont)
Definition: wrtw8sty.cxx:914
sal_uInt64 Tell() const
void * p
FIB - the File Information Block.
Definition: ww8scan.hxx:1104
const SfxPoolItem & GetFormatAttr(sal_uInt16 nWhich, bool bInParents=true) const
If bInParents is FALSE, search only in this format for attribute.
Definition: format.cxx:369
void WriteSepx(SvStream &rStrm) const
Definition: wrtw8sty.cxx:2026
std::unique_ptr< WW8_WrPlc0 > pTextPos
Definition: wrtww8.hxx:248
virtual void StartSection() override
Start of the section properties.
Definition: wrtw8sty.cxx:1340
sal_uInt16 GetSlot(const SwFormat *pFormat) const
Get id of the style (rFormat).
Definition: wrtw8sty.cxx:172
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
WW8_CP m_ccpText
Definition: ww8scan.hxx:1209
sal_uInt16 fpc
Definition: ww8scan.hxx:1623
sal_uLong nOfs
Definition: wrtw8sty.cxx:108
bool IsPlausableSingleWordSection(const SwFrameFormat &rTitleFormat, const SwFrameFormat &rFollowFormat)
See if two page formats can be expressed as a single word section.
virtual void SectionBiDi(bool bBiDi)=0
Columns populated from right/numbers on the right side?
WW8_CP m_ccpFootnote
Definition: ww8scan.hxx:1210
std::vector< WW8_CP > aCps
Definition: wrtww8.hxx:244
SvStream & WriteChar(char nChar)
OUString m_sInitials
Definition: wrtww8.hxx:1256
Header, for PageFormats Client of FrameFormat describing the header.
Definition: fmthdft.hxx:33
static void InsUInt16(ww::bytes &rO, sal_uInt16 n)
Definition: wrtww8.cxx:1707
sal_uInt16 m_nLen
Definition: wrtw8sty.cxx:81
sal_uInt32 m_lcbHplxsdr
Definition: ww8scan.hxx:1519
void OutputStyleItemSet(const SfxItemSet &rSet, bool bTestForDefault)
Use OutputItem() on an item set - for styles.
Definition: ww8atr.cxx:5606
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:718
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
void InitFontTable(const SwDoc &rDoc)
rDoc used only to get the initial standard font(s) in use.
Definition: wrtw8sty.cxx:875
sal_uInt16 m_nUsedSlots
Definition: wrtww8.hxx:1576
OUString msAltNm
Definition: wrtww8.hxx:303
OUString m_aQuoVadis
Definition: ftninfo.hxx:95
virtual void SectionLineNumbering(sal_uLong nRestartNo, const SwLineNumberInfo &rLnNumInfo)=0
Numbering of the lines in the document.
virtual bool ignoreAttributeForStyleDefaults(sal_uInt16) const
Used to filter out attributes that can be e.g. written to .doc but not to .docx.
Definition: wrtww8.hxx:691
constexpr TypedWhichId< SwFormatFooter > RES_FOOTER(97)
SwNodeIndex * GetStartNode() const
Definition: txtftn.hxx:41
Line numbering.
Definition: poolfmt.hxx:125
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:634
const SwFormat * m_pCurrentStyle
Definition: wrtww8.hxx:539
Base class for WW8Export and DocxExport.
Definition: wrtww8.hxx:450
bool IsTableNode() const
Definition: node.hxx:644
constexpr TypedWhichId< SwFormatLineNumber > RES_LINENUMBER(116)
Subgroup index tables.
Definition: poolfmt.hxx:367
WW8_FC m_fcStshfOrig
Definition: ww8scan.hxx:1246
Subgroup table of contents.
Definition: poolfmt.hxx:374
SwSectionNode * GetSectionNode()
Definition: node.hxx:611
virtual void StartStyles()=0
Start of the styles table.
virtual void SectionPageBorders(const SwFrameFormat *pFormat, const SwFrameFormat *pFirstPageFormat) override
Description of the page borders.
Definition: wrtw8sty.cxx:1408
const SfxItemSet * m_pISet
Definition: wrtww8.hxx:457
bool IsFirstShared() const
Definition: pagedesc.cxx:397
void WriteOutliner(const OutlinerParaObject &rOutliner, sal_uInt8 nTyp)
Definition: wrtw8esh.cxx:1341
void GetStyleData(SwFormat *pFormat, bool &bFormatColl, sal_uInt16 &nBase, sal_uInt16 &nNext, sal_uInt16 &nLink)
Return information about one style.
Definition: wrtw8sty.cxx:552
SectionType GetType() const
Definition: section.hxx:173
static bool NoPageBreakSection(const SfxItemSet *pSet)
Definition: wrtw8nds.cxx:3218
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:120
std::map< const OUString, std::pair< WW8_CP, bool > > m_aRangeStartPositions
Definition: wrtww8.hxx:1273
const OUString & GetInitials() const
Definition: docufld.hxx:493
SwSection * GetSection() const
Definition: section.cxx:660
std::pair< const_iterator, bool > insert(Value &&x)
MSWordSections(const MSWordSections &)
index of authorities.
Definition: poolfmt.hxx:408
sal_Int32 WW8_FC
Definition: ww8struc.hxx:152
sal_uInt8 maWW8_FFN[6]
Definition: wrtww8.hxx:301
static void WriteLong(SvStream &rStrm, sal_Int32 nVal)
Definition: wrtww8.hxx:965
static void FillCount(SvStream &rStrm, sal_uLong nCount)
Definition: wrtww8.cxx:931
virtual void TextVerticalAdjustment(const css::drawing::TextVerticalAdjust)
WW8_CP m_ccpHdr
Definition: ww8scan.hxx:1211
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:630
SvxFrameDirection TrueFrameDirection(const SwFrameFormat &rFlyFormat) const
Right to left?
Definition: wrtw8nds.cxx:1669
static void InsAsString16(ww::bytes &rO, const OUString &rStr)
Definition: wrtww8.cxx:1725
const SwEndNoteInfo & GetEndNoteInfo() const
Definition: doc.hxx:632
virtual void SectionType(sal_uInt8 nBreakCode) override
The type of breaking.
Definition: wrtw8sty.cxx:1465
constexpr TypedWhichId< SvxWidowsItem > RES_PARATR_WIDOWS(67)
OUString m_aErgoSum
Definition: ftninfo.hxx:96
sal_uInt16 nFootnote
Definition: ww8scan.hxx:1629
sal_Int32 m_lcbPlcfAtnbkl
Definition: ww8scan.hxx:1400
const SwFrameFormat * GetHeaderFormat() const
Definition: fmthdft.hxx:54
const HdFtFlags WW8_FOOTER_ODD
Definition: ww8scan.hxx:1599
sal_Int32 m_lcbPlcfAtnbkf
Definition: ww8scan.hxx:1397
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1319
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:856
const SwNode * pPDNd
Definition: wrtww8.hxx:177
std::unique_ptr< MSWordStyles > m_pStyles
Definition: wrtww8.hxx:502
const HdFtFlags WW8_HEADER_EVEN
Definition: ww8scan.hxx:1596
void FontFamilyType(FontFamily eFamily) const
Font family.
Base class of the Writer document model elements.
Definition: node.hxx:81
const SvxNumberType & GetNumType() const
Definition: pagedesc.hxx:202