LCOV - code coverage report
Current view: top level - libreoffice/sc/source/filter/excel - xestyle.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 931 1480 62.9 %
Date: 2012-12-27 Functions: 147 192 76.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10