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