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

Generated by: LCOV version 1.10