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

Generated by: LCOV version 1.10