LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - wrtw8num.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 239 410 58.3 %
Date: 2014-04-11 Functions: 13 21 61.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <doc.hxx>
      25             : #include <docary.hxx>
      26             : #include <numrule.hxx>
      27             : #include <paratr.hxx>
      28             : #include <charfmt.hxx>
      29             : #include <ndtxt.hxx>
      30             : #include <unotools/fontcfg.hxx>
      31             : #include <com/sun/star/i18n/ScriptType.hpp>
      32             : 
      33             : #include <filter/msfilter/sprmids.hxx>
      34             : 
      35             : #include "ww8attributeoutput.hxx"
      36             : #include "writerhelper.hxx"
      37             : #include "writerwordglue.hxx"
      38             : #include "wrtww8.hxx"
      39             : #include "ww8par.hxx"
      40             : 
      41             : using namespace ::com::sun::star;
      42             : using namespace sw::types;
      43             : using namespace sw::util;
      44             : 
      45           3 : sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal )
      46             : {
      47           3 :     sal_uInt16 nNumId = USHRT_MAX;
      48           3 :     const OUString sPrefix("WW8TempExport" + OUString::number( nUniqueList++ ));
      49             :     SwNumRule* pMyNumRule =
      50             :             new SwNumRule( pDoc->GetUniqueNumRuleName( &sPrefix ),
      51           3 :                            SvxNumberFormat::LABEL_WIDTH_AND_POSITION );
      52           3 :     pUsedNumTbl->push_back( pMyNumRule );
      53             : 
      54          33 :     for ( sal_uInt16 i = 0; i < MAXLEVEL; i++ )
      55             :     {
      56          30 :         const SwNumFmt& rSubRule = pRule->Get(i);
      57          30 :         pMyNumRule->Set( i, rSubRule );
      58             :     }
      59             : 
      60           6 :     SwNumFmt aNumFmt( pMyNumRule->Get( nLevel ) );
      61           3 :     aNumFmt.SetStart( nVal );
      62           3 :     pMyNumRule->Set( nLevel, aNumFmt );
      63             : 
      64           3 :     nNumId = GetId( *pMyNumRule );
      65             : 
      66             :     // Map the old list to our new list
      67           3 :     aRuleDuplicates[GetId( *pRule )] = nNumId;
      68             : 
      69           6 :     return nNumId;
      70             : }
      71             : 
      72         542 : sal_uInt16 MSWordExportBase::GetId( const SwNumRule& rNumRule )
      73             : {
      74         542 :     if ( !pUsedNumTbl )
      75             :     {
      76          35 :         pUsedNumTbl = new SwNumRuleTbl;
      77          35 :         pUsedNumTbl->insert( pUsedNumTbl->begin(), pDoc->GetNumRuleTbl().begin(), pDoc->GetNumRuleTbl().end() );
      78             :         // Check, if the outline rule is already inserted into <pUsedNumTbl>.
      79             :         // If yes, do not insert it again.
      80          35 :         bool bOutlineRuleAdded( false );
      81         632 :         for ( sal_uInt16 n = pUsedNumTbl->size(); n; )
      82             :         {
      83         562 :             const SwNumRule& rRule = *(*pUsedNumTbl)[ --n ];
      84         562 :             if ( !pDoc->IsUsed( rRule ) )
      85             :             {
      86         458 :                 pUsedNumTbl->erase( pUsedNumTbl->begin() + n );
      87             :             }
      88         104 :             else if ( &rRule == pDoc->GetOutlineNumRule() )
      89             :             {
      90           4 :                 bOutlineRuleAdded = true;
      91             :             }
      92             :         }
      93             : 
      94          35 :         if ( !bOutlineRuleAdded )
      95             :         {
      96             :             // still need to paste the OutlineRule
      97          31 :             SwNumRule* pR = (SwNumRule*)pDoc->GetOutlineNumRule();
      98          31 :             pUsedNumTbl->push_back( pR );
      99             :         }
     100             :     }
     101         542 :     SwNumRule* p = (SwNumRule*)&rNumRule;
     102         542 :     sal_uInt16 nRet = pUsedNumTbl->GetPos(p);
     103             : 
     104             :     // Is this list now duplicated into a new list which we should use
     105             :     // #i77812# - perform 'deep' search in duplication map
     106         542 :     ::std::map<sal_uInt16,sal_uInt16>::const_iterator aResult = aRuleDuplicates.end();
     107        1182 :     do {
     108         591 :         aResult = aRuleDuplicates.find(nRet);
     109         591 :         if ( aResult != aRuleDuplicates.end() )
     110             :         {
     111          49 :             nRet = (*aResult).second;
     112             :         }
     113        1182 :     } while ( aResult != aRuleDuplicates.end() );
     114             : 
     115         542 :     return nRet;
     116             : }
     117             : 
     118             : // GetFirstLineOffset should problem never appear unadorned apart from
     119             : // here in the ww export filter
     120          65 : sal_Int16 GetWordFirstLineOffset(const SwNumFmt &rFmt)
     121             : {
     122             :     OSL_ENSURE( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION,
     123             :             "<GetWordFirstLineOffset> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION" );
     124             : 
     125             :     short nFirstLineOffset;
     126          65 :     if (rFmt.GetNumAdjust() == SVX_ADJUST_RIGHT)
     127           0 :         nFirstLineOffset = -rFmt.GetCharTextDistance();
     128             :     else
     129          65 :         nFirstLineOffset = rFmt.GetFirstLineOffset();
     130          65 :     return nFirstLineOffset;
     131             : }
     132             : 
     133          12 : void WW8Export::WriteNumbering()
     134             : {
     135          12 :     if ( !pUsedNumTbl )
     136          21 :         return; // no numbering is used
     137             : 
     138             :     // list formats - LSTF
     139           3 :     pFib->fcPlcfLst = pTableStrm->Tell();
     140           3 :     SwWW8Writer::WriteShort( *pTableStrm, pUsedNumTbl->size() );
     141           3 :     NumberingDefinitions();
     142             :     // set len to FIB
     143           3 :     pFib->lcbPlcfLst = pTableStrm->Tell() - pFib->fcPlcfLst;
     144             : 
     145             :     // list formats - LVLF
     146           3 :     AbstractNumberingDefinitions();
     147             : 
     148             :     // list formats - LFO
     149           3 :     OutOverrideListTab();
     150             : 
     151             :     // list formats - ListNames
     152           3 :     OutListNamesTab();
     153             : }
     154             : 
     155           5 : void WW8AttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule )
     156             : {
     157           5 :     SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId );
     158           5 :     SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId );
     159             : 
     160             :     // not associated with a Style
     161          50 :     for ( int i = 0; i < WW8ListManager::nMaxLevel; ++i )
     162          45 :         SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0xFFF );
     163             : 
     164           5 :     sal_uInt8 nFlags = 0, nDummy = 0;
     165           5 :     if ( rRule.IsContinusNum() )
     166           2 :         nFlags |= 0x1;
     167             : 
     168           5 :     m_rWW8Export.pTableStrm->WriteUChar( nFlags ).WriteUChar( nDummy );
     169           5 : }
     170             : 
     171          35 : void MSWordExportBase::NumberingDefinitions()
     172             : {
     173          35 :     if ( !pUsedNumTbl )
     174          35 :         return; // no numbering is used
     175             : 
     176          35 :     sal_uInt16 nCount = pUsedNumTbl->size();
     177             : 
     178             :     // Write static data of SwNumRule - LSTF
     179         170 :     for ( sal_uInt16 n = 0; n < nCount; ++n )
     180             :     {
     181         135 :         const SwNumRule& rRule = *(*pUsedNumTbl)[ n ];
     182             : 
     183         135 :         AttrOutput().NumberingDefinition( n + 1, rRule );
     184             :     }
     185             : }
     186             : 
     187          29 : void WW8AttributeOutput::NumberingLevel( sal_uInt8 /*nLevel*/,
     188             :         sal_uInt16 nStart,
     189             :         sal_uInt16 nNumberingType,
     190             :         SvxAdjust eAdjust,
     191             :         const sal_uInt8 *pNumLvlPos,
     192             :         sal_uInt8 nFollow,
     193             :         const wwFont *pFont,
     194             :         const SfxItemSet *pOutSet,
     195             :         sal_Int16 nIndentAt,
     196             :         sal_Int16 nFirstLineIndex,
     197             :         sal_Int16 nListTabPos,
     198             :         const OUString &rNumberingString,
     199             :         const SvxBrushItem* pBrush //For i120928,to transfer graphic of bullet
     200             :     )
     201             : {
     202             :     // Start value
     203          29 :     SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nStart );
     204             : 
     205             :     // Type
     206          29 :     m_rWW8Export.pTableStrm->WriteUChar( WW8Export::GetNumId( nNumberingType ) );
     207             : 
     208             :     // Justification
     209             :     sal_uInt8 nAlign;
     210          29 :     switch ( eAdjust )
     211             :     {
     212             :     case SVX_ADJUST_CENTER:
     213           0 :         nAlign = 1;
     214           0 :         break;
     215             :     case SVX_ADJUST_RIGHT:
     216           0 :         nAlign = 2;
     217           0 :         break;
     218             :     default:
     219          29 :         nAlign = 0;
     220          29 :         break;
     221             :     }
     222          29 :     m_rWW8Export.pTableStrm->WriteUChar( nAlign );
     223             : 
     224             :     // Write the rgbxchNums[9], positions of placeholders for paragraph
     225             :     // numbers in the text
     226          29 :     m_rWW8Export.pTableStrm->Write( pNumLvlPos, WW8ListManager::nMaxLevel );
     227             : 
     228             :     // Type of the character between the bullet and the text
     229          29 :     m_rWW8Export.pTableStrm->WriteUChar( nFollow );
     230             : 
     231             :     // dxaSoace/dxaIndent (Word 6 compatibility)
     232          29 :     SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
     233          29 :     SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
     234             : 
     235             :     // cbGrpprlChpx
     236          29 :     ww::bytes aCharAtrs;
     237          29 :     if ( pOutSet )
     238             :     {
     239           2 :         ww::bytes* pOldpO = m_rWW8Export.pO;
     240           2 :         m_rWW8Export.pO = &aCharAtrs;
     241           2 :         if ( pFont )
     242             :         {
     243           2 :             sal_uInt16 nFontID = m_rWW8Export.maFontHelper.GetId( *pFont );
     244             : 
     245           2 :             if ( m_rWW8Export.bWrtWW8 )
     246             :             {
     247           2 :                 m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc0 );
     248           2 :                 m_rWW8Export.InsUInt16( nFontID );
     249           2 :                 m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc2 );
     250             :             }
     251             :             else
     252           0 :                 m_rWW8Export.pO->push_back( 93 );
     253           2 :             m_rWW8Export.InsUInt16( nFontID );
     254             :         }
     255             : 
     256           2 :         m_rWW8Export.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rWW8Export.mbExportModeRTF );
     257             :         //For i120928,achieve graphic's index of bullet from the bullet bookmark
     258           2 :         if (SVX_NUM_BITMAP == nNumberingType && pBrush)
     259             :         {
     260           0 :             int nIndex = m_rWW8Export.GetGrfIndex(*pBrush);
     261           0 :             if ( nIndex != -1 )
     262             :             {
     263           0 :                 m_rWW8Export.InsUInt16(NS_sprm::LN_CPbiIBullet);
     264           0 :                 m_rWW8Export.InsUInt32(nIndex);
     265           0 :                 m_rWW8Export.InsUInt16(NS_sprm::LN_CPbiGrf);
     266           0 :                 m_rWW8Export.InsUInt16(1);
     267             :             }
     268             :         }
     269             : 
     270           2 :         m_rWW8Export.pO = pOldpO;
     271             :     }
     272          29 :     m_rWW8Export.pTableStrm->WriteUChar( sal_uInt8( aCharAtrs.size() ) );
     273             : 
     274             :     // cbGrpprlPapx
     275             :     sal_uInt8 aPapSprms [] = {
     276             :         0x5e, 0x84, 0, 0,               // sprmPDxaLeft
     277             :         0x60, 0x84, 0, 0,               // sprmPDxaLeft1
     278             :         0x15, 0xc6, 0x05, 0x00, 0x01, 0, 0, 0x06
     279          29 :     };
     280          29 :     m_rWW8Export.pTableStrm->WriteUChar( sal_uInt8( sizeof( aPapSprms ) ) );
     281             : 
     282             :     // reserved
     283          29 :     SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0 );
     284             : 
     285             :     // pap sprms
     286          29 :     sal_uInt8* pData = aPapSprms + 2;
     287          29 :     Set_UInt16( pData, nIndentAt );
     288          29 :     pData += 2;
     289          29 :     Set_UInt16( pData, nFirstLineIndex );
     290          29 :     pData += 5;
     291          29 :     Set_UInt16( pData, nListTabPos );
     292             : 
     293          29 :     m_rWW8Export.pTableStrm->Write( aPapSprms, sizeof( aPapSprms ));
     294             : 
     295             :     // write Chpx
     296          29 :     if( !aCharAtrs.empty() )
     297           2 :         m_rWW8Export.pTableStrm->Write( aCharAtrs.data(), aCharAtrs.size() );
     298             : 
     299             :     // write the num string
     300          29 :     SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, rNumberingString.getLength() );
     301          29 :     SwWW8Writer::WriteString16( *m_rWW8Export.pTableStrm, rNumberingString, false );
     302          29 : }
     303             : 
     304          35 : void MSWordExportBase::AbstractNumberingDefinitions()
     305             : {
     306          35 :     sal_uInt16 nCount = pUsedNumTbl->size();
     307             :     sal_uInt16 n;
     308             : 
     309             :     // prepare the NodeNum to generate the NumString
     310          35 :     SwNumberTree::tNumberVector aNumVector;
     311         350 :     for ( n = 0; n < WW8ListManager::nMaxLevel; ++n )
     312         315 :         aNumVector.push_back( n );
     313             : 
     314         170 :     for( n = 0; n < nCount; ++n )
     315             :     {
     316         135 :         AttrOutput().StartAbstractNumbering( n + 1 );
     317             : 
     318         135 :         const SwNumRule& rRule = *(*pUsedNumTbl)[ n ];
     319             :         sal_uInt8 nLvl;
     320         135 :         sal_uInt8 nLevels = static_cast< sal_uInt8 >(rRule.IsContinusNum() ?
     321         135 :             WW8ListManager::nMinLevel : WW8ListManager::nMaxLevel);
     322        1334 :         for( nLvl = 0; nLvl < nLevels; ++nLvl )
     323             :         {
     324             :             // write the static data of the SwNumFmt of this level
     325        1199 :             sal_uInt8 aNumLvlPos[WW8ListManager::nMaxLevel] = { 0,0,0,0,0,0,0,0,0 };
     326             : 
     327        1199 :             const SwNumFmt& rFmt = rRule.Get( nLvl );
     328             : 
     329        1199 :             sal_uInt8 nFollow = 0;
     330             :             // #i86652#
     331        1199 :             if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
     332             :             {
     333          27 :                 nFollow = 2;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
     334             :             }
     335        1172 :             else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
     336             :             {
     337        1172 :                 switch ( rFmt.GetLabelFollowedBy() )
     338             :                 {
     339             :                     case SvxNumberFormat::LISTTAB:
     340             :                     {
     341             :             // 0 (tab) unless there would be no content before the tab, in which case 2 (nothing)
     342        1163 :             nFollow = (SVX_NUM_NUMBER_NONE != rFmt.GetNumberingType()) ? 0 : 2;
     343             :                     }
     344        1163 :                     break;
     345             :                     case SvxNumberFormat::SPACE:
     346             :                     {
     347             :             // 1 (space) unless there would be no content before the space in which case 2 (nothing)
     348           0 :             nFollow = (SVX_NUM_NUMBER_NONE != rFmt.GetNumberingType()) ? 1 : 2;
     349             :                     }
     350           0 :                     break;
     351             :                     case SvxNumberFormat::NOTHING:
     352             :                     {
     353           9 :                         nFollow = 2;
     354             :                     }
     355           9 :                     break;
     356             :                     default:
     357             :                     {
     358           0 :                         nFollow = 0;
     359             :                         OSL_FAIL( "unknown GetLabelFollowedBy() return value" );
     360             :                     }
     361             :                 }
     362             :             }
     363             : 
     364             :             // Build the NumString for this Level
     365        1199 :             OUString sNumStr;
     366        2398 :             OUString sFontName;
     367        1199 :             bool bWriteBullet = false;
     368        1199 :             const Font* pBulletFont=0;
     369        1199 :             rtl_TextEncoding eChrSet=0;
     370        1199 :             FontFamily eFamily=FAMILY_DECORATIVE;
     371        2103 :             if( SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType() ||
     372         904 :                 SVX_NUM_BITMAP == rFmt.GetNumberingType() )
     373             :             {
     374         299 :                 sNumStr = OUString(rFmt.GetBulletChar());
     375         299 :                 bWriteBullet = true;
     376             : 
     377         299 :                 pBulletFont = rFmt.GetBulletFont();
     378         299 :                 if (!pBulletFont)
     379             :                 {
     380           3 :                     pBulletFont = &numfunc::GetDefBulletFont();
     381             :                 }
     382             : 
     383         299 :                 eChrSet = pBulletFont->GetCharSet();
     384         299 :                 sFontName = pBulletFont->GetName();
     385         299 :                 eFamily = pBulletFont->GetFamily();
     386             : 
     387         299 :                 if ( IsStarSymbol(sFontName) )
     388           3 :                     SubstituteBullet( sNumStr, eChrSet, sFontName );
     389             : 
     390             :                 // #i86652#
     391         299 :                 if ( rFmt.GetPositionAndSpaceMode() ==
     392             :                                         SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
     393             :                 {
     394             :                     // <nFollow = 2>, if minimum label width equals 0 and
     395             :                     // minimum distance between label and text equals 0
     396           0 :                     nFollow = ( rFmt.GetFirstLineOffset() == 0 &&
     397           0 :                                 rFmt.GetCharTextDistance() == 0 )
     398           0 :                               ? 2 : 0;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
     399             :                 }
     400             :             }
     401             :             else
     402             :             {
     403         900 :                 if (SVX_NUM_NUMBER_NONE != rFmt.GetNumberingType())
     404             :                 {
     405         610 :                     sal_uInt8* pLvlPos = aNumLvlPos;
     406             :                     // the numbering string has to be restrict
     407             :                     // to the level currently working on.
     408         610 :                     sNumStr = rRule.MakeNumString(aNumVector, false, true, nLvl);
     409             : 
     410             :                     // now search the nums in the string
     411        3742 :                     for( sal_uInt8 i = 0; i <= nLvl; ++i )
     412             :                     {
     413        3132 :                         OUString sSrch( OUString::number( i ));
     414        3132 :                         sal_Int32 nFnd = sNumStr.indexOf( sSrch );
     415        3132 :                         if( -1 != nFnd )
     416             :                         {
     417        1015 :                             *pLvlPos = (sal_uInt8)(nFnd + rFmt.GetPrefix().getLength() + 1 );
     418        1015 :                             ++pLvlPos;
     419        1015 :                             sNumStr = sNumStr.replaceAt( nFnd, 1, OUString((char)i) );
     420             :                         }
     421        3132 :                     }
     422             :                     // #i86652#
     423         610 :                     if ( rFmt.GetPositionAndSpaceMode() ==
     424             :                                             SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
     425             :                     {
     426             :                         // <nFollow = 2>, if minimum label width equals 0 and
     427             :                         // minimum distance between label and text equals 0
     428          18 :                         nFollow = ( rFmt.GetFirstLineOffset() == 0 &&
     429           0 :                                     rFmt.GetCharTextDistance() == 0 )
     430          18 :                                   ? 2 : 0;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
     431             :                     }
     432             :                 }
     433             : 
     434         900 :                 if( !rFmt.GetPrefix().isEmpty() )
     435          16 :                     sNumStr = rFmt.GetPrefix() + sNumStr;
     436         900 :                 sNumStr += rFmt.GetSuffix();
     437             :             }
     438             : 
     439             :             // Attributes of the numbering
     440        1199 :             wwFont *pPseudoFont = NULL;
     441        1199 :             const SfxItemSet* pOutSet = NULL;
     442             : 
     443             :             // cbGrpprlChpx
     444        1199 :             SfxItemSet aSet( pDoc->GetAttrPool(), RES_CHRATR_BEGIN,
     445        2398 :                                                   RES_CHRATR_END );
     446        1199 :             if ( rFmt.GetCharFmt() || bWriteBullet )
     447             :             {
     448         347 :                 if ( bWriteBullet )
     449             :                 {
     450         299 :                     pOutSet = &aSet;
     451             : 
     452         299 :                     if ( rFmt.GetCharFmt() )
     453         149 :                         aSet.Put( rFmt.GetCharFmt()->GetAttrSet() );
     454         299 :                     aSet.ClearItem( RES_CHRATR_CJK_FONT );
     455         299 :                     aSet.ClearItem( RES_CHRATR_FONT );
     456             : 
     457         299 :                     if ( sFontName.isEmpty() )
     458           0 :                         sFontName = pBulletFont->GetName();
     459             : 
     460             :                     pPseudoFont = new wwFont( sFontName, pBulletFont->GetPitch(),
     461         299 :                         eFamily, eChrSet, SupportsUnicode() );
     462             :                 }
     463             :                 else
     464          48 :                     pOutSet = &rFmt.GetCharFmt()->GetAttrSet();
     465             :             }
     466             : 
     467        1199 :             sal_Int16 nIndentAt = 0;
     468        1199 :             sal_Int16 nFirstLineIndex = 0;
     469        1199 :             sal_Int16 nListTabPos = 0;
     470             : 
     471             :             // #i86652#
     472        1199 :             if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
     473             :             {
     474          27 :                 nIndentAt = nListTabPos = rFmt.GetAbsLSpace();
     475          27 :                 nFirstLineIndex = GetWordFirstLineOffset(rFmt);
     476             :             }
     477        1172 :             else if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
     478             :             {
     479        1172 :                 nIndentAt = static_cast<sal_Int16>(rFmt.GetIndentAt());
     480        1172 :                 nFirstLineIndex = static_cast<sal_Int16>(rFmt.GetFirstLineIndent());
     481        1172 :                 nListTabPos = rFmt.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB?
     482        1172 :                               static_cast<sal_Int16>( rFmt.GetListtabPos() ) : 0;
     483             :             }
     484             : 
     485        1199 :             AttrOutput().NumberingLevel( nLvl,
     486        1199 :                     rFmt.GetStart(),
     487        1199 :                     rFmt.GetNumberingType(),
     488             :                     rFmt.GetNumAdjust(),
     489             :                     aNumLvlPos,
     490             :                     nFollow,
     491             :                     pPseudoFont, pOutSet,
     492             :                     nIndentAt, nFirstLineIndex, nListTabPos,
     493             :                     sNumStr,
     494        3597 :                     rFmt.GetNumberingType()==SVX_NUM_BITMAP ? rFmt.GetBrush():0);
     495             : 
     496        1199 :             delete pPseudoFont;
     497        1199 :         }
     498         135 :         AttrOutput().EndAbstractNumbering();
     499          35 :     }
     500          35 : }
     501             : 
     502           3 : void WW8Export::OutOverrideListTab()
     503             : {
     504           3 :     if( !pUsedNumTbl )
     505           3 :         return ;            // no numbering is used
     506             : 
     507             :     // write the "list format override" - LFO
     508           3 :     sal_uInt16 nCount = pUsedNumTbl->size();
     509             :     sal_uInt16 n;
     510             : 
     511           3 :     pFib->fcPlfLfo = pTableStrm->Tell();
     512           3 :     SwWW8Writer::WriteLong( *pTableStrm, nCount );
     513             : 
     514           8 :     for( n = 0; n < nCount; ++n )
     515             :     {
     516           5 :         SwWW8Writer::WriteLong( *pTableStrm, n + 1 );
     517           5 :         SwWW8Writer::FillCount( *pTableStrm, 12 );
     518             :     }
     519           8 :     for( n = 0; n < nCount; ++n )
     520           5 :         SwWW8Writer::WriteLong( *pTableStrm, -1 );  // no overwrite
     521             : 
     522             :     // set len to FIB
     523           3 :     pFib->lcbPlfLfo = pTableStrm->Tell() - pFib->fcPlfLfo;
     524             : }
     525             : 
     526           3 : void WW8Export::OutListNamesTab()
     527             : {
     528           3 :     if( !pUsedNumTbl )
     529           3 :         return ;            // no numbering is used
     530             : 
     531             :     // write the "list format override" - LFO
     532           3 :     sal_uInt16 nNms = 0, nCount = pUsedNumTbl->size();
     533             : 
     534           3 :     pFib->fcSttbListNames = pTableStrm->Tell();
     535           3 :     SwWW8Writer::WriteShort( *pTableStrm, -1 );
     536           3 :     SwWW8Writer::WriteLong( *pTableStrm, nCount );
     537             : 
     538           8 :     for( ; nNms < nCount; ++nNms )
     539             :     {
     540           5 :         const SwNumRule& rRule = *(*pUsedNumTbl)[ nNms ];
     541           5 :         OUString sNm;
     542           5 :         if( !rRule.IsAutoRule() )
     543           2 :             sNm = rRule.GetName();
     544             : 
     545           5 :         SwWW8Writer::WriteShort( *pTableStrm, sNm.getLength() );
     546           5 :         if (!sNm.isEmpty())
     547           2 :             SwWW8Writer::WriteString16(*pTableStrm, sNm, false);
     548           5 :     }
     549             : 
     550           3 :     SwWW8Writer::WriteLong( *pTableStrm, pFib->fcSttbListNames + 2, nNms );
     551             :     // set len to FIB
     552           3 :     pFib->lcbSttbListNames = pTableStrm->Tell() - pFib->fcSttbListNames;
     553             : }
     554             : 
     555             : // old WW95-Code
     556             : 
     557           0 : void WW8Export::OutputOlst( const SwNumRule& rRule )
     558             : {
     559           0 :     if ( bWrtWW8 )
     560           0 :         return;
     561             : 
     562             :     static const sal_uInt8 aAnlvBase[] = { // Defaults
     563             :                                 1,0,0,          // Upper Roman
     564             :                                 0x0C,           // Hanging Indent, fPrev
     565             :                                 0,0,1,0x80,0,0,1,0,0x1b,1,0,0 };
     566             : 
     567             :     static const sal_uInt8 aSprmOlstHdr[] = { 133, 212 };
     568             : 
     569           0 :     pO->insert( pO->end(), aSprmOlstHdr, aSprmOlstHdr+sizeof( aSprmOlstHdr ) );
     570             :     WW8_OLST aOlst;
     571           0 :     memset( &aOlst, 0, sizeof(aOlst) );
     572           0 :     sal_uInt8* pC = aOlst.rgch;
     573           0 :     sal_uInt8* pChars = (sal_uInt8*)pC;
     574           0 :     sal_uInt16 nCharLen = 64;
     575             : 
     576           0 :     for (sal_uInt16 j = 0; j < WW8ListManager::nMaxLevel; j++ ) // 9 variable ANLVs
     577             :     {
     578           0 :         memcpy( &aOlst.rganlv[j], aAnlvBase, sizeof( WW8_ANLV ) );  // Defaults
     579             : 
     580           0 :         const SwNumFmt* pFmt = rRule.GetNumFmt( j );
     581           0 :         if( pFmt )
     582           0 :             BuildAnlvBase( aOlst.rganlv[j], pChars, nCharLen, rRule,
     583           0 :                             *pFmt, (sal_uInt8)j );
     584             :     }
     585             : 
     586           0 :     pO->insert( pO->end(), (sal_uInt8*)&aOlst, (sal_uInt8*)&aOlst+sizeof( aOlst ) );
     587             : }
     588             : 
     589           0 : void WW8Export::Out_WwNumLvl( sal_uInt8 nWwLevel )
     590             : {
     591           0 :     pO->push_back( 13 );
     592           0 :     pO->push_back( nWwLevel );
     593           0 : }
     594             : 
     595           0 : void WW8Export::Out_SwNumLvl( sal_uInt8 nSwLevel )
     596             : {
     597             :     OSL_ENSURE( nSwLevel < MAXLEVEL, "numbered?");
     598           0 :     Out_WwNumLvl( nSwLevel + 1 );
     599           0 : }
     600             : 
     601           0 : void WW8Export::BuildAnlvBulletBase(WW8_ANLV& rAnlv, sal_uInt8*& rpCh,
     602             :     sal_uInt16& rCharLen, const SwNumFmt& rFmt)
     603             : {
     604           0 :     rAnlv.nfc = 11;
     605             : 
     606           0 :     sal_uInt8 nb = 0;                                // type of number
     607           0 :     switch (rFmt.GetNumAdjust())
     608             :     {
     609             :         case SVX_ADJUST_RIGHT:
     610           0 :             nb = 2;
     611           0 :             break;
     612             :         case SVX_ADJUST_CENTER:
     613           0 :             nb = 1;
     614           0 :             break;
     615             :         case SVX_ADJUST_BLOCK:
     616             :         case SVX_ADJUST_BLOCKLINE:
     617           0 :             nb = 3;
     618           0 :             break;
     619             :         case SVX_ADJUST_LEFT:
     620             :         case SVX_ADJUST_END:
     621           0 :             break;
     622             :     }
     623             : 
     624             :     // #i86652#
     625           0 :     if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
     626             :     {
     627           0 :         if (GetWordFirstLineOffset(rFmt) < 0)
     628           0 :             nb |= 0x8;          // number will be displayed using a hanging indent
     629             :     }
     630           0 :     rAnlv.aBits1 = nb;
     631             : 
     632           0 :     if (1 < rCharLen)
     633             :     {
     634           0 :         const Font& rFont = rFmt.GetBulletFont()
     635           0 :                             ? *rFmt.GetBulletFont()
     636           0 :                             : numfunc::GetDefBulletFont();
     637           0 :         OUString sNumStr = OUString(rFmt.GetBulletChar());
     638           0 :         rtl_TextEncoding eChrSet = rFont.GetCharSet();
     639           0 :         OUString sFontName = rFont.GetName();
     640             : 
     641             :         sal_uInt16 nFontId;
     642           0 :         if ( IsStarSymbol(sFontName) )
     643             :         {
     644             :             /*
     645             :             If we are starsymbol then in ww7- mode we will always convert to a
     646             :             windows 8bit symbol font and an index into it, to conversion to
     647             :             8 bit is complete at this stage.
     648             :             */
     649           0 :             SubstituteBullet(sNumStr, eChrSet, sFontName);
     650             :             wwFont aPseudoFont(sFontName, rFont.GetPitch(), rFont.GetFamily(),
     651           0 :                 eChrSet, bWrtWW8);
     652           0 :             nFontId = maFontHelper.GetId(aPseudoFont);
     653           0 :             *rpCh = static_cast<sal_uInt8>(sNumStr[0]);
     654             :         }
     655             :         else
     656             :         {
     657             :             /*
     658             :             Otherwise we are a unicode char and need to be converted back to
     659             :             an 8 bit format. We happen to know that if the font is already an
     660             :             8 bit windows font currently, staroffice promotes the char into
     661             :             the F000->F0FF range, so we can undo this, and we'll be back to
     662             :             the equivalent 8bit location, otherwise we have to convert from
     663             :             true unicode to an 8bit charset
     664             :             */
     665           0 :             nFontId = maFontHelper.GetId(rFont);
     666           0 :             sal_Unicode cChar = sNumStr[0];
     667           0 :             if ( (eChrSet == RTL_TEXTENCODING_SYMBOL) && (cChar >= 0xF000) && (
     668             :                 cChar <= 0xF0FF) )
     669             :             {
     670           0 :                 *rpCh = static_cast< sal_uInt8 >(cChar - 0xF000);
     671             :             }
     672             :             else
     673           0 :                 *rpCh = OUStringToOString(OUString(cChar), eChrSet).toChar();
     674             :         }
     675           0 :         rpCh++;
     676           0 :         rCharLen--;
     677           0 :         ShortToSVBT16(nFontId, rAnlv.ftc);
     678           0 :         rAnlv.cbTextBefore = 1;
     679             :     }
     680             :     // #i86652#
     681           0 :     if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
     682             :     {
     683           0 :         ShortToSVBT16( -GetWordFirstLineOffset(rFmt), rAnlv.dxaIndent );
     684           0 :         ShortToSVBT16( rFmt.GetCharTextDistance(), rAnlv.dxaSpace );
     685             :     }
     686             :     else
     687             :     {
     688           0 :         ShortToSVBT16( 0, rAnlv.dxaIndent );
     689           0 :         ShortToSVBT16( 0, rAnlv.dxaSpace );
     690             :     }
     691           0 : }
     692             : 
     693           3 : void MSWordExportBase::SubstituteBullet( OUString& rNumStr,
     694             :     rtl_TextEncoding& rChrSet, OUString& rFontName ) const
     695             : {
     696           3 :     if (!bSubstituteBullets)
     697           3 :         return;
     698           3 :     OUString sFontName = rFontName;
     699             : 
     700             :     // If Bullet char is "", don't change
     701           3 :     if (rNumStr[0] != sal_Unicode(0x0))
     702             :     {
     703           3 :         rNumStr = rNumStr.replaceAt(0, 1, OUString( msfilter::util::bestFitOpenSymbolToMSFont(rNumStr[0], rChrSet, sFontName, !SupportsUnicode()) ));
     704             :     }
     705             : 
     706           3 :     rFontName = sFontName;
     707             : }
     708             : 
     709           0 : static void SwWw8_InsertAnlText( const OUString& rStr, sal_uInt8*& rpCh,
     710             :                                  sal_uInt16& rCharLen, sal_uInt8& r8Len )
     711             : {
     712           0 :     sal_uInt8 nb = 0;
     713           0 :     ww::bytes aO;
     714           0 :     SwWW8Writer::InsAsString8( aO, rStr, RTL_TEXTENCODING_MS_1252 );
     715             : 
     716           0 :     sal_uInt16 nCnt = aO.size();
     717           0 :     if( nCnt && nCnt < rCharLen )
     718             :     {
     719           0 :         nb = (sal_uInt8)nCnt;
     720           0 :         std::copy( aO.begin(), aO.end(), rpCh );
     721           0 :         rpCh += nCnt;
     722           0 :         rCharLen = rCharLen - nCnt;
     723             :     }
     724           0 :     r8Len = nb;
     725           0 : }
     726             : 
     727           0 : void WW8Export::BuildAnlvBase(WW8_ANLV& rAnlv, sal_uInt8*& rpCh,
     728             :     sal_uInt16& rCharLen, const SwNumRule& rRul, const SwNumFmt& rFmt,
     729             :     sal_uInt8 nSwLevel)
     730             : {
     731           0 :     rAnlv.nfc = WW8Export::GetNumId(rFmt.GetNumberingType());
     732             : 
     733           0 :     sal_uInt8 nb = 0;
     734           0 :     switch (rFmt.GetNumAdjust())
     735             :     {
     736             :         case SVX_ADJUST_RIGHT:
     737           0 :             nb = 2;
     738           0 :             break;
     739             :         case SVX_ADJUST_CENTER:
     740           0 :             nb = 1;
     741           0 :             break;
     742             :         case SVX_ADJUST_BLOCK:
     743             :         case SVX_ADJUST_BLOCKLINE:
     744           0 :             nb = 3;
     745           0 :             break;
     746             :         case SVX_ADJUST_LEFT:
     747             :         case SVX_ADJUST_END:
     748           0 :             break;
     749             :     }
     750             : 
     751           0 :     bool bInclUpper = rFmt.GetIncludeUpperLevels() > 0;
     752           0 :     if( bInclUpper )
     753           0 :         nb |= 0x4;          // include previous levels
     754             : 
     755           0 :     if (GetWordFirstLineOffset(rFmt) < 0)
     756           0 :         nb |= 0x8;          // number will be displayed using a hanging indent
     757           0 :     rAnlv.aBits1 = nb;
     758             : 
     759           0 :     if( bInclUpper && !rRul.IsContinusNum() )
     760             :     {
     761           0 :         if( (nSwLevel >= WW8ListManager::nMinLevel )
     762           0 :             && (nSwLevel<= WW8ListManager::nMaxLevel )
     763           0 :             && (rFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE ) )  // UEberhaupt Nummerierung ?
     764             :         {                                               // -> suche, ob noch Zahlen davor
     765           0 :             sal_uInt8 nUpper = rFmt.GetIncludeUpperLevels();
     766           0 :             if( (nUpper <= WW8ListManager::nMaxLevel) &&
     767           0 :                 (rRul.Get(nUpper).GetNumberingType() != SVX_NUM_NUMBER_NONE ) ) // Nummerierung drueber ?
     768             :             {
     769             :                                                     // dann Punkt einfuegen
     770             :                 SwWw8_InsertAnlText( ".", rpCh, rCharLen,
     771           0 :                                     rAnlv.cbTextBefore );
     772             :             }
     773             : 
     774             :         }
     775             :     }
     776             :     else
     777             :     {
     778           0 :         SwWw8_InsertAnlText( rFmt.GetPrefix(), rpCh, rCharLen,
     779           0 :                              rAnlv.cbTextBefore );
     780           0 :         SwWw8_InsertAnlText( rFmt.GetSuffix(), rpCh, rCharLen,
     781           0 :                              rAnlv.cbTextAfter );
     782             :     }
     783             : 
     784           0 :     ShortToSVBT16( rFmt.GetStart(), rAnlv.iStartAt );
     785             :     // #i86652#
     786           0 :     if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
     787             :     {
     788           0 :         ShortToSVBT16( -GetWordFirstLineOffset(rFmt), rAnlv.dxaIndent );
     789           0 :         ShortToSVBT16( rFmt.GetCharTextDistance(), rAnlv.dxaSpace );
     790             :     }
     791             :     else
     792             :     {
     793           0 :         ShortToSVBT16( 0, rAnlv.dxaIndent );
     794           0 :         ShortToSVBT16( 0, rAnlv.dxaSpace );
     795             :     }
     796           0 : }
     797             : 
     798           0 : void WW8Export::Out_NumRuleAnld( const SwNumRule& rRul, const SwNumFmt& rFmt,
     799             :                                    sal_uInt8 nSwLevel )
     800             : {
     801             :     static const sal_uInt8 aSprmAnldDefault[54] = {
     802             :                          12, 52,
     803             :                          1,0,0,0x0c,0,0,1,0x80,0,0,1,0,0x1b,1,0,0,0x2e,
     804             :                          0,0,0,
     805             :                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     806             :                          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
     807             :     sal_uInt8 aSprmAnld[54];
     808             : 
     809           0 :     memcpy( aSprmAnld, aSprmAnldDefault, sizeof( aSprmAnld ) );
     810           0 :     WW8_ANLD* pA = (WW8_ANLD*)(aSprmAnld + 2);  // handy pointer
     811             : 
     812           0 :     sal_uInt8* pChars = (sal_uInt8*)(pA->rgchAnld);
     813           0 :     sal_uInt16 nCharLen = 31;
     814             : 
     815           0 :     if( nSwLevel == 11 )
     816           0 :         BuildAnlvBulletBase( pA->eAnlv, pChars, nCharLen, rFmt );
     817             :     else
     818           0 :         BuildAnlvBase( pA->eAnlv, pChars, nCharLen, rRul, rFmt, nSwLevel );
     819             : 
     820             :     // ... spit it out
     821           0 :     OutSprmBytes( (sal_uInt8*)&aSprmAnld, sizeof( aSprmAnld ) );
     822           0 : }
     823             : 
     824             : // Return: is it an outline?
     825           0 : bool WW8Export::Out_SwNum(const SwTxtNode* pNd)
     826             : {
     827           0 :     int nLevel = pNd->GetActualListLevel();
     828             : 
     829           0 :     if (nLevel < 0 || nLevel >= MAXLEVEL)
     830             :     {
     831             :         OSL_FAIL("Invalid level");
     832             : 
     833           0 :         return false;
     834             :     }
     835             : 
     836           0 :     sal_uInt8 nSwLevel = static_cast< sal_uInt8 >(nLevel);
     837             : 
     838           0 :     const SwNumRule* pRul = pNd->GetNumRule();
     839           0 :     if( !pRul || nSwLevel == WW8ListManager::nMaxLevel)
     840           0 :         return false;
     841             : 
     842           0 :     bool bRet = true;
     843             : 
     844           0 :     SwNumFmt aFmt(pRul->Get(nSwLevel));
     845             :     // #i86652#
     846           0 :     if ( aFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
     847             :     {
     848           0 :         const SvxLRSpaceItem& rLR = ItemGet<SvxLRSpaceItem>(*pNd, RES_LR_SPACE);
     849           0 :         aFmt.SetAbsLSpace(writer_cast<short>(aFmt.GetAbsLSpace() + rLR.GetLeft()));
     850             :     }
     851             : 
     852           0 :     if (
     853           0 :          aFmt.GetNumberingType() == SVX_NUM_NUMBER_NONE ||
     854           0 :          aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL ||
     855           0 :          aFmt.GetNumberingType() == SVX_NUM_BITMAP
     856             :        )
     857             :     {
     858           0 :         Out_WwNumLvl(11);
     859           0 :         Out_NumRuleAnld(*pRul, aFmt, 11);
     860           0 :         bRet = false;
     861             :     }
     862           0 :     else if (
     863           0 :               pRul->IsContinusNum() ||
     864           0 :               (pRul->Get(1).GetIncludeUpperLevels() <= 1)
     865             :             )
     866             :     {
     867           0 :         Out_WwNumLvl(10);
     868           0 :         Out_NumRuleAnld(*pRul, aFmt, 10);
     869           0 :         bRet = false;
     870             :     }
     871             :     else
     872             :     {
     873           0 :         Out_SwNumLvl(nSwLevel);
     874           0 :         Out_NumRuleAnld(*pRul, aFmt, nSwLevel);
     875             :     }
     876           0 :     return bRet;
     877          33 : }
     878             : 
     879             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10