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/fontitem.hxx>
23 #include <editeng/lrspitem.hxx>
24 #include <editeng/langitem.hxx>
25 #include <doc.hxx>
26 #include <docary.hxx>
27 #include <numrule.hxx>
28 #include <paratr.hxx>
29 #include <charfmt.hxx>
30 #include <ndtxt.hxx>
31 #include <unotools/fontcfg.hxx>
32 #include <com/sun/star/i18n/ScriptType.hpp>
33 
34 #include "sprmids.hxx"
35 
36 #include "ww8attributeoutput.hxx"
37 #include "writerhelper.hxx"
38 #include "writerwordglue.hxx"
39 #include "wrtww8.hxx"
40 #include "ww8par.hxx"
41 
42 #include <mutex>
43 
44 using namespace ::com::sun::star;
45 using namespace sw::types;
46 using namespace sw::util;
47 
48 sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal )
49 {
50  sal_uInt16 nNumId = USHRT_MAX;
51  const OUString sPrefix("WW8TempExport" + OUString::number( m_nUniqueList++ ));
52  SwNumRule* pMyNumRule =
53  new SwNumRule( m_pDoc->GetUniqueNumRuleName( &sPrefix ),
55  m_pUsedNumTable->push_back( pMyNumRule );
56 
57  for ( sal_uInt16 i = 0; i < MAXLEVEL; i++ )
58  {
59  const SwNumFormat& rSubRule = pRule->Get(i);
60  pMyNumRule->Set( i, rSubRule );
61  }
62 
63  SwNumFormat aNumFormat( pMyNumRule->Get( nLevel ) );
64  aNumFormat.SetStart( nVal );
65  pMyNumRule->Set( nLevel, aNumFormat );
66 
67  nNumId = GetNumberingId( *pMyNumRule );
68 
69  // Map the old list to our new list
70  m_aRuleDuplicates[GetNumberingId( *pRule )] = nNumId;
71 
72  return nNumId;
73 }
74 
75 // Ideally we want to map SwList to w:abstractNum and SwNumRule to w:num
76 // The current approach is to keep exporting every SwNumRule to
77 // 1 w:abstractNum and 1 w:num, and then add extra w:num via this function
78 // that reference an existing w:abstractNum and may override its formatting;
79 // of course this will end up exporting some w:num that aren't actually used.
81  SwNumRule const& rExistingRule,
82  SwNumRule const& rAbstractRule)
83 {
84  assert(&rExistingRule != &rAbstractRule);
85  auto const numdef = GetNumberingId(rExistingRule);
86  auto const absnumdef = GetNumberingId(rAbstractRule);
87  auto const mapping = std::make_pair(numdef, absnumdef);
88 
89  auto it = m_OverridingNumsR.find(mapping);
90  if (it == m_OverridingNumsR.end())
91  {
92  it = m_OverridingNumsR.insert(std::make_pair(mapping, m_pUsedNumTable->size())).first;
93  m_OverridingNums.insert(std::make_pair(m_pUsedNumTable->size(), mapping));
94  m_pUsedNumTable->push_back(nullptr); // dummy, it's unique_ptr...
95  ++m_nUniqueList; // counter for DuplicateNumRule...
96  }
97  return it->second;
98 }
99 
100 sal_uInt16 MSWordExportBase::GetNumberingId( const SwNumRule& rNumRule )
101 {
102  if ( !m_pUsedNumTable )
103  {
104  m_pUsedNumTable.reset(new SwNumRuleTable);
105  m_pUsedNumTable->insert( m_pUsedNumTable->begin(), m_pDoc->GetNumRuleTable().begin(), m_pDoc->GetNumRuleTable().end() );
106  // Check, if the outline rule is already inserted into <pUsedNumTable>.
107  // If yes, do not insert it again.
108  bool bOutlineRuleAdded( false );
109  for ( sal_uInt16 n = m_pUsedNumTable->size(); n; )
110  {
111  const SwNumRule& rRule = *(*m_pUsedNumTable)[ --n ];
112  if ( !SwDoc::IsUsed( rRule ) )
113  {
114  m_pUsedNumTable->erase( m_pUsedNumTable->begin() + n );
115  }
116  else if ( &rRule == m_pDoc->GetOutlineNumRule() )
117  {
118  bOutlineRuleAdded = true;
119  }
120  }
121 
122  if ( !bOutlineRuleAdded )
123  {
124  // still need to paste the OutlineRule
125  SwNumRule* pR = m_pDoc->GetOutlineNumRule();
126  m_pUsedNumTable->push_back( pR );
127  }
128  }
129  SwNumRule* p = const_cast<SwNumRule*>(&rNumRule);
130  sal_uInt16 nRet = static_cast<sal_uInt16>(m_pUsedNumTable->GetPos(p));
131 
132  // Is this list now duplicated into a new list which we should use
133  // #i77812# - perform 'deep' search in duplication map
134  std::map<sal_uInt16,sal_uInt16>::const_iterator aResult = m_aRuleDuplicates.end();
135  do {
136  aResult = m_aRuleDuplicates.find(nRet);
137  if ( aResult != m_aRuleDuplicates.end() )
138  {
139  nRet = (*aResult).second;
140  }
141  } while ( aResult != m_aRuleDuplicates.end() );
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);
221  }
222  }
223 }
224 
225 static sal_uInt8 GetLevelNFC( sal_uInt16 eNumType, const SfxItemSet *pOutSet)
226 {
227  sal_uInt8 nRet = 0;
228  switch( eNumType )
229  {
231  case SVX_NUM_CHARS_UPPER_LETTER_N: nRet = 3; break;
233  case SVX_NUM_CHARS_LOWER_LETTER_N: nRet = 4; break;
234  case SVX_NUM_ROMAN_UPPER: nRet = 1; break;
235  case SVX_NUM_ROMAN_LOWER: nRet = 2; break;
236 
237  case SVX_NUM_BITMAP:
238  case SVX_NUM_CHAR_SPECIAL: nRet = 23; break;
239  case SVX_NUM_FULL_WIDTH_ARABIC: nRet = 14; break;
240  case SVX_NUM_CIRCLE_NUMBER: nRet = 18;break;
242  nRet = 35;
243  if ( pOutSet ) {
244  const SvxLanguageItem& rLang = pOutSet->Get( RES_CHRATR_CJK_LANGUAGE);
245  const LanguageType eLang = rLang.GetLanguage();
246  if (LANGUAGE_CHINESE_SIMPLIFIED ==eLang) {
247  nRet = 39;
248  }
249  }
250  break;
251  case SVX_NUM_NUMBER_UPPER_ZH: nRet = 38; break;
252  case SVX_NUM_NUMBER_UPPER_ZH_TW: nRet = 34;break;
253  case SVX_NUM_TIAN_GAN_ZH: nRet = 30; break;
254  case SVX_NUM_DI_ZI_ZH: nRet = 31; break;
255  case SVX_NUM_NUMBER_TRADITIONAL_JA: nRet = 16; break;
256  case SVX_NUM_AIU_FULLWIDTH_JA: nRet = 20; break;
257  case SVX_NUM_AIU_HALFWIDTH_JA: nRet = 12; break;
258  case SVX_NUM_IROHA_FULLWIDTH_JA: nRet = 21; break;
259  case SVX_NUM_IROHA_HALFWIDTH_JA: nRet = 13; break;
260  case style::NumberingType::HANGUL_SYLLABLE_KO: nRet = 24; break;// ganada
261  case style::NumberingType::HANGUL_JAMO_KO: nRet = 25; break;// chosung
262  case style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO: nRet = 24; break;
263  case style::NumberingType::HANGUL_CIRCLED_JAMO_KO: nRet = 25; break;
264  case style::NumberingType::NUMBER_HANGUL_KO: nRet = 41; break;
265  case style::NumberingType::NUMBER_UPPER_KO: nRet = 44; break;
266  case SVX_NUM_NUMBER_NONE: nRet = 0xff; break;
267  }
268  return nRet;
269 }
270 
271 
273  sal_uInt16 nStart,
274  sal_uInt16 nNumberingType,
275  SvxAdjust eAdjust,
276  const sal_uInt8 *pNumLvlPos,
277  sal_uInt8 nFollow,
278  const wwFont *pFont,
279  const SfxItemSet *pOutSet,
280  sal_Int16 nIndentAt,
281  sal_Int16 nFirstLineIndex,
282  sal_Int16 nListTabPos,
283  const OUString &rNumberingString,
284  const SvxBrushItem* pBrush //For i120928,to transfer graphic of bullet
285  )
286 {
287  // Start value
288  SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nStart );
289 
290  // Type
291  m_rWW8Export.pTableStrm->WriteUChar( GetLevelNFC( nNumberingType ,pOutSet) );
292 
293  // Justification
294  sal_uInt8 nAlign;
295  switch ( eAdjust )
296  {
297  case SvxAdjust::Center:
298  nAlign = 1;
299  break;
300  case SvxAdjust::Right:
301  nAlign = 2;
302  break;
303  default:
304  nAlign = 0;
305  break;
306  }
307  m_rWW8Export.pTableStrm->WriteUChar( nAlign );
308 
309  // Write the rgbxchNums[9], positions of placeholders for paragraph
310  // numbers in the text
311  m_rWW8Export.pTableStrm->WriteBytes(pNumLvlPos, WW8ListManager::nMaxLevel);
312 
313  // Type of the character between the bullet and the text
314  m_rWW8Export.pTableStrm->WriteUChar( nFollow );
315 
316  // dxaSoace/dxaIndent (Word 6 compatibility)
317  SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
318  SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
319 
320  // cbGrpprlChpx
321  std::unique_ptr<ww::bytes> pCharAtrs;
322  if ( pOutSet )
323  {
324  std::unique_ptr<ww::bytes> pOldpO = std::move(m_rWW8Export.pO);
325  m_rWW8Export.pO.reset(new ww::bytes);
326  if ( pFont )
327  {
328  sal_uInt16 nFontID = m_rWW8Export.m_aFontHelper.GetId( *pFont );
329 
330  m_rWW8Export.InsUInt16( NS_sprm::sprmCRgFtc0 );
331  m_rWW8Export.InsUInt16( nFontID );
332  m_rWW8Export.InsUInt16( NS_sprm::sprmCRgFtc2 );
333  m_rWW8Export.InsUInt16( nFontID );
334  }
335 
336  m_rWW8Export.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rWW8Export.m_bExportModeRTF );
337  //For i120928,achieve graphic's index of bullet from the bullet bookmark
338  if (SVX_NUM_BITMAP == nNumberingType && pBrush)
339  {
340  int nIndex = m_rWW8Export.GetGrfIndex(*pBrush);
341  if ( nIndex != -1 )
342  {
343  m_rWW8Export.InsUInt16(NS_sprm::sprmCPbiIBullet);
344  m_rWW8Export.InsUInt32(nIndex);
345  m_rWW8Export.InsUInt16(NS_sprm::sprmCPbiGrf);
346  m_rWW8Export.InsUInt16(1);
347  }
348  }
349 
350  pCharAtrs = std::move(m_rWW8Export.pO);
351  m_rWW8Export.pO = std::move(pOldpO);
352  }
353  m_rWW8Export.pTableStrm->WriteUChar(sal_uInt8(pCharAtrs ? pCharAtrs->size() : 0));
354 
355  // cbGrpprlPapx
356  sal_uInt8 aPapSprms [] = {
357  0x5e, 0x84, 0, 0, // sprmPDxaLeft
358  0x60, 0x84, 0, 0, // sprmPDxaLeft1
359  0x15, 0xc6, 0x05, 0x00, 0x01, 0, 0, 0x06
360  };
361  m_rWW8Export.pTableStrm->WriteUChar( sal_uInt8( sizeof( aPapSprms ) ) );
362 
363  // reserved
364  SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0 );
365 
366  // pap sprms
367  sal_uInt8* pData = aPapSprms + 2;
368  Set_UInt16( pData, nIndentAt );
369  pData += 2;
370  Set_UInt16( pData, nFirstLineIndex );
371  pData += 5;
372  Set_UInt16( pData, nListTabPos );
373 
374  m_rWW8Export.pTableStrm->WriteBytes(aPapSprms, sizeof(aPapSprms));
375 
376  // write Chpx
377  if (pCharAtrs && !pCharAtrs->empty())
378  m_rWW8Export.pTableStrm->WriteBytes(pCharAtrs->data(), pCharAtrs->size());
379 
380  // write the num string
381  SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, rNumberingString.getLength() );
382  SwWW8Writer::WriteString16( *m_rWW8Export.pTableStrm, rNumberingString, false );
383 }
384 
386 {
387  sal_uInt16 nCount = m_pUsedNumTable->size();
388  sal_uInt16 n;
389 
390  for( n = 0; n < nCount; ++n )
391  {
392  if (nullptr == (*m_pUsedNumTable)[ n ])
393  {
394  continue;
395  }
396 
397  AttrOutput().StartAbstractNumbering( n + 1 );
398 
399  const SwNumRule& rRule = *(*m_pUsedNumTable)[ n ];
400  sal_uInt8 nLvl;
401  sal_uInt8 nLevels = static_cast< sal_uInt8 >(rRule.IsContinusNum() ?
403  for( nLvl = 0; nLvl < nLevels; ++nLvl )
404  {
405  NumberingLevel(rRule, nLvl);
406  }
407 
408  AttrOutput().EndAbstractNumbering();
409  }
410 }
411 
413  SwNumRule const& rRule, sal_uInt8 const nLvl)
414 {
415  // prepare the NodeNum to generate the NumString
416  static SwNumberTree::tNumberVector aNumVector;
417  static std::once_flag aInitOnce;
418  std::call_once(aInitOnce, []
419  {
420  for (int n = 0; n < WW8ListManager::nMaxLevel; ++n)
421  {
422  aNumVector.push_back( n );
423  }
424  });
425 
426  // write the static data of the SwNumFormat of this level
427  sal_uInt8 aNumLvlPos[WW8ListManager::nMaxLevel] = { 0,0,0,0,0,0,0,0,0 };
428 
429  const SwNumFormat& rFormat = rRule.Get( nLvl );
430 
431  sal_uInt8 nFollow = 0;
432  // #i86652#
434  {
435  nFollow = 2; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
436  }
438  {
439  switch (rFormat.GetLabelFollowedBy())
440  {
442  {
443  // 0 (tab) unless there would be no content before the tab, in which case 2 (nothing)
444  nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 0 : 2;
445  }
446  break;
448  {
449  // 1 (space) unless there would be no content before the space in which case 2 (nothing)
450  nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 1 : 2;
451  }
452  break;
454  {
455  nFollow = 2;
456  }
457  break;
458  default:
459  {
460  nFollow = 0;
461  OSL_FAIL( "unknown GetLabelFollowedBy() return value" );
462  }
463  }
464  }
465 
466  // Build the NumString for this Level
467  OUString sNumStr;
468  OUString sFontName;
469  bool bWriteBullet = false;
470  const vcl::Font* pBulletFont=nullptr;
471  rtl_TextEncoding eChrSet=0;
473  if (SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
474  SVX_NUM_BITMAP == rFormat.GetNumberingType())
475  {
476  sNumStr = OUString(rFormat.GetBulletChar());
477  bWriteBullet = true;
478 
479  pBulletFont = rFormat.GetBulletFont();
480  if (!pBulletFont)
481  {
482  pBulletFont = &numfunc::GetDefBulletFont();
483  }
484 
485  eChrSet = pBulletFont->GetCharSet();
486  sFontName = pBulletFont->GetFamilyName();
487  eFamily = pBulletFont->GetFamilyType();
488 
489  if (IsStarSymbol(sFontName))
490  SubstituteBullet( sNumStr, eChrSet, sFontName );
491 
492  // #i86652#
493  if (rFormat.GetPositionAndSpaceMode() ==
495  {
496  // <nFollow = 2>, if minimum label width equals 0 and
497  // minimum distance between label and text equals 0
498  nFollow = (rFormat.GetFirstLineOffset() == 0 &&
499  rFormat.GetCharTextDistance() == 0)
500  ? 2 : 0; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
501  }
502  }
503  else
504  {
505  if (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType())
506  {
507  sal_uInt8* pLvlPos = aNumLvlPos;
508  // the numbering string has to be restrict
509  // to the level currently working on.
510  sNumStr = rRule.MakeNumString(aNumVector, false, true, nLvl);
511 
512  // now search the nums in the string
513  for (sal_uInt8 i = 0; i <= nLvl; ++i)
514  {
515  OUString sSrch( OUString::number( i ));
516  sal_Int32 nFnd = sNumStr.indexOf( sSrch );
517  if( -1 != nFnd )
518  {
519  *pLvlPos = static_cast<sal_uInt8>(nFnd + rFormat.GetPrefix().getLength() + 1 );
520  ++pLvlPos;
521  sNumStr = sNumStr.replaceAt( nFnd, 1, OUString(static_cast<char>(i)) );
522  }
523  }
524  // #i86652#
525  if (rFormat.GetPositionAndSpaceMode() ==
527  {
528  // <nFollow = 2>, if minimum label width equals 0 and
529  // minimum distance between label and text equals 0
530  nFollow = (rFormat.GetFirstLineOffset() == 0 &&
531  rFormat.GetCharTextDistance() == 0)
532  ? 2 : 0; // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
533  }
534  }
535 
536  if (!rFormat.GetPrefix().isEmpty())
537  sNumStr = rFormat.GetPrefix() + sNumStr;
538  sNumStr += rFormat.GetSuffix();
539  }
540 
541  // Attributes of the numbering
542  std::unique_ptr<wwFont> pPseudoFont;
543  const SfxItemSet* pOutSet = nullptr;
544 
545  // cbGrpprlChpx
546  SfxItemSet aSet( m_pDoc->GetAttrPool(), svl::Items<RES_CHRATR_BEGIN,
547  RES_CHRATR_END>{} );
548  if (rFormat.GetCharFormat() || bWriteBullet)
549  {
550  if (bWriteBullet)
551  {
552  pOutSet = &aSet;
553 
554  if (rFormat.GetCharFormat())
555  aSet.Put( rFormat.GetCharFormat()->GetAttrSet() );
556  aSet.ClearItem( RES_CHRATR_CJK_FONT );
557  aSet.ClearItem( RES_CHRATR_FONT );
558 
559  if (sFontName.isEmpty())
560  sFontName = pBulletFont->GetFamilyName();
561 
562  pPseudoFont.reset(new wwFont( sFontName, pBulletFont->GetPitch(),
563  eFamily, eChrSet));
564  }
565  else
566  pOutSet = &rFormat.GetCharFormat()->GetAttrSet();
567  }
568 
569  sal_Int16 nIndentAt = 0;
570  sal_Int16 nFirstLineIndex = 0;
571  sal_Int16 nListTabPos = 0;
572 
573  // #i86652#
575  {
576  nIndentAt = nListTabPos = rFormat.GetAbsLSpace(); //TODO: overflow
577  nFirstLineIndex = GetWordFirstLineOffset(rFormat);
578  }
580  {
581  nIndentAt = static_cast<sal_Int16>(rFormat.GetIndentAt());
582  nFirstLineIndex = static_cast<sal_Int16>(rFormat.GetFirstLineIndent());
583  nListTabPos = rFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB?
584  static_cast<sal_Int16>( rFormat.GetListtabPos() ) : 0;
585  }
586 
587  AttrOutput().NumberingLevel( nLvl,
588  rFormat.GetStart(),
589  rFormat.GetNumberingType(),
590  rFormat.GetNumAdjust(),
591  aNumLvlPos,
592  nFollow,
593  pPseudoFont.get(), pOutSet,
594  nIndentAt, nFirstLineIndex, nListTabPos,
595  sNumStr,
596  rFormat.GetNumberingType()==SVX_NUM_BITMAP ? rFormat.GetBrush() : nullptr);
597 }
598 
600 {
601  if( !m_pUsedNumTable )
602  return ; // no numbering is used
603 
604  // write the "list format override" - LFO
605  sal_uInt16 nCount = m_pUsedNumTable->size();
606  sal_uInt16 n;
607 
608  pFib->m_fcPlfLfo = pTableStrm->Tell();
609  SwWW8Writer::WriteLong( *pTableStrm, nCount );
610 
611  for( n = 0; n < nCount; ++n )
612  {
613  SwWW8Writer::WriteLong( *pTableStrm, n + 1 );
614  SwWW8Writer::FillCount( *pTableStrm, 12 );
615  }
616  for( n = 0; n < nCount; ++n )
617  SwWW8Writer::WriteLong( *pTableStrm, -1 ); // no overwrite
618 
619  // set len to FIB
620  pFib->m_lcbPlfLfo = pTableStrm->Tell() - pFib->m_fcPlfLfo;
621 }
622 
624 {
625  if( !m_pUsedNumTable )
626  return ; // no numbering is used
627 
628  // write the "list format override" - LFO
629  sal_uInt16 nNms = 0, nCount = m_pUsedNumTable->size();
630 
631  pFib->m_fcSttbListNames = pTableStrm->Tell();
632  SwWW8Writer::WriteShort( *pTableStrm, -1 );
633  SwWW8Writer::WriteLong( *pTableStrm, nCount );
634 
635  for( ; nNms < nCount; ++nNms )
636  {
637  const SwNumRule& rRule = *(*m_pUsedNumTable)[ nNms ];
638  OUString sNm;
639  if( !rRule.IsAutoRule() )
640  sNm = rRule.GetName();
641 
642  SwWW8Writer::WriteShort( *pTableStrm, sNm.getLength() );
643  if (!sNm.isEmpty())
644  SwWW8Writer::WriteString16(*pTableStrm, sNm, false);
645  }
646 
647  SwWW8Writer::WriteLong( *pTableStrm, pFib->m_fcSttbListNames + 2, nNms );
648  // set len to FIB
649  pFib->m_lcbSttbListNames = pTableStrm->Tell() - pFib->m_fcSttbListNames;
650 }
651 
652 void MSWordExportBase::SubstituteBullet( OUString& rNumStr,
653  rtl_TextEncoding& rChrSet, OUString& rFontName ) const
654 {
655  if (!m_bSubstituteBullets)
656  return;
657  OUString sFontName = rFontName;
658 
659  // If Bullet char is "", don't change
660  if (rNumStr[0] != u'\0')
661  {
662  rNumStr = rNumStr.replaceAt(0, 1, OUString(
663  msfilter::util::bestFitOpenSymbolToMSFont(rNumStr[0], rChrSet, sFontName)));
664  }
665 
666  rFontName = sFontName;
667 }
668 
669 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 DuplicateNumRule(const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal)
In case of numbering restart.
Definition: wrtw8num.cxx:48
SvxNumType GetNumberingType() const
const sal_uInt16 sprmCPbiIBullet
Definition: sprmids.hxx:350
SVX_NUM_CHARS_UPPER_LETTER_N
#define RES_CHRATR_CJK_LANGUAGE
Definition: hintids.hxx:92
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:617
SVX_NUM_FULL_WIDTH_ARABIC
const sal_uInt16 sprmCRgFtc0
Definition: sprmids.hxx:308
const SvxBrushItem * GetBrush() const
SVX_NUM_NUMBER_NONE
std::vector< sal_uInt8 > bytes
Definition: types.hxx:29
SVX_NUM_CHARS_UPPER_LETTER
bool IsAutoRule() const
Definition: numrule.hxx:227
SVX_NUM_CIRCLE_NUMBER
#define RES_CHRATR_FONT
Definition: hintids.hxx:75
virtual void WriteNumbering() override
Output the numbering table.
Definition: wrtw8num.cxx:161
const OUString & GetName() const
Definition: numrule.hxx:222
#define RES_CHRATR_CJK_FONT
Definition: hintids.hxx:90
virtual void NumberingDefinition(sal_uInt16 nId, const SwNumRule &rRule) override
Definition of a numbering instance.
Definition: wrtw8num.cxx:183
FontFamily GetFamilyType()
void OutListNamesTab()
Definition: wrtw8num.cxx:623
#define RES_CHRATR_END
Definition: hintids.hxx:114
const sal_uInt16 sprmCPbiGrf
Definition: sprmids.hxx:351
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:299
bool IsContinusNum() const
Definition: numrule.hxx:233
static void WriteString16(SvStream &rStrm, const OUString &rStr, bool bAddZero)
Definition: wrtww8.cxx:1768
SVX_NUM_BITMAP
SVX_NUM_CHAR_SPECIAL
SwCharFormat * GetCharFormat() const
Definition: numrule.hxx:74
SVX_NUM_IROHA_HALFWIDTH_JA
SVX_NUM_TIAN_GAN_ZH
SVX_NUM_CHARS_LOWER_LETTER
FontPitch GetPitch()
SvxAdjust
void SubstituteBullet(OUString &rNumStr, rtl_TextEncoding &rChrSet, OUString &rFontName) const
Definition: wrtw8num.cxx:652
LabelFollowedBy GetLabelFollowedBy() const
sal_Int32 GetAbsLSpace() const
const vcl::Font & GetDefBulletFont()
retrieve font used for the default bullet list characters
Definition: number.cxx:1264
int i
static void WriteShort(SvStream &rStrm, sal_Int16 nVal)
Definition: wrtww8.hxx:951
const vcl::Font * GetBulletFont() const
static sal_uInt8 GetLevelNFC(sal_uInt16 eNumType, const SfxItemSet *pOutSet)
Definition: wrtw8num.cxx:225
float u
#define RES_CHRATR_BEGIN
Definition: hintids.hxx:68
#define LANGUAGE_CHINESE_SIMPLIFIED
SvxAdjust GetNumAdjust() const
sal_uInt16 GetStart() const
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
SVX_NUM_CHARS_LOWER_LETTER_N
sal_Int16 GetWordFirstLineOffset(const SwNumFormat &rFormat)
Definition: wrtw8num.cxx:148
sal_uInt16 OverrideNumRule(SwNumRule const &rExistingRule, SwNumRule const &rAbstractRule)
Create a overriding numbering definition (if it does not yet exist)
Definition: wrtw8num.cxx:80
std::vector< tSwNumTreeNumber > tNumberVector
long GetIndentAt() const
const sal_uInt16 sprmCRgFtc2
Definition: sprmids.hxx:310
SVX_NUM_NUMBER_UPPER_ZH_TW
FontFamily
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:83
sal_uInt16 GetNumberingId(const SwNumRule &rNumRule)
Return the numeric id of the numbering rule.
Definition: wrtw8num.cxx:100
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
LanguageType GetLanguage() const
void Set(sal_uInt16 i, const SwNumFormat *)
Definition: number.cxx:592
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:261
SVX_NUM_NUMBER_LOWER_ZH
SVX_NUM_NUMBER_UPPER_ZH
bool IsUsed(const SwModify &) const
Definition: poolfmt.cxx:122
void NumberingDefinitions()
Write static data of SwNumRule - LSTF.
Definition: wrtw8num.cxx:199
long GetListtabPos() const
sal_Int32 GetFirstLineOffset() const
sal_Unicode GetBulletChar() const
void SetStart(sal_uInt16 nSet)
void OutOverrideListTab()
Definition: wrtw8num.cxx:599
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:954
static void FillCount(SvStream &rStrm, sal_uLong nCount)
Definition: wrtww8.cxx:954
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:272
rtl_TextEncoding GetCharSet() const
void AbstractNumberingDefinitions()
Write all Levels for all SwNumRules - LVLF.
Definition: wrtw8num.cxx:385
void NumberingLevel(SwNumRule const &rRule, sal_uInt8 nLvl)
Write one numbering level.
Definition: wrtw8num.cxx:412