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