LibreOffice Module sw (master)  1
wrtw8num.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 <hintids.hxx>
21 #include <vcl/font.hxx>
22 #include <editeng/langitem.hxx>
23 #include <doc.hxx>
24 #include <docary.hxx>
25 #include <numrule.hxx>
26 #include <charfmt.hxx>
27 #include <com/sun/star/i18n/ScriptType.hpp>
28 
29 #include "sprmids.hxx"
30 
31 #include "ww8attributeoutput.hxx"
32 #include "writerhelper.hxx"
33 #include "writerwordglue.hxx"
34 #include "wrtww8.hxx"
35 #include "ww8par.hxx"
36 
37 #include <numeric>
38 
39 using namespace ::com::sun::star;
40 using namespace sw::types;
41 using namespace sw::util;
42 
44 {
45  const OUString sPrefix("WW8TempExport" + OUString::number( m_nUniqueList++ ));
46  SwNumRule* pMyNumRule =
47  new SwNumRule( m_rDoc.GetUniqueNumRuleName( &sPrefix ),
49  m_pUsedNumTable->push_back( pMyNumRule );
50 
51  for ( sal_uInt16 i = 0; i < MAXLEVEL; i++ )
52  {
53  const SwNumFormat& rSubRule = pRule->Get(i);
54  pMyNumRule->Set( i, rSubRule );
55  }
56  return pMyNumRule;
57 }
58 
59 // multiple SwList can be based on the same SwNumRule; ensure one w:abstractNum
60 // per SwList
61 sal_uInt16 MSWordExportBase::DuplicateAbsNum(OUString const& rListId,
62  SwNumRule const& rAbstractRule)
63 {
64  auto const it(m_Lists.find(rListId));
65  if (it != m_Lists.end())
66  {
67  return it->second;
68  }
69  else
70  {
71  auto const pNewAbstractRule = DuplicateNumRuleImpl(&rAbstractRule);
72  assert(GetNumberingId(*pNewAbstractRule) == m_pUsedNumTable->size() - 1);
73  (void) pNewAbstractRule;
74  m_Lists.insert(std::make_pair(rListId, m_pUsedNumTable->size() - 1));
75  return m_pUsedNumTable->size() - 1;
76  }
77 }
78 
79 // Ideally we want to map SwList to w:abstractNum and SwNumRule to w:num
80 // The current approach is to keep exporting every SwNumRule to
81 // 1 w:abstractNum and 1 w:num, and then add extra w:num via this function
82 // that reference an existing w:abstractNum and may override its formatting;
83 // of course this will end up exporting some w:num that aren't actually used.
85  SwNumRule const& rExistingRule,
86  OUString const& rListId,
87  SwNumRule const& rAbstractRule)
88 {
89  const sal_uInt16 numdef = GetNumberingId(rExistingRule);
90 
91  const sal_uInt16 absnumdef = rListId == rAbstractRule.GetDefaultListId()
92  ? GetNumberingId(rAbstractRule)
93  : DuplicateAbsNum(rListId, rAbstractRule);
94  auto const mapping = std::make_pair(numdef, absnumdef);
95 
96  auto it = m_OverridingNums.insert(std::make_pair(m_pUsedNumTable->size(), mapping));
97 
98  m_pUsedNumTable->push_back(nullptr); // dummy, it's unique_ptr...
99  ++m_nUniqueList; // counter for DuplicateNumRule...
100 
101  return it.first->first;
102 }
103 
105  sal_uInt16 nLevelNum,
106  sal_uInt16 nStartAt)
107 {
108  m_ListLevelOverrides[nListId][nLevelNum] = nStartAt;
109 }
110 
111 sal_uInt16 MSWordExportBase::GetNumberingId( const SwNumRule& rNumRule )
112 {
113  if ( !m_pUsedNumTable )
114  {
115  m_pUsedNumTable.reset(new SwNumRuleTable);
116  m_pUsedNumTable->insert( m_pUsedNumTable->begin(), m_rDoc.GetNumRuleTable().begin(), m_rDoc.GetNumRuleTable().end() );
117  // Check, if the outline rule is already inserted into <pUsedNumTable>.
118  // If yes, do not insert it again.
119  bool bOutlineRuleAdded( false );
120  for ( sal_uInt16 n = m_pUsedNumTable->size(); n; )
121  {
122  const SwNumRule& rRule = *(*m_pUsedNumTable)[ --n ];
123  if ( !SwDoc::IsUsed( rRule ) )
124  {
125  m_pUsedNumTable->erase( m_pUsedNumTable->begin() + n );
126  }
127  else if ( &rRule == m_rDoc.GetOutlineNumRule() )
128  {
129  bOutlineRuleAdded = true;
130  }
131  }
132 
133  if ( !bOutlineRuleAdded )
134  {
135  // still need to paste the OutlineRule
137  m_pUsedNumTable->push_back( pR );
138  }
139  }
140  SwNumRule* p = const_cast<SwNumRule*>(&rNumRule);
141  sal_uInt16 nRet = static_cast<sal_uInt16>(m_pUsedNumTable->GetPos(p));
142 
143  return nRet;
144 }
145 
146 // GetFirstLineOffset should problem never appear unadorned apart from
147 // here in the ww export filter
148 sal_Int16 GetWordFirstLineOffset(const SwNumFormat &rFormat)
149 {
151  "<GetWordFirstLineOffset> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION" );
152 
153  short nFirstLineOffset;
154  if (rFormat.GetNumAdjust() == SvxAdjust::Right)
155  nFirstLineOffset = -rFormat.GetCharTextDistance();
156  else
157  nFirstLineOffset = rFormat.GetFirstLineOffset(); //TODO: overflow
158  return nFirstLineOffset;
159 }
160 
162 {
163  if ( !m_pUsedNumTable )
164  return; // no numbering is used
165 
166  // list formats - LSTF
167  pFib->m_fcPlcfLst = pTableStrm->Tell();
168  SwWW8Writer::WriteShort( *pTableStrm, m_pUsedNumTable->size() );
169  NumberingDefinitions();
170  // set len to FIB
171  pFib->m_lcbPlcfLst = pTableStrm->Tell() - pFib->m_fcPlcfLst;
172 
173  // list formats - LVLF
174  AbstractNumberingDefinitions();
175 
176  // list formats - LFO
177  OutOverrideListTab();
178 
179  // list formats - ListNames
180  OutListNamesTab();
181 }
182 
183 void WW8AttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule )
184 {
185  SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId );
186  SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId );
187 
188  // not associated with a Style
189  for ( int i = 0; i < WW8ListManager::nMaxLevel; ++i )
190  SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0xFFF );
191 
192  sal_uInt8 nFlags = 0;
193  if ( rRule.IsContinusNum() )
194  nFlags |= 0x1;
195 
196  m_rWW8Export.pTableStrm->WriteUChar( nFlags ).WriteUChar( 0/*nDummy*/ );
197 }
198 
200 {
201  if ( !m_pUsedNumTable )
202  return; // no numbering is used
203 
204  sal_uInt16 nCount = m_pUsedNumTable->size();
205 
206  // Write static data of SwNumRule - LSTF
207  for ( sal_uInt16 n = 0; n < nCount; ++n )
208  {
209  const SwNumRule * pRule = (*m_pUsedNumTable)[ n ];
210  if (pRule)
211  {
212  AttrOutput().NumberingDefinition(n + 1, *pRule);
213  }
214  else
215  {
216  auto it = m_OverridingNums.find(n);
217  assert(it != m_OverridingNums.end());
218  pRule = (*m_pUsedNumTable)[it->second.first];
219  assert(pRule);
220  AttrOutput().OverrideNumberingDefinition(*pRule, n + 1, it->second.second + 1, m_ListLevelOverrides[n]);
221  }
222  }
223 }
224 
230 static sal_uInt8 GetLevelNFC( sal_uInt16 eNumType, const SfxItemSet *pOutSet)
231 {
232  sal_uInt8 nRet = 0;
233  switch( eNumType )
234  {
236  case SVX_NUM_CHARS_UPPER_LETTER_N: nRet = 3; break;
238  case SVX_NUM_CHARS_LOWER_LETTER_N: nRet = 4; break;
239  case SVX_NUM_ROMAN_UPPER: nRet = 1; break;
240  case SVX_NUM_ROMAN_LOWER: nRet = 2; break;
241 
242  case SVX_NUM_BITMAP:
243  case SVX_NUM_CHAR_SPECIAL: nRet = 23; break;
244  case SVX_NUM_FULL_WIDTH_ARABIC: nRet = 14; break;
245  case SVX_NUM_CIRCLE_NUMBER: nRet = 18;break;
247  nRet = 35;
248  if ( pOutSet ) {
249  const SvxLanguageItem& rLang = pOutSet->Get( RES_CHRATR_CJK_LANGUAGE);
250  const LanguageType eLang = rLang.GetLanguage();
251  if (LANGUAGE_CHINESE_SIMPLIFIED ==eLang) {
252  nRet = 39;
253  }
254  }
255  break;
256  case SVX_NUM_NUMBER_UPPER_ZH: nRet = 38; break;
257  case SVX_NUM_NUMBER_UPPER_ZH_TW: nRet = 34;break;
258  case SVX_NUM_TIAN_GAN_ZH: nRet = 30; break;
259  case SVX_NUM_DI_ZI_ZH: nRet = 31; break;
260  case SVX_NUM_NUMBER_TRADITIONAL_JA: nRet = 16; break;
261  case SVX_NUM_AIU_FULLWIDTH_JA: nRet = 20; break;
262  case SVX_NUM_AIU_HALFWIDTH_JA: nRet = 12; break;
263  case SVX_NUM_IROHA_FULLWIDTH_JA: nRet = 21; break;
264  case SVX_NUM_IROHA_HALFWIDTH_JA: nRet = 13; break;
265  case style::NumberingType::HANGUL_SYLLABLE_KO: nRet = 24; break;// ganada
266  case style::NumberingType::HANGUL_JAMO_KO: nRet = 25; break;// chosung
267  case style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO: nRet = 24; break;
268  case style::NumberingType::HANGUL_CIRCLED_JAMO_KO: nRet = 25; break;
269  case style::NumberingType::NUMBER_HANGUL_KO: nRet = 41; break;
270  case style::NumberingType::NUMBER_UPPER_KO: nRet = 44; break;
271  case SVX_NUM_NUMBER_NONE: nRet = 0xff; break;
272  // No SVX_NUM_SYMBOL_CHICAGO here: LVLF can't contain 0x09, msonfcChiManSty.
273  case SVX_NUM_ARABIC_ZERO:
274  // 0x16, msonfcArabicLZ
275  nRet = 22;
276  break;
277  }
278  return nRet;
279 }
280 
281 
283  sal_uInt16 nStart,
284  sal_uInt16 nNumberingType,
285  SvxAdjust eAdjust,
286  const sal_uInt8 *pNumLvlPos,
287  sal_uInt8 nFollow,
288  const wwFont *pFont,
289  const SfxItemSet *pOutSet,
290  sal_Int16 nIndentAt,
291  sal_Int16 nFirstLineIndex,
292  sal_Int16 nListTabPos,
293  const OUString &rNumberingString,
294  const SvxBrushItem* pBrush //For i120928,to transfer graphic of bullet
295  )
296 {
297  // Start value
298  SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nStart );
299 
300  // Type
301  m_rWW8Export.pTableStrm->WriteUChar( GetLevelNFC( nNumberingType ,pOutSet) );
302 
303  // Justification
304  sal_uInt8 nAlign;
305  switch ( eAdjust )
306  {
307  case SvxAdjust::Center:
308  nAlign = 1;
309  break;
310  case SvxAdjust::Right:
311  nAlign = 2;
312  break;
313  default:
314  nAlign = 0;
315  break;
316  }
317  m_rWW8Export.pTableStrm->WriteUChar( nAlign );
318 
319  // Write the rgbxchNums[9], positions of placeholders for paragraph
320  // numbers in the text
321  m_rWW8Export.pTableStrm->WriteBytes(pNumLvlPos, WW8ListManager::nMaxLevel);
322 
323  // Type of the character between the bullet and the text
324  m_rWW8Export.pTableStrm->WriteUChar( nFollow );
325 
326  // dxaSoace/dxaIndent (Word 6 compatibility)
327  SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
328  SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
329 
330  // cbGrpprlChpx
331  std::unique_ptr<ww::bytes> pCharAtrs;
332  if ( pOutSet )
333  {
334  std::unique_ptr<ww::bytes> pOldpO = std::move(m_rWW8Export.pO);
335  m_rWW8Export.pO.reset(new ww::bytes);
336  if ( pFont )
337  {
338  sal_uInt16 nFontID = m_rWW8Export.m_aFontHelper.GetId( *pFont );
339 
340  m_rWW8Export.InsUInt16( NS_sprm::CRgFtc0::val );
341  m_rWW8Export.InsUInt16( nFontID );
342  m_rWW8Export.InsUInt16( NS_sprm::CRgFtc2::val );
343  m_rWW8Export.InsUInt16( nFontID );
344  }
345 
346  m_rWW8Export.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rWW8Export.m_bExportModeRTF );
347  //For i120928,achieve graphic's index of bullet from the bullet bookmark
348  if (SVX_NUM_BITMAP == nNumberingType && pBrush)
349  {
350  int nIndex = m_rWW8Export.GetGrfIndex(*pBrush);
351  if ( nIndex != -1 )
352  {
353  m_rWW8Export.InsUInt16(NS_sprm::CPbiIBullet::val);
354  m_rWW8Export.InsUInt32(nIndex);
355  m_rWW8Export.InsUInt16(NS_sprm::CPbiGrf::val);
356  m_rWW8Export.InsUInt16(1);
357  }
358  }
359 
360  pCharAtrs = std::move(m_rWW8Export.pO);
361  m_rWW8Export.pO = std::move(pOldpO);
362  }
363  m_rWW8Export.pTableStrm->WriteUChar(sal_uInt8(pCharAtrs ? pCharAtrs->size() : 0));
364 
365  // cbGrpprlPapx
366  sal_uInt8 aPapSprms [] = {
367  0x5e, 0x84, 0, 0, // sprmPDxaLeft
368  0x60, 0x84, 0, 0, // sprmPDxaLeft1
369  0x15, 0xc6, 0x05, 0x00, 0x01, 0, 0, 0x06
370  };
371  m_rWW8Export.pTableStrm->WriteUChar( sal_uInt8( sizeof( aPapSprms ) ) );
372 
373  // reserved
374  SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0 );
375 
376  // pap sprms
377  sal_uInt8* pData = aPapSprms + 2;
378  Set_UInt16( pData, nIndentAt );
379  pData += 2;
380  Set_UInt16( pData, nFirstLineIndex );
381  pData += 5;
382  Set_UInt16( pData, nListTabPos );
383 
384  m_rWW8Export.pTableStrm->WriteBytes(aPapSprms, sizeof(aPapSprms));
385 
386  // write Chpx
387  if (pCharAtrs && !pCharAtrs->empty())
388  m_rWW8Export.pTableStrm->WriteBytes(pCharAtrs->data(), pCharAtrs->size());
389 
390  // write the num string
391  SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, rNumberingString.getLength() );
392  SwWW8Writer::WriteString16( *m_rWW8Export.pTableStrm, rNumberingString, false );
393 }
394 
396 {
397  sal_uInt16 nCount = m_pUsedNumTable->size();
398  sal_uInt16 n;
399 
400  for( n = 0; n < nCount; ++n )
401  {
402  if (nullptr == (*m_pUsedNumTable)[ n ])
403  {
404  continue;
405  }
406 
407  AttrOutput().StartAbstractNumbering( n + 1 );
408 
409  const SwNumRule& rRule = *(*m_pUsedNumTable)[ n ];
410  sal_uInt8 nLvl;
411  sal_uInt8 nLevels = static_cast< sal_uInt8 >(rRule.IsContinusNum() ?
413  for( nLvl = 0; nLvl < nLevels; ++nLvl )
414  {
415  NumberingLevel(rRule, nLvl);
416  }
417 
418  AttrOutput().EndAbstractNumbering();
419  }
420 }
421 
423  SwNumRule const& rRule, sal_uInt8 const nLvl)
424 {
425  // prepare the NodeNum to generate the NumString
426  static const SwNumberTree::tNumberVector aNumVector = [] {
428  std::iota(vec.begin(), vec.end(), 0);
429  return vec;
430  }();
431 
432  // write the static data of the SwNumFormat of this level
433  sal_uInt8 aNumLvlPos[WW8ListManager::nMaxLevel] = { 0,0,0,0,0,0,0,0,0 };
434 
435  const SwNumFormat& rFormat = rRule.Get( nLvl );
436 
437  sal_uInt8 nFollow = 0;
438  // #i86652#
440  {
441  // <nFollow = 2>, if minimum label width equals 0 and
442  // minimum distance between label and text equals 0
443  nFollow = (rFormat.GetFirstLineOffset() == 0 &&
444  rFormat.GetCharTextDistance() == 0)
445  ? 2 : 0; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
446  }
448  {
449  switch (rFormat.GetLabelFollowedBy())
450  {
452  {
453  // 0 (tab) unless there would be no content before the tab, in which case 2 (nothing)
454  nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 0 : 2;
455  }
456  break;
458  {
459  // 1 (space) unless there would be no content before the space in which case 2 (nothing)
460  nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 1 : 2;
461  }
462  break;
464  {
465  nFollow = 2;
466  }
467  break;
468  default:
469  {
470  nFollow = 0;
471  OSL_FAIL( "unknown GetLabelFollowedBy() return value" );
472  }
473  }
474  }
475 
476  // Build the NumString for this Level
477  OUString sNumStr;
478  OUString sFontName;
479  bool bWriteBullet = false;
480  const vcl::Font* pBulletFont=nullptr;
481  rtl_TextEncoding eChrSet=0;
483  if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
484  SVX_NUM_BITMAP == rFormat.GetNumberingType())
485  {
486  // Use bullet
487  sal_UCS4 cBullet = rFormat.GetBulletChar();
488  sNumStr = OUString(&cBullet, 1);
489  }
490  else
491  {
492  // Create level string
493  // For docx it is not the best way: we can just take it from rRule.Get(nLvl).GetListFormat()
494  // But for compatibility with doc we follow same routine
495  if (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType())
496  {
497  sal_uInt8* pLvlPos = aNumLvlPos;
498  // the numbering string has to be restrict
499  // to the level currently working on.
500  sNumStr = rRule.MakeNumString(aNumVector, false, true, nLvl);
501 
502  // now search the nums in the string
503  for (sal_uInt8 i = 0; i <= nLvl; ++i)
504  {
505  OUString sSrch(OUString::number(i));
506  sal_Int32 nFnd = sNumStr.indexOf(sSrch);
507  if (-1 != nFnd)
508  {
509  *pLvlPos = static_cast<sal_uInt8>(nFnd + rFormat.GetPrefix().getLength() + 1);
510  ++pLvlPos;
511  sNumStr = sNumStr.replaceAt(nFnd, 1, OUString(static_cast<char>(i)));
512  }
513  }
514  }
515 
516  if (!rRule.Get(nLvl).HasListFormat())
517  {
518  if (!rFormat.GetPrefix().isEmpty())
519  sNumStr = rFormat.GetPrefix() + sNumStr;
520  sNumStr += rFormat.GetSuffix();
521  }
522  }
523 
524  if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
525  SVX_NUM_BITMAP == rFormat.GetNumberingType())
526  {
527  bWriteBullet = true;
528 
529  pBulletFont = rFormat.GetBulletFont();
530  if (!pBulletFont)
531  {
532  pBulletFont = &numfunc::GetDefBulletFont();
533  }
534 
535  eChrSet = pBulletFont->GetCharSet();
536  sFontName = pBulletFont->GetFamilyName();
537  eFamily = pBulletFont->GetFamilyType();
538 
539  if (IsStarSymbol(sFontName))
540  SubstituteBullet(sNumStr, eChrSet, sFontName);
541  }
542 
543  // Attributes of the numbering
544  std::unique_ptr<wwFont> pPseudoFont;
545  const SfxItemSet* pOutSet = nullptr;
546 
547  // cbGrpprlChpx
549  RES_CHRATR_END>{} );
550  if (rFormat.GetCharFormat() || bWriteBullet)
551  {
552  if (bWriteBullet)
553  {
554  pOutSet = &aSet;
555 
556  if (rFormat.GetCharFormat())
557  aSet.Put( rFormat.GetCharFormat()->GetAttrSet() );
558  aSet.ClearItem( RES_CHRATR_CJK_FONT );
559  aSet.ClearItem( RES_CHRATR_FONT );
560 
561  if (sFontName.isEmpty())
562  sFontName = pBulletFont->GetFamilyName();
563 
564  pPseudoFont.reset(new wwFont( sFontName, pBulletFont->GetPitch(),
565  eFamily, eChrSet));
566  }
567  else
568  pOutSet = &rFormat.GetCharFormat()->GetAttrSet();
569  }
570 
571  sal_Int16 nIndentAt = 0;
572  sal_Int16 nFirstLineIndex = 0;
573  sal_Int16 nListTabPos = -1;
574 
575  // #i86652#
577  {
578  nIndentAt = nListTabPos = rFormat.GetAbsLSpace(); //TODO: overflow
579  nFirstLineIndex = GetWordFirstLineOffset(rFormat);
580  }
582  {
583  nIndentAt = static_cast<sal_Int16>(rFormat.GetIndentAt());
584  nFirstLineIndex = static_cast<sal_Int16>(rFormat.GetFirstLineIndent());
585  nListTabPos = rFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB?
586  static_cast<sal_Int16>( rFormat.GetListtabPos() ) : 0;
587  }
588 
589  AttrOutput().NumberingLevel( nLvl,
590  rFormat.GetStart(),
591  rFormat.GetNumberingType(),
592  rFormat.GetNumAdjust(),
593  aNumLvlPos,
594  nFollow,
595  pPseudoFont.get(), pOutSet,
596  nIndentAt, nFirstLineIndex, nListTabPos,
597  sNumStr,
598  rFormat.GetNumberingType()==SVX_NUM_BITMAP ? rFormat.GetBrush() : nullptr);
599 }
600 
602 {
603  if( !m_pUsedNumTable )
604  return ; // no numbering is used
605 
606  // write the "list format override" - LFO
607  sal_uInt16 nCount = m_pUsedNumTable->size();
608  sal_uInt16 n;
609 
610  pFib->m_fcPlfLfo = pTableStrm->Tell();
611  SwWW8Writer::WriteLong( *pTableStrm, nCount );
612 
613  for( n = 0; n < nCount; ++n )
614  {
615  SwWW8Writer::WriteLong( *pTableStrm, n + 1 );
616  SwWW8Writer::FillCount( *pTableStrm, 12 );
617  }
618  for( n = 0; n < nCount; ++n )
619  SwWW8Writer::WriteLong( *pTableStrm, -1 ); // no overwrite
620 
621  // set len to FIB
622  pFib->m_lcbPlfLfo = pTableStrm->Tell() - pFib->m_fcPlfLfo;
623 }
624 
626 {
627  if( !m_pUsedNumTable )
628  return ; // no numbering is used
629 
630  // write the "list format override" - LFO
631  sal_uInt16 nNms = 0, nCount = m_pUsedNumTable->size();
632 
633  pFib->m_fcSttbListNames = pTableStrm->Tell();
634  SwWW8Writer::WriteShort( *pTableStrm, -1 );
635  SwWW8Writer::WriteLong( *pTableStrm, nCount );
636 
637  for( ; nNms < nCount; ++nNms )
638  {
639  const SwNumRule& rRule = *(*m_pUsedNumTable)[ nNms ];
640  OUString sNm;
641  if( !rRule.IsAutoRule() )
642  sNm = rRule.GetName();
643 
644  SwWW8Writer::WriteShort( *pTableStrm, sNm.getLength() );
645  if (!sNm.isEmpty())
646  SwWW8Writer::WriteString16(*pTableStrm, sNm, false);
647  }
648 
649  SwWW8Writer::WriteLong( *pTableStrm, pFib->m_fcSttbListNames + 2, nNms );
650  // set len to FIB
651  pFib->m_lcbSttbListNames = pTableStrm->Tell() - pFib->m_fcSttbListNames;
652 }
653 
654 void MSWordExportBase::SubstituteBullet( OUString& rNumStr,
655  rtl_TextEncoding& rChrSet, OUString& rFontName ) const
656 {
657  if (!m_bSubstituteBullets)
658  return;
659  OUString sFontName = rFontName;
660 
661  // If Bullet char is "", don't change
662  if (rNumStr[0] != u'\0')
663  {
664  rNumStr = rNumStr.replaceAt(0, 1, OUString(
665  msfilter::util::bestFitOpenSymbolToMSFont(rNumStr[0], rChrSet, sFontName)));
666  }
667 
668  rFontName = sFontName;
669 }
670 
671 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvxNumType GetNumberingType() const
tools::Long GetFirstLineIndent() const
SVX_NUM_CHARS_UPPER_LETTER_N
bool IsUsed(const sw::BroadcastingModify &) const
Definition: poolfmt.cxx:84
sal_Int32 nIndex
const OUString & GetFamilyName() const
sal_UCS4 GetBulletChar() const
sal_Unicode bestFitOpenSymbolToMSFont(sal_Unicode cBullet, rtl_TextEncoding &r_ioChrSet, OUString &r_ioFontName)
sal_uInt32 sal_UCS4
OUString MakeNumString(const SwNodeNum &, bool bInclStrings=true) const
Definition: number.cxx:616
SVX_NUM_FULL_WIDTH_ARABIC
std::unique_ptr< ContentProperties > pData
const SvxBrushItem * GetBrush() const
void AddListLevelOverride(sal_uInt16 nListId, sal_uInt16 nLevelNum, sal_uInt16 nStartAt)
Store list level overrides (restart of list)
Definition: wrtw8num.cxx:104
SVX_NUM_NUMBER_NONE
std::vector< sal_uInt8 > bytes
Definition: types.hxx:29
SVX_NUM_CHARS_UPPER_LETTER
const OUString & GetDefaultListId() const
Definition: numrule.hxx:193
bool IsAutoRule() const
Definition: numrule.hxx:228
sal_Int64 n
SVX_NUM_CIRCLE_NUMBER
tools::Long GetListtabPos() const
virtual void WriteNumbering() override
Output the numbering table.
Definition: wrtw8num.cxx:161
const OUString & GetName() const
Definition: numrule.hxx:223
OUString GetUniqueNumRuleName(const OUString *pChkStr=nullptr, bool bAutoNum=true) const
Definition: docnum.cxx:2493
static constexpr sal_uInt16 val
Definition: sprmids.hxx:277
sal_Int32 nFirstLineOffset
virtual void NumberingDefinition(sal_uInt16 nId, const SwNumRule &rRule) override
Definition of a numbering instance.
Definition: wrtw8num.cxx:183
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
SVX_NUM_ARABIC_ZERO
FontFamily GetFamilyType()
void OutListNamesTab()
Definition: wrtw8num.cxx:625
bool HasListFormat() const
SwDoc & m_rDoc
Definition: docbm.cxx:1205
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
int nCount
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
short GetCharTextDistance() const
SVX_NUM_ROMAN_UPPER
SVX_NUM_ROMAN_LOWER
SVX_NUM_IROHA_FULLWIDTH_JA
void Set_UInt16(sal_uInt8 *&p, sal_uInt16 n)
Definition: ww8struc.hxx:47
const OUString & GetPrefix() const
const OUString & GetSuffix() const
FAMILY_DECORATIVE
SVX_NUM_DI_ZI_ZH
Collects and outputs fonts.
Definition: wrtww8.hxx:293
sal_uInt16 DuplicateAbsNum(OUString const &rListId, SwNumRule const &rAbstractRule)
check if a new abstractNum is needed for this list
Definition: wrtw8num.cxx:61
bool IsContinusNum() const
Definition: numrule.hxx:234
static void WriteString16(SvStream &rStrm, const OUString &rStr, bool bAddZero)
Definition: wrtww8.cxx:1736
SVX_NUM_BITMAP
SVX_NUM_CHAR_SPECIAL
SwCharFormat * GetCharFormat() const
Definition: numrule.hxx:74
SwNumRule * DuplicateNumRuleImpl(const SwNumRule *pRule)
In case of numbering restart.
Definition: wrtw8num.cxx:43
SVX_NUM_IROHA_HALFWIDTH_JA
SVX_NUM_TIAN_GAN_ZH
SVX_NUM_CHARS_LOWER_LETTER
FontPitch GetPitch()
SvxAdjust
int i
void SubstituteBullet(OUString &rNumStr, rtl_TextEncoding &rChrSet, OUString &rFontName) const
Definition: wrtw8num.cxx:654
LabelFollowedBy GetLabelFollowedBy() const
sal_Int32 GetAbsLSpace() const
iterator begin()
Definition: docary.hxx:85
const vcl::Font & GetDefBulletFont()
retrieve font used for the default bullet list characters
Definition: number.cxx:1322
static void WriteShort(SvStream &rStrm, sal_Int16 nVal)
Definition: wrtww8.hxx:955
const vcl::Font * GetBulletFont() const
static sal_uInt8 GetLevelNFC(sal_uInt16 eNumType, const SfxItemSet *pOutSet)
Converts the SVX numbering type to MSONFC.
Definition: wrtw8num.cxx:230
float u
#define LANGUAGE_CHINESE_SIMPLIFIED
SvxAdjust GetNumAdjust() const
sal_uInt16 GetStart() const
OUString sPrefix
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
SVX_NUM_CHARS_LOWER_LETTER_N
iterator end()
Definition: docary.hxx:87
sal_Int16 GetWordFirstLineOffset(const SwNumFormat &rFormat)
Definition: wrtw8num.cxx:148
std::vector< tSwNumTreeNumber > tNumberVector
SVX_NUM_NUMBER_UPPER_ZH_TW
FontFamily
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:79
sal_uInt16 GetNumberingId(const SwNumRule &rNumRule)
Return the numeric id of the numbering rule.
Definition: wrtw8num.cxx:111
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
LanguageType GetLanguage() const
void Set(sal_uInt16 i, const SwNumFormat *)
Definition: number.cxx:591
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
unsigned char sal_uInt8
SVX_NUM_NUMBER_TRADITIONAL_JA
const SwNumRuleTable & GetNumRuleTable() const
Definition: doc.hxx:1065
SVX_NUM_NUMBER_LOWER_ZH
SVX_NUM_NUMBER_UPPER_ZH
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_CJK_FONT(22)
void NumberingDefinitions()
Write static data of SwNumRule - LSTF.
Definition: wrtw8num.cxx:199
void * p
sal_uInt16 OverrideNumRule(SwNumRule const &rExistingRule, OUString const &rListId, SwNumRule const &rAbstractRule)
Create a overriding numbering definition (if it does not yet exist)
Definition: wrtw8num.cxx:84
sal_Int32 GetFirstLineOffset() const
constexpr sal_uInt16 RES_CHRATR_END(46)
void OutOverrideListTab()
Definition: wrtw8num.cxx:601
SVX_NUM_AIU_HALFWIDTH_JA
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
bool IsStarSymbol(const OUString &rFontName)
tools::Long GetIndentAt() const
static void WriteLong(SvStream &rStrm, sal_Int32 nVal)
Definition: wrtww8.hxx:958
static void FillCount(SvStream &rStrm, sal_uLong nCount)
Definition: wrtww8.cxx:926
constexpr TypedWhichId< SvxLanguageItem > RES_CHRATR_CJK_LANGUAGE(24)
SVX_NUM_AIU_FULLWIDTH_JA
virtual void NumberingLevel(sal_uInt8 nLevel, sal_uInt16 nStart, sal_uInt16 nNumberingType, SvxAdjust eAdjust, const sal_uInt8 *pNumLvlPos, sal_uInt8 nFollow, const wwFont *pFont, const SfxItemSet *pOutSet, sal_Int16 nIndentAt, sal_Int16 nFirstLineIndex, sal_Int16 nListTabPos, const OUString &rNumberingString, const SvxBrushItem *pBrush) override
All the numbering level information.
Definition: wrtw8num.cxx:282
rtl_TextEncoding GetCharSet() const
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1317
void AbstractNumberingDefinitions()
Write all Levels for all SwNumRules - LVLF.
Definition: wrtw8num.cxx:395
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1023
void NumberingLevel(SwNumRule const &rRule, sal_uInt8 nLvl)
Write one numbering level.
Definition: wrtw8num.cxx:422
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo