LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/filter/excel - xestyle.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1099 1506 73.0 %
Date: 2013-07-09 Functions: 165 192 85.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "xestyle.hxx"
      21             : 
      22             : #include <iostream>
      23             : #include <algorithm>
      24             : #include <iterator>
      25             : #include <set>
      26             : #include <com/sun/star/i18n/ScriptType.hpp>
      27             : #include <vcl/font.hxx>
      28             : #include <svl/zformat.hxx>
      29             : #include <svl/itempool.hxx>
      30             : #include <svl/languageoptions.hxx>
      31             : #include <sfx2/printer.hxx>
      32             : #include "scitems.hxx"
      33             : #include <svx/algitem.hxx>
      34             : #include <editeng/boxitem.hxx>
      35             : #include <editeng/lineitem.hxx>
      36             : #include <svx/rotmodit.hxx>
      37             : #include <editeng/colritem.hxx>
      38             : #include <editeng/brushitem.hxx>
      39             : #include <editeng/frmdiritem.hxx>
      40             : #include <editeng/eeitem.hxx>
      41             : #include <editeng/escapementitem.hxx>
      42             : #include <editeng/justifyitem.hxx>
      43             : #include "document.hxx"
      44             : #include "stlpool.hxx"
      45             : #include "stlsheet.hxx"
      46             : #include "patattr.hxx"
      47             : #include "attrib.hxx"
      48             : #include "globstr.hrc"
      49             : #include "xestring.hxx"
      50             : #include "conditio.hxx"
      51             : 
      52             : #include <oox/token/tokens.hxx>
      53             : #include <boost/ptr_container/ptr_vector.hpp>
      54             : 
      55             : using namespace ::com::sun::star;
      56             : using namespace oox;
      57             : 
      58             : // PALETTE record - color information =========================================
      59             : 
      60             : namespace {
      61             : 
      62          40 : sal_uInt32 lclGetWeighting( XclExpColorType eType )
      63             : {
      64          40 :     switch( eType )
      65             :     {
      66          10 :         case EXC_COLOR_CHARTLINE:   return 1;
      67             :         case EXC_COLOR_CELLBORDER:
      68           2 :         case EXC_COLOR_CHARTAREA:   return 2;
      69             :         case EXC_COLOR_CELLTEXT:
      70             :         case EXC_COLOR_CHARTTEXT:
      71          28 :         case EXC_COLOR_CTRLTEXT:    return 10;
      72             :         case EXC_COLOR_TABBG:
      73           0 :         case EXC_COLOR_CELLAREA:    return 20;
      74           0 :         case EXC_COLOR_GRID:        return 50;
      75             :         default:    OSL_FAIL( "lclGetWeighting - unknown color type" );
      76             :     }
      77           0 :     return 1;
      78             : }
      79             : 
      80        1056 : sal_Int32 lclGetColorDistance( const Color& rColor1, const Color& rColor2 )
      81             : {
      82        1056 :     sal_Int32 nDist = rColor1.GetRed() - rColor2.GetRed();
      83        1056 :     nDist *= nDist * 77;
      84        1056 :     sal_Int32 nDummy = rColor1.GetGreen() - rColor2.GetGreen();
      85        1056 :     nDist += nDummy * nDummy * 151;
      86        1056 :     nDummy = rColor1.GetBlue() - rColor2.GetBlue();
      87        1056 :     nDist += nDummy * nDummy * 28;
      88        1056 :     return nDist;
      89             : }
      90             : 
      91           0 : sal_uInt8 lclGetMergedColorComp( sal_uInt8 nComp1, sal_uInt32 nWeight1, sal_uInt8 nComp2, sal_uInt32 nWeight2 )
      92             : {
      93           0 :     sal_uInt8 nComp1Dist = ::std::min< sal_uInt8 >( nComp1, 0xFF - nComp1 );
      94           0 :     sal_uInt8 nComp2Dist = ::std::min< sal_uInt8 >( nComp2, 0xFF - nComp2 );
      95           0 :     if( nComp1Dist != nComp2Dist )
      96             :     {
      97             :         /*  #i36945# One of the passed RGB components is nearer at the limits (0x00 or 0xFF).
      98             :             Increase its weighting to prevent fading of the colors during reduction. */
      99           0 :         const sal_uInt8& rnCompNearer = (nComp1Dist < nComp2Dist) ? nComp1 : nComp2;
     100           0 :         sal_uInt32& rnWeight = (nComp1Dist < nComp2Dist) ? nWeight1 : nWeight2;
     101           0 :         rnWeight *= ((rnCompNearer - 0x80L) * (rnCompNearer - 0x7FL) / 0x1000L + 1);
     102             :     }
     103           0 :     sal_uInt32 nWSum = nWeight1 + nWeight2;
     104           0 :     return static_cast< sal_uInt8 >( (nComp1 * nWeight1 + nComp2 * nWeight2 + nWSum / 2) / nWSum );
     105             : }
     106             : 
     107           0 : void lclSetMixedColor( Color& rDest, const Color& rSrc1, const Color& rSrc2 )
     108             : {
     109           0 :     rDest.SetRed( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetRed() ) + rSrc2.GetRed()) / 2 ) );
     110           0 :     rDest.SetGreen( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetGreen() ) + rSrc2.GetGreen()) / 2 ) );
     111           0 :     rDest.SetBlue( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetBlue() ) + rSrc2.GetBlue()) / 2 ) );
     112           0 : }
     113             : 
     114             : } // namespace
     115             : 
     116             : // additional classes for color reduction -------------------------------------
     117             : 
     118             : namespace {
     119             : 
     120             : /** Represents an entry in a color list.
     121             : 
     122             :     The color stores a weighting value, which increases the more the color is
     123             :     used in the document. Heavy-weighted colors will change less than others on
     124             :     color reduction.
     125             :  */
     126             : class XclListColor
     127             : {
     128          26 :     DECL_FIXEDMEMPOOL_NEWDEL( XclListColor )
     129             : 
     130             : private:
     131             :     Color               maColor;        /// The color value of this palette entry.
     132             :     sal_uInt32          mnColorId;      /// Unique color ID for color reduction.
     133             :     sal_uInt32          mnWeight;       /// Weighting for color reduction.
     134             :     bool                mbBaseColor;    /// true = Handle as base color, (don't remove/merge).
     135             : 
     136             : public:
     137             :     explicit            XclListColor( const Color& rColor, sal_uInt32 nColorId );
     138             : 
     139             :     /** Returns the RGB color value of the color. */
     140         115 :     inline const Color& GetColor() const { return maColor; }
     141             :     /** Returns the unique ID of the color. */
     142          53 :     inline sal_uInt32   GetColorId() const { return mnColorId; }
     143             :     /** Returns the current weighting of the color. */
     144           0 :     inline sal_uInt32   GetWeighting() const { return mnWeight; }
     145             :     /** Returns true, if this color is a base color, i.e. it will not be removed or merged. */
     146           0 :     inline bool         IsBaseColor() const { return mbBaseColor; }
     147             : 
     148             :     /** Adds the passed weighting to this color. */
     149          40 :     inline void         AddWeighting( sal_uInt32 nWeight ) { mnWeight += nWeight; }
     150             :     /** Merges this color with rColor, regarding weighting settings. */
     151             :     void                Merge( const XclListColor& rColor );
     152             : };
     153             : 
     154           5 : IMPL_FIXEDMEMPOOL_NEWDEL( XclListColor )
     155             : 
     156          13 : XclListColor::XclListColor( const Color& rColor, sal_uInt32 nColorId ) :
     157             :     maColor( rColor ),
     158             :     mnColorId( nColorId ),
     159          13 :     mnWeight( 0 )
     160             : {
     161             :     mbBaseColor =
     162          26 :         ((rColor.GetRed()   == 0x00) || (rColor.GetRed()   == 0xFF)) &&
     163          44 :         ((rColor.GetGreen() == 0x00) || (rColor.GetGreen() == 0xFF)) &&
     164          22 :         ((rColor.GetBlue()  == 0x00) || (rColor.GetBlue()  == 0xFF));
     165          13 : }
     166             : 
     167           0 : void XclListColor::Merge( const XclListColor& rColor )
     168             : {
     169           0 :     sal_uInt32 nWeight2 = rColor.GetWeighting();
     170             :     // do not change RGB value of base colors
     171           0 :     if( !mbBaseColor )
     172             :     {
     173           0 :         maColor.SetRed(   lclGetMergedColorComp( maColor.GetRed(),   mnWeight, rColor.maColor.GetRed(),   nWeight2 ) );
     174           0 :         maColor.SetGreen( lclGetMergedColorComp( maColor.GetGreen(), mnWeight, rColor.maColor.GetGreen(), nWeight2 ) );
     175           0 :         maColor.SetBlue(  lclGetMergedColorComp( maColor.GetBlue(),  mnWeight, rColor.maColor.GetBlue(),  nWeight2 ) );
     176             :     }
     177           0 :     AddWeighting( nWeight2 );
     178           0 : }
     179             : 
     180             : // ----------------------------------------------------------------------------
     181             : 
     182             : /** Data for each inserted original color, represented by a color ID. */
     183          13 : struct XclColorIdData
     184             : {
     185             :     Color               maColor;        /// The original inserted color.
     186             :     sal_uInt32          mnIndex;        /// Maps current color ID to color list or export color vector.
     187             :     /** Sets the contents of this struct. */
     188          13 :     inline void         Set( const Color& rColor, sal_uInt32 nIndex ) { maColor = rColor; mnIndex = nIndex; }
     189             : };
     190             : 
     191             : /** A color that will be written to the Excel file. */
     192             : struct XclPaletteColor
     193             : {
     194             :     Color               maColor;        /// Resulting color to export.
     195             :     bool                mbUsed;         /// true = Entry is used in the document.
     196             : 
     197         504 :     inline explicit     XclPaletteColor( const Color& rColor ) : maColor( rColor ), mbUsed( false ) {}
     198          13 :     inline void         SetColor( const Color& rColor ) { maColor = rColor; mbUsed = true; }
     199             : };
     200             : 
     201             : /** Maps a color list index to a palette index.
     202             :     @descr  Used to remap the color ID data vector from list indexes to palette indexes. */
     203             : struct XclRemap
     204             : {
     205             :     sal_uInt32          mnPalIndex;     /// Index to palette.
     206             :     bool                mbProcessed;    /// true = List color already processed.
     207             : 
     208          13 :     inline explicit     XclRemap() : mnPalIndex( 0 ), mbProcessed( false ) {}
     209          13 :     inline void         SetIndex( sal_uInt32 nPalIndex )
     210          13 :                             { mnPalIndex = nPalIndex; mbProcessed = true; }
     211             : };
     212             : 
     213             : /** Stores the nearest palette color index of a list color. */
     214             : struct XclNearest
     215             : {
     216             :     sal_uInt32          mnPalIndex;     /// Index to nearest palette color.
     217             :     sal_Int32           mnDist;         /// Distance to palette color.
     218             : 
     219          13 :     inline explicit     XclNearest() : mnPalIndex( 0 ), mnDist( 0 ) {}
     220             : };
     221             : 
     222             : typedef ::std::vector< XclRemap >   XclRemapVec;
     223             : typedef ::std::vector< XclNearest > XclNearestVec;
     224             : 
     225             : } // namespace
     226             : 
     227             : // ----------------------------------------------------------------------------
     228             : 
     229           9 : class XclExpPaletteImpl
     230             : {
     231             : public:
     232             :     explicit            XclExpPaletteImpl( const XclDefaultPalette& rDefPal );
     233             : 
     234             :     /** Inserts the color into the list and updates weighting.
     235             :         @param nAutoDefault  The Excel palette index for automatic color.
     236             :         @return  A unique ID for this color. */
     237             :     sal_uInt32          InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault = 0 );
     238             :     /** Returns the color ID representing a fixed Excel palette index (i.e. for auto colors). */
     239             :     static sal_uInt32   GetColorIdFromIndex( sal_uInt16 nIndex );
     240             : 
     241             :     /** Reduces the color list to the maximum count of the current BIFF version. */
     242             :     void                Finalize();
     243             : 
     244             :     /** Returns the Excel palette index of the color with passed color ID. */
     245             :     sal_uInt16          GetColorIndex( sal_uInt32 nColorId ) const;
     246             : 
     247             :     /** Returns a foreground and background color for the two passed color IDs.
     248             :         @descr  If rnXclPattern contains a solid pattern, this function tries to find
     249             :         the two best fitting colors and a mix pattern (25%, 50% or 75%) for nForeColorId.
     250             :         This will result in a better approximation to the passed foreground color. */
     251             :     void                GetMixedColors(
     252             :                             sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
     253             :                             sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const;
     254             : 
     255             :     /** Returns the RGB color data for a (non-zero-based) Excel palette entry.
     256             :         @return  The color from current or default palette or COL_AUTO, if nothing else found. */
     257             :     ColorData           GetColorData( sal_uInt16 nXclIndex ) const;
     258             :     /** Returns the color for a (non-zero-based) Excel palette entry.
     259             :         @return  The color from current or default palette or COL_AUTO, if nothing else found. */
     260             :     inline Color        GetColor( sal_uInt16 nXclIndex ) const
     261             :                             { return Color( GetColorData( nXclIndex ) ); }
     262             : 
     263             :     /** Returns true, if all colors of the palette are equal to default palette colors. */
     264             :     bool                IsDefaultPalette() const;
     265             :     /** Writes the color list (contents of the palette record) to the passed stream. */
     266             :     void                WriteBody( XclExpStream& rStrm );
     267             :     void                SaveXml( XclExpXmlStream& rStrm );
     268             : 
     269             : private:
     270             :     /** Returns the Excel index of a 0-based color index. */
     271         927 :     inline sal_uInt16   GetXclIndex( sal_uInt32 nIndex ) const
     272         927 :                             { return static_cast< sal_uInt16 >( nIndex + EXC_COLOR_USEROFFSET ); }
     273             : 
     274             :     /** Returns the original inserted color represented by the color ID nColorId. */
     275             :     const Color&        GetOriginalColor( sal_uInt32 nColorId ) const;
     276             : 
     277             :     /** Searches for rColor, returns the ordered insertion index for rColor in rnIndex. */
     278             :     XclListColor*       SearchListEntry( const Color& rColor, sal_uInt32& rnIndex );
     279             :     /** Creates and inserts a new color list entry at the specified list position. */
     280             :     XclListColor*       CreateListEntry( const Color& rColor, sal_uInt32 nIndex );
     281             : 
     282             :     /** Raw and fast reduction of the palette. */
     283             :     void                RawReducePalette( sal_uInt32 nPass );
     284             :     /** Reduction of one color using advanced color merging based on color weighting. */
     285             :     void                ReduceLeastUsedColor();
     286             : 
     287             :     /** Finds the least used color and returns its current list index. */
     288             :     sal_uInt32          GetLeastUsedListColor() const;
     289             :     /** Returns the list index of the color nearest to rColor.
     290             :         @param nIgnore  List index of a color which will be ignored.
     291             :         @return  The list index of the found color. */
     292             :     sal_uInt32          GetNearestListColor( const Color& rColor, sal_uInt32 nIgnore ) const;
     293             :     /** Returns the list index of the color nearest to the color with list index nIndex. */
     294             :     sal_uInt32          GetNearestListColor( sal_uInt32 nIndex ) const;
     295             : 
     296             :     /** Returns in rnIndex the palette index of the color nearest to rColor.
     297             :         @param bDefaultOnly  true = Searches for default colors only (colors never replaced).
     298             :         @return  The distance from passed color to found color. */
     299             :     sal_Int32           GetNearestPaletteColor(
     300             :                             sal_uInt32& rnIndex,
     301             :                             const Color& rColor, bool bDefaultOnly ) const;
     302             :     /** Returns in rnFirst and rnSecond the palette indexes of the two colors nearest to rColor.
     303             :         @return  The minimum distance from passed color to found colors. */
     304             :     sal_Int32           GetNearPaletteColors(
     305             :                             sal_uInt32& rnFirst, sal_uInt32& rnSecond,
     306             :                             const Color& rColor ) const;
     307             : 
     308             : private:
     309             :     typedef boost::ptr_vector< XclListColor >     XclListColorList;
     310             :     typedef boost::shared_ptr< XclListColorList > XclListColorListRef;
     311             :     typedef ::std::vector< XclColorIdData >       XclColorIdDataVec;
     312             :     typedef ::std::vector< XclPaletteColor >      XclPaletteColorVec;
     313             : 
     314             :     const XclDefaultPalette& mrDefPal;      /// The default palette for the current BIFF version.
     315             :     XclListColorListRef mxColorList;        /// Working color list.
     316             :     XclColorIdDataVec   maColorIdDataVec;   /// Data of all CIDs.
     317             :     XclPaletteColorVec  maPalette;          /// Contains resulting colors to export.
     318             :     sal_uInt32          mnLastIdx;          /// Last insertion index for search opt.
     319             : };
     320             : 
     321             : // ----------------------------------------------------------------------------
     322             : 
     323             : const sal_uInt32 EXC_PAL_INDEXBASE          = 0xFFFF0000;
     324             : const sal_uInt32 EXC_PAL_MAXRAWSIZE         = 1024;
     325             : 
     326           9 : XclExpPaletteImpl::XclExpPaletteImpl( const XclDefaultPalette& rDefPal ) :
     327             :     mrDefPal( rDefPal ),
     328           9 :     mxColorList( new XclListColorList ),
     329          18 :     mnLastIdx( 0 )
     330             : {
     331             :     // initialize maPalette with default colors
     332           9 :     sal_uInt16 nCount = static_cast< sal_uInt16 >( mrDefPal.GetColorCount() );
     333           9 :     maPalette.reserve( nCount );
     334         513 :     for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
     335         504 :         maPalette.push_back( XclPaletteColor( mrDefPal.GetDefColor( GetXclIndex( nIdx ) ) ) );
     336             : 
     337           9 :     InsertColor( Color( COL_BLACK ), EXC_COLOR_CELLTEXT );
     338           9 : }
     339             : 
     340          58 : sal_uInt32 XclExpPaletteImpl::InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault )
     341             : {
     342          58 :     if( rColor.GetColor() == COL_AUTO )
     343          18 :         return GetColorIdFromIndex( nAutoDefault );
     344             : 
     345          40 :     sal_uInt32 nFoundIdx = 0;
     346          40 :     XclListColor* pEntry = SearchListEntry( rColor, nFoundIdx );
     347          40 :     if( !pEntry || (pEntry->GetColor() != rColor) )
     348          13 :         pEntry = CreateListEntry( rColor, nFoundIdx );
     349          40 :     pEntry->AddWeighting( lclGetWeighting( eType ) );
     350             : 
     351          40 :     return pEntry->GetColorId();
     352             : }
     353             : 
     354         926 : sal_uInt32 XclExpPaletteImpl::GetColorIdFromIndex( sal_uInt16 nIndex )
     355             : {
     356         926 :     return EXC_PAL_INDEXBASE | nIndex;
     357             : }
     358             : 
     359           9 : void XclExpPaletteImpl::Finalize()
     360             : {
     361             : // --- build initial color ID data vector (maColorIdDataVec) ---
     362             : 
     363           9 :     sal_uInt32 nCount = mxColorList->size();
     364           9 :     maColorIdDataVec.resize( nCount );
     365          22 :     for( sal_uInt32 nIdx = 0; nIdx < nCount; ++nIdx )
     366             :     {
     367          13 :         const XclListColor& listColor = mxColorList->at( nIdx );
     368          13 :         maColorIdDataVec[ listColor.GetColorId() ].Set( listColor.GetColor(), nIdx );
     369             :     }
     370             : 
     371             : // --- loop as long as current color count does not fit into palette of current BIFF ---
     372             : 
     373             :     // phase 1: raw reduction (performance reasons, #i36945#)
     374           9 :     sal_uInt32 nPass = 0;
     375          18 :     while( mxColorList->size() > EXC_PAL_MAXRAWSIZE )
     376           0 :         RawReducePalette( nPass++ );
     377             : 
     378             :     // phase 2: precise reduction using advanced color merging based on color weighting
     379          18 :     while( mxColorList->size() > mrDefPal.GetColorCount() )
     380           0 :         ReduceLeastUsedColor();
     381             : 
     382             : // --- use default palette and replace colors with nearest used colors ---
     383             : 
     384           9 :     nCount = mxColorList->size();
     385           9 :     XclRemapVec aRemapVec( nCount );
     386          18 :     XclNearestVec aNearestVec( nCount );
     387             : 
     388             :     // in each run: search the best fitting color and replace a default color with it
     389          22 :     for( sal_uInt32 nRun = 0; nRun < nCount; ++nRun )
     390             :     {
     391             :         sal_uInt32 nIndex;
     392             :         // find nearest unused default color for each unprocessed list color
     393          38 :         for( nIndex = 0; nIndex < nCount; ++nIndex )
     394          25 :             aNearestVec[ nIndex ].mnDist = aRemapVec[ nIndex ].mbProcessed ? SAL_MAX_INT32 :
     395          25 :                 GetNearestPaletteColor( aNearestVec[ nIndex ].mnPalIndex, mxColorList->at( nIndex ).GetColor(), true );
     396             :         // find the list color which is nearest to a default color
     397          13 :         sal_uInt32 nFound = 0;
     398          25 :         for( nIndex = 1; nIndex < nCount; ++nIndex )
     399          12 :             if( aNearestVec[ nIndex ].mnDist < aNearestVec[ nFound ].mnDist )
     400           6 :                 nFound = nIndex;
     401             :         // replace default color with list color
     402          13 :         sal_uInt32 nNearest = aNearestVec[ nFound ].mnPalIndex;
     403             :         OSL_ENSURE( nNearest < maPalette.size(), "XclExpPaletteImpl::Finalize - algorithm error" );
     404          13 :         maPalette[ nNearest ].SetColor( mxColorList->at( nFound ).GetColor() );
     405          13 :         aRemapVec[ nFound ].SetIndex( nNearest );
     406             :     }
     407             : 
     408             :     // remap color ID data map (maColorIdDataVec) from list indexes to palette indexes
     409          22 :     for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
     410          22 :         aIt->mnIndex = aRemapVec[ aIt->mnIndex ].mnPalIndex;
     411           9 : }
     412             : 
     413        1433 : sal_uInt16 XclExpPaletteImpl::GetColorIndex( sal_uInt32 nColorId ) const
     414             : {
     415        1433 :     sal_uInt16 nRet = 0;
     416        1433 :     if( nColorId >= EXC_PAL_INDEXBASE )
     417        1432 :         nRet = static_cast< sal_uInt16 >( nColorId & ~EXC_PAL_INDEXBASE );
     418           1 :     else if( nColorId < maColorIdDataVec.size() )
     419           1 :         nRet = GetXclIndex( maColorIdDataVec[ nColorId ].mnIndex );
     420        1433 :     return nRet;
     421             : }
     422             : 
     423         201 : void XclExpPaletteImpl::GetMixedColors(
     424             :         sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
     425             :         sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const
     426             : {
     427         201 :     rnXclForeIx = GetColorIndex( nForeColorId );
     428         201 :     rnXclBackIx = GetColorIndex( nBackColorId );
     429         201 :     if( (rnXclPattern != EXC_PATT_SOLID) || (nForeColorId >= maColorIdDataVec.size()) )
     430         402 :         return;
     431             : 
     432             :     // now we have solid pattern, and a defined foreground (background doesn't care for solid pattern)
     433             : 
     434             :     sal_uInt32 nIndex1, nIndex2;
     435           0 :     Color aForeColor( GetOriginalColor( nForeColorId ) );
     436           0 :     sal_Int32 nFirstDist = GetNearPaletteColors( nIndex1, nIndex2, aForeColor );
     437           0 :     if( (nIndex1 >= maPalette.size()) || (nIndex2 >= maPalette.size()) )
     438           0 :         return;
     439             : 
     440           0 :     Color aColorArr[ 5 ];
     441           0 :     aColorArr[ 0 ] = maPalette[ nIndex1 ].maColor;
     442           0 :     aColorArr[ 4 ] = maPalette[ nIndex2 ].maColor;
     443           0 :     lclSetMixedColor( aColorArr[ 2 ], aColorArr[ 0 ], aColorArr[ 4 ] );
     444           0 :     lclSetMixedColor( aColorArr[ 1 ], aColorArr[ 0 ], aColorArr[ 2 ] );
     445           0 :     lclSetMixedColor( aColorArr[ 3 ], aColorArr[ 2 ], aColorArr[ 4 ] );
     446             : 
     447           0 :     sal_Int32 nMinDist = nFirstDist;
     448           0 :     sal_uInt32 nMinIndex = 0;
     449           0 :     for( sal_uInt32 nCnt = 1; nCnt < 4; ++nCnt )
     450             :     {
     451           0 :         sal_Int32 nDist = lclGetColorDistance( aForeColor, aColorArr[ nCnt ] );
     452           0 :         if( nDist < nMinDist )
     453             :         {
     454           0 :             nMinDist = nDist;
     455           0 :             nMinIndex = nCnt;
     456             :         }
     457             :     }
     458           0 :     rnXclForeIx = GetXclIndex( nIndex1 );
     459           0 :     rnXclBackIx = GetXclIndex( nIndex2 );
     460           0 :     if( nMinDist < nFirstDist )
     461             :     {
     462           0 :         switch( nMinIndex )
     463             :         {
     464           0 :             case 1: rnXclPattern = EXC_PATT_75_PERC;    break;
     465           0 :             case 2: rnXclPattern = EXC_PATT_50_PERC;    break;
     466           0 :             case 3: rnXclPattern = EXC_PATT_25_PERC;    break;
     467             :         }
     468             :     }
     469             : }
     470             : 
     471          30 : ColorData XclExpPaletteImpl::GetColorData( sal_uInt16 nXclIndex ) const
     472             : {
     473          30 :     if( nXclIndex >= EXC_COLOR_USEROFFSET )
     474             :     {
     475           0 :         sal_uInt32 nIdx = nXclIndex - EXC_COLOR_USEROFFSET;
     476           0 :         if( nIdx < maPalette.size() )
     477           0 :             return maPalette[ nIdx ].maColor.GetColor();
     478             :     }
     479          30 :     return mrDefPal.GetDefColorData( nXclIndex );
     480             : }
     481             : 
     482           9 : bool XclExpPaletteImpl::IsDefaultPalette() const
     483             : {
     484           9 :     bool bDefault = true;
     485         431 :     for( sal_uInt32 nIdx = 0, nSize = static_cast< sal_uInt32 >( maPalette.size() ); bDefault && (nIdx < nSize); ++nIdx )
     486         422 :         bDefault = maPalette[ nIdx ].maColor == mrDefPal.GetDefColor( GetXclIndex( nIdx ) );
     487           9 :     return bDefault;
     488             : }
     489             : 
     490           0 : void XclExpPaletteImpl::WriteBody( XclExpStream& rStrm )
     491             : {
     492           0 :     rStrm << static_cast< sal_uInt16 >( maPalette.size() );
     493           0 :     for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end(); aIt != aEnd; ++aIt )
     494           0 :         rStrm << aIt->maColor;
     495           0 : }
     496             : 
     497           2 : void XclExpPaletteImpl::SaveXml( XclExpXmlStream& rStrm )
     498             : {
     499           2 :     if( !maPalette.size() )
     500           2 :         return;
     501             : 
     502           2 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
     503           2 :     rStyleSheet->startElement( XML_colors, FSEND );
     504           2 :     rStyleSheet->startElement( XML_indexedColors, FSEND );
     505         114 :     for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end(); aIt != aEnd; ++aIt )
     506             :         rStyleSheet->singleElement( XML_rgbColor,
     507         112 :                 XML_rgb,    XclXmlUtils::ToOString( aIt->maColor ).getStr(),
     508         112 :                 FSEND );
     509           2 :     rStyleSheet->endElement( XML_indexedColors );
     510           2 :     rStyleSheet->endElement( XML_colors );
     511             : }
     512             : 
     513           0 : const Color& XclExpPaletteImpl::GetOriginalColor( sal_uInt32 nColorId ) const
     514             : {
     515           0 :     if( nColorId < maColorIdDataVec.size() )
     516           0 :         return maColorIdDataVec[ nColorId ].maColor;
     517           0 :     return maPalette[ 0 ].maColor;
     518             : }
     519             : 
     520          40 : XclListColor* XclExpPaletteImpl::SearchListEntry( const Color& rColor, sal_uInt32& rnIndex )
     521             : {
     522          40 :     rnIndex = mnLastIdx;
     523          40 :     XclListColor* pEntry = NULL;
     524             : 
     525          40 :     if (mxColorList->empty())
     526           9 :         return NULL;
     527             : 
     528             :     // search optimization for equal-colored objects occurring repeatedly
     529          31 :     if (rnIndex < mxColorList->size())
     530             :     {
     531          31 :         pEntry = &(*mxColorList)[rnIndex];
     532          31 :         if( pEntry->GetColor() == rColor )
     533          27 :             return pEntry;
     534             :     }
     535             : 
     536             :     // binary search for color
     537           4 :     sal_uInt32 nBegIdx = 0;
     538           4 :     sal_uInt32 nEndIdx = mxColorList->size();
     539           4 :     bool bFound = false;
     540          12 :     while( !bFound && (nBegIdx < nEndIdx) )
     541             :     {
     542           4 :         rnIndex = (nBegIdx + nEndIdx) / 2;
     543           4 :         pEntry = &(*mxColorList)[rnIndex];
     544           4 :         bFound = pEntry->GetColor() == rColor;
     545           4 :         if( !bFound )
     546             :         {
     547           4 :             if( pEntry->GetColor().GetColor() < rColor.GetColor() )
     548           4 :                 nBegIdx = rnIndex + 1;
     549             :             else
     550           0 :                 nEndIdx = rnIndex;
     551             :         }
     552             :     }
     553             : 
     554             :     // not found - use end of range as new insertion position
     555           4 :     if( !bFound )
     556           4 :         rnIndex = nEndIdx;
     557             : 
     558           4 :     mnLastIdx = rnIndex;
     559           4 :     return pEntry;
     560             : }
     561             : 
     562          13 : XclListColor* XclExpPaletteImpl::CreateListEntry( const Color& rColor, sal_uInt32 nIndex )
     563             : {
     564          13 :     XclListColor* pEntry = new XclListColor( rColor, mxColorList->size() );
     565          13 :     XclListColorList::iterator itr = mxColorList->begin();
     566          13 :     ::std::advance(itr, nIndex);
     567          13 :     mxColorList->insert(itr, pEntry);
     568          13 :     return pEntry;
     569             : }
     570             : 
     571           0 : void XclExpPaletteImpl::RawReducePalette( sal_uInt32 nPass )
     572             : {
     573             :     /*  Fast palette reduction - in each call of this function one RGB component
     574             :         of each color is reduced to a lower number of distinct values.
     575             :         Pass 0: Blue is reduced to 128 distinct values.
     576             :         Pass 1: Red is reduced to 128 distinct values.
     577             :         Pass 2: Green is reduced to 128 distinct values.
     578             :         Pass 3: Blue is reduced to 64 distinct values.
     579             :         Pass 4: Red is reduced to 64 distinct values.
     580             :         Pass 5: Green is reduced to 64 distinct values.
     581             :         And so on...
     582             :      */
     583             : 
     584           0 :     XclListColorListRef xOldList = mxColorList;
     585           0 :     mxColorList.reset( new XclListColorList );
     586             : 
     587             :     // maps old list indexes to new list indexes, used to update maColorIdDataVec
     588           0 :     ScfUInt32Vec aListIndexMap;
     589           0 :     aListIndexMap.reserve( xOldList->size() );
     590             : 
     591             :     // preparations
     592             :     sal_uInt8 nR, nG, nB;
     593           0 :     sal_uInt8& rnComp = ((nPass % 3 == 0) ? nB : ((nPass % 3 == 1) ? nR : nG));
     594           0 :     nPass /= 3;
     595             :     OSL_ENSURE( nPass < 7, "XclExpPaletteImpl::RawReducePalette - reduction not terminated" );
     596             : 
     597             :     static const sal_uInt8 spnFactor2[] = { 0x81, 0x82, 0x84, 0x88, 0x92, 0xAA, 0xFF };
     598           0 :     sal_uInt8 nFactor1 = static_cast< sal_uInt8 >( 0x02 << nPass );
     599           0 :     sal_uInt8 nFactor2 = spnFactor2[ nPass ];
     600           0 :     sal_uInt8 nFactor3 = static_cast< sal_uInt8 >( 0x40 >> nPass );
     601             : 
     602             :     // process each color in the old color list
     603           0 :     for( sal_uInt32 nIdx = 0, nCount = xOldList->size(); nIdx < nCount; ++nIdx )
     604             :     {
     605             :         // get the old list entry
     606           0 :         const XclListColor* pOldEntry = &(xOldList->at( nIdx ));
     607           0 :         nR = pOldEntry->GetColor().GetRed();
     608           0 :         nG = pOldEntry->GetColor().GetGreen();
     609           0 :         nB = pOldEntry->GetColor().GetBlue();
     610             : 
     611             :         /*  Calculate the new RGB component (rnComp points to one of nR, nG, nB).
     612             :             Using integer arithmetic with its rounding errors, the results of
     613             :             this calculation are always exactly in the range 0x00 to 0xFF
     614             :             (simply cutting the lower bits would darken the colors slightly). */
     615           0 :         sal_uInt32 nNewComp = rnComp;
     616           0 :         nNewComp /= nFactor1;
     617           0 :         nNewComp *= nFactor2;
     618           0 :         nNewComp /= nFactor3;
     619           0 :         rnComp = static_cast< sal_uInt8 >( nNewComp );
     620           0 :         Color aNewColor( nR, nG, nB );
     621             : 
     622             :         // find or insert the new color
     623           0 :         sal_uInt32 nFoundIdx = 0;
     624           0 :         XclListColor* pNewEntry = SearchListEntry( aNewColor, nFoundIdx );
     625           0 :         if( !pNewEntry || (pNewEntry->GetColor() != aNewColor) )
     626           0 :             pNewEntry = CreateListEntry( aNewColor, nFoundIdx );
     627           0 :         pNewEntry->AddWeighting( pOldEntry->GetWeighting() );
     628           0 :         aListIndexMap.push_back( nFoundIdx );
     629             :     }
     630             : 
     631             :     // update color ID data map (maps color IDs to color list indexes), replace old by new list indexes
     632           0 :     for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
     633           0 :         aIt->mnIndex = aListIndexMap[ aIt->mnIndex ];
     634           0 : }
     635             : 
     636           0 : void XclExpPaletteImpl::ReduceLeastUsedColor()
     637             : {
     638             :     // find a list color to remove
     639           0 :     sal_uInt32 nRemove = GetLeastUsedListColor();
     640             :     // find its nearest neighbor
     641           0 :     sal_uInt32 nKeep = GetNearestListColor( nRemove );
     642             : 
     643             :     // merge both colors to one color, remove one color from list
     644           0 :     XclListColor* pKeepEntry = &mxColorList->at(nKeep);
     645           0 :     XclListColor* pRemoveEntry = &mxColorList->at(nRemove);
     646           0 :     if( pKeepEntry && pRemoveEntry )
     647             :     {
     648             :         // merge both colors (if pKeepEntry is a base color, it will not change)
     649           0 :         pKeepEntry->Merge( *pRemoveEntry );
     650             :         // remove the less used color, adjust nKeep index if kept color follows removed color
     651           0 :         XclListColorList::iterator itr = mxColorList->begin();
     652           0 :         ::std::advance(itr, nRemove);
     653           0 :         mxColorList->erase(itr);
     654           0 :         if( nKeep > nRemove ) --nKeep;
     655             : 
     656             :         // recalculate color ID data map (maps color IDs to color list indexes)
     657           0 :         for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
     658             :         {
     659           0 :             if( aIt->mnIndex > nRemove )
     660           0 :                 --aIt->mnIndex;
     661           0 :             else if( aIt->mnIndex == nRemove )
     662           0 :                 aIt->mnIndex = nKeep;
     663             :         }
     664             :     }
     665           0 : }
     666             : 
     667           0 : sal_uInt32 XclExpPaletteImpl::GetLeastUsedListColor() const
     668             : {
     669           0 :     sal_uInt32 nFound = 0;
     670           0 :     sal_uInt32 nMinW = SAL_MAX_UINT32;
     671             : 
     672           0 :     for( sal_uInt32 nIdx = 0, nCount = mxColorList->size(); nIdx < nCount; ++nIdx )
     673             :     {
     674           0 :         XclListColor& pEntry = mxColorList->at( nIdx );
     675             :         // ignore the base colors
     676           0 :         if( !pEntry.IsBaseColor() && (pEntry.GetWeighting() < nMinW) )
     677             :         {
     678           0 :             nFound = nIdx;
     679           0 :             nMinW = pEntry.GetWeighting();
     680             :         }
     681             :     }
     682           0 :     return nFound;
     683             : }
     684             : 
     685           0 : sal_uInt32 XclExpPaletteImpl::GetNearestListColor( const Color& rColor, sal_uInt32 nIgnore ) const
     686             : {
     687           0 :     sal_uInt32 nFound = 0;
     688           0 :     sal_Int32 nMinD = SAL_MAX_INT32;
     689             : 
     690           0 :     for( sal_uInt32 nIdx = 0, nCount = mxColorList->size(); nIdx < nCount; ++nIdx )
     691             :     {
     692           0 :         if( nIdx != nIgnore )
     693             :         {
     694           0 :             if( XclListColor* pEntry = &mxColorList->at(nIdx) )
     695             :             {
     696           0 :                 sal_Int32 nDist = lclGetColorDistance( rColor, pEntry->GetColor() );
     697           0 :                 if( nDist < nMinD )
     698             :                 {
     699           0 :                     nFound = nIdx;
     700           0 :                     nMinD = nDist;
     701             :                 }
     702             :             }
     703             :         }
     704             :     }
     705           0 :     return nFound;
     706             : }
     707             : 
     708           0 : sal_uInt32 XclExpPaletteImpl::GetNearestListColor( sal_uInt32 nIndex ) const
     709             : {
     710           0 :     if (nIndex >= mxColorList->size())
     711           0 :         return 0;
     712           0 :     XclListColor* pEntry = &mxColorList->at(nIndex);
     713           0 :     return GetNearestListColor( pEntry->GetColor(), nIndex );
     714             : }
     715             : 
     716          19 : sal_Int32 XclExpPaletteImpl::GetNearestPaletteColor(
     717             :         sal_uInt32& rnIndex, const Color& rColor, bool bDefaultOnly ) const
     718             : {
     719          19 :     rnIndex = 0;
     720          19 :     sal_Int32 nDist = SAL_MAX_INT32;
     721             : 
     722        1083 :     for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end();
     723             :             aIt != aEnd; ++aIt )
     724             :     {
     725        1064 :         if( !bDefaultOnly || !aIt->mbUsed )
     726             :         {
     727        1056 :             sal_Int32 nCurrDist = lclGetColorDistance( rColor, aIt->maColor );
     728        1056 :             if( nCurrDist < nDist )
     729             :             {
     730          69 :                 rnIndex = aIt - maPalette.begin();
     731          69 :                 nDist = nCurrDist;
     732             :             }
     733             :         }
     734             :     }
     735          19 :     return nDist;
     736             : }
     737             : 
     738           0 : sal_Int32 XclExpPaletteImpl::GetNearPaletteColors(
     739             :         sal_uInt32& rnFirst, sal_uInt32& rnSecond, const Color& rColor ) const
     740             : {
     741           0 :     rnFirst = rnSecond = 0;
     742           0 :     sal_Int32 nDist1 = SAL_MAX_INT32;
     743           0 :     sal_Int32 nDist2 = SAL_MAX_INT32;
     744             : 
     745           0 :     for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end();
     746             :             aIt != aEnd; ++aIt )
     747             :     {
     748           0 :         sal_Int32 nCurrDist = lclGetColorDistance( rColor, aIt->maColor );
     749           0 :         if( nCurrDist < nDist1 )
     750             :         {
     751           0 :             rnSecond = rnFirst;
     752           0 :             nDist2 = nDist1;
     753           0 :             rnFirst = aIt - maPalette.begin();
     754           0 :             nDist1 = nCurrDist;
     755             :         }
     756           0 :         else if( nCurrDist < nDist2 )
     757             :         {
     758           0 :             rnSecond = aIt - maPalette.begin();
     759           0 :             nDist2 = nCurrDist;
     760             :         }
     761             :     }
     762           0 :     return nDist1;
     763             : }
     764             : 
     765             : // ----------------------------------------------------------------------------
     766             : 
     767           9 : XclExpPalette::XclExpPalette( const XclExpRoot& rRoot ) :
     768             :     XclDefaultPalette( rRoot ),
     769           9 :     XclExpRecord( EXC_ID_PALETTE )
     770             : {
     771           9 :     mxImpl.reset( new XclExpPaletteImpl( *this ) );
     772           9 :     SetRecSize( GetColorCount() * 4 + 2 );
     773           9 : }
     774             : 
     775          18 : XclExpPalette::~XclExpPalette()
     776             : {
     777          18 : }
     778             : 
     779          49 : sal_uInt32 XclExpPalette::InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault )
     780             : {
     781          49 :     return mxImpl->InsertColor( rColor, eType, nAutoDefault );
     782             : }
     783             : 
     784         908 : sal_uInt32 XclExpPalette::GetColorIdFromIndex( sal_uInt16 nIndex )
     785             : {
     786         908 :     return XclExpPaletteImpl::GetColorIdFromIndex( nIndex );
     787             : }
     788             : 
     789           9 : void XclExpPalette::Finalize()
     790             : {
     791           9 :     mxImpl->Finalize();
     792           9 : }
     793             : 
     794        1031 : sal_uInt16 XclExpPalette::GetColorIndex( sal_uInt32 nColorId ) const
     795             : {
     796        1031 :     return mxImpl->GetColorIndex( nColorId );
     797             : }
     798             : 
     799         201 : void XclExpPalette::GetMixedColors(
     800             :         sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
     801             :         sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const
     802             : {
     803         201 :     return mxImpl->GetMixedColors( rnXclForeIx, rnXclBackIx, rnXclPattern, nForeColorId, nBackColorId );
     804             : }
     805             : 
     806          30 : ColorData XclExpPalette::GetColorData( sal_uInt16 nXclIndex ) const
     807             : {
     808          30 :     return mxImpl->GetColorData( nXclIndex );
     809             : }
     810             : 
     811           3 : void XclExpPalette::Save( XclExpStream& rStrm )
     812             : {
     813           3 :     if( !mxImpl->IsDefaultPalette() )
     814           0 :         XclExpRecord::Save( rStrm );
     815           3 : }
     816             : 
     817           6 : void XclExpPalette::SaveXml( XclExpXmlStream& rStrm )
     818             : {
     819           6 :     if( !mxImpl->IsDefaultPalette() )
     820           2 :         mxImpl->SaveXml( rStrm );
     821           6 : }
     822             : 
     823           0 : void XclExpPalette::WriteBody( XclExpStream& rStrm )
     824             : {
     825           0 :     mxImpl->WriteBody( rStrm );
     826           0 : }
     827             : 
     828             : // FONT record - font information =============================================
     829             : 
     830             : namespace {
     831             : 
     832             : typedef ::std::pair< sal_uInt16, sal_Int16 > WhichAndScript;
     833             : 
     834          16 : sal_Int16 lclCheckFontItems( const SfxItemSet& rItemSet,
     835             :         const WhichAndScript& rWAS1, const WhichAndScript& rWAS2, const WhichAndScript& rWAS3 )
     836             : {
     837          16 :     if( ScfTools::CheckItem( rItemSet, rWAS1.first, false ) ) return rWAS1.second;
     838           8 :     if( ScfTools::CheckItem( rItemSet, rWAS2.first, false ) ) return rWAS2.second;
     839           8 :     if( ScfTools::CheckItem( rItemSet, rWAS3.first, false ) ) return rWAS3.second;
     840           8 :     return 0;
     841             : };
     842             : 
     843             : } // namespace
     844             : 
     845           8 : sal_Int16 XclExpFontHelper::GetFirstUsedScript( const XclExpRoot& rRoot, const SfxItemSet& rItemSet )
     846             : {
     847             :     namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
     848             : 
     849             :     /*  #i17050# #i107170# We need to determine which font items are set in the
     850             :         item set, and which script type we should prefer according to the
     851             :         current language settings. */
     852             : 
     853             :     static const WhichAndScript WAS_LATIN( ATTR_FONT, ::com::sun::star::i18n::ScriptType::LATIN );
     854             :     static const WhichAndScript WAS_ASIAN( ATTR_CJK_FONT, ::com::sun::star::i18n::ScriptType::ASIAN );
     855             :     static const WhichAndScript WAS_CMPLX( ATTR_CTL_FONT, ::com::sun::star::i18n::ScriptType::COMPLEX );
     856             : 
     857             :     /*  do not let a font from a parent style override an explicit
     858             :         cell font. */
     859             : 
     860           8 :     sal_Int16 nDefScript = rRoot.GetDefApiScript();
     861           8 :     sal_Int16 nScript = 0;
     862           8 :     const SfxItemSet* pCurrSet = &rItemSet;
     863             : 
     864          32 :     while( (nScript == 0) && pCurrSet )
     865             :     {
     866          16 :         switch( nDefScript )
     867             :         {
     868             :             case ApiScriptType::LATIN:
     869          16 :                 nScript = lclCheckFontItems( *pCurrSet, WAS_LATIN, WAS_CMPLX, WAS_ASIAN );
     870          16 :             break;
     871             :             case ApiScriptType::ASIAN:
     872           0 :                 nScript = lclCheckFontItems( *pCurrSet, WAS_ASIAN, WAS_CMPLX, WAS_LATIN );
     873           0 :             break;
     874             :             case ApiScriptType::COMPLEX:
     875           0 :                 nScript = lclCheckFontItems( *pCurrSet, WAS_CMPLX, WAS_ASIAN, WAS_LATIN );
     876           0 :             break;
     877             :             default:
     878             :                 OSL_FAIL( "XclExpFontHelper::GetFirstUsedScript - unknown script type" );
     879           0 :                 nScript = ApiScriptType::LATIN;
     880             :         };
     881          16 :         pCurrSet = pCurrSet->GetParent();
     882             :     }
     883             : 
     884           8 :     return nScript;
     885             : }
     886             : 
     887          50 : Font XclExpFontHelper::GetFontFromItemSet( const XclExpRoot& rRoot, const SfxItemSet& rItemSet, sal_Int16 nScript )
     888             : {
     889             :     namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
     890             : 
     891             :     // if WEAK is passed, guess script type from existing items in the item set
     892          50 :     if( nScript == ApiScriptType::WEAK )
     893           8 :         nScript = GetFirstUsedScript( rRoot, rItemSet );
     894             : 
     895             :     // convert to core script type constants
     896          50 :     sal_uInt8 nScScript = SCRIPTTYPE_LATIN;
     897          50 :     switch( nScript )
     898             :     {
     899          50 :         case ApiScriptType::LATIN:      nScScript = SCRIPTTYPE_LATIN;   break;
     900           0 :         case ApiScriptType::ASIAN:      nScScript = SCRIPTTYPE_ASIAN;   break;
     901           0 :         case ApiScriptType::COMPLEX:    nScScript = SCRIPTTYPE_COMPLEX; break;
     902             :         default:    OSL_FAIL( "XclExpFontHelper::GetFontFromItemSet - unknown script type" );
     903             :     }
     904             : 
     905             :     // fill the font object
     906          50 :     Font aFont;
     907          50 :     ScPatternAttr::GetFont( aFont, rItemSet, SC_AUTOCOL_RAW, 0, 0, 0, nScScript );
     908          50 :     return aFont;
     909             : }
     910             : 
     911          30 : bool XclExpFontHelper::CheckItems( const XclExpRoot& rRoot, const SfxItemSet& rItemSet, sal_Int16 nScript, bool bDeep )
     912             : {
     913             :     static const sal_uInt16 pnCommonIds[] = {
     914             :         ATTR_FONT_UNDERLINE, ATTR_FONT_CROSSEDOUT, ATTR_FONT_CONTOUR,
     915             :         ATTR_FONT_SHADOWED, ATTR_FONT_COLOR, ATTR_FONT_LANGUAGE, 0 };
     916             :     static const sal_uInt16 pnLatinIds[] = {
     917             :         ATTR_FONT, ATTR_FONT_HEIGHT, ATTR_FONT_WEIGHT, ATTR_FONT_POSTURE, 0 };
     918             :     static const sal_uInt16 pnAsianIds[] = {
     919             :         ATTR_CJK_FONT, ATTR_CJK_FONT_HEIGHT, ATTR_CJK_FONT_WEIGHT, ATTR_CJK_FONT_POSTURE, 0 };
     920             :     static const sal_uInt16 pnComplexIds[] = {
     921             :         ATTR_CTL_FONT, ATTR_CTL_FONT_HEIGHT, ATTR_CTL_FONT_WEIGHT, ATTR_CTL_FONT_POSTURE, 0 };
     922             : 
     923          30 :     bool bUsed = ScfTools::CheckItems( rItemSet, pnCommonIds, bDeep );
     924          30 :     if( !bUsed )
     925             :     {
     926             :         namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
     927             :         // if WEAK is passed, guess script type from existing items in the item set
     928          27 :         if( nScript == ApiScriptType::WEAK )
     929           0 :             nScript = GetFirstUsedScript( rRoot, rItemSet );
     930             :         // check the correct items
     931          27 :         switch( nScript )
     932             :         {
     933          27 :             case ApiScriptType::LATIN:      bUsed = ScfTools::CheckItems( rItemSet, pnLatinIds, bDeep );    break;
     934           0 :             case ApiScriptType::ASIAN:      bUsed = ScfTools::CheckItems( rItemSet, pnAsianIds, bDeep );    break;
     935           0 :             case ApiScriptType::COMPLEX:    bUsed = ScfTools::CheckItems( rItemSet, pnComplexIds, bDeep );  break;
     936             :             default:    OSL_FAIL( "XclExpFontHelper::CheckItems - unknown script type" );
     937             :         }
     938             :     }
     939          30 :     return bUsed;
     940             : }
     941             : 
     942             : // ----------------------------------------------------------------------------
     943             : 
     944             : namespace {
     945             : 
     946          68 : sal_uInt32 lclCalcHash( const XclFontData& rFontData )
     947             : {
     948          68 :     sal_uInt32 nHash = rFontData.maName.Len();
     949          68 :     nHash += rFontData.maColor.GetColor() * 2;
     950          68 :     nHash += rFontData.mnWeight * 3;
     951          68 :     nHash += rFontData.mnCharSet * 5;
     952          68 :     nHash += rFontData.mnFamily * 7;
     953          68 :     nHash += rFontData.mnHeight * 11;
     954          68 :     nHash += rFontData.mnUnderline * 13;
     955          68 :     nHash += rFontData.mnEscapem * 17;
     956          68 :     if( rFontData.mbItalic ) nHash += 19;
     957          68 :     if( rFontData.mbStrikeout ) nHash += 23;
     958          68 :     if( rFontData.mbOutline ) nHash += 29;
     959          68 :     if( rFontData.mbShadow ) nHash += 31;
     960          68 :     return nHash;
     961             : }
     962             : 
     963             : } // namespace
     964             : 
     965             : // ----------------------------------------------------------------------------
     966             : 
     967          29 : XclExpFont::XclExpFont( const XclExpRoot& rRoot,
     968             :         const XclFontData& rFontData, XclExpColorType eColorType ) :
     969             :     XclExpRecord( EXC_ID2_FONT, 14 ),
     970             :     XclExpRoot( rRoot ),
     971          29 :     maData( rFontData )
     972             : {
     973             :     // insert font color into palette
     974          29 :     mnColorId = rRoot.GetPalette().InsertColor( rFontData.maColor, eColorType, EXC_COLOR_FONTAUTO );
     975             :     // hash value for faster comparison
     976          29 :     mnHash = lclCalcHash( maData );
     977             :     // record size
     978          29 :     sal_Size nStrLen = maData.maName.Len();
     979          29 :     SetRecSize( ((GetBiff() == EXC_BIFF8) ? (nStrLen * 2 + 1) : nStrLen) + 15 );
     980          29 : }
     981             : 
     982          39 : bool XclExpFont::Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const
     983             : {
     984          39 :     return (mnHash == nHash) && (maData == rFontData);
     985             : }
     986             : 
     987          32 : void XclExpFont::SaveXml( XclExpXmlStream& rStrm )
     988             : {
     989          32 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
     990          32 :     rStyleSheet->startElement( XML_font, FSEND );
     991          32 :     XclXmlUtils::WriteFontData( rStyleSheet, maData, XML_name );
     992             :     // OOXTODO: XML_scheme; //scheme/@val values: "major", "minor", "none"
     993          32 :     rStyleSheet->endElement( XML_font );
     994          32 : }
     995             : 
     996             : // private --------------------------------------------------------------------
     997             : 
     998          12 : void XclExpFont::WriteBody( XclExpStream& rStrm )
     999             : {
    1000          12 :     sal_uInt16 nAttr = EXC_FONTATTR_NONE;
    1001          12 :     ::set_flag( nAttr, EXC_FONTATTR_ITALIC, maData.mbItalic );
    1002          12 :     ::set_flag( nAttr, EXC_FONTATTR_STRIKEOUT, maData.mbStrikeout );
    1003          12 :     ::set_flag( nAttr, EXC_FONTATTR_OUTLINE, maData.mbOutline );
    1004          12 :     ::set_flag( nAttr, EXC_FONTATTR_SHADOW, maData.mbShadow );
    1005             : 
    1006             :     OSL_ENSURE( maData.maName.Len() < 256, "XclExpFont::WriteBody - font name too long" );
    1007          12 :     XclExpString aFontName;
    1008          12 :     if( GetBiff() <= EXC_BIFF5 )
    1009           0 :         aFontName.AssignByte( maData.maName, GetTextEncoding(), EXC_STR_8BITLENGTH );
    1010             :     else
    1011          12 :         aFontName.Assign( maData.maName, EXC_STR_FORCEUNICODE | EXC_STR_8BITLENGTH );
    1012             : 
    1013          12 :     rStrm   << maData.mnHeight
    1014          24 :             << nAttr
    1015          24 :             << GetPalette().GetColorIndex( mnColorId )
    1016          24 :             << maData.mnWeight
    1017          24 :             << maData.mnEscapem
    1018          24 :             << maData.mnUnderline
    1019          24 :             << maData.mnFamily
    1020          24 :             << maData.mnCharSet
    1021          12 :             << sal_uInt8( 0 )
    1022          12 :             << aFontName;
    1023          12 : }
    1024             : 
    1025             : // ----------------------------------------------------------------------------
    1026             : 
    1027           3 : XclExpBlindFont::XclExpBlindFont( const XclExpRoot& rRoot ) :
    1028           3 :     XclExpFont( rRoot, XclFontData(), EXC_COLOR_CELLTEXT )
    1029             : {
    1030           3 : }
    1031             : 
    1032           0 : bool XclExpBlindFont::Equals( const XclFontData& /*rFontData*/, sal_uInt32 /*nHash*/ ) const
    1033             : {
    1034           0 :     return false;
    1035             : }
    1036             : 
    1037           3 : void XclExpBlindFont::Save( XclExpStream& /*rStrm*/ )
    1038             : {
    1039             :     // do nothing
    1040           3 : }
    1041             : 
    1042             : // ============================================================================
    1043             : 
    1044           9 : XclExpFontBuffer::XclExpFontBuffer( const XclExpRoot& rRoot ) :
    1045             :     XclExpRoot( rRoot ),
    1046           9 :     mnXclMaxSize( 0 )
    1047             : {
    1048           9 :     switch( GetBiff() )
    1049             :     {
    1050           0 :         case EXC_BIFF4: mnXclMaxSize = EXC_FONT_MAXCOUNT4;  break;
    1051           0 :         case EXC_BIFF5: mnXclMaxSize = EXC_FONT_MAXCOUNT5;  break;
    1052           9 :         case EXC_BIFF8: mnXclMaxSize = EXC_FONT_MAXCOUNT8;  break;
    1053             :         default:        DBG_ERROR_BIFF();
    1054             :     }
    1055           9 :     InitDefaultFonts();
    1056           9 : }
    1057             : 
    1058          48 : const XclExpFont* XclExpFontBuffer::GetFont( sal_uInt16 nXclFont ) const
    1059             : {
    1060          48 :     return maFontList.GetRecord( nXclFont ).get();
    1061             : }
    1062             : 
    1063          28 : const XclFontData& XclExpFontBuffer::GetAppFontData() const
    1064             : {
    1065          28 :     return maFontList.GetRecord( EXC_FONT_APP )->GetFontData(); // exists always
    1066             : }
    1067             : 
    1068          48 : sal_uInt16 XclExpFontBuffer::Insert(
    1069             :         const XclFontData& rFontData, XclExpColorType eColorType, bool bAppFont )
    1070             : {
    1071          48 :     if( bAppFont )
    1072             :     {
    1073           9 :         XclExpFontRef xFont( new XclExpFont( GetRoot(), rFontData, eColorType ) );
    1074           9 :         maFontList.ReplaceRecord( xFont, EXC_FONT_APP );
    1075             :         // set width of '0' character for column width export
    1076           9 :         SetCharWidth( xFont->GetFontData() );
    1077           9 :         return EXC_FONT_APP;
    1078             :     }
    1079             : 
    1080          39 :     size_t nPos = Find( rFontData );
    1081          39 :     if( nPos == EXC_FONTLIST_NOTFOUND )
    1082             :     {
    1083             :         // not found in buffer - create new font
    1084           0 :         size_t nSize = maFontList.GetSize();
    1085           0 :         if( nSize < mnXclMaxSize )
    1086             :         {
    1087             :             // possible to insert
    1088           0 :             maFontList.AppendNewRecord( new XclExpFont( GetRoot(), rFontData, eColorType ) );
    1089           0 :             nPos = nSize;       // old size is last position now
    1090             :         }
    1091             :         else
    1092             :         {
    1093             :             // buffer is full - ignore new font, use default font
    1094           0 :             nPos = EXC_FONT_APP;
    1095             :         }
    1096             :     }
    1097          39 :     return static_cast< sal_uInt16 >( nPos );
    1098             : }
    1099             : 
    1100          30 : sal_uInt16 XclExpFontBuffer::Insert(
    1101             :         const Font& rFont, XclExpColorType eColorType, bool bAppFont )
    1102             : {
    1103          30 :     return Insert( XclFontData( rFont ), eColorType, bAppFont );
    1104             : }
    1105             : 
    1106          12 : sal_uInt16 XclExpFontBuffer::Insert(
    1107             :         const SvxFont& rFont, XclExpColorType eColorType, bool bAppFont )
    1108             : {
    1109          12 :     return Insert( XclFontData( rFont ), eColorType, bAppFont );
    1110             : }
    1111             : 
    1112          30 : sal_uInt16 XclExpFontBuffer::Insert( const SfxItemSet& rItemSet,
    1113             :         sal_Int16 nScript, XclExpColorType eColorType, bool bAppFont )
    1114             : {
    1115             :     // #i17050# script type now provided by caller
    1116          30 :     Font aFont = XclExpFontHelper::GetFontFromItemSet( GetRoot(), rItemSet, nScript );
    1117          30 :     return Insert( aFont, eColorType, bAppFont );
    1118             : }
    1119             : 
    1120           3 : void XclExpFontBuffer::Save( XclExpStream& rStrm )
    1121             : {
    1122           3 :     maFontList.Save( rStrm );
    1123           3 : }
    1124             : 
    1125           6 : void XclExpFontBuffer::SaveXml( XclExpXmlStream& rStrm )
    1126             : {
    1127           6 :     if( maFontList.IsEmpty() )
    1128           6 :         return;
    1129             : 
    1130           6 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    1131             :     rStyleSheet->startElement( XML_fonts,
    1132           6 :             XML_count,  OString::valueOf( (sal_Int32) maFontList.GetSize() ).getStr(),
    1133           6 :             FSEND );
    1134             : 
    1135           6 :     maFontList.SaveXml( rStrm );
    1136             : 
    1137           6 :     rStyleSheet->endElement( XML_fonts );
    1138             : }
    1139             : 
    1140             : // private --------------------------------------------------------------------
    1141             : 
    1142           9 : void XclExpFontBuffer::InitDefaultFonts()
    1143             : {
    1144           9 :     XclFontData aFontData;
    1145           9 :     aFontData.maName.AssignAscii( "Arial" );
    1146           9 :     aFontData.SetScFamily( FAMILY_DONTKNOW );
    1147           9 :     aFontData.SetFontEncoding( ScfTools::GetSystemTextEncoding() );
    1148           9 :     aFontData.SetScHeight( 200 );   // 200 twips = 10 pt
    1149           9 :     aFontData.SetScWeight( WEIGHT_NORMAL );
    1150             : 
    1151           9 :     switch( GetBiff() )
    1152             :     {
    1153             :         case EXC_BIFF5:
    1154             :         {
    1155           0 :             maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
    1156           0 :             aFontData.SetScWeight( WEIGHT_BOLD );
    1157           0 :             maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
    1158           0 :             aFontData.SetScWeight( WEIGHT_NORMAL );
    1159           0 :             aFontData.SetScPosture( ITALIC_NORMAL );
    1160           0 :             maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
    1161           0 :             aFontData.SetScWeight( WEIGHT_BOLD );
    1162           0 :             maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
    1163             :             // the blind font with index 4
    1164           0 :             maFontList.AppendNewRecord( new XclExpBlindFont( GetRoot() ) );
    1165             :             // already add the first user defined font (Excel does it too)
    1166           0 :             aFontData.SetScWeight( WEIGHT_NORMAL );
    1167           0 :             aFontData.SetScPosture( ITALIC_NONE );
    1168           0 :             maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
    1169             :         }
    1170           0 :         break;
    1171             :         case EXC_BIFF8:
    1172             :         {
    1173           9 :             XclExpFontRef xFont( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
    1174           9 :             maFontList.AppendRecord( xFont );
    1175           9 :             maFontList.AppendRecord( xFont );
    1176           9 :             maFontList.AppendRecord( xFont );
    1177           9 :             maFontList.AppendRecord( xFont );
    1178           9 :             if( GetOutput() == EXC_OUTPUT_BINARY )
    1179             :                 // the blind font with index 4
    1180           3 :                 maFontList.AppendNewRecord( new XclExpBlindFont( GetRoot() ) );
    1181             :         }
    1182           9 :         break;
    1183             :         default:
    1184             :             DBG_ERROR_BIFF();
    1185           9 :     }
    1186           9 : }
    1187             : 
    1188          39 : size_t XclExpFontBuffer::Find( const XclFontData& rFontData )
    1189             : {
    1190          39 :     sal_uInt32 nHash = lclCalcHash( rFontData );
    1191          39 :     for( size_t nPos = 0, nSize = maFontList.GetSize(); nPos < nSize; ++nPos )
    1192          39 :         if( maFontList.GetRecord( nPos )->Equals( rFontData, nHash ) )
    1193          39 :             return nPos;
    1194           0 :     return EXC_FONTLIST_NOTFOUND;
    1195             : }
    1196             : 
    1197             : // FORMAT record - number formats =============================================
    1198             : 
    1199             : /** Predicate for search algorithm. */
    1200             : struct XclExpNumFmtPred
    1201             : {
    1202             :     sal_uLong               mnScNumFmt;
    1203          38 :     inline explicit     XclExpNumFmtPred( sal_uLong nScNumFmt ) : mnScNumFmt( nScNumFmt ) {}
    1204          38 :     inline bool         operator()( const XclExpNumFmt& rFormat ) const
    1205          38 :                             { return rFormat.mnScNumFmt == mnScNumFmt; }
    1206             : };
    1207             : 
    1208             : // ----------------------------------------------------------------------------
    1209             : 
    1210          15 : void XclExpNumFmt::SaveXml( XclExpXmlStream& rStrm )
    1211             : {
    1212          15 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    1213             :     rStyleSheet->singleElement( XML_numFmt,
    1214             :             XML_numFmtId,   OString::number( mnXclNumFmt ).getStr(),
    1215             :             XML_formatCode, OUStringToOString(maNumFmtString, RTL_TEXTENCODING_UTF8).getStr(),
    1216          15 :             FSEND );
    1217          15 : }
    1218             : 
    1219             : // ----------------------------------------------------------------------------
    1220             : 
    1221           9 : XclExpNumFmtBuffer::XclExpNumFmtBuffer( const XclExpRoot& rRoot ) :
    1222             :     XclExpRoot( rRoot ),
    1223             :     /*  Compiler needs a hint, this doesn't work: new NfKeywordTable;
    1224             :         cannot convert from 'class String *' to 'class String (*)[54]'
    1225             :         The effective result here is class String (*)[54*1] */
    1226           9 :     mxFormatter( new SvNumberFormatter( comphelper::getProcessComponentContext(), LANGUAGE_ENGLISH_US ) ),
    1227           9 :     mpKeywordTable( new NfKeywordTable ),
    1228          27 :     mnStdFmt( GetFormatter().GetStandardFormat( ScGlobal::eLnge ) )
    1229             : {
    1230           9 :     switch( GetBiff() )
    1231             :     {
    1232           0 :         case EXC_BIFF5: mnXclOffset = EXC_FORMAT_OFFSET5;   break;
    1233           9 :         case EXC_BIFF8: mnXclOffset = EXC_FORMAT_OFFSET8;   break;
    1234             :         default:        DBG_ERROR_BIFF();
    1235             :     }
    1236             : 
    1237           9 :     mxFormatter->FillKeywordTable( *mpKeywordTable, LANGUAGE_ENGLISH_US );
    1238             :     // remap codes unknown to Excel
    1239           9 :     (*mpKeywordTable)[ NF_KEY_NN ] = "DDD";
    1240           9 :     (*mpKeywordTable)[ NF_KEY_NNN ] = "DDDD";
    1241             :     // NNNN gets a separator appended in SvNumberformat::GetMappedFormatString()
    1242           9 :     (*mpKeywordTable)[ NF_KEY_NNNN ] = "DDDD";
    1243             :     // Export the Thai T NatNum modifier.
    1244           9 :     (*mpKeywordTable)[ NF_KEY_THAI_T ] = "T";
    1245           9 : }
    1246             : 
    1247          18 : XclExpNumFmtBuffer::~XclExpNumFmtBuffer()
    1248             : {
    1249          18 : }
    1250             : 
    1251          38 : sal_uInt16 XclExpNumFmtBuffer::Insert( sal_uLong nScNumFmt )
    1252             : {
    1253             :     XclExpNumFmtVec::const_iterator aIt =
    1254          38 :         ::std::find_if( maFormatMap.begin(), maFormatMap.end(), XclExpNumFmtPred( nScNumFmt ) );
    1255          38 :     if( aIt != maFormatMap.end() )
    1256          28 :         return aIt->mnXclNumFmt;
    1257             : 
    1258          10 :     size_t nSize = maFormatMap.size();
    1259          10 :     if( nSize < static_cast< size_t >( 0xFFFF - mnXclOffset ) )
    1260             :     {
    1261          10 :         sal_uInt16 nXclNumFmt = static_cast< sal_uInt16 >( nSize + mnXclOffset );
    1262          10 :         maFormatMap.push_back( XclExpNumFmt( nScNumFmt, nXclNumFmt, GetFormatCode( nScNumFmt ) ) );
    1263          10 :         return nXclNumFmt;
    1264             :     }
    1265             : 
    1266           0 :     return 0;
    1267             : }
    1268             : 
    1269           3 : void XclExpNumFmtBuffer::Save( XclExpStream& rStrm )
    1270             : {
    1271           6 :     for( XclExpNumFmtVec::const_iterator aIt = maFormatMap.begin(), aEnd = maFormatMap.end(); aIt != aEnd; ++aIt )
    1272           3 :         WriteFormatRecord( rStrm, *aIt );
    1273           3 : }
    1274             : 
    1275           6 : void XclExpNumFmtBuffer::SaveXml( XclExpXmlStream& rStrm )
    1276             : {
    1277           6 :     if( !maFormatMap.size() )
    1278           6 :         return;
    1279             : 
    1280           6 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    1281             :     rStyleSheet->startElement( XML_numFmts,
    1282           6 :             XML_count,  OString::valueOf( (sal_Int32) maFormatMap.size() ).getStr(),
    1283           6 :             FSEND );
    1284          13 :     for( XclExpNumFmtVec::iterator aIt = maFormatMap.begin(), aEnd = maFormatMap.end(); aIt != aEnd; ++aIt )
    1285             :     {
    1286           7 :         aIt->SaveXml( rStrm );
    1287             :     }
    1288           6 :     rStyleSheet->endElement( XML_numFmts );
    1289             : }
    1290             : 
    1291           3 : void XclExpNumFmtBuffer::WriteFormatRecord( XclExpStream& rStrm, sal_uInt16 nXclNumFmt, const String& rFormatStr )
    1292             : {
    1293           3 :     XclExpString aExpStr;
    1294           3 :     if( GetBiff() <= EXC_BIFF5 )
    1295           0 :         aExpStr.AssignByte( rFormatStr, GetTextEncoding(), EXC_STR_8BITLENGTH );
    1296             :     else
    1297           3 :         aExpStr.Assign( rFormatStr );
    1298             : 
    1299           3 :     rStrm.StartRecord( EXC_ID4_FORMAT, 2 + aExpStr.GetSize() );
    1300           3 :     rStrm << nXclNumFmt << aExpStr;
    1301           3 :     rStrm.EndRecord();
    1302           3 : }
    1303             : 
    1304           3 : void XclExpNumFmtBuffer::WriteFormatRecord( XclExpStream& rStrm, const XclExpNumFmt& rFormat )
    1305             : {
    1306           3 :     WriteFormatRecord( rStrm, rFormat.mnXclNumFmt, GetFormatCode( rFormat.mnScNumFmt ) );
    1307           3 : }
    1308             : 
    1309             : namespace {
    1310             : 
    1311          21 : String GetNumberFormatCode(XclRoot& rRoot, const sal_uInt16 nScNumFmt, SvNumberFormatter* xFormatter, NfKeywordTable* pKeywordTable)
    1312             : {
    1313          21 :     String aFormatStr;
    1314             : 
    1315          21 :     if( const SvNumberformat* pEntry = rRoot.GetFormatter().GetEntry( nScNumFmt ) )
    1316             :     {
    1317          21 :         if( pEntry->GetType() == NUMBERFORMAT_LOGICAL )
    1318             :         {
    1319             :             // build Boolean number format
    1320           0 :             Color* pColor = 0;
    1321           0 :             OUString aTemp;
    1322           0 :             const_cast< SvNumberformat* >( pEntry )->GetOutputString( 1.0, aTemp, &pColor );
    1323           0 :             aFormatStr.Append( '"' ).Append( aTemp ).AppendAscii( "\";\"" ).Append( aTemp ).AppendAscii( "\";\"" );
    1324           0 :             const_cast< SvNumberformat* >( pEntry )->GetOutputString( 0.0, aTemp, &pColor );
    1325           0 :             aFormatStr.Append( aTemp ).Append( '"' );
    1326             :         }
    1327             :         else
    1328             :         {
    1329          21 :             LanguageType eLang = pEntry->GetLanguage();
    1330          21 :             if( eLang != LANGUAGE_ENGLISH_US )
    1331             :             {
    1332             :                 sal_Int32 nCheckPos;
    1333          21 :                 short nType = NUMBERFORMAT_DEFINED;
    1334             :                 sal_uInt32 nKey;
    1335          21 :                 OUString aTemp( pEntry->GetFormatstring() );
    1336          21 :                 xFormatter->PutandConvertEntry( aTemp, nCheckPos, nType, nKey, eLang, LANGUAGE_ENGLISH_US );
    1337             :                 OSL_ENSURE( nCheckPos == 0, "XclExpNumFmtBuffer::WriteFormatRecord - format code not convertible" );
    1338          21 :                 pEntry = xFormatter->GetEntry( nKey );
    1339             :             }
    1340             : 
    1341          21 :             aFormatStr = pEntry->GetMappedFormatstring( *pKeywordTable, *xFormatter->GetLocaleData() );
    1342          21 :             if( aFormatStr.EqualsAscii( "Standard" ) )
    1343           0 :                 aFormatStr.AssignAscii( "General" );
    1344             :         }
    1345             :     }
    1346             :     else
    1347             :     {
    1348             :         OSL_FAIL( "XclExpNumFmtBuffer::WriteFormatRecord - format not found" );
    1349           0 :         aFormatStr.AssignAscii( "General" );
    1350             :     }
    1351             : 
    1352          21 :     return aFormatStr;
    1353             : }
    1354             : 
    1355             : }
    1356             : 
    1357          13 : String XclExpNumFmtBuffer::GetFormatCode( sal_uInt16 nScNumFmt )
    1358             : {
    1359          13 :     return GetNumberFormatCode( *this, nScNumFmt, mxFormatter.get(), mpKeywordTable.get() );
    1360             : }
    1361             : 
    1362             : // XF, STYLE record - Cell formatting =========================================
    1363             : 
    1364          38 : bool XclExpCellProt::FillFromItemSet( const SfxItemSet& rItemSet, bool bStyle )
    1365             : {
    1366          38 :     const ScProtectionAttr& rProtItem = GETITEM( rItemSet, ScProtectionAttr, ATTR_PROTECTION );
    1367          38 :     mbLocked = rProtItem.GetProtection();
    1368          38 :     mbHidden = rProtItem.GetHideFormula() || rProtItem.GetHideCell();
    1369          38 :     return ScfTools::CheckItem( rItemSet, ATTR_PROTECTION, bStyle );
    1370             : }
    1371             : 
    1372          63 : void XclExpCellProt::FillToXF3( sal_uInt16& rnProt ) const
    1373             : {
    1374          63 :     ::set_flag( rnProt, EXC_XF_LOCKED, mbLocked );
    1375          63 :     ::set_flag( rnProt, EXC_XF_HIDDEN, mbHidden );
    1376          63 : }
    1377             : 
    1378          12 : void XclExpCellProt::SaveXml( XclExpXmlStream& rStrm ) const
    1379             : {
    1380          12 :     rStrm.GetCurrentStream()->singleElement( XML_protection,
    1381             :             XML_locked,     XclXmlUtils::ToPsz( mbLocked ),
    1382             :             XML_hidden,     XclXmlUtils::ToPsz( mbHidden ),
    1383          24 :             FSEND );
    1384          12 : }
    1385             : 
    1386             : // ----------------------------------------------------------------------------
    1387             : 
    1388          38 : bool XclExpCellAlign::FillFromItemSet(
    1389             :         const SfxItemSet& rItemSet, bool bForceLineBreak, XclBiff eBiff, bool bStyle )
    1390             : {
    1391          38 :     bool bUsed = false;
    1392          38 :     SvxCellHorJustify eHorAlign = GETITEMVALUE( rItemSet, SvxHorJustifyItem, ATTR_HOR_JUSTIFY, SvxCellHorJustify );
    1393          38 :     SvxCellVerJustify eVerAlign = GETITEMVALUE( rItemSet, SvxVerJustifyItem, ATTR_VER_JUSTIFY, SvxCellVerJustify );
    1394             : 
    1395          38 :     switch( eBiff )
    1396             :     {
    1397             :         // ALL 'case's - run through!
    1398             : 
    1399             :         case EXC_BIFF8: // attributes new in BIFF8
    1400             :         {
    1401             :             // text indent
    1402          38 :             long nTmpIndent = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_INDENT, sal_Int32 );
    1403          38 :             (nTmpIndent += 100) /= 200; // 1 Excel unit == 10 pt == 200 twips
    1404          38 :             mnIndent = limit_cast< sal_uInt8 >( nTmpIndent, 0, 15 );
    1405          38 :             bUsed |= ScfTools::CheckItem( rItemSet, ATTR_INDENT, bStyle );
    1406             : 
    1407             :             // shrink to fit
    1408          38 :             mbShrink = GETITEMVALUE( rItemSet, SfxBoolItem, ATTR_SHRINKTOFIT, sal_Bool );
    1409          38 :             bUsed |= ScfTools::CheckItem( rItemSet, ATTR_SHRINKTOFIT, bStyle );
    1410             : 
    1411             :             // CTL text direction
    1412          38 :             SetScFrameDir( GETITEMVALUE( rItemSet, SvxFrameDirectionItem, ATTR_WRITINGDIR, SvxFrameDirection ) );
    1413          38 :             bUsed |= ScfTools::CheckItem( rItemSet, ATTR_WRITINGDIR, bStyle );
    1414             :         }
    1415             : 
    1416             :         case EXC_BIFF5: // attributes new in BIFF5
    1417             :         case EXC_BIFF4: // attributes new in BIFF4
    1418             :         {
    1419             :             // vertical alignment
    1420          38 :             SetScVerAlign( eVerAlign );
    1421          38 :             bUsed |= ScfTools::CheckItem( rItemSet, ATTR_VER_JUSTIFY, bStyle );
    1422             : 
    1423             :             // stacked/rotation
    1424          38 :             bool bStacked = GETITEMVALUE( rItemSet, SfxBoolItem, ATTR_STACKED, sal_Bool );
    1425          38 :             bUsed |= ScfTools::CheckItem( rItemSet, ATTR_STACKED, bStyle );
    1426          38 :             if( bStacked )
    1427             :             {
    1428           0 :                 mnRotation = EXC_ROT_STACKED;
    1429             :             }
    1430             :             else
    1431             :             {
    1432             :                 // rotation
    1433          38 :                 sal_Int32 nScRot = GETITEMVALUE( rItemSet, SfxInt32Item, ATTR_ROTATE_VALUE, sal_Int32 );
    1434          38 :                 mnRotation = XclTools::GetXclRotation( nScRot );
    1435          38 :                 bUsed |= ScfTools::CheckItem( rItemSet, ATTR_ROTATE_VALUE, bStyle );
    1436             :             }
    1437          38 :             mnOrient = XclTools::GetXclOrientFromRot( mnRotation );
    1438             :         }
    1439             : 
    1440             :         case EXC_BIFF3: // attributes new in BIFF3
    1441             :         {
    1442             :             // text wrap
    1443          38 :             mbLineBreak = bForceLineBreak || GETITEMBOOL( rItemSet, ATTR_LINEBREAK );
    1444          38 :             bUsed |= bForceLineBreak || ScfTools::CheckItem( rItemSet, ATTR_LINEBREAK, bStyle );
    1445             :         }
    1446             : 
    1447             :         case EXC_BIFF2: // attributes new in BIFF2
    1448             :         {
    1449             :             // horizontal alignment
    1450          38 :             SetScHorAlign( eHorAlign );
    1451          38 :             bUsed |= ScfTools::CheckItem( rItemSet, ATTR_HOR_JUSTIFY, bStyle );
    1452             :         }
    1453             : 
    1454          38 :         break;
    1455             :         default:    DBG_ERROR_BIFF();
    1456             :     }
    1457             : 
    1458          38 :     if (eBiff == EXC_BIFF8)
    1459             :     {
    1460             :         // Adjust for distributed alignments.
    1461          38 :         if (eHorAlign == SVX_HOR_JUSTIFY_BLOCK)
    1462             :         {
    1463           0 :             SvxCellJustifyMethod eHorJustMethod = GETITEMVALUE(
    1464             :                 rItemSet, SvxJustifyMethodItem, ATTR_HOR_JUSTIFY_METHOD, SvxCellJustifyMethod);
    1465           0 :             if (eHorJustMethod == SVX_JUSTIFY_METHOD_DISTRIBUTE)
    1466           0 :                 mnHorAlign = EXC_XF_HOR_DISTRIB;
    1467             :         }
    1468             : 
    1469          38 :         if (eVerAlign == SVX_VER_JUSTIFY_BLOCK)
    1470             :         {
    1471           0 :             SvxCellJustifyMethod eVerJustMethod = GETITEMVALUE(
    1472             :                 rItemSet, SvxJustifyMethodItem, ATTR_VER_JUSTIFY_METHOD, SvxCellJustifyMethod);
    1473           0 :             if (eVerJustMethod == SVX_JUSTIFY_METHOD_DISTRIBUTE)
    1474           0 :                 mnVerAlign = EXC_XF_VER_DISTRIB;
    1475             :         }
    1476             :     }
    1477             : 
    1478          38 :     return bUsed;
    1479             : }
    1480             : 
    1481           0 : void XclExpCellAlign::FillToXF5( sal_uInt16& rnAlign ) const
    1482             : {
    1483           0 :     ::insert_value( rnAlign, mnHorAlign, 0, 3 );
    1484           0 :     ::set_flag( rnAlign, EXC_XF_LINEBREAK, mbLineBreak );
    1485           0 :     ::insert_value( rnAlign, mnVerAlign, 4, 3 );
    1486           0 :     ::insert_value( rnAlign, mnOrient, 8, 2 );
    1487           0 : }
    1488             : 
    1489          63 : void XclExpCellAlign::FillToXF8( sal_uInt16& rnAlign, sal_uInt16& rnMiscAttrib ) const
    1490             : {
    1491          63 :     ::insert_value( rnAlign, mnHorAlign, 0, 3 );
    1492          63 :     ::set_flag( rnAlign, EXC_XF_LINEBREAK, mbLineBreak );
    1493          63 :     ::insert_value( rnAlign, mnVerAlign, 4, 3 );
    1494          63 :     ::insert_value( rnAlign, mnRotation, 8, 8 );
    1495          63 :     ::insert_value( rnMiscAttrib, mnIndent, 0, 4 );
    1496          63 :     ::set_flag( rnMiscAttrib, EXC_XF8_SHRINK, mbShrink );
    1497          63 :     ::insert_value( rnMiscAttrib, mnTextDir, 6, 2 );
    1498          63 : }
    1499             : 
    1500          12 : static const char* ToHorizontalAlignment( sal_uInt8 nHorAlign )
    1501             : {
    1502          12 :     switch( nHorAlign )
    1503             :     {
    1504          12 :         case EXC_XF_HOR_GENERAL:    return "general";
    1505           0 :         case EXC_XF_HOR_LEFT:       return "left";
    1506           0 :         case EXC_XF_HOR_CENTER:     return "center";
    1507           0 :         case EXC_XF_HOR_RIGHT:      return "right";
    1508           0 :         case EXC_XF_HOR_FILL:       return "fill";
    1509           0 :         case EXC_XF_HOR_JUSTIFY:    return "justify";
    1510           0 :         case EXC_XF_HOR_CENTER_AS:  return "centerContinuous";
    1511           0 :         case EXC_XF_HOR_DISTRIB:    return "distributed";
    1512             :     }
    1513           0 :     return "*unknown*";
    1514             : }
    1515             : 
    1516          12 : static const char* ToVerticalAlignment( sal_uInt8 nVerAlign )
    1517             : {
    1518          12 :     switch( nVerAlign )
    1519             :     {
    1520           0 :         case EXC_XF_VER_TOP:        return "top";
    1521           0 :         case EXC_XF_VER_CENTER:     return "center";
    1522          12 :         case EXC_XF_VER_BOTTOM:     return "bottom";
    1523           0 :         case EXC_XF_VER_JUSTIFY:    return "justify";
    1524           0 :         case EXC_XF_VER_DISTRIB:    return "distributed";
    1525             :     }
    1526           0 :     return "*unknown*";
    1527             : }
    1528             : 
    1529          12 : void XclExpCellAlign::SaveXml( XclExpXmlStream& rStrm ) const
    1530             : {
    1531          12 :     rStrm.GetCurrentStream()->singleElement( XML_alignment,
    1532             :             XML_horizontal,         ToHorizontalAlignment( mnHorAlign ),
    1533             :             XML_vertical,           ToVerticalAlignment( mnVerAlign ),
    1534             :             XML_textRotation,       OString::valueOf( (sal_Int32) mnRotation ).getStr(),
    1535             :             XML_wrapText,           XclXmlUtils::ToPsz( mbLineBreak ),
    1536             :             XML_indent,             OString::valueOf( (sal_Int32) mnIndent ).getStr(),
    1537             :             // OOXTODO: XML_relativeIndent,     mnIndent?
    1538             :             // OOXTODO: XML_justifyLastLine,
    1539             :             XML_shrinkToFit,        XclXmlUtils::ToPsz( mbShrink ),
    1540             :             // OOXTODO: XML_readingOrder,
    1541          24 :             FSEND );
    1542          12 : }
    1543             : 
    1544             : // ----------------------------------------------------------------------------
    1545             : 
    1546             : namespace {
    1547             : 
    1548         228 : void lclGetBorderLine(
    1549             :         sal_uInt8& rnXclLine, sal_uInt32& rnColorId,
    1550             :         const ::editeng::SvxBorderLine* pLine, XclExpPalette& rPalette, XclBiff eBiff )
    1551             : {
    1552         228 :     rnXclLine = EXC_LINE_NONE;
    1553         228 :     if( pLine )
    1554             :     {
    1555           0 :         sal_uInt16 nOuterWidth = pLine->GetOutWidth();
    1556           0 :         sal_uInt16 nDistance = pLine->GetDistance();
    1557           0 :         if( nDistance > 0 )
    1558           0 :             rnXclLine = EXC_LINE_DOUBLE;
    1559           0 :         else if( nOuterWidth >= EXC_BORDER_THICK )
    1560           0 :             rnXclLine = EXC_LINE_THICK;
    1561           0 :         else if( nOuterWidth >= EXC_BORDER_MEDIUM )
    1562             :         {
    1563           0 :             rnXclLine = EXC_LINE_MEDIUM;
    1564           0 :             if (pLine->GetBorderLineStyle( ) == table::BorderLineStyle::DASHED)
    1565           0 :                 rnXclLine = EXC_LINE_MEDIUMDASHED;
    1566             :         }
    1567           0 :         else if( nOuterWidth >= EXC_BORDER_THIN )
    1568             :         {
    1569           0 :             rnXclLine = EXC_LINE_THIN;
    1570           0 :             switch (pLine->GetBorderLineStyle())
    1571             :             {
    1572             :                 case table::BorderLineStyle::DASHED:
    1573           0 :                     rnXclLine = EXC_LINE_DASHED;
    1574           0 :                     break;
    1575             :                 case table::BorderLineStyle::DOTTED:
    1576           0 :                     rnXclLine = EXC_LINE_DOTTED;
    1577           0 :                     break;
    1578             :                 case table::BorderLineStyle::FINE_DASHED:
    1579           0 :                     rnXclLine = EXC_LINE_HAIR;
    1580           0 :                     break;
    1581             :                 default:
    1582           0 :                     break;
    1583             :             }
    1584             :         }
    1585             :         else
    1586           0 :             rnXclLine = EXC_LINE_NONE;
    1587             :     }
    1588         228 :     if( (eBiff == EXC_BIFF2) && (rnXclLine != EXC_LINE_NONE) )
    1589           0 :         rnXclLine = EXC_LINE_THIN;
    1590             : 
    1591           0 :     rnColorId = (pLine && (rnXclLine != EXC_LINE_NONE)) ?
    1592           0 :         rPalette.InsertColor( pLine->GetColor(), EXC_COLOR_CELLBORDER ) :
    1593         228 :         XclExpPalette::GetColorIdFromIndex( 0 );
    1594         228 : }
    1595             : 
    1596             : } // namespace
    1597             : 
    1598             : // ----------------------------------------------------------------------------
    1599             : 
    1600          73 : XclExpCellBorder::XclExpCellBorder() :
    1601          73 :     mnLeftColorId(   XclExpPalette::GetColorIdFromIndex( mnLeftColor ) ),
    1602          73 :     mnRightColorId(  XclExpPalette::GetColorIdFromIndex( mnRightColor ) ),
    1603          73 :     mnTopColorId(    XclExpPalette::GetColorIdFromIndex( mnTopColor ) ),
    1604          73 :     mnBottomColorId( XclExpPalette::GetColorIdFromIndex( mnBottomColor ) ),
    1605         365 :     mnDiagColorId(   XclExpPalette::GetColorIdFromIndex( mnDiagColor ) )
    1606             : {
    1607          73 : }
    1608             : 
    1609          38 : bool XclExpCellBorder::FillFromItemSet(
    1610             :         const SfxItemSet& rItemSet, XclExpPalette& rPalette, XclBiff eBiff, bool bStyle )
    1611             : {
    1612          38 :     bool bUsed = false;
    1613             : 
    1614          38 :     switch( eBiff )
    1615             :     {
    1616             :         // ALL 'case's - run through!
    1617             : 
    1618             :         case EXC_BIFF8: // attributes new in BIFF8
    1619             :         {
    1620          38 :             const SvxLineItem& rTLBRItem = GETITEM( rItemSet, SvxLineItem, ATTR_BORDER_TLBR );
    1621             :             sal_uInt8 nTLBRLine;
    1622             :             sal_uInt32 nTLBRColorId;
    1623          38 :             lclGetBorderLine( nTLBRLine, nTLBRColorId, rTLBRItem.GetLine(), rPalette, eBiff );
    1624          38 :             mbDiagTLtoBR = (nTLBRLine != EXC_LINE_NONE);
    1625             : 
    1626          38 :             const SvxLineItem& rBLTRItem = GETITEM( rItemSet, SvxLineItem, ATTR_BORDER_BLTR );
    1627             :             sal_uInt8 nBLTRLine;
    1628             :             sal_uInt32 nBLTRColorId;
    1629          38 :             lclGetBorderLine( nBLTRLine, nBLTRColorId, rBLTRItem.GetLine(), rPalette, eBiff );
    1630          38 :             mbDiagBLtoTR = (nBLTRLine != EXC_LINE_NONE);
    1631             : 
    1632          38 :             if( ::ScHasPriority( rTLBRItem.GetLine(), rBLTRItem.GetLine() ) )
    1633             :             {
    1634           0 :                 mnDiagLine = nTLBRLine;
    1635           0 :                 mnDiagColorId = nTLBRColorId;
    1636             :             }
    1637             :             else
    1638             :             {
    1639          38 :                 mnDiagLine = nBLTRLine;
    1640          38 :                 mnDiagColorId = nBLTRColorId;
    1641             :             }
    1642             : 
    1643          76 :             bUsed |= ScfTools::CheckItem( rItemSet, ATTR_BORDER_TLBR, bStyle ) ||
    1644          76 :                      ScfTools::CheckItem( rItemSet, ATTR_BORDER_BLTR, bStyle );
    1645             :         }
    1646             : 
    1647             :         case EXC_BIFF5:
    1648             :         case EXC_BIFF4:
    1649             :         case EXC_BIFF3:
    1650             :         case EXC_BIFF2:
    1651             :         {
    1652          38 :             const SvxBoxItem& rBoxItem = GETITEM( rItemSet, SvxBoxItem, ATTR_BORDER );
    1653          38 :             lclGetBorderLine( mnLeftLine,   mnLeftColorId,   rBoxItem.GetLeft(),   rPalette, eBiff );
    1654          38 :             lclGetBorderLine( mnRightLine,  mnRightColorId,  rBoxItem.GetRight(),  rPalette, eBiff );
    1655          38 :             lclGetBorderLine( mnTopLine,    mnTopColorId,    rBoxItem.GetTop(),    rPalette, eBiff );
    1656          38 :             lclGetBorderLine( mnBottomLine, mnBottomColorId, rBoxItem.GetBottom(), rPalette, eBiff );
    1657          38 :             bUsed |= ScfTools::CheckItem( rItemSet, ATTR_BORDER, bStyle );
    1658             :         }
    1659             : 
    1660          38 :         break;
    1661             :         default:    DBG_ERROR_BIFF();
    1662             :     }
    1663             : 
    1664          38 :     return bUsed;
    1665             : }
    1666             : 
    1667         201 : void XclExpCellBorder::SetFinalColors( const XclExpPalette& rPalette )
    1668             : {
    1669         201 :     mnLeftColor   = rPalette.GetColorIndex( mnLeftColorId );
    1670         201 :     mnRightColor  = rPalette.GetColorIndex( mnRightColorId );
    1671         201 :     mnTopColor    = rPalette.GetColorIndex( mnTopColorId );
    1672         201 :     mnBottomColor = rPalette.GetColorIndex( mnBottomColorId );
    1673         201 :     mnDiagColor   = rPalette.GetColorIndex( mnDiagColorId );
    1674         201 : }
    1675             : 
    1676             : 
    1677           0 : void XclExpCellBorder::FillToXF5( sal_uInt32& rnBorder, sal_uInt32& rnArea ) const
    1678             : {
    1679           0 :     ::insert_value( rnBorder, mnTopLine,      0, 3 );
    1680           0 :     ::insert_value( rnBorder, mnLeftLine,     3, 3 );
    1681           0 :     ::insert_value( rnArea,   mnBottomLine,  22, 3 );
    1682           0 :     ::insert_value( rnBorder, mnRightLine,    6, 3 );
    1683           0 :     ::insert_value( rnBorder, mnTopColor,     9, 7 );
    1684           0 :     ::insert_value( rnBorder, mnLeftColor,   16, 7 );
    1685           0 :     ::insert_value( rnArea,   mnBottomColor, 25, 7 );
    1686           0 :     ::insert_value( rnBorder, mnRightColor,  23, 7 );
    1687           0 : }
    1688             : 
    1689          63 : void XclExpCellBorder::FillToXF8( sal_uInt32& rnBorder1, sal_uInt32& rnBorder2 ) const
    1690             : {
    1691          63 :     ::insert_value( rnBorder1, mnLeftLine,     0, 4 );
    1692          63 :     ::insert_value( rnBorder1, mnRightLine,    4, 4 );
    1693          63 :     ::insert_value( rnBorder1, mnTopLine,      8, 4 );
    1694          63 :     ::insert_value( rnBorder1, mnBottomLine,  12, 4 );
    1695          63 :     ::insert_value( rnBorder1, mnLeftColor,   16, 7 );
    1696          63 :     ::insert_value( rnBorder1, mnRightColor,  23, 7 );
    1697          63 :     ::insert_value( rnBorder2, mnTopColor,     0, 7 );
    1698          63 :     ::insert_value( rnBorder2, mnBottomColor,  7, 7 );
    1699          63 :     ::insert_value( rnBorder2, mnDiagColor,   14, 7 );
    1700          63 :     ::insert_value( rnBorder2, mnDiagLine,    21, 4 );
    1701          63 :     ::set_flag( rnBorder1, EXC_XF_DIAGONAL_TL_TO_BR, mbDiagTLtoBR );
    1702          63 :     ::set_flag( rnBorder1, EXC_XF_DIAGONAL_BL_TO_TR, mbDiagBLtoTR );
    1703          63 : }
    1704             : 
    1705           0 : void XclExpCellBorder::FillToCF8( sal_uInt16& rnLine, sal_uInt32& rnColor ) const
    1706             : {
    1707           0 :     ::insert_value( rnLine,  mnLeftLine,     0, 4 );
    1708           0 :     ::insert_value( rnLine,  mnRightLine,    4, 4 );
    1709           0 :     ::insert_value( rnLine,  mnTopLine,      8, 4 );
    1710           0 :     ::insert_value( rnLine,  mnBottomLine,  12, 4 );
    1711           0 :     ::insert_value( rnColor, mnLeftColor,    0, 7 );
    1712           0 :     ::insert_value( rnColor, mnRightColor,   7, 7 );
    1713           0 :     ::insert_value( rnColor, mnTopColor,    16, 7 );
    1714           0 :     ::insert_value( rnColor, mnBottomColor, 23, 7 );
    1715           0 : }
    1716             : 
    1717           0 : static const char* ToLineStyle( sal_uInt8 nLineStyle )
    1718             : {
    1719           0 :     switch( nLineStyle )
    1720             :     {
    1721           0 :         case EXC_LINE_NONE:     return "none";
    1722           0 :         case EXC_LINE_THIN:     return "thin";
    1723           0 :         case EXC_LINE_MEDIUM:   return "medium";
    1724           0 :         case EXC_LINE_THICK:    return "thick";
    1725           0 :         case EXC_LINE_DOUBLE:   return "double";
    1726           0 :         case EXC_LINE_HAIR:     return "hair";
    1727           0 :         case EXC_LINE_DOTTED:     return "dotted";
    1728           0 :         case EXC_LINE_DASHED:     return "dashed";
    1729           0 :         case EXC_LINE_MEDIUMDASHED:     return "mediumdashed";
    1730             :     }
    1731           0 :     return "*unknown*";
    1732             : }
    1733             : 
    1734          30 : static void lcl_WriteBorder( XclExpXmlStream& rStrm, sal_Int32 nElement, sal_uInt8 nLineStyle, const Color& rColor )
    1735             : {
    1736          30 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    1737          30 :     if( nLineStyle == EXC_LINE_NONE )
    1738          30 :         rStyleSheet->singleElement( nElement, FSEND );
    1739           0 :     else if( rColor == Color( 0, 0, 0, 0 ) )
    1740             :         rStyleSheet->singleElement( nElement,
    1741             :                 XML_style,  ToLineStyle( nLineStyle ),
    1742           0 :                 FSEND );
    1743             :     else
    1744             :     {
    1745             :         rStyleSheet->startElement( nElement,
    1746             :                 XML_style,  ToLineStyle( nLineStyle ),
    1747           0 :                 FSEND );
    1748             :         rStyleSheet->singleElement( XML_color,
    1749             :                 XML_rgb,    XclXmlUtils::ToOString( rColor ).getStr(),
    1750           0 :                 FSEND );
    1751           0 :         rStyleSheet->endElement( nElement );
    1752             :     }
    1753          30 : }
    1754             : 
    1755           6 : void XclExpCellBorder::SaveXml( XclExpXmlStream& rStrm ) const
    1756             : {
    1757           6 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    1758             : 
    1759           6 :     XclExpPalette& rPalette = rStrm.GetRoot().GetPalette();
    1760             : 
    1761             :     rStyleSheet->startElement( XML_border,
    1762             :             XML_diagonalUp,     XclXmlUtils::ToPsz( mbDiagBLtoTR ),
    1763             :             XML_diagonalDown,   XclXmlUtils::ToPsz( mbDiagTLtoBR ),
    1764             :             // OOXTODO: XML_outline,
    1765           6 :             FSEND );
    1766           6 :     lcl_WriteBorder( rStrm, XML_left,       mnLeftLine,     rPalette.GetColor( mnLeftColor ) );
    1767           6 :     lcl_WriteBorder( rStrm, XML_right,      mnRightLine,    rPalette.GetColor( mnRightColor ) );
    1768           6 :     lcl_WriteBorder( rStrm, XML_top,        mnTopLine,      rPalette.GetColor( mnTopColor ) );
    1769           6 :     lcl_WriteBorder( rStrm, XML_bottom,     mnBottomLine,   rPalette.GetColor( mnBottomColor ) );
    1770           6 :     lcl_WriteBorder( rStrm, XML_diagonal,   mnDiagLine,     rPalette.GetColor( mnDiagColor ) );
    1771             :     // OOXTODO: XML_vertical, XML_horizontal
    1772           6 :     rStyleSheet->endElement( XML_border );
    1773           6 : }
    1774             : 
    1775             : // ----------------------------------------------------------------------------
    1776             : 
    1777          83 : XclExpCellArea::XclExpCellArea() :
    1778          83 :     mnForeColorId( XclExpPalette::GetColorIdFromIndex( mnForeColor ) ),
    1779         166 :     mnBackColorId( XclExpPalette::GetColorIdFromIndex( mnBackColor ) )
    1780             : {
    1781          83 : }
    1782             : 
    1783          30 : bool XclExpCellArea::FillFromItemSet( const SfxItemSet& rItemSet, XclExpPalette& rPalette, bool bStyle )
    1784             : {
    1785          30 :     const SvxBrushItem& rBrushItem = GETITEM( rItemSet, SvxBrushItem, ATTR_BACKGROUND );
    1786          30 :     if( rBrushItem.GetColor().GetTransparency() )
    1787             :     {
    1788          30 :         mnPattern = EXC_PATT_NONE;
    1789          30 :         mnForeColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT );
    1790          30 :         mnBackColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWBACK );
    1791             :     }
    1792             :     else
    1793             :     {
    1794           0 :         mnPattern = EXC_PATT_SOLID;
    1795           0 :         mnForeColorId = rPalette.InsertColor( rBrushItem.GetColor(), EXC_COLOR_CELLAREA );
    1796           0 :         mnBackColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT );
    1797             :     }
    1798          30 :     return ScfTools::CheckItem( rItemSet, ATTR_BACKGROUND, bStyle );
    1799             : }
    1800             : 
    1801         201 : void XclExpCellArea::SetFinalColors( const XclExpPalette& rPalette )
    1802             : {
    1803         201 :     rPalette.GetMixedColors( mnForeColor, mnBackColor, mnPattern, mnForeColorId, mnBackColorId );
    1804         201 : }
    1805             : 
    1806           0 : void XclExpCellArea::FillToXF5( sal_uInt32& rnArea ) const
    1807             : {
    1808           0 :     ::insert_value( rnArea, mnPattern,   16, 6 );
    1809           0 :     ::insert_value( rnArea, mnForeColor,  0, 7 );
    1810           0 :     ::insert_value( rnArea, mnBackColor,  7, 7 );
    1811           0 : }
    1812             : 
    1813          63 : void XclExpCellArea::FillToXF8( sal_uInt32& rnBorder2, sal_uInt16& rnArea ) const
    1814             : {
    1815          63 :     ::insert_value( rnBorder2, mnPattern,   26, 6 );
    1816          63 :     ::insert_value( rnArea,    mnForeColor,  0, 7 );
    1817          63 :     ::insert_value( rnArea,    mnBackColor,  7, 7 );
    1818          63 : }
    1819             : 
    1820           0 : void XclExpCellArea::FillToCF8( sal_uInt16& rnPattern, sal_uInt16& rnColor ) const
    1821             : {
    1822           0 :     XclCellArea aTmp( *this );
    1823           0 :     if( !aTmp.IsTransparent() && (aTmp.mnBackColor == EXC_COLOR_WINDOWTEXT) )
    1824           0 :         aTmp.mnBackColor = 0;
    1825           0 :     if( aTmp.mnPattern == EXC_PATT_SOLID )
    1826           0 :         ::std::swap( aTmp.mnForeColor, aTmp.mnBackColor );
    1827           0 :     ::insert_value( rnColor,   aTmp.mnForeColor,  0, 7 );
    1828           0 :     ::insert_value( rnColor,   aTmp.mnBackColor,  7, 7 );
    1829           0 :     ::insert_value( rnPattern, aTmp.mnPattern,   10, 6 );
    1830           0 : }
    1831             : 
    1832          12 : static const char* ToPatternType( sal_uInt8 nPattern )
    1833             : {
    1834          12 :     switch( nPattern )
    1835             :     {
    1836           6 :         case EXC_PATT_NONE:         return "none";
    1837           0 :         case EXC_PATT_SOLID:        return "solid";
    1838           0 :         case EXC_PATT_50_PERC:      return "mediumGray";
    1839           0 :         case EXC_PATT_75_PERC:      return "darkGray";
    1840           0 :         case EXC_PATT_25_PERC:      return "lightGray";
    1841           6 :         case EXC_PATT_12_5_PERC:    return "gray125";
    1842           0 :         case EXC_PATT_6_25_PERC:    return "gray0625";
    1843             :     }
    1844           0 :     return "*unknown*";
    1845             : }
    1846             : 
    1847          12 : void XclExpCellArea::SaveXml( XclExpXmlStream& rStrm ) const
    1848             : {
    1849          12 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    1850             :     rStyleSheet->startElement( XML_fill,
    1851          12 :             FSEND );
    1852             : 
    1853             :     // OOXTODO: XML_gradientFill
    1854             : 
    1855          12 :     XclExpPalette& rPalette = rStrm.GetRoot().GetPalette();
    1856             : 
    1857          12 :     if( mnPattern == EXC_PATT_NONE || ( mnForeColor == 0 && mnBackColor == 0 ) )
    1858             :         rStyleSheet->singleElement( XML_patternFill,
    1859             :                 XML_patternType,    ToPatternType( mnPattern ),
    1860          12 :                 FSEND );
    1861             :     else
    1862             :     {
    1863             :         rStyleSheet->startElement( XML_patternFill,
    1864             :                 XML_patternType,    ToPatternType( mnPattern ),
    1865           0 :                 FSEND );
    1866             :         rStyleSheet->singleElement( XML_fgColor,
    1867           0 :                 XML_rgb,    XclXmlUtils::ToOString( rPalette.GetColor( mnForeColor ) ).getStr(),
    1868           0 :                 FSEND );
    1869             :         rStyleSheet->singleElement( XML_bgColor,
    1870           0 :                 XML_rgb,    XclXmlUtils::ToOString( rPalette.GetColor( mnBackColor ) ).getStr(),
    1871           0 :                 FSEND );
    1872           0 :         rStyleSheet->endElement( XML_patternFill );
    1873             :     }
    1874             : 
    1875          12 :     rStyleSheet->endElement( XML_fill );
    1876          12 : }
    1877             : 
    1878             : 
    1879           8 : bool XclExpColor::FillFromItemSet( const SfxItemSet& rItemSet )
    1880             : {
    1881           8 :     if( !ScfTools::CheckItem( rItemSet, ATTR_BACKGROUND, true ) )
    1882           8 :         return false;
    1883             : 
    1884           0 :     const SvxBrushItem& rBrushItem = GETITEM( rItemSet, SvxBrushItem, ATTR_BACKGROUND );
    1885           0 :     maColor = rBrushItem.GetColor();
    1886             : 
    1887           0 :     return true;
    1888             : }
    1889             : 
    1890           0 : void XclExpColor::SaveXml( XclExpXmlStream& rStrm ) const
    1891             : {
    1892           0 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    1893             :     rStyleSheet->startElement( XML_fill,
    1894           0 :             FSEND );
    1895             :     rStyleSheet->startElement( XML_patternFill,
    1896           0 :             FSEND );
    1897             :     rStyleSheet->singleElement( XML_bgColor,
    1898             :             XML_rgb, XclXmlUtils::ToOString(maColor).getStr(),
    1899           0 :             FSEND );
    1900             : 
    1901           0 :     rStyleSheet->endElement( XML_patternFill );
    1902           0 :     rStyleSheet->endElement( XML_fill );
    1903           0 : }
    1904             : 
    1905             : // ----------------------------------------------------------------------------
    1906             : 
    1907       10496 : XclExpXFId::XclExpXFId() :
    1908       10496 :     mnXFId( XclExpXFBuffer::GetDefCellXFId() ),
    1909       10496 :     mnXFIndex( EXC_XF_DEFAULTCELL )
    1910             : {
    1911       10496 : }
    1912             : 
    1913         759 : XclExpXFId::XclExpXFId( sal_uInt32 nXFId ) :
    1914             :     mnXFId( nXFId ),
    1915         759 :     mnXFIndex( EXC_XF_DEFAULTCELL )
    1916             : {
    1917         759 : }
    1918             : 
    1919       10933 : void XclExpXFId::ConvertXFIndex( const XclExpRoot& rRoot )
    1920             : {
    1921       10933 :     mnXFIndex = rRoot.GetXFBuffer().GetXFIndex( mnXFId );
    1922       10933 : }
    1923             : 
    1924             : // ----------------------------------------------------------------------------
    1925             : 
    1926          21 : XclExpXF::XclExpXF(
    1927             :         const XclExpRoot& rRoot, const ScPatternAttr& rPattern, sal_Int16 nScript,
    1928             :         sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) :
    1929             :     XclXFBase( true ),
    1930          21 :     XclExpRoot( rRoot )
    1931             : {
    1932          21 :     mnParentXFId = GetXFBuffer().InsertStyle( rPattern.GetStyleSheet() );
    1933          21 :     Init( rPattern.GetItemSet(), nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak, false );
    1934          21 : }
    1935             : 
    1936           9 : XclExpXF::XclExpXF( const XclExpRoot& rRoot, const SfxStyleSheetBase& rStyleSheet ) :
    1937             :     XclXFBase( false ),
    1938             :     XclExpRoot( rRoot ),
    1939           9 :     mnParentXFId( XclExpXFBuffer::GetXFIdFromIndex( EXC_XF_STYLEPARENT ) )
    1940             : {
    1941           9 :     bool bDefStyle = (rStyleSheet.GetName() == ScGlobal::GetRscString( STR_STYLENAME_STANDARD ));
    1942           9 :     sal_Int16 nScript = bDefStyle ? GetDefApiScript() : ::com::sun::star::i18n::ScriptType::WEAK;
    1943           9 :     Init( const_cast< SfxStyleSheetBase& >( rStyleSheet ).GetItemSet(), nScript,
    1944          18 :         NUMBERFORMAT_ENTRY_NOT_FOUND, EXC_FONT_NOTFOUND, false, bDefStyle );
    1945           9 : }
    1946             : 
    1947          27 : XclExpXF::XclExpXF( const XclExpRoot& rRoot, bool bCellXF ) :
    1948             :     XclXFBase( bCellXF ),
    1949             :     XclExpRoot( rRoot ),
    1950          27 :     mnParentXFId( XclExpXFBuffer::GetXFIdFromIndex( EXC_XF_STYLEPARENT ) )
    1951             : {
    1952          27 :     InitDefault();
    1953          27 : }
    1954             : 
    1955       50966 : bool XclExpXF::Equals( const ScPatternAttr& rPattern,
    1956             :         sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) const
    1957             : {
    1958       58451 :     return IsCellXF() && (mpItemSet == &rPattern.GetItemSet()) &&
    1959        2279 :         (!bForceLineBreak || maAlignment.mbLineBreak) &&
    1960       53245 :         ((nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) || (mnScNumFmt == nForceScNumFmt)) &&
    1961       50978 :         ((nForceXclFont == EXC_FONT_NOTFOUND) || (mnXclFont == nForceXclFont));
    1962             : }
    1963             : 
    1964           0 : bool XclExpXF::Equals( const SfxStyleSheetBase& rStyleSheet ) const
    1965             : {
    1966           0 :     return IsStyleXF() && (mpItemSet == &const_cast< SfxStyleSheetBase& >( rStyleSheet ).GetItemSet());
    1967             : }
    1968             : 
    1969         201 : void XclExpXF::SetFinalColors()
    1970             : {
    1971         201 :     maBorder.SetFinalColors( GetPalette() );
    1972         201 :     maArea.SetFinalColors( GetPalette() );
    1973         201 : }
    1974             : 
    1975          12 : bool XclExpXF::Equals( const XclExpXF& rCmpXF ) const
    1976             : {
    1977          24 :     return XclXFBase::Equals( rCmpXF ) &&
    1978          36 :         (maProtection == rCmpXF.maProtection) && (maAlignment  == rCmpXF.maAlignment) &&
    1979          36 :         (maBorder     == rCmpXF.maBorder)     && (maArea       == rCmpXF.maArea)      &&
    1980          48 :         (mnXclFont    == rCmpXF.mnXclFont)    && (mnXclNumFmt  == rCmpXF.mnXclNumFmt) &&
    1981          24 :         (mnParentXFId == rCmpXF.mnParentXFId);
    1982             : }
    1983             : 
    1984          57 : void XclExpXF::InitDefault()
    1985             : {
    1986          57 :     SetRecHeader( EXC_ID5_XF, (GetBiff() == EXC_BIFF8) ? 20 : 16 );
    1987          57 :     mpItemSet = 0;
    1988          57 :     mnScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND;
    1989          57 :     mnXclFont = mnXclNumFmt = 0;
    1990          57 : }
    1991             : 
    1992          30 : void XclExpXF::Init( const SfxItemSet& rItemSet, sal_Int16 nScript,
    1993             :         sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak, bool bDefStyle )
    1994             : {
    1995          30 :     InitDefault();
    1996          30 :     mpItemSet = &rItemSet;
    1997             : 
    1998             :     // cell protection
    1999          30 :     mbProtUsed = maProtection.FillFromItemSet( rItemSet, IsStyleXF() );
    2000             : 
    2001             :     // font
    2002          30 :     if( nForceXclFont == EXC_FONT_NOTFOUND )
    2003             :     {
    2004          30 :         mnXclFont = GetFontBuffer().Insert( rItemSet, nScript, EXC_COLOR_CELLTEXT, bDefStyle );
    2005          30 :         mbFontUsed = XclExpFontHelper::CheckItems( GetRoot(), rItemSet, nScript, IsStyleXF() );
    2006             :     }
    2007             :     else
    2008             :     {
    2009           0 :         mnXclFont = nForceXclFont;
    2010           0 :         mbFontUsed = true;
    2011             :     }
    2012             : 
    2013             :     // number format
    2014             :     mnScNumFmt = (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) ?
    2015          30 :         GETITEMVALUE( rItemSet, SfxUInt32Item, ATTR_VALUE_FORMAT, sal_uLong ) : nForceScNumFmt;
    2016          30 :     mnXclNumFmt = GetNumFmtBuffer().Insert( mnScNumFmt );
    2017          30 :     mbFmtUsed = ScfTools::CheckItem( rItemSet, ATTR_VALUE_FORMAT, IsStyleXF() );
    2018             :     // alignment
    2019          30 :     mbAlignUsed = maAlignment.FillFromItemSet( rItemSet, bForceLineBreak, GetBiff(), IsStyleXF() );
    2020             : 
    2021             :     // cell border
    2022          30 :     mbBorderUsed = maBorder.FillFromItemSet( rItemSet, GetPalette(), GetBiff(), IsStyleXF() );
    2023             : 
    2024             :     // background area
    2025          30 :     mbAreaUsed = maArea.FillFromItemSet( rItemSet, GetPalette(), IsStyleXF() );
    2026             : 
    2027             :     // set all b***Used flags to true in "Default"/"Normal" style
    2028          30 :     if( bDefStyle )
    2029           9 :         SetAllUsedFlags( true );
    2030          30 : }
    2031             : 
    2032          63 : sal_uInt8 XclExpXF::GetUsedFlags() const
    2033             : {
    2034          63 :     sal_uInt8 nUsedFlags = 0;
    2035             :     /*  In cell XFs a set bit means a used attribute, in style XFs a cleared bit.
    2036             :         "mbCellXF == mb***Used" evaluates to correct value in cell and style XFs. */
    2037          63 :     ::set_flag( nUsedFlags, EXC_XF_DIFF_PROT,   mbCellXF == mbProtUsed );
    2038          63 :     ::set_flag( nUsedFlags, EXC_XF_DIFF_FONT,   mbCellXF == mbFontUsed );
    2039          63 :     ::set_flag( nUsedFlags, EXC_XF_DIFF_VALFMT, mbCellXF == mbFmtUsed );
    2040          63 :     ::set_flag( nUsedFlags, EXC_XF_DIFF_ALIGN,  mbCellXF == mbAlignUsed );
    2041          63 :     ::set_flag( nUsedFlags, EXC_XF_DIFF_BORDER, mbCellXF == mbBorderUsed );
    2042          63 :     ::set_flag( nUsedFlags, EXC_XF_DIFF_AREA,   mbCellXF == mbAreaUsed );
    2043          63 :     return nUsedFlags;
    2044             : }
    2045             : 
    2046           0 : void XclExpXF::WriteBody5( XclExpStream& rStrm )
    2047             : {
    2048           0 :     sal_uInt16 nTypeProt = 0, nAlign = 0;
    2049           0 :     sal_uInt32 nArea = 0, nBorder = 0;
    2050             : 
    2051           0 :     ::set_flag( nTypeProt, EXC_XF_STYLE, IsStyleXF() );
    2052           0 :     ::insert_value( nTypeProt, mnParent, 4, 12 );
    2053           0 :     ::insert_value( nAlign, GetUsedFlags(), 10, 6 );
    2054             : 
    2055           0 :     maProtection.FillToXF3( nTypeProt );
    2056           0 :     maAlignment.FillToXF5( nAlign );
    2057           0 :     maBorder.FillToXF5( nBorder, nArea );
    2058           0 :     maArea.FillToXF5( nArea );
    2059             : 
    2060           0 :     rStrm << mnXclFont << mnXclNumFmt << nTypeProt << nAlign << nArea << nBorder;
    2061           0 : }
    2062             : 
    2063          63 : void XclExpXF::WriteBody8( XclExpStream& rStrm )
    2064             : {
    2065          63 :     sal_uInt16 nTypeProt = 0, nAlign = 0, nMiscAttrib = 0, nArea = 0;
    2066          63 :     sal_uInt32 nBorder1 = 0, nBorder2 = 0;
    2067             : 
    2068          63 :     ::set_flag( nTypeProt, EXC_XF_STYLE, IsStyleXF() );
    2069          63 :     ::insert_value( nTypeProt, mnParent, 4, 12 );
    2070          63 :     ::insert_value( nMiscAttrib, GetUsedFlags(), 10, 6 );
    2071             : 
    2072          63 :     maProtection.FillToXF3( nTypeProt );
    2073          63 :     maAlignment.FillToXF8( nAlign, nMiscAttrib );
    2074          63 :     maBorder.FillToXF8( nBorder1, nBorder2 );
    2075          63 :     maArea.FillToXF8( nBorder2, nArea );
    2076             : 
    2077          63 :     rStrm << mnXclFont << mnXclNumFmt << nTypeProt << nAlign << nMiscAttrib << nBorder1 << nBorder2 << nArea;
    2078          63 : }
    2079             : 
    2080          63 : void XclExpXF::WriteBody( XclExpStream& rStrm )
    2081             : {
    2082          63 :     XclExpXFId aParentId( mnParentXFId );
    2083          63 :     aParentId.ConvertXFIndex( GetRoot() );
    2084          63 :     mnParent = aParentId.mnXFIndex;
    2085          63 :     switch( GetBiff() )
    2086             :     {
    2087           0 :         case EXC_BIFF5: WriteBody5( rStrm );    break;
    2088          63 :         case EXC_BIFF8: WriteBody8( rStrm );    break;
    2089             :         default:        DBG_ERROR_BIFF();
    2090             :     }
    2091          63 : }
    2092             : 
    2093         126 : void XclExpXF::SetXmlIds( sal_uInt32 nBorderId, sal_uInt32 nFillId )
    2094             : {
    2095         126 :     mnBorderId = nBorderId;
    2096         126 :     mnFillId   = nFillId;
    2097         126 : }
    2098             : 
    2099         126 : void XclExpXF::SaveXml( XclExpXmlStream& rStrm )
    2100             : {
    2101         126 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    2102             : 
    2103         126 :     sal_Int32 nXfId = 0;
    2104         126 :     const XclExpXF* pStyleXF = NULL;
    2105         126 :     if( IsCellXF() )
    2106             :     {
    2107           6 :         sal_uInt16 nXFIndex = rStrm.GetRoot().GetXFBuffer().GetXFIndex( mnParentXFId );
    2108           6 :         nXfId = rStrm.GetRoot().GetXFBuffer().GetXmlStyleIndex( nXFIndex );
    2109           6 :         pStyleXF = rStrm.GetRoot().GetXFBuffer().GetXFById( mnParentXFId );
    2110             :     }
    2111             : 
    2112             :     rStyleSheet->startElement( XML_xf,
    2113             :             XML_numFmtId,           OString::valueOf( (sal_Int32) mnXclNumFmt ).getStr(),
    2114             :             XML_fontId,             OString::valueOf( (sal_Int32) mnXclFont ).getStr(),
    2115             :             XML_fillId,             OString::valueOf( (sal_Int32) mnFillId ).getStr(),
    2116             :             XML_borderId,           OString::valueOf( (sal_Int32) mnBorderId ).getStr(),
    2117         264 :             XML_xfId,               IsStyleXF() ? NULL : OString::valueOf( nXfId ).getStr(),
    2118             :             // OOXTODO: XML_quotePrefix,
    2119             :             // OOXTODO: XML_pivotButton,
    2120             :             // OOXTODO: XML_applyNumberFormat,  ;
    2121             :             XML_applyFont,          XclXmlUtils::ToPsz( mbFontUsed ),
    2122             :             // OOXTODO: XML_applyFill,
    2123             :             XML_applyBorder,        XclXmlUtils::ToPsz( mbBorderUsed ),
    2124             :             XML_applyAlignment,     XclXmlUtils::ToPsz( mbAlignUsed ),
    2125             :             XML_applyProtection,    XclXmlUtils::ToPsz( mbProtUsed ),
    2126         378 :             FSEND );
    2127         126 :     if( mbAlignUsed )
    2128           6 :         maAlignment.SaveXml( rStrm );
    2129         120 :     else if ( pStyleXF )
    2130           6 :         pStyleXF->GetAlignmentData().SaveXml( rStrm );
    2131         126 :     if( mbProtUsed )
    2132           6 :         maProtection.SaveXml( rStrm );
    2133         120 :     else if ( pStyleXF )
    2134           6 :         pStyleXF->GetProtectionData().SaveXml( rStrm );
    2135             : 
    2136             :     // OOXTODO: XML_extLst
    2137         126 :     rStyleSheet->endElement( XML_xf );
    2138         126 : }
    2139             : 
    2140             : // ----------------------------------------------------------------------------
    2141             : 
    2142          27 : XclExpDefaultXF::XclExpDefaultXF( const XclExpRoot& rRoot, bool bCellXF ) :
    2143          27 :     XclExpXF( rRoot, bCellXF )
    2144             : {
    2145          27 : }
    2146             : 
    2147          36 : void XclExpDefaultXF::SetFont( sal_uInt16 nXclFont )
    2148             : {
    2149          36 :     mnXclFont = nXclFont;
    2150          36 :     mbFontUsed = true;
    2151          36 : }
    2152             : 
    2153          45 : void XclExpDefaultXF::SetNumFmt( sal_uInt16 nXclNumFmt )
    2154             : {
    2155          45 :     mnXclNumFmt = nXclNumFmt;
    2156          45 :     mbFmtUsed = true;
    2157          45 : }
    2158             : 
    2159             : // ----------------------------------------------------------------------------
    2160             : 
    2161           0 : XclExpStyle::XclExpStyle( sal_uInt32 nXFId, const String& rStyleName ) :
    2162             :     XclExpRecord( EXC_ID_STYLE, 4 ),
    2163             :     maName( rStyleName ),
    2164             :     maXFId( nXFId ),
    2165             :     mnStyleId( EXC_STYLE_USERDEF ),
    2166           0 :     mnLevel( EXC_STYLE_NOLEVEL )
    2167             : {
    2168             :     OSL_ENSURE( maName.Len(), "XclExpStyle::XclExpStyle - empty style name" );
    2169             : #if OSL_DEBUG_LEVEL > 0
    2170             :     sal_uInt8 nStyleId, nLevel; // do not use members for debug tests
    2171             :     OSL_ENSURE( !XclTools::GetBuiltInStyleId( nStyleId, nLevel, maName ),
    2172             :         "XclExpStyle::XclExpStyle - this is a built-in style" );
    2173             : #endif
    2174           0 : }
    2175             : 
    2176          54 : XclExpStyle::XclExpStyle( sal_uInt32 nXFId, sal_uInt8 nStyleId, sal_uInt8 nLevel ) :
    2177             :     XclExpRecord( EXC_ID_STYLE, 4 ),
    2178             :     maXFId( nXFId ),
    2179             :     mnStyleId( nStyleId ),
    2180          54 :     mnLevel( nLevel )
    2181             : {
    2182          54 : }
    2183             : 
    2184          18 : void XclExpStyle::WriteBody( XclExpStream& rStrm )
    2185             : {
    2186          18 :     maXFId.ConvertXFIndex( rStrm.GetRoot() );
    2187          18 :     ::set_flag( maXFId.mnXFIndex, EXC_STYLE_BUILTIN, IsBuiltIn() );
    2188          18 :     rStrm << maXFId.mnXFIndex;
    2189             : 
    2190          18 :     if( IsBuiltIn() )
    2191             :     {
    2192          18 :         rStrm << mnStyleId << mnLevel;
    2193             :     }
    2194             :     else
    2195             :     {
    2196           0 :         XclExpString aNameEx;
    2197           0 :         if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
    2198           0 :             aNameEx.Assign( maName );
    2199             :         else
    2200           0 :             aNameEx.AssignByte( maName, rStrm.GetRoot().GetTextEncoding(), EXC_STR_8BITLENGTH );
    2201           0 :         rStrm << aNameEx;
    2202             :     }
    2203          18 : }
    2204             : 
    2205          36 : static const char* lcl_StyleNameFromId( sal_Int32 nStyleId )
    2206             : {
    2207          36 :     switch( nStyleId )
    2208             :     {
    2209           6 :         case 0:     return "Normal";
    2210           6 :         case 3:     return "Comma";
    2211           6 :         case 4:     return "Currency";
    2212           6 :         case 5:     return "Percent";
    2213           6 :         case 6:     return "Comma [0]";
    2214           6 :         case 7:     return "Currency [0]";
    2215             :     }
    2216           0 :     return "*unknown*";
    2217             : }
    2218             : 
    2219          36 : void XclExpStyle::SaveXml( XclExpXmlStream& rStrm )
    2220             : {
    2221          36 :     OString sName;
    2222          36 :     if( IsBuiltIn() )
    2223             :     {
    2224          36 :         sName = OString( lcl_StyleNameFromId( mnStyleId ) );
    2225             :     }
    2226             :     else
    2227           0 :         sName = XclXmlUtils::ToOString( maName );
    2228             :     // get the index in sortedlist associated with the mnXId
    2229          36 :     sal_Int32 nXFId = rStrm.GetRoot().GetXFBuffer().GetXFIndex( maXFId.mnXFId );
    2230             :     // get the style index associated with index into sortedlist
    2231          36 :     nXFId = rStrm.GetRoot().GetXFBuffer().GetXmlStyleIndex( nXFId );
    2232          36 :     rStrm.GetCurrentStream()->singleElement( XML_cellStyle,
    2233             :             XML_name,           sName.getStr(),
    2234             :             XML_xfId,           OString::valueOf( nXFId ).getStr(),
    2235             : /* mso-excel 2007 complains when it finds builtinId >= 55, it is not
    2236             :  * bothered by multiple 54 values. */
    2237             : #define CELL_STYLE_MAX_BUILTIN_ID 55
    2238          72 :                                              XML_builtinId, OString::valueOf( std::min( static_cast<sal_Int32>( CELL_STYLE_MAX_BUILTIN_ID - 1 ), static_cast <sal_Int32>( mnStyleId ) ) ).getStr(),
    2239             :             // OOXTODO: XML_iLevel,
    2240             :             // OOXTODO: XML_hidden,
    2241          36 :             XML_customBuiltin,  XclXmlUtils::ToPsz( ! IsBuiltIn() ),
    2242         144 :             FSEND );
    2243             :     // OOXTODO: XML_extLst
    2244          36 : }
    2245             : 
    2246             : // ----------------------------------------------------------------------------
    2247             : 
    2248             : namespace {
    2249             : 
    2250             : const sal_uInt32 EXC_XFLIST_INDEXBASE   = 0xFFFE0000;
    2251             : /** Maximum count of XF records to store in the XF list (performance). */
    2252             : const sal_uInt32 EXC_XFLIST_HARDLIMIT   = 256 * 1024;
    2253             : 
    2254           8 : bool lclIsBuiltInStyle( const String& rStyleName )
    2255             : {
    2256             :     return
    2257          40 :         XclTools::IsBuiltInStyleName( rStyleName ) ||
    2258          32 :         XclTools::IsCondFormatStyleName( rStyleName );
    2259             : }
    2260             : 
    2261             : } // namespace
    2262             : 
    2263             : // ----------------------------------------------------------------------------
    2264             : 
    2265         189 : XclExpXFBuffer::XclExpBuiltInInfo::XclExpBuiltInInfo() :
    2266             :     mnStyleId( EXC_STYLE_USERDEF ),
    2267             :     mnLevel( EXC_STYLE_NOLEVEL ),
    2268             :     mbPredefined( true ),
    2269         189 :     mbHasStyleRec( false )
    2270             : {
    2271         189 : }
    2272             : 
    2273             : // ----------------------------------------------------------------------------
    2274             : 
    2275             : /** Predicate for search algorithm. */
    2276             : struct XclExpBorderPred
    2277             : {
    2278             :     const XclExpCellBorder&
    2279             :                         mrBorder;
    2280         315 :     inline explicit     XclExpBorderPred( const XclExpCellBorder& rBorder ) : mrBorder( rBorder ) {}
    2281             :     bool                operator()( const XclExpCellBorder& rBorder ) const;
    2282             : };
    2283             : 
    2284         306 : bool XclExpBorderPred::operator()( const XclExpCellBorder& rBorder ) const
    2285             : {
    2286             :     return
    2287         612 :         mrBorder.mnLeftColor     == rBorder.mnLeftColor &&
    2288         612 :         mrBorder.mnRightColor    == rBorder.mnRightColor &&
    2289         612 :         mrBorder.mnTopColor      == rBorder.mnTopColor &&
    2290         612 :         mrBorder.mnBottomColor   == rBorder.mnBottomColor &&
    2291         612 :         mrBorder.mnDiagColor     == rBorder.mnDiagColor &&
    2292         612 :         mrBorder.mnLeftLine      == rBorder.mnLeftLine &&
    2293         612 :         mrBorder.mnRightLine     == rBorder.mnRightLine &&
    2294         612 :         mrBorder.mnTopLine       == rBorder.mnTopLine &&
    2295         612 :         mrBorder.mnBottomLine    == rBorder.mnBottomLine &&
    2296         612 :         mrBorder.mnDiagLine      == rBorder.mnDiagLine &&
    2297         612 :         mrBorder.mbDiagTLtoBR    == rBorder.mbDiagTLtoBR &&
    2298         612 :         mrBorder.mbDiagBLtoTR    == rBorder.mbDiagBLtoTR &&
    2299         612 :         mrBorder.mnLeftColorId   == rBorder.mnLeftColorId &&
    2300         612 :         mrBorder.mnRightColorId  == rBorder.mnRightColorId &&
    2301         612 :         mrBorder.mnTopColorId    == rBorder.mnTopColorId &&
    2302         918 :         mrBorder.mnBottomColorId == rBorder.mnBottomColorId &&
    2303         612 :         mrBorder.mnDiagColorId   == rBorder.mnDiagColorId;
    2304             : }
    2305             : 
    2306             : struct XclExpFillPred
    2307             : {
    2308             :     const XclExpCellArea&
    2309             :                         mrFill;
    2310         315 :     inline explicit     XclExpFillPred( const XclExpCellArea& rFill ) : mrFill( rFill ) {}
    2311             :     bool                operator()( const XclExpCellArea& rFill ) const;
    2312             : };
    2313             : 
    2314         315 : bool XclExpFillPred::operator()( const XclExpCellArea& rFill ) const
    2315             : {
    2316             :     return
    2317         630 :         mrFill.mnForeColor      == rFill.mnForeColor &&
    2318         630 :         mrFill.mnBackColor      == rFill.mnBackColor &&
    2319         630 :         mrFill.mnPattern        == rFill.mnPattern &&
    2320         945 :         mrFill.mnForeColorId    == rFill.mnForeColorId &&
    2321         630 :         mrFill.mnBackColorId    == rFill.mnBackColorId;
    2322             : }
    2323             : 
    2324           9 : XclExpXFBuffer::XclExpXFBuffer( const XclExpRoot& rRoot ) :
    2325           9 :     XclExpRoot( rRoot )
    2326             : {
    2327           9 : }
    2328             : 
    2329           9 : void XclExpXFBuffer::Initialize()
    2330             : {
    2331           9 :     InsertDefaultRecords();
    2332           9 :     InsertUserStyles();
    2333           9 : }
    2334             : 
    2335       10778 : sal_uInt32 XclExpXFBuffer::Insert( const ScPatternAttr* pPattern, sal_Int16 nScript )
    2336             : {
    2337       10778 :     return InsertCellXF( pPattern, nScript, NUMBERFORMAT_ENTRY_NOT_FOUND, EXC_FONT_NOTFOUND, false );
    2338             : }
    2339             : 
    2340          12 : sal_uInt32 XclExpXFBuffer::InsertWithFont( const ScPatternAttr* pPattern, sal_Int16 nScript,
    2341             :         sal_uInt16 nForceXclFont, bool bForceLineBreak )
    2342             : {
    2343          12 :     return InsertCellXF( pPattern, nScript, NUMBERFORMAT_ENTRY_NOT_FOUND, nForceXclFont, bForceLineBreak );
    2344             : }
    2345             : 
    2346           0 : sal_uInt32 XclExpXFBuffer::InsertWithNumFmt( const ScPatternAttr* pPattern, sal_Int16 nScript, sal_uLong nForceScNumFmt, bool bForceLineBreak )
    2347             : {
    2348           0 :     return InsertCellXF( pPattern, nScript, nForceScNumFmt, EXC_FONT_NOTFOUND, bForceLineBreak );
    2349             : }
    2350             : 
    2351          21 : sal_uInt32 XclExpXFBuffer::InsertStyle( const SfxStyleSheetBase* pStyleSheet )
    2352             : {
    2353          21 :     return pStyleSheet ? InsertStyleXF( *pStyleSheet ) : GetXFIdFromIndex( EXC_XF_DEFAULTSTYLE );
    2354             : }
    2355             : 
    2356       19102 : sal_uInt32 XclExpXFBuffer::GetXFIdFromIndex( sal_uInt16 nXFIndex )
    2357             : {
    2358       19102 :     return EXC_XFLIST_INDEXBASE | nXFIndex;
    2359             : }
    2360             : 
    2361       19066 : sal_uInt32 XclExpXFBuffer::GetDefCellXFId()
    2362             : {
    2363       19066 :     return GetXFIdFromIndex( EXC_XF_DEFAULTCELL );
    2364             : }
    2365             : 
    2366          18 : const XclExpXF* XclExpXFBuffer::GetXFById( sal_uInt32 nXFId ) const
    2367             : {
    2368          18 :     return maXFList.GetRecord( nXFId ).get();
    2369             : }
    2370             : 
    2371           9 : void XclExpXFBuffer::Finalize()
    2372             : {
    2373         210 :     for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
    2374         201 :         maXFList.GetRecord( nPos )->SetFinalColors();
    2375             : 
    2376           9 :     sal_uInt32 nTotalCount = static_cast< sal_uInt32 >( maXFList.GetSize() );
    2377             :     sal_uInt32 nId;
    2378           9 :     maXFIndexVec.resize( nTotalCount, EXC_XF_DEFAULTCELL );
    2379           9 :     maStyleIndexes.resize( nTotalCount, EXC_XF_DEFAULTCELL );
    2380           9 :     maCellIndexes.resize( nTotalCount, EXC_XF_DEFAULTCELL );
    2381             : 
    2382           9 :     XclExpBuiltInMap::const_iterator aBuiltInEnd = maBuiltInMap.end();
    2383             :     /*  nMaxBuiltInXFId used to decide faster whether an XF record is
    2384             :         user-defined. If the current XF ID is greater than this value,
    2385             :         maBuiltInMap doesn't need to be searched. */
    2386           9 :     sal_uInt32 nMaxBuiltInXFId = maBuiltInMap.empty() ? 0 : maBuiltInMap.rbegin()->first;
    2387             : 
    2388             :     // *** map all built-in XF records (cell and style) *** -------------------
    2389             : 
    2390             :     // do not change XF order -> std::map<> iterates elements in ascending order
    2391         198 :     for( XclExpBuiltInMap::const_iterator aIt = maBuiltInMap.begin(); aIt != aBuiltInEnd; ++aIt )
    2392         189 :         AppendXFIndex( aIt->first );
    2393             : 
    2394             :     // *** insert all user-defined style XF records, without reduce *** -------
    2395             : 
    2396           9 :     sal_uInt32 nStyleXFCount = 0;       // counts up to EXC_XF_MAXSTYLECOUNT limit
    2397             : 
    2398         210 :     for( nId = 0; nId < nTotalCount; ++nId )
    2399             :     {
    2400         201 :         XclExpXFRef xXF = maXFList.GetRecord( nId );
    2401         201 :         if( xXF->IsStyleXF() && ((nId > nMaxBuiltInXFId) || (maBuiltInMap.find( nId ) == aBuiltInEnd)) )
    2402             :         {
    2403           0 :             if( nStyleXFCount < EXC_XF_MAXSTYLECOUNT )
    2404             :             {
    2405             :                 // maximum count of styles not reached
    2406           0 :                 AppendXFIndex( nId );
    2407           0 :                 ++nStyleXFCount;
    2408             :             }
    2409             :             else
    2410             :             {
    2411             :                 /*  Maximum count of styles reached - do not append more
    2412             :                     pointers to XFs; use default style XF instead; do not break
    2413             :                     the loop to initialize all maXFIndexVec elements. */
    2414           0 :                 maXFIndexVec[ nId ] = EXC_XF_DEFAULTSTYLE;
    2415             :             }
    2416             :         }
    2417         201 :     }
    2418             : 
    2419             :     // *** insert all cell XF records *** -------------------------------------
    2420             : 
    2421             :     // start position to search for equal inserted XF records
    2422           9 :     size_t nSearchStart = maSortedXFList.GetSize();
    2423             : 
    2424             :     // break the loop if XF limit reached - maXFIndexVec is already initialized with default index
    2425           9 :     XclExpXFRef xDefCellXF = maXFList.GetRecord( EXC_XF_DEFAULTCELL );
    2426         210 :     for( nId = 0; (nId < nTotalCount) && (maSortedXFList.GetSize() < EXC_XF_MAXCOUNT); ++nId )
    2427             :     {
    2428         201 :         XclExpXFRef xXF = maXFList.GetRecord( nId );
    2429         201 :         if( xXF->IsCellXF() && ((nId > nMaxBuiltInXFId) || (maBuiltInMap.find( nId ) == aBuiltInEnd)) )
    2430             :         {
    2431             :             // try to find an XF record equal to *xXF, which is already inserted
    2432          12 :             sal_uInt16 nFoundIndex = EXC_XF_NOTFOUND;
    2433             : 
    2434             :             // first try if it is equal to the default cell XF
    2435          12 :             if( xDefCellXF->Equals( *xXF ) )
    2436             :             {
    2437          12 :                 nFoundIndex = EXC_XF_DEFAULTCELL;
    2438             :             }
    2439           0 :             else for( size_t nSearchPos = nSearchStart, nSearchEnd = maSortedXFList.GetSize();
    2440           0 :                         (nSearchPos < nSearchEnd) && (nFoundIndex == EXC_XF_NOTFOUND); ++nSearchPos )
    2441             :             {
    2442           0 :                 if( maSortedXFList.GetRecord( nSearchPos )->Equals( *xXF ) )
    2443           0 :                     nFoundIndex = static_cast< sal_uInt16 >( nSearchPos );
    2444             :             }
    2445             : 
    2446          12 :             if( nFoundIndex != EXC_XF_NOTFOUND )
    2447             :                 // equal XF already in the list, use its resulting XF index
    2448          12 :                 maXFIndexVec[ nId ] = nFoundIndex;
    2449             :             else
    2450           0 :                 AppendXFIndex( nId );
    2451             :         }
    2452         201 :     }
    2453             : 
    2454           9 :     sal_uInt16 nXmlStyleIndex   = 0;
    2455           9 :     sal_uInt16 nXmlCellIndex    = 0;
    2456             : 
    2457           9 :     size_t nXFCount = maSortedXFList.GetSize();
    2458         198 :     for( size_t i = 0; i < nXFCount; ++i )
    2459             :     {
    2460         189 :         XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
    2461         189 :         if( xXF->IsStyleXF() )
    2462         180 :             maStyleIndexes[ i ] = nXmlStyleIndex++;
    2463             :         else
    2464           9 :             maCellIndexes[ i ] = nXmlCellIndex++;
    2465         198 :     }
    2466           9 : }
    2467             : 
    2468       10987 : sal_uInt16 XclExpXFBuffer::GetXFIndex( sal_uInt32 nXFId ) const
    2469             : {
    2470       10987 :     sal_uInt16 nXFIndex = EXC_XF_DEFAULTSTYLE;
    2471       10987 :     if( nXFId >= EXC_XFLIST_INDEXBASE )
    2472        8621 :         nXFIndex = static_cast< sal_uInt16 >( nXFId & ~EXC_XFLIST_INDEXBASE );
    2473        2366 :     else if( nXFId < maXFIndexVec.size() )
    2474        2366 :         nXFIndex = maXFIndexVec[ nXFId ];
    2475       10987 :     return nXFIndex;
    2476             : }
    2477             : 
    2478          42 : sal_Int32 XclExpXFBuffer::GetXmlStyleIndex( sal_uInt32 nXFIndex ) const
    2479             : {
    2480             :     OSL_ENSURE( nXFIndex < maStyleIndexes.size(), "XclExpXFBuffer::GetXmlStyleIndex - invalid index!" );
    2481          42 :     if( nXFIndex > maStyleIndexes.size() )
    2482           0 :         return 0;   // should be caught/debugged via above assert; return "valid" index.
    2483          42 :     return maStyleIndexes[ nXFIndex ];
    2484             : }
    2485             : 
    2486         245 : sal_Int32 XclExpXFBuffer::GetXmlCellIndex( sal_uInt32 nXFIndex ) const
    2487             : {
    2488             :     OSL_ENSURE( nXFIndex < maCellIndexes.size(), "XclExpXFBuffer::GetXmlStyleIndex - invalid index!" );
    2489         245 :     if( nXFIndex > maCellIndexes.size() )
    2490           0 :         return 0;   // should be caught/debugged via above assert; return "valid" index.
    2491         245 :     return maCellIndexes[ nXFIndex ];
    2492             : }
    2493             : 
    2494           3 : void XclExpXFBuffer::Save( XclExpStream& rStrm )
    2495             : {
    2496             :     // save all XF records contained in the maSortedXFList vector (sorted by XF index)
    2497           3 :     maSortedXFList.Save( rStrm );
    2498             :     // save all STYLE records
    2499           3 :     maStyleList.Save( rStrm );
    2500           3 : }
    2501             : 
    2502           6 : static void lcl_GetCellCounts( const XclExpRecordList< XclExpXF >& rXFList, sal_Int32& rCells, sal_Int32& rStyles )
    2503             : {
    2504           6 :     rCells  = 0;
    2505           6 :     rStyles = 0;
    2506           6 :     size_t nXFCount = rXFList.GetSize();
    2507         132 :     for( size_t i = 0; i < nXFCount; ++i )
    2508             :     {
    2509         126 :         XclExpRecordList< XclExpXF >::RecordRefType xXF = rXFList.GetRecord( i );
    2510         126 :         if( xXF->IsCellXF() )
    2511           6 :             ++rCells;
    2512         120 :         else if( xXF->IsStyleXF() )
    2513         120 :             ++rStyles;
    2514         126 :     }
    2515           6 : }
    2516             : 
    2517           6 : void XclExpXFBuffer::SaveXml( XclExpXmlStream& rStrm )
    2518             : {
    2519           6 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    2520             : 
    2521             :     rStyleSheet->startElement( XML_fills,
    2522           6 :             XML_count,  OString::valueOf( (sal_Int32) maFills.size() ).getStr(),
    2523           6 :             FSEND );
    2524          18 :     for( XclExpFillList::iterator aIt = maFills.begin(), aEnd = maFills.end();
    2525             :             aIt != aEnd; ++aIt )
    2526             :     {
    2527          12 :         aIt->SaveXml( rStrm );
    2528             :     }
    2529           6 :     rStyleSheet->endElement( XML_fills );
    2530             : 
    2531             :     rStyleSheet->startElement( XML_borders,
    2532           6 :             XML_count,  OString::valueOf( (sal_Int32) maBorders.size() ).getStr(),
    2533           6 :             FSEND );
    2534          12 :     for( XclExpBorderList::iterator aIt = maBorders.begin(), aEnd = maBorders.end();
    2535             :             aIt != aEnd; ++aIt )
    2536             :     {
    2537           6 :         aIt->SaveXml( rStrm );
    2538             :     }
    2539           6 :     rStyleSheet->endElement( XML_borders );
    2540             : 
    2541             :     // save all XF records contained in the maSortedXFList vector (sorted by XF index)
    2542             :     sal_Int32 nCells, nStyles;
    2543           6 :     lcl_GetCellCounts( maSortedXFList, nCells, nStyles );
    2544             : 
    2545           6 :     if( nStyles > 0 )
    2546             :     {
    2547             :         rStyleSheet->startElement( XML_cellStyleXfs,
    2548             :                 XML_count,  OString::valueOf( nStyles ).getStr(),
    2549           6 :                 FSEND );
    2550           6 :         size_t nXFCount = maSortedXFList.GetSize();
    2551         132 :         for( size_t i = 0; i < nXFCount; ++i )
    2552             :         {
    2553         126 :             XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
    2554         126 :             if( ! xXF->IsStyleXF() )
    2555           6 :                 continue;
    2556         120 :             SaveXFXml( rStrm, *xXF );
    2557         120 :         }
    2558           6 :         rStyleSheet->endElement( XML_cellStyleXfs );
    2559             :     }
    2560             : 
    2561           6 :     if( nCells > 0 )
    2562             :     {
    2563             :         rStyleSheet->startElement( XML_cellXfs,
    2564             :                 XML_count,  OString::valueOf( nCells ).getStr(),
    2565           6 :                 FSEND );
    2566           6 :         size_t nXFCount = maSortedXFList.GetSize();
    2567         132 :         for( size_t i = 0; i < nXFCount; ++i )
    2568             :         {
    2569         126 :             XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
    2570         126 :             if( ! xXF->IsCellXF() )
    2571         120 :                 continue;
    2572           6 :             SaveXFXml( rStrm, *xXF );
    2573           6 :         }
    2574           6 :         rStyleSheet->endElement( XML_cellXfs );
    2575             :     }
    2576             : 
    2577             :     // save all STYLE records
    2578             :     rStyleSheet->startElement( XML_cellStyles,
    2579           6 :             XML_count,  OString::valueOf( (sal_Int32) maStyleList.GetSize() ).getStr(),
    2580           6 :             FSEND );
    2581           6 :     maStyleList.SaveXml( rStrm );
    2582           6 :     rStyleSheet->endElement( XML_cellStyles );
    2583           6 : }
    2584             : 
    2585         126 : void XclExpXFBuffer::SaveXFXml( XclExpXmlStream& rStrm, XclExpXF& rXF )
    2586             : {
    2587             :     XclExpBorderList::iterator aBorderPos =
    2588         126 :         std::find_if( maBorders.begin(), maBorders.end(), XclExpBorderPred( rXF.GetBorderData() ) );
    2589             :     OSL_ENSURE( aBorderPos != maBorders.end(), "XclExpXFBuffer::SaveXml - Invalid @borderId!" );
    2590             :     XclExpFillList::iterator aFillPos =
    2591         126 :         std::find_if( maFills.begin(), maFills.end(), XclExpFillPred( rXF.GetAreaData() ) );
    2592             :     OSL_ENSURE( aFillPos != maFills.end(), "XclExpXFBuffer::SaveXml - Invalid @fillId!" );
    2593             : 
    2594         126 :     sal_Int32 nBorderId = 0, nFillId = 0;
    2595         126 :     if( aBorderPos != maBorders.end() )
    2596         126 :         nBorderId = std::distance( maBorders.begin(), aBorderPos );
    2597         126 :     if( aFillPos != maFills.end() )
    2598         126 :         nFillId = std::distance( maFills.begin(), aFillPos );
    2599             : 
    2600         126 :     rXF.SetXmlIds( nBorderId, nFillId );
    2601         126 :     rXF.SaveXml( rStrm );
    2602         126 : }
    2603             : 
    2604        2291 : sal_uInt32 XclExpXFBuffer::FindXF( const ScPatternAttr& rPattern,
    2605             :         sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) const
    2606             : {
    2607       50978 :     for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
    2608       50966 :         if( maXFList.GetRecord( nPos )->Equals( rPattern, nForceScNumFmt, nForceXclFont, bForceLineBreak ) )
    2609        2279 :             return static_cast< sal_uInt32 >( nPos );
    2610          12 :     return EXC_XFID_NOTFOUND;
    2611             : }
    2612             : 
    2613           0 : sal_uInt32 XclExpXFBuffer::FindXF( const SfxStyleSheetBase& rStyleSheet ) const
    2614             : {
    2615           0 :     for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
    2616           0 :         if( maXFList.GetRecord( nPos )->Equals( rStyleSheet ) )
    2617           0 :             return static_cast< sal_uInt32 >( nPos );
    2618           0 :     return EXC_XFID_NOTFOUND;
    2619             : }
    2620             : 
    2621          21 : sal_uInt32 XclExpXFBuffer::FindBuiltInXF( sal_uInt8 nStyleId, sal_uInt8 nLevel ) const
    2622             : {
    2623          21 :     for( XclExpBuiltInMap::const_iterator aIt = maBuiltInMap.begin(), aEnd = maBuiltInMap.end(); aIt != aEnd; ++aIt )
    2624          21 :         if( (aIt->second.mnStyleId == nStyleId) && (aIt->second.mnLevel == nLevel) )
    2625          21 :             return aIt->first;
    2626           0 :     return EXC_XFID_NOTFOUND;
    2627             : }
    2628             : 
    2629       10790 : sal_uInt32 XclExpXFBuffer::InsertCellXF( const ScPatternAttr* pPattern, sal_Int16 nScript,
    2630             :         sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak )
    2631             : {
    2632       10790 :     const ScPatternAttr* pDefPattern = GetDoc().GetDefPattern();
    2633       10790 :     if( !pPattern )
    2634          55 :         pPattern = pDefPattern;
    2635             : 
    2636             :     // special handling for default cell formatting
    2637       10790 :     if( (pPattern == pDefPattern) && !bForceLineBreak &&
    2638        8511 :         (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) &&
    2639             :         (nForceXclFont == EXC_FONT_NOTFOUND) )
    2640             :     {
    2641             :         // Is it the first try to insert the default cell format?
    2642        8499 :         bool& rbPredefined = maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined;
    2643        8499 :         if( rbPredefined )
    2644             :         {
    2645             :             // replace default cell pattern
    2646           9 :             XclExpXFRef xNewXF( new XclExpXF( GetRoot(), *pPattern, nScript ) );
    2647           9 :             maXFList.ReplaceRecord( xNewXF, EXC_XF_DEFAULTCELL );
    2648           9 :             rbPredefined = false;
    2649             :         }
    2650        8499 :         return GetDefCellXFId();
    2651             :     }
    2652             : 
    2653        2291 :     sal_uInt32 nXFId = FindXF( *pPattern, nForceScNumFmt, nForceXclFont, bForceLineBreak );
    2654        2291 :     if( nXFId == EXC_XFID_NOTFOUND )
    2655             :     {
    2656             :         // not found - insert new cell XF
    2657          12 :         if( maXFList.GetSize() < EXC_XFLIST_HARDLIMIT )
    2658             :         {
    2659             :             maXFList.AppendNewRecord( new XclExpXF(
    2660          12 :                 GetRoot(), *pPattern, nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak ) );
    2661             :             // do not set nXFId before the AppendNewRecord() call - it may insert 2 XFs (style+cell)
    2662          12 :             nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() - 1 );
    2663             :         }
    2664             :         else
    2665             :         {
    2666             :             // list full - fall back to default cell XF
    2667           0 :             nXFId = GetDefCellXFId();
    2668             :         }
    2669             :     }
    2670        2291 :     return nXFId;
    2671             : }
    2672             : 
    2673          21 : sal_uInt32 XclExpXFBuffer::InsertStyleXF( const SfxStyleSheetBase& rStyleSheet )
    2674             : {
    2675             :     // *** try, if it is a built-in style - create new XF or replace existing predefined XF ***
    2676             : 
    2677             :     sal_uInt8 nStyleId, nLevel;
    2678          21 :     if( XclTools::GetBuiltInStyleId( nStyleId, nLevel, rStyleSheet.GetName() ) )
    2679             :     {
    2680             :         // try to find the built-in XF record (if already created in InsertDefaultRecords())
    2681          21 :         sal_uInt32 nXFId = FindBuiltInXF( nStyleId, nLevel );
    2682          21 :         if( nXFId == EXC_XFID_NOTFOUND )
    2683             :         {
    2684             :             // built-in style XF not yet created - do it now
    2685           0 :             XclExpXFRef xXF( new XclExpXF( GetRoot(), rStyleSheet ) );
    2686           0 :             nXFId = AppendBuiltInXFWithStyle( xXF, nStyleId, nLevel );
    2687             :             // this new XF record is not predefined
    2688           0 :             maBuiltInMap[ nXFId ].mbPredefined = false;
    2689             :         }
    2690             :         else
    2691             :         {
    2692             :             OSL_ENSURE( maXFList.HasRecord( nXFId ), "XclExpXFBuffer::InsertStyleXF - built-in XF not found" );
    2693             :             // XF record still predefined? -> Replace with real XF
    2694          21 :             bool& rbPredefined = maBuiltInMap[ nXFId ].mbPredefined;
    2695          21 :             if( rbPredefined )
    2696             :             {
    2697             :                 // replace predefined built-in style (ReplaceRecord() deletes old record)
    2698           0 :                 maXFList.ReplaceRecord( XclExpXFRef( new XclExpXF( GetRoot(), rStyleSheet ) ), nXFId );
    2699           0 :                 rbPredefined = false;
    2700             :             }
    2701             :         }
    2702             : 
    2703             :         // STYLE already inserted? (may be not, i.e. for RowLevel/ColLevel or Hyperlink styles)
    2704          21 :         bool& rbHasStyleRec = maBuiltInMap[ nXFId ].mbHasStyleRec;
    2705          21 :         if( !rbHasStyleRec )
    2706             :         {
    2707           0 :             maStyleList.AppendNewRecord( new XclExpStyle( nXFId, nStyleId, nLevel ) );
    2708           0 :             rbHasStyleRec = true;
    2709             :         }
    2710             : 
    2711          21 :         return nXFId;
    2712             :     }
    2713             : 
    2714             :     // *** try to find the XF record of a user-defined style ***
    2715             : 
    2716           0 :     sal_uInt32 nXFId = FindXF( rStyleSheet );
    2717           0 :     if( nXFId == EXC_XFID_NOTFOUND )
    2718             :     {
    2719             :         // not found - insert new style XF and STYLE
    2720           0 :         nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() );
    2721           0 :         if( nXFId < EXC_XFLIST_HARDLIMIT )
    2722             :         {
    2723           0 :             maXFList.AppendNewRecord( new XclExpXF( GetRoot(), rStyleSheet ) );
    2724             :             // create the STYLE record
    2725           0 :             if( !rStyleSheet.GetName().isEmpty() )
    2726           0 :                 maStyleList.AppendNewRecord( new XclExpStyle( nXFId, rStyleSheet.GetName() ) );
    2727             :         }
    2728             :         else
    2729             :             // list full - fall back to default style XF
    2730           0 :             nXFId = GetXFIdFromIndex( EXC_XF_DEFAULTSTYLE );
    2731             :     }
    2732           0 :     return nXFId;
    2733             : }
    2734             : 
    2735           9 : void XclExpXFBuffer::InsertUserStyles()
    2736             : {
    2737           9 :     SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
    2738          62 :     for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() )
    2739          53 :         if( pStyleSheet->IsUserDefined() && !lclIsBuiltInStyle( pStyleSheet->GetName() ) )
    2740           9 :             InsertStyleXF( *pStyleSheet );
    2741           9 : }
    2742             : 
    2743         180 : sal_uInt32 XclExpXFBuffer::AppendBuiltInXF( XclExpXFRef xXF, sal_uInt8 nStyleId, sal_uInt8 nLevel )
    2744             : {
    2745         180 :     sal_uInt32 nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() );
    2746         180 :     maXFList.AppendRecord( xXF );
    2747         180 :     XclExpBuiltInInfo& rInfo = maBuiltInMap[ nXFId ];
    2748         180 :     rInfo.mnStyleId = nStyleId;
    2749         180 :     rInfo.mnLevel = nLevel;
    2750         180 :     rInfo.mbPredefined = true;
    2751         180 :     return nXFId;
    2752             : }
    2753             : 
    2754          54 : sal_uInt32 XclExpXFBuffer::AppendBuiltInXFWithStyle( XclExpXFRef xXF, sal_uInt8 nStyleId, sal_uInt8 nLevel )
    2755             : {
    2756          54 :     sal_uInt32 nXFId = AppendBuiltInXF( xXF, nStyleId, nLevel );
    2757          54 :     maStyleList.AppendNewRecord( new XclExpStyle( nXFId, nStyleId, nLevel ) );
    2758          54 :     maBuiltInMap[ nXFId ].mbHasStyleRec = true;  // mark existing STYLE record
    2759          54 :     return nXFId;
    2760             : }
    2761             : 
    2762           9 : static XclExpCellArea lcl_GetPatternFill_None()
    2763             : {
    2764           9 :     XclExpCellArea aFill;
    2765           9 :     aFill.mnPattern = EXC_PATT_NONE;
    2766           9 :     return aFill;
    2767             : }
    2768             : 
    2769           9 : static XclExpCellArea lcl_GetPatternFill_Gray125()
    2770             : {
    2771           9 :     XclExpCellArea aFill;
    2772           9 :     aFill.mnPattern     = EXC_PATT_12_5_PERC;
    2773           9 :     aFill.mnForeColor   = 0;
    2774           9 :     aFill.mnBackColor   = 0;
    2775           9 :     return aFill;
    2776             : }
    2777             : 
    2778           9 : void XclExpXFBuffer::InsertDefaultRecords()
    2779             : {
    2780           9 :     maFills.push_back( lcl_GetPatternFill_None() );
    2781           9 :     maFills.push_back( lcl_GetPatternFill_Gray125() );
    2782             : 
    2783             :     // index 0: default style
    2784           9 :     if( SfxStyleSheetBase* pDefStyleSheet = GetStyleSheetPool().Find( ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) )
    2785             :     {
    2786           9 :         XclExpXFRef xDefStyle( new XclExpXF( GetRoot(), *pDefStyleSheet ) );
    2787           9 :         sal_uInt32 nXFId = AppendBuiltInXFWithStyle( xDefStyle, EXC_STYLE_NORMAL );
    2788             :         // mark this XF as not predefined, prevents overwriting
    2789           9 :         maBuiltInMap[ nXFId ].mbPredefined = false;
    2790             :     }
    2791             :     else
    2792             :     {
    2793             :         OSL_FAIL( "XclExpXFBuffer::InsertDefaultRecords - default style not found" );
    2794           0 :         XclExpXFRef xDefStyle( new XclExpDefaultXF( GetRoot(), false ) );
    2795           0 :         xDefStyle->SetAllUsedFlags( true );
    2796           0 :         AppendBuiltInXFWithStyle( xDefStyle, EXC_STYLE_NORMAL );
    2797             :     }
    2798             : 
    2799             :     // index 1-14: RowLevel and ColLevel styles (without STYLE records)
    2800           9 :     XclExpDefaultXF aLevelStyle( GetRoot(), false );
    2801             :     // RowLevel_1, ColLevel_1
    2802           9 :     aLevelStyle.SetFont( 1 );
    2803           9 :     AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, 0 );
    2804           9 :     AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, 0 );
    2805             :     // RowLevel_2, ColLevel_2
    2806           9 :     aLevelStyle.SetFont( 2 );
    2807           9 :     AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, 1 );
    2808           9 :     AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, 1 );
    2809             :     // RowLevel_3, ColLevel_3 ... RowLevel_7, ColLevel_7
    2810           9 :     aLevelStyle.SetFont( 0 );
    2811          54 :     for( sal_uInt8 nLevel = 2; nLevel < EXC_STYLE_LEVELCOUNT; ++nLevel )
    2812             :     {
    2813          45 :         AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, nLevel );
    2814          45 :         AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, nLevel );
    2815             :     }
    2816             : 
    2817             :     // index 15: default hard cell format, placeholder to be able to add more built-in styles
    2818           9 :     maXFList.AppendNewRecord( new XclExpDefaultXF( GetRoot(), true ) );
    2819           9 :     maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined = true;
    2820             : 
    2821             :     // index 16-20: other built-in styles
    2822          18 :     XclExpDefaultXF aFormatStyle( GetRoot(), false );
    2823           9 :     aFormatStyle.SetFont( 1 );
    2824           9 :     aFormatStyle.SetNumFmt( 43 );
    2825           9 :     AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_COMMA );
    2826           9 :     aFormatStyle.SetNumFmt( 41 );
    2827           9 :     AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_COMMA_0 );
    2828           9 :     aFormatStyle.SetNumFmt( 44 );
    2829           9 :     AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_CURRENCY );
    2830           9 :     aFormatStyle.SetNumFmt( 42 );
    2831           9 :     AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_CURRENCY_0 );
    2832           9 :     aFormatStyle.SetNumFmt( 9 );
    2833           9 :     AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_PERCENT );
    2834             : 
    2835             :     // other built-in style XF records (i.e. Hyperlink styles) are created on demand
    2836             : 
    2837             :     /*  Insert the real default hard cell format -> 0 is document default pattern.
    2838             :         Do it here (and not already above) to really have all built-in styles. */
    2839          18 :     Insert( 0, GetDefApiScript() );
    2840           9 : }
    2841             : 
    2842         189 : void XclExpXFBuffer::AppendXFIndex( sal_uInt32 nXFId )
    2843             : {
    2844             :     OSL_ENSURE( nXFId < maXFIndexVec.size(), "XclExpXFBuffer::AppendXFIndex - XF ID out of range" );
    2845         189 :     maXFIndexVec[ nXFId ] = static_cast< sal_uInt16 >( maSortedXFList.GetSize() );
    2846         189 :     XclExpXFRef xXF = maXFList.GetRecord( nXFId );
    2847         189 :     AddBorderAndFill( *xXF );
    2848         189 :     maSortedXFList.AppendRecord( xXF );
    2849         189 :     OSL_ENSURE( maXFList.HasRecord( nXFId ), "XclExpXFBuffer::AppendXFIndex - XF not found" );
    2850         189 : }
    2851             : 
    2852         189 : void XclExpXFBuffer::AddBorderAndFill( const XclExpXF& rXF )
    2853             : {
    2854         189 :     if( std::find_if( maBorders.begin(), maBorders.end(), XclExpBorderPred( rXF.GetBorderData() ) ) == maBorders.end() )
    2855             :     {
    2856           9 :         maBorders.push_back( rXF.GetBorderData() );
    2857             :     }
    2858             : 
    2859         189 :     if( std::find_if( maFills.begin(), maFills.end(), XclExpFillPred( rXF.GetAreaData() ) ) == maFills.end() )
    2860             :     {
    2861           0 :         maFills.push_back( rXF.GetAreaData() );
    2862             :     }
    2863         189 : }
    2864             : 
    2865             : 
    2866           9 : XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot )
    2867             :     : XclExpRoot( rRoot ),
    2868           9 :     mxFormatter( new SvNumberFormatter( comphelper::getProcessComponentContext(), LANGUAGE_ENGLISH_US ) ),
    2869          18 :     mpKeywordTable( new NfKeywordTable )
    2870             : {
    2871           9 :     mxFormatter->FillKeywordTable( *mpKeywordTable, LANGUAGE_ENGLISH_US );
    2872             :     // remap codes unknown to Excel
    2873           9 :     (*mpKeywordTable)[ NF_KEY_NN ] = "DDD";
    2874           9 :     (*mpKeywordTable)[ NF_KEY_NNN ] = "DDDD";
    2875             :     // NNNN gets a separator appended in SvNumberformat::GetMappedFormatString()
    2876           9 :     (*mpKeywordTable)[ NF_KEY_NNNN ] = "DDDD";
    2877             :     // Export the Thai T NatNum modifier.
    2878           9 :     (*mpKeywordTable)[ NF_KEY_THAI_T ] = "T";
    2879             : 
    2880           9 :     SCTAB nTables = rRoot.GetDoc().GetTableCount();
    2881          23 :     for(SCTAB nTab = 0; nTab < nTables; ++nTab)
    2882             :     {
    2883          14 :         ScConditionalFormatList* pList = rRoot.GetDoc().GetCondFormList(nTab);
    2884          14 :         if (pList)
    2885             :         {
    2886          14 :             sal_Int32 nIndex = 0;
    2887          84 :             for (ScConditionalFormatList::const_iterator itr = pList->begin();
    2888          56 :                     itr != pList->end(); ++itr)
    2889             :             {
    2890          14 :                 size_t nEntryCount = itr->size();
    2891          28 :                 for (size_t nFormatEntry = 0; nFormatEntry < nEntryCount; ++nFormatEntry)
    2892             :                 {
    2893          14 :                     const ScFormatEntry* pFormatEntry = itr->GetEntry(nFormatEntry);
    2894          20 :                     if (!pFormatEntry || (pFormatEntry->GetType() != condformat::CONDITION &&
    2895           6 :                                 pFormatEntry->GetType() != condformat::DATE))
    2896          12 :                         continue;
    2897             : 
    2898           8 :                     OUString aStyleName;
    2899           8 :                     if(pFormatEntry->GetType() == condformat::CONDITION)
    2900             :                     {
    2901           8 :                         const ScCondFormatEntry* pEntry = static_cast<const ScCondFormatEntry*>(pFormatEntry);
    2902           8 :                         aStyleName= pEntry->GetStyle();
    2903             :                     }
    2904             :                     else
    2905             :                     {
    2906           0 :                         const ScCondDateFormatEntry* pEntry = static_cast<const ScCondDateFormatEntry*>(pFormatEntry);
    2907           0 :                         aStyleName = pEntry->GetStyleName();
    2908             :                     }
    2909             : 
    2910           8 :                     if (maStyleNameToDxfId.find(aStyleName) == maStyleNameToDxfId.end())
    2911             :                     {
    2912           8 :                         maStyleNameToDxfId.insert(std::pair<OUString, sal_Int32>(aStyleName, nIndex));
    2913             : 
    2914           8 :                         SfxStyleSheetBase* pStyle = rRoot.GetDoc().GetStyleSheetPool()->Find(aStyleName);
    2915           8 :                         if(!pStyle)
    2916           0 :                             continue;
    2917             : 
    2918           8 :                         SfxItemSet& rSet = pStyle->GetItemSet();
    2919             : 
    2920           8 :                         XclExpCellBorder* pBorder = new XclExpCellBorder;
    2921           8 :                         if (!pBorder->FillFromItemSet( rSet, GetPalette(), GetBiff()) )
    2922             :                         {
    2923           8 :                             delete pBorder;
    2924           8 :                             pBorder = NULL;
    2925             :                         }
    2926             : 
    2927           8 :                         XclExpCellAlign* pAlign = new XclExpCellAlign;
    2928           8 :                         if (!pAlign->FillFromItemSet( rSet, false, GetBiff()))
    2929             :                         {
    2930           8 :                             delete pAlign;
    2931           8 :                             pAlign = NULL;
    2932             :                         }
    2933             : 
    2934           8 :                         XclExpCellProt* pCellProt = new XclExpCellProt;
    2935           8 :                         if (!pCellProt->FillFromItemSet( rSet ))
    2936             :                         {
    2937           8 :                             delete pCellProt;
    2938           8 :                             pCellProt = NULL;
    2939             :                         }
    2940             : 
    2941           8 :                         XclExpColor* pColor = new XclExpColor();
    2942           8 :                         if(!pColor->FillFromItemSet( rSet ))
    2943             :                         {
    2944           8 :                             delete pColor;
    2945           8 :                             pColor = NULL;
    2946             :                         }
    2947             : 
    2948           8 :                         XclExpFont* pFont = NULL;
    2949             :                         // check if non default font is set and only export then
    2950           8 :                         if (rSet.GetItemState(rSet.GetPool()->GetWhich( SID_ATTR_CHAR_FONT )) == SFX_ITEM_SET )
    2951             :                         {
    2952           8 :                             Font aFont = XclExpFontHelper::GetFontFromItemSet( GetRoot(), rSet, com::sun::star::i18n::ScriptType::WEAK );
    2953           8 :                             pFont = new XclExpFont( GetRoot(), XclFontData( aFont ), EXC_COLOR_CELLTEXT );
    2954             :                         }
    2955             : 
    2956           8 :                         XclExpNumFmt* pNumFormat = NULL;
    2957           8 :                         const SfxPoolItem *pPoolItem = NULL;
    2958           8 :                         if( rSet.GetItemState( ATTR_VALUE_FORMAT, sal_True, &pPoolItem ) == SFX_ITEM_SET )
    2959             :                         {
    2960           8 :                             sal_uLong nScNumFmt = static_cast< sal_uInt32 >( static_cast< const SfxInt32Item* >(pPoolItem)->GetValue());
    2961           8 :                             sal_Int32 nXclNumFmt = GetRoot().GetNumFmtBuffer().Insert(nScNumFmt);
    2962           8 :                             pNumFormat = new XclExpNumFmt( nScNumFmt, nXclNumFmt, GetNumberFormatCode( *this, nScNumFmt, mxFormatter.get(), mpKeywordTable.get() ));
    2963             :                         }
    2964             : 
    2965           8 :                         maDxf.push_back(new XclExpDxf( rRoot, pAlign, pBorder, pFont, pNumFormat, pCellProt, pColor ));
    2966           8 :                         ++nIndex;
    2967             :                     }
    2968             : 
    2969           8 :                 }
    2970             :             }
    2971             :         }
    2972             :     }
    2973           9 : }
    2974             : 
    2975           8 : sal_Int32 XclExpDxfs::GetDxfId( const OUString& rStyleName )
    2976             : {
    2977           8 :     std::map<OUString, sal_Int32>::iterator itr = maStyleNameToDxfId.find(rStyleName);
    2978           8 :     if(itr!= maStyleNameToDxfId.end())
    2979           8 :         return itr->second;
    2980           0 :     return -1;
    2981             : }
    2982             : 
    2983           6 : void XclExpDxfs::SaveXml( XclExpXmlStream& rStrm )
    2984             : {
    2985           6 :     if(maDxf.empty())
    2986          11 :         return;
    2987             : 
    2988           1 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    2989             :     rStyleSheet->startElement( XML_dxfs,
    2990             :             XML_count, OString::number(maDxf.size()).getStr(),
    2991           1 :             FSEND );
    2992             : 
    2993           9 :     for ( DxfContainer::iterator itr = maDxf.begin(); itr != maDxf.end(); ++itr )
    2994             :     {
    2995           8 :         itr->SaveXml( rStrm );
    2996             :     }
    2997             : 
    2998           1 :     rStyleSheet->endElement( XML_dxfs );
    2999             : }
    3000             : 
    3001             : // ============================================================================
    3002             : 
    3003           8 : XclExpDxf::XclExpDxf( const XclExpRoot& rRoot, XclExpCellAlign* pAlign, XclExpCellBorder* pBorder,
    3004             :             XclExpFont* pFont, XclExpNumFmt* pNumberFmt, XclExpCellProt* pProt, XclExpColor* pColor)
    3005             :     : XclExpRoot( rRoot ),
    3006             :     mpAlign(pAlign),
    3007             :     mpBorder(pBorder),
    3008             :     mpFont(pFont),
    3009             :     mpNumberFmt(pNumberFmt),
    3010             :     mpProt(pProt),
    3011           8 :     mpColor(pColor)
    3012             : {
    3013           8 : }
    3014             : 
    3015          16 : XclExpDxf::~XclExpDxf()
    3016             : {
    3017          16 : }
    3018             : 
    3019           8 : void XclExpDxf::SaveXml( XclExpXmlStream& rStrm )
    3020             : {
    3021           8 :     sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
    3022           8 :     rStyleSheet->startElement( XML_dxf, FSEND );
    3023             : 
    3024           8 :     if (mpAlign)
    3025           0 :         mpAlign->SaveXml(rStrm);
    3026           8 :     if (mpBorder)
    3027           0 :         mpBorder->SaveXml(rStrm);
    3028           8 :     if (mpFont)
    3029           8 :         mpFont->SaveXml(rStrm);
    3030           8 :     if (mpNumberFmt)
    3031           8 :         mpNumberFmt->SaveXml(rStrm);
    3032           8 :     if (mpProt)
    3033           0 :         mpProt->SaveXml(rStrm);
    3034           8 :     if (mpColor)
    3035           0 :         mpColor->SaveXml(rStrm);
    3036           8 :     rStyleSheet->endElement( XML_dxf );
    3037           8 : }
    3038             : 
    3039             : // ============================================================================
    3040             : 
    3041           6 : XclExpXmlStyleSheet::XclExpXmlStyleSheet( const XclExpRoot& rRoot )
    3042           6 :     : XclExpRoot( rRoot )
    3043             : {
    3044           6 : }
    3045             : 
    3046           6 : void XclExpXmlStyleSheet::SaveXml( XclExpXmlStream& rStrm )
    3047             : {
    3048             :     sax_fastparser::FSHelperPtr aStyleSheet = rStrm.CreateOutputStream(
    3049             :             OUString( "xl/styles.xml"),
    3050             :             OUString( "styles.xml" ),
    3051           6 :             rStrm.GetCurrentStream()->getOutputStream(),
    3052             :             "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
    3053           6 :             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" );
    3054           6 :     rStrm.PushStream( aStyleSheet );
    3055             : 
    3056             :     aStyleSheet->startElement( XML_styleSheet,
    3057             :             XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
    3058           6 :             FSEND );
    3059             : 
    3060           6 :     CreateRecord( EXC_ID_FORMATLIST )->SaveXml( rStrm );
    3061           6 :     CreateRecord( EXC_ID_FONTLIST )->SaveXml( rStrm );
    3062           6 :     CreateRecord( EXC_ID_XFLIST )->SaveXml( rStrm );
    3063           6 :     CreateRecord( EXC_ID_DXFS )->SaveXml( rStrm );
    3064           6 :     CreateRecord( EXC_ID_PALETTE )->SaveXml( rStrm );
    3065             : 
    3066           6 :     aStyleSheet->endElement( XML_styleSheet );
    3067             : 
    3068           6 :     rStrm.PopStream();
    3069          21 : }
    3070             : 
    3071             : // ============================================================================
    3072             : 
    3073             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10