diff options
author | Eike Rathke <erack@redhat.com> | 2012-05-14 18:18:25 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2012-05-14 18:18:52 +0200 |
commit | 435c117c1c684d4603f557ed821c1fd5ee057086 (patch) | |
tree | ef8ebdfb4cb970999adcc3416b967511a53af490 | |
parent | 904763b1134bdd84a4e64de1e037da5cac192f27 (diff) |
some optimization of ScAttrArray::GetLastVisibleAttr()
Method assumed that not much attribution happens below data and started from
the end of attribution, in the case of not much attribution it worked fine.
For the case of many differently formatted areas with a sufficiently large
area of visibly equal attribution near data end it was a bottle neck looping
over unnecessarily many comparisons. Start at data end instead. For the case
of not much attribution it doesn't really matter, and for the case of no
sufficiently large area below data end it doesn't matter at all and compares
the same number of entries. The drawback would be a large area near
attribution end with many small areas between data end and the large area.
Observed with test case of fdo#46160
-rw-r--r-- | sc/source/core/data/attarray.cxx | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx index 72d08fc0013b..9de2b0211519 100644 --- a/sc/source/core/data/attarray.cxx +++ b/sc/source/core/data/attarray.cxx @@ -1762,6 +1762,8 @@ const SCROW SC_VISATTR_STOP = 84; bool ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData, bool bFullFormattedArea ) const { + OSL_ENSURE( nCount, "nCount == 0" ); + // #i30830# changed behavior: // ignore all attributes starting with the first run of SC_VISATTR_STOP equal rows // below the last content cell @@ -1772,36 +1774,49 @@ bool ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData, bool bFu return true; } - bool bFound = false; - - // loop backwards from the end instead of using Search, assuming that - // there usually aren't many attributes below the last cell - - SCSIZE nPos = nCount; - while ( nPos > 0 && pData[nPos-1].nRow > nLastData ) + // Quick check: last data row in or immediately preceding a run that is the + // last attribution down to the end, e.g. default style or column style. + SCSIZE nPos = nCount - 1; + SCROW nStartRow = (nPos ? pData[nPos-1].nRow + 1 : 0); + if (nStartRow <= nLastData + 1) { - SCSIZE nEndPos = nPos - 1; - SCSIZE nStartPos = nEndPos; // find range of visually equal formats - while ( nStartPos > 0 && - pData[nStartPos-1].nRow > nLastData && - pData[nStartPos-1].pPattern->IsVisibleEqual(*pData[nStartPos].pPattern) ) - --nStartPos; + if (bFullFormattedArea && pData[nPos].pPattern->IsVisible()) + { + rLastRow = pData[nPos].nRow; + return true; + } + else + { + // Ignore here a few rows if data happens to end within + // SC_VISATTR_STOP rows before MAXROW. + rLastRow = nLastData; + return false; + } + } + // Find a run below last data row. + bool bFound = false; + Search( nLastData, nPos ); + while ( nPos < nCount ) + { + // find range of visually equal formats + SCSIZE nStartPos = nPos; + SCSIZE nEndPos = nStartPos + 1; + while ( nEndPos < nCount-1 && + pData[nEndPos].pPattern->IsVisibleEqual( *pData[nEndPos+1].pPattern)) + ++nEndPos; SCROW nAttrStartRow = ( nStartPos > 0 ) ? ( pData[nStartPos-1].nRow + 1 ) : 0; if ( nAttrStartRow <= nLastData ) nAttrStartRow = nLastData + 1; SCROW nAttrSize = pData[nEndPos].nRow + 1 - nAttrStartRow; if ( nAttrSize >= SC_VISATTR_STOP && !bFullFormattedArea ) - { - bFound = false; // ignore this range and below - } - else if ( !bFound && pData[nEndPos].pPattern->IsVisible() ) + break; // while, ignore this range and below + else if ( pData[nEndPos].pPattern->IsVisible() ) { rLastRow = pData[nEndPos].nRow; bFound = true; } - - nPos = nStartPos; // look further from the top of the range + nPos = nEndPos; } return bFound; |