diff options
author | Eike Rathke [er] <erAck@sun.com> | 2010-07-16 15:58:36 +0200 |
---|---|---|
committer | Eike Rathke [er] <erAck@sun.com> | 2010-07-16 15:58:36 +0200 |
commit | 98cdf3324314ebf7ee69605af2a8fc28be092528 (patch) | |
tree | d65a24b2527fbfa240a7bf5323fd3f929876a6ed /sc/source/ui | |
parent | d5d147219645771f745d46db17d6fd2c31347aae (diff) |
calc56: #i113139# various performance improvements for 1MB rows, especially with large hidden segments
Diffstat (limited to 'sc/source/ui')
-rw-r--r-- | sc/source/ui/inc/viewdata.hxx | 18 | ||||
-rw-r--r-- | sc/source/ui/undo/undoblk.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin4.cxx | 12 | ||||
-rw-r--r-- | sc/source/ui/view/output.cxx | 14 | ||||
-rw-r--r-- | sc/source/ui/view/viewdata.cxx | 161 |
5 files changed, 144 insertions, 63 deletions
diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx index 106d196a8175..fb9c674a4488 100644 --- a/sc/source/ui/inc/viewdata.hxx +++ b/sc/source/ui/inc/viewdata.hxx @@ -482,6 +482,24 @@ public: BOOL IsSelCtrlMouseClick() { return bSelCtrlMouseClick; } static inline long ToPixel( USHORT nTwips, double nFactor ); + + /** while (rScrY <= nEndPixels && rPosY <= nEndRow) add pixels of row + heights converted with nPPTY to rScrY, optimized for row height + segments. Upon return rPosY is the last row evaluated <= nEndRow, rScrY + may be > nEndPixels! + */ + static void AddPixelsWhile( long & rScrY, long nEndPixels, + SCROW & rPosY, SCROW nEndRow, double nPPTY, + const ScDocument * pDoc, SCTAB nTabNo ); + + /** while (rScrY <= nEndPixels && rPosY >= nStartRow) add pixels of row + heights converted with nPPTY to rScrY, optimized for row height + segments. Upon return rPosY is the last row evaluated >= nStartRow, + rScrY may be > nEndPixels! + */ + static void AddPixelsWhileBackward( long & rScrY, long nEndPixels, + SCROW & rPosY, SCROW nStartRow, double nPPTY, + const ScDocument * pDoc, SCTAB nTabNo ); }; diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index c284045c5b11..3fb2c74a9954 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -592,7 +592,7 @@ ScUndoDeleteMulti::ScUndoDeleteMulti( ScDocShell* pNewDocShell, __EXPORT ScUndoDeleteMulti::~ScUndoDeleteMulti() { - delete pRanges; + delete [] pRanges; } String __EXPORT ScUndoDeleteMulti::GetComment() const diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index 6bf27387314a..ba73fbf00269 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -401,17 +401,13 @@ void __EXPORT ScGridWindow::Paint( const Rectangle& rRect ) nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX2, nTab ), nPPTX ); } - long nScrY = ScViewData::ToPixel( pDoc->GetRowHeight( nY1, nTab ), nPPTY ); - while ( nScrY <= aPixRect.Top() && nY1 < MAXROW ) - { - ++nY1; - nScrY += ScViewData::ToPixel( pDoc->GetRowHeight( nY1, nTab ), nPPTY ); - } + long nScrY = 0; + ScViewData::AddPixelsWhile( nScrY, aPixRect.Top(), nY1, MAXROW, nPPTY, pDoc, nTab); SCROW nY2 = nY1; - while ( nScrY <= aPixRect.Bottom() && nY2 < MAXROW ) + if (nScrY <= aPixRect.Bottom() && nY2 < MAXROW) { ++nY2; - nScrY += ScViewData::ToPixel( pDoc->GetRowHeight( nY2, nTab ), nPPTY ); + ScViewData::AddPixelsWhile( nScrY, aPixRect.Bottom(), nY2, MAXROW, nPPTY, pDoc, nTab); } Draw( nX1,nY1,nX2,nY2, SC_UPDATE_MARKS ); // nicht weiterzeichnen diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx index 961572fc0185..7b27ddf3f8cc 100644 --- a/sc/source/ui/view/output.cxx +++ b/sc/source/ui/view/output.cxx @@ -489,6 +489,8 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) // Horizontale Linien // + bool bHiddenRow = true; + SCROW nHiddenEndRow = -1; nPosY = nScrY; for (nArrY=1; nArrY+1<nArrCount; nArrY++) { @@ -503,9 +505,17 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) { for (SCROW i = nYplus1; i <= MAXROW; ++i) { + if (i > nHiddenEndRow) + bHiddenRow = pDoc->RowHidden(i, nTab, nHiddenEndRow); + /* TODO: optimize the row break thing for large hidden + * segments where HasRowBreak() has to be called + * nevertheless for each row, as a row break is drawn also + * for hidden rows, above them. This needed to be done only + * once per hidden segment, maybe giving manual breaks + * priority. Something like GetNextRowBreak() and + * GetNextManualRowBreak(). */ nBreak = pDoc->HasRowBreak(i, nTab); - bool bHidden = pDoc->RowHidden(i, nTab); - if (nBreak || !bHidden) + if (!bHiddenRow || nBreak) break; } diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index c034836d4d4a..38d5aa60eaeb 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -1696,50 +1696,32 @@ SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, USHO if (pView) ((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY); - SCROW nY; - USHORT nScrPosY = 0; - if (nScrSizeY == SC_SIZE_NONE) nScrSizeY = (USHORT) aScrSize.Height(); - if (nDir==1) - nY = nPosY; // vorwaerts - else - nY = nPosY-1; // rueckwaerts - - BOOL bOut = FALSE; - for ( ; nScrPosY<=nScrSizeY && !bOut; nY+=nDir ) - { - SCsROW nRowNo = nY; - if ( nRowNo < 0 || nRowNo > MAXROW ) - bOut = TRUE; - else - { - USHORT nTSize = pDoc->GetRowHeight( nRowNo, nTabNo ); - if (nTSize) - { - long nSizeYPix = ToPixel( nTSize, nPPTY ); - nScrPosY = sal::static_int_cast<USHORT>( nScrPosY + (USHORT) nSizeYPix ); - } - else if ( nDir == 1 && nRowNo < MAXROW ) - { - // skip multiple hidden rows (forward only for now) - SCROW nNext = pDoc->FirstVisibleRow(nRowNo + 1, MAXROW, nTabNo); - if ( nNext > MAXROW ) - { - // same behavior as without the optimization: set bOut with nY=MAXROW+1 - nY = MAXROW+1; - bOut = TRUE; - } - else - nY = nNext - 1; // +=nDir advances to next visible row - } - } - } + SCROW nY; if (nDir==1) + { + // forward + nY = nPosY; + long nScrPosY = 0; + AddPixelsWhile( nScrPosY, nScrSizeY, nY, MAXROW, nPPTY, pDoc, nTabNo); + // Original loop ended on last evaluated +1 or if that was MAXROW even + // on MAXROW+2. + nY += (nY == MAXROW ? 2 : 1); nY -= nPosY; + } else + { + // backward + nY = nPosY-1; + long nScrPosY = 0; + AddPixelsWhileBackward( nScrPosY, nScrSizeY, nY, 0, nPPTY, pDoc, nTabNo); + // Original loop ended on last evaluated -1 or if that was 0 even on + // -2. + nY -= (nY == 0 ? 2 : 1); nY = (nPosY-1)-nY; + } if (nY>0) --nY; return nY; @@ -1855,16 +1837,10 @@ BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich, } if (nClickY > 0) - { - while ( rPosY<=MAXROW && nClickY >= nScrY ) - { - nScrY += ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY ); - ++rPosY; - } - --rPosY; - } + AddPixelsWhile( nScrY, nClickY, rPosY, MAXROW, nPPTY, pDoc, nTabNo ); else { + /* TODO: could need some "SubPixelsWhileBackward" method */ while ( rPosY>0 && nClickY < nScrY ) { --rPosY; @@ -1984,20 +1960,24 @@ void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY ) SCROW nOldPosY = pThisTab->nPosY[eWhich]; long nTPosY = pThisTab->nTPosY[eWhich]; long nPixPosY = pThisTab->nPixPosY[eWhich]; - SCROW i; + SCROW i, nHeightEndRow; if ( nNewPosY > nOldPosY ) for ( i=nOldPosY; i<nNewPosY; i++ ) { - long nThis = pDoc->GetRowHeight( i,nTabNo ); - nTPosY -= nThis; - nPixPosY -= ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY); + long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow ); + SCROW nRows = std::min( nNewPosY, nHeightEndRow + 1) - i; + i = nHeightEndRow; + nTPosY -= nThis * nRows; + nPixPosY -= ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY) * nRows; } else for ( i=nNewPosY; i<nOldPosY; i++ ) { - long nThis = pDoc->GetRowHeight( i,nTabNo ); - nTPosY += nThis; - nPixPosY += ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY); + long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow ); + SCROW nRows = std::min( nOldPosY, nHeightEndRow + 1) - i; + i = nHeightEndRow; + nTPosY += nThis * nRows; + nPixPosY += ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY) * nRows; } pThisTab->nPosY[eWhich] = nNewPosY; @@ -3118,5 +3098,82 @@ ScAddress ScViewData::GetCurPos() const } +// static +void ScViewData::AddPixelsWhile( long & rScrY, long nEndPixels, SCROW & rPosY, + SCROW nEndRow, double nPPTY, const ScDocument * pDoc, SCTAB nTabNo ) +{ + SCROW nRow = rPosY; + while (rScrY <= nEndPixels && nRow <= nEndRow) + { + SCROW nHeightEndRow; + USHORT nHeight = pDoc->GetRowHeight( nRow, nTabNo, NULL, &nHeightEndRow); + if (nHeightEndRow > nEndRow) + nHeightEndRow = nEndRow; + if (!nHeight) + nRow = nHeightEndRow + 1; + else + { + SCROW nRows = nHeightEndRow - nRow + 1; + sal_Int64 nPixel = ToPixel( nHeight, nPPTY); + sal_Int64 nAdd = nPixel * nRows; + if (nAdd + rScrY > nEndPixels) + { + sal_Int64 nDiff = rScrY + nAdd - nEndPixels; + nRows -= nDiff / nPixel; + nAdd = nPixel * nRows; + // We're looking for a value that satisfies loop condition. + if (nAdd + rScrY <= nEndPixels) + { + ++nRows; + nAdd += nPixel; + } + } + rScrY += static_cast<long>(nAdd); + nRow += nRows; + } + } + if (nRow > rPosY) + --nRow; + rPosY = nRow; +} +// static +void ScViewData::AddPixelsWhileBackward( long & rScrY, long nEndPixels, + SCROW & rPosY, SCROW nStartRow, double nPPTY, const ScDocument * pDoc, + SCTAB nTabNo ) +{ + SCROW nRow = rPosY; + while (rScrY <= nEndPixels && nRow >= nStartRow) + { + SCROW nHeightStartRow; + USHORT nHeight = pDoc->GetRowHeight( nRow, nTabNo, &nHeightStartRow, NULL); + if (nHeightStartRow < nStartRow) + nHeightStartRow = nStartRow; + if (!nHeight) + nRow = nHeightStartRow - 1; + else + { + SCROW nRows = nRow - nHeightStartRow + 1; + sal_Int64 nPixel = ToPixel( nHeight, nPPTY); + sal_Int64 nAdd = nPixel * nRows; + if (nAdd + rScrY > nEndPixels) + { + sal_Int64 nDiff = nAdd + rScrY - nEndPixels; + nRows -= nDiff / nPixel; + nAdd = nPixel * nRows; + // We're looking for a value that satisfies loop condition. + if (nAdd + rScrY <= nEndPixels) + { + ++nRows; + nAdd += nPixel; + } + } + rScrY += static_cast<long>(nAdd); + nRow -= nRows; + } + } + if (nRow < rPosY) + ++nRow; + rPosY = nRow; +} |