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

Generated by: LCOV version 1.10