/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
 
#include <hintids.hxx>
#include <vcl/font.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/langitem.hxx>
#include <doc.hxx>
#include <docary.hxx>
#include <numrule.hxx>
#include <paratr.hxx>
#include <charfmt.hxx>
#include <ndtxt.hxx>
#include <unotools/fontcfg.hxx>
#include <com/sun/star/i18n/ScriptType.hpp>
 
#include "sprmids.hxx"
 
#include "ww8attributeoutput.hxx"
#include "writerhelper.hxx"
#include "writerwordglue.hxx"
#include "wrtww8.hxx"
#include "ww8par.hxx"
 
using namespace ::com::sun::star;
using namespace sw::types;
using namespace sw::util;
 
sal_uInt16 MSWordExportBase::DuplicateNumRule( const SwNumRule *pRule, sal_uInt8 nLevel, sal_uInt16 nVal )
{
    sal_uInt16 nNumId = USHRT_MAX;
    const OUString sPrefix("WW8TempExport" + OUString::number( m_nUniqueList++ ));
    SwNumRule* pMyNumRule =
            new SwNumRule( m_pDoc->GetUniqueNumRuleName( &sPrefix ),
                           SvxNumberFormat::LABEL_WIDTH_AND_POSITION );
    m_pUsedNumTable->push_back( pMyNumRule );
 
    for ( sal_uInt16 i = 0; i < MAXLEVEL; i++ )
    {
        const SwNumFormat& rSubRule = pRule->Get(i);
        pMyNumRule->Set( i, rSubRule );
    }
 
    SwNumFormat aNumFormat( pMyNumRule->Get( nLevel ) );
    aNumFormat.SetStart( nVal );
    pMyNumRule->Set( nLevel, aNumFormat );
 
    nNumId = GetId( *pMyNumRule );
 
    // Map the old list to our new list
    m_aRuleDuplicates[GetId( *pRule )] = nNumId;
 
    return nNumId;
}
 
sal_uInt16 MSWordExportBase::GetId( const SwNumRule& rNumRule )
{
    if ( !m_pUsedNumTable )
    {
        m_pUsedNumTable.reset(new SwNumRuleTable);
        m_pUsedNumTable->insert( m_pUsedNumTable->begin(), m_pDoc->GetNumRuleTable().begin(), m_pDoc->GetNumRuleTable().end() );
        // Check, if the outline rule is already inserted into <pUsedNumTable>.
        // If yes, do not insert it again.
        bool bOutlineRuleAdded( false );
        for ( sal_uInt16 n = m_pUsedNumTable->size(); n; )
        {
            const SwNumRule& rRule = *(*m_pUsedNumTable)[ --n ];
            if ( !SwDoc::IsUsed( rRule ) )
            {
                m_pUsedNumTable->erase( m_pUsedNumTable->begin() + n );
            }
            else if ( &rRule == m_pDoc->GetOutlineNumRule() )
            {
                bOutlineRuleAdded = true;
            }
        }
 
        if ( !bOutlineRuleAdded )
        {
            // still need to paste the OutlineRule
            SwNumRule* pR = m_pDoc->GetOutlineNumRule();
            m_pUsedNumTable->push_back( pR );
        }
    }
    SwNumRule* p = const_cast<SwNumRule*>(&rNumRule);
    sal_uInt16 nRet = static_cast<sal_uInt16>(m_pUsedNumTable->GetPos(p));
 
    // Is this list now duplicated into a new list which we should use
    // #i77812# - perform 'deep' search in duplication map
    std::map<sal_uInt16,sal_uInt16>::const_iterator aResult = m_aRuleDuplicates.end();
    do {
        aResult = m_aRuleDuplicates.find(nRet);
        if ( aResult != m_aRuleDuplicates.end() )
        {
            nRet = (*aResult).second;
        }
    } while ( aResult != m_aRuleDuplicates.end() );
 
    return nRet;
}
 
// GetFirstLineOffset should problem never appear unadorned apart from
// here in the ww export filter
sal_Int16 GetWordFirstLineOffset(const SwNumFormat &rFormat)
{
    OSL_ENSURE( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION,
            "<GetWordFirstLineOffset> - misusage: position-and-space-mode does not equal LABEL_WIDTH_AND_POSITION" );
 
    short nFirstLineOffset;
    if (rFormat.GetNumAdjust() == SvxAdjust::Right)
        nFirstLineOffset = -rFormat.GetCharTextDistance();
    else
        nFirstLineOffset = rFormat.GetFirstLineOffset(); //TODO: overflow
    return nFirstLineOffset;
}
 
void WW8Export::WriteNumbering()
{
    if ( !m_pUsedNumTable )
        return; // no numbering is used
 
    // list formats - LSTF
    pFib->m_fcPlcfLst = pTableStrm->Tell();
    SwWW8Writer::WriteShort( *pTableStrm, m_pUsedNumTable->size() );
    NumberingDefinitions();
    // set len to FIB
    pFib->m_lcbPlcfLst = pTableStrm->Tell() - pFib->m_fcPlcfLst;
 
    // list formats - LVLF
    AbstractNumberingDefinitions();
 
    // list formats - LFO
    OutOverrideListTab();
 
    // list formats - ListNames
    OutListNamesTab();
}
 
void WW8AttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule )
{
    SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId );
    SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nId );
 
    // not associated with a Style
    for ( int i = 0; i < WW8ListManager::nMaxLevel; ++i )
        SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0xFFF );
 
    sal_uInt8 nFlags = 0;
    if ( rRule.IsContinusNum() )
        nFlags |= 0x1;
 
    m_rWW8Export.pTableStrm->WriteUChar( nFlags ).WriteUChar( 0/*nDummy*/ );
}
 
void MSWordExportBase::NumberingDefinitions()
{
    if ( !m_pUsedNumTable )
        return; // no numbering is used
 
    sal_uInt16 nCount = m_pUsedNumTable->size();
 
    // Write static data of SwNumRule - LSTF
    for ( sal_uInt16 n = 0; n < nCount; ++n )
    {
        const SwNumRule& rRule = *(*m_pUsedNumTable)[ n ];
 
        AttrOutput().NumberingDefinition( n + 1, rRule );
    }
}
 
static sal_uInt8 GetLevelNFC(  sal_uInt16 eNumType, const SfxItemSet *pOutSet)
{
    sal_uInt8 nRet = 0;
    switch( eNumType )
    {
    case SVX_NUM_CHARS_UPPER_LETTER:
    case SVX_NUM_CHARS_UPPER_LETTER_N:  nRet = 3;       break;
    case SVX_NUM_CHARS_LOWER_LETTER:
    case SVX_NUM_CHARS_LOWER_LETTER_N:  nRet = 4;       break;
    case SVX_NUM_ROMAN_UPPER:           nRet = 1;       break;
    case SVX_NUM_ROMAN_LOWER:           nRet = 2;       break;
 
    case SVX_NUM_BITMAP:
    case SVX_NUM_CHAR_SPECIAL:         nRet = 23;      break;
    case SVX_NUM_FULL_WIDTH_ARABIC: nRet = 14; break;
    case SVX_NUM_CIRCLE_NUMBER: nRet = 18;break;
    case SVX_NUM_NUMBER_LOWER_ZH:
        nRet = 35;
        if ( pOutSet ) {
            const SvxLanguageItem rLang = pOutSet->Get( RES_CHRATR_CJK_LANGUAGE);
            const LanguageType eLang = rLang.GetLanguage();
            if (LANGUAGE_CHINESE_SIMPLIFIED ==eLang) {
                nRet = 39;
            }
        }
        break;
    case SVX_NUM_NUMBER_UPPER_ZH: nRet = 38; break;
    case SVX_NUM_NUMBER_UPPER_ZH_TW: nRet = 34;break;
    case SVX_NUM_TIAN_GAN_ZH: nRet = 30; break;
    case SVX_NUM_DI_ZI_ZH: nRet = 31; break;
    case SVX_NUM_NUMBER_TRADITIONAL_JA: nRet = 16; break;
    case SVX_NUM_AIU_FULLWIDTH_JA: nRet = 20; break;
    case SVX_NUM_AIU_HALFWIDTH_JA: nRet = 12; break;
    case SVX_NUM_IROHA_FULLWIDTH_JA: nRet = 21; break;
    case SVX_NUM_IROHA_HALFWIDTH_JA: nRet = 13; break;
    case style::NumberingType::HANGUL_SYLLABLE_KO: nRet = 24; break;// ganada
    case style::NumberingType::HANGUL_JAMO_KO: nRet = 25; break;// chosung
    case style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO: nRet = 24; break;
    case style::NumberingType::HANGUL_CIRCLED_JAMO_KO: nRet = 25; break;
    case style::NumberingType::NUMBER_HANGUL_KO: nRet = 41; break;
    case style::NumberingType::NUMBER_UPPER_KO: nRet = 44; break;
    case SVX_NUM_NUMBER_NONE:           nRet = 0xff;    break;
    }
    return nRet;
}
 
 
void WW8AttributeOutput::NumberingLevel( sal_uInt8 /*nLevel*/,
        sal_uInt16 nStart,
        sal_uInt16 nNumberingType,
        SvxAdjust eAdjust,
        const sal_uInt8 *pNumLvlPos,
        sal_uInt8 nFollow,
        const wwFont *pFont,
        const SfxItemSet *pOutSet,
        sal_Int16 nIndentAt,
        sal_Int16 nFirstLineIndex,
        sal_Int16 nListTabPos,
        const OUString &rNumberingString,
        const SvxBrushItem* pBrush //For i120928,to transfer graphic of bullet
    )
{
    // Start value
    SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, nStart );
 
    // Type
    m_rWW8Export.pTableStrm->WriteUChar( GetLevelNFC( nNumberingType ,pOutSet) );
 
    // Justification
    sal_uInt8 nAlign;
    switch ( eAdjust )
    {
    case SvxAdjust::Center:
        nAlign = 1;
        break;
    case SvxAdjust::Right:
        nAlign = 2;
        break;
    default:
        nAlign = 0;
        break;
    }
    m_rWW8Export.pTableStrm->WriteUChar( nAlign );
 
    // Write the rgbxchNums[9], positions of placeholders for paragraph
    // numbers in the text
    m_rWW8Export.pTableStrm->WriteBytes(pNumLvlPos, WW8ListManager::nMaxLevel);
 
    // Type of the character between the bullet and the text
    m_rWW8Export.pTableStrm->WriteUChar( nFollow );
 
    // dxaSoace/dxaIndent (Word 6 compatibility)
    SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
    SwWW8Writer::WriteLong( *m_rWW8Export.pTableStrm, 0 );
 
    // cbGrpprlChpx
    ww::bytes aCharAtrs;
    if ( pOutSet )
    {
        ww::bytes* pOldpO = m_rWW8Export.pO;
        m_rWW8Export.pO = &aCharAtrs;
        if ( pFont )
        {
            sal_uInt16 nFontID = m_rWW8Export.m_aFontHelper.GetId( *pFont );
 
            m_rWW8Export.InsUInt16( NS_sprm::sprmCRgFtc0 );
            m_rWW8Export.InsUInt16( nFontID );
            m_rWW8Export.InsUInt16( NS_sprm::sprmCRgFtc2 );
            m_rWW8Export.InsUInt16( nFontID );
        }
 
        m_rWW8Export.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN, m_rWW8Export.m_bExportModeRTF );
        //For i120928,achieve graphic's index of bullet from the bullet bookmark
        if (SVX_NUM_BITMAP == nNumberingType && pBrush)
        {
            int nIndex = m_rWW8Export.GetGrfIndex(*pBrush);
            if ( nIndex != -1 )
            {
                m_rWW8Export.InsUInt16(NS_sprm::sprmCPbiIBullet);
                m_rWW8Export.InsUInt32(nIndex);
                m_rWW8Export.InsUInt16(NS_sprm::sprmCPbiGrf);
                m_rWW8Export.InsUInt16(1);
            }
        }
 
        m_rWW8Export.pO = pOldpO;
    }
    m_rWW8Export.pTableStrm->WriteUChar( sal_uInt8( aCharAtrs.size() ) );
 
    // cbGrpprlPapx
    sal_uInt8 aPapSprms [] = {
        0x5e, 0x84, 0, 0,               // sprmPDxaLeft
        0x60, 0x84, 0, 0,               // sprmPDxaLeft1
        0x15, 0xc6, 0x05, 0x00, 0x01, 0, 0, 0x06
    };
    m_rWW8Export.pTableStrm->WriteUChar( sal_uInt8( sizeof( aPapSprms ) ) );
 
    // reserved
    SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, 0 );
 
    // pap sprms
    sal_uInt8* pData = aPapSprms + 2;
    Set_UInt16( pData, nIndentAt );
    pData += 2;
    Set_UInt16( pData, nFirstLineIndex );
    pData += 5;
    Set_UInt16( pData, nListTabPos );
 
    m_rWW8Export.pTableStrm->WriteBytes(aPapSprms, sizeof(aPapSprms));
 
    // write Chpx
    if( !aCharAtrs.empty() )
        m_rWW8Export.pTableStrm->WriteBytes(aCharAtrs.data(), aCharAtrs.size());
 
    // write the num string
    SwWW8Writer::WriteShort( *m_rWW8Export.pTableStrm, rNumberingString.getLength() );
    SwWW8Writer::WriteString16( *m_rWW8Export.pTableStrm, rNumberingString, false );
}
 
void MSWordExportBase::AbstractNumberingDefinitions()
{
    sal_uInt16 nCount = m_pUsedNumTable->size();
    sal_uInt16 n;
 
    // prepare the NodeNum to generate the NumString
    SwNumberTree::tNumberVector aNumVector;
    for ( n = 0; n < WW8ListManager::nMaxLevel; ++n )
        aNumVector.push_back( n );
 
    for( n = 0; n < nCount; ++n )
    {
        AttrOutput().StartAbstractNumbering( n + 1 );
 
        const SwNumRule& rRule = *(*m_pUsedNumTable)[ n ];
        sal_uInt8 nLvl;
        sal_uInt8 nLevels = static_cast< sal_uInt8 >(rRule.IsContinusNum() ?
            WW8ListManager::nMinLevel : WW8ListManager::nMaxLevel);
        for( nLvl = 0; nLvl < nLevels; ++nLvl )
        {
            // write the static data of the SwNumFormat of this level
            sal_uInt8 aNumLvlPos[WW8ListManager::nMaxLevel] = { 0,0,0,0,0,0,0,0,0 };
 
            const SwNumFormat& rFormat = rRule.Get( nLvl );
 
            sal_uInt8 nFollow = 0;
            // #i86652#
            if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
            {
                nFollow = 2;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
            }
            else if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
            {
                switch ( rFormat.GetLabelFollowedBy() )
                {
                    case SvxNumberFormat::LISTTAB:
                    {
            // 0 (tab) unless there would be no content before the tab, in which case 2 (nothing)
            nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 0 : 2;
                    }
                    break;
                    case SvxNumberFormat::SPACE:
                    {
            // 1 (space) unless there would be no content before the space in which case 2 (nothing)
            nFollow = (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType()) ? 1 : 2;
                    }
                    break;
                    case SvxNumberFormat::NOTHING:
                    {
                        nFollow = 2;
                    }
                    break;
                    default:
                    {
                        nFollow = 0;
                        OSL_FAIL( "unknown GetLabelFollowedBy() return value" );
                    }
                }
            }
 
            // Build the NumString for this Level
            OUString sNumStr;
            OUString sFontName;
            bool bWriteBullet = false;
            const vcl::Font* pBulletFont=nullptr;
            rtl_TextEncoding eChrSet=0;
            FontFamily eFamily=FAMILY_DECORATIVE;
            if( SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType() ||
                SVX_NUM_BITMAP == rFormat.GetNumberingType() )
            {
                sNumStr = OUString(rFormat.GetBulletChar());
                bWriteBullet = true;
 
                pBulletFont = rFormat.GetBulletFont();
                if (!pBulletFont)
                {
                    pBulletFont = &numfunc::GetDefBulletFont();
                }
 
                eChrSet = pBulletFont->GetCharSet();
                sFontName = pBulletFont->GetFamilyName();
                eFamily = pBulletFont->GetFamilyType();
 
                if ( IsStarSymbol(sFontName) )
                    SubstituteBullet( sNumStr, eChrSet, sFontName );
 
                // #i86652#
                if ( rFormat.GetPositionAndSpaceMode() ==
                                        SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
                {
                    // <nFollow = 2>, if minimum label width equals 0 and
                    // minimum distance between label and text equals 0
                    nFollow = ( rFormat.GetFirstLineOffset() == 0 &&
                                rFormat.GetCharTextDistance() == 0 )
                              ? 2 : 0;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
                }
            }
            else
            {
                if (SVX_NUM_NUMBER_NONE != rFormat.GetNumberingType())
                {
                    sal_uInt8* pLvlPos = aNumLvlPos;
                    // the numbering string has to be restrict
                    // to the level currently working on.
                    sNumStr = rRule.MakeNumString(aNumVector, false, true, nLvl);
 
                    // now search the nums in the string
                    for( sal_uInt8 i = 0; i <= nLvl; ++i )
                    {
                        OUString sSrch( OUString::number( i ));
                        sal_Int32 nFnd = sNumStr.indexOf( sSrch );
                        if( -1 != nFnd )
                        {
                            *pLvlPos = static_cast<sal_uInt8>(nFnd + rFormat.GetPrefix().getLength() + 1 );
                            ++pLvlPos;
                            sNumStr = sNumStr.replaceAt( nFnd, 1, OUString(static_cast<char>(i)) );
                        }
                    }
                    // #i86652#
                    if ( rFormat.GetPositionAndSpaceMode() ==
                                            SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
                    {
                        // <nFollow = 2>, if minimum label width equals 0 and
                        // minimum distance between label and text equals 0
                        nFollow = ( rFormat.GetFirstLineOffset() == 0 &&
                                    rFormat.GetCharTextDistance() == 0 )
                                  ? 2 : 0;     // ixchFollow: 0 - tab, 1 - blank, 2 - nothing
                    }
                }
 
                if( !rFormat.GetPrefix().isEmpty() )
                    sNumStr = rFormat.GetPrefix() + sNumStr;
                sNumStr += rFormat.GetSuffix();
            }
 
            // Attributes of the numbering
            wwFont *pPseudoFont = nullptr;
            const SfxItemSet* pOutSet = nullptr;
 
            // cbGrpprlChpx
            SfxItemSet aSet( m_pDoc->GetAttrPool(), svl::Items<RES_CHRATR_BEGIN,
                                                  RES_CHRATR_END>{} );
            if ( rFormat.GetCharFormat() || bWriteBullet )
            {
                if ( bWriteBullet )
                {
                    pOutSet = &aSet;
 
                    if ( rFormat.GetCharFormat() )
                        aSet.Put( rFormat.GetCharFormat()->GetAttrSet() );
                    aSet.ClearItem( RES_CHRATR_CJK_FONT );
                    aSet.ClearItem( RES_CHRATR_FONT );
 
                    if ( sFontName.isEmpty() )
                        sFontName = pBulletFont->GetFamilyName();
 
                    pPseudoFont = new wwFont( sFontName, pBulletFont->GetPitch(),
                        eFamily, eChrSet);
                }
                else
                    pOutSet = &rFormat.GetCharFormat()->GetAttrSet();
            }
 
            sal_Int16 nIndentAt = 0;
            sal_Int16 nFirstLineIndex = 0;
            sal_Int16 nListTabPos = 0;
 
            // #i86652#
            if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
            {
                nIndentAt = nListTabPos = rFormat.GetAbsLSpace(); //TODO: overflow
                nFirstLineIndex = GetWordFirstLineOffset(rFormat);
            }
            else if ( rFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
            {
                nIndentAt = static_cast<sal_Int16>(rFormat.GetIndentAt());
                nFirstLineIndex = static_cast<sal_Int16>(rFormat.GetFirstLineIndent());
                nListTabPos = rFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB?
                              static_cast<sal_Int16>( rFormat.GetListtabPos() ) : 0;
            }
 
            AttrOutput().NumberingLevel( nLvl,
                    rFormat.GetStart(),
                    rFormat.GetNumberingType(),
                    rFormat.GetNumAdjust(),
                    aNumLvlPos,
                    nFollow,
                    pPseudoFont, pOutSet,
                    nIndentAt, nFirstLineIndex, nListTabPos,
                    sNumStr,
                    rFormat.GetNumberingType()==SVX_NUM_BITMAP ? rFormat.GetBrush():nullptr);
 
            delete pPseudoFont;
        }
        AttrOutput().EndAbstractNumbering();
    }
}
 
void WW8Export::OutOverrideListTab()
{
    if( !m_pUsedNumTable )
        return ;            // no numbering is used
 
    // write the "list format override" - LFO
    sal_uInt16 nCount = m_pUsedNumTable->size();
    sal_uInt16 n;
 
    pFib->m_fcPlfLfo = pTableStrm->Tell();
    SwWW8Writer::WriteLong( *pTableStrm, nCount );
 
    for( n = 0; n < nCount; ++n )
    {
        SwWW8Writer::WriteLong( *pTableStrm, n + 1 );
        SwWW8Writer::FillCount( *pTableStrm, 12 );
    }
    for( n = 0; n < nCount; ++n )
        SwWW8Writer::WriteLong( *pTableStrm, -1 );  // no overwrite
 
    // set len to FIB
    pFib->m_lcbPlfLfo = pTableStrm->Tell() - pFib->m_fcPlfLfo;
}
 
void WW8Export::OutListNamesTab()
{
    if( !m_pUsedNumTable )
        return ;            // no numbering is used
 
    // write the "list format override" - LFO
    sal_uInt16 nNms = 0, nCount = m_pUsedNumTable->size();
 
    pFib->m_fcSttbListNames = pTableStrm->Tell();
    SwWW8Writer::WriteShort( *pTableStrm, -1 );
    SwWW8Writer::WriteLong( *pTableStrm, nCount );
 
    for( ; nNms < nCount; ++nNms )
    {
        const SwNumRule& rRule = *(*m_pUsedNumTable)[ nNms ];
        OUString sNm;
        if( !rRule.IsAutoRule() )
            sNm = rRule.GetName();
 
        SwWW8Writer::WriteShort( *pTableStrm, sNm.getLength() );
        if (!sNm.isEmpty())
            SwWW8Writer::WriteString16(*pTableStrm, sNm, false);
    }
 
    SwWW8Writer::WriteLong( *pTableStrm, pFib->m_fcSttbListNames + 2, nNms );
    // set len to FIB
    pFib->m_lcbSttbListNames = pTableStrm->Tell() - pFib->m_fcSttbListNames;
}
 
void MSWordExportBase::SubstituteBullet( OUString& rNumStr,
    rtl_TextEncoding& rChrSet, OUString& rFontName ) const
{
    if (!m_bSubstituteBullets)
        return;
    OUString sFontName = rFontName;
 
    // If Bullet char is "", don't change
    if (rNumStr[0] != u'\0')
    {
        rNumStr = rNumStr.replaceAt(0, 1, OUString(
            msfilter::util::bestFitOpenSymbolToMSFont(rNumStr[0], rChrSet, sFontName)));
    }
 
    rFontName = sFontName;
}
 
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

V1029 Numeric Truncation Error. Result of the 'size' function is written to the 16-bit variable.

V1029 Numeric Truncation Error. Result of the 'size' function is written to the 16-bit variable.

V1029 Numeric Truncation Error. Result of the 'size' function is written to the 16-bit variable.

V1029 Numeric Truncation Error. Result of the 'size' function is written to the 16-bit variable.

V1029 Numeric Truncation Error. Result of the 'size' function is written to the 16-bit variable.