LCOV - code coverage report
Current view: top level - sc/source/filter/excel - xestyle.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1197 1516 79.0 %
Date: 2014-11-03 Functions: 173 192 90.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10