[ooo-build-commit] .: patches/dev300

Kohei Yoshida kohei at kemper.freedesktop.org
Wed Sep 22 10:09:29 PDT 2010


 patches/dev300/apply                              |    3 
 patches/dev300/calc-xls-import-mem-footprint.diff |  737 ++++++++++++++++++++++
 2 files changed, 740 insertions(+)

New commits:
commit 163500a9dd214be25ab80dbcb4745a4af81ea3fc
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Sep 22 11:03:42 2010 -0400

    Reduce memory footprint during import of Excel documents.
    
    This patch cuts memory footprint of Excel import filter by roughly
    20MB per sheet, and introduces performance enhancement.
    
    With the (confidential) test document I used, the footprint dropped
    from 1.6GB to 224MB with this change, and the time it takes was cut
    by 80% to 90%. (n#637925)
    
    * patches/dev300/apply:
    * patches/dev300/calc-xls-import-mem-footprint.diff:

diff --git a/patches/dev300/apply b/patches/dev300/apply
index 13e1d8d..e253e41 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -2818,6 +2818,9 @@ calc-extref-interpreter-rework-sc.diff,      n#628876, kohei
 # Keep track of cells with SUBTOTAL functions the right way.
 calc-subtotal-function-update.diff, n#578802, kohei
 
+# Reduce memory footprint per sheet during import of xls document.
+calc-xls-import-mem-footprint.diff, n#637925, kohei
+
 [ GentooExperimental ]
 SectionOwner => hmth
 # jemalloc allocator
diff --git a/patches/dev300/calc-xls-import-mem-footprint.diff b/patches/dev300/calc-xls-import-mem-footprint.diff
new file mode 100644
index 0000000..181e768
--- /dev/null
+++ b/patches/dev300/calc-xls-import-mem-footprint.diff
@@ -0,0 +1,737 @@
+diff --git sc/inc/document.hxx sc/inc/document.hxx
+index e59bdee..0e01558 100644
+--- sc/inc/document.hxx
++++ sc/inc/document.hxx
+@@ -1298,13 +1298,14 @@ public:
+     void			DeleteSelectionTab( SCTAB nTab, USHORT nDelFlag, const ScMarkData& rMark );
+ 
+     SC_DLLPUBLIC void           SetColWidth( SCCOL nCol, SCTAB nTab, USHORT nNewWidth );
++    SC_DLLPUBLIC void			SetColWidthOnly( SCCOL nCol, SCTAB nTab, USHORT nNewWidth );
+     SC_DLLPUBLIC void           SetRowHeight( SCROW nRow, SCTAB nTab, USHORT nNewHeight );
+     SC_DLLPUBLIC void           SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, SCTAB nTab,
+                                             USHORT nNewHeight );
+ 
+     SC_DLLPUBLIC void           SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, SCTAB nTab,
+                                                   USHORT nNewHeight );
+-    void                        SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual );
++    SC_DLLPUBLIC void           SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual );
+ 
+     SC_DLLPUBLIC USHORT         GetColWidth( SCCOL nCol, SCTAB nTab ) const;
+     SC_DLLPUBLIC USHORT         GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero = true ) const;
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index db8f171..faf3058 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -622,6 +622,7 @@ public:
+                                     const Fraction& rZoomX, const Fraction& rZoomY,
+                                     BOOL bWidth, BOOL bTotalSize );
+     void		SetColWidth( SCCOL nCol, USHORT nNewWidth );
++    void        SetColWidthOnly( SCCOL nCol, USHORT nNewWidth );
+     void		SetRowHeight( SCROW nRow, USHORT nNewHeight );
+     BOOL		SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight,
+                                     double nPPTX, double nPPTY );
+diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
+index 790c40b..01fbaa2 100644
+--- sc/source/core/data/document.cxx
++++ sc/source/core/data/document.cxx
+@@ -3201,6 +3201,11 @@ void ScDocument::SetColWidth( SCCOL nCol, SCTAB nTab, USHORT nNewWidth )
+         pTab[nTab]->SetColWidth( nCol, nNewWidth );
+ }
+ 
++void ScDocument::SetColWidthOnly( SCCOL nCol, SCTAB nTab, USHORT nNewWidth )
++{
++    if ( ValidTab(nTab) && pTab[nTab] )
++        pTab[nTab]->SetColWidthOnly( nCol, nNewWidth );
++}
+ 
+ void ScDocument::SetRowHeight( SCROW nRow, SCTAB nTab, USHORT nNewHeight )
+ {
+diff --git sc/source/core/data/table2.cxx sc/source/core/data/table2.cxx
+index 5c85eeb..194d80e 100644
+--- sc/source/core/data/table2.cxx
++++ sc/source/core/data/table2.cxx
+@@ -2143,6 +2143,17 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth )
+     }
+ }
+ 
++void ScTable::SetColWidthOnly( SCCOL nCol, USHORT nNewWidth )
++{
++    if (!VALIDCOL(nCol) || !pColWidth)
++        return;
++
++    if (!nNewWidth)
++        nNewWidth = STD_COL_WIDTH;
++
++    if (nNewWidth != pColWidth[nCol])
++        pColWidth[nCol] = nNewWidth;
++}
+ 
+ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight )
+ {
+diff --git sc/source/filter/excel/colrowst.cxx sc/source/filter/excel/colrowst.cxx
+index b62ebea..745d60a 100644
+--- sc/source/filter/excel/colrowst.cxx
++++ sc/source/filter/excel/colrowst.cxx
+@@ -58,8 +58,9 @@ XclImpColRowSettings::XclImpColRowSettings( const XclImpRoot& rRoot ) :
+     XclImpRoot( rRoot ),
+     maWidths( MAXCOLCOUNT, 0 ),
+     maColFlags( MAXCOLCOUNT, 0 ),
+-    maHeights( MAXROWCOUNT, 0 ),
+-    maRowFlags( MAXROWCOUNT, 0 ),
++    maRowHeights(0, MAXROWCOUNT, 0),
++    maRowFlags(0, MAXROWCOUNT, 0),
++    maHiddenRows(0, MAXROWCOUNT, false),
+     mnLastScRow( -1 ),
+     mnDefWidth( STD_COL_WIDTH ),
+     mnDefHeight( static_cast< sal_uInt16 >( STD_ROW_HEIGHT ) ),
+@@ -134,38 +135,59 @@ void XclImpColRowSettings::SetDefHeight( sal_uInt16 nDefHeight, sal_uInt16 nFlag
+ 
+ void XclImpColRowSettings::SetHeight( SCROW nScRow, sal_uInt16 nHeight )
+ {
+-    if( ValidRow( nScRow ) )
+-    {
+-        sal_uInt16 nRawHeight = nHeight & EXC_ROW_HEIGHTMASK;
+-        bool bDefHeight = ::get_flag( nHeight, EXC_ROW_FLAGDEFHEIGHT ) || (nRawHeight == 0);
+-        maHeights[ nScRow ] = nRawHeight;
+-        sal_uInt8& rnFlags = maRowFlags[ nScRow ];
+-        ::set_flag( rnFlags, EXC_COLROW_USED );
+-        if( !bDefHeight && (nRawHeight == 0) )
+-            ::set_flag( rnFlags, EXC_COLROW_HIDDEN );
+-        ::set_flag( rnFlags, EXC_COLROW_DEFAULT, bDefHeight );
+-        if( nScRow > mnLastScRow )
+-            mnLastScRow = nScRow;
+-    }
++    if (!ValidRow(nScRow))
++        return;
++
++    sal_uInt16 nRawHeight = nHeight & EXC_ROW_HEIGHTMASK;
++    bool bDefHeight = ::get_flag( nHeight, EXC_ROW_FLAGDEFHEIGHT ) || (nRawHeight == 0);
++    maRowHeights.insert_back(nScRow, nScRow+1, nRawHeight);
++    sal_uInt8 nFlagVal = 0;
++    if (!maRowFlags.search(nScRow, nFlagVal))
++        return;
++
++    ::set_flag(nFlagVal, EXC_COLROW_USED);
++    ::set_flag(nFlagVal, EXC_COLROW_DEFAULT, bDefHeight);
++
++    if (!bDefHeight && nRawHeight == 0)
++        maHiddenRows.insert_back(nScRow, nScRow+1, true);
++
++    maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
++
++    if (nScRow > mnLastScRow)
++        mnLastScRow = nScRow;
+ }
+ 
+ void XclImpColRowSettings::SetRowSettings( SCROW nScRow, sal_uInt16 nHeight, sal_uInt16 nFlags )
+ {
+-    if( ValidRow( nScRow ) )
+-    {
+-        SetHeight( nScRow, nHeight );
+-        sal_uInt8& rnFlags = maRowFlags[ nScRow ];
+-        if( ::get_flag( nFlags, EXC_ROW_UNSYNCED ) )
+-            ::set_flag( rnFlags, EXC_COLROW_MAN );
+-        if( ::get_flag( nFlags, EXC_ROW_HIDDEN ) )
+-            ::set_flag( rnFlags, EXC_COLROW_HIDDEN );
+-    }
++    if (!ValidRow(nScRow))
++        return;
++
++    SetHeight(nScRow, nHeight);
++
++    sal_uInt8 nFlagVal = 0;
++    if (!maRowFlags.search(nScRow, nFlagVal))
++        return;
++
++    if (::get_flag(nFlags, EXC_ROW_UNSYNCED))
++        ::set_flag(nFlagVal, EXC_COLROW_MAN);
++
++    maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
++
++    if (::get_flag(nFlags, EXC_ROW_HIDDEN))
++        maHiddenRows.insert_back(nScRow, nScRow+1, true);
+ }
+ 
+ void XclImpColRowSettings::SetManualRowHeight( SCROW nScRow )
+ {
+-    if( ValidRow( nScRow ) )
+-        ::set_flag( maRowFlags[ nScRow ], EXC_COLROW_MAN );
++    if (!ValidRow(nScRow))
++        return;
++
++    sal_uInt8 nFlagVal = 0;
++    if (!maRowFlags.search(nScRow, nFlagVal))
++        return;
++
++    ::set_flag(nFlagVal, EXC_COLROW_MAN);
++    maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
+ }
+ 
+ void XclImpColRowSettings::SetDefaultXF( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nXFIndex )
+@@ -201,7 +223,7 @@ void XclImpColRowSettings::Convert( SCTAB nScTab )
+             ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN );
+             nWidth = mnDefWidth;
+         }
+-        rDoc.SetColWidth( nScCol, nScTab, nWidth );
++        rDoc.SetColWidthOnly( nScCol, nScTab, nWidth );
+     }
+ 
+     // row heights ------------------------------------------------------------
+@@ -213,62 +235,64 @@ void XclImpColRowSettings::Convert( SCTAB nScTab )
+         rDoc.SetRowFlags( 0, MAXROW, nScTab, CR_MANUALSIZE );
+     bool bDefHideRow = ::get_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN );
+ 
+-    SCROW nFirstScRow = -1;
+-    sal_uInt16 nLastHeight = 0;
+-    for( SCROW nScRow = 0; nScRow <= mnLastScRow ; ++nScRow )
++    maRowHeights.build_tree();
++    if (!maRowHeights.is_tree_valid())
++        return;
++
++    RowFlagsType::const_iterator itrFlags = maRowFlags.begin(), itrFlagsEnd = maRowFlags.end();
++    SCROW nPrevRow = -1;
++    sal_uInt8 nPrevFlags = 0;
++    sal_uInt16 nPrevHeight = 0;
++    for (; itrFlags != itrFlagsEnd; ++itrFlags)
+     {
+-        // get height and hidden state from cached data
+-        sal_uInt8 nFlags = maRowFlags[ nScRow ];
+-        sal_uInt16 nHeight = 0;
+-        bool bHideRow = false;
+-        if( ::get_flag( nFlags, EXC_COLROW_USED ) )
++        SCROW nRow = itrFlags->first;
++        sal_uInt8 nFlags = itrFlags->second;
++        if (nPrevRow >= 0)
+         {
+-            if( ::get_flag( nFlags, EXC_COLROW_DEFAULT ) )
+-            {
+-                nHeight = mnDefHeight;
+-                bHideRow = bDefHideRow;
+-            }
+-            else
++            sal_uInt16 nHeight = 0;
++
++            if (::get_flag(nPrevFlags, EXC_COLROW_USED))
+             {
+-                nHeight = maHeights[ nScRow ];
+-                if( nHeight == 0 )
++                if (::get_flag(nPrevFlags, EXC_COLROW_DEFAULT))
+                 {
+                     nHeight = mnDefHeight;
+-                    bHideRow = true;
++                    rDoc.SetRowHeightOnly(nPrevRow, nRow-1, nScTab, nHeight);
++                }
++                else
++                {
++                    for (SCROW i = nPrevRow; i <= nRow - 1; ++i)
++                    {
++                        SCROW nLast;
++                        if (!maRowHeights.search_tree(i, nHeight, NULL, &nLast))
++                        {
++                            // search failed for some reason
++                            return;
++                        }
++
++                        if (nLast > nRow)
++                            nLast = nRow;
++
++                        rDoc.SetRowHeightOnly(i, nLast-1, nScTab, nHeight);
++                        i = nLast-1;
++                        nPrevHeight = nHeight;
++                    }
+                 }
+-            }
+ 
+-            if( ::get_flag( nFlags, EXC_COLROW_MAN ) )
+-                rDoc.SetRowFlags( nScRow, nScTab, rDoc.GetRowFlags( nScRow, nScTab ) | CR_MANUALSIZE );
+-        }
+-        else
+-        {
+-            nHeight = mnDefHeight;
+-            bHideRow = bDefHideRow;
++                if (::get_flag(nPrevFlags, EXC_COLROW_MAN))
++                    rDoc.SetManualHeight(nPrevRow, nRow-1, nScTab, true);
++            }
++            else
++            {
++                nHeight = mnDefHeight;
++                rDoc.SetRowHeightOnly(nPrevRow, nRow-1, nScTab, nHeight);
++            }
++            nPrevHeight = nHeight;
+         }
+ 
+-        /*  Hidden rows: remember hidden state, but do not set hidden state in
+-            document here. Needed for #i11776#, no HIDDEN flags in the document,
+-            until filters and outlines are inserted. */
+-        if( bHideRow )
+-            ::set_flag( maRowFlags[ nScRow ], EXC_COLROW_HIDDEN );
+-
+-        // set height range
+-        if( (nLastHeight != nHeight) || (nScRow == 0) )
+-        {
+-            DBG_ASSERT( (nScRow == 0) || (nFirstScRow >= 0), "XclImpColRowSettings::Convert - algorithm error" );
+-            if( nScRow > 0 )
+-                rDoc.SetRowHeightOnly( nFirstScRow, nScRow - 1, nScTab, nLastHeight );
+-
+-            nFirstScRow = nScRow;
+-            nLastHeight = nHeight;
+-        }
++        nPrevRow = nRow;
++        nPrevFlags = nFlags;
+     }
+ 
+-    // set row height of last portion
+-    if( mnLastScRow >= 0 )
+-        rDoc.SetRowHeightOnly( nFirstScRow, mnLastScRow, nScTab, nLastHeight );
+-
+     // ------------------------------------------------------------------------
+ 
+     mbDirty = false;
+@@ -298,17 +322,41 @@ void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab )
+         }
+     }
+ 
+-    // hide the rows
+-    for( SCROW nScRow = 0; nScRow <= mnLastScRow; ++nScRow )
++    // In case the excel row limit is lower than calc's, use the visibility of
++    // the last row and extend it to calc's last row.
++    SCROW nLastXLRow = GetRoot().GetXclMaxPos().Row();
++    if (nLastXLRow < MAXROW)
+     {
+-        if( ::get_flag( maRowFlags[ nScRow ], EXC_COLROW_HIDDEN ) )
++        bool bHidden = false;
++        if (!maHiddenRows.search(nLastXLRow, bHidden))
++            return;
++    
++        maHiddenRows.insert_back(nLastXLRow, MAXROWCOUNT, bHidden);
++    }
++
++    SCROW nPrevRow = -1;
++    bool bPrevHidden = false;
++    RowHiddenType::const_iterator itr = maHiddenRows.begin(), itrEnd = maHiddenRows.end();
++    for (; itr != itrEnd; ++itr)
++    {
++        SCROW nRow = itr->first;
++        bool bHidden = itr->second;
++        if (nPrevRow >= 0)
+         {
+-            // hide the row
+-            rDoc.ShowRow( nScRow, nScTab, FALSE );
+-            // #i38093# rows hidden by filter need extra flag
+-            if( (nFirstFilterScRow <= nScRow) && (nScRow <= nLastFilterScRow) )
+-                rDoc.SetRowFiltered(nScRow, nScRow, nScTab, true);
++            if (bPrevHidden)
++            {
++                rDoc.ShowRows(nPrevRow, nRow-1, nScTab, false);
++                // #i38093# rows hidden by filter need extra flag
++                if (nFirstFilterScRow <= nPrevRow && nPrevRow <= nLastFilterScRow)
++                {
++                    SCROW nLast = ::std::min(nRow-1, nLastFilterScRow);
++                    rDoc.SetRowFiltered(nPrevRow, nLast, nScTab, true);
++                }
++            }
+         }
++
++        nPrevRow = nRow;
++        bPrevHidden = bHidden;
+     }
+ 
+     // #i47438# if default row format is hidden, hide remaining rows
+diff --git sc/source/filter/excel/exctools.cxx sc/source/filter/excel/exctools.cxx
+index c6a5e5e..a37ff1b 100644
+--- sc/source/filter/excel/exctools.cxx
++++ sc/source/filter/excel/exctools.cxx
+@@ -59,6 +59,8 @@
+ #include "xilink.hxx"
+ #include "xecontent.hxx"
+ 
++#include <vector>
++
+ // - ALLGEMEINE ----------------------------------------------------------
+ 
+ RootData::RootData( void )
+@@ -91,192 +93,93 @@ RootData::~RootData()
+ }
+ 
+ 
+-
+-
+-XclImpOutlineBuffer::XclImpOutlineBuffer( SCSIZE nNewSize )
++XclImpOutlineBuffer::XclImpOutlineBuffer( SCSIZE nNewSize ) :
++    maLevels(0, nNewSize, 0),
++    mpOutlineArray(NULL),
++    mnMaxLevel(0),
++    mbButtonAfter(true)
+ {
+-    DBG_ASSERT( nNewSize > 0, "-OutlineBuffer::Ctor: nNewSize == 0!" );
+-
+-    nSize = nNewSize + 1;
+-    pLevel = new BYTE[ nSize ];
+-    pOuted = new BOOL[ nSize ];
+-    pHidden = new BOOL[ nSize ];
+-    pOutlineArray = NULL;
+-
+-    Reset();
+ }
+ 
+-
+ XclImpOutlineBuffer::~XclImpOutlineBuffer()
+ {
+-    delete[] pLevel;
+-    delete[] pOuted;
+-    delete[] pHidden;
+ }
+ 
+-
+-void XclImpOutlineBuffer::SetLevel( SCSIZE nIndex, BYTE nVal, BOOL bOuted, BOOL bHidden )
++void XclImpOutlineBuffer::SetLevel( SCSIZE nIndex, sal_uInt8 nVal, bool bCollapsed )
+ {
+-    if( nIndex < nSize )
+-    {
+-        pLevel[ nIndex ] = nVal;
+-        pOuted[ nIndex ] = bOuted;
+-        pHidden[ nIndex ] = bHidden;
+-
+-        if( nIndex > nLast )
+-            nLast = nIndex;
+-        if( nVal > nMaxLevel )
+-            nMaxLevel = nVal;
+-    }
++    maLevels.insert_back(nIndex, nIndex+1, nVal);
++    if (nVal > mnMaxLevel)
++        mnMaxLevel = nVal;
++    if (bCollapsed)
++        maCollapsedPosSet.insert(nIndex);
+ }
+ 
+-
+ void XclImpOutlineBuffer::SetOutlineArray( ScOutlineArray* pOArray )
+ {
+-    pOutlineArray = pOArray;
++    mpOutlineArray = pOArray;
+ }
+ 
+-
+-// transtorm xcl-outline into SC-outline
+-void XclImpOutlineBuffer::MakeScOutline( void )
++void XclImpOutlineBuffer::MakeScOutline()
+ {
+-    if( !pOutlineArray || !HasOutline() )
++    if (!mpOutlineArray)
+         return;
+ 
+-    const UINT16	nNumLev			= 8;
+-    BOOL			bPreOutedLevel	= FALSE;
+-    BYTE			nCurrLevel		= 0;
+-    BOOL			bMakeHidden[ nNumLev ];
+-    BOOL			bMakeVisible[ nNumLev + 1 ];
+-
+-    sal_uInt16 nLevel;
+-    for( nLevel = 0; nLevel < nNumLev; ++nLevel )
+-        bMakeHidden[ nLevel ] = FALSE;
+-    for( nLevel = 0; nLevel <= nNumLev; ++nLevel )
+-        bMakeVisible[ nLevel ] = TRUE;
+-    if( nLast < (nSize - 1) )
+-        nLast++;
+-
+-    // search for hidden attributes at end of level, move them to begin
+-    if( bButtonNormal )
++    ::std::vector<sal_uInt8> aOutlineStack;
++    aOutlineStack.reserve(mnMaxLevel);
++    OutlineLevels::const_iterator itr = maLevels.begin(), itr_end = maLevels.end();
++    for (; itr != itr_end; ++itr)
+     {
+-        for( BYTE nWorkLevel = 1; nWorkLevel <= nMaxLevel; nWorkLevel++ )
++        SCSIZE nPos = itr->first;
++        sal_uInt8 nLevel = itr->second;
++        sal_uInt8 nCurLevel = static_cast<sal_uInt8>(aOutlineStack.size());
++        if (nLevel > nCurLevel)
+         {
+-            UINT16	nStartPos       = 0;
+-            BYTE    nCurrLevel2 = 0;
+-            BYTE	nPrevLevel	= 0;
+-
+-            for( SCSIZE nC = 0 ; nC <= nLast ; nC++ )
++            for (sal_uInt8 i = 0; i < nLevel - nCurLevel; ++i)
++                aOutlineStack.push_back(nPos);
++        }
++        else
++        {
++            DBG_ASSERT(nLevel < nCurLevel, "XclImpOutlineBuffer::MakeScOutline: unexpected level!");
++            for (sal_uInt8 i = 0; i < nCurLevel - nLevel; ++i)
+             {
+-                nPrevLevel = nCurrLevel2;
+-                nCurrLevel2 = pLevel[ nC ];
+-                if( (nPrevLevel < nWorkLevel) && (nCurrLevel2 >= nWorkLevel) )
+-                    nStartPos = static_cast< sal_uInt16 >( nC );
+-                else if( (nPrevLevel >= nWorkLevel) && (nCurrLevel2 < nWorkLevel) )
++                if (aOutlineStack.empty())
+                 {
+-                    if( pOuted[ nC ] && pHidden[ nStartPos ] )
+-                    {
+-                        if( nStartPos )
+-                            pOuted[ nStartPos - 1 ] = TRUE;
+-                        else
+-                            bPreOutedLevel = TRUE;
+-                        pOuted[ nC ] = FALSE;
+-                    }
++                    // Something is wrong.
++                    return;
+                 }
++                SCSIZE nFirstPos = aOutlineStack.back();
++                sal_uInt8 nThisLevel = static_cast<sal_uInt8>(aOutlineStack.size());
++                aOutlineStack.pop_back();
++                bool bCollapsed = false;
++                if (mbButtonAfter)
++                    bCollapsed = maCollapsedPosSet.count(nPos) > 0;
++                else if (nFirstPos > 0)
++                    bCollapsed = maCollapsedPosSet.count(nFirstPos-1) > 0;
++
++                BOOL bDummy;
++                mpOutlineArray->Insert(nFirstPos, nPos-1, bDummy, bCollapsed);
+             }
+         }
+     }
+-    else
+-        bPreOutedLevel = pHidden[ 0 ];
+-
+-    // generate SC outlines
+-    UINT16	nPrevC;
+-    UINT16	nStart[ nNumLev ];
+-    BOOL	bDummy;
+-    BOOL	bPrevOuted	= bPreOutedLevel;
+-    BOOL	bCurrHidden = FALSE;
+-    BOOL	bPrevHidden = FALSE;
+-
+-    for( SCSIZE nC = 0; nC <= nLast; nC++ )
+-    {
+-        BYTE nWorkLevel = pLevel[ nC ];
+-
+-        nPrevC      = static_cast< sal_uInt16 >( nC ? nC - 1 : 0 );
+-        bPrevHidden	= bCurrHidden;
+-        bCurrHidden	= pHidden[ nC ];
+-
+-        // open new levels
+-        while( nWorkLevel > nCurrLevel )
+-        {
+-            nCurrLevel++;
+-            bMakeHidden[ nCurrLevel ] = bPrevOuted;
+-            bMakeVisible[ nCurrLevel + 1 ] =
+-                bMakeVisible[ nCurrLevel ] && !bMakeHidden[ nCurrLevel ];
+-            nStart[ nCurrLevel ] = static_cast< sal_uInt16 >( nC );
+-        }
+-        // close levels
+-        while( nWorkLevel < nCurrLevel )
+-        {
+-            BOOL bLastLevel		= (nWorkLevel == (nCurrLevel - 1));
+-            BOOL bRealHidden	= (bMakeHidden[ nCurrLevel ] && bPrevHidden );
+-            BOOL bRealVisible	= (bMakeVisible[ nCurrLevel ] ||
+-                                    (!bCurrHidden && bLastLevel));
+-
+-            pOutlineArray->Insert( nStart[ nCurrLevel ], nPrevC , bDummy,
+-                bRealHidden, bRealVisible );
+-            nCurrLevel--;
+-        }
+-
+-        bPrevOuted = pOuted[ nC ];
+-    }
+ }
+ 
+-
+-void XclImpOutlineBuffer::SetLevelRange( SCSIZE nF, SCSIZE nL, BYTE nVal,
+-                                    BOOL bOuted, BOOL bHidden )
++void XclImpOutlineBuffer::SetLevelRange( SCSIZE nF, SCSIZE nL, sal_uInt8 nVal, bool bCollapsed )
+ {
+-    DBG_ASSERT( nF <= nL, "+OutlineBuffer::SetLevelRange(): Last < First!" );
+-
+-    if( nL < nSize )
+-    {
+-        if( nL > nLast )
+-            nLast = nL;
+-
+-        BYTE*	pLevelCount;
+-        BYTE*	pLast;
+-        BOOL*	pOutedCount;
+-        BOOL*	pHiddenCount;
++    if (nF > nL)
++        // invalid range
++        return;
+ 
+-        pLevelCount = &pLevel[ nF ];
+-        pLast = &pLevel[ nL ];
+-        pOutedCount = &pOuted[ nF ];
+-        pHiddenCount = &pHidden[ nF ];
++    maLevels.insert_back(nF, nL+1, nVal);
+ 
+-        while( pLevelCount <= pLast )
+-        {
+-            *( pLevelCount++ ) = nVal;
+-            *( pOutedCount++ ) = bOuted;
+-            *( pHiddenCount++ ) = bHidden;
+-        }
+-
+-        if( nVal > nMaxLevel )
+-            nMaxLevel = nVal;
+-    }
++    if (bCollapsed)
++        maCollapsedPosSet.insert(nF);
+ }
+ 
+-
+-void XclImpOutlineBuffer::Reset( void )
++void XclImpOutlineBuffer::SetButtonMode( bool bRightOrUnder )
+ {
+-    for( SCSIZE nC = 0 ; nC < nSize ; nC++  )
+-    {
+-        pLevel[ nC ] = 0;
+-        pOuted[ nC ] = pHidden[ nC ] = FALSE;
+-    }
+-    nLast = 0;
+-    nMaxLevel = 0;
++    mbButtonAfter = bRightOrUnder;
+ }
+ 
+-
+ //___________________________________________________________________
+ 
+ 
+diff --git sc/source/filter/excel/impop.cxx sc/source/filter/excel/impop.cxx
+index 16060ba..8dd0258 100644
+--- sc/source/filter/excel/impop.cxx
++++ sc/source/filter/excel/impop.cxx
+@@ -405,9 +405,7 @@ void ImportExcel::Row25( void )
+             aIn >> nGrbit;
+ 
+             sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
+-            pRowOutlineBuff->SetLevel( nRow, nLevel,
+-                ::get_flag( nGrbit, EXC_ROW_COLLAPSED ), ::get_flag( nGrbit, EXC_ROW_HIDDEN ) );
+-
++            pRowOutlineBuff->SetLevel( nRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
+             pColRowBuff->SetRowSettings( nRow, nRowHeight, nGrbit );
+         }
+     }
+@@ -668,7 +666,7 @@ void ImportExcel::Colinfo( void )
+     bool bHidden = ::get_flag( nOpt, EXC_COLINFO_HIDDEN );
+     bool bCollapsed = ::get_flag( nOpt, EXC_COLINFO_COLLAPSED );
+     sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nOpt, 8, 3 );
+-    pColOutlineBuff->SetLevelRange( nColFirst, nColLast, nLevel, bCollapsed, bHidden );
++    pColOutlineBuff->SetLevelRange( nColFirst, nColLast, nLevel, bCollapsed );
+ 
+     if( bHidden )
+         pColRowBuff->HideColRange( nColFirst, nColLast );
+@@ -943,9 +941,7 @@ void ImportExcel::Row34( void )
+         aIn >> nGrbit >> nXF;
+ 
+         sal_uInt8 nLevel = ::extract_value< sal_uInt8 >( nGrbit, 0, 3 );
+-        pRowOutlineBuff->SetLevel( nScRow, nLevel,
+-            ::get_flag( nGrbit, EXC_ROW_COLLAPSED ), ::get_flag( nGrbit, EXC_ROW_HIDDEN ) );
+-
++        pRowOutlineBuff->SetLevel( nScRow, nLevel, ::get_flag( nGrbit, EXC_ROW_COLLAPSED ) );
+         pColRowBuff->SetRowSettings( nScRow, nRowHeight, nGrbit );
+ 
+         if( nGrbit & EXC_ROW_USEDEFXF )
+diff --git sc/source/filter/inc/colrowst.hxx sc/source/filter/inc/colrowst.hxx
+index 768622c..8c664ad 100644
+--- sc/source/filter/inc/colrowst.hxx
++++ sc/source/filter/inc/colrowst.hxx
+@@ -29,6 +29,10 @@
+ #define SC_COLROWST_HXX
+ 
+ #include "xiroot.hxx"
++#include <mdds/flat_segment_tree.hpp>
++
++#define XLS_USE_NEW_ROW_CONT 1
++
+ 
+ class XclImpStream;
+ 
+@@ -59,8 +63,13 @@ public:
+ private:
+     ScfUInt16Vec        maWidths;           /// Column widths in twips.
+     ScfUInt8Vec         maColFlags;         /// Flags for all columns.
+-    ScfUInt16Vec        maHeights;          /// Row heights in twips.
+-    ScfUInt8Vec         maRowFlags;         /// Flags for all rows.
++                                            ///
++    typedef ::mdds::flat_segment_tree<SCROW, sal_uInt16> RowHeightsType;
++    typedef ::mdds::flat_segment_tree<SCROW, sal_uInt8>  RowFlagsType;
++    typedef ::mdds::flat_segment_tree<SCROW, bool>       RowHiddenType;
++    RowHeightsType      maRowHeights;
++    RowFlagsType        maRowFlags;
++    RowHiddenType       maHiddenRows;
+ 
+     SCROW               mnLastScRow;
+ 
+diff --git sc/source/filter/inc/otlnbuff.hxx sc/source/filter/inc/otlnbuff.hxx
+index 036a55f..5d509b9 100644
+--- sc/source/filter/inc/otlnbuff.hxx
++++ sc/source/filter/inc/otlnbuff.hxx
+@@ -29,50 +29,31 @@
+ #define SC_OTLNBUFF_HXX
+ 
+ #include <tools/solar.h>
++#include <mdds/flat_segment_tree.hpp>
++#include <set>
+ 
+ class ScOutlineArray;
+ 
+ class XclImpOutlineBuffer
+ {
+-    // -> exctools.cxx
+-    private:
+-        BYTE*			pLevel;
+-        BOOL*			pOuted;
+-        BOOL*			pHidden;
+-        SCSIZE			nSize;
+-        SCSIZE			nLast;
+-        BYTE			nMaxLevel;
+-        ScOutlineArray*	pOutlineArray;
+-        BOOL			bButtonNormal;	// TRUE -> right / under
+-    public:
+-                        XclImpOutlineBuffer( SCSIZE nNewSize );
+-                        ~XclImpOutlineBuffer();
+-        void			SetLevel( SCSIZE nIndex, BYTE nVal, BOOL bOuted, BOOL bHidden );
+-        void			SetOutlineArray( ScOutlineArray* pOArray );
+-        void			Reset( void );
+-        void			MakeScOutline( void );
+-        void			SetLevelRange( SCSIZE nF, SCSIZE nL, BYTE nVal,
+-                            BOOL bOuted, BOOL bHidden );
+-
+-        inline BOOL		HasOutline( void ) const;
+-
+-        inline void		SetButtonMode( const BOOL bRightOrUnder );
++public:
++    XclImpOutlineBuffer( SCSIZE nNewSize );
++    ~XclImpOutlineBuffer();
++
++    void SetLevel( SCSIZE nIndex, sal_uInt8 nVal, bool bCollapsed );
++    void SetOutlineArray( ScOutlineArray* pOArray );
++    void MakeScOutline();
++    void SetLevelRange( SCSIZE nF, SCSIZE nL, sal_uInt8 nVal, bool bCollapsed );
++    void SetButtonMode( bool bRightOrUnder );
++
++private:
++    typedef ::mdds::flat_segment_tree<SCSIZE, sal_uInt8> OutlineLevels;
++    OutlineLevels       maLevels;
++    ::std::set<SCSIZE>  maCollapsedPosSet;
++    ScOutlineArray*     mpOutlineArray;
++    sal_uInt8           mnMaxLevel;
++    bool                mbButtonAfter:1;
+ };
+ 
+-
+-
+-
+-inline BOOL XclImpOutlineBuffer::HasOutline( void ) const
+-{
+-    return nMaxLevel > 0;
+-}
+-
+-
+-inline void XclImpOutlineBuffer::SetButtonMode( const BOOL b )
+-{
+-    bButtonNormal = b;
+-}
+-
+-
+ #endif
+ 


More information about the ooo-build-commit mailing list